From 66517edf1de22c8203daa256abffddae43bae704 Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期五, 16 十月 2026 17:58:28 +0800
Subject: [PATCH] feat(mes): 袋码绑定托盘免先录生产批次

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/pallet/MesProPalletService.java             |    8 ++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/pallet/MesProPalletController.java |   10 ++
 docs/mes_pro_batch_bag_code_integration.md                                                                         |    4 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/bagcode/MesProBagCodeServiceImpl.java       |   54 +++++++++++-
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/pallet/MesProPalletMapper.java            |   16 ++++
 docs/mes_bag_code_integration.md                                                                                   |    6 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/pallet/MesProPalletServiceImpl.java         |    5 +
 docs/mes_bag_code_bind_pallet_without_batch_integration.md                                                         |   80 ++++++++++++++++++++
 8 files changed, 171 insertions(+), 12 deletions(-)

diff --git a/docs/mes_bag_code_bind_pallet_without_batch_integration.md b/docs/mes_bag_code_bind_pallet_without_batch_integration.md
new file mode 100644
index 0000000..5dd3c06
--- /dev/null
+++ b/docs/mes_bag_code_bind_pallet_without_batch_integration.md
@@ -0,0 +1,80 @@
+# 琚嬬爜缁戝畾鎵樼洏锛堝厤鍏堝綍鎵规锛� - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- 璧嬬爜绠$悊锛堣鐮佸垪琛級鈫� 宸ュ叿鏍忋�岀粦瀹氭墭鐩樸�嶆寜閽� + 銆岃鐮佺粦瀹氭墭鐩樸�嶅脊绐�
+
+## 鍙e緞鍙樻洿
+
+鍘熴�岀粦瀹氭墭鐩樸�嶈姹傛墍閫夎鐮佸厛褰曞叆鐢熶骇鎵规锛屽惁鍒欐彁绀恒�岃鍏堝綍鍏ョ敓浜ф壒娆★紝鍐嶇粦瀹氭墭鐩樸�嶃�傜幇鍘绘帀璇ュ墠缃檺鍒讹紝鎸夊嬀閫夎鐮佺殑鎵规鐘舵�佸垎娴侊細
+
+| 鎵�閫夎鐮� | 鍙�夋墭鐩� | 缁戝畾缁撴灉 |
+|---|---|---|
+| 鍧囧凡褰曞叆鍚屼竴鎵规 | 璇ユ壒娆$殑鎵樼洏 | 浠呯粦瀹氭墭鐩橈紙涓庢敼閫犲墠涓�鑷达級 |
+| 鍧囨湭褰曞叆鎵规 | 璇ュ搧绉嶅彲鐢ㄧ殑鍏ㄩ儴鎵樼洏锛堜复鏃舵墭鐩� + 姝e紡鎵樼洏锛� | 缁戝埌涓存椂鎵樼洏锛氳鐮佷繚鎸佹湭褰曞叆鎵规锛涚粦鍒版煇鎵规鐨勬寮忔墭鐩橈細鍏堣嚜鍔ㄦ妸琚嬬爜琛ュ綍杩涜鎵规锛屽啀缁戝畾 |
+| 娣峰悎锛堥儴鍒嗗凡褰曟壒娆°�侀儴鍒嗘湭褰曪級 | 鈥� | 鍓嶇鎷︽埅锛屾彁绀哄垎寮�鎿嶄綔 |
+
+**瑙g粦涓嶅洖閫�鎵规**锛氳鐮佸洜缁戞墭鐩樿�岃ˉ褰曡繘鎵规鍚庯紝鍚庣画銆岃В缁戞墭鐩樸�嶅彧瑙i櫎鎵樼洏鍏崇郴锛屾壒娆″綊灞炰繚鐣欙紝涓庛�岀紪杈戞壒娆″彇娑堝嬀閫夋墭鐩樹笉鍥為��鐘舵�併�嶅彛寰勪竴鑷淬��
+
+## API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|---|---|---|
+| GET | /mes/pro/pallet/bindable-list | **鏂板**锛氳鐮佺粦瀹氭墭鐩樻椂鐨勫彲閫夌洰鏍囨墭鐩樺垪琛紙涓存椂鎵樼洏 + 姝e紡鎵樼洏锛屾帓闄ゅ凡浣滃簾锛� |
+| PUT | /mes/pro/bag-code/bind-pallet | 澶嶇敤锛岃姹備笌鍝嶅簲缁撴瀯涓嶅彉 |
+
+**璇锋眰鍙傛暟锛堟柊澧炴帴鍙o級锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|---|---|---|---|
+| itemId | Long | 鍚� | 琚嬬爜鍝佺缂栧彿銆備紶鍏ュ悗浠呰繑鍥炶鍝佺鐨勬墭鐩橈紝浠ュ強灏氭湭纭畾鍝佺鐨勯鐢熸垚涓存椂鎵樼洏锛坄item_id` 涓虹┖锛岀粦瀹氳鐮佹椂鍥炲~鍝佺锛� |
+
+**鍝嶅簲锛�** `MesProPalletRespVO` 鏁扮粍锛屽叧閿瓧娈碉細
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|---|---|---|
+| id | Long | 鎵樼洏缂栧彿锛堟彁浜ょ粦瀹氱敤锛� |
+| code | String | 姝e紡鎵樼洏鐮侊紱涓存椂鎵樼洏涓虹┖ |
+| tempCode | String | 涓存椂鎵樼洏鐮侊紱`code` 涓虹┖鏃剁敤瀹冨睍绀� |
+| batchId / batchCode | Long / String | 宸茬粦瀹氱殑鐢熶骇鎵规锛涗复鏃舵墭鐩樹负绌� |
+| itemId / itemName | Long / String | 鍝佺 |
+| bagCount | Integer | 宸茶琚嬫暟 |
+| capacity | Integer | 鍙琚嬫暟 |
+| status | Integer | 鎵樼洏鐘舵�侊紙瀛楀吀 `mes_pro_pallet_status`锛夛紝宸叉帓闄や綔搴�(20) |
+
+## 鎺ュ彛璋冪敤鏃跺簭
+
+1. 鐢ㄦ埛鍕鹃�夎鐮侊紝鐐瑰嚮銆岀粦瀹氭墭鐩樸�嶃��
+2. 鎸夊嬀閫夎鐮佺殑鎵规鐘舵�侀�夋嫨鎵樼洏鏁版嵁婧愶細
+   - 閮藉凡褰曞叆鍚屼竴鎵规 鈫� `GET /mes/pro/pallet/simple-list?batchId=`
+   - 閮芥湭褰曞叆鎵规 鈫� `GET /mes/pro/pallet/bindable-list?itemId=`锛宍itemId` 鍙栨墍閫夎鐮佺殑鍝佺
+3. 鎻愪氦 `PUT /mes/pro/bag-code/bind-pallet`锛宐ody 涓� `{ palletId, ids }`銆�
+
+## 瀛楁灞曠ず瑙勫垯
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|---|---|---|
+| batchCode | 寮圭獥銆岀敓浜ф壒娆°�嶈緭鍏ユ锛堝彧璇伙級 | 宸插綍鍏ユ壒娆℃樉绀烘壒娆″彿锛涙湭褰曞叆鎵规鏄剧ず銆屾湭褰曞叆鎵规銆� |
+| bagCount | 寮圭獥銆岀粦瀹氳鏁般�嶈緭鍏ユ锛堝彧璇伙級 | 鏈鍕鹃�夌殑琚嬬爜鏁伴噺 |
+| code / tempCode | 鎵樼洏涓嬫媺閫夐」 | 姝e紡鎵樼洏鍙� `code`锛屼复鏃舵墭鐩樺洖閫�鍒� `tempCode` |
+| batchCode | 鎵樼洏涓嬫媺閫夐」 | 鏈綍鍏ユ壒娆″満鏅笅鏄剧ず銆屾壒娆� xxx銆嶆垨銆屼复鏃舵墭鐩樸�嶏紝渚夸簬鍦ㄦ贩鍚堝垪琛ㄤ腑鍒嗚鲸 |
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|---|---|
+| 琚嬬爜宸插綍鍏ユ壒娆★紝鎵樼洏鍚屾壒娆� | 鍏佽 |
+| 琚嬬爜宸插綍鍏ユ壒娆★紝鎵樼洏璺ㄦ壒娆� | 鎷掔粷锛氳鐮佷笌鎵樼洏涓嶅睘浜庡悓涓�鐢熶骇鎵规锛屼笉鍏佽缁戝畾 |
+| 琚嬬爜鏈綍鍏ユ壒娆� + 涓存椂鎵樼洏 | 鍏佽锛涜鐮佷繚鎸佹湭褰曞叆鎵规锛屽悗缁�屽綍鍏ユ壒娆°�嶆椂鎸夋棦鏈夌骇鑱旈�昏緫鎶婅涓存椂鎵樼洏鍗囦负姝e紡鎵樼洏鐮� |
+| 琚嬬爜鏈綍鍏ユ壒娆� + 鏌愭壒娆℃寮忔墭鐩� | 鍏佽锛涘悗绔厛澶嶇敤銆屽綍鍏ユ壒娆°�嶉�昏緫鎶婅鐮佽ˉ褰曡繘璇ユ壒娆★紝鍐嶇粦瀹氭墭鐩� |
+| 琚嬬爜鏈綍鍏ユ壒娆� + 闈炵敓浜т腑鎵规 / 鏈ˉ褰曟壒娆� | 鎷掔粷锛氱敓浜ф壒娆′笉鏄敓浜т腑鐘舵�侊紝涓嶅厑璁哥敓鎴愯鐮�/鎵樼洏鐮侊紱鎴栫敓浜ф壒娆″皻鏈ˉ褰曟寮忎俊鎭� |
+| 琚嬬爜鏈綍鍏ユ壒娆� + 鍝佺涓庢壒娆′笉涓�鑷� | 鎷掔粷锛氳鐮�/鎵樼洏蹇呴』涓庢壒娆″搧绉嶄竴鑷� |
+| 鎵樼洏鏈粦瀹氭壒娆� + 琚嬬爜宸插綍鍏ユ壒娆� | 鎷掔粷锛氭墍閫夎鐮佸凡褰曞叆鐢熶骇鎵规锛岃鏀归�夎鎵规涓嬬殑鎵樼洏 |
+| 瑙g粦鎵樼洏 | 鍙В闄ゆ墭鐩樺叧绯伙紝鎵规褰掑睘涓嶅洖閫� |
+
+## 娉ㄦ剰浜嬮」
+
+- 銆岃ˉ褰曟壒娆� + 缁戝畾鎵樼洏銆嶅湪鍚屼竴浜嬪姟鍐呭畬鎴愶紝浠讳竴姝ユ牎楠屽け璐ユ暣浣撳洖婊氾紝涓嶄細鍑虹幇琚嬬爜宸茶繘鎵规浣嗘湭缁戞墭鐩樸��
+- 鏈綍鍏ユ壒娆″満鏅笅鎵樼洏涓嬫媺鍙兘杈冮暱锛岃淇濇寔 `showSearch` 骞舵寜琚嬬爜鍝佺浼� `itemId` 鏀剁獎鑼冨洿銆�
+- `bindable-list` 宸叉帓闄や綔搴熸墭鐩橈紱`simple-list` 鏈帓闄わ紝鍘熸湁鐨勫墠绔綔搴熻繃婊ら渶淇濈暀銆�
+- 琚嬬爜涓庢墭鐩樺繀椤诲悓鍝佺锛歚bindable-list` 鎸� `itemId` 杩囨护锛屼絾鍚庣浠嶄細浜屾鏍¢獙锛屽墠绔笉蹇呮嵁姝ゅ仛纭嫤鎴��
diff --git a/docs/mes_bag_code_integration.md b/docs/mes_bag_code_integration.md
index c574bc8..ea5c87d 100644
--- a/docs/mes_bag_code_integration.md
+++ b/docs/mes_bag_code_integration.md
@@ -112,13 +112,13 @@
 | 鎵樼洏缁戝畾鎵规 | 涓存椂鎵樼洏浠呰兘缁戝畾宸叉寮忚ˉ褰曚笖鐢熶骇涓殑鎵规锛涜法鎵规銆侀噸澶嶇粦瀹氳鎷掔粷 |
 | 涓存椂鎵樼洏鍑哄簱 | 鏈粦瀹氭壒娆$殑鎵樼洏绂佹鍙備笌閿�鍞嚭搴撶瓑涓氬姟鎿嶄綔 |
 | 琚嬬爜褰曞叆鎵规 | 浠呭厑璁哥敓浜т腑鐨勬寮忔壒娆★紱涓存椂鎵规涓嶅彲浣滀负褰曞叆鐩爣 |
-| 琚嬬爜缁戝畾鎵樼洏 | 鍙屾柟蹇呴』涓哄悓涓�姝e紡鎵规锛涙湭缁戝畾鎵规鐨勪复鏃舵墭鐩樹笉鍙弬涓庣粦瀹� |
+| 琚嬬爜缁戝畾鎵樼洏 | 鏈綍鍏ユ壒娆$殑琚嬬爜鍙粦涓存椂鎵樼洏锛屼篃鍙粦鏌愭壒娆$殑姝e紡鎵樼洏锛堟鏃跺厛鑷姩琛ュ綍鎵规鍐嶇粦瀹氾級锛涘凡褰曞叆鎵规鐨勮鐮佸彧鑳界粦鍚屾壒娆℃墭鐩� |
 | 浜岀淮鐮佸鍑� | 涓存椂鎵规/涓存椂鎵樼洏鎸変复鏃剁爜瀵煎嚭锛涗笟鍔′俊鎭负绌烘椂涓嶆樉绀鸿櫄鏋勫唴瀹� |
 | 鎵爜璇嗗埆 | `PB-YYYYYYYY`鈫掓壒娆°�乣PL-YYYYYYYY`鈫掓墭鐩樸�乣鎵规鍙�-PXX`鈫掓墭鐩樸�乣BAG-YYYYYYYY`鈫掕鐮侊紱姝e紡鎵规鍙�/鎵樼洏鐮佺収甯歌瘑鍒� |
 
 ## 娉ㄦ剰浜嬮」
 
-- 鍓嶇璋冪敤椤哄簭锛氭壒娆♀�滈鐢熸垚 鈫� 琛ュ綍淇℃伅 鈫� 寮�濮嬬敓浜р�濓紱鎵樼洏鈥滈鐢熸垚 鈫� 缁戝畾鎵规 鈫� 缁戝畾琚嬬爜鈥濓紱琚嬬爜鈥滅敓鎴� 鈫� 褰曞叆鎵规 鈫� 缁戝畾鎵樼洏鈥濄��
+- 鍓嶇璋冪敤椤哄簭锛氭壒娆♀�滈鐢熸垚 鈫� 琛ュ綍淇℃伅 鈫� 寮�濮嬬敓浜р�濓紱鎵樼洏鈥滈鐢熸垚 鈫� 缁戝畾鎵规 鈫� 缁戝畾琚嬬爜鈥濓紱琚嬬爜鈥滅敓鎴� 鈫� 缁戝畾鎵樼洏 鈫� 褰曞叆鎵规鈥濇垨鈥滅敓鎴� 鈫� 褰曞叆鎵规 鈫� 缁戝畾鎵樼洏鈥濆潎鍙紙缁戝畾鍒嗘壒娆$殑姝e紡鎵樼洏鏃朵細鑷姩琛ュ綍鎵规锛夈��
 - 鎵规姝e紡鍖栧悗 `tempCode` 涓嶅垹闄わ紝鍘嗗彶鎵撳嵃鐨勪复鏃朵簩缁寸爜鎵爜浠嶈兘杩芥函锛屽嬁鐢ㄦ寮忕爜瑕嗙洊涓存椂鐮併��
-- 涓存椂鎵樼洏鍦ㄧ粦瀹氭壒娆″墠涓嶅彲琚鐮佺粦瀹氥�佷笉鍙攢鍞嚭搴擄紱鎵归噺缁戝畾闇�鍏堝嬀閫夊鏉′复鏃舵墭鐩樿褰曘��
+- 涓存椂鎵樼洏鍦ㄧ粦瀹氭壒娆″墠鍙鏈綍鍏ユ壒娆$殑琚嬬爜缁戝畾锛堜笉鍙攢鍞嚭搴擄級锛涙壒閲忕粦瀹氶渶鍏堝嬀閫夊鏉′复鏃舵墭鐩樿褰曘��
 - 琛ュ綍/缁戝畾澶辫触鏃朵繚鐣欏綋鍓嶉�夋嫨锛岄伩鍏嶈浠ヤ负宸插畬鎴愪笟鍔″叧鑱斻��
\ No newline at end of file
diff --git a/docs/mes_pro_batch_bag_code_integration.md b/docs/mes_pro_batch_bag_code_integration.md
index 0ee97b4..a050290 100644
--- a/docs/mes_pro_batch_bag_code_integration.md
+++ b/docs/mes_pro_batch_bag_code_integration.md
@@ -249,7 +249,7 @@
 | 鎵规淇敼 | 浠呰崏绋�/鐢熶骇涓彲淇敼锛涗慨鏀瑰搧绉嶆垨浜х嚎缂栫爜浼氳嚜鍔ㄩ噸鏂扮敓鎴愭壒娆″彿 |
 | 鎵规鍒犻櫎 | 浠呰崏绋�/宸蹭綔搴熷彲鍒犻櫎锛涘凡鐢熸垚琚嬬爜鎴栨墭鐩樼爜鐨勬壒娆′笉鍏佽鍒犻櫎 |
 | 鐢熸垚缁勫垹闄� | 浠呯粍鍐呰鐮佸叏閮ㄤ负"宸茬敓鎴�"涓旀湭缁戝畾鎵樼洏鏃跺厑璁革紱鍒犻櫎鍚庢壒娆¤鐮佹暟閲忚嚜鍔ㄥ洖鍑� |
-| 琚嬬爜缁戝畾鎵樼洏 | 琚嬬爜涓庢墭鐩樺繀椤诲睘浜庡悓涓�鎵规锛涜鐮佹湭缁戝畾杩囨墭鐩橈紱缁戝畾鍚庢�绘暟涓嶈秴杩囨墭鐩樺彲瑁呰鏁� |
+| 琚嬬爜缁戝畾鎵樼洏 | 涓嶈姹傝鐮佸厛褰曞叆鎵规锛氭湭褰曞叆鎵规鐨勮鐮佸彲缁戜复鏃舵墭鐩橈紝涔熷彲缁戞煇鎵规鐨勬寮忔墭鐩橈紙姝ゆ椂鍏堣嚜鍔ㄨˉ褰曟壒娆″啀缁戝畾锛夛紱宸插綍鍏ユ壒娆$殑琚嬬爜鍙兘缁戝悓鎵规鎵樼洏锛涜鐮佹湭缁戝畾杩囨墭鐩橈紱缁戝畾鍚庢�绘暟涓嶈秴杩囨墭鐩樺彲瑁呰鏁� |
 | 瀵煎嚭鍗冲嵃鍒� | 瀵煎嚭 Excel 鍚庯紝瀵煎嚭鐨�"宸茬敓鎴�"琚嬬爜鑷姩鍙樹负"宸插鍑哄嵃鍒�"骞惰褰曟椂闂� |
 | 浜岀淮鐮佸唴瀹� | 浜岀淮鐮佸唴瀹� = 琚嬬爜瀛楃涓诧紙濡� PC20260818L01NY001-0001锛夛紝鎵爜鍚庤皟 get-by-code 鍙嶆煡 |
 
@@ -261,7 +261,7 @@
 
 - 鎵规鍙枫�佽鐮併�佹墭鐩樼爜鍧囩敱鍚庣鑷姩鐢熸垚锛�**鍓嶇琛ㄥ崟涓嶆彁渚涗换浣曠紪鐮佽緭鍏ユ**銆�
 - 鐢熸垚琚嬬爜/鎵樼洏鐮佸墠锛屽厛鐢� `GET /mes/pro/batch/simple-list` 璁╃敤鎴烽�夋嫨鎵规锛堝彧鍏佽閫夋嫨"鐢熶骇涓�"鐘舵�佺殑鎵规锛屽墠绔彲鎸� status=20 杩囨护锛夈��
-- 缁戝畾鎵樼洏鏃讹紝鎵樼洏涓嬫媺搴旇皟鐢� `GET /mes/pro/pallet/simple-list?batchId=`锛岀‘淇濇墭鐩樹笌琚嬬爜鍚屾壒娆°��
+- 缁戝畾鎵樼洏鏃讹紝鎵樼洏涓嬫媺鎸夎鐮佹壒娆$姸鎬佸垎娴侊細宸插綍鍏ユ壒娆$敤 `GET /mes/pro/pallet/simple-list?batchId=`锛涙湭褰曞叆鎵规鐢� `GET /mes/pro/pallet/bindable-list?itemId=`銆傝瑙� `mes_bag_code_bind_pallet_without_batch_integration.md`銆�
 - 鐢熸垚琚嬬爜鐨� `count` 涓烘墜鍔ㄨ緭鍏ョ殑鏈琚嬫暟锛屽彲鑳藉垎澶氭鐢熸垚锛屽簭鍙疯嚜鍔ㄦ帴缁紝涓嶄細閲嶅銆�
 - 鎵爜杩芥函鎺ュ彛瀵逛笉瀛樺湪鐨勮鐮佽繑鍥為敊璇紙閿欒鐮� 1040752000锛夛紝鍓嶇闇�鎻愮ず"琚嬬爜涓嶅瓨鍦�"銆�
 - 瀵煎嚭琚嬬爜 Excel 浼氭敼鍙樿鐮佺姸鎬侊紙宸茬敓鎴� 鈫� 宸插鍑哄嵃鍒凤級锛屽鍑哄悗璇峰埛鏂板垪琛紱閲嶅瀵煎嚭鍚屼竴鏁版嵁鍖呬笉浼氶噸澶嶅彉鏇寸姸鎬併��
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/pallet/MesProPalletController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/pallet/MesProPalletController.java
index 511b68e..51614da 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/pallet/MesProPalletController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/pallet/MesProPalletController.java
@@ -163,6 +163,16 @@
         return success(buildPalletRespVOList(list));
     }
 
+    @GetMapping("/bindable-list")
+    @Operation(summary = "鑾峰緱琚嬬爜缁戝畾鎵樼洏鏃跺彲閫夌殑鐩爣鎵樼洏鍒楄〃锛堜复鏃舵墭鐩� + 姝e紡鎵樼洏锛屾帓闄ゅ凡浣滃簾锛�")
+    @Parameter(name = "itemId", description = "琚嬬爜鍝佺缂栧彿锛堝彲閫夛紝鐢ㄤ簬杩囨护闈炲悓鍝佺鎵樼洏锛�", example = "1024")
+    @PreAuthorize("@ss.hasPermission('mes:pro-pallet:query')")
+    public CommonResult<List<MesProPalletRespVO>> getBindablePalletList(
+            @RequestParam(value = "itemId", required = false) Long itemId) {
+        List<MesProPalletDO> list = palletService.getBindablePalletList(itemId);
+        return success(buildPalletRespVOList(list));
+    }
+
     @GetMapping("/export-excel")
     @Operation(summary = "瀵煎嚭鎵樼洏鐮� Excel")
     @PreAuthorize("@ss.hasPermission('mes:pro-pallet:export')")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/pallet/MesProPalletMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/pallet/MesProPalletMapper.java
index 045b669..6c1b01f 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/pallet/MesProPalletMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/pallet/MesProPalletMapper.java
@@ -56,6 +56,22 @@
                 .orderByAsc(MesProPalletDO::getId));
     }
 
+    /**
+     * 鏌ヨ琚嬬爜缁戝畾鎵樼洏鏃跺彲閫夌殑鐩爣鎵樼洏锛氭湭浣滃簾鐨勪复鏃舵墭鐩樹笌姝e紡鎵樼洏銆�
+     * <p>
+     * 浼犲叆鍝佺鏃朵粎杩斿洖璇ュ搧绉嶇殑鎵樼洏锛屼互鍙婂皻鏈‘瀹氬搧绉嶇殑棰勭敓鎴愪复鏃舵墭鐩橈紙item_id 涓虹┖锛岀粦瀹氳鐮佹椂鍥炲~鍝佺锛夈��
+     *
+     * @param itemId 琚嬬爜鍝佺缂栧彿锛屽彲涓虹┖
+     * @return 鎵樼洏鍒楄〃
+     */
+    default List<MesProPalletDO> selectBindableList(Long itemId) {
+        return selectList(new LambdaQueryWrapperX<MesProPalletDO>()
+                .ne(MesProPalletDO::getStatus, MesProPalletStatusEnum.CANCELED.getStatus())
+                .and(itemId != null, q -> q.eq(MesProPalletDO::getItemId, itemId)
+                        .or().isNull(MesProPalletDO::getItemId))
+                .orderByDesc(MesProPalletDO::getId));
+    }
+
     default PageResult<MesProPalletDO> selectPage(MesProPalletPageReqVO reqVO) {
         return selectPage(reqVO, new LambdaQueryWrapperX<MesProPalletDO>()
                 .likeIfPresent(MesProPalletDO::getBusinessCode, reqVO.getBusinessCode())
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/bagcode/MesProBagCodeServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/bagcode/MesProBagCodeServiceImpl.java
index ddd169b..bfcd3af 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/bagcode/MesProBagCodeServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/bagcode/MesProBagCodeServiceImpl.java
@@ -223,7 +223,20 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void bindBatch(MesProBagCodeBindBatchReqVO bindReqVO) {
-        MesProBatchDO batch = batchMapper.selectByIdForUpdate(bindReqVO.getBatchId());
+        doBindBatch(bindReqVO.getBatchId(), bindReqVO.getIds());
+    }
+
+    /**
+     * 灏嗚鐮佸綍鍏ユ寚瀹氭壒娆★紝鍔犻攣椤哄簭涓恒�屾壒娆� 鈫� 琚嬬爜 鈫� 鎵樼洏銆嶃��
+     * <p>
+     * 銆屽綍鍏ユ壒娆°�嶄笌銆岀粦瀹氭墭鐩樸�嶅叡鐢ㄦ瀹炵幇锛氱粦瀹氭墭鐩樻椂鑻ユ墭鐩樺凡灞炴煇鎵规銆佽�屾墍閫夎鐮佸皻鏈綍鍏ユ壒娆★紝
+     * 鍏堟寜鏈柟娉曞畬鎴愬綍鍏ワ紝浠庤�屼繚璇佹壒娆″噯鍏ユ牎楠屻�佸搧绉嶄竴鑷存�ф牎楠屻�佹壒娆℃眹鎬诲洖鍐欎笌瀹屾暣鎬ц褰曞彧鏈変竴浠姐��
+     *
+     * @param batchId 鐢熶骇鎵规缂栧彿
+     * @param rawIds  寰呭綍鍏ョ殑琚嬬爜缂栧彿锛堟湭鍘婚噸锛�
+     */
+    private void doBindBatch(Long batchId, List<Long> rawIds) {
+        MesProBatchDO batch = batchMapper.selectByIdForUpdate(batchId);
         if (batch == null) {
             throw exception(PRO_BATCH_NOT_EXISTS);
         }
@@ -234,7 +247,7 @@
         if (StrUtil.isEmpty(batch.getCode())) {
             throw exception(PRO_BATCH_NOT_FILLED);
         }
-        List<Long> ids = bindReqVO.getIds().stream().distinct().toList();
+        List<Long> ids = rawIds.stream().distinct().toList();
         List<MesProBagCodeDO> bagCodes = bagCodeMapper.selectListByIdsForUpdate(ids);
         if (bagCodes.size() != ids.size() || bagCodes.stream().anyMatch(code ->
                 code.getBatchId() != null
@@ -459,13 +472,40 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void bindPallet(MesProBagCodeBindReqVO bindReqVO) {
-        // 1. 閿佸畾鎵樼洏锛岄伩鍏嶄笌鑷姩褰掗泦骞跺彂淇敼琚嬫暟
+        // 1. 鏃犻攣棰勮鎵樼洏涓庢墍閫夎鐮侊紝鍒ゆ柇鏄惁闇�瑕佸厛涓烘湭褰曞叆鎵规鐨勮鐮佽ˉ褰曟壒娆°��
+        //    鍔犻攣椤哄簭蹇呴』涓庛�屽綍鍏ユ壒娆°�嶄竴鑷达紙鎵规 鈫� 琚嬬爜 鈫� 鎵樼洏锛夛紝鍚﹀垯涓や釜鍏ュ彛骞跺彂鏃朵氦鍙夌瓑寰呬細姝婚攣銆�
+        List<Long> ids = bindReqVO.getIds().stream().distinct().toList();
+        MesProPalletDO palletSnapshot = palletMapper.selectById(bindReqVO.getPalletId());
+        if (palletSnapshot == null) {
+            throw exception(PRO_PALLET_NOT_EXISTS);
+        }
+        List<MesProBagCodeDO> snapshots = bagCodeMapper.selectListByIds(ids);
+        if (snapshots.size() != ids.size()) {
+            throw exception(PRO_BAG_CODE_NOT_EXISTS);
+        }
+        // 2. 鎵樼洏鏈粦瀹氭壒娆℃椂锛岃鐮佷篃蹇呴』鏈綍鍏ユ壒娆★紙鍙嶅悜涓嶆垚绔嬶細鏈綍鍏ユ壒娆$殑琚嬬爜鍙粦鍒颁换鎰忔墭鐩橈級
+        if (palletSnapshot.getBatchId() == null
+                && snapshots.stream().anyMatch(code -> code.getBatchId() != null)) {
+            throw new cn.iocoder.yudao.framework.common.exception.ServiceException(400,
+                    "鎵�閫夎鐮佸凡褰曞叆鐢熶骇鎵规锛岃鏀归�夎鎵规涓嬬殑鎵樼洏");
+        }
+        // 3. 鎵樼洏宸茬粦瀹氭壒娆°�佷笖瀛樺湪鏈綍鍏ユ壒娆$殑琚嬬爜鏃讹紝澶嶇敤銆屽綍鍏ユ壒娆°�嶉�昏緫琛ュ綍
+        if (palletSnapshot.getBatchId() != null) {
+            List<Long> unboundIds = snapshots.stream()
+                    .filter(code -> code.getBatchId() == null && code.getPalletId() == null
+                            && !MesProBagCodeStatusEnum.CANCELED.getStatus().equals(code.getStatus()))
+                    .map(MesProBagCodeDO::getId).toList();
+            if (!unboundIds.isEmpty()) {
+                doBindBatch(palletSnapshot.getBatchId(), unboundIds);
+            }
+        }
+        // 4. 閿佸畾鎵樼洏锛岄伩鍏嶄笌鑷姩褰掗泦骞跺彂淇敼琚嬫暟
         MesProPalletDO pallet = palletMapper.selectByIdForUpdate(bindReqVO.getPalletId());
         if (pallet == null) {
             throw exception(PRO_PALLET_NOT_EXISTS);
         }
-        // 2. 閿佸畾骞舵牎楠岃鐮�
-        List<MesProBagCodeDO> bagCodes = validateBagCodesForBind(bindReqVO.getIds(), pallet, true);
+        // 5. 閿佸畾骞舵牎楠岃鐮侊紙褰曞叆鎵规鍚庯紝琚嬬爜涓庢墭鐩樺繀鐒跺悓鎵规锛�
+        List<MesProBagCodeDO> bagCodes = validateBagCodesForBind(ids, pallet, true);
         Long itemId = cn.iocoder.yudao.module.mes.service.pro.pallet.MesProPalletItemResolver.resolve(pallet,
                 bagCodeMapper.selectListByPalletId(pallet.getId()));
         for (MesProBagCodeDO bag : bagCodes) {
@@ -473,9 +513,9 @@
             itemId = cn.iocoder.yudao.module.mes.service.pro.pallet.MesProPalletItemResolver.merge(itemId, bag.getItemId());
         }
         palletMapper.updateById(new MesProPalletDO().setId(pallet.getId()).setItemId(itemId));
-        // 3. 缁戝畾琚嬬爜骞剁疮鍔犳墭鐩樺凡瑁呰鏁帮紙鎵樼洏鏃犲閲忎笂闄愶級
+        // 6. 缁戝畾琚嬬爜骞剁疮鍔犳墭鐩樺凡瑁呰鏁帮紙鎵樼洏鏃犲閲忎笂闄愶級
         int currentCount = pallet.getBagCount() == null ? 0 : pallet.getBagCount();
-        bagCodeMapper.bindPalletByIds(bindReqVO.getIds(), pallet.getId(), StrUtil.isNotBlank(pallet.getCode()) ? pallet.getCode() : pallet.getTempCode());
+        bagCodeMapper.bindPalletByIds(ids, pallet.getId(), StrUtil.isNotBlank(pallet.getCode()) ? pallet.getCode() : pallet.getTempCode());
         palletService.updatePalletBagCount(pallet.getId(), currentCount + bagCodes.size());
     }
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/pallet/MesProPalletService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/pallet/MesProPalletService.java
index 704855b..8aea7bb 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/pallet/MesProPalletService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/pallet/MesProPalletService.java
@@ -102,6 +102,14 @@
     List<MesProPalletDO> getUnboundPalletList();
 
     /**
+     * 鑾峰緱琚嬬爜缁戝畾鎵樼洏鏃跺彲閫夌殑鐩爣鎵樼洏鍒楄〃锛堜复鏃舵墭鐩� + 姝e紡鎵樼洏锛屾帓闄ゅ凡浣滃簾锛�
+     *
+     * @param itemId 琚嬬爜鍝佺缂栧彿锛岀敤浜庤繃婊ら潪鍚屽搧绉嶆墭鐩橈紱鍙负绌�
+     * @return 鎵樼洏鐮佸垪琛�
+     */
+    List<MesProPalletDO> getBindablePalletList(Long itemId);
+
+    /**
      * 鑾峰緱鎵樼洏鐮佸垪琛紙鎸夌紪鍙峰垪琛級
      *
      * @param ids 缂栧彿鍒楄〃
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/pallet/MesProPalletServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/pallet/MesProPalletServiceImpl.java
index ec1de18..2d48d63 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/pallet/MesProPalletServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/pallet/MesProPalletServiceImpl.java
@@ -290,6 +290,11 @@
     }
 
     @Override
+    public List<MesProPalletDO> getBindablePalletList(Long itemId) {
+        return palletMapper.selectBindableList(itemId);
+    }
+
+    @Override
     public List<MesProPalletDO> getPalletListByIds(Collection<Long> ids) {
         if (CollUtil.isEmpty(ids)) {
             return List.of();

--
Gitblit v1.9.3