From 0f792c9b3b88dc4b1b7b306f89e257d931d2d0bd Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期六, 18 七月 2026 15:38:57 +0800
Subject: [PATCH] 代码提交

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java            |   21 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java    |   39 +++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueDetailServiceImpl.java        |    9 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java                |   75 ++++--
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java                            |   22 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessSaveReqVO.java |    3 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineServiceImpl.java            |    3 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueLinePageVO.java          |   38 +++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineService.java                |    3 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnissue/MesWmReturnIssueLineMapper.java               |   16 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessRespVO.java    |    9 
 docs/route_process_output_item_integration.md                                                                                     |  143 +++++++++++++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemServiceImpl.java                  |    7 
 yudao-module-mes/src/main/resources/mapper/wm/returnissue/MesWmReturnIssueLineMapper.xml                                          |   16 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/transaction/MesWmTransactionMapper.java                   |   24 ++
 yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml                                        |    8 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProcessController.java           |   14 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueDetailServiceImpl.java          |   25 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProcessDO.java                     |    7 
 docs/return_issue_integration.md                                                                                                  |  105 +++++++++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateItemController.java          |   12 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueSaveReqVO.java      |    3 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java              |    2 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockService.java                |   14 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java                |   19 +
 25 files changed, 576 insertions(+), 61 deletions(-)

diff --git a/docs/return_issue_integration.md b/docs/return_issue_integration.md
new file mode 100644
index 0000000..495f006
--- /dev/null
+++ b/docs/return_issue_integration.md
@@ -0,0 +1,105 @@
+# 鐢熶骇閫�鏂� - 鍓嶇鑱旇皟鏂规
+
+## 闂鑳屾櫙
+
+閫�鏂欐槑缁嗭紙detail锛夌殑 `warehouseId`/`locationId`/`areaId` 璇箟鍙樻洿锛�
+- **鍙樻洿鍓�**锛氭潵婧愪粨搴擄紙浠庡簱瀛樿褰曞甫鍏ワ紝鍗宠櫄鎷熺嚎杈瑰簱锛�
+- **鍙樻洿鍚�**锛氫笂鏋剁洰鏍囦粨搴擄紙閫�鏂欒鏀惧洖鐨勫疄闄呬粨搴擄級
+
+鍓嶇浼犺櫄鎷熺嚎杈瑰簱淇℃伅 鈫� 鍚庣鍏ュ簱涔熷叆铏氭嫙搴� 鈫� 瀹為檯浠撳簱搴撳瓨娌℃仮澶嶃��
+
+## 娑夊強椤甸潰
+
+- 鐢熶骇閫�鏂欏崟 - 鏄庣粏鏂板/缂栬緫寮圭獥
+- 鐢熶骇閫�鏂欏崟 - 涓婃灦鎿嶄綔椤甸潰
+
+## 鏍稿績鍙樻洿
+
+### 閫�鏂欐槑缁嗙殑浠撳簱瀛楁璇箟
+
+| 瀛楁 | 鍙樻洿鍓嶈涔� | 鍙樻洿鍚庤涔� | 璇存槑 |
+|------|-----------|-----------|------|
+| `materialStockId` | 铏氭嫙绾胯竟搴撳簱瀛樿褰� ID | 涓嶅彉 | 鐢ㄤ簬浠庤櫄鎷熺嚎杈瑰簱鍑哄簱 |
+| `warehouseId` | 鏉ユ簮浠撳簱锛堣櫄鎷熷簱锛� | **涓婃灦鐩爣浠撳簱锛堝疄闄呬粨搴擄級** | 閫�鏂欏叆搴撶殑鐩爣浠撳簱 |
+| `locationId` | 鏉ユ簮搴撳尯 | **涓婃灦鐩爣搴撳尯** | 閫�鏂欏叆搴撶殑鐩爣搴撳尯 |
+| `areaId` | 鏉ユ簮搴撲綅 | **涓婃灦鐩爣搴撲綅** | 閫�鏂欏叆搴撶殑鐩爣搴撲綅 |
+
+### 鍚庣宸插仛鐨勫吋瀹�
+
+鍚庣 `createTransactionList` 宸插仛鍏滃簳锛�
+- 濡傛灉 detail 鐨� `warehouseId` 浠嶆槸铏氭嫙绾胯竟搴擄紙鏃ф暟鎹�/鍓嶇鏈敼锛夛紝浼氳嚜鍔ㄩ�氳繃浜嬪姟娴佹按鍙嶆煡鍘熷浠撳簱
+- 鍓嶇鏀瑰畬鍚庯紝鐩存帴浣跨敤 detail 鐨勪粨搴撲俊鎭綔涓哄叆搴撶洰鏍囷紝涓嶅啀璧板弽鏌�
+
+## 鍓嶇淇敼鐐�
+
+### 1. 鏄庣粏鏂板/缂栬緫寮圭獥 - 浠撳簱閫夋嫨閫昏緫
+
+**褰撳墠閫昏緫**锛氶�夋嫨铏氭嫙绾胯竟搴撳簱瀛樿褰曞悗锛岃嚜鍔ㄥ甫鍏ヨ搴撳瓨璁板綍鐨� warehouseId/locationId/areaId锛堣櫄鎷熷簱锛�
+
+**鏀逛负**锛�
+- `materialStockId`锛氫粛浠庤櫄鎷熺嚎杈瑰簱搴撳瓨璁板綍鑾峰彇锛堢敤浜庢爣璇嗕粠鍝釜搴撳瓨鍑猴級
+- `warehouseId`/`locationId`/`areaId`锛�**鏀逛负璁╃敤鎴烽�夋嫨涓婃灦鐩爣搴撲綅**锛堝疄闄呬粨搴撶殑搴撲綅锛夛紝涓嶅啀鑷姩浠庡簱瀛樿褰曞甫鍏�
+
+#### 閫夋嫨搴撳瓨璁板綍鏃�
+
+```
+閫夋嫨搴撳瓨璁板綍 鈫� 鑷姩甯﹀叆锛歩temId, batchId, batchCode, materialStockId
+                涓嶅啀甯﹀叆锛歸arehouseId, locationId, areaId
+```
+
+#### 涓婃灦鐩爣搴撲綅閫夋嫨
+
+鏂板涓�涓簱浣嶉�夋嫨鍣紝璁╃敤鎴烽�夋嫨閫�鏂欒鏀惧洖鐨勫疄闄呬粨搴撳簱浣嶏細
+- 浠撳簱涓嬫媺锛氳繃婊ゆ帀铏氭嫙绾胯竟浠撳簱锛坈ode = `WIP_VIRTUAL_WAREHOUSE`锛�
+- 搴撳尯涓嬫媺锛氳仈鍔ㄤ粨搴�
+- 搴撲綅涓嬫媺锛氳仈鍔ㄥ簱鍖�
+
+### 2. 鏁版嵁甯﹀叆璇存槑
+
+| 鍦烘櫙 | 浠庡摢甯﹀叆 | 瀛楁 |
+|------|---------|------|
+| 閫夋嫨搴撳瓨璁板綍 | 铏氭嫙绾胯竟搴撳簱瀛� | materialStockId, itemId, batchId, batchCode |
+| 閫夋嫨涓婃灦搴撲綅 | 鐢ㄦ埛鎵嬪姩閫夋嫨 | warehouseId, locationId, areaId |
+| 榛樿涓婃灦搴撲綅 | 棰嗘枡鍑哄簱鏃剁殑鍘熷浠撳簱 | warehouseId, locationId, areaId |
+
+**寤鸿**锛氶�夋嫨搴撳瓨璁板綍鍚庯紝鑷姩鏌ヨ璇ョ墿鏂欑殑棰嗘枡鍑哄簱璁板綍锛屽皢鍘熷鍑哄簱浠撳簱浣滀负榛樿涓婃灦鐩爣搴撲綅锛岀敤鎴峰彲淇敼銆�
+
+### 3. API 璇存槑
+
+淇濆瓨鏄庣粏鐨勬帴鍙d笉鍙橈細
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /mes/wm-return-issue-detail/create | 鏂板鏄庣粏 |
+| PUT | /mes/wm-return-issue-detail/update | 淇敼鏄庣粏 |
+
+**璇锋眰鍙傛暟锛堝悓涔嬪墠锛屼絾璇箟鍙樻洿锛夛細**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| materialStockId | Long | 鍚� | 铏氭嫙绾胯竟搴撳簱瀛樿褰� ID锛堟潵婧愶級 |
+| warehouseId | Long | 鏄� | **涓婃灦鐩爣浠撳簱 ID**锛堜笉鍐嶆槸鏉ユ簮浠撳簱锛� |
+| locationId | Long | 鏄� | **涓婃灦鐩爣搴撳尯 ID** |
+| areaId | Long | 鏄� | **涓婃灦鐩爣搴撲綅 ID** |
+
+### 4. 鍚庣鏍¢獙鍙樻洿
+
+鍚庣鏍¢獙宸茶皟鏁达細
+- 鉁� 鏍¢獙 `materialStockId` 瀵瑰簲鐨勫簱瀛樿褰曞瓨鍦ㄣ�佺墿鏂欎竴鑷淬�佸簱瀛樺厖瓒�
+- 鉂� 涓嶅啀鏍¢獙 `materialStockId` 鐨勪粨搴撲笌 `warehouseId` 涓�鑷达紙鍥犱负鏉ユ簮鏄櫄鎷熷簱锛岀洰鏍囨槸瀹為檯搴擄級
+- 鉁� 鏍¢獙涓婃灦鐩爣搴撲綅鐨勬贩鏀捐鍒�
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 閫�鏂欏嚭搴� | 浠庤櫄鎷熺嚎杈瑰簱鎵e噺锛坈heckFlag=false锛屽厑璁歌礋搴撳瓨锛� |
+| 閫�鏂欏叆搴� | 鍏ュ埌鐢ㄦ埛閫夋嫨鐨勫疄闄呬粨搴撳簱浣� |
+| 榛樿涓婃灦搴撲綅 | 寤鸿榛樿濉叆棰嗘枡鍑哄簱鏃剁殑鍘熷浠撳簱搴撲綅 |
+| 浠撳簱杩囨护 | 涓婃灦鐩爣浠撳簱涓嬫媺搴旀帓闄よ櫄鎷熺嚎杈逛粨搴� |
+
+## 娉ㄦ剰浜嬮」
+
+- 鍚庣宸插仛鍏煎锛氬鏋滃墠绔殏鏃朵笉鏀癸紝鏃ф暟鎹紙warehouseId=铏氭嫙搴擄級浠嶈兘閫氳繃浜嬪姟娴佹按鍙嶆煡鍘熷浠撳簱锛屼笉浼氭姤閿�
+- 鍓嶇鏀瑰畬鍚庯紝鏂扮殑閫�鏂欏崟 detail 搴斾紶瀹為檯浠撳簱鐨勫簱浣嶏紝閫昏緫鏇存竻鏅�
+- 宸插瓨鍦ㄧ殑鏃ч��鏂欐暟鎹笉鍙楀奖鍝嶏紙鍙嶆煡鍏滃簳锛�
diff --git a/docs/route_process_output_item_integration.md b/docs/route_process_output_item_integration.md
new file mode 100644
index 0000000..d1ec864
--- /dev/null
+++ b/docs/route_process_output_item_integration.md
@@ -0,0 +1,143 @@
+# 宸ヨ壓璺嚎宸ュ簭 - 浜у嚭浜у搧瀛楁 - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- 宸ヨ壓璺嚎 - 宸ュ簭閰嶇疆椤碉紙鏂板/缂栬緫宸ュ簭鏃堕�夋嫨浜у嚭浜у搧锛�
+- 鎺掍骇 - 浠诲姟鏂板椤碉紙鑷姩甯﹀叆浜у嚭浜у搧锛�
+- BOM 閰嶇疆椤碉紙宸ュ簭浜у嚭浜у搧鍙樻洿鍚庯紝BOM 鐨勪骇鍝佸瓧娈佃仈鍔級
+
+## 涓氬姟鑳屾櫙
+
+**闂**锛氬綋鍓嶆墍鏈夊伐搴忕殑浜у嚭閮芥槸鏈�缁堟垚鍝侊紝鏃犳硶鍖哄垎涓棿宸ュ簭鐨勫崐鎴愬搧浜у嚭銆備緥濡傦細
+- 宸ュ簭1锛氭媺涓� 鈫� 浜у嚭"閾濇潌"锛堝崐鎴愬搧锛夛紝涓嶆槸"閽㈣姱閾濈粸绾�"
+- 宸ュ簭2锛氱粸绾� 鈫� 浜у嚭"閽㈣姱閾濈粸绾�"锛堟渶缁堟垚鍝侊級
+
+**瑙e喅**锛氬伐鑹鸿矾绾垮伐搴忔柊澧�"浜у嚭浜у搧"瀛楁锛屾帓浜ф椂鑷姩甯﹀叆浠诲姟鐨勭墿鏂欍��
+
+## 涓氬姟娴佺▼涓庢暟鎹甫鍏�
+
+1. **宸ヨ壓璺嚎閰嶇疆** 鈫� 姣忛亾宸ュ簭閫夋嫨浜у嚭浜у搧锛堝崐鎴愬搧/鎴愬搧锛�
+2. **鎺掍骇** 鈫� 閫夋嫨宸ュ簭鍚庯紝鑷姩浠庡伐搴忓甫鍑� `outputItemId` 浣滀负浠诲姟鐨� `itemId`
+3. **鎶ュ伐浜у嚭** 鈫� 浠庝换鍔″啑浣� `itemId`锛堝彲鑳芥槸鍗婃垚鍝侊級锛屼骇鍑哄崟鍜屽簱瀛樿嚜鍔ㄦ纭�
+4. **鍊掑啿鎵f枡** 鈫� BOM 鏌ヨ鎸夊伐搴�+浜у嚭浜у搧鍖归厤锛岃嚜鍔ㄦ纭�
+
+## API
+
+### 宸ュ簭淇濆瓨鎺ュ彛锛堝彉鏇达級
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /mes/pro/route-process/create | 鍒涘缓宸ュ簭 |
+| PUT | /mes/pro/route-process/update | 鏇存柊宸ュ簭 |
+
+**璇锋眰鍙傛暟鏂板锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| outputItemId | Long | 鍚� | 浜у嚭浜у搧鐗╂枡缂栧彿锛堜负绌烘椂榛樿鐢ㄥ伐鍗曟垚鍝侊級 |
+
+**璇锋眰绀轰緥锛堟柊澧炲瓧娈碉級锛�**
+
+```json
+{
+  "routeId": 7,
+  "processId": 10,
+  "sort": 1,
+  "keyFlag": false,
+  "checkFlag": false,
+  "backflushFlag": true,
+  "outputItemId": 31
+}
+```
+
+### 宸ュ簭鏌ヨ鎺ュ彛锛堝彉鏇达級
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/pro/route-process/list-by-route | 鎸夊伐鑹鸿矾绾挎煡宸ュ簭鍒楄〃 |
+| GET | /mes/pro/route-process/get-by-route-and-process | 鎸夎矾绾�+宸ュ簭鏌ラ厤缃� |
+| GET | /mes/pro/route-process/get | 鑾峰彇鍗曚釜宸ュ簭 |
+
+**鍝嶅簲瀛楁鏂板锛�**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| outputItemId | Long | 浜у嚭浜у搧鐗╂枡缂栧彿 |
+| outputItemCode | String | 浜у嚭浜у搧鐗╂枡缂栫爜 |
+| outputItemName | String | 浜у嚭浜у搧鐗╂枡鍚嶇О |
+
+**鍝嶅簲绀轰緥锛堟柊澧炲瓧娈碉級锛�**
+
+```json
+{
+  "code": 0,
+  "data": {
+    "id": 1,
+    "routeId": 7,
+    "processId": 10,
+    "processCode": "PROC_001",
+    "processName": "鎷変笣",
+    "sort": 1,
+    "keyFlag": false,
+    "checkFlag": false,
+    "backflushFlag": true,
+    "outputItemId": 31,
+    "outputItemCode": "ITEM_20260716004",
+    "outputItemName": "閾濇潌"
+  }
+}
+```
+
+## 瀛楁灞曠ず瑙勫垯
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| outputItemId | 宸ュ簭閰嶇疆琛ㄥ崟 | 鐗╂枡閫夋嫨鍣紝鍙�夊崐鎴愬搧鎴栨垚鍝� |
+| outputItemCode | 宸ュ簭鍒楄〃銆佸伐搴忚鎯� | 鍙灞曠ず |
+| outputItemName | 宸ュ簭鍒楄〃銆佸伐搴忚鎯� | 鍙灞曠ず |
+
+## 鍓嶇淇敼鐐�
+
+### 1. 宸ヨ壓璺嚎 - 宸ュ簭閰嶇疆
+
+鍦�"鏄惁鍊掑啿"寮�鍏充箣鍚庯紝鏂板"浜у嚭浜у搧"閫夋嫨鍣細
+
+- 浣跨敤鐗╂枡閫夋嫨缁勪欢锛岀瓫閫夎寖鍥翠笌宸ュ崟浜у搧閫夋嫨鍣ㄤ竴鑷�
+- 闈炴渶鍚庡伐搴忥細閫夋嫨璇ュ伐搴忎骇鍑虹殑鍗婃垚鍝�
+- 鏈�鍚庝竴閬撳伐搴忥細鍙暀绌猴紙榛樿涓哄伐鍗曟垚鍝侊級锛屼篃鍙樉寮忛�夋嫨鏈�缁堟垚鍝�
+- 淇濆瓨鏃跺皢 `outputItemId` 鎻愪氦鍒板悗绔�
+
+### 2. 鎺掍骇 - 浠诲姟鏂板
+
+- 褰撶敤鎴烽�夋嫨宸ュ崟 + 宸ヨ壓璺嚎 + 宸ュ簭鍚庯紝璋冪敤 `/mes/pro/route-process/get-by-route-and-process` 鑾峰彇宸ュ簭閰嶇疆
+- 濡傛灉宸ュ簭閰嶇疆浜� `outputItemId`锛岃嚜鍔ㄥ~鍏ヤ换鍔$殑鐗╂枡瀛楁锛堝睍绀� `outputItemName`锛�
+- 濡傛灉宸ュ簭鏈厤缃� `outputItemId`锛岃嚜鍔ㄥ洖閫�宸ュ崟鐨勬垚鍝�
+- 鐢ㄦ埛鍙互鎵嬪姩淇敼浠诲姟鐨勭墿鏂欙紙瑕嗙洊鑷姩濉叆鍊硷級
+
+### 3. BOM 閰嶇疆
+
+褰撳伐搴忛厤缃簡 `outputItemId` 鍚庯細
+- 璇ュ伐搴忕殑 BOM 璁板綍鐨�"浜у搧"瀛楁搴旇嚜鍔ㄥ叧鑱斿埌 `outputItemId`
+- 鍗� BOM 琛� `mes_pro_route_product_bom.product_id` 搴斾笌宸ュ簭鐨� `outputItemId` 涓�鑷�
+- **娉ㄦ剰**锛氱幇鏈� BOM 鏁版嵁鐨� `product_id` 鍏ㄩ儴鏄渶缁堟垚鍝� ID锛岄厤缃伐搴忎骇鍑轰骇鍝佸悗闇�閲嶆柊璋冩暣 BOM
+
+### 4. 宸ュ簭鍒楄〃灞曠ず
+
+宸ュ簭鍒楄〃涓柊澧�"浜у嚭浜у搧"鍒楋紝灞曠ず `outputItemName`锛屾湭閰嶇疆鏃舵樉绀�"榛樿锛堝伐鍗曟垚鍝侊級"銆�
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| outputItemId 涓虹┖ | 鎺掍骇鏃朵换鍔$殑 itemId 榛樿鐢ㄥ伐鍗曠殑 productId锛堝悜鍚庡吋瀹癸級 |
+| outputItemId 涓嶄负绌� | 鎺掍骇鏃朵换鍔$殑 itemId 鑷姩鐢ㄥ伐搴忕殑 outputItemId |
+| 鏈�鍚庝竴閬撳伐搴� | 寤鸿涓嶅~ outputItemId锛屾垨濉渶缁堟垚鍝侊紝鏁堟灉涓�鏍� |
+| 闈炴渶鍚庡伐搴� | 寤鸿濉啓鍗婃垚鍝侊紝杩欐牱鎶ュ伐浜у嚭鏃跺叆绾胯竟搴撶殑鏄崐鎴愬搧 |
+| 鍓嶇鏄惧紡浼� itemId | 鍚庣浼樺厛浣跨敤鍓嶇浼犲叆鍊硷紙鍚戝悗鍏煎鐜版湁鎺掍骇閫昏緫锛� |
+
+## 娉ㄦ剰浜嬮」
+
+- 鐜版湁宸ヨ壓鏈嚎鏁版嵁涓嶉渶瑕佽縼绉伙紝`outputItemId` 涓虹┖鏃惰涓轰笌涔嬪墠瀹屽叏涓�鑷�
+- 閰嶇疆浜� `outputItemId` 鍚庯紝闇�鍚屾璋冩暣璇ュ伐搴忕殑 BOM 閰嶇疆锛坄product_id` 鏀逛负鍗婃垚鍝� ID锛�
+- 鍗婃垚鍝佷骇鍑哄悗浼氬叆绾胯竟搴擄紙WIP锛夛紝涓嬩竴閬撳伐搴忔秷鑰楁椂閫氳繃 BOM 鍊掑啿鎴栨墜宸ユ姇鏂欐墸鍑�
+- 鎶ュ伐椤甸潰鐨�"浜у搧鐗╂枡"瀛楁鍙兘鏄剧ず鍗婃垚鍝侊紝杩欐槸姝g‘鐨勶紝涓嶈璇互涓烘槸鏁版嵁閿欒
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProcessController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProcessController.java
index 7504915..8c8d2fd 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProcessController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/MesProRouteProcessController.java
@@ -7,8 +7,10 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.pro.route.vo.process.MesProRouteProcessSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
 import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService;
 import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -40,6 +42,8 @@
     private MesProRouteProcessService routeProcessService;
     @Resource
     private MesProProcessService processService;
+    @Resource
+    private MesMdItemService mdItemService;
 
     @PostMapping("/create")
     @Operation(summary = "鍒涘缓宸ヨ壓璺嚎宸ュ簭")
@@ -116,12 +120,20 @@
         list.forEach(item -> { if (item.getNextProcessId() != null) processIds.add(item.getNextProcessId()); });
         Map<Long, MesProProcessDO> processMap = convertMap(
                 processService.getProcessList(new ArrayList<>(processIds)), MesProProcessDO::getId);
-        // 2. 鎷兼帴 VO
+        // 2. 鎵归噺鑾峰彇浜у嚭浜у搧鐗╂枡淇℃伅
+        Set<Long> outputItemIds = convertSet(list, MesProRouteProcessDO::getOutputItemId);
+        outputItemIds.remove(null);
+        Map<Long, MesMdItemDO> outputItemMap = outputItemIds.isEmpty()
+                ? Collections.emptyMap()
+                : mdItemService.getItemMap(outputItemIds);
+        // 3. 鎷兼帴 VO
         return BeanUtils.toBean(list, MesProRouteProcessRespVO.class, vo -> {
             MapUtils.findAndThen(processMap, vo.getProcessId(),
                     process -> vo.setProcessCode(process.getCode()).setProcessName(process.getName()));
             MapUtils.findAndThen(processMap, vo.getNextProcessId(),
                     nextProcess -> vo.setNextProcessName(nextProcess.getName()));
+            MapUtils.findAndThen(outputItemMap, vo.getOutputItemId(),
+                    item -> vo.setOutputItemCode(item.getCode()).setOutputItemName(item.getName()));
         });
     }
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessRespVO.java
index 44d6790..41fb1f0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessRespVO.java
@@ -54,6 +54,15 @@
     @Schema(description = "鏄惁鍊掑啿锛坱rue=鎶ュ伐鏃舵寜BOM鑷姩鎵f枡锛沠alse=涓嶈嚜鍔ㄦ墸鏂欙級", example = "true")
     private Boolean backflushFlag;
 
+    @Schema(description = "浜у嚭浜у搧鐗╂枡缂栧彿", example = "100")
+    private Long outputItemId;
+
+    @Schema(description = "浜у嚭浜у搧鐗╂枡缂栫爜")
+    private String outputItemCode;
+
+    @Schema(description = "浜у嚭浜у搧鐗╂枡鍚嶇О")
+    private String outputItemName;
+
     @Schema(description = "澶囨敞")
     private String remark;
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessSaveReqVO.java
index 5589e8c..8a4fa09 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessSaveReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/route/vo/process/MesProRouteProcessSaveReqVO.java
@@ -44,6 +44,9 @@
     @Schema(description = "鏄惁鍊掑啿锛坱rue=鎶ュ伐鏃舵寜BOM鑷姩鎵f枡锛沠alse=涓嶈嚜鍔ㄦ墸鏂欙級", example = "true")
     private Boolean backflushFlag;
 
+    @Schema(description = "浜у嚭浜у搧鐗╂枡缂栧彿锛堜负绌烘椂榛樿鐢ㄥ伐鍗曟垚鍝侊級", example = "100")
+    private Long outputItemId;
+
     @Schema(description = "澶囨敞")
     private String remark;
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateItemController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateItemController.java
index 25289d2..32562ac 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateItemController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateItemController.java
@@ -6,10 +6,10 @@
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.item.MesQcTemplateItemPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.item.MesQcTemplateItemRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.item.MesQcTemplateItemSaveReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
+import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -38,7 +38,7 @@
     @Resource
     private MesQcTemplateItemService templateItemService;
     @Resource
-    private MesMdItemService mdItemService;
+    private MesMdmItemService mdmItemService;
     @Resource
     private MesMdUnitMeasureService unitMeasureService;
 
@@ -90,12 +90,12 @@
         if (list.isEmpty()) {
             return Collections.emptyList();
         }
-        // 鎵归噺鏌ヨ鐗╂枡
-        Map<Long, MesMdItemDO> itemMap = mdItemService.getItemMap(
+        // 鎵归噺鏌ヨ鐗╂枡锛坕temId 瀛樼殑鏄� mdm_item_id锛屽叧鑱� mdm_item 琛級
+        Map<Long, MesMdmItemDO> itemMap = mdmItemService.getItemMap(
                 convertSet(list, MesQcTemplateItemDO::getItemId));
         // 鎵归噺鏌ヨ璁¢噺鍗曚綅
         Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
-                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
+                convertSet(itemMap.values(), MesMdmItemDO::getUnitMeasureId));
         // 鎷艰 VO
         return BeanUtils.toBean(list, MesQcTemplateItemRespVO.class, vo -> {
             findAndThen(itemMap, vo.getItemId(), item -> {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java
index 23aa6e7..ea53e5e 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java
@@ -12,6 +12,7 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLinePageVO;
 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
@@ -88,8 +89,8 @@
     @PreAuthorize("@ss.hasPermission('mes:wm-return-issue:query')")
     public CommonResult<PageResult<MesWmReturnIssueLineRespVO>> getReturnIssueLinePage(
             @Valid MesWmReturnIssueLinePageReqVO pageReqVO) {
-        PageResult<MesWmReturnIssueLineDO> pageResult = issueLineService.getReturnIssueLinePage(pageReqVO);
-        return success(new PageResult<>(buildRespVOList(pageResult.getList()), pageResult.getTotal()));
+        PageResult<MesWmReturnIssueLinePageVO> pageResult = issueLineService.getReturnIssueLinePage(pageReqVO);
+        return success(new PageResult<>(buildRespVOListFromPageVO(pageResult.getList()), pageResult.getTotal()));
     }
 
     @GetMapping("/list-by-issue")
@@ -104,6 +105,40 @@
 
     // ==================== 鎷兼帴 VO ====================
 
+    /**
+     * 鍒嗛〉鏌ヨ缁撴灉鏋勫缓 RespVO锛圫QL 宸插叧鑱� mdm_item锛宑ode/name/specification 鐩存帴浠� PageVO 鍙栵級
+     */
+    private List<MesWmReturnIssueLineRespVO> buildRespVOListFromPageVO(List<MesWmReturnIssueLinePageVO> list) {
+        if (CollUtil.isEmpty(list)) {
+            return Collections.emptyList();
+        }
+        // 1. 鑾峰緱鍏宠仈鏁版嵁锛堣閲忓崟浣嶃�佺敓浜т换鍔★級
+        Map<Long, MesMdItemDO> itemMap = mdmItemService.getItemMap(
+                convertSet(list, MesWmReturnIssueLinePageVO::getItemId));
+        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
+                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
+        Map<Long, MesProTaskDO> taskMap = taskService.getTaskMap(
+                convertSet(list, MesWmReturnIssueLinePageVO::getTaskId));
+        // 2. 鏋勫缓缁撴灉
+        return BeanUtils.toBean(list, MesWmReturnIssueLineRespVO.class, vo -> {
+            // code/name/specification 浠� PageVO 鐩存帴鏄犲皠锛堝瓧娈靛悕涓嶅悓闇�鎵嬪姩璧嬪�硷級
+            list.stream()
+                    .filter(v -> java.util.Objects.equals(v.getId(), vo.getId()))
+                    .findFirst()
+                    .ifPresent(pageVO -> {
+                        vo.setItemCode(pageVO.getCode());
+                        vo.setItemName(pageVO.getName());
+                        vo.setSpecification(pageVO.getSpecification());
+                    });
+            // 璁¢噺鍗曚綅浠嶉渶浠� itemMap 鑾峰彇
+            MapUtils.findAndThen(itemMap, vo.getItemId(), item ->
+                    MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
+                            unit -> vo.setUnitMeasureName(unit.getName())));
+            MapUtils.findAndThen(taskMap, vo.getTaskId(), task ->
+                    vo.setTaskCode(task.getCode()).setTaskName(task.getName()));
+        });
+    }
+
     private List<MesWmReturnIssueLineRespVO> buildRespVOList(List<MesWmReturnIssueLineDO> list) {
         if (CollUtil.isEmpty(list)) {
             return Collections.emptyList();
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueSaveReqVO.java
index 891141c..a4c7fb0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueSaveReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueSaveReqVO.java
@@ -22,8 +22,7 @@
     @NotBlank(message = "閫�鏂欏崟鍚嶇О涓嶈兘涓虹┖")
     private String name;
 
-    @Schema(description = "鐢熶骇浠诲姟 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @NotNull(message = "鐢熶骇浠诲姟 ID 涓嶈兘涓虹┖")
+    @Schema(description = "鐢熶骇浠诲姟 ID锛堥潪蹇呭~锛屼笉鍏宠仈浠诲姟鏃朵紶绌猴級", example = "1")
     private Long taskId;
 
     @Schema(description = "鐢熶骇宸ュ崟 ID", example = "1")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProcessDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProcessDO.java
index 14160b4..82ca417 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProcessDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/route/MesProRouteProcessDO.java
@@ -84,6 +84,13 @@
      */
     private Boolean backflushFlag;
     /**
+     * 浜у嚭浜у搧鐗╂枡缂栧彿
+     *
+     * 鍏宠仈 {@link cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO#getId()}
+     * 涓虹┖鏃堕粯璁ょ敤宸ュ崟鐨勬垚鍝�
+     */
+    private Long outputItemId;
+    /**
      * 澶囨敞
      */
     private String remark;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueLinePageVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueLinePageVO.java
new file mode 100644
index 0000000..f0d1ed4
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueLinePageVO.java
@@ -0,0 +1,38 @@
+package cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import java.math.BigDecimal;
+
+/**
+ * MES 鐢熶骇閫�鏂欏崟琛� 鍒嗛〉鏌ヨ VO锛堝叧鑱� mdm_item 鐨� code/name/specification锛�
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesWmReturnIssueLinePageVO extends MesWmReturnIssueLineDO {
+
+    /**
+     * 鐗╂枡缂栫爜
+     *
+     * 鍏宠仈 {@link cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO#getCode()}
+     */
+    private String code;
+
+    /**
+     * 鐗╂枡鍚嶇О
+     *
+     * 鍏宠仈 {@link cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO#getName()}
+     */
+    private String name;
+
+    /**
+     * 瑙勬牸鍨嬪彿
+     *
+     * 鍏宠仈 {@link cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO#getSpecification()}
+     */
+    private String specification;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnissue/MesWmReturnIssueLineMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnissue/MesWmReturnIssueLineMapper.java
index 03df6ba..6e9397c 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnissue/MesWmReturnIssueLineMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnissue/MesWmReturnIssueLineMapper.java
@@ -2,10 +2,13 @@
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 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.returnissue.vo.line.MesWmReturnIssueLinePageReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLinePageVO;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -15,10 +18,13 @@
 @Mapper
 public interface MesWmReturnIssueLineMapper extends BaseMapperX<MesWmReturnIssueLineDO> {
 
-    default PageResult<MesWmReturnIssueLineDO> selectPage(MesWmReturnIssueLinePageReqVO reqVO) {
-        return selectPage(reqVO, new LambdaQueryWrapperX<MesWmReturnIssueLineDO>()
-                .eqIfPresent(MesWmReturnIssueLineDO::getIssueId, reqVO.getIssueId())
-                .orderByDesc(MesWmReturnIssueLineDO::getId));
+    IPage<MesWmReturnIssueLinePageVO> selectPageByReqVO(Page<MesWmReturnIssueLinePageVO> page,
+                                                         @Param("reqVO") MesWmReturnIssueLinePageReqVO reqVO);
+
+    default PageResult<MesWmReturnIssueLinePageVO> selectPage(MesWmReturnIssueLinePageReqVO reqVO) {
+        Page<MesWmReturnIssueLinePageVO> mpPage = new Page<>(reqVO.getPageNo(), reqVO.getPageSize());
+        IPage<MesWmReturnIssueLinePageVO> result = selectPageByReqVO(mpPage, reqVO);
+        return new PageResult<>(result.getRecords(), result.getTotal());
     }
 
     default List<MesWmReturnIssueLineDO> selectListByIssueId(Long issueId) {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/transaction/MesWmTransactionMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/transaction/MesWmTransactionMapper.java
index 8f55684..878347e 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/transaction/MesWmTransactionMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/transaction/MesWmTransactionMapper.java
@@ -29,4 +29,28 @@
                 .orderByDesc(MesWmTransactionDO::getTransactionTime));
     }
 
+    /**
+     * 鏌ユ壘铏氭嫙绾胯竟搴撳簱瀛樿褰曞搴旂殑鍘熷鍑哄簱浠撳簱淇℃伅
+     * <p>
+     * 閫氳繃铏氭嫙绾胯竟搴撶殑 materialStockId锛屾壘鍒伴娆″叆搴撲簨鍔★紙IN锛夛紝
+     * 鍐嶉�氳繃 relatedTransactionId 鎵惧埌鍏宠仈鐨勫嚭搴撲簨鍔★紙OUT锛夛紝
+     * 鑾峰彇鐗╂枡浠庡摢涓疄闄呬粨搴撳嚭搴撹繘鍏ヨ櫄鎷熺嚎杈瑰簱鐨勩��
+     *
+     * @param materialStockId 铏氭嫙绾胯竟搴撳簱瀛樿褰� ID
+     * @return 鍘熷鍑哄簱浜嬪姟锛堝寘鍚� warehouseId/locationId/areaId锛夛紝涓嶅瓨鍦ㄨ繑鍥� null
+     */
+    default MesWmTransactionDO selectOriginalOutTransaction(Long materialStockId) {
+        // 1. 鎵惧埌璇ュ簱瀛樿褰曠殑棣栨鍏ュ簱浜嬪姟
+        MesWmTransactionDO firstInTransaction = selectOne(new LambdaQueryWrapperX<MesWmTransactionDO>()
+                .eq(MesWmTransactionDO::getMaterialStockId, materialStockId)
+                .eq(MesWmTransactionDO::getType, 1) // IN
+                .orderByAsc(MesWmTransactionDO::getId)
+                .last("LIMIT 1"));
+        if (firstInTransaction == null || firstInTransaction.getRelatedTransactionId() == null) {
+            return null;
+        }
+        // 2. 閫氳繃 relatedTransactionId 鎵惧埌鍘熷鍑哄簱浜嬪姟
+        return selectById(firstInTransaction.getRelatedTransactionId());
+    }
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java
index f45fb1b..64b2076 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskServiceImpl.java
@@ -18,6 +18,8 @@
 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 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.dal.dataobject.pro.route.MesProRouteProcessDO;
+import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
 import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteService;
 import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
 import jakarta.annotation.Resource;
@@ -66,6 +68,9 @@
     @Resource
     private MesProRouteService routeService;
     @Resource
+    @Lazy
+    private MesProRouteProcessService routeProcessService;
+    @Resource
     private MesMdAutoCodeRecordService autoCodeRecordService;
 
     @Override
@@ -75,10 +80,23 @@
         workstationService.validateWorkstationExists(createReqVO.getWorkstationId());
         routeService.validateRouteExists(createReqVO.getRouteId());
         processService.validateProcessExistsAndEnable(createReqVO.getProcessId());
-        MesMdItemDO item = itemService.validateItemExists(createReqVO.getItemId());
 
-        // 2.1 鏋勫缓浠诲姟 DO锛氳嚜鍔ㄥ~鍏呭鎴蜂俊鎭�
+        // 2. 鑷姩纭畾 itemId锛氫紭鍏堝墠绔紶鍏� 鈫� 宸ヨ壓璺嚎宸ュ簭鐨勪骇鍑轰骇鍝� 鈫� 宸ュ崟鎴愬搧
+        Long itemId = createReqVO.getItemId();
+        if (itemId == null) {
+            MesProRouteProcessDO routeProcess = routeProcessService
+                    .getRouteProcessByRouteIdAndProcessId(createReqVO.getRouteId(), createReqVO.getProcessId());
+            if (routeProcess != null && routeProcess.getOutputItemId() != null) {
+                itemId = routeProcess.getOutputItemId();
+            } else {
+                itemId = workOrder.getProductId();
+            }
+        }
+        MesMdItemDO item = itemService.validateItemExists(itemId);
+
+        // 3.1 鏋勫缓浠诲姟 DO锛氳嚜鍔ㄥ~鍏呭鎴蜂俊鎭�
         MesProTaskDO task = BeanUtils.toBean(createReqVO, MesProTaskDO.class)
+                .setItemId(itemId) // 纭繚浣跨敤璁$畻鍚庣殑 itemId
                 .setName(buildTaskName(item, createReqVO.getQuantity()))
                 .setCode(autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.PRO_TASK_CODE.getCode()))
                 .setStatus(MesProTaskStatusEnum.PREPARE.getStatus());
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemServiceImpl.java
index 2b49345..ffba036 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemServiceImpl.java
@@ -7,9 +7,11 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.item.MesQcTemplateItemPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.item.MesQcTemplateItemSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateItemMapper;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
 import jakarta.annotation.Resource;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
@@ -38,6 +40,8 @@
     @Resource
     @Lazy
     private MesQcTemplateService templateService;
+    @Resource
+    private MesMdItemService mesMdItemService;
 
     @Override
     public Long createTemplateItem(MesQcTemplateItemSaveReqVO createReqVO) {
@@ -113,7 +117,8 @@
     @Override
     public MesQcTemplateItemDO getRequiredTemplateByItemIdAndType(Long itemId, Integer qcType) {
         // 1. 鏌ュ嚭 itemId 鍏宠仈鐨勬墍鏈� templateItem
-        List<MesQcTemplateItemDO> templateItems = templateItemMapper.selectListByItemId(itemId);
+        MesMdItemDO item1 = mesMdItemService.getItem(itemId);
+        List<MesQcTemplateItemDO> templateItems = templateItemMapper.selectListByItemId(item1.getMdmItemId());
         if (CollUtil.isEmpty(templateItems)) {
             throw exception(QC_NO_TEMPLATE);
         }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockService.java
index fb9cd45..2ae9a0f 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockService.java
@@ -114,6 +114,20 @@
                                                   Long batchId, String batchCode, Long vendorId, LocalDateTime receiptTime);
 
     /**
+     * 鎸夌粍鍚堥敭鏌ユ壘搴撳瓨璁板綍锛堝彧鏌ヤ笉鍒涘缓锛�
+     *
+     * @param itemId      鐗╂枡缂栧彿
+     * @param warehouseId 浠撳簱缂栧彿
+     * @param locationId  搴撳尯缂栧彿
+     * @param areaId      搴撲綅缂栧彿
+     * @param batchId     鎵规缂栧彿
+     * @param vendorId    渚涘簲鍟嗙紪鍙�
+     * @return 搴撳瓨璁板綍锛堜笉瀛樺湪杩斿洖 null锛�
+     */
+    MesWmMaterialStockDO getMaterialStockByCompositeKey(Long itemId, Long warehouseId, Long locationId, Long areaId,
+                                                         Long batchId, Long vendorId);
+
+    /**
      * 鏇存柊搴撳瓨鏁伴噺
      *
      * @param id 搴撳瓨璁板綍缂栧彿
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java
index f78cdbd..b62bbec 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java
@@ -9,6 +9,7 @@
 import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockFreezeReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockListReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo.MesWmMaterialStockPageReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
@@ -17,6 +18,7 @@
 import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper;
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
 import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService;
 import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
@@ -52,6 +54,8 @@
 
     @Resource
     private MesMdmItemService mdmItemService;
+    @Resource
+    private MesMdItemService mdItemService;
     @Resource
     private MesMdItemTypeService itemTypeService;
     @Resource
@@ -94,10 +98,13 @@
             List<MesMdItemTypeDO> children = itemTypeService.getItemTypeChildrenList(pageReqVO.getItemTypeId());
             itemTypeIds.addAll(convertSet(children, MesMdItemTypeDO::getId));
         }
-        // 1.2 瑙f瀽 itemId
+        // 1.2 瑙f瀽 itemId锛氬墠绔紶鐨勬槸 mes_md_item.id锛屽簱瀛樿〃瀛樼殑鏄� mdm_item_id锛岄渶瑕佽浆鎹�
         Set<Long> itemIds = null;
         if (pageReqVO.getItemId() != null) {
-            itemIds = SetUtils.asSet(pageReqVO.getItemId());
+            MesMdItemDO item = mdItemService.getItem(pageReqVO.getItemId());
+            if (item != null && item.getMdmItemId() != null) {
+                itemIds = SetUtils.asSet(item.getMdmItemId());
+            }
         }
         // 1.3 瑙f瀽 virtualFilter锛氳浆鎹负铏氭嫙浠� warehouseId
         Long virtualWarehouseId = null;
@@ -181,7 +188,15 @@
                 .frozen(false)
                 .build();
         materialStockMapper.insert(newStock);
-        return newStock;
+        // 3. 閲嶆柊鏌ヨ锛岀‘淇濇嬁鍒版暟鎹簱鐢熸垚鐨勫畬鏁磋褰曪紙id銆乧reateTime 绛夛級
+        MesWmMaterialStockDO inserted = materialStockMapper.selectById(newStock.getId());
+        return inserted != null ? inserted : newStock;
+    }
+
+    @Override
+    public MesWmMaterialStockDO getMaterialStockByCompositeKey(Long itemId, Long warehouseId, Long locationId, Long areaId,
+                                                                Long batchId, Long vendorId) {
+        return materialStockMapper.selectByCompositeKey(itemId, warehouseId, locationId, areaId, batchId, vendorId);
     }
 
     @Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueDetailServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueDetailServiceImpl.java
index 55d1887..86e1de8 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueDetailServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueDetailServiceImpl.java
@@ -4,14 +4,18 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.detail.MesWmProductIssueDetailSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDetailDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueLineDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.wm.productissue.MesWmProductIssueDetailMapper;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductIssueStatusEnum;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
+import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
 import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
 import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
 import jakarta.annotation.Resource;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
@@ -41,6 +45,8 @@
     private MesWmWarehouseAreaService warehouseAreaService;
     @Resource
     private MesWmMaterialStockService materialStockService;
+    @Resource
+    private MesMdItemService mesMdItemService;
 
     @Override
     public Long createProductIssueDetail(MesWmProductIssueDetailSaveReqVO createReqVO) {
@@ -122,6 +128,7 @@
     private void validateProductIssueDetailSaveData(MesWmProductIssueDetailSaveReqVO reqVO) {
         // 鏍¢獙鐖舵暟鎹瓨鍦�
         MesWmProductIssueLineDO line = issueLineService.validateProductIssueLineExists(reqVO.getLineId());
+        MesMdItemDO item = mesMdItemService.getItem(line.getItemId());
         if (ObjUtil.notEqual(line.getIssueId(), reqVO.getIssueId())) {
             throw exception(WM_PRODUCT_ISSUE_DETAIL_LINE_NOT_MATCH);
         }
@@ -131,7 +138,7 @@
             throw exception(WM_PRODUCT_ISSUE_STATUS_INVALID);
         }
         // 鏍¢獙鐗╂枡鍖归厤锛堟槑缁� itemId 蹇呴』涓庤 itemId 涓�鑷达級
-        validateDetailItemMatch(reqVO.getItemId(), line.getItemId());
+        validateDetailItemMatch(reqVO.getItemId(), item.getMdmItemId());
         // 鏍¢獙浠撳簱銆佸簱鍖恒�佸簱浣嶇殑鍏宠仈鍏崇郴
         warehouseAreaService.validateWarehouseAreaExists(
                 reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId());
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
index 0856972..ee24926 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
@@ -248,7 +248,7 @@
             Long outTransactionId = wmTransactionService.createTransaction(new MesWmTransactionSaveReqDTO()
                     .setType(MesWmTransactionTypeEnum.OUT.getType()).setItemId(detail.getItemId())
                     .setQuantity(detail.getQuantity().negate()) // 搴撳瓨鍑忓皯
-                    .setBatchId(detail.getBatchId()).setBatchCode(detail.getBatchCode())
+                    .setBatchId(detail.getBatchId()).setBatchCode(detail.getBatchCode()).setMaterialStockId(detail.getMaterialStockId())
                     .setWarehouseId(detail.getWarehouseId()).setLocationId(detail.getLocationId()).setAreaId(detail.getAreaId())
                     .setBizType(MesBizTypeConstants.WM_ISSUE).setBizId(issue.getId())
                     .setBizCode(issue.getCode()).setBizLineId(detail.getLineId()));
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueDetailServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueDetailServiceImpl.java
index 885df10..fec1bfe 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueDetailServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueDetailServiceImpl.java
@@ -6,6 +6,7 @@
 import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.detail.MesWmReturnIssueDetailSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueDetailDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnissue.MesWmReturnIssueDetailMapper;
 import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
 import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
@@ -111,15 +112,27 @@
         if (ObjUtil.notEqual(line.getItemId(), reqVO.getItemId())) {
             throw exception(WM_RETURN_ISSUE_DETAIL_ITEM_MISMATCH);
         }
-        // 鏍¢獙浠撳簱銆佸簱鍖恒�佸簱浣嶇殑鍏宠仈鍏崇郴
+        // 鏍¢獙涓婃灦鐩爣浠撳簱銆佸簱鍖恒�佸簱浣嶇殑鍏宠仈鍏崇郴
         warehouseAreaService.validateWarehouseAreaExists(
                 reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId());
-        // 鏍¢獙搴撲綅鐗╂枡/鎵规娣锋斁瑙勫垯
+        // 鏍¢獙涓婃灦鐩爣搴撲綅鐨勭墿鏂�/鎵规娣锋斁瑙勫垯
         materialStockService.checkAreaMixingRule(reqVO.getAreaId(), reqVO.getItemId(), reqVO.getBatchId());
-        // 鏍¢獙搴撳瓨璁板綍
-        materialStockService.validateSelectedStock(
-                reqVO.getMaterialStockId(), reqVO.getItemId(), reqVO.getBatchId(), reqVO.getBatchCode(),
-                reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId(), reqVO.getQuantity());
+        // 鏍¢獙鏉ユ簮搴撳瓨璁板綍锛坢aterialStockId 鎸囧悜铏氭嫙绾胯竟搴擄紝warehouseId 鏄笂鏋剁洰鏍囦粨搴擄紝涓よ�呬粨搴撲笉鍚屾槸姝e父鐨勶級
+        if (reqVO.getMaterialStockId() != null) {
+            MesWmMaterialStockDO stock = materialStockService.getMaterialStock(reqVO.getMaterialStockId());
+            if (stock == null) {
+                throw exception(WM_MATERIAL_STOCK_NOT_EXISTS);
+            }
+            // 鏍¢獙鐗╂枡鍜屾壒娆′竴鑷�
+            if (ObjUtil.notEqual(stock.getItemId(), reqVO.getItemId())) {
+                throw exception(WM_MATERIAL_STOCK_SELECTION_MISMATCH);
+            }
+            // 鏍¢獙搴撳瓨鏁伴噺鍏呰冻
+            if (reqVO.getQuantity() != null && stock.getQuantity() != null
+                    && stock.getQuantity().compareTo(reqVO.getQuantity()) < 0) {
+                throw exception(WM_MATERIAL_STOCK_INSUFFICIENT);
+            }
+        }
         // 鏍¢獙鏄庣粏鎬绘暟閲忎笉瓒呰繃琛屾暟閲忥紙鎺掗櫎鑷韩锛�
         validateDetailQuantityNotExceed(reqVO.getLineId(), reqVO.getQuantity(), reqVO.getId(), line);
     }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineService.java
index 6a8786f..3657104 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineService.java
@@ -4,6 +4,7 @@
 import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWmReturnIssueLinePageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWmReturnIssueLineSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLinePageVO;
 import jakarta.validation.Valid;
 
 import java.math.BigDecimal;
@@ -50,7 +51,7 @@
      * @param pageReqVO 鍒嗛〉鏌ヨ
      * @return 鐢熶骇閫�鏂欏崟琛屽垎椤�
      */
-    PageResult<MesWmReturnIssueLineDO> getReturnIssueLinePage(MesWmReturnIssueLinePageReqVO pageReqVO);
+    PageResult<MesWmReturnIssueLinePageVO> getReturnIssueLinePage(MesWmReturnIssueLinePageReqVO pageReqVO);
 
     /**
      * 鏍规嵁閫�鏂欏崟 ID 鑾峰彇琛屽垪琛�
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineServiceImpl.java
index f966893..fcf0034 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineServiceImpl.java
@@ -8,6 +8,7 @@
 import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWmReturnIssueLineSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLinePageVO;
 import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnissue.MesWmReturnIssueLineMapper;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnIssueStatusEnum;
@@ -87,7 +88,7 @@
     }
 
     @Override
-    public PageResult<MesWmReturnIssueLineDO> getReturnIssueLinePage(MesWmReturnIssueLinePageReqVO pageReqVO) {
+    public PageResult<MesWmReturnIssueLinePageVO> getReturnIssueLinePage(MesWmReturnIssueLinePageReqVO pageReqVO) {
         return issueLineMapper.selectPage(pageReqVO);
     }
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java
index 529c4df..c84bcc0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java
@@ -33,6 +33,8 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseLocationDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transaction.MesWmTransactionDO;
+import cn.iocoder.yudao.module.mes.dal.mysql.wm.transaction.MesWmTransactionMapper;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -78,6 +80,8 @@
     private MesWmWarehouseLocationService locationService;
     @Resource
     private MesWmWarehouseAreaService areaService;
+    @Resource
+    private MesWmTransactionMapper transactionMapper;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -85,13 +89,15 @@
         // 1. 鏍¢獙鍏宠仈鏁版嵁
         validateReturnIssueSaveData(createReqVO);
 
-        // 2. 浠� task 鑷姩甯﹀叆 workOrderId 鍜� workstationId
-        MesProTaskDO task = taskService.validateTaskExists(createReqVO.getTaskId());
-        if (createReqVO.getWorkOrderId() == null) {
-            createReqVO.setWorkOrderId(task.getWorkOrderId());
-        }
-        if (createReqVO.getWorkstationId() == null) {
-            createReqVO.setWorkstationId(task.getWorkstationId());
+        // 2. 浠� task 鑷姩甯﹀叆 workOrderId 鍜� workstationId锛坱askId 闈炲繀濉級
+        if (createReqVO.getTaskId() != null) {
+            MesProTaskDO task = taskService.validateTaskExists(createReqVO.getTaskId());
+            if (createReqVO.getWorkOrderId() == null) {
+                createReqVO.setWorkOrderId(task.getWorkOrderId());
+            }
+            if (createReqVO.getWorkstationId() == null) {
+                createReqVO.setWorkstationId(task.getWorkstationId());
+            }
         }
 
         // 3. 鎻掑叆涓昏〃
@@ -109,13 +115,15 @@
         // 1.2 鏍¢獙鍏宠仈鏁版嵁
         validateReturnIssueSaveData(updateReqVO);
 
-        // 2. 浠� task 鑷姩甯﹀叆 workOrderId 鍜� workstationId
-        MesProTaskDO task = taskService.validateTaskExists(updateReqVO.getTaskId());
-        if (updateReqVO.getWorkOrderId() == null) {
-            updateReqVO.setWorkOrderId(task.getWorkOrderId());
-        }
-        if (updateReqVO.getWorkstationId() == null) {
-            updateReqVO.setWorkstationId(task.getWorkstationId());
+        // 2. 浠� task 鑷姩甯﹀叆 workOrderId 鍜� workstationId锛坱askId 闈炲繀濉級
+        if (updateReqVO.getTaskId() != null) {
+            MesProTaskDO task = taskService.validateTaskExists(updateReqVO.getTaskId());
+            if (updateReqVO.getWorkOrderId() == null) {
+                updateReqVO.setWorkOrderId(task.getWorkOrderId());
+            }
+            if (updateReqVO.getWorkstationId() == null) {
+                updateReqVO.setWorkstationId(task.getWorkstationId());
+            }
         }
 
         // 3. 鏇存柊涓昏〃
@@ -232,7 +240,7 @@
         MesWmWarehouseLocationDO virtualLocation = locationService.getWarehouseLocationByCode(MesWmWarehouseLocationDO.WIP_VIRTUAL_LOCATION);
         MesWmWarehouseAreaDO virtualArea = areaService.getWarehouseAreaByCode(MesWmWarehouseAreaDO.WIP_VIRTUAL_AREA);
 
-        // 2. 閬嶅巻鏄庣粏锛屾瘡鏉℃槑缁嗕骇鐢� OUT锛堣櫄鎷熺嚎杈瑰簱鎵e噺锛�+ IN锛堝疄闄呬粨搴撳鍔狅級
+        // 2. 閬嶅巻鏄庣粏锛屾瘡鏉℃槑缁嗕骇鐢� OUT锛堣櫄鎷熺嚎杈瑰簱鎵e噺锛�+ IN锛堜笂鏋剁洰鏍囦粨搴撳鍔狅級
         List<MesWmReturnIssueDetailDO> details = issueDetailService.getReturnIssueDetailListByIssueId(issue.getId());
         for (MesWmReturnIssueDetailDO detail : details) {
             // 2.1 鍏堜粠铏氭嫙绾胯竟搴撳嚭搴擄紙搴撳瓨鍑忓皯锛�
@@ -241,15 +249,31 @@
                     .setQuantity(detail.getQuantity().negate()) // 搴撳瓨鍑忓皯
                     .setBatchId(detail.getBatchId()).setBatchCode(detail.getBatchCode())
                     .setWarehouseId(virtualWarehouse.getId()).setLocationId(virtualLocation.getId()).setAreaId(virtualArea.getId())
+                    .setMaterialStockId(detail.getMaterialStockId()) // 鎸囧畾铏氭嫙绾胯竟搴撳簱瀛樿褰�
                     .setCheckFlag(false) // 绾胯竟搴撳厑璁歌礋搴撳瓨
                     .setBizType(MesBizTypeConstants.WM_RETURN_ISSUE).setBizId(issue.getId())
                     .setBizCode(issue.getCode()).setBizLineId(detail.getLineId()));
-            // 2.2 鍐嶅叆瀹為檯浠撳簱锛堝簱瀛樺鍔狅級
+
+            // 2.2 纭畾涓婃灦鐩爣浠撳簱锛歞etail 鐨� warehouseId/locationId/areaId 鏄笂鏋剁洰鏍囷紙瀹為檯浠撳簱锛�
+            //     濡傛灉鍓嶇浠嶄紶浜嗚櫄鎷熺嚎杈瑰簱锛堝吋瀹规棫鏁版嵁锛夛紝鍒欓�氳繃浜嬪姟娴佹按鍙嶆煡鍘熷浠撳簱
+            Long targetWarehouseId = detail.getWarehouseId();
+            Long targetLocationId = detail.getLocationId();
+            Long targetAreaId = detail.getAreaId();
+            if (virtualWarehouse.getId().equals(targetWarehouseId) && detail.getMaterialStockId() != null) {
+                MesWmTransactionDO originalOutTx = transactionMapper.selectOriginalOutTransaction(detail.getMaterialStockId());
+                if (originalOutTx != null) {
+                    targetWarehouseId = originalOutTx.getWarehouseId();
+                    targetLocationId = originalOutTx.getLocationId();
+                    targetAreaId = originalOutTx.getAreaId();
+                }
+            }
+
+            // 2.3 鍏ヤ笂鏋剁洰鏍囦粨搴擄紙搴撳瓨澧炲姞锛�
             wmTransactionService.createTransaction(new MesWmTransactionSaveReqDTO()
                     .setType(MesWmTransactionTypeEnum.IN.getType()).setItemId(detail.getItemId())
                     .setQuantity(detail.getQuantity()) // 搴撳瓨澧炲姞锛堥��鏂欏洖浠擄級
                     .setBatchId(detail.getBatchId()).setBatchCode(detail.getBatchCode())
-                    .setWarehouseId(detail.getWarehouseId()).setLocationId(detail.getLocationId()).setAreaId(detail.getAreaId())
+                    .setWarehouseId(targetWarehouseId).setLocationId(targetLocationId).setAreaId(targetAreaId)
                     .setBizType(MesBizTypeConstants.WM_RETURN_ISSUE).setBizId(issue.getId())
                     .setBizCode(issue.getCode()).setBizLineId(detail.getLineId())
                     .setRelatedTransactionId(outTransactionId)); // 鍏宠仈鍑哄簱浜嬪姟
@@ -348,12 +372,17 @@
      */
     private void validateReturnIssueSaveData(MesWmReturnIssueSaveReqVO reqVO) {
         validateCodeUnique(reqVO.getId(), reqVO.getCode());
-        // 鏍¢獙 task 瀛樺湪
-        MesProTaskDO task = taskService.validateTaskExists(reqVO.getTaskId());
-        // 鏍¢獙 task 鍏宠仈鐨勫伐鍗曞凡纭
-        Long workOrderId = reqVO.getWorkOrderId() != null ? reqVO.getWorkOrderId() : task.getWorkOrderId();
-        if (workOrderId != null) {
-            workOrderService.validateWorkOrderConfirmed(workOrderId);
+        // 鏍¢獙 task 瀛樺湪锛坱askId 闈炲繀濉紝浼犱簡鎵嶆牎楠岋級
+        if (reqVO.getTaskId() != null) {
+            MesProTaskDO task = taskService.validateTaskExists(reqVO.getTaskId());
+            // 鏍¢獙 task 鍏宠仈鐨勫伐鍗曞凡纭
+            Long workOrderId = reqVO.getWorkOrderId() != null ? reqVO.getWorkOrderId() : task.getWorkOrderId();
+            if (workOrderId != null) {
+                workOrderService.validateWorkOrderConfirmed(workOrderId);
+            }
+        } else if (reqVO.getWorkOrderId() != null) {
+            // 娌′紶 taskId 浣嗕紶浜� workOrderId锛屾牎楠屽伐鍗曞凡纭
+            workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId());
         }
         if (reqVO.getWorkstationId() != null) {
             workstationService.validateWorkstationExistsAndEnable(reqVO.getWorkstationId());
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java
index 9459550..17d0dc8 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java
@@ -77,9 +77,12 @@
         // 1.5 鍏宠仈浜嬪姟鏍¢獙
         checkRelatedTransaction(reqDTO);
 
-        // 2.1 鑾峰彇鎴栧垱寤哄簱瀛樿褰曪紙濡傛灉浼犲叆浜� materialStockId 鍒欑洿鎺ヤ娇鐢紝閬垮厤閲嶆柊鍖归厤锛�
+        // 2.1 鑾峰彇搴撳瓨璁板綍
         MesWmMaterialStockDO materialStock;
+        MesWmTransactionTypeEnum transactionType = MesWmTransactionTypeEnum.valueOf(reqDTO.getType());
+        boolean isInbound = transactionType != null && transactionType.isInbound();
         if (reqDTO.getMaterialStockId() != null) {
+            // 浼犲叆浜� materialStockId锛岀洿鎺ヤ娇鐢�
             materialStock = materialStockService.getMaterialStock(reqDTO.getMaterialStockId());
             if (materialStock == null) {
                 throw exception(WM_MATERIAL_STOCK_NOT_EXISTS);
@@ -91,10 +94,22 @@
                     || ObjUtil.notEqual(materialStock.getAreaId(), reqDTO.getAreaId())) {
                 throw exception(WM_MATERIAL_STOCK_SELECTION_MISMATCH);
             }
-        } else {
+        } else if (isInbound) {
+            // 鍏ュ簱浜嬪姟锛氭壘涓嶅埌鍒欒嚜鍔ㄥ垱寤哄簱瀛樿褰�
             materialStock = materialStockService.getOrCreateMaterialStock(
                     reqDTO.getItemId(), reqDTO.getWarehouseId(), reqDTO.getLocationId(), reqDTO.getAreaId(),
                     reqDTO.getBatchId(), reqDTO.getBatchCode(), reqDTO.getVendorId(), reqDTO.getReceiptTime());
+        } else {
+            // 鍑哄簱浜嬪姟锛氬簱瀛樿褰曞繀椤诲凡瀛樺湪锛屼笉鍏佽鑷姩鍒涘缓
+            materialStock = materialStockService.getMaterialStockByCompositeKey(
+                    reqDTO.getItemId(), reqDTO.getWarehouseId(), reqDTO.getLocationId(), reqDTO.getAreaId(),
+                    reqDTO.getBatchId(), reqDTO.getVendorId());
+            if (materialStock == null) {
+                throw exception(WM_MATERIAL_STOCK_NOT_EXISTS);
+            }
+        }
+        if (materialStock == null || materialStock.getId() == null) {
+            throw exception(WM_MATERIAL_STOCK_NOT_EXISTS);
         }
         // 2.2 鍐荤粨鏍¢獙锛堜粨搴撱�佸簱鍖恒�佸簱浣嶃�佸簱瀛樿褰曪級
         checkFrozen(reqDTO, materialStock);
diff --git a/yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml b/yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml
index ce2de7c..ab88c74 100644
--- a/yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml
+++ b/yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml
@@ -74,9 +74,9 @@
                 ppl.item_id AS itemId,
                 ppl.quantity AS quantity,
                 NULL AS vendorId,
-                pp.work_order_id AS workOrderId,
-                pp.workstation_id AS workstationId,
-                pp.task_id AS taskId,
+                pf.work_order_id AS workOrderId,
+                pf.workstation_id AS workstationId,
+                pf.task_id AS taskId,
                 NULL AS clientId
             FROM mes_wm_product_produce_line ppl
                 JOIN mes_wm_product_produce pp ON ppl.produce_id = pp.id
@@ -126,7 +126,7 @@
                 NULL AS vendorId,
                 ri.work_order_id AS workOrderId,
                 ri.workstation_id AS workstationId,
-                NULL AS taskId,
+                ri.task_id AS taskId,
                 NULL AS clientId
             FROM mes_wm_return_issue ri
                 JOIN mes_wm_return_issue_line ril ON ri.id = ril.issue_id
diff --git a/yudao-module-mes/src/main/resources/mapper/wm/returnissue/MesWmReturnIssueLineMapper.xml b/yudao-module-mes/src/main/resources/mapper/wm/returnissue/MesWmReturnIssueLineMapper.xml
new file mode 100644
index 0000000..3453dd6
--- /dev/null
+++ b/yudao-module-mes/src/main/resources/mapper/wm/returnissue/MesWmReturnIssueLineMapper.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.iocoder.yudao.module.mes.dal.mysql.wm.returnissue.MesWmReturnIssueLineMapper">
+
+    <select id="selectPageByReqVO" resultType="cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLinePageVO">
+        SELECT t1.*, t2.code, t2.name, t2.specification
+        FROM mes_wm_return_issue_line t1
+        LEFT JOIN mdm_item t2 ON t1.item_id = t2.id AND t2.deleted = 0
+        WHERE t1.deleted = 0
+        <if test="reqVO.issueId != null">
+            AND t1.issue_id = #{reqVO.issueId}
+        </if>
+        ORDER BY t1.id DESC
+    </select>
+
+</mapper>

--
Gitblit v1.9.3