| | |
| | | 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; |
| | |
| | | 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; |
| | |
| | | @Resource |
| | | private MesMdmItemService mdmItemService; |
| | | @Resource |
| | | private MdmUnitMeasureApi unitMeasureApi; |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | | @Resource |
| | | private MesWmBatchService mesWmBatchService; |
| | |
| | | } |
| | | 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. 聚合全程信息 |
| | |
| | | // ② 托盘码 |
| | | 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); |
| | |
| | | // ==================== 聚合构建 ==================== |
| | | |
| | | 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(); |
| | |
| | | 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())) |
| | |
| | | * 品种已下沉到袋码数据包:优先取扫码袋码品种,历史批次回退批次品种,批次/托盘入口取批内任一袋码品种 |
| | | */ |
| | | 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; |
| | |
| | | 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) { |