2 天以前 3be684af887afe4c0e45f281cc53adfef6f12b78
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java
@@ -22,6 +22,8 @@
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService;
import cn.iocoder.yudao.module.mdm.api.item.MdmItemSyncApi;
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemSyncReqDTO;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -38,7 +40,7 @@
/**
 * MES 物料产品 Service 实现类
 *
 * 注意:当前保持使用 MES 本地表,待 MDM 数据迁移完成后再切换到 MDM API
 * 支持 MES 和 MDM 物料数据双向同步
 *
 * @author 芋道源码
 */
@@ -66,10 +68,24 @@
    @Resource
    private MesMdAutoCodeRecordService autoCodeRecordService;
    @Resource
    private MdmItemSyncApi mdmItemSyncApi;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createItem(MesMdItemSaveReqVO createReqVO) {
        // 校验数据
        validateItemSaveData(createReqVO);
        // 如果指定了 ID,检查该 ID 是否已存在(用于 MDM 同步时保持 ID 一致)
        if (createReqVO.getId() != null) {
            MesMdItemDO existItem = itemMapper.selectById(createReqVO.getId());
            if (existItem != null) {
                // ID 已存在,转为更新
                updateItem(createReqVO);
                return createReqVO.getId();
            }
        }
        // 插入
        MesMdItemDO item = BeanUtils.toBean(createReqVO, MesMdItemDO.class);
@@ -80,10 +96,17 @@
        // 自动生成条码
        barcodeService.autoGenerateBarcode(BarcodeBizTypeEnum.ITEM.getValue(),
                item.getId(), item.getCode(), item.getName());
        // 同步到 MDM(勾选 syncMdm 时)
        if (Boolean.TRUE.equals(createReqVO.getSyncMdm())) {
            syncItemToMdm(item, createReqVO);
        }
        return item.getId();
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateItem(MesMdItemSaveReqVO updateReqVO) {
        // 校验存在
        validateItemExists(updateReqVO.getId());
@@ -94,6 +117,12 @@
        MesMdItemDO updateObj = BeanUtils.toBean(updateReqVO, MesMdItemDO.class);
        clearStockIfNotSafe(updateObj); // 如果未启用安全库存,清零库存上下限
        itemMapper.updateById(updateObj);
        // 同步到 MDM(勾选 syncMdm 时)
        if (Boolean.TRUE.equals(updateReqVO.getSyncMdm())) {
            MesMdItemDO item = itemMapper.selectById(updateReqVO.getId());
            syncItemToMdm(item, updateReqVO);
        }
    }
    private void validateItemSaveData(MesMdItemSaveReqVO reqVO) {
@@ -369,4 +398,111 @@
        return respVO;
    }
    /**
     * 同步物料到 MDM
     *
     * @param item     MES 物料数据
     * @param saveReqVO 保存请求(包含批次配置)
     */
    private void syncItemToMdm(MesMdItemDO item, MesMdItemSaveReqVO saveReqVO) {
        // 1. 获取物料类型对应的 itemType
        Long itemType = null;
        if (item.getItemTypeId() != null) {
            MesMdItemTypeDO itemTypeDO = itemTypeService.getItemType(item.getItemTypeId());
            if (itemTypeDO != null) {
                // MES: ITEM=物料, PRODUCT=产品 -> MDM: 1=原料, 2=半成品, 3=成品, 4=辅料
//                itemType = convertMesItemTypeToMdm(itemTypeDO.getItemOrProduct(), itemTypeDO.getName());
                itemType = itemTypeDO.getId();
            }
        }
        // 2. 获取计量单位编码
        String unitCode = null;
        Long unitMeasureId = null;
        if (item.getUnitMeasureId() != null) {
            MesMdUnitMeasureDO unitMeasure = unitMeasureService.getUnitMeasure(item.getUnitMeasureId());
            if (unitMeasure != null) {
                unitCode = unitMeasure.getCode();
            }
            unitMeasureId = item.getUnitMeasureId();
        }
        // 3. 获取批次配置
        MesMdItemBatchConfigDO batchConfig = itemBatchConfigService.getItemBatchConfigByItemId(item.getId());
        // 4. 组装同步 DTO
        MdmItemSyncReqDTO syncReqDTO = new MdmItemSyncReqDTO();
        syncReqDTO.setCode(item.getCode());
        syncReqDTO.setName(item.getName());
        syncReqDTO.setSpecification(item.getSpecification());
        syncReqDTO.setItemType(itemType);
        syncReqDTO.setUnitMeasureId(unitMeasureId);
        syncReqDTO.setCategoryId(item.getItemTypeId());
        syncReqDTO.setStatus(item.getStatus());
        syncReqDTO.setMinStock(item.getMinStock());
        syncReqDTO.setMaxStock(item.getMaxStock());
        syncReqDTO.setIsBatchManaged(item.getBatchFlag());
        syncReqDTO.setIsHighValue(item.getHighValue());
        syncReqDTO.setRemark(item.getRemark());
        // 5. 同步批次配置
        if (batchConfig != null) {
            syncReqDTO.setProduceDateFlag(batchConfig.getProduceDateFlag());
            syncReqDTO.setExpireDateFlag(batchConfig.getExpireDateFlag());
            syncReqDTO.setReceiptDateFlag(batchConfig.getReceiptDateFlag());
            syncReqDTO.setVendorFlag(batchConfig.getVendorFlag());
            syncReqDTO.setPurchaseOrderCodeFlag(batchConfig.getPurchaseOrderCodeFlag());
            syncReqDTO.setLotNumberFlag(batchConfig.getLotNumberFlag());
            syncReqDTO.setQualityStatusFlag(batchConfig.getQualityStatusFlag());
        }
        // 6. 调用 MDM 同步 API
        mdmItemSyncApi.syncItemToMdm(syncReqDTO);
    }
    /**
     * 将 MES 物料类型转换为 MDM 物料类型
     * MES: ITEM(物料)/PRODUCT(产品)
     * MDM: 1原料, 2半成品, 3成品, 4辅料
     */
    private Integer convertMesItemTypeToMdm(String itemOrProduct, String typeName) {
        if (itemOrProduct == null) {
            return null;
        }
        // 根据名称匹配
        if (typeName != null) {
            if (typeName.contains("原料")) {
                return 1;
            } else if (typeName.contains("半成品")) {
                return 2;
            } else if (typeName.contains("成品")) {
                return 3;
            } else if (typeName.contains("辅料")) {
                return 4;
            }
        }
        // 根据 ITEM/PRODUCT 兜底
        if ("PRODUCT".equals(itemOrProduct)) {
            return 3; // 产品 -> 成品
        }
        return 1; // 默认原料
    }
    @Override
    public MesMdItemDO getItemByMdmItemId(Long mdmItemId) {
        if (mdmItemId == null) {
            return null;
        }
        return itemMapper.selectByMdmItemId(mdmItemId);
    }
    @Override
    public MesMdItemDO validateItemExistsByMdmItemId(Long mdmItemId) {
        MesMdItemDO item = getItemByMdmItemId(mdmItemId);
        if (item == null) {
            throw exception(MD_ITEM_NOT_EXISTS);
        }
        return item;
    }
}