From de0202274ed147e89fdbba0a953936a3b9997ec7 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 22 九月 2026 17:37:50 +0800
Subject: [PATCH] feat(mes): 更新IPQC过程检验功能

---
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcLineController.java                   |   10 
 docs/sql/config_export_all_20260918.sql                                                                                          |   69 +++
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcPageReqVO.java                   |    4 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcController.java                       |   28 
 yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImplTest.java                         |  373 +++++--------------
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java                               |    2 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcSaveReqVO.java                     |   12 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcLineController.java                   |   10 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/ipqc/MesQcIpqcDO.java                               |   32 -
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/MesQcPendingInspectController.java |   22 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcSaveReqVO.java                   |   25 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcController.java                     |   58 --
 docs/project-business/index.html                                                                                                 |    2 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/qc/MesQcReportApiImpl.java                                        |   50 +-
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcLineController.java                 |   10 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemServiceImpl.java                 |   36 -
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/ipqc/MesQcIpqcMapper.java                                |    2 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcRespVO.java                        |    4 
 yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml                                       |    6 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ncr/MesQcNcrController.java                       |   10 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java                               |    5 
 yudao-module-qcreport/src/main/java/cn/iocoder/yudao/module/qcreport/service/instance/MesQcReportContextMapper.java              |    2 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcController.java                       |   28 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/MesQcOqcLineController.java                   |   10 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/oqc/MesQcOqcMapper.java                                  |    7 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java                             |  145 +------
 yudao-module-mes/src/test/resources/sql/create_tables.sql                                                                        |    5 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/ai/MesProAiServiceImpl.java                               |   12 
 docs/project-business/data/objects.json                                                                                          |    2 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/MesQcOqcController.java                       |   29 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemService.java                     |   10 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImpl.java                               |   10 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/vo/MesQcPendingInspectRespVO.java  |    3 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java                                         |    1 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateItemController.java         |   27 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateIndicatorController.java    |    8 
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcRespVO.java                      |   33 -
 yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ai/MesQcAiServiceImpl.java                                 |    3 
 38 files changed, 388 insertions(+), 717 deletions(-)

diff --git a/docs/project-business/data/objects.json b/docs/project-business/data/objects.json
index ac4ea65..ca2a564 100644
--- a/docs/project-business/data/objects.json
+++ b/docs/project-business/data/objects.json
@@ -36,7 +36,7 @@
     {"name": "搴撳瓨鍙拌处", "module": "浠撳偍", "table": "mes_wm_material_stock", "doc": "鐗╂枡脳浠撳簱脳搴撳尯脳搴撲綅脳鎵规脳渚涘簲鍟嗗叚鍏冪粍锛屾暟閲�/鍐荤粨/鍗犵敤/鍦ㄩ�斿洓閲�", "upstream": ["鍏ㄩ儴鍏ュ簱鍗�"], "downstream": ["鍏ㄩ儴鍑哄簱鍗�", "浜嬪姟娴佹按"], "keywords": "搴撳瓨 鍙拌处 stock 鍙敤閲�"},
     {"name": "鎵规", "module": "浠撳偍", "table": "mes_wm_batch", "doc": "鍏宠仈鐗╂枡/宸ュ崟/渚涘簲鍟�/瀹㈡埛/璐ㄩ噺鐘舵�侊紱SN 鐮佸惈鎵规 uuid锛涙潯鐮佹敮鎸�18绉嶄笟鍔″璞�", "upstream": ["鍏ュ簱鍗曟嵁"], "downstream": ["搴撳瓨鍙拌处"], "keywords": "鎵规 batch SN 鏉$爜 杩芥函"},
     {"name": "IQC鏉ユ枡妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_iqc", "doc": "鍒拌揣閫氱煡/澶栧崗鍏ュ簱瑙﹀彂锛岃崏绋�0鈫掑畬鎴�4锛岀粨璁哄洖鍐欐潵婧愬崟鎹紱琛屾搷浣溿�屽嚭鎶ュ憡銆嶄粎鍦ㄥ凡瀹屾垚鏃跺彲瑙�", "upstream": ["鍒拌揣閫氱煡", "澶栧崗鍏ュ簱"], "downstream": ["閲囪喘鍏ュ簱", "渚涘簲鍟嗛��璐�", "NCR", "鎶ュ憡瀹炰緥(鍑烘姤鍛�)"], "keywords": "IQC 鏉ユ枡妫�楠� 鍑烘姤鍛�"},
-    {"name": "IPQC杩囩▼妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_ipqc", "doc": "鎶ュ伐璐ㄦ宸ュ簭浜у嚭琛岃Е鍙戯紝瀹屾垚鍥炶皟鎺ㄨ繘鎶ュ伐涓庝骇鍑哄叆搴擄紱琛屾搷浣溿�屽嚭鎶ュ憡銆嶄粎鍦ㄥ凡瀹屾垚鏃跺彲瑙�", "upstream": ["鎶ュ伐"], "downstream": ["浜у嚭鍏ュ簱", "NCR", "鎶ュ憡瀹炰緥(鍑烘姤鍛�)"], "keywords": "IPQC 杩囩▼妫�楠� 宸℃ 鍑烘姤鍛�"},
+    {"name": "IPQC杩囩▼妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_ipqc", "doc": "鎶ュ伐璐ㄦ宸ュ簭浜у嚭琛岃Е鍙戯紝瀹屾垚鍥炶皟鎺ㄨ繘鎶ュ伐涓庝骇鍑哄叆搴擄紱琛ㄥ崟鍙暀銆屾潵婧愬崟鎹� + 浜у搧鐗╂枡(鍓嶇鎵嬮�� MDM 鐗╂枡) + 鎵瑰彿(蹇呭~) + 鏁伴噺 + 妫�楠屼俊鎭�嶏紝宸插幓鐢熶骇璁㈠崟/鐢熶骇浠诲姟/宸ヤ綅/宸ュ簭锛屾壒鍙烽殢鎶ュ憡钀芥锛涜鎿嶄綔銆屽嚭鎶ュ憡銆嶄粎鍦ㄥ凡瀹屾垚鏃跺彲瑙�", "upstream": ["鎶ュ伐"], "downstream": ["浜у嚭鍏ュ簱", "NCR", "鎶ュ憡瀹炰緥(鍑烘姤鍛�)"], "keywords": "IPQC 杩囩▼妫�楠� 宸℃ 鍑烘姤鍛� 鎵瑰彿 batchCode MDM鐗╂枡"},
     {"name": "OQC鍑鸿揣妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_oqc", "doc": "閿�鍞嚭搴撴彁浜よЕ鍙戯紝瀹屾垚鎺ㄨ繘鍑哄簱鍗曞緟鎷h揣锛涜鎿嶄綔銆屽嚭鎶ュ憡銆嶄粎鍦ㄥ凡瀹屾垚鏃跺彲瑙�", "upstream": ["閿�鍞嚭搴撳崟"], "downstream": ["閿�鍞嚭搴撳崟(鎺ㄨ繘)", "鎶ュ憡瀹炰緥(鍑烘姤鍛�)"], "keywords": "OQC 鍑鸿揣妫�楠� 鍑哄巶妫�楠� 鍑烘姤鍛�"},
     {"name": "RQC閫�璐ф楠�", "module": "璐ㄩ噺", "table": "mes_qc_rqc", "doc": "鐢熶骇閫�鏂�/閿�鍞��璐�/鍞悗閫�璐цЕ鍙戯紝缁撹鍥炶皟鍞悗锛涜鎿嶄綔銆屽嚭鎶ュ憡銆嶄粎鍦ㄥ凡瀹屾垚鏃跺彲瑙併�傛帾杈炲凡缁熶竴涓恒�岄��璐ф楠屻�嶏紙鍘熻彍鍗曠埗椤逛笌 mes_qc_type 瀛楀吀鍐欍�岄��鏂欐楠屻�嶏紝涓庡悗绔灇涓�/琛ㄦ敞閲�/鑿滃崟鏉冮檺瀛愰」涓嶄竴鑷达紱RQC 涓夎�呴兘瑕嗙洊锛屾晠鍙栥�岄��璐ф楠屻�嶏級", "upstream": ["閫�鏂�", "閫�璐�"], "downstream": ["閫�璐у叆搴�", "鍞悗鍥炶皟", "鎶ュ憡瀹炰緥(鍑烘姤鍛�)"], "keywords": "RQC 閫�璐ф楠� 閫�鏂欐楠� 鍑烘姤鍛�"},
     {"name": "NCR涓嶅悎鏍煎搧", "module": "璐ㄩ噺", "table": "mes_qc_ncr", "doc": "寰呰瘎瀹�0鈫掑凡璇勫6鈫掑凡澶勭疆7鈫掑凡鍏抽棴8锛屽缃�:閫�璐�/鎶ュ簾/杩斿伐/璁╂鎺ユ敹/闄嶇骇", "upstream": ["IQC/IPQC/OQC/RQC"], "downstream": ["閫�璐�/鎶ュ簾/杩斿伐(鍙拌处)"], "keywords": "NCR 涓嶅悎鏍� 澶勭疆 鐗归噰 鎶ュ簾"},
diff --git a/docs/project-business/index.html b/docs/project-business/index.html
index 72f2500..551ce3d 100644
--- a/docs/project-business/index.html
+++ b/docs/project-business/index.html
@@ -479,7 +479,7 @@
     {"name": "搴撳瓨鍙拌处", "module": "浠撳偍", "table": "mes_wm_material_stock", "doc": "鐗╂枡脳浠撳簱脳搴撳尯脳搴撲綅脳鎵规脳渚涘簲鍟嗗叚鍏冪粍锛屾暟閲�/鍐荤粨/鍗犵敤/鍦ㄩ�斿洓閲�", "upstream": ["鍏ㄩ儴鍏ュ簱鍗�"], "downstream": ["鍏ㄩ儴鍑哄簱鍗�", "浜嬪姟娴佹按"], "keywords": "搴撳瓨 鍙拌处 stock 鍙敤閲�"},
     {"name": "鎵规", "module": "浠撳偍", "table": "mes_wm_batch", "doc": "鍏宠仈鐗╂枡/宸ュ崟/渚涘簲鍟�/瀹㈡埛/璐ㄩ噺鐘舵�侊紱SN 鐮佸惈鎵规 uuid锛涙潯鐮佹敮鎸�18绉嶄笟鍔″璞�", "upstream": ["鍏ュ簱鍗曟嵁"], "downstream": ["搴撳瓨鍙拌处"], "keywords": "鎵规 batch SN 鏉$爜 杩芥函"},
     {"name": "IQC鏉ユ枡妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_iqc", "doc": "鍒拌揣閫氱煡/澶栧崗鍏ュ簱瑙﹀彂锛岃崏绋�0鈫掑畬鎴�4锛岀粨璁哄洖鍐欐潵婧愬崟鎹紱琛屾搷浣溿�屽嚭鎶ュ憡銆嶄粎鍦ㄥ凡瀹屾垚鏃跺彲瑙�", "upstream": ["鍒拌揣閫氱煡", "澶栧崗鍏ュ簱"], "downstream": ["閲囪喘鍏ュ簱", "渚涘簲鍟嗛��璐�", "NCR", "鎶ュ憡瀹炰緥(鍑烘姤鍛�)"], "keywords": "IQC 鏉ユ枡妫�楠� 鍑烘姤鍛�"},
-    {"name": "IPQC杩囩▼妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_ipqc", "doc": "鎶ュ伐璐ㄦ宸ュ簭浜у嚭琛岃Е鍙戯紝瀹屾垚鍥炶皟鎺ㄨ繘鎶ュ伐涓庝骇鍑哄叆搴擄紱琛屾搷浣溿�屽嚭鎶ュ憡銆嶄粎鍦ㄥ凡瀹屾垚鏃跺彲瑙�", "upstream": ["鎶ュ伐"], "downstream": ["浜у嚭鍏ュ簱", "NCR", "鎶ュ憡瀹炰緥(鍑烘姤鍛�)"], "keywords": "IPQC 杩囩▼妫�楠� 宸℃ 鍑烘姤鍛�"},
+    {"name": "IPQC杩囩▼妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_ipqc", "doc": "鎶ュ伐璐ㄦ宸ュ簭浜у嚭琛岃Е鍙戯紝瀹屾垚鍥炶皟鎺ㄨ繘鎶ュ伐涓庝骇鍑哄叆搴擄紱琛ㄥ崟鍙暀銆屾潵婧愬崟鎹� + 浜у搧鐗╂枡(鍓嶇鎵嬮�� MDM 鐗╂枡) + 鎵瑰彿(蹇呭~) + 鏁伴噺 + 妫�楠屼俊鎭�嶏紝宸插幓鐢熶骇璁㈠崟/鐢熶骇浠诲姟/宸ヤ綅/宸ュ簭锛屾壒鍙烽殢鎶ュ憡钀芥锛涜鎿嶄綔銆屽嚭鎶ュ憡銆嶄粎鍦ㄥ凡瀹屾垚鏃跺彲瑙�", "upstream": ["鎶ュ伐"], "downstream": ["浜у嚭鍏ュ簱", "NCR", "鎶ュ憡瀹炰緥(鍑烘姤鍛�)"], "keywords": "IPQC 杩囩▼妫�楠� 宸℃ 鍑烘姤鍛� 鎵瑰彿 batchCode MDM鐗╂枡"},
     {"name": "OQC鍑鸿揣妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_oqc", "doc": "閿�鍞嚭搴撴彁浜よЕ鍙戯紝瀹屾垚鎺ㄨ繘鍑哄簱鍗曞緟鎷h揣锛涜鎿嶄綔銆屽嚭鎶ュ憡銆嶄粎鍦ㄥ凡瀹屾垚鏃跺彲瑙�", "upstream": ["閿�鍞嚭搴撳崟"], "downstream": ["閿�鍞嚭搴撳崟(鎺ㄨ繘)", "鎶ュ憡瀹炰緥(鍑烘姤鍛�)"], "keywords": "OQC 鍑鸿揣妫�楠� 鍑哄巶妫�楠� 鍑烘姤鍛�"},
     {"name": "RQC閫�璐ф楠�", "module": "璐ㄩ噺", "table": "mes_qc_rqc", "doc": "鐢熶骇閫�鏂�/閿�鍞��璐�/鍞悗閫�璐цЕ鍙戯紝缁撹鍥炶皟鍞悗锛涜鎿嶄綔銆屽嚭鎶ュ憡銆嶄粎鍦ㄥ凡瀹屾垚鏃跺彲瑙併�傛帾杈炲凡缁熶竴涓恒�岄��璐ф楠屻�嶏紙鍘熻彍鍗曠埗椤逛笌 mes_qc_type 瀛楀吀鍐欍�岄��鏂欐楠屻�嶏紝涓庡悗绔灇涓�/琛ㄦ敞閲�/鑿滃崟鏉冮檺瀛愰」涓嶄竴鑷达紱RQC 涓夎�呴兘瑕嗙洊锛屾晠鍙栥�岄��璐ф楠屻�嶏級", "upstream": ["閫�鏂�", "閫�璐�"], "downstream": ["閫�璐у叆搴�", "鍞悗鍥炶皟", "鎶ュ憡瀹炰緥(鍑烘姤鍛�)"], "keywords": "RQC 閫�璐ф楠� 閫�鏂欐楠� 鍑烘姤鍛�"},
     {"name": "NCR涓嶅悎鏍煎搧", "module": "璐ㄩ噺", "table": "mes_qc_ncr", "doc": "寰呰瘎瀹�0鈫掑凡璇勫6鈫掑凡澶勭疆7鈫掑凡鍏抽棴8锛屽缃�:閫�璐�/鎶ュ簾/杩斿伐/璁╂鎺ユ敹/闄嶇骇", "upstream": ["IQC/IPQC/OQC/RQC"], "downstream": ["閫�璐�/鎶ュ簾/杩斿伐(鍙拌处)"], "keywords": "NCR 涓嶅悎鏍� 澶勭疆 鐗归噰 鎶ュ簾"},
diff --git a/docs/sql/config_export_all_20260918.sql b/docs/sql/config_export_all_20260918.sql
index f948f41..fe459fb 100644
--- a/docs/sql/config_export_all_20260918.sql
+++ b/docs/sql/config_export_all_20260918.sql
@@ -22,9 +22,73 @@
 --      ruoyi-vue-pro.system_menu WHERE deleted=b'0'`锛屾槸鎵ц鏈熻法搴撳叏閲忔嫹璐濓紝
 --      鍙婧愬簱 ruoyi-vue-pro 鏈夎繖鍑犺灏变細琚甫杩囧幓 鈥斺�� 涓庨樁娈典竴鐨勫瓧闈㈤噺 INSERT 涓嶅悓銆�
 --      鍦ㄦ鐧昏鍙负璇存槑銆岃繖鐗堟枃浠剁‘瀹炶鐩栦簡璇ュ彉鏇淬�嶏紝閬垮厤鍚庢潵鑰呬互涓烘紡浜嗐��
+--   鈶� 琛� 116 涓寜閽潈闄� + 鍒� 1 涓け鏁堣彍鍗曪紙2026-09-22锛屽墠鍚庣鑿滃崟/鏉冮檺瀵归綈锛夛細
+--      116 涓寜閽潈闄愭槸銆屽悗绔� @PreAuthorize 娉ㄨВ閲屾湁銆乻ystem_menu 閲屾病鏈夈�嶇殑宸泦
+--      锛圓 绫� 19 涓細鍓嶅悗绔兘鍦ㄧ敤鑰屽簱缂哄け锛屽睘鐪熺己锛汢 绫� 97 涓細浠呭悗绔畾涔夛級锛�
+--      鎸夈�屾ā鍧�:瀹炰綋銆嶅墠缂�鍒嗗埆鎸傚埌瀵瑰簲 type=2 鐨勮彍鍗曚笅锛堝 erp:supplier:* 鈫� 602525 渚涘簲鍟嗘。妗堬級銆�
+--      鍚屾椂杞垹 1063009 浠撳簱鍧愭爣閰嶇疆鍙婂叾 2 涓寜閽� 1063091/1063092 鈥斺��
+--      璇ヨ彍鍗� component 鎸囧悜 bi/config/warehouse-coordinate/index锛屽墠绔苟鏃犳椤甸潰锛堝巻鍙叉畫鐣欙級锛�
+--      骞剁墿鐞嗘竻鎺夎繖 3 涓彍鍗曠殑 9 鏉� system_role_menu 瀛ゅ効鎺堟潈銆�
+--      **鏈枃浠跺悓鏍锋棤闇�涓烘鏀瑰姩**锛氶樁娈碘憽 璺ㄥ簱鍏ㄩ噺鎷疯礉 system_menu(deleted=b'0') 涓�
+--      system_role_menu锛屾簮搴� ruoyi-vue-pro 宸插啓鍏ワ紝鎵ц鏈熻嚜浼氬甫杩囧幓銆傜悊鐢卞悓 鈶ゃ��
+--   鈶� 钖叕鎸夐挳鏉冮檺鐮佹敼鍚嶅榻� + 鍒犻櫎銆孍RP 绯荤粺銆嶆暣涓彍鍗曪紙2026-09-22锛夛細
+--      鈶� 鍓嶇 hrm/salary/calculation/index.vue銆乸ayment/index.vue 鍘熷厛鐢�
+--         hrm:salary-calculation:* / hrm:salary-payment:*锛岃�屽悗绔�
+--         HrmSalaryCalculationController / HrmSalaryPaymentController 鐢ㄧ殑鏄� hrm:salary:*锛�
+--         涓よ竟瀵逛笉涓婏紙鎸夐挳瑕佷箞鍘嬫牴涓嶆樉绀猴紝瑕佷箞鏄剧ず浜嗚鍚庣 403锛夈�傚凡鏀瑰墠绔榻愬悗绔紝
+--         骞惰蒋鍒犲簱涓� 5 鏉℃棫鐮佹寜閽紙60212/60213/60214/60244/60245锛夊強鍏� 15 鏉� role_menu銆�
+--         娉細鏃ф寜閽師鏈寕鍦ㄣ�岃秴绾х鐞嗗憳/楂樺眰绠$悊/閿�鍞汉鍛樸��3 涓鑹蹭笂锛堥攢鍞汉鍛樻寔鏈夎柂璧勫彂鏀炬潈闄愶紝
+--         鐤戜负瑙掕壊椤靛叏閫夎鎺堬級锛屽垹闄ゅ悗鏈縼绉绘巿鏉冿紝鏂版寜閽� hrm:salary:* 鐩墠鏃犱换浣曡鑹叉巿鏉冿紝
+--         闇�鍦ㄨ鑹茬鐞嗛〉鎸夊疄闄呭矖浣嶉噸鏂板嬀閫夈��
+--      鈶� 杞垹銆孍RP 绯荤粺銆�(id=2563, path=/erp) 鏁存5瀛愭爲鍏� 83 涓妭鐐� 鈥斺��
+--         浜у搧绠$悊 17 + 搴撳瓨绠$悊 43 + 璐㈠姟绠$悊 20 + ERP棣栭〉 1 + 鐩綍鑺傜偣 2锛�
+--         骞剁墿鐞嗘竻鎺夊叾 83 鏉� system_role_menu锛堣瀛愭爲浠呰秴绾х鐞嗗憳涓�涓鑹叉寕鏈夋巿鏉冿級銆�
+--         鍏朵腑浜у搧绠$悊 / 搴撳瓨绠$悊鍦ㄥ悗绔� yudao-module-erp 宸叉棤浠讳綍鎺у埗鍣�
+--         锛坋rp:product* / erp:warehouse* / erp:stock* 鍏ㄩ儴涓嶅瓨鍦級锛屽睘鍘嗗彶娈嬬暀锛�
+--         璐㈠姟绠$悊锛堢粨绠楄处鎴�/浠樻鍗�/鏀舵鍗曪級鍚庣鎺у埗鍣ㄤ粛鍦紝鍒犲悗杩欎袱涓〉闈㈠け鍘昏彍鍗曞叆鍙�
+--         锛堜粯娆惧崟鍦ㄣ�岄噰璐鐞嗐�嶄笅鍙︽湁閲嶅鍏ュ彛 1063116锛夈�傘�岄噰璐鐞嗐��(2602)銆�
+--         銆岃惀閿�绠$悊銆�(2617) 涓や釜鏍圭洰褰曟湭鍔紝鍏朵腑鐨� ERP 椤甸潰鐓у父淇濈暀銆�
+--         鈿� 杩欐槸**宸茬煡涓斿凡纭鎺ュ彈鐨勪唬浠�**锛氬垹闄ゅ悗 13 涓粛鍦ㄤ娇鐢ㄧ殑鏉冮檺鐮佸け鍘� system_menu 杞戒綋 鈥斺��
+--           erp:account:create/update/delete/export锛圓 绫伙細鍓嶅悗绔兘鍦ㄧ敤锛夈��
+--           erp:finance-receipt:create/update/delete/export/query/update-status锛圓 绫伙級銆�
+--           erp:account:query銆乪rp:statistics:query锛圔 绫伙細浠呭悗绔� @PreAuthorize锛夈��
+--           鍗崇粨绠楄处鎴枫�佹敹娆惧崟涓ら〉鍦ㄥ簱涓凡鏃犳潈闄愯锛屾墍鏈夎鑹叉寜閽叏闅愯棌涓斿悗绔繑鍥� 403锛�
+--           鏃ュ悗鑻ヨ鎭㈠杩欎袱涓〉闈紝闇�閲嶅缓鑿滃崟骞惰ˉ鍥炰笂杩� 13 涓潈闄愮爜銆�
+--      **鏈枃浠跺悓鏍锋棤闇�涓烘鏀瑰姩**锛岀悊鐢卞悓 鈶も懃銆�
+--   鈶� 杩囩▼妫�楠屽崟 mes_qc_ipqc 瀛楁璋冩暣锛�2026-09-22锛孖PQC 鍘荤敓浜т俊鎭� + 鎵瑰彿蹇呭~锛夛細
+--      鍒� work_order_id / task_id / workstation_id / process_id 鍥涘垪锛�
+--      鍦� source_doc_code 涔嬪悗鏂板 batch_code varchar(100) COMMENT '鎵瑰彿'銆�
+--      鍚屾鏀逛簡鏈湴 H2 鍗曟祴寤鸿〃鑴氭湰 create_tables.sql锛堝惁鍒� MesQcIpqcServiceImplTest 鍏ㄦ寕锛夈��
+--      **鏈枃浠跺繀椤绘敼**锛氶樁娈典竴鏄叏搴� CREATE TABLE 瀛楅潰閲忓鍑猴紝涓嶉噸瀵煎嚭灏变細寤哄嚭鏃х粨鏋勩��
+--      婧愬簱 ruoyi-vue-pro 宸叉墽琛屽悓鏍风殑 DDL锛岀粨鏋勪互鏈枃浠朵负鍑嗐��
+--   鈶� 琛� 18 涓寜閽潈闄愶紙2026-09-22锛孋2 绫伙細銆屽墠绔湪鐢ㄣ�佸悗绔� @PreAuthorize 鏈畾涔夈�佸簱涓害鏃犮�嶏級锛�
+--      1075533~1075550锛屽垎鍒负銆屾ā鏉垮鍑恒��(system:notify-template:export 鈫� 2145)銆�
+--      銆岀鑱屼氦鎺ャ��(hrm:resignation:handover 鈫� 6005)銆併�屾潅椤瑰叆搴撳崟銆�6 涓姩浣�
+--      (mes:wm-misc-receipt:create/update/delete/export/cancel/finish 鈫� 5888)銆�
+--      銆屽浘绾稿鏍搞��1 涓�併�岃璁′换鍔°��5 涓�併�岀増鏈彉鏇淬��4 涓姩浣� (mes:pd-* 鈫� 602572)銆�
+--      琛ュ綍鏃� C2 鍏� 93 涓紙鍒犮�孍RP 绯荤粺銆嶅悗鐢� 54 娑ㄤ笂鏉ワ級锛屽叾涓粎杩� 18 涓兘瀹氫綅鍒� type=2 鐖惰彍鍗曪紱
+--      宸插叏閮ㄨ惤搴撳苟閫愪釜澶嶆牳銆岀埗鑿滃崟 type=2銆乻tatus=0銆嶉�氳繃銆�
+--      鍓╀綑 75 涓�**鍒绘剰鏈ˉ**锛屽垎涓夌被锛�
+--        鈶� 67 涓� erp:*锛坧roduct / product-category / product-unit / warehouse / stock /
+--           stock-in / stock-out / stock-move / stock-check / stock-record / purchase-in /
+--           purchase-return / sale-out / sale-return锛夆�斺�� 瀵瑰簲椤甸潰**鍙湁鍓嶇銆佹病鏈夊悗绔�**锛�
+--           yudao-module-erp 鏃犱换浣曡繖浜涙帶鍒跺櫒锛屽叏浠� grep 涔熸棤瀵瑰簲 @PreAuthorize銆�
+--           鍏朵腑 42 涓殑鐖惰彍鍗曪紙浜у搧绠$悊/搴撳瓨绠$悊瀛愭爲锛夊凡闅� 鈶� 涓�骞跺垹闄わ紝鍙� 25 涓�
+--           锛堥噰璐叆搴�/閲囪喘閫�璐�/閿�鍞嚭搴�/閿�鍞��璐э級鑷缓搴撹捣灏辨病鏈夎彍鍗曘�傚睘鍘嗗彶娈嬬暀锛屾寜鏃㈠畾鍙e緞璺宠繃銆�
+--        鈶� 7 涓� crm:product:* / crm:product-category:* 鈥斺�� 涓诲伐浣滃尯 yudao-module-crm 涓嬪苟鏃�
+--           CrmProductController / CrmProductCategoryController锛屽彧瀛樺湪浜庝袱涓苟琛� agent 鐨�
+--           worktree 鍓湰閲岋紙灏氭湭鍚堝苟锛夛紱涓斿嵆渚垮悎骞朵篃缂恒�屽晢鍝併�嶈彍鍗曪紝鍗曡ˉ鎸夐挳鏃犳剰涔夛紝鐣欑粰璇ュ垎鏀嚜宸辫ˉ銆�
+--        鈶� 1 涓� mes:wm-approval:save 鈥斺�� 鍓嶇 views/wls/approval/config/index.vue 鐨�**鐮佸啓閿欎簡**锛�
+--           鍚庣 /mes/wms/approval/config/save 瀹為檯瑕佹眰 mes:wm-warehouse:update锛堝簱涓凡鏈夛紝id=5784锛夛紝
+--           涓� 鈶︹憼 鐨勮柂閰紓绉诲悓绫婚棶棰樸�傛纭慨娉曟槸鏀瑰墠绔繖涓�琛岋紝鍥犳湭鑾锋巿鏉冩敼鍓嶇鏁呮湭鍔ㄣ��
+--           锛堝彟锛氳椤垫墍鎸傜殑鐖剁洰褰� 6002銆屼汉浜嬪鎵广�嶆槸涓病鏈夊瓙鑿滃崟鐨勭┖ type=1锛屾湰灏辨病鏈夎彍鍗曟寕鍒拌椤甸潰锛�
+--      **鏈枃浠跺悓鏍锋棤闇�涓烘鏀瑰姩**锛岀悊鐢卞悓 鈶も懃銆�
 -- 楠岃瘉锛氭湰鏂囦欢宸插湪鍏ㄦ柊绌哄簱锛圡ySQL 8.4.6锛夋暣浠芥墽琛岄�氳繃 鈥斺�� 419 寮犺〃銆�6 寮� qc_report_*銆�
 --       6 涓瓧鍏哥被鍨� + 21 鏉″瓧鍏告暟鎹�乤dmin 璐﹀彿 / 1258 鏉¤彍鍗� / 2349 鏉� role_menu /
 --       榛樿 OAuth2 瀹㈡埛绔潎姝g‘钀藉簱銆�
+-- 2026-09-22 涓婅堪鍙樻洿鍏ㄩ儴钀藉湴鍚庯紝婧愬簱 ruoyi-vue-pro 鐜版湁鏈夋晥鑿滃崟 1308 鏉★紙鍏朵腑鎸夐挳 1021 鏉★級銆�
+-- 闃舵鈶� 灏嗘嫹璐濈殑 system_role_menu 1708 鏉★紙= admin 鍚嶄笅銆岃秴绾х鐞嗗憳銆�852 + 銆屾櫘閫氳鑹层��856锛�
+-- 璇ユ瀛愭煡璇笉甯� deleted 杩囨护锛屽疄娴嬭繖涓よ鑹蹭笅鏃犺蒋鍒犺锛屾晠 1708 鍗虫渶缁堣鏁帮級锛屾墽琛屾椂搴斾笌姝や竴鑷淬��
 -- 鑼冨洿锛氬叏搴� BASE TABLE 鍏� 419 寮狅紝鍏ㄩ儴杈撳嚭 CREATE TABLE锛�
 --       浠呬互涓嬮厤缃被琛ㄥ甫鏁版嵁(INSERT)锛屽叾浣欎笟鍔�/绯荤粺/杩愯鍘嗗彶琛ㄥ彧淇濈暀绌鸿〃缁撴瀯锛�
 --     鈶� 鍗忓悓瀹℃壒娴佺▼锛堝紩鎿庡厓鏁版嵁+瀹氫箟锛屼粎婵�娲绘祦绋嬶紝鍓斿巻鍙�/杩愯/韬唤锛夛細act_ge_property銆乤ct_id_property銆乤ct_re_procdef銆乤ct_re_deployment銆乤ct_ge_bytearray銆乤ct_re_model銆乥pm_process_definition_info
@@ -8036,10 +8100,7 @@
   `source_doc_id` bigint DEFAULT NULL COMMENT '鏉ユ簮鍗曟嵁缂栧彿',
   `source_line_id` bigint DEFAULT NULL COMMENT '鏉ユ簮鍗曟嵁琛岀紪鍙�',
   `source_doc_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '鏉ユ簮鍗曟嵁缂栧彿',
-  `work_order_id` bigint DEFAULT NULL COMMENT '鐢熶骇宸ュ崟缂栧彿',
-  `task_id` bigint DEFAULT NULL COMMENT '鐢熶骇浠诲姟缂栧彿',
-  `workstation_id` bigint DEFAULT NULL COMMENT '宸ヤ綅缂栧彿',
-  `process_id` bigint DEFAULT NULL COMMENT '宸ュ簭缂栧彿',
+  `batch_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '鎵瑰彿',
   `item_id` bigint DEFAULT NULL COMMENT '浜у搧鐗╂枡缂栧彿',
   `check_quantity` decimal(24,6) DEFAULT NULL COMMENT '妫�娴嬫暟閲�',
   `qualified_quantity` decimal(24,6) DEFAULT NULL COMMENT '鍚堟牸鍝佹暟閲�',
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/qc/MesQcReportApiImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/qc/MesQcReportApiImpl.java
index f936cca..715068f 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/qc/MesQcReportApiImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/qc/MesQcReportApiImpl.java
@@ -4,10 +4,12 @@
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
 import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
 import cn.iocoder.yudao.module.mes.api.qc.dto.MesQcReportItemRespDTO;
 import cn.iocoder.yudao.module.mes.api.qc.dto.MesQcReportRespDTO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDetailDO;
@@ -19,15 +21,11 @@
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.oqc.MesQcOqcLineDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.rqc.MesQcRqcDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.rqc.MesQcRqcLineDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcIndicatorItemTypeEnum;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcResultValueTypeEnum;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
-import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
-import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
 import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
 import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcLineService;
@@ -102,11 +100,9 @@
     private MesQcIndicatorService indicatorService;
 
     @Resource
-    private MesMdItemService itemService;
+    private MdmItemApi mdmItemApi;
     @Resource
-    private MesMdUnitMeasureService unitMeasureService;
-    @Resource
-    private MesProWorkOrderService workOrderService;
+    private MdmUnitMeasureApi mdmUnitMeasureApi;
     @Resource
     private AdminUserApi adminUserApi;
     @Resource
@@ -144,7 +140,7 @@
                     order.getSourceDocType(), order.getSourceDocCode(), order.getItemId(), order.getCheckQuantity(),
                     order.getQualifiedQuantity(), order.getUnqualifiedQuantity(), order.getCheckResult(),
                     order.getInspectDate(), order.getStatus(), order.getRemark());
-            resp.setWorkOrderCode(workOrderCode(order.getWorkOrderId()));
+            resp.setBatchCode(defaultStr(order.getBatchCode()));
             lines = loadIpqcLines(qcId);
             inspectorUserId = order.getInspectorUserId();
         } else if (Objects.equals(qcType, MesQcTypeEnum.OQC.getType())) {
@@ -176,17 +172,17 @@
             throw new IllegalArgumentException("鏆備笉鏀寔 qcType=" + qcType);
         }
 
-        // 鐗╂枡涓庡崟浣嶏細鍗曚綅浼樺厛鍙栬涓婄殑锛堟楠屾椂瀹為檯鐢ㄧ殑鍗曚綅锛夛紝缂哄け鎵嶅洖閫�鐗╂枡鐨勯粯璁ゅ崟浣�
-        MesMdItemDO item = resp.getItemId() == null ? null
-                : itemService.getItemMap(Collections.singletonList(resp.getItemId())).get(resp.getItemId());
+        // 鐗╂枡涓庡崟浣嶏細鐗╂枡 ID 鏉ヨ嚜 MDM锛涘崟浣嶄紭鍏堝彇琛屼笂鐨勶紙妫�楠屾椂瀹為檯鐢ㄧ殑鍗曚綅锛夛紝缂哄け鎵嶅洖閫�鐗╂枡鐨勯粯璁ゅ崟浣�
+        MdmItemRespDTO item = resp.getItemId() == null ? null
+                : mdmItemApi.getItemMap(Collections.singletonList(resp.getItemId())).get(resp.getItemId());
         if (item != null) {
             resp.setItemCode(defaultStr(item.getCode()));
             resp.setItemName(defaultStr(item.getName()));
             resp.setItemSpecification(defaultStr(item.getSpecification()));
         }
-        Map<Long, MesMdUnitMeasureDO> unitMap = unitMapOf(lines, item);
+        Map<Long, MdmUnitMeasureRespDTO> unitMap = unitMapOf(lines, item);
         if (item != null) {
-            MesMdUnitMeasureDO itemUnit = unitMap.get(item.getUnitMeasureId());
+            MdmUnitMeasureRespDTO itemUnit = unitMap.get(item.getUnitMeasureId());
             resp.setUnitName(itemUnit == null ? "" : defaultStr(itemUnit.getName()));
         }
         resp.setInspectorName(userName(inspectorUserId));
@@ -235,7 +231,7 @@
      * 锛堢粍鍚嶄笌鍏紡鏄垎缁勬楠岄」鏈�涓嶈涓㈢殑涓ゆ牱涓滆タ锛夈��
      */
     private BuiltItems buildItems(Long qcId, Integer qcType, List<LineRow> lines,
-                                  Map<Long, MesMdUnitMeasureDO> unitMap, MesMdItemDO item) {
+                                  Map<Long, MdmUnitMeasureRespDTO> unitMap, MdmItemRespDTO item) {
         if (CollUtil.isEmpty(lines)) {
             return new BuiltItems(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), 0);
         }
@@ -408,7 +404,7 @@
     private List<MesQcReportItemRespDTO> expandRows(MesQcIndicatorDO indicator, LineRow line,
                                                     List<MesQcIndicatorResultDO> samples,
                                                     Map<Long, List<MesQcIndicatorResultDetailDO>> detailMap,
-                                                    Map<Long, MesMdUnitMeasureDO> unitMap, MesMdItemDO item) {
+                                                    Map<Long, MdmUnitMeasureRespDTO> unitMap, MdmItemRespDTO item) {
         List<MesQcReportItemRespDTO> rows = new ArrayList<>();
         for (MesQcIndicatorResultDO sample : samples) {
             for (MesQcIndicatorResultDetailDO detail : detailMap.getOrDefault(sample.getId(),
@@ -441,9 +437,9 @@
     }
 
     private MesQcReportItemRespDTO toItem(MesQcIndicatorDO indicator, LineRow line, String sampleCode, String value,
-                                          String detailRemark, Map<Long, MesMdUnitMeasureDO> unitMap,
-                                          MesMdItemDO item) {
-        MesMdUnitMeasureDO unit = unitMap.get(line.unitMeasureId());
+                                          String detailRemark, Map<Long, MdmUnitMeasureRespDTO> unitMap,
+                                          MdmItemRespDTO item) {
+        MdmUnitMeasureRespDTO unit = unitMap.get(line.unitMeasureId());
         if (unit == null && item != null) {
             unit = unitMap.get(item.getUnitMeasureId());
         }
@@ -524,7 +520,7 @@
 
     // ==================== 鍏宠仈鍚嶇О ====================
 
-    private Map<Long, MesMdUnitMeasureDO> unitMapOf(List<LineRow> lines, MesMdItemDO item) {
+    private Map<Long, MdmUnitMeasureRespDTO> unitMapOf(List<LineRow> lines, MdmItemRespDTO item) {
         List<Long> unitIds = new ArrayList<>();
         for (LineRow line : lines) {
             if (line.unitMeasureId() != null) {
@@ -534,7 +530,7 @@
         if (item != null && item.getUnitMeasureId() != null) {
             unitIds.add(item.getUnitMeasureId());
         }
-        return unitIds.isEmpty() ? Collections.emptyMap() : unitMeasureService.getUnitMeasureMap(unitIds);
+        return unitIds.isEmpty() ? Collections.emptyMap() : mdmUnitMeasureApi.getUnitMeasureMap(unitIds);
     }
 
     private String supplierName(Long vendorId) {
@@ -552,14 +548,6 @@
         }
         CrmCustomerRespDTO client = customerApi.getCustomerMap(Collections.singleton(clientId)).get(clientId);
         return client == null ? "" : defaultStr(client.getName());
-    }
-
-    private String workOrderCode(Long workOrderId) {
-        if (workOrderId == null) {
-            return "";
-        }
-        MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(workOrderId);
-        return workOrder == null ? "" : defaultStr(workOrder.getCode());
     }
 
     private String userName(Long userId) {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcController.java
index 1113942..f07a326 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcController.java
@@ -9,15 +9,14 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcSaveReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcQualityExportVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDetailDO;
@@ -26,11 +25,6 @@
 import cn.iocoder.yudao.module.mes.dal.mysql.qc.ipqc.MesQcIpqcLineMapper;
 import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
-import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
-import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
-import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService;
-import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
 import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
 import cn.iocoder.yudao.module.mes.service.qc.ipqc.MesQcIpqcService;
@@ -70,15 +64,9 @@
     @Resource
     private MesQcIpqcService ipqcService;
     @Resource
-    private MesProWorkOrderService workOrderService;
+    private MdmItemApi mdmItemApi;
     @Resource
-    private MesMdWorkstationService workstationService;
-    @Resource
-    private MesProProcessService processService;
-    @Resource
-    private MesMdItemService itemService;
-    @Resource
-    private MesMdUnitMeasureService unitMeasureService;
+    private MdmUnitMeasureApi mdmUnitMeasureApi;
     @Resource
     private MesQcIndicatorResultService indicatorResultService;
     @Resource
@@ -157,21 +145,12 @@
         if (CollUtil.isEmpty(list)) {
             return Collections.emptyList();
         }
-        // 鎵归噺鏌ヨ宸ュ崟
-        Map<Long, MesProWorkOrderDO> workOrderMap = workOrderService.getWorkOrderMap(
-                convertSet(list, MesQcIpqcDO::getWorkOrderId));
-        // 鎵归噺鏌ヨ宸ヤ綅
-        Map<Long, MesMdWorkstationDO> workstationMap = workstationService.getWorkstationMap(
-                convertSet(list, MesQcIpqcDO::getWorkstationId));
-        // 鎵归噺鏌ヨ宸ュ簭
-        Map<Long, MesProProcessDO> processMap = processService.getProcessMap(
-                convertSet(list, MesQcIpqcDO::getProcessId));
-        // 鎵归噺鏌ヨ鐗╂枡
-        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
+        // 鎵归噺鏌ヨ鐗╂枡锛堢墿鏂� ID 鏉ヨ嚜 MDM锛�
+        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                 convertSet(list, MesQcIpqcDO::getItemId));
-        // 鎵归噺鏌ヨ璁¢噺鍗曚綅锛�
-        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
-                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
+        // 鎵归噺鏌ヨ璁¢噺鍗曚綅锛堟潵鑷� MDM锛�
+        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap(
+                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId));
         // 鎵归噺鏌ヨ妫�娴嬩汉鍛�
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                 convertSet(list, MesQcIpqcDO::getInspectorUserId));
@@ -179,12 +158,6 @@
         Map<Long, String> indicatorSummaryMap = buildIndicatorSummaryMap(list);
         // 鎷艰 VO
         return BeanUtils.toBean(list, MesQcIpqcRespVO.class, vo -> {
-            findAndThen(workOrderMap, vo.getWorkOrderId(), workOrder -> vo
-                    .setWorkOrderCode(workOrder.getCode()).setWorkOrderName(workOrder.getName()));
-            findAndThen(workstationMap, vo.getWorkstationId(),
-                    ws -> vo.setWorkstationName(ws.getName()));
-            findAndThen(processMap, vo.getProcessId(),
-                    process -> vo.setProcessName(process.getName()));
             findAndThen(itemMap, vo.getItemId(), item -> {
                 vo.setItemCode(item.getCode()).setItemName(item.getName()).setItemSpecification(item.getSpecification());
                 findAndThen(unitMeasureMap, item.getUnitMeasureId(),
@@ -262,8 +235,8 @@
         // 鎵归噺鏌ヨ妫�娴嬩汉鍛�
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                 convertSet(list, MesQcIpqcDO::getInspectorUserId));
-        // 鎵归噺鏌ヨ鐗╂枡
-        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
+        // 鎵归噺鏌ヨ鐗╂枡锛堢墿鏂� ID 鏉ヨ嚜 MDM锛�
+        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                 convertSet(list, MesQcIpqcDO::getItemId));
         // 鎵归噺鏌ヨ琛屾槑缁�
         List<MesQcIpqcLineDO> lines = ipqcLineMapper.selectListByIpqcIds(convertSet(list, MesQcIpqcDO::getId));
@@ -280,10 +253,9 @@
         for (MesQcIpqcDO ipqc : list) {
             MesQcQualityExportVO vo = new MesQcQualityExportVO();
             vo.setDocName(ipqc.getName());
-            MesMdItemDO item = itemMap.get(ipqc.getItemId());
+            MdmItemRespDTO item = itemMap.get(ipqc.getItemId());
             vo.setItemName(item != null ? item.getName() : "");
-            // IPQC 鏃犳壒娆″彿瀛楁锛屾殏鐢ㄦ潵婧愬崟鎹紪鍙凤紙涓�鑸负鐢熶骇宸ュ崟鍙凤級浣滀负鎵瑰彿
-            vo.setBatchNo(ipqc.getSourceDocCode());
+            vo.setBatchNo(ipqc.getBatchCode());
             vo.setInspectDate(MesQcQualityExportVO.formatDateTime(ipqc.getInspectDate()));
             List<String> indicatorNames = new ArrayList<>();
             List<String> judgementSegments = new ArrayList<>();
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcLineController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcLineController.java
index 61b5bd6..781a47a 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcLineController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcLineController.java
@@ -6,10 +6,10 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.line.MesQcIpqcLinePageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.line.MesQcIpqcLineRespVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.ipqc.MesQcIpqcLineDO;
-import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
 import cn.iocoder.yudao.module.mes.service.qc.ipqc.MesQcIpqcLineService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -43,7 +43,7 @@
     @Resource
     private MesQcIndicatorService indicatorService;
     @Resource
-    private MesMdUnitMeasureService unitMeasureService;
+    private MdmUnitMeasureApi mdmUnitMeasureApi;
 
     @GetMapping("/get")
     @Operation(summary = "鑾峰緱杩囩▼妫�楠屽崟琛�")
@@ -71,8 +71,8 @@
         // 鎵归噺鏌ヨ妫�娴嬫寚鏍�
         Map<Long, MesQcIndicatorDO> indicatorMap = indicatorService.getIndicatorMap(
                 convertSet(list, MesQcIpqcLineDO::getIndicatorId));
-        // 鎵归噺鏌ヨ璁¢噺鍗曚綅
-        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
+        // 鎵归噺鏌ヨ璁¢噺鍗曚綅锛堟潵鑷� MDM锛�
+        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap(
                 convertSet(list, MesQcIpqcLineDO::getUnitMeasureId));
         // 鎷艰 VO
         return BeanUtils.toBean(list, MesQcIpqcLineRespVO.class, vo -> {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcPageReqVO.java
index 8221b17..e00932b 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcPageReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcPageReqVO.java
@@ -23,8 +23,8 @@
     @Schema(description = "IPQC 妫�楠岀被鍨�", example = "1")
     private Integer type;
 
-    @Schema(description = "鐢熶骇宸ュ崟 ID", example = "10")
-    private Long workOrderId;
+    @Schema(description = "鎵瑰彿锛堟ā绯婂尮閰嶏級", example = "BC2025")
+    private String batchCode;
 
     @Schema(description = "浜у搧鐗╂枡 ID", example = "50")
     private Long itemId;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcRespVO.java
index cec6752..1cfaee7 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcRespVO.java
@@ -50,37 +50,12 @@
     @Schema(description = "鏉ユ簮鍗曟嵁缂栧彿", example = "FB20250101001")
     private String sourceDocCode;
 
-    // ========== 鐢熶骇鍏宠仈 ==========
-
-    @Schema(description = "鐢熶骇宸ュ崟 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
-    private Long workOrderId;
-
-    @Schema(description = "宸ュ崟缂栧彿", example = "WO20250101001")
-    @ExcelProperty("宸ュ崟缂栧彿")
-    private String workOrderCode;
-
-    @Schema(description = "宸ュ崟鍚嶇О", example = "鐢熶骇宸ュ崟A")
-    private String workOrderName;
-
-    @Schema(description = "鐢熶骇浠诲姟 ID", example = "20")
-    private Long taskId;
-
-    @Schema(description = "宸ヤ綅 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30")
-    private Long workstationId;
-
-    @Schema(description = "宸ヤ綅鍚嶇О", example = "宸ヤ綅A")
-    @ExcelProperty("宸ヤ綅鍚嶇О")
-    private String workstationName;
-
-    @Schema(description = "宸ュ簭 ID", example = "40")
-    private Long processId;
-
-    @Schema(description = "宸ュ簭鍚嶇О", example = "缁勮")
-    @ExcelProperty("宸ュ簭鍚嶇О")
-    private String processName;
-
     // ========== 鐗╂枡 ==========
 
+    @Schema(description = "鎵瑰彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "BC20250101")
+    @ExcelProperty("鎵瑰彿")
+    private String batchCode;
+
     @Schema(description = "浜у搧鐗╂枡 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
     private Long itemId;
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcSaveReqVO.java
index 8ada36b..edbb641 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcSaveReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcSaveReqVO.java
@@ -7,6 +7,7 @@
 import jakarta.validation.constraints.DecimalMin;
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
 import lombok.Data;
 
 import java.math.BigDecimal;
@@ -42,25 +43,15 @@
     @Schema(description = "鏉ユ簮鍗曟嵁琛� ID", example = "300")
     private Long sourceLineId;
 
-    // ========== 鐢熶骇鍏宠仈 ==========
-
-    @Schema(description = "鐢熶骇宸ュ崟 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
-    @NotNull(message = "鐢熶骇宸ュ崟涓嶈兘涓虹┖")
-    private Long workOrderId;
-
-    @Schema(description = "鐢熶骇浠诲姟 ID", example = "20")
-    private Long taskId;
-
-    @Schema(description = "宸ヤ綅 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30")
-    @NotNull(message = "宸ヤ綅涓嶈兘涓虹┖")
-    private Long workstationId;
-
-    @Schema(description = "宸ュ簭 ID", example = "40")
-    private Long processId;
-
     // ========== 鐗╂枡 ==========
 
-    @Schema(description = "浜у搧鐗╂枡 ID", example = "50")
+    @Schema(description = "鎵瑰彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "BC20250101")
+    @NotEmpty(message = "鎵瑰彿涓嶈兘涓虹┖")
+    @Size(max = 100, message = "鎵瑰彿闀垮害涓嶈兘瓒呰繃 100 涓瓧绗�")
+    private String batchCode;
+
+    @Schema(description = "浜у搧鐗╂枡 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "50")
+    @NotNull(message = "浜у搧鐗╂枡涓嶈兘涓虹┖")
     private Long itemId;
 
     @Schema(description = "璐ㄦ鏂规 ID", example = "5")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcController.java
index e535b20..8a9f255 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcController.java
@@ -13,18 +13,18 @@
 import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcSaveReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcQualityExportVO;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
 import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi;
 import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDetailDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcLineDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.qc.iqc.MesQcIqcLineMapper;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
-import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
@@ -73,9 +73,9 @@
     @Resource
     private MesQcIndicatorService indicatorService;
     @Resource
-    private MesMdItemService itemService;
+    private MdmItemApi mdmItemApi;
     @Resource
-    private MesMdUnitMeasureService unitMeasureService;
+    private MdmUnitMeasureApi mdmUnitMeasureApi;
     @Resource
     private MesQcIqcLineMapper iqcLineMapper;
 
@@ -154,12 +154,12 @@
         Map<Long, SrmSupplierRespDTO> vendorMap = srmSupplierApi.getSupplierList(
                 convertSet(list, MesQcIqcDO::getVendorId)).getCheckedData().stream()
                 .collect(java.util.stream.Collectors.toMap(SrmSupplierRespDTO::getId, s -> s));
-        // 鎵归噺鏌ヨ鐗╂枡
-        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
+        // 鎵归噺鏌ヨ鐗╂枡锛堢墿鏂� ID 鏉ヨ嚜 MDM锛�
+        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                 convertSet(list, MesQcIqcDO::getItemId));
-        // 鎵归噺鏌ヨ璁¢噺鍗曚綅锛堥�氳繃鐗╂枡鐨� unitMeasureId锛�
-        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
-                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
+        // 鎵归噺鏌ヨ璁¢噺鍗曚綅锛堟潵鑷� MDM锛岄�氳繃鐗╂枡鐨� unitMeasureId锛�
+        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap(
+                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId));
         // 鎵归噺鏌ヨ妫�娴嬩汉鍛�
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                 convertSet(list, MesQcIqcDO::getInspectorUserId));
@@ -248,8 +248,8 @@
         // 鎵归噺鏌ヨ妫�娴嬩汉鍛�
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                 convertSet(list, MesQcIqcDO::getInspectorUserId));
-        // 鎵归噺鏌ヨ鐗╂枡
-        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
+        // 鎵归噺鏌ヨ鐗╂枡锛堢墿鏂� ID 鏉ヨ嚜 MDM锛�
+        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                 convertSet(list, MesQcIqcDO::getItemId));
         // 鎵归噺鏌ヨ琛屾槑缁�
         List<MesQcIqcLineDO> lines = iqcLineMapper.selectListByIqcIds(convertSet(list, MesQcIqcDO::getId));
@@ -266,7 +266,7 @@
         for (MesQcIqcDO iqc : list) {
             MesQcQualityExportVO vo = new MesQcQualityExportVO();
             vo.setDocName(iqc.getName());
-            MesMdItemDO item = itemMap.get(iqc.getItemId());
+            MdmItemRespDTO item = itemMap.get(iqc.getItemId());
             vo.setItemName(item != null ? item.getName() : "");
             vo.setBatchNo(iqc.getVendorBatch());
             vo.setInspectDate(MesQcQualityExportVO.formatDateTime(iqc.getInspectDate()));
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcLineController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcLineController.java
index 10ea277..8076290 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcLineController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/iqc/MesQcIqcLineController.java
@@ -6,10 +6,10 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLinePageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.line.MesQcIqcLineRespVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcLineDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
-import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcLineService;
 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -43,7 +43,7 @@
     @Resource
     private MesQcIndicatorService indicatorService;
     @Resource
-    private MesMdUnitMeasureService unitMeasureService;
+    private MdmUnitMeasureApi mdmUnitMeasureApi;
 
     @GetMapping("/get")
     @Operation(summary = "鑾峰緱鏉ユ枡妫�楠屽崟琛�")
@@ -71,8 +71,8 @@
         // 鎵归噺鏌ヨ妫�娴嬫寚鏍�
         Map<Long, MesQcIndicatorDO> indicatorMap = indicatorService.getIndicatorMap(
                 convertSet(list, MesQcIqcLineDO::getIndicatorId));
-        // 鎵归噺鏌ヨ璁¢噺鍗曚綅
-        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
+        // 鎵归噺鏌ヨ璁¢噺鍗曚綅锛堟潵鑷� MDM锛�
+        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap(
                 convertSet(list, MesQcIqcLineDO::getUnitMeasureId));
         // 鎷艰 VO
         return BeanUtils.toBean(list, MesQcIqcLineRespVO.class, vo -> {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ncr/MesQcNcrController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ncr/MesQcNcrController.java
index bc6e5d3..22ae139 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ncr/MesQcNcrController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ncr/MesQcNcrController.java
@@ -7,10 +7,10 @@
 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.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ncr.vo.*;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.ncr.MesQcNcrDO;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
 import cn.iocoder.yudao.module.mes.service.qc.ncr.MesQcNcrService;
 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
 import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
@@ -44,7 +44,7 @@
     private MesQcNcrService ncrService;
 
     @Resource
-    private MesMdItemService itemService;
+    private MdmItemApi mdmItemApi;
 
     @Resource
     private AdminUserApi adminUserApi;
@@ -138,8 +138,8 @@
         if (CollUtil.isEmpty(list)) {
             return Collections.emptyList();
         }
-        // 鎵归噺鏌ヨ鐗╂枡
-        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
+        // 鎵归噺鏌ヨ鐗╂枡锛堢墿鏂� ID 鏉ヨ嚜 MDM锛�
+        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                 convertSet(list, MesQcNcrDO::getItemId));
         // 鎵归噺鏌ヨ璇勫浜�
         Set<Long> reviewerUserIds = convertSet(list, MesQcNcrDO::getReviewerUserId);
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/MesQcOqcController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/MesQcOqcController.java
index 299e4f7..c77e06e 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/MesQcOqcController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/MesQcOqcController.java
@@ -15,8 +15,10 @@
 import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcQualityExportVO;
 import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
 import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDetailDO;
@@ -25,9 +27,6 @@
 import cn.iocoder.yudao.module.mes.dal.mysql.qc.oqc.MesQcOqcLineMapper;
 import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
-import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
-import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
 import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
 import cn.iocoder.yudao.module.mes.service.qc.oqc.MesQcOqcService;
@@ -69,9 +68,9 @@
     @Resource
     private CrmCustomerApi customerApi;
     @Resource
-    private MesMdItemService itemService;
+    private MdmItemApi mdmItemApi;
     @Resource
-    private MesMdUnitMeasureService unitMeasureService;
+    private MdmUnitMeasureApi mdmUnitMeasureApi;
     @Resource
     private MesQcIndicatorResultService indicatorResultService;
     @Resource
@@ -153,12 +152,12 @@
         // 鎵归噺鏌ヨ瀹㈡埛
         Map<Long, CrmCustomerRespDTO> clientMap = customerApi.getCustomerMap(
                 convertSet(list, MesQcOqcDO::getClientId));
-        // 鎵归噺鏌ヨ鐗╂枡
-        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
+        // 鎵归噺鏌ヨ鐗╂枡锛堢墿鏂� ID 鏉ヨ嚜 MDM锛�
+        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                 convertSet(list, MesQcOqcDO::getItemId));
-        // 鎵归噺鏌ヨ璁¢噺鍗曚綅
-        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
-                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
+        // 鎵归噺鏌ヨ璁¢噺鍗曚綅锛堟潵鑷� MDM锛�
+        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap(
+                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId));
         // 鎵归噺鏌ヨ妫�娴嬩汉鍛�
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                 convertSet(list, MesQcOqcDO::getInspectorUserId));
@@ -189,8 +188,8 @@
         // 鎵归噺鏌ヨ妫�娴嬩汉鍛�
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                 convertSet(list, MesQcOqcDO::getInspectorUserId));
-        // 鎵归噺鏌ヨ鐗╂枡
-        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
+        // 鎵归噺鏌ヨ鐗╂枡锛堢墿鏂� ID 鏉ヨ嚜 MDM锛�
+        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                 convertSet(list, MesQcOqcDO::getItemId));
         // 鎵归噺鏌ヨ琛屾槑缁�
         List<MesQcOqcLineDO> lines = oqcLineMapper.selectListByOqcIds(convertSet(list, MesQcOqcDO::getId));
@@ -207,7 +206,7 @@
         for (MesQcOqcDO oqc : list) {
             MesQcQualityExportVO vo = new MesQcQualityExportVO();
             vo.setDocName(oqc.getName());
-            MesMdItemDO item = itemMap.get(oqc.getItemId());
+            MdmItemRespDTO item = itemMap.get(oqc.getItemId());
             vo.setItemName(item != null ? item.getName() : "");
             vo.setBatchNo(oqc.getBatchCode());
             vo.setInspectDate(MesQcQualityExportVO.formatDateTime(oqc.getInspectDate()));
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/MesQcOqcLineController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/MesQcOqcLineController.java
index 5973061..4facbe4 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/MesQcOqcLineController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/MesQcOqcLineController.java
@@ -6,10 +6,10 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.line.MesQcOqcLinePageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.line.MesQcOqcLineRespVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.oqc.MesQcOqcLineDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
-import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.qc.oqc.MesQcOqcLineService;
 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -43,7 +43,7 @@
     @Resource
     private MesQcIndicatorService indicatorService;
     @Resource
-    private MesMdUnitMeasureService unitMeasureService;
+    private MdmUnitMeasureApi mdmUnitMeasureApi;
 
     @GetMapping("/get")
     @Operation(summary = "鑾峰緱鍑鸿揣妫�楠屽崟琛�")
@@ -71,8 +71,8 @@
         // 鎵归噺鏌ヨ妫�娴嬫寚鏍�
         Map<Long, MesQcIndicatorDO> indicatorMap = indicatorService.getIndicatorMap(
                 convertSet(list, MesQcOqcLineDO::getIndicatorId));
-        // 鎵归噺鏌ヨ璁¢噺鍗曚綅
-        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
+        // 鎵归噺鏌ヨ璁¢噺鍗曚綅锛堟潵鑷� MDM锛�
+        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap(
                 convertSet(list, MesQcOqcLineDO::getUnitMeasureId));
         // 鎷艰 VO
         return BeanUtils.toBean(list, MesQcOqcLineRespVO.class, vo -> {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcRespVO.java
index 6d360a9..9289874 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcRespVO.java
@@ -47,7 +47,7 @@
 
     // ========== 瀹㈡埛 ==========
 
-    @Schema(description = "瀹㈡埛 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
+    @Schema(description = "瀹㈡埛 ID", example = "10")
     private Long clientId;
 
     @Schema(description = "瀹㈡埛绠�绉�", example = "瀹㈡埛A")
@@ -87,7 +87,7 @@
     @Schema(description = "鏈�澶т笉鍚堟牸鏁�", example = "0")
     private Integer maxUnqualifiedQuantity;
 
-    @Schema(description = "鏈鍑鸿揣鏁伴噺", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
+    @Schema(description = "鏈鍑鸿揣鏁伴噺", example = "100")
     @ExcelProperty("鍑鸿揣鏁伴噺")
     private BigDecimal outQuantity;
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcSaveReqVO.java
index c720ae8..326bdd0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcSaveReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcSaveReqVO.java
@@ -37,8 +37,7 @@
 
     // ========== 瀹㈡埛 ==========
 
-    @Schema(description = "瀹㈡埛 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
-    @NotNull(message = "瀹㈡埛涓嶈兘涓虹┖")
+    @Schema(description = "瀹㈡埛 ID", example = "10")
     private Long clientId;
 
     // ========== 鐗╂枡 ==========
@@ -55,13 +54,11 @@
 
     // ========== 鏁伴噺 ==========
 
-    @Schema(description = "鏈鍑鸿揣鏁伴噺", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
-    @NotNull(message = "鏈鍑鸿揣鏁伴噺涓嶈兘涓虹┖")
+    @Schema(description = "鏈鍑鸿揣鏁伴噺", example = "100")
     @DecimalMin(value = "0", message = "鏈鍑鸿揣鏁伴噺涓嶈兘灏忎簬 0")
     private BigDecimal outQuantity;
 
-    @Schema(description = "鏈妫�娴嬫暟閲�", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
-    @NotNull(message = "鏈妫�娴嬫暟閲忎笉鑳戒负绌�")
+    @Schema(description = "鏈妫�娴嬫暟閲�", example = "10")
     @DecimalMin(value = "0", message = "鏈妫�娴嬫暟閲忎笉鑳藉皬浜� 0")
     private BigDecimal checkQuantity;
 
@@ -80,8 +77,7 @@
     @Schema(description = "妫�娴嬬粨鏋�", example = "1")
     private Integer checkResult;
 
-    @Schema(description = "鍑鸿揣鏃ユ湡", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotNull(message = "鍑鸿揣鏃ユ湡涓嶈兘涓虹┖")
+    @Schema(description = "鍑鸿揣鏃ユ湡")
     private LocalDateTime outDate;
 
     @Schema(description = "妫�娴嬫棩鏈�", requiredMode = Schema.RequiredMode.REQUIRED)
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/MesQcPendingInspectController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/MesQcPendingInspectController.java
index 00fbe2b..e5f3e6c 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/MesQcPendingInspectController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/MesQcPendingInspectController.java
@@ -9,12 +9,12 @@
 import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
 import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi;
 import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
-import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
 import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
 import cn.iocoder.yudao.module.mes.service.qc.pendinginspect.MesQcPendingInspectService;
@@ -44,9 +44,9 @@
     @Resource
     private MesQcPendingInspectService pendingInspectService;
     @Resource
-    private MesMdItemService itemService;
+    private MdmItemApi mdmItemApi;
     @Resource
-    private MesMdUnitMeasureService unitMeasureService;
+    private MdmUnitMeasureApi mdmUnitMeasureApi;
     @Resource
     private SrmSupplierApi srmSupplierApi;
     @Resource
@@ -73,12 +73,12 @@
         if (CollUtil.isEmpty(list)) {
             return;
         }
-        // 鎵归噺鏌ヨ鐗╂枡
-        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
+        // 鎵归噺鏌ヨ鐗╂枡锛堢墿鏂� ID 鏉ヨ嚜 MDM锛�
+        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                 convertSet(list, MesQcPendingInspectRespVO::getItemId));
-        // 鎵归噺鏌ヨ璁¢噺鍗曚綅锛堥�氳繃鐗╂枡鐨� unitMeasureId锛�
-        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
-                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
+        // 鎵归噺鏌ヨ璁¢噺鍗曚綅锛堟潵鑷� MDM锛岄�氳繃鐗╂枡鐨� unitMeasureId锛�
+        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap(
+                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId));
         // 鎵归噺鏌ヨ渚涘簲鍟嗭紙IQC 鍦烘櫙锛�
         Map<Long, SrmSupplierRespDTO> vendorMap = srmSupplierApi.getSupplierList(
                 convertSet(list, MesQcPendingInspectRespVO::getVendorId)).getCheckedData().stream()
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/vo/MesQcPendingInspectRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/vo/MesQcPendingInspectRespVO.java
index effe2a5..c7dcca0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/vo/MesQcPendingInspectRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/vo/MesQcPendingInspectRespVO.java
@@ -21,6 +21,9 @@
     @Schema(description = "鏉ユ簮鍗曟嵁缂栧彿", example = "AN2025001")
     private String sourceDocCode;
 
+    @Schema(description = "鎵瑰彿锛堜粎 IPQC/OQC/RQC 鏉ユ簮鍗曟嵁鏈夊�硷級", example = "BC20250101")
+    private String batchCode;
+
     @Schema(description = "妫�楠岀被鍨嬶紙MesQcTypeEnum锛�", example = "1")
     private Integer qcType;
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcController.java
index 8ddc929..625a473 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcController.java
@@ -13,8 +13,10 @@
 import cn.iocoder.yudao.module.mes.controller.admin.qc.rqc.vo.MesQcRqcRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.rqc.vo.MesQcRqcSaveReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcQualityExportVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDetailDO;
@@ -23,8 +25,6 @@
 import cn.iocoder.yudao.module.mes.dal.mysql.qc.rqc.MesQcRqcLineMapper;
 import cn.iocoder.yudao.module.mes.enums.DictTypeConstants;
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
-import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
 import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
 import cn.iocoder.yudao.module.mes.service.qc.rqc.MesQcRqcService;
@@ -64,9 +64,9 @@
     @Resource
     private MesQcRqcService rqcService;
     @Resource
-    private MesMdItemService itemService;
+    private MdmItemApi mdmItemApi;
     @Resource
-    private MesMdUnitMeasureService unitMeasureService;
+    private MdmUnitMeasureApi mdmUnitMeasureApi;
     @Resource
     private MesQcIndicatorResultService indicatorResultService;
     @Resource
@@ -145,12 +145,12 @@
         if (CollUtil.isEmpty(list)) {
             return Collections.emptyList();
         }
-        // 鎵归噺鏌ヨ鐗╂枡
-        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
+        // 鎵归噺鏌ヨ鐗╂枡锛堢墿鏂� ID 鏉ヨ嚜 MDM锛�
+        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                 convertSet(list, MesQcRqcDO::getItemId));
-        // 鎵归噺鏌ヨ璁¢噺鍗曚綅
-        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
-                convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
+        // 鎵归噺鏌ヨ璁¢噺鍗曚綅锛堟潵鑷� MDM锛�
+        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap(
+                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId));
         // 鎵归噺鏌ヨ妫�娴嬩汉鍛�
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                 convertSet(list, MesQcRqcDO::getInspectorUserId));
@@ -235,8 +235,8 @@
         // 鎵归噺鏌ヨ妫�娴嬩汉鍛�
         Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
                 convertSet(list, MesQcRqcDO::getInspectorUserId));
-        // 鎵归噺鏌ヨ鐗╂枡
-        Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
+        // 鎵归噺鏌ヨ鐗╂枡锛堢墿鏂� ID 鏉ヨ嚜 MDM锛�
+        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                 convertSet(list, MesQcRqcDO::getItemId));
         // 鎵归噺鏌ヨ琛屾槑缁�
         List<MesQcRqcLineDO> lines = rqcLineMapper.selectListByRqcIds(convertSet(list, MesQcRqcDO::getId));
@@ -253,7 +253,7 @@
         for (MesQcRqcDO rqc : list) {
             MesQcQualityExportVO vo = new MesQcQualityExportVO();
             vo.setDocName(rqc.getName());
-            MesMdItemDO item = itemMap.get(rqc.getItemId());
+            MdmItemRespDTO item = itemMap.get(rqc.getItemId());
             vo.setItemName(item != null ? item.getName() : "");
             vo.setBatchNo(rqc.getBatchCode());
             vo.setInspectDate(MesQcQualityExportVO.formatDateTime(rqc.getInspectDate()));
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcLineController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcLineController.java
index 2139ba5..c7707b1 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcLineController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcLineController.java
@@ -6,10 +6,10 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.rqc.vo.line.MesQcRqcLinePageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.rqc.vo.line.MesQcRqcLineRespVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.rqc.MesQcRqcLineDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
-import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.qc.rqc.MesQcRqcLineService;
 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
 import io.swagger.v3.oas.annotations.Operation;
@@ -43,7 +43,7 @@
     @Resource
     private MesQcIndicatorService indicatorService;
     @Resource
-    private MesMdUnitMeasureService unitMeasureService;
+    private MdmUnitMeasureApi mdmUnitMeasureApi;
 
     @GetMapping("/get")
     @Operation(summary = "鑾峰緱閫�璐ф楠屽崟琛�")
@@ -71,8 +71,8 @@
         // 鎵归噺鏌ヨ妫�娴嬫寚鏍�
         Map<Long, MesQcIndicatorDO> indicatorMap = indicatorService.getIndicatorMap(
                 convertSet(list, MesQcRqcLineDO::getIndicatorId));
-        // 鎵归噺鏌ヨ璁¢噺鍗曚綅
-        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
+        // 鎵归噺鏌ヨ璁¢噺鍗曚綅锛堟潵鑷� MDM锛�
+        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap(
                 convertSet(list, MesQcRqcLineDO::getUnitMeasureId));
         // 鎷艰 VO
         return BeanUtils.toBean(list, MesQcRqcLineRespVO.class, vo -> {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateIndicatorController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateIndicatorController.java
index 0d2e747..e80c78e 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateIndicatorController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateIndicatorController.java
@@ -7,12 +7,12 @@
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.indicator.MesQcTemplateIndicatorPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.indicator.MesQcTemplateIndicatorRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.indicator.MesQcTemplateIndicatorSaveReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateIndicatorDO;
-import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService;
 import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateIndicatorService;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
 import io.swagger.v3.oas.annotations.tags.Tag;
@@ -41,7 +41,7 @@
     @Resource
     private MesQcIndicatorService indicatorService;
     @Resource
-    private MesMdUnitMeasureService unitMeasureService;
+    private MdmUnitMeasureApi mdmUnitMeasureApi;
 
     @PostMapping("/create")
     @Operation(summary = "鍒涘缓璐ㄦ鏂规-妫�娴嬫寚鏍囬」")
@@ -95,7 +95,7 @@
         Map<Long, MesQcIndicatorDO> indicatorMap = indicatorService.getIndicatorMap(
                 convertSet(list, MesQcTemplateIndicatorDO::getIndicatorId));
         // 鎵归噺鏌ヨ璁¢噺鍗曚綅
-        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
+        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap(
                 convertSet(list, MesQcTemplateIndicatorDO::getUnitMeasureId));
         // 鎷艰 VO
         return BeanUtils.toBean(list, MesQcTemplateIndicatorRespVO.class, vo -> {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateItemController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateItemController.java
index cdd5397..edf33a9 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateItemController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/template/MesQcTemplateItemController.java
@@ -8,13 +8,13 @@
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.item.MesQcTemplateItemPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.item.MesQcTemplateItemRespVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.item.MesQcTemplateItemSaveReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO;
-import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
-import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
 import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
+import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
 import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -44,9 +44,9 @@
     @Resource
     private MesQcTemplateService templateService;
     @Resource
-    private MesMdmItemService mdmItemService;
+    private MdmItemApi mdmItemApi;
     @Resource
-    private MesMdUnitMeasureService unitMeasureService;
+    private MdmUnitMeasureApi mdmUnitMeasureApi;
 
     @PostMapping("/create")
     @Operation(summary = "鍒涘缓璐ㄦ鏂规-浜у搧鍏宠仈")
@@ -91,15 +91,12 @@
     }
 
     @GetMapping("/list-by-item-and-type")
-    @Operation(summary = "鏍规嵁鐗╂枡鎴栧伐鍗�/浠诲姟鍜屾娴嬬绫昏幏鍙栧彲鐢ㄨ川妫�鏂规")
+    @Operation(summary = "鏍规嵁鐗╂枡鍜屾娴嬬绫昏幏鍙栧彲鐢ㄨ川妫�鏂规")
     @PreAuthorize("@ss.hasPermission('mes:qc-template:query')")
     public CommonResult<List<MesQcTemplateItemOptionRespVO>> getTemplateItemOptionList(
             @RequestParam(value = "qcType", required = false) Integer qcType,
-            @RequestParam(value = "itemId", required = false) Long itemId,
-            @RequestParam(value = "workOrderId", required = false) Long workOrderId,
-            @RequestParam(value = "taskId", required = false) Long taskId) {
-        List<MesQcTemplateItemDO> list = templateItemService.getTemplateItemList(
-                itemId, qcType, workOrderId, taskId);
+            @RequestParam(value = "itemId", required = false) Long itemId) {
+        List<MesQcTemplateItemDO> list = templateItemService.getTemplateItemList(itemId, qcType);
         if (CollUtil.isEmpty(list)) {
             return success(Collections.emptyList());
         }
@@ -122,11 +119,11 @@
             return Collections.emptyList();
         }
         // 鎵归噺鏌ヨ鐗╂枡锛坕temId 瀛樼殑鏄� mdm_item_id锛屽叧鑱� mdm_item 琛級
-        Map<Long, MesMdmItemDO> itemMap = mdmItemService.getItemMap(
+        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
                 convertSet(list, MesQcTemplateItemDO::getItemId));
         // 鎵归噺鏌ヨ璁¢噺鍗曚綅
-        Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
-                convertSet(itemMap.values(), MesMdmItemDO::getUnitMeasureId));
+        Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap(
+                convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId));
         // 鎷艰 VO
         return BeanUtils.toBean(list, MesQcTemplateItemRespVO.class, vo -> {
             findAndThen(itemMap, vo.getItemId(), item -> {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/ipqc/MesQcIpqcDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/ipqc/MesQcIpqcDO.java
index 6382ec2..380c427 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/ipqc/MesQcIpqcDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/ipqc/MesQcIpqcDO.java
@@ -1,10 +1,7 @@
 package cn.iocoder.yudao.module.mes.dal.dataobject.qc.ipqc;
 
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateDO;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcSourceDocTypeEnum;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum;
@@ -85,40 +82,17 @@
      * 鏉ユ簮鍗曟嵁缂栧彿锛堝啑浣欙級
      */
     private String sourceDocCode;
-
-    // ========== 鐢熶骇鍏宠仈 ==========
-
     /**
-     * 鐢熶骇宸ュ崟 ID
-     *
-     * 鍏宠仈 {@link MesProWorkOrderDO#getId()}
+     * 鎵瑰彿
      */
-    private Long workOrderId;
-    /**
-     * 鐢熶骇浠诲姟 ID
-     *
-     * 鍏宠仈 {@link cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO#getId()}
-     */
-    private Long taskId;
-    /**
-     * 宸ヤ綅 ID
-     *
-     * 鍏宠仈 {@link MesMdWorkstationDO#getId()}
-     */
-    private Long workstationId;
-    /**
-     * 宸ュ簭 ID
-     *
-     * 鍏宠仈 {@link cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO#getId()}
-     */
-    private Long processId;
+    private String batchCode;
 
     // ========== 鐗╂枡 ==========
 
     /**
      * 浜у搧鐗╂枡 ID
      *
-     * 鍏宠仈 {@link MesMdItemDO#getId()}
+     * 鍏宠仈 MDM 鐗╂枡 {@link cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO#getId()}
      */
     private Long itemId;
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/ipqc/MesQcIpqcMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/ipqc/MesQcIpqcMapper.java
index 105c503..24185c1 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/ipqc/MesQcIpqcMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/ipqc/MesQcIpqcMapper.java
@@ -21,7 +21,7 @@
         return selectPage(reqVO, new LambdaQueryWrapperX<MesQcIpqcDO>()
                 .likeIfPresent(MesQcIpqcDO::getCode, reqVO.getCode())
                 .eqIfPresent(MesQcIpqcDO::getType, reqVO.getType())
-                .eqIfPresent(MesQcIpqcDO::getWorkOrderId, reqVO.getWorkOrderId())
+                .likeIfPresent(MesQcIpqcDO::getBatchCode, reqVO.getBatchCode())
                 .eqIfPresent(MesQcIpqcDO::getItemId, reqVO.getItemId())
                 .eqIfPresent(MesQcIpqcDO::getCheckResult, reqVO.getCheckResult())
                 .eqIfPresent(MesQcIpqcDO::getStatus, reqVO.getStatus())
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/oqc/MesQcOqcMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/oqc/MesQcOqcMapper.java
index 7c175d3..af252fd 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/oqc/MesQcOqcMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/oqc/MesQcOqcMapper.java
@@ -42,10 +42,13 @@
                 .betweenIfPresent(MesQcOqcDO::getInspectDate, reqVO.getInspectDate())
                 .orderByDesc(MesQcOqcDO::getId);
         if (permittedClientIds != null) {
+            // 鏈~瀹㈡埛鐨勫崟鎹笉灞炰簬浠讳綍瀹㈡埛锛屼笉鍙楀鎴锋潈闄愰伄鎸�
             if (CollUtil.isEmpty(permittedClientIds)) {
-                return PageResult.empty();
+                wrapper.isNull(MesQcOqcDO::getClientId);
+            } else {
+                wrapper.and(w -> w.isNull(MesQcOqcDO::getClientId)
+                        .or().in(MesQcOqcDO::getClientId, permittedClientIds));
             }
-            wrapper.in(MesQcOqcDO::getClientId, permittedClientIds);
         }
         return selectPage(reqVO, wrapper);
     }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
index d93fca2..c3f6f6c 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -408,6 +408,7 @@
     ErrorCode QC_IPQC_SOURCE_LINE_NOT_BELONG = new ErrorCode(1_040_604_009, "鏉ユ簮鍗曟嵁琛屼笉灞炰簬璇ユ姤宸ュ崟");
     ErrorCode QC_IPQC_SOURCE_LINE_REQUIRED = new ErrorCode(1_040_604_010, "鏉ユ簮鍗曟嵁绫诲瀷涓烘姤宸ユ椂锛屾潵婧愪骇鍑鸿 ID 涓嶈兘涓虹┖");
     ErrorCode QC_IPQC_SOURCE_LINE_NOT_PENDING = new ErrorCode(1_040_604_011, "鏉ユ簮浜у嚭琛屼笉鏄緟妫�楠岀姸鎬�");
+    ErrorCode QC_IPQC_BATCH_CODE_REQUIRED = new ErrorCode(1_040_604_012, "鎵瑰彿涓嶈兘涓虹┖");
     // ========== MES 璐ㄩ噺绠$悊-杩囩▼妫�楠岃锛�1-040-604-100锛� ==========
     ErrorCode QC_IPQC_LINE_NOT_EXISTS = new ErrorCode(1_040_604_100, "杩囩▼妫�楠岃涓嶅瓨鍦�");
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/ai/MesProAiServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/ai/MesProAiServiceImpl.java
index 208b2d9..d496f32 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/ai/MesProAiServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/ai/MesProAiServiceImpl.java
@@ -524,10 +524,14 @@
         data.put("宸茬敓浜ф暟閲�", workOrder.getQuantityProduced());
         fillItemInfo(data, workOrder.getProductId());
 
-        // 璐ㄩ噺椋庨櫓 - IPQC
-        List<MesQcIpqcDO> ipqcList = ipqcMapper.selectList(
-                new LambdaQueryWrapper<MesQcIpqcDO>()
-                        .eq(MesQcIpqcDO::getWorkOrderId, workOrderId));
+        // 璐ㄩ噺椋庨櫓 - IPQC锛堣繃绋嬫楠屽崟宸叉棤宸ュ崟瀛楁锛岀粡鏉ユ簮鎶ュ伐鍗曞弽鏌ユ湰宸ュ崟涓嬬殑妫�楠岃褰曪級
+        List<Long> feedbackIds = feedbackMapper.selectList(
+                new LambdaQueryWrapper<MesProFeedbackDO>()
+                        .eq(MesProFeedbackDO::getWorkOrderId, workOrderId))
+                .stream().map(MesProFeedbackDO::getId).collect(Collectors.toList());
+        List<MesQcIpqcDO> ipqcList = CollUtil.isEmpty(feedbackIds) ? Collections.emptyList()
+                : ipqcMapper.selectList(new LambdaQueryWrapper<MesQcIpqcDO>()
+                        .in(MesQcIpqcDO::getSourceDocId, feedbackIds));
         if (CollUtil.isNotEmpty(ipqcList)) {
             List<Map<String, Object>> qcData = ipqcList.stream().map(ipqc -> {
                 Map<String, Object> item = new LinkedHashMap<>();
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ai/MesQcAiServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ai/MesQcAiServiceImpl.java
index 2005d29..907a1ea 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ai/MesQcAiServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ai/MesQcAiServiceImpl.java
@@ -141,8 +141,7 @@
             data.put("妫�娴嬫暟閲�", ipqc.getCheckQuantity());
             data.put("鍚堟牸鏁伴噺", ipqc.getQualifiedQuantity());
             data.put("涓嶅悎鏍兼暟閲�", ipqc.getUnqualifiedQuantity());
-            data.put("宸ュ崟ID", ipqc.getWorkOrderId());
-            data.put("宸ュ簭ID", ipqc.getProcessId());
+            data.put("鎵瑰彿", ipqc.getBatchCode());
             fillItemInfo(data, ipqc.getItemId());
         } else if (MesBizTypeConstants.QC_OQC == qcType) {
             data.put("璐ㄦ绫诲瀷", "鍑鸿揣妫�楠�");
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java
index 6abef96..b609e4c 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java
@@ -3,16 +3,14 @@
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceLineDO;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcSaveReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.ipqc.MesQcIpqcDO;
@@ -21,15 +19,8 @@
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum;
-import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum;
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
-import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
 import cn.iocoder.yudao.module.mes.service.pro.feedback.MesProFeedbackService;
-import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
-import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductService;
-import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
-import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
 import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService;
 import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
 import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService;
@@ -62,14 +53,6 @@
 @Slf4j
 public class MesQcIpqcServiceImpl implements MesQcIpqcService {
 
-    /**
-     * IPQC 淇濆瓨鏁版嵁鏍¢獙涓婁笅鏂�
-     *
-     * @param workstation 宸ヤ綅
-     * @param task        鐢熶骇浠诲姟锛堝彲閫夛紝鎸囧畾 taskId 鏃堕潪绌猴級
-     */
-    private record SaveDataContext(MesMdWorkstationDO workstation, MesProTaskDO task) {}
-
     @Resource
     private MesQcIpqcMapper ipqcMapper;
 
@@ -79,25 +62,7 @@
     private MesQcIpqcLineService ipqcLineService;
     @Resource
     @Lazy
-    private MesProWorkOrderService workOrderService;
-    @Resource
-    @Lazy
-    private MesMdWorkstationService workstationService;
-    @Resource
-    @Lazy
-    private MesMdItemService itemService;
-    @Resource
-    @Lazy
     private MesQcDefectRecordService defectRecordService;
-    @Resource
-    @Lazy
-    private MesProRouteProductService routeProductService;
-    @Resource
-    @Lazy
-    private MesProRouteProcessService routeProcessService;
-    @Resource
-    @Lazy
-    private MesProTaskService taskService;
     @Resource
     @Lazy
     private MesProFeedbackService feedbackService;
@@ -113,20 +78,21 @@
     private MesQcNcrService ncrService;
 
     @Resource
+    private MdmItemApi mdmItemApi;
+
+    @Resource
     private AdminUserApi adminUserApi;
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long createIpqc(MesQcIpqcSaveReqVO createReqVO) {
         // 1.1 鏍¢獙鏁版嵁
-        SaveDataContext ctx = validateIpqcSaveData(createReqVO);
-        // 1.2 鏍¢獙宸ュ崟瀛樺湪
-        MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderExists(createReqVO.getWorkOrderId());
-        // 1.3 纭畾妫�楠岀墿鏂欙細鏈変换鍔℃椂鍙栦换鍔$殑鐗╂枡锛屾棤浠诲姟鏃跺彇宸ュ崟鐨勪骇鍝�
-        Long itemId = (ctx.task() != null) ? ctx.task().getItemId() : workOrder.getProductId();
-        // 1.4 鏍规嵁鐗╂枡 + IPQC 绫诲瀷鏌ユ壘鍙敤璐ㄦ鏂规锛堟敮鎸佸墠绔樉寮忔寚瀹氾級
+        validateIpqcSaveData(createReqVO);
+        // 1.2 浜у搧鐗╂枡鐢卞墠绔寚瀹氾紙MDM 鐗╂枡锛夛紝鏍¢獙鍏跺瓨鍦�
+        Long itemId = createReqVO.getItemId();
+        // 1.3 鏍规嵁鐗╂枡 + IPQC 绫诲瀷鏌ユ壘鍙敤璐ㄦ鏂规锛堟敮鎸佸墠绔樉寮忔寚瀹氾級
         List<MesQcTemplateItemDO> templateItems = templateItemService.getTemplateItemList(
-                itemId, MesQcTypeEnum.IPQC.getType(), null, null);
+                itemId, MesQcTypeEnum.IPQC.getType());
         if (CollUtil.isEmpty(templateItems)) {
             throw exception(QC_NO_TEMPLATE);
         }
@@ -147,7 +113,6 @@
         // 2. 鎻掑叆涓昏〃
         MesQcIpqcDO ipqc = BeanUtils.toBean(createReqVO, MesQcIpqcDO.class)
                 .setItemId(itemId)
-                .setProcessId(getProcessId(itemId, ctx.workstation().getProcessId()))
                 .setTemplateId(templateId)
                 .setSourceDocCode(sourceDocCode)
                 .setStatus(MesQcStatusEnum.DRAFT.getStatus());
@@ -163,60 +128,27 @@
         // 1.1 鏍¢獙瀛樺湪 + 鑽夌鐘舵��
         validateIpqcStatusPrepare(updateReqVO.getId());
         // 1.2 鏍¢獙鏁版嵁
-        SaveDataContext ctx = validateIpqcSaveData(updateReqVO);
+        validateIpqcSaveData(updateReqVO);
 
         // 2. 鏇存柊涓昏〃
-        MesQcIpqcDO existIpqc = validateIpqcExists(updateReqVO.getId());
         MesQcIpqcDO updateObj = BeanUtils.toBean(updateReqVO, MesQcIpqcDO.class);
         updateObj.setSourceDocType(null).setSourceDocId(null).setSourceLineId(null); // 涓嶅厑璁镐慨鏀规潵婧愬崟鎹�
         updateObj.setTemplateId(null); // 涓嶅厑璁镐慨鏀规ā鏉�
         updateObj.setItemId(null); // 涓嶅厑璁镐慨鏀圭墿鏂�
-        updateObj.setWorkOrderId(null); // 涓嶅厑璁镐慨鏀瑰伐鍗�
-        updateObj.setProcessId(getProcessId(existIpqc.getItemId(), ctx.workstation().getProcessId()));
         ipqcMapper.updateById(updateObj);
     }
 
-    private SaveDataContext validateIpqcSaveData(MesQcIpqcSaveReqVO reqVO) {
+    private void validateIpqcSaveData(MesQcIpqcSaveReqVO reqVO) {
         // 鏍¢獙缂栧彿鍞竴
         validateIpqcCodeUnique(reqVO.getId(), reqVO.getCode());
-        // 鏍¢獙宸ヤ綅銆佹娴嬩汉鍛樺瓨鍦�
-        MesMdWorkstationDO workstation = workstationService.validateWorkstationExists(reqVO.getWorkstationId());
+        // 鏍¢獙鎵瑰彿闈炵┖锛圴O 灞傚凡鏍¢獙锛屾澶勫厹搴曞唴閮�/RPC 璋冪敤缁曡繃鏍¢獙鐨勬儏鍐碉級
+        if (StrUtil.isBlank(reqVO.getBatchCode())) {
+            throw exception(QC_IPQC_BATCH_CODE_REQUIRED);
+        }
+        // 鏍¢獙浜у搧鐗╂枡瀛樺湪锛堢墿鏂� ID 鏉ヨ嚜 MDM锛�
+        mdmItemApi.validateItemExists(reqVO.getItemId());
+        // 鏍¢獙妫�娴嬩汉鍛樺瓨鍦�
         adminUserApi.validateUser(reqVO.getInspectorUserId());
-        // 鏍¢獙宸ュ崟瀛樺湪
-        MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId());
-        if (reqVO.getProcessId() != null && ObjUtil.notEqual(workstation.getProcessId(), reqVO.getProcessId())) {
-            throw exception(PRO_WORKSTATION_PROCESS_MISMATCH);
-        }
-        // 鏍¢獙浠诲姟鍏崇郴锛堝鏋滄寚瀹氫簡浠诲姟锛�
-        MesProTaskDO task = null;
-        if (reqVO.getTaskId() != null) {
-            task = taskService.validateTaskNotFinished(reqVO.getTaskId());
-            validateTaskRelation(task, workstation, workOrder, reqVO);
-        } else {
-            // 鏃犱换鍔℃椂锛宨temId 浠嶉渶涓庡伐鍗曚骇鍝佷竴鑷�
-            if (reqVO.getItemId() != null && ObjUtil.notEqual(reqVO.getItemId(), workOrder.getProductId())) {
-                throw exception(PRO_WORK_ORDER_PRODUCT_MISMATCH);
-            }
-        }
-        return new SaveDataContext(workstation, task);
-    }
-
-    private void validateTaskRelation(MesProTaskDO task, MesMdWorkstationDO workstation,
-                                      MesProWorkOrderDO workOrder, MesQcIpqcSaveReqVO reqVO) {
-        if (ObjUtil.notEqual(task.getWorkOrderId(), workOrder.getId())) {
-            throw exception(PRO_TASK_WORK_ORDER_MISMATCH);
-        }
-        if (ObjUtil.notEqual(task.getWorkstationId(), workstation.getId())) {
-            throw exception(PRO_TASK_WORKSTATION_MISMATCH);
-        }
-        Long expectedProcessId = reqVO.getProcessId() != null ? reqVO.getProcessId() : workstation.getProcessId();
-        if (expectedProcessId != null && ObjUtil.notEqual(task.getProcessId(), expectedProcessId)) {
-            throw exception(PRO_TASK_ROUTE_PROCESS_MISMATCH);
-        }
-        // 鏍¢獙妫�楠岀墿鏂欎笌浠诲姟鐗╂枡涓�鑷达紙鏈変换鍔℃椂锛孖PQC 妫�楠岀殑鐗╂枡搴斾笌浠诲姟鍔犲伐鐨勭墿鏂欎竴鑷达級
-        if (reqVO.getItemId() != null && ObjUtil.notEqual(reqVO.getItemId(), task.getItemId())) {
-            throw exception(PRO_TASK_ITEM_MISMATCH);
-        }
     }
 
     @Override
@@ -277,18 +209,6 @@
         // 1. 纭畾 sourceDocType/sourceDocId
         Long sourceDocId = ipqc.getSourceDocId();
         Long sourceLineId = ipqc.getSourceLineId();
-
-        // 濡傛灉 IPQC 鍗曟病鏈夎缃潵婧愶紝灏濊瘯閫氳繃 taskId 鏌ユ壘鍏宠仈鐨勫緟妫�楠屾姤宸�
-        if (sourceDocId == null && ipqc.getTaskId() != null) {
-            MesProFeedbackDO feedback = feedbackService.getFeedbackListByTaskId(ipqc.getTaskId()).stream()
-                    .filter(f -> MesProFeedbackStatusEnum.UNCHECK.getStatus().equals(f.getStatus()))
-                    .findFirst().orElse(null);
-            if (feedback != null) {
-                sourceDocId = feedback.getId();
-                log.info("[writeBackSourceDoc] IPQC({}) 鏈缃潵婧愬崟鎹紝閫氳繃 taskId({}) 鎵惧埌寰呮楠屾姤宸�({})",
-                        ipqc.getId(), ipqc.getTaskId(), feedback.getId());
-            }
-        }
 
         if (sourceDocId == null) {
             log.warn("[writeBackSourceDoc] IPQC({}) 鏃犳硶纭畾鏉ユ簮鎶ュ伐锛岃烦杩囧洖鍐�", ipqc.getId());
@@ -375,33 +295,6 @@
         }
         // 鏈煡鏉ユ簮绫诲瀷搴旀姤閿欙紝鑰屼笉鏄潤榛樺拷鐣�
         throw exception(QC_IPQC_SOURCE_DOC_TYPE_UNKNOWN);
-    }
-
-    /**
-     * 鎺ㄥ宸ュ簭 ID
-     *
-     * <p>閫氳繃浜у搧 鈫� 宸ヨ壓璺嚎浜у搧 鈫� 宸ヨ壓璺嚎 鈫� 鏍¢獙宸ヤ綅宸ュ簭鏄惁鍦ㄨ璺嚎涓�
-     * <p>濡傛灉宸ヤ綅鐨勫伐搴忓湪璺嚎涓紝鍒欒繑鍥炶 processId锛涘惁鍒欒繑鍥� null
-     *
-     * @param productId 浜у搧 ID锛堝伐鍗曚骇鍝侊級
-     * @param workstationProcessId 宸ヤ綅鍏宠仈鐨勫伐搴� ID
-     * @return 鎺ㄥ鍑虹殑宸ュ簭 ID锛屾棤娉曟帹瀵兼椂杩斿洖 null
-     */
-    private Long getProcessId(Long productId, Long workstationProcessId) {
-        if (productId == null || workstationProcessId == null) {
-            return null;
-        }
-        // 1. 浜у搧 鈫� 宸ヨ壓璺嚎
-        MesProRouteProductDO routeProduct = routeProductService.getRouteProductByItemId(productId);
-        if (routeProduct == null) {
-            return null;
-        }
-        // 2. 鏍¢獙宸ヤ綅鐨勫伐搴忔槸鍚﹀湪璇ヨ矾绾夸腑
-        if (routeProcessService.getRouteProcessByRouteIdAndProcessId(
-                routeProduct.getRouteId(), workstationProcessId) == null) {
-            return null;
-        }
-        return workstationProcessId;
     }
 
     @Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java
index 975ddc0..1714b66 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java
@@ -16,7 +16,6 @@
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
 import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService;
 import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
 import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService;
@@ -68,8 +67,6 @@
     @Resource
     private SrmSupplierApi srmSupplierApi;
     @Resource
-    private MesMdItemService itemService;
-    @Resource
     @Lazy
     private MesQcIndicatorResultService indicatorResultService;
 
@@ -93,7 +90,7 @@
                 createReqVO.getSourceDocType(), createReqVO.getSourceDocId(), createReqVO.getSourceLineId());
         // 1.3 鏍规嵁浜у搧 + IQC 绫诲瀷鏌ユ壘鍙敤璐ㄦ鏂规锛堟敮鎸佸墠绔樉寮忔寚瀹氾級
         List<MesQcTemplateItemDO> templateItems = templateItemService.getTemplateItemList(
-                createReqVO.getItemId(), MesQcTypeEnum.IQC.getType(), null, null);
+                createReqVO.getItemId(), MesQcTypeEnum.IQC.getType());
         if (CollUtil.isEmpty(templateItems)) {
             throw exception(QC_NO_TEMPLATE);
         }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java
index 30bf336..e50b21e 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java
@@ -91,7 +91,7 @@
                 createReqVO.getSourceDocType(), createReqVO.getSourceLineId());
         // 1.3 鏍规嵁浜у搧 + OQC 绫诲瀷鏌ユ壘鍙敤璐ㄦ鏂规锛堟敮鎸佸墠绔樉寮忔寚瀹氾級
         List<MesQcTemplateItemDO> templateItems = templateItemService.getTemplateItemList(
-                createReqVO.getItemId(), MesQcTypeEnum.OQC.getType(), null, null);
+                createReqVO.getItemId(), MesQcTypeEnum.OQC.getType());
         if (CollUtil.isEmpty(templateItems)) {
             throw exception(QC_NO_TEMPLATE);
         }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImpl.java
index 86d79a9..072f660 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImpl.java
@@ -14,7 +14,7 @@
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum;
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
 import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService;
 import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
 import cn.iocoder.yudao.module.mes.service.wm.returnissue.MesWmReturnIssueService;
@@ -58,7 +58,7 @@
     private MesQcRqcLineService rqcLineService;
     @Resource
     @Lazy
-    private MesMdItemService itemService;
+    private MdmItemApi mdmItemApi;
     @Resource
     @Lazy
     private MesQcDefectRecordService defectRecordService;
@@ -92,7 +92,7 @@
         validateRqcSaveData(createReqVO);
         // 1.2 鏍规嵁鐗╂枡 + RQC 妫�娴嬬绫绘煡鎵惧彲鐢ㄨ川妫�鏂规锛堟敮鎸佸墠绔樉寮忔寚瀹氾級
         List<MesQcTemplateItemDO> templateItems = templateItemService.getTemplateItemList(
-                createReqVO.getItemId(), MesQcTypeEnum.RQC.getType(), null, null);
+                createReqVO.getItemId(), MesQcTypeEnum.RQC.getType());
         if (CollUtil.isEmpty(templateItems)) {
             throw exception(QC_NO_TEMPLATE);
         }
@@ -140,8 +140,8 @@
     private void validateRqcSaveData(MesQcRqcSaveReqVO reqVO) {
         // 鏍¢獙缂栧彿鍞竴
         validateRqcCodeUnique(reqVO.getId(), reqVO.getCode());
-        // 鏍¢獙鐗╂枡銆佹娴嬩汉鍛樺瓨鍦�
-        itemService.validateItemExists(reqVO.getItemId());
+        // 鏍¢獙鐗╂枡锛堢墿鏂� ID 鏉ヨ嚜 MDM锛夈�佹娴嬩汉鍛樺瓨鍦�
+        mdmItemApi.validateItemExists(reqVO.getItemId());
         adminUserApi.validateUser(reqVO.getInspectorUserId());
     }
 
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemService.java
index 4a6ab79..0674720 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemService.java
@@ -71,14 +71,12 @@
     MesQcTemplateItemDO getRequiredTemplateByItemIdAndType(Long itemId, Integer qcType);
 
     /**
-     * 鏍规嵁浜у搧鐗╂枡锛堟垨宸ュ崟/浠诲姟锛夊拰 QC 绫诲瀷锛岃幏鍙栨墍鏈夊彲鐢ㄧ殑璐ㄦ鏂规浜у搧鍏宠仈鍒楄〃
+     * 鏍规嵁浜у搧鐗╂枡鍜� QC 绫诲瀷锛岃幏鍙栨墍鏈夊彲鐢ㄧ殑璐ㄦ鏂规浜у搧鍏宠仈鍒楄〃
      *
-     * @param itemId      浜у搧鐗╂枡 ID锛坢es_md_item.id锛夛紱涓� workOrderId/taskId 鑷冲皯鍏朵竴
-     * @param qcType      妫�娴嬬绫伙紙鏋氫妇 {@link MesQcTypeEnum}锛�
-     * @param workOrderId 鐢熶骇宸ュ崟 ID锛堝彲閫夛紝IPQC 鍦烘櫙鐢ㄤ簬瑙f瀽浜у搧鐗╂枡锛�
-     * @param taskId      鐢熶骇浠诲姟 ID锛堝彲閫夛紝浼樺厛鐢ㄤ簬瑙f瀽浜у搧鐗╂枡锛�
+     * @param itemId 浜у搧鐗╂枡 ID锛圡DM 鐗╂枡 ID锛屽嵆 mdm_item.id锛�
+     * @param qcType 妫�娴嬬绫伙紙鏋氫妇 {@link MesQcTypeEnum}锛�
      * @return 鍖归厤鐨勪骇鍝佸叧鑱斿垪琛紙淇濇寔鍘熼『搴忥級锛屾棤鍖归厤杩斿洖绌哄垪琛�
      */
-    List<MesQcTemplateItemDO> getTemplateItemList(Long itemId, Integer qcType, Long workOrderId, Long taskId);
+    List<MesQcTemplateItemDO> getTemplateItemList(Long itemId, Integer qcType);
 
 }
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemServiceImpl.java
index 712c693..7a3d219 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/template/MesQcTemplateItemServiceImpl.java
@@ -7,13 +7,9 @@
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.item.MesQcTemplateItemPageReqVO;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.template.vo.item.MesQcTemplateItemSaveReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO;
 import cn.iocoder.yudao.module.mes.dal.mysql.qc.template.MesQcTemplateItemMapper;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
-import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
-import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
 import jakarta.annotation.Resource;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
@@ -45,14 +41,6 @@
     @Resource
     @Lazy
     private MesQcTemplateService templateService;
-    @Resource
-    private MesMdItemService mesMdItemService;
-    @Resource
-    @Lazy
-    private MesProTaskService proTaskService;
-    @Resource
-    @Lazy
-    private MesProWorkOrderService proWorkOrderService;
 
     @Override
     public Long createTemplateItem(MesQcTemplateItemSaveReqVO createReqVO) {
@@ -127,7 +115,7 @@
 
     @Override
     public MesQcTemplateItemDO getRequiredTemplateByItemIdAndType(Long itemId, Integer qcType) {
-        List<MesQcTemplateItemDO> templateItems = getTemplateItemList(itemId, qcType, null, null);
+        List<MesQcTemplateItemDO> templateItems = getTemplateItemList(itemId, qcType);
         if (CollUtil.isEmpty(templateItems)) {
             throw exception(QC_NO_TEMPLATE);
         }
@@ -135,28 +123,16 @@
     }
 
     @Override
-    public List<MesQcTemplateItemDO> getTemplateItemList(Long itemId, Integer qcType, Long workOrderId, Long taskId) {
-        // 1. 瑙f瀽鐪熷疄浜у搧鐗╂枡 ID锛氫换鍔′紭鍏堬紝鍏舵宸ュ崟锛屾渶鍚庣洿鎺ョ敤鍏ュ弬
-        Long resolvedItemId = itemId;
-        if (taskId != null) {
-            resolvedItemId = proTaskService.validateTaskExists(taskId).getItemId();
-        } else if (workOrderId != null) {
-            resolvedItemId = proWorkOrderService.validateWorkOrderExists(workOrderId).getProductId();
-        }
-        if (resolvedItemId == null) {
+    public List<MesQcTemplateItemDO> getTemplateItemList(Long itemId, Integer qcType) {
+        // 1. 浜у搧鍏宠仈琛� item_id 瀛樼殑鏄� MDM 鐗╂枡 ID锛坢dm_item.id锛夛紝璐ㄦ渚х粺涓�鎸� MDM 鐗╂枡鏌ヨ
+        if (itemId == null) {
             return Collections.emptyList();
         }
-        // 2. mes_md_item.id 杞� mdm_item.id锛堜骇鍝佸叧鑱旇〃瀛樼殑鏄� mdm 鐗╂枡锛�
-        MesMdItemDO item = mesMdItemService.getItem(resolvedItemId);
-        if (item == null || item.getMdmItemId() == null) {
-            return Collections.emptyList();
-        }
-        // 3. 鏌ュ嚭璇ョ墿鏂欏叧鑱旂殑鎵�鏈変骇鍝佸叧鑱�
-        List<MesQcTemplateItemDO> templateItems = templateItemMapper.selectListByItemId(item.getMdmItemId());
+        List<MesQcTemplateItemDO> templateItems = templateItemMapper.selectListByItemId(itemId);
         if (CollUtil.isEmpty(templateItems)) {
             return Collections.emptyList();
         }
-        // 4. 杩囨护锛氭柟妗堝惎鐢ㄤ笖妫�娴嬬绫诲寘鍚� qcType锛岃繑鍥炲叏閮ㄥ尮閰嶉」
+        // 2. 杩囨护锛氭柟妗堝惎鐢ㄤ笖妫�娴嬬绫诲寘鍚� qcType锛岃繑鍥炲叏閮ㄥ尮閰嶉」
         List<MesQcTemplateDO> templates = templateService.getTemplateList(
                 convertSet(templateItems, MesQcTemplateItemDO::getTemplateId));
         Set<Long> matchedTemplateIds = templates.stream()
diff --git a/yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml b/yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml
index ab88c74..8f28e73 100644
--- a/yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml
+++ b/yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml
@@ -18,6 +18,7 @@
                 n.id AS sourceDocId,
                 ${@cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants@WM_ARRIVAL_NOTICE} AS sourceDocType,
                 n.code AS sourceDocCode,
+                NULL AS batchCode,
                 l.id AS sourceLineId,
                 n.arrival_date AS recordTime,
                 ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IQC.type} AS qcType,
@@ -43,6 +44,7 @@
                 r.id AS sourceDocId,
                 ${@cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants@WM_OUTSOURCE_RECPT} AS sourceDocType,
                 r.code AS sourceDocCode,
+                NULL AS batchCode,
                 rl.id AS sourceLineId,
                 r.receipt_date AS recordTime,
                 ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IQC.type} AS qcType,
@@ -68,6 +70,7 @@
                 pf.id AS sourceDocId,
                 ${@cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants@PRO_FEEDBACK} AS sourceDocType,
                 pf.code AS sourceDocCode,
+                ppl.batch_code AS batchCode,
                 ppl.id AS sourceLineId,
                 pf.feedback_time AS recordTime,
                 ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IPQC.type} AS qcType,
@@ -93,6 +96,7 @@
                 s.id AS sourceDocId,
                 ${@cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants@WM_PRODUCT_SALES} AS sourceDocType,
                 s.code AS sourceDocCode,
+                sl.batch_code AS batchCode,
                 sl.id AS sourceLineId,
                 s.sales_date AS recordTime,
                 ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@OQC.type} AS qcType,
@@ -118,6 +122,7 @@
                 ri.id AS sourceDocId,
                 ${@cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants@WM_RETURN_ISSUE} AS sourceDocType,
                 ri.code AS sourceDocCode,
+                ril.batch_code AS batchCode,
                 ril.id AS sourceLineId,
                 ri.return_date AS recordTime,
                 ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@RQC.type} AS qcType,
@@ -144,6 +149,7 @@
                 r.id AS sourceDocId,
                 ${@cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants@WM_RETURN_SALES} AS sourceDocType,
                 r.code AS sourceDocCode,
+                rl.batch_code AS batchCode,
                 rl.id AS sourceLineId,
                 r.return_date AS recordTime,
                 ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@RQC.type} AS qcType,
diff --git a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImplTest.java b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImplTest.java
index 7207edb..26c638d 100644
--- a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImplTest.java
+++ b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImplTest.java
@@ -2,13 +2,9 @@
 
 import cn.iocoder.yudao.framework.common.exception.ServiceException;
 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
 import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcSaveReqVO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.ipqc.MesQcIpqcDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO;
 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceLineDO;
@@ -16,15 +12,10 @@
 import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
 import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum;
 import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
-import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
-import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
 import cn.iocoder.yudao.module.mes.service.pro.feedback.MesProFeedbackService;
-import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
-import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductService;
-import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
-import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
 import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService;
 import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService;
+import cn.iocoder.yudao.module.mes.service.qc.ncr.MesQcNcrService;
 import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService;
 import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
@@ -34,6 +25,7 @@
 import org.springframework.test.context.bean.override.mockito.MockitoBean;
 
 import java.math.BigDecimal;
+import java.util.List;
 
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
@@ -60,11 +52,7 @@
     @MockitoBean
     private MesQcIpqcLineService ipqcLineService;
     @MockitoBean
-    private MesProWorkOrderService workOrderService;
-    @MockitoBean
-    private MesMdWorkstationService workstationService;
-    @MockitoBean
-    private MesMdItemService itemService;
+    private MdmItemApi mdmItemApi;
     @MockitoBean
     private MesQcDefectRecordService defectRecordService;
     @MockitoBean
@@ -72,15 +60,11 @@
     @MockitoBean
     private MesProFeedbackService feedbackService;
     @MockitoBean
-    private MesProRouteProductService routeProductService;
-    @MockitoBean
-    private MesProRouteProcessService routeProcessService;
-    @MockitoBean
-    private MesProTaskService taskService;
-    @MockitoBean
     private MesQcIndicatorResultService indicatorResultService;
     @MockitoBean
     private MesWmProductProduceLineService productProduceLineService;
+    @MockitoBean
+    private MesQcNcrService ncrService;
 
     @Test
     public void testFinishIpqc_writeBack_feedback() {
@@ -185,34 +169,46 @@
 
     @Test
     public void testFinishIpqc_writeBack_sourceDocTypeDirtyData() {
-        // 鍑嗗鏁版嵁锛歴ourceDocType 闈炵┖浣� sourceDocId 涓虹┖锛屽簲璇ユ姏寮傚父
+        // 鍑嗗鏁版嵁锛歴ourceDocType 闈炵┖浣� sourceDocId 涓虹┖锛岃烦杩囧洖鍐�
         MesQcIpqcDO ipqc = randomPojo(MesQcIpqcDO.class, o -> {
             o.setStatus(MesQcStatusEnum.DRAFT.getStatus());
             o.setCheckResult(1);
             o.setSourceDocType(MesBizTypeConstants.PRO_FEEDBACK);
             o.setSourceDocId(null); // 鑴忔暟鎹�
             o.setSourceLineId(null);
+            o.setUnqualifiedQuantity(BigDecimal.ZERO);
         });
         ipqcMapper.insert(ipqc);
 
-        // 璋冪敤锛屽苟鏂█寮傚父
-        assertThrows(IllegalArgumentException.class, () -> ipqcService.finishIpqc(ipqc.getId()));
+        // 璋冪敤锛氫笉鎶涘紓甯革紝浠呰烦杩囧洖鍐�
+        ipqcService.finishIpqc(ipqc.getId());
+
+        MesQcIpqcDO updatedIpqc = ipqcMapper.selectById(ipqc.getId());
+        assertEquals(MesQcStatusEnum.FINISHED.getStatus(), updatedIpqc.getStatus());
+        verify(feedbackService, never()).updateProFeedbackWhenIpqcFinish(
+                anyLong(), anyLong(), any(), any(), any(), any(), any());
     }
 
     @Test
     public void testFinishIpqc_writeBack_unknownSourceDocType() {
-        // 鍑嗗鏁版嵁锛歴ourceDocType 鏃犳硶璇嗗埆
+        // 鍑嗗鏁版嵁锛歴ourceDocType 鏃犳硶璇嗗埆锛屽洖鍐欓樁娈典笉鏍¢獙绫诲瀷锛堜粎鎸� sourceDocId 鍥炲啓鎶ュ伐锛�
         MesQcIpqcDO ipqc = randomPojo(MesQcIpqcDO.class, o -> {
             o.setStatus(MesQcStatusEnum.DRAFT.getStatus());
             o.setCheckResult(1);
             o.setSourceDocType(99999); // 鏃犳硶璇嗗埆鐨勭被鍨�
             o.setSourceDocId(randomLongId());
-            o.setSourceLineId(null);
+            o.setSourceLineId(randomLongId());
+            o.setUnqualifiedQuantity(BigDecimal.ZERO);
         });
         ipqcMapper.insert(ipqc);
 
-        // 璋冪敤锛屽苟鏂█寮傚父
-        assertThrows(IllegalArgumentException.class, () -> ipqcService.finishIpqc(ipqc.getId()));
+        // 璋冪敤锛氭寜 sourceDocId 鍥炲啓鎶ュ伐
+        ipqcService.finishIpqc(ipqc.getId());
+
+        MesQcIpqcDO updatedIpqc = ipqcMapper.selectById(ipqc.getId());
+        assertEquals(MesQcStatusEnum.FINISHED.getStatus(), updatedIpqc.getStatus());
+        verify(feedbackService).updateProFeedbackWhenIpqcFinish(
+                anyLong(), anyLong(), any(), any(), any(), any(), any());
     }
 
     @Test
@@ -242,159 +238,82 @@
         assertThrows(Exception.class, () -> ipqcService.finishIpqc(ipqc.getId()));
     }
 
-    // ==================== processId 鎺ㄥ琛屼负娴嬭瘯 ====================
+    // ==================== 鎵瑰彿蹇呭~鏍¢獙 ====================
 
     /**
-     * 宸ヤ綅鏈夊伐搴� + 璇ュ伐搴忓湪浜у搧宸ヨ壓璺嚎涓� 鈫� processId 搴旇琚缃负宸ヤ綅宸ュ簭
+     * 鎵瑰彿涓� null 鈫� 鍒涘缓澶辫触
      */
     @Test
-    public void testCreateIpqc_processId_workstationHasProcess() {
-        // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
-        Long processId = randomLongId();
-        Long routeId = randomLongId();
-        Long templateId = randomLongId();
-
+    public void testCreateIpqc_batchCode_null() {
         MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-TEST-001");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
+        reqVO.setCode("IPQC-BC-001");
+        reqVO.setBatchCode(null);
+        reqVO.setItemId(randomLongId());
         reqVO.setInspectorUserId(randomLongId());
 
-        // mock 宸ヤ綅杩斿洖鏈夊伐搴�
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(processId);
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        // mock 宸ュ崟
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        // mock 妯℃澘鍖归厤
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
-        // mock 宸ヨ壓璺嚎
-        MesProRouteProductDO routeProduct = new MesProRouteProductDO();
-        routeProduct.setRouteId(routeId);
-        when(routeProductService.getRouteProductByItemId(productId)).thenReturn(routeProduct);
-        // mock 宸ュ簭鍦ㄨ矾绾夸腑
-        when(routeProcessService.getRouteProcessByRouteIdAndProcessId(routeId, processId))
-                .thenReturn(new MesProRouteProcessDO());
-
-        // 璋冪敤
-        Long ipqcId = ipqcService.createIpqc(reqVO);
-
-        // 鏂█锛歱rocessId 搴旇鏄伐浣嶅伐搴�
-        MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
-        assertEquals(processId, ipqc.getProcessId());
+        ServiceException ex = assertThrows(ServiceException.class, () -> ipqcService.createIpqc(reqVO));
+        assertEquals(QC_IPQC_BATCH_CODE_REQUIRED.getCode(), ex.getCode());
     }
 
     /**
-     * 宸ヤ綅娌℃湁宸ュ簭锛坧rocessId=null锛夆啋 processId 搴旇鐣� null锛堜笉鍥為��鍒颁换鍔″伐搴忥級
+     * 鎵瑰彿涓虹┖鐧戒覆 鈫� 鍒涘缓澶辫触锛堝厹搴曞唴閮�/RPC 璋冪敤缁曡繃 VO 鏍¢獙鐨勬儏鍐碉級
      */
     @Test
-    public void testCreateIpqc_processId_workstationNoProcess_shouldBeNull() {
-        // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
-        Long taskId = randomLongId();
-        Long templateId = randomLongId();
-
+    public void testCreateIpqc_batchCode_blank() {
         MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-TEST-002");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
-        reqVO.setTaskId(taskId); // 鏁呮剰浼犲叆 taskId锛岄獙璇佷笉浼氬洖閫�
+        reqVO.setCode("IPQC-BC-002");
+        reqVO.setBatchCode("  ");
+        reqVO.setItemId(randomLongId());
         reqVO.setInspectorUserId(randomLongId());
 
-        // mock 宸ヤ綅娌℃湁宸ュ簭
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(null); // 鏃犲伐搴�
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        // mock 宸ュ崟
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        // mock 浠诲姟
-        MesProTaskDO task = new MesProTaskDO();
-        task.setId(taskId);
-        task.setWorkOrderId(workOrderId);
-        task.setWorkstationId(workstationId);
-        task.setItemId(productId);
-        when(taskService.validateTaskNotFinished(taskId)).thenReturn(task);
-        // mock 妯℃澘鍖归厤
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
+        ServiceException ex = assertThrows(ServiceException.class, () -> ipqcService.createIpqc(reqVO));
+        assertEquals(QC_IPQC_BATCH_CODE_REQUIRED.getCode(), ex.getCode());
+    }
+
+    // ==================== 鍒涘缓鎴愬姛锛氭壒鍙� / 鐗╂枡钀藉簱 ====================
+
+    @Test
+    public void testCreateIpqc_success() {
+        // 鍑嗗鍙傛暟
+        Long itemId = randomLongId();
+        Long templateId = randomLongId();
+        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
+        reqVO.setCode("IPQC-OK-001");
+        reqVO.setName("娴嬭瘯杩囩▼妫�楠�");
+        reqVO.setBatchCode("BC-2025-001");
+        reqVO.setItemId(itemId);
+        reqVO.setInspectorUserId(randomLongId());
+        mockTemplate(itemId, templateId);
 
         // 璋冪敤
         Long ipqcId = ipqcService.createIpqc(reqVO);
 
-        // 鏂█锛歱rocessId 搴旇鏄� null锛屽嵆浣夸紶鍏ヤ簡 taskId 涔熶笉搴旇鍥為��
+        // 鏂█锛氭壒鍙蜂笌鐗╂枡钀藉簱锛屾ā鏉挎寜鐗╂枡+IPQC 绫诲瀷鍖归厤
         MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
-        assertNull(ipqc.getProcessId(),
-                "宸ヤ綅鏃犲伐搴忔椂 processId 搴斾负 null锛屼笉搴斿洖閫�鍒颁换鍔″伐搴�");
-        // 鏂█锛氫笉搴旇璇诲彇浠诲姟鐨� processId
-        verify(routeProductService, never()).getRouteProductByItemId(any());
+        assertNotNull(ipqc);
+        assertEquals("BC-2025-001", ipqc.getBatchCode());
+        assertEquals(itemId, ipqc.getItemId());
+        assertEquals(templateId, ipqc.getTemplateId());
+        verify(mdmItemApi).validateItemExists(itemId);
     }
 
     /**
-     * 宸ヤ綅鏈夊伐搴忎絾璇ュ伐搴忎笉鍦ㄤ骇鍝佸伐鑹鸿矾绾夸腑 鈫� processId 搴旇鐣� null
+     * 浼犲叆浜嗕笉鍦ㄥ尮閰嶅垪琛ㄤ腑鐨� templateId 鈫� 鎷掔粷鍒涘缓
      */
     @Test
-    public void testCreateIpqc_processId_processNotInRoute() {
-        // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
-        Long processId = randomLongId();
-        Long routeId = randomLongId();
-        Long templateId = randomLongId();
-
+    public void testCreateIpqc_templateId_notMatched() {
+        Long itemId = randomLongId();
         MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-TEST-003");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
+        reqVO.setCode("IPQC-TPL-001");
+        reqVO.setName("鎸囧畾鏂规涓嶅尮閰�");
+        reqVO.setBatchCode("BC-2025-002");
+        reqVO.setItemId(itemId);
         reqVO.setInspectorUserId(randomLongId());
+        reqVO.setTemplateId(randomLongId()); // 涓庡尮閰嶇粨鏋滀笉涓�鑷�
+        mockTemplate(itemId, randomLongId());
 
-        // mock 宸ヤ綅鏈夊伐搴�
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(processId);
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        // mock 宸ュ崟
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        // mock 妯℃澘鍖归厤
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
-        // mock 宸ヨ壓璺嚎瀛樺湪
-        MesProRouteProductDO routeProduct = new MesProRouteProductDO();
-        routeProduct.setRouteId(routeId);
-        when(routeProductService.getRouteProductByItemId(productId)).thenReturn(routeProduct);
-        // mock 宸ュ簭涓嶅湪璺嚎涓�
-        when(routeProcessService.getRouteProcessByRouteIdAndProcessId(routeId, processId))
-                .thenReturn(null);
-
-        // 璋冪敤
-        Long ipqcId = ipqcService.createIpqc(reqVO);
-
-        // 鏂█锛歱rocessId 搴旇鏄� null
-        MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
-        assertNull(ipqc.getProcessId());
+        ServiceException ex = assertThrows(ServiceException.class, () -> ipqcService.createIpqc(reqVO));
+        assertEquals(QC_NO_TEMPLATE.getCode(), ex.getCode());
     }
 
     // ==================== sourceLineId 鏍¢獙娴嬭瘯 ====================
@@ -404,35 +323,10 @@
      */
     @Test
     public void testCreateIpqc_sourceLineId_required() {
-        // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
+        Long itemId = randomLongId();
         Long feedbackId = randomLongId();
-        Long templateId = randomLongId();
-
-        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-SL-001");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
-        reqVO.setInspectorUserId(randomLongId());
-        reqVO.setSourceDocType(MesBizTypeConstants.PRO_FEEDBACK);
-        reqVO.setSourceDocId(feedbackId);
-        reqVO.setSourceLineId(null); // 涓嶄紶 sourceLineId
-
-        // mock
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(null);
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
+        MesQcIpqcSaveReqVO reqVO = buildFeedbackReqVO("IPQC-SL-001", itemId, feedbackId, null);
+        mockTemplate(itemId, randomLongId());
         when(feedbackService.validateFeedbackExists(feedbackId)).thenReturn(new MesProFeedbackDO());
 
         // 璋冪敤锛屾柇瑷�寮傚父
@@ -445,36 +339,11 @@
      */
     @Test
     public void testCreateIpqc_sourceLineId_notBelong() {
-        // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
+        Long itemId = randomLongId();
         Long feedbackId = randomLongId();
         Long sourceLineId = randomLongId();
-        Long templateId = randomLongId();
-
-        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-SL-002");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
-        reqVO.setInspectorUserId(randomLongId());
-        reqVO.setSourceDocType(MesBizTypeConstants.PRO_FEEDBACK);
-        reqVO.setSourceDocId(feedbackId);
-        reqVO.setSourceLineId(sourceLineId);
-
-        // mock
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(null);
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
+        MesQcIpqcSaveReqVO reqVO = buildFeedbackReqVO("IPQC-SL-002", itemId, feedbackId, sourceLineId);
+        mockTemplate(itemId, randomLongId());
         when(feedbackService.validateFeedbackExists(feedbackId)).thenReturn(new MesProFeedbackDO());
         // mock锛氫骇鍑鸿瀛樺湪浣� feedbackId 涓嶅尮閰�
         MesWmProductProduceLineDO line = new MesWmProductProduceLineDO();
@@ -493,36 +362,11 @@
      */
     @Test
     public void testCreateIpqc_sourceLineId_notPending() {
-        // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
+        Long itemId = randomLongId();
         Long feedbackId = randomLongId();
         Long sourceLineId = randomLongId();
-        Long templateId = randomLongId();
-
-        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-SL-003");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
-        reqVO.setInspectorUserId(randomLongId());
-        reqVO.setSourceDocType(MesBizTypeConstants.PRO_FEEDBACK);
-        reqVO.setSourceDocId(feedbackId);
-        reqVO.setSourceLineId(sourceLineId);
-
-        // mock
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(null);
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
+        MesQcIpqcSaveReqVO reqVO = buildFeedbackReqVO("IPQC-SL-003", itemId, feedbackId, sourceLineId);
+        mockTemplate(itemId, randomLongId());
         when(feedbackService.validateFeedbackExists(feedbackId)).thenReturn(new MesProFeedbackDO());
         // mock锛氫骇鍑鸿瀛樺湪涓斿綊灞炴纭紝浣嗕笉鏄� PENDING 鐘舵��
         MesWmProductProduceLineDO line = new MesWmProductProduceLineDO();
@@ -541,36 +385,11 @@
      */
     @Test
     public void testCreateIpqc_sourceLineId_success() {
-        // 鍑嗗鍙傛暟
-        Long workstationId = randomLongId();
-        Long workOrderId = randomLongId();
-        Long productId = randomLongId();
+        Long itemId = randomLongId();
         Long feedbackId = randomLongId();
         Long sourceLineId = randomLongId();
-        Long templateId = randomLongId();
-
-        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
-        reqVO.setCode("IPQC-SL-004");
-        reqVO.setWorkstationId(workstationId);
-        reqVO.setWorkOrderId(workOrderId);
-        reqVO.setInspectorUserId(randomLongId());
-        reqVO.setSourceDocType(MesBizTypeConstants.PRO_FEEDBACK);
-        reqVO.setSourceDocId(feedbackId);
-        reqVO.setSourceLineId(sourceLineId);
-
-        // mock
-        MesMdWorkstationDO workstation = new MesMdWorkstationDO();
-        workstation.setId(workstationId);
-        workstation.setProcessId(null);
-        when(workstationService.validateWorkstationExists(workstationId)).thenReturn(workstation);
-        MesProWorkOrderDO workOrder = new MesProWorkOrderDO();
-        workOrder.setId(workOrderId);
-        workOrder.setProductId(productId);
-        when(workOrderService.validateWorkOrderExists(workOrderId)).thenReturn(workOrder);
-        when(workOrderService.validateWorkOrderConfirmed(workOrderId)).thenReturn(workOrder);
-        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
-        templateItem.setTemplateId(templateId);
-        when(templateItemService.getRequiredTemplateByItemIdAndType(eq(productId), anyInt())).thenReturn(templateItem);
+        MesQcIpqcSaveReqVO reqVO = buildFeedbackReqVO("IPQC-SL-004", itemId, feedbackId, sourceLineId);
+        mockTemplate(itemId, randomLongId());
         MesProFeedbackDO feedback = new MesProFeedbackDO();
         feedback.setId(feedbackId);
         feedback.setCode("FB-001");
@@ -593,4 +412,26 @@
         assertEquals("FB-001", ipqc.getSourceDocCode());
     }
 
+    // ==================== 娴嬭瘯杈呭姪 ====================
+
+    private MesQcIpqcSaveReqVO buildFeedbackReqVO(String code, Long itemId, Long feedbackId, Long sourceLineId) {
+        MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
+        reqVO.setCode(code);
+        reqVO.setName("鏉ユ簮鏍¢獙杩囩▼妫�楠�");
+        reqVO.setBatchCode("BC-SL-001");
+        reqVO.setItemId(itemId);
+        reqVO.setInspectorUserId(randomLongId());
+        reqVO.setSourceDocType(MesBizTypeConstants.PRO_FEEDBACK);
+        reqVO.setSourceDocId(feedbackId);
+        reqVO.setSourceLineId(sourceLineId);
+        return reqVO;
+    }
+
+    private void mockTemplate(Long itemId, Long templateId) {
+        MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
+        templateItem.setTemplateId(templateId);
+        when(templateItemService.getTemplateItemList(eq(itemId), anyInt()))
+                .thenReturn(List.of(templateItem));
+    }
+
 }
diff --git a/yudao-module-mes/src/test/resources/sql/create_tables.sql b/yudao-module-mes/src/test/resources/sql/create_tables.sql
index 780ff99..08ce82c 100644
--- a/yudao-module-mes/src/test/resources/sql/create_tables.sql
+++ b/yudao-module-mes/src/test/resources/sql/create_tables.sql
@@ -242,10 +242,7 @@
     "source_doc_id" bigint DEFAULT NULL,
     "source_line_id" bigint DEFAULT NULL,
     "source_doc_code" varchar(64) DEFAULT NULL,
-    "work_order_id" bigint DEFAULT NULL,
-    "task_id" bigint DEFAULT NULL,
-    "workstation_id" bigint DEFAULT NULL,
-    "process_id" bigint DEFAULT NULL,
+    "batch_code" varchar(100) DEFAULT NULL,
     "item_id" bigint DEFAULT NULL,
     "check_quantity" decimal(14,2) DEFAULT NULL,
     "qualified_quantity" decimal(14,2) DEFAULT NULL,
diff --git a/yudao-module-qcreport/src/main/java/cn/iocoder/yudao/module/qcreport/service/instance/MesQcReportContextMapper.java b/yudao-module-qcreport/src/main/java/cn/iocoder/yudao/module/qcreport/service/instance/MesQcReportContextMapper.java
index d668d17..dfbe40b 100644
--- a/yudao-module-qcreport/src/main/java/cn/iocoder/yudao/module/qcreport/service/instance/MesQcReportContextMapper.java
+++ b/yudao-module-qcreport/src/main/java/cn/iocoder/yudao/module/qcreport/service/instance/MesQcReportContextMapper.java
@@ -67,7 +67,7 @@
                 .setProductCode(StrUtil.nullToEmpty(data.getItemCode()))
                 .setProductName(StrUtil.nullToEmpty(data.getItemName()))
                 .setSpec(StrUtil.nullToEmpty(data.getItemSpecification()))
-                // 鏉ユ枡妫�楠岀殑鎵规鍦ㄤ緵搴斿晢鎵瑰彿涓婏紝鍑鸿揣/閫�璐у湪鎵规鍙蜂笂锛岃繃绋嬫楠屼袱鑰呴兘娌℃湁锛堝彧鏈夊伐鍗曪級
+                // 杩囩▼/鍑鸿揣/閫�璐ф楠岀殑鎵规鍙栬嚜鍗曟嵁鐨勬壒鍙凤紝鏉ユ枡妫�楠屾病鏈夋壒鍙峰垯鍥炶惤鍒颁緵搴斿晢鎵瑰彿
                 .setBatchNo(firstNonBlank(data.getBatchCode(), data.getVendorBatch()))
                 .setWorkOrderNo(StrUtil.nullToEmpty(data.getWorkOrderCode()))
                 .setInspectType(StrUtil.nullToEmpty(data.getQcTypeName()))

--
Gitblit v1.9.3