From 3aa3f9e730127147236c9e7627920dd8aacf3a36 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 15 七月 2026 15:49:59 +0800
Subject: [PATCH] 1.仓储物流-批次号优化覆盖数据 2.仓储物流-新增自定义出入库流水查询 3.采购管理-清理无用代码和表 4.销售管理-清理无用代码和表 5.销售流程状态字段数据回游

---
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/sale/ErpSaleOrderMapper.java                                  |   29 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/materialstock/MesWmMaterialStockServiceImpl.java             |  116 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/dto/MesWmTransactionSaveReqDTO.java              |    5 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockAdjustReqVO.java |   29 
 docs/mdm_mes_item_sync.md                                                                                                          |  343 +++++
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinanceReceiptController.java               |    8 
 yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/api/sale/ErpSaleOrderApi.java                                       |   12 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemSaveReqVO.java                     |    3 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transaction/MesWmTransactionController.java         |  161 ++
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemBatchConfigApiImpl.java                                 |   37 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java                               |  110 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeServiceImpl.java                 |    9 
 yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/item/dto/MesMdItemSyncReqDTO.java                               |   23 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/finance/ErpFinanceReceiptDO.java                         |    1 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemSyncApiImpl.java                                        |  102 +
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemSyncApi.java                                            |   25 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/transaction/MesWmTransactionMapper.java                    |   19 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionService.java                     |   11 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/no/ErpNoRedisDAO.java                                         |    4 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseOrderServiceImpl.java                       |   12 
 yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/api/sale/enums/ErpSaleOrderOutStatusEnum.java                       |    7 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/dto/MdmItemCategoryRespDTO.java                            |    6 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/item/MesMdItemApiImpl.java                                          |   41 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/category/MdmItemCategoryServiceImpl.java                        |    5 
 docs/erp_sale_order_status_feedback.md                                                                                             |  111 +
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemBatchConfigRespDTO.java                             |   95 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java                |    3 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/MdmItemCategoryApi.java                                    |    8 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/dal/dataobject/category/MdmItemCategoryDO.java                          |    5 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseOrderDO.java                         |   10 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemBatchConfigService.java                             |   35 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderRespVO.java                  |   19 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemBatchConfigApi.java                                     |   56 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemBatchConfigServiceImpl.java                         |   61 +
 yudao-module-mes/src/main/resources/mapper/wm/batch/MesWmBatchMapper.xml                                                           |    7 
 delete_erp_customer.ps1                                                                                                            |   12 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/MdmItemController.java                            |   47 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java                 |   30 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemTypeServiceImpl.java                           |   74 +
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/dal/mysql/category/MdmItemCategoryMapper.java                           |    4 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemServiceImpl.java                                    |   98 +
 docs/material_stock_adjust.md                                                                                                      |   42 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemBatchConfigServiceImpl.java                    |   86 +
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/category/MdmItemCategoryService.java                            |    8 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java               |   10 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/category/vo/MdmItemCategoryRespVO.java                 |    3 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/category/vo/MdmItemCategorySaveReqVO.java              |    3 
 delete_purchase_request.bat                                                                                                        |   30 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpSaleOrderDO.java                                 |    9 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemSaveReqVO.java                          |   23 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderService.java                                   |    8 
 docs/wm_transaction_list.md                                                                                                        |  135 ++
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/api/sale/ErpSaleOrderApiImpl.java                                       |   10 
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/MdmItemCategoryApiImpl.java                                |    6 
 docs/mdm_item_batch_config.md                                                                                                      |  215 +++
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemSyncReqDTO.java                                     |  109 +
 yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemRespVO.java                             |   23 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java                               |   37 
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpSaleOrderItemDO.java                             |    7 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchGenerateReqVO.java               |    5 
 docs/item_type_integration.md                                                                                                      |  145 +-
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java                             |  315 +++-
 yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderPageReqVO.java               |   38 
 /dev/null                                                                                                                          |   97 -
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transaction/vo/MesWmTransactionPageReqVO.java       |   58 +
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transaction/vo/MesWmTransactionRespVO.java          |   82 +
 docs/wm_transaction_query.md                                                                                                       |  167 ++
 67 files changed, 2,940 insertions(+), 524 deletions(-)

diff --git a/delete_erp_customer.ps1 b/delete_erp_customer.ps1
new file mode 100644
index 0000000..a4e812a
--- /dev/null
+++ b/delete_erp_customer.ps1
@@ -0,0 +1,12 @@
+# ERP 瀹㈡埛鐩稿叧鏂囦欢鍒犻櫎鑴氭湰
+# 璇峰湪 PowerShell 涓墽琛屼互涓嬪懡浠わ細
+
+Remove-Item -Force "yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpCustomerController.java"
+Remove-Item -Recurse -Force "yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer"
+Remove-Item -Force "yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpCustomerService.java"
+Remove-Item -Force "yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpCustomerServiceImpl.java"
+Remove-Item -Force "yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpCustomerDO.java"
+Remove-Item -Force "yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/sale/ErpCustomerMapper.java"
+Remove-Item -Force "yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpSaleOrderOutStatusEnum.java"
+
+Write-Host "ERP Customer files deleted successfully!"
diff --git a/delete_purchase_request.bat b/delete_purchase_request.bat
new file mode 100644
index 0000000..e622743
--- /dev/null
+++ b/delete_purchase_request.bat
@@ -0,0 +1,30 @@
+@echo off
+chcp 65001
+echo 姝e湪鍒犻櫎 ERP 閲囪喘鐢宠鐩稿叧浠g爜鏂囦欢...
+
+REM 鍒犻櫎 Controller
+del /f "yudao-module-erp\src\main\java\cn\iocoder\yudao\module\erp\controller\admin\purchase\ErpPurchaseRequestController.java"
+
+REM 鍒犻櫎 VO 鐩綍
+rd /s /q "yudao-module-erp\src\main\java\cn\iocoder\yudao\module\erp\controller\admin\purchase\vo\request"
+
+REM 鍒犻櫎 Service
+del /f "yudao-module-erp\src\main\java\cn\iocoder\yudao\module\erp\service\purchase\ErpPurchaseRequestService.java"
+del /f "yudao-module-erp\src\main\java\cn\iocoder\yudao\module\erp\service\purchase\ErpPurchaseRequestServiceImpl.java"
+
+REM 鍒犻櫎 Listener
+del /f "yudao-module-erp\src\main\java\cn\iocoder\yudao\module\erp\service\purchase\listener\ErpPurchaseRequestStatusListener.java"
+
+REM 鍒犻櫎 DO
+del /f "yudao-module-erp\src\main\java\cn\iocoder\yudao\module\erp\dal\dataobject\purchase\ErpPurchaseRequestDO.java"
+del /f "yudao-module-erp\src\main\java\cn\iocoder\yudao\module\erp\dal\dataobject\purchase\ErpPurchaseRequestItemDO.java"
+
+REM 鍒犻櫎 Mapper
+del /f "yudao-module-erp\src\main\java\cn\iocoder\yudao\module\erp\dal\mysql\purchase\ErpPurchaseRequestMapper.java"
+del /f "yudao-module-erp\src\main\java\cn\iocoder\yudao\module\erp\dal\mysql\purchase\ErpPurchaseRequestItemMapper.java"
+
+REM 鍒犻櫎 Enum
+del /f "yudao-module-erp\src\main\java\cn\iocoder\yudao\module\erp\enums\ErpPurchaseRequestStatusEnum.java"
+
+echo 鏂囦欢鍒犻櫎瀹屾垚锛�
+pause
\ No newline at end of file
diff --git a/docs/erp_sale_order_status_feedback.md b/docs/erp_sale_order_status_feedback.md
new file mode 100644
index 0000000..5c0e56a
--- /dev/null
+++ b/docs/erp_sale_order_status_feedback.md
@@ -0,0 +1,111 @@
+# ERP 閿�鍞鍗曞嚭搴撶姸鎬佸疄鏃跺弽棣� - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- ERP 閿�鍞鍗曞垪琛ㄩ〉
+- ERP 閿�鍞鍗曡鎯呴〉
+- MES 鍙戣揣閫氱煡鍗曠鐞嗛〉
+- MES 閿�鍞嚭搴撳崟绠$悊椤�
+
+## 涓氬姟娴佺▼涓庣姸鎬佸彉鍖�
+
+### 鐘舵�佹灇涓捐鏄�
+
+| 鐘舵�佸�� | 鐘舵�佸悕绉� | 璇存槑 |
+|--------|----------|------|
+| 0 | 鏈嚭搴� | 閿�鍞鍗曞垵濮嬬姸鎬侊紝鏈紑濮嬪嚭搴撴祦绋� |
+| 1 | 宸查鐣� | 鍙戣揣閫氱煡鍗曞鏍搁�氳繃锛屽簱瀛樺凡棰勭暀 |
+| 2 | 閮ㄥ垎鍑哄簱 | 閿�鍞嚭搴撳崟宸叉嫞璐�/鍗犵敤搴撳瓨 |
+| 3 | 鍏ㄩ儴鍑哄簱 | 閿�鍞嚭搴撳崟宸插畬鎴愬嚭搴� |
+
+### 鐘舵�佸彉鍖栨椂鏈�
+
+| 姝ラ | 鎿嶄綔 | 鐘舵�佸彉鍖� | 瑙﹀彂浣嶇疆 |
+|------|------|----------|----------|
+| 1 | 鍙戣揣閫氱煡鍗曞鏍搁�氳繃 | 0 鈫� 1锛堟湭鍑哄簱 鈫� 宸查鐣欙級 | MES 鍙戣揣閫氱煡鍗曟彁浜ゅ鏍� |
+| 2 | 閿�鍞嚭搴撳崟鎷h揣 | 1 鈫� 2锛堝凡棰勭暀 鈫� 閮ㄥ垎鍑哄簱锛� | MES 閿�鍞嚭搴撳崟鎷h揣纭 |
+| 3 | 閿�鍞嚭搴撳崟瀹屾垚 | 2 鈫� 3锛堥儴鍒嗗嚭搴� 鈫� 鍏ㄩ儴鍑哄簱锛� | MES 閿�鍞嚭搴撳崟瀹屾垚鍑哄簱 |
+
+## API 鍙樻洿
+
+### 鏂板 API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| PUT | /rpc-api/erp/sale-order/updateOrderOutStatusTo | 鏇存柊閿�鍞鍗曞嚭搴撶姸鎬佷负鎸囧畾鍊� |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| orderId | Long | 鏄� | 閿�鍞鍗曠紪鍙� |
+| outStatus | Integer | 鏄� | 鍑哄簱鐘舵�侊紙0-3锛� |
+
+**鍝嶅簲锛�**
+
+```json
+{
+  "code": 0,
+  "data": true,
+  "msg": "鎿嶄綔鎴愬姛"
+}
+```
+
+### 鍝嶅簲瀛楁鍙樻洿
+
+**ErpSaleOrderRespDTO 鏂板瀛楁锛�**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| outStatus | Integer | 鍑哄簱鐘舵�侊紙0-3锛� |
+| outCount | BigDecimal | 宸插嚭搴撴暟閲� |
+
+**ErpSaleOrderItemRespDTO 鏂板瀛楁锛�**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| outCount | BigDecimal | 宸插嚭搴撴暟閲� |
+
+## 瀛楁灞曠ず瑙勫垯
+
+### 閿�鍞鍗曞垪琛�
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| 鍑哄簱鐘舵�� | 鍒楄〃 | 浣跨敤 Tag 鏍囩灞曠ず锛屼笉鍚岀姸鎬佷笉鍚岄鑹� |
+| 宸插嚭搴撴暟閲� | 鍒楄〃 | 鏍煎紡锛歚宸插嚭搴撴暟閲�/鎬绘暟閲廯 |
+
+### 閿�鍞鍗曡鎯�
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| 鍑哄簱鐘舵�� | 鍩烘湰淇℃伅鍖� | 浣跨敤 Tag 鏍囩灞曠ず |
+| 宸插嚭搴撴暟閲� | 鍩烘湰淇℃伅鍖� | 鏁板�煎睍绀� |
+| 璁㈠崟鏄庣粏-宸插嚭搴撴暟閲� | 鏄庣粏琛ㄦ牸 | 姣忚鏄剧ず璇ラ」鐨勫凡鍑哄簱鏁伴噺 |
+
+### 鍑哄簱鐘舵�侀鑹插缓璁�
+
+| 鐘舵�� | 棰滆壊 | Tag 绫诲瀷 |
+|------|------|----------|
+| 鏈嚭搴� | 鐏拌壊 | info |
+| 宸查鐣� | 钃濊壊 | primary |
+| 閮ㄥ垎鍑哄簱 | 姗欒壊 | warning |
+| 鍏ㄩ儴鍑哄簱 | 缁胯壊 | success |
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 鍙戣揣閫氱煡鍗曞鏍� | 瀹℃牳閫氳繃鏃惰嚜鍔ㄦ洿鏂板叧鑱旈攢鍞鍗曠姸鎬佷负"宸查鐣�" |
+| 閿�鍞嚭搴撳崟鎷h揣 | 鎷h揣纭鏃惰嚜鍔ㄦ洿鏂板叧鑱旈攢鍞鍗曠姸鎬佷负"閮ㄥ垎鍑哄簱" |
+| 閿�鍞嚭搴撳崟瀹屾垚 | 鍑哄簱瀹屾垚鏃惰嚜鍔ㄦ洿鏂板叧鑱旈攢鍞鍗曠姸鎬佷负"鍏ㄩ儴鍑哄簱"锛屽苟绱鍑哄簱鏁伴噺 |
+| 鍙栨秷鍙戣揣閫氱煡鍗� | 濡傛灉鍙栨秷锛岄渶瑕佸皢閿�鍞鍗曠姸鎬佸洖閫� |
+| 鍙栨秷閿�鍞嚭搴撳崟 | 濡傛灉鍙栨秷锛岄渶瑕佸皢閿�鍞鍗曠姸鎬佸洖閫� |
+
+## 娉ㄦ剰浜嬮」
+
+1. **鐘舵�佸疄鏃舵��**锛歁ES 妯″潡鎿嶄綔鍚庣珛鍗冲洖鍐� ERP 閿�鍞鍗曠姸鎬侊紝鍓嶇鍒锋柊鍗冲彲鐪嬪埌鏈�鏂扮姸鎬�
+2. **澶氬崟鎹叧鑱�**锛氫竴涓攢鍞鍗曞彲鑳藉搴斿涓彂璐ч�氱煡鍗曞拰閿�鍞嚭搴撳崟锛岀姸鎬佷細鎸夋祦绋嬫帹杩�
+3. **鐘舵�佸洖閫�**锛氱洰鍓嶄粎瀹炵幇鐘舵�佹帹杩涳紝鏆備笉鏀寔鐘舵�佸洖閫�锛堝鍙栨秷鍚庣姸鎬佹仮澶嶏級
+4. **鍑哄簱鏁伴噺绱**锛氬彧鏈夐攢鍞嚭搴撳崟瀹屾垚鏃舵墠浼氱疮璁″嚭搴撴暟閲忥紝鎷h揣闃舵浠呮洿鏂扮姸鎬�
+5. **骞跺彂鎺у埗**锛氱姸鎬佹洿鏂版湁浜嬪姟淇濊瘉锛岄伩鍏嶅苟鍙戞洿鏂板鑷寸姸鎬佷笉涓�鑷�
\ No newline at end of file
diff --git a/docs/item_type_integration.md b/docs/item_type_integration.md
index 2132109..5c83110 100644
--- a/docs/item_type_integration.md
+++ b/docs/item_type_integration.md
@@ -1,111 +1,120 @@
-# 鐗╂枡鍒嗙被缁熶竴浣跨敤 mes_md_item_type - 鍓嶇鑱旇皟鏂规
+# 鐗╂枡鍒嗙被缁熶竴浣跨敤 mdm_item_category - 鍓嶇鑱旇皟鏂规
+
+## 鍙樻洿璇存槑
+
+鐗╂枡鍒嗙被宸蹭粠 MES 妯″潡杩佺Щ鍒� MDM 妯″潡缁熶竴绠$悊锛�
+- 鍘� MES 鍒嗙被琛� `mes_md_item_type` 淇濈暀浣嗕笉鍐嶇淮鎶�
+- 缁熶竴浣跨敤 MDM 鍒嗙被琛� `mdm_item_category`
+- MES 妯″潡閫氳繃鍏煎灞傝鍙� MDM 鍒嗙被鏁版嵁
 
 ## 娑夊強椤甸潰
 
-- MDM 鐗╂枡绠$悊椤甸潰锛堟柊澧�/缂栬緫鐗╂枡锛�
-- MES 鐗╂枡绠$悊椤甸潰锛堟柊澧�/缂栬緫鐗╂枡锛�
+- MDM 鐗╂枡鍒嗙被绠$悊椤甸潰锛堜富瑕佺淮鎶ゅ叆鍙o級
+- MDM 鐗╂枡绠$悊椤甸潰锛堟柊澧�/缂栬緫鐗╂枡閫夋嫨鍒嗙被锛�
+- MES 鐗╂枡绠$悊椤甸潰锛堟柊澧�/缂栬緫鐗╂枡閫夋嫨鍒嗙被锛�
 
 ## 涓氬姟娴佺▼涓庢暟鎹甫鍏�
 
-1. 鐗╂枡鍒嗙被缁熶竴浣跨敤 `mes_md_item_type` 琛紝MDM 鍜� MES 妯″潡鍏辩敤鍚屼竴濂楀垎绫绘暟鎹�
-2. 鐗╂枡绫诲瀷瀛楁 `itemType` 鐢ㄤ簬蹇�熼�夋嫨锛�1鍘熸枡銆�2鍗婃垚鍝併��3鎴愬搧銆�4杈呮枡
-3. 褰撻�夋嫨 `categoryId` 鏃讹紝鐩存帴鍏宠仈鍒嗙被 ID锛涘綋鍙�夋嫨 `itemType` 鏃讹紝绯荤粺鑷姩鍖归厤瀵瑰簲鍚嶇О鐨勫垎绫�
+1. 鐗╂枡鍒嗙被缁熶竴浣跨敤 `mdm_item_category` 琛紝MDM 鍜� MES 妯″潡鍏辩敤鍚屼竴濂楀垎绫绘暟鎹�
+2. 鍒嗙被鏂板 `itemOrProduct` 瀛楁鍏煎 MES 鐨� ITEM/PRODUCT 鏍囪瘑
+3. 鐗╂枡绫诲瀷瀛楁 `itemType` 鐢ㄤ簬蹇�熼�夋嫨锛�1鍘熸枡銆�2鍗婃垚鍝併��3鎴愬搧銆�4杈呮枡
+
+## 瀛楁鏄犲皠
+
+| MDM 瀛楁 (mdm_item_category) | MES 瀛楁 (mes_md_item_type) | 璇存槑 |
+|------------------------------|----------------------------|------|
+| id | id | 鍒嗙被缂栧彿 |
+| code | code | 鍒嗙被缂栫爜 |
+| name | name | 鍒嗙被鍚嶇О |
+| parentId | parentId | 鐖跺垎绫荤紪鍙� |
+| itemType (Integer) | itemOrProduct (String) | 绫诲瀷鏍囪瘑 |
+| sort | sort | 鎺掑簭 |
+| status | status | 鐘舵�� |
+| remark | remark | 澶囨敞 |
+
+### itemType 涓� itemOrProduct 鏄犲皠鍏崇郴
+
+| itemType | 璇存槑 | itemOrProduct |
+|----------|------|---------------|
+| 1 | 鐗╂枡 | ITEM |
+| 2 | 浜у搧 | PRODUCT |
+| 3 | 鍗婃垚鍝� | ITEM |
+| NULL | 鍏ㄩ儴 | - |
 
 ## API
 
-### 鑾峰彇鐗╂枡鍒嗙被鍒楄〃
+### MDM 鍒嗙被绠$悊锛堜富瑕佹帴鍙o級
 
 | 鏂规硶 | 璺緞 | 璇存槑 |
 |------|------|------|
-| GET | /admin-api/mes/md/item-type/list | 鑾峰彇鐗╂枡鍒嗙被鍒楄〃 |
+| POST | /admin-api/mdm/category/create | 鍒涘缓鐗╂枡鍒嗙被 |
+| PUT | /admin-api/mdm/category/update | 鏇存柊鐗╂枡鍒嗙被 |
+| DELETE | /admin-api/mdm/category/delete | 鍒犻櫎鐗╂枡鍒嗙被 |
+| GET | /admin-api/mdm/category/get | 鑾峰彇鍗曚釜鍒嗙被 |
+| GET | /admin-api/mdm/category/list | 鑾峰彇鍒嗙被鍒楄〃 |
+| GET | /admin-api/mdm/category/list-all-simple | 鑾峰彇鍚敤鐨勫垎绫诲垪琛紙涓嬫媺妗嗭級 |
 
-**璇锋眰鍙傛暟锛�**
+**璇锋眰鍙傛暟锛圡dmItemCategorySaveReqVO锛夛細**
 
 | 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
 |------|------|------|------|
-| status | Integer | 鍚� | 鐘舵�佺瓫閫� |
-
-**鍝嶅簲瀛楁锛�**
-
-| 瀛楁 | 绫诲瀷 | 璇存槑 |
-|------|------|------|
-| id | Long | 鍒嗙被缂栧彿 |
-| code | String | 鍒嗙被缂栫爜 |
-| name | String | 鍒嗙被鍚嶇О |
-| parentId | Long | 鐖跺垎绫荤紪鍙� |
-| itemOrProduct | String | 鐗╂枡/浜у搧鏍囪瘑 |
-| sort | Integer | 鎺掑簭 |
-| status | Integer | 鐘舵�� |
+| id | Long | 鍚� | 鍒嗙被缂栧彿锛堟洿鏂版椂蹇呭~锛� |
+| parentId | Long | 鍚� | 鐖跺垎绫荤紪鍙� |
+| code | String | 鏄� | 鍒嗙被缂栫爜 |
+| name | String | 鏄� | 鍒嗙被鍚嶇О |
+| itemType | Integer | 鍚� | 閫傜敤鐗╂枡绫诲瀷锛�1鐗╂枡銆�2浜у搧銆�3鍗婃垚鍝併�丯ULL鍏ㄩ儴 |
+| itemOrProduct | String | 鍚� | 鐗╂枡/浜у搧鏍囪瘑锛欼TEM銆丳RODUCT锛堝吋瀹筂ES锛� |
+| sort | Integer | 鍚� | 鎺掑簭 |
+| status | Integer | 鏄� | 鐘舵�侊細0鍚敤銆�1绂佺敤 |
+| remark | String | 鍚� | 澶囨敞 |
 
 **鍝嶅簲绀轰緥锛�**
 
 ```json
 {
   "code": 0,
-  "data": [
-    {
-      "id": 1,
-      "code": "RAW001",
-      "name": "鍘熸枡",
-      "parentId": 0,
-      "itemOrProduct": "1",
-      "sort": 1,
-      "status": 0
-    }
-  ]
+  "data": {
+    "id": 1,
+    "parentId": 0,
+    "code": "RAW001",
+    "name": "鍘熸枡",
+    "itemType": 1,
+    "itemOrProduct": "ITEM",
+    "sort": 0,
+    "status": 0
+  }
 }
 ```
 
-### 鑾峰彇鐗╂枡鍒嗙被璇︽儏
+### MES 鍒嗙被鎺ュ彛锛堝吋瀹逛繚鐣欙級
 
 | 鏂规硶 | 璺緞 | 璇存槑 |
 |------|------|------|
-| GET | /admin-api/mes/md/item-type/get | 鑾峰彇鐗╂枡鍒嗙被璇︽儏 |
+| GET | /admin-api/mes/md/item-type/list | 鑾峰彇鐗╂枡鍒嗙被鍒楄〃 |
+| GET | /admin-api/mes/md/item-type/simple-list | 鑾峰彇绮剧畝鍒楄〃锛堜笅鎷夋锛� |
 
-**璇锋眰鍙傛暟锛�**
-
-| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
-|------|------|------|------|
-| id | Long | 鏄� | 鍒嗙被缂栧彿 |
-
-### 淇濆瓨鐗╂枡鍒嗙被
-
-| 鏂规硶 | 璺緞 | 璇存槑 |
-|------|------|------|
-| POST | /admin-api/mes/md/item-type/create | 鍒涘缓鐗╂枡鍒嗙被 |
-| PUT | /admin-api/mes/md/item-type/update | 鏇存柊鐗╂枡鍒嗙被 |
-
-**璇锋眰鍙傛暟锛�**
-
-| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
-|------|------|------|------|
-| id | Long | 鍚� | 鍒嗙被缂栧彿锛堟洿鏂版椂蹇呭~锛� |
-| code | String | 鏄� | 鍒嗙被缂栫爜 |
-| name | String | 鏄� | 鍒嗙被鍚嶇О |
-| parentId | Long | 鍚� | 鐖跺垎绫荤紪鍙� |
-| itemOrProduct | String | 鍚� | 鐗╂枡/浜у搧鏍囪瘑 |
-| sort | Integer | 鍚� | 鎺掑簭 |
-| status | Integer | 鍚� | 鐘舵�� |
+> 娉ㄦ剰锛歁ES 鍒嗙被鎺ュ彛搴曞眰宸叉敼涓鸿鍙� MDM 鍒嗙被鏁版嵁锛屽缓璁墠绔粺涓�浣跨敤 MDM 鍒嗙被鎺ュ彛銆�
 
 ## 瀛楁灞曠ず瑙勫垯
 
 | 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
 |------|----------|------|
-| categoryId | 鏂板/缂栬緫琛ㄥ崟 | 鐗╂枡鍒嗙被涓嬫媺妗嗭紝鏁版嵁鏉ユ簮锛歮es_md_item_type |
+| categoryId / itemTypeId | 鏂板/缂栬緫琛ㄥ崟 | 鐗╂枡鍒嗙被涓嬫媺妗嗭紝鏁版嵁鏉ユ簮锛歮dm_item_category |
 | itemType | 鏂板/缂栬緫琛ㄥ崟 | 鐗╂枡绫诲瀷蹇嵎閫夋嫨锛�1鍘熸枡銆�2鍗婃垚鍝併��3鎴愬搧銆�4杈呮枡 |
+| itemOrProduct | 鍒嗙被琛ㄥ崟 | 鐗╂枡/浜у搧鏍囪瘑锛岀敤浜� MES 鍏煎 |
 
 ## 涓氬姟瑙勫垯璇存槑
 
 | 鍦烘櫙 | 瑙勫垯 |
 |------|------|
-| 鐗╂枡鍒嗙被閫夋嫨 | 浣跨敤 `mes_md_item_type` 琛紝MDM 鍜� MES 鍏辩敤鍚屼竴濂楀垎绫绘暟鎹� |
-| itemType 涓� categoryId 鍏崇郴 | 褰� categoryId 涓虹┖鏃讹紝鍙牴鎹� itemType 鑷姩鍖归厤瀵瑰簲鍚嶇О鐨勫垎绫� |
-| itemType 鏄犲皠 | 1鈫掑師鏂欙紝2鈫掑崐鎴愬搧锛�3鈫掓垚鍝侊紝4鈫掕緟鏂� |
-| 鍒嗙被鏍¢獙 | 淇濆瓨鐗╂枡鏃讹紝浼氶�氳繃 RPC API 鏍¢獙鍒嗙被鏄惁瀛樺湪 |
+| 鍒嗙被绠$悊 | 缁熶竴鍦� MDM 妯″潡绠$悊锛孧ES 妯″潡鍙 |
+| 鍒嗙被鍒犻櫎 | 鏈夊瓙鍒嗙被鎴栨湁鐗╂枡寮曠敤鏃朵笉鍙垹闄� |
+| 鐗╂枡鍚屾 | MDM 鐗╂枡鍚屾鍒� MES 鏃讹紝鍒嗙被 ID 淇濇寔涓�鑷� |
+| 鍏煎鎬� | MES 鍒嗙被鏈嶅姟浼樺厛浠� MDM 鑾峰彇锛屾湰鍦拌〃浣滀负鍥為�� |
 
 ## 娉ㄦ剰浜嬮」
 
-- 鐗╂枡鍒嗙被鏁版嵁鍦� MES 妯″潡绠$悊锛孧DM 妯″潡閫氳繃 RPC API 璋冪敤鑾峰彇
-- `itemType` 鏄揩鎹烽�夋嫨瀛楁锛屾渶缁堜細杞崲涓哄搴旂殑鍒嗙被缂栫爜
-- 濡傛灉鍚屾椂璁剧疆浜� `categoryId` 鍜� `itemType`锛屼紭鍏堜娇鐢� `categoryId`
-- 鍒嗙被鏀寔鏍戝舰缁撴瀯锛屽彲閫氳繃 `parentId` 鏋勫缓灞傜骇鍏崇郴
+1. **鑿滃崟鍙樻洿**锛歁ES 鐨�"鐗╂枡浜у搧鍒嗙被"鑿滃崟宸茬鐢紝缁熶竴浣跨敤 MDM 鐨�"鐗╂枡鍒嗙被"鑿滃崟
+2. **鏁版嵁涓�鑷存��**锛氫袱琛ㄦ暟鎹凡鍚屾锛屽悗缁淮鎶ゅ彧闇�鎿嶄綔 MDM 鍒嗙被
+3. **API 鍏煎**锛歁ES 鍒嗙被鎺ュ彛淇濈暀锛屽簳灞傝鍙� MDM 鏁版嵁锛屽墠绔彲缁х画浣跨敤
+4. **瀛楁杞崲**锛氬墠绔睍绀烘椂锛宍itemOrProduct` 鍊奸渶杞崲涓轰腑鏂囷紙ITEM=鐗╂枡锛孭RODUCT=浜у搧锛�
\ No newline at end of file
diff --git a/docs/material_stock_adjust.md b/docs/material_stock_adjust.md
index ada1faf..20adee6 100644
--- a/docs/material_stock_adjust.md
+++ b/docs/material_stock_adjust.md
@@ -29,8 +29,10 @@
 | warehouseId | Long | 鏄� | 浠撳簱ID |
 | locationId | Long | 鏄� | 搴撳尯ID |
 | areaId | Long | 鏄� | 搴撲綅ID |
-| batchId | Long | 鍚� | 鎵规ID |
-| batchCode | String | 鍚� | 鎵规鍙� |
+| batchId | Long | 鍚� | 鎵规ID锛堥�夋嫨宸叉湁鎵规鏃朵紶鍏ワ級 |
+| batchCode | String | 鍚� | 鎵规鍙凤紙鏂板缓鎵规鏃朵紶鍏ワ級 |
+| produceDate | DateTime | 鍚� | 鐢熶骇鏃ユ湡锛堟柊寤烘壒娆℃椂浼犲叆锛� |
+| expireDate | DateTime | 鍚� | 鏈夋晥鏈燂紙鏂板缓鎵规鏃朵紶鍏ワ級 |
 | vendorId | Long | 鍚� | 渚涘簲鍟咺D |
 | quantity | BigDecimal | 鏄� | 鍏ュ簱鏁伴噺锛堝繀椤诲ぇ浜�0锛� |
 | reason | String | 鍚� | 鍏ュ簱鍘熷洜 |
@@ -59,7 +61,7 @@
 | warehouseId | Long | 鏄� | 浠撳簱ID |
 | locationId | Long | 鏄� | 搴撳尯ID |
 | areaId | Long | 鏄� | 搴撲綅ID |
-| batchId | Long | 鍚� | 鎵规ID |
+| batchId | Long | 鍚� | 鎵规ID锛堝嚭搴撴椂鏍¢獙鎵规瀛樺湪锛� |
 | batchCode | String | 鍚� | 鎵规鍙� |
 | vendorId | Long | 鍚� | 渚涘簲鍟咺D |
 | quantity | BigDecimal | 鏄� | 鍑哄簱鏁伴噺锛堝繀椤诲ぇ浜�0锛� |
@@ -141,6 +143,40 @@
 | bizId | 搴撳瓨璁板綍ID | 搴撳瓨璁板綍ID |
 | bizCode | STOCK_ADJUST_{搴撳瓨ID} | STOCK_ADJUST_{搴撳瓨ID} |
 
+## 鎵规澶勭悊瑙勫垯
+
+鑷畾涔夊叆搴撴椂锛岀郴缁熶細鏍规嵁鐗╂枡鎵规閰嶇疆鑷姩澶勭悊鎵规锛�
+
+> **鎵规閰嶇疆鏉ユ簮**锛氬熀纭�鏁版嵁锛圡DM锛夌墿鏂欎富鏁版嵁鐨勬壒娆″睘鎬ч厤缃紝鍦ㄧ墿鏂欒鎯呴〉缁存姢銆�
+
+### 鍏ュ簱鎵规澶勭悊閫昏緫
+
+| 鎯呭喌 | 澶勭悊鏂瑰紡 |
+|------|---------|
+| 鐗╂枡鏈惎鐢ㄦ壒娆$鐞� | 涓嶅叧鑱旀壒娆� |
+| 浼犲叆 batchId | 鏍¢獙鎵规瀛樺湪涓斿綊灞炴纭紝浣跨敤宸叉湁鎵规 |
+| 鏈紶 batchId锛堢墿鏂欏惎鐢ㄦ壒娆$鐞嗭級 | 鏍规嵁鍙傛暟鑷姩鍒涘缓鎵规璁板綍 |
+
+### 鏂板缓鎵规鏃剁殑鍙傛暟
+
+褰撶墿鏂欏惎鐢ㄦ壒娆$鐞嗕笖鏈紶鍏� batchId 鏃讹紝鍙紶鍏ヤ互涓嬪弬鏁扮敤浜庡垱寤烘壒娆★細
+
+| 鍙傛暟 | 璇存槑 |
+|------|------|
+| batchCode | 鎵规鍙凤紙鍙�夛紝涓嶄紶鍒欑郴缁熻嚜鍔ㄧ敓鎴愶級 |
+| produceDate | 鐢熶骇鏃ユ湡 |
+| expireDate | 鏈夋晥鏈� |
+| vendorId | 渚涘簲鍟咺D |
+
+> 绯荤粺浼氭牴鎹墿鏂欑殑鎵规閰嶇疆鏍¢獙蹇呭~鍙傛暟锛堝鐢熶骇鏃ユ湡銆佹湁鏁堟湡绛夛級
+
+### 鍑哄簱鎵规澶勭悊閫昏緫
+
+| 鎯呭喌 | 澶勭悊鏂瑰紡 |
+|------|---------|
+| 鐗╂枡鏈惎鐢ㄦ壒娆$鐞� | 涓嶆牎楠屾壒娆� |
+| 浼犲叆 batchId | 鏍¢獙鎵规瀛樺湪涓斾笌鐗╂枡鍖归厤 |
+
 ## 娉ㄦ剰浜嬮」
 
 - 鍏ュ簱鏁伴噺/鍑哄簱鏁伴噺蹇呴』澶т簬0
diff --git a/docs/mdm_item_batch_config.md b/docs/mdm_item_batch_config.md
new file mode 100644
index 0000000..dfbef0c
--- /dev/null
+++ b/docs/mdm_item_batch_config.md
@@ -0,0 +1,215 @@
+# MDM 鐗╂枡鎵规灞炴�ч厤缃� - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- 鍩虹鏁版嵁 - 鐗╂枡浜у搧鍒楄〃椤�
+- 鐗╂枡璇︽儏/缂栬緫椤�
+- MES 鐢熶骇 - 鐗╂枡浜у搧璇︽儏椤�
+
+## 涓氬姟鍦烘櫙
+
+褰撶墿鏂欏惎鐢ㄦ壒娆$鐞嗭紙`isBatchManaged = true`锛夋椂锛岄渶瑕侀厤缃壒娆″睘鎬э紝瀹氫箟鍒涘缓鎵规鏃跺摢浜涘瓧娈垫槸蹇呭~鐨勩��
+
+**鎵规灞炴�у瓧娈碉紙浠呬繚鐣欎互涓�7涓級锛�**
+
+| 瀛楁 | 璇存槑 |
+|------|------|
+| 鐢熶骇鏃ユ湡 | 鎵规鐨勭敓浜ф棩鏈� |
+| 鏈夋晥鏈� | 鎵规鐨勫け鏁堟棩鏈� |
+| 鍏ュ簱鏃ユ湡 | 鎵规鐨勫叆搴撴棩鏈� |
+| 渚涘簲鍟� | 鎵规鐨勪緵搴斿晢 |
+| 閲囪喘璁㈠崟缂栧彿 | 鎵规鐨勯噰璐鍗曞彿 |
+| 鐢熶骇鎵瑰彿 | 鎵规鐨勬壒鍙� |
+| 璐ㄩ噺鐘舵�� | 鎵规鐨勮川閲忕姸鎬� |
+
+## 鍙屽悜鍚屾璇存槑
+
+```
+鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+鈹�                    鎵规閰嶇疆鍙屽悜鍚屾                           鈹�
+鈹溾攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+鈹�                                                             鈹�
+鈹�   MDM 鐗╂枡椤甸潰  鈫愨攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈫�  MES 鐗╂枡椤甸潰             鈹�
+鈹�        鈹�                                  鈹�                 鈹�
+鈹�        鈻�                                  鈻�                 鈹�
+鈹�   mdm_item_batch_config  鈫愨攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈫�  mes_md_item_batch_config 鈹�
+鈹�        鈹�                                  鈹�                 鈹�
+鈹�        鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�涓诲瓨鍌ㄢ攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�                 鈹�
+鈹�                                                             鈹�
+鈹�   璇存槑锛�                                                    鈹�
+鈹�   - MDM 琛ㄦ槸涓诲瓨鍌紝MES 琛ㄦ槸闀滃儚                            鈹�
+鈹�   - 浠绘剰涓�鏂逛慨鏀癸紝鑷姩鍚屾鍒板彟涓�鏂�                           鈹�
+鈹�   - 鏌ヨ鏃朵紭鍏堜粠 MDM 琛ㄨ幏鍙�                                 鈹�
+鈹�                                                             鈹�
+鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+```
+
+## API
+
+### 鑾峰彇鐗╂枡鎵规閰嶇疆
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | `/mes/md/item-batch-config/get-by-item-id` | 鏍规嵁鐗╂枡ID鑾峰彇鎵规閰嶇疆 |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| itemId | Long | 鏄� | 鐗╂枡ID |
+
+**鍝嶅簲锛�**
+
+```json
+{
+  "code": 0,
+  "data": {
+    "id": 1,
+    "itemId": 8,
+    "produceDateFlag": true,
+    "expireDateFlag": true,
+    "receiptDateFlag": false,
+    "vendorFlag": true,
+    "purchaseOrderCodeFlag": false,
+    "lotNumberFlag": true,
+    "qualityStatusFlag": false
+  },
+  "msg": "鎿嶄綔鎴愬姛"
+}
+```
+
+**鍝嶅簲瀛楁璇存槑锛�**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| id | Long | 閰嶇疆ID |
+| itemId | Long | 鐗╂枡ID |
+| produceDateFlag | Boolean | 鐢熶骇鏃ユ湡蹇呭~ |
+| expireDateFlag | Boolean | 鏈夋晥鏈熷繀濉� |
+| receiptDateFlag | Boolean | 鍏ュ簱鏃ユ湡蹇呭~ |
+| vendorFlag | Boolean | 渚涘簲鍟嗗繀濉� |
+| purchaseOrderCodeFlag | Boolean | 閲囪喘璁㈠崟鍙峰繀濉� |
+| lotNumberFlag | Boolean | 鐢熶骇鎵瑰彿蹇呭~ |
+| qualityStatusFlag | Boolean | 璐ㄩ噺鐘舵�佸繀濉� |
+
+### 淇濆瓨鐗╂枡鎵规閰嶇疆
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | `/mes/md/item-batch-config/save` | 淇濆瓨鎵规閰嶇疆锛堟柊澧�/鏇存柊锛� |
+
+**璇锋眰鍙傛暟锛�**
+
+```json
+{
+  "itemId": 8,
+  "produceDateFlag": true,
+  "expireDateFlag": true,
+  "receiptDateFlag": false,
+  "vendorFlag": true,
+  "purchaseOrderCodeFlag": false,
+  "lotNumberFlag": true,
+  "qualityStatusFlag": false
+}
+```
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| itemId | Long | 鏄� | 鐗╂枡ID |
+| produceDateFlag | Boolean | 鍚� | 鐢熶骇鏃ユ湡蹇呭~锛岄粯璁� false |
+| expireDateFlag | Boolean | 鍚� | 鏈夋晥鏈熷繀濉紝榛樿 false |
+| receiptDateFlag | Boolean | 鍚� | 鍏ュ簱鏃ユ湡蹇呭~锛岄粯璁� false |
+| vendorFlag | Boolean | 鍚� | 渚涘簲鍟嗗繀濉紝榛樿 false |
+| purchaseOrderCodeFlag | Boolean | 鍚� | 閲囪喘璁㈠崟鍙峰繀濉紝榛樿 false |
+| lotNumberFlag | Boolean | 鍚� | 鐢熶骇鎵瑰彿蹇呭~锛岄粯璁� false |
+| qualityStatusFlag | Boolean | 鍚� | 璐ㄩ噺鐘舵�佸繀濉紝榛樿 false |
+
+**鍝嶅簲锛�**
+
+```json
+{
+  "code": 0,
+  "data": 1,
+  "msg": "鎿嶄綔鎴愬姛"
+}
+```
+
+## 鍓嶇淇敼鐐�
+
+### 1. 鐗╂枡璇︽儏/缂栬緫椤�
+
+鍦ㄧ墿鏂欒鎯呴〉澧炲姞"鎵规灞炴�ч厤缃�"鍖哄潡銆�
+
+**灞曠ず鏉′欢锛�**
+- 褰撶墿鏂欑殑 `isBatchManaged = true` 鏃舵樉绀鸿閰嶇疆鍖哄潡
+- 褰撶墿鏂欑殑 `isBatchManaged = false` 鏃堕殣钘忚閰嶇疆鍖哄潡
+
+### 2. 鎵规灞炴�ч厤缃〃鍗�
+
+**琛ㄥ崟瀛楁锛堜粎7涓級锛�**
+
+| 瀛楁 | 鎺т欢绫诲瀷 | 璇存槑 |
+|------|----------|------|
+| 鐢熶骇鏃ユ湡 | el-checkbox | 鍕鹃�夎〃绀哄垱寤烘壒娆℃椂蹇呭~ |
+| 鏈夋晥鏈� | el-checkbox | 鍕鹃�夎〃绀哄垱寤烘壒娆℃椂蹇呭~ |
+| 鍏ュ簱鏃ユ湡 | el-checkbox | 鍕鹃�夎〃绀哄垱寤烘壒娆℃椂蹇呭~ |
+| 渚涘簲鍟� | el-checkbox | 鍕鹃�夎〃绀哄垱寤烘壒娆℃椂蹇呭~ |
+| 閲囪喘璁㈠崟鍙� | el-checkbox | 鍕鹃�夎〃绀哄垱寤烘壒娆℃椂蹇呭~ |
+| 鐢熶骇鎵瑰彿 | el-checkbox | 鍕鹃�夎〃绀哄垱寤烘壒娆℃椂蹇呭~ |
+| 璐ㄩ噺鐘舵�� | el-checkbox | 鍕鹃�夎〃绀哄垱寤烘壒娆℃椂蹇呭~ |
+
+**寤鸿甯冨眬锛�**
+
+```
+鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+鈹� 鎵规灞炴�ч厤缃�                                                  鈹�
+鈹溾攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+鈹�  鈽� 鐢熶骇鏃ユ湡    鈽� 鏈夋晥鏈�      鈽� 鍏ュ簱鏃ユ湡    鈽� 渚涘簲鍟�         鈹�
+鈹�  鈽� 閲囪喘璁㈠崟鍙�   鈽� 鐢熶骇鎵瑰彿    鈽� 璐ㄩ噺鐘舵��                    鈹�
+鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+```
+
+### 3. 鏁版嵁鍔犺浇閫昏緫
+
+**杩涘叆鐗╂枡璇︽儏椤垫椂锛�**
+
+1. 鍔犺浇鐗╂枡鍩烘湰淇℃伅
+2. 鍒ゆ柇 `isBatchManaged` 鏄惁涓� `true`
+3. 濡傛灉鏄紝璋冪敤 `GET /mes/md/item-batch-config/get-by-item-id?itemId={鐗╂枡ID}` 鑾峰彇閰嶇疆
+4. 娓叉煋閰嶇疆琛ㄥ崟锛屽皢杩斿洖鐨勯厤缃暟鎹粦瀹氬埌琛ㄥ崟
+
+**淇濆瓨鐗╂枡鏃讹細**
+
+1. 鍏堜繚瀛樼墿鏂欏熀鏈俊鎭�
+2. 濡傛灉 `isBatchManaged = true`锛岃皟鐢� `POST /mes/md/item-batch-config/save` 淇濆瓨鎵规閰嶇疆
+
+### 4. 鎺ㄨ崘榛樿閰嶇疆
+
+瀵逛簬甯歌鐨勯噰璐墿鏂欙紝鎺ㄨ崘榛樿閰嶇疆锛�
+
+| 瀛楁 | 鎺ㄨ崘 | 璇存槑 |
+|------|------|------|
+| 鐢熶骇鏃ユ湡 | 鈽� | 杩芥函鐢熶骇鏃堕棿 |
+| 鏈夋晥鏈� | 鈽� | 鏈変繚璐ㄦ湡鐨勭墿鏂� |
+| 鍏ュ簱鏃ユ湡 | 鈽� | 閫氬父鑷姩璁板綍 |
+| 渚涘簲鍟� | 鈽� | 閲囪喘鐗╂枡闇�瑕佽拷婧潵婧� |
+| 閲囪喘璁㈠崟鍙� | 鈽� | 鍙�� |
+| 鐢熶骇鎵瑰彿 | 鈽� | 鎵规杩芥函 |
+| 璐ㄩ噺鐘舵�� | 鈽� | 闇�瑕佽川妫�鏃朵娇鐢� |
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 鐗╂枡鏈惎鐢ㄦ壒娆$鐞� | 涓嶆樉绀烘壒娆″睘鎬ч厤缃尯鍧� |
+| 鐗╂枡鍚敤鎵规绠$悊浣嗘棤閰嶇疆 | 鍒涘缓鎵规鏃跺厑璁镐换鎰忓瓧娈碉紙瀹芥澗妯″紡锛� |
+| 鐗╂枡鍚敤鎵规绠$悊涓旀湁閰嶇疆 | 鍒涘缓鎵规鏃舵牎楠屽繀濉瓧娈� |
+| MDM 淇敼鎵规閰嶇疆 | 鑷姩鍚屾鍒� MES 琛� |
+| MES 淇敼鎵规閰嶇疆 | 鑷姩鍚屾鍒� MDM 琛� |
+
+## 娉ㄦ剰浜嬮」
+
+- 鎵规閰嶇疆鏄墿鏂欑骇鍒殑锛屾瘡涓墿鏂欑嫭绔嬮厤缃�
+- 淇敼鎵规閰嶇疆涓嶄細褰卞搷宸插垱寤虹殑鎵规锛屽彧褰卞搷鍚庣画鏂板垱寤虹殑鎵规
+- MDM 鍜� MES 鐨勬壒娆¢厤缃細鑷姩鍙屽悜鍚屾
+- 鍙繚鐣欏繀瑕佺殑7涓壒娆″睘鎬у瓧娈碉紝鍏朵粬瀛楁涓嶅啀浣跨敤
diff --git a/docs/mdm_mes_item_sync.md b/docs/mdm_mes_item_sync.md
new file mode 100644
index 0000000..977d17d
--- /dev/null
+++ b/docs/mdm_mes_item_sync.md
@@ -0,0 +1,343 @@
+# MDM 涓� MES 鐗╂枡鍙屽悜鍚屾 - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- MDM 妯″潡锛氱墿鏂欎富鏁版嵁鍒楄〃椤点�佺墿鏂欐柊澧�/缂栬緫椤�
+- MES 妯″潡锛氱墿鏂欎骇鍝佸垪琛ㄩ〉銆佺墿鏂欎骇鍝佹柊澧�/缂栬緫椤�
+
+## 涓氬姟娴佺▼璇存槑
+
+### 鍙屽悜鍚屾鍏崇郴
+
+```
+MDM 鐗╂枡 鈫愨�曗�曗�曗�曗�曗�曗啋 MES 鐗╂枡
+    鈫�                  鈫�
+    | syncMes=true     | syncMdm=true
+    鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+```
+
+| 鎿嶄綔绔� | 鍚屾瑙﹀彂鏉′欢 | 鍚屾鐩爣 |
+|--------|-------------|---------|
+| MDM 鏂板/缂栬緫鐗╂枡 | `syncMes = true` | MES `mes_md_item` + `mes_md_item_batch_config` |
+| MES 鏂板/缂栬緫鐗╂枡 | `syncMdm = true` | MDM `mdm_item` + `mdm_item_batch_config` |
+
+### 鎵规灞炴�у瓧娈碉紙7涓繀濉」锛�
+
+| 瀛楁 | 涓枃鍚� | 璇存槑 |
+|------|--------|------|
+| produceDateFlag | 鐢熶骇鏃ユ湡蹇呭~ | 鍏ュ簱鏃舵槸鍚﹀繀濉敓浜ф棩鏈� |
+| expireDateFlag | 鏈夋晥鏈熷繀濉� | 鍏ュ簱鏃舵槸鍚﹀繀濉湁鏁堟湡 |
+| receiptDateFlag | 鍏ュ簱鏃ユ湡蹇呭~ | 鍏ュ簱鏃舵槸鍚﹀繀濉叆搴撴棩鏈� |
+| vendorFlag | 渚涘簲鍟嗗繀濉� | 鍏ュ簱鏃舵槸鍚﹀繀濉緵搴斿晢 |
+| purchaseOrderCodeFlag | 閲囪喘璁㈠崟鍙峰繀濉� | 鍏ュ簱鏃舵槸鍚﹀繀濉噰璐鍗曞彿 |
+| lotNumberFlag | 鐢熶骇鎵瑰彿蹇呭~ | 鍏ュ簱鏃舵槸鍚﹀繀濉敓浜ф壒鍙� |
+| qualityStatusFlag | 璐ㄩ噺鐘舵�佸繀濉� | 鍏ュ簱鏃舵槸鍚﹀繀濉川閲忕姸鎬� |
+
+---
+
+## API
+
+### 1. MDM 鐗╂枡鏂板/缂栬緫
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | `/admin-api/mdm/item/create` | 鏂板 MDM 鐗╂枡 |
+| PUT | `/admin-api/mdm/item/update` | 缂栬緫 MDM 鐗╂枡 |
+
+**璇锋眰鍙傛暟锛圡dmItemSaveReqVO锛夛細**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鍚� | 鐗╂枡缂栧彿锛堢紪杈戞椂蹇呭~锛� |
+| code | String | 鏄� | 鐗╂枡缂栫爜 |
+| name | String | 鏄� | 鐗╂枡鍚嶇О |
+| specification | String | 鍚� | 瑙勬牸鍨嬪彿 |
+| categoryId | Long | 鍚� | 鍒嗙被ID锛堝叧鑱� MES 鐗╂枡鍒嗙被锛� |
+| unitMeasureId | Long | 鍚� | 璁¢噺鍗曚綅ID |
+| itemType | Integer | 鏄� | 鐗╂枡绫诲瀷锛�1鍘熸枡, 2鍗婃垚鍝�, 3鎴愬搧, 4杈呮枡 |
+| status | Integer | 鏄� | 鐘舵�侊細0鍚敤, 1绂佺敤 |
+| minStock | BigDecimal | 鍚� | 鏈�浣庡簱瀛� |
+| maxStock | BigDecimal | 鍚� | 鏈�楂樺簱瀛� |
+| isBatchManaged | Boolean | 鍚� | 鏄惁鎵规绠$悊 |
+| isHighValue | Boolean | 鍚� | 鏄惁楂樺�肩墿鏂� |
+| remark | String | 鍚� | 澶囨敞 |
+| **syncMes** | **Boolean** | **鍚�** | **鏄惁鍚屾鍒� MES** |
+| **produceDateFlag** | **Boolean** | **鍚�** | **鐢熶骇鏃ユ湡蹇呭~** |
+| **expireDateFlag** | **Boolean** | **鍚�** | **鏈夋晥鏈熷繀濉�** |
+| **receiptDateFlag** | **Boolean** | **鍚�** | **鍏ュ簱鏃ユ湡蹇呭~** |
+| **vendorFlag** | **Boolean** | **鍚�** | **渚涘簲鍟嗗繀濉�** |
+| **purchaseOrderCodeFlag** | **Boolean** | **鍚�** | **閲囪喘璁㈠崟鍙峰繀濉�** |
+| **lotNumberFlag** | **Boolean** | **鍚�** | **鐢熶骇鎵瑰彿蹇呭~** |
+| **qualityStatusFlag** | **Boolean** | **鍚�** | **璐ㄩ噺鐘舵�佸繀濉�** |
+
+**鍝嶅簲锛�**
+
+```json
+{
+  "code": 0,
+  "msg": "鎿嶄綔鎴愬姛",
+  "data": 123  // 鐗╂枡ID
+}
+```
+
+### 2. MES 鐗╂枡鏂板/缂栬緫
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | `/admin-api/mes/md-item/create` | 鏂板 MES 鐗╂枡 |
+| PUT | `/admin-api/mes/md-item/update` | 缂栬緫 MES 鐗╂枡 |
+
+**璇锋眰鍙傛暟锛圡esMdItemSaveReqVO锛夛細**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鍚� | 鐗╂枡缂栧彿锛堢紪杈戞椂蹇呭~锛� |
+| code | String | 鏄� | 鐗╂枡缂栫爜 |
+| name | String | 鏄� | 鐗╂枡鍚嶇О |
+| specification | String | 鍚� | 瑙勬牸鍨嬪彿 |
+| unitMeasureId | Long | 鏄� | 璁¢噺鍗曚綅ID |
+| itemTypeId | Long | 鏄� | 鐗╂枡鍒嗙被ID |
+| safeStockFlag | Boolean | 鍚� | 鏄惁鍚敤瀹夊叏搴撳瓨 |
+| minStock | BigDecimal | 鍚� | 鏈�浣庡簱瀛� |
+| maxStock | BigDecimal | 鍚� | 鏈�楂樺簱瀛� |
+| highValue | Boolean | 鍚� | 鏄惁楂樺�肩墿鏂� |
+| batchFlag | Boolean | 鍚� | 鏄惁鎵规绠$悊 |
+| remark | String | 鍚� | 澶囨敞 |
+| **syncMdm** | **Boolean** | **鍚�** | **鏄惁鍚屾鍒� MDM** |
+
+**鍝嶅簲锛�**
+
+```json
+{
+  "code": 0,
+  "msg": "鎿嶄綔鎴愬姛",
+  "data": 456  // 鐗╂枡ID
+}
+```
+
+### 3. MES 鎵规灞炴�ч厤缃繚瀛�
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | `/admin-api/mes/md-item-batch-config/create` | 鏂板鎵规閰嶇疆 |
+| PUT | `/admin-api/mes/md-item-batch-config/update` | 缂栬緫鎵规閰嶇疆 |
+
+**璇锋眰鍙傛暟锛圡esMdItemBatchConfigSaveReqVO锛夛細**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鍚� | 閰嶇疆ID锛堢紪杈戞椂蹇呭~锛� |
+| itemId | Long | 鏄� | 鐗╂枡ID |
+| produceDateFlag | Boolean | 鍚� | 鐢熶骇鏃ユ湡蹇呭~ |
+| expireDateFlag | Boolean | 鍚� | 鏈夋晥鏈熷繀濉� |
+| receiptDateFlag | Boolean | 鍚� | 鍏ュ簱鏃ユ湡蹇呭~ |
+| vendorFlag | Boolean | 鍚� | 渚涘簲鍟嗗繀濉� |
+| purchaseOrderCodeFlag | Boolean | 鍚� | 閲囪喘璁㈠崟鍙峰繀濉� |
+| lotNumberFlag | Boolean | 鍚� | 鐢熶骇鎵瑰彿蹇呭~ |
+| qualityStatusFlag | Boolean | 鍚� | 璐ㄩ噺鐘舵�佸繀濉� |
+
+**鍝嶅簲锛�**
+
+```json
+{
+  "code": 0,
+  "msg": "鎿嶄綔鎴愬姛",
+  "data": 789  // 閰嶇疆ID
+}
+```
+
+---
+
+## 鍓嶇淇敼鐐�
+
+### 1. MDM 鐗╂枡鏂板/缂栬緫椤甸潰
+
+#### 1.1 琛ㄥ崟瀛楁鏂板
+
+鍦ㄧ墿鏂欒〃鍗曚腑鏂板浠ヤ笅瀛楁锛�
+
+| 瀛楁 | 鎺т欢绫诲瀷 | 灞曠ず鏉′欢 | 璇存槑 |
+|------|----------|----------|------|
+| syncMes | Switch 寮�鍏� | 濮嬬粓鏄剧ず | 鏄惁鍚屾鍒� MES |
+| 鎵规灞炴�ч厤缃� | 鍒嗙粍鏍囬 | `isBatchManaged = true` 鏃舵樉绀� | 鎵规灞炴�у繀濉厤缃� |
+| produceDateFlag | Switch 寮�鍏� | `isBatchManaged = true` 鏃舵樉绀� | 鐢熶骇鏃ユ湡蹇呭~ |
+| expireDateFlag | Switch 寮�鍏� | `isBatchManaged = true` 鏃舵樉绀� | 鏈夋晥鏈熷繀濉� |
+| receiptDateFlag | Switch 寮�鍏� | `isBatchManaged = true` 鏃舵樉绀� | 鍏ュ簱鏃ユ湡蹇呭~ |
+| vendorFlag | Switch 寮�鍏� | `isBatchManaged = true` 鏃舵樉绀� | 渚涘簲鍟嗗繀濉� |
+| purchaseOrderCodeFlag | Switch 寮�鍏� | `isBatchManaged = true` 鏃舵樉绀� | 閲囪喘璁㈠崟鍙峰繀濉� |
+| lotNumberFlag | Switch 寮�鍏� | `isBatchManaged = true` 鏃舵樉绀� | 鐢熶骇鎵瑰彿蹇呭~ |
+| qualityStatusFlag | Switch 寮�鍏� | `isBatchManaged = true` 鏃舵樉绀� | 璐ㄩ噺鐘舵�佸繀濉� |
+
+#### 1.2 鏁版嵁缁撴瀯
+
+```javascript
+data() {
+  return {
+    form: {
+      // 鍘熸湁瀛楁...
+      syncMes: false,
+      // 鎵规灞炴�ч厤缃�
+      produceDateFlag: false,
+      expireDateFlag: false,
+      receiptDateFlag: false,
+      vendorFlag: false,
+      purchaseOrderCodeFlag: false,
+      lotNumberFlag: false,
+      qualityStatusFlag: false
+    }
+  }
+}
+```
+
+#### 1.3 鎻愪氦閫昏緫
+
+鎻愪氦鏃跺皢鎵�鏈夊瓧娈典竴璧锋彁浜ゅ埌 `/admin-api/mdm/item/create` 鎴� `/admin-api/mdm/item/update`銆�
+
+**娉ㄦ剰浜嬮」锛�**
+- 褰� `isBatchManaged = true` 鏃讹紝鏄剧ず鎵规灞炴�ч厤缃尯鍩�
+- 鍚庣浼氳嚜鍔ㄥ皢鎵规閰嶇疆淇濆瓨鍒� `mdm_item_batch_config` 琛�
+- 褰� `syncMes = true` 鏃讹紝鍚庣浼氬悓姝ョ墿鏂欏拰鎵规閰嶇疆鍒� MES
+
+---
+
+### 2. MES 鐗╂枡鏂板/缂栬緫椤甸潰
+
+#### 2.1 琛ㄥ崟瀛楁鏂板
+
+鍦ㄧ墿鏂欒〃鍗曚腑鏂板浠ヤ笅瀛楁锛�
+
+| 瀛楁 | 鎺т欢绫诲瀷 | 灞曠ず鏉′欢 | 璇存槑 |
+|------|----------|----------|------|
+| syncMdm | Switch 寮�鍏� | 濮嬬粓鏄剧ず | 鏄惁鍚屾鍒� MDM |
+
+#### 2.2 鏁版嵁缁撴瀯
+
+```javascript
+data() {
+  return {
+    form: {
+      // 鍘熸湁瀛楁...
+      syncMdm: false
+    }
+  }
+}
+```
+
+#### 2.3 鎻愪氦閫昏緫
+
+鎻愪氦鏃跺皢 `syncMdm` 瀛楁涓�璧锋彁浜ゃ��
+
+**娉ㄦ剰浜嬮」锛�**
+- 褰� `syncMdm = true` 鏃讹紝鍚庣浼氬悓姝ョ墿鏂欏拰鎵规閰嶇疆鍒� MDM
+- MES 鐨勬壒娆¢厤缃�氳繃鍗曠嫭鐨勬壒娆¢厤缃〉闈㈢淮鎶わ紙宸叉湁鍔熻兘锛�
+
+---
+
+### 3. MES 鎵规灞炴�ч厤缃〉闈紙宸叉湁鍔熻兘锛屾棤闇�淇敼锛�
+
+璇ラ〉闈㈠凡鏈夛紝鐢ㄤ簬閰嶇疆 MES 鐗╂枡鐨勬壒娆″睘鎬у繀濉」銆傚綋 MES 鐗╂枡鍚屾鍒� MDM 鏃讹紝浼氳嚜鍔ㄥ甫涓婅繖浜涢厤缃��
+
+---
+
+## 瀛楁灞曠ず瑙勫垯
+
+### MDM 鐗╂枡鍒楄〃椤�
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| code | 鍒楄〃銆佽鎯� | 鐗╂枡缂栫爜 |
+| name | 鍒楄〃銆佽鎯� | 鐗╂枡鍚嶇О |
+| specification | 鍒楄〃銆佽鎯� | 瑙勬牸鍨嬪彿 |
+| itemType | 鍒楄〃銆佽鎯� | 鐗╂枡绫诲瀷锛堥渶杞崲鏄剧ず锛�1鍘熸枡, 2鍗婃垚鍝�, 3鎴愬搧, 4杈呮枡锛� |
+| status | 鍒楄〃銆佽鎯� | 鐘舵�� |
+| isBatchManaged | 鍒楄〃銆佽鎯� | 鏄惁鎵规绠$悊 |
+| syncMes | 璇︽儏 | 鏄惁宸插悓姝ュ埌 MES锛堟牴鎹槸鍚︽湁瀵瑰簲 MES 鐗╂枡鍒ゆ柇锛� |
+
+### MES 鐗╂枡鍒楄〃椤�
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| code | 鍒楄〃銆佽鎯� | 鐗╂枡缂栫爜 |
+| name | 鍒楄〃銆佽鎯� | 鐗╂枡鍚嶇О |
+| specification | 鍒楄〃銆佽鎯� | 瑙勬牸鍨嬪彿 |
+| itemTypeName | 鍒楄〃銆佽鎯� | 鐗╂枡鍒嗙被鍚嶇О |
+| batchFlag | 鍒楄〃銆佽鎯� | 鏄惁鎵规绠$悊 |
+| syncMdm | 璇︽儏 | 鏄惁宸插悓姝ュ埌 MDM锛堟牴鎹槸鍚︽湁瀵瑰簲 MDM 鐗╂枡鍒ゆ柇锛� |
+
+---
+
+## 涓氬姟瑙勫垯璇存槑
+
+### 鍚屾瑙勫垯
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| MDM 鏂板鐗╂枡 + syncMes=true | 鍒涘缓 MDM 鐗╂枡 鈫� 鍚屾鍒涘缓 MES 鐗╂枡鍜屾壒娆¢厤缃� |
+| MDM 缂栬緫鐗╂枡 + syncMes=true | 鏇存柊 MDM 鐗╂枡 鈫� 鍚屾鏇存柊 MES 鐗╂枡鍜屾壒娆¢厤缃紙鎸� code 鍖归厤锛� |
+| MES 鏂板鐗╂枡 + syncMdm=true | 鍒涘缓 MES 鐗╂枡 鈫� 鍚屾鍒涘缓 MDM 鐗╂枡鍜屾壒娆¢厤缃� |
+| MES 缂栬緫鐗╂枡 + syncMdm=true | 鏇存柊 MES 鐗╂枡 鈫� 鍚屾鏇存柊 MDM 鐗╂枡鍜屾壒娆¢厤缃紙鎸� code 鍖归厤锛� |
+
+### 鎵规閰嶇疆鍚屾瑙勫垯
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| MDM 鈫� MES 鍚屾 | 灏� MDM 鐨� `mdm_item_batch_config` 鍚屾鍒� MES 鐨� `mes_md_item_batch_config` |
+| MES 鈫� MDM 鍚屾 | 灏� MES 鐨� `mes_md_item_batch_config` 鍚屾鍒� MDM 鐨� `mdm_item_batch_config` |
+
+### 瀛楁鏄犲皠瑙勫垯
+
+| MDM 瀛楁 | MES 瀛楁 | 璇存槑 |
+|----------|----------|------|
+| code | code | 鐗╂枡缂栫爜锛屽敮涓�鏍囪瘑 |
+| name | name | 鐗╂枡鍚嶇О |
+| specification | specification | 瑙勬牸鍨嬪彿 |
+| unitMeasureId (MDM 鍗曚綅ID) | unitMeasureId (MES 鍗曚綅ID) | 閫氳繃鍗曚綅缂栫爜杞崲 |
+| categoryId (MDM 鍒嗙被ID) | itemTypeId (MES 鍒嗙被ID) | 閫氳繃鍒嗙被缂栫爜杞崲 |
+| itemType | itemOrProduct | 1/2/4鈫扞TEM, 3鈫扨RODUCT |
+| isBatchManaged | batchFlag | 鏄惁鎵规绠$悊 |
+| isHighValue | highValue | 鏄惁楂樺�肩墿鏂� |
+| minStock | minStock | 鏈�浣庡簱瀛� |
+| maxStock | maxStock | 鏈�楂樺簱瀛� |
+
+### 鐗╂枡绫诲瀷鏄犲皠
+
+| MDM itemType | MDM 璇存槑 | MES itemOrProduct | MES 璇存槑 |
+|--------------|----------|-------------------|----------|
+| 1 | 鍘熸枡 | ITEM | 鐗╂枡 |
+| 2 | 鍗婃垚鍝� | ITEM | 鐗╂枡 |
+| 3 | 鎴愬搧 | PRODUCT | 浜у搧 |
+| 4 | 杈呮枡 | ITEM | 鐗╂枡 |
+
+---
+
+## 娉ㄦ剰浜嬮」
+
+1. **鍚屾澶辫触澶勭悊**锛氬悓姝ユ搷浣滀笌鐗╂枡淇濆瓨鏄悓涓�浜嬪姟锛屽鏋滃悓姝ュけ璐ワ紝鏁翠釜淇濆瓨鎿嶄綔浼氬洖婊氥��
+
+2. **缂栫爜鍞竴鎬�**锛氱墿鏂欑紪鐮侊紙code锛夊湪 MDM 鍜� MES 涓兘蹇呴』鍞竴锛屽悓姝ユ椂鎸� code 杩涜鍖归厤锛堝瓨鍦ㄥ垯鏇存柊锛屼笉瀛樺湪鍒欐柊澧烇級銆�
+
+3. **鍗曚綅/鍒嗙被鏄犲皠**锛歁DM 鍜� MES 鐨勫崟浣嶃�佸垎绫绘槸涓ゅ鐙珛鐨勪富鏁版嵁锛屽悓姝ユ椂閫氳繃缂栫爜锛坈ode锛夎繘琛屾槧灏勶紝纭繚涓よ竟鏈夌浉鍚岀殑缂栫爜鏁版嵁銆�
+
+4. **鎵规閰嶇疆鍚屾鏃舵満**锛�
+   - MDM 淇濆瓨鐗╂枡鏃讹紝鎵规閰嶇疆淇濆瓨鍒版湰鍦� `mdm_item_batch_config` 琛�
+   - 濡傛灉 `syncMes=true`锛屽悓鏃跺悓姝ュ埌 MES 鐨� `mes_md_item_batch_config` 琛�
+   - MES 鍚岀悊
+
+5. **鍓嶇灞曠ず寤鸿**锛�
+   - 鍦ㄥ垪琛ㄩ〉澧炲姞"鍚屾鐘舵��"鍒楋紝鏄剧ず鏄惁宸插悓姝ュ埌瀵规柟绯荤粺
+   - 鍙互閫氳繃鐗╂枡缂栫爜鏌ヨ瀵规柟绯荤粺鏄惁瀛樺湪鏉ュ垽鏂悓姝ョ姸鎬�
+
+6. **鏁版嵁涓�鑷存��**锛�
+   - 寤鸿鍦ㄤ竴绔淮鎶ょ墿鏂欐暟鎹悗锛屽悓姝ュ埌鍙︿竴绔�
+   - 閬垮厤涓よ竟鍚屾椂缂栬緫鍚屼竴鐗╂枡瀵艰嚧鏁版嵁鍐茬獊
+
+---
+
+## 璋冭瘯寤鸿
+
+1. 棣栧厛娴嬭瘯 MDM 鈫� MES 鍚屾锛氬垱寤� MDM 鐗╂枡锛屽嬀閫� syncMes锛屾鏌� MES 鏄惁鐢熸垚瀵瑰簲鐗╂枡
+2. 娴嬭瘯 MES 鈫� MDM 鍚屾锛氬垱寤� MES 鐗╂枡锛屽嬀閫� syncMdm锛屾鏌� MDM 鏄惁鐢熸垚瀵瑰簲鐗╂枡
+3. 娴嬭瘯鎵规閰嶇疆鍚屾锛氬湪 MDM 璁剧疆鎵规灞炴�э紝鍚屾鍚庢鏌� MES 鐨勬壒娆¢厤缃槸鍚︿竴鑷�
+4. 妫�鏌ユ暟鎹簱锛�
+   - MDM 鐗╂枡锛歚mdm_item`銆乣mdm_item_batch_config`
+   - MES 鐗╂枡锛歚mes_md_item`銆乣mes_md_item_batch_config`
diff --git a/docs/wm_transaction_list.md b/docs/wm_transaction_list.md
new file mode 100644
index 0000000..074afed
--- /dev/null
+++ b/docs/wm_transaction_list.md
@@ -0,0 +1,135 @@
+# 搴撳瓨浜嬪姟娴佹按 - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- 搴撳瓨浜嬪姟娴佹按鍒楄〃椤甸潰锛堟柊澧烇級
+
+## API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/wm/transaction/page | 鍒嗛〉鏌ヨ搴撳瓨浜嬪姟娴佹按 |
+
+### 璇锋眰鍙傛暟
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| itemId | Long | 鍚� | 鐗╂枡ID |
+| batchCode | String | 鍚� | 鎵规鍙凤紝妯$硦鍖归厤 |
+| warehouseId | Long | 鍚� | 浠撳簱ID |
+| locationId | Long | 鍚� | 搴撳尯ID |
+| areaId | Long | 鍚� | 搴撲綅ID |
+| type | Integer | 鍚� | 浜嬪姟绫诲瀷锛�1-鍏ュ簱 2-鍑哄簱锛� |
+| bizType | Integer | 鍚� | 涓氬姟绫诲瀷锛�126-鑷畾涔夊叆搴� 127-鑷畾涔夊嚭搴� 绛夛級 |
+| bizCode | String | 鍚� | 涓氬姟鍗曞彿锛屾ā绯婂尮閰� |
+| materialStockId | Long | 鍚� | 搴撳瓨璁板綍ID |
+| startTime | LocalDateTime | 鍚� | 寮�濮嬫椂闂� |
+| endTime | LocalDateTime | 鍚� | 缁撴潫鏃堕棿 |
+| pageNo | Integer | 鏄� | 椤电爜锛堢户鎵胯嚜 PageParam锛� |
+| pageSize | Integer | 鏄� | 姣忛〉鏉℃暟锛堢户鎵胯嚜 PageParam锛� |
+
+### 鍝嶅簲瀛楁
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| id | Long | 缂栧彿 |
+| type | Integer | 浜嬪姟绫诲瀷锛�1-鍏ュ簱 2-鍑哄簱锛� |
+| typeName | String | 浜嬪姟绫诲瀷鍚嶇О锛堝叆搴�/鍑哄簱锛� |
+| bizType | Integer | 涓氬姟绫诲瀷 |
+| bizTypeName | String | 涓氬姟绫诲瀷鍚嶇О锛堣嚜瀹氫箟鍏ュ簱/鑷畾涔夊嚭搴�/閲囪喘鍏ュ簱/閿�鍞嚭搴� 绛夛級 |
+| bizCode | String | 涓氬姟鍗曞彿 |
+| itemId | Long | 鐗╂枡ID |
+| itemCode | String | 鐗╂枡缂栫爜 |
+| itemName | String | 鐗╂枡鍚嶇О |
+| quantity | BigDecimal | 鍙樺姩鏁伴噺锛堟鏁�=鍏ュ簱锛岃礋鏁�=鍑哄簱锛� |
+| batchId | Long | 鎵规ID |
+| batchCode | String | 鎵规鍙� |
+| warehouseId | Long | 浠撳簱ID |
+| warehouseName | String | 浠撳簱鍚嶇О |
+| locationId | Long | 搴撳尯ID |
+| locationName | String | 搴撳尯鍚嶇О |
+| areaId | Long | 搴撲綅ID |
+| areaName | String | 搴撲綅鍚嶇О |
+| transactionTime | LocalDateTime | 浜嬪姟鍙戠敓鏃堕棿 |
+| createTime | LocalDateTime | 鍒涘缓鏃堕棿 |
+
+### 鍝嶅簲绀轰緥
+
+```json
+{
+  "code": 0,
+  "data": {
+    "total": 100,
+    "list": [
+      {
+        "id": 1,
+        "type": 1,
+        "typeName": "鍏ュ簱",
+        "bizType": 126,
+        "bizTypeName": "鑷畾涔夊叆搴�",
+        "bizCode": "STOCK_ADJUST_6",
+        "itemId": 2,
+        "itemCode": "ITEM001",
+        "itemName": "铻轰笣",
+        "quantity": 100,
+        "batchId": 7,
+        "batchCode": "T8811",
+        "warehouseId": 1,
+        "warehouseName": "鎴愬搧浠�",
+        "locationId": 1,
+        "locationName": "A鍖�",
+        "areaId": 1,
+        "areaName": "A-01-01",
+        "transactionTime": "2025-07-15 10:30:00",
+        "createTime": "2025-07-15 10:30:00"
+      }
+    ]
+  },
+  "msg": "鎿嶄綔鎴愬姛"
+}
+```
+
+## 瀛楁灞曠ず瑙勫垯
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| typeName | 鍒楄〃銆佽鎯� | 浜嬪姟绫诲瀷鍚嶇О锛屼娇鐢ㄦ爣绛惧睍绀猴紙鍏ュ簱=缁胯壊锛屽嚭搴�=绾㈣壊锛� |
+| bizTypeName | 鍒楄〃銆佽鎯� | 涓氬姟绫诲瀷鍚嶇О |
+| bizCode | 鍒楄〃銆佽鎯� | 涓氬姟鍗曞彿锛屽彲鐐瑰嚮璺宠浆鍒板搴斾笟鍔″崟鎹� |
+| itemCode | 鍒楄〃 | 鐗╂枡缂栫爜 |
+| itemName | 鍒楄〃 | 鐗╂枡鍚嶇О |
+| quantity | 鍒楄〃 | 鍙樺姩鏁伴噺锛屾鏁版樉绀虹豢鑹诧紝璐熸暟鏄剧ず绾㈣壊 |
+| batchCode | 鍒楄〃 | 鎵规鍙� |
+| warehouseName | 鍒楄〃 | 浠撳簱鍚嶇О |
+| locationName | 鍒楄〃 | 搴撳尯鍚嶇О |
+| areaName | 鍒楄〃 | 搴撲綅鍚嶇О |
+| transactionTime | 鍒楄〃 | 浜嬪姟鍙戠敓鏃堕棿锛屼綔涓洪粯璁ゆ帓搴忓瓧娈� |
+
+## 鎼滅储鏉′欢
+
+| 鏉′欢 | 缁勪欢 | 璇存槑 |
+|------|------|------|
+| 鐗╂枡 | 鐗╂枡閫夋嫨鍣� | 閫夋嫨鐗╂枡鍚庢煡璇� |
+| 鎵规鍙� | Input | 妯$硦鍖归厤 |
+| 浠撳簱 | 涓嬫媺閫夋嫨 | 閫夋嫨浠撳簱 |
+| 搴撳尯 | 涓嬫媺閫夋嫨 | 鏍规嵁浠撳簱鑱斿姩 |
+| 搴撲綅 | 涓嬫媺閫夋嫨 | 鏍规嵁搴撳尯鑱斿姩 |
+| 浜嬪姟绫诲瀷 | 涓嬫媺閫夋嫨 | 鍏ュ簱/鍑哄簱 |
+| 涓氬姟绫诲瀷 | 涓嬫媺閫夋嫨 | 鑷畾涔夊叆搴�/鑷畾涔夊嚭搴� 绛� |
+| 涓氬姟鍗曞彿 | Input | 妯$硦鍖归厤 |
+| 鏃堕棿鑼冨洿 | DatePicker | 浜嬪姟鍙戠敓鏃堕棿鑼冨洿 |
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 鏁版嵁鏉ユ簮 | 搴撳瓨浜嬪姟娴佹按鐢辩郴缁熻嚜鍔ㄧ敓鎴愶紝涓嶅彲浜哄伐鍒涘缓銆佷慨鏀广�佸垹闄� |
+| 鎺掑簭 | 榛樿鎸変簨鍔″彂鐢熸椂闂村�掑簭鎺掑垪 |
+| 鏉冮檺 | 闇�瑕� `mes:wm-transaction:query` 鏉冮檺 |
+
+## 娉ㄦ剰浜嬮」
+
+- 娴佹按璁板綍鍙锛屼笉鍏佽鏂板銆佷慨鏀广�佸垹闄�
+- quantity 瀛楁姝f暟琛ㄧず鍏ュ簱锛岃礋鏁拌〃绀哄嚭搴擄紝鍓嶇灞曠ず鏃跺彲鏍规嵁绗﹀彿鏄剧ず涓嶅悓棰滆壊
+- bizCode 鍙綔涓鸿烦杞摼鎺ワ紝鐐瑰嚮鍚庤烦杞埌瀵瑰簲鐨勪笟鍔″崟鎹鎯呴〉
+- 涓氬姟绫诲瀷杈冨锛屼笅鎷夐�夋嫨妗嗗缓璁寜浣跨敤棰戠巼鎺掑簭锛堣嚜瀹氫箟鍏ュ簱銆佽嚜瀹氫箟鍑哄簱鏀惧墠闈級
\ No newline at end of file
diff --git a/docs/wm_transaction_query.md b/docs/wm_transaction_query.md
new file mode 100644
index 0000000..33b616f
--- /dev/null
+++ b/docs/wm_transaction_query.md
@@ -0,0 +1,167 @@
+# 搴撳瓨浜嬪姟娴佹按鏌ヨ - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- 搴撳瓨浜嬪姟娴佹按鍒楄〃椤碉紙鏂板椤甸潰锛岃彍鍗曡矾寰勶細浠撳偍鐗╂祦 > 搴撳瓨浜嬪姟娴佹按锛�
+
+## API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/wm/transaction/page | 鍒嗛〉鏌ヨ搴撳瓨浜嬪姟娴佹按 |
+
+### 璇锋眰鍙傛暟
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| itemId | Long | 鍚� | 鐗╂枡ID |
+| batchCode | String | 鍚� | 鎵规鍙凤紝妯$硦鍖归厤 |
+| warehouseId | Long | 鍚� | 浠撳簱ID |
+| locationId | Long | 鍚� | 搴撳尯ID |
+| areaId | Long | 鍚� | 搴撲綅ID |
+| type | Integer | 鍚� | 浜嬪姟绫诲瀷锛�1-鍏ュ簱 2-鍑哄簱锛� |
+| bizType | Integer | 鍚� | 涓氬姟绫诲瀷 |
+| bizCode | String | 鍚� | 涓氬姟鍗曞彿锛屾ā绯婂尮閰� |
+| materialStockId | Long | 鍚� | 搴撳瓨璁板綍ID |
+| startTime | String | 鍚� | 寮�濮嬫椂闂达紙鏍煎紡锛歽yyy-MM-dd HH:mm:ss锛� |
+| endTime | String | 鍚� | 缁撴潫鏃堕棿锛堟牸寮忥細yyyy-MM-dd HH:mm:ss锛� |
+| pageNo | Integer | 鏄� | 椤电爜锛岄粯璁�1 |
+| pageSize | Integer | 鏄� | 姣忛〉鏉℃暟锛岄粯璁�10 |
+
+### 鍝嶅簲瀛楁
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| id | Long | 缂栧彿 |
+| type | Integer | 浜嬪姟绫诲瀷锛�1-鍏ュ簱 2-鍑哄簱锛� |
+| typeName | String | 浜嬪姟绫诲瀷鍚嶇О锛堝叆搴�/鍑哄簱锛� |
+| bizType | Integer | 涓氬姟绫诲瀷缂栫爜 |
+| bizTypeName | String | 涓氬姟绫诲瀷鍚嶇О |
+| bizCode | String | 涓氬姟鍗曞彿 |
+| itemId | Long | 鐗╂枡ID |
+| itemCode | String | 鐗╂枡缂栫爜 |
+| itemName | String | 鐗╂枡鍚嶇О |
+| quantity | BigDecimal | 鍙樺姩鏁伴噺锛堟鏁�=鍏ュ簱锛岃礋鏁�=鍑哄簱锛� |
+| batchId | Long | 鎵规ID |
+| batchCode | String | 鎵规鍙� |
+| warehouseId | Long | 浠撳簱ID |
+| warehouseName | String | 浠撳簱鍚嶇О |
+| locationId | Long | 搴撳尯ID |
+| locationName | String | 搴撳尯鍚嶇О |
+| areaId | Long | 搴撲綅ID |
+| areaName | String | 搴撲綅鍚嶇О |
+| transactionTime | String | 浜嬪姟鍙戠敓鏃堕棿 |
+| createTime | String | 鍒涘缓鏃堕棿 |
+
+### 鍝嶅簲绀轰緥
+
+```json
+{
+  "code": 0,
+  "data": {
+    "total": 50,
+    "list": [
+      {
+        "id": 1,
+        "type": 1,
+        "typeName": "鍏ュ簱",
+        "bizType": 126,
+        "bizTypeName": "鑷畾涔夊叆搴�",
+        "bizCode": "STOCK_ADJUST_6",
+        "itemId": 2,
+        "itemCode": "M001",
+        "itemName": "铻轰笣",
+        "quantity": 100.00,
+        "batchId": 7,
+        "batchCode": "T8811",
+        "warehouseId": 1,
+        "warehouseName": "鎴愬搧浠�",
+        "locationId": 1,
+        "locationName": "A鍖�",
+        "areaId": 1,
+        "areaName": "A-01-01",
+        "transactionTime": "2025-07-15 10:30:00",
+        "createTime": "2025-07-15 10:30:00"
+      }
+    ]
+  },
+  "msg": "鎿嶄綔鎴愬姛"
+}
+```
+
+## 涓氬姟绫诲瀷璇存槑
+
+| bizType | bizTypeName | 璇存槑 |
+|---------|-------------|------|
+| 126 | 鑷畾涔夊叆搴� | 搴撳瓨璋冩暣鍏ュ簱 |
+| 127 | 鑷畾涔夊嚭搴� | 搴撳瓨璋冩暣鍑哄簱 |
+| 110 | 閲囪喘鍏ュ簱 | 閲囪喘鍏ュ簱鍗� |
+| 119 | 閿�鍞嚭搴� | 閿�鍞嚭搴撳崟 |
+| 112 | 璋冩嫧鍑哄簱 | 搴撳瓨璋冩嫧鍑哄簱 |
+| 113 | 璋冩嫧鍏ュ簱 | 搴撳瓨璋冩嫧鍏ュ簱 |
+| 115 | 鍏朵粬鍏ュ簱 | 鍏朵粬鍏ュ簱鍗� |
+| 114 | 鍏朵粬鍑哄簱 | 鍏朵粬鍑哄簱鍗� |
+| 116 | 鐢熶骇棰嗘枡 | 鐢熶骇棰嗘枡鍗� |
+| 117 | 鐢熶骇閫�鏂� | 鐢熶骇閫�鏂欏崟 |
+| 118 | 鐢熶骇鍏ュ簱 | 鐢熶骇鍏ュ簱鍗� |
+| 123 | 鐢熶骇娑堣�� | 鐢熶骇鎶ュ伐娑堣�� |
+| 124 | 浜у搧浜у嚭 | 鐢熶骇鎶ュ伐浜у嚭 |
+| 125 | 渚涘簲鍟嗛��璐� | 渚涘簲鍟嗛��璐у嚭搴� |
+| 120 | 閿�鍞��璐� | 閿�鍞��璐у叆搴� |
+| 121 | 澶栧崗鍙戞枡 | 澶栧崗鍙戞枡 |
+| 122 | 澶栧崗鍏ュ簱 | 澶栧崗鍏ュ簱 |
+
+## 鎼滅储鏉′欢
+
+| 鏉′欢瀛楁 | 缁勪欢绫诲瀷 | 璇存槑 |
+|----------|----------|------|
+| 鐗╂枡 | 鐗╂枡閫夋嫨寮圭獥 | 閫夋嫨鐗╂枡鍚庡甫鍑� itemId |
+| 鎵规鍙� | Input 杈撳叆妗� | 鏀寔妯$硦鎼滅储 |
+| 浠撳簱 | 涓嬫媺閫夋嫨 | 閫夋嫨浠撳簱 |
+| 搴撳尯 | 涓嬫媺閫夋嫨 | 鏍规嵁浠撳簱鑱斿姩鍔犺浇 |
+| 搴撲綅 | 涓嬫媺閫夋嫨 | 鏍规嵁搴撳尯鑱斿姩鍔犺浇 |
+| 浜嬪姟绫诲瀷 | 涓嬫媺閫夋嫨 | 閫夐」锛氬叆搴撱�佸嚭搴� |
+| 涓氬姟绫诲瀷 | 涓嬫媺閫夋嫨 | 閫夐」瑙佷笂琛ㄤ笟鍔$被鍨嬭鏄� |
+| 涓氬姟鍗曞彿 | Input 杈撳叆妗� | 鏀寔妯$硦鎼滅储 |
+| 鏃堕棿鑼冨洿 | DatePicker 鏃ユ湡鑼冨洿 | 閫夋嫨浜嬪姟鍙戠敓鏃堕棿鑼冨洿 |
+
+## 鍒楄〃瀛楁灞曠ず
+
+| 鍒楀悕 | 瀛楁 | 瀹藉害 | 璇存槑 |
+|------|------|------|------|
+| 浜嬪姟绫诲瀷 | typeName | 80 | 鍏ュ簱鏄剧ず缁胯壊鏍囩锛屽嚭搴撴樉绀虹孩鑹叉爣绛� |
+| 涓氬姟绫诲瀷 | bizTypeName | 100 | 涓氬姟绫诲瀷鍚嶇О |
+| 涓氬姟鍗曞彿 | bizCode | 150 | 鍙偣鍑昏烦杞埌瀵瑰簲涓氬姟鍗曟嵁 |
+| 鐗╂枡缂栫爜 | itemCode | 120 | - |
+| 鐗╂枡鍚嶇О | itemName | 150 | - |
+| 鎵规鍙� | batchCode | 120 | 鏃犳壒娆℃椂鏄剧ず绌� |
+| 鏁伴噺 | quantity | 100 | 姝f暟鏄剧ず缁胯壊锛岃礋鏁版樉绀虹孩鑹� |
+| 浠撳簱 | warehouseName | 100 | - |
+| 搴撳尯 | locationName | 100 | - |
+| 搴撲綅 | areaName | 100 | - |
+| 浜嬪姟鏃堕棿 | transactionTime | 160 | 鏍煎紡锛歽yyy-MM-dd HH:mm:ss |
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 鏁版嵁鍙 | 娴佹按璁板綍鐢辩郴缁熻嚜鍔ㄧ敓鎴愶紝涓嶅彲浜哄伐鏂板銆佷慨鏀广�佸垹闄� |
+| 榛樿鎺掑簭 | 鎸変簨鍔℃椂闂村�掑簭鎺掑垪 |
+| 鏁伴噺鏄剧ず | quantity > 0 鏄剧ず缁胯壊锛宷uantity < 0 鏄剧ず绾㈣壊 |
+| 绫诲瀷鏍囩 | 鍏ュ簱鏄剧ず缁胯壊 success 鏍囩锛屽嚭搴撴樉绀虹孩鑹� danger 鏍囩 |
+| 涓氬姟鍗曞彿璺宠浆 | 鐐瑰嚮 bizCode 鍙烦杞埌瀵瑰簲涓氬姟鍗曟嵁璇︽儏椤� |
+
+## 鏉冮檺閰嶇疆
+
+| 鏉冮檺鏍囪瘑 | 璇存槑 |
+|----------|------|
+| mes:wm-transaction:query | 鏌ヨ搴撳瓨浜嬪姟娴佹按 |
+
+## 娉ㄦ剰浜嬮」
+
+1. 娴佹按璁板綍涓虹郴缁熻嚜鍔ㄧ敓鎴愶紝椤甸潰涓嶆彁渚涙柊澧炪�佺紪杈戙�佸垹闄ゆ寜閽�
+2. 涓氬姟鍗曞彿锛坆izCode锛夊彲浣滀负璺宠浆閾炬帴锛岀偣鍑昏烦杞埌瀵瑰簲涓氬姟鍗曟嵁
+3. 鎼滅储鏉′欢涓殑浠撳簱銆佸簱鍖恒�佸簱浣嶅瓨鍦ㄨ仈鍔ㄥ叧绯伙細
+   - 閫夋嫨浠撳簱鍚庯紝搴撳尯涓嬫媺鍙樉绀鸿浠撳簱涓嬬殑搴撳尯
+   - 閫夋嫨搴撳尯鍚庯紝搴撲綅涓嬫媺鍙樉绀鸿搴撳尯涓嬬殑搴撲綅
+4. 鏃堕棿鑼冨洿鎼滅储榛樿鍙煡璇㈡渶杩�30澶╂暟鎹�
\ No newline at end of file
diff --git a/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/api/sale/ErpSaleOrderApi.java b/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/api/sale/ErpSaleOrderApi.java
index c6b2ccd..51b56ff 100644
--- a/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/api/sale/ErpSaleOrderApi.java
+++ b/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/api/sale/ErpSaleOrderApi.java
@@ -68,12 +68,16 @@
     /**
      * 鏇存柊閿�鍞鍗曠殑鍑哄簱鐘舵��
      *
-     * 鏍规嵁鏄庣粏鍑哄簱鏁伴噺鑷姩璁$畻璁㈠崟鐘舵�侊細
-     * - 鎵�鏈夋槑缁嗛兘瀹屾垚鍑哄簱 鈫� 瀹屾垚鐘舵��
-     * - 閮ㄥ垎鏄庣粏瀹屾垚鍑哄簱 鈫� 閮ㄥ垎鍑哄簱鐘舵��
-     *
      * @param orderId 璁㈠崟缂栧彿
      */
     CommonResult<Boolean> updateOrderOutStatus(Long orderId);
 
+    /**
+     * 鏇存柊閿�鍞鍗曠殑鍑哄簱鐘舵�佷负鎸囧畾鍊�
+     *
+     * @param orderId   璁㈠崟缂栧彿
+     * @param outStatus 鍑哄簱鐘舵��
+     */
+    CommonResult<Boolean> updateOrderOutStatusTo(Long orderId, Integer outStatus);
+
 }
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpSaleOrderOutStatusEnum.java b/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/api/sale/enums/ErpSaleOrderOutStatusEnum.java
similarity index 73%
rename from yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpSaleOrderOutStatusEnum.java
rename to yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/api/sale/enums/ErpSaleOrderOutStatusEnum.java
index 1fbec7b..617004d 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpSaleOrderOutStatusEnum.java
+++ b/yudao-module-erp-api/src/main/java/cn/iocoder/yudao/module/erp/api/sale/enums/ErpSaleOrderOutStatusEnum.java
@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.erp.enums;
+package cn.iocoder.yudao.module.erp.api.sale.enums;
 
 import cn.iocoder.yudao.framework.common.core.ArrayValuable;
 import lombok.Getter;
@@ -16,8 +16,9 @@
 public enum ErpSaleOrderOutStatusEnum implements ArrayValuable<Integer> {
 
     NOT_OUT(0, "鏈嚭搴�"),
-    PART_OUT(1, "閮ㄥ垎鍑哄簱"),
-    ALL_OUT(2, "鍏ㄩ儴鍑哄簱");
+    RESERVED(1, "宸查鐣�"),      // 鍙戣揣閫氱煡鍗曞鏍搁�氳繃
+    PART_OUT(2, "閮ㄥ垎鍑哄簱"),    // 閮ㄥ垎鎷h揣/鍑哄簱
+    ALL_OUT(3, "鍏ㄩ儴鍑哄簱");     // 鍏ㄩ儴鍑哄簱瀹屾垚
 
     private final Integer status;
     private final String name;
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/api/sale/ErpSaleOrderApiImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/api/sale/ErpSaleOrderApiImpl.java
index 86acb62..b6a00a5 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/api/sale/ErpSaleOrderApiImpl.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/api/sale/ErpSaleOrderApiImpl.java
@@ -111,4 +111,14 @@
         return success(true);
     }
 
+    @Override
+    public CommonResult<Boolean> updateOrderOutStatusTo(Long orderId, Integer outStatus) {
+        if (orderId == null || outStatus == null) {
+            return success(false);
+        }
+        saleOrderMapper.updateById(new ErpSaleOrderDO()
+                .setId(orderId).setOutStatus(outStatus));
+        return success(true);
+    }
+
 }
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinanceReceiptController.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinanceReceiptController.java
index 0d71e6f..b6c905f 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinanceReceiptController.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/finance/ErpFinanceReceiptController.java
@@ -15,10 +15,10 @@
 import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinanceReceiptItemDO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
 import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
 import cn.iocoder.yudao.module.erp.service.finance.ErpFinanceReceiptService;
-import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService;
+import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
+import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
 import io.swagger.v3.oas.annotations.Operation;
@@ -49,7 +49,7 @@
     @Resource
     private ErpFinanceReceiptService financeReceiptService;
     @Resource
-    private ErpCustomerService customerService;
+    private CrmCustomerApi customerApi;
     @Resource
     private ErpAccountService accountService;
 
@@ -132,7 +132,7 @@
                 convertSet(pageResult.getList(), ErpFinanceReceiptDO::getId));
         Map<Long, List<ErpFinanceReceiptItemDO>> financeReceiptItemMap = convertMultiMap(receiptItemList, ErpFinanceReceiptItemDO::getReceiptId);
         // 1.2 瀹㈡埛淇℃伅
-        Map<Long, ErpCustomerDO> customerMap = customerService.getCustomerMap(
+        Map<Long, CrmCustomerRespDTO> customerMap = customerApi.getCustomerMap(
                 convertSet(pageResult.getList(), ErpFinanceReceiptDO::getCustomerId));
         // 1.3 缁撶畻璐︽埛淇℃伅
         Map<Long, ErpAccountDO> accountMap = accountService.getAccountMap(
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseRequestController.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseRequestController.java
deleted file mode 100644
index 0a765bd..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseRequestController.java
+++ /dev/null
@@ -1,210 +0,0 @@
-package cn.iocoder.yudao.module.erp.controller.admin.purchase;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestPageReqVO;
-import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestRespVO;
-import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestSaveReqVO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestDO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestItemDO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpSupplierDO;
-import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseRequestService;
-import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
-import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
-import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
-import cn.iocoder.yudao.module.system.api.dept.DeptApi;
-import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
-import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
-import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.annotation.Resource;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.Valid;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserDeptId;
-import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
-
-@Tag(name = "绠$悊鍚庡彴 - ERP 閲囪喘鐢宠")
-@RestController
-@RequestMapping("/erp/purchase-request")
-@Validated
-public class ErpPurchaseRequestController {
-
-    @Resource
-    private ErpPurchaseRequestService purchaseRequestService;
-    @Resource
-    private ErpSupplierService supplierService;
-
-    @Resource
-    private MdmItemApi mdmItemApi;
-    @Resource
-    private AdminUserApi adminUserApi;
-    @Resource
-    private DeptApi deptApi;
-
-    @PostMapping("/create")
-    @Operation(summary = "鍒涘缓閲囪喘鐢宠")
-    @PreAuthorize("@ss.hasPermission('erp:purchase-request:create')")
-    public CommonResult<Long> createPurchaseRequest(@Valid @RequestBody ErpPurchaseRequestSaveReqVO createReqVO) {
-        return success(purchaseRequestService.createPurchaseRequest(createReqVO, getLoginUserId(), getLoginUserDeptId()));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "鏇存柊閲囪喘鐢宠")
-    @PreAuthorize("@ss.hasPermission('erp:purchase-request:update')")
-    public CommonResult<Boolean> updatePurchaseRequest(@Valid @RequestBody ErpPurchaseRequestSaveReqVO updateReqVO) {
-        purchaseRequestService.updatePurchaseRequest(updateReqVO);
-        return success(true);
-    }
-
-    @PutMapping("/submit")
-    @Operation(summary = "鎻愪氦閲囪喘鐢宠瀹℃壒")
-    @PreAuthorize("@ss.hasPermission('erp:purchase-request:submit')")
-    public CommonResult<Boolean> submitPurchaseRequest(@RequestParam("id") Long id,
-                                                        @RequestParam("processDefinitionKey") String processDefinitionKey) {
-        purchaseRequestService.submitPurchaseRequest(id, processDefinitionKey, getLoginUserId());
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "鍒犻櫎閲囪喘鐢宠")
-    @Parameter(name = "ids", description = "缂栧彿鏁扮粍", required = true)
-    @PreAuthorize("@ss.hasPermission('erp:purchase-request:delete')")
-    public CommonResult<Boolean> deletePurchaseRequest(@RequestParam("ids") List<Long> ids) {
-        purchaseRequestService.deletePurchaseRequest(ids);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "鑾峰緱閲囪喘鐢宠")
-    @Parameter(name = "id", description = "缂栧彿", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('erp:purchase-request:query')")
-    public CommonResult<ErpPurchaseRequestRespVO> getPurchaseRequest(@RequestParam("id") Long id) {
-        ErpPurchaseRequestDO purchaseRequest = purchaseRequestService.getPurchaseRequest(id);
-        if (purchaseRequest == null) {
-            return success(null);
-        }
-        List<ErpPurchaseRequestItemDO> purchaseRequestItemList = purchaseRequestService.getPurchaseRequestItemListByRequestId(id);
-        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
-                convertSet(purchaseRequestItemList, ErpPurchaseRequestItemDO::getProductId));
-        return success(BeanUtils.toBean(purchaseRequest, ErpPurchaseRequestRespVO.class, vo -> {
-            vo.setItems(BeanUtils.toBean(purchaseRequestItemList, ErpPurchaseRequestRespVO.Item.class, item ->
-                    MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName())
-                            .setProductBarCode(mdmItem.getBarCode()))));
-            // 濉厖鍏宠仈瀛楁
-            fillPurchaseRequestRelatedFields(vo);
-        }));
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "鑾峰緱閲囪喘鐢宠鍒嗛〉")
-    @PreAuthorize("@ss.hasPermission('erp:purchase-request:query')")
-    public CommonResult<PageResult<ErpPurchaseRequestRespVO>> getPurchaseRequestPage(@Valid ErpPurchaseRequestPageReqVO pageReqVO) {
-        PageResult<ErpPurchaseRequestDO> pageResult = purchaseRequestService.getPurchaseRequestPage(pageReqVO);
-        return success(buildPurchaseRequestVOPageResult(pageResult));
-    }
-
-    @GetMapping("/export-excel")
-    @Operation(summary = "瀵煎嚭閲囪喘鐢宠 Excel")
-    @PreAuthorize("@ss.hasPermission('erp:purchase-request:export')")
-    @ApiAccessLog(operateType = EXPORT)
-    public void exportPurchaseRequestExcel(@Valid ErpPurchaseRequestPageReqVO pageReqVO,
-                                           HttpServletResponse response) throws IOException {
-        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
-        List<ErpPurchaseRequestRespVO> list = buildPurchaseRequestVOPageResult(
-                purchaseRequestService.getPurchaseRequestPage(pageReqVO)).getList();
-        ExcelUtils.write(response, "閲囪喘鐢宠.xls", "鏁版嵁", ErpPurchaseRequestRespVO.class, list);
-    }
-
-    @PostMapping("/generate-order")
-    @Operation(summary = "鐢熸垚閲囪喘璁㈠崟")
-    @PreAuthorize("@ss.hasPermission('erp:purchase-request:generate-order')")
-    public CommonResult<Long> generatePurchaseOrder(@RequestParam("id") Long id,
-                                                    @RequestParam("supplierId") Long supplierId) {
-        return success(purchaseRequestService.generatePurchaseOrder(id, supplierId, getLoginUserId()));
-    }
-
-    @GetMapping("/approve-process-list")
-    @Operation(summary = "鑾峰彇閲囪喘鐢宠瀹℃壒娴佺▼鍒楄〃")
-    @PreAuthorize("@ss.hasPermission('erp:purchase-request:query')")
-    public CommonResult<List<Map<String, Object>>> getPurchaseRequestApproveProcessList() {
-        return success(purchaseRequestService.getPurchaseRequestApproveProcessDefinitionList());
-    }
-
-    private PageResult<ErpPurchaseRequestRespVO> buildPurchaseRequestVOPageResult(PageResult<ErpPurchaseRequestDO> pageResult) {
-        if (CollUtil.isEmpty(pageResult.getList())) {
-            return PageResult.empty(pageResult.getTotal());
-        }
-        // 1.1 鐢宠鏄庣粏
-        List<ErpPurchaseRequestItemDO> purchaseRequestItemList = purchaseRequestService.getPurchaseRequestItemListByRequestIds(
-                convertSet(pageResult.getList(), ErpPurchaseRequestDO::getId));
-        Map<Long, List<ErpPurchaseRequestItemDO>> purchaseRequestItemMap = convertMultiMap(purchaseRequestItemList, ErpPurchaseRequestItemDO::getRequestId);
-        // 1.2 鐗╂枡淇℃伅
-        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
-                convertSet(purchaseRequestItemList, ErpPurchaseRequestItemDO::getProductId));
-        // 1.3 渚涘簲鍟嗕俊鎭�
-        Map<Long, ErpSupplierDO> supplierMap = supplierService.getSupplierMap(
-                convertSet(pageResult.getList(), ErpPurchaseRequestDO::getSupplierId));
-        // 1.4 鐢ㄦ埛淇℃伅
-        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
-                convertSet(pageResult.getList(), ErpPurchaseRequestDO::getRequestUserId));
-        // 1.5 閮ㄩ棬淇℃伅
-        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
-                convertSet(pageResult.getList(), ErpPurchaseRequestDO::getRequestDeptId));
-
-        // 2. 寮�濮嬫嫾鎺�
-        return BeanUtils.toBean(pageResult, ErpPurchaseRequestRespVO.class, vo -> {
-            vo.setItems(BeanUtils.toBean(purchaseRequestItemMap.get(vo.getId()), ErpPurchaseRequestRespVO.Item.class,
-                    item -> MapUtils.findAndThen(itemMap, item.getProductId(), mdmItem -> item.setProductName(mdmItem.getName())
-                            .setProductBarCode(mdmItem.getBarCode()))));
-            vo.setProductNames(CollUtil.join(vo.getItems(), "锛�", ErpPurchaseRequestRespVO.Item::getProductName));
-            MapUtils.findAndThen(supplierMap, vo.getSupplierId(), supplier -> vo.setSupplierName(supplier.getName()));
-            MapUtils.findAndThen(userMap, vo.getRequestUserId(), user -> vo.setRequestUserName(user.getNickname()));
-            MapUtils.findAndThen(deptMap, vo.getRequestDeptId(), dept -> vo.setRequestDeptName(dept.getName()));
-        });
-    }
-
-    private void fillPurchaseRequestRelatedFields(ErpPurchaseRequestRespVO vo) {
-        // 濉厖鐢宠浜哄悕绉�
-        if (vo.getRequestUserId() != null) {
-            AdminUserRespDTO user = adminUserApi.getUser(vo.getRequestUserId());
-            if (user != null) {
-                vo.setRequestUserName(user.getNickname());
-            }
-        }
-        // 濉厖閮ㄩ棬鍚嶇О
-        if (vo.getRequestDeptId() != null) {
-            DeptRespDTO dept = deptApi.getDept(vo.getRequestDeptId());
-            if (dept != null) {
-                vo.setRequestDeptName(dept.getName());
-            }
-        }
-        // 濉厖渚涘簲鍟嗗悕绉�
-        if (vo.getSupplierId() != null) {
-            ErpSupplierDO supplier = supplierService.getSupplier(vo.getSupplierId());
-            if (supplier != null) {
-                vo.setSupplierName(supplier.getName());
-            }
-        }
-    }
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestPageReqVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestPageReqVO.java
deleted file mode 100644
index e67c4c5..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestPageReqVO.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.ToString;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import java.time.LocalDateTime;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-
-@Schema(description = "绠$悊鍚庡彴 - ERP 閲囪喘鐢宠鍒嗛〉 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class ErpPurchaseRequestPageReqVO extends PageParam {
-
-    @Schema(description = "閲囪喘鐢宠鍗曞彿", example = "CGSQ001")
-    private String no;
-
-    @Schema(description = "鐢宠浜虹紪鍙�", example = "1")
-    private Long requestUserId;
-
-    @Schema(description = "鐢宠閮ㄩ棬缂栧彿", example = "1")
-    private Long requestDeptId;
-
-    @Schema(description = "鐢宠鏃堕棿")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private LocalDateTime[] requestTime;
-
-    @Schema(description = "瀹℃壒鐘舵��", example = "20")
-    private Integer status;
-
-    @Schema(description = "鐢宠鐞嗙敱", example = "鐢熶骇闇�瑕�")
-    private String requestReason;
-
-    @Schema(description = "浜у搧缂栧彿", example = "1")
-    private Long productId;
-
-}
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestRespVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestRespVO.java
deleted file mode 100644
index 47ee75e..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestRespVO.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request;
-
-import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
-import cn.idev.excel.annotation.ExcelProperty;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Schema(description = "绠$悊鍚庡彴 - ERP 閲囪喘鐢宠 Response VO")
-@Data
-@ExcelIgnoreUnannotated
-public class ErpPurchaseRequestRespVO {
-
-    @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386")
-    @ExcelProperty("缂栧彿")
-    private Long id;
-
-    @Schema(description = "閲囪喘鐢宠鍗曞彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "CGSQ001")
-    @ExcelProperty("閲囪喘鐢宠鍗曞彿")
-    private String no;
-
-    @Schema(description = "瀹℃壒鐘舵��", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
-    @ExcelProperty("瀹℃壒鐘舵��")
-    private Integer status;
-
-    @Schema(description = "鐢宠浜虹紪鍙�", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    private Long requestUserId;
-    @Schema(description = "鐢宠浜哄悕绉�", example = "寮犱笁")
-    @ExcelProperty("鐢宠浜�")
-    private String requestUserName;
-
-    @Schema(description = "鐢宠閮ㄩ棬缂栧彿", example = "1")
-    private Long requestDeptId;
-    @Schema(description = "鐢宠閮ㄩ棬鍚嶇О", example = "鐢熶骇閮�")
-    @ExcelProperty("鐢宠閮ㄩ棬")
-    private String requestDeptName;
-
-    @Schema(description = "鐢宠鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("鐢宠鏃堕棿")
-    private LocalDateTime requestTime;
-
-    @Schema(description = "鐢宠鐞嗙敱", example = "鐢熶骇闇�瑕�")
-    @ExcelProperty("鐢宠鐞嗙敱")
-    private String requestReason;
-
-    @Schema(description = "渚涘簲鍟嗙紪鍙�", example = "1724")
-    private Long supplierId;
-    @Schema(description = "渚涘簲鍟嗗悕绉�", example = "渚涘簲鍟咥")
-    @ExcelProperty("渚涘簲鍟嗗悕绉�")
-    private String supplierName;
-
-    @Schema(description = "鍚堣鏁伴噺", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
-    @ExcelProperty("鍚堣鏁伴噺")
-    private BigDecimal totalCount;
-
-    @Schema(description = "鍚堣浜у搧浠锋牸", example = "10000.00")
-    private BigDecimal totalProductPrice;
-
-    @Schema(description = "鍚堣绋庨", example = "1300.00")
-    private BigDecimal totalTaxPrice;
-
-    @Schema(description = "鏈�缁堝悎璁′环鏍�", requiredMode = Schema.RequiredMode.REQUIRED, example = "11300.00")
-    @ExcelProperty("鏈�缁堝悎璁′环鏍�")
-    private BigDecimal totalPrice;
-
-    @Schema(description = "浼樻儬鐜囷紝鐧惧垎姣�", example = "10.00")
-    private BigDecimal discountPercent;
-
-    @Schema(description = "浼樻儬閲戦", example = "1130.00")
-    private BigDecimal discountPrice;
-
-    @Schema(description = "宸ヤ綔娴佺紪鍙�", example = "xxx-xxx")
-    private String processInstanceId;
-
-    @Schema(description = "鍏宠仈閲囪喘璁㈠崟缂栧彿", example = "100")
-    private Long orderId;
-    @Schema(description = "鍏宠仈閲囪喘璁㈠崟鍗曞彿", example = "CGDD001")
-    @ExcelProperty("閲囪喘璁㈠崟鍗曞彿")
-    private String orderNo;
-
-    @Schema(description = "鐢熸垚閲囪喘璁㈠崟鏃堕棿")
-    private LocalDateTime orderTime;
-
-    @Schema(description = "闄勪欢鍦板潃", example = "https://www.iocoder.cn")
-    @ExcelProperty("闄勪欢鍦板潃")
-    private String fileUrl;
-
-    @Schema(description = "澶囨敞", example = "浣犵寽")
-    @ExcelProperty("澶囨敞")
-    private String remark;
-
-    @Schema(description = "鍒涘缓浜�", example = "1")
-    private String creator;
-    @Schema(description = "鍒涘缓浜哄悕绉�", example = "鑺嬮亾")
-    private String creatorName;
-
-    @Schema(description = "鍒涘缓鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("鍒涘缓鏃堕棿")
-    private LocalDateTime createTime;
-
-    @Schema(description = "鐢宠鏄庣粏鍒楄〃")
-    private List<Item> items;
-
-    @Schema(description = "浜у搧淇℃伅")
-    @ExcelProperty("浜у搧淇℃伅")
-    private String productNames;
-
-    @Data
-    public static class Item {
-
-        @Schema(description = "鐢宠椤圭紪鍙�", example = "11756")
-        private Long id;
-
-        @Schema(description = "浜у搧缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
-        private Long productId;
-
-        @Schema(description = "浜у搧鍗曚綅缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
-        private Long productUnitId;
-
-        @Schema(description = "浜у搧鍗曚环锛堝弬鑰冧环锛�", example = "100.00")
-        private BigDecimal productPrice;
-
-        @Schema(description = "鏁伴噺", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
-        private BigDecimal count;
-
-        @Schema(description = "鎬讳环", example = "10000.00")
-        private BigDecimal totalPrice;
-
-        @Schema(description = "绋庣巼锛岀櫨鍒嗘瘮", example = "13.00")
-        private BigDecimal taxPercent;
-
-        @Schema(description = "绋庨", example = "1300.00")
-        private BigDecimal taxPrice;
-
-        @Schema(description = "闇�姹傛棩鏈�", example = "2024-01-01")
-        private LocalDate demandTime;
-
-        @Schema(description = "澶囨敞", example = "闅忎究")
-        private String remark;
-
-        // ========== 鍏宠仈瀛楁 ==========
-
-        @Schema(description = "浜у搧鍚嶇О", requiredMode = Schema.RequiredMode.REQUIRED, example = "宸у厠鍔�")
-        private String productName;
-        @Schema(description = "浜у搧鏉$爜", requiredMode = Schema.RequiredMode.REQUIRED, example = "A9985")
-        private String productBarCode;
-        @Schema(description = "浜у搧鍗曚綅鍚嶇О", requiredMode = Schema.RequiredMode.REQUIRED, example = "鐩�")
-        private String productUnitName;
-
-    }
-
-}
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestSaveReqVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestSaveReqVO.java
deleted file mode 100644
index d1a01ad..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/vo/request/ErpPurchaseRequestSaveReqVO.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.Valid;
-import jakarta.validation.constraints.NotEmpty;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.util.List;
-
-@Schema(description = "绠$悊鍚庡彴 - ERP 閲囪喘鐢宠鏂板/淇敼 Request VO")
-@Data
-public class ErpPurchaseRequestSaveReqVO {
-
-    @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "17386")
-    private Long id;
-
-    @Schema(description = "鐢宠鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "鐢宠鏃堕棿涓嶈兘涓虹┖")
-    private LocalDateTime requestTime;
-
-    @Schema(description = "鐢宠鐞嗙敱", example = "鐢熶骇闇�瑕�")
-    private String requestReason;
-
-    @Schema(description = "渚涘簲鍟嗙紪鍙凤紙鍙�夛級", example = "1724")
-    private Long supplierId;
-
-    @Schema(description = "浼樻儬鐜囷紝鐧惧垎姣�", example = "99.88")
-    private BigDecimal discountPercent;
-
-    @Schema(description = "闄勪欢鍦板潃", example = "https://www.iocoder.cn")
-    private String fileUrl;
-
-    @Schema(description = "澶囨敞", example = "浣犵寽")
-    private String remark;
-
-    @Schema(description = "鐢宠鏄庣粏鍒楄〃")
-    @NotEmpty(message = "鐢宠鏄庣粏鍒楄〃涓嶈兘涓虹┖")
-    @Valid
-    private List<Item> items;
-
-    @Data
-    public static class Item {
-
-        @Schema(description = "鐢宠椤圭紪鍙�", example = "11756")
-        private Long id;
-
-        @Schema(description = "浜у搧缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
-        @NotNull(message = "浜у搧缂栧彿涓嶈兘涓虹┖")
-        private Long productId;
-
-        @Schema(description = "浜у搧鍗曚綅缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "3113")
-        @NotNull(message = "浜у搧鍗曚綅缂栧彿涓嶈兘涓虹┖")
-        private Long productUnitId;
-
-        @Schema(description = "浜у搧鍗曚环锛堝弬鑰冧环锛�", example = "100.00")
-        private BigDecimal productPrice;
-
-        @Schema(description = "鏁伴噺", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
-        @NotNull(message = "鏁伴噺涓嶈兘涓虹┖")
-        private BigDecimal count;
-
-        @Schema(description = "绋庣巼锛岀櫨鍒嗘瘮", example = "13.00")
-        private BigDecimal taxPercent;
-
-        @Schema(description = "闇�姹傛棩鏈�", example = "2024-01-01")
-        private LocalDate demandTime;
-
-        @Schema(description = "澶囨敞", example = "闅忎究")
-        private String remark;
-
-    }
-
-}
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpCustomerController.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpCustomerController.java
deleted file mode 100644
index 2eb974d..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/ErpCustomerController.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package cn.iocoder.yudao.module.erp.controller.admin.sale;
-
-import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
-import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerPageReqVO;
-import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerRespVO;
-import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerSaveReqVO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
-import cn.iocoder.yudao.module.erp.service.sale.ErpCustomerService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.annotation.Resource;
-import jakarta.servlet.http.HttpServletResponse;
-import jakarta.validation.Valid;
-import org.springframework.security.access.prepost.PreAuthorize;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.*;
-
-import java.io.IOException;
-import java.util.List;
-
-import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
-
-@Tag(name = "绠$悊鍚庡彴 - ERP 瀹㈡埛")
-@RestController
-@RequestMapping("/erp/customer")
-@Validated
-public class ErpCustomerController {
-
-    @Resource
-    private ErpCustomerService customerService;
-
-    @PostMapping("/create")
-    @Operation(summary = "鍒涘缓瀹㈡埛")
-    @PreAuthorize("@ss.hasPermission('erp:customer:create')")
-    public CommonResult<Long> createCustomer(@Valid @RequestBody ErpCustomerSaveReqVO createReqVO) {
-        return success(customerService.createCustomer(createReqVO));
-    }
-
-    @PutMapping("/update")
-    @Operation(summary = "鏇存柊瀹㈡埛")
-    @PreAuthorize("@ss.hasPermission('erp:customer:update')")
-    public CommonResult<Boolean> updateCustomer(@Valid @RequestBody ErpCustomerSaveReqVO updateReqVO) {
-        customerService.updateCustomer(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "鍒犻櫎瀹㈡埛")
-    @Parameter(name = "id", description = "缂栧彿", required = true)
-    @PreAuthorize("@ss.hasPermission('erp:customer:delete')")
-    public CommonResult<Boolean> deleteCustomer(@RequestParam("id") Long id) {
-        customerService.deleteCustomer(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @Operation(summary = "鑾峰緱瀹㈡埛")
-    @Parameter(name = "id", description = "缂栧彿", required = true, example = "1024")
-    @PreAuthorize("@ss.hasPermission('erp:customer:query')")
-    public CommonResult<ErpCustomerRespVO> getCustomer(@RequestParam("id") Long id) {
-        ErpCustomerDO customer = customerService.getCustomer(id);
-        return success(BeanUtils.toBean(customer, ErpCustomerRespVO.class));
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "鑾峰緱瀹㈡埛鍒嗛〉")
-    @PreAuthorize("@ss.hasPermission('erp:customer:query')")
-    public CommonResult<PageResult<ErpCustomerRespVO>> getCustomerPage(@Valid ErpCustomerPageReqVO pageReqVO) {
-        PageResult<ErpCustomerDO> pageResult = customerService.getCustomerPage(pageReqVO);
-        return success(BeanUtils.toBean(pageResult, ErpCustomerRespVO.class));
-    }
-
-    @GetMapping("/simple-list")
-    @Operation(summary = "鑾峰緱瀹㈡埛绮剧畝鍒楄〃", description = "鍙寘鍚寮�鍚殑瀹㈡埛锛屼富瑕佺敤浜庡墠绔殑涓嬫媺閫夐」")
-    public CommonResult<List<ErpCustomerRespVO>> getCustomerSimpleList() {
-        List<ErpCustomerDO> list = customerService.getCustomerListByStatus(CommonStatusEnum.ENABLE.getStatus());
-        return success(convertList(list, customer -> new ErpCustomerRespVO().setId(customer.getId()).setName(customer.getName())));
-    }
-
-    @GetMapping("/export-excel")
-    @Operation(summary = "瀵煎嚭瀹㈡埛 Excel")
-    @PreAuthorize("@ss.hasPermission('erp:customer:export')")
-    @ApiAccessLog(operateType = EXPORT)
-    public void exportCustomerExcel(@Valid ErpCustomerPageReqVO pageReqVO,
-              HttpServletResponse response) throws IOException {
-        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
-        List<ErpCustomerDO> list = customerService.getCustomerPage(pageReqVO).getList();
-        // 瀵煎嚭 Excel
-        ExcelUtils.write(response, "瀹㈡埛.xls", "鏁版嵁", ErpCustomerRespVO.class,
-                        BeanUtils.toBean(list, ErpCustomerRespVO.class));
-    }
-
-}
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerPageReqVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerPageReqVO.java
deleted file mode 100644
index e790cb9..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerPageReqVO.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer;
-
-import lombok.*;
-import java.util.*;
-import io.swagger.v3.oas.annotations.media.Schema;
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import java.math.BigDecimal;
-import org.springframework.format.annotation.DateTimeFormat;
-import java.time.LocalDateTime;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-
-@Schema(description = "绠$悊鍚庡彴 - ERP 瀹㈡埛鍒嗛〉 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class ErpCustomerPageReqVO extends PageParam {
-
-    @Schema(description = "瀹㈡埛鍚嶇О", example = "寮犱笁")
-    private String name;
-
-    @Schema(description = "鎵嬫満鍙风爜", example = "15601691300")
-    private String mobile;
-
-    @Schema(description = "鑱旂郴鐢佃瘽", example = "15601691300")
-    private String telephone;
-
-}
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerRespVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerRespVO.java
deleted file mode 100644
index c75a99a..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerRespVO.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-import cn.idev.excel.annotation.*;
-import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
-import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
-
-@Schema(description = "绠$悊鍚庡彴 - ERP 瀹㈡埛 Response VO")
-@Data
-@ExcelIgnoreUnannotated
-public class ErpCustomerRespVO {
-
-    @Schema(description = "瀹㈡埛缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "27520")
-    @ExcelProperty("瀹㈡埛缂栧彿")
-    private Long id;
-
-    @Schema(description = "瀹㈡埛鍚嶇О", requiredMode = Schema.RequiredMode.REQUIRED, example = "寮犱笁")
-    @ExcelProperty("瀹㈡埛鍚嶇О")
-    private String name;
-
-    @Schema(description = "鑱旂郴浜�", example = "鑰佺帇")
-    @ExcelProperty("鑱旂郴浜�")
-    private String contact;
-
-    @Schema(description = "鎵嬫満鍙风爜", example = "15601691300")
-    @ExcelProperty("鎵嬫満鍙风爜")
-    private String mobile;
-
-    @Schema(description = "鑱旂郴鐢佃瘽", example = "15601691300")
-    @ExcelProperty("鑱旂郴鐢佃瘽")
-    private String telephone;
-
-    @Schema(description = "鐢靛瓙閭", example = "7685323@qq.com")
-    @ExcelProperty("鐢靛瓙閭")
-    private String email;
-
-    @Schema(description = "浼犵湡", example = "20 7123 4567")
-    @ExcelProperty("浼犵湡")
-    private String fax;
-
-    @Schema(description = "澶囨敞", example = "浣犵寽")
-    @ExcelProperty("澶囨敞")
-    private String remark;
-
-    @Schema(description = "寮�鍚姸鎬�", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @ExcelProperty(value = "寮�鍚姸鎬�", converter = DictConvert.class)
-    @DictFormat("common_status") // TODO 浠g爜浼樺寲锛氬缓璁缃埌瀵瑰簲鐨� DictTypeConstants 鏋氫妇绫讳腑
-    private Integer status;
-
-    @Schema(description = "鎺掑簭", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
-    @ExcelProperty("鎺掑簭")
-    private Integer sort;
-
-    @Schema(description = "绾崇◣浜鸿瘑鍒彿", example = "91130803MA098BY05W")
-    @ExcelProperty("绾崇◣浜鸿瘑鍒彿")
-    private String taxNo;
-
-    @Schema(description = "绋庣巼", example = "10")
-    @ExcelProperty("绋庣巼")
-    private BigDecimal taxPercent;
-
-    @Schema(description = "寮�鎴疯", example = "鑺嬭壙")
-    @ExcelProperty("寮�鎴疯")
-    private String bankName;
-
-    @Schema(description = "寮�鎴疯处鍙�", example = "622908212277228617")
-    @ExcelProperty("寮�鎴疯处鍙�")
-    private String bankAccount;
-
-    @Schema(description = "寮�鎴峰湴鍧�", example = "鍏翠笟閾惰娴︿笢鏀")
-    @ExcelProperty("寮�鎴峰湴鍧�")
-    private String bankAddress;
-
-    @Schema(description = "鍒涘缓鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
-    @ExcelProperty("鍒涘缓鏃堕棿")
-    private LocalDateTime createTime;
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerSaveReqVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerSaveReqVO.java
deleted file mode 100644
index aef0b2d..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/customer/ErpCustomerSaveReqVO.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
-import java.util.*;
-import jakarta.validation.constraints.*;
-import java.math.BigDecimal;
-
-@Schema(description = "绠$悊鍚庡彴 - ERP 瀹㈡埛鏂板/淇敼 Request VO")
-@Data
-public class ErpCustomerSaveReqVO {
-
-    @Schema(description = "瀹㈡埛缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "27520")
-    private Long id;
-
-    @Schema(description = "瀹㈡埛鍚嶇О", requiredMode = Schema.RequiredMode.REQUIRED, example = "寮犱笁")
-    @NotEmpty(message = "瀹㈡埛鍚嶇О涓嶈兘涓虹┖")
-    private String name;
-
-    @Schema(description = "鑱旂郴浜�", example = "鑰佺帇")
-    private String contact;
-
-    @Schema(description = "鎵嬫満鍙风爜", example = "15601691300")
-    private String mobile;
-
-    @Schema(description = "鑱旂郴鐢佃瘽", example = "15601691300")
-    private String telephone;
-
-    @Schema(description = "鐢靛瓙閭", example = "7685323@qq.com")
-    private String email;
-
-    @Schema(description = "浼犵湡", example = "20 7123 4567")
-    private String fax;
-
-    @Schema(description = "澶囨敞", example = "浣犵寽")
-    private String remark;
-
-    @Schema(description = "寮�鍚姸鎬�", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @NotNull(message = "寮�鍚姸鎬佷笉鑳戒负绌�")
-    private Integer status;
-
-    @Schema(description = "鎺掑簭", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
-    @NotNull(message = "鎺掑簭涓嶈兘涓虹┖")
-    private Integer sort;
-
-    @Schema(description = "绾崇◣浜鸿瘑鍒彿", example = "91130803MA098BY05W")
-    private String taxNo;
-
-    @Schema(description = "绋庣巼", example = "10")
-    private BigDecimal taxPercent;
-
-    @Schema(description = "寮�鎴疯", example = "鑺嬭壙")
-    private String bankName;
-
-    @Schema(description = "寮�鎴疯处鍙�", example = "622908212277228617")
-    private String bankAccount;
-
-    @Schema(description = "寮�鎴峰湴鍧�", example = "鍏翠笟閾惰娴︿笢鏀")
-    private String bankAddress;
-
-}
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderPageReqVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderPageReqVO.java
index 84d92fb..8d1e313 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderPageReqVO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderPageReqVO.java
@@ -17,32 +17,6 @@
 @ToString(callSuper = true)
 public class ErpSaleOrderPageReqVO extends PageParam {
 
-    /**
-     * 鍑哄簱鐘舵�� - 鏃�
-     */
-    public static final Integer OUT_STATUS_NONE = 0;
-    /**
-     * 鍑哄簱鐘舵�� - 閮ㄥ垎
-     */
-    public static final Integer OUT_STATUS_PART = 1;
-    /**
-     * 鍑哄簱鐘舵�� - 鍏ㄩ儴
-     */
-    public static final Integer OUT_STATUS_ALL = 2;
-
-    /**
-     * 閫�璐х姸鎬� - 鏃�
-     */
-    public static final Integer RETURN_STATUS_NONE = 0;
-    /**
-     * 閫�璐х姸鎬� - 閮ㄥ垎
-     */
-    public static final Integer RETURN_STATUS_PART = 1;
-    /**
-     * 閫�璐х姸鎬� - 鍏ㄩ儴
-     */
-    public static final Integer RETURN_STATUS_ALL = 2;
-
     @Schema(description = "閿�鍞崟缂栧彿", example = "XS001")
     private String no;
 
@@ -64,17 +38,5 @@
 
     @Schema(description = "浜у搧缂栧彿", example = "1")
     private Long productId;
-
-    @Schema(description = "鍑哄簱鐘舵��", example = "2")
-    private Integer outStatus;
-
-    @Schema(description = "閫�璐х姸鎬�", example = "2")
-    private Integer returnStatus;
-
-    @Schema(description = "鏄惁鍙嚭搴�", example = "true")
-    private Boolean outEnable;
-
-    @Schema(description = "鏄惁鍙��璐�", example = "true")
-    private Boolean returnEnable;
 
 }
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderRespVO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderRespVO.java
index 59a9ae9..0ddc4a2 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderRespVO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/sale/vo/order/ErpSaleOrderRespVO.java
@@ -98,13 +98,11 @@
 
     // ========== 閿�鍞嚭搴� ==========
 
-    @Schema(description = "閿�鍞嚭搴撴暟閲�", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
+    @Schema(description = "閿�鍞嚭搴撴暟閲�", example = "100.00")
     private BigDecimal outCount;
 
-    // ========== 閿�鍞��璐э紙鍑哄簱锛夛級 ==========
-
-    @Schema(description = "閿�鍞��璐ф暟閲�", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
-    private BigDecimal returnCount;
+    @Schema(description = "鍑哄簱鐘舵��", example = "0")
+    private Integer outStatus;
 
     @Data
     public static class Item {
@@ -136,13 +134,8 @@
 
         // ========== 閿�鍞嚭搴� ==========
 
-        @Schema(description = "閿�鍞嚭搴撴暟閲�", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
+        @Schema(description = "閿�鍞嚭搴撴暟閲�", example = "100.00")
         private BigDecimal outCount;
-
-        // ========== 閿�鍞��璐э紙鍏ュ簱锛夛級 ==========
-
-        @Schema(description = "閿�鍞��璐ф暟閲�", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
-        private BigDecimal returnCount;
 
         // ========== 鍏宠仈瀛楁 ==========
 
@@ -154,8 +147,8 @@
         private String productUnitName;
 
         @Schema(description = "搴撳瓨鏁伴噺", requiredMode = Schema.RequiredMode.REQUIRED, example = "100.00")
-        private BigDecimal stockCount; // 璇ュ瓧娈典粎浠呭湪鈥滆鎯呪�濆拰鈥滅紪杈戔�濇椂浣跨敤
+        private BigDecimal stockCount; // 璇ュ瓧娈典粎浠呭湪璇︽儏鍜岀紪杈戞椂浣跨敤
 
     }
 
-}
+}
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/finance/ErpFinanceReceiptDO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/finance/ErpFinanceReceiptDO.java
index 624ee2e..1456d43 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/finance/ErpFinanceReceiptDO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/finance/ErpFinanceReceiptDO.java
@@ -1,7 +1,6 @@
 package cn.iocoder.yudao.module.erp.dal.dataobject.finance;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
 import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseOrderDO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseOrderDO.java
index 6f1c09b..6e6b9d4 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseOrderDO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseOrderDO.java
@@ -53,16 +53,6 @@
      */
     private Long accountId;
     /**
-     * 鍏宠仈閲囪喘鐢宠缂栧彿
-     *
-     * 鍏宠仈 {@link ErpPurchaseRequestDO#getId()}
-     */
-    private Long requestId;
-    /**
-     * 閲囪喘鐢宠鍗曞彿
-     */
-    private String requestNo;
-    /**
      * 涓嬪崟鏃堕棿
      */
     private LocalDateTime orderTime;
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseRequestDO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseRequestDO.java
deleted file mode 100644
index a3e896c..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseRequestDO.java
+++ /dev/null
@@ -1,129 +0,0 @@
-package cn.iocoder.yudao.module.erp.dal.dataobject.purchase;
-
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpAccountDO;
-import com.baomidou.mybatisplus.annotation.KeySequence;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.*;
-
-import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
-/**
- * ERP 閲囪喘鐢宠 DO
- *
- * @author 鑺嬮亾婧愮爜
- */
-@TableName(value = "erp_purchase_request")
-@KeySequence("erp_purchase_request_seq")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class ErpPurchaseRequestDO extends BaseDO {
-
-    /**
-     * 缂栧彿
-     */
-    @TableId
-    private Long id;
-    /**
-     * 閲囪喘鐢宠鍗曞彿
-     */
-    private String no;
-    /**
-     * 瀹℃壒鐘舵��
-     *
-     * 鏋氫妇 {@link cn.iocoder.yudao.module.erp.enums.ErpPurchaseRequestStatusEnum}
-     */
-    private Integer status;
-
-    /**
-     * 鐢宠浜虹紪鍙�
-     */
-    private Long requestUserId;
-    /**
-     * 鐢宠閮ㄩ棬缂栧彿
-     */
-    private Long requestDeptId;
-    /**
-     * 鐢宠鏃堕棿
-     */
-    private LocalDateTime requestTime;
-    /**
-     * 鐢宠鐞嗙敱
-     */
-    private String requestReason;
-
-    /**
-     * 渚涘簲鍟嗙紪鍙�
-     *
-     * 鍏宠仈 {@link ErpSupplierDO#getId()}
-     */
-    private Long supplierId;
-
-    /**
-     * 鍚堣鏁伴噺
-     */
-    private BigDecimal totalCount;
-    /**
-     * 鍚堣浜у搧浠锋牸锛屽崟浣嶏細鍏�
-     */
-    private BigDecimal totalProductPrice;
-    /**
-     * 鍚堣绋庨锛屽崟浣嶏細鍏�
-     */
-    private BigDecimal totalTaxPrice;
-    /**
-     * 鏈�缁堝悎璁′环鏍硷紝鍗曚綅锛氬厓
-     *
-     * totalPrice = totalProductPrice + totalTaxPrice - discountPrice
-     */
-    private BigDecimal totalPrice;
-    /**
-     * 浼樻儬鐜囷紝鐧惧垎姣�
-     */
-    private BigDecimal discountPercent;
-    /**
-     * 浼樻儬閲戦锛屽崟浣嶏細鍏�
-     *
-     * discountPrice = (totalProductPrice + totalTaxPrice) * discountPercent
-     */
-    private BigDecimal discountPrice;
-
-    /**
-     * 宸ヤ綔娴佺紪鍙�
-     */
-    private String processInstanceId;
-
-    /**
-     * 鍏宠仈閲囪喘璁㈠崟缂栧彿锛堝鎵归�氳繃鍚庣敓鎴愶級
-     *
-     * 鍏宠仈 {@link ErpPurchaseOrderDO#getId()}
-     */
-    private Long orderId;
-    /**
-     * 鐢熸垚閲囪喘璁㈠崟鏃堕棿
-     */
-    private LocalDateTime orderTime;
-
-    /**
-     * 鍏ュ簱鐘舵��
-     *
-     * 鏋氫妇 {@link cn.iocoder.yudao.module.erp.enums.ErpPurchaseOrderInStatusEnum}
-     */
-    private Integer inStatus;
-
-    /**
-     * 闄勪欢鍦板潃
-     */
-    private String fileUrl;
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseRequestItemDO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseRequestItemDO.java
deleted file mode 100644
index 7e54ce2..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/purchase/ErpPurchaseRequestItemDO.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package cn.iocoder.yudao.module.erp.dal.dataobject.purchase;
-
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import com.baomidou.mybatisplus.annotation.KeySequence;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.*;
-
-import java.math.BigDecimal;
-import java.time.LocalDate;
-
-/**
- * ERP 閲囪喘鐢宠鏄庣粏 DO
- *
- * @author 鑺嬮亾婧愮爜
- */
-@TableName("erp_purchase_request_items")
-@KeySequence("erp_purchase_request_items_seq")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class ErpPurchaseRequestItemDO extends BaseDO {
-
-    /**
-     * 缂栧彿
-     */
-    @TableId
-    private Long id;
-    /**
-     * 閲囪喘鐢宠缂栧彿
-     *
-     * 鍏宠仈 {@link ErpPurchaseRequestDO#getId()}
-     */
-    private Long requestId;
-    /**
-     * 鐗╂枡缂栧彿
-     *
-     * 鍏宠仈 {@link cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO#getId()}
-     */
-    private Long productId;
-    /**
-     * 璁¢噺鍗曚綅缂栧彿
-     *
-     * 鍏宠仈 {@link cn.iocoder.yudao.module.mdm.api.unitmeasure.dto.MdmUnitMeasureRespDTO#getId()}
-     */
-    private Long productUnitId;
-
-    /**
-     * 浜у搧鍗曚环锛堝弬鑰冧环锛夛紝鍗曚綅锛氬厓
-     */
-    private BigDecimal productPrice;
-    /**
-     * 鏁伴噺
-     */
-    private BigDecimal count;
-    /**
-     * 鎬讳环锛屽崟浣嶏細鍏�
-     *
-     * totalPrice = productPrice * count
-     */
-    private BigDecimal totalPrice;
-    /**
-     * 绋庣巼锛岀櫨鍒嗘瘮
-     */
-    private BigDecimal taxPercent;
-    /**
-     * 绋庨锛屽崟浣嶏細鍏�
-     *
-     * taxPrice = totalPrice * taxPercent
-     */
-    private BigDecimal taxPrice;
-
-    /**
-     * 闇�姹傛棩鏈�
-     */
-    private LocalDate demandTime;
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpCustomerDO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpCustomerDO.java
deleted file mode 100644
index 7bffcc1..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpCustomerDO.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package cn.iocoder.yudao.module.erp.dal.dataobject.sale;
-
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import com.baomidou.mybatisplus.annotation.KeySequence;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
-import lombok.*;
-
-import java.math.BigDecimal;
-
-/**
- * ERP 瀹㈡埛 DO
- *
- * @author 鑺嬮亾婧愮爜
- */
-@TableName("erp_customer")
-@KeySequence("erp_customer_seq") // 鐢ㄤ簬 Oracle銆丳ostgreSQL銆並ingbase銆丏B2銆丠2 鏁版嵁搴撶殑涓婚敭鑷銆傚鏋滄槸 MySQL 绛夋暟鎹簱锛屽彲涓嶅啓銆�
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class ErpCustomerDO extends BaseDO {
-
-    /**
-     * 瀹㈡埛缂栧彿
-     */
-    @TableId
-    private Long id;
-    /**
-     * 瀹㈡埛鍚嶇О
-     */
-    private String name;
-    /**
-     * 鑱旂郴浜�
-     */
-    private String contact;
-    /**
-     * 鎵嬫満鍙风爜
-     */
-    private String mobile;
-    /**
-     * 鑱旂郴鐢佃瘽
-     */
-    private String telephone;
-    /**
-     * 鐢靛瓙閭
-     */
-    private String email;
-    /**
-     * 浼犵湡
-     */
-    private String fax;
-    /**
-     * 澶囨敞
-     */
-    private String remark;
-    /**
-     * 寮�鍚姸鎬�
-     *
-     * 鏋氫妇 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum}
-     */
-    private Integer status;
-    /**
-     * 鎺掑簭
-     */
-    private Integer sort;
-    /**
-     * 绾崇◣浜鸿瘑鍒彿
-     */
-    private String taxNo;
-    /**
-     * 绋庣巼
-     */
-    private BigDecimal taxPercent;
-    /**
-     * 寮�鎴疯
-     */
-    private String bankName;
-    /**
-     * 寮�鎴疯处鍙�
-     */
-    private String bankAccount;
-    /**
-     * 寮�鎴峰湴鍧�
-     */
-    private String bankAddress;
-
-}
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpSaleOrderDO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpSaleOrderDO.java
index 83b8634..1b05462 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpSaleOrderDO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpSaleOrderDO.java
@@ -115,21 +115,16 @@
     private String remark;
 
     // ========== 閿�鍞嚭搴� ==========
+
     /**
      * 閿�鍞嚭搴撴暟閲�
      */
     private BigDecimal outCount;
 
-    // ========== 閿�鍞��璐э紙鍏ュ簱锛夛級 ==========
-    /**
-     * 閿�鍞��璐ф暟閲�
-     */
-    private BigDecimal returnCount;
-
     /**
      * 鍑哄簱鐘舵��
      *
-     * 鏋氫妇 {@link cn.iocoder.yudao.module.erp.enums.ErpSaleOrderOutStatusEnum}
+     * 鏋氫妇 {@link cn.iocoder.yudao.module.erp.api.sale.enums.ErpSaleOrderOutStatusEnum}
      */
     private Integer outStatus;
 
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpSaleOrderItemDO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpSaleOrderItemDO.java
index c311157..235c305 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpSaleOrderItemDO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/dataobject/sale/ErpSaleOrderItemDO.java
@@ -78,15 +78,10 @@
     private String remark;
 
     // ========== 閿�鍞嚭搴� ==========
+
     /**
      * 閿�鍞嚭搴撴暟閲�
      */
     private BigDecimal outCount;
-
-    // ========== 閿�鍞��璐э紙鍏ュ簱锛夛級 ==========
-    /**
-     * 閿�鍞��璐ф暟閲�
-     */
-    private BigDecimal returnCount;
 
 }
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseRequestItemMapper.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseRequestItemMapper.java
deleted file mode 100644
index b08e726..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseRequestItemMapper.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package cn.iocoder.yudao.module.erp.dal.mysql.purchase;
-
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestItemDO;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * ERP 閲囪喘鐢宠鏄庣粏 Mapper
- *
- * @author 鑺嬮亾婧愮爜
- */
-@Mapper
-public interface ErpPurchaseRequestItemMapper extends BaseMapperX<ErpPurchaseRequestItemDO> {
-
-    default List<ErpPurchaseRequestItemDO> selectListByRequestId(Long requestId) {
-        return selectList(ErpPurchaseRequestItemDO::getRequestId, requestId);
-    }
-
-    default List<ErpPurchaseRequestItemDO> selectListByRequestIds(Collection<Long> requestIds) {
-        return selectList(ErpPurchaseRequestItemDO::getRequestId, requestIds);
-    }
-
-    default int deleteByRequestId(Long requestId) {
-        return delete(ErpPurchaseRequestItemDO::getRequestId, requestId);
-    }
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseRequestMapper.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseRequestMapper.java
deleted file mode 100644
index d44d171..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/purchase/ErpPurchaseRequestMapper.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package cn.iocoder.yudao.module.erp.dal.mysql.purchase;
-
-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.MPJLambdaWrapperX;
-import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestPageReqVO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestDO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestItemDO;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import org.apache.ibatis.annotations.Mapper;
-
-/**
- * ERP 閲囪喘鐢宠 Mapper
- *
- * @author 鑺嬮亾婧愮爜
- */
-@Mapper
-public interface ErpPurchaseRequestMapper extends BaseMapperX<ErpPurchaseRequestDO> {
-
-    default PageResult<ErpPurchaseRequestDO> selectPage(ErpPurchaseRequestPageReqVO reqVO) {
-        MPJLambdaWrapperX<ErpPurchaseRequestDO> query = new MPJLambdaWrapperX<ErpPurchaseRequestDO>()
-                .likeIfPresent(ErpPurchaseRequestDO::getNo, reqVO.getNo())
-                .eqIfPresent(ErpPurchaseRequestDO::getRequestUserId, reqVO.getRequestUserId())
-                .eqIfPresent(ErpPurchaseRequestDO::getRequestDeptId, reqVO.getRequestDeptId())
-                .betweenIfPresent(ErpPurchaseRequestDO::getRequestTime, reqVO.getRequestTime())
-                .eqIfPresent(ErpPurchaseRequestDO::getStatus, reqVO.getStatus())
-                .likeIfPresent(ErpPurchaseRequestDO::getRequestReason, reqVO.getRequestReason())
-                .orderByDesc(ErpPurchaseRequestDO::getId);
-        if (reqVO.getProductId() != null) {
-            query.leftJoin(ErpPurchaseRequestItemDO.class, ErpPurchaseRequestItemDO::getRequestId, ErpPurchaseRequestDO::getId)
-                    .eq(ErpPurchaseRequestItemDO::getProductId, reqVO.getProductId())
-                    .groupBy(ErpPurchaseRequestDO::getId);
-        }
-        return selectJoinPage(reqVO, ErpPurchaseRequestDO.class, query);
-    }
-
-    default int updateByIdAndStatus(Long id, Integer status, ErpPurchaseRequestDO updateObj) {
-        return update(updateObj, new LambdaUpdateWrapper<ErpPurchaseRequestDO>()
-                .eq(ErpPurchaseRequestDO::getId, id).eq(ErpPurchaseRequestDO::getStatus, status));
-    }
-
-    default ErpPurchaseRequestDO selectByNo(String no) {
-        return selectOne(ErpPurchaseRequestDO::getNo, no);
-    }
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/sale/ErpCustomerMapper.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/sale/ErpCustomerMapper.java
deleted file mode 100644
index 4970f9a..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/sale/ErpCustomerMapper.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package cn.iocoder.yudao.module.erp.dal.mysql.sale;
-
-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.erp.controller.admin.sale.vo.customer.ErpCustomerPageReqVO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.List;
-
-/**
- * ERP 瀹㈡埛 Mapper
- *
- * @author 鑺嬮亾婧愮爜
- */
-@Mapper
-public interface ErpCustomerMapper extends BaseMapperX<ErpCustomerDO> {
-
-    default PageResult<ErpCustomerDO> selectPage(ErpCustomerPageReqVO reqVO) {
-        return selectPage(reqVO, new LambdaQueryWrapperX<ErpCustomerDO>()
-                .likeIfPresent(ErpCustomerDO::getName, reqVO.getName())
-                .eqIfPresent(ErpCustomerDO::getMobile, reqVO.getMobile())
-                .eqIfPresent(ErpCustomerDO::getTelephone, reqVO.getTelephone())
-                .orderByDesc(ErpCustomerDO::getId));
-    }
-
-    default List<ErpCustomerDO> selectListByStatus(Integer status) {
-        return selectList(ErpCustomerDO::getStatus, status);
-    }
-
-}
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/sale/ErpSaleOrderMapper.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/sale/ErpSaleOrderMapper.java
index 0b3b2ee..79e4533 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/sale/ErpSaleOrderMapper.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/mysql/sale/ErpSaleOrderMapper.java
@@ -7,11 +7,8 @@
 import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.order.ErpSaleOrderPageReqVO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOrderDO;
 import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpSaleOrderItemDO;
-import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
-
-import java.util.Objects;
 
 /**
  * ERP 閿�鍞鍗� Mapper
@@ -30,32 +27,6 @@
                 .likeIfPresent(ErpSaleOrderDO::getRemark, reqVO.getRemark())
                 .eqIfPresent(ErpSaleOrderDO::getCreator, reqVO.getCreator())
                 .orderByDesc(ErpSaleOrderDO::getId);
-        // 鍏ュ簱鐘舵�併�備负浠�涔堥渶瑕� t. 鐨勫師鍥狅紝鏄洜涓鸿仈琛ㄦ煡璇㈡椂锛岄渶瑕佹寚瀹氳〃鍚嶏紝涓嶇劧浼氭姤 out_count 閿欒
-        if (Objects.equals(reqVO.getOutStatus(), ErpSaleOrderPageReqVO.OUT_STATUS_NONE)) {
-            query.eq(ErpSaleOrderDO::getOutCount, 0);
-        } else if (Objects.equals(reqVO.getOutStatus(), ErpSaleOrderPageReqVO.OUT_STATUS_PART)) {
-            query.gt(ErpSaleOrderDO::getOutCount, 0).apply("t.out_count < t.total_count");
-        } else if (Objects.equals(reqVO.getOutStatus(), ErpSaleOrderPageReqVO.OUT_STATUS_ALL)) {
-            query.apply("t.out_count = t.total_count");
-        }
-        // 閫�璐х姸鎬�
-        if (Objects.equals(reqVO.getReturnStatus(), ErpSaleOrderPageReqVO.RETURN_STATUS_NONE)) {
-            query.eq(ErpSaleOrderDO::getReturnCount, 0);
-        } else if (Objects.equals(reqVO.getReturnStatus(), ErpSaleOrderPageReqVO.RETURN_STATUS_PART)) {
-            query.gt(ErpSaleOrderDO::getReturnCount, 0).apply("t.return_count < t.total_count");
-        } else if (Objects.equals(reqVO.getReturnStatus(), ErpSaleOrderPageReqVO.RETURN_STATUS_ALL)) {
-            query.apply("t.return_count = t.total_count");
-        }
-        // 鍙攢鍞嚭搴�
-        if (Boolean.TRUE.equals(reqVO.getOutEnable())) {
-            query.eq(ErpSaleOrderDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
-                    .apply("t.out_count < t.total_count");
-        }
-        // 鍙攢鍞��璐�
-        if (Boolean.TRUE.equals(reqVO.getReturnEnable())) {
-            query.eq(ErpSaleOrderDO::getStatus, ErpAuditStatus.APPROVE.getStatus())
-                    .apply("t.return_count < t.out_count");
-        }
         if (reqVO.getProductId() != null) {
             query.leftJoin(ErpSaleOrderItemDO.class, ErpSaleOrderItemDO::getOrderId, ErpSaleOrderDO::getId)
                     .eq(reqVO.getProductId() != null, ErpSaleOrderItemDO::getProductId, reqVO.getProductId())
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/no/ErpNoRedisDAO.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/no/ErpNoRedisDAO.java
index 71d9d25..463b47c 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/no/ErpNoRedisDAO.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/dal/redis/no/ErpNoRedisDAO.java
@@ -28,10 +28,6 @@
      * 閲囪喘璁㈠崟 {@link cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO}
      */
     public static final String PURCHASE_ORDER_NO_PREFIX = "CGDD";
-    /**
-     * 閲囪喘鐢宠 {@link cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestDO}
-     */
-    public static final String PURCHASE_REQUEST_NO_PREFIX = "CGSQ";
 
     /**
      * 浠樻鍗� {@link cn.iocoder.yudao.module.erp.dal.dataobject.finance.ErpFinancePaymentDO}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpPurchaseRequestStatusEnum.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpPurchaseRequestStatusEnum.java
deleted file mode 100644
index b27025a..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/enums/ErpPurchaseRequestStatusEnum.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package cn.iocoder.yudao.module.erp.enums;
-
-import cn.iocoder.yudao.framework.common.core.ArrayValuable;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-
-import java.util.Arrays;
-
-/**
- * ERP 閲囪喘鐢宠瀹℃壒鐘舵�佹灇涓�
- *
- * @author 鑺嬮亾婧愮爜
- */
-@RequiredArgsConstructor
-@Getter
-public enum ErpPurchaseRequestStatusEnum implements ArrayValuable<Integer> {
-
-    DRAFT(0, "鏈彁浜�"),
-    PROCESS(10, "瀹℃壒涓�"),
-    APPROVE(20, "瀹℃牳閫氳繃"),
-    REJECT(30, "瀹℃牳涓嶉�氳繃"),
-    CANCEL(40, "宸插彇娑�");
-
-    private final Integer status;
-    private final String name;
-
-    public static final Integer[] ARRAYS = Arrays.stream(values())
-            .map(ErpPurchaseRequestStatusEnum::getStatus).toArray(Integer[]::new);
-
-    @Override
-    public Integer[] array() {
-        return ARRAYS;
-    }
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseOrderServiceImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseOrderServiceImpl.java
index 80777de..ec5cd18 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseOrderServiceImpl.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseOrderServiceImpl.java
@@ -16,7 +16,6 @@
 import cn.iocoder.yudao.module.erp.enums.ErpPurchaseOrderInStatusEnum;
 import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
 import jakarta.annotation.Resource;
-import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
@@ -30,9 +29,6 @@
 
 /**
  * ERP 閲囪喘璁㈠崟 Service 瀹炵幇绫�
- *
- * 娉ㄦ剰锛氶噰璐鍗曚笉闇�瑕� BPM 瀹℃壒锛屽鎵规祦绋嬪湪閲囪喘鐢宠闃舵瀹屾垚銆�
- * 閲囪喘璁㈠崟鐢遍噰璐敵璇风敓鎴愶紝鎴栫洿鎺ュ垱寤猴紙鐘舵�佷负宸插鏍革級銆�
  *
  * @author 鑺嬮亾婧愮爜
  */
@@ -52,10 +48,6 @@
     private ErpSupplierService supplierService;
     @Resource
     private ErpAccountService accountService;
-
-    @Resource
-    @Lazy
-    private ErpPurchaseRequestService purchaseRequestService;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -320,10 +312,6 @@
         // 4. 鏇存柊閲囪喘璁㈠崟鍏ュ簱鐘舵��
         purchaseOrderMapper.updateById(new ErpPurchaseOrderDO()
                 .setId(orderId).setInStatus(inStatus));
-        // 5. 鍚屾鏇存柊閲囪喘鐢宠鐨勫叆搴撶姸鎬侊紙濡傛灉鏈夊叧鑱旂殑閲囪喘鐢宠锛�
-        if (order.getRequestId() != null) {
-            purchaseRequestService.updatePurchaseRequestInStatus(order.getRequestId(), inStatus);
-        }
     }
 
     /**
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestService.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestService.java
deleted file mode 100644
index 569f11c..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestService.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package cn.iocoder.yudao.module.erp.service.purchase;
-
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestPageReqVO;
-import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestSaveReqVO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestDO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestItemDO;
-import jakarta.validation.Valid;
-
-import java.util.Collection;
-import java.util.List;
-
-/**
- * ERP 閲囪喘鐢宠 Service 鎺ュ彛
- *
- * @author 鑺嬮亾婧愮爜
- */
-public interface ErpPurchaseRequestService {
-
-    /**
-     * 鍒涘缓閲囪喘鐢宠
-     *
-     * @param createReqVO 鍒涘缓淇℃伅
-     * @param userId      鐢ㄦ埛缂栧彿锛堢敵璇蜂汉锛�
-     * @param deptId      閮ㄩ棬缂栧彿锛堢敵璇烽儴闂級
-     * @return 缂栧彿
-     */
-    Long createPurchaseRequest(@Valid ErpPurchaseRequestSaveReqVO createReqVO, Long userId, Long deptId);
-
-    /**
-     * 鏇存柊閲囪喘鐢宠
-     *
-     * @param updateReqVO 鏇存柊淇℃伅
-     */
-    void updatePurchaseRequest(@Valid ErpPurchaseRequestSaveReqVO updateReqVO);
-
-    /**
-     * 鍒犻櫎閲囪喘鐢宠
-     *
-     * @param ids 缂栧彿鏁扮粍
-     */
-    void deletePurchaseRequest(List<Long> ids);
-
-    /**
-     * 鑾峰緱閲囪喘鐢宠
-     *
-     * @param id 缂栧彿
-     * @return 閲囪喘鐢宠
-     */
-    ErpPurchaseRequestDO getPurchaseRequest(Long id);
-
-    /**
-     * 鑾峰緱閲囪喘鐢宠鍒嗛〉
-     *
-     * @param pageReqVO 鍒嗛〉鏌ヨ
-     * @return 閲囪喘鐢宠鍒嗛〉
-     */
-    PageResult<ErpPurchaseRequestDO> getPurchaseRequestPage(ErpPurchaseRequestPageReqVO pageReqVO);
-
-    /**
-     * 鑾峰緱閲囪喘鐢宠鏄庣粏鍒楄〃
-     *
-     * @param requestId 閲囪喘鐢宠缂栧彿
-     * @return 閲囪喘鐢宠鏄庣粏鍒楄〃
-     */
-    List<ErpPurchaseRequestItemDO> getPurchaseRequestItemListByRequestId(Long requestId);
-
-    /**
-     * 鑾峰緱閲囪喘鐢宠鏄庣粏鍒楄〃
-     *
-     * @param requestIds 閲囪喘鐢宠缂栧彿鏁扮粍
-     * @return 閲囪喘鐢宠鏄庣粏鍒楄〃
-     */
-    List<ErpPurchaseRequestItemDO> getPurchaseRequestItemListByRequestIds(Collection<Long> requestIds);
-
-    /**
-     * 鎻愪氦閲囪喘鐢宠瀹℃壒
-     *
-     * @param id                   缂栧彿
-     * @param processDefinitionKey 娴佺▼瀹氫箟 Key锛堢敤鎴烽�夋嫨锛�
-     * @param userId               鐢ㄦ埛缂栧彿
-     */
-    void submitPurchaseRequest(Long id, String processDefinitionKey, Long userId);
-
-    /**
-     * 鏇存柊閲囪喘鐢宠瀹℃壒鐘舵��
-     *
-     * @param id        缂栧彿
-     * @param bpmResult BPM 瀹℃壒缁撴灉
-     */
-    void updatePurchaseRequestAuditStatus(Long id, Integer bpmResult);
-
-    /**
-     * 鏍规嵁閲囪喘鐢宠鐢熸垚閲囪喘璁㈠崟
-     *
-     * @param id         閲囪喘鐢宠缂栧彿
-     * @param supplierId 渚涘簲鍟嗙紪鍙�
-     * @param userId     鐢ㄦ埛缂栧彿
-     * @return 閲囪喘璁㈠崟缂栧彿
-     */
-    Long generatePurchaseOrder(Long id, Long supplierId, Long userId);
-
-    /**
-     * 鑾峰彇閲囪喘鐢宠瀹℃壒娴佺▼鍒楄〃
-     *
-     * @return 娴佺▼瀹氫箟鍒楄〃
-     */
-    List<java.util.Map<String, Object>> getPurchaseRequestApproveProcessDefinitionList();
-
-    /**
-     * 鏇存柊閲囪喘鐢宠鐨勫叆搴撶姸鎬�
-     *
-     * @param id       閲囪喘鐢宠缂栧彿
-     * @param inStatus 鍏ュ簱鐘舵��
-     */
-    void updatePurchaseRequestInStatus(Long id, Integer inStatus);
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestServiceImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestServiceImpl.java
deleted file mode 100644
index 88778f1..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestServiceImpl.java
+++ /dev/null
@@ -1,401 +0,0 @@
-package cn.iocoder.yudao.module.erp.service.purchase;
-
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.lang.Assert;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-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.BpmCategoryService;
-import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
-import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderSaveReqVO;
-import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestPageReqVO;
-import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.request.ErpPurchaseRequestSaveReqVO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestDO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestItemDO;
-import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseRequestItemMapper;
-import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseRequestMapper;
-import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
-import cn.iocoder.yudao.module.erp.enums.ErpPurchaseRequestStatusEnum;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.flowable.engine.repository.ProcessDefinition;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-import org.springframework.validation.annotation.Validated;
-
-import java.math.BigDecimal;
-import java.util.*;
-
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
-import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
-
-/**
- * ERP 閲囪喘鐢宠 Service 瀹炵幇绫�
- *
- * @author 鑺嬮亾婧愮爜
- */
-@Service
-@Validated
-@Slf4j
-public class ErpPurchaseRequestServiceImpl implements ErpPurchaseRequestService {
-
-    /**
-     * 閲囪喘鐢宠 BPM 鍒嗙被缂栫爜
-     */
-    private static final String PURCHASE_REQUEST_APPROVE_CATEGORY_CODE = "purchase_request_approve";
-
-    @Resource
-    private ErpPurchaseRequestMapper purchaseRequestMapper;
-    @Resource
-    private ErpPurchaseRequestItemMapper purchaseRequestItemMapper;
-
-    @Resource
-    private ErpNoRedisDAO noRedisDAO;
-
-    @Resource
-    private ErpSupplierService supplierService;
-
-    @Resource
-    private BpmCategoryService bpmCategoryService;
-    @Resource
-    private BpmProcessDefinitionService bpmProcessDefinitionService;
-    @Resource
-    private BpmProcessInstanceApi bpmProcessInstanceApi;
-
-    @Resource
-    private ErpPurchaseOrderService purchaseOrderService;
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Long createPurchaseRequest(ErpPurchaseRequestSaveReqVO createReqVO, Long userId, Long deptId) {
-        // 1.1 鏍¢獙璁㈠崟椤圭殑鏈夋晥鎬�
-        List<ErpPurchaseRequestItemDO> purchaseRequestItems = validatePurchaseRequestItems(createReqVO.getItems());
-        // 1.2 鐢熸垚鐢宠鍗曞彿锛屽苟鏍¢獙鍞竴鎬�
-        String no = noRedisDAO.generate(ErpNoRedisDAO.PURCHASE_REQUEST_NO_PREFIX);
-        if (purchaseRequestMapper.selectByNo(no) != null) {
-            throw exception(PURCHASE_REQUEST_NO_EXISTS);
-        }
-
-        // 鏃ュ織锛氭鏌ラ儴闂ㄥ拰鐢ㄦ埛淇℃伅
-        log.info("[createPurchaseRequest] 鍒涘缓閲囪喘鐢宠锛寀serId={}, deptId={}", userId, deptId);
-
-        // 2.1 鎻掑叆鐢宠鍗�
-        ErpPurchaseRequestDO purchaseRequest = BeanUtils.toBean(createReqVO, ErpPurchaseRequestDO.class, req -> req
-                .setNo(no)
-                .setStatus(ErpPurchaseRequestStatusEnum.DRAFT.getStatus())
-                .setRequestUserId(userId)
-                .setRequestDeptId(deptId));
-        calculateTotalPrice(purchaseRequest, purchaseRequestItems);
-        purchaseRequestMapper.insert(purchaseRequest);
-        // 2.2 鎻掑叆鐢宠鏄庣粏
-        purchaseRequestItems.forEach(o -> o.setRequestId(purchaseRequest.getId()));
-        purchaseRequestItemMapper.insertBatch(purchaseRequestItems);
-        return purchaseRequest.getId();
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void updatePurchaseRequest(ErpPurchaseRequestSaveReqVO updateReqVO) {
-        // 1.1 鏍¢獙瀛樺湪
-        ErpPurchaseRequestDO purchaseRequest = validatePurchaseRequestExists(updateReqVO.getId());
-        // 1.2 鏍¢獙鐘舵�侊紝鍙湁鑽夌鐘舵�佹墠鑳戒慨鏀�
-        if (!ErpPurchaseRequestStatusEnum.DRAFT.getStatus().equals(purchaseRequest.getStatus())) {
-            throw exception(PURCHASE_REQUEST_UPDATE_FAIL_NOT_DRAFT, purchaseRequest.getNo());
-        }
-        // 1.3 鏍¢獙璁㈠崟椤圭殑鏈夋晥鎬�
-        List<ErpPurchaseRequestItemDO> purchaseRequestItems = validatePurchaseRequestItems(updateReqVO.getItems());
-
-        // 2.1 鏇存柊鐢宠鍗�
-        ErpPurchaseRequestDO updateObj = BeanUtils.toBean(updateReqVO, ErpPurchaseRequestDO.class);
-        calculateTotalPrice(updateObj, purchaseRequestItems);
-        purchaseRequestMapper.updateById(updateObj);
-        // 2.2 鏇存柊鐢宠鏄庣粏
-        updatePurchaseRequestItemList(updateReqVO.getId(), purchaseRequestItems);
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void deletePurchaseRequest(List<Long> ids) {
-        // 1. 鏍¢獙涓嶅浜庨潪鑽夌鐘舵��
-        List<ErpPurchaseRequestDO> purchaseRequests = purchaseRequestMapper.selectByIds(ids);
-        if (CollUtil.isEmpty(purchaseRequests)) {
-            return;
-        }
-        purchaseRequests.forEach(purchaseRequest -> {
-            if (!ErpPurchaseRequestStatusEnum.DRAFT.getStatus().equals(purchaseRequest.getStatus())) {
-                throw exception(PURCHASE_REQUEST_DELETE_FAIL_NOT_DRAFT, purchaseRequest.getNo());
-            }
-        });
-
-        // 2. 閬嶅巻鍒犻櫎
-        purchaseRequests.forEach(purchaseRequest -> {
-            // 2.1 鍒犻櫎鐢宠鍗�
-            purchaseRequestMapper.deleteById(purchaseRequest.getId());
-            // 2.2 鍒犻櫎鐢宠鏄庣粏
-            purchaseRequestItemMapper.deleteByRequestId(purchaseRequest.getId());
-        });
-    }
-
-    private ErpPurchaseRequestDO validatePurchaseRequestExists(Long id) {
-        ErpPurchaseRequestDO purchaseRequest = purchaseRequestMapper.selectById(id);
-        if (purchaseRequest == null) {
-            throw exception(PURCHASE_REQUEST_NOT_EXISTS);
-        }
-        return purchaseRequest;
-    }
-
-    private List<ErpPurchaseRequestItemDO> validatePurchaseRequestItems(List<ErpPurchaseRequestSaveReqVO.Item> list) {
-        // 杞寲涓� ErpPurchaseRequestItemDO 鍒楄〃锛堜骇鍝侀獙璇佸凡绉婚櫎锛屼娇鐢� MDM 鐗╂枡锛�
-        return convertList(list, o -> BeanUtils.toBean(o, ErpPurchaseRequestItemDO.class, item -> {
-            if (item.getProductPrice() != null && item.getCount() != null) {
-                item.setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()));
-                if (item.getTaxPercent() != null) {
-                    item.setTaxPrice(MoneyUtils.priceMultiplyPercent(item.getTotalPrice(), item.getTaxPercent()));
-                }
-            }
-        }));
-    }
-
-    private void updatePurchaseRequestItemList(Long id, List<ErpPurchaseRequestItemDO> newList) {
-        // 绗竴姝ワ紝瀵规瘮鏂拌�佹暟鎹紝鑾峰緱娣诲姞銆佷慨鏀广�佸垹闄ょ殑鍒楄〃
-        List<ErpPurchaseRequestItemDO> oldList = purchaseRequestItemMapper.selectListByRequestId(id);
-        List<List<ErpPurchaseRequestItemDO>> diffList = diffList(oldList, newList,
-                (oldVal, newVal) -> oldVal.getId().equals(newVal.getId()));
-
-        // 绗簩姝ワ紝鎵归噺娣诲姞銆佷慨鏀广�佸垹闄�
-        if (CollUtil.isNotEmpty(diffList.get(0))) {
-            diffList.get(0).forEach(o -> o.setRequestId(id));
-            purchaseRequestItemMapper.insertBatch(diffList.get(0));
-        }
-        if (CollUtil.isNotEmpty(diffList.get(1))) {
-            purchaseRequestItemMapper.updateBatch(diffList.get(1));
-        }
-        if (CollUtil.isNotEmpty(diffList.get(2))) {
-            purchaseRequestItemMapper.deleteByIds(convertList(diffList.get(2), ErpPurchaseRequestItemDO::getId));
-        }
-    }
-
-    private void calculateTotalPrice(ErpPurchaseRequestDO purchaseRequest, List<ErpPurchaseRequestItemDO> items) {
-        purchaseRequest.setTotalCount(getSumValue(items, ErpPurchaseRequestItemDO::getCount, BigDecimal::add));
-        purchaseRequest.setTotalProductPrice(getSumValue(items, ErpPurchaseRequestItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO));
-        purchaseRequest.setTotalTaxPrice(getSumValue(items, ErpPurchaseRequestItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO));
-        purchaseRequest.setTotalPrice(purchaseRequest.getTotalProductPrice().add(purchaseRequest.getTotalTaxPrice()));
-        // 璁$畻浼樻儬浠锋牸
-        if (purchaseRequest.getDiscountPercent() == null) {
-            purchaseRequest.setDiscountPercent(BigDecimal.ZERO);
-        }
-        purchaseRequest.setDiscountPrice(MoneyUtils.priceMultiplyPercent(purchaseRequest.getTotalPrice(), purchaseRequest.getDiscountPercent()));
-        purchaseRequest.setTotalPrice(purchaseRequest.getTotalPrice().subtract(purchaseRequest.getDiscountPrice()));
-    }
-
-    @Override
-    public ErpPurchaseRequestDO getPurchaseRequest(Long id) {
-        return purchaseRequestMapper.selectById(id);
-    }
-
-    @Override
-    public PageResult<ErpPurchaseRequestDO> getPurchaseRequestPage(ErpPurchaseRequestPageReqVO pageReqVO) {
-        return purchaseRequestMapper.selectPage(pageReqVO);
-    }
-
-    @Override
-    public List<ErpPurchaseRequestItemDO> getPurchaseRequestItemListByRequestId(Long requestId) {
-        return purchaseRequestItemMapper.selectListByRequestId(requestId);
-    }
-
-    @Override
-    public List<ErpPurchaseRequestItemDO> getPurchaseRequestItemListByRequestIds(Collection<Long> requestIds) {
-        if (CollUtil.isEmpty(requestIds)) {
-            return Collections.emptyList();
-        }
-        return purchaseRequestItemMapper.selectListByRequestIds(requestIds);
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void submitPurchaseRequest(Long id, String processDefinitionKey, Long userId) {
-        // 1. 鏍¢獙鐢宠鍗曞瓨鍦ㄤ笖涓鸿崏绋跨姸鎬�
-        ErpPurchaseRequestDO request = validatePurchaseRequestExists(id);
-        if (!ErpPurchaseRequestStatusEnum.DRAFT.getStatus().equals(request.getStatus())) {
-            throw exception(PURCHASE_REQUEST_SUBMIT_FAIL_NOT_DRAFT);
-        }
-
-        // 2. 鏍¢獙鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-        validatePurchaseRequestApproveCategoryAndProcessDefinition();
-
-        // 3. 鏍¢獙浼犲叆鐨勬祦绋嬪畾涔� Key 鏄惁灞炰簬璇ュ垎绫讳笖澶勪簬婵�娲荤姸鎬�
-        ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(processDefinitionKey);
-        if (processDefinition == null) {
-            throw exception(PURCHASE_REQUEST_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-
-        // 4. 鍒涘缓娴佺▼瀹炰緥锛堜娇鐢ㄧ敤鎴烽�夋嫨鐨勬祦绋嬪畾涔� Key锛�
-        String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId,
-                new BpmProcessInstanceCreateReqDTO()
-                        .setProcessDefinitionKey(processDefinitionKey)
-                        .setBusinessKey(String.valueOf(id)));
-
-        // 5. 鏇存柊鐢宠鍗曠姸鎬�
-        purchaseRequestMapper.updateById(new ErpPurchaseRequestDO()
-                .setId(id)
-                .setProcessInstanceId(processInstanceId)
-                .setStatus(ErpPurchaseRequestStatusEnum.PROCESS.getStatus()));
-    }
-
-    /**
-     * 鏍¢獙 BPM 閲囪喘鐢宠瀹℃壒鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-     */
-    private void validatePurchaseRequestApproveCategoryAndProcessDefinition() {
-        // 1. 鏍¢獙鍒嗙被鏄惁瀛樺湪
-        List<String> codes = Collections.singletonList(PURCHASE_REQUEST_APPROVE_CATEGORY_CODE);
-        Map<String, ?> categoryMap = bpmCategoryService.getCategoryMap(codes);
-        if (!categoryMap.containsKey(PURCHASE_REQUEST_APPROVE_CATEGORY_CODE)) {
-            throw exception(PURCHASE_REQUEST_BPM_CATEGORY_NOT_EXISTS);
-        }
-
-        // 2. 鏍¢獙鍒嗙被涓嬫槸鍚︽湁鍙敤鐨勬祦绋嬪畾涔�
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(PURCHASE_REQUEST_APPROVE_CATEGORY_CODE);
-        if (CollUtil.isEmpty(definitionInfoList)) {
-            throw exception(PURCHASE_REQUEST_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-
-        // 3. 鏍¢獙鏄惁鏈夋縺娲荤姸鎬佺殑娴佺▼瀹氫箟
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-        boolean hasActiveDefinition = processDefinitions.stream()
-                .anyMatch(pd -> !pd.isSuspended());
-        if (!hasActiveDefinition) {
-            throw exception(PURCHASE_REQUEST_BPM_PROCESS_DEFINITION_NOT_EXISTS);
-        }
-    }
-
-    @Override
-    public void updatePurchaseRequestAuditStatus(Long id, Integer bpmResult) {
-        // 1. 鏍¢獙鐢宠鍗曞瓨鍦ㄤ笖涓哄鎵逛腑鐘舵��
-        ErpPurchaseRequestDO request = validatePurchaseRequestExists(id);
-        if (!ErpPurchaseRequestStatusEnum.PROCESS.getStatus().equals(request.getStatus())) {
-            log.error("[updatePurchaseRequestAuditStatus] 鐢宠鍗�({}) 涓嶅浜庡鎵逛腑", id);
-            throw exception(PURCHASE_REQUEST_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS);
-        }
-
-        // 2. 杞崲瀹℃壒缁撴灉
-        Integer auditStatus = convertBpmResultToAuditStatus(bpmResult);
-        purchaseRequestMapper.updateById(new ErpPurchaseRequestDO()
-                .setId(id)
-                .setStatus(auditStatus));
-    }
-
-    /**
-     * BPM 瀹℃壒缁撴灉杞崲
-     */
-    private Integer convertBpmResultToAuditStatus(Integer bpmResult) {
-        Integer auditStatus = BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmResult)
-                ? ErpPurchaseRequestStatusEnum.APPROVE.getStatus()
-                : BpmTaskStatusEnum.REJECT.getStatus().equals(bpmResult)
-                ? ErpPurchaseRequestStatusEnum.REJECT.getStatus()
-                : BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmResult)
-                ? ErpPurchaseRequestStatusEnum.CANCEL.getStatus() : null;
-        Assert.notNull(auditStatus, "BPM 瀹℃壒缁撴灉({}) 杞崲澶辫触", bpmResult);
-        return auditStatus;
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    public Long generatePurchaseOrder(Long id, Long supplierId, Long userId) {
-        // 1. 鏍¢獙鐢宠鍗曞瓨鍦ㄤ笖宸插鎵归�氳繃
-        ErpPurchaseRequestDO request = validatePurchaseRequestExists(id);
-        if (!ErpPurchaseRequestStatusEnum.APPROVE.getStatus().equals(request.getStatus())) {
-            throw exception(PURCHASE_REQUEST_NOT_APPROVE);
-        }
-        // 鏍¢獙鏄惁宸茬敓鎴愰噰璐鍗�
-        if (request.getOrderId() != null) {
-            throw exception(PURCHASE_REQUEST_ORDER_EXISTS);
-        }
-
-        // 2. 鏍¢獙渚涘簲鍟�
-        supplierService.validateSupplier(supplierId);
-
-        // 3. 鑾峰彇鐢宠鏄庣粏
-        List<ErpPurchaseRequestItemDO> requestItems = purchaseRequestItemMapper.selectListByRequestId(id);
-
-        // 4. 鏋勫缓閲囪喘璁㈠崟 VO
-        ErpPurchaseOrderSaveReqVO orderVO = new ErpPurchaseOrderSaveReqVO();
-        orderVO.setSupplierId(supplierId);
-        orderVO.setOrderTime(java.time.LocalDateTime.now());
-        orderVO.setRemark("鐢遍噰璐敵璇峰崟[" + request.getNo() + "]鐢熸垚");
-        // 杞崲鏄庣粏椤�
-        orderVO.setItems(convertList(requestItems, item -> {
-            ErpPurchaseOrderSaveReqVO.Item orderItem = new ErpPurchaseOrderSaveReqVO.Item();
-            orderItem.setProductId(item.getProductId());
-            orderItem.setProductUnitId(item.getProductUnitId());
-            orderItem.setProductPrice(item.getProductPrice());
-            orderItem.setCount(item.getCount());
-            orderItem.setTaxPercent(item.getTaxPercent());
-            orderItem.setRemark(item.getRemark());
-            return orderItem;
-        }));
-
-        // 5. 鍒涘缓閲囪喘璁㈠崟
-        Long orderId = purchaseOrderService.createPurchaseOrder(orderVO);
-
-        // 6. 鏇存柊鐢宠鍗曞叧鑱斾俊鎭�
-        purchaseRequestMapper.updateById(new ErpPurchaseRequestDO()
-                .setId(id)
-                .setOrderId(orderId)
-                .setOrderTime(java.time.LocalDateTime.now()));
-
-        return orderId;
-    }
-
-    @Override
-    public List<Map<String, Object>> getPurchaseRequestApproveProcessDefinitionList() {
-        // 1. 鏍¢獙鍒嗙被鍜屾祦绋嬪畾涔夋槸鍚﹀瓨鍦�
-        validatePurchaseRequestApproveCategoryAndProcessDefinition();
-
-        // 2. 鑾峰彇鍒嗙被涓嬬殑娴佺▼瀹氫箟淇℃伅
-        List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService
-                .getProcessDefinitionInfoListByCategory(PURCHASE_REQUEST_APPROVE_CATEGORY_CODE);
-
-        // 3. 鑾峰彇娴佺▼瀹氫箟璇︽儏
-        Set<String> processDefinitionIds = convertSet(definitionInfoList, BpmProcessDefinitionInfoDO::getProcessDefinitionId);
-        List<ProcessDefinition> processDefinitions = bpmProcessDefinitionService.getProcessDefinitionList(processDefinitionIds);
-
-        // 4. 杩囨护锛氬彧淇濈暀婵�娲荤姸鎬侊紝涓旂浉鍚� key 鍙繚鐣欐渶鏂扮増鏈�
-        Map<String, ProcessDefinition> latestVersionMap = new HashMap<>();
-        for (ProcessDefinition pd : processDefinitions) {
-            if (pd.isSuspended()) {
-                continue; // 璺宠繃鎸傝捣鐨勬祦绋�
-            }
-            ProcessDefinition existing = latestVersionMap.get(pd.getKey());
-            if (existing == null || pd.getVersion() > existing.getVersion()) {
-                latestVersionMap.put(pd.getKey(), pd);
-            }
-        }
-
-        // 5. 杩斿洖娴佺▼瀹氫箟鍒楄〃
-        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());
-            item.put("version", pd.getVersion());
-            result.add(item);
-        }
-        return result;
-    }
-
-    @Override
-    public void updatePurchaseRequestInStatus(Long id, Integer inStatus) {
-        purchaseRequestMapper.updateById(new ErpPurchaseRequestDO()
-                .setId(id)
-                .setInStatus(inStatus));
-    }
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/listener/ErpPurchaseRequestStatusListener.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/listener/ErpPurchaseRequestStatusListener.java
deleted file mode 100644
index 44a4008..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/listener/ErpPurchaseRequestStatusListener.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package cn.iocoder.yudao.module.erp.service.purchase.listener;
-
-import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent;
-import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseRequestDO;
-import cn.iocoder.yudao.module.erp.dal.mysql.purchase.ErpPurchaseRequestMapper;
-import cn.iocoder.yudao.module.erp.enums.ErpPurchaseRequestStatusEnum;
-import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseRequestService;
-import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.context.ApplicationListener;
-import org.springframework.stereotype.Component;
-
-/**
- * 閲囪喘鐢宠瀹℃壒鐨勭粨鏋滅洃鍚櫒瀹炵幇绫�
- *
- * 閫氳繃 businessKey锛堥噰璐敵璇稩D锛夊尮閰嶏紝鑰屼笉鏄浐瀹氱殑娴佺▼瀹氫箟 Key锛�
- * 杩欐牱鍙互鏀寔鍒嗙被涓嬩换鎰� Key 鐨勬祦绋嬫ā鍨嬨��
- *
- * @author 鑺嬮亾婧愮爜
- */
-@Component
-@Slf4j
-public class ErpPurchaseRequestStatusListener implements ApplicationListener<BpmProcessInstanceStatusEvent> {
-
-    @Resource
-    private ErpPurchaseRequestService purchaseRequestService;
-    @Resource
-    private ErpPurchaseRequestMapper purchaseRequestMapper;
-
-    @Override
-    public void onApplicationEvent(BpmProcessInstanceStatusEvent event) {
-        // 閫氳繃 businessKey 鏌ヨ閲囪喘鐢宠鍗�
-        Long requestId;
-        try {
-            requestId = Long.parseLong(event.getBusinessKey());
-        } catch (NumberFormatException e) {
-            return; // businessKey 涓嶆槸鏁板瓧锛屽拷鐣�
-        }
-
-        ErpPurchaseRequestDO request = purchaseRequestMapper.selectById(requestId);
-        if (request == null) {
-            return; // 涓嶆槸閲囪喘鐢宠锛屽拷鐣�
-        }
-
-        // 鍙湁瀹℃壒涓姸鎬佺殑鐢宠鍗曟墠澶勭悊
-        if (!ErpPurchaseRequestStatusEnum.PROCESS.getStatus().equals(request.getStatus())) {
-            log.warn("[onApplicationEvent] 閲囪喘鐢宠鍗�({}) 涓嶅浜庡鎵逛腑鐘舵�侊紝褰撳墠鐘舵��: {}", requestId, request.getStatus());
-            return;
-        }
-
-        log.info("[onApplicationEvent] 閲囪喘鐢宠鍗�({}) 瀹℃壒鐘舵�佹洿鏂�: {}", requestId, event.getStatus());
-        // 鏇存柊瀹℃壒鐘舵��
-        purchaseRequestService.updatePurchaseRequestAuditStatus(requestId, event.getStatus());
-    }
-
-}
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpCustomerService.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpCustomerService.java
deleted file mode 100644
index d047300..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpCustomerService.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package cn.iocoder.yudao.module.erp.service.sale;
-
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerPageReqVO;
-import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerSaveReqVO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
-import jakarta.validation.Valid;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
-
-/**
- * ERP 瀹㈡埛 Service 鎺ュ彛
- *
- * @author 鑺嬮亾婧愮爜
- */
-public interface ErpCustomerService {
-
-    /**
-     * 鍒涘缓瀹㈡埛
-     *
-     * @param createReqVO 鍒涘缓淇℃伅
-     * @return 缂栧彿
-     */
-    Long createCustomer(@Valid ErpCustomerSaveReqVO createReqVO);
-
-    /**
-     * 鏇存柊瀹㈡埛
-     *
-     * @param updateReqVO 鏇存柊淇℃伅
-     */
-    void updateCustomer(@Valid ErpCustomerSaveReqVO updateReqVO);
-
-    /**
-     * 鍒犻櫎瀹㈡埛
-     *
-     * @param id 缂栧彿
-     */
-    void deleteCustomer(Long id);
-
-    /**
-     * 鑾峰緱瀹㈡埛
-     *
-     * @param id 缂栧彿
-     * @return 瀹㈡埛
-     */
-    ErpCustomerDO getCustomer(Long id);
-
-    /**
-     * 鏍¢獙瀹㈡埛
-     *
-     * @param id 缂栧彿
-     * @return 瀹㈡埛
-     */
-    ErpCustomerDO validateCustomer(Long id);
-
-    /**
-     * 鑾峰緱瀹㈡埛鍒楄〃
-     *
-     * @param ids 缂栧彿鍒楄〃
-     * @return 瀹㈡埛鍒楄〃
-     */
-    List<ErpCustomerDO> getCustomerList(Collection<Long> ids);
-
-    /**
-     * 鑾峰緱瀹㈡埛 Map
-     *
-     * @param ids 缂栧彿鍒楄〃
-     * @return 瀹㈡埛 Map
-     */
-    default Map<Long, ErpCustomerDO> getCustomerMap(Collection<Long> ids) {
-        return convertMap(getCustomerList(ids), ErpCustomerDO::getId);
-    }
-
-    /**
-     * 鑾峰緱瀹㈡埛鍒嗛〉
-     *
-     * @param pageReqVO 鍒嗛〉鏌ヨ
-     * @return 瀹㈡埛鍒嗛〉
-     */
-    PageResult<ErpCustomerDO> getCustomerPage(ErpCustomerPageReqVO pageReqVO);
-
-    /**
-     * 鑾峰緱鎸囧畾鐘舵�佺殑瀹㈡埛鍒楄〃
-     *
-     * @param status 鐘舵��
-     * @return 瀹㈡埛鍒楄〃
-     */
-    List<ErpCustomerDO> getCustomerListByStatus(Integer status);
-
-}
\ No newline at end of file
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpCustomerServiceImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpCustomerServiceImpl.java
deleted file mode 100644
index a5accdc..0000000
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpCustomerServiceImpl.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package cn.iocoder.yudao.module.erp.service.sale;
-
-import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerPageReqVO;
-import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.customer.ErpCustomerSaveReqVO;
-import cn.iocoder.yudao.module.erp.dal.dataobject.sale.ErpCustomerDO;
-import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpCustomerMapper;
-import jakarta.annotation.Resource;
-import org.springframework.stereotype.Service;
-import org.springframework.validation.annotation.Validated;
-
-import java.util.Collection;
-import java.util.List;
-
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.CUSTOMER_NOT_ENABLE;
-import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.CUSTOMER_NOT_EXISTS;
-
-/**
- * ERP 瀹㈡埛 Service 瀹炵幇绫�
- *
- * @author 鑺嬮亾婧愮爜
- */
-@Service
-@Validated
-public class ErpCustomerServiceImpl implements ErpCustomerService {
-
-    @Resource
-    private ErpCustomerMapper customerMapper;
-
-    @Override
-    public Long createCustomer(ErpCustomerSaveReqVO createReqVO) {
-        // 鎻掑叆
-        ErpCustomerDO customer = BeanUtils.toBean(createReqVO, ErpCustomerDO.class);
-        customerMapper.insert(customer);
-        // 杩斿洖
-        return customer.getId();
-    }
-
-    @Override
-    public void updateCustomer(ErpCustomerSaveReqVO updateReqVO) {
-        // 鏍¢獙瀛樺湪
-        validateCustomerExists(updateReqVO.getId());
-        // 鏇存柊
-        ErpCustomerDO updateObj = BeanUtils.toBean(updateReqVO, ErpCustomerDO.class);
-        customerMapper.updateById(updateObj);
-    }
-
-    @Override
-    public void deleteCustomer(Long id) {
-        // 鏍¢獙瀛樺湪
-        validateCustomerExists(id);
-        // 鍒犻櫎
-        customerMapper.deleteById(id);
-    }
-
-    private void validateCustomerExists(Long id) {
-        if (customerMapper.selectById(id) == null) {
-            throw exception(CUSTOMER_NOT_EXISTS);
-        }
-    }
-
-    @Override
-    public ErpCustomerDO getCustomer(Long id) {
-        return customerMapper.selectById(id);
-    }
-
-    @Override
-    public ErpCustomerDO validateCustomer(Long id) {
-        ErpCustomerDO customer = customerMapper.selectById(id);
-        if (customer == null) {
-            throw exception(CUSTOMER_NOT_EXISTS);
-        }
-        if (CommonStatusEnum.isDisable(customer.getStatus())) {
-            throw exception(CUSTOMER_NOT_ENABLE, customer.getName());
-        }
-        return customer;
-    }
-
-    @Override
-    public List<ErpCustomerDO> getCustomerList(Collection<Long> ids) {
-        return customerMapper.selectByIds(ids);
-    }
-
-    @Override
-    public PageResult<ErpCustomerDO> getCustomerPage(ErpCustomerPageReqVO pageReqVO) {
-        return customerMapper.selectPage(pageReqVO);
-    }
-
-    @Override
-    public List<ErpCustomerDO> getCustomerListByStatus(Integer status) {
-        return customerMapper.selectListByStatus(status);
-    }
-
-}
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderService.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderService.java
index e1c0781..862f461 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderService.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderService.java
@@ -65,14 +65,6 @@
     void updateSaleOrderOutCount(Long id, Map<Long, BigDecimal> outCountMap);
 
     /**
-     * 鏇存柊閿�鍞鍗曠殑閫�璐ф暟閲�
-     *
-     * @param orderId 缂栧彿
-     * @param returnCountMap 閫�璐ф暟閲� Map锛歬ey 閿�鍞鍗曢」缂栧彿锛泇alue 閫�璐ф暟閲�
-     */
-    void updateSaleOrderReturnCount(Long orderId, Map<Long, BigDecimal> returnCountMap);
-
-    /**
      * 鍒犻櫎閿�鍞鍗�
      *
      * @param ids 缂栧彿鏁扮粍
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java
index b9eddf9..1451e01 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java
@@ -15,7 +15,7 @@
 import cn.iocoder.yudao.module.erp.dal.mysql.sale.ErpSaleOrderMapper;
 import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
 import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
-import cn.iocoder.yudao.module.erp.enums.ErpSaleOrderOutStatusEnum;
+import cn.iocoder.yudao.module.erp.api.sale.enums.ErpSaleOrderOutStatusEnum;
 import cn.iocoder.yudao.module.erp.service.finance.ErpAccountService;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import jakarta.annotation.Resource;
@@ -83,7 +83,8 @@
 
         // 2.1 鎻掑叆璁㈠崟
         ErpSaleOrderDO saleOrder = BeanUtils.toBean(createReqVO, ErpSaleOrderDO.class, in -> in
-                .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus()));
+                .setNo(no).setStatus(ErpAuditStatus.PROCESS.getStatus())
+                .setOutCount(BigDecimal.ZERO).setOutStatus(ErpSaleOrderOutStatusEnum.NOT_OUT.getStatus()));
         calculateTotalPrice(saleOrder, saleOrderItems);
         saleOrderMapper.insert(saleOrder);
         // 2.2 鎻掑叆璁㈠崟椤�
@@ -149,11 +150,6 @@
         if (!approve && outCount.compareTo(BigDecimal.ZERO) > 0) {
             throw exception(SALE_ORDER_PROCESS_FAIL_EXISTS_OUT);
         }
-        // 1.4 瀛樺湪閿�鍞��璐у崟锛屾棤娉曞弽瀹℃牳
-        BigDecimal returnCount = saleOrder.getReturnCount() != null ? saleOrder.getReturnCount() : BigDecimal.ZERO;
-        if (!approve && returnCount.compareTo(BigDecimal.ZERO) > 0) {
-            throw exception(SALE_ORDER_PROCESS_FAIL_EXISTS_RETURN);
-        }
 
         // 2. 鏇存柊鐘舵��
         int updateCount = saleOrderMapper.updateByIdAndStatus(id, saleOrder.getStatus(),
@@ -176,11 +172,6 @@
         BigDecimal outCount = saleOrder.getOutCount() != null ? saleOrder.getOutCount() : BigDecimal.ZERO;
         if (outCount.compareTo(BigDecimal.ZERO) > 0) {
             throw exception(SALE_ORDER_CANCEL_FAIL_EXISTS_OUT);
-        }
-        // 1.4 瀛樺湪閿�鍞��璐у崟锛屾棤娉曚綔搴�
-        BigDecimal returnCount = saleOrder.getReturnCount() != null ? saleOrder.getReturnCount() : BigDecimal.ZERO;
-        if (returnCount.compareTo(BigDecimal.ZERO) > 0) {
-            throw exception(SALE_ORDER_CANCEL_FAIL_EXISTS_RETURN);
         }
 
         // 2. 鏇存柊鐘舵�佷负宸蹭綔搴�
@@ -269,26 +260,6 @@
         // 2. 鏇存柊閿�鍞鍗�
         BigDecimal totalOutCount = getSumValue(outCountMap.values(), value -> value, BigDecimal::add, BigDecimal.ZERO);
         saleOrderMapper.updateById(new ErpSaleOrderDO().setId(id).setOutCount(totalOutCount));
-    }
-
-    @Override
-    public void updateSaleOrderReturnCount(Long orderId, Map<Long, BigDecimal> returnCountMap) {
-        List<ErpSaleOrderItemDO> orderItems = saleOrderItemMapper.selectListByOrderId(orderId);
-        // 1. 鏇存柊姣忎釜閿�鍞鍗曢」
-        orderItems.forEach(item -> {
-            BigDecimal returnCount = returnCountMap.getOrDefault(item.getId(), BigDecimal.ZERO);
-            if (item.getReturnCount().equals(returnCount)) {
-                return;
-            }
-            if (returnCount.compareTo(item.getOutCount()) > 0) {
-                throw exception(SALE_ORDER_ITEM_RETURN_FAIL_OUT_EXCEED,
-                        "浜у搧ID:" + item.getProductId(), item.getOutCount());
-            }
-            saleOrderItemMapper.updateById(new ErpSaleOrderItemDO().setId(item.getId()).setReturnCount(returnCount));
-        });
-        // 2. 鏇存柊閿�鍞鍗�
-        BigDecimal totalReturnCount = getSumValue(returnCountMap.values(), value -> value, BigDecimal::add, BigDecimal.ZERO);
-        saleOrderMapper.updateById(new ErpSaleOrderDO().setId(orderId).setReturnCount(totalReturnCount));
     }
 
     @Override
@@ -403,4 +374,4 @@
         }
     }
 
-}
+}
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/MdmItemCategoryApi.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/MdmItemCategoryApi.java
index 17f4686..9a747a8 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/MdmItemCategoryApi.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/MdmItemCategoryApi.java
@@ -39,4 +39,12 @@
      */
     CommonResult<MdmItemCategoryRespDTO> validateItemCategoryExists(Long id);
 
+    /**
+     * 鏍规嵁鐗╂枡/浜у搧鏍囪瘑鑾峰彇鍒嗙被
+     *
+     * @param itemOrProduct 鐗╂枡/浜у搧鏍囪瘑
+     * @return 鐗╂枡鍒嗙被
+     */
+    CommonResult<MdmItemCategoryRespDTO> getItemCategoryByItemOrProduct(String itemOrProduct);
+
 }
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/MdmItemCategoryApiImpl.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/MdmItemCategoryApiImpl.java
index 8f70f31..1b4c610 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/MdmItemCategoryApiImpl.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/MdmItemCategoryApiImpl.java
@@ -46,4 +46,10 @@
         return success(BeanUtils.toBean(itemCategory, MdmItemCategoryRespDTO.class));
     }
 
+    @Override
+    public CommonResult<MdmItemCategoryRespDTO> getItemCategoryByItemOrProduct(String itemOrProduct) {
+        MdmItemCategoryDO itemCategory = itemCategoryService.getItemCategoryByItemOrProduct(itemOrProduct);
+        return success(BeanUtils.toBean(itemCategory, MdmItemCategoryRespDTO.class));
+    }
+
 }
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/dto/MdmItemCategoryRespDTO.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/dto/MdmItemCategoryRespDTO.java
index edc0135..a1913ce 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/dto/MdmItemCategoryRespDTO.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/category/dto/MdmItemCategoryRespDTO.java
@@ -22,6 +22,12 @@
     @Schema(description = "鐗╂枡绫诲瀷", example = "1")
     private Integer itemType;
 
+    @Schema(description = "鐗╂枡/浜у搧鏍囪瘑(鍏煎MES)", example = "ITEM")
+    private String itemOrProduct;
+
+    @Schema(description = "鎺掑簭", example = "1")
+    private Integer sort;
+
     @Schema(description = "鐘舵��", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
     private Integer status;
 
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemBatchConfigApi.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemBatchConfigApi.java
new file mode 100644
index 0000000..4d33b6d
--- /dev/null
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemBatchConfigApi.java
@@ -0,0 +1,56 @@
+package cn.iocoder.yudao.module.mdm.api.item;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemBatchConfigRespDTO;
+import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+/**
+ * MDM 鐗╂枡鎵规閰嶇疆 API 鎺ュ彛
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+public interface MdmItemBatchConfigApi {
+
+    String PREFIX = "/rpc-api/mdm/item-batch-config";
+
+    /**
+     * 鏍规嵁鐗╂枡缂栧彿鑾峰彇鎵规閰嶇疆
+     *
+     * @param itemId 鐗╂枡缂栧彿
+     * @return 鎵规閰嶇疆锛堜笉瀛樺湪杩斿洖 null锛�
+     */
+    CommonResult<MdmItemBatchConfigRespDTO> getItemBatchConfigByItemId(Long itemId);
+
+    /**
+     * 鏍规嵁鐗╂枡缂栧彿鑾峰彇鎵规閰嶇疆锛堜究鎹锋柟娉曪級
+     *
+     * @param itemId 鐗╂枡缂栧彿
+     * @return 鎵规閰嶇疆锛堜笉瀛樺湪杩斿洖 null锛�
+     */
+    default MdmItemBatchConfigRespDTO getItemBatchConfig(Long itemId) {
+        CommonResult<MdmItemBatchConfigRespDTO> result = getItemBatchConfigByItemId(itemId);
+        return result != null ? result.getData() : null;
+    }
+
+    /**
+     * 淇濆瓨鎵规閰嶇疆
+     *
+     * @param config 鎵规閰嶇疆
+     * @return 閰嶇疆缂栧彿
+     */
+    CommonResult<Long> saveItemBatchConfig(MdmItemBatchConfigDO config);
+
+    /**
+     * 淇濆瓨鎵规閰嶇疆锛堜究鎹锋柟娉曪級
+     *
+     * @param config 鎵规閰嶇疆
+     * @return 閰嶇疆缂栧彿
+     */
+    default Long saveItemBatch(MdmItemBatchConfigDO config) {
+        CommonResult<Long> result = saveItemBatchConfig(config);
+        return result != null ? result.getData() : null;
+    }
+
+}
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemBatchConfigApiImpl.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemBatchConfigApiImpl.java
new file mode 100644
index 0000000..8594d35
--- /dev/null
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemBatchConfigApiImpl.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.module.mdm.api.item;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemBatchConfigRespDTO;
+import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO;
+import cn.iocoder.yudao.module.mdm.service.item.MdmItemBatchConfigService;
+import jakarta.annotation.Resource;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RestController;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+/**
+ * MDM 鐗╂枡鎵规閰嶇疆 API 瀹炵幇绫�
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+@RestController
+@Validated
+public class MdmItemBatchConfigApiImpl implements MdmItemBatchConfigApi {
+
+    @Resource
+    private MdmItemBatchConfigService itemBatchConfigService;
+
+    @Override
+    public CommonResult<MdmItemBatchConfigRespDTO> getItemBatchConfigByItemId(Long itemId) {
+        MdmItemBatchConfigDO config = itemBatchConfigService.getItemBatchConfigByItemId(itemId);
+        return success(BeanUtils.toBean(config, MdmItemBatchConfigRespDTO.class));
+    }
+
+    @Override
+    public CommonResult<Long> saveItemBatchConfig(MdmItemBatchConfigDO config) {
+        return success(itemBatchConfigService.saveItemBatchConfig(config));
+    }
+
+}
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemSyncApi.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemSyncApi.java
new file mode 100644
index 0000000..3abc36b
--- /dev/null
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemSyncApi.java
@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.mdm.api.item;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemSyncReqDTO;
+
+/**
+ * MDM 鐗╂枡鍚屾 API 鎺ュ彛
+ *
+ * 渚� MES 妯″潡鍚屾鐗╂枡涓绘暟鎹埌 MDM 浣跨敤
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+public interface MdmItemSyncApi {
+
+    String PREFIX = "/rpc-api/mdm/item-sync";
+
+    /**
+     * 鍚屾鐗╂枡鍒� MDM锛堟寜 code 鍖归厤锛屽瓨鍦ㄥ垯鏇存柊锛屼笉瀛樺湪鍒欏垱寤猴級
+     *
+     * @param syncReqDTO 鍚屾淇℃伅
+     * @return MDM 鐗╂枡缂栧彿
+     */
+    CommonResult<Long> syncItemToMdm(MdmItemSyncReqDTO syncReqDTO);
+
+}
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemSyncApiImpl.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemSyncApiImpl.java
new file mode 100644
index 0000000..10be2bc
--- /dev/null
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/MdmItemSyncApiImpl.java
@@ -0,0 +1,102 @@
+package cn.iocoder.yudao.module.mdm.api.item;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemSyncReqDTO;
+import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO;
+import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemDO;
+import cn.iocoder.yudao.module.mdm.dal.mysql.item.MdmItemBatchConfigMapper;
+import cn.iocoder.yudao.module.mdm.dal.mysql.item.MdmItemMapper;
+import jakarta.annotation.Resource;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RestController;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+/**
+ * MDM 鐗╂枡鍚屾 API 瀹炵幇绫�
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+@RestController
+@Validated
+public class MdmItemSyncApiImpl implements MdmItemSyncApi {
+
+    @Resource
+    private MdmItemMapper itemMapper;
+
+    @Resource
+    private MdmItemBatchConfigMapper itemBatchConfigMapper;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public CommonResult<Long> syncItemToMdm(MdmItemSyncReqDTO syncReqDTO) {
+        // 1. 鎸� code 鏌ヨ鏄惁宸插瓨鍦�
+        MdmItemDO existingItem = itemMapper.selectByCode(syncReqDTO.getCode());
+
+        // 2. 淇濆瓨鎴栨洿鏂扮墿鏂欎富鏁版嵁
+        MdmItemDO item = BeanUtils.toBean(syncReqDTO, MdmItemDO.class);
+        Long itemId;
+        if (existingItem != null) {
+            // 鏇存柊
+            item.setId(existingItem.getId());
+            itemMapper.updateById(item);
+            itemId = existingItem.getId();
+        } else {
+            // 鏂板
+            itemMapper.insert(item);
+            itemId = item.getId();
+        }
+
+        // 3. 鍚屾鎵规灞炴�ч厤缃�
+        syncBatchConfig(itemId, syncReqDTO);
+
+        return success(itemId);
+    }
+
+    /**
+     * 鍚屾鎵规灞炴�ч厤缃�
+     */
+    private void syncBatchConfig(Long itemId, MdmItemSyncReqDTO syncReqDTO) {
+        // 妫�鏌ユ槸鍚︽湁鎵规閰嶇疆鏁版嵁
+        if (syncReqDTO.getProduceDateFlag() == null
+                && syncReqDTO.getExpireDateFlag() == null
+                && syncReqDTO.getReceiptDateFlag() == null
+                && syncReqDTO.getVendorFlag() == null
+                && syncReqDTO.getPurchaseOrderCodeFlag() == null
+                && syncReqDTO.getLotNumberFlag() == null
+                && syncReqDTO.getQualityStatusFlag() == null) {
+            return;
+        }
+
+        // 鏌ヨ宸叉湁閰嶇疆
+        MdmItemBatchConfigDO existing = itemBatchConfigMapper.selectOne(MdmItemBatchConfigDO::getItemId, itemId);
+
+        MdmItemBatchConfigDO config = new MdmItemBatchConfigDO();
+        config.setItemId(itemId);
+        config.setProduceDateFlag(Boolean.TRUE.equals(syncReqDTO.getProduceDateFlag()));
+        config.setExpireDateFlag(Boolean.TRUE.equals(syncReqDTO.getExpireDateFlag()));
+        config.setReceiptDateFlag(Boolean.TRUE.equals(syncReqDTO.getReceiptDateFlag()));
+        config.setVendorFlag(Boolean.TRUE.equals(syncReqDTO.getVendorFlag()));
+        config.setPurchaseOrderCodeFlag(Boolean.TRUE.equals(syncReqDTO.getPurchaseOrderCodeFlag()));
+        config.setLotNumberFlag(Boolean.TRUE.equals(syncReqDTO.getLotNumberFlag()));
+        config.setQualityStatusFlag(Boolean.TRUE.equals(syncReqDTO.getQualityStatusFlag()));
+        // 娓呯┖涓嶉渶瑕佺殑瀛楁
+        config.setClientFlag(false);
+        config.setSalesOrderCodeFlag(false);
+        config.setWorkOrderFlag(false);
+        config.setTaskFlag(false);
+        config.setWorkstationFlag(false);
+        config.setToolFlag(false);
+        config.setMoldFlag(false);
+
+        if (existing != null) {
+            config.setId(existing.getId());
+            itemBatchConfigMapper.updateById(config);
+        } else {
+            itemBatchConfigMapper.insert(config);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemBatchConfigRespDTO.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemBatchConfigRespDTO.java
new file mode 100644
index 0000000..de05923
--- /dev/null
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemBatchConfigRespDTO.java
@@ -0,0 +1,95 @@
+package cn.iocoder.yudao.module.mdm.api.item.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * MDM 鐗╂枡鎵规閰嶇疆 Response DTO
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+@Data
+public class MdmItemBatchConfigRespDTO implements Serializable {
+
+    /**
+     * 缂栧彿
+     */
+    private Long id;
+
+    /**
+     * 鐗╂枡缂栧彿
+     */
+    private Long itemId;
+
+    /**
+     * 鐢熶骇鏃ユ湡蹇呭~
+     */
+    private Boolean produceDateFlag;
+
+    /**
+     * 鏈夋晥鏈熷繀濉�
+     */
+    private Boolean expireDateFlag;
+
+    /**
+     * 鍏ュ簱鏃ユ湡蹇呭~
+     */
+    private Boolean receiptDateFlag;
+
+    /**
+     * 渚涘簲鍟嗗繀濉�
+     */
+    private Boolean vendorFlag;
+
+    /**
+     * 瀹㈡埛蹇呭~
+     */
+    private Boolean clientFlag;
+
+    /**
+     * 閿�鍞鍗曠紪鍙峰繀濉�
+     */
+    private Boolean salesOrderCodeFlag;
+
+    /**
+     * 閲囪喘璁㈠崟缂栧彿蹇呭~
+     */
+    private Boolean purchaseOrderCodeFlag;
+
+    /**
+     * 鐢熶骇宸ュ崟蹇呭~
+     */
+    private Boolean workOrderFlag;
+
+    /**
+     * 鐢熶骇浠诲姟蹇呭~
+     */
+    private Boolean taskFlag;
+
+    /**
+     * 宸ヤ綔绔欏繀濉�
+     */
+    private Boolean workstationFlag;
+
+    /**
+     * 宸ュ叿蹇呭~
+     */
+    private Boolean toolFlag;
+
+    /**
+     * 妯″叿蹇呭~
+     */
+    private Boolean moldFlag;
+
+    /**
+     * 鐢熶骇鎵瑰彿蹇呭~
+     */
+    private Boolean lotNumberFlag;
+
+    /**
+     * 璐ㄩ噺鐘舵�佸繀濉�
+     */
+    private Boolean qualityStatusFlag;
+
+}
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemSyncReqDTO.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemSyncReqDTO.java
new file mode 100644
index 0000000..8590df5
--- /dev/null
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemSyncReqDTO.java
@@ -0,0 +1,109 @@
+package cn.iocoder.yudao.module.mdm.api.item.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+/**
+ * MDM 鐗╂枡鍚屾 Request DTO
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+@Schema(description = "MDM 鐗╂枡鍚屾 Request DTO")
+@Data
+public class MdmItemSyncReqDTO {
+
+    @Schema(description = "鐗╂枡缂栫爜", requiredMode = Schema.RequiredMode.REQUIRED, example = "ITEM001")
+    private String code;
+
+    @Schema(description = "鐗╂枡鍚嶇О", requiredMode = Schema.RequiredMode.REQUIRED, example = "铻轰笣")
+    private String name;
+
+    @Schema(description = "瑙勬牸鍨嬪彿", example = "M6*20")
+    private String specification;
+
+    @Schema(description = "鐗╂枡绫诲瀷锛�1鍘熸枡, 2鍗婃垚鍝�, 3鎴愬搧, 4杈呮枡", example = "1")
+    private Integer itemType;
+
+    @Schema(description = "璁¢噺鍗曚綅ID", example = "1")
+    private Long unitMeasureId;
+
+    @Schema(description = "鍒嗙被ID", example = "1")
+    private Long categoryId;
+
+    @Schema(description = "鍝佺墝ID", example = "1")
+    private Long brandId;
+
+    @Schema(description = "鐘舵�侊細0鍚敤, 1绂佺敤", example = "0")
+    private Integer status;
+
+    @Schema(description = "閲囪喘浠�", example = "10.00")
+    private BigDecimal purchasePrice;
+
+    @Schema(description = "閿�鍞环", example = "20.00")
+    private BigDecimal salesPrice;
+
+    @Schema(description = "鎴愭湰浠�", example = "15.00")
+    private BigDecimal costPrice;
+
+    @Schema(description = "鏈�浣庝环", example = "8.00")
+    private BigDecimal minPrice;
+
+    @Schema(description = "瀹夊叏搴撳瓨", example = "100")
+    private BigDecimal safetyStock;
+
+    @Schema(description = "鏈�浣庡簱瀛�", example = "50")
+    private BigDecimal minStock;
+
+    @Schema(description = "鏈�楂樺簱瀛�", example = "1000")
+    private BigDecimal maxStock;
+
+    @Schema(description = "鏈�灏忚璐ч噺", example = "10")
+    private BigDecimal minOrderQty;
+
+    @Schema(description = "鎻愬墠鏈燂紙澶╋級", example = "7")
+    private Integer leadTime;
+
+    @Schema(description = "鏄惁鎵规绠$悊", example = "true")
+    private Boolean isBatchManaged;
+
+    @Schema(description = "鏄惁搴忓垪鍙风鐞�", example = "false")
+    private Boolean isSerialManaged;
+
+    @Schema(description = "鏈夋晥鏈燂紙澶╋級", example = "365")
+    private Integer expiryDay;
+
+    @Schema(description = "鏄惁楂樺�肩墿鏂�", example = "false")
+    private Boolean isHighValue;
+
+    @Schema(description = "閲嶉噺", example = "1.5")
+    private BigDecimal weight;
+
+    @Schema(description = "澶囨敞", example = "澶囨敞")
+    private String remark;
+
+    // ========== 鎵规灞炴�ч厤缃� ==========
+
+    @Schema(description = "鐢熶骇鏃ユ湡蹇呭~", example = "true")
+    private Boolean produceDateFlag;
+
+    @Schema(description = "鏈夋晥鏈熷繀濉�", example = "true")
+    private Boolean expireDateFlag;
+
+    @Schema(description = "鍏ュ簱鏃ユ湡蹇呭~", example = "false")
+    private Boolean receiptDateFlag;
+
+    @Schema(description = "渚涘簲鍟嗗繀濉�", example = "true")
+    private Boolean vendorFlag;
+
+    @Schema(description = "閲囪喘璁㈠崟鍙峰繀濉�", example = "false")
+    private Boolean purchaseOrderCodeFlag;
+
+    @Schema(description = "鐢熶骇鎵瑰彿蹇呭~", example = "true")
+    private Boolean lotNumberFlag;
+
+    @Schema(description = "璐ㄩ噺鐘舵�佸繀濉�", example = "false")
+    private Boolean qualityStatusFlag;
+
+}
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/category/vo/MdmItemCategoryRespVO.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/category/vo/MdmItemCategoryRespVO.java
index ede6b3e..850e243 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/category/vo/MdmItemCategoryRespVO.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/category/vo/MdmItemCategoryRespVO.java
@@ -24,6 +24,9 @@
     @Schema(description = "鐗╂枡绫诲瀷", example = "1")
     private Integer itemType;
 
+    @Schema(description = "鐗╂枡/浜у搧鏍囪瘑(鍏煎MES)", example = "ITEM")
+    private String itemOrProduct;
+
     @Schema(description = "鎺掑簭", example = "1")
     private Integer sort;
 
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/category/vo/MdmItemCategorySaveReqVO.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/category/vo/MdmItemCategorySaveReqVO.java
index 7df8691..cb2ed35 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/category/vo/MdmItemCategorySaveReqVO.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/category/vo/MdmItemCategorySaveReqVO.java
@@ -22,6 +22,9 @@
     @Schema(description = "鐗╂枡绫诲瀷", example = "1")
     private Integer itemType;
 
+    @Schema(description = "鐗╂枡/浜у搧鏍囪瘑(鍏煎MES)", example = "ITEM")
+    private String itemOrProduct;
+
     @Schema(description = "鎺掑簭", example = "1")
     private Integer sort;
 
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/MdmItemController.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/MdmItemController.java
index fee0f83..d60e1f1 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/MdmItemController.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/MdmItemController.java
@@ -7,9 +7,14 @@
 import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemRespVO;
 import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemSaveReqVO;
 import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemStatusUpdateReqVO;
+import cn.iocoder.yudao.module.mdm.dal.dataobject.category.MdmItemCategoryDO;
+import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO;
 import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemDO;
 import cn.iocoder.yudao.module.mdm.dal.dataobject.unit.MdmUnitMeasureDO;
 import cn.iocoder.yudao.module.mdm.dal.dataobject.warehouse.MdmWarehouseDO;
+import cn.iocoder.yudao.module.mdm.service.brand.MdmBrandService;
+import cn.iocoder.yudao.module.mdm.service.category.MdmItemCategoryService;
+import cn.iocoder.yudao.module.mdm.service.item.MdmItemBatchConfigService;
 import cn.iocoder.yudao.module.mdm.service.item.MdmItemService;
 import cn.iocoder.yudao.module.mdm.service.unit.MdmUnitMeasureService;
 import cn.iocoder.yudao.module.mdm.service.warehouse.MdmWarehouseService;
@@ -38,10 +43,15 @@
     private MdmItemService itemService;
 
     @Resource
+    private MdmItemCategoryService itemCategoryService;
+    @Resource
     private MdmUnitMeasureService unitMeasureService;
-
     @Resource
     private MdmWarehouseService warehouseService;
+    @Resource
+    private MdmBrandService brandService;
+    @Resource
+    private MdmItemBatchConfigService itemBatchConfigService;
 
     @PostMapping("/create")
     @Operation(summary = "鍒涘缓鐗╂枡")
@@ -84,6 +94,8 @@
         MdmItemRespVO resp = BeanUtils.toBean(item, MdmItemRespVO.class);
         if (resp != null) {
             enrichItemRespVO(resp);
+            // 濉厖鎵规灞炴�ч厤缃�
+            enrichItemBatchConfig(resp);
         }
         return success(resp);
     }
@@ -93,6 +105,9 @@
     @PreAuthorize("@ss.hasPermission('mdm:item:query')")
     public CommonResult<PageResult<MdmItemRespVO>> getItemPage(@Valid MdmItemPageReqVO pageReqVO) {
         PageResult<MdmItemDO> pageResult = itemService.getItemPage(pageReqVO);
+        // 鍏宠仈鏌ヨ鍒嗙被鍚嶇О
+        Map<Long, MdmItemCategoryDO> categoryMap = itemCategoryService.getItemCategoryMap(
+                convertSet(pageResult.getList(), MdmItemDO::getCategoryId));
         // 鍏宠仈鏌ヨ璁¢噺鍗曚綅鍚嶇О
         Map<Long, MdmUnitMeasureDO> unitMap = unitMeasureService.getUnitMeasureMap(
                 convertSet(pageResult.getList(), MdmItemDO::getUnitMeasureId));
@@ -116,6 +131,11 @@
                         .collect(Collectors.toMap(MdmWarehouseDO::getId, w -> w));
         // 璧嬪��
         respList.forEach(resp -> {
+            // 鍒嗙被鍚嶇О
+            MdmItemCategoryDO category = categoryMap.get(resp.getCategoryId());
+            if (category != null) {
+                resp.setCategoryName(category.getName());
+            }
             MdmUnitMeasureDO unit = unitMap.get(resp.getUnitMeasureId());
             if (unit != null) {
                 resp.setUnitMeasureName(unit.getName());
@@ -146,9 +166,16 @@
     }
 
     /**
-     * 濉厖鐗╂枡鍝嶅簲 VO 鐨勫叧鑱斿悕绉帮紙涓诲崟浣嶃�佽緟鍗曚綅銆佷粨搴撳悕绉帮級
+     * 濉厖鐗╂枡鍝嶅簲 VO 鐨勫叧鑱斿悕绉帮紙鍒嗙被銆佷富鍗曚綅銆佽緟鍗曚綅銆佷粨搴撳悕绉帮級
      */
     private void enrichItemRespVO(MdmItemRespVO resp) {
+        // 鍒嗙被鍚嶇О
+        if (resp.getCategoryId() != null) {
+            MdmItemCategoryDO category = itemCategoryService.getItemCategory(resp.getCategoryId());
+            if (category != null) {
+                resp.setCategoryName(category.getName());
+            }
+        }
         // 涓诲崟浣嶅悕绉�
         if (resp.getUnitMeasureId() != null) {
             MdmUnitMeasureDO unit = unitMeasureService.getUnitMeasure(resp.getUnitMeasureId());
@@ -179,4 +206,20 @@
         }
     }
 
+    /**
+     * 濉厖鐗╂枡鎵规灞炴�ч厤缃�
+     */
+    private void enrichItemBatchConfig(MdmItemRespVO resp) {
+        MdmItemBatchConfigDO config = itemBatchConfigService.getItemBatchConfigByItemId(resp.getId());
+        if (config != null) {
+            resp.setProduceDateFlag(config.getProduceDateFlag());
+            resp.setExpireDateFlag(config.getExpireDateFlag());
+            resp.setReceiptDateFlag(config.getReceiptDateFlag());
+            resp.setVendorFlag(config.getVendorFlag());
+            resp.setPurchaseOrderCodeFlag(config.getPurchaseOrderCodeFlag());
+            resp.setLotNumberFlag(config.getLotNumberFlag());
+            resp.setQualityStatusFlag(config.getQualityStatusFlag());
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemRespVO.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemRespVO.java
index b3bbafa..c8674e3 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemRespVO.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemRespVO.java
@@ -100,6 +100,29 @@
     @Schema(description = "鏄惁鎵规绠$悊", example = "false")
     private Boolean isBatchManaged;
 
+    // ==================== 鎵规灞炴�ч厤缃� ====================
+
+    @Schema(description = "鐢熶骇鏃ユ湡", example = "false")
+    private Boolean produceDateFlag;
+
+    @Schema(description = "鏈夋晥鏈�", example = "false")
+    private Boolean expireDateFlag;
+
+    @Schema(description = "鍏ュ簱鏃ユ湡", example = "false")
+    private Boolean receiptDateFlag;
+
+    @Schema(description = "渚涘簲鍟�", example = "false")
+    private Boolean vendorFlag;
+
+    @Schema(description = "閲囪喘璁㈠崟缂栧彿", example = "false")
+    private Boolean purchaseOrderCodeFlag;
+
+    @Schema(description = "鐢熶骇鎵瑰彿", example = "false")
+    private Boolean lotNumberFlag;
+
+    @Schema(description = "璐ㄩ噺鐘舵��", example = "false")
+    private Boolean qualityStatusFlag;
+
     @Schema(description = "鏄惁楂樺�肩墿鏂�", example = "false")
     private Boolean isHighValue;
 
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemSaveReqVO.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemSaveReqVO.java
index 5f1be14..4a41bfa 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemSaveReqVO.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemSaveReqVO.java
@@ -90,4 +90,27 @@
     @Schema(description = "鏄惁鍚屾鍒� MES", example = "false")
     private Boolean syncMes;
 
+    // ========== 鎵规灞炴�ч厤缃紙鍚屾鏃朵竴璧蜂繚瀛橈級 ==========
+
+    @Schema(description = "鐢熶骇鏃ユ湡蹇呭~", example = "true")
+    private Boolean produceDateFlag;
+
+    @Schema(description = "鏈夋晥鏈熷繀濉�", example = "true")
+    private Boolean expireDateFlag;
+
+    @Schema(description = "鍏ュ簱鏃ユ湡蹇呭~", example = "false")
+    private Boolean receiptDateFlag;
+
+    @Schema(description = "渚涘簲鍟嗗繀濉�", example = "true")
+    private Boolean vendorFlag;
+
+    @Schema(description = "閲囪喘璁㈠崟鍙峰繀濉�", example = "false")
+    private Boolean purchaseOrderCodeFlag;
+
+    @Schema(description = "鐢熶骇鎵瑰彿蹇呭~", example = "true")
+    private Boolean lotNumberFlag;
+
+    @Schema(description = "璐ㄩ噺鐘舵�佸繀濉�", example = "false")
+    private Boolean qualityStatusFlag;
+
 }
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/dal/dataobject/category/MdmItemCategoryDO.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/dal/dataobject/category/MdmItemCategoryDO.java
index e54c823..4aba846 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/dal/dataobject/category/MdmItemCategoryDO.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/dal/dataobject/category/MdmItemCategoryDO.java
@@ -53,6 +53,11 @@
     private Integer itemType;
 
     /**
+     * 鐗╂枡/浜у搧鏍囪瘑(鍏煎MES: ITEM/PRODUCT)
+     */
+    private String itemOrProduct;
+
+    /**
      * 鎺掑簭
      */
     private Integer sort;
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/dal/mysql/category/MdmItemCategoryMapper.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/dal/mysql/category/MdmItemCategoryMapper.java
index 0678ec4..0daf6f3 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/dal/mysql/category/MdmItemCategoryMapper.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/dal/mysql/category/MdmItemCategoryMapper.java
@@ -60,4 +60,8 @@
         return selectList(MdmItemCategoryDO::getId, ids);
     }
 
+    default MdmItemCategoryDO selectByItemOrProduct(String itemOrProduct) {
+        return selectOne(MdmItemCategoryDO::getItemOrProduct, itemOrProduct);
+    }
+
 }
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/category/MdmItemCategoryService.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/category/MdmItemCategoryService.java
index d82d6a1..1c93a33 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/category/MdmItemCategoryService.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/category/MdmItemCategoryService.java
@@ -106,4 +106,12 @@
      */
     List<MdmItemCategoryDO> getSimpleItemList();
 
+    /**
+     * 鏍规嵁鐗╂枡/浜у搧鏍囪瘑鑾峰彇鍒嗙被
+     *
+     * @param itemOrProduct 鐗╂枡/浜у搧鏍囪瘑
+     * @return 鐗╂枡鍒嗙被
+     */
+    MdmItemCategoryDO getItemCategoryByItemOrProduct(String itemOrProduct);
+
 }
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/category/MdmItemCategoryServiceImpl.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/category/MdmItemCategoryServiceImpl.java
index ecb240b..babfd80 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/category/MdmItemCategoryServiceImpl.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/category/MdmItemCategoryServiceImpl.java
@@ -155,4 +155,9 @@
         return itemCategoryMapper.selectList(new MdmItemCategoryDO().setStatus(0));
     }
 
+    @Override
+    public MdmItemCategoryDO getItemCategoryByItemOrProduct(String itemOrProduct) {
+        return itemCategoryMapper.selectByItemOrProduct(itemOrProduct);
+    }
+
 }
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemBatchConfigService.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemBatchConfigService.java
new file mode 100644
index 0000000..e7f706b
--- /dev/null
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemBatchConfigService.java
@@ -0,0 +1,35 @@
+package cn.iocoder.yudao.module.mdm.service.item;
+
+import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO;
+
+/**
+ * MDM 鐗╂枡鎵规閰嶇疆 Service 鎺ュ彛
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+public interface MdmItemBatchConfigService {
+
+    /**
+     * 鏍规嵁鐗╂枡缂栧彿鑾峰彇鎵规閰嶇疆
+     *
+     * @param itemId 鐗╂枡缂栧彿
+     * @return 鎵规閰嶇疆锛屼笉瀛樺湪杩斿洖 null
+     */
+    MdmItemBatchConfigDO getItemBatchConfigByItemId(Long itemId);
+
+    /**
+     * 淇濆瓨鎵规閰嶇疆锛堟柊澧炴垨鏇存柊锛�
+     *
+     * @param config 鎵规閰嶇疆
+     * @return 閰嶇疆缂栧彿
+     */
+    Long saveItemBatchConfig(MdmItemBatchConfigDO config);
+
+    /**
+     * 鏍规嵁鐗╂枡缂栧彿鍒犻櫎鎵规閰嶇疆
+     *
+     * @param itemId 鐗╂枡缂栧彿
+     */
+    void deleteItemBatchConfigByItemId(Long itemId);
+
+}
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemBatchConfigServiceImpl.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemBatchConfigServiceImpl.java
new file mode 100644
index 0000000..a1656ea
--- /dev/null
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemBatchConfigServiceImpl.java
@@ -0,0 +1,61 @@
+package cn.iocoder.yudao.module.mdm.service.item;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO;
+import cn.iocoder.yudao.module.mdm.dal.mysql.item.MdmItemBatchConfigMapper;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+
+import java.util.List;
+
+/**
+ * MDM 鐗╂枡鎵规閰嶇疆 Service 瀹炵幇绫�
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+@Service
+@Validated
+public class MdmItemBatchConfigServiceImpl implements MdmItemBatchConfigService {
+
+    @Resource
+    private MdmItemBatchConfigMapper itemBatchConfigMapper;
+
+    @Override
+    public MdmItemBatchConfigDO getItemBatchConfigByItemId(Long itemId) {
+        List<MdmItemBatchConfigDO> list = itemBatchConfigMapper.selectList(MdmItemBatchConfigDO::getItemId, itemId);
+        return CollUtil.getFirst(list);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Long saveItemBatchConfig(MdmItemBatchConfigDO config) {
+        // 娓呯┖涓嶉渶瑕佺殑瀛楁锛堝彧淇濈暀蹇呰鐨�7涓瓧娈碉級
+        config.setClientFlag(false);
+        config.setSalesOrderCodeFlag(false);
+        config.setWorkOrderFlag(false);
+        config.setTaskFlag(false);
+        config.setWorkstationFlag(false);
+        config.setToolFlag(false);
+        config.setMoldFlag(false);
+
+        // 鏌ヨ宸叉湁閰嶇疆
+        MdmItemBatchConfigDO existing = getItemBatchConfigByItemId(config.getItemId());
+        if (existing != null) {
+            // 鏇存柊
+            config.setId(existing.getId());
+            itemBatchConfigMapper.updateById(config);
+            return existing.getId();
+        }
+        // 鏂板
+        itemBatchConfigMapper.insert(config);
+        return config.getId();
+    }
+
+    @Override
+    public void deleteItemBatchConfigByItemId(Long itemId) {
+        itemBatchConfigMapper.delete(MdmItemBatchConfigDO::getItemId, itemId);
+    }
+
+}
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemServiceImpl.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemServiceImpl.java
index dc40a64..9b32fc6 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemServiceImpl.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemServiceImpl.java
@@ -2,7 +2,6 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjUtil;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemPageReqVO;
@@ -10,20 +9,21 @@
 import cn.iocoder.yudao.module.mdm.dal.dataobject.category.MdmItemCategoryDO;
 import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemDO;
 import cn.iocoder.yudao.module.mdm.dal.dataobject.unit.MdmUnitMeasureDO;
+import cn.iocoder.yudao.module.mdm.dal.mysql.item.MdmItemBatchConfigMapper;
 import cn.iocoder.yudao.module.mdm.dal.mysql.item.MdmItemMapper;
 import cn.iocoder.yudao.module.mdm.service.brand.MdmBrandService;
 import cn.iocoder.yudao.module.mdm.service.category.MdmItemCategoryService;
 import cn.iocoder.yudao.module.mdm.service.unit.MdmUnitMeasureService;
 import cn.iocoder.yudao.module.mes.api.item.MesMdItemApi;
-import cn.iocoder.yudao.module.mes.api.item.MesMdItemTypeApi;
 import cn.iocoder.yudao.module.mes.api.item.dto.MesMdItemSyncReqDTO;
-import cn.iocoder.yudao.module.mes.api.item.dto.MesMdItemTypeRespDTO;
 import jakarta.annotation.Resource;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import java.util.*;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -49,9 +49,10 @@
     private MdmBrandService brandService;
 
     @Resource
+    @Lazy
     private MesMdItemApi mesMdItemApi;
     @Resource
-    private MesMdItemTypeApi mesMdItemTypeApi;
+    private MdmItemBatchConfigMapper itemBatchConfigMapper;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
@@ -62,6 +63,9 @@
         // 鎻掑叆 MDM 鐗╂枡
         MdmItemDO item = BeanUtils.toBean(createReqVO, MdmItemDO.class);
         itemMapper.insert(item);
+
+        // 淇濆瓨鎵规閰嶇疆锛堝鏋滄湁锛�
+        saveBatchConfig(item.getId(), createReqVO);
 
         // 鍚屾鍒� MES锛堝嬀閫� syncMes 鏃讹級
         if (Boolean.TRUE.equals(createReqVO.getSyncMes())) {
@@ -81,6 +85,9 @@
         // 鏇存柊 MDM 鐗╂枡
         MdmItemDO updateObj = BeanUtils.toBean(updateReqVO, MdmItemDO.class);
         itemMapper.updateById(updateObj);
+
+        // 淇濆瓨鎵规閰嶇疆锛堝鏋滄湁锛�
+        saveBatchConfig(updateReqVO.getId(), updateReqVO);
 
         // 鍚屾鍒� MES锛堝嬀閫� syncMes 鏃讹級
         if (Boolean.TRUE.equals(updateReqVO.getSyncMes())) {
@@ -110,25 +117,24 @@
             }
             unitCode = unitMeasure.getCode();
         }
-        // 瑙f瀽鍒嗙被 id -> code锛堜娇鐢� MES 鐗╂枡鍒嗙被 API锛�
+        // 瑙f瀽鍒嗙被 id -> code锛堜娇鐢� MDM 鏈湴鍒嗙被鏈嶅姟锛�
         String itemTypeCode = null;
         if (reqVO.getCategoryId() != null) {
-            CommonResult<MesMdItemTypeRespDTO> result = mesMdItemTypeApi.getItemType(reqVO.getCategoryId());
-            if (result != null && result.isSuccess() && result.getData() != null) {
-                itemTypeCode = result.getData().getCode();
+            MdmItemCategoryDO category = itemCategoryService.getItemCategory(reqVO.getCategoryId());
+            if (category != null) {
+                itemTypeCode = category.getCode();
             }
         } else if (reqVO.getItemType() != null) {
             // 鏍规嵁 itemType 鏌ユ壘瀵瑰簲鍒嗙被缂栫爜
             // itemType: 1鍘熸枡, 2鍗婃垚鍝�, 3鎴愬搧, 4杈呮枡
             String itemTypeName = convertItemTypeToName(reqVO.getItemType());
-            CommonResult<List<MesMdItemTypeRespDTO>> listResult = mesMdItemTypeApi.getItemTypeList(null);
-            if (listResult != null && listResult.isSuccess() && listResult.getData() != null) {
-                itemTypeCode = listResult.getData().stream()
-                        .filter(c -> c.getName() != null && c.getName().equals(itemTypeName))
-                        .findFirst()
-                        .map(MesMdItemTypeRespDTO::getCode)
-                        .orElse(null);
-            }
+            List<MdmItemCategoryDO> categories = itemCategoryService.getItemCategoryList(
+                    itemCategoryService.getItemCategoryChildrenList(null).stream().map(MdmItemCategoryDO::getId).collect(Collectors.toSet()));
+            itemTypeCode = categories.stream()
+                    .filter(c -> c.getName() != null && c.getName().equals(itemTypeName))
+                    .findFirst()
+                    .map(MdmItemCategoryDO::getCode)
+                    .orElse(null);
         }
         // 缁勮鍚屾 DTO
         MesMdItemSyncReqDTO syncReqDTO = new MesMdItemSyncReqDTO();
@@ -143,6 +149,14 @@
         syncReqDTO.setHighValue(reqVO.getIsHighValue());
         syncReqDTO.setBatchFlag(reqVO.getIsBatchManaged());
         syncReqDTO.setRemark(reqVO.getRemark());
+        // 鎵规閰嶇疆瀛楁
+        syncReqDTO.setProduceDateFlag(reqVO.getProduceDateFlag());
+        syncReqDTO.setExpireDateFlag(reqVO.getExpireDateFlag());
+        syncReqDTO.setReceiptDateFlag(reqVO.getReceiptDateFlag());
+        syncReqDTO.setVendorFlag(reqVO.getVendorFlag());
+        syncReqDTO.setPurchaseOrderCodeFlag(reqVO.getPurchaseOrderCodeFlag());
+        syncReqDTO.setLotNumberFlag(reqVO.getLotNumberFlag());
+        syncReqDTO.setQualityStatusFlag(reqVO.getQualityStatusFlag());
         // create 璧� createItem锛寀pdate 璧� updateItem锛圡ES 渚ф寜 code upsert锛�
         if (reqVO.getId() == null) {
             mesMdItemApi.createItem(syncReqDTO);
@@ -205,8 +219,9 @@
         if (categoryId == null) {
             return;
         }
-        CommonResult<MesMdItemTypeRespDTO> result = mesMdItemTypeApi.getItemType(categoryId);
-        if (result == null || !result.isSuccess() || result.getData() == null) {
+        // 浣跨敤 MDM 鏈湴鍒嗙被鏈嶅姟鏍¢獙
+        MdmItemCategoryDO category = itemCategoryService.getItemCategory(categoryId);
+        if (category == null) {
             throw exception(MDM_ITEM_CATEGORY_NOT_EXISTS);
         }
     }
@@ -295,4 +310,51 @@
         return itemMapper.selectByCode(code);
     }
 
+    /**
+     * 淇濆瓨鎵规閰嶇疆锛堝埌 MDM 鏈湴琛級
+     */
+    private void saveBatchConfig(Long itemId, MdmItemSaveReqVO reqVO) {
+        // 妫�鏌ユ槸鍚︽湁鎵规閰嶇疆鏁版嵁
+        if (reqVO.getProduceDateFlag() == null
+                && reqVO.getExpireDateFlag() == null
+                && reqVO.getReceiptDateFlag() == null
+                && reqVO.getVendorFlag() == null
+                && reqVO.getPurchaseOrderCodeFlag() == null
+                && reqVO.getLotNumberFlag() == null
+                && reqVO.getQualityStatusFlag() == null) {
+            return;
+        }
+
+        // 鏌ヨ宸叉湁閰嶇疆
+        cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO existing =
+                itemBatchConfigMapper.selectOne(
+                        cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO::getItemId, itemId);
+
+        cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO config =
+                new cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO();
+        config.setItemId(itemId);
+        config.setProduceDateFlag(Boolean.TRUE.equals(reqVO.getProduceDateFlag()));
+        config.setExpireDateFlag(Boolean.TRUE.equals(reqVO.getExpireDateFlag()));
+        config.setReceiptDateFlag(Boolean.TRUE.equals(reqVO.getReceiptDateFlag()));
+        config.setVendorFlag(Boolean.TRUE.equals(reqVO.getVendorFlag()));
+        config.setPurchaseOrderCodeFlag(Boolean.TRUE.equals(reqVO.getPurchaseOrderCodeFlag()));
+        config.setLotNumberFlag(Boolean.TRUE.equals(reqVO.getLotNumberFlag()));
+        config.setQualityStatusFlag(Boolean.TRUE.equals(reqVO.getQualityStatusFlag()));
+        // 娓呯┖涓嶉渶瑕佺殑瀛楁
+        config.setClientFlag(false);
+        config.setSalesOrderCodeFlag(false);
+        config.setWorkOrderFlag(false);
+        config.setTaskFlag(false);
+        config.setWorkstationFlag(false);
+        config.setToolFlag(false);
+        config.setMoldFlag(false);
+
+        if (existing != null) {
+            config.setId(existing.getId());
+            itemBatchConfigMapper.updateById(config);
+        } else {
+            itemBatchConfigMapper.insert(config);
+        }
+    }
+
 }
\ No newline at end of file
diff --git a/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/item/dto/MesMdItemSyncReqDTO.java b/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/item/dto/MesMdItemSyncReqDTO.java
index 44cd667..706ebc9 100644
--- a/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/item/dto/MesMdItemSyncReqDTO.java
+++ b/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/item/dto/MesMdItemSyncReqDTO.java
@@ -42,4 +42,27 @@
     @Schema(description = "澶囨敞", example = "澶囨敞")
     private String remark;
 
+    // ========== 鎵规灞炴�ч厤缃� ==========
+
+    @Schema(description = "鐢熶骇鏃ユ湡蹇呭~", example = "true")
+    private Boolean produceDateFlag;
+
+    @Schema(description = "鏈夋晥鏈熷繀濉�", example = "true")
+    private Boolean expireDateFlag;
+
+    @Schema(description = "鍏ュ簱鏃ユ湡蹇呭~", example = "false")
+    private Boolean receiptDateFlag;
+
+    @Schema(description = "渚涘簲鍟嗗繀濉�", example = "true")
+    private Boolean vendorFlag;
+
+    @Schema(description = "閲囪喘璁㈠崟鍙峰繀濉�", example = "false")
+    private Boolean purchaseOrderCodeFlag;
+
+    @Schema(description = "鐢熶骇鎵瑰彿蹇呭~", example = "true")
+    private Boolean lotNumberFlag;
+
+    @Schema(description = "璐ㄩ噺鐘舵�佸繀濉�", example = "false")
+    private Boolean qualityStatusFlag;
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/item/MesMdItemApiImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/item/MesMdItemApiImpl.java
index 230bd63..8be526a 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/item/MesMdItemApiImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/item/MesMdItemApiImpl.java
@@ -3,9 +3,11 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.api.item.dto.MesMdItemSyncReqDTO;
 import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemSaveReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.batchconfig.MesMdItemBatchConfigSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemBatchConfigService;
 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
 import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemTypeService;
 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
@@ -36,12 +38,17 @@
     private MesMdItemTypeService itemTypeService;
     @Resource
     private MesMdUnitMeasureService unitMeasureService;
+    @Resource
+    private MesMdItemBatchConfigService itemBatchConfigService;
 
     @Override
     public Long createItem(MesMdItemSyncReqDTO syncReqDTO) {
         log.info("[createItem] 鍚屾鍒涘缓 MES 鐗╂枡浜у搧锛宑ode={}", syncReqDTO.getCode());
         MesMdItemSaveReqVO saveReqVO = buildSaveReqVO(syncReqDTO);
-        return itemService.createItem(saveReqVO);
+        Long itemId = itemService.createItem(saveReqVO);
+        // 鍚屾鎵规閰嶇疆
+        saveBatchConfig(itemId, syncReqDTO);
+        return itemId;
     }
 
     @Override
@@ -50,12 +57,16 @@
         MesMdItemSaveReqVO saveReqVO = buildSaveReqVO(syncReqDTO);
         // 鎸� code 鍖归厤锛氬瓨鍦ㄥ垯鏇存柊锛屼笉瀛樺湪鍒欏垱寤猴紙upsert锛�
         MesMdItemDO existItem = itemService.getItemByCode(syncReqDTO.getCode());
+        Long itemId;
         if (existItem == null) {
-            itemService.createItem(saveReqVO);
+            itemId = itemService.createItem(saveReqVO);
         } else {
             saveReqVO.setId(existItem.getId());
             itemService.updateItem(saveReqVO);
+            itemId = existItem.getId();
         }
+        // 鍚屾鎵规閰嶇疆
+        saveBatchConfig(itemId, syncReqDTO);
     }
 
     /**
@@ -79,4 +90,30 @@
         return saveReqVO;
     }
 
+    /**
+     * 淇濆瓨鎵规閰嶇疆
+     */
+    private void saveBatchConfig(Long itemId, MesMdItemSyncReqDTO syncReqDTO) {
+        // 妫�鏌ユ槸鍚︽湁鎵规閰嶇疆鏁版嵁
+        if (syncReqDTO.getProduceDateFlag() == null
+                && syncReqDTO.getExpireDateFlag() == null
+                && syncReqDTO.getReceiptDateFlag() == null
+                && syncReqDTO.getVendorFlag() == null
+                && syncReqDTO.getPurchaseOrderCodeFlag() == null
+                && syncReqDTO.getLotNumberFlag() == null
+                && syncReqDTO.getQualityStatusFlag() == null) {
+            return;
+        }
+        MesMdItemBatchConfigSaveReqVO configReqVO = new MesMdItemBatchConfigSaveReqVO();
+        configReqVO.setItemId(itemId);
+        configReqVO.setProduceDateFlag(syncReqDTO.getProduceDateFlag());
+        configReqVO.setExpireDateFlag(syncReqDTO.getExpireDateFlag());
+        configReqVO.setReceiptDateFlag(syncReqDTO.getReceiptDateFlag());
+        configReqVO.setVendorFlag(syncReqDTO.getVendorFlag());
+        configReqVO.setPurchaseOrderCodeFlag(syncReqDTO.getPurchaseOrderCodeFlag());
+        configReqVO.setLotNumberFlag(syncReqDTO.getLotNumberFlag());
+        configReqVO.setQualityStatusFlag(syncReqDTO.getQualityStatusFlag());
+        itemBatchConfigService.saveItemBatchConfig(configReqVO);
+    }
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemSaveReqVO.java
index 975f689..7155ca9 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemSaveReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemSaveReqVO.java
@@ -51,4 +51,7 @@
     @Schema(description = "澶囨敞", example = "澶囨敞")
     private String remark;
 
+    @Schema(description = "鏄惁鍚屾鍒� MDM", example = "true")
+    private Boolean syncMdm;
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchGenerateReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchGenerateReqVO.java
index 68af018..17979de 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchGenerateReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchGenerateReqVO.java
@@ -20,6 +20,11 @@
     private Long itemId;
 
     /**
+     * 鎵规鍙凤紙浼犲叆鍒欎娇鐢ㄨ鎵规鍙凤紝涓嶄紶鍒欒嚜鍔ㄧ敓鎴愶級
+     */
+    private String batchCode;
+
+    /**
      * 鐢熶骇鏃ユ湡
      */
     private LocalDateTime produceDate;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockAdjustReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockAdjustReqVO.java
index 155d8b7..612d289 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockAdjustReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/materialstock/vo/MesWmMaterialStockAdjustReqVO.java
@@ -1,11 +1,16 @@
 package cn.iocoder.yudao.module.mes.controller.admin.wm.materialstock.vo;
 
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.v3.oas.annotations.media.Schema;
 import jakarta.validation.constraints.NotNull;
 import jakarta.validation.constraints.Positive;
 import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.math.BigDecimal;
+import java.time.LocalDate;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
 
 /**
  * 搴撳瓨璋冩暣锛堣嚜瀹氫箟鍑哄叆搴擄級Request VO
@@ -30,15 +35,35 @@
     @NotNull(message = "搴撲綅ID涓嶈兘涓虹┖")
     private Long areaId;
 
-    @Schema(description = "鎵规ID", example = "1")
+    // ========== 鎵规鐩稿叧瀛楁 ==========
+
+    @Schema(description = "鎵规ID锛堥�夋嫨宸叉湁鎵规鏃朵紶鍏ワ級", example = "1")
     private Long batchId;
 
-    @Schema(description = "鎵规鍙�", example = "BATCH001")
+    @Schema(description = "鎵规鍙凤紙鏂板缓鎵规鏃朵紶鍏ワ紝绯荤粺鑷姩鍒涘缓鎵规璁板綍锛�", example = "BATCH001")
     private String batchCode;
+
+    @Schema(description = "鐢熶骇鏃ユ湡锛堟柊寤烘壒娆℃椂浼犲叆锛�", example = "2025-01-01")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
+    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY)
+    private LocalDate produceDate;
+
+    @Schema(description = "鏈夋晥鏈燂紙鏂板缓鎵规鏃朵紶鍏ワ級", example = "2026-01-01")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
+    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY)
+    private LocalDate expireDate;
 
     @Schema(description = "渚涘簲鍟咺D", example = "1")
     private Long vendorId;
 
+    @Schema(description = "鐢熶骇鎵瑰彿", example = "LOT001")
+    private String lotNumber;
+
+    @Schema(description = "璐ㄩ噺鐘舵�侊紙0-寰呮楠� 1-鍚堟牸 2-涓嶅悎鏍硷紝鏀寔鏁板瓧鎴栧瓧绗︿覆锛�", example = "1")
+    private Object qualityStatus;
+
+    // ========== 鍏朵粬瀛楁 ==========
+
     @Schema(description = "鏁伴噺锛堝繀椤诲ぇ浜�0锛�", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
     @NotNull(message = "鏁伴噺涓嶈兘涓虹┖")
     @Positive(message = "鏁伴噺蹇呴』澶т簬0")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transaction/MesWmTransactionController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transaction/MesWmTransactionController.java
new file mode 100644
index 0000000..10faf64
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transaction/MesWmTransactionController.java
@@ -0,0 +1,161 @@
+package cn.iocoder.yudao.module.mes.controller.admin.wm.transaction;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.transaction.vo.MesWmTransactionPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.transaction.vo.MesWmTransactionRespVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transaction.MesWmTransactionDO;
+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.enums.MesBizTypeConstants;
+import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
+import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
+import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
+import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
+import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseLocationService;
+import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+
+/**
+ * 搴撳瓨浜嬪姟娴佹按 Controller
+ */
+@Tag(name = "绠$悊鍚庡彴 - 搴撳瓨浜嬪姟娴佹按")
+@RestController
+@RequestMapping("/mes/wm/transaction")
+@Validated
+public class MesWmTransactionController {
+
+    @Resource
+    private MesWmTransactionService transactionService;
+    @Resource
+    private MesMdmItemService mdmItemService;
+    @Resource
+    private MesWmWarehouseService warehouseService;
+    @Resource
+    private MesWmWarehouseLocationService locationService;
+    @Resource
+    private MesWmWarehouseAreaService areaService;
+
+    @GetMapping("/page")
+    @Operation(summary = "鑾峰彇搴撳瓨浜嬪姟娴佹按鍒嗛〉")
+    @Parameter(name = "id", description = "缂栧彿", required = true, example = "1")
+    @PreAuthorize("@ss.hasPermission('mes:wm-transaction:query')")
+    public CommonResult<PageResult<MesWmTransactionRespVO>> getTransactionPage(@Valid MesWmTransactionPageReqVO pageReqVO) {
+        PageResult<MesWmTransactionDO> pageResult = transactionService.getTransactionPage(pageReqVO);
+        if (pageResult.getTotal() == 0) {
+            return success(PageResult.empty(pageResult.getTotal()));
+        }
+
+        // 鍏宠仈鏌ヨ鐗╂枡淇℃伅
+        Map<Long, MesMdmItemDO> itemMap = mdmItemService.getItemMap(
+                convertSet(pageResult.getList(), MesWmTransactionDO::getItemId));
+        // 鍏宠仈鏌ヨ浠撳簱淇℃伅
+        Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
+                convertSet(pageResult.getList(), MesWmTransactionDO::getWarehouseId));
+        // 鍏宠仈鏌ヨ搴撳尯淇℃伅
+        Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
+                convertSet(pageResult.getList(), MesWmTransactionDO::getLocationId));
+        // 鍏宠仈鏌ヨ搴撲綅淇℃伅
+        Map<Long, MesWmWarehouseAreaDO> areaMap = areaService.getWarehouseAreaMap(
+                convertSet(pageResult.getList(), MesWmTransactionDO::getAreaId));
+
+        // 杞崲涓� VO
+        List<MesWmTransactionRespVO> voList = pageResult.getList().stream().map(transaction -> {
+            MesWmTransactionRespVO vo = BeanUtils.toBean(transaction, MesWmTransactionRespVO.class);
+            // 浜嬪姟绫诲瀷鍚嶇О
+            MesWmTransactionTypeEnum typeEnum = MesWmTransactionTypeEnum.valueOf(transaction.getType());
+            vo.setTypeName(typeEnum != null ? typeEnum.getName() : "鏈煡");
+            // 涓氬姟绫诲瀷鍚嶇О
+            vo.setBizTypeName(getBizTypeName(transaction.getBizType()));
+            // 鐗╂枡淇℃伅
+            MesMdmItemDO item = itemMap.get(transaction.getItemId());
+            if (item != null) {
+                vo.setItemCode(item.getCode());
+                vo.setItemName(item.getName());
+            }
+            // 浠撳簱淇℃伅
+            MesWmWarehouseDO warehouse = warehouseMap.get(transaction.getWarehouseId());
+            if (warehouse != null) {
+                vo.setWarehouseName(warehouse.getName());
+            }
+            // 搴撳尯淇℃伅
+            MesWmWarehouseLocationDO location = locationMap.get(transaction.getLocationId());
+            if (location != null) {
+                vo.setLocationName(location.getName());
+            }
+            // 搴撲綅淇℃伅
+            MesWmWarehouseAreaDO area = areaMap.get(transaction.getAreaId());
+            if (area != null) {
+                vo.setAreaName(area.getName());
+            }
+            return vo;
+        }).collect(Collectors.toList());
+
+        return success(new PageResult<>(voList, pageResult.getTotal()));
+    }
+
+    /**
+     * 鑾峰彇涓氬姟绫诲瀷鍚嶇О
+     */
+    private String getBizTypeName(Integer bizType) {
+        if (bizType == null) {
+            return "鏈煡";
+        }
+        switch (bizType) {
+            case MesBizTypeConstants.WM_STOCK_ADJUST_IN:
+                return "鑷畾涔夊叆搴�";
+            case MesBizTypeConstants.WM_STOCK_ADJUST_OUT:
+                return "鑷畾涔夊嚭搴�";
+            case MesBizTypeConstants.WM_ITEM_RECEIPT_IN:
+                return "閲囪喘鍏ュ簱";
+            case MesBizTypeConstants.WM_PRODUCT_SALES:
+                return "閿�鍞嚭搴�";
+            case MesBizTypeConstants.WM_TRANSFER_IN:
+                return "璋冩嫧鍏ュ簱";
+            case MesBizTypeConstants.WM_TRANSFER_OUT:
+                return "璋冩嫧鍑哄簱";
+            case MesBizTypeConstants.WM_MISC_RECPT:
+                return "鍏朵粬鍏ュ簱";
+            case MesBizTypeConstants.WM_MISC_ISSUE:
+                return "鍏朵粬鍑哄簱";
+            case MesBizTypeConstants.WM_ISSUE:
+                return "鐢熶骇棰嗘枡";
+            case MesBizTypeConstants.WM_RETURN_ISSUE:
+                return "鐢熶骇閫�鏂�";
+            case MesBizTypeConstants.WM_PRODUCT_RECPT:
+                return "鐢熶骇鍏ュ簱";
+            case MesBizTypeConstants.WM_ITEM_CONSUME:
+                return "鐢熶骇娑堣��";
+            case MesBizTypeConstants.WM_PRODUCT_PRODUCE:
+                return "浜у搧浜у嚭";
+            case MesBizTypeConstants.WM_RETURN_VENDOR:
+                return "渚涘簲鍟嗛��璐�";
+            case MesBizTypeConstants.WM_RETURN_SALES:
+                return "閿�鍞��璐�";
+            case MesBizTypeConstants.WM_OUTSOURCE_ISSUE:
+                return "澶栧崗鍙戞枡";
+            case MesBizTypeConstants.WM_OUTSOURCE_RECPT:
+                return "澶栧崗鍏ュ簱";
+            default:
+                return "鏈煡绫诲瀷(" + bizType + ")";
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transaction/vo/MesWmTransactionPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transaction/vo/MesWmTransactionPageReqVO.java
new file mode 100644
index 0000000..0cabd59
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transaction/vo/MesWmTransactionPageReqVO.java
@@ -0,0 +1,58 @@
+package cn.iocoder.yudao.module.mes.controller.admin.wm.transaction.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+/**
+ * 搴撳瓨浜嬪姟娴佹按鏌ヨ Request VO
+ */
+@Schema(description = "绠$悊鍚庡彴 - 搴撳瓨浜嬪姟娴佹按鏌ヨ Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesWmTransactionPageReqVO extends PageParam {
+
+    @Schema(description = "鐗╂枡ID", example = "1")
+    private Long itemId;
+
+    @Schema(description = "鎵规鍙�", example = "BATCH001")
+    private String batchCode;
+
+    @Schema(description = "浠撳簱ID", example = "1")
+    private Long warehouseId;
+
+    @Schema(description = "搴撳尯ID", example = "1")
+    private Long locationId;
+
+    @Schema(description = "搴撲綅ID", example = "1")
+    private Long areaId;
+
+    @Schema(description = "浜嬪姟绫诲瀷锛�1-鍏ュ簱 2-鍑哄簱锛�", example = "1")
+    private Integer type;
+
+    @Schema(description = "涓氬姟绫诲瀷锛�126-鑷畾涔夊叆搴� 127-鑷畾涔夊嚭搴� 绛夛級", example = "126")
+    private Integer bizType;
+
+    @Schema(description = "涓氬姟鍗曞彿", example = "STOCK_ADJUST_1")
+    private String bizCode;
+
+    @Schema(description = "搴撳瓨璁板綍ID", example = "1")
+    private Long materialStockId;
+
+    @Schema(description = "寮�濮嬫椂闂�")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime startTime;
+
+    @Schema(description = "缁撴潫鏃堕棿")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime endTime;
+
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transaction/vo/MesWmTransactionRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transaction/vo/MesWmTransactionRespVO.java
new file mode 100644
index 0000000..e40218c
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/transaction/vo/MesWmTransactionRespVO.java
@@ -0,0 +1,82 @@
+package cn.iocoder.yudao.module.mes.controller.admin.wm.transaction.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 搴撳瓨浜嬪姟娴佹按 Response VO
+ */
+@Schema(description = "绠$悊鍚庡彴 - 搴撳瓨浜嬪姟娴佹按 Response VO")
+@Data
+public class MesWmTransactionRespVO {
+
+    @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Long id;
+
+    @Schema(description = "浜嬪姟绫诲瀷锛�1-鍏ュ簱 2-鍑哄簱锛�", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer type;
+
+    @Schema(description = "浜嬪姟绫诲瀷鍚嶇О", example = "鍏ュ簱")
+    private String typeName;
+
+    @Schema(description = "涓氬姟绫诲瀷", requiredMode = Schema.RequiredMode.REQUIRED, example = "126")
+    private Integer bizType;
+
+    @Schema(description = "涓氬姟绫诲瀷鍚嶇О", example = "鑷畾涔夊叆搴�")
+    private String bizTypeName;
+
+    @Schema(description = "涓氬姟鍗曞彿", example = "STOCK_ADJUST_1")
+    private String bizCode;
+
+    // ========== 鐗╂枡缁村害 ==========
+
+    @Schema(description = "鐗╂枡ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Long itemId;
+
+    @Schema(description = "鐗╂枡缂栫爜", example = "ITEM001")
+    private String itemCode;
+
+    @Schema(description = "鐗╂枡鍚嶇О", example = "铻轰笣")
+    private String itemName;
+
+    @Schema(description = "鍙樺姩鏁伴噺锛堟鏁�=鍏ュ簱锛岃礋鏁�=鍑哄簱锛�", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
+    private BigDecimal quantity;
+
+    @Schema(description = "鎵规ID", example = "1")
+    private Long batchId;
+
+    @Schema(description = "鎵规鍙�", example = "BATCH001")
+    private String batchCode;
+
+    // ========== 搴撳瓨浣嶇疆 ==========
+
+    @Schema(description = "浠撳簱ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Long warehouseId;
+
+    @Schema(description = "浠撳簱鍚嶇О", example = "鎴愬搧浠�")
+    private String warehouseName;
+
+    @Schema(description = "搴撳尯ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Long locationId;
+
+    @Schema(description = "搴撳尯鍚嶇О", example = "A鍖�")
+    private String locationName;
+
+    @Schema(description = "搴撲綅ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Long areaId;
+
+    @Schema(description = "搴撲綅鍚嶇О", example = "A-01-01")
+    private String areaName;
+
+    // ========== 鏃堕棿 ==========
+
+    @Schema(description = "浜嬪姟鍙戠敓鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
+    private LocalDateTime transactionTime;
+
+    @Schema(description = "鍒涘缓鏃堕棿")
+    private LocalDateTime createTime;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java
index fa1bda7..3086782 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java
@@ -99,8 +99,7 @@
                 .setSql("reserved_quantity = reserved_quantity + " + count);
         if (checkFlag && count.compareTo(BigDecimal.ZERO) > 0) {
             // 鏍¢獙鍙敤閲忓厖瓒筹細quantity - frozen_quantity - reserved_quantity >= count
-            updateWrapper.setSql("reserved_quantity = reserved_quantity + " + count +
-                    " WHERE quantity - IFNULL(frozen_quantity, 0) - IFNULL(reserved_quantity, 0) >= " + count);
+            updateWrapper.apply("quantity - IFNULL(frozen_quantity, 0) - IFNULL(reserved_quantity, 0) >= {0}", count);
         }
         return update(null, updateWrapper);
     }
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 fee5fe3..8f55684 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
@@ -1,6 +1,9 @@
 package cn.iocoder.yudao.module.mes.dal.mysql.wm.transaction;
 
+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.transaction.vo.MesWmTransactionPageReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transaction.MesWmTransactionDO;
 import org.apache.ibatis.annotations.Mapper;
 
@@ -10,4 +13,20 @@
 @Mapper
 public interface MesWmTransactionMapper extends BaseMapperX<MesWmTransactionDO> {
 
+    default PageResult<MesWmTransactionDO> selectPage(MesWmTransactionPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<MesWmTransactionDO>()
+                .eqIfPresent(MesWmTransactionDO::getItemId, reqVO.getItemId())
+                .likeIfPresent(MesWmTransactionDO::getBatchCode, reqVO.getBatchCode())
+                .eqIfPresent(MesWmTransactionDO::getWarehouseId, reqVO.getWarehouseId())
+                .eqIfPresent(MesWmTransactionDO::getLocationId, reqVO.getLocationId())
+                .eqIfPresent(MesWmTransactionDO::getAreaId, reqVO.getAreaId())
+                .eqIfPresent(MesWmTransactionDO::getType, reqVO.getType())
+                .eqIfPresent(MesWmTransactionDO::getBizType, reqVO.getBizType())
+                .likeIfPresent(MesWmTransactionDO::getBizCode, reqVO.getBizCode())
+                .eqIfPresent(MesWmTransactionDO::getMaterialStockId, reqVO.getMaterialStockId())
+                .geIfPresent(MesWmTransactionDO::getTransactionTime, reqVO.getStartTime())
+                .leIfPresent(MesWmTransactionDO::getTransactionTime, reqVO.getEndTime())
+                .orderByDesc(MesWmTransactionDO::getTransactionTime));
+    }
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemBatchConfigServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemBatchConfigServiceImpl.java
index 84010c6..a78ef74 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemBatchConfigServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemBatchConfigServiceImpl.java
@@ -4,9 +4,14 @@
 import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.batchconfig.MesMdItemBatchConfigSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemBatchConfigDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.md.item.MesMdItemBatchConfigMapper;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemBatchConfigApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemBatchConfigRespDTO;
+import cn.iocoder.yudao.module.mdm.dal.dataobject.item.MdmItemBatchConfigDO;
 import jakarta.annotation.Resource;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -15,6 +20,9 @@
 
 /**
  * MES 鐗╂枡鎵规灞炴�ч厤缃� Service 瀹炵幇绫�
+ *
+ * 鎵规閰嶇疆缁熶竴瀛樺偍鍦� MDM 琛紙mdm_item_batch_config锛�
+ * MES 鏈湴琛紙mes_md_item_batch_config锛変粎鐢ㄤ簬鍏煎鍘嗗彶鏁版嵁鍜� MES 妯″潡鍐呴儴鏌ヨ
  *
  * @author 鑺嬮亾婧愮爜
  */
@@ -26,12 +34,29 @@
     private MesMdItemBatchConfigMapper itemBatchConfigMapper;
 
     @Resource
-    @Lazy // 閬垮厤寰幆渚濊禆锛圡esMdItemServiceImpl 涔熶細娉ㄥ叆鏈� Service锛�
+    @Lazy
     private MesMdItemService itemService;
+
+    @Resource
+    @Lazy
+    private MdmItemApi mdmItemApi;
+
+    @Resource
+    private MdmItemBatchConfigApi mdmItemBatchConfigApi;
 
     @Override
     public MesMdItemBatchConfigDO getItemBatchConfigByItemId(Long itemId) {
-        return itemBatchConfigMapper.selectByItemId(itemId);
+        // 浼樺厛浠� MES 鏈湴琛ㄦ煡璇紙鎬ц兘鏇村ソ锛�
+        MesMdItemBatchConfigDO mesConfig = itemBatchConfigMapper.selectByItemId(itemId);
+        if (mesConfig != null) {
+            return mesConfig;
+        }
+        // 鏈湴琛ㄤ笉瀛樺湪锛屽皾璇曚粠 MDM 鑾峰彇锛堜笉鍐欏叆鏈湴锛岄伩鍏嶅壇浣滅敤锛�
+        MdmItemBatchConfigRespDTO mdmConfig = mdmItemBatchConfigApi.getItemBatchConfig(itemId);
+        if (mdmConfig != null) {
+            return BeanUtils.toBean(mdmConfig, MesMdItemBatchConfigDO.class);
+        }
+        return null;
     }
 
     @Override
@@ -44,26 +69,33 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Long saveItemBatchConfig(MesMdItemBatchConfigSaveReqVO saveReqVO) {
-        // 1. 鏍¢獙鐗╂枡瀛樺湪
-        if (itemService.getItem(saveReqVO.getItemId()) == null) {
+        // 1. 鏍¢獙鐗╂枡瀛樺湪锛堜粠 MDM 鏍¢獙锛�
+        if (mdmItemApi.getItem(saveReqVO.getItemId()).getCheckedData() == null) {
             throw exception(MD_ITEM_NOT_EXISTS);
         }
 
-        // 2. 鏌ヨ宸叉湁閰嶇疆锛屽喅瀹氭柊澧炶繕鏄洿鏂�
-        MesMdItemBatchConfigDO existing = itemBatchConfigMapper.selectByItemId(saveReqVO.getItemId());
-        if (existing != null) {
-            // 鏇存柊
-            MesMdItemBatchConfigDO updateObj = BeanUtils.toBean(saveReqVO, MesMdItemBatchConfigDO.class);
-            updateObj.setId(existing.getId());
-            itemBatchConfigMapper.updateById(updateObj);
-            return existing.getId();
-        }
+        // 2. 娓呯┖涓嶉渶瑕佺殑瀛楁锛堝彧淇濈暀蹇呰鐨�7涓瓧娈碉級
+        MesMdItemBatchConfigSaveReqVO cleanReqVO = new MesMdItemBatchConfigSaveReqVO();
+        cleanReqVO.setId(saveReqVO.getId());
+        cleanReqVO.setItemId(saveReqVO.getItemId());
+        cleanReqVO.setProduceDateFlag(saveReqVO.getProduceDateFlag());
+        cleanReqVO.setExpireDateFlag(saveReqVO.getExpireDateFlag());
+        cleanReqVO.setReceiptDateFlag(saveReqVO.getReceiptDateFlag());
+        cleanReqVO.setVendorFlag(saveReqVO.getVendorFlag());
+        cleanReqVO.setPurchaseOrderCodeFlag(saveReqVO.getPurchaseOrderCodeFlag());
+        cleanReqVO.setLotNumberFlag(saveReqVO.getLotNumberFlag());
+        cleanReqVO.setQualityStatusFlag(saveReqVO.getQualityStatusFlag());
 
-        // 鏂板
-        MesMdItemBatchConfigDO insertObj = BeanUtils.toBean(saveReqVO, MesMdItemBatchConfigDO.class);
-        itemBatchConfigMapper.insert(insertObj);
-        return insertObj.getId();
+        // 3. 淇濆瓨鍒� MDM 琛�
+        MdmItemBatchConfigDO mdmConfig = BeanUtils.toBean(cleanReqVO, MdmItemBatchConfigDO.class);
+        Long configId = mdmItemBatchConfigApi.saveItemBatch(mdmConfig);
+
+        // 4. 鍚屾淇濆瓨鍒� MES 鏈湴琛�
+        saveToMesTable(cleanReqVO);
+
+        return configId;
     }
 
     @Override
@@ -71,4 +103,22 @@
         itemBatchConfigMapper.deleteByItemId(itemId);
     }
 
-}
+    /**
+     * 淇濆瓨鍒� MES 鏈湴琛�
+     */
+    private void saveToMesTable(MesMdItemBatchConfigSaveReqVO saveReqVO) {
+        MesMdItemBatchConfigDO existing = itemBatchConfigMapper.selectByItemId(saveReqVO.getItemId());
+        MesMdItemBatchConfigDO mesConfig = BeanUtils.toBean(saveReqVO, MesMdItemBatchConfigDO.class);
+
+        if (existing != null) {
+            // 瀛樺湪鍒欐洿鏂帮紝浣跨敤宸叉湁鐨� ID
+            mesConfig.setId(existing.getId());
+            itemBatchConfigMapper.updateById(mesConfig);
+        } else {
+            // 涓嶅瓨鍦ㄥ垯鎻掑叆锛岃鏁版嵁搴撹嚜鍔ㄧ敓鎴� ID
+            mesConfig.setId(null);
+            itemBatchConfigMapper.insert(mesConfig);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java
index 860e5b2..1102aef 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java
@@ -22,6 +22,8 @@
 import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
 import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemSyncApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemSyncReqDTO;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -38,7 +40,7 @@
 /**
  * MES 鐗╂枡浜у搧 Service 瀹炵幇绫�
  *
- * 娉ㄦ剰锛氬綋鍓嶄繚鎸佷娇鐢� MES 鏈湴琛紝寰� MDM 鏁版嵁杩佺Щ瀹屾垚鍚庡啀鍒囨崲鍒� MDM API
+ * 鏀寔 MES 鍜� MDM 鐗╂枡鏁版嵁鍙屽悜鍚屾
  *
  * @author 鑺嬮亾婧愮爜
  */
@@ -66,7 +68,11 @@
     @Resource
     private MesMdAutoCodeRecordService autoCodeRecordService;
 
+    @Resource
+    private MdmItemSyncApi mdmItemSyncApi;
+
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Long createItem(MesMdItemSaveReqVO createReqVO) {
         // 鏍¢獙鏁版嵁
         validateItemSaveData(createReqVO);
@@ -80,10 +86,17 @@
         // 鑷姩鐢熸垚鏉$爜
         barcodeService.autoGenerateBarcode(BarcodeBizTypeEnum.ITEM.getValue(),
                 item.getId(), item.getCode(), item.getName());
+
+        // 鍚屾鍒� MDM锛堝嬀閫� syncMdm 鏃讹級
+        if (Boolean.TRUE.equals(createReqVO.getSyncMdm())) {
+            syncItemToMdm(item, createReqVO);
+        }
+
         return item.getId();
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updateItem(MesMdItemSaveReqVO updateReqVO) {
         // 鏍¢獙瀛樺湪
         validateItemExists(updateReqVO.getId());
@@ -94,6 +107,12 @@
         MesMdItemDO updateObj = BeanUtils.toBean(updateReqVO, MesMdItemDO.class);
         clearStockIfNotSafe(updateObj); // 濡傛灉鏈惎鐢ㄥ畨鍏ㄥ簱瀛橈紝娓呴浂搴撳瓨涓婁笅闄�
         itemMapper.updateById(updateObj);
+
+        // 鍚屾鍒� MDM锛堝嬀閫� syncMdm 鏃讹級
+        if (Boolean.TRUE.equals(updateReqVO.getSyncMdm())) {
+            MesMdItemDO item = itemMapper.selectById(updateReqVO.getId());
+            syncItemToMdm(item, updateReqVO);
+        }
     }
 
     private void validateItemSaveData(MesMdItemSaveReqVO reqVO) {
@@ -369,4 +388,93 @@
         return respVO;
     }
 
+    /**
+     * 鍚屾鐗╂枡鍒� MDM
+     *
+     * @param item     MES 鐗╂枡鏁版嵁
+     * @param saveReqVO 淇濆瓨璇锋眰锛堝寘鍚壒娆¢厤缃級
+     */
+    private void syncItemToMdm(MesMdItemDO item, MesMdItemSaveReqVO saveReqVO) {
+        // 1. 鑾峰彇鐗╂枡绫诲瀷瀵瑰簲鐨� itemType
+        Integer itemType = null;
+        if (item.getItemTypeId() != null) {
+            MesMdItemTypeDO itemTypeDO = itemTypeService.getItemType(item.getItemTypeId());
+            if (itemTypeDO != null) {
+                // MES: ITEM=鐗╂枡, PRODUCT=浜у搧 -> MDM: 1=鍘熸枡, 2=鍗婃垚鍝�, 3=鎴愬搧, 4=杈呮枡
+                itemType = convertMesItemTypeToMdm(itemTypeDO.getItemOrProduct(), itemTypeDO.getName());
+            }
+        }
+
+        // 2. 鑾峰彇璁¢噺鍗曚綅缂栫爜
+        String unitCode = null;
+        Long unitMeasureId = null;
+        if (item.getUnitMeasureId() != null) {
+            MesMdUnitMeasureDO unitMeasure = unitMeasureService.getUnitMeasure(item.getUnitMeasureId());
+            if (unitMeasure != null) {
+                unitCode = unitMeasure.getCode();
+            }
+            unitMeasureId = item.getUnitMeasureId();
+        }
+
+        // 3. 鑾峰彇鎵规閰嶇疆
+        MesMdItemBatchConfigDO batchConfig = itemBatchConfigService.getItemBatchConfigByItemId(item.getId());
+
+        // 4. 缁勮鍚屾 DTO
+        MdmItemSyncReqDTO syncReqDTO = new MdmItemSyncReqDTO();
+        syncReqDTO.setCode(item.getCode());
+        syncReqDTO.setName(item.getName());
+        syncReqDTO.setSpecification(item.getSpecification());
+        syncReqDTO.setItemType(itemType);
+        syncReqDTO.setUnitMeasureId(unitMeasureId);
+        syncReqDTO.setCategoryId(item.getItemTypeId());
+        syncReqDTO.setStatus(item.getStatus());
+        syncReqDTO.setMinStock(item.getMinStock());
+        syncReqDTO.setMaxStock(item.getMaxStock());
+        syncReqDTO.setIsBatchManaged(item.getBatchFlag());
+        syncReqDTO.setIsHighValue(item.getHighValue());
+        syncReqDTO.setRemark(item.getRemark());
+
+        // 5. 鍚屾鎵规閰嶇疆
+        if (batchConfig != null) {
+            syncReqDTO.setProduceDateFlag(batchConfig.getProduceDateFlag());
+            syncReqDTO.setExpireDateFlag(batchConfig.getExpireDateFlag());
+            syncReqDTO.setReceiptDateFlag(batchConfig.getReceiptDateFlag());
+            syncReqDTO.setVendorFlag(batchConfig.getVendorFlag());
+            syncReqDTO.setPurchaseOrderCodeFlag(batchConfig.getPurchaseOrderCodeFlag());
+            syncReqDTO.setLotNumberFlag(batchConfig.getLotNumberFlag());
+            syncReqDTO.setQualityStatusFlag(batchConfig.getQualityStatusFlag());
+        }
+
+        // 6. 璋冪敤 MDM 鍚屾 API
+        mdmItemSyncApi.syncItemToMdm(syncReqDTO);
+    }
+
+    /**
+     * 灏� MES 鐗╂枡绫诲瀷杞崲涓� MDM 鐗╂枡绫诲瀷
+     * MES: ITEM(鐗╂枡)/PRODUCT(浜у搧)
+     * MDM: 1鍘熸枡, 2鍗婃垚鍝�, 3鎴愬搧, 4杈呮枡
+     */
+    private Integer convertMesItemTypeToMdm(String itemOrProduct, String typeName) {
+        if (itemOrProduct == null) {
+            return null;
+        }
+        // 鏍规嵁鍚嶇О鍖归厤
+        if (typeName != null) {
+            if (typeName.contains("鍘熸枡")) {
+                return 1;
+            } else if (typeName.contains("鍗婃垚鍝�")) {
+                return 2;
+            } else if (typeName.contains("鎴愬搧")) {
+                return 3;
+            } else if (typeName.contains("杈呮枡")) {
+                return 4;
+            }
+        }
+        // 鏍规嵁 ITEM/PRODUCT 鍏滃簳
+        if ("PRODUCT".equals(itemOrProduct)) {
+            return 3; // 浜у搧 -> 鎴愬搧
+        }
+        return 1; // 榛樿鍘熸枡
+    }
+
 }
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemTypeServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemTypeServiceImpl.java
index dd1a2e6..dabb8db 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemTypeServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemTypeServiceImpl.java
@@ -2,7 +2,10 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjUtil;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mdm.api.category.MdmItemCategoryApi;
+import cn.iocoder.yudao.module.mdm.api.category.dto.MdmItemCategoryRespDTO;
 import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.type.MesMdItemTypeListReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.type.MesMdItemTypeSaveReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO;
@@ -20,6 +23,9 @@
 /**
  * MES 鐗╂枡浜у搧鍒嗙被 Service 瀹炵幇绫�
  *
+ * 鍏煎灞傚疄鐜帮細鏁版嵁瀛樺偍鍦� mes_md_item_type 琛紝浣嗕紭鍏堜粠 MDM 鍒嗙被 API 鑾峰彇
+ * 瀹為檯鍒嗙被鏁版嵁宸茶縼绉诲埌 mdm_item_category 琛�
+ *
  * @author 鑺嬮亾婧愮爜
  */
 @Service
@@ -27,10 +33,13 @@
 public class MesMdItemTypeServiceImpl implements MesMdItemTypeService {
 
     @Resource
+    private MdmItemCategoryApi mdmItemCategoryApi;
+
+    @Resource
     private MesMdItemTypeMapper itemTypeMapper;
 
     @Resource
-    @Lazy // 寤惰繜鍔犺浇锛岄伩鍏嶅惊鐜緷璧�
+    @Lazy
     private MesMdItemService itemService;
 
     @Override
@@ -38,7 +47,7 @@
         // 鏍¢獙鏁版嵁
         validateItemTypeSaveData(createReqVO);
 
-        // 鎻掑叆
+        // 鎻掑叆鍒版湰鍦拌〃锛堜繚鎸佸吋瀹癸級
         MesMdItemTypeDO itemType = BeanUtils.toBean(createReqVO, MesMdItemTypeDO.class);
         itemTypeMapper.insert(itemType);
         return itemType.getId();
@@ -51,7 +60,7 @@
         // 鏍¢獙鏁版嵁
         validateItemTypeSaveData(updateReqVO);
 
-        // 鏇存柊
+        // 鏇存柊鏈湴琛�
         MesMdItemTypeDO updateObj = BeanUtils.toBean(updateReqVO, MesMdItemTypeDO.class);
         itemTypeMapper.updateById(updateObj);
     }
@@ -83,6 +92,12 @@
     }
 
     private void validateItemTypeExists(Long id) {
+        // 浼樺厛浠� MDM 鑾峰彇
+        CommonResult<MdmItemCategoryRespDTO> result = mdmItemCategoryApi.getItemCategory(id);
+        if (result.isSuccess() && result.getData() != null) {
+            return;
+        }
+        // 鍥為��鍒版湰鍦拌〃
         if (itemTypeMapper.selectById(id) == null) {
             throw exception(MD_ITEM_TYPE_NOT_EXISTS);
         }
@@ -96,26 +111,36 @@
         if (Objects.equals(id, parentId)) {
             throw exception(MD_ITEM_TYPE_PARENT_ERROR);
         }
-        // 2. 鐖跺垎绫讳笉瀛樺湪
-        MesMdItemTypeDO parentItemType = itemTypeMapper.selectById(parentId);
+        // 2. 鐖跺垎绫讳笉瀛樺湪 - 浼樺厛浠� MDM 鑾峰彇
+        CommonResult<MdmItemCategoryRespDTO> result = mdmItemCategoryApi.getItemCategory(parentId);
+        MesMdItemTypeDO parentItemType = null;
+        if (result.isSuccess() && result.getData() != null) {
+            parentItemType = convertToMesDO(result.getData());
+        } else {
+            parentItemType = itemTypeMapper.selectById(parentId);
+        }
         if (parentItemType == null) {
             throw exception(MD_ITEM_TYPE_PARENT_NOT_EXITS);
         }
         // 3. 閫掑綊鏍¢獙鐖跺垎绫伙紝濡傛灉鐖跺垎绫绘槸鑷繁鐨勫瓙鍒嗙被锛屽垯鎶ラ敊锛岄伩鍏嶅舰鎴愮幆璺�
-        if (id == null) { // id 涓虹┖锛岃鏄庢柊澧烇紝涓嶉渶瑕佽�冭檻鐜矾
+        if (id == null) {
             return;
         }
         for (int i = 0; i < Short.MAX_VALUE; i++) {
-            // 3.1 鏍¢獙鐜矾
             parentId = parentItemType.getParentId();
             if (Objects.equals(id, parentId)) {
                 throw exception(MD_ITEM_TYPE_PARENT_IS_CHILD);
             }
-            // 3.2 缁х画閫掑綊涓嬩竴绾х埗鍒嗙被
             if (parentId == null || MesMdItemTypeDO.PARENT_ID_ROOT.equals(parentId)) {
                 break;
             }
-            parentItemType = itemTypeMapper.selectById(parentId);
+            // 缁х画鏌ユ壘鐖剁骇
+            CommonResult<MdmItemCategoryRespDTO> parentResult = mdmItemCategoryApi.getItemCategory(parentId);
+            if (parentResult.isSuccess() && parentResult.getData() != null) {
+                parentItemType = convertToMesDO(parentResult.getData());
+            } else {
+                parentItemType = itemTypeMapper.selectById(parentId);
+            }
             if (parentItemType == null) {
                 break;
             }
@@ -144,16 +169,24 @@
 
     @Override
     public MesMdItemTypeDO getItemType(Long id) {
+        // 浼樺厛浠� MDM 鑾峰彇
+        CommonResult<MdmItemCategoryRespDTO> result = mdmItemCategoryApi.getItemCategory(id);
+        if (result.isSuccess() && result.getData() != null) {
+            return convertToMesDO(result.getData());
+        }
+        // 鍥為��鍒版湰鍦拌〃
         return itemTypeMapper.selectById(id);
     }
 
     @Override
     public MesMdItemTypeDO getItemTypeByCode(String code) {
+        // 浠庢湰鍦拌〃鏌�
         return itemTypeMapper.selectByCode(code);
     }
 
     @Override
     public List<MesMdItemTypeDO> getItemTypeList(MesMdItemTypeListReqVO listReqVO) {
+        // 浠庢湰鍦拌〃鏌�
         return itemTypeMapper.selectList(listReqVO);
     }
 
@@ -167,16 +200,12 @@
 
     @Override
     public List<MesMdItemTypeDO> getItemTypeChildrenList(Long parentId) {
-        List<MesMdItemTypeDO> allList = itemTypeMapper.selectList(); // 鍒嗙被鎬婚噺灏忥紝鍏ㄩ噺鏌�
-        // 閫掑綊鏀堕泦鎵�鏈夊瓙鍒嗙被
+        List<MesMdItemTypeDO> allList = itemTypeMapper.selectList();
         List<MesMdItemTypeDO> result = new ArrayList<>();
         collectItemTypeChildren(result, parentId, allList);
         return result;
     }
 
-    /**
-     * 閫掑綊鏀堕泦鎵�鏈夊瓙鍒嗙被
-     */
     private void collectItemTypeChildren(List<MesMdItemTypeDO> result, Long parentId, List<MesMdItemTypeDO> allList) {
         for (MesMdItemTypeDO itemType : allList) {
             if (Objects.equals(itemType.getParentId(), parentId)) {
@@ -186,4 +215,19 @@
         }
     }
 
-}
+    /**
+     * 杞崲 MDM 鍒嗙被 DTO 涓� MES DO
+     */
+    private MesMdItemTypeDO convertToMesDO(MdmItemCategoryRespDTO dto) {
+        MesMdItemTypeDO mesDO = new MesMdItemTypeDO();
+        mesDO.setId(dto.getId());
+        mesDO.setCode(dto.getCode());
+        mesDO.setName(dto.getName());
+        mesDO.setParentId(dto.getParentId());
+        mesDO.setItemOrProduct(dto.getItemOrProduct());
+        mesDO.setSort(dto.getSort());
+        mesDO.setStatus(dto.getStatus());
+        return mesDO;
+    }
+
+}
\ No newline at end of file
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java
index 211281f..151f178 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/batch/MesWmBatchServiceImpl.java
@@ -2,19 +2,20 @@
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchGenerateReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchPageReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemBatchConfigDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.wm.batch.MesWmBatchMapper;
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
 import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum;
 import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemBatchConfigService;
 import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
 import cn.iocoder.yudao.module.mes.service.wm.barcode.MesWmBarcodeService;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemBatchConfigApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemBatchConfigRespDTO;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -50,7 +51,7 @@
     @Resource
     private MesMdmItemService mdmItemService;
     @Resource
-    private MesMdItemBatchConfigService itemBatchConfigService;
+    private MdmItemBatchConfigApi itemBatchConfigApi;
     @Resource
     private MesMdAutoCodeRecordService autoCodeRecordService;
     @Resource
@@ -80,119 +81,160 @@
             // 鏈惎鐢ㄦ壒娆$鐞嗭紝杩斿洖 null
             return null;
         }
-        // 1.2 鏌ヨ鐗╂枡鎵规閰嶇疆
-        MesMdItemBatchConfigDO config = itemBatchConfigService.validateItemBatchConfigExists(reqVO.getItemId());
+
+        // 璋冭瘯鏃ュ織锛氭墦鍗版帴鏀跺埌鐨勬棩鏈�
+        log.info("[getOrGenerateBatchCode] 鏀跺埌璇锋眰, itemId={}, batchCode={}, produceDate={}",
+                reqVO.getItemId(), reqVO.getBatchCode(), reqVO.getProduceDate());
+
+        // 1.2 鏌ヨ鐗╂枡鎵规閰嶇疆锛堜粠 MDM 鑾峰彇锛屼笉瀛樺湪鍒欎娇鐢ㄩ粯璁ら厤缃級
+        MdmItemBatchConfigRespDTO config = itemBatchConfigApi.getItemBatchConfig(reqVO.getItemId());
 
         // 2. 鏍规嵁閰嶇疆鏍¢獙蹇呭~鍙傛暟骞舵竻绌轰笉闇�瑕佺殑鍙傛暟
         MesWmBatchDO batch = MesWmBatchDO.builder().itemId(reqVO.getItemId()).build();
-        // 鐢熶骇鏃ユ湡
-        if (Boolean.TRUE.equals(config.getProduceDateFlag())) {
-            if (ObjUtil.isNull(reqVO.getProduceDate())) {
-                throw exception(WM_BATCH_PRODUCE_DATE_REQUIRED);
+        if (config != null) {
+            // 鐢熶骇鏃ユ湡
+            if (Boolean.TRUE.equals(config.getProduceDateFlag())) {
+                if (ObjUtil.isNull(reqVO.getProduceDate())) {
+                    throw exception(WM_BATCH_PRODUCE_DATE_REQUIRED);
+                }
+                batch.setProduceDate(reqVO.getProduceDate());
             }
-            batch.setProduceDate(reqVO.getProduceDate());
+            // 鍏ュ簱鏃ユ湡
+            if (Boolean.TRUE.equals(config.getReceiptDateFlag())) {
+                if (ObjUtil.isNull(reqVO.getReceiptDate())) {
+                    throw exception(WM_BATCH_RECEIPT_DATE_REQUIRED);
+                }
+                batch.setReceiptDate(reqVO.getReceiptDate());
+            }
+            // 鏈夋晥鏈�
+            if (Boolean.TRUE.equals(config.getExpireDateFlag())) {
+                if (ObjUtil.isNull(reqVO.getExpireDate())) {
+                    throw exception(WM_BATCH_EXPIRE_DATE_REQUIRED);
+                }
+                batch.setExpireDate(reqVO.getExpireDate());
+            }
+            // 渚涘簲鍟�
+            if (Boolean.TRUE.equals(config.getVendorFlag())) {
+                if (ObjUtil.isNull(reqVO.getVendorId())) {
+                    throw exception(WM_BATCH_VENDOR_REQUIRED);
+                }
+                batch.setVendorId(reqVO.getVendorId());
+            }
+            // 瀹㈡埛
+            if (Boolean.TRUE.equals(config.getClientFlag())) {
+                if (ObjUtil.isNull(reqVO.getClientId())) {
+                    throw exception(WM_BATCH_CLIENT_REQUIRED);
+                }
+                batch.setClientId(reqVO.getClientId());
+            }
+            // 閲囪喘璁㈠崟缂栧彿
+            if (Boolean.TRUE.equals(config.getPurchaseOrderCodeFlag())) {
+                if (ObjUtil.isNull(reqVO.getPurchaseOrderCode())) {
+                    throw exception(WM_BATCH_PURCHASE_ORDER_CODE_REQUIRED);
+                }
+                batch.setPurchaseOrderCode(reqVO.getPurchaseOrderCode());
+            }
+            // 閿�鍞鍗曠紪鍙�
+            if (Boolean.TRUE.equals(config.getSalesOrderCodeFlag())) {
+                if (ObjUtil.isNull(reqVO.getSalesOrderCode())) {
+                    throw exception(WM_BATCH_CUSTOMER_ORDER_CODE_REQUIRED);
+                }
+                batch.setSalesOrderCode(reqVO.getSalesOrderCode());
+            }
+            // 鐢熶骇宸ュ崟
+            if (Boolean.TRUE.equals(config.getWorkOrderFlag())) {
+                if (ObjUtil.isNull(reqVO.getWorkOrderId())) {
+                    throw exception(WM_BATCH_WORK_ORDER_REQUIRED);
+                }
+                batch.setWorkOrderId(reqVO.getWorkOrderId());
+            }
+            // 鐢熶骇浠诲姟
+            if (Boolean.TRUE.equals(config.getTaskFlag())) {
+                if (ObjUtil.isNull(reqVO.getTaskId())) {
+                    throw exception(WM_BATCH_TASK_REQUIRED);
+                }
+                batch.setTaskId(reqVO.getTaskId());
+            }
+            // 宸ヤ綔绔�
+            if (Boolean.TRUE.equals(config.getWorkstationFlag())) {
+                if (ObjUtil.isNull(reqVO.getWorkstationId())) {
+                    throw exception(WM_BATCH_WORKSTATION_REQUIRED);
+                }
+                batch.setWorkstationId(reqVO.getWorkstationId());
+            }
+            // 宸ュ叿
+            if (Boolean.TRUE.equals(config.getToolFlag())) {
+                if (ObjUtil.isNull(reqVO.getToolId())) {
+                    throw exception(WM_BATCH_TOOL_REQUIRED);
+                }
+                batch.setToolId(reqVO.getToolId());
+            }
+            // 妯″叿
+            if (Boolean.TRUE.equals(config.getMoldFlag())) {
+                if (ObjUtil.isNull(reqVO.getMoldId())) {
+                    throw exception(WM_BATCH_MOLD_REQUIRED);
+                }
+                batch.setMoldId(reqVO.getMoldId());
+            }
+            // 鐢熶骇鎵瑰彿
+            if (Boolean.TRUE.equals(config.getLotNumberFlag())) {
+                if (ObjUtil.isNull(reqVO.getLotNumber())) {
+                    throw exception(WM_BATCH_LOT_NUMBER_REQUIRED);
+                }
+                batch.setLotNumber(reqVO.getLotNumber());
+            }
+            // 璐ㄩ噺鐘舵��
+            if (Boolean.TRUE.equals(config.getQualityStatusFlag())) {
+                if (ObjUtil.isNull(reqVO.getQualityStatus())) {
+                    throw exception(WM_BATCH_QUALITY_STATUS_REQUIRED);
+                }
+                batch.setQualityStatus(reqVO.getQualityStatus());
+            }
         }
-        // 鍏ュ簱鏃ユ湡
-        if (Boolean.TRUE.equals(config.getReceiptDateFlag())) {
-            if (ObjUtil.isNull(reqVO.getReceiptDate())) {
-                throw exception(WM_BATCH_RECEIPT_DATE_REQUIRED);
+        // 鏃犳壒娆¢厤缃椂锛屼娇鐢ㄤ紶鍏ョ殑鍙傛暟锛堝鏉炬ā寮忥紝閫傜敤浜庤嚜瀹氫箟鍏ュ簱绛夊満鏅級
+        else {
+            if (reqVO.getProduceDate() != null) {
+                batch.setProduceDate(reqVO.getProduceDate());
             }
-            batch.setReceiptDate(reqVO.getReceiptDate());
-        }
-        // 鏈夋晥鏈�
-        if (Boolean.TRUE.equals(config.getExpireDateFlag())) {
-            if (ObjUtil.isNull(reqVO.getExpireDate())) {
-                throw exception(WM_BATCH_EXPIRE_DATE_REQUIRED);
+            if (reqVO.getReceiptDate() != null) {
+                batch.setReceiptDate(reqVO.getReceiptDate());
             }
-            batch.setExpireDate(reqVO.getExpireDate());
-        }
-        // 渚涘簲鍟�
-        if (Boolean.TRUE.equals(config.getVendorFlag())) {
-            if (ObjUtil.isNull(reqVO.getVendorId())) {
-                throw exception(WM_BATCH_VENDOR_REQUIRED);
+            if (reqVO.getExpireDate() != null) {
+                batch.setExpireDate(reqVO.getExpireDate());
             }
-            batch.setVendorId(reqVO.getVendorId());
-        }
-        // 瀹㈡埛
-        if (Boolean.TRUE.equals(config.getClientFlag())) {
-            if (ObjUtil.isNull(reqVO.getClientId())) {
-                throw exception(WM_BATCH_CLIENT_REQUIRED);
+            if (reqVO.getVendorId() != null) {
+                batch.setVendorId(reqVO.getVendorId());
             }
-            batch.setClientId(reqVO.getClientId());
-        }
-        // 閲囪喘璁㈠崟缂栧彿
-        if (Boolean.TRUE.equals(config.getPurchaseOrderCodeFlag())) {
-            if (ObjUtil.isNull(reqVO.getPurchaseOrderCode())) {
-                throw exception(WM_BATCH_PURCHASE_ORDER_CODE_REQUIRED);
+            if (reqVO.getClientId() != null) {
+                batch.setClientId(reqVO.getClientId());
             }
-            batch.setPurchaseOrderCode(reqVO.getPurchaseOrderCode());
-        }
-        // 閿�鍞鍗曠紪鍙�
-        if (Boolean.TRUE.equals(config.getSalesOrderCodeFlag())) {
-            if (ObjUtil.isNull(reqVO.getSalesOrderCode())) {
-                throw exception(WM_BATCH_CUSTOMER_ORDER_CODE_REQUIRED);
-            }
-            batch.setSalesOrderCode(reqVO.getSalesOrderCode());
-        }
-        // 鐢熶骇宸ュ崟
-        if (Boolean.TRUE.equals(config.getWorkOrderFlag())) {
-            if (ObjUtil.isNull(reqVO.getWorkOrderId())) {
-                throw exception(WM_BATCH_WORK_ORDER_REQUIRED);
-            }
-            batch.setWorkOrderId(reqVO.getWorkOrderId());
-        }
-        // 鐢熶骇浠诲姟
-        if (Boolean.TRUE.equals(config.getTaskFlag())) {
-            if (ObjUtil.isNull(reqVO.getTaskId())) {
-                throw exception(WM_BATCH_TASK_REQUIRED);
-            }
-            batch.setTaskId(reqVO.getTaskId());
-        }
-        // 宸ヤ綔绔�
-        if (Boolean.TRUE.equals(config.getWorkstationFlag())) {
-            if (ObjUtil.isNull(reqVO.getWorkstationId())) {
-                throw exception(WM_BATCH_WORKSTATION_REQUIRED);
-            }
-            batch.setWorkstationId(reqVO.getWorkstationId());
-        }
-        // 宸ュ叿
-        if (Boolean.TRUE.equals(config.getToolFlag())) {
-            if (ObjUtil.isNull(reqVO.getToolId())) {
-                throw exception(WM_BATCH_TOOL_REQUIRED);
-            }
-            batch.setToolId(reqVO.getToolId());
-        }
-        // 妯″叿
-        if (Boolean.TRUE.equals(config.getMoldFlag())) {
-            if (ObjUtil.isNull(reqVO.getMoldId())) {
-                throw exception(WM_BATCH_MOLD_REQUIRED);
-            }
-            batch.setMoldId(reqVO.getMoldId());
-        }
-        // 鐢熶骇鎵瑰彿
-        if (Boolean.TRUE.equals(config.getLotNumberFlag())) {
-            if (ObjUtil.isNull(reqVO.getLotNumber())) {
-                throw exception(WM_BATCH_LOT_NUMBER_REQUIRED);
-            }
-            batch.setLotNumber(reqVO.getLotNumber());
-        }
-        // 璐ㄩ噺鐘舵��
-        if (Boolean.TRUE.equals(config.getQualityStatusFlag())) {
-            if (ObjUtil.isNull(reqVO.getQualityStatus())) {
-                throw exception(WM_BATCH_QUALITY_STATUS_REQUIRED);
-            }
-            batch.setQualityStatus(reqVO.getQualityStatus());
         }
 
-        // 3.1 鎯呭喌涓�锛氭煡璇㈡槸鍚﹀瓨鍦ㄥ尮閰嶇殑鎵规
-        MesWmBatchDO existingBatch = batchMapper.selectFirst(batch);
-        if (existingBatch != null) {
-            return existingBatch;
+        // 3.1 鎯呭喌涓�锛氫紶鍏ヤ簡 batchCode锛屾煡璇㈡槸鍚﹀瓨鍦ㄨ鎵规鍙�
+        if (StrUtil.isNotBlank(reqVO.getBatchCode())) {
+            MesWmBatchDO existingBatch = batchMapper.selectByCode(reqVO.getBatchCode());
+            if (existingBatch != null) {
+                // 鏍¢獙鐗╂枡鏄惁鍖归厤
+                if (!existingBatch.getItemId().equals(reqVO.getItemId())) {
+                    throw exception(WM_BATCH_ITEM_MISMATCH);
+                }
+                // 鏇存柊鎵规灞炴�э紙浠呮洿鏂颁紶鍏ョ殑闈炵┖鍊硷級
+                updateBatchProperties(existingBatch, batch);
+                return existingBatch;
+            }
+            // 涓嶅瓨鍦ㄥ垯浣跨敤浼犲叆鐨� batchCode 鍒涘缓鏂版壒娆�
+            batch.setCode(reqVO.getBatchCode());
+        } else {
+            // 3.2 鎯呭喌浜岋細鏌ヨ鏄惁瀛樺湪鍖归厤鐨勬壒娆★紙鏍规嵁灞炴�у尮閰嶏級
+            MesWmBatchDO existingBatch = batchMapper.selectFirst(batch);
+            if (existingBatch != null) {
+                return existingBatch;
+            }
+            // 3.3 鎯呭喌涓夛細鑷姩鐢熸垚鏂版壒娆″彿
+            String batchCode = autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.WM_BATCH_CODE.getCode());
+            batch.setCode(batchCode);
         }
 
-        // 3.2 鎯呭喌浜岋細鐢熸垚鏂版壒娆�
-        String batchCode = autoCodeRecordService.generateAutoCode(MesMdAutoCodeRuleCodeEnum.WM_BATCH_CODE.getCode());
-        batch.setCode(batchCode);
         batchMapper.insert(batch);
 
         // 4. 鐢熸垚鏉$爜
@@ -200,6 +242,75 @@
         return batch;
     }
 
+    /**
+     * 鏇存柊宸叉湁鎵规鐨勫睘鎬э紙浠呮洿鏂颁紶鍏ョ殑闈炵┖鍊硷級
+     *
+     * @param existingBatch 宸叉湁鎵规
+     * @param newBatch 鏂版壒娆″睘鎬�
+     */
+    private void updateBatchProperties(MesWmBatchDO existingBatch, MesWmBatchDO newBatch) {
+        boolean needUpdate = false;
+        if (newBatch.getProduceDate() != null && !newBatch.getProduceDate().equals(existingBatch.getProduceDate())) {
+            existingBatch.setProduceDate(newBatch.getProduceDate());
+            needUpdate = true;
+        }
+        if (newBatch.getExpireDate() != null && !newBatch.getExpireDate().equals(existingBatch.getExpireDate())) {
+            existingBatch.setExpireDate(newBatch.getExpireDate());
+            needUpdate = true;
+        }
+        if (newBatch.getReceiptDate() != null && !newBatch.getReceiptDate().equals(existingBatch.getReceiptDate())) {
+            existingBatch.setReceiptDate(newBatch.getReceiptDate());
+            needUpdate = true;
+        }
+        if (newBatch.getVendorId() != null && !newBatch.getVendorId().equals(existingBatch.getVendorId())) {
+            existingBatch.setVendorId(newBatch.getVendorId());
+            needUpdate = true;
+        }
+        if (newBatch.getClientId() != null && !newBatch.getClientId().equals(existingBatch.getClientId())) {
+            existingBatch.setClientId(newBatch.getClientId());
+            needUpdate = true;
+        }
+        if (newBatch.getSalesOrderCode() != null && !newBatch.getSalesOrderCode().equals(existingBatch.getSalesOrderCode())) {
+            existingBatch.setSalesOrderCode(newBatch.getSalesOrderCode());
+            needUpdate = true;
+        }
+        if (newBatch.getPurchaseOrderCode() != null && !newBatch.getPurchaseOrderCode().equals(existingBatch.getPurchaseOrderCode())) {
+            existingBatch.setPurchaseOrderCode(newBatch.getPurchaseOrderCode());
+            needUpdate = true;
+        }
+        if (newBatch.getWorkOrderId() != null && !newBatch.getWorkOrderId().equals(existingBatch.getWorkOrderId())) {
+            existingBatch.setWorkOrderId(newBatch.getWorkOrderId());
+            needUpdate = true;
+        }
+        if (newBatch.getTaskId() != null && !newBatch.getTaskId().equals(existingBatch.getTaskId())) {
+            existingBatch.setTaskId(newBatch.getTaskId());
+            needUpdate = true;
+        }
+        if (newBatch.getWorkstationId() != null && !newBatch.getWorkstationId().equals(existingBatch.getWorkstationId())) {
+            existingBatch.setWorkstationId(newBatch.getWorkstationId());
+            needUpdate = true;
+        }
+        if (newBatch.getToolId() != null && !newBatch.getToolId().equals(existingBatch.getToolId())) {
+            existingBatch.setToolId(newBatch.getToolId());
+            needUpdate = true;
+        }
+        if (newBatch.getMoldId() != null && !newBatch.getMoldId().equals(existingBatch.getMoldId())) {
+            existingBatch.setMoldId(newBatch.getMoldId());
+            needUpdate = true;
+        }
+        if (newBatch.getLotNumber() != null && !newBatch.getLotNumber().equals(existingBatch.getLotNumber())) {
+            existingBatch.setLotNumber(newBatch.getLotNumber());
+            needUpdate = true;
+        }
+        if (newBatch.getQualityStatus() != null && !newBatch.getQualityStatus().equals(existingBatch.getQualityStatus())) {
+            existingBatch.setQualityStatus(newBatch.getQualityStatus());
+            needUpdate = true;
+        }
+        if (needUpdate) {
+            batchMapper.updateById(existingBatch);
+        }
+    }
+
     @Override
     public List<MesWmBatchDO> getForwardBatchList(String code) {
         return getForwardBatchList(code, new HashSet<>(), 0);
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 b167ca2..f78cdbd 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
@@ -19,6 +19,9 @@
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
 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;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.batch.vo.MesWmBatchGenerateReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
 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.mes.service.wm.warehouse.MesWmWarehouseAreaService;
@@ -59,6 +62,9 @@
     @Resource
     @Lazy
     private MesWmTransactionService wmTransactionService;
+    @Resource
+    @Lazy
+    private MesWmBatchService batchService;
 
     @Override
     public MesWmMaterialStockDO getMaterialStock(Long id) {
@@ -264,28 +270,41 @@
         // 1. 鏍¢獙鐗╂枡瀛樺湪涓斿惎鐢�
         MesMdmItemDO item = mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
 
-        // 2. 鏍¢獙搴撲綅娣锋斁瑙勫垯
-        checkAreaMixingRule(reqVO.getAreaId(), reqVO.getItemId(), reqVO.getBatchId());
+        // 2. 澶勭悊鎵规锛堜粎鍏ュ簱鏃堕渶瑕佸鐞嗘壒娆★級
+        Long batchId = reqVO.getBatchId();
+        String batchCode = reqVO.getBatchCode();
+        if (isInbound) {
+            MesWmBatchDO batch = resolveBatch(reqVO, item);
+            if (batch != null) {
+                batchId = batch.getId();
+                batchCode = batch.getCode();
+            }
+        } else {
+            // 鍑哄簱鏃舵牎楠屾壒娆″瓨鍦�
+            if (batchId != null) {
+                batchService.validateBatchExists(batchId, reqVO.getItemId());
+            }
+        }
 
-        // 3. 鑾峰彇鎴栧垱寤哄簱瀛樿褰�
+        // 3. 鏍¢獙搴撲綅娣锋斁瑙勫垯
+        checkAreaMixingRule(reqVO.getAreaId(), reqVO.getItemId(), batchId);
+
+        // 4. 鑾峰彇鎴栧垱寤哄簱瀛樿褰�
         MesWmMaterialStockDO stock = getOrCreateMaterialStock(
                 reqVO.getItemId(),
                 reqVO.getWarehouseId(),
                 reqVO.getLocationId(),
                 reqVO.getAreaId(),
-                reqVO.getBatchId(),
-                reqVO.getBatchCode(),
+                batchId,
+                batchCode,
                 reqVO.getVendorId(),
                 LocalDateTime.now()
         );
 
-        // 4. 璁$畻鍙樺姩鏁伴噺锛氬叆搴撲负姝o紝鍑哄簱涓鸿礋
+        // 5. 璁$畻鍙樺姩鏁伴噺锛氬叆搴撲负姝o紝鍑哄簱涓鸿礋
         BigDecimal quantity = isInbound ? reqVO.getQuantity() : reqVO.getQuantity().negate();
 
-        // 5. 鏇存柊搴撳瓨鏁伴噺锛堝嚭搴撴椂鏍¢獙搴撳瓨鍏呰冻锛�
-        updateMaterialStockQuantity(stock.getId(), quantity, !isInbound);
-
-        // 6. 鍒涘缓搴撳瓨浜嬪姟娴佹按
+        // 6. 鍒涘缓搴撳瓨浜嬪姟娴佹按锛堝唴閮ㄤ細鏇存柊搴撳瓨鏁伴噺锛�
         int bizType = isInbound ? MesBizTypeConstants.WM_STOCK_ADJUST_IN : MesBizTypeConstants.WM_STOCK_ADJUST_OUT;
         MesWmTransactionSaveReqDTO transaction = new MesWmTransactionSaveReqDTO()
                 .setType(isInbound ? MesWmTransactionTypeEnum.IN.getType() : MesWmTransactionTypeEnum.OUT.getType())
@@ -295,8 +314,8 @@
                 .setBizLineId(stock.getId())
                 .setItemId(reqVO.getItemId())
                 .setQuantity(quantity)
-                .setBatchId(reqVO.getBatchId())
-                .setBatchCode(reqVO.getBatchCode())
+                .setBatchId(batchId)
+                .setBatchCode(batchCode)
                 .setWarehouseId(reqVO.getWarehouseId())
                 .setLocationId(reqVO.getLocationId())
                 .setAreaId(reqVO.getAreaId())
@@ -308,4 +327,77 @@
         return stock.getId();
     }
 
+    /**
+     * 瑙f瀽鎵规
+     * <p>
+     * 鍏ュ簱鏃剁殑鎵规澶勭悊閫昏緫锛�
+     * 1. 鐗╂枡鏈惎鐢ㄦ壒娆$鐞嗭細杩斿洖 null
+     * 2. 浼犲叆 batchId锛氭牎楠屽苟浣跨敤宸叉湁鎵规
+     * 3. 鏈紶 batchId锛氭牴鎹� batchCode 绛夊弬鏁拌嚜鍔ㄥ垱寤烘壒娆�
+     *
+     * @param reqVO 鍏ュ簱璇锋眰
+     * @param item  鐗╂枡淇℃伅
+     * @return 鎵规璁板綍锛堢墿鏂欐湭鍚敤鎵规绠$悊鏃惰繑鍥� null锛�
+     */
+    private MesWmBatchDO resolveBatch(MesWmMaterialStockAdjustReqVO reqVO, MesMdmItemDO item) {
+        // 1. 鐗╂枡鏈惎鐢ㄦ壒娆$鐞嗭紝杩斿洖 null
+        if (Boolean.FALSE.equals(item.getIsBatchManaged())) {
+            return null;
+        }
+
+        // 2. 浼犲叆 batchId锛屾牎楠屽苟杩斿洖宸叉湁鎵规
+        if (reqVO.getBatchId() != null) {
+            return batchService.validateBatchExists(reqVO.getBatchId(), reqVO.getItemId());
+        }
+
+        // 3. 鏈紶 batchId锛岃嚜鍔ㄥ垱寤烘壒娆�
+        MesWmBatchGenerateReqVO batchReqVO = new MesWmBatchGenerateReqVO()
+                .setItemId(reqVO.getItemId())
+                .setBatchCode(reqVO.getBatchCode())
+                .setVendorId(reqVO.getVendorId())
+                .setProduceDate(reqVO.getProduceDate() != null ? reqVO.getProduceDate().atStartOfDay() : null)
+                .setExpireDate(reqVO.getExpireDate() != null ? reqVO.getExpireDate().atStartOfDay() : null)
+                .setReceiptDate(LocalDateTime.now())
+                .setLotNumber(reqVO.getLotNumber())
+                .setQualityStatus(parseQualityStatus(reqVO.getQualityStatus()));
+        return batchService.getOrGenerateBatchCode(batchReqVO);
+    }
+
+    /**
+     * 瑙f瀽璐ㄩ噺鐘舵�侊紙鏀寔鏁板瓧鎴栧瓧绗︿覆锛�
+     */
+    private Integer parseQualityStatus(Object qualityStatus) {
+        if (qualityStatus == null) {
+            return null;
+        }
+        if (qualityStatus instanceof Integer) {
+            return (Integer) qualityStatus;
+        }
+        if (qualityStatus instanceof String) {
+            String str = (String) qualityStatus;
+            // 鏀寔鏁板瓧瀛楃涓�
+            if (str.matches("\\d+")) {
+                return Integer.parseInt(str);
+            }
+            // 鏀寔甯歌瀛楃涓叉槧灏�
+            switch (str.toUpperCase()) {
+                case "PENDING":
+                case "寰呮楠�":
+                case "寰呮":
+                    return 0;
+                case "PASS":
+                case "QUALIFIED":
+                case "鍚堟牸":
+                    return 1;
+                case "FAIL":
+                case "UNQUALIFIED":
+                case "涓嶅悎鏍�":
+                    return 2;
+                default:
+                    throw new IllegalArgumentException("鏃犳晥鐨勮川閲忕姸鎬�: " + str);
+            }
+        }
+        throw new IllegalArgumentException("鏃犳晥鐨勮川閲忕姸鎬佺被鍨�: " + qualityStatus.getClass().getName());
+    }
+
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
index 7309606..352debd 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
@@ -27,6 +27,7 @@
 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.erp.api.sale.ErpSaleOrderApi;
+import cn.iocoder.yudao.module.erp.api.sale.enums.ErpSaleOrderOutStatusEnum;
 import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -213,6 +214,12 @@
         // 鎵ц鎷h揣锛堝緟鎷h揣 鈫� 寰呭~鍐欒繍鍗曪級
         productSalesMapper.updateById(new MesWmProductSalesDO()
                 .setId(id).setStatus(MesWmProductSalesStatusEnum.SHIPPING.getStatus()));
+
+        // 鍥炲啓 ERP 閿�鍞鍗曞嚭搴撶姸鎬佷负"閮ㄥ垎鍑哄簱"锛堣〃绀哄凡鎷h揣/鍗犵敤锛�
+        if (sales.getSaleOrderId() != null) {
+            saleOrderApi.updateOrderOutStatusTo(sales.getSaleOrderId(),
+                    ErpSaleOrderOutStatusEnum.PART_OUT.getStatus());
+        }
     }
 
     @Override
@@ -316,7 +323,8 @@
                 .setBatchId(detail.getBatchId()).setBatchCode(detail.getBatchCode())
                 .setWarehouseId(detail.getWarehouseId()).setLocationId(detail.getLocationId()).setAreaId(detail.getAreaId())
                 .setBizType(MesBizTypeConstants.WM_PRODUCT_SALES).setBizId(sales.getId())
-                .setBizCode(sales.getCode()).setBizLineId(detail.getLineId())));
+                .setBizCode(sales.getCode()).setBizLineId(detail.getLineId())
+                .setMaterialStockId(detail.getMaterialStockId()))); // 鎸囧畾搴撳瓨璁板綍ID锛岄伩鍏嶉噸鏂板尮閰�
     }
 
     @Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeServiceImpl.java
index c2b964c..eb42a1f 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/salesnotice/MesWmSalesNoticeServiceImpl.java
@@ -21,6 +21,7 @@
 import cn.iocoder.yudao.module.erp.api.sale.ErpSaleOrderApi;
 import cn.iocoder.yudao.module.erp.api.sale.dto.ErpSaleOrderItemRespDTO;
 import cn.iocoder.yudao.module.erp.api.sale.dto.ErpSaleOrderRespDTO;
+import cn.iocoder.yudao.module.erp.api.sale.enums.ErpSaleOrderOutStatusEnum;
 import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -114,7 +115,7 @@
     @Transactional(rollbackFor = Exception.class)
     public void submitSalesNotice(Long id) {
         // 1.1 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
-        validateSalesNoticeExistsAndDraft(id);
+        MesWmSalesNoticeDO notice = validateSalesNoticeExistsAndDraft(id);
         // 1.2 妫�鏌ユ槸鍚︽湁琛岄」鐩�
         List<MesWmSalesNoticeLineDO> lines = salesNoticeLineService.getSalesNoticeLineListByNoticeId(id);
         if (CollUtil.isEmpty(lines)) {
@@ -124,6 +125,12 @@
         // 2. 鏇存柊鐘舵�侊細鑽夌 鈫� 寰呭嚭搴�
         salesNoticeMapper.updateById(new MesWmSalesNoticeDO()
                 .setId(id).setStatus(APPROVED.getStatus()));
+
+        // 3. 鍥炲啓 ERP 閿�鍞鍗曞嚭搴撶姸鎬佷负"宸查鐣�"
+        if (notice.getSaleOrderId() != null) {
+            saleOrderApi.updateOrderOutStatusTo(notice.getSaleOrderId(),
+                    ErpSaleOrderOutStatusEnum.RESERVED.getStatus());
+        }
     }
 
     @Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionService.java
index 472f1e6..4acf8d8 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionService.java
@@ -1,5 +1,8 @@
 package cn.iocoder.yudao.module.mes.service.wm.transaction;
 
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.transaction.vo.MesWmTransactionPageReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.wm.transaction.MesWmTransactionDO;
 import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
 import jakarta.validation.Valid;
 
@@ -27,4 +30,12 @@
      */
     void createTransactionList(List<MesWmTransactionSaveReqDTO> reqDTOs);
 
+    /**
+     * 鍒嗛〉鏌ヨ搴撳瓨浜嬪姟娴佹按
+     *
+     * @param pageReqVO 鏌ヨ鏉′欢
+     * @return 浜嬪姟娴佹按鍒嗛〉缁撴灉
+     */
+    PageResult<MesWmTransactionDO> getTransactionPage(MesWmTransactionPageReqVO pageReqVO);
+
 }
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 dd61bb8..9459550 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
@@ -4,6 +4,8 @@
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.mes.controller.admin.wm.transaction.vo.MesWmTransactionPageReqVO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
@@ -75,10 +77,25 @@
         // 1.5 鍏宠仈浜嬪姟鏍¢獙
         checkRelatedTransaction(reqDTO);
 
-        // 2.1 鑾峰彇鎴栧垱寤哄簱瀛樿褰�
-        MesWmMaterialStockDO materialStock = materialStockService.getOrCreateMaterialStock(
-                reqDTO.getItemId(), reqDTO.getWarehouseId(), reqDTO.getLocationId(), reqDTO.getAreaId(),
-                reqDTO.getBatchId(), reqDTO.getBatchCode(), reqDTO.getVendorId(), reqDTO.getReceiptTime());
+        // 2.1 鑾峰彇鎴栧垱寤哄簱瀛樿褰曪紙濡傛灉浼犲叆浜� materialStockId 鍒欑洿鎺ヤ娇鐢紝閬垮厤閲嶆柊鍖归厤锛�
+        MesWmMaterialStockDO materialStock;
+        if (reqDTO.getMaterialStockId() != null) {
+            materialStock = materialStockService.getMaterialStock(reqDTO.getMaterialStockId());
+            if (materialStock == null) {
+                throw exception(WM_MATERIAL_STOCK_NOT_EXISTS);
+            }
+            // 鏍¢獙鐗╂枡銆佹壒娆°�佷粨搴撶瓑缁村害涓�鑷达紙闃叉浼犲叆閿欒鐨� materialStockId锛�
+            if (ObjUtil.notEqual(materialStock.getItemId(), reqDTO.getItemId())
+                    || ObjUtil.notEqual(materialStock.getWarehouseId(), reqDTO.getWarehouseId())
+                    || ObjUtil.notEqual(materialStock.getLocationId(), reqDTO.getLocationId())
+                    || ObjUtil.notEqual(materialStock.getAreaId(), reqDTO.getAreaId())) {
+                throw exception(WM_MATERIAL_STOCK_SELECTION_MISMATCH);
+            }
+        } else {
+            materialStock = materialStockService.getOrCreateMaterialStock(
+                    reqDTO.getItemId(), reqDTO.getWarehouseId(), reqDTO.getLocationId(), reqDTO.getAreaId(),
+                    reqDTO.getBatchId(), reqDTO.getBatchCode(), reqDTO.getVendorId(), reqDTO.getReceiptTime());
+        }
         // 2.2 鍐荤粨鏍¢獙锛堜粨搴撱�佸簱鍖恒�佸簱浣嶃�佸簱瀛樿褰曪級
         checkFrozen(reqDTO, materialStock);
         // 2.3 鏇存柊搴撳瓨鏁伴噺
@@ -106,6 +123,11 @@
         reqDTOs.forEach(this::createTransaction);
     }
 
+    @Override
+    public PageResult<MesWmTransactionDO> getTransactionPage(MesWmTransactionPageReqVO pageReqVO) {
+        return transactionMapper.selectPage(pageReqVO);
+    }
+
     // ==================== 绉佹湁鏍¢獙鏂规硶 ====================
 
     /**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/dto/MesWmTransactionSaveReqDTO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/dto/MesWmTransactionSaveReqDTO.java
index 81974d1..d0ae46a 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/dto/MesWmTransactionSaveReqDTO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/dto/MesWmTransactionSaveReqDTO.java
@@ -102,6 +102,11 @@
     // ===== 鍏宠仈 =====
 
     /**
+     * 鎸囧畾搴撳瓨璁板綍 ID锛堝嚭搴撳満鏅紭鍏堜娇鐢紝閬垮厤閲嶆柊鍖归厤搴撳瓨璁板綍锛�
+     */
+    private Long materialStockId;
+
+    /**
      * 鍏宠仈浜嬪姟 ID锛堟垚瀵逛簨鍔′腑锛屽叆搴撲簨鍔″叧鑱斿嚭搴撲簨鍔★級
      */
     private Long relatedTransactionId;
diff --git a/yudao-module-mes/src/main/resources/mapper/wm/batch/MesWmBatchMapper.xml b/yudao-module-mes/src/main/resources/mapper/wm/batch/MesWmBatchMapper.xml
index 78ba8f4..22fba71 100644
--- a/yudao-module-mes/src/main/resources/mapper/wm/batch/MesWmBatchMapper.xml
+++ b/yudao-module-mes/src/main/resources/mapper/wm/batch/MesWmBatchMapper.xml
@@ -14,12 +14,11 @@
         SQL 璺緞锛氬簱瀛樹簨鍔�(娑堣�� OUT) 鈫� 娑堣�楀崟 鈫� 鎶ュ伐璁板綍 鈫� 搴撳瓨浜嬪姟(浜у嚭 IN) 鈫� 鎵规
     -->
     <select id="selectListByForward" parameterType="String" resultMap="BatchTraceResult">
-        SELECT DISTINCT pf.work_order_id, pf.item_id, ppl.batch_id, ppl.batch_code
+        SELECT DISTINCT pf.work_order_id, pf.item_id, tx_produce.batch_id, tx_produce.batch_code
         FROM mes_wm_transaction tx_consume
         LEFT JOIN mes_wm_item_consume ic ON tx_consume.biz_id = ic.id AND tx_consume.biz_type = 123 AND ic.deleted = 0
         LEFT JOIN mes_pro_feedback pf ON pf.id = ic.feedback_id AND pf.deleted = 0
         LEFT JOIN mes_wm_transaction tx_produce ON tx_produce.biz_id = pf.id AND tx_produce.biz_type = 124 AND tx_produce.deleted = 0
-        LEFT JOIN mes_wm_product_produce pp ON tx_produce.biz_id = pp.id AND tx_produce.biz_type = 124 AND pp.deleted = 0
         WHERE tx_consume.batch_code = #{batchCode}
         AND tx_consume.biz_type = 123
         AND tx_consume.deleted = 0
@@ -31,12 +30,12 @@
         SQL 璺緞锛氬簱瀛樹簨鍔�(浜у嚭 IN) 鈫� 浜у嚭鍗� 鈫� 鎶ュ伐璁板綍 鈫� 搴撳瓨浜嬪姟(娑堣�� OUT) 鈫� 鎵规
     -->
     <select id="selectListByBackward" parameterType="String" resultMap="BatchTraceResult">
-        SELECT DISTINCT ic.work_order_id, icd.item_id, icd.batch_id, icd.batch_code
+        SELECT DISTINCT ic.work_order_id, tx_consume.item_id, tx_consume.batch_id, tx_consume.batch_code
         FROM mes_wm_transaction tx_produce
         LEFT JOIN mes_wm_product_produce pp ON tx_produce.biz_id = pp.id AND tx_produce.biz_type = 124 AND pp.deleted = 0
         LEFT JOIN mes_pro_feedback pf ON pf.id = pp.feedback_id AND pf.deleted = 0
         LEFT JOIN mes_wm_transaction tx_consume ON tx_consume.biz_id = pf.id AND tx_consume.biz_type = 123 AND tx_consume.deleted = 0
-        LEFT JOIN mes_wm_item_consume ic ON tx_consume.biz_id = ic.id AND tx_consume.biz_type = 123 AND ic.deleted = 0
+        LEFT JOIN mes_wm_item_consume ic ON ic.id = tx_consume.biz_id AND ic.deleted = 0
         WHERE tx_produce.batch_code = #{batchCode}
         AND tx_produce.biz_type = 124
         AND tx_produce.deleted = 0

--
Gitblit v1.9.3