src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -14,6 +14,9 @@
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.project.system.service.ISysDictDataService;
import com.ruoyi.quality.dto.QualityInspectDto;
import com.ruoyi.quality.service.IQualityInspectService;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.stock.dto.StockInRecordDto;
@@ -29,7 +32,8 @@
import com.ruoyi.stock.service.StockOutRecordService;
import com.ruoyi.stock.service.StockUninventoryService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
@@ -51,7 +55,6 @@
 * @since 2026-01-21 04:16:36
 */
@Service
@RequiredArgsConstructor
public class StockInventoryServiceImpl extends ServiceImpl<StockInventoryMapper, StockInventory> implements StockInventoryService {
    private final StockInventoryMapper stockInventoryMapper;
@@ -60,6 +63,27 @@
    private final StockUninventoryService stockUninventoryService;
    private final SalesLedgerProductMapper salesLedgerProductMapper;
    private final ProductModelMapper productModelMapper;
    private final ISysDictDataService sysDictDataService;
    private final IQualityInspectService qualityInspectService;
    public StockInventoryServiceImpl(
            StockInventoryMapper stockInventoryMapper,
            StockInRecordService stockInRecordService,
            StockOutRecordService stockOutRecordService,
            StockUninventoryService stockUninventoryService,
            SalesLedgerProductMapper salesLedgerProductMapper,
            ProductModelMapper productModelMapper,
            ISysDictDataService sysDictDataService,
            @Lazy IQualityInspectService qualityInspectService) {
        this.stockInventoryMapper = stockInventoryMapper;
        this.stockInRecordService = stockInRecordService;
        this.stockOutRecordService = stockOutRecordService;
        this.stockUninventoryService = stockUninventoryService;
        this.salesLedgerProductMapper = salesLedgerProductMapper;
        this.productModelMapper = productModelMapper;
        this.sysDictDataService = sysDictDataService;
        this.qualityInspectService = qualityInspectService;
    }
    @Override
    public IPage<StockInventoryDto> pagestockInventory(Page page, StockInventoryDto stockInventoryDto) {
@@ -80,6 +104,12 @@
            batchNo = generateAutoBatchNo(stockInventoryDto.getProductModelId());
        }
        stockInventoryDto.setBatchNo(batchNo);
        // 处理仓库字段:空字符串或null时取消绑定
        String warehouse = stockInventoryDto.getWarehouse();
        if (StringUtils.isEmpty(warehouse)) {
            stockInventoryDto.setWarehouse(null);
        }
        LambdaQueryWrapper<StockInventory> eq = new QueryWrapper<StockInventory>().lambda()
                .eq(StockInventory::getProductModelId, stockInventoryDto.getProductModelId());
@@ -106,11 +136,57 @@
            newStockInventory.setBatchNo(stockInventoryDto.getBatchNo());
            newStockInventory.setLockedQuantity(stockInventoryDto.getLockedQuantity());
            newStockInventory.setWarnNum(stockInventoryDto.getWarnNum());
            newStockInventory.setWarehouse(stockInventoryDto.getWarehouse());
            stockInventoryMapper.insert(newStockInventory);
        } else {
            stockInventoryMapper.updateAddStockInventory(stockInventoryDto);
        }
        return true;
    }
    /**
     * 创建质检单
     * 根据 inspectType 决定质检类型:
     * - 0: 原材料检验
     * - 1: 过程检验
     * 如果未指定 inspectType,则根据产品信息自动判断
     */
    private void createQualityInspect(StockInventoryDto stockInventoryDto) {
        // 查询产品信息
        ProductModel productModel = productModelMapper.selectById(stockInventoryDto.getProductModelId());
        if (productModel == null) {
            throw new ServiceException("产品规格不存在");
        }
        // 确定 inspectType
        Integer inspectType = stockInventoryDto.getInspectType();
        if (inspectType == null) {
            // 默认使用原材料检验
            inspectType = 0;
        }
        // 构建质检单
        QualityInspectDto qualityInspectDto = new QualityInspectDto();
        qualityInspectDto.setInspectType(inspectType);
        qualityInspectDto.setProductModelId(stockInventoryDto.getProductModelId());
        qualityInspectDto.setProductId(productModel.getProductId());
        qualityInspectDto.setProductName(stockInventoryDto.getProductName());
        qualityInspectDto.setQuantity(stockInventoryDto.getQualitity());
        qualityInspectDto.setInspectState(0); // 未提交
//        qualityInspectDto.setRemark(stockInventoryDto.getRemark());
        // 设置产品信息
        if (productModel.getProductName() != null) {
            qualityInspectDto.setProductName(productModel.getProductName());
        }
        qualityInspectDto.setModel(productModel.getModel());
        qualityInspectDto.setUnit(productModel.getUnit());
        // 初始化空的检验参数列表
        qualityInspectDto.setQualityInspectParams(new ArrayList<>());
        // 保存质检单
        qualityInspectService.add(qualityInspectDto);
    }
    //出库调用
@@ -132,6 +208,7 @@
        stockOutRecordDto.setStockOutNum(stockInventoryDto.getQualitity());
        stockOutRecordDto.setBatchNo(stockInventoryDto.getBatchNo());
        stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId());
        stockOutRecordDto.setOutboundBatches(stockInventoryDto.getOutboundBatches());
        stockOutRecordDto.setType("0");
        stockOutRecordService.add(stockOutRecordDto);
@@ -161,6 +238,14 @@
        }
        stockInventoryDto.setBatchNo(batchNo);
        // 判断是否需要质检
        if (Boolean.TRUE.equals(stockInventoryDto.getNeedInspect())) {
            // 创建质检单
            createQualityInspect(stockInventoryDto);
            return true;
        }
        // 不需要质检,直接创建入库记录
        StockInRecordDto stockInRecordDto = new StockInRecordDto();
        stockInRecordDto.setRecordId(stockInventoryDto.getRecordId());
        stockInRecordDto.setRecordType(stockInventoryDto.getRecordType());
@@ -171,6 +256,7 @@
        stockInRecordDto.setRemark(stockInventoryDto.getRemark());
        stockInRecordDto.setWarnNum(stockInventoryDto.getWarnNum());
        stockInRecordDto.setCreateTime(stockInventoryDto.getCreateTime());
        stockInRecordDto.setWarehouse(stockInventoryDto.getWarehouse());
        stockInRecordService.add(stockInRecordDto);
        return true;
    }
@@ -289,6 +375,7 @@
        stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId());
        stockOutRecordDto.setType("0");
        stockOutRecordDto.setRemark(stockInventoryDto.getRemark());
        stockOutRecordDto.setOutboundBatches(stockInventoryDto.getOutboundBatches());
        stockOutRecordService.add(stockOutRecordDto);
        return true;
    }
@@ -315,6 +402,14 @@
            int successCount = 0;
            for (StockInventoryExportData dto : list) {
                // 验证仓库是否存在于字典中
                if (StringUtils.isNotEmpty(dto.getWarehouse())) {
                    String warehouseLabel = sysDictDataService.selectDictLabel("warehouse", dto.getWarehouse());
                    if (StringUtils.isEmpty(warehouseLabel)) {
                        throw new RuntimeException("仓库值 " + dto.getWarehouse() + " 不存在于字典中");
                    }
                }
                // 构建查找键
                String key = dto.getProductName() + "|" + dto.getModel();
                SalesLedgerProduct matchedProduct = productMap.get(key);
@@ -328,6 +423,7 @@
                        stockInventoryDto.setQualitity(dto.getQualifiedQuantity());
                        stockInventoryDto.setRemark(dto.getRemark());
                        stockInventoryDto.setWarnNum(dto.getWarnNum());
                        stockInventoryDto.setWarehouse(dto.getWarehouse());
                        // 验证合格冻结数量
                        if (ObjectUtils.isNotEmpty(dto.getQualifiedLockedQuantity())) {
@@ -351,6 +447,7 @@
                        stockUninventoryDto.setRecordType(StockInQualifiedRecordTypeEnum.CUSTOMIZATION_UNSTOCK_IN.getCode());
                        stockUninventoryDto.setQualitity(dto.getUnQualifiedQuantity());
                        stockUninventoryDto.setRemark(dto.getRemark());
                        stockUninventoryDto.setWarehouse(dto.getWarehouse());
                        // 验证不合格冻结数量
                        if (ObjectUtils.isNotEmpty(dto.getUnQualifiedLockedQuantity())) {