From 4ca4444ad33a2a1a51f5c06e78ee9365dfb1eed6 Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期四, 08 十月 2026 17:11:11 +0800
Subject: [PATCH] feat(mes): 种子二维码标签国标四要素合规改造
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/trace/MesProTracePublicServiceImpl.java | 132 ++++++++++++++++++++++++++++++++++++++-----
1 files changed, 115 insertions(+), 17 deletions(-)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/trace/MesProTracePublicServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/trace/MesProTracePublicServiceImpl.java
index 04ff12f..98da11f 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/trace/MesProTracePublicServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/trace/MesProTracePublicServiceImpl.java
@@ -2,9 +2,11 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchFlowRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchProcessTraceRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchPurchaseSourceRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchSalesTargetRespVO;
+import cn.iocoder.yudao.module.mes.controller.pub.trace.vo.MesProTracePublicConfigRespVO;
import cn.iocoder.yudao.module.mes.controller.pub.trace.vo.MesProTracePublicRespVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeDO;
@@ -17,6 +19,9 @@
import cn.iocoder.yudao.module.mes.enums.pro.MesProBagCodeStatusEnum;
import cn.iocoder.yudao.module.mes.enums.pro.MesProBatchStatusEnum;
import cn.iocoder.yudao.module.mes.enums.pro.MesProBatchWorkerTypeEnum;
+import cn.iocoder.yudao.module.mes.enums.pro.MesProPalletStatusEnum;
+import cn.iocoder.yudao.module.mes.enums.trace.MesTraceCodeStatusEnum;
+import cn.iocoder.yudao.module.mes.framework.qrcode.MesProQrLabelBuilder;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.pro.bagcode.MesProBagCodeService;
import cn.iocoder.yudao.module.mes.service.pro.batch.MesProBatchService;
@@ -29,6 +34,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;
@@ -43,6 +51,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;
@@ -78,6 +87,8 @@
@Resource
private MesMdmItemService mdmItemService;
@Resource
+ private MdmUnitMeasureApi unitMeasureApi;
+ @Resource
private AdminUserApi adminUserApi;
@Resource
private MesWmBatchService mesWmBatchService;
@@ -100,13 +111,13 @@
}
TraceEntry entry = null;
try {
- // 1. 瑙f瀽杩芥函鍏ュ彛锛屽畾浣嶆壒娆�
+ // 1. 瑙f瀽杩芥函鍏ュ彛锛屽畾浣嶆壒娆★紙琚嬬爜/鎵樼洏宸茬敓鎴愪絾鏈綍鍏ユ壒娆℃椂锛岄檷绾т负浠呰繑鍥炲搧绉嶄俊鎭級
entry = resolveEntry(traceCode);
- if (entry.batchId == null) {
+ if (entry.batchId == null && entry.bagItemId == null) {
throw exception(MES_TRACE_CODE_NOT_FOUND);
}
- // 2. 鑱氬悎鍏ㄧ▼淇℃伅
- MesProTracePublicRespVO result = buildRespVO(rawCode, traceCode, entry.sourceType, entry.batchId);
+ // 2. 鑱氬悎鍏ㄧ▼淇℃伅锛堜綔搴熺爜浠嶆甯歌繑鍥炲苟璁板綍鎵爜锛氫綔搴熺爜琚壂鏄噸瑕佺殑闃蹭吉淇″彿锛屼笉搴旇涓烘煡璇㈠け璐ワ級
+ MesProTracePublicRespVO result = buildRespVO(rawCode, traceCode, entry);
recordConsumerScan(rawCode, traceCode, entry.sourceType, entry.batchId, true);
return result;
} catch (RuntimeException ex) {
@@ -114,6 +125,15 @@
entry == null ? null : entry.batchId, false);
throw ex;
}
+ }
+
+ @Override
+ public MesProTracePublicConfigRespVO getPublicConfig() {
+ MesProTracePublicConfigRespVO respVO = new MesProTracePublicConfigRespVO();
+ respVO.setOperatorName(MesProQrLabelBuilder.resolveOperatorName());
+ respVO.setTraceUrl(MesProQrLabelBuilder.resolveTraceUrl());
+ respVO.setImported(MesProQrLabelBuilder.isImported());
+ return respVO;
}
/**
@@ -166,33 +186,65 @@
// 鈶� 琚嬬爜
MesProBagCodeDO bag = bagCodeService.getBagCodeByCode(traceCode);
if (bag != null) {
- return new TraceEntry("BAG", bag.getBatchId());
+ // 宸蹭綔搴熺殑琚嬬爜锛堢牬鎹熸浛鎹㈠悗浣滃簾锛夊繀椤诲澶栧け鏁堬細鍥芥爣瑕佹眰浜岀淮鐮佷笉寰楅噸澶嶄娇鐢紝
+ // 鑻ヤ綔搴熺爜浠嶈繑鍥炴湁鏁堟函婧愪俊鎭紝浣滃簾鐮佸嵆鍙鍐掔敤閿�鍞�
+ if (MesProBagCodeStatusEnum.CANCELED.getStatus().equals(bag.getStatus())) {
+ return new TraceEntry("BAG", bag.getBatchId(), bag.getItemId(),
+ MesTraceCodeStatusEnum.CANCELED.getStatus());
+ }
+ return TraceEntry.valid("BAG", bag.getBatchId(), bag.getItemId());
}
// 鈶� 鎵樼洏鐮�
MesProPalletDO pallet = palletService.getPalletByCode(traceCode);
if (pallet != null) {
- return new TraceEntry("PALLET", pallet.getBatchId());
+ // 鏈綍鍏ユ壒娆$殑鎵樼洏鍙栨墭鐩樺唴浠讳竴琚嬬爜鍝佺锛屼繚璇佷粛鑳藉睍绀哄搧绉嶄俊鎭�
+ Long itemId = pallet.getBatchId() == null
+ ? firstItemId(bagCodeService.getBagCodeListByPalletId(pallet.getId())) : null;
+ if (MesProPalletStatusEnum.CANCELED.getStatus().equals(pallet.getStatus())) {
+ return new TraceEntry("PALLET", pallet.getBatchId(), itemId,
+ MesTraceCodeStatusEnum.CANCELED.getStatus());
+ }
+ return TraceEntry.valid("PALLET", pallet.getBatchId(), itemId);
}
// 鈶� 鎵规鐮侊紙鍚复鏃舵壒娆$爜锛実etBatchByCode 鍐呴儴鍏煎锛�
MesProBatchDO batch = batchService.getBatchByCode(traceCode);
if (batch != null) {
- return new TraceEntry("BATCH", batch.getId());
+ if (MesProBatchStatusEnum.CANCELED.getStatus().equals(batch.getStatus())) {
+ return new TraceEntry("BATCH", batch.getId(), null,
+ MesTraceCodeStatusEnum.CANCELED.getStatus());
+ }
+ return TraceEntry.valid("BATCH", batch.getId(), null);
}
- return new TraceEntry("", null);
+ return new TraceEntry("", null, null, MesTraceCodeStatusEnum.VALID.getStatus());
}
// ==================== 鑱氬悎鏋勫缓 ====================
- private MesProTracePublicRespVO buildRespVO(String requestCode, String traceCode, String sourceType, Long batchId) {
- MesProBatchDO batch = batchService.getBatch(batchId);
- if (batch == null) {
+ private MesProTracePublicRespVO buildRespVO(String requestCode, String traceCode, TraceEntry entry) {
+ String sourceType = entry.sourceType();
+ Long batchId = entry.batchId();
+ Long bagItemId = entry.bagItemId();
+ 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.setSourceType(sourceType);
resp.setRequestCode(requestCode);
+ // 杩芥函鐮佹湁鏁堟�� + 鏍囩鍥涜绱犱腑鐨勭敓浜х粡钀ヨ�呬笌杩芥函缃戝潃锛屼繚璇佷笌鏍囩鍗板埛鍐呭涓�鑷�
+ resp.setCodeStatus(entry.codeStatus());
+ resp.setOperatorName(MesProQrLabelBuilder.resolveOperatorName());
+ resp.setTraceUrl(MesProQrLabelBuilder.resolveTraceUrl());
// 鍝佺鍖哄潡
- fillItem(resp, batch);
+ 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()))
@@ -219,15 +271,45 @@
return resp;
}
- private void fillItem(MesProTracePublicRespVO resp, MesProBatchDO batch) {
- if (batch.getItemId() == null) {
+ /**
+ * 鍝佺宸蹭笅娌夊埌琚嬬爜鏁版嵁鍖咃細浼樺厛鍙栨壂鐮佽鐮佸搧绉嶏紝鍘嗗彶鎵规鍥為��鎵规鍝佺锛屾壒娆�/鎵樼洏鍏ュ彛鍙栨壒鍐呬换涓�琚嬬爜鍝佺
+ */
+ private void fillItem(MesProTracePublicRespVO resp, MesProBatchDO batch, Long bagItemId) {
+ 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;
}
- MesMdmItemDO item = mdmItemService.getItem(batch.getItemId());
+ MesMdmItemDO item = mdmItemService.getItem(itemId);
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) {
@@ -333,12 +415,15 @@
resp.setPurchaseSources(CollUtil.isNotEmpty(purchaseSources) ? purchaseSources : List.of());
resp.setSalesTargets(CollUtil.isNotEmpty(salesTargets) ? salesTargets : List.of());
resp.setProcessTraces(CollUtil.isNotEmpty(processTraces) ? processTraces : List.of());
+ List<MesWmBatchFlowRespVO> seedFlows = mesWmBatchService.getBatchFlowList(batch.getCode());
+ resp.setSeedFlows(CollUtil.isNotEmpty(seedFlows) ? seedFlows : List.of());
} catch (Exception ex) {
// 浠撳簱鎵规浣撶郴锛堥噰璐�/閿�鍞�/娴佽浆锛夋湭鍚敤鏃跺閿欙紝涓嶅奖鍝嶆牳蹇冭拷婧�
log.warn("[fillOptionalModules][鎵规 {} 鎵╁睍妯″潡鏌ヨ澶辫触: {}]", batch.getCode(), ex.getMessage());
resp.setPurchaseSources(List.of());
resp.setSalesTargets(List.of());
resp.setProcessTraces(List.of());
+ resp.setSeedFlows(List.of());
}
}
@@ -454,7 +539,20 @@
};
}
- private record TraceEntry(String sourceType, Long batchId) {
+ /**
+ * 杩芥函鍏ュ彛瑙f瀽缁撴灉
+ *
+ * @param sourceType 鍏ュ彛绫诲瀷锛欱AG / PALLET / BATCH锛屾湭鍖归厤鍒版椂涓虹┖涓�
+ * @param batchId 鐢熶骇鎵规缂栧彿
+ * @param bagItemId 琚嬬爜缁戝畾鐨勫搧绉嶇紪鍙凤紙鏈綍鎵规鏃剁敤浜庡睍绀哄搧绉嶏級
+ * @param codeStatus 杩芥函鐮佹湁鏁堟�э細{@link MesTraceCodeStatusEnum#VALID} / {@link MesTraceCodeStatusEnum#CANCELED}
+ */
+ private record TraceEntry(String sourceType, Long batchId, Long bagItemId, String codeStatus) {
+
+ static TraceEntry valid(String sourceType, Long batchId, Long bagItemId) {
+ return new TraceEntry(sourceType, batchId, bagItemId, MesTraceCodeStatusEnum.VALID.getStatus());
+ }
+
}
}
--
Gitblit v1.9.3