yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderProcessServiceImpl.java
@@ -24,6 +24,7 @@
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
@@ -31,7 +32,7 @@
/**
 * MES 生产工单工序 Service 实现类
 *
 * @author 芋道源码
 * @author 超级管理员
 */
@Service
@Validated
@@ -60,6 +61,12 @@
        // 2. 插入数据
        MesProWorkOrderProcessDO workOrderProcess = BeanUtils.toBean(createReqVO, MesProWorkOrderProcessDO.class);
        if (CollUtil.isNotEmpty(createReqVO.getOutputItemIds())) {
            workOrderProcess.setOutputItemId(
                createReqVO.getOutputItemIds().stream()
                    .map(String::valueOf)
                    .collect(Collectors.joining(",")));
        }
        workOrderProcessMapper.insert(workOrderProcess);
        // 3. 重建工序链
@@ -75,6 +82,12 @@
        // 2. 更新数据
        MesProWorkOrderProcessDO updateObj = BeanUtils.toBean(updateReqVO, MesProWorkOrderProcessDO.class);
        if (CollUtil.isNotEmpty(updateReqVO.getOutputItemIds())) {
            updateObj.setOutputItemId(
                updateReqVO.getOutputItemIds().stream()
                    .map(String::valueOf)
                    .collect(Collectors.joining(",")));
        }
        workOrderProcessMapper.updateById(updateObj);
        // 3. 重建工序链
@@ -106,6 +119,19 @@
    @Override
    public List<MesProWorkOrderProcessDO> getWorkOrderProcessListByWorkOrderId(Long workOrderId) {
        return workOrderProcessMapper.selectListByWorkOrderId(workOrderId);
    }
    @Override
    public MesProWorkOrderProcessDO getLastWorkOrderProcessByWorkOrderId(Long workOrderId) {
        return workOrderProcessMapper.selectLastByWorkOrderId(workOrderId);
    }
    @Override
    public List<MesProWorkOrderProcessDO> getWorkOrderProcessListByWorkOrderIds(java.util.Collection<Long> workOrderIds) {
        if (CollUtil.isEmpty(workOrderIds)) {
            return Collections.emptyList();
        }
        return workOrderProcessMapper.selectListByWorkOrderIds(workOrderIds);
    }
    @Override
@@ -175,10 +201,16 @@
            if (item.getId() == null) {
                // 新增
                MesProWorkOrderProcessDO process = BeanUtils.toBean(item, MesProWorkOrderProcessDO.class);
                if (CollUtil.isNotEmpty(item.getOutputItemIds())) {
                    process.setOutputItemId(item.getOutputItemIds().stream().map(String::valueOf).collect(Collectors.joining(",")));
                }
                workOrderProcessMapper.insert(process);
            } else {
                // 更新
                MesProWorkOrderProcessDO updateObj = BeanUtils.toBean(item, MesProWorkOrderProcessDO.class);
                if (CollUtil.isNotEmpty(item.getOutputItemIds())) {
                    updateObj.setOutputItemId(item.getOutputItemIds().stream().map(String::valueOf).collect(Collectors.joining(",")));
                }
                workOrderProcessMapper.updateById(updateObj);
            }
        }
@@ -191,32 +223,27 @@
    }
    /**
     * 从工序列表中提取 BOM 投料,合并去重后保存到工单 BOM 表
     * 从工序列表中提取 BOM 投料,按工序分别保存到工单 BOM 表
     */
    private void saveWorkOrderBomFromProcesses(Long workOrderId, List<MesProWorkOrderProcessSaveReqVO> list) {
        // 收集所有工序的 bomItems,按 itemId 去重(保留第一个出现的 quantity)
        java.util.Map<Long, MesProWorkOrderProcessSaveReqVO.BomItem> merged = new java.util.LinkedHashMap<>();
        workOrderBomService.deleteWorkOrderBomByWorkOrderId(workOrderId);
        List<MesProWorkOrderBomDO> bomList = new ArrayList<>();
        for (MesProWorkOrderProcessSaveReqVO item : list) {
            if (CollUtil.isNotEmpty(item.getBomItems())) {
                for (MesProWorkOrderProcessSaveReqVO.BomItem bomItem : item.getBomItems()) {
                    if (bomItem.getItemId() != null) {
                        merged.putIfAbsent(bomItem.getItemId(), bomItem);
                        bomList.add(MesProWorkOrderBomDO.builder()
                                .workOrderId(workOrderId)
                                .processId(item.getProcessId())
                                .itemId(bomItem.getItemId())
                                .quantity(bomItem.getQuantity())
                                .remark(bomItem.getRemark())
                                .build());
                    }
                }
            }
        }
        // 删除旧 BOM,批量插入新 BOM
        workOrderBomService.deleteWorkOrderBomByWorkOrderId(workOrderId);
        if (CollUtil.isNotEmpty(merged)) {
            List<MesProWorkOrderBomDO> bomList = new ArrayList<>(merged.size());
            for (MesProWorkOrderProcessSaveReqVO.BomItem bomItem : merged.values()) {
                bomList.add(MesProWorkOrderBomDO.builder()
                        .workOrderId(workOrderId)
                        .itemId(bomItem.getItemId())
                        .quantity(bomItem.getQuantity())
                        .remark(bomItem.getRemark())
                        .build());
            }
        if (CollUtil.isNotEmpty(bomList)) {
            workOrderBomMapper.insertBatch(bomList);
        }
    }