Kaynağa Gözat

商城数据显示优化,溯源码功能提交

yjwang 1 hafta önce
ebeveyn
işleme
16021449d0

+ 177 - 0
fs-admin/src/main/java/com/fs/hisStore/controller/FsStoreVerifyCodeScrmController.java

@@ -0,0 +1,177 @@
+package com.fs.hisStore.controller;
+
+import java.util.List;
+
+import com.fs.common.core.domain.R;
+import com.fs.common.core.domain.model.LoginUser;
+import com.fs.common.utils.ServletUtils;
+import com.fs.common.utils.poi.ExcelUtil;
+
+import com.fs.course.dto.FsStoreVerifyCodeDTO;
+import com.fs.framework.web.service.TokenService;
+import com.fs.hisStore.domain.FsStoreVerifyCodeScrm;
+import com.fs.hisStore.service.IFsStoreVerifyCodeScrmService;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.fs.common.annotation.Log;
+import com.fs.common.core.controller.BaseController;
+import com.fs.common.core.domain.AjaxResult;
+import com.fs.common.enums.BusinessType;
+import com.fs.common.core.page.TableDataInfo;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 核销码Controller
+ * 
+ * @author fs
+ * @date 2025-11-27
+ */
+@RestController
+@RequestMapping("/shop/scrm")
+public class FsStoreVerifyCodeScrmController extends BaseController
+{
+    @Autowired
+    private IFsStoreVerifyCodeScrmService fsStoreVerifyCodeScrmService;
+
+    @Autowired
+    private TokenService tokenService;
+
+
+    // 允许的文件扩展名
+    private static final String[] ALLOWED_EXCEL_EXTENSIONS = {".xlsx", ".xls"};
+
+    // 最大文件大小(5MB)
+    private static final long MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
+
+
+    /**
+     * 查询核销码列表
+     */
+    @PreAuthorize("@ss.hasPermi('shop:scrm:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm)
+    {
+        startPage();
+        List<FsStoreVerifyCodeScrm> list = fsStoreVerifyCodeScrmService.selectFsStoreVerifyCodeScrmList(fsStoreVerifyCodeScrm);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出核销码列表
+     */
+    @PreAuthorize("@ss.hasPermi('shop:scrm:export')")
+    @Log(title = "核销码", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm)
+    {
+        List<FsStoreVerifyCodeScrm> list = fsStoreVerifyCodeScrmService.selectFsStoreVerifyCodeScrmList(fsStoreVerifyCodeScrm);
+        ExcelUtil<FsStoreVerifyCodeScrm> util = new ExcelUtil<FsStoreVerifyCodeScrm>(FsStoreVerifyCodeScrm.class);
+        return util.exportExcel(list, "核销码数据");
+    }
+
+    /**
+     * 获取核销码详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('shop:scrm:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") String id)
+    {
+        return AjaxResult.success(fsStoreVerifyCodeScrmService.selectFsStoreVerifyCodeScrmById(id));
+    }
+
+    /**
+     * 新增核销码
+     */
+    @PreAuthorize("@ss.hasPermi('shop:scrm:add')")
+    @Log(title = "核销码", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm)
+    {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        fsStoreVerifyCodeScrm.setCreateBy(loginUser.getUserId().toString());
+        return toAjax(fsStoreVerifyCodeScrmService.insertFsStoreVerifyCodeScrm(fsStoreVerifyCodeScrm));
+    }
+
+    /**
+     * 修改核销码
+     */
+    @PreAuthorize("@ss.hasPermi('shop:scrm:edit')")
+    @Log(title = "核销码", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm)
+    {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        fsStoreVerifyCodeScrm.setUpdateBy(loginUser.getUserId().toString());
+        return toAjax(fsStoreVerifyCodeScrmService.updateFsStoreVerifyCodeScrm(fsStoreVerifyCodeScrm));
+    }
+
+    /**
+     * 删除核销码
+     */
+    @PreAuthorize("@ss.hasPermi('shop:scrm:remove')")
+    @Log(title = "核销码", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+        return toAjax(fsStoreVerifyCodeScrmService.deleteFsStoreVerifyCodeScrmByIds(ids,loginUser.getUserId()));
+    }
+
+    @GetMapping("/downloadTemplate")
+    public AjaxResult downloadTemplate() {
+        ExcelUtil<FsStoreVerifyCodeDTO> util = new ExcelUtil<>(FsStoreVerifyCodeDTO.class);
+        return util.importTemplateExcel("溯源码那导入模板");
+    }
+
+    /**
+     * 溯源码导入
+     * @param file 导入文件
+     * @return R
+     * **/
+    @Log(title = "发货同步导入", businessType = BusinessType.IMPORT)
+    @PostMapping("/importExpress")
+    public R importExpress(@RequestParam("file") MultipartFile file) {
+        // 1. 检查文件是否为空
+        if (file.isEmpty()) {
+            return R.error("上传的文件不能为空");
+        }
+        // 2. 检查文件大小
+        if (file.getSize() > MAX_FILE_SIZE) {
+            return R.error("文件大小不能超过5MB");
+        }
+        // 3. 检查文件扩展名
+        String fileName = file.getOriginalFilename();
+        if (fileName == null || !isValidExcelFile(fileName)) {
+            return R.error("请上传Excel文件(.xlsx或.xls格式)");
+        }
+
+        ExcelUtil<FsStoreVerifyCodeDTO> util=new ExcelUtil<>(FsStoreVerifyCodeDTO.class);
+        try {
+            List<FsStoreVerifyCodeDTO> dtoList = util.importExcel(file.getInputStream());
+            if(!dtoList.isEmpty()){
+                if(dtoList.size() > 200){
+                    R.error("操作失败,导入数据不能大于200条!");
+                }
+                LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+                return fsStoreVerifyCodeScrmService.importExpress(dtoList,String.valueOf(loginUser.getUserId()));
+            }else {
+                R.error("操作失败,导入数据不能小于1条!");
+            }
+        }catch (Exception e){
+            e.getStackTrace();
+        }
+        return R.ok();
+    }
+
+
+    // 检查文件是否为有效的Excel文件
+    private boolean isValidExcelFile(String fileName) {
+        for (String ext : ALLOWED_EXCEL_EXTENSIONS) {
+            if (fileName.toLowerCase().endsWith(ext)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

+ 17 - 0
fs-service/src/main/java/com/fs/course/dto/FsStoreVerifyCodeDTO.java

@@ -0,0 +1,17 @@
+package com.fs.course.dto;
+
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+
+@Data
+public class FsStoreVerifyCodeDTO {
+
+    /**
+     * 溯源码
+     * **/
+    @Excel(name = "溯源码(必填)",width = 20,sort = 1)
+    private String verifyCode;
+
+    @Excel(name = "商品ID(必填)",width = 20,sort = 1)
+    private Long productId;
+}

+ 47 - 0
fs-service/src/main/java/com/fs/hisStore/domain/FsStoreVerifyCodeScrm.java

@@ -0,0 +1,47 @@
+package com.fs.hisStore.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fs.common.annotation.Excel;
+import lombok.Data;
+import com.fs.common.core.domain.BaseEntity;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 核销码对象 fs_store_verify_code_scrm
+ *
+ * @author fs
+ * @date 2025-11-27
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class FsStoreVerifyCodeScrm extends BaseEntity{
+
+    /** 主键ID */
+    private Long id;
+
+    /** 用户自定义核销码(数字/文字) */
+    @Excel(name = "用户自定义核销码", readConverterExp = "数=字/文字")
+    private String verifyCode;
+
+    /** 关联商品ID */
+    @Excel(name = "关联商品ID")
+    private Long productId;
+
+    /** 出库状态(0未出库、1已出库) */
+    @Excel(name = "出库状态", readConverterExp = "0=未出库、1已出库")
+    private Long outboundStatus;
+
+    /** 核销状态(0未核销、1已核销) */
+    @Excel(name = "核销状态", readConverterExp = "0=未核销、1已核销")
+    private Long verifyStatus;
+
+    /** 数据状态(0停用、1正常) */
+    @Excel(name = "数据状态", readConverterExp = "0=停用、1正常")
+    private Long status;
+
+    /** 是否删除(0未删除、1已删除) */
+    @Excel(name = "是否删除", readConverterExp = "0=未删除、1已删除")
+    private Long isDel;
+
+
+}

+ 70 - 0
fs-service/src/main/java/com/fs/hisStore/mapper/FsStoreVerifyCodeScrmMapper.java

@@ -0,0 +1,70 @@
+package com.fs.hisStore.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fs.hisStore.domain.FsStoreVerifyCodeScrm;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 核销码Mapper接口
+ * 
+ * @author fs
+ * @date 2025-11-27
+ */
+public interface FsStoreVerifyCodeScrmMapper extends BaseMapper<FsStoreVerifyCodeScrm> {
+    /**
+     * 查询核销码
+     * 
+     * @param id 核销码主键
+     * @return 核销码
+     */
+    FsStoreVerifyCodeScrm selectFsStoreVerifyCodeScrmById(String id);
+
+    /**
+     * 查询核销码列表
+     * 
+     * @param fsStoreVerifyCodeScrm 核销码
+     * @return 核销码集合
+     */
+    List<FsStoreVerifyCodeScrm> selectFsStoreVerifyCodeScrmList(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm);
+
+    /**
+     * 新增核销码
+     * 
+     * @param fsStoreVerifyCodeScrm 核销码
+     * @return 结果
+     */
+    int insertFsStoreVerifyCodeScrm(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm);
+
+    /**
+     * 修改核销码
+     * 
+     * @param fsStoreVerifyCodeScrm 核销码
+     * @return 结果
+     */
+    int updateFsStoreVerifyCodeScrm(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm);
+
+    /**
+     * 删除核销码
+     * 
+     * @param id 核销码主键
+     * @return 结果
+     */
+    int deleteFsStoreVerifyCodeScrmById(String id);
+
+    /**
+     * 批量删除核销码
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int deleteFsStoreVerifyCodeScrmByIds(String[] ids);
+
+    /**
+     * 批量插入核销码
+     * @param list 数据集合
+     * **/
+    void batchInsertVerifyCode(@Param("list") List<FsStoreVerifyCodeScrm> list);
+}

+ 71 - 0
fs-service/src/main/java/com/fs/hisStore/service/IFsStoreVerifyCodeScrmService.java

@@ -0,0 +1,71 @@
+package com.fs.hisStore.service;
+
+import java.util.List;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fs.common.core.domain.R;
+import com.fs.course.dto.FsStoreVerifyCodeDTO;
+import com.fs.hisStore.domain.FsStoreVerifyCodeScrm;
+
+/**
+ * 核销码Service接口
+ * 
+ * @author fs
+ * @date 2025-11-27
+ */
+public interface IFsStoreVerifyCodeScrmService extends IService<FsStoreVerifyCodeScrm>{
+    /**
+     * 查询核销码
+     * 
+     * @param id 核销码主键
+     * @return 核销码
+     */
+    FsStoreVerifyCodeScrm selectFsStoreVerifyCodeScrmById(String id);
+
+    /**
+     * 查询核销码列表
+     * 
+     * @param fsStoreVerifyCodeScrm 核销码
+     * @return 核销码集合
+     */
+    List<FsStoreVerifyCodeScrm> selectFsStoreVerifyCodeScrmList(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm);
+
+    /**
+     * 新增核销码
+     * 
+     * @param fsStoreVerifyCodeScrm 核销码
+     * @return 结果
+     */
+    int insertFsStoreVerifyCodeScrm(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm);
+
+    /**
+     * 修改核销码
+     * 
+     * @param fsStoreVerifyCodeScrm 核销码
+     * @return 结果
+     */
+    int updateFsStoreVerifyCodeScrm(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm);
+
+    /**
+     * 批量删除核销码
+     * 
+     * @param ids 需要删除的核销码主键集合
+     * @return 结果
+     */
+    int deleteFsStoreVerifyCodeScrmByIds(Long[] ids,Long userId);
+
+    /**
+     * 删除核销码信息
+     * 
+     * @param id 核销码主键
+     * @return 结果
+     */
+    int deleteFsStoreVerifyCodeScrmById(String id);
+
+    /**
+     * 批量导入
+     * @param verifyCodeDTOS
+     * @param userId 用户ID
+     * @return R
+     * **/
+    R importExpress(List<FsStoreVerifyCodeDTO> verifyCodeDTOS,String userId);
+}

+ 272 - 0
fs-service/src/main/java/com/fs/hisStore/service/impl/FsStoreVerifyCodeScrmServiceImpl.java

@@ -0,0 +1,272 @@
+package com.fs.hisStore.service.impl;
+
+import cn.hutool.core.lang.Assert;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fs.common.core.domain.BaseEntity;
+import com.fs.common.core.domain.R;
+import com.fs.common.exception.ServiceException;
+import com.fs.common.utils.DateUtils;
+import com.fs.course.dto.FsStoreVerifyCodeDTO;
+import com.fs.hisStore.domain.FsStoreProductScrm;
+import com.fs.hisStore.domain.FsStoreVerifyCodeScrm;
+import com.fs.hisStore.mapper.FsStoreProductScrmMapper;
+import com.fs.hisStore.mapper.FsStoreVerifyCodeScrmMapper;
+import com.fs.hisStore.service.IFsStoreVerifyCodeScrmService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+/**
+ * 核销码Service业务层处理
+ *
+ * @author fs
+ * @date 2025-11-27
+ */
+@Slf4j
+@Service
+public class FsStoreVerifyCodeScrmServiceImpl extends ServiceImpl<FsStoreVerifyCodeScrmMapper, FsStoreVerifyCodeScrm> implements IFsStoreVerifyCodeScrmService {
+    private static final Long NOT_DELETED = 0L;
+    private static final Long DELETED = 1L;
+    private static final Long STATUS_ENABLE = 1L;
+
+    private static final int BATCH_SIZE = 500;
+
+    @Autowired
+    private FsStoreProductScrmMapper fsStoreProductScrmMapper;
+
+    /**
+     * 查询核销码
+     *
+     * @param id 核销码主键
+     * @return 核销码
+     */
+    @Override
+    public FsStoreVerifyCodeScrm selectFsStoreVerifyCodeScrmById(String id) {
+        return baseMapper.selectFsStoreVerifyCodeScrmById(id);
+    }
+
+    /**
+     * 查询核销码列表
+     *
+     * @param fsStoreVerifyCodeScrm 核销码
+     * @return 核销码
+     */
+    @Override
+    public List<FsStoreVerifyCodeScrm> selectFsStoreVerifyCodeScrmList(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm) {
+        fsStoreVerifyCodeScrm.setIsDel(0L);
+        return baseMapper.selectFsStoreVerifyCodeScrmList(fsStoreVerifyCodeScrm);
+    }
+
+    /**
+     * 新增核销码
+     *
+     * @param fsStoreVerifyCodeScrm 核销码
+     * @return 结果
+     */
+    @Override
+    public int insertFsStoreVerifyCodeScrm(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm) {
+        //验证核销码是否存在
+        if (baseMapper.selectCount(new LambdaQueryWrapper<FsStoreVerifyCodeScrm>().eq(FsStoreVerifyCodeScrm::getVerifyCode, fsStoreVerifyCodeScrm.getVerifyCode())) > 0) {
+            throw new ServiceException("操作失败,核销码:" + fsStoreVerifyCodeScrm.getVerifyCode() + "已存在");
+        }
+        fsStoreVerifyCodeScrm.setCreateTime(DateUtils.getNowDate());
+        return baseMapper.insert(fsStoreVerifyCodeScrm);
+    }
+
+    /**
+     * 修改核销码
+     *
+     * @param fsStoreVerifyCodeScrm 核销码
+     * @return 结果
+     */
+    @Override
+    public int updateFsStoreVerifyCodeScrm(FsStoreVerifyCodeScrm fsStoreVerifyCodeScrm) {
+        if (baseMapper.selectCount(new LambdaQueryWrapper<FsStoreVerifyCodeScrm>().eq(FsStoreVerifyCodeScrm::getVerifyCode, fsStoreVerifyCodeScrm.getVerifyCode()).eq(FsStoreVerifyCodeScrm::getIsDel, 0L)) > 0 && !fsStoreVerifyCodeScrm.getId().equals(fsStoreVerifyCodeScrm.getId())) {
+            throw new ServiceException("操作失败,核销码:" + fsStoreVerifyCodeScrm.getVerifyCode() + "已存在");
+        }
+        fsStoreVerifyCodeScrm.setUpdateTime(DateUtils.getNowDate());
+        return baseMapper.updateById(fsStoreVerifyCodeScrm);
+    }
+
+    /**
+     * 批量删除核销码
+     *
+     * @param ids 需要删除的核销码主键
+     * @return 结果
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class) // 声明事务,确保批量操作原子性
+    public int deleteFsStoreVerifyCodeScrmByIds(Long[] ids, Long userId) {
+        Assert.notNull(ids, "核销码ID数组不能为空!");
+        if (ids.length == 0) {
+            log.warn("核销码ID数组为空,无需执行删除操作");
+            return 0;
+        }
+
+        LambdaQueryWrapper<FsStoreVerifyCodeScrm> queryWrapper = new LambdaQueryWrapper<FsStoreVerifyCodeScrm>()
+                .in(FsStoreVerifyCodeScrm::getId, ids)
+                .eq(FsStoreVerifyCodeScrm::getIsDel, NOT_DELETED);
+        List<FsStoreVerifyCodeScrm> list = baseMapper.selectList(queryWrapper);
+
+
+        if (list.size() != ids.length) {
+            log.error("核销码删除失败,数据不一致!入参ID数量:{},有效数据数量:{}", ids.length, list.size());
+            throw new ServiceException("操作失败,数据不一致!");
+        }
+
+        boolean hasInvalidData = list.stream()
+                .anyMatch(scrm -> STATUS_ENABLE.equals(scrm.getOutboundStatus())
+                        || STATUS_ENABLE.equals(scrm.getVerifyStatus()));
+        if (hasInvalidData) {
+            log.error("核销码删除失败,存在已出库或已核销的核销码!ID列表:{}", Arrays.toString(ids));
+            throw new ServiceException("操作失败,存在出库或者核销的核销码!");
+        }
+
+        if (!list.isEmpty()) {
+            LambdaUpdateWrapper<FsStoreVerifyCodeScrm> updateWrapper = new LambdaUpdateWrapper<FsStoreVerifyCodeScrm>()
+                    .in(FsStoreVerifyCodeScrm::getId, ids)
+                    .set(FsStoreVerifyCodeScrm::getIsDel, DELETED)
+                    .set(BaseEntity::getUpdateBy, userId)
+                    .set(BaseEntity::getUpdateTime, new Date());
+            int updateCount = baseMapper.update(null, updateWrapper);
+            log.info("核销码批量删除成功,更新数量:{},ID列表:{}", updateCount, Arrays.toString(ids));
+            return updateCount;
+        }
+
+        return 0;
+    }
+
+    /**
+     * 删除核销码信息
+     *
+     * @param id 核销码主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsStoreVerifyCodeScrmById(String id) {
+        return baseMapper.deleteFsStoreVerifyCodeScrmById(id);
+    }
+
+
+    /**
+     * 核销码导入实现类
+     *
+     * @param verifyCodeDTOS 数据
+     * @param userId 用户id
+     * @return R
+     */
+    @Override
+    public R importExpress(List<FsStoreVerifyCodeDTO> verifyCodeDTOS,String userId) {
+        if (CollectionUtils.isEmpty(verifyCodeDTOS)) {
+            return R.ok("导入成功!无待导入数据");
+        }
+
+        List<String> verifyCodes = verifyCodeDTOS.stream()
+                .map(FsStoreVerifyCodeDTO::getVerifyCode)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+
+        StringBuilder errorMsg = new StringBuilder();
+        long emptyCodeCount = verifyCodeDTOS.stream()
+                .filter(dto -> dto.getVerifyCode() == null || dto.getVerifyCode().trim().isEmpty())
+                .count();
+
+        Long[] productIds = verifyCodeDTOS.stream()
+                .map(FsStoreVerifyCodeDTO::getProductId)
+                .filter(Objects::nonNull)
+                .toArray(Long[]::new);
+
+        if (emptyCodeCount > 0) {
+            errorMsg.append("发现").append(emptyCodeCount).append("条核销码为空的数据\n");
+        }
+
+        Map<String, Long> existVerifyCodeMap = new HashMap<>();
+        if (!CollectionUtils.isEmpty(verifyCodes)) {
+            List<FsStoreVerifyCodeScrm> existList = baseMapper.selectList(
+                    new LambdaQueryWrapper<FsStoreVerifyCodeScrm>()
+                            .in(FsStoreVerifyCodeScrm::getVerifyCode, verifyCodes)
+                            .eq(FsStoreVerifyCodeScrm::getIsDel, 0)
+            );
+            if (!CollectionUtils.isEmpty(existList)) {
+                existVerifyCodeMap = existList.stream()
+                        .collect(Collectors.toMap(
+                                FsStoreVerifyCodeScrm::getVerifyCode,
+                                FsStoreVerifyCodeScrm::getId,
+                                (k1, k2) -> k1
+                        ));
+            }
+        }
+
+        //获取商品
+        Map<Long, Long> existProductrMap = new HashMap<>();
+        if (!CollectionUtils.isEmpty(Arrays.asList(productIds))) {
+            List<FsStoreProductScrm> productScrmList = fsStoreProductScrmMapper.selectProductByIds(productIds);
+
+            if (!CollectionUtils.isEmpty(productScrmList)) {
+                existProductrMap = productScrmList.stream()
+                        .collect(Collectors.toMap(FsStoreProductScrm::getProductId, FsStoreProductScrm::getProductId));
+            }
+        }
+
+        List<FsStoreVerifyCodeScrm> insertList = new ArrayList<>();
+        for (FsStoreVerifyCodeDTO dto : verifyCodeDTOS) {
+            String verifyCode = dto.getVerifyCode();
+
+            if (verifyCode == null || verifyCode.trim().isEmpty()) {
+                continue;
+            }
+
+            // 检查是否重复
+            if (existVerifyCodeMap.containsKey(verifyCode)) {
+                errorMsg.append("核销码:").append(verifyCode)
+                        .append("(商品ID:").append(dto.getProductId()).append(")已存在,重复新增\n");
+                continue;
+            } else if (!existProductrMap.containsKey(dto.getProductId())) {
+                errorMsg.append("核销码:").append(verifyCode)
+                        .append("绑定(商品ID:不存在!");
+                continue;
+            }
+
+            FsStoreVerifyCodeScrm entity = new FsStoreVerifyCodeScrm();
+            entity.setVerifyCode(verifyCode);
+            entity.setProductId(dto.getProductId());
+            entity.setOutboundStatus(0L);
+            entity.setVerifyStatus(0L);
+            entity.setStatus(1L);
+            entity.setIsDel(0L);
+            Date now = new Date();
+            entity.setCreateTime(now);
+            // 创建人
+            entity.setCreateBy(userId != null ? userId : "0");
+            insertList.add(entity);
+            existVerifyCodeMap.put(verifyCode, 0L);
+        }
+
+        //批量插入
+        if (!CollectionUtils.isEmpty(insertList)) {
+            try {
+                for (int i = 0; i < insertList.size(); i += BATCH_SIZE) {
+                    int end = Math.min(i + BATCH_SIZE, insertList.size());
+                    List<FsStoreVerifyCodeScrm> batchList = insertList.subList(i, end);
+                    baseMapper.batchInsertVerifyCode(batchList);
+                }
+            } catch (Exception e) {
+                log.error("核销码批量插入失败", e);
+                return R.error("导入失败:" + e.getMessage());
+            }
+        }
+
+        String resultMsg = errorMsg.length() > 0
+                ? "部分数据导入成功,错误信息:\n" + errorMsg.toString()
+                : "导入成功!共导入" + insertList.size() + "条核销码";
+        return R.ok(resultMsg);
+    }
+}

+ 1 - 1
fs-service/src/main/resources/mapper/hisStore/FsStoreProductScrmMapper.xml

@@ -605,7 +605,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <if test='config.isAudit == "1"'>
             inner join fs_store_scrm fs on fs.store_id = p.store_id and fs.is_audit = 1
         </if>
-        where p.is_del=0 and p.is_show=1
+        where p.is_del=0 and p.is_show=1 and p.is_drug = 1
         <if test='config.isAudit == "1"'>
             and p.is_audit = '1'
         </if>

+ 118 - 0
fs-service/src/main/resources/mapper/hisStore/FsStoreVerifyCodeScrmMapper.xml

@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.hisStore.mapper.FsStoreVerifyCodeScrmMapper">
+    
+    <resultMap type="FsStoreVerifyCodeScrm" id="FsStoreVerifyCodeScrmResult">
+        <result property="id"    column="id"    />
+        <result property="verifyCode"    column="verify_code"    />
+        <result property="productId"    column="product_id"    />
+        <result property="outboundStatus"    column="outbound_status"    />
+        <result property="verifyStatus"    column="verify_status"    />
+        <result property="status"    column="status"    />
+        <result property="isDel"    column="is_del"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectFsStoreVerifyCodeScrmVo">
+        select id, verify_code, product_id, outbound_status, verify_status, status, is_del, create_time, update_time from fs_store_verify_code_scrm
+    </sql>
+
+    <select id="selectFsStoreVerifyCodeScrmList" parameterType="FsStoreVerifyCodeScrm" resultMap="FsStoreVerifyCodeScrmResult">
+        <include refid="selectFsStoreVerifyCodeScrmVo"/>
+        <where>  
+            <if test="verifyCode != null  and verifyCode != ''"> and verify_code = #{verifyCode}</if>
+            <if test="productId != null  and productId != ''"> and product_id = #{productId}</if>
+            <if test="outboundStatus != null "> and outbound_status = #{outboundStatus}</if>
+            <if test="verifyStatus != null "> and verify_status = #{verifyStatus}</if>
+            <if test="status != null "> and status = #{status}</if>
+            <if test="isDel != null "> and is_del = #{isDel}</if>
+        </where>
+    </select>
+    
+    <select id="selectFsStoreVerifyCodeScrmById" parameterType="String" resultMap="FsStoreVerifyCodeScrmResult">
+        <include refid="selectFsStoreVerifyCodeScrmVo"/>
+        where id = #{id}
+    </select>
+        
+    <insert id="insertFsStoreVerifyCodeScrm" parameterType="FsStoreVerifyCodeScrm" useGeneratedKeys="true" keyProperty="id">
+        insert into fs_store_verify_code_scrm
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="verifyCode != null and verifyCode != ''">verify_code,</if>
+            <if test="productId != null and productId != ''">product_id,</if>
+            <if test="outboundStatus != null">outbound_status,</if>
+            <if test="verifyStatus != null">verify_status,</if>
+            <if test="status != null">status,</if>
+            <if test="isDel != null">is_del,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="verifyCode != null and verifyCode != ''">#{verifyCode},</if>
+            <if test="productId != null and productId != ''">#{productId},</if>
+            <if test="outboundStatus != null">#{outboundStatus},</if>
+            <if test="verifyStatus != null">#{verifyStatus},</if>
+            <if test="status != null">#{status},</if>
+            <if test="isDel != null">#{isDel},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateFsStoreVerifyCodeScrm" parameterType="FsStoreVerifyCodeScrm">
+        update fs_store_verify_code_scrm
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="verifyCode != null and verifyCode != ''">verify_code = #{verifyCode},</if>
+            <if test="productId != null and productId != ''">product_id = #{productId},</if>
+            <if test="outboundStatus != null">outbound_status = #{outboundStatus},</if>
+            <if test="verifyStatus != null">verify_status = #{verifyStatus},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="isDel != null">is_del = #{isDel},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteFsStoreVerifyCodeScrmById" parameterType="String">
+        delete from fs_store_verify_code_scrm where id = #{id}
+    </delete>
+
+    <delete id="deleteFsStoreVerifyCodeScrmByIds" parameterType="String">
+        delete from fs_store_verify_code_scrm where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+    <insert id="batchInsertVerifyCode">
+        INSERT INTO fs_store_verify_code_scrm (
+        verify_code,
+        product_id,
+        outbound_status,
+        verify_status,
+        status,
+        is_del,
+        create_time,
+        update_time,
+        create_by,
+        update_by
+        ) VALUES
+        <foreach collection="list" item="item" separator=",">
+            (
+            #{item.verifyCode},
+            #{item.productId},
+            #{item.outboundStatus},
+            #{item.verifyStatus},
+            #{item.status},
+            #{item.isDel},
+            #{item.createTime},
+            #{item.updateTime},
+            #{item.createBy},
+            #{item.updateBy}
+            )
+        </foreach>
+    </insert>
+</mapper>

+ 2 - 2
fs-user-app/src/main/java/com/fs/app/controller/store/IndexScrmController.java

@@ -63,13 +63,13 @@ public class IndexScrmController extends AppBaseController {
 		List<FsArticleCateListQueryVO> articleCateList=articleCateService.selectFsArticleCateListQuery();
 		List<FsAdvListQueryVO> advList=advService.selectFsAdvListQuery(1);
 		List<FsStoreProductListQueryVO> newProductList=productService.selectFsStoreProductNewQuery(10);
-		List<FsStoreProductListQueryVO> hotProductList=null;
+		List<FsStoreProductListQueryVO> hotProductList = null;
 		if(isDrug != null && isDrug.equals("0")){
 			hotProductList = new LinkedList<>();
 		}else {
 			newProductList=productService.selectFsStoreProductNewQuery(10);
+			hotProductList = productService.selectFsStoreProductHotQuery(10);
 		}
-		productService.selectFsStoreProductHotQuery(10);
 		IndexVO vo=IndexVO.builder().articleCateList(articleCateList).advList(advList).newProductList(newProductList).hotProductList(hotProductList).build();
 		return R.ok().put("data", vo);
 	}