yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java
@@ -5,15 +5,22 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueBomItemRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueLineDO;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderBomService;
import cn.iocoder.yudao.module.mes.service.wm.productissue.MesWmProductIssueLineService;
import cn.iocoder.yudao.module.mes.service.wm.productissue.MesWmProductIssueService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -23,7 +30,10 @@
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -39,9 +49,15 @@
    @Resource
    private MesWmProductIssueLineService issueLineService;
    @Resource
    private MesMdItemService itemService;
    private MesWmProductIssueService issueService;
    @Resource
    private MesProWorkOrderBomService workOrderBomService;
    @Resource
    private MesMdItemService mdmItemService;
    @Resource
    private MesMdUnitMeasureService unitMeasureService;
    @Resource
    private MesProTaskService taskService;
    @PostMapping("/create")
    @Operation(summary = "创建领料出库单行")
@@ -98,6 +114,47 @@
        return success(buildRespVOList(list));
    }
    @GetMapping("/bom-item-list")
    @Operation(summary = "获得领料出库单可领物料列表",
            description = "仅返回当前领料单对应生产工单 BOM 中的物料,用于新增行物料选择器过滤,避免选择 BOM 之外的物料")
    @Parameter(name = "issueId", description = "领料单编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('mes:wm-product-issue:query')")
    public CommonResult<List<MesWmProductIssueBomItemRespVO>> getBomItemList(@RequestParam("issueId") Long issueId) {
        // 1. 校验领料单存在,获取关联工单
        MesWmProductIssueDO issue = issueService.validateProductIssueExists(issueId);
        if (issue.getWorkOrderId() == null) {
            return success(Collections.emptyList());
        }
        // 2. 获取工单 BOM 物料(同一物料跨工序多次投料时,需求量按物料汇总)
        List<MesProWorkOrderBomDO> bomList = workOrderBomService.getWorkOrderBomListByWorkOrderId(issue.getWorkOrderId());
        if (CollUtil.isEmpty(bomList)) {
            return success(Collections.emptyList());
        }
        Map<Long, BigDecimal> requiredQtyMap = new LinkedHashMap<>();
        for (MesProWorkOrderBomDO bom : bomList) {
            BigDecimal quantity = bom.getQuantity() != null ? bom.getQuantity() : BigDecimal.ZERO;
            requiredQtyMap.merge(bom.getItemId(), quantity, BigDecimal::add);
        }
        // 3. 批量获取物料与单位信息,拼接 VO
        Map<Long, MesMdItemDO> itemMap = mdmItemService.getItemMap(requiredQtyMap.keySet());
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        List<MesWmProductIssueBomItemRespVO> result = new ArrayList<>(requiredQtyMap.size());
        requiredQtyMap.forEach((itemId, requiredQuantity) -> {
            MesMdItemDO item = itemMap.get(itemId);
            if (item == null) {
                return;
            }
            MesWmProductIssueBomItemRespVO vo = new MesWmProductIssueBomItemRespVO()
                    .setItemId(itemId).setItemCode(item.getCode()).setItemName(item.getName())
                    .setItemSpecification(item.getSpecification()).setRequiredQuantity(requiredQuantity);
            MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
                    unit -> vo.setUnitMeasureName(unit.getName()));
            result.add(vo);
        });
        return success(result);
    }
    // ==================== 拼接 VO ====================
    private List<MesWmProductIssueLineRespVO> buildRespVOList(List<MesWmProductIssueLineDO> list) {
@@ -105,17 +162,21 @@
            return Collections.emptyList();
        }
        // 1. 获得关联数据
        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
        Map<Long, MesMdItemDO> itemMap = mdmItemService.getItemMap(
                convertSet(list, MesWmProductIssueLineDO::getItemId));
        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
        Map<Long, MesProTaskDO> taskMap = taskService.getTaskMap(
                convertSet(list, MesWmProductIssueLineDO::getTaskId));
        // 2. 构建结果
        return BeanUtils.toBean(list, MesWmProductIssueLineRespVO.class, vo -> {
            MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
                vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification());
                vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()).setMdmItemId(item.getMdmItemId());
                MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
                        unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName()));
                        unit -> vo.setUnitMeasureName(unit.getName()));
            });
            MapUtils.findAndThen(taskMap, vo.getTaskId(), task ->
                    vo.setTaskCode(task.getCode()).setTaskName(task.getName()));
        });
    }