ソースを参照

导入分类记录

fubojin 1 日 前
コミット
d993293187

+ 11 - 6
yami-shop-bean/src/main/java/com/yami/shop/bean/dto/ShopCategoryExcelDTO.java

@@ -12,18 +12,23 @@ public class ShopCategoryExcelDTO {
 
     @ExcelProperty("门店ID")
     @ColumnWidth(20)
-    private String shopId;
+    private String hbShopId;
 
-    @ExcelProperty("门店名称")
-    @ColumnWidth(20)
-    private String shopName;
+//    @ExcelProperty("门店名称")
+//    @ColumnWidth(20)
+//    private String shopName;
 
-    @ExcelProperty("一级类名称")
+    @ExcelProperty("一级类名称")
     @ColumnWidth(30)
     private String name;
 
-    @ExcelProperty("二级类名称")
+    @ExcelProperty("二级类名称")
     @ColumnWidth(30)
     private String subName;
 
+
+    @ExcelProperty("三级分类名称")
+    @ColumnWidth(30)
+    private String subSubName;
+
 }

+ 6 - 0
yami-shop-bean/src/main/java/com/yami/shop/bean/model/ShopCategory.java

@@ -100,6 +100,12 @@ public class ShopCategory implements Serializable {
     @TableField(exist = false)
     private String subName;
 
+    /**
+     * 三级类名称(导入时处理需要)
+     */
+    @TableField(exist = false)
+    private String subSubName;
+
     /**
      * 商品数量
      */

+ 83 - 0
yami-shop-bean/src/main/java/com/yami/shop/bean/model/ShopCategoryLog.java

@@ -0,0 +1,83 @@
+package com.yami.shop.bean.model;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 门店前台类目日志表
+ *
+ * @author fbj
+ */
+@Data
+@TableName("tz_shop_category_log")
+public class ShopCategoryLog implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Long id;
+
+    /**
+     * 导入是否成功
+     */
+    private Boolean isFail;
+
+    /**
+     * 失败原因
+     */
+    private String reason;
+
+    /**
+     * 海博门店ID
+     */
+    private String hbShopId;
+
+    /**
+     * 店铺ID
+     */
+    private Long shopId;
+
+    /**
+     * 操作人
+     */
+    private Long sysUserId;
+    /**
+     * 操作人名称
+     */
+    private String sysUserName;
+
+    /**
+     * 一级分类名称
+     */
+    private String name;
+
+    /**
+     * 二级分类名称
+     */
+    private String subName;
+
+    /**
+     * 三级分类名称
+     */
+    private String subSubName;
+
+    /**
+     * 创建时间
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+
+}

+ 1 - 0
yami-shop-platform/src/main/java/com/yami/shop/platform/controller/PointsRechargeController.java

@@ -47,6 +47,7 @@ public class PointsRechargeController {
         IPage<PointsRecharge> page = pointsRechargeService.page(pageParam,new LambdaQueryWrapper<PointsRecharge>()
                 .eq(ObjectUtils.isNotEmpty(pointsRecharge.getChannelId()),PointsRecharge::getChannelId,pointsRecharge.getChannelId())
                 .eq(ObjectUtils.isNotEmpty(pointsRecharge.getUserPhone()),PointsRecharge::getUserPhone,pointsRecharge.getUserPhone())
+                .orderByDesc(PointsRecharge::getCreateTime)
         );
         return R.SUCCESS(page);
     }

+ 3 - 1
yami-shop-platform/src/main/java/com/yami/shop/platform/controller/PointsRecordController.java

@@ -1,7 +1,9 @@
 // PointsRecordController.java
 package com.yami.shop.platform.controller;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yami.shop.bean.model.PointsRecharge;
 import com.yami.shop.bean.model.PointsRecord;
 import com.yami.shop.common.util.PageParam;
 import com.yami.shop.common.util.R;
@@ -32,7 +34,7 @@ public class PointsRecordController {
      */
     @GetMapping("/page")
     public R<IPage<PointsRecord>> page(PageParam<PointsRecord> pageParam) {
-        IPage<PointsRecord> page = pointsRecordService.page(pageParam);
+        IPage<PointsRecord> page = pointsRecordService.page(pageParam,new QueryWrapper<PointsRecord>().orderByDesc("creationDate"));
         return R.SUCCESS(page);
     }
 

+ 4 - 2
yami-shop-platform/src/main/java/com/yami/shop/platform/controller/ShopCategoryController.java

@@ -6,6 +6,8 @@ import com.yami.shop.bean.model.ShopCategory;
 import com.yami.shop.bean.param.CategoryProductDTO;
 import com.yami.shop.common.util.PageParam;
 import com.yami.shop.common.util.R;
+import com.yami.shop.security.platform.model.YamiSysUser;
+import com.yami.shop.security.platform.util.SecurityUtils;
 import com.yami.shop.service.IShopCategoryService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
@@ -92,8 +94,8 @@ public class ShopCategoryController {
     @PostMapping("/import")
     @ApiOperation(value = "导入门店前台类目", notes = "导入门店前台类目")
     public R importCategory(@RequestParam("file") MultipartFile file) {
-
-        shopCategoryService.importCategory(file);
+        YamiSysUser sysUser = SecurityUtils.getSysUser();
+        shopCategoryService.importCategory(file, sysUser.getUserId(), sysUser.getUsername());
         return R.SUCCESS();
     }
 

+ 18 - 0
yami-shop-service/src/main/java/com/yami/shop/dao/ShopCategoryLogMapper.java

@@ -0,0 +1,18 @@
+
+package com.yami.shop.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yami.shop.bean.model.ShopCategory;
+import com.yami.shop.bean.model.ShopCategoryLog;
+import com.yami.shop.bean.vo.FrontCategoryVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @author fbj
+ */
+public interface ShopCategoryLogMapper extends BaseMapper<ShopCategoryLog> {
+
+
+}

+ 1 - 1
yami-shop-service/src/main/java/com/yami/shop/dao/ShopCategoryMapper.java

@@ -18,7 +18,7 @@ import org.apache.ibatis.annotations.Param;
 import java.util.List;
 
 /**
- * @author LGH
+ * @author fbj
  */
 public interface ShopCategoryMapper extends BaseMapper<ShopCategory> {
 

+ 2 - 1
yami-shop-service/src/main/java/com/yami/shop/service/IShopCategoryService.java

@@ -35,7 +35,7 @@ public interface IShopCategoryService extends IService<ShopCategory> {
      * 导入类目
      * @param file  文件
      */
-    void importCategory(MultipartFile file);
+    void importCategory(MultipartFile file, Long userId, String username);
     /**
      * 根据店铺id和顶级分类id,获取分类
      * @param parentId
@@ -49,4 +49,5 @@ public interface IShopCategoryService extends IService<ShopCategory> {
      * @param categoryProductDTO 分类商品参数
      */
     void categoryProduct(CategoryProductDTO categoryProductDTO);
+
 }

+ 103 - 88
yami-shop-service/src/main/java/com/yami/shop/service/impl/ShopCategoryServiceImpl.java

@@ -23,7 +23,9 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
 import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -41,6 +43,7 @@ import java.util.stream.Collectors;
 public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, ShopCategory> implements IShopCategoryService {
 
     private final ShopCategoryMapper shopCategoryMapper;
+    private final ShopCategoryLogMapper shopCategoryLogMapper;
 
     private final FrontCategoryMapper frontCategoryMapper;
     private final CategoryProdMapper categoryProdMapper;
@@ -99,7 +102,7 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void importCategory(MultipartFile file) {
+    public void importCategory(MultipartFile file, Long userId, String username) {
         try {
             // 检查文件是否为空
             if (file == null || file.isEmpty()) {
@@ -111,35 +114,33 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
                 throw new GlobalException("文件格式不正确,请上传Excel文件(.xls或.xlsx)");
             }
             // 解析Excel文件
-            List<ShopCategory> shopCategories = parseExcelFile(file);
+            List<ShopCategoryExcelDTO> shopCategories = parseExcelFile(file);
 
             // 批量保存数据
             if (!shopCategories.isEmpty()) {
-
                 for (int i = 0; i < shopCategories.size(); i++) {
-                    ShopCategory category = shopCategories.get(i);
-                    // 检查数据有效性
-                    Long shopId = validateShopCategories(category, i);
-                    ShopCategory shopCategory = shopCategoryMapper.selectOne(
-                            new LambdaQueryWrapper<ShopCategory>()
-                                    .eq(ShopCategory::getName, category.getName())
-                                    .eq(ShopCategory::getShopId, shopId)
-                                    .eq(ShopCategory::getIsDelete, 0).eq(ShopCategory::getPid, 0L));
-                    if (ObjectUtils.isEmpty(shopCategory)) {
-                        category.setShopId(shopId);
-                        category.setPid(0L);
-                        this.save(category);
-                    } else {
-                        category.setId(shopCategory.getId());
+                    ShopCategoryExcelDTO category = shopCategories.get(i);
+
+                    ShopCategoryLog shopCategoryLog = new ShopCategoryLog();
+                    shopCategoryLog.setName(category.getName());
+                    shopCategoryLog.setSubName(category.getSubName());
+                    shopCategoryLog.setSubSubName(category.getSubSubName());
+                    shopCategoryLog.setHbShopId(category.getHbShopId());
+                    shopCategoryLog.setIsFail(true);
+                    // 设置操作人 获取当前操作人信息
+                    shopCategoryLog.setSysUserId(userId);
+                    shopCategoryLog.setSysUserName(username);
+                    shopCategoryLog.setCreateTime(new Date());
+                    shopCategoryLog.setUpdateTime(new Date());
+
+                    try {
+                        // 检查数据有效性 及 添加
+                        validateShopCategories(category, i);
+                    } catch (Exception e) {
+                        shopCategoryLog.setReason(e.getMessage());
+                        shopCategoryLog.setIsFail(false);
                     }
-
-                    System.out.println(category);
-
-                    //添加对应的二级和三级类目
-                    FrontCategory frontCategoryByName = frontCategoryMapper.selectListName(category.getSubName());
-                    frontCategoryByName.setParentCode(category.getCode());
-                    frontCategoryByName.setParentName(category.getName());
-                    addShopCategory(frontCategoryByName, category.getHbShopId(), shopId, category.getId());
+                    shopCategoryLogMapper.insert(shopCategoryLog);
                 }
             }
         } catch (Exception e) {
@@ -185,7 +186,7 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
     @Override
     public void categoryProduct(CategoryProductDTO categoryProductDTO) {
         List<Long> prodIdList = categoryProductDTO.getProdIdList();
-        if (ObjectUtils.isEmpty(prodIdList)){
+        if (ObjectUtils.isEmpty(prodIdList)) {
             new GlobalException("新增商品为空!请选择商品");
         }
         for (Long aLong : prodIdList) {
@@ -215,7 +216,7 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
      * @param hbShopId      海报
      * @param shopId        门店ID
      */
-    private void addShopCategory(FrontCategory frontCategory, String hbShopId, Long shopId, Long id) {
+    private ShopCategory addShopCategory(FrontCategory frontCategory, String hbShopId, Long shopId, Long id) {
         ShopCategory shopCategory = new ShopCategory();
         shopCategory.setPid(id);
         shopCategory.setName(frontCategory.getName());
@@ -238,6 +239,7 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
         for (FrontCategory frontCategory1 : frontCategoryList) {
             addShopCategory(frontCategory1, hbShopId, shopId, shopCategory.getId());
         }
+        return shopCategory;
     }
 
     /**
@@ -246,27 +248,25 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
      * @param file Excel文件
      * @return 门店前台类目列表
      */
-    private List<ShopCategory> parseExcelFile(MultipartFile file) throws Exception {
-        List<ShopCategory> shopCategories = new ArrayList<>();
-
-        // 使用EasyExcel或Apache POI解析Excel
-        // 这里以EasyExcel为例
-        EasyExcel.read(file.getInputStream(), ShopCategoryExcelDTO.class, new AnalysisEventListener<ShopCategoryExcelDTO>() {
-            @Override
-            public void invoke(ShopCategoryExcelDTO excelDTO, AnalysisContext context) {
-                ShopCategory shopCategory = convertToShopCategory(excelDTO);
-                if (shopCategory != null) {
-                    shopCategories.add(shopCategory);
+    private List<ShopCategoryExcelDTO> parseExcelFile(MultipartFile file) throws Exception {
+
+        List<ShopCategoryExcelDTO> excelDataList = new ArrayList<>();
+        try (InputStream inputStream = file.getInputStream()) {
+            // 使用EasyExcel读取Excel文件
+            EasyExcel.read(inputStream, ShopCategoryExcelDTO.class, new AnalysisEventListener<ShopCategoryExcelDTO>() {
+                @Override
+                public void invoke(ShopCategoryExcelDTO data, AnalysisContext context) {
+                    // 处理每一行数据
+                    excelDataList.add(data);
                 }
-            }
-
-            @Override
-            public void doAfterAllAnalysed(AnalysisContext context) {
-                // 解析完成后的操作
-            }
-        }).sheet().doRead();
+                @Override
+                public void doAfterAllAnalysed(AnalysisContext context) {
+                    // 所有数据解析完成后的操作
+                }
+            }).sheet().doRead();
+        }
 
-        return shopCategories;
+        return excelDataList;
     }
 
     /**
@@ -283,8 +283,9 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
         ShopCategory shopCategory = new ShopCategory();
         shopCategory.setName(excelDTO.getName());
         shopCategory.setSubName(excelDTO.getSubName());
+        shopCategory.setSubSubName(excelDTO.getSubSubName());
         shopCategory.setCode(generateUniqueCode());
-        shopCategory.setHbShopId(excelDTO.getShopId());
+        shopCategory.setHbShopId(excelDTO.getHbShopId());
         shopCategory.setIsDelete(0); // 默认未删除
         shopCategory.setParentCode("0"); // 默认未删除
 
@@ -297,10 +298,11 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
      * @return 唯一编码
      */
     private synchronized String generateUniqueCode() {
-        // 使用时间戳+随机数生成唯一编码
-        long timestamp = System.currentTimeMillis();
-        int randomNum = (int) (Math.random() * 9999);
-        return "BM" + timestamp + String.format("%04d", randomNum);
+        // 使用时间年月日+四位随机数生成唯一编码
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+        String date = sdf.format(new Date());
+        String random = String.valueOf((int) (Math.random() * 10000));
+        return "F" + date + random;
     }
 
     /**
@@ -308,49 +310,62 @@ public class ShopCategoryServiceImpl extends ServiceImpl<ShopCategoryMapper, Sho
      *
      * @param category 门店前台类目
      */
-    private Long validateShopCategories(ShopCategory category, int i) {
-        // 检查必填字段
-        if (ObjectUtils.isEmpty(category.getName())) {
-            throw new GlobalException("第" + (i + 1) + "行:类目名称不能为空");
-        }
-        if (ObjectUtils.isEmpty(category.getHbShopId())) {
-            throw new GlobalException("第" + (i + 1) + "行:门店ID不能为空");
-        }
-        ShopDetail shopDetail = shopDetailMapper.selectByHbStationId(category.getHbShopId());
-        if (ObjectUtils.isEmpty(shopDetail)) {
-            throw new GlobalException("第" + (i + 1) + "行:门店不存在");
-        }
+    private void validateShopCategories(ShopCategoryExcelDTO category, int i) {
 
-        // 检查类目名称长度
-        if (category.getName().length() > 255) {
-            throw new GlobalException("第" + (i + 1) + "行:类目名称长度不能超过255个字符");
-        }
+            // 检查必填字段
+            if (ObjectUtils.isEmpty(category.getHbShopId())) {
+                throw new GlobalException("第" + (i + 1) + "行:门店ID不能为空");
+            }
+            ShopDetail shopDetail = shopDetailMapper.selectByHbStationId(category.getHbShopId());
+            if (ObjectUtils.isEmpty(shopDetail)) {
+                throw new GlobalException("第" + (i + 1) + "行:门店不存在");
+            }
+            if (ObjectUtils.isEmpty(category.getSubSubName())) {
+                throw new GlobalException("第" + (i + 1) + "行:类目名称不能为空");
+            }
+            // 检查类目名称长度
+            if (category.getSubSubName().length() > 255) {
+                throw new GlobalException("第" + (i + 1) + "行:类目名称长度不能超过255个字符");
+            }
 
-        // 检查是否已存在相同记录(根据类目名称+门店ID)
-        ShopCategory existingCategory = this.getOne(new LambdaQueryWrapper<ShopCategory>()
-                .eq(ShopCategory::getName, category.getName())
-                .eq(ShopCategory::getShopId, category.getShopId())
-                .last("LIMIT 1"));
+            //查看前台类目模板里面是否存在二级类目
+            FrontCategory frontCategory = frontCategoryMapper.selectOne(new LambdaQueryWrapper<FrontCategory>()
+                    .eq(FrontCategory::getParentName, category.getName())
+                    .eq(FrontCategory::getName, category.getSubName())
+                    .eq(FrontCategory::getIsDelete, 0));
 
-        if (existingCategory != null) {
-            throw new GlobalException("第" + (i + 1) + "行:门店'" + category.getShopId() +
-                    "'下已存在类目名称为'" + category.getName() + "'的记录");
-        }
 
-        //查看前台类目模板里面是否存在二级类目
-        Integer integer = frontCategoryMapper.selectCount(new LambdaQueryWrapper<FrontCategory>()
-                .eq(FrontCategory::getName, category.getSubName())
-                .eq(FrontCategory::getIsDelete, 0));
+            if (frontCategory == null) {
+                throw new GlobalException("第" + (i + 1) + "行:一二级对应类目不存在");
+            }
+
 
-        if (integer < 1) {
-            throw new GlobalException("第" + (i + 1) + "行:二级类目" + category.getSubName() + "不存在");
-        }
+            ShopCategory shopCategoryByCode1 = shopCategoryMapper.selectOne(new LambdaQueryWrapper<ShopCategory>()
+                    .eq(ShopCategory::getCode, frontCategory.getCode())
+                    .eq(ShopCategory::getIsDelete, 0)
+                    .eq(ShopCategory::getShopId, shopDetail.getShopId()));
+            if (shopCategoryByCode1 == null) {
+                shopCategoryByCode1 = addShopCategory(frontCategory, shopDetail.getHbStationId(), shopDetail.getShopId(), shopCategoryByCode1.getId());
+            }
 
-        if (integer > 1) {
-            throw new GlobalException("第" + (i + 1) + "行:二级类目" + category.getSubName() + "存在多个");
-        }
-        return shopDetail.getShopId();
-    }
+            ShopCategory shopCategory = new ShopCategory();
+            shopCategory.setPid(shopCategoryByCode1.getId());
+            shopCategory.setName(category.getSubSubName());
+            shopCategory.setCode(generateUniqueCode());
+            shopCategory.setParentCode(shopCategoryByCode1.getCode());
+            shopCategory.setParentName(shopCategoryByCode1.getName());
+            shopCategory.setLevel(3);
+            shopCategory.setNum(0);
+            shopCategory.setIsDelete(0);
+            shopCategory.setOperateUser("admin");
+            shopCategory.setIsLeaves(1);
+            shopCategory.setIcon("https://zswl-shop.oss-cn-chengdu.aliyuncs.com/2025/09/eae85a85269045f6ba484bd1edf5f975.jpg");
+
+            shopCategory.setHbShopId(shopDetail.getHbStationId());
+            shopCategory.setShopId(shopDetail.getShopId());
+            log.info("添加门店前台类目:{}", shopCategory);
+            this.save(shopCategory);
 
+    }
 
 }