From d80fa460742ddf052844746482801de355e85528 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期六, 07 十一月 2026 14:24:30 +0800
Subject: [PATCH] feat(qc): 拆分部门审批流程并支持扫码自动识别

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/seedquality/MesQcSeedQualityServiceImpl.java |   69 ++++++++++++++++++++++++++++------
 1 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/seedquality/MesQcSeedQualityServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/seedquality/MesQcSeedQualityServiceImpl.java
index f8ac385..dc95b1d 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/seedquality/MesQcSeedQualityServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/seedquality/MesQcSeedQualityServiceImpl.java
@@ -12,9 +12,11 @@
 import cn.iocoder.yudao.module.mes.controller.admin.qc.seedquality.vo.MesQcSeedQualitySubmitReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.seedquality.vo.MesQcSeedReturnQualitySubmitReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
+import cn.iocoder.yudao.module.mes.framework.qrcode.MesTraceCodeUtils;
 import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
 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.dal.dataobject.qc.seedquality.*;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesDO;
@@ -78,8 +80,10 @@
     private static final int QC_LINE_PROCESS = 1, QC_LINE_SALES = 2;
     /** 涓氬姟绫诲瀷锛�1 鐢熶骇鍏ュ簱璐ㄦ锛�2 缁忛攢鍟嗛��璐ц川妫� */
     private static final int BIZ_TYPE_PRODUCTION = 1, BIZ_TYPE_RETURN = 2;
-    /** 鏈嚎棰嗗瀹℃壒娴佺▼瀹氫箟鏍囪瘑 */
+    /** 鍔犲伐閮ㄩ瀵煎鎵规祦绋嬪畾涔夋爣璇� */
     private static final String LINE_PROCESS_KEY = "mes_seed_quality_line_approve";
+    /** 閿�鍞儴棰嗗瀹℃壒娴佺▼瀹氫箟鏍囪瘑 */
+    private static final String SALES_LINE_PROCESS_KEY = "mes_seed_quality_sales_line_approve";
     /** 鍏徃璐ㄦ瀹℃壒娴佺▼瀹氫箟鏍囪瘑 */
     private static final String COMPANY_PROCESS_KEY = "mes_seed_quality_company_approve";
     /** 缁忛攢鍟嗛��璐ц川妫�瀹℃壒娴佺▼瀹氫箟鏍囪瘑 */
@@ -194,7 +198,7 @@
 
     @Override
     public Map<String, Object> resolveScan(String code) {
-        MesProBagCodeDO bag = bagCodeMapper.selectByScanCode(code);
+        MesProBagCodeDO bag = bagCodeMapper.selectByScanCode(MesTraceCodeUtils.extractCode(code));
         if (bag == null) throw new IllegalArgumentException("鏈В鏋愬埌鏈夋晥琚嬬爜锛岃鎵弿琚嬬爜");
         Map<String, Object> result = new HashMap<>();
         result.put("code", bag.getCode());
@@ -227,28 +231,66 @@
         return result;
     }
 
-    private record Scope(String code, String businessCode, String batchCode, boolean canceled, List<MesProBagCodeDO> bags) { }
+    private record Scope(String type, String code, String businessCode, String batchCode, boolean canceled, List<MesProBagCodeDO> bags) { }
+
+    /** 鎵爜绫诲瀷锛氱敱鐮佸�艰嚜鍔ㄨ瘑鍒鐮� / 鎵樼洏鐮� / 鐢熶骇鎵规鐮� */
+    private static final String SCAN_TYPE_AUTO = "AUTO";
 
     private Scope scope(String code, String type, boolean lock) {
+        // 鏍囩浜岀淮鐮佸唴瀹瑰彲鑳芥槸鏁存杩芥函閾炬帴锛屽厛鎷嗚В涓虹函鐮佸�煎啀鍖归厤
+        code = MesTraceCodeUtils.extractCode(code);
+        if (StrUtil.isBlank(type) || SCAN_TYPE_AUTO.equalsIgnoreCase(type)) {
+            return autoScope(code, lock);
+        }
         if ("BAG".equals(type)) {
             MesProBagCodeDO bag = bagCodeMapper.selectByScanCode(code);
             if (bag == null) throw invalidParamException("鏈壘鍒拌鐮侊紝璇锋牳瀵规壂鐮佺被鍨嬪拰鐮佸��");
-            return new Scope(bag.getCode(), bag.getBusinessCode(), bag.getBatchCode(), Integer.valueOf(30).equals(bag.getStatus()), List.of(bag));
+            return bagScope(bag);
         }
         if ("PALLET".equals(type)) {
             var pallet = lock ? palletMapper.selectByScanCodeForUpdate(code) : palletMapper.selectByScanCode(code);
             if (pallet == null) throw invalidParamException("鏈壘鍒版墭鐩樼爜锛岃鏍稿鎵爜绫诲瀷鍜岀爜鍊�");
-            if (pallet.getBatchId() == null) throw invalidParamException("鎵樼洏灏氭湭缁戝畾鐢熶骇鎵规锛屾棤娉曡川妫�");
-            return new Scope(StrUtil.blankToDefault(pallet.getCode(), pallet.getTempCode()), pallet.getBusinessCode(), pallet.getBatchCode(),
-                    Integer.valueOf(20).equals(pallet.getStatus()), lock ? bagCodeMapper.selectListByPalletIdForUpdate(pallet.getId()) : bagCodeMapper.selectListByPalletId(pallet.getId()));
+            return palletScope(pallet, lock);
         }
         if ("BATCH".equals(type)) {
             var batch = lock ? batchMapper.selectByScanCodeForUpdate(code) : batchMapper.selectByScanCode(code);
             if (batch == null) throw invalidParamException("鏈壘鍒扮敓浜ф壒娆$爜锛岃鏍稿鎵爜绫诲瀷鍜岀爜鍊�");
-            return new Scope(StrUtil.blankToDefault(batch.getCode(), batch.getTempCode()), batch.getBusinessCode(), batch.getCode(),
-                    Integer.valueOf(40).equals(batch.getStatus()), lock ? bagCodeMapper.selectListByBatchIdForUpdate(batch.getId()) : bagCodeMapper.selectListByBatchId(batch.getId()));
+            return batchScope(batch, lock);
         }
         throw invalidParamException("涓嶆敮鎸佺殑璐ㄦ鎵爜绫诲瀷");
+    }
+
+    /** 涓庢壂鐮佺粦瀹氭墭鐩樹竴鑷达細鎸夌爜鍊艰嚜鍔ㄨ瘑鍒被鍨嬶紝渚濇灏濊瘯琚嬬爜銆佹墭鐩樼爜銆佺敓浜ф壒娆$爜 */
+    private Scope autoScope(String code, boolean lock) {
+        MesProBagCodeDO bag = bagCodeMapper.selectByScanCode(code);
+        if (bag != null) {
+            return bagScope(bag);
+        }
+        var pallet = lock ? palletMapper.selectByScanCodeForUpdate(code) : palletMapper.selectByScanCode(code);
+        if (pallet != null) {
+            return palletScope(pallet, lock);
+        }
+        var batch = lock ? batchMapper.selectByScanCodeForUpdate(code) : batchMapper.selectByScanCode(code);
+        if (batch != null) {
+            return batchScope(batch, lock);
+        }
+        throw invalidParamException("鏈壘鍒板搴旂殑琚嬬爜銆佹墭鐩樼爜鎴栫敓浜ф壒娆$爜锛岃鏍稿鐮佸��");
+    }
+
+    private Scope bagScope(MesProBagCodeDO bag) {
+        return new Scope("BAG", bag.getCode(), bag.getBusinessCode(), bag.getBatchCode(),
+                Integer.valueOf(30).equals(bag.getStatus()), List.of(bag));
+    }
+
+    private Scope palletScope(MesProPalletDO pallet, boolean lock) {
+        if (pallet.getBatchId() == null) throw invalidParamException("鎵樼洏灏氭湭缁戝畾鐢熶骇鎵规锛屾棤娉曡川妫�");
+        return new Scope("PALLET", StrUtil.blankToDefault(pallet.getCode(), pallet.getTempCode()), pallet.getBusinessCode(), pallet.getBatchCode(),
+                Integer.valueOf(20).equals(pallet.getStatus()), lock ? bagCodeMapper.selectListByPalletIdForUpdate(pallet.getId()) : bagCodeMapper.selectListByPalletId(pallet.getId()));
+    }
+
+    private Scope batchScope(MesProBatchDO batch, boolean lock) {
+        return new Scope("BATCH", StrUtil.blankToDefault(batch.getCode(), batch.getTempCode()), batch.getBusinessCode(), batch.getCode(),
+                Integer.valueOf(40).equals(batch.getStatus()), lock ? bagCodeMapper.selectListByBatchIdForUpdate(batch.getId()) : bagCodeMapper.selectListByBatchId(batch.getId()));
     }
 
     @Override
@@ -266,7 +308,8 @@
                 .filter(q -> !isReturnQuality(q))
                 .map(MesQcSeedQualityDO::getCode).collect(java.util.stream.Collectors.toSet());
         Map<String, Object> result = new HashMap<>();
-        result.put("scanType", scanType); result.put("code", scope.code()); result.put("businessCode", scope.businessCode());
+        // 鑷姩璇嗗埆鏃跺洖浼犲疄闄呯爜绫诲瀷锛屽墠绔嵁姝ゅ睍绀哄璞$被鍨嬪苟鐢ㄤ簬鎻愪氦
+        result.put("scanType", scope.type()); result.put("code", scope.code()); result.put("businessCode", scope.businessCode());
         result.put("batchCode", scope.batchCode()); result.put("canceled", scope.canceled());
         result.put("totalCount", effective.size());
         result.put("inbound", !effective.isEmpty() && effective.stream().allMatch(b -> b.getInboundEventId() != null));
@@ -278,7 +321,7 @@
         result.put("itemCode", item == null ? null : item.getCode());
         result.put("itemName", item == null ? null : item.getName());
         result.put("indicators", toRangePayload(itemId));
-        if ("BAG".equals(scanType)) {
+        if ("BAG".equals(scope.type())) {
             List<MesQcSeedQualityDO> qualities = qualityMapper.selectListByCode(scope.code());
             MesQcSeedQualityDO quality = qualities.stream()
                     .filter(q -> !isReturnQuality(q)).findFirst().orElse(null);
@@ -1076,9 +1119,11 @@
         Map<String, Object> variables = new HashMap<>();
         variables.put("qcLine", qcLine);
         variables.put("batchCode", batchCode);
+        String processDefinitionKey = Objects.equals(qcLine, QC_LINE_SALES)
+                ? SALES_LINE_PROCESS_KEY : LINE_PROCESS_KEY;
         String processInstanceId = processInstanceApi.createProcessInstance(operatorId,
                 new BpmProcessInstanceCreateReqDTO()
-                        .setProcessDefinitionKey(LINE_PROCESS_KEY)
+                        .setProcessDefinitionKey(processDefinitionKey)
                         .setBusinessKey(qcLine + "#" + batchCode)
                         .setVariables(variables));
         for (MesQcSeedQualityDO quality : pending) {

--
Gitblit v1.9.3