From 7ac5fb62d3ac852ec9505eb5c1999064aafee85f Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期四, 13 八月 2026 16:26:39 +0800
Subject: [PATCH] feat(mes): 添加MES模块配置和功能
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectRespVO.java | 3
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/MesPdStatusConstants.java | 4
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/listener/MesPdProjectStatusListener.java | 47 ++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchProcessTraceRespVO.java | 46 ++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchPurchaseSourceRespVO.java | 52 ++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchSalesTargetRespVO.java | 55 ++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/MesWmBatchController.java | 97 ++++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java | 43 +
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/batch/MesWmBatchMapper.java | 27 +
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectService.java | 24
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectServiceImpl.java | 121 ++++
docs/pd_project_bpm_approval_frontend.md | 87 +++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/MesPdProjectController.java | 17
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java | 3
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdProjectStatusEnum.java | 10
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchService.java | 35 +
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/project/MesPdProjectDO.java | 8
yudao-module-mes/src/main/resources/mapper/wm/batch/MesWmBatchMapper.xml | 65 ++
yudao-server/src/main/resources/application-yzfx.yaml | 324 ++++++++++++++
docs/batch_trace_extended_frontend.md | 305 +++++++++++++
20 files changed, 1,348 insertions(+), 25 deletions(-)
diff --git a/docs/batch_trace_extended_frontend.md b/docs/batch_trace_extended_frontend.md
new file mode 100644
index 0000000..8a04534
--- /dev/null
+++ b/docs/batch_trace_extended_frontend.md
@@ -0,0 +1,305 @@
+# 鎵规杩芥函鎵╁睍 - 鍓嶇鑱旇皟鏂规
+
+## 姒傝堪
+
+鍦ㄧ幇鏈夋壒娆¤拷婧紙鍚戝墠/鍚戝悗锛夊熀纭�涓婏紝鎵╁睍 4 涓兘鍔涳紝琛ラ綈鎵规鍏ㄩ摼璺拷婧細
+
+1. **閲囪喘鏉ユ簮**锛氫粠鎵规鍙嶆煡閲囪喘鍏ュ簱鍗� + IQC 璐ㄦ缁撹锛堝師鏂欎晶鏂摼鎵撻�氾級
+2. **閿�鍞幓鍚�**锛氫粠鎵规鍙嶆煡閿�鍞嚭搴撳崟 + OQC 璐ㄦ缁撹锛堟垚鍝佷晶鏂摼鎵撻�氾級
+3. **宸ュ簭娴佽浆**锛氫粠鎵规鏌ョ湅浜у嚭/鎶曞叆鐨勫伐搴忕骇浜嬩欢锛堟棤闇�寤鸿〃锛屽姩鎬佽仛鍚堬級
+4. **SN 鍙嶆煡**锛氳緭鍏� SN 搴忓垪鍙风洿鎺ュ畾浣嶆壒娆″苟璺宠浆璇︽儏
+
+鍚庣 4 涓柊鎺ュ彛鍧囧凡瀹屾垚骞剁紪璇戦�氳繃锛屾湰鏂囨。鎸囧鍓嶇瀵规帴銆�
+
+---
+
+## 涓�銆佹秹鍙婇〉闈�
+
+| 椤甸潰 | 璺緞 | 鏀瑰姩璇存槑 |
+|------|------|----------|
+| 鎵规杩芥函椤� | `src/views/mes/qc/batchtrace/index.vue` | 椤堕儴鏂板 SN 鍙嶆煡杈撳叆妗� |
+| 杩芥函璇︽儏寮圭獥 | `src/views/mes/qc/batchtrace/modules/trace-detail.vue` | 瀛愰〉绛炬墿灞曚负 5 涓紙鐢熶骇/閲囪喘鏉ユ簮/閿�鍞幓鍚�/宸ュ簭娴佽浆/璐ㄦ锛� |
+| 閲囪喘鏉ユ簮瀛愬垪琛� | `src/views/mes/qc/batchtrace/modules/purchase-source-list.vue` | 鏂板瀛愮粍浠� |
+| 閿�鍞幓鍚戝瓙鍒楄〃 | `src/views/mes/qc/batchtrace/modules/sales-target-list.vue` | 鏂板瀛愮粍浠� |
+| 宸ュ簭娴佽浆瀛愬垪琛� | `src/views/mes/qc/batchtrace/modules/process-trace-list.vue` | 鏂板瀛愮粍浠� |
+| 鎵规 API | `src/api/mes/wm/batch/index.ts` | 鏂板 4 涓帴鍙e嚱鏁� |
+| 鍒楀畾涔� | `src/views/mes/qc/batchtrace/data.ts` | 鏂板 3 缁勫垪閰嶇疆 |
+
+---
+
+## 浜屻�丄PI 鎺ュ彛
+
+### 2.1 鎵规閲囪喘鏉ユ簮
+
+**璇锋眰鏂瑰紡**锛欸ET
+
+**璇锋眰璺緞**锛歚/mes/wm/batch/purchase-sources`
+
+**璇锋眰鍙傛暟**锛�
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| code | String | 鏄� | 鎵规缂栫爜 |
+
+**鍝嶅簲**锛�
+
+```json
+{
+ "code": 0,
+ "data": [
+ {
+ "receiptCode": "IR20250713001",
+ "receiptDate": "2026-08-01 10:00:00",
+ "purchaseOrderCode": "PO20250701001",
+ "vendorId": 20,
+ "vendorCode": "VENDOR001",
+ "vendorName": "渚涘簲鍟咥",
+ "iqcCode": "IQC20250713001",
+ "checkResult": 1,
+ "itemId": 100,
+ "itemCode": "ITEM001",
+ "itemName": "鍘熸枡A",
+ "batchCode": "BT20260731001",
+ "receivedQuantity": 100
+ }
+ ]
+}
+```
+
+**瀛楁璇存槑**锛�
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| receiptCode | String | 閲囪喘鍏ュ簱鍗曞彿 |
+| receiptDate | Date | 鍏ュ簱鏃ユ湡 |
+| purchaseOrderCode | String | 閲囪喘璁㈠崟鍙� |
+| vendorCode / vendorName | String | 渚涘簲鍟嗙紪鐮�/鍚嶇О锛堝悗绔瘜鍖栵級 |
+| iqcCode | String | IQC 璐ㄦ鍗曞彿锛堝彲鑳戒负绌猴級 |
+| checkResult | Integer | IQC 璐ㄦ缁撹锛屽瓧鍏� `mes_qc_check_result` |
+| itemCode / itemName | String | 鐗╂枡缂栫爜/鍚嶇О锛堝悗绔瘜鍖栵級 |
+| batchCode | String | 鎵规缂栫爜 |
+| receivedQuantity | BigDecimal | 鍏ュ簱鏁伴噺 |
+
+### 2.2 鎵规閿�鍞幓鍚�
+
+**璇锋眰鏂瑰紡**锛欸ET
+
+**璇锋眰璺緞**锛歚/mes/wm/batch/sales-targets`
+
+**璇锋眰鍙傛暟**锛�
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| code | String | 鏄� | 鎵规缂栫爜 |
+
+**鍝嶅簲**锛�
+
+```json
+{
+ "code": 0,
+ "data": [
+ {
+ "salesCode": "SS20250713001",
+ "salesDate": "2026-08-05 14:00:00",
+ "salesOrderCode": "SO20250701001",
+ "clientId": 30,
+ "clientName": "瀹㈡埛A",
+ "oqcCode": "OQC20250713001",
+ "checkResult": 1,
+ "itemId": 100,
+ "itemCode": "ITEM001",
+ "itemName": "鎴愬搧A",
+ "batchCode": "BT20260804001",
+ "quantity": 50,
+ "qualityStatus": 1
+ }
+ ]
+}
+```
+
+**瀛楁璇存槑**锛�
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| salesCode | String | 閿�鍞嚭搴撳崟鍙� |
+| salesDate | Date | 鍑哄簱鏃ユ湡 |
+| salesOrderCode | String | 閿�鍞鍗曞彿 |
+| clientName | String | 瀹㈡埛鍚嶇О锛堝悗绔瘜鍖栵紝娉ㄦ剰锛氬鎴锋棤缂栫爜瀛楁锛� |
+| oqcCode | String | OQC 璐ㄦ鍗曞彿锛堝彲鑳戒负绌猴級 |
+| checkResult | Integer | OQC 璐ㄦ缁撹锛屽瓧鍏� `mes_qc_check_result` |
+| itemCode / itemName | String | 鐗╂枡缂栫爜/鍚嶇О锛堝悗绔瘜鍖栵級 |
+| batchCode | String | 鎵规缂栫爜 |
+| quantity | BigDecimal | 鍑哄簱鏁伴噺 |
+| qualityStatus | Integer | 璐ㄩ噺鐘舵�侊紝瀛楀吀 `mes_wm_quality_status` |
+
+### 2.3 鎵规宸ュ簭娴佽浆
+
+**璇锋眰鏂瑰紡**锛欸ET
+
+**璇锋眰璺緞**锛歚/mes/wm/batch/process-trace`
+
+**璇锋眰鍙傛暟**锛�
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| code | String | 鏄� | 鎵规缂栫爜 |
+
+**鍝嶅簲**锛�
+
+```json
+{
+ "code": 0,
+ "data": [
+ {
+ "eventType": "IN",
+ "workOrderId": 50,
+ "workOrderCode": "WO20260730001",
+ "processId": 10,
+ "processCode": "P001",
+ "processName": "涓嬫枡",
+ "batchCode": "BT20260804001",
+ "quantity": 100,
+ "qualityStatus": null,
+ "eventTime": "2026-08-04 09:00:00",
+ "processSort": 1
+ },
+ {
+ "eventType": "OUT",
+ "workOrderId": 50,
+ "workOrderCode": "WO20260730001",
+ "processId": 10,
+ "processCode": "P001",
+ "processName": "涓嬫枡",
+ "batchCode": "BT20260804001",
+ "quantity": 90,
+ "qualityStatus": 1,
+ "eventTime": "2026-08-04 10:00:00",
+ "processSort": 1
+ }
+ ]
+}
+```
+
+**瀛楁璇存槑**锛�
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| eventType | String | 浜嬩欢绫诲瀷锛歚OUT` = 浜у嚭銆乣IN` = 鎶曞叆 |
+| workOrderCode | String | 宸ュ崟鍙凤紙鍚庣瀵屽寲锛� |
+| processCode / processName | String | 宸ュ簭缂栫爜/鍚嶇О锛堝悗绔瘜鍖栵級 |
+| batchCode | String | 鎵规缂栫爜 |
+| quantity | BigDecimal | 鏁伴噺锛圤UT=浜у嚭鏁伴噺锛孖N=鎶曞叆鏁伴噺锛� |
+| qualityStatus | Integer | 璐ㄩ噺鐘舵�侊紙浠� OUT 渚ф湁鍊硷紝IN 渚т负 null锛� |
+| eventTime | Date | 浜嬩欢鏃堕棿锛圤UT=浜у嚭鏃ユ湡锛孖N=娑堣�楁棩鏈燂級 |
+| processSort | Integer | 宸ュ簭搴忓彿锛堢敤浜庡睍绀哄伐搴忓厛鍚庯級 |
+
+**鎺掑簭瑙勫垯**锛氬悗绔凡鎸� `workOrderId asc 鈫� processSort asc锛堢┖鍊肩疆鍚庯級鈫� eventTime asc` 鎺掑簭锛屽墠绔洿鎺ユ寜杩斿洖椤哄簭灞曠ず鍗冲彲銆�
+
+### 2.4 SN 鍙嶆煡鎵规
+
+**璇锋眰鏂瑰紡**锛欸ET
+
+**璇锋眰璺緞**锛歚/mes/wm/batch/get-by-sn`
+
+**璇锋眰鍙傛暟**锛�
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| sn | String | 鏄� | SN 搴忓垪鍙� |
+
+**鍝嶅簲**锛氫笌 `GET /mes/wm/batch/get` 瀹屽叏涓�鑷达紙`MesWmBatchRespVO`锛夛紝鏈懡涓繑鍥� `data: null`锛�
+
+```json
+{
+ "code": 0,
+ "data": {
+ "id": 1,
+ "code": "BT20260804001",
+ "itemId": 100,
+ "itemCode": "ITEM001",
+ "itemName": "鎴愬搧A",
+ "vendorCode": "VENDOR001",
+ "vendorName": "渚涘簲鍟咥",
+ "clientName": "瀹㈡埛A",
+ "workOrderCode": "WO20260730001",
+ "taskCode": "TASK001",
+ "workstationCode": "WS001",
+ "toolCode": "TOOL001",
+ "lotNumber": "LOT20260801"
+ }
+}
+```
+
+**璇存槑**锛歋N 鍦� `mes_wm_sn` 琛ㄩ�氳繃 `code` 鍞竴鍖归厤锛屽懡涓悗鍙栧叾 `batch_code` 鍙嶆煡鎵规銆傚墠绔牴鎹� `data` 鏄惁涓虹┖鍒ゆ柇鏄惁鎻愮ず"鏈壘鍒板搴旀壒娆�"銆�
+
+---
+
+## 涓夈�佸瓧娈靛睍绀鸿鍒�
+
+| 鍔熻兘 | 灞曠ず浣嶇疆 | 瀛楁璇存槑 |
+|------|----------|----------|
+| 閲囪喘鏉ユ簮 | 璇︽儏寮圭獥瀛愰〉绛�"閲囪喘鏉ユ簮" | 鍏ュ簱鍗曞彿銆佸叆搴撴棩鏈熴�侀噰璐鍗曘�佷緵搴斿晢銆両QC鍗曞彿銆両QC缁撹銆佺墿鏂欍�佹暟閲� |
+| 閿�鍞幓鍚� | 璇︽儏寮圭獥瀛愰〉绛�"閿�鍞幓鍚�" | 鍑哄簱鍗曞彿銆佸嚭搴撴棩鏈熴�侀攢鍞鍗曘�佸鎴枫�丱QC鍗曞彿銆丱QC缁撹銆佺墿鏂欍�佹暟閲忋�佽川閲忕姸鎬� |
+| 宸ュ簭娴佽浆 | 璇︽儏寮圭獥瀛愰〉绛�"宸ュ簭娴佽浆" | 浜嬩欢绫诲瀷銆佸伐鍗曞彿銆佸伐搴忕紪鐮�/鍚嶇О銆佹暟閲忋�佹椂闂淬�佽川閲忕姸鎬� |
+| SN 鍙嶆煡 | 杩芥函椤甸《閮ㄨ緭鍏ユ | 杈撳叆 SN 鈫� 鍛戒腑鐩存帴鎵撳紑鎵规璇︽儏寮圭獥 |
+
+**瀛楀吀璇存槑**锛�
+
+| 瀛楀吀 | 鍙栧�� |
+|------|------|
+| `mes_qc_check_result` | 1=鍚堟牸銆�2=鐗归噰銆�3=閫�璐с��4=鎶ュ簾 |
+| `mes_wm_quality_status` | 0=寰呮銆�1=鍚堟牸銆�2=涓嶅悎鏍� |
+
+---
+
+## 鍥涖�佹暟鎹甫鍏ヨ鏄�
+
+| 鍦烘櫙 | 甯﹀叆璇存槑 |
+|------|----------|
+| 杩芥函椤� 鈫� 閲囪喘鏉ユ簮 | 鐐瑰嚮鎵规琛岋紝鎼哄甫璇ヨ鐨� `code` 璋冪敤 `getPurchaseSourceList(code)` |
+| 杩芥函椤� 鈫� 閿�鍞幓鍚� | 鐐瑰嚮鎵规琛岋紝鎼哄甫璇ヨ鐨� `code` 璋冪敤 `getSalesTargetList(code)` |
+| 杩芥函椤� 鈫� 宸ュ簭娴佽浆 | 鐐瑰嚮鎵规琛岋紝鎼哄甫璇ヨ鐨� `code` 璋冪敤 `getProcessTraceList(code)` |
+| SN 杈撳叆妗� 鈫� 璇︽儏 | 杈撳叆 SN 璋冪敤 `getBatchBySn(sn)`锛岃繑鍥炵殑 `code` 浣滀负璇︽儏寮圭獥鏌ヨ渚濇嵁锛堟垨鐩存帴浣跨敤杩斿洖鏁版嵁锛� |
+
+---
+
+## 浜斻�佹帴鍙h皟鐢ㄦ椂搴�
+
+1. 杩芥函椤靛姞杞芥壒娆″垪琛紙`/mes/wm/batch/page`锛�
+2. 鐐瑰嚮鏌愭壒娆¤ 鈫� 鎵撳紑璇︽儏寮圭獥锛屽脊绐楀唴榛樿灞曠ず"鐢熶骇"椤电锛堝悜鍓�/鍚戝悗杩芥函锛�
+3. 鍒囨崲"閲囪喘鏉ユ簮/閿�鍞幓鍚�/宸ュ簭娴佽浆"椤电鏃讹紝鎸夐渶璋冪敤瀵瑰簲鎺ュ彛锛堝缓璁噿鍔犺浇锛氶娆″垏鎹㈡墠璇锋眰锛�
+4. 椤堕儴 SN 杈撳叆妗� 鈫� 鎸夊洖杞︽垨鐐瑰嚮鎼滅储 鈫� `getBatchBySn` 鈫� 鍛戒腑鎵撳紑璇︽儏寮圭獥锛屾湭鍛戒腑鎻愮ず鏃犺褰�
+
+---
+
+## 鍏�佷笟鍔¤鍒欒鏄�
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 鍘熸枡鎵规 | 鏈夐噰璐潵婧愶紙鍏ュ簱+IQC锛夛紝鏃犻攢鍞幓鍚戯紱宸ュ簭娴佽浆浠� IN 鎶曞叆涓轰富 |
+| 鎴愬搧鎵规 | 鏈夐攢鍞幓鍚戯紙鍑哄簱+OQC锛夛紝鏃犻噰璐潵婧愶紱宸ュ簭娴佽浆浠� OUT 浜у嚭涓轰富 |
+| 涓棿鎵规 | 鍚屾椂瀛樺湪 IN 涓� OUT 浜嬩欢锛屼綋鐜板伐搴忕骇娴佽浆 |
+| 璐ㄦ鍗曠己澶� | `iqcCode`/`oqcCode` 鍙兘涓虹┖锛堝崟鎹湭鍏宠仈锛夛紝缁撹鍒楀睍绀�"-" |
+| SN 鏈懡涓� | `get-by-sn` 杩斿洖 `data: null`锛屽墠绔彁绀�"鏈壘鍒拌 SN 瀵瑰簲鐨勬壒娆�" |
+| 鏁版嵁涓虹┖ | 涓変釜瀛愬垪琛ㄦ帴鍙e潎鍙兘杩斿洖绌烘暟缁勶紝椤甸潰灞曠ず绌烘�佹彁绀� |
+
+---
+
+## 涓冦�佹敞鎰忎簨椤�
+
+- 涓変釜鍒楄〃鎺ュ彛涓庢棦鏈� forward/backward 鐩稿悓锛屽潎闇�瑕� `mes:wm-batch:query` 鏉冮檺
+- 瀛愰〉绛惧缓璁噿鍔犺浇 + 缂撳瓨锛岄伩鍏嶆瘡娆″垏鎹㈤噸澶嶈姹�
+- 宸ュ簭娴佽浆鐨� `processSort` 鐢卞悗绔帓濂藉簭锛屽墠绔嬁鍐嶆帓搴�
+- 閿�鍞晶 `qualityStatus` 涓哄瓧鍏稿�硷紝灞曠ず鐢� `mes_wm_quality_status` 瀛楀吀缈昏瘧
+- 娴嬭瘯鐜鍙兘瀛樺湪鏃� `batchCode` 鐨勯攢鍞嚭搴撹鏁版嵁锛屽睘鍘嗗彶鑴忔暟鎹紝鍓嶇瀵圭┖瀛楁鍋氬厹搴曞睍绀哄嵆鍙�
+
+---
+
+## 鍏�佺浉鍏虫帴鍙f眹鎬�
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/wm/batch/purchase-sources | 鎵规閲囪喘鏉ユ簮锛堝叆搴� + IQC锛� |
+| GET | /mes/wm/batch/sales-targets | 鎵规閿�鍞幓鍚戯紙鍑哄簱 + OQC锛� |
+| GET | /mes/wm/batch/process-trace | 鎵规宸ュ簭娴佽浆锛堜骇鍑�/鎶曞叆锛� |
+| GET | /mes/wm/batch/get-by-sn | SN 鍙嶆煡鎵规 |
diff --git a/docs/pd_project_bpm_approval_frontend.md b/docs/pd_project_bpm_approval_frontend.md
new file mode 100644
index 0000000..f9ef944
--- /dev/null
+++ b/docs/pd_project_bpm_approval_frontend.md
@@ -0,0 +1,87 @@
+# MES 浜у搧椤圭洰鎺ュ叆 BPM 瀹℃壒 - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- 鐢熶骇绠℃帶-浜у搧璁捐-浜у搧椤圭洰 鍒楄〃椤碉紙`src/views/mes/pd/project/index.vue`锛�
+- 浜у搧椤圭洰 璇︽儏椤碉紙`src/views/mes/pd/project/detail/index.vue`锛�
+- 浜у搧椤圭洰 娴佺▼杩涘害缁勪欢锛坄src/views/mes/pd/project/modules/workflow-timeline.vue`锛�
+
+## 涓氬姟娴佺▼涓庢暟鎹甫鍏�
+
+1. 寰呭鏍�(2) 鈫� 鍒楄〃/璇︽儏鐐广�屾彁浜ゅ鎵广�嶏細鍏堣皟 `GET /mes/pd/project/approve-process-list` 鑾峰彇鍙敤 BPM 娴佺▼ 鈫� 鎵撳紑娴佺▼閫夋嫨寮圭獥 鈫� 閫変腑娴佺▼鍚庤皟 `PUT /mes/pd/project/submit-approval?id={id}&processDefinitionKey={key}` 鈫� 椤圭洰鐘舵�佸彉涓� **瀹℃壒涓�(5)**
+2. BPM 鍚庡彴瀹℃壒閫氳繃 鈫� 鍚庣鐩戝惉鍣ㄥ洖璋� 鈫� 椤圭洰鐘舵�佸彉涓� **寰呭綊妗�(3)**锛涘鎵归┏鍥�/鍙栨秷 鈫� 鐘舵�佸洖鍒� **寰呭鏍�(2)**锛屽彲閲嶆柊鎻愪氦
+3. 瀹℃壒涓�(5) 鈫� 鍒楄〃/璇︽儏鏄剧ず銆屾煡鐪嬪鎵广�嶆寜閽� 鈫� 璺宠浆 BPM 娴佺▼璇︽儏椤垫煡鐪嬪鎵硅繘搴�
+4. 寰呭綊妗�(3) 鈫� 鐐广�屽綊妗c�嶁啋 `PUT /mes/pd/project/archive?id={id}` 鈫� 鐘舵�佸彉涓� **宸插綊妗�(4)**
+
+## API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/pd/project/approve-process-list | 鑾峰緱鍙敤 BPM 瀹℃壒娴佺▼鍒楄〃 |
+| PUT | /mes/pd/project/submit-approval | 鎻愪氦瀹℃壒锛堝緟瀹℃牳鈫掑鎵逛腑锛� |
+| PUT | /mes/pd/project/archive | 褰掓。锛堝緟褰掓。鈫掑凡褰掓。锛� |
+
+**璇锋眰鍙傛暟锛坰ubmit-approval锛夛細**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 椤圭洰缂栧彿 |
+| processDefinitionKey | String | 鏄� | 閫変腑鐨� BPM 娴佺▼瀹氫箟 Key |
+
+**鍝嶅簲瀛楁鍙樻洿锛�/get銆�/page锛夛細**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| processInstanceId | String | BPM 娴佺▼瀹炰緥缂栧彿锛屽鎵逛腑鍙婁互鍚庢湁鍊� |
+
+**鍝嶅簲绀轰緥锛坅pprove-process-list锛夛細**
+
+```json
+{
+ "code": 0,
+ "data": [
+ { "id": "xxx", "name": "浜у搧椤圭洰瀹℃壒娴佺▼", "key": "mes-pd-project-audit" }
+ ]
+}
+```
+
+## 瀛楁灞曠ず瑙勫垯
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| 鐘舵�� | 鍒楄〃銆佽鎯� | 鏂板瀛楀吀鍊笺�屽鎵逛腑銆�(value=5)锛屽垪琛� `CellDict` 鑷姩娓叉煋 |
+| processInstanceId | 鍒楄〃/璇︽儏銆屾煡鐪嬪鎵广�� | 鏈夊�兼墠鏄剧ず銆屾煡鐪嬪鎵广�嶆寜閽� |
+
+## 椤甸潰鏀瑰姩
+
+### 1. 鍒楄〃椤� index.vue
+
+- 銆屽鏍搞�嶆寜閽敼涓恒�屾彁浜ゅ鎵广�嶏細`ifShow` 浠嶄负 `status === PENDING_AUDIT`锛岀偣鍑诲厛鏌ユ祦绋嬪垪琛紙绌哄垯鎻愮ず銆屾殏鏃犲彲鐢ㄥ鎵规祦绋嬶紝璇峰厛閰嶇疆 BPM 娴佺▼銆嶏級锛屾湁鍒欐墦寮�娴佺▼閫夋嫨寮圭獥
+- 鏂板銆屾煡鐪嬪鎵广�嶆寜閽細`ifShow` 涓� `status === APPROVING` 涓� `processInstanceId` 鏈夊�硷紝鐐瑰嚮璺� BPM 娴佺▼璇︽儏
+- 鏂板娴佺▼閫夋嫨寮圭獥缁勪欢 `process-select-modal.vue`锛圫elect 涓嬫媺閫夋祦绋嬶紝榛樿閫夌涓�涓紝纭鍚庤皟 submit-approval锛�
+
+### 2. 璇︽儏椤� detail/index.vue
+
+- 銆屽鏍搁�氳繃銆嶆寜閽敼涓恒�屾彁浜ゅ鎵广�嶏紝閫昏緫鍚屼笂锛屾垚鍔熷悗鍒锋柊璇︽儏
+- 鏂板銆屾煡鐪嬪鎵广�嶆寜閽細`ifShow` 涓哄鎵逛腑鐘舵�侊紝鐐瑰嚮璺� BPM 娴佺▼璇︽儏
+- 椤堕儴鎸夐挳鍖烘柊澧炲鎵逛腑鍒ゆ柇
+
+### 3. 娴佺▼杩涘害缁勪欢 workflow-timeline.vue
+
+- 姝ラ鐢� 5 姝ユ墿涓� 6 姝ワ細寰呭彂甯� 鈫� 寰呬笂浼� 鈫� 寰呭鏍� 鈫� **瀹℃壒涓�** 鈫� 寰呭綊妗� 鈫� 宸插綊妗�
+- 鐘舵�佸�煎埌姝ラ绱㈠紩鐨勬槧灏勯渶鏄惧紡澶勭悊锛堝鎵逛腑 value=5 鎻掑湪寰呭鏍镐箣鍚庯級
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 鎻愪氦瀹℃壒 | 浠呭緟瀹℃牳(2)鐘舵�佸彲鎻愪氦锛涜嫢椤圭洰涓嬪瓨鍦ㄦ湭瀹℃牳鐨勮璁¤祫鏂欙紝鍚庣杩斿洖閿欒銆岃椤圭洰涓嬪瓨鍦ㄦ湭瀹℃牳鐨勮祫鏂欍�� |
+| 瀹℃壒閫氳繃 | 鐘舵�� 鈫� 寰呭綊妗�(3)锛屽彲鎵ц褰掓。 |
+| 瀹℃壒椹冲洖/鍙栨秷 | 鐘舵�� 鈫� 寰呭鏍�(2)锛屽彲淇敼鍚庨噸鏂版彁浜� |
+| 褰掓。 | 浠呭緟褰掓。(3)鐘舵�佸彲褰掓。锛屽綊妗e悗鐢熸垚鍙拌处璁板綍銆侀」鐩笉鍙啀淇敼 |
+
+## 娉ㄦ剰浜嬮」
+
+- 闇�鍏堝湪 BPM 鍚庡彴鎵嬪伐閮ㄧ讲瀹℃壒娴佺▼锛堟祦绋� key=`mes-pd-project-audit`锛屽垎绫�=`mes_pd_project_approve`锛夛紝鍚﹀垯銆屾彁浜ゅ鎵广�嶆彁绀烘殏鏃犲彲鐢ㄦ祦绋�
+- 鏈彁浜ゅ鎵癸紙processInstanceId 涓虹┖锛夋椂鐐广�屾煡鐪嬪鎵广�嶅簲鎻愮ず銆岃椤圭洰灏氭湭鎻愪氦瀹℃壒銆�
+- 鍘嗗彶鏁版嵁 status 0-4 涓嶅彈褰卞搷锛涙椂闂寸嚎缁勪欢闇�鍏煎鐘舵�佸�煎埌姝ラ鐨勯潪杩炵画鏄犲皠
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/MesPdProjectController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/MesPdProjectController.java
index 88b79d1..45c7cb9 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/MesPdProjectController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/MesPdProjectController.java
@@ -124,15 +124,24 @@
return success(true);
}
- @PutMapping("/audit")
- @Operation(summary = "瀹℃牳璁捐椤圭洰锛堝緟瀹℃牳鈫掑緟褰掓。锛�")
+ @PutMapping("/submit-approval")
+ @Operation(summary = "鎻愪氦璁捐椤圭洰瀹℃壒锛堝緟瀹℃牳鈫掑鎵逛腑锛�")
@Parameter(name = "id", description = "缂栧彿", required = true)
+ @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟 Key", required = true)
@PreAuthorize("@ss.hasPermission('mes:pd-project:update')")
- public CommonResult<Boolean> auditProject(@RequestParam("id") Long id) {
- projectService.auditProject(id);
+ public CommonResult<Boolean> submitProjectApproval(@RequestParam("id") Long id,
+ @RequestParam("processDefinitionKey") String processDefinitionKey) {
+ projectService.submitProjectApproval(id, processDefinitionKey);
return success(true);
}
+ @GetMapping("/approve-process-list")
+ @Operation(summary = "鑾峰緱璁捐椤圭洰瀹℃壒娴佺▼鍒楄〃")
+ @PreAuthorize("@ss.hasPermission('mes:pd-project:update')")
+ public CommonResult<List<Map<String, Object>>> getProjectApproveProcessDefinitionList() {
+ return success(projectService.getProjectApproveProcessDefinitionList());
+ }
+
@PutMapping("/archive")
@Operation(summary = "褰掓。璁捐椤圭洰锛堝緟褰掓。鈫掑凡褰掓。锛夛紝鍚屾椂鑷姩鍒涘缓褰掓。鍙拌处")
@Parameter(name = "id", description = "缂栧彿", required = true)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectRespVO.java
index d0ea908..28a581f 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pd/project/vo/MesPdProjectRespVO.java
@@ -66,6 +66,9 @@
@ExcelProperty("澶囨敞")
private String remark;
+ @Schema(description = "BPM 娴佺▼瀹炰緥缂栧彿")
+ private String processInstanceId;
+
@Schema(description = "鍒涘缓鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("鍒涘缓鏃堕棿")
private LocalDateTime createTime;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/MesWmBatchController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/MesWmBatchController.java
index 5a9257e..6fff993 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/MesWmBatchController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/MesWmBatchController.java
@@ -6,7 +6,10 @@
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchPageReqVO;
+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.MesWmBatchRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchSalesTargetRespVO;
import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi;
@@ -15,6 +18,7 @@
import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.tm.tool.MesTmToolDO;
@@ -23,6 +27,7 @@
import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
+import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService;
import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import cn.iocoder.yudao.module.mes.service.tm.tool.MesTmToolService;
@@ -71,6 +76,8 @@
private MesMdWorkstationService workstationService;
@Resource
private MesTmToolService toolService;
+ @Resource
+ private MesProProcessService processService;
@GetMapping("/get")
@Operation(summary = "鑾峰緱鎵规璇︽儏")
@@ -105,6 +112,42 @@
public CommonResult<List<MesWmBatchRespVO>> getBackwardList(@RequestParam("code") @Valid String code) {
List<MesWmBatchDO> list = batchService.getBackwardBatchList(code);
return success(buildBatchRespVOList(list));
+ }
+
+ @GetMapping("/purchase-sources")
+ @Operation(summary = "鎵规閲囪喘鏉ユ簮锛堥噰璐叆搴撳崟 + IQC锛�")
+ @Parameter(name = "code", description = "鎵规缂栫爜", required = true, example = "BATCH20250314001")
+ @PreAuthorize("@ss.hasPermission('mes:wm-batch:query')")
+ public CommonResult<List<MesWmBatchPurchaseSourceRespVO>> getPurchaseSourceList(@RequestParam("code") @Valid String code) {
+ List<MesWmBatchPurchaseSourceRespVO> list = batchService.getPurchaseSourceList(code);
+ return success(buildPurchaseSourceRespVOList(list));
+ }
+
+ @GetMapping("/sales-targets")
+ @Operation(summary = "鎵规閿�鍞幓鍚戯紙閿�鍞嚭搴撳崟 + OQC锛�")
+ @Parameter(name = "code", description = "鎵规缂栫爜", required = true, example = "BATCH20250314001")
+ @PreAuthorize("@ss.hasPermission('mes:wm-batch:query')")
+ public CommonResult<List<MesWmBatchSalesTargetRespVO>> getSalesTargetList(@RequestParam("code") @Valid String code) {
+ List<MesWmBatchSalesTargetRespVO> list = batchService.getSalesTargetList(code);
+ return success(buildSalesTargetRespVOList(list));
+ }
+
+ @GetMapping("/process-trace")
+ @Operation(summary = "鎵规宸ュ簭娴佽浆锛堜骇鍑�/鎶曞叆浜嬩欢锛�")
+ @Parameter(name = "code", description = "鎵规缂栫爜", required = true, example = "BATCH20250314001")
+ @PreAuthorize("@ss.hasPermission('mes:wm-batch:query')")
+ public CommonResult<List<MesWmBatchProcessTraceRespVO>> getProcessTraceList(@RequestParam("code") @Valid String code) {
+ List<MesWmBatchProcessTraceRespVO> list = batchService.getProcessTraceList(code);
+ return success(buildProcessTraceRespVOList(list));
+ }
+
+ @GetMapping("/get-by-sn")
+ @Operation(summary = "鏍规嵁 SN 鐮佸弽鏌ユ壒娆�")
+ @Parameter(name = "sn", description = "SN 搴忓垪鍙�", required = true, example = "SN20250314001")
+ @PreAuthorize("@ss.hasPermission('mes:wm-batch:query')")
+ public CommonResult<MesWmBatchRespVO> getBatchBySn(@RequestParam("sn") @Valid String sn) {
+ MesWmBatchDO batch = batchService.getBatchBySn(sn);
+ return success(buildBatchRespVO(batch));
}
// ==================== 鎷兼帴 VO ====================
@@ -162,4 +205,58 @@
return buildBatchRespVOList(Collections.singletonList(batch)).get(0);
}
+ private List<MesWmBatchPurchaseSourceRespVO> buildPurchaseSourceRespVOList(List<MesWmBatchPurchaseSourceRespVO> list) {
+ if (CollUtil.isEmpty(list)) {
+ return Collections.emptyList();
+ }
+ Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
+ convertSet(list, MesWmBatchPurchaseSourceRespVO::getItemId));
+ Map<Long, SrmSupplierRespDTO> vendorMap = srmSupplierApi.getSupplierList(
+ convertSet(list, MesWmBatchPurchaseSourceRespVO::getVendorId)).getCheckedData().stream()
+ .collect(Collectors.toMap(SrmSupplierRespDTO::getId, s -> s));
+ list.forEach(vo -> {
+ MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
+ vo.setItemCode(item.getCode()).setItemName(item.getName());
+ });
+ MapUtils.findAndThen(vendorMap, vo.getVendorId(),
+ vendor -> vo.setVendorCode(vendor.getCode()).setVendorName(vendor.getName()));
+ });
+ return list;
+ }
+
+ private List<MesWmBatchSalesTargetRespVO> buildSalesTargetRespVOList(List<MesWmBatchSalesTargetRespVO> list) {
+ if (CollUtil.isEmpty(list)) {
+ return Collections.emptyList();
+ }
+ Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
+ convertSet(list, MesWmBatchSalesTargetRespVO::getItemId));
+ Map<Long, CrmCustomerRespDTO> clientMap = customerApi.getCustomerMap(
+ convertSet(list, MesWmBatchSalesTargetRespVO::getClientId));
+ list.forEach(vo -> {
+ MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
+ vo.setItemCode(item.getCode()).setItemName(item.getName());
+ });
+ MapUtils.findAndThen(clientMap, vo.getClientId(),
+ client -> vo.setClientName(client.getName()));
+ });
+ return list;
+ }
+
+ private List<MesWmBatchProcessTraceRespVO> buildProcessTraceRespVOList(List<MesWmBatchProcessTraceRespVO> list) {
+ if (CollUtil.isEmpty(list)) {
+ return Collections.emptyList();
+ }
+ Map<Long, MesProWorkOrderDO> workOrderMap = workOrderService.getWorkOrderMap(
+ convertSet(list, MesWmBatchProcessTraceRespVO::getWorkOrderId));
+ Map<Long, MesProProcessDO> processMap = processService.getProcessMap(
+ convertSet(list, MesWmBatchProcessTraceRespVO::getProcessId));
+ list.forEach(vo -> {
+ MapUtils.findAndThen(workOrderMap, vo.getWorkOrderId(),
+ workOrder -> vo.setWorkOrderCode(workOrder.getCode()));
+ MapUtils.findAndThen(processMap, vo.getProcessId(),
+ process -> vo.setProcessCode(process.getCode()).setProcessName(process.getName()));
+ });
+ return list;
+ }
+
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchProcessTraceRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchProcessTraceRespVO.java
new file mode 100644
index 0000000..ce165eb
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchProcessTraceRespVO.java
@@ -0,0 +1,46 @@
+package cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Schema(description = "绠$悊鍚庡彴 - MES 鎵规宸ュ簭娴佽浆 Response VO")
+@Data
+public class MesWmBatchProcessTraceRespVO {
+
+ @Schema(description = "浜嬩欢绫诲瀷锛欼N-宸ュ簭鎶曞叆 / OUT-宸ュ簭浜у嚭", example = "OUT")
+ private String eventType;
+
+ @Schema(description = "鐢熶骇宸ュ崟 ID", example = "1")
+ private Long workOrderId;
+
+ @Schema(description = "鐢熶骇宸ュ崟缂栧彿", example = "WO20250801001")
+ private String workOrderCode;
+
+ @Schema(description = "宸ュ簭 ID", example = "1")
+ private Long processId;
+
+ @Schema(description = "宸ュ簭缂栫爜", example = "PROC001")
+ private String processCode;
+
+ @Schema(description = "宸ュ簭鍚嶇О", example = "CNC 鍔犲伐")
+ private String processName;
+
+ @Schema(description = "鎵规鍙�", example = "BATCH20250801001")
+ private String batchCode;
+
+ @Schema(description = "鏁伴噺", example = "100")
+ private BigDecimal quantity;
+
+ @Schema(description = "璐ㄩ噺鐘舵�侊紙瀛楀吀 mes_wm_quality_status锛夛紝浠呬骇鍑轰晶鏈夊��", example = "1")
+ private Integer qualityStatus;
+
+ @Schema(description = "浜嬩欢鏃堕棿")
+ private LocalDateTime eventTime;
+
+ @Schema(description = "宸ュ簭搴忓彿锛堟帓搴忕敤锛�", example = "1")
+ private Integer processSort;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchPurchaseSourceRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchPurchaseSourceRespVO.java
new file mode 100644
index 0000000..ddbd9e9
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchPurchaseSourceRespVO.java
@@ -0,0 +1,52 @@
+package cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Schema(description = "绠$悊鍚庡彴 - MES 鎵规閲囪喘鏉ユ簮 Response VO")
+@Data
+public class MesWmBatchPurchaseSourceRespVO {
+
+ @Schema(description = "閲囪喘鍏ュ簱鍗曞彿", example = "IR20250731001")
+ private String receiptCode;
+
+ @Schema(description = "鍏ュ簱鏃ユ湡")
+ private LocalDateTime receiptDate;
+
+ @Schema(description = "閲囪喘璁㈠崟缂栧彿", example = "PO20250731001")
+ private String purchaseOrderCode;
+
+ @Schema(description = "渚涘簲鍟� ID", example = "1")
+ private Long vendorId;
+
+ @Schema(description = "渚涘簲鍟嗙紪鐮�", example = "V001")
+ private String vendorCode;
+
+ @Schema(description = "渚涘簲鍟嗗悕绉�", example = "渚涘簲鍟咥")
+ private String vendorName;
+
+ @Schema(description = "鏉ユ枡妫�楠屽崟鍙凤紙IQC锛�", example = "IQC20250731001")
+ private String iqcCode;
+
+ @Schema(description = "IQC 妫�楠岀粨璁猴紙瀛楀吀 mes_qc_check_result锛�", example = "1")
+ private Integer checkResult;
+
+ @Schema(description = "鐗╂枡 ID", example = "1")
+ private Long itemId;
+
+ @Schema(description = "鐗╂枡缂栫爜", example = "ITEM001")
+ private String itemCode;
+
+ @Schema(description = "鐗╂枡鍚嶇О", example = "浜у搧A")
+ private String itemName;
+
+ @Schema(description = "鎵规鍙�", example = "BATCH20250731001")
+ private String batchCode;
+
+ @Schema(description = "鍏ュ簱鏁伴噺", example = "100")
+ private BigDecimal receivedQuantity;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchSalesTargetRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchSalesTargetRespVO.java
new file mode 100644
index 0000000..5da84ae
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchSalesTargetRespVO.java
@@ -0,0 +1,55 @@
+package cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+@Schema(description = "绠$悊鍚庡彴 - MES 鎵规閿�鍞幓鍚� Response VO")
+@Data
+public class MesWmBatchSalesTargetRespVO {
+
+ @Schema(description = "閿�鍞嚭搴撳崟鍙�", example = "SO20250801001")
+ private String salesCode;
+
+ @Schema(description = "鍑哄簱鏃ユ湡")
+ private LocalDateTime salesDate;
+
+ @Schema(description = "閿�鍞鍗曠紪鍙�", example = "SO20250801001")
+ private String salesOrderCode;
+
+ @Schema(description = "瀹㈡埛 ID", example = "1")
+ private Long clientId;
+
+ @Schema(description = "瀹㈡埛缂栫爜", example = "C001")
+ private String clientCode;
+
+ @Schema(description = "瀹㈡埛鍚嶇О", example = "瀹㈡埛A")
+ private String clientName;
+
+ @Schema(description = "鍑哄巶妫�楠屽崟鍙凤紙OQC锛�", example = "OQC20250801001")
+ private String oqcCode;
+
+ @Schema(description = "OQC 妫�楠岀粨璁猴紙瀛楀吀 mes_qc_check_result锛�", example = "1")
+ private Integer checkResult;
+
+ @Schema(description = "鐗╂枡 ID", example = "1")
+ private Long itemId;
+
+ @Schema(description = "鐗╂枡缂栫爜", example = "ITEM001")
+ private String itemCode;
+
+ @Schema(description = "鐗╂枡鍚嶇О", example = "浜у搧A")
+ private String itemName;
+
+ @Schema(description = "鎵规鍙�", example = "BATCH20250801001")
+ private String batchCode;
+
+ @Schema(description = "鍑哄簱鏁伴噺", example = "100")
+ private BigDecimal quantity;
+
+ @Schema(description = "璐ㄩ噺鐘舵�侊紙瀛楀吀 mes_wm_quality_status锛�", example = "1")
+ private Integer qualityStatus;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/project/MesPdProjectDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/project/MesPdProjectDO.java
index c6f449e..bbfd926 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/project/MesPdProjectDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pd/project/MesPdProjectDO.java
@@ -58,6 +58,14 @@
*/
private Integer status;
/**
+ * BPM 娴佺▼瀹炰緥缂栧彿
+ */
+ private String processInstanceId;
+ /**
+ * BPM 娴佺▼瀹氫箟 Key
+ */
+ private String processDefinitionKey;
+ /**
* 涓昏璁″笀
*
* 鍏宠仈 AdminUserDO#getId()
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/batch/MesWmBatchMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/batch/MesWmBatchMapper.java
index 8294d56..084e2ad 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/batch/MesWmBatchMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/batch/MesWmBatchMapper.java
@@ -7,6 +7,9 @@
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchPageReqVO;
+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.dal.dataobject.wm.batch.MesWmBatchDO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.ibatis.annotations.Mapper;
@@ -185,4 +188,28 @@
*/
List<MesWmBatchDO> selectListByBackward(String batchCode);
+ /**
+ * 鏌ヨ鎵规閲囪喘鏉ユ簮锛堥噰璐叆搴撳崟 + IQC锛�
+ *
+ * @param batchCode 鎵规鍙�
+ * @return 閲囪喘鏉ユ簮鍒楄〃
+ */
+ List<MesWmBatchPurchaseSourceRespVO> selectPurchaseSourceList(String batchCode);
+
+ /**
+ * 鏌ヨ鎵规閿�鍞幓鍚戯紙閿�鍞嚭搴撳崟 + OQC锛�
+ *
+ * @param batchCode 鎵规鍙�
+ * @return 閿�鍞幓鍚戝垪琛�
+ */
+ List<MesWmBatchSalesTargetRespVO> selectSalesTargetList(String batchCode);
+
+ /**
+ * 鏌ヨ鎵规宸ュ簭娴佽浆锛堜骇鍑�/鎶曞叆浜嬩欢锛�
+ *
+ * @param batchCode 鎵规鍙�
+ * @return 宸ュ簭娴佽浆鍒楄〃
+ */
+ List<MesWmBatchProcessTraceRespVO> selectProcessTraceList(String batchCode);
+
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
index ca229f4..a5459f0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -773,6 +773,9 @@
ErrorCode PD_PROJECT_NOT_UPLOAD_FOR_AUDIT = new ErrorCode(1_040_800_005, "鍙湁寰呭鏍哥姸鎬佺殑璁捐椤圭洰鎵嶈兘瀹℃牳");
ErrorCode PD_PROJECT_NOT_AUDIT_FOR_ARCHIVE = new ErrorCode(1_040_800_006, "鍙湁寰呭綊妗g姸鎬佺殑璁捐椤圭洰鎵嶈兘褰掓。");
ErrorCode PD_PROJECT_AUDIT_NOT_FINISHED = new ErrorCode(1_040_800_007, "璇ラ」鐩笅瀛樺湪鏈鏍哥殑璧勬枡锛岃鍏堝畬鎴愭墍鏈夎祫鏂欏鏍�");
+ ErrorCode PD_PROJECT_NOT_UPLOAD_FOR_APPROVAL = new ErrorCode(1_040_800_008, "鍙湁寰呭鏍哥姸鎬佺殑璁捐椤圭洰鎵嶈兘鎻愪氦瀹℃壒");
+ ErrorCode PD_PROJECT_NOT_APPROVING = new ErrorCode(1_040_800_009, "璁捐椤圭洰涓嶅浜庡鎵逛腑鐘舵��");
+ ErrorCode PD_PROJECT_BPM_CATEGORY_NOT_EXISTS = new ErrorCode(1_040_800_010, "璁捐椤圭洰瀹℃壒鍒嗙被涓嶅瓨鍦紝璇峰厛閰嶇疆 BPM 瀹℃壒娴佺▼");
// ========== MES 浜у搧璁捐-璧勬枡瀛愯〃锛�1-040-801-000锛� ==========
ErrorCode PD_DOCUMENT_NOT_EXISTS = new ErrorCode(1_040_801_000, "璁捐璧勬枡涓嶅瓨鍦�");
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/MesPdStatusConstants.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/MesPdStatusConstants.java
index 1771e05..5b763af 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/MesPdStatusConstants.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/MesPdStatusConstants.java
@@ -32,5 +32,9 @@
* 宸插綊妗�
*/
public static final int ARCHIVE = 4;
+ /**
+ * 瀹℃壒涓紙BPM 瀹℃壒杩涜涓級
+ */
+ public static final int APPROVING = 5;
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdProjectStatusEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdProjectStatusEnum.java
index 94fd5e8..8aa13ec 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdProjectStatusEnum.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/pd/MesPdProjectStatusEnum.java
@@ -39,7 +39,7 @@
/**
* 寰呭綊妗�
*
- * 瀵瑰簲 MesPdProjectService#auditProject 鏂规硶
+ * 瀵瑰簲 MesPdProjectService#updateProjectAuditStatus 鏂规硶锛圔PM 瀹℃壒閫氳繃鍚庯級
*/
AUDIT(MesPdStatusConstants.AUDIT, "寰呭綊妗�"),
/**
@@ -47,7 +47,13 @@
*
* 瀵瑰簲 MesPdProjectService#archiveProject 鏂规硶
*/
- ARCHIVE(MesPdStatusConstants.ARCHIVE, "宸插綊妗�");
+ ARCHIVE(MesPdStatusConstants.ARCHIVE, "宸插綊妗�"),
+ /**
+ * 瀹℃壒涓�
+ *
+ * 瀵瑰簲 MesPdProjectService#submitProjectApproval 鏂规硶
+ */
+ APPROVING(MesPdStatusConstants.APPROVING, "瀹℃壒涓�");
public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesPdProjectStatusEnum::getStatus).toArray(Integer[]::new);
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectService.java
index 2e1bb45..54deaeb 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectService.java
@@ -81,11 +81,29 @@
void uploadProject(Long id, Long userId);
/**
- * 瀹℃牳璁捐椤圭洰锛堝緟瀹℃牳鈫掑緟褰掓。锛�
+ * 鎻愪氦璁捐椤圭洰瀹℃壒锛堝緟瀹℃牳鈫掑鎵逛腑锛�
+ * <p>
+ * 鍒涘缓 BPM 娴佺▼瀹炰緥锛屽鎵归�氳繃鍚庣敱鐩戝惉鍣ㄥ洖璋冩洿鏂颁负寰呭綊妗�
*
- * @param id 缂栧彿
+ * @param id 缂栧彿
+ * @param processDefinitionKey 娴佺▼瀹氫箟 Key
*/
- void auditProject(Long id);
+ void submitProjectApproval(Long id, String processDefinitionKey);
+
+ /**
+ * 鑾峰緱璁捐椤圭洰瀹℃壒娴佺▼鍒楄〃
+ *
+ * @return 娴佺▼鍒楄〃锛坕d/name/version/key锛�
+ */
+ List<Map<String, Object>> getProjectApproveProcessDefinitionList();
+
+ /**
+ * 鏇存柊璁捐椤圭洰瀹℃壒鐘舵�侊紙BPM 鐩戝惉鍣ㄥ洖璋冿級
+ *
+ * @param id 缂栧彿
+ * @param bpmResult BPM 瀹℃壒缁撴灉
+ */
+ void updateProjectAuditStatus(Long id, Integer bpmResult);
/**
* 褰掓。璁捐椤圭洰锛堝緟褰掓。鈫掑凡褰掓。锛�
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectServiceImpl.java
index 12a637d..6648c60 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/MesPdProjectServiceImpl.java
@@ -1,6 +1,14 @@
package cn.iocoder.yudao.module.mes.service.pd.project;
+import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
+import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
+import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
+import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pd.document.MesPdDocumentDO;
@@ -16,18 +24,24 @@
import cn.iocoder.yudao.module.mes.service.pd.document.MesPdDocumentService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.time.LocalDateTime;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
/**
@@ -37,7 +51,13 @@
*/
@Service
@Validated
+@Slf4j
public class MesPdProjectServiceImpl implements MesPdProjectService {
+
+ /**
+ * BPM 浜у搧椤圭洰瀹℃壒鍒嗙被缂栫爜
+ */
+ private static final String BPM_PROCESS_DEFINITION_CATEGORY_CODE = "mes_pd_project_approve";
@Resource
private MesPdProjectMapper projectMapper;
@@ -55,6 +75,15 @@
@Resource
@Lazy
private MesMdAutoCodeRecordService autoCodeRecordService;
+
+ @Resource
+ private BpmProcessInstanceApi processInstanceApi;
+
+ @Resource
+ private BpmCategoryService bpmCategoryService;
+
+ @Resource
+ private BpmProcessDefinitionService bpmProcessDefinitionService;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -180,27 +209,105 @@
}
@Override
- public void auditProject(Long id) {
- // 鏍¢獙瀛樺湪
+ @Transactional(rollbackFor = Exception.class)
+ public void submitProjectApproval(Long id, String processDefinitionKey) {
+ // 1. 鏍¢獙瀛樺湪 + 寰呭鏍哥姸鎬�
MesPdProjectDO project = validateProjectExists(id);
- // 鏍¢獙鐘舵�佷负寰呭鏍�
if (!MesPdProjectStatusEnum.UPLOAD.getStatus().equals(project.getStatus())) {
- throw exception(PD_PROJECT_NOT_UPLOAD_FOR_AUDIT);
+ throw exception(PD_PROJECT_NOT_UPLOAD_FOR_APPROVAL);
}
- // 鏍¢獙璇ラ」鐩笅鎵�鏈夎祫鏂欏鏍歌褰曞潎宸插鏍革紙涓嶅瓨鍦ㄥ緟瀹℃牳鐨勮褰曪級
+ // 2. 鏍¢獙璇ラ」鐩笅鎵�鏈夎祫鏂欏鏍歌褰曞潎宸插鏍革紙涓嶅瓨鍦ㄥ緟瀹℃牳鐨勮褰曪級
List<MesPdDocumentDO> documents = documentService.getDocumentListByProjectId(id);
List<Long> documentIds = documents.stream().map(MesPdDocumentDO::getId).toList();
if (documentAuditMapper.existsPendingAuditByDocumentIds(documentIds)) {
throw exception(PD_PROJECT_AUDIT_NOT_FINISHED);
}
- // 鏇存柊鐘舵��
+ // 3. 鍒涘缓 BPM 娴佺▼瀹炰緥
+ String processInstanceId = processInstanceApi.createProcessInstance(getLoginUserId(),
+ new BpmProcessInstanceCreateReqDTO()
+ .setProcessDefinitionKey(processDefinitionKey)
+ .setBusinessKey(String.valueOf(id)));
+ // 4. 鏇存柊椤圭洰鐘舵�佷负瀹℃壒涓�
projectMapper.updateById(MesPdProjectDO.builder()
.id(id)
- .status(MesPdProjectStatusEnum.AUDIT.getStatus())
+ .status(MesPdProjectStatusEnum.APPROVING.getStatus())
+ .processInstanceId(processInstanceId)
+ .processDefinitionKey(processDefinitionKey)
.build());
}
@Override
+ public List<Map<String, Object>> getProjectApproveProcessDefinitionList() {
+ // 1. 鏍¢獙鍒嗙被鏄惁瀛樺湪
+ List<BpmCategoryDO> categories = bpmCategoryService.getCategoryListByCode(
+ Collections.singletonList(BPM_PROCESS_DEFINITION_CATEGORY_CODE));
+ if (CollUtil.isEmpty(categories)) {
+ throw exception(PD_PROJECT_BPM_CATEGORY_NOT_EXISTS);
+ }
+ // 2. 鑾峰彇鍒嗙被涓嬬殑娴佺▼瀹氫箟淇℃伅
+ List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
+ .getProcessDefinitionInfoListByCategory(BPM_PROCESS_DEFINITION_CATEGORY_CODE);
+ if (CollUtil.isEmpty(definitionInfoList)) {
+ return Collections.emptyList();
+ }
+ // 3. 杩囨护婵�娲荤姸鎬侊紝淇濈暀鏈�鏂扮増鏈�
+ Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
+ for (BpmProcessDefinitionInfoDO info : definitionInfoList) {
+ ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId());
+ if (pd == null || pd.isSuspended()) {
+ continue;
+ }
+ ProcessDefinition existing = latestVersionMap.get(pd.getKey());
+ if (existing == null || pd.getVersion() > existing.getVersion()) {
+ latestVersionMap.put(pd.getKey(), pd);
+ }
+ }
+ // 4. 杩斿洖娴佺▼瀹氫箟鍒楄〃
+ List<Map<String, Object>> result = new ArrayList<>();
+ for (ProcessDefinition pd : latestVersionMap.values()) {
+ Map<String, Object> item = new HashMap<>();
+ item.put("id", pd.getId());
+ item.put("key", pd.getKey());
+ item.put("name", pd.getName());
+ result.add(item);
+ }
+ return result;
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void updateProjectAuditStatus(Long id, Integer bpmResult) {
+ // 1. 鏍¢獙瀛樺湪
+ MesPdProjectDO project = validateProjectExists(id);
+ if (!MesPdProjectStatusEnum.APPROVING.getStatus().equals(project.getStatus())) {
+ log.warn("[updateProjectAuditStatus] 璁捐椤圭洰({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵�侊細{}", id, project.getStatus());
+ return;
+ }
+ // 2. 鏍规嵁瀹℃壒缁撴灉鏇存柊鐘舵��
+ Integer newStatus = convertBpmResultToProjectStatus(bpmResult);
+ if (newStatus != null) {
+ projectMapper.updateById(MesPdProjectDO.builder()
+ .id(id)
+ .status(newStatus)
+ .build());
+ }
+ }
+
+ /**
+ * 杞崲 BPM 瀹℃壒缁撴灉涓鸿璁¢」鐩姸鎬�
+ */
+ private Integer convertBpmResultToProjectStatus(Integer bpmResult) {
+ if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
+ return MesPdProjectStatusEnum.AUDIT.getStatus();
+ } else if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
+ return MesPdProjectStatusEnum.UPLOAD.getStatus();
+ } else if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
+ return MesPdProjectStatusEnum.UPLOAD.getStatus();
+ }
+ return null;
+ }
+
+ @Override
@Transactional(rollbackFor = Exception.class)
public void archiveProject(Long id, Long userId) {
// 鏍¢獙瀛樺湪
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/listener/MesPdProjectStatusListener.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/listener/MesPdProjectStatusListener.java
new file mode 100644
index 0000000..31402d1
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pd/project/listener/MesPdProjectStatusListener.java
@@ -0,0 +1,47 @@
+package cn.iocoder.yudao.module.mes.service.pd.project.listener;
+
+import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
+import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener;
+import cn.iocoder.yudao.module.mes.service.pd.project.MesPdProjectService;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * 璁捐椤圭洰瀹℃壒鐘舵�佺洃鍚櫒
+ *
+ * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝鏇存柊璁捐椤圭洰鐨勫鎵圭姸鎬�
+ *
+ * @author 瓒呯骇绠$悊鍛�
+ */
+@Component
+@Slf4j
+public class MesPdProjectStatusListener extends BpmProcessInstanceStatusEventListener {
+
+ /**
+ * BPM 璁捐椤圭洰瀹℃壒娴佺▼瀹氫箟 key
+ */
+ private static final String BPM_PROCESS_DEFINITION_KEY = "mes-pd-project-audit";
+
+ @Resource
+ private MesPdProjectService projectService;
+
+ @Override
+ protected String getProcessDefinitionKey() {
+ return BPM_PROCESS_DEFINITION_KEY;
+ }
+
+ @Override
+ protected void onEvent(BpmProcessInstanceStatusEvent event) {
+ Long projectId;
+ try {
+ projectId = Long.parseLong(event.getBusinessKey());
+ } catch (NumberFormatException e) {
+ log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勮璁¢」鐩紪鍙�", event.getBusinessKey());
+ return;
+ }
+ log.info("[onEvent] 鏀跺埌BPM瀹℃壒浜嬩欢锛宲rojectId={}, status={}", projectId, event.getStatus());
+ projectService.updateProjectAuditStatus(projectId, event.getStatus());
+ }
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchService.java
index 66048dd..cf58d84 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchService.java
@@ -3,6 +3,9 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchGenerateReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchPageReqVO;
+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.dal.dataobject.wm.batch.MesWmBatchDO;
import java.util.List;
@@ -96,4 +99,36 @@
*/
Long getBatchCountByToolId(Long toolId);
+ /**
+ * 鑾峰緱鎵规閲囪喘鏉ユ簮锛堥噰璐叆搴撳崟 + IQC锛�
+ *
+ * @param code 鎵规鍙�
+ * @return 閲囪喘鏉ユ簮鍒楄〃
+ */
+ List<MesWmBatchPurchaseSourceRespVO> getPurchaseSourceList(String code);
+
+ /**
+ * 鑾峰緱鎵规閿�鍞幓鍚戯紙閿�鍞嚭搴撳崟 + OQC锛�
+ *
+ * @param code 鎵规鍙�
+ * @return 閿�鍞幓鍚戝垪琛�
+ */
+ List<MesWmBatchSalesTargetRespVO> getSalesTargetList(String code);
+
+ /**
+ * 鑾峰緱鎵规宸ュ簭娴佽浆锛堜骇鍑�/鎶曞叆浜嬩欢锛�
+ *
+ * @param code 鎵规鍙�
+ * @return 宸ュ簭娴佽浆鍒楄〃
+ */
+ List<MesWmBatchProcessTraceRespVO> getProcessTraceList(String code);
+
+ /**
+ * 鏍规嵁 SN 鐮佽幏寰楁壒娆�
+ *
+ * @param sn SN 鐮�
+ * @return 鎵规璁板綍锛堟湭鍛戒腑杩斿洖 null锛�
+ */
+ MesWmBatchDO getBatchBySn(String sn);
+
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java
index d218f8c..ea88533 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java
@@ -6,9 +6,14 @@
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchGenerateReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchPageReqVO;
+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.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.sn.MesWmSnDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.batch.MesWmBatchMapper;
+import cn.iocoder.yudao.module.mes.dal.mysql.wm.sn.MesWmSnMapper;
import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum;
import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
@@ -24,6 +29,7 @@
import org.springframework.validation.annotation.Validated;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -51,6 +57,8 @@
@Resource
private MesMdmItemService mdmItemService;
+ @Resource
+ private MesWmSnMapper snMapper;
@Resource
private MdmItemBatchConfigApi itemBatchConfigApi;
@Resource
@@ -372,4 +380,39 @@
return batchMapper.selectCountByToolId(toolId);
}
+ @Override
+ public List<MesWmBatchPurchaseSourceRespVO> getPurchaseSourceList(String code) {
+ return batchMapper.selectPurchaseSourceList(code);
+ }
+
+ @Override
+ public List<MesWmBatchSalesTargetRespVO> getSalesTargetList(String code) {
+ return batchMapper.selectSalesTargetList(code);
+ }
+
+ @Override
+ public List<MesWmBatchProcessTraceRespVO> getProcessTraceList(String code) {
+ List<MesWmBatchProcessTraceRespVO> list = batchMapper.selectProcessTraceList(code);
+ if (CollUtil.isEmpty(list)) {
+ return list;
+ }
+ // 鎸夊伐鍗曘�佸伐搴忓簭鍙枫�佷簨浠舵椂闂存帓搴忥紙sort 鍙兘涓虹┖锛岀┖鍊煎厹搴曪級
+ list.sort(Comparator.comparing(MesWmBatchProcessTraceRespVO::getWorkOrderId,
+ Comparator.nullsLast(Comparator.naturalOrder()))
+ .thenComparing(MesWmBatchProcessTraceRespVO::getProcessSort,
+ Comparator.nullsLast(Comparator.naturalOrder()))
+ .thenComparing(MesWmBatchProcessTraceRespVO::getEventTime,
+ Comparator.nullsLast(Comparator.naturalOrder())));
+ return list;
+ }
+
+ @Override
+ public MesWmBatchDO getBatchBySn(String sn) {
+ MesWmSnDO snDO = snMapper.selectOne(MesWmSnDO::getCode, sn);
+ if (snDO == null || StrUtil.isBlank(snDO.getBatchCode())) {
+ return null;
+ }
+ return batchMapper.selectByCode(snDO.getBatchCode());
+ }
+
}
diff --git a/yudao-module-mes/src/main/resources/mapper/wm/batch/MesWmBatchMapper.xml b/yudao-module-mes/src/main/resources/mapper/wm/batch/MesWmBatchMapper.xml
index 22fba71..0eda416 100644
--- a/yudao-module-mes/src/main/resources/mapper/wm/batch/MesWmBatchMapper.xml
+++ b/yudao-module-mes/src/main/resources/mapper/wm/batch/MesWmBatchMapper.xml
@@ -11,14 +11,15 @@
<!--
鍚戝墠杩芥函锛氫粠鏌愪釜鍘熸潗鏂欐壒娆″嚭鍙戯紝鏌ユ壘瀹冭鍝簺宸ュ崟娑堣�楀悗锛屼骇鍑轰簡鍝簺鎴愬搧鎵规
- SQL 璺緞锛氬簱瀛樹簨鍔�(娑堣�� OUT) 鈫� 娑堣�楀崟 鈫� 鎶ュ伐璁板綍 鈫� 搴撳瓨浜嬪姟(浜у嚭 IN) 鈫� 鎵规
+ 閾捐矾锛氬簱瀛樹簨鍔�(娑堣�� OUT, biz=123, biz_id=娑堣�楀崟id) 鈫� 娑堣�楀崟 鈫� 鎶ュ伐 鈫� 浜у嚭鍗�(feedback_id) 鈫� 搴撳瓨浜嬪姟(浜у嚭 IN, biz=124, biz_id=浜у嚭鍗昳d) 鈫� 鎵规
-->
<select id="selectListByForward" parameterType="String" resultMap="BatchTraceResult">
SELECT DISTINCT pf.work_order_id, pf.item_id, tx_produce.batch_id, tx_produce.batch_code
FROM mes_wm_transaction tx_consume
- LEFT JOIN mes_wm_item_consume ic ON tx_consume.biz_id = ic.id AND tx_consume.biz_type = 123 AND ic.deleted = 0
- LEFT JOIN mes_pro_feedback pf ON pf.id = ic.feedback_id AND pf.deleted = 0
- LEFT JOIN mes_wm_transaction tx_produce ON tx_produce.biz_id = pf.id AND tx_produce.biz_type = 124 AND tx_produce.deleted = 0
+ JOIN mes_wm_item_consume ic ON tx_consume.biz_id = ic.id AND tx_consume.biz_type = 123 AND ic.deleted = 0
+ JOIN mes_pro_feedback pf ON pf.id = ic.feedback_id AND pf.deleted = 0
+ JOIN mes_wm_product_produce pp ON pp.feedback_id = pf.id AND pp.deleted = 0
+ JOIN mes_wm_transaction tx_produce ON tx_produce.biz_id = pp.id AND tx_produce.biz_type = 124 AND tx_produce.deleted = 0
WHERE tx_consume.batch_code = #{batchCode}
AND tx_consume.biz_type = 123
AND tx_consume.deleted = 0
@@ -27,19 +28,65 @@
<!--
鍚戝悗杩芥函锛氫粠鏌愪釜鎴愬搧鎵规鍑哄彂锛屾煡鎵剧敓浜у畠鏃舵秷鑰椾簡鍝簺鍘熸潗鏂欐壒娆�
- SQL 璺緞锛氬簱瀛樹簨鍔�(浜у嚭 IN) 鈫� 浜у嚭鍗� 鈫� 鎶ュ伐璁板綍 鈫� 搴撳瓨浜嬪姟(娑堣�� OUT) 鈫� 鎵规
+ 閾捐矾锛氬簱瀛樹簨鍔�(浜у嚭 IN, biz=124, biz_id=浜у嚭鍗昳d) 鈫� 浜у嚭鍗� 鈫� 鎶ュ伐 鈫� 娑堣�楀崟(feedback_id) 鈫� 搴撳瓨浜嬪姟(娑堣�� OUT, biz=123, biz_id=娑堣�楀崟id) 鈫� 鎵规
-->
<select id="selectListByBackward" parameterType="String" resultMap="BatchTraceResult">
SELECT DISTINCT ic.work_order_id, tx_consume.item_id, tx_consume.batch_id, tx_consume.batch_code
FROM mes_wm_transaction tx_produce
- LEFT JOIN mes_wm_product_produce pp ON tx_produce.biz_id = pp.id AND tx_produce.biz_type = 124 AND pp.deleted = 0
- LEFT JOIN mes_pro_feedback pf ON pf.id = pp.feedback_id AND pf.deleted = 0
- LEFT JOIN mes_wm_transaction tx_consume ON tx_consume.biz_id = pf.id AND tx_consume.biz_type = 123 AND tx_consume.deleted = 0
- LEFT JOIN mes_wm_item_consume ic ON ic.id = tx_consume.biz_id AND ic.deleted = 0
+ JOIN mes_wm_product_produce pp ON tx_produce.biz_id = pp.id AND tx_produce.biz_type = 124 AND pp.deleted = 0
+ JOIN mes_pro_feedback pf ON pf.id = pp.feedback_id AND pf.deleted = 0
+ JOIN mes_wm_item_consume ic ON ic.feedback_id = pf.id AND ic.deleted = 0
+ JOIN mes_wm_transaction tx_consume ON tx_consume.biz_id = ic.id AND tx_consume.biz_type = 123 AND tx_consume.deleted = 0
WHERE tx_produce.batch_code = #{batchCode}
AND tx_produce.biz_type = 124
AND tx_produce.deleted = 0
AND tx_consume.batch_id IS NOT NULL
</select>
+ <!-- 鎵规閲囪喘鏉ユ簮锛氭壒娆� 鈫� 閲囪喘鍏ュ簱琛� 鈫� 閲囪喘鍏ュ簱鍗� 鈫� IQC -->
+ <select id="selectPurchaseSourceList" parameterType="String"
+ resultType="cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchPurchaseSourceRespVO">
+ SELECT r.code AS receipt_code, r.receipt_date, r.purchase_order_code, r.vendor_id,
+ iqc.code AS iqc_code, iqc.check_result AS check_result,
+ rl.batch_code, rl.item_id, rl.received_quantity
+ FROM mes_wm_item_receipt_line rl
+ JOIN mes_wm_item_receipt r ON r.id = rl.receipt_id AND r.deleted = 0
+ LEFT JOIN mes_qc_iqc iqc ON iqc.id = r.iqc_id AND iqc.deleted = 0
+ WHERE rl.batch_code = #{batchCode} AND rl.deleted = 0
+ </select>
+
+ <!-- 鎵规閿�鍞幓鍚戯細鎵规 鈫� 閿�鍞嚭搴撹 鈫� 閿�鍞嚭搴撳崟 鈫� OQC -->
+ <select id="selectSalesTargetList" parameterType="String"
+ resultType="cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchSalesTargetRespVO">
+ SELECT s.code AS sales_code, s.sales_date, s.sales_order_code, s.client_id,
+ oqc.code AS oqc_code, oqc.check_result AS check_result,
+ sl.batch_code, sl.item_id, sl.quantity, sl.quality_status
+ FROM mes_wm_product_sales_line sl
+ JOIN mes_wm_product_sales s ON s.id = sl.sales_id AND s.deleted = 0
+ LEFT JOIN mes_qc_oqc oqc ON oqc.id = sl.oqc_id AND oqc.deleted = 0
+ WHERE sl.batch_code = #{batchCode} AND sl.deleted = 0
+ </select>
+
+ <!-- 鎵规宸ュ簭娴佽浆锛氫骇鍑�(OUT)/鎶曞叆(IN) 浜嬩欢鑱氬悎锛屾棤闇�寤鸿〃 -->
+ <select id="selectProcessTraceList" parameterType="String"
+ resultType="cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchProcessTraceRespVO">
+ SELECT 'OUT' AS event_type, pp.work_order_id, pp.process_id,
+ ppl.batch_code, ppl.quantity, ppl.quality_status, pp.produce_date AS event_time,
+ wop.sort AS process_sort
+ FROM mes_wm_product_produce_line ppl
+ JOIN mes_wm_product_produce pp ON pp.id = ppl.produce_id AND pp.deleted = 0
+ LEFT JOIN mes_pro_work_order_process wop
+ ON wop.work_order_id = pp.work_order_id AND wop.process_id = pp.process_id AND wop.deleted = 0
+ WHERE ppl.batch_code = #{batchCode} AND ppl.deleted = 0
+ UNION ALL
+ SELECT 'IN' AS event_type, ic.work_order_id, ic.process_id,
+ icd.batch_code, icd.quantity, NULL AS quality_status, ic.consume_date AS event_time,
+ wop.sort AS process_sort
+ FROM mes_wm_item_consume_detail icd
+ JOIN mes_wm_item_consume ic ON ic.id = icd.consume_id AND ic.deleted = 0
+ LEFT JOIN mes_pro_work_order_process wop
+ ON wop.work_order_id = ic.work_order_id AND wop.process_id = ic.process_id AND wop.deleted = 0
+ WHERE icd.batch_code = #{batchCode} AND icd.deleted = 0
+ </select>
+
</mapper>
diff --git a/yudao-server/src/main/resources/application-yzfx.yaml b/yudao-server/src/main/resources/application-yzfx.yaml
new file mode 100644
index 0000000..080012b
--- /dev/null
+++ b/yudao-server/src/main/resources/application-yzfx.yaml
@@ -0,0 +1,324 @@
+server:
+ port: 48080
+
+--- #################### 鏁版嵁搴撶浉鍏抽厤缃� ####################
+spring:
+ autoconfigure:
+ # noinspection SpringBootApplicationYaml
+ exclude:
+ - org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration # 榛樿 local 鐜锛屼笉寮�鍚� Quartz 鐨勮嚜鍔ㄩ厤缃�
+ - org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreAutoConfiguration # 绂佺敤 AI 妯″潡鐨� Qdrant锛屾墜鍔ㄥ垱寤�
+ - org.springframework.ai.vectorstore.redis.autoconfigure.RedisVectorStoreAutoConfiguration # 绂佺敤 AI 妯″潡鐨� Redis锛屾墜鍔ㄥ垱寤�
+ - org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration # 绂佺敤 AI 妯″潡鐨� Milvus锛屾墜鍔ㄥ垱寤�
+ - org.dromara.trans.config.TransServiceConfig # TODO 鑺嬭壙锛歟asy-trans 鍏煎 Spring Boot 4 鍚庣Щ闄わ紙TransServiceConfig 寮曠敤浜嗗凡绉婚櫎鐨� RestTemplateBuilder锛�
+ # 绂佺敤鏈厤缃� API Key 鐨勬ā鍨嬭嚜鍔ㄩ厤缃紙鍙繚鐣欓�氫箟鍗冮棶 Embedding 鐨勬墜鍔ㄩ厤缃級
+ - org.springframework.ai.model.openai.autoconfigure.OpenAiChatAutoConfiguration
+ - org.springframework.ai.model.openai.autoconfigure.OpenAiEmbeddingAutoConfiguration
+ - org.springframework.ai.model.openai.autoconfigure.OpenAiImageAutoConfiguration
+ - org.springframework.ai.model.openai.autoconfigure.OpenAiAudioSpeechAutoConfiguration
+ - org.springframework.ai.model.openai.autoconfigure.OpenAiAudioTranscriptionAutoConfiguration
+ - org.springframework.ai.model.openai.autoconfigure.OpenAiModerationAutoConfiguration
+ - org.springframework.ai.model.deepseek.autoconfigure.DeepSeekChatAutoConfiguration
+ - org.springframework.ai.model.anthropic.autoconfigure.AnthropicChatAutoConfiguration
+ - org.springframework.ai.model.google.genai.autoconfigure.chat.GoogleGenAiChatAutoConfiguration
+ - org.springframework.ai.model.google.genai.autoconfigure.embedding.GoogleGenAiEmbeddingConnectionAutoConfiguration
+ - org.springframework.ai.model.google.genai.autoconfigure.embedding.GoogleGenAiTextEmbeddingAutoConfiguration
+ - org.springframework.ai.model.ollama.autoconfigure.OllamaApiAutoConfiguration
+ - org.springframework.ai.model.ollama.autoconfigure.OllamaChatAutoConfiguration
+ - org.springframework.ai.model.ollama.autoconfigure.OllamaEmbeddingAutoConfiguration
+ - org.springframework.ai.model.stabilityai.autoconfigure.StabilityAiImageAutoConfiguration
+ # 鏁版嵁婧愰厤缃」
+ datasource:
+ druid: # Druid 銆愮洃鎺с�戠浉鍏崇殑鍏ㄥ眬閰嶇疆
+ web-stat-filter:
+ enabled: true
+ stat-view-servlet:
+ enabled: true
+ allow: # 璁剧疆鐧藉悕鍗曪紝涓嶅~鍒欏厑璁告墍鏈夎闂�
+ url-pattern: /druid/*
+ login-username: # 鎺у埗鍙扮鐞嗙敤鎴峰悕鍜屽瘑鐮�
+ login-password:
+ filter:
+ stat:
+ enabled: true
+ log-slow-sql: true # 鎱� SQL 璁板綍
+ slow-sql-millis: 100
+ merge-sql: true
+ wall:
+ config:
+ multi-statement-allow: true
+ dynamic: # 澶氭暟鎹簮閰嶇疆
+ druid: # Druid 銆愯繛鎺ユ睜銆戠浉鍏崇殑鍏ㄥ眬閰嶇疆
+ initial-size: 1 # 鍒濆杩炴帴鏁�
+ min-idle: 1 # 鏈�灏忚繛鎺ユ睜鏁伴噺
+ max-active: 20 # 鏈�澶ц繛鎺ユ睜鏁伴噺
+ max-wait: 60000 # 閰嶇疆鑾峰彇杩炴帴绛夊緟瓒呮椂鐨勬椂闂达紝鍗曚綅锛氭绉掞紙1 鍒嗛挓锛�
+ time-between-eviction-runs-millis: 60000 # 閰嶇疆闂撮殧澶氫箙鎵嶈繘琛屼竴娆℃娴嬶紝妫�娴嬮渶瑕佸叧闂殑绌洪棽杩炴帴锛屽崟浣嶏細姣锛�1 鍒嗛挓锛�
+ min-evictable-idle-time-millis: 600000 # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�灏忕敓瀛樼殑鏃堕棿锛屽崟浣嶏細姣锛�10 鍒嗛挓锛�
+ max-evictable-idle-time-millis: 1800000 # 閰嶇疆涓�涓繛鎺ュ湪姹犱腑鏈�澶х敓瀛樼殑鏃堕棿锛屽崟浣嶏細姣锛�30 鍒嗛挓锛�
+ validation-query: SELECT 1 FROM DUAL # 閰嶇疆妫�娴嬭繛鎺ユ槸鍚︽湁鏁�
+ test-while-idle: true
+ test-on-borrow: false
+ test-on-return: false
+ pool-prepared-statements: true # 鏄惁寮�鍚� PreparedStatement 缂撳瓨
+ max-pool-prepared-statement-per-connection-size: 20 # 姣忎釜杩炴帴缂撳瓨鐨� PreparedStatement 鏁伴噺
+ primary: master
+ datasource:
+ master:
+ url: jdbc:mysql://172.17.0.1:9002/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 杩炴帴鐨勭ず渚�
+ # url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true # MySQL Connector/J 5.X 杩炴帴鐨勭ず渚�
+ # url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 杩炴帴鐨勭ず渚�
+ # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 杩炴帴鐨勭ず渚�
+ # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer 杩炴帴鐨勭ず渚�
+ # url: jdbc:dm://127.0.0.1:5236?schema=RUOYI_VUE_PRO # DM 杩炴帴鐨勭ず渚�
+ # url: jdbc:kingbase8://127.0.0.1:54321/test # 浜哄ぇ閲戜粨 KingbaseES 杩炴帴鐨勭ず渚�
+ # url: jdbc:postgresql://127.0.0.1:5432/postgres # OpenGauss 杩炴帴鐨勭ず渚�
+ # url: jdbc:postgresql://127.0.0.1:5866/ruoyi-vue-pro # 鐎氶珮 HighGo 杩炴帴鐨勭ず渚�
+ username: root
+ password: yzfx@123456..
+ # username: sa # SQL Server 杩炴帴鐨勭ず渚�
+ # password: Yudao@2024 # SQL Server 杩炴帴鐨勭ず渚�
+ # username: SYSDBA # DM 杩炴帴鐨勭ず渚�
+ # password: SYSDBA001 # DM 杩炴帴鐨勭ず渚�
+ # username: root # OpenGauss 杩炴帴鐨勭ず渚�
+ # password: Yudao@2024 # OpenGauss 杩炴帴鐨勭ず渚�
+ # username: root # 鐎氶珮 HighGo 杩炴帴鐨勭ず渚�
+ # password: 123456 # 鐎氶珮 HighGo 杩炴帴鐨勭ず渚�
+ slave: # 妯℃嫙浠庡簱锛屽彲鏍规嵁鑷繁闇�瑕佷慨鏀�
+ lazy: true # 寮�鍚噿鍔犺浇锛屼繚璇佸惎鍔ㄩ�熷害
+ url: jdbc:mysql://172.17.0.1:9002/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true
+ username: root
+ password: yzfx@123456
+# tdengine: # IoT 鏁版嵁搴擄紙闇�瑕� IoT 鐗╄仈缃戝啀寮�鍚櫌锛侊級
+# lazy: true # 寮�鍚噿鍔犺浇锛屼繚璇佸惎鍔ㄩ�熷害
+# url: jdbc:TAOS-WS://127.0.0.1:6041/ruoyi_vue_pro?varcharAsString=true&enableAutoReconnect=true # 鍙傝锛歨ttps://t.zsxq.com/qaX9c锛屽紑鍚� TDengine WebSocket 鑷姩閲嶈繛
+# driver-class-name: com.taosdata.jdbc.ws.WebSocketDriver
+# username: root
+# password: taosdata
+# druid:
+# validation-query: SELECT SERVER_STATUS() # TDengine 鏁版嵁婧愮殑鏈夋晥鎬ф鏌� SQL
+
+ # Redis 閰嶇疆銆俁edisson 榛樿鐨勯厤缃冻澶熶娇鐢紝涓�鑸笉闇�瑕佽繘琛岃皟浼�
+ data:
+ redis:
+ host: 172.17.0.1 # 鍦板潃
+ port: 6379 # 绔彛
+ database: 1 # 鏁版嵁搴撶储寮�
+# password: dev # 瀵嗙爜锛屽缓璁敓浜х幆澧冨紑鍚�
+
+--- #################### 瀹氭椂浠诲姟鐩稿叧閰嶇疆 ####################
+
+# Quartz 閰嶇疆椤癸紝瀵瑰簲 QuartzProperties 閰嶇疆绫�
+spring:
+ quartz:
+ auto-startup: true # 鏈湴寮�鍙戠幆澧冿紝灏介噺涓嶈寮�鍚� Job
+ scheduler-name: schedulerName # Scheduler 鍚嶅瓧銆傞粯璁や负 schedulerName
+ job-store-type: jdbc # Job 瀛樺偍鍣ㄧ被鍨嬨�傞粯璁や负 memory 琛ㄧず鍐呭瓨锛屽彲閫� jdbc 浣跨敤鏁版嵁搴撱��
+ wait-for-jobs-to-complete-on-shutdown: true # 搴旂敤鍏抽棴鏃讹紝鏄惁绛夊緟瀹氭椂浠诲姟鎵ц瀹屾垚銆傞粯璁や负 false 锛屽缓璁缃负 true
+ properties: # 娣诲姞 Quartz Scheduler 闄勫姞灞炴�э紝鏇村鍙互鐪� http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html 鏂囨。
+ org:
+ quartz:
+ # Scheduler 鐩稿叧閰嶇疆
+ scheduler:
+ instanceName: schedulerName
+ instanceId: AUTO # 鑷姩鐢熸垚 instance ID
+ # JobStore 鐩稿叧閰嶇疆
+ jobStore:
+ # JobStore 瀹炵幇绫汇�傚彲瑙佸崥瀹細https://blog.csdn.net/weixin_42458219/article/details/122247162
+ class: org.springframework.scheduling.quartz.LocalDataSourceJobStore
+ isClustered: true # 鏄泦缇ゆā寮�
+ clusterCheckinInterval: 15000 # 闆嗙兢妫�鏌ラ鐜囷紝鍗曚綅锛氭绉掋�傞粯璁や负 15000锛屽嵆 15 绉�
+ misfireThreshold: 60000 # misfire 闃�鍊硷紝鍗曚綅锛氭绉掋��
+ # 绾跨▼姹犵浉鍏抽厤缃�
+ threadPool:
+ threadCount: 25 # 绾跨▼姹犲ぇ灏忋�傞粯璁や负 10 銆�
+ threadPriority: 5 # 绾跨▼浼樺厛绾�
+ class: org.quartz.simpl.SimpleThreadPool # 绾跨▼姹犵被鍨�
+ jdbc: # 浣跨敤 JDBC 鐨� JobStore 鐨勬椂鍊欙紝JDBC 鐨勯厤缃�
+ initialize-schema: NEVER # 鏄惁鑷姩浣跨敤 SQL 鍒濆鍖� Quartz 琛ㄧ粨鏋勩�傝繖閲岃缃垚 never 锛屾垜浠墜鍔ㄥ垱寤鸿〃缁撴瀯銆�
+
+--- #################### 娑堟伅闃熷垪鐩稿叧 ####################
+
+# rocketmq 閰嶇疆椤癸紝瀵瑰簲 RocketMQProperties 閰嶇疆绫�
+rocketmq:
+ name-server: 127.0.0.1:9876 # RocketMQ Namesrv
+
+spring:
+ # RabbitMQ 閰嶇疆椤癸紝瀵瑰簲 RabbitProperties 閰嶇疆绫�
+ rabbitmq:
+ host: 127.0.0.1 # RabbitMQ 鏈嶅姟鐨勫湴鍧�
+ port: 5672 # RabbitMQ 鏈嶅姟鐨勭鍙�
+ username: rabbit # RabbitMQ 鏈嶅姟鐨勮处鍙�
+ password: rabbit # RabbitMQ 鏈嶅姟鐨勫瘑鐮�
+ # Kafka 閰嶇疆椤癸紝瀵瑰簲 KafkaProperties 閰嶇疆绫�
+ kafka:
+ bootstrap-servers: 127.0.0.1:9092 # 鎸囧畾 Kafka Broker 鍦板潃锛屽彲浠ヨ缃涓紝浠ラ�楀彿鍒嗛殧
+
+--- #################### 鏈嶅姟淇濋殰鐩稿叧閰嶇疆 ####################
+
+# Lock4j 閰嶇疆椤�
+lock4j:
+ acquire-timeout: 3000 # 鑾峰彇鍒嗗竷寮忛攣瓒呮椂鏃堕棿锛岄粯璁や负 3000 姣
+ expire: 30000 # 鍒嗗竷寮忛攣鐨勮秴鏃舵椂闂达紝榛樿涓� 30000 姣
+
+--- #################### 鐩戞帶鐩稿叧閰嶇疆 ####################
+
+# Actuator 鐩戞帶绔偣鐨勯厤缃」
+management:
+ endpoints:
+ web:
+ base-path: /actuator # Actuator 鎻愪緵鐨� API 鎺ュ彛鐨勬牴鐩綍銆傞粯璁や负 /actuator
+ exposure:
+ include: '*' # 闇�瑕佸紑鏀剧殑绔偣銆傞粯璁ゅ�煎彧鎵撳紑 health 鍜� info 涓や釜绔偣銆傞�氳繃璁剧疆 * 锛屽彲浠ュ紑鏀炬墍鏈夌鐐广��
+
+# Spring Boot Admin 閰嶇疆椤�
+spring:
+ boot:
+ admin:
+ # Spring Boot Admin Client 瀹㈡埛绔殑鐩稿叧閰嶇疆
+ client:
+ url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 璁剧疆 Spring Boot Admin Server 鍦板潃
+ instance:
+ service-host-type: IP # 娉ㄥ唽瀹炰緥鏃讹紝浼樺厛浣跨敤 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
+ username: admin
+ password: admin
+ # Spring Boot Admin Server 鏈嶅姟绔殑鐩稿叧閰嶇疆
+ context-path: /admin # 閰嶇疆 Spring
+ # 鍏佽宓屽叆 iframe 鐨勫煙鍚嶏紙鏀寔閫氶厤绗︼級锛屽疄闄呴儴缃叉椂锛屽彲浠ユ敼涓� "'self' [浣犵殑鍏綉鍩熷悕]"
+ frame-ancestors: "'self' localhost localhost:48080 127.0.0.1 127.0.0.1:48080"
+
+# 鏃ュ織鏂囦欢閰嶇疆
+logging:
+ file:
+ name: logs/${spring.application.name}.log # 鏃ュ織鏂囦欢鍚嶏紝鐩稿浜庨」鐩牴鐩綍
+ level:
+ # 閰嶇疆鑷繁鍐欑殑 MyBatis Mapper 鎵撳嵃鏃ュ織
+ cn.iocoder.yudao.module.bpm.dal.mysql: debug
+ cn.iocoder.yudao.module.infra.dal.mysql: debug
+ cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiErrorLogMapper: INFO # 閰嶇疆 ApiErrorLogMapper 鐨勬棩蹇楃骇鍒负 info锛岄伩鍏嶅拰 GlobalExceptionHandler 閲嶅鎵撳嵃
+ cn.iocoder.yudao.module.infra.dal.mysql.job.JobLogMapper: INFO # 閰嶇疆 JobLogMapper 鐨勬棩蹇楃骇鍒负 info
+ cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper: INFO # 閰嶇疆 FileConfigMapper 鐨勬棩蹇楃骇鍒负 info
+ cn.iocoder.yudao.module.pay.dal.mysql: debug
+ cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskMapper: INFO # 閰嶇疆 PayNotifyTaskMapper 鐨勬棩蹇楃骇鍒负 info
+ cn.iocoder.yudao.module.system.dal.mysql: debug
+ cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper: INFO # 閰嶇疆 SmsChannelMapper 鐨勬棩蹇楃骇鍒负 info
+ cn.iocoder.yudao.module.tool.dal.mysql: debug
+ cn.iocoder.yudao.module.member.dal.mysql: debug
+ cn.iocoder.yudao.module.trade.dal.mysql: debug
+ cn.iocoder.yudao.module.promotion.dal.mysql: debug
+ cn.iocoder.yudao.module.statistics.dal.mysql: debug
+ cn.iocoder.yudao.module.crm.dal.mysql: debug
+ cn.iocoder.yudao.module.erp.dal.mysql: debug
+ cn.iocoder.yudao.module.mes.dal.mysql: debug
+ cn.iocoder.yudao.module.wms.dal.mysql: debug
+ cn.iocoder.yudao.module.iot.dal.mysql: debug
+ cn.iocoder.yudao.module.iot.dal.tdengine: DEBUG
+ cn.iocoder.yudao.module.iot.service.rule: debug
+ cn.iocoder.yudao.module.ai.dal.mysql: debug
+ cn.iocoder.yudao.module.im.dal.mysql: debug
+ org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 鑺嬭壙锛氬厛绂佺敤锛孲pring Boot 3.X 瀛樺湪閮ㄥ垎閿欒鐨� WARN 鎻愮ず
+
+debug: false
+
+yudao:
+ ai:
+ vector-store:
+ type: milvus # 鍚戦噺搴撶被鍨嬶細milvus
+ milvus:
+ initialize-schema: true
+ database-name: test
+ collection-name: knowledge_segment_yzfx
+ host: 36.213.180.217
+ port: 19530
+
+--- #################### 寰俊鍏紬鍙枫�佸皬绋嬪簭鐩稿叧閰嶇疆 ####################
+wx:
+ mp: # 鍏紬鍙烽厤缃紙蹇呭~锛夛紝鍙傝 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 鏂囨。
+# app-id: wx041349c6f39b268b # 娴嬭瘯鍙凤紙鐗涘笇灏ф彁渚涚殑锛�
+# secret: 5abee519483bc9f8cb37ce280e814bd0
+# app-id: wx5b23ba7a5589ecbb # 娴嬭瘯鍙凤紙鑷繁鐨勶級
+# secret: 2a7b3b20c537e52e74afd395eb85f61f
+ app-id: wxf56b1542b9e85f8a # 娴嬭瘯鍙凤紙Kongdy 鎻愪緵鐨勶級
+ secret: 496379dcef1ba869e9234de8d598cfd3
+ # 瀛樺偍閰嶇疆锛岃В鍐� AccessToken 鐨勮法鑺傜偣鐨勫叡浜�
+ config-storage:
+ type: RedisTemplate # 閲囩敤 RedisTemplate 鎿嶄綔 Redis锛屼細鑷姩浠� Spring 涓幏鍙�
+ key-prefix: wx # Redis Key 鐨勫墠缂�
+ http-client-type: HttpComponents # 閲囩敤 HttpComponents锛圚ttpClient 5锛夎姹傚井淇″叕浼楀彿骞冲彴
+ miniapp: # 灏忕▼搴忛厤缃紙蹇呭~锛夛紝鍙傝 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 鏂囨。
+ # appid: wx62056c0d5e8db250 # 娴嬭瘯鍙凤紙鐗涘笇灏ф彁渚涚殑锛�
+ # secret: 333ae72f41552af1e998fe1f54e1584a
+# appid: wx63c280fe3248a3e7 # wenhualian鐨勬帴鍙f祴璇曞彿
+# secret: 6f270509224a7ae1296bbf1c8cb97aed
+ appid: wxc4598c446f8a9cb3 # 娴嬭瘯鍙凤紙Kongdy 鎻愪緵鐨勶級
+ secret: 4a1a04e07f6a4a0751b39c3064a92c8b
+# appid: wx66186af0759f47c9 # 娴嬭瘯鍙凤紙puhui 鎻愪緵鐨勶級
+# secret: 3218bcbd112cbc614c7264ceb20144ac
+ config-storage:
+ type: RedisTemplate # 閲囩敤 RedisTemplate 鎿嶄綔 Redis锛屼細鑷姩浠� Spring 涓幏鍙�
+ key-prefix: wa # Redis Key 鐨勫墠缂�
+ http-client-type: HttpComponents # 閲囩敤 HttpComponents锛圚ttpClient 5锛夎姹傚井淇″皬绋嬪簭骞冲彴
+
+--- #################### 瓒呯骇绠$悊鍛樼浉鍏抽厤缃� ####################
+
+# 瓒呯骇绠$悊鍛橀厤缃」锛岃缃綋鍓嶉」鐩墍鏈夎嚜瀹氫箟鐨勯厤缃�
+yudao:
+ captcha:
+ enable: false # 鏈湴鐜锛屾殏鏃跺叧闂浘鐗囬獙璇佺爜锛屾柟渚跨櫥褰曠瓑鎺ュ彛鐨勬祴璇曪紱
+ security:
+ mock-enable: true
+ pay:
+ order-notify-url: https://yutou.mynatapp.cc/admin-api/pay/notify/order # 鏀粯娓犻亾鐨勩�愭敮浠樸�戝洖璋冨湴鍧�
+ refund-notify-url: https://yutou.mynatapp.cc/admin-api/pay/notify/refund # 鏀粯娓犻亾鐨勩�愰��娆俱�戝洖璋冨湴鍧�
+ transfer-notify-url: https://yutou.mynatapp.cc/admin-api/pay/notify/transfer # 鏀粯娓犻亾鐨勩�愯浆璐︺�戝洖璋冨湴鍧�
+ access-log: # 璁块棶鏃ュ織鐨勯厤缃」
+ enable: false
+ demo: false # 鍏抽棴婕旂ず妯″紡
+ wxa-code:
+ env-version: develop # 灏忕▼搴忕増鏈�: 姝e紡鐗堜负 "release"锛涗綋楠岀増涓� "trial"锛涘紑鍙戠増涓� "develop"
+ wxa-subscribe-message:
+ miniprogram-state: developer # 璺宠浆灏忕▼搴忕被鍨嬶細寮�鍙戠増涓� 鈥渄eveloper鈥濓紱浣撻獙鐗堜负 鈥渢rial鈥濅负锛涙寮忕増涓� 鈥渇ormal鈥�
+ tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 鍦板浘鐨勫瘑閽� https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
+ storage: # 鏂囦欢涓婁紶閰嶇疆
+ path: /data/javaWork/mom/file # 鏂囦欢瀛樺偍鏍圭洰褰�
+ url-prefix: /admin-api/system/storage-blob # URL璺緞鍓嶇紑
+ domain: http://42.63.70.231:9001 # 鍩熷悕鍓嶇紑锛堟寜瀹為檯鍩熷悕閰嶇疆锛夛紝鍓嶇閰嶇疆濂藉儚涓嶅お瀵圭幇鍦ㄦ槸鐩磋繛鍚庣锛屾墍鏈夎鍚庣绔彛
+ expired: 120 # token杩囨湡鏃堕棿锛堝垎閽燂級
+ use-limit: 10 # token浣跨敤娆℃暟涓婇檺
+ jwt-secret: abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG # JWT瀵嗛挜
+ compress: true # 鏄惁鍘嬬缉鍥剧墖
+ need-compress-size: 10MB # 瑙﹀彂鍘嬬缉鐨勬枃浠跺ぇ灏忛槇鍊�
+ compress-quality: 0.5 # 鍘嬬缉璐ㄩ噺(0.0-1.0)
+
+justauth:
+ enabled: true
+ type:
+ DINGTALK: # 閽夐拤
+ client-id: dingvrnreaje3yqvzhxg
+ client-secret: i8E6iZyDvZj51JIb0tYsYfVQYOks9Cq1lgryEjFRqC79P3iJcrxEwT6Qk2QvLrLI
+ ignore-check-redirect-uri: true
+ WECHAT_ENTERPRISE: # 浼佷笟寰俊
+ client-id: wwd411c69a39ad2e54
+ client-secret: 1wTb7hYxnpT2TUbIeHGXGo7T0odav1ic10mLdyyATOw
+ agent-id: 1000004
+ ignore-check-redirect-uri: true
+ # noinspection SpringBootApplicationYaml
+ WECHAT_MINI_PROGRAM: # 寰俊灏忕▼搴�
+ client-id: ${wx.miniapp.appid}
+ client-secret: ${wx.miniapp.secret}
+ ignore-check-redirect-uri: true
+ ignore-check-state: true # 寰俊灏忕▼搴忥紝涓嶄細浣跨敤鍒� state锛屾墍浠ヤ笉杩涜鏍¢獙
+ WECHAT_MP: # 寰俊鍏紬鍙�
+ client-id: ${wx.mp.app-id}
+ client-secret: ${wx.mp.secret}
+ ignore-check-redirect-uri: true
+ ALIPAY: # 鏀粯瀹濆皬绋嬪簭
+ client-id: xx
+ client-secret: xx
+ alipay-public-key: xx
+ ignore-check-redirect-uri: true
+ ignore-check-state: true
+ cache:
+ type: REDIS
+ prefix: 'social_auth_state:' # 缂撳瓨鍓嶇紑锛岀洰鍓嶅彧瀵� Redis 缂撳瓨鐢熸晥锛岄粯璁� JUSTAUTH::STATE::
+ timeout: 24h # 瓒呮椂鏃堕暱锛岀洰鍓嶅彧瀵� Redis 缂撳瓨鐢熸晥锛岄粯璁� 3 鍒嗛挓
--
Gitblit v1.9.3