From 1d56cb54d8e606547ba5e763cade1c3e26c46be9 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 07 九月 2026 18:05:50 +0800
Subject: [PATCH] feat(mes): 为MES仓储模块添加BPM审批流程支持

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptServiceImpl.java               |   98 ++++++++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/MesWmMiscReceiptController.java       |   15 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/listener/MesWmMiscIssueStatusListener.java       |   45 ++++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnvendor/MesWmReturnVendorDO.java               |    4 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorService.java                 |   28 ++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueService.java                       |   28 ++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptRespVO.java        |    3 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorRespVO.java      |    3 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/listener/MesWmMiscReceiptStatusListener.java   |   45 ++++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/MesWmMiscIssueController.java           |   15 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscreceipt/MesWmMiscReceiptDO.java                 |    4 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java                                |    8 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java                              |    8 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java             |  101 ++++++++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/listener/MesWmReturnVendorStatusListener.java |   45 ++++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscissue/MesWmMiscIssueDO.java                     |    4 
 docs/wm_bpm_progress.md                                                                                                          |   37 +++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptService.java                   |   28 ++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueRespVO.java            |    3 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorController.java     |   15 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueServiceImpl.java                   |   99 ++++++++
 21 files changed, 602 insertions(+), 34 deletions(-)

diff --git a/docs/wm_bpm_progress.md b/docs/wm_bpm_progress.md
index cb115ad..fa29eb9 100644
--- a/docs/wm_bpm_progress.md
+++ b/docs/wm_bpm_progress.md
@@ -1,7 +1,7 @@
 # WM 浠撳偍鍗曟嵁 BPM 瀹℃壒 + 璁惧鑱斿姩 - 瀹炴柦杩涘害
 
 > 璁板綍鏃ユ湡锛�2026-09-07
-> 鐘舵�侊細闃舵1 鍒嗘瀽瀹屾垚锛屽皻鏈敼鐮侊紱闃舵2/3 灏氭湭寮�濮�
+> 鐘舵�侊細闃舵1 鏀圭爜瀹屾垚涓� MES 妯″潡缂栬瘧閫氳繃銆佹暟鎹簱瀛楁宸茶ˉ锛涢樁娈�2 宸插畬鎴愪唬鐮佸垎鏋愶紝灏氭湭鏀圭爜锛涢樁娈�3 灏氭湭寮�濮�
 
 ## 闇�姹�
 
@@ -9,7 +9,7 @@
 2. 璁惧绠$悊锛堣澶囧彴璐︼級鍒涘缓鏃惰嚜鍔ㄥ叆搴撹澶囦粨锛屼笌搴撳瓨鑱斿姩銆�
 3. 璁惧**澶嶇敤鐗╂枡涓绘暟鎹ā鍨�**锛堝凡纭锛夈��
 
-## 闃舵1锛氫笁澶у崟鎹ˉ榻� BPM 瀹℃壒闂幆 鈥斺�� 鍒嗘瀽瀹屾垚锛屾湭鏀圭爜
+## 闃舵1锛氫笁澶у崟鎹ˉ榻� BPM 瀹℃壒闂幆 鈥斺�� 鏀圭爜瀹屾垚锛岀紪璇戦�氳繃
 
 ### 宸茬‘璁ょ幇鐘讹紙鍙洿鎺ラ噰淇★級
 
@@ -37,11 +37,42 @@
 6. 鏂板 3 涓洃鍚櫒锛歚MesWmMiscReceiptStatusListener`/`MesWmMiscIssueStatusListener`/`MesWmReturnVendorStatusListener`锛屽垎绫� `misc_receipt_approve`/`misc_issue_approve`/`return_vendor_approve`銆�
 7. 鏁版嵁搴擄細涓変釜琛ㄥ悇鍔� `process_instance_id VARCHAR(64)`锛堥伒瀹� sql-syntax/sql-script 瑙勮寖锛夈��
 
-## 闃舵2锛氳澶囧彴璐﹁仈鍔ㄨ澶囦粨锛堟湭寮�濮嬫敼鐮侊級
+### 宸插畬鎴愶紙鏀圭爜锛�
+
+- 鏋氫妇锛歮iscreceipt/miscissue 宸插姞 `APPROVING(MesOrderStatusConstants.APPROVING, "瀹℃壒涓�")`銆�
+- DO锛氫笁涓� DO 鍧囧凡鍔� `processInstanceId` 瀛楁銆�
+- RespVO锛氫笁涓崟鎹� RespVO 鍧囧凡鍔� `processInstanceId`銆�
+- Service 鎺ュ彛 + Impl锛氫笁涓崟鎹凡鍔� `submit<Biz>Approval(id, processDefinitionKey)`銆乣update<Biz>AuditStatus(id, bpmResult)`锛圓PPROVE鈫扐PPROVED, REJECT鈫扨REPARE, CANCEL鈫扖ANCELED锛夈�乣get<Biz>ApprovalProcessDefinitionList()`锛堝鐢� `MesWmItemReceipt` 妯″紡锛岃繃婊ゆ寕璧枫�佸彇鏈�鏂扮増鏈級銆備笁涓柊澧炲父閲忓垎绫伙細`APPROVE_CATEGORY_CODE = misc_receipt_approve / misc_issue_approve / return_vendor_approve`銆�
+- Controller锛氫笁涓崟鎹凡鍔� `GET /approval-process-list`锛沗/submit` 鏀逛负甯� `processDefinitionKey`锛岃皟鐢ㄥ鎵规彁浜ゆ柟娉曘��
+- 鐩戝惉鍣細宸叉柊澧� `MesWmMiscReceiptStatusListener`銆乣MesWmMiscIssueStatusListener`銆乣MesWmReturnVendorStatusListener`锛屽悓 `MesWmItemReceiptStatusListener` 椋庢牸銆�
+- 缂栬瘧锛歚mvn compile -pl yudao-module-mes -am -q` 閫氳繃銆�
+- 鏁版嵁搴擄紙瀹為檯杩愯搴� mom-xgdl锛夛細
+  - `mes_wm_misc_receipt`銆乣mes_wm_misc_issue` 鍘熷凡鏈� `process_instance_id`銆�
+  - `mes_wm_return_vendor` 宸茶ˉ `process_instance_id VARCHAR(64)`锛堝凡楠岃瘉鐢熸晥锛夈��
+
+### 鏈畬鎴愶紙闃舵1 鏀跺熬锛�
+
+- 杈撳嚭鍓嶇鑱旇皟鏂规鏂囨。鍒� `docs/`銆�
+
+## 闃舵2锛氳澶囧彴璐﹁仈鍔ㄨ澶囦粨锛堝垎鏋愬畬鎴愶紝鏈敼鐮侊級
 
 - 鍏抽敭浜嬪疄锛歚MdmItemApi.createItem(MdmItemCreateReqDTO)` 鍙缓鐗╂枡锛堝繀濉� code/name/categoryId/unitMeasureId/itemType锛夛紱`MesDvMachineryDO` 鏃� item_id锛涘唴缃澶囦粨 id=5 / 搴撳尯 SYS-EQUIP-LOC-01(id=11) / 搴撲綅 SYS-EQUIP-BIN-01(id=10)銆�
 - 鏂规锛歚createMachinery` 鍔犱簨鍔� 鈫� 寤� MDM 鐗╂枡 鈫� 鎻掕澶囧彴璐�(item_id) 鈫� 鑷姩鐢熸垚鏉$爜 鈫� `MesWmTransactionService` 鍏ヨ澶囦粨锛圛N, qty=1锛夈�傛洿鏂�/鍒犻櫎/瀵煎叆璺緞鍚屾銆�
 
+### 闃舵2 鐜扮姸涓庡垎鏋愮粨璁猴紙2026-09-07 琛ュ厖锛�
+
+- 璁惧鍙拌处宸插畾浣嶏細`MesDvMachineryServiceImpl.java`锛堥渶鏀瑰叆鍙f枃浠讹級锛宍createMachinery`/`updateMachinery`/`deleteMachinery` 褰撳墠鍧�**鏃�** `@Transactional`锛涗粎鏈� `importMachineryList` 鏈� `@Transactional`銆�
+- 鐜版湁渚濊禆锛歚machineryMapper`銆乣barcodeService`锛堣嚜鍔ㄧ敓鎴愭潯鐮� 鈫� `BarcodeBizTypeEnum.MACHINERY`=DV_MACHINERY=400锛夈��
+- 闇�杩藉姞娉ㄥ叆锛歚MdmItemApi`锛坢es 妯″潡宸蹭緷璧� yudao-module-mdm锛屼笖鏈夌幇鎴愭敞鍏ュ厛渚嬶級銆乣MesWmTransactionService`銆�
+-`MdmItemCreateReqDTO` 蹇呭~锛歝ode/name/categoryId/unitMeasureId/itemType锛涘彲閫� warehouseId/warehouseCode/barCode/specification/remark銆�**鏃犺澶囦笓鐢ㄥ瓧娈�**锛岃澶�-鐗╂枡鍏宠仈渚濊禆鏂板 `mes_dv_machinery.item_id` 淇濆瓨杩斿洖鐨� itemId銆�
+- `MdmItemCreateReqDTO` 缂哄皯 categoryId/unitMeasureId/itemType 鐨勬潵婧愶細璁惧 SaveReqVO 娌℃湁杩欎簺瀛楁锛�**闇�鏄庣‘榛樿鐗╂枡鍒嗙被銆侀粯璁よ閲忓崟浣嶃�佺墿鏂欑被鍨嬶紙璁惧锛�**鍐嶅疄鐜帮紙妯嚎鐣欏緟纭畾锛夈��
+- 搴撳瓨浜嬪姟 DTO `MesWmTransactionSaveReqDTO` 蹇呭~锛歵ype(IN=姝f暟)/bizType/bizId/bizCode/bizLineId/itemId/quantity/warehouseId/locationId/areaId銆傝澶囧彴璐︽棤鐙珛琛� ID锛宐izLineId 涓氬姟绾﹀畾鐢�**璁惧涓婚敭 id**銆�
+- 璁惧 StatusEnum 闇�纭锛堣澶囩姸鎬佸瓧娈� `status` 宸叉湁锛屼絾鍏舵灇涓惧懡鍚嶄笌鍙栧�煎皻鏈牳瀵癸紱鐗╂枡鐘舵�佺敱 MDM 鎺у埗锛夈��
+- 璁惧鐗╂枡绫诲瀷锛氬綋鍓� MDM 鐗╂枡绫诲瀷涓氬姟鏄惁鍏佽璁惧绫诲瀷闇�纭锛岃嫢鍙厑璁� 1/2/3锛屽垯鏂板姝e紡璁惧绫诲瀷鍊煎苟鍚屾瀛楀吀锛堜笉鍦� MES 鍐呴儴纭紪鐮佹湭鐭ョ被鍨嬶級銆�
+- 璁惧銆宒eleteMachinery銆嶅凡鏈夌偣妫�/淇濆吇/缁翠慨鍏宠仈鏍¢獙锛屽垹闄ゅ簱瀛樻牎楠屽彲鍦ㄥ簱瀛樹簨鍔″瓨鍦ㄦ�ф牎楠屽琛ュ厖銆�
+
+锛堥樁娈�2 灏氭湭寮�濮嬫敼鐮侊級
+
 ## 闃舵3锛氱嫭绔嬭澶囧叆搴撳崟锛堟湭寮�濮嬶級
 
 - 鏂板 `mes_wm_equipment_receipt` 涓昏〃+鏄庣粏琛ㄣ�丏O/Mapper/Service/VO/Controller/鏋氫妇/涓氬姟甯搁噺锛孊PM 闂幆锛屽畬鎴愬叆搴撳啓璁惧浠撱��
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/MesWmMiscIssueController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/MesWmMiscIssueController.java
index 0008b06..a5b1ed9 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/MesWmMiscIssueController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/MesWmMiscIssueController.java
@@ -96,14 +96,23 @@
     }
 
     @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦鏉傞」鍑哄簱鍗�")
+    @Operation(summary = "鎻愪氦鏉傞」鍑哄簱鍗曞鎵�")
     @Parameter(name = "id", description = "缂栧彿", required = true)
+    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟 Key", required = true)
     @PreAuthorize("@ss.hasPermission('mes:wm-misc-issue:update')")
-    public CommonResult<Boolean> submitMiscIssue(@RequestParam("id") Long id) {
-        miscIssueService.submitMiscIssue(id);
+    public CommonResult<Boolean> submitMiscIssue(@RequestParam("id") Long id,
+                                                  @RequestParam("processDefinitionKey") String processDefinitionKey) {
+        miscIssueService.submitMiscIssueApproval(id, processDefinitionKey);
         return success(true);
     }
 
+    @GetMapping("/approval-process-list")
+    @Operation(summary = "鑾峰緱鏉傞」鍑哄簱瀹℃壒娴佺▼瀹氫箟鍒楄〃")
+    @PreAuthorize("@ss.hasPermission('mes:wm-misc-issue:query')")
+    public CommonResult<List<java.util.Map<String, Object>>> getApprovalProcessList() {
+        return success(miscIssueService.getMiscIssueApprovalProcessDefinitionList());
+    }
+
     @PutMapping("/finish")
     @Operation(summary = "鎵ц鍑哄簱")
     @Parameter(name = "id", description = "缂栧彿", required = true)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueRespVO.java
index 63cc752..9eeea53 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscissue/vo/MesWmMiscIssueRespVO.java
@@ -35,6 +35,9 @@
     @Schema(description = "鐘舵��", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
     private Integer status;
 
+    @Schema(description = "BPM 娴佺▼瀹炰緥缂栧彿", example = "xxx")
+    private String processInstanceId;
+
     @Schema(description = "澶囨敞", example = "澶囨敞")
     private String remark;
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/MesWmMiscReceiptController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/MesWmMiscReceiptController.java
index 24a5379..88ea25b 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/MesWmMiscReceiptController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/MesWmMiscReceiptController.java
@@ -77,14 +77,23 @@
     }
 
     @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦瀹℃壒")
+    @Operation(summary = "鎻愪氦鏉傞」鍏ュ簱鍗曞鎵�")
     @Parameter(name = "id", description = "缂栧彿", required = true)
+    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟 Key", required = true)
     @PreAuthorize("@ss.hasPermission('mes:wm:misc-receipt:submit')")
-    public CommonResult<Boolean> submitMiscReceipt(@RequestParam("id") Long id) {
-        miscReceiptService.submitMiscReceipt(id);
+    public CommonResult<Boolean> submitMiscReceipt(@RequestParam("id") Long id,
+                                                    @RequestParam("processDefinitionKey") String processDefinitionKey) {
+        miscReceiptService.submitMiscReceiptApproval(id, processDefinitionKey);
         return success(true);
     }
 
+    @GetMapping("/approval-process-list")
+    @Operation(summary = "鑾峰緱鏉傞」鍏ュ簱瀹℃壒娴佺▼瀹氫箟鍒楄〃")
+    @PreAuthorize("@ss.hasPermission('mes:wm:misc-receipt:query')")
+    public CommonResult<List<java.util.Map<String, Object>>> getApprovalProcessList() {
+        return success(miscReceiptService.getMiscReceiptApprovalProcessDefinitionList());
+    }
+
     @PutMapping("/finish")
     @Operation(summary = "鎵ц鍏ュ簱")
     @Parameter(name = "id", description = "缂栧彿", required = true)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptRespVO.java
index effeabf..2fa6c34 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/miscreceipt/vo/MesWmMiscReceiptRespVO.java
@@ -35,6 +35,9 @@
     @Schema(description = "鐘舵��", example = "0")
     private Integer status;
 
+    @Schema(description = "BPM 娴佺▼瀹炰緥缂栧彿", example = "xxx")
+    private String processInstanceId;
+
     @Schema(description = "澶囨敞", example = "澶囨敞")
     private String remark;
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorController.java
index 8cbe7ec..3642e16 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/MesWmReturnVendorController.java
@@ -103,14 +103,23 @@
     }
 
     @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦渚涘簲鍟嗛��璐у崟")
+    @Operation(summary = "鎻愪氦渚涘簲鍟嗛��璐у崟瀹℃壒")
     @Parameter(name = "id", description = "缂栧彿", required = true)
+    @Parameter(name = "processDefinitionKey", description = "娴佺▼瀹氫箟 Key", required = true)
     @PreAuthorize("@ss.hasPermission('mes:wm-return-vendor:update')")
-    public CommonResult<Boolean> submitReturnVendor(@RequestParam("id") Long id) {
-        returnVendorService.submitReturnVendor(id);
+    public CommonResult<Boolean> submitReturnVendor(@RequestParam("id") Long id,
+                                                     @RequestParam("processDefinitionKey") String processDefinitionKey) {
+        returnVendorService.submitReturnVendorApproval(id, processDefinitionKey);
         return success(true);
     }
 
+    @GetMapping("/approval-process-list")
+    @Operation(summary = "鑾峰緱渚涘簲鍟嗛��璐у鎵规祦绋嬪畾涔夊垪琛�")
+    @PreAuthorize("@ss.hasPermission('mes:wm-return-vendor:query')")
+    public CommonResult<List<java.util.Map<String, Object>>> getApprovalProcessList() {
+        return success(returnVendorService.getReturnVendorApprovalProcessDefinitionList());
+    }
+
     @PutMapping("/stock")
     @Operation(summary = "鎵ц鎷h揣")
     @Parameter(name = "id", description = "缂栧彿", required = true)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorRespVO.java
index e6f0263..5af5624 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnvendor/vo/MesWmReturnVendorRespVO.java
@@ -48,6 +48,9 @@
     @Schema(description = "鐘舵��", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
     private Integer status;
 
+    @Schema(description = "BPM 娴佺▼瀹炰緥缂栧彿", example = "xxx")
+    private String processInstanceId;
+
     @Schema(description = "澶囨敞", example = "澶囨敞")
     private String remark;
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscissue/MesWmMiscIssueDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscissue/MesWmMiscIssueDO.java
index a93ed5b..126e77a 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscissue/MesWmMiscIssueDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscissue/MesWmMiscIssueDO.java
@@ -68,6 +68,10 @@
      */
     private Integer status;
     /**
+     * BPM 娴佺▼瀹炰緥缂栧彿
+     */
+    private String processInstanceId;
+    /**
      * 澶囨敞
      */
     private String remark;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscreceipt/MesWmMiscReceiptDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscreceipt/MesWmMiscReceiptDO.java
index bcb3f64..9502fdd 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscreceipt/MesWmMiscReceiptDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/miscreceipt/MesWmMiscReceiptDO.java
@@ -68,6 +68,10 @@
      */
     private Integer status;
     /**
+     * BPM 娴佺▼瀹炰緥缂栧彿
+     */
+    private String processInstanceId;
+    /**
      * 澶囨敞
      */
     private String remark;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnvendor/MesWmReturnVendorDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnvendor/MesWmReturnVendorDO.java
index 9b8b4be..c96cdfb 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnvendor/MesWmReturnVendorDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnvendor/MesWmReturnVendorDO.java
@@ -70,6 +70,10 @@
      */
     private Integer status;
     /**
+     * BPM 娴佺▼瀹炰緥缂栧彿
+     */
+    private String processInstanceId;
+    /**
      * 澶囨敞
      */
     private String remark;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java
index 8fd77a5..8a11385 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscIssueStatusEnum.java
@@ -25,9 +25,15 @@
      */
     PREPARE(MesOrderStatusConstants.PREPARE, "鑽夌"),
     /**
+     * 瀹℃壒涓�
+     *
+     * 瀵瑰簲 MesWmMiscIssueService#submitMiscIssueApproval 鏂规硶
+     */
+    APPROVING(MesOrderStatusConstants.APPROVING, "瀹℃壒涓�"),
+    /**
      * 寰呮墽琛屽嚭搴�
      *
-     * 瀵瑰簲 MesWmMiscIssueService#submitMiscIssue 鏂规硶
+     * 瀵瑰簲 MesWmMiscIssueService#updateMiscIssueAuditStatus 鏂规硶
      */
     APPROVED(MesOrderStatusConstants.APPROVED, "寰呮墽琛屽嚭搴�"),
     /**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java
index d54bb4f..e09fbbb 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmMiscReceiptStatusEnum.java
@@ -23,9 +23,15 @@
      */
     PREPARE(MesOrderStatusConstants.PREPARE, "鑽夌"),
     /**
+     * 瀹℃壒涓�
+     *
+     * 瀵瑰簲 MesWmMiscReceiptService#submitMiscReceiptApproval 鏂规硶
+     */
+    APPROVING(MesOrderStatusConstants.APPROVING, "瀹℃壒涓�"),
+    /**
      * 宸插鎵�
      *
-     * 瀵瑰簲 MesWmMiscReceiptService#submitMiscReceipt 鏂规硶
+     * 瀵瑰簲 MesWmMiscReceiptService#updateMiscReceiptAuditStatus 鏂规硶
      */
     APPROVED(MesOrderStatusConstants.APPROVED, "宸插鎵�"),
     /**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueService.java
index 36971d7..81da3b0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueService.java
@@ -6,10 +6,18 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.miscissue.MesWmMiscIssueDO;
 import jakarta.validation.Valid;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * MES 鏉傞」鍑哄簱鍗� Service 鎺ュ彛
  */
 public interface MesWmMiscIssueService {
+
+    /**
+     * 鏉傞」鍑哄簱 BPM 瀹℃壒鍒嗙被缂栫爜
+     */
+    String APPROVE_CATEGORY_CODE = "misc_issue_approve";
 
     /**
      * 鍒涘缓鏉傞」鍑哄簱鍗�
@@ -50,11 +58,27 @@
     PageResult<MesWmMiscIssueDO> getMiscIssuePage(MesWmMiscIssuePageReqVO pageReqVO);
 
     /**
-     * 鎻愪氦鏉傞」鍑哄簱鍗曪紙鑽夌 鈫� 寰呮墽琛屽嚭搴擄級
+     * 鎻愪氦鏉傞」鍑哄簱鍗曞鎵癸紙鑽夌 鈫� 瀹℃壒涓級锛屽垱寤� BPM 娴佺▼瀹炰緥
      *
      * @param id 缂栧彿
+     * @param processDefinitionKey 娴佺▼瀹氫箟 Key
      */
-    void submitMiscIssue(Long id);
+    void submitMiscIssueApproval(Long id, String processDefinitionKey);
+
+    /**
+     * 鏇存柊鏉傞」鍑哄簱鍗曞鎵圭姸鎬侊紙瀹℃壒涓� 鈫� 寰呮墽琛屽嚭搴�/鑽夌/宸插彇娑堬級
+     *
+     * @param id 缂栧彿
+     * @param bpmResult BPM 瀹℃壒缁撴灉
+     */
+    void updateMiscIssueAuditStatus(Long id, Integer bpmResult);
+
+    /**
+     * 鑾峰彇鏉傞」鍑哄簱瀹℃壒鍙敤鐨� BPM 娴佺▼瀹氫箟鍒楄〃
+     *
+     * @return 娴佺▼瀹氫箟鍒楄〃锛坕d/key/name锛�
+     */
+    List<Map<String, Object>> getMiscIssueApprovalProcessDefinitionList();
 
     /**
      * 鎵ц鍑哄簱锛堝緟鎵ц鍑哄簱 鈫� 宸插畬鎴愶級锛屾墸鍑忓簱瀛�
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueServiceImpl.java
index 8861bc8..c179604 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/MesWmMiscIssueServiceImpl.java
@@ -15,13 +15,21 @@
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
+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.BpmProcessDefinitionInfoDO;
+import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
+import org.flowable.engine.repository.ProcessDefinition;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
-import java.util.List;
+import java.util.*;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@@ -42,6 +50,10 @@
     private MesWmMiscIssueLineService miscIssueLineService;
     @Resource
     private MesWmTransactionService wmTransactionService;
+    @Resource
+    private BpmProcessInstanceApi processInstanceApi;
+    @Resource
+    private BpmProcessDefinitionService bpmProcessDefinitionService;
 
     @Override
     public Long createMiscIssue(MesWmMiscIssueSaveReqVO createReqVO) {
@@ -91,7 +103,7 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitMiscIssue(Long id) {
+    public void submitMiscIssueApproval(Long id, String processDefinitionKey) {
         // 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
         validateMiscIssueExistsAndDraft(id);
         // 鏍¢獙鑷冲皯鏈変竴鏉¤
@@ -99,10 +111,87 @@
         if (CollUtil.isEmpty(lines)) {
             throw exception(WM_MISC_ISSUE_NO_LINE);
         }
-
-        // 鎻愪氦锛堣崏绋� 鈫� 寰呮墽琛屽嚭搴擄級
+        // 鍒涘缓 BPM 娴佺▼瀹炰緥
+        String processInstanceId = processInstanceApi.createProcessInstance(getCurrentUserId(),
+                new BpmProcessInstanceCreateReqDTO()
+                        .setProcessDefinitionKey(processDefinitionKey)
+                        .setBusinessKey(String.valueOf(id)));
+        // 鎻愪氦瀹℃壒锛堣崏绋� 鈫� 瀹℃壒涓級
         miscIssueMapper.updateById(new MesWmMiscIssueDO()
-                .setId(id).setStatus(MesWmMiscIssueStatusEnum.APPROVED.getStatus()));
+                .setId(id)
+                .setStatus(MesWmMiscIssueStatusEnum.APPROVING.getStatus())
+                .setProcessInstanceId(processInstanceId));
+    }
+
+    @Override
+    public List<Map<String, Object>> getMiscIssueApprovalProcessDefinitionList() {
+        return getProcessDefinitionListByCategory(APPROVE_CATEGORY_CODE);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateMiscIssueAuditStatus(Long id, Integer bpmResult) {
+        // 1. 鏍¢獙瀛樺湪
+        MesWmMiscIssueDO issue = validateMiscIssueExists(id);
+        if (!MesWmMiscIssueStatusEnum.APPROVING.getStatus().equals(issue.getStatus())) {
+            log.warn("[updateMiscIssueAuditStatus] 鏉傞」鍑哄簱鍗�({}) 涓嶅浜庡鎵逛腑鐘舵��", id);
+            return;
+        }
+        // 2. 鏍规嵁瀹℃壒缁撴灉鏇存柊鐘舵��
+        Integer newStatus = convertBpmResultToStatus(bpmResult);
+        if (newStatus != null) {
+            miscIssueMapper.updateById(new MesWmMiscIssueDO().setId(id).setStatus(newStatus));
+        }
+    }
+
+    private Integer convertBpmResultToStatus(Integer bpmResult) {
+        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
+            return MesWmMiscIssueStatusEnum.APPROVED.getStatus();
+        }
+        if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
+            return MesWmMiscIssueStatusEnum.PREPARE.getStatus();
+        }
+        if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
+            return MesWmMiscIssueStatusEnum.CANCELED.getStatus();
+        }
+        return null;
+    }
+
+    private List<Map<String, Object>> getProcessDefinitionListByCategory(String categoryCode) {
+        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
+                .getProcessDefinitionInfoListByCategory(categoryCode);
+        if (CollUtil.isEmpty(definitionInfoList)) {
+            return Collections.emptyList();
+        }
+        // 杩囨护婵�娲荤姸鎬侊紝淇濈暀鏈�鏂扮増鏈�
+        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);
+            }
+        }
+        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;
+    }
+
+    private Long getCurrentUserId() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof Long) {
+            return (Long) authentication.getPrincipal();
+        }
+        return 1L; // 榛樿鐢ㄦ埛
     }
 
     @Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/listener/MesWmMiscIssueStatusListener.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/listener/MesWmMiscIssueStatusListener.java
new file mode 100644
index 0000000..95186d1
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscissue/listener/MesWmMiscIssueStatusListener.java
@@ -0,0 +1,45 @@
+package cn.iocoder.yudao.module.mes.service.wm.miscissue.listener;
+
+import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
+import cn.iocoder.yudao.module.mes.service.wm.miscissue.MesWmMiscIssueService;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * 鏉傞」鍑哄簱鍗� BPM 瀹℃壒鐘舵�佺洃鍚櫒
+ *
+ * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝鏇存柊鏉傞」鍑哄簱鍗曠殑瀹℃壒鐘舵��
+ */
+@Component
+@Slf4j
+public class MesWmMiscIssueStatusListener
+        extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener {
+
+    @Resource
+    private MesWmMiscIssueService miscIssueService;
+
+    @Override
+    protected String getProcessDefinitionKey() {
+        return MesWmMiscIssueService.APPROVE_CATEGORY_CODE;
+    }
+
+    @Override
+    protected void onEvent(BpmProcessInstanceStatusEvent event) {
+        Long id;
+        try {
+            id = Long.parseLong(event.getBusinessKey());
+        } catch (NumberFormatException e) {
+            log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勬潅椤瑰嚭搴撳崟缂栧彿", event.getBusinessKey());
+            return;
+        }
+        log.info("[onEvent] 鏀跺埌BPM瀹℃壒浜嬩欢锛宮iscIssueId={}, status={}", id, event.getStatus());
+        try {
+            miscIssueService.updateMiscIssueAuditStatus(id, event.getStatus());
+            log.info("[onEvent] 鏉傞」鍑哄簱鍗�({}) 瀹℃壒鐘舵�佹洿鏂板畬鎴�", id);
+        } catch (Exception e) {
+            log.error("[onEvent] 鏇存柊鏉傞」鍑哄簱鍗曞鎵圭姸鎬佸け璐ワ紝miscIssueId={}", id, e);
+        }
+    }
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptService.java
index 7d797b3..242c749 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptService.java
@@ -6,12 +6,20 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.miscreceipt.MesWmMiscReceiptDO;
 import jakarta.validation.Valid;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * MES 鏉傞」鍏ュ簱鍗� Service 鎺ュ彛
  *
  * @author 瓒呯骇绠$悊鍛�
  */
 public interface MesWmMiscReceiptService {
+
+    /**
+     * 鏉傞」鍏ュ簱 BPM 瀹℃壒鍒嗙被缂栫爜
+     */
+    String APPROVE_CATEGORY_CODE = "misc_receipt_approve";
 
     /**
      * 鍒涘缓鏉傞」鍏ュ簱鍗�
@@ -52,11 +60,27 @@
     PageResult<MesWmMiscReceiptDO> getMiscReceiptPage(MesWmMiscReceiptPageReqVO pageReqVO);
 
     /**
-     * 鎻愪氦瀹℃壒锛堣崏绋� 鈫� 宸插鎵癸級
+     * 鎻愪氦鏉傞」鍏ュ簱鍗曞鎵癸紙鑽夌 鈫� 瀹℃壒涓級锛屽垱寤� BPM 娴佺▼瀹炰緥
      *
      * @param id 缂栧彿
+     * @param processDefinitionKey 娴佺▼瀹氫箟 Key
      */
-    void submitMiscReceipt(Long id);
+    void submitMiscReceiptApproval(Long id, String processDefinitionKey);
+
+    /**
+     * 鏇存柊鏉傞」鍏ュ簱鍗曞鎵圭姸鎬侊紙瀹℃壒涓� 鈫� 宸插鎵�/鑽夌/宸插彇娑堬級
+     *
+     * @param id 缂栧彿
+     * @param bpmResult BPM 瀹℃壒缁撴灉
+     */
+    void updateMiscReceiptAuditStatus(Long id, Integer bpmResult);
+
+    /**
+     * 鑾峰彇鏉傞」鍏ュ簱瀹℃壒鍙敤鐨� BPM 娴佺▼瀹氫箟鍒楄〃
+     *
+     * @return 娴佺▼瀹氫箟鍒楄〃锛坕d/key/name锛�
+     */
+    List<Map<String, Object>> getMiscReceiptApprovalProcessDefinitionList();
 
     /**
      * 鎵ц鍏ュ簱锛堝凡瀹℃壒 鈫� 宸插畬鎴愶級锛屾洿鏂板簱瀛樺彴璐�
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptServiceImpl.java
index 72a9f3d..2e7ed10 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/MesWmMiscReceiptServiceImpl.java
@@ -14,13 +14,22 @@
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
+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.BpmProcessDefinitionInfoDO;
+import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
+import org.flowable.engine.repository.ProcessDefinition;
 import org.springframework.context.annotation.Lazy;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
+import java.util.*;
 import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -43,6 +52,10 @@
     private MesWmMiscReceiptLineService miscReceiptLineService;
     @Resource
     private MesWmTransactionService wmTransactionService;
+    @Resource
+    private BpmProcessInstanceApi processInstanceApi;
+    @Resource
+    private BpmProcessDefinitionService bpmProcessDefinitionService;
 
     @Override
     public Long createMiscReceipt(MesWmMiscReceiptSaveReqVO createReqVO) {
@@ -92,7 +105,7 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitMiscReceipt(Long id) {
+    public void submitMiscReceiptApproval(Long id, String processDefinitionKey) {
         // 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
         validateMiscReceiptExistsAndPrepare(id);
         // 鏍¢獙鑷冲皯鏈変竴鏉¤
@@ -100,10 +113,87 @@
         if (CollUtil.isEmpty(lines)) {
             throw exception(WM_MISC_RECEIPT_NO_LINE);
         }
-
-        // 鎻愪氦瀹℃壒锛堣崏绋� 鈫� 宸插鎵癸級
+        // 鍒涘缓 BPM 娴佺▼瀹炰緥
+        String processInstanceId = processInstanceApi.createProcessInstance(getCurrentUserId(),
+                new BpmProcessInstanceCreateReqDTO()
+                        .setProcessDefinitionKey(processDefinitionKey)
+                        .setBusinessKey(String.valueOf(id)));
+        // 鎻愪氦瀹℃壒锛堣崏绋� 鈫� 瀹℃壒涓級
         miscReceiptMapper.updateById(new MesWmMiscReceiptDO()
-                .setId(id).setStatus(MesWmMiscReceiptStatusEnum.APPROVED.getStatus()));
+                .setId(id)
+                .setStatus(MesWmMiscReceiptStatusEnum.APPROVING.getStatus())
+                .setProcessInstanceId(processInstanceId));
+    }
+
+    @Override
+    public List<Map<String, Object>> getMiscReceiptApprovalProcessDefinitionList() {
+        return getProcessDefinitionListByCategory(APPROVE_CATEGORY_CODE);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateMiscReceiptAuditStatus(Long id, Integer bpmResult) {
+        // 1. 鏍¢獙瀛樺湪
+        MesWmMiscReceiptDO receipt = validateMiscReceiptExists(id);
+        if (!MesWmMiscReceiptStatusEnum.APPROVING.getStatus().equals(receipt.getStatus())) {
+            log.warn("[updateMiscReceiptAuditStatus] 鏉傞」鍏ュ簱鍗�({}) 涓嶅浜庡鎵逛腑鐘舵��", id);
+            return;
+        }
+        // 2. 鏍规嵁瀹℃壒缁撴灉鏇存柊鐘舵��
+        Integer newStatus = convertBpmResultToStatus(bpmResult);
+        if (newStatus != null) {
+            miscReceiptMapper.updateById(new MesWmMiscReceiptDO().setId(id).setStatus(newStatus));
+        }
+    }
+
+    private Integer convertBpmResultToStatus(Integer bpmResult) {
+        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
+            return MesWmMiscReceiptStatusEnum.APPROVED.getStatus();
+        }
+        if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
+            return MesWmMiscReceiptStatusEnum.PREPARE.getStatus();
+        }
+        if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
+            return MesWmMiscReceiptStatusEnum.CANCELED.getStatus();
+        }
+        return null;
+    }
+
+    private List<Map<String, Object>> getProcessDefinitionListByCategory(String categoryCode) {
+        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
+                .getProcessDefinitionInfoListByCategory(categoryCode);
+        if (CollUtil.isEmpty(definitionInfoList)) {
+            return Collections.emptyList();
+        }
+        // 杩囨护婵�娲荤姸鎬侊紝淇濈暀鏈�鏂扮増鏈�
+        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);
+            }
+        }
+        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;
+    }
+
+    private Long getCurrentUserId() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof Long) {
+            return (Long) authentication.getPrincipal();
+        }
+        return 1L; // 榛樿鐢ㄦ埛
     }
 
     @Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/listener/MesWmMiscReceiptStatusListener.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/listener/MesWmMiscReceiptStatusListener.java
new file mode 100644
index 0000000..17ab0b8
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/miscreceipt/listener/MesWmMiscReceiptStatusListener.java
@@ -0,0 +1,45 @@
+package cn.iocoder.yudao.module.mes.service.wm.miscreceipt.listener;
+
+import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
+import cn.iocoder.yudao.module.mes.service.wm.miscreceipt.MesWmMiscReceiptService;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * 鏉傞」鍏ュ簱鍗� BPM 瀹℃壒鐘舵�佺洃鍚櫒
+ *
+ * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝鏇存柊鏉傞」鍏ュ簱鍗曠殑瀹℃壒鐘舵��
+ */
+@Component
+@Slf4j
+public class MesWmMiscReceiptStatusListener
+        extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener {
+
+    @Resource
+    private MesWmMiscReceiptService miscReceiptService;
+
+    @Override
+    protected String getProcessDefinitionKey() {
+        return MesWmMiscReceiptService.APPROVE_CATEGORY_CODE;
+    }
+
+    @Override
+    protected void onEvent(BpmProcessInstanceStatusEvent event) {
+        Long id;
+        try {
+            id = Long.parseLong(event.getBusinessKey());
+        } catch (NumberFormatException e) {
+            log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勬潅椤瑰叆搴撳崟缂栧彿", event.getBusinessKey());
+            return;
+        }
+        log.info("[onEvent] 鏀跺埌BPM瀹℃壒浜嬩欢锛宮iscReceiptId={}, status={}", id, event.getStatus());
+        try {
+            miscReceiptService.updateMiscReceiptAuditStatus(id, event.getStatus());
+            log.info("[onEvent] 鏉傞」鍏ュ簱鍗�({}) 瀹℃壒鐘舵�佹洿鏂板畬鎴�", id);
+        } catch (Exception e) {
+            log.error("[onEvent] 鏇存柊鏉傞」鍏ュ簱鍗曞鎵圭姸鎬佸け璐ワ紝miscReceiptId={}", id, e);
+        }
+    }
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorService.java
index 9a74087..872d206 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorService.java
@@ -6,10 +6,18 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnvendor.MesWmReturnVendorDO;
 import jakarta.validation.Valid;
 
+import java.util.List;
+import java.util.Map;
+
 /**
  * MES 渚涘簲鍟嗛��璐у崟 Service 鎺ュ彛
  */
 public interface MesWmReturnVendorService {
+
+    /**
+     * 渚涘簲鍟嗛��璐� BPM 瀹℃壒鍒嗙被缂栫爜
+     */
+    String APPROVE_CATEGORY_CODE = "return_vendor_approve";
 
     /**
      * 鍒涘缓渚涘簲鍟嗛��璐у崟
@@ -58,11 +66,27 @@
     MesWmReturnVendorDO validateReturnVendorExists(Long id);
 
     /**
-     * 鎻愪氦渚涘簲鍟嗛��璐у崟锛堣崏绋� -> 寰呮嫞璐э級
+     * 鎻愪氦渚涘簲鍟嗛��璐у崟瀹℃壒锛堣崏绋� -> 瀹℃壒涓級锛屽垱寤� BPM 娴佺▼瀹炰緥
      *
      * @param id 缂栧彿
+     * @param processDefinitionKey 娴佺▼瀹氫箟 Key
      */
-    void submitReturnVendor(Long id);
+    void submitReturnVendorApproval(Long id, String processDefinitionKey);
+
+    /**
+     * 鏇存柊渚涘簲鍟嗛��璐у崟瀹℃壒鐘舵�侊紙瀹℃壒涓� -> 寰呮墽琛岄��璐�/鑽夌/宸插彇娑堬級
+     *
+     * @param id 缂栧彿
+     * @param bpmResult BPM 瀹℃壒缁撴灉
+     */
+    void updateReturnVendorAuditStatus(Long id, Integer bpmResult);
+
+    /**
+     * 鑾峰彇渚涘簲鍟嗛��璐у鎵瑰彲鐢ㄧ殑 BPM 娴佺▼瀹氫箟鍒楄〃
+     *
+     * @return 娴佺▼瀹氫箟鍒楄〃锛坕d/key/name锛�
+     */
+    List<Map<String, Object>> getReturnVendorApprovalProcessDefinitionList();
 
     /**
      * 鎵ц鎷h揣锛堝緟鎷h揣 -> 寰呮墽琛岄��璐э級
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java
index 37f56fb..f5a6f07 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/MesWmReturnVendorServiceImpl.java
@@ -18,13 +18,22 @@
 import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
+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.BpmProcessDefinitionInfoDO;
+import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
+import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
 import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.flowable.engine.repository.ProcessDefinition;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import java.math.BigDecimal;
-import java.util.List;
+import java.util.*;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@@ -35,6 +44,7 @@
  */
 @Service
 @Validated
+@Slf4j
 public class MesWmReturnVendorServiceImpl implements MesWmReturnVendorService {
 
     @Resource
@@ -48,6 +58,10 @@
     private SrmSupplierApi srmSupplierApi;
     @Resource
     private MesWmTransactionService wmTransactionService;
+    @Resource
+    private BpmProcessInstanceApi processInstanceApi;
+    @Resource
+    private BpmProcessDefinitionService bpmProcessDefinitionService;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -99,7 +113,7 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void submitReturnVendor(Long id) {
+    public void submitReturnVendorApproval(Long id, String processDefinitionKey) {
         // 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
         validateReturnVendorExistsAndPrepare(id);
         // 鏍¢獙鑷冲皯鏈変竴鏉¤
@@ -107,10 +121,87 @@
         if (CollUtil.isEmpty(lines)) {
             throw exception(WM_RETURN_VENDOR_NO_LINE);
         }
-
-        // 鎻愪氦锛堣崏绋� -> 寰呮嫞璐э級
+        // 鍒涘缓 BPM 娴佺▼瀹炰緥
+        String processInstanceId = processInstanceApi.createProcessInstance(getCurrentUserId(),
+                new BpmProcessInstanceCreateReqDTO()
+                        .setProcessDefinitionKey(processDefinitionKey)
+                        .setBusinessKey(String.valueOf(id)));
+        // 鎻愪氦瀹℃壒锛堣崏绋� 鈫� 瀹℃壒涓級
         returnVendorMapper.updateById(new MesWmReturnVendorDO()
-                .setId(id).setStatus(MesWmReturnVendorStatusEnum.APPROVING.getStatus()));
+                .setId(id)
+                .setStatus(MesWmReturnVendorStatusEnum.APPROVING.getStatus())
+                .setProcessInstanceId(processInstanceId));
+    }
+
+    @Override
+    public List<Map<String, Object>> getReturnVendorApprovalProcessDefinitionList() {
+        return getProcessDefinitionListByCategory(APPROVE_CATEGORY_CODE);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateReturnVendorAuditStatus(Long id, Integer bpmResult) {
+        // 1. 鏍¢獙瀛樺湪
+        MesWmReturnVendorDO returnVendor = validateReturnVendorExists(id);
+        if (!MesWmReturnVendorStatusEnum.APPROVING.getStatus().equals(returnVendor.getStatus())) {
+            log.warn("[updateReturnVendorAuditStatus] 渚涘簲鍟嗛��璐у崟({}) 涓嶅浜庡鎵逛腑鐘舵��", id);
+            return;
+        }
+        // 2. 鏍规嵁瀹℃壒缁撴灉鏇存柊鐘舵��
+        Integer newStatus = convertBpmResultToStatus(bpmResult);
+        if (newStatus != null) {
+            returnVendorMapper.updateById(new MesWmReturnVendorDO().setId(id).setStatus(newStatus));
+        }
+    }
+
+    private Integer convertBpmResultToStatus(Integer bpmResult) {
+        if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)) {
+            return MesWmReturnVendorStatusEnum.APPROVED.getStatus();
+        }
+        if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)) {
+            return MesWmReturnVendorStatusEnum.PREPARE.getStatus();
+        }
+        if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)) {
+            return MesWmReturnVendorStatusEnum.CANCELED.getStatus();
+        }
+        return null;
+    }
+
+    private List<Map<String, Object>> getProcessDefinitionListByCategory(String categoryCode) {
+        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
+                .getProcessDefinitionInfoListByCategory(categoryCode);
+        if (CollUtil.isEmpty(definitionInfoList)) {
+            return Collections.emptyList();
+        }
+        // 杩囨护婵�娲荤姸鎬侊紝淇濈暀鏈�鏂扮増鏈�
+        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);
+            }
+        }
+        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;
+    }
+
+    private Long getCurrentUserId() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        if (authentication != null && authentication.getPrincipal() instanceof Long) {
+            return (Long) authentication.getPrincipal();
+        }
+        return 1L; // 榛樿鐢ㄦ埛
     }
 
     @Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/listener/MesWmReturnVendorStatusListener.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/listener/MesWmReturnVendorStatusListener.java
new file mode 100644
index 0000000..886f882
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnvendor/listener/MesWmReturnVendorStatusListener.java
@@ -0,0 +1,45 @@
+package cn.iocoder.yudao.module.mes.service.wm.returnvendor.listener;
+
+import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
+import cn.iocoder.yudao.module.mes.service.wm.returnvendor.MesWmReturnVendorService;
+import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * 渚涘簲鍟嗛��璐у崟 BPM 瀹℃壒鐘舵�佺洃鍚櫒
+ *
+ * 鐩戝惉 BPM 娴佺▼瀹炰緥鐘舵�佸彉鏇翠簨浠讹紝鏇存柊渚涘簲鍟嗛��璐у崟鐨勫鎵圭姸鎬�
+ */
+@Component
+@Slf4j
+public class MesWmReturnVendorStatusListener
+        extends cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener {
+
+    @Resource
+    private MesWmReturnVendorService returnVendorService;
+
+    @Override
+    protected String getProcessDefinitionKey() {
+        return MesWmReturnVendorService.APPROVE_CATEGORY_CODE;
+    }
+
+    @Override
+    protected void onEvent(BpmProcessInstanceStatusEvent event) {
+        Long id;
+        try {
+            id = Long.parseLong(event.getBusinessKey());
+        } catch (NumberFormatException e) {
+            log.warn("[onEvent] businessKey({}) 涓嶆槸鏈夋晥鐨勪緵搴斿晢閫�璐у崟缂栧彿", event.getBusinessKey());
+            return;
+        }
+        log.info("[onEvent] 鏀跺埌BPM瀹℃壒浜嬩欢锛宺eturnVendorId={}, status={}", id, event.getStatus());
+        try {
+            returnVendorService.updateReturnVendorAuditStatus(id, event.getStatus());
+            log.info("[onEvent] 渚涘簲鍟嗛��璐у崟({}) 瀹℃壒鐘舵�佹洿鏂板畬鎴�", id);
+        } catch (Exception e) {
+            log.error("[onEvent] 鏇存柊渚涘簲鍟嗛��璐у崟瀹℃壒鐘舵�佸け璐ワ紝returnVendorId={}", id, e);
+        }
+    }
+
+}

--
Gitblit v1.9.3