云
5 小时以前 8ea92030610fd1e62136f7b26e10d5396359d8f8
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/trace/MesProTracePublicServiceImpl.java
@@ -30,6 +30,9 @@
import cn.iocoder.yudao.module.mes.service.trace.crossregion.MesTraceCrossRegionService;
import cn.iocoder.yudao.module.mes.service.trace.integrity.MesTraceIntegrityService;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import jakarta.annotation.Resource;
@@ -44,6 +47,7 @@
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -79,6 +83,8 @@
    @Resource
    private MesMdmItemService mdmItemService;
    @Resource
    private MdmUnitMeasureApi unitMeasureApi;
    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private MesWmBatchService mesWmBatchService;
@@ -101,9 +107,9 @@
        }
        TraceEntry entry = null;
        try {
            // 1. 解析追溯入口,定位批次
            // 1. 解析追溯入口,定位批次(袋码/托盘已生成但未录入批次时,降级为仅返回品种信息)
            entry = resolveEntry(traceCode);
            if (entry.batchId == null) {
            if (entry.batchId == null && entry.bagItemId == null) {
                throw exception(MES_TRACE_CODE_NOT_FOUND);
            }
            // 2. 聚合全程信息
@@ -172,7 +178,10 @@
        // ② 托盘码
        MesProPalletDO pallet = palletService.getPalletByCode(traceCode);
        if (pallet != null) {
            return new TraceEntry("PALLET", pallet.getBatchId(), null);
            // 未录入批次的托盘取托盘内任一袋码品种,保证仍能展示品种信息
            Long itemId = pallet.getBatchId() == null
                    ? firstItemId(bagCodeService.getBagCodeListByPalletId(pallet.getId())) : null;
            return new TraceEntry("PALLET", pallet.getBatchId(), itemId);
        }
        // ③ 批次码(含临时批次码,getBatchByCode 内部兼容)
        MesProBatchDO batch = batchService.getBatchByCode(traceCode);
@@ -185,8 +194,8 @@
    // ==================== 聚合构建 ====================
    private MesProTracePublicRespVO buildRespVO(String requestCode, String traceCode, String sourceType, Long batchId, Long bagItemId) {
        MesProBatchDO batch = batchService.getBatch(batchId);
        if (batch == null) {
        MesProBatchDO batch = batchId == null ? null : batchService.getBatch(batchId);
        if (batchId != null && batch == null) {
            throw exception(MES_TRACE_CODE_NOT_FOUND);
        }
        MesProTracePublicRespVO resp = new MesProTracePublicRespVO();
@@ -194,6 +203,14 @@
        resp.setRequestCode(requestCode);
        // 品种区块
        fillItem(resp, batch, bagItemId);
        if (batch == null) {
            // 袋码/托盘已生成但尚未录入生产批次:只返回品种信息,由前端提示未绑定批次
            resp.setBatchBound(false);
            fillAntiFake(resp, traceCode);
            fillTimelineAndDecision(resp);
            return resp;
        }
        resp.setBatchBound(true);
        // 批次区块
        resp.setBatchCode(batch.getCode()).setTempCode(batch.getTempCode())
                .setBatchStatus(batch.getStatus()).setBatchStatusName(batchStatusName(batch.getStatus()))
@@ -224,11 +241,9 @@
     * 品种已下沉到袋码数据包:优先取扫码袋码品种,历史批次回退批次品种,批次/托盘入口取批内任一袋码品种
     */
    private void fillItem(MesProTracePublicRespVO resp, MesProBatchDO batch, Long bagItemId) {
        Long itemId = bagItemId != null ? bagItemId : batch.getItemId();
        if (itemId == null) {
            List<MesProBagCodeDO> bags = bagCodeService.getBagCodeListByBatchId(batch.getId());
            itemId = bags == null ? null : bags.stream().map(MesProBagCodeDO::getItemId)
                    .filter(id -> id != null).findFirst().orElse(null);
        Long itemId = bagItemId != null ? bagItemId : (batch == null ? null : batch.getItemId());
        if (itemId == null && batch != null) {
            itemId = firstItemId(bagCodeService.getBagCodeListByBatchId(batch.getId()));
        }
        if (itemId == null) {
            return;
@@ -237,7 +252,30 @@
        if (item == null) {
            return;
        }
        resp.setItemCode(item.getCode()).setItemName(item.getName()).setItemSpecification(item.getSpecification());
        resp.setItemCode(item.getCode()).setItemName(item.getName()).setItemSpecification(item.getSpecification())
                .setItemUnitMeasureName(unitMeasureName(item.getUnitMeasureId()));
    }
    /**
     * 读取袋码列表中第一个非空品种编号
     */
    private Long firstItemId(List<MesProBagCodeDO> bags) {
        return CollUtil.isEmpty(bags) ? null : bags.stream().map(MesProBagCodeDO::getItemId)
                .filter(Objects::nonNull).findFirst().orElse(null);
    }
    /**
     * 读取品种主计量单位名称,未配置单位或单位不存在时返回 null
     */
    private String unitMeasureName(Long unitMeasureId) {
        if (unitMeasureId == null) {
            return null;
        }
        CommonResult<MdmUnitMeasureRespDTO> result = unitMeasureApi.getUnitMeasure(unitMeasureId);
        if (result == null || !result.isSuccess() || result.getData() == null) {
            return null;
        }
        return StrUtil.trimToNull(result.getData().getName());
    }
    private List<MesProTracePublicRespVO.WorkerVO> buildWorkers(Long batchId) {