From da93fafc417b4f590b6ab639ccbbe67c14c8753c Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期五, 16 十月 2026 17:58:21 +0800
Subject: [PATCH] feat(mes): 种子标签追溯配置改为字典驱动

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/framework/qrcode/MesProQrLabelBuilder.java |   90 ++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 76 insertions(+), 14 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/framework/qrcode/MesProQrLabelBuilder.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/framework/qrcode/MesProQrLabelBuilder.java
index 89bb98d..fcc1855 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/framework/qrcode/MesProQrLabelBuilder.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/framework/qrcode/MesProQrLabelBuilder.java
@@ -7,6 +7,7 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.bagcode.MesProBagCodeDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.batch.MesProBatchDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.pallet.MesProPalletDO;
+import cn.iocoder.yudao.module.mes.framework.config.MesTraceConfigSnapshot;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 
 import java.net.URLEncoder;
@@ -69,16 +70,30 @@
      */
     private static final Pattern UNIT_CODE_PATTERN = Pattern.compile("^[0-9A-Za-z]{1,20}$");
 
-    /** H5 婧簮椤甸潰鍩虹鍦板潃锛岀敱 {@code MesQrCodeConfig} 鍚姩鏃舵敞鍏ワ紱涓虹┖鏃朵簩缁寸爜缂栫爜绾爜鍊� */
+    /**
+     * 閰嶇疆鏉ユ簮锛氱敱 {@code MesQrCodeConfig} 鍚姩鏃惰閰嶏紝鎸囧悜瀛楀吀瑙f瀽鍣ㄣ��
+     * <p>
+     * 涓� null 鏃讹紙鍗曟祴銆侀潪 Spring 涓婁笅鏂囷級鍥為��涓嬮潰鍑犱釜闈欐�佸瓧娈碉紝涔熷氨鏄厤缃枃浠剁殑鍊笺��
+     */
+    private static volatile MesTraceConfigProvider configProvider;
+
+    /** H5 婧簮椤甸潰鍩虹鍦板潃锛岄厤缃枃浠� {@code mes.trace-base-url} 鐨勫�硷紱瀛楀吀鏈厤缃椂鐨勫厹搴� */
     private static volatile String traceBaseUrl = "";
-    /** 鐢熶骇缁忚惀鑰呭悕绉帮紝鐢� {@code MesQrCodeConfig} 鍚姩鏃舵敞鍏� */
+    /** 鐢熶骇缁忚惀鑰呭悕绉帮紝閰嶇疆鏂囦欢 {@code mes.operator-name} 鐨勫�硷紱瀛楀吀鏈厤缃椂鐨勫厹搴� */
     private static volatile String operatorName = "";
-    /** 杩涘彛鍟嗗悕绉帮紝杩涘彛绉嶅瓙鍦烘櫙浣跨敤 */
+    /** 杩涘彛鍟嗗悕绉帮紝閰嶇疆鏂囦欢 {@code mes.importer-name} 鐨勫�硷紱瀛楀吀鏈厤缃椂鐨勫厹搴� */
     private static volatile String importerName = "";
-    /** 鏄惁杩涘彛绉嶅瓙鍦烘櫙 */
+    /** 鏄惁杩涘彛绉嶅瓙鍦烘櫙锛岄厤缃枃浠� {@code mes.imported} 鐨勫�硷紱瀛楀吀鏈厤缃椂鐨勫厹搴� */
     private static volatile boolean imported = false;
     /** 鏄惁鍏佽浜岀淮鐮侀檷绾х紪鐮佺函鐮佸�硷紙浠呴檺鏈湴鍏煎鍘嗗彶鐮侊級 */
     private static volatile boolean allowPlainQrCode = false;
+
+    /**
+     * 瑁呴厤閰嶇疆鏉ユ簮銆備紶 null 鍙仮澶嶄负銆屽彧璇婚厤缃枃浠堕潤鎬佸�笺�嶏紝鍗曟祴鍊熸閬垮厤闈欐�佺姸鎬佷覆鍛炽��
+     */
+    public static void setTraceConfigProvider(MesTraceConfigProvider provider) {
+        MesProQrLabelBuilder.configProvider = provider;
+    }
 
     public static void setTraceBaseUrl(String traceBaseUrl) {
         MesProQrLabelBuilder.traceBaseUrl = StrUtil.blankToDefault(traceBaseUrl, "");
@@ -101,21 +116,46 @@
     }
 
     /**
+     * 鍙栧綋鍓嶇敓鏁堢殑閰嶇疆蹇収
+     *
+     * @return 蹇収锛涙湭瑁呴厤閰嶇疆鏉ユ簮鏃惰繑鍥� null锛岃皟鐢ㄦ柟鍥為��闈欐�佸瓧娈碉紙閰嶇疆鏂囦欢鐨勫�硷級
+     */
+    private static MesTraceConfigSnapshot currentSnapshot() {
+        MesTraceConfigProvider provider = configProvider;
+        return provider != null ? provider.get() : null;
+    }
+
+    /**
      * 褰撳墠搴旀爣娉ㄧ殑鐢熶骇缁忚惀鑰呭悕绉帮細杩涘彛绉嶅瓙鍦烘櫙浼樺厛鍙栬繘鍙e晢鍚嶇О锛屽惁鍒欏彇鐢熶骇缁忚惀鑰呭悕绉�
      *
      * @return 鍚嶇О锛屾湭閰嶇疆鏃惰繑鍥炵┖涓�
      */
     public static String resolveOperatorName() {
-        if (imported && StrUtil.isNotBlank(importerName)) {
-            return importerName;
+        return resolveOperatorName(currentSnapshot());
+    }
+
+    private static String resolveOperatorName(MesTraceConfigSnapshot snapshot) {
+        boolean importedScene = snapshot != null ? snapshot.imported() : imported;
+        String currentImporterName = snapshot != null ? snapshot.importerName() : importerName;
+        String currentOperatorName = snapshot != null ? snapshot.operatorName() : operatorName;
+        if (importedScene && StrUtil.isNotBlank(currentImporterName)) {
+            return currentImporterName;
         }
-        return operatorName;
+        return currentOperatorName;
     }
 
     /**
      * 杩芥函缃戝潃锛堝澶栧睍绀虹敤锛屼笉鍚� code 鍙傛暟锛�
      */
     public static String resolveTraceUrl() {
+        return resolveTraceUrl(currentSnapshot());
+    }
+
+    private static String resolveTraceUrl(MesTraceConfigSnapshot snapshot) {
+        // 蹇収涓虹┖鍊兼椂涓嶈鐩栭厤缃枃浠剁殑鍊硷細閰嶇疆鏉ユ簮鍙簲銆岃ˉ鍏呫�嶈�屼笉搴旀妸鍏滃簳鍊兼姽鎴愮┖
+        if (snapshot != null && StrUtil.isNotBlank(snapshot.traceUrl())) {
+            return snapshot.traceUrl().trim();
+        }
         return traceBaseUrl;
     }
 
@@ -123,7 +163,11 @@
      * 鏄惁杩涘彛绉嶅瓙鍦烘櫙锛氫负 true 鏃舵爣绛句笌婧簮椤靛簲灞曠ず銆岃繘鍙e晢鍚嶇О銆�
      */
     public static boolean isImported() {
-        return imported;
+        return isImported(currentSnapshot());
+    }
+
+    private static boolean isImported(MesTraceConfigSnapshot snapshot) {
+        return snapshot != null ? snapshot.imported() : imported;
     }
 
     /**
@@ -132,13 +176,26 @@
      * 鏈厤缃函婧愬湴鍧�涓旀湭寮�鍚檷绾у紑鍏虫椂鐩存帴鎶ラ敊锛岄伩鍏嶅嵃鍑轰笉鍚拷婧綉鍧�鐨勬爣绛俱��
      */
     private static String buildQrCodeContent(String code) {
-        if (StrUtil.isEmpty(traceBaseUrl)) {
+        return buildQrCodeContent(code, resolveTraceUrl());
+    }
+
+    /**
+     * 缁勮浜岀淮鐮佸唴瀹癸紙浣跨敤璋冪敤鏂圭粰瀹氱殑杩芥函缃戝潃锛�
+     * <p>
+     * 鏍囩涓婃棦鏈変簩缁寸爜鍐呭銆佸張鏈夊彲璇荤殑銆岃拷婧綉鍧�銆嶆枃鏈椂锛屼袱澶勫繀椤讳紶鍚屼竴涓綉鍧�锛�
+     * 鍒嗗埆鍙栧�煎彲鑳借法瓒婄紦瀛樺埛鏂帮紝瀵艰嚧鍚屼竴寮犳爣绛句笂鏂囧瓧涓庝簩缁寸爜鎸囧悜涓嶅悓鍦板潃銆�
+     *
+     * @param code     鐮佸��
+     * @param traceUrl 鏈鐢熸晥鐨勮拷婧綉鍧�锛屼负绌鸿〃绀烘湭閰嶇疆
+     */
+    private static String buildQrCodeContent(String code, String traceUrl) {
+        if (StrUtil.isEmpty(traceUrl)) {
             if (allowPlainQrCode) {
                 return code;
             }
             throw exception(PRO_QR_LABEL_TRACE_URL_NOT_CONFIGURED);
         }
-        return traceBaseUrl + "?code=" + URLEncoder.encode(code, StandardCharsets.UTF_8);
+        return traceUrl + "?code=" + URLEncoder.encode(code, StandardCharsets.UTF_8);
     }
 
     /**
@@ -217,16 +274,21 @@
                                                 MesProBatchDO batch,
                                                 Map<Long, MesMdmItemDO> itemMap,
                                                 Map<Long, AdminUserRespDTO> userMap) {
+        // 鏁村紶鏍囩鍙彇涓�娆¢厤缃揩鐓э細鍙鏂囨湰涓庝簩缁寸爜鍐呭鍏辩敤鍚屼竴涓拷婧綉鍧�銆�
+        // 鑻ヤ袱澶勫悇鑷彇鍊硷紝缂撳瓨鍙兘鎭板ソ鍦ㄥ叾闂村埛鏂帮紝鍚屼竴寮犳爣绛句笂鐨勬枃瀛椾笌浜岀淮鐮佸氨浼氭寚鍚戜笉鍚屽湴鍧�銆�
+        MesTraceConfigSnapshot snapshot = currentSnapshot();
+        String traceUrl = resolveTraceUrl(snapshot);
+
         LinkedHashMap<String, String> keyValues = new LinkedHashMap<>();
 
         // ===== 鍥涜绱狅紙鍥芥爣瑕佹眰锛岄『搴忓浐瀹氾紝缂哄け鍗抽樆鏂鍑猴級=====
         putRequired(keyValues, "鍝佺鍚嶇О", resolveItemName(bagCode, batch, itemMap),
                 PRO_QR_LABEL_ITEM_NAME_MISSING);
-        putRequired(keyValues, imported ? "杩涘彛鍟嗗悕绉�" : "鐢熶骇缁忚惀鑰呭悕绉�", resolveOperatorName(),
-                PRO_QR_LABEL_OPERATOR_MISSING);
+        putRequired(keyValues, isImported(snapshot) ? "杩涘彛鍟嗗悕绉�" : "鐢熶骇缁忚惀鑰呭悕绉�",
+                resolveOperatorName(snapshot), PRO_QR_LABEL_OPERATOR_MISSING);
         putRequired(keyValues, "鍗曞厓璇嗗埆浠g爜", resolveUnitCode(bagCode.getCode()),
                 PRO_QR_LABEL_UNIT_CODE_MISSING);
-        putRequired(keyValues, "杩芥函缃戝潃", resolveTraceUrl(), PRO_QR_LABEL_TRACE_URL_NOT_CONFIGURED);
+        putRequired(keyValues, "杩芥函缃戝潃", traceUrl, PRO_QR_LABEL_TRACE_URL_NOT_CONFIGURED);
 
         // ===== 浠ヤ笅涓鸿緟鍔╃敓浜т俊鎭� =====
         if (bagCode.getBagNo() != null) {
@@ -243,7 +305,7 @@
         }
         return QrLabelInfo.builder()
                 .fileName(bagCode.getCode())
-                .code(buildQrCodeContent(bagCode.getCode()))
+                .code(buildQrCodeContent(bagCode.getCode(), traceUrl))
                 .keyValues(keyValues)
                 .build();
     }

--
Gitblit v1.9.3