liyong
4 天以前 be5783c8a7e13bbc76d33c95643d75779cce21db
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java
@@ -2,19 +2,21 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchGenerateReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchPageReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemBatchConfigDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.batch.MesWmBatchMapper;
import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum;
import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemBatchConfigService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService;
import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemBatchConfigApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemBatchConfigRespDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -50,15 +52,19 @@
    @Resource
    private MesMdmItemService mdmItemService;
    @Resource
    private MesMdItemBatchConfigService itemBatchConfigService;
    private MdmItemBatchConfigApi itemBatchConfigApi;
    @Resource
    private MesMdAutoCodeRecordService autoCodeRecordService;
    @Resource
    private MesWmBarcodeService barcodeService;
    @Resource
    private CrmCustomerApi customerApi;
    @Override
    public PageResult<MesWmBatchDO> getBatchPage(MesWmBatchPageReqVO pageReqVO) {
        return batchMapper.selectPage(pageReqVO);
        // 获取用户有权限的客户 ID 列表
        List<Long> permittedClientIds = customerApi.getPermittedCustomerIds();
        return batchMapper.selectPage(pageReqVO, permittedClientIds);
    }
    @Override
@@ -80,119 +86,160 @@
            // 未启用批次管理,返回 null
            return null;
        }
        // 1.2 查询物料批次配置
        MesMdItemBatchConfigDO config = itemBatchConfigService.validateItemBatchConfigExists(reqVO.getItemId());
        // 调试日志:打印接收到的日期
        log.info("[getOrGenerateBatchCode] 收到请求, itemId={}, batchCode={}, produceDate={}",
                reqVO.getItemId(), reqVO.getBatchCode(), reqVO.getProduceDate());
        // 1.2 查询物料批次配置(从 MDM 获取,不存在则使用默认配置)
        MdmItemBatchConfigRespDTO config = itemBatchConfigApi.getItemBatchConfig(reqVO.getItemId());
        // 2. 根据配置校验必填参数并清空不需要的参数
        MesWmBatchDO batch = MesWmBatchDO.builder().itemId(reqVO.getItemId()).build();
        // 生产日期
        if (Boolean.TRUE.equals(config.getProduceDateFlag())) {
            if (ObjUtil.isNull(reqVO.getProduceDate())) {
                throw exception(WM_BATCH_PRODUCE_DATE_REQUIRED);
        if (config != null) {
            // 生产日期
            if (Boolean.TRUE.equals(config.getProduceDateFlag())) {
                if (ObjUtil.isNull(reqVO.getProduceDate())) {
                    throw exception(WM_BATCH_PRODUCE_DATE_REQUIRED);
                }
                batch.setProduceDate(reqVO.getProduceDate());
            }
            batch.setProduceDate(reqVO.getProduceDate());
            // 入库日期
            if (Boolean.TRUE.equals(config.getReceiptDateFlag())) {
                if (ObjUtil.isNull(reqVO.getReceiptDate())) {
                    throw exception(WM_BATCH_RECEIPT_DATE_REQUIRED);
                }
                batch.setReceiptDate(reqVO.getReceiptDate());
            }
            // 有效期
            if (Boolean.TRUE.equals(config.getExpireDateFlag())) {
                if (ObjUtil.isNull(reqVO.getExpireDate())) {
                    throw exception(WM_BATCH_EXPIRE_DATE_REQUIRED);
                }
                batch.setExpireDate(reqVO.getExpireDate());
            }
            // 供应商
            if (Boolean.TRUE.equals(config.getVendorFlag())) {
                if (ObjUtil.isNull(reqVO.getVendorId())) {
                    throw exception(WM_BATCH_VENDOR_REQUIRED);
                }
                batch.setVendorId(reqVO.getVendorId());
            }
            // 客户
            if (Boolean.TRUE.equals(config.getClientFlag())) {
                if (ObjUtil.isNull(reqVO.getClientId())) {
                    throw exception(WM_BATCH_CLIENT_REQUIRED);
                }
                batch.setClientId(reqVO.getClientId());
            }
            // 采购订单编号
            if (Boolean.TRUE.equals(config.getPurchaseOrderCodeFlag())) {
                if (ObjUtil.isNull(reqVO.getPurchaseOrderCode())) {
                    throw exception(WM_BATCH_PURCHASE_ORDER_CODE_REQUIRED);
                }
                batch.setPurchaseOrderCode(reqVO.getPurchaseOrderCode());
            }
            // 销售订单编号
            if (Boolean.TRUE.equals(config.getSalesOrderCodeFlag())) {
                if (ObjUtil.isNull(reqVO.getSalesOrderCode())) {
                    throw exception(WM_BATCH_CUSTOMER_ORDER_CODE_REQUIRED);
                }
                batch.setSalesOrderCode(reqVO.getSalesOrderCode());
            }
            // 生产工单
            if (Boolean.TRUE.equals(config.getWorkOrderFlag())) {
                if (ObjUtil.isNull(reqVO.getWorkOrderId())) {
                    throw exception(WM_BATCH_WORK_ORDER_REQUIRED);
                }
                batch.setWorkOrderId(reqVO.getWorkOrderId());
            }
            // 生产任务
            if (Boolean.TRUE.equals(config.getTaskFlag())) {
                if (ObjUtil.isNull(reqVO.getTaskId())) {
                    throw exception(WM_BATCH_TASK_REQUIRED);
                }
                batch.setTaskId(reqVO.getTaskId());
            }
            // 工作站
            if (Boolean.TRUE.equals(config.getWorkstationFlag())) {
                if (ObjUtil.isNull(reqVO.getWorkstationId())) {
                    throw exception(WM_BATCH_WORKSTATION_REQUIRED);
                }
                batch.setWorkstationId(reqVO.getWorkstationId());
            }
            // 工具
            if (Boolean.TRUE.equals(config.getToolFlag())) {
                if (ObjUtil.isNull(reqVO.getToolId())) {
                    throw exception(WM_BATCH_TOOL_REQUIRED);
                }
                batch.setToolId(reqVO.getToolId());
            }
            // 模具
            if (Boolean.TRUE.equals(config.getMoldFlag())) {
                if (ObjUtil.isNull(reqVO.getMoldId())) {
                    throw exception(WM_BATCH_MOLD_REQUIRED);
                }
                batch.setMoldId(reqVO.getMoldId());
            }
            // 生产批号
            if (Boolean.TRUE.equals(config.getLotNumberFlag())) {
                if (ObjUtil.isNull(reqVO.getLotNumber())) {
                    throw exception(WM_BATCH_LOT_NUMBER_REQUIRED);
                }
                batch.setLotNumber(reqVO.getLotNumber());
            }
            // 质量状态
            if (Boolean.TRUE.equals(config.getQualityStatusFlag())) {
                if (ObjUtil.isNull(reqVO.getQualityStatus())) {
                    throw exception(WM_BATCH_QUALITY_STATUS_REQUIRED);
                }
                batch.setQualityStatus(reqVO.getQualityStatus());
            }
        }
        // 入库日期
        if (Boolean.TRUE.equals(config.getReceiptDateFlag())) {
            if (ObjUtil.isNull(reqVO.getReceiptDate())) {
                throw exception(WM_BATCH_RECEIPT_DATE_REQUIRED);
        // 无批次配置时,使用传入的参数(宽松模式,适用于自定义入库等场景)
        else {
            if (reqVO.getProduceDate() != null) {
                batch.setProduceDate(reqVO.getProduceDate());
            }
            batch.setReceiptDate(reqVO.getReceiptDate());
        }
        // 有效期
        if (Boolean.TRUE.equals(config.getExpireDateFlag())) {
            if (ObjUtil.isNull(reqVO.getExpireDate())) {
                throw exception(WM_BATCH_EXPIRE_DATE_REQUIRED);
            if (reqVO.getReceiptDate() != null) {
                batch.setReceiptDate(reqVO.getReceiptDate());
            }
            batch.setExpireDate(reqVO.getExpireDate());
        }
        // 供应商
        if (Boolean.TRUE.equals(config.getVendorFlag())) {
            if (ObjUtil.isNull(reqVO.getVendorId())) {
                throw exception(WM_BATCH_VENDOR_REQUIRED);
            if (reqVO.getExpireDate() != null) {
                batch.setExpireDate(reqVO.getExpireDate());
            }
            batch.setVendorId(reqVO.getVendorId());
        }
        // 客户
        if (Boolean.TRUE.equals(config.getClientFlag())) {
            if (ObjUtil.isNull(reqVO.getClientId())) {
                throw exception(WM_BATCH_CLIENT_REQUIRED);
            if (reqVO.getVendorId() != null) {
                batch.setVendorId(reqVO.getVendorId());
            }
            batch.setClientId(reqVO.getClientId());
        }
        // 采购订单编号
        if (Boolean.TRUE.equals(config.getPurchaseOrderCodeFlag())) {
            if (ObjUtil.isNull(reqVO.getPurchaseOrderCode())) {
                throw exception(WM_BATCH_PURCHASE_ORDER_CODE_REQUIRED);
            if (reqVO.getClientId() != null) {
                batch.setClientId(reqVO.getClientId());
            }
            batch.setPurchaseOrderCode(reqVO.getPurchaseOrderCode());
        }
        // 销售订单编号
        if (Boolean.TRUE.equals(config.getSalesOrderCodeFlag())) {
            if (ObjUtil.isNull(reqVO.getSalesOrderCode())) {
                throw exception(WM_BATCH_CUSTOMER_ORDER_CODE_REQUIRED);
            }
            batch.setSalesOrderCode(reqVO.getSalesOrderCode());
        }
        // 生产工单
        if (Boolean.TRUE.equals(config.getWorkOrderFlag())) {
            if (ObjUtil.isNull(reqVO.getWorkOrderId())) {
                throw exception(WM_BATCH_WORK_ORDER_REQUIRED);
            }
            batch.setWorkOrderId(reqVO.getWorkOrderId());
        }
        // 生产任务
        if (Boolean.TRUE.equals(config.getTaskFlag())) {
            if (ObjUtil.isNull(reqVO.getTaskId())) {
                throw exception(WM_BATCH_TASK_REQUIRED);
            }
            batch.setTaskId(reqVO.getTaskId());
        }
        // 工作站
        if (Boolean.TRUE.equals(config.getWorkstationFlag())) {
            if (ObjUtil.isNull(reqVO.getWorkstationId())) {
                throw exception(WM_BATCH_WORKSTATION_REQUIRED);
            }
            batch.setWorkstationId(reqVO.getWorkstationId());
        }
        // 工具
        if (Boolean.TRUE.equals(config.getToolFlag())) {
            if (ObjUtil.isNull(reqVO.getToolId())) {
                throw exception(WM_BATCH_TOOL_REQUIRED);
            }
            batch.setToolId(reqVO.getToolId());
        }
        // 模具
        if (Boolean.TRUE.equals(config.getMoldFlag())) {
            if (ObjUtil.isNull(reqVO.getMoldId())) {
                throw exception(WM_BATCH_MOLD_REQUIRED);
            }
            batch.setMoldId(reqVO.getMoldId());
        }
        // 生产批号
        if (Boolean.TRUE.equals(config.getLotNumberFlag())) {
            if (ObjUtil.isNull(reqVO.getLotNumber())) {
                throw exception(WM_BATCH_LOT_NUMBER_REQUIRED);
            }
            batch.setLotNumber(reqVO.getLotNumber());
        }
        // 质量状态
        if (Boolean.TRUE.equals(config.getQualityStatusFlag())) {
            if (ObjUtil.isNull(reqVO.getQualityStatus())) {
                throw exception(WM_BATCH_QUALITY_STATUS_REQUIRED);
            }
            batch.setQualityStatus(reqVO.getQualityStatus());
        }
        // 3.1 情况一:查询是否存在匹配的批次
        MesWmBatchDO existingBatch = batchMapper.selectFirst(batch);
        if (existingBatch != null) {
            return existingBatch;
        // 3.1 情况一:传入了 batchCode,查询是否存在该批次号
        if (StrUtil.isNotBlank(reqVO.getBatchCode())) {
            MesWmBatchDO existingBatch = batchMapper.selectByCode(reqVO.getBatchCode());
            if (existingBatch != null) {
                // 校验物料是否匹配
                if (!existingBatch.getItemId().equals(reqVO.getItemId())) {
                    throw exception(WM_BATCH_ITEM_MISMATCH);
                }
                // 更新批次属性(仅更新传入的非空值)
                updateBatchProperties(existingBatch, batch);
                return existingBatch;
            }
            // 不存在则使用传入的 batchCode 创建新批次
            batch.setCode(reqVO.getBatchCode());
        } else {
            // 3.2 情况二:查询是否存在匹配的批次(根据属性匹配)
            MesWmBatchDO existingBatch = batchMapper.selectFirst(batch);
            if (existingBatch != null) {
                return existingBatch;
            }
            // 3.3 情况三:自动生成新批次号
            String batchCode = autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.WM_BATCH_CODE.getCode());
            batch.setCode(batchCode);
        }
        // 3.2 情况二:生成新批次
        String batchCode = autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.WM_BATCH_CODE.getCode());
        batch.setCode(batchCode);
        batchMapper.insert(batch);
        // 4. 生成条码
@@ -200,6 +247,75 @@
        return batch;
    }
    /**
     * 更新已有批次的属性(仅更新传入的非空值)
     *
     * @param existingBatch 已有批次
     * @param newBatch 新批次属性
     */
    private void updateBatchProperties(MesWmBatchDO existingBatch, MesWmBatchDO newBatch) {
        boolean needUpdate = false;
        if (newBatch.getProduceDate() != null && !newBatch.getProduceDate().equals(existingBatch.getProduceDate())) {
            existingBatch.setProduceDate(newBatch.getProduceDate());
            needUpdate = true;
        }
        if (newBatch.getExpireDate() != null && !newBatch.getExpireDate().equals(existingBatch.getExpireDate())) {
            existingBatch.setExpireDate(newBatch.getExpireDate());
            needUpdate = true;
        }
        if (newBatch.getReceiptDate() != null && !newBatch.getReceiptDate().equals(existingBatch.getReceiptDate())) {
            existingBatch.setReceiptDate(newBatch.getReceiptDate());
            needUpdate = true;
        }
        if (newBatch.getVendorId() != null && !newBatch.getVendorId().equals(existingBatch.getVendorId())) {
            existingBatch.setVendorId(newBatch.getVendorId());
            needUpdate = true;
        }
        if (newBatch.getClientId() != null && !newBatch.getClientId().equals(existingBatch.getClientId())) {
            existingBatch.setClientId(newBatch.getClientId());
            needUpdate = true;
        }
        if (newBatch.getSalesOrderCode() != null && !newBatch.getSalesOrderCode().equals(existingBatch.getSalesOrderCode())) {
            existingBatch.setSalesOrderCode(newBatch.getSalesOrderCode());
            needUpdate = true;
        }
        if (newBatch.getPurchaseOrderCode() != null && !newBatch.getPurchaseOrderCode().equals(existingBatch.getPurchaseOrderCode())) {
            existingBatch.setPurchaseOrderCode(newBatch.getPurchaseOrderCode());
            needUpdate = true;
        }
        if (newBatch.getWorkOrderId() != null && !newBatch.getWorkOrderId().equals(existingBatch.getWorkOrderId())) {
            existingBatch.setWorkOrderId(newBatch.getWorkOrderId());
            needUpdate = true;
        }
        if (newBatch.getTaskId() != null && !newBatch.getTaskId().equals(existingBatch.getTaskId())) {
            existingBatch.setTaskId(newBatch.getTaskId());
            needUpdate = true;
        }
        if (newBatch.getWorkstationId() != null && !newBatch.getWorkstationId().equals(existingBatch.getWorkstationId())) {
            existingBatch.setWorkstationId(newBatch.getWorkstationId());
            needUpdate = true;
        }
        if (newBatch.getToolId() != null && !newBatch.getToolId().equals(existingBatch.getToolId())) {
            existingBatch.setToolId(newBatch.getToolId());
            needUpdate = true;
        }
        if (newBatch.getMoldId() != null && !newBatch.getMoldId().equals(existingBatch.getMoldId())) {
            existingBatch.setMoldId(newBatch.getMoldId());
            needUpdate = true;
        }
        if (newBatch.getLotNumber() != null && !newBatch.getLotNumber().equals(existingBatch.getLotNumber())) {
            existingBatch.setLotNumber(newBatch.getLotNumber());
            needUpdate = true;
        }
        if (newBatch.getQualityStatus() != null && !newBatch.getQualityStatus().equals(existingBatch.getQualityStatus())) {
            existingBatch.setQualityStatus(newBatch.getQualityStatus());
            needUpdate = true;
        }
        if (needUpdate) {
            batchMapper.updateById(existingBatch);
        }
    }
    @Override
    public List<MesWmBatchDO> getForwardBatchList(String code) {
        return getForwardBatchList(code, new HashSet<>(), 0);