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