From b630f868ae5cb4bc2e92c48d275341d36d260499 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 22 九月 2026 12:58:07 +0800
Subject: [PATCH] feat(qc): 新增OQC出货检验功能及优化质量流程
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcPageReqVO.java | 4
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImplTest.java | 411 +++++++-----------------
docs/project-business/mermaid/05-quality-flow.mmd | 11
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/DictTypeConstants.java | 3
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcSaveReqVO.java | 9
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcOqcCheckResultEnum.java | 51 +++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/MesQcIndicatorResultController.java | 2
docs/project-business/data/modules.json | 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/ipqc/MesQcIpqcDO.java | 28 -
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineServiceImpl.java | 6
docs/sql/config_export_all_20260904.sql | 9
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcSaveReqVO.java | 21 -
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/MesQcIpqcController.java | 30 -
docs/project-business/index.html | 30 +
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/qc/ipqc/MesQcIpqcMapper.java | 2
docs/qc_chemical_report_integration.md | 6
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcRespVO.java | 2
yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml | 6
docs/project-business/data/flows.json | 6
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcReportServiceImpl.java | 15
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java | 146 --------
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcProductReportWordBuilderTest.java | 7
yudao-module-mes/src/test/resources/sql/create_tables.sql | 10
docs/project-business/data/business.json | 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/ai/MesProAiServiceImpl.java | 37 -
docs/project-business/mermaid/11-ai-business-flow.mmd | 2
docs/project-business/data/objects.json | 6
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcQcReportRespVO.java | 5
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/MesQcOqcController.java | 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcProductReportWordBuilder.java | 14
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/vo/MesQcPendingInspectRespVO.java | 3
.playwright-mcp/产品检验单-1.docx | 0
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcRespVO.java | 31 -
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ai/MesQcAiServiceImpl.java | 3
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcDO.java | 4
35 files changed, 317 insertions(+), 609 deletions(-)
diff --git "a/.playwright-mcp/\344\272\247\345\223\201\346\243\200\351\252\214\345\215\225-1.docx" "b/.playwright-mcp/\344\272\247\345\223\201\346\243\200\351\252\214\345\215\225-1.docx"
new file mode 100644
index 0000000..e6e47f5
--- /dev/null
+++ "b/.playwright-mcp/\344\272\247\345\223\201\346\243\200\351\252\214\345\215\225-1.docx"
Binary files differ
diff --git a/docs/project-business/data/business.json b/docs/project-business/data/business.json
index 7aec6dc..8546e4f 100644
--- a/docs/project-business/data/business.json
+++ b/docs/project-business/data/business.json
@@ -110,7 +110,7 @@
},
{
"name": "鐢熶骇椋庨櫓棰勬祴",
- "flow": "IPQC 缂洪櫡鐜�+璁惧淇濆吇鐐规+鐗╂枡鍙敤鐜�<20%+鍏抽敭宸ュ簭 鈫� chat 鈫� 缁煎悎椋庨櫓+鍥犵礌",
+ "flow": "璁惧淇濆吇鐐规+鐗╂枡鍙敤鐜�<20%+鍏抽敭宸ュ簭 鈫� chat 鈫� 缁煎悎椋庨櫓+鍥犵礌",
"callsApis": [
"MdmItemApi"
]
diff --git a/docs/project-business/data/flows.json b/docs/project-business/data/flows.json
index aef97e3..55797d2 100644
--- a/docs/project-business/data/flows.json
+++ b/docs/project-business/data/flows.json
@@ -29,13 +29,13 @@
{"stage": "鑱斿姩", "action": "瀹℃壒閫氳繃鎸夊伐搴忔爣璁�: 鍊掑啿鈫掕嚜鍔ㄧ墿鏂欐秷鑰楁墸绾胯竟搴�(鍏佽璐熷簱瀛�)锛涜川妫�鈫掍骇鍑哄緟妫�琛岀瓑 IPQC锛涘叧閿潪妫�鈫掔洿鎺ヤ骇鍑哄叆搴�", "roles": ["绯荤粺鑷姩"]},
{"stage": "瀹屽伐", "action": "浠呮湯閬撳伐搴忓洖鍐欏伐鍗曞凡鐢熶骇鏁伴噺锛岃揪鏍囪嚜鍔ㄥ畬鎴愶紱MPS 绱鍒ゆ柇瀹屾垚骞跺彂浜嬩欢缁欓攢鍞鍗�", "roles": ["绯荤粺鑷姩"]}]},
{"id": "quality", "name": "璐ㄩ噺娴佺▼", "mermaid": "mermaid/05-quality-flow.mmd", "color": "#e06c6c",
- "summary": "鍥涢亾妫�楠岄椄鍙�(IQC/IPQC/OQC/RQC锛屼簩鎬� 0鈫�4) + 鍒ゅ畾鍥涙灉(鍚堟牸/鐗归噰/閫�璐�/鎶ュ簾) + NCR 璇勫澶勭疆鍏抽棴锛汚I 鎻愪緵鍒ゅ畾寤鸿锛汵CR 褰撳墠浠呭彴璐︿笉瑙﹀彂杩斿伐鍗曘�傛敮鎸佸寲宸ユ姤鍛婅寖寮忥細鍒嗙粍鎸囨爣鏍�+鍏紡鏂囨湰+骞宠娴嬮噺鎵规+閲囨牱琛ㄥご+绛惧瓧鍖猴紝娴忚鍣ㄦ墦鍗版楠屾姤鍛婏紱骞跺彲瀵煎嚭浜у搧妫�楠屽崟 Word锛堢焊璐ㄦ楠屽崟鐗堝紡锛屽垽瀹氱粨璁�/璐ㄦ绔�/妫�楠屄峰鏍嘎锋壒鍑嗙瀛楃暀绌烘墜濉紝Word 鎵撳嵃锛夈��",
+ "summary": "鍥涢亾妫�楠岄椄鍙�(IQC/IPQC/OQC/RQC锛屼簩鎬� 0鈫�4) + 鍒ゅ畾鍥涙灉(鍚堟牸/鐗归噰/閫�璐�/鎶ュ簾锛汷QC 鏀规寜浜у搧绛夌骇 1鍨�/2鍨�/搴熷搧锛屼粎搴熷搧鍒や笉鍚堟牸) + NCR 璇勫澶勭疆鍏抽棴锛汚I 鎻愪緵鍒ゅ畾寤鸿锛汵CR 褰撳墠浠呭彴璐︿笉瑙﹀彂杩斿伐鍗曘�傛敮鎸佸寲宸ユ姤鍛婅寖寮忥細鍒嗙粍鎸囨爣鏍�+鍏紡鏂囨湰+骞宠娴嬮噺鎵规+閲囨牱琛ㄥご+绛惧瓧鍖猴紝娴忚鍣ㄦ墦鍗版楠屾姤鍛婏紱骞跺彲瀵煎嚭浜у搧妫�楠屽崟 Word锛堢焊璐ㄦ楠屽崟鐗堝紡锛屽垽瀹氱粨璁�/璐ㄦ绔�/妫�楠屄峰鏍嘎锋壒鍑嗙瀛楃暀绌烘墜濉紝Word 鎵撳嵃锛夈��",
"steps": [
{"stage": "鏉ユ枡", "action": "鍒拌揣閫氱煡/澶栧崗鍏ュ簱鈫扞QC锛岀粨璁哄洖鍐欐帹杩涘緟鍏ュ簱鎴栬Е鍙戦��璐�", "roles": ["IQC 璐ㄦ鍛�"]},
{"stage": "杩囩▼", "action": "鎶ュ伐璐ㄦ宸ュ簭浜у嚭琛屸啋IPQC锛屽悎鏍兼媶琛屽叆搴撱�佷笉鍚堟牸鐢熸垚 NCR", "roles": ["IPQC 璐ㄦ鍛�"]},
- {"stage": "鍑鸿揣", "action": "閿�鍞嚭搴撴彁浜も啋OQC锛屽畬鎴愬悗鍑哄簱鍗曡繘鍏ュ緟鎷h揣", "roles": ["OQC 璐ㄦ鍛�"]},
+ {"stage": "鍑鸿揣", "action": "閿�鍞嚭搴撴彁浜も啋OQC(妫�娴嬬粨鏋滄寜浜у搧绛夌骇 1鍨�/2鍨�/搴熷搧蹇呭~锛�1鍨�/2鍨嬪垽琛屽悎鏍硷紝搴熷搧鍒よ涓嶅悎鏍�)锛屽叏閮ㄥ悎鏍煎悗鍑哄簱鍗曡繘鍏ュ緟鎷h揣锛屽嚭鐜板簾鍝佸垯鏁村崟鍙栨秷", "roles": ["OQC 璐ㄦ鍛�"]},
{"stage": "閫�璐�", "action": "閫�鏂�/閿�鍞��璐�/鍞悗閫�璐р啋RQC锛岀粨璁哄洖璋冨崟鎹笌鍞悗", "roles": ["RQC 璐ㄦ鍛�"]},
- {"stage": "鎶ュ憡", "action": "妫�楠岀粨鏋滄寜鍒嗙粍鏍�+娴嬮噺鎵规褰曞叆锛�/indicator-result/report 鑱氬悎鍚庡墠绔墦鍗版楠屾姤鍛�(鍚噰鏍峰湴鐐�/璇佷功缂栧彿/鎵ц鏍囧噯/澶嶆牳路瀹℃牳绛惧瓧鍖�)锛�/indicator-result/export-product-word 瀵煎嚭浜у搧妫�楠屽崟Word(鏃犳妧鏈寚鏍囧垪路鍒ゅ畾缁撹/璐ㄦ涓撶敤绔�/妫�楠屄峰鏍嘎锋壒鍑嗙瀛楃暀绌烘墜濉峰钩琛屾祴閲忛】鍙峰悎骞堵蜂笅杞藉悗Word鎵撳嵃锛涜川妫�鍗曡鎯呮娴嬬粨鏋淭ab鍙寜鏍峰搧鏌ョ湅鍙妫�娴嬪�兼槑缁�)", "roles": ["璐ㄦ鍛�", "澶嶆牳浜�", "瀹℃牳浜�"]},
+ {"stage": "鎶ュ憡", "action": "妫�楠岀粨鏋滄寜鍒嗙粍鏍�+娴嬮噺鎵规褰曞叆锛�/indicator-result/report 鑱氬悎鍚庡墠绔墦鍗版楠屾姤鍛�(鍚噰鏍峰湴鐐�/璇佷功缂栧彿/鎵ц鏍囧噯/鍒ゅ畾缁撹路璐ㄦ涓撶敤绔�/澶嶆牳路瀹℃牳绛惧瓧鍖猴紱鍒ゅ畾缁撹甯﹀嚭妫�楠岀粨鏋溌疯川妫�绔犵暀绌虹洊绔犅锋棤骞宠娴嬮噺鏃跺垪澶寸О娴嬮噺鍊�)锛�/indicator-result/export-product-word 瀵煎嚭浜у搧妫�楠屽崟Word(鏃犳妧鏈寚鏍囧垪路鍒ゅ畾缁撹甯﹀嚭妫�楠岀粨鏋溌疯川妫�绔�/妫�楠屄峰鏍嘎锋壒鍑嗙瀛楃暀绌烘墜濉峰钩琛屾祴閲忛】鍙峰悎骞堵蜂笅杞藉悗Word鎵撳嵃锛涜川妫�鍗曡鎯呮娴嬬粨鏋淭ab鍙寜鏍峰搧鏌ョ湅鍙妫�娴嬪�兼槑缁�)", "roles": ["璐ㄦ鍛�", "澶嶆牳浜�", "瀹℃牳浜�"]},
{"stage": "涓嶅悎鏍�", "action": "NCR: 寰呰瘎瀹♀啋璇勫鈫掑缃�(閫�璐�/鎶ュ簾/杩斿伐/璁╂鎺ユ敹/闄嶇骇)鈫掑叧闂�", "roles": ["璐ㄩ噺宸ョ▼甯�"]}]},
{"id": "warehouse", "name": "浠撳偍娴佺▼", "mermaid": "mermaid/06-warehouse-flow.mmd", "color": "#7e6bd6",
"summary": "15 绫诲崟鎹┍鍔ㄥ簱瀛樺彴璐�(鍏厓缁勩�佸洓閲�)鍙樺姩锛屽叏閮ㄧ粡浜嬪姟娴佹按鐣欑棔锛涙敮鎸佽皟鎷ㄥ湪閫斻�佺洏鐐硅皟鏁淬�佹壒娆�/SN 杩芥函銆佸簱瀛樺崰鐢ㄤ笌鍥涚骇鍐荤粨銆佺嚎杈硅櫄鎷熷簱璐熷簱瀛橈紱瀵瑰 WmsStockApi 渚� ERP 鏀跺彂銆�",
diff --git a/docs/project-business/data/modules.json b/docs/project-business/data/modules.json
index 09137e1..dd2e10b 100644
--- a/docs/project-business/data/modules.json
+++ b/docs/project-business/data/modules.json
@@ -51,7 +51,7 @@
{"key": "qc", "name": "璐ㄩ噺绠$悊", "color": "#e06c6c", "tag": "MES-QC", "flow": "quality",
"positioning": "鍥涢亾妫�楠岄椄鍙� + 涓嶅悎鏍煎搧闂幆澶勭疆",
"problem": "鏉ユ枡/杩囩▼/鍑鸿揣/閫�璐ф楠屾爣鍑嗗寲锛屼笉鍚堟牸鍙拷婧缃�",
- "features": ["IQC 鏉ユ枡(鍒拌揣/澶栧崗)", "IPQC 杩囩▼(鑱斿姩鎶ュ伐)", "OQC 鍑鸿揣(鑱斿姩閿�鍞嚭搴�)", "RQC 閫�璐�(鑱斿姩閫�鏂�/鍞悗)", "璐ㄦ鏂规路鎸囨爣路缂洪櫡搴�", "妫�娴嬬粨鏋�:鍚堟牸/鐗归噰/閫�璐�/鎶ュ簾", "NCR:璇勫鈫掑缃�(閫�璐�/鎶ュ簾/杩斿伐/璁╂/闄嶇骇)鈫掑叧闂�", "AI 鍒ゅ畾寤鸿"],
+ "features": ["IQC 鏉ユ枡(鍒拌揣/澶栧崗)", "IPQC 杩囩▼(鑱斿姩鎶ュ伐)", "OQC 鍑鸿揣(鑱斿姩閿�鍞嚭搴�)", "RQC 閫�璐�(鑱斿姩閫�鏂�/鍞悗)", "璐ㄦ鏂规路鎸囨爣路缂洪櫡搴�", "妫�娴嬬粨鏋�:IQC/IPQC/RQC 鍚堟牸路鐗归噰路閫�璐锋姤搴� / OQC 1鍨嬄�2鍨嬄峰簾鍝�", "NCR:璇勫鈫掑缃�(閫�璐�/鎶ュ簾/杩斿伐/璁╂/闄嶇骇)鈫掑叧闂�", "AI 鍒ゅ畾寤鸿"],
"objects": ["IQC", "IPQC", "OQC", "RQC", "璐ㄦ鏂规", "NCR", "缂洪櫡璁板綍"],
"roles": ["璐ㄦ鍛�(IQC/IPQC/OQC)", "璐ㄩ噺宸ョ▼甯�"],
"upstream": ["浠撳偍(鍒拌揣)", "鐢熶骇(鎶ュ伐)", "閿�鍞�(鍑哄簱)", "鍞悗(閫�璐�)"], "downstream": ["浠撳偍(鍚堟牸鍏ュ簱/鎶ュ簾鍑哄簱)", "鐢熶骇(NCR杩斿伐)"],
diff --git a/docs/project-business/data/objects.json b/docs/project-business/data/objects.json
index 29ac7ce..8cc8a93 100644
--- a/docs/project-business/data/objects.json
+++ b/docs/project-business/data/objects.json
@@ -28,7 +28,7 @@
{"name": "鍒拌揣閫氱煡鍗�", "module": "浠撳偍", "table": "mes_wm_arrival_notice", "doc": "閲囪喘璁㈠崟纭鏀惰揣鐢熸垚锛岃崏绋�0鈫掑緟璐ㄦ2鈫掑緟鍏ュ簱3鈫掑畬鎴�4", "upstream": ["閲囪喘璁㈠崟"], "downstream": ["IQC", "閲囪喘鍏ュ簱"], "keywords": "鍒拌揣 鏀惰揣 arrival"},
{"name": "閲囪喘鍏ュ簱鍗�", "module": "浠撳偍", "table": "mes_wm_item_receipt", "doc": "鑽夌0鈫掑緟涓婃灦2鈫掑緟鎵ц3鈫掑畬鎴�4锛屽畬鎴愬悗搴撳瓨+骞跺洖鍐� ERP inCount/inStatus", "upstream": ["鍒拌揣閫氱煡"], "downstream": ["搴撳瓨鍙拌处", "閲囪喘璁㈠崟(鍥炲啓)"], "keywords": "閲囪喘鍏ュ簱 鏀惰揣鍏ュ簱 receipt"},
{"name": "鐢熶骇棰嗘枡鍗�", "module": "浠撳偍", "table": "mes_wm_product_issue", "doc": "鑽夌0鈫掑緟鎷h揣2鈫掑緟鎵ц3鈫掑畬鎴�4锛屽簱瀛�-", "upstream": ["鐢熶骇宸ュ崟"], "downstream": ["搴撳瓨鍙拌处"], "keywords": "棰嗘枡 issue"},
- {"name": "閿�鍞嚭搴撳崟", "module": "浠撳偍", "table": "mes_wm_product_sales", "doc": "鍙戣揣閫氱煡瀹℃牳鍚庣敓鎴愶紝鎻愪氦鈫扥QC妫�娴嬧啋鎷h揣鈫掑彂杩�10鈫掑緟鎵ц3鈫掑畬鎴�4锛屽洖鍐欓攢鍞鍗曞嚭搴撴暟涓庣姸鎬�", "upstream": ["鍙戣揣閫氱煡", "閿�鍞鍗�"], "downstream": ["搴撳瓨鍙拌处", "OQC"], "keywords": "閿�鍞嚭搴� 鍙戣揣 鍑哄簱鍗� sales"},
+ {"name": "閿�鍞嚭搴撳崟", "module": "浠撳偍", "table": "mes_wm_product_sales", "doc": "鍙戣揣閫氱煡瀹℃牳鍚庣敓鎴愶紝鎻愪氦鈫扥QC妫�娴嬧啋鎷h揣鈫掑彂杩�10鈫掑緟鎵ц3鈫掑畬鎴�4锛屽洖鍐欓攢鍞鍗曞嚭搴撴暟涓庣姸鎬侊紱浠讳竴 OQC 琛屽垽搴熷搧鍒欐暣鍗曞彇娑�", "upstream": ["鍙戣揣閫氱煡", "閿�鍞鍗�"], "downstream": ["搴撳瓨鍙拌处", "OQC"], "keywords": "閿�鍞嚭搴� 鍙戣揣 鍑哄簱鍗� sales"},
{"name": "閿�鍞��璐у崟", "module": "浠撳偍", "table": "mes_wm_return_sales", "doc": "鑽夌鈫掑緟妫�楠�(RQC)鈫掑緟涓婃灦鈫掑緟鍏ュ簱鈫掑畬鎴愶紝鍞悗涓庢墜宸ヤ袱鏉ユ簮", "upstream": ["鍞悗閫�璐х敵璇�"], "downstream": ["搴撳瓨鍙拌处", "RQC"], "keywords": "閿�鍞��璐� 閫�璐у叆搴�"},
{"name": "渚涘簲鍟嗛��璐у崟", "module": "浠撳偍", "table": "mes_wm_return_vendor", "doc": "IQC 涓嶅悎鏍奸��璐у彂璧凤紝寰呮嫞璐р啋寰呮墽琛屸啋瀹屾垚锛屽簱瀛�-", "upstream": ["IQC"], "downstream": ["搴撳瓨鍙拌处", "閲囪喘璁㈠崟(returnCount)"], "keywords": "渚涘簲鍟嗛��璐� 閫�鏂� 閫�璐� vendor"},
{"name": "璋冩嫧鍗�", "module": "浠撳偍", "table": "mes_wm_transfer", "doc": "鍐呴儴/澶栭儴璋冩嫧锛屾垚瀵� MOVE_OUT+MOVE_IN 浜嬪姟锛屽湪閫旀暟閲�", "upstream": [], "downstream": ["搴撳瓨鍙拌处"], "keywords": "璋冩嫧 绉诲簱 transfer"},
@@ -36,8 +36,8 @@
{"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": "OQC鍑鸿揣妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_oqc", "doc": "閿�鍞嚭搴撴彁浜よЕ鍙戯紝瀹屾垚鎺ㄨ繘鍑哄簱鍗曞緟鎷h揣", "upstream": ["閿�鍞嚭搴撳崟"], "downstream": ["閿�鍞嚭搴撳崟(鎺ㄨ繘)"], "keywords": "OQC 鍑鸿揣妫�楠� 鍑哄巶妫�楠�"},
+ {"name": "IPQC杩囩▼妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_ipqc", "doc": "鎶ュ伐璐ㄦ宸ュ簭浜у嚭琛岃Е鍙戯紝瀹屾垚鍥炶皟鎺ㄨ繘鎶ュ伐涓庝骇鍑哄叆搴擄紱琛ㄥご=鏉ユ簮鍗曟嵁(鍙)+浜у搧鐗╂枡(MDM,蹇呭~)+鎵瑰彿(蹇呭~)+鏁伴噺+妫�楠屼俊鎭紝宸插幓鎺夌敓浜ц鍗�/宸ヤ綅/鐢熶骇浠诲姟/宸ュ簭", "upstream": ["鎶ュ伐"], "downstream": ["浜у嚭鍏ュ簱", "NCR"], "keywords": "IPQC 杩囩▼妫�楠� 宸℃ 鎵瑰彿"},
+ {"name": "OQC鍑鸿揣妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_oqc", "doc": "閿�鍞嚭搴撴彁浜よЕ鍙戯紝鑽夌0鈫掑畬鎴�4锛涙娴嬬粨鏋滄寜浜у搧绛夌骇鍒ゅ畾(1鍨�/2鍨�/搴熷搧锛屽繀濉�)锛�1鍨�/2鍨嬪垽琛屽悎鏍煎苟鎺ㄨ繘鍑哄簱鍗曞緟鎷h揣锛屽簾鍝佸垽琛屼笉鍚堟牸骞跺彇娑堥攢鍞嚭搴撳崟锛涘彂璐ф暟閲�/鍑鸿揣鏃ユ湡鍙┖", "upstream": ["閿�鍞嚭搴撳崟"], "downstream": ["閿�鍞嚭搴撳崟(鎺ㄨ繘鎴栧彇娑�)"], "keywords": "OQC 鍑鸿揣妫�楠� 鍑哄巶妫�楠� 1鍨� 2鍨� 搴熷搧"},
{"name": "RQC閫�璐ф楠�", "module": "璐ㄩ噺", "table": "mes_qc_rqc", "doc": "鐢熶骇閫�鏂�/閿�鍞��璐�/鍞悗閫�璐цЕ鍙戯紝缁撹鍥炶皟鍞悗锛涘洓绫绘楠屽崟鍧囨敮鎸侀噰鏍峰湴鐐�/璇佷功缂栧彿/鎵ц鏍囧噯琛ㄥご涓庡鏍嘎峰鏍镐汉锛屽苟鍙墦鍗版楠屾姤鍛�", "upstream": ["閫�鏂�", "閫�璐�"], "downstream": ["閫�璐у叆搴�", "鍞悗鍥炶皟", "妫�楠屾姤鍛婃墦鍗�"], "keywords": "RQC 閫�璐ф楠�"},
{"name": "妫�楠屾寚鏍�", "module": "璐ㄩ噺", "table": "mes_qc_indicator", "doc": "鏀寔涓ょ骇鍒嗙粍鏍�(itemType褰曞叆/鍒嗙粍+parentId)銆佸叕寮忔枃鏈睍绀恒�佸崟浣嶆枃鏈�佸悓绾ф帓搴忥紱鍒嗙粍椤逛笉褰曞�硷紱鏈夊瓙椤圭鍒狅紱鍚屽眰绾у悕绉板彲閲嶅", "upstream": [], "downstream": ["璐ㄦ鏂规", "妫�楠屾姤鍛婃墦鍗�"], "keywords": "妫�楠屾寚鏍� indicator 鍒嗙粍 鍏紡 鍖栧伐"},
{"name": "妫�楠屾姤鍛婃墦鍗�", "module": "璐ㄩ噺", "table": "mes_qc_indicator_result_detail", "doc": "鍖栧伐鎶ュ憡鑼冨紡锛氬钩琛屾祴閲忔壒娆�(measure_no)+鍒嗙粍鐭╅樀+鍏紡鍒�+绛惧瓧鍖猴紱/mes/qc/indicator-result/report 鑱氬悎锛屽墠绔祻瑙堝櫒鎵撳嵃", "upstream": ["IQC鏉ユ枡妫�楠�", "IPQC杩囩▼妫�楠�", "OQC鍑鸿揣妫�楠�", "RQC閫�璐ф楠�", "妫�楠屾寚鏍�"], "downstream": [], "keywords": "鎵撳嵃 鎶ュ憡 娴嬮噺鎵规 绛惧瓧 姝d竵閱� GB/T6027"},
diff --git a/docs/project-business/index.html b/docs/project-business/index.html
index 47214d7..6ba4d3c 100644
--- a/docs/project-business/index.html
+++ b/docs/project-business/index.html
@@ -290,7 +290,7 @@
},
{
"name": "鐢熶骇椋庨櫓棰勬祴",
- "flow": "IPQC 缂洪櫡鐜�+璁惧淇濆吇鐐规+鐗╂枡鍙敤鐜�<20%+鍏抽敭宸ュ簭 鈫� chat 鈫� 缁煎悎椋庨櫓+鍥犵礌",
+ "flow": "璁惧淇濆吇鐐规+鐗╂枡鍙敤鐜�<20%+鍏抽敭宸ュ簭 鈫� chat 鈫� 缁煎悎椋庨櫓+鍥犵礌",
"callsApis": [
"MdmItemApi"
]
@@ -381,7 +381,7 @@
{"key": "qc", "name": "璐ㄩ噺绠$悊", "color": "#e06c6c", "tag": "MES-QC", "flow": "quality",
"positioning": "鍥涢亾妫�楠岄椄鍙� + 涓嶅悎鏍煎搧闂幆澶勭疆",
"problem": "鏉ユ枡/杩囩▼/鍑鸿揣/閫�璐ф楠屾爣鍑嗗寲锛屼笉鍚堟牸鍙拷婧缃�",
- "features": ["IQC 鏉ユ枡(鍒拌揣/澶栧崗)", "IPQC 杩囩▼(鑱斿姩鎶ュ伐)", "OQC 鍑鸿揣(鑱斿姩閿�鍞嚭搴�)", "RQC 閫�璐�(鑱斿姩閫�鏂�/鍞悗)", "璐ㄦ鏂规路鎸囨爣路缂洪櫡搴�", "妫�娴嬬粨鏋�:鍚堟牸/鐗归噰/閫�璐�/鎶ュ簾", "NCR:璇勫鈫掑缃�(閫�璐�/鎶ュ簾/杩斿伐/璁╂/闄嶇骇)鈫掑叧闂�", "AI 鍒ゅ畾寤鸿"],
+ "features": ["IQC 鏉ユ枡(鍒拌揣/澶栧崗)", "IPQC 杩囩▼(鑱斿姩鎶ュ伐)", "OQC 鍑鸿揣(鑱斿姩閿�鍞嚭搴�)", "RQC 閫�璐�(鑱斿姩閫�鏂�/鍞悗)", "璐ㄦ鏂规路鎸囨爣路缂洪櫡搴�", "妫�娴嬬粨鏋�:IQC/IPQC/RQC 鍚堟牸路鐗归噰路閫�璐锋姤搴� / OQC 1鍨嬄�2鍨嬄峰簾鍝�", "NCR:璇勫鈫掑缃�(閫�璐�/鎶ュ簾/杩斿伐/璁╂/闄嶇骇)鈫掑叧闂�", "AI 鍒ゅ畾寤鸿"],
"objects": ["IQC", "IPQC", "OQC", "RQC", "璐ㄦ鏂规", "NCR", "缂洪櫡璁板綍"],
"roles": ["璐ㄦ鍛�(IQC/IPQC/OQC)", "璐ㄩ噺宸ョ▼甯�"],
"upstream": ["浠撳偍(鍒拌揣)", "鐢熶骇(鎶ュ伐)", "閿�鍞�(鍑哄簱)", "鍞悗(閫�璐�)"], "downstream": ["浠撳偍(鍚堟牸鍏ュ簱/鎶ュ簾鍑哄簱)", "鐢熶骇(NCR杩斿伐)"],
@@ -463,7 +463,7 @@
{"name": "鍒拌揣閫氱煡鍗�", "module": "浠撳偍", "table": "mes_wm_arrival_notice", "doc": "閲囪喘璁㈠崟纭鏀惰揣鐢熸垚锛岃崏绋�0鈫掑緟璐ㄦ2鈫掑緟鍏ュ簱3鈫掑畬鎴�4", "upstream": ["閲囪喘璁㈠崟"], "downstream": ["IQC", "閲囪喘鍏ュ簱"], "keywords": "鍒拌揣 鏀惰揣 arrival"},
{"name": "閲囪喘鍏ュ簱鍗�", "module": "浠撳偍", "table": "mes_wm_item_receipt", "doc": "鑽夌0鈫掑緟涓婃灦2鈫掑緟鎵ц3鈫掑畬鎴�4锛屽畬鎴愬悗搴撳瓨+骞跺洖鍐� ERP inCount/inStatus", "upstream": ["鍒拌揣閫氱煡"], "downstream": ["搴撳瓨鍙拌处", "閲囪喘璁㈠崟(鍥炲啓)"], "keywords": "閲囪喘鍏ュ簱 鏀惰揣鍏ュ簱 receipt"},
{"name": "鐢熶骇棰嗘枡鍗�", "module": "浠撳偍", "table": "mes_wm_product_issue", "doc": "鑽夌0鈫掑緟鎷h揣2鈫掑緟鎵ц3鈫掑畬鎴�4锛屽簱瀛�-", "upstream": ["鐢熶骇宸ュ崟"], "downstream": ["搴撳瓨鍙拌处"], "keywords": "棰嗘枡 issue"},
- {"name": "閿�鍞嚭搴撳崟", "module": "浠撳偍", "table": "mes_wm_product_sales", "doc": "鍙戣揣閫氱煡瀹℃牳鍚庣敓鎴愶紝鎻愪氦鈫扥QC妫�娴嬧啋鎷h揣鈫掑彂杩�10鈫掑緟鎵ц3鈫掑畬鎴�4锛屽洖鍐欓攢鍞鍗曞嚭搴撴暟涓庣姸鎬�", "upstream": ["鍙戣揣閫氱煡", "閿�鍞鍗�"], "downstream": ["搴撳瓨鍙拌处", "OQC"], "keywords": "閿�鍞嚭搴� 鍙戣揣 鍑哄簱鍗� sales"},
+ {"name": "閿�鍞嚭搴撳崟", "module": "浠撳偍", "table": "mes_wm_product_sales", "doc": "鍙戣揣閫氱煡瀹℃牳鍚庣敓鎴愶紝鎻愪氦鈫扥QC妫�娴嬧啋鎷h揣鈫掑彂杩�10鈫掑緟鎵ц3鈫掑畬鎴�4锛屽洖鍐欓攢鍞鍗曞嚭搴撴暟涓庣姸鎬侊紱浠讳竴 OQC 琛屽垽搴熷搧鍒欐暣鍗曞彇娑�", "upstream": ["鍙戣揣閫氱煡", "閿�鍞鍗�"], "downstream": ["搴撳瓨鍙拌处", "OQC"], "keywords": "閿�鍞嚭搴� 鍙戣揣 鍑哄簱鍗� sales"},
{"name": "閿�鍞��璐у崟", "module": "浠撳偍", "table": "mes_wm_return_sales", "doc": "鑽夌鈫掑緟妫�楠�(RQC)鈫掑緟涓婃灦鈫掑緟鍏ュ簱鈫掑畬鎴愶紝鍞悗涓庢墜宸ヤ袱鏉ユ簮", "upstream": ["鍞悗閫�璐х敵璇�"], "downstream": ["搴撳瓨鍙拌处", "RQC"], "keywords": "閿�鍞��璐� 閫�璐у叆搴�"},
{"name": "渚涘簲鍟嗛��璐у崟", "module": "浠撳偍", "table": "mes_wm_return_vendor", "doc": "IQC 涓嶅悎鏍奸��璐у彂璧凤紝寰呮嫞璐р啋寰呮墽琛屸啋瀹屾垚锛屽簱瀛�-", "upstream": ["IQC"], "downstream": ["搴撳瓨鍙拌处", "閲囪喘璁㈠崟(returnCount)"], "keywords": "渚涘簲鍟嗛��璐� 閫�鏂� 閫�璐� vendor"},
{"name": "璋冩嫧鍗�", "module": "浠撳偍", "table": "mes_wm_transfer", "doc": "鍐呴儴/澶栭儴璋冩嫧锛屾垚瀵� MOVE_OUT+MOVE_IN 浜嬪姟锛屽湪閫旀暟閲�", "upstream": [], "downstream": ["搴撳瓨鍙拌处"], "keywords": "璋冩嫧 绉诲簱 transfer"},
@@ -471,11 +471,11 @@
{"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": "OQC鍑鸿揣妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_oqc", "doc": "閿�鍞嚭搴撴彁浜よЕ鍙戯紝瀹屾垚鎺ㄨ繘鍑哄簱鍗曞緟鎷h揣", "upstream": ["閿�鍞嚭搴撳崟"], "downstream": ["閿�鍞嚭搴撳崟(鎺ㄨ繘)"], "keywords": "OQC 鍑鸿揣妫�楠� 鍑哄巶妫�楠�"},
+ {"name": "IPQC杩囩▼妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_ipqc", "doc": "鎶ュ伐璐ㄦ宸ュ簭浜у嚭琛岃Е鍙戯紝瀹屾垚鍥炶皟鎺ㄨ繘鎶ュ伐涓庝骇鍑哄叆搴擄紱琛ㄥご=鏉ユ簮鍗曟嵁(鍙)+浜у搧鐗╂枡(MDM,蹇呭~)+鎵瑰彿(蹇呭~)+鏁伴噺+妫�楠屼俊鎭紝宸插幓鎺夌敓浜ц鍗�/宸ヤ綅/鐢熶骇浠诲姟/宸ュ簭", "upstream": ["鎶ュ伐"], "downstream": ["浜у嚭鍏ュ簱", "NCR"], "keywords": "IPQC 杩囩▼妫�楠� 宸℃ 鎵瑰彿"},
+ {"name": "OQC鍑鸿揣妫�楠�", "module": "璐ㄩ噺", "table": "mes_qc_oqc", "doc": "閿�鍞嚭搴撴彁浜よЕ鍙戯紝鑽夌0鈫掑畬鎴�4锛涙娴嬬粨鏋滄寜浜у搧绛夌骇鍒ゅ畾(1鍨�/2鍨�/搴熷搧锛屽繀濉�)锛�1鍨�/2鍨嬪垽琛屽悎鏍煎苟鎺ㄨ繘鍑哄簱鍗曞緟鎷h揣锛屽簾鍝佸垽琛屼笉鍚堟牸骞跺彇娑堥攢鍞嚭搴撳崟锛涘彂璐ф暟閲�/鍑鸿揣鏃ユ湡鍙┖", "upstream": ["閿�鍞嚭搴撳崟"], "downstream": ["閿�鍞嚭搴撳崟(鎺ㄨ繘鎴栧彇娑�)"], "keywords": "OQC 鍑鸿揣妫�楠� 鍑哄巶妫�楠� 1鍨� 2鍨� 搴熷搧"},
{"name": "RQC閫�璐ф楠�", "module": "璐ㄩ噺", "table": "mes_qc_rqc", "doc": "鐢熶骇閫�鏂�/閿�鍞��璐�/鍞悗閫�璐цЕ鍙戯紝缁撹鍥炶皟鍞悗锛涘洓绫绘楠屽崟鍧囨敮鎸侀噰鏍峰湴鐐�/璇佷功缂栧彿/鎵ц鏍囧噯琛ㄥご涓庡鏍嘎峰鏍镐汉锛屽苟鍙墦鍗版楠屾姤鍛�", "upstream": ["閫�鏂�", "閫�璐�"], "downstream": ["閫�璐у叆搴�", "鍞悗鍥炶皟", "妫�楠屾姤鍛婃墦鍗�"], "keywords": "RQC 閫�璐ф楠�"},
{"name": "妫�楠屾寚鏍�", "module": "璐ㄩ噺", "table": "mes_qc_indicator", "doc": "鏀寔涓ょ骇鍒嗙粍鏍�(itemType褰曞叆/鍒嗙粍+parentId)銆佸叕寮忔枃鏈睍绀恒�佸崟浣嶆枃鏈�佸悓绾ф帓搴忥紱鍒嗙粍椤逛笉褰曞�硷紱鏈夊瓙椤圭鍒狅紱鍚屽眰绾у悕绉板彲閲嶅", "upstream": [], "downstream": ["璐ㄦ鏂规", "妫�楠屾姤鍛婃墦鍗�"], "keywords": "妫�楠屾寚鏍� indicator 鍒嗙粍 鍏紡 鍖栧伐"},
- {"name": "妫�楠屾姤鍛婃墦鍗�", "module": "璐ㄩ噺", "table": "mes_qc_indicator_result_detail", "doc": "鍖栧伐鎶ュ憡鑼冨紡锛氬钩琛屾祴閲忔壒娆�(measure_no)+鍒嗙粍鐭╅樀+鍏紡鍒�+绛惧瓧鍖猴紱/mes/qc/indicator-result/report 鑱氬悎锛屽墠绔祻瑙堝櫒鎵撳嵃锛涘彟鏈変骇鍝佹楠屽崟Word瀵煎嚭 /mes/qc/indicator-result/export-product-word锛堢焊璐ㄦ楠屽崟鐗堝紡锛氭棤鎶�鏈寚鏍囧垪锛屽垽瀹氱粨璁�/璐ㄦ涓撶敤绔犵暀绌烘墜濉紝骞宠娴嬮噺椤垮彿鍚堝苟锛岀敓浜у崟浣嶅啓姝汇�佺敓浜ф椂闂�=鍗曟嵁鍒涘缓鏃堕棿锛屼笅杞藉悗Word鎵撳嵃锛�", "upstream": ["IQC鏉ユ枡妫�楠�", "IPQC杩囩▼妫�楠�", "OQC鍑鸿揣妫�楠�", "RQC閫�璐ф楠�", "妫�楠屾寚鏍�"], "downstream": [], "keywords": "鎵撳嵃 鎶ュ憡 娴嬮噺鎵规 绛惧瓧 姝d竵閱� GB/T6027 Word 浜у搧妫�楠屽崟"},
+ {"name": "妫�楠屾姤鍛婃墦鍗�", "module": "璐ㄩ噺", "table": "mes_qc_indicator_result_detail", "doc": "鍖栧伐鎶ュ憡鑼冨紡锛氬钩琛屾祴閲忔壒娆�(measure_no)+鍒嗙粍鐭╅樀+鍏紡鍒�+绛惧瓧鍖猴紱/mes/qc/indicator-result/report 鑱氬悎锛屽墠绔祻瑙堝櫒鎵撳嵃", "upstream": ["IQC鏉ユ枡妫�楠�", "IPQC杩囩▼妫�楠�", "OQC鍑鸿揣妫�楠�", "RQC閫�璐ф楠�", "妫�楠屾寚鏍�"], "downstream": [], "keywords": "鎵撳嵃 鎶ュ憡 娴嬮噺鎵规 绛惧瓧 姝d竵閱� GB/T6027"},
{"name": "NCR涓嶅悎鏍煎搧", "module": "璐ㄩ噺", "table": "mes_qc_ncr", "doc": "寰呰瘎瀹�0鈫掑凡璇勫6鈫掑凡澶勭疆7鈫掑凡鍏抽棴8锛屽缃�:閫�璐�/鎶ュ簾/杩斿伐/璁╂鎺ユ敹/闄嶇骇", "upstream": ["IQC/IPQC/OQC/RQC"], "downstream": ["閫�璐�/鎶ュ簾/杩斿伐(鍙拌处)"], "keywords": "NCR 涓嶅悎鏍� 澶勭疆 鐗归噰 鎶ュ簾"},
{"name": "璁惧", "module": "璁惧", "table": "mes_dv_machinery", "doc": "鍙拌处鐘舵��:鍋滄満/鐢熶骇涓�/淇濆吇涓紱鐐规路淇濆吇路缁翠慨宸ュ崟锛汚I 椋庨櫓棰勬祴娑堣垂鍏舵暟鎹�", "upstream": [], "downstream": ["鐐规", "缁翠慨", "鐢熶骇椋庨櫓棰勬祴"], "keywords": "璁惧 鐐规 淇濆吇 缁翠慨 machinery"},
{"name": "鍞悗宸ュ崟", "module": "鍞悗", "table": "after_sale_ticket", "doc": "鑽夌0鈫掑鐞嗕腑10鈫掑緟鍏ュ簱30鈫掑緟閫�娆�40鈫掑畬缁�50鈫掑叧闂�60/鍙栨秷99锛屽垽瀹�:涓�鑸�/缁翠慨/閫�璐�", "upstream": ["瀹㈡埛鍙嶉(浜哄伐褰曞叆)"], "downstream": ["缁翠慨璁板綍", "閫�璐х敵璇�"], "keywords": "鍞悗 宸ュ崟 ticket 缁翠慨"},
@@ -516,13 +516,13 @@
{"stage": "鑱斿姩", "action": "瀹℃壒閫氳繃鎸夊伐搴忔爣璁�: 鍊掑啿鈫掕嚜鍔ㄧ墿鏂欐秷鑰楁墸绾胯竟搴�(鍏佽璐熷簱瀛�)锛涜川妫�鈫掍骇鍑哄緟妫�琛岀瓑 IPQC锛涘叧閿潪妫�鈫掔洿鎺ヤ骇鍑哄叆搴�", "roles": ["绯荤粺鑷姩"]},
{"stage": "瀹屽伐", "action": "浠呮湯閬撳伐搴忓洖鍐欏伐鍗曞凡鐢熶骇鏁伴噺锛岃揪鏍囪嚜鍔ㄥ畬鎴愶紱MPS 绱鍒ゆ柇瀹屾垚骞跺彂浜嬩欢缁欓攢鍞鍗�", "roles": ["绯荤粺鑷姩"]}]},
{"id": "quality", "name": "璐ㄩ噺娴佺▼", "mermaid": "mermaid/05-quality-flow.mmd", "color": "#e06c6c",
- "summary": "鍥涢亾妫�楠岄椄鍙�(IQC/IPQC/OQC/RQC锛屼簩鎬� 0鈫�4) + 鍒ゅ畾鍥涙灉(鍚堟牸/鐗归噰/閫�璐�/鎶ュ簾) + NCR 璇勫澶勭疆鍏抽棴锛汚I 鎻愪緵鍒ゅ畾寤鸿锛汵CR 褰撳墠浠呭彴璐︿笉瑙﹀彂杩斿伐鍗曘�傛敮鎸佸寲宸ユ姤鍛婅寖寮忥細鍒嗙粍鎸囨爣鏍�+鍏紡鏂囨湰+骞宠娴嬮噺鎵规+閲囨牱琛ㄥご+绛惧瓧鍖猴紝娴忚鍣ㄦ墦鍗版楠屾姤鍛婏紱骞跺彲瀵煎嚭浜у搧妫�楠屽崟 Word锛堢焊璐ㄧ増寮忥紝鍒ゅ畾缁撹/璐ㄦ绔�/妫�楠屄峰鏍嘎锋壒鍑嗙瀛楃暀绌烘墜濉紝Word 鎵撳嵃锛夈��",
+ "summary": "鍥涢亾妫�楠岄椄鍙�(IQC/IPQC/OQC/RQC锛屼簩鎬� 0鈫�4) + 鍒ゅ畾鍥涙灉(鍚堟牸/鐗归噰/閫�璐�/鎶ュ簾锛汷QC 鏀规寜浜у搧绛夌骇 1鍨�/2鍨�/搴熷搧锛屼粎搴熷搧鍒や笉鍚堟牸) + NCR 璇勫澶勭疆鍏抽棴锛汚I 鎻愪緵鍒ゅ畾寤鸿锛汵CR 褰撳墠浠呭彴璐︿笉瑙﹀彂杩斿伐鍗曘�傛敮鎸佸寲宸ユ姤鍛婅寖寮忥細鍒嗙粍鎸囨爣鏍�+鍏紡鏂囨湰+骞宠娴嬮噺鎵规+閲囨牱琛ㄥご+绛惧瓧鍖猴紝娴忚鍣ㄦ墦鍗版楠屾姤鍛婏紱骞跺彲瀵煎嚭浜у搧妫�楠屽崟 Word锛堢焊璐ㄦ楠屽崟鐗堝紡锛屽垽瀹氱粨璁�/璐ㄦ绔�/妫�楠屄峰鏍嘎锋壒鍑嗙瀛楃暀绌烘墜濉紝Word 鎵撳嵃锛夈��",
"steps": [
{"stage": "鏉ユ枡", "action": "鍒拌揣閫氱煡/澶栧崗鍏ュ簱鈫扞QC锛岀粨璁哄洖鍐欐帹杩涘緟鍏ュ簱鎴栬Е鍙戦��璐�", "roles": ["IQC 璐ㄦ鍛�"]},
{"stage": "杩囩▼", "action": "鎶ュ伐璐ㄦ宸ュ簭浜у嚭琛屸啋IPQC锛屽悎鏍兼媶琛屽叆搴撱�佷笉鍚堟牸鐢熸垚 NCR", "roles": ["IPQC 璐ㄦ鍛�"]},
- {"stage": "鍑鸿揣", "action": "閿�鍞嚭搴撴彁浜も啋OQC锛屽畬鎴愬悗鍑哄簱鍗曡繘鍏ュ緟鎷h揣", "roles": ["OQC 璐ㄦ鍛�"]},
+ {"stage": "鍑鸿揣", "action": "閿�鍞嚭搴撴彁浜も啋OQC(妫�娴嬬粨鏋滄寜浜у搧绛夌骇 1鍨�/2鍨�/搴熷搧蹇呭~锛�1鍨�/2鍨嬪垽琛屽悎鏍硷紝搴熷搧鍒よ涓嶅悎鏍�)锛屽叏閮ㄥ悎鏍煎悗鍑哄簱鍗曡繘鍏ュ緟鎷h揣锛屽嚭鐜板簾鍝佸垯鏁村崟鍙栨秷", "roles": ["OQC 璐ㄦ鍛�"]},
{"stage": "閫�璐�", "action": "閫�鏂�/閿�鍞��璐�/鍞悗閫�璐р啋RQC锛岀粨璁哄洖璋冨崟鎹笌鍞悗", "roles": ["RQC 璐ㄦ鍛�"]},
- {"stage": "鎶ュ憡", "action": "妫�楠岀粨鏋滄寜鍒嗙粍鏍�+娴嬮噺鎵规褰曞叆锛�/indicator-result/report 鑱氬悎鍚庡墠绔墦鍗版楠屾姤鍛�(鍚噰鏍峰湴鐐�/璇佷功缂栧彿/鎵ц鏍囧噯/澶嶆牳路瀹℃牳绛惧瓧鍖�)锛�/indicator-result/export-product-word 瀵煎嚭浜у搧妫�楠屽崟Word(鏃犳妧鏈寚鏍囧垪路鍒ゅ畾缁撹/璐ㄦ绔�/妫�楠屄峰鏍嘎锋壒鍑嗙瀛楃暀绌烘墜濉稺ord鎵撳嵃锛涜鎯呮娴嬬粨鏋淭ab鍙寜鏍峰搧鏌ョ湅鍙鏄庣粏)", "roles": ["璐ㄦ鍛�", "澶嶆牳浜�", "瀹℃牳浜�"]},
+ {"stage": "鎶ュ憡", "action": "妫�楠岀粨鏋滄寜鍒嗙粍鏍�+娴嬮噺鎵规褰曞叆锛�/indicator-result/report 鑱氬悎鍚庡墠绔墦鍗版楠屾姤鍛�(鍚噰鏍峰湴鐐�/璇佷功缂栧彿/鎵ц鏍囧噯/鍒ゅ畾缁撹路璐ㄦ涓撶敤绔�/澶嶆牳路瀹℃牳绛惧瓧鍖猴紱鍒ゅ畾缁撹甯﹀嚭妫�楠岀粨鏋溌疯川妫�绔犵暀绌虹洊绔犅锋棤骞宠娴嬮噺鏃跺垪澶寸О娴嬮噺鍊�)锛�/indicator-result/export-product-word 瀵煎嚭浜у搧妫�楠屽崟Word(鏃犳妧鏈寚鏍囧垪路鍒ゅ畾缁撹甯﹀嚭妫�楠岀粨鏋溌疯川妫�绔�/妫�楠屄峰鏍嘎锋壒鍑嗙瀛楃暀绌烘墜濉峰钩琛屾祴閲忛】鍙峰悎骞堵蜂笅杞藉悗Word鎵撳嵃锛涜川妫�鍗曡鎯呮娴嬬粨鏋淭ab鍙寜鏍峰搧鏌ョ湅鍙妫�娴嬪�兼槑缁�)", "roles": ["璐ㄦ鍛�", "澶嶆牳浜�", "瀹℃牳浜�"]},
{"stage": "涓嶅悎鏍�", "action": "NCR: 寰呰瘎瀹♀啋璇勫鈫掑缃�(閫�璐�/鎶ュ簾/杩斿伐/璁╂鎺ユ敹/闄嶇骇)鈫掑叧闂�", "roles": ["璐ㄩ噺宸ョ▼甯�"]}]},
{"id": "warehouse", "name": "浠撳偍娴佺▼", "mermaid": "mermaid/06-warehouse-flow.mmd", "color": "#7e6bd6",
"summary": "15 绫诲崟鎹┍鍔ㄥ簱瀛樺彴璐�(鍏厓缁勩�佸洓閲�)鍙樺姩锛屽叏閮ㄧ粡浜嬪姟娴佹按鐣欑棔锛涙敮鎸佽皟鎷ㄥ湪閫斻�佺洏鐐硅皟鏁淬�佹壒娆�/SN 杩芥函銆佸簱瀛樺崰鐢ㄤ笌鍥涚骇鍐荤粨銆佺嚎杈硅櫄鎷熷簱璐熷簱瀛橈紱瀵瑰 WmsStockApi 渚� ERP 鏀跺彂銆�",
@@ -739,19 +739,25 @@
T4[鐢熶骇閫�鏂欏崟 鎴� 閿�鍞��璐у崟 鎴� 鍞悗閫�璐 --> A4[RQC 閫�璐ф楠屄疯崏绋�0鈫掑畬鎴�4]
A1 --> R{妫�楠屽垽瀹� MesQcCheckResultEnum}
A2 --> R
- A3 --> R
A4 --> R
R -->|1 鍚堟牸| Q1[鍏佽鍏ュ簱路鍥炲啓鏉ユ簮鍗曟嵁鎺ㄨ繘鐘舵�乚
R -->|2 鐗归噰| Q2[鍏佽鍏ュ簱路骞剁敓鎴怤CR鐣欑棔]
R -->|3 涓嶅悎鏍奸��璐 Q3[鐢熸垚NCR路璧颁緵搴斿晢閫�璐ф垨閿�鍞��璐
R -->|4 涓嶅悎鏍兼姤搴焲 Q4[鐢熸垚NCR路璧版姤搴熷嚭搴揮
+ A3 --> R2{鍑鸿揣鍒ゅ畾 MesQcOqcCheckResultEnum路蹇呭~}
+ R2 -->|1鍨�/2鍨媩 S1[鍑哄簱琛屽垽鍚堟牸路鎺ㄨ繘鍑哄簱鍗曞緟鎷h揣]
+ R2 -->|搴熷搧| S2[鍑哄簱琛屽垽涓嶅悎鏍悸峰彇娑堥攢鍞嚭搴撳崟]
+ A3 -.-> N5[琛ㄥご:鍙戣揣鏁伴噺/鍑鸿揣鏃ユ湡闈炲繀濉锋娴嬬粨鏋滃繀濉玗
+ A2 -.-> N6[琛ㄥご:鏉ユ簮鍗曟嵁鍙路浜у搧鐗╂枡(MDM)蹇呭~路鎵瑰彿蹇呭~路宸插幓鎺夌敓浜ц鍗�/宸ヤ綅/鐢熶骇浠诲姟/宸ュ簭]
A2 -->|鍚堟牸鏁伴噺| Q5[鎶ュ伐杞畬鎴惵蜂骇鍑烘媶琛屽叆搴揮
- A3 -->|瀹屾垚| Q6[閿�鍞嚭搴撳崟鎺ㄨ繘寰呮嫞璐
A4 -->|瀹屾垚| Q7[閫�璐у崟鎺ㄨ繘涓婃灦鎴栧叆搴撀峰敭鍚庡洖璋冪粨璁篯
N1[NCR 寰呰瘎瀹�0] -->|璇勫| N2[宸茶瘎瀹�6]
N2 -->|澶勭疆鏂瑰紡:閫�璐�1鎶ュ簾2杩斿伐3璁╂鎺ユ敹4闄嶇骇浣跨敤5| N3[宸插缃�7]
N3 -->|鍏抽棴| N4[宸插叧闂�8]
Q8[鏀拺鏁版嵁:璐ㄦ鏂规路妫�楠屾寚鏍嚶风己闄峰簱路鎸囨爣缁撴灉] --- A1
+ Q9[鍖栧伐鎶ュ憡澧炲己:鎸囨爣鍒嗙粍鏍�+鍏紡鏂囨湰路骞宠娴嬮噺鎵规路閲囨牱鍦扮偣/璇佷功缂栧彿/鎵ц鏍囧噯琛ㄥご路澶嶆牳浜�/瀹℃牳浜篯 --- Q8
+ A1 & A2 & A3 & A4 --> P1[妫�楠屾姤鍛婂崟鎵撳嵃路鍓嶇娴忚鍣ㄦ墦鍗奥峰垽瀹氱粨璁哄甫鍑烘楠岀粨鏋�+璐ㄦ涓撶敤绔犵暀绌虹洊绔�+绛惧瓧鍖郝锋棤骞宠娴嬮噺鏃跺垪澶寸О娴嬮噺鍊糫
+ A1 & A2 & A3 & A4 --> P2[浜у搧妫�楠屽崟Word瀵煎嚭路export-product-word路鏃犳妧鏈寚鏍囧垪路鍒ゅ畾缁撹甯﹀嚭妫�楠岀粨鏋�/璐ㄦ绔犵暀绌虹洊绔犅稺ord鎵撳嵃]
</pre>
<pre style="display:none" class="mmd-src" data-mmd="06-warehouse-flow">
flowchart LR
@@ -932,7 +938,7 @@
J4 --> J5[璐ㄦ鍛樺弬鑰冨垽瀹毬稟I涓嶅彲鐢ㄦ椂鎻愮ず浜哄伐鍒ゅ畾]
R1[宸ュ崟BOM+搴撳瓨鍙敤閲�+宸叉姇鏂橾 --> R2[鐗╂枡鐭己棰勬祴路椋庨櫓绛夌骇涓庣己鍙f竻鍗昡
R3[宸ュ簭鏍囧噯宸ユ椂+璁惧姣忓皬鏃朵骇閲�+浼犻�佸�嶇巼] --> R4[鐢熶骇鏃堕暱棰勬祴]
- R5[IPQC缂洪櫡鐜�+璁惧淇濆吇鐐规+鐗╂枡鍙敤鐜�+鍏抽敭宸ュ簭] --> R6[鐢熶骇椋庨櫓棰勬祴]
+ R5[璁惧淇濆吇鐐规+鐗╂枡鍙敤鐜�+鍏抽敭宸ュ簭] --> R6[鐢熶骇椋庨櫓棰勬祴]
R7[杩涘害+鍓╀綑澶╂暟+浠诲姟瀹屾垚鐘舵��+瀹㈡埛浜ゆ湡] --> R8[浜や粯棰勬祴路鑳藉惁鎸夋椂+缃俊搴�+寤惰鍥犵礌]
KB1[鐭ヨ瘑搴撴枃妗d笂浼燯RL] --> KB2[POI/Tika鎻愬彇鏂囨湰] --> KB3[鍒囩墖绾�800tokens鈫掑悜閲忓寲鈫扢ilvus]
KB3 --> KB4[鍒嗘妫�绱㈡帴鍙� topK+鐩镐技搴﹂槇鍊糫
diff --git a/docs/project-business/mermaid/05-quality-flow.mmd b/docs/project-business/mermaid/05-quality-flow.mmd
index af16dd4..3b21b28 100644
--- a/docs/project-business/mermaid/05-quality-flow.mmd
+++ b/docs/project-business/mermaid/05-quality-flow.mmd
@@ -5,19 +5,22 @@
T4[鐢熶骇閫�鏂欏崟 鎴� 閿�鍞��璐у崟 鎴� 鍞悗閫�璐 --> A4[RQC 閫�璐ф楠屄疯崏绋�0鈫掑畬鎴�4]
A1 --> R{妫�楠屽垽瀹� MesQcCheckResultEnum}
A2 --> R
- A3 --> R
A4 --> R
R -->|1 鍚堟牸| Q1[鍏佽鍏ュ簱路鍥炲啓鏉ユ簮鍗曟嵁鎺ㄨ繘鐘舵�乚
R -->|2 鐗归噰| Q2[鍏佽鍏ュ簱路骞剁敓鎴怤CR鐣欑棔]
R -->|3 涓嶅悎鏍奸��璐 Q3[鐢熸垚NCR路璧颁緵搴斿晢閫�璐ф垨閿�鍞��璐
R -->|4 涓嶅悎鏍兼姤搴焲 Q4[鐢熸垚NCR路璧版姤搴熷嚭搴揮
+ A3 --> R2{鍑鸿揣鍒ゅ畾 MesQcOqcCheckResultEnum路蹇呭~}
+ R2 -->|1鍨�/2鍨媩 S1[鍑哄簱琛屽垽鍚堟牸路鎺ㄨ繘鍑哄簱鍗曞緟鎷h揣]
+ R2 -->|搴熷搧| S2[鍑哄簱琛屽垽涓嶅悎鏍悸峰彇娑堥攢鍞嚭搴撳崟]
+ A3 -.-> N5[琛ㄥご:鍙戣揣鏁伴噺/鍑鸿揣鏃ユ湡闈炲繀濉锋娴嬬粨鏋滃繀濉玗
+ A2 -.-> N6[琛ㄥご:鏉ユ簮鍗曟嵁鍙路浜у搧鐗╂枡(MDM)蹇呭~路鎵瑰彿蹇呭~路宸插幓鎺夌敓浜ц鍗�/宸ヤ綅/鐢熶骇浠诲姟/宸ュ簭]
A2 -->|鍚堟牸鏁伴噺| Q5[鎶ュ伐杞畬鎴惵蜂骇鍑烘媶琛屽叆搴揮
- A3 -->|瀹屾垚| Q6[閿�鍞嚭搴撳崟鎺ㄨ繘寰呮嫞璐
A4 -->|瀹屾垚| Q7[閫�璐у崟鎺ㄨ繘涓婃灦鎴栧叆搴撀峰敭鍚庡洖璋冪粨璁篯
N1[NCR 寰呰瘎瀹�0] -->|璇勫| N2[宸茶瘎瀹�6]
N2 -->|澶勭疆鏂瑰紡:閫�璐�1鎶ュ簾2杩斿伐3璁╂鎺ユ敹4闄嶇骇浣跨敤5| N3[宸插缃�7]
N3 -->|鍏抽棴| N4[宸插叧闂�8]
Q8[鏀拺鏁版嵁:璐ㄦ鏂规路妫�楠屾寚鏍嚶风己闄峰簱路鎸囨爣缁撴灉] --- A1
Q9[鍖栧伐鎶ュ憡澧炲己:鎸囨爣鍒嗙粍鏍�+鍏紡鏂囨湰路骞宠娴嬮噺鎵规路閲囨牱鍦扮偣/璇佷功缂栧彿/鎵ц鏍囧噯琛ㄥご路澶嶆牳浜�/瀹℃牳浜篯 --- Q8
- A1 & A2 & A3 & A4 --> P1[妫�楠屾姤鍛婂崟鎵撳嵃路鍓嶇娴忚鍣ㄦ墦鍗奥峰惈绛惧瓧鍖篯
- A1 & A2 & A3 & A4 --> P2[浜у搧妫�楠屽崟Word瀵煎嚭路export-product-word路鏃犳妧鏈寚鏍囧垪路鍒ゅ畾缁撹/璐ㄦ绔犵暀绌烘墜濉稺ord鎵撳嵃]
+ A1 & A2 & A3 & A4 --> P1[妫�楠屾姤鍛婂崟鎵撳嵃路鍓嶇娴忚鍣ㄦ墦鍗奥峰垽瀹氱粨璁哄甫鍑烘楠岀粨鏋�+璐ㄦ涓撶敤绔犵暀绌虹洊绔�+绛惧瓧鍖郝锋棤骞宠娴嬮噺鏃跺垪澶寸О娴嬮噺鍊糫
+ A1 & A2 & A3 & A4 --> P2[浜у搧妫�楠屽崟Word瀵煎嚭路export-product-word路鏃犳妧鏈寚鏍囧垪路鍒ゅ畾缁撹甯﹀嚭妫�楠岀粨鏋�/璐ㄦ绔犵暀绌虹洊绔犅稺ord鎵撳嵃]
diff --git a/docs/project-business/mermaid/11-ai-business-flow.mmd b/docs/project-business/mermaid/11-ai-business-flow.mmd
index 947d2eb..94f13cf 100644
--- a/docs/project-business/mermaid/11-ai-business-flow.mmd
+++ b/docs/project-business/mermaid/11-ai-business-flow.mmd
@@ -15,7 +15,7 @@
J4 --> J5[璐ㄦ鍛樺弬鑰冨垽瀹毬稟I涓嶅彲鐢ㄦ椂鎻愮ず浜哄伐鍒ゅ畾]
R1[宸ュ崟BOM+搴撳瓨鍙敤閲�+宸叉姇鏂橾 --> R2[鐗╂枡鐭己棰勬祴路椋庨櫓绛夌骇涓庣己鍙f竻鍗昡
R3[宸ュ簭鏍囧噯宸ユ椂+璁惧姣忓皬鏃朵骇閲�+浼犻�佸�嶇巼] --> R4[鐢熶骇鏃堕暱棰勬祴]
- R5[IPQC缂洪櫡鐜�+璁惧淇濆吇鐐规+鐗╂枡鍙敤鐜�+鍏抽敭宸ュ簭] --> R6[鐢熶骇椋庨櫓棰勬祴]
+ R5[璁惧淇濆吇鐐规+鐗╂枡鍙敤鐜�+鍏抽敭宸ュ簭] --> R6[鐢熶骇椋庨櫓棰勬祴]
R7[杩涘害+鍓╀綑澶╂暟+浠诲姟瀹屾垚鐘舵��+瀹㈡埛浜ゆ湡] --> R8[浜や粯棰勬祴路鑳藉惁鎸夋椂+缃俊搴�+寤惰鍥犵礌]
KB1[鐭ヨ瘑搴撴枃妗d笂浼燯RL] --> KB2[POI/Tika鎻愬彇鏂囨湰] --> KB3[鍒囩墖绾�800tokens鈫掑悜閲忓寲鈫扢ilvus]
KB3 --> KB4[鍒嗘妫�绱㈡帴鍙� topK+鐩镐技搴﹂槇鍊糫
diff --git a/docs/qc_chemical_report_integration.md b/docs/qc_chemical_report_integration.md
index c0ca1d2..0a2b546 100644
--- a/docs/qc_chemical_report_integration.md
+++ b/docs/qc_chemical_report_integration.md
@@ -50,6 +50,7 @@
"samplingTime": "2026-08-30T01:00:00",
"batchQuantity": 30,
"checkResult": 1,
+ "checkResultText": "鏍¢獙閫氳繃",
"inspectorName": "鏂拌壋",
"auditName": "娴蜂附",
"approveName": "鐜嬩簲",
@@ -83,8 +84,10 @@
| 璇佷功缂栧彿 / 閲囨牱鍦扮偣 / 鎵归噺 / 閲囨牱鏃堕棿 / 鎵ц鏍囧噯 | report 鍚屽悕瀛楁 |
| 鍒嗙粍琛岋紙姘村垎/閰稿惈閲忊�︼級 | itemType=2 鑺傜偣锛氬悕绉拌 + 鍏紡鏂囨湰(formulaText) |
| 鍙傛暟琛�/缁撴灉琛� | 鍒嗙粍 children 褰曞叆椤癸紝鎸� sortOrder 鎺掑簭 |
-| 骞宠娴嬮噺涓ゅ垪 | measureNos 鏁扮粍椹卞姩鍒楀ご锛屾瘡 measureNo 涓�鍒� |
+| 骞宠娴嬮噺鍒楀ご | measureNos 鏁扮粍椹卞姩锛涗粎涓�鍒楁椂鍒楀ご鏄剧ず銆屾祴閲忓�笺�嶏紝澶氬垪鏃舵樉绀恒�屾祴閲�1銆嶃�屾祴閲�2銆嶁�� |
| 澶栬绛夊畾鎬ч」 | resultType=鏂囨湰/瀛楀吀 鐨勫綍鍏ラ」鐩存帴鏄剧ず value |
+| 鍒ゅ畾缁撹 | `checkResultText`锛堝悗绔寜 qcType 瀵瑰簲瀛楀吀瑙f瀽锛� |
+| 璐ㄦ涓撶敤绔� | 鏃犳暟鎹潵婧愶紝鐣欏嚭绌虹櫧鍗曞厓鏍间緵鎵撳嵃鍚庝汉宸ョ洊绔� |
| 鍒嗘瀽鑰�/澶嶆牳浜�/瀹℃牳浜� | inspectorName / auditName / approveName |
## 涓氬姟瑙勫垯
@@ -101,6 +104,7 @@
- 鎵撳嵃涓烘祻瑙堝櫒 `window.print()`锛屽缓璁湪 Chrome 涓嬮瑙堬紱闅愯棌鎵撳嵃澶栧叾浠栧厓绱犵敱缁勪欢鍐� `@media print` 鎺у埗銆�
- `/report` 鐨� `qcType`锛�1=IQC銆�2=IPQC銆�3=OQC銆�4=RQC锛屼笌 `MesQcTypeEnum` 涓�鑷淬��
+- 鍒ゅ畾缁撹鏂囨鐢卞悗绔寜 `qcType` 閫夊瓧鍏歌В鏋愶細OQC 璧� `mes_oqc_check_result`锛�1鍨�/2鍨�/搴熷搧锛夛紝IQC/IPQC/RQC 璧� `mes_qc_check_result`锛堟牎楠岄�氳繃/鏍¢獙涓嶉�氳繃锛夈�傛湭鍒ゅ畾锛坄checkResult` 涓虹┖锛夋椂鎵撳嵃涓恒��-銆嶏紝鍓嶇鍙洖閫�鎸� `checkResult` 鑷鍙栧瓧鍏告爣绛俱��
- 澶嶆牳浜�/瀹℃牳浜轰粎浣滀负璁板綍涓庢墦鍗扮瀛楀尯锛屼笉寮曞叆瀹℃壒娴佽浆銆�
- 鏂囦欢闄勪欢绫绘寚鏍囷紙resultType=鏂囦欢锛夋部鐢ㄥ師鏈哄埗锛屾湭鍦ㄦ湰娆¤寖鍥淬��
- 鍥炲綊鐐癸細鏃㈡湁鎵佸钩鎸囨爣鐨勮�佹楠屽崟锛堝綍鍏�/瀹屾垚/Excel 瀵煎嚭锛夎涓轰笉鍙橈紱`measure_no` 榛樿 1 瀵硅�佹暟鎹�忔槑銆�
diff --git a/docs/sql/config_export_all_20260904.sql b/docs/sql/config_export_all_20260904.sql
index d91386f..754c734 100644
--- a/docs/sql/config_export_all_20260904.sql
+++ b/docs/sql/config_export_all_20260904.sql
@@ -988,6 +988,7 @@
('2046', 'MES 缁翠慨宸ュ崟鐘舵��', 'mes_dv_repair_status', '0', 'MES 璁惧绠$悊 - 缁翠慨宸ュ崟鐘舵�侊紙10=寰呯淮淇紝20=缁翠慨涓紝30=宸插畬鎴愶紝40=宸查獙鏀讹級', '1', '2026-02-20 10:56:24', '1', '2026-02-20 10:56:24', X'00', NULL),
('2047', 'MES 缁翠慨缁撴灉', 'mes_dv_repair_result', '0', 'MES 璁惧绠$悊 - 缁翠慨缁撴灉锛�1=淇鎴愬姛锛�2=鎶ュ簾锛�', '1', '2026-02-20 10:56:24', '1', '2026-02-20 10:56:24', X'00', NULL),
('2049', 'MES 妫�娴嬬粨鏋�', 'mes_qc_check_result', '0', '鏉ユ枡妫�楠岀殑鏈�缁堢粨鏋滃垽瀹�', '1', '2026-02-20 11:23:35', '1', '2026-02-20 11:23:35', X'00', NULL),
+('1065400', 'MES 鍑鸿揣妫�楠屾娴嬬粨鏋�', 'mes_oqc_check_result', '0', '鍑鸿揣妫�楠屽崟(OQC)鍒ゅ畾缁撴灉锛�1鍨�/2鍨嬩负鍙彂璐х瓑绾э紝搴熷搧涓嶆斁琛�', '1', '2026-09-22 00:00:00', '1', '2026-09-22 00:00:00', X'00', NULL),
('2050', 'MES 鏉ユ簮鍗曟嵁绫诲瀷', 'mes_qc_source_doc_type', '0', 'IQC 鏉ユ枡妫�楠岀殑鏉ユ簮鍗曟嵁绫诲瀷', '1', '2026-02-20 11:23:35', '1', '2026-02-20 11:23:35', X'00', NULL),
('2051', 'MES 瀹夌伅澶勭疆鐘舵��', 'mes_pro_andon_status', '0', 'MES 鐢熶骇绠$悊 - 瀹夌伅澶勭疆鐘舵�侊紙0=鏈缃紝1=宸插缃級', '1', '2026-02-21 00:08:38', '1', '2026-02-21 00:08:38', X'00', NULL),
('2052', 'MES 瀹夌伅绾у埆', 'mes_pro_andon_level', '0', 'MES 鐢熶骇绠$悊 - 瀹夌伅绾у埆锛�1=涓�绾э紝2=浜岀骇锛�3=涓夌骇锛�', '1', '2026-02-21 00:08:38', '1', '2026-02-21 00:08:38', X'00', NULL),
@@ -1822,6 +1823,9 @@
('3158', '2', '鎶ュ簾', '2', 'mes_dv_repair_result', '0', 'danger', '', '', '1', '2026-02-20 10:56:24', '1', '2026-02-20 10:56:24', X'00'),
('3161', '1', '鏍¢獙閫氳繃', '1', 'mes_qc_check_result', '0', 'success', '', '', '1', '2026-02-20 11:23:35', '1', '2026-02-20 16:15:54', X'00'),
('3162', '2', '鏍¢獙涓嶉�氳繃', '2', 'mes_qc_check_result', '0', 'danger', '', '', '1', '2026-02-20 11:23:35', '1', '2026-02-20 16:15:52', X'00'),
+('1065401', '1', '1鍨�', '1', 'mes_oqc_check_result', '0', 'success', '', '', '1', '2026-09-22 00:00:00', '1', '2026-09-22 00:00:00', X'00'),
+('1065402', '2', '2鍨�', '2', 'mes_oqc_check_result', '0', 'primary', '', '', '1', '2026-09-22 00:00:00', '1', '2026-09-22 00:00:00', X'00'),
+('1065403', '3', '搴熷搧', '3', 'mes_oqc_check_result', '0', 'danger', '', '', '1', '2026-09-22 00:00:00', '1', '2026-09-22 00:00:00', X'00'),
('3166', '0', '鏈缃�', '0', 'mes_pro_andon_status', '0', 'danger', '', '', '1', '2026-02-21 00:08:38', '1', '2026-02-21 00:08:38', X'00'),
('3167', '1', '宸插缃�', '1', 'mes_pro_andon_status', '0', 'success', '', '', '1', '2026-02-21 00:08:38', '1', '2026-02-21 00:08:38', X'00'),
('3168', '1', '涓�绾�', '1', 'mes_pro_andon_level', '0', 'danger', '', '', '1', '2026-02-21 00:08:38', '1', '2026-02-21 00:08:38', X'00'),
@@ -7995,10 +7999,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/controller/admin/qc/indicatorresult/MesQcIndicatorResultController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/MesQcIndicatorResultController.java
index 6a8021e..831586b 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/MesQcIndicatorResultController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/MesQcIndicatorResultController.java
@@ -143,7 +143,7 @@
}
@GetMapping("/export-product-word")
- @Operation(summary = "瀵煎嚭浜у搧妫�楠屽崟 Word锛堢焊璐ㄦ楠屽崟鐗堝紡锛氭棤鎶�鏈寚鏍囧垪锛屽垽瀹氱粨璁�/璐ㄦ涓撶敤绔犵暀绌烘墜濉紝鎵撳嵃鐢� Word 鎵撳紑锛�")
+ @Operation(summary = "瀵煎嚭浜у搧妫�楠屽崟 Word锛堢焊璐ㄦ楠屽崟鐗堝紡锛氭棤鎶�鏈寚鏍囧垪锛屽垽瀹氱粨璁鸿嚜鍔ㄥ甫鍑烘楠岀粨鏋溿�佽川妫�涓撶敤绔犵暀绌虹洊绔狅紝鎵撳嵃鐢� Word 鎵撳紑锛�")
@Parameters({
@Parameter(name = "qcId", description = "璐ㄦ鍗旾D", required = true, example = "1"),
@Parameter(name = "qcType", description = "璐ㄦ绫诲瀷", required = true, example = "1"),
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcQcReportRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcQcReportRespVO.java
index 9ca3a6f..c957b5d 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcQcReportRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/indicatorresult/vo/MesQcQcReportRespVO.java
@@ -49,9 +49,12 @@
@Schema(description = "鎵归噺锛堟潵鏂�=鎺ユ敹鏁伴噺锛岃繃绋�/閫�璐�=妫�娴嬫暟閲忥紝鍑鸿揣=鍑鸿揣鏁伴噺锛�", example = "30")
private BigDecimal batchQuantity;
- @Schema(description = "妫�娴嬬粨鏋滐紙瀛楀吀 mes_qc_check_result锛�", example = "1")
+ @Schema(description = "妫�娴嬬粨鏋滐紙IQC/IPQC/RQC=瀛楀吀 mes_qc_check_result锛汷QC=瀛楀吀 mes_oqc_check_result锛�", example = "1")
private Integer checkResult;
+ @Schema(description = "妫�娴嬬粨鏋滄枃妗堬紙鎸夎川妫�绫诲瀷瀵瑰簲瀛楀吀瑙f瀽锛屼緵鍒ゅ畾缁撹灞曠ず锛涙湭鍒ゅ畾鏃朵负绌猴級", example = "鏍¢獙閫氳繃")
+ private String checkResultText;
+
@Schema(description = "妫�楠屾棩鏈�", example = "2026-08-30T01:00:00")
private LocalDateTime inspectDate;
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 39682ab..2030742 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
@@ -15,9 +15,6 @@
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;
@@ -28,9 +25,6 @@
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;
@@ -69,12 +63,6 @@
@Resource
private MesQcIpqcService ipqcService;
- @Resource
- private MesProWorkOrderService workOrderService;
- @Resource
- private MesMdWorkstationService workstationService;
- @Resource
- private MesProProcessService processService;
@Resource
private MesMdItemService itemService;
@Resource
@@ -157,15 +145,6 @@
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(
convertSet(list, MesQcIpqcDO::getItemId));
@@ -182,12 +161,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(),
@@ -289,8 +262,7 @@
vo.setDocName(ipqc.getName());
MesMdItemDO 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/vo/MesQcIpqcPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/ipqc/vo/MesQcIpqcPageReqVO.java
index 8221b17..488603f 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 = "BC20250101")
+ 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 3df24d5..b91a0b2 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,34 +50,9 @@
@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 = "鎵瑰彿", example = "BC20250101")
+ @ExcelProperty("鎵瑰彿")
+ private String batchCode;
// ========== 鐗╂枡 ==========
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 ba73cf7..8214c1d 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
@@ -42,25 +42,14 @@
@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 = "鎵瑰彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "BC20250101")
+ @NotEmpty(message = "鎵瑰彿涓嶈兘涓虹┖")
+ private String batchCode;
// ========== 鐗╂枡 ==========
- @Schema(description = "浜у搧鐗╂枡 ID", example = "50")
+ @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/oqc/MesQcOqcController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/MesQcOqcController.java
index a8cfea2..40d7285 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
@@ -285,7 +285,7 @@
return "";
}
return DictFrameworkUtils.parseDictDataLabel(
- DictTypeConstants.MES_QC_CHECK_RESULT, String.valueOf(checkResult));
+ DictTypeConstants.MES_OQC_CHECK_RESULT, String.valueOf(checkResult));
}
/**
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 fab9c40..4d1bec6 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
@@ -127,7 +127,7 @@
@Schema(description = "妫�娴嬬粨鏋�", example = "1")
@ExcelProperty(value = "妫�娴嬬粨鏋�", converter = DictConvert.class)
- @DictFormat(DictTypeConstants.MES_QC_CHECK_RESULT)
+ @DictFormat(DictTypeConstants.MES_OQC_CHECK_RESULT)
private Integer checkResult;
// ========== 妫�楠岄」鎸囨爣 ==========
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 6e9b826..0738fee 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
@@ -54,8 +54,7 @@
// ========== 鏁伴噺 ==========
- @Schema(description = "鏈鍑鸿揣鏁伴噺", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
- @NotNull(message = "鏈鍑鸿揣鏁伴噺涓嶈兘涓虹┖")
+ @Schema(description = "鏈鍑鸿揣鏁伴噺", example = "100")
@DecimalMin(value = "0", message = "鏈鍑鸿揣鏁伴噺涓嶈兘灏忎簬 0")
private BigDecimal outQuantity;
@@ -76,11 +75,11 @@
// ========== 妫�楠� ==========
- @Schema(description = "妫�娴嬬粨鏋�", example = "1")
+ @Schema(description = "妫�娴嬬粨鏋�", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "妫�娴嬬粨鏋滀笉鑳戒负绌�")
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/vo/MesQcPendingInspectRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/pendinginspect/vo/MesQcPendingInspectRespVO.java
index effe2a5..fd8a276 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
@@ -41,6 +41,9 @@
@Schema(description = "鍗曚綅鍚嶇О", example = "涓�")
private String unitName;
+ @Schema(description = "鎵瑰彿锛堝綋鍓嶄粎 IPQC 鏉ユ簮鎻愪緵锛�", example = "BC20250101")
+ private String batchCode;
+
// ========== 鏁伴噺 ==========
@Schema(description = "寰呮鏁伴噺", example = "100.00")
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 f06c921..c309810 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
@@ -2,9 +2,7 @@
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;
@@ -86,32 +84,10 @@
*/
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;
// ========== 鐗╂枡 ==========
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcDO.java
index c66a438..724be95 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcDO.java
@@ -156,8 +156,8 @@
/**
* 妫�娴嬬粨鏋�
*
- * 瀛楀吀 {@link DictTypeConstants#MES_QC_CHECK_RESULT}
- * 鏋氫妇 {@link cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum}
+ * 瀛楀吀 {@link DictTypeConstants#MES_OQC_CHECK_RESULT}
+ * 鏋氫妇 {@link cn.iocoder.yudao.module.mes.enums.qc.MesQcOqcCheckResultEnum}
*/
private Integer checkResult;
/**
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/enums/DictTypeConstants.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/DictTypeConstants.java
index 71b6607..147f33f 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/DictTypeConstants.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/DictTypeConstants.java
@@ -78,7 +78,8 @@
String MES_IPQC_TYPE = "mes_ipqc_type"; // MES IPQC 妫�楠岀被鍨�
String MES_RQC_TYPE = "mes_rqc_type"; // MES 閫�璐ф楠岀被鍨�
String MES_ORDER_STATUS = "mes_order_status"; // MES 鍗曟嵁鐘舵�侊紙IQC/IPQC/OQC/RQC 閫氱敤锛�
- String MES_QC_CHECK_RESULT = "mes_qc_check_result"; // MES 妫�娴嬬粨鏋�
+ String MES_QC_CHECK_RESULT = "mes_qc_check_result"; // MES 妫�娴嬬粨鏋滐紙IQC/IPQC/RQC 鍏辩敤锛�
+ String MES_OQC_CHECK_RESULT = "mes_oqc_check_result"; // MES 鍑鸿揣妫�楠屾娴嬬粨鏋滐紙OQC 涓撶敤锛�
String MES_QC_SOURCE_DOC_TYPE = "mes_qc_source_doc_type"; // MES 鏉ユ簮鍗曟嵁绫诲瀷
String MES_NCR_STATUS = "mes_ncr_status"; // MES NCR 鐘舵��
String MES_NCR_DISPOSITION = "mes_ncr_disposition"; // MES NCR 澶勭疆鏂瑰紡
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcOqcCheckResultEnum.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcOqcCheckResultEnum.java
new file mode 100644
index 0000000..19b45b2
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/qc/MesQcOqcCheckResultEnum.java
@@ -0,0 +1,51 @@
+package cn.iocoder.yudao.module.mes.enums.qc;
+
+import cn.iocoder.yudao.framework.common.core.ArrayValuable;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+
+/**
+ * MES 鍑鸿揣妫�楠屽崟妫�娴嬬粨鏋滄灇涓撅紙OQC 涓撶敤锛�
+ *
+ * <p>涓� IQC/IPQC/RQC 鍏辩敤鐨� {@link MesQcCheckResultEnum} 涓嶅悓锛屽嚭璐ф楠屾寜浜у搧绛夌骇鍒ゅ畾锛�
+ * 瀛楀吀 {@link cn.iocoder.yudao.module.mes.enums.DictTypeConstants#MES_OQC_CHECK_RESULT}</p>
+ */
+@Getter
+@AllArgsConstructor
+public enum MesQcOqcCheckResultEnum implements ArrayValuable<Integer> {
+
+ TYPE_1(1, "1鍨�"),
+ TYPE_2(2, "2鍨�"),
+ SCRAP(3, "搴熷搧");
+
+ public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesQcOqcCheckResultEnum::getType).toArray(Integer[]::new);
+
+ /**
+ * 缁撴灉鍊�
+ */
+ private final Integer type;
+ /**
+ * 缁撴灉鍚�
+ */
+ private final String name;
+
+ @Override
+ public Integer[] array() {
+ return ARRAYS;
+ }
+
+ /**
+ * 鍒ゆ柇鏄惁鍙互鏀捐鍙戣揣
+ *
+ * <p>1 鍨嬨��2 鍨嬪潎涓哄彲鍙戣揣绛夌骇锛屼粎搴熷搧涓嶆斁琛�</p>
+ *
+ * @param type 妫�娴嬬粨鏋�
+ * @return true 鍙互鏀捐
+ */
+ public static boolean canShip(Integer type) {
+ return type != null && !SCRAP.getType().equals(type);
+ }
+
+}
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..00591b4 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
@@ -19,7 +19,6 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderBomDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderProcessDO;
-import cn.iocoder.yudao.module.mes.dal.dataobject.qc.ipqc.MesQcIpqcDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
import cn.iocoder.yudao.module.mes.dal.mysql.dv.machinery.MesDvMachineryMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationMachineMapper;
@@ -28,7 +27,6 @@
import cn.iocoder.yudao.module.mes.dal.mysql.pro.task.MesProTaskIssueMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.pro.task.MesProTaskMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderBomMapper;
-import cn.iocoder.yudao.module.mes.dal.mysql.qc.ipqc.MesQcIpqcMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.materialstock.MesWmMaterialStockMapper;
import cn.iocoder.yudao.module.mes.service.pro.mps.MesProMpsService;
import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService;
@@ -101,14 +99,13 @@
浣犻渶瑕佺患鍚堝垎鏋愪互涓嬩俊鎭紝缁欏嚭涓撲笟鐨勯闄╄瘎浼帮細
## 鍒嗘瀽缁村害
- 1. 璐ㄩ噺椋庨櫓锛氳繃绋嬫楠�(IPQC)鐨勭己闄风巼鏁版嵁锛堣嚧鍛�/涓ラ噸/杞诲井缂洪櫡鐜囷級
- 2. 璁惧椋庨櫓锛氳澶囩姸鎬併�佷笂娆′繚鍏绘椂闂淬�佷笂娆$偣妫�鏃堕棿銆佺敓浜ф晥鐜�
- 3. 鐗╂枡椋庨櫓锛氱墿鏂欏簱瀛樺彲鐢ㄩ噺涓庨渶姹傞噺鐨勫姣�
- 4. 宸ヨ壓鐡堕锛氬叧閿伐搴忕殑璁惧浜ц兘銆佷换鍔℃帓闃熸儏鍐�
+ 1. 璁惧椋庨櫓锛氳澶囩姸鎬併�佷笂娆′繚鍏绘椂闂淬�佷笂娆$偣妫�鏃堕棿銆佺敓浜ф晥鐜�
+ 2. 鐗╂枡椋庨櫓锛氱墿鏂欏簱瀛樺彲鐢ㄩ噺涓庨渶姹傞噺鐨勫姣�
+ 3. 宸ヨ壓鐡堕锛氬叧閿伐搴忕殑璁惧浜ц兘銆佷换鍔℃帓闃熸儏鍐�
## 椋庨櫓绛夌骇瀹氫箟
- - 楂橈細瀛樺湪鑷村懡缂洪櫡鐜�>5% 鎴� 璁惧鏁呴殰 鎴� 鍏抽敭鐗╂枡鐭己>50% 鎴� 鍏抽敭宸ュ簭涓ラ噸绉帇
- - 涓細瀛樺湪涓ラ噸缂洪櫡鐜�>10% 鎴� 璁惧闀挎湡鏈繚鍏� 鎴� 鐗╂枡绱у紶
+ - 楂橈細瀛樺湪璁惧鏁呴殰 鎴� 鍏抽敭鐗╂枡鐭己>50% 鎴� 鍏抽敭宸ュ簭涓ラ噸绉帇
+ - 涓細瀛樺湪璁惧闀挎湡鏈繚鍏� 鎴� 鐗╂枡绱у紶
- 浣庯細鍚勯」鎸囨爣姝e父
## 杈撳嚭鏍煎紡
@@ -118,7 +115,7 @@
overallRiskLevel 鍙栧�硷細1=浣庨闄� 2=涓闄� 3=楂橀闄�
riskLevel 鍙栧�硷細鍏呰冻/绱у紶/鐭己
severity 鍙栧�硷細楂�/涓�/浣�
- category 鍙栧�硷細璐ㄩ噺/璁惧/鐗╂枡/宸ヨ壓鐡堕
+ category 鍙栧�硷細璁惧/鐗╂枡/宸ヨ壓鐡堕
""";
private static final String SYSTEM_PROMPT_DELIVERY = """
@@ -159,8 +156,6 @@
private MesProTaskIssueMapper taskIssueMapper;
@Resource
private MesProFeedbackMapper feedbackMapper;
- @Resource
- private MesQcIpqcMapper ipqcMapper;
@Resource
private MesWmMaterialStockMapper materialStockMapper;
@Resource
@@ -523,26 +518,6 @@
data.put("璁″垝鏁伴噺", workOrder.getQuantity());
data.put("宸茬敓浜ф暟閲�", workOrder.getQuantityProduced());
fillItemInfo(data, workOrder.getProductId());
-
- // 璐ㄩ噺椋庨櫓 - IPQC
- List<MesQcIpqcDO> ipqcList = ipqcMapper.selectList(
- new LambdaQueryWrapper<MesQcIpqcDO>()
- .eq(MesQcIpqcDO::getWorkOrderId, workOrderId));
- if (CollUtil.isNotEmpty(ipqcList)) {
- List<Map<String, Object>> qcData = ipqcList.stream().map(ipqc -> {
- Map<String, Object> item = new LinkedHashMap<>();
- item.put("妫�楠屽崟缂栧彿", ipqc.getCode());
- item.put("鑷村懡缂洪櫡鐜�", ipqc.getCriticalRate() != null ? ipqc.getCriticalRate() + "%" : "0%");
- item.put("涓ラ噸缂洪櫡鐜�", ipqc.getMajorRate() != null ? ipqc.getMajorRate() + "%" : "0%");
- item.put("杞诲井缂洪櫡鐜�", ipqc.getMinorRate() != null ? ipqc.getMinorRate() + "%" : "0%");
- item.put("鑷村懡缂洪櫡鏁�", ipqc.getCriticalQuantity() != null ? ipqc.getCriticalQuantity() : 0);
- item.put("涓ラ噸缂洪櫡鏁�", ipqc.getMajorQuantity() != null ? ipqc.getMajorQuantity() : 0);
- item.put("杞诲井缂洪櫡鏁�", ipqc.getMinorQuantity() != null ? ipqc.getMinorQuantity() : 0);
- item.put("妫�楠岀粨鏋�", ipqc.getCheckResult());
- return item;
- }).collect(Collectors.toList());
- data.put("杩囩▼妫�楠�(IPQC)璁板綍", qcData);
- }
// 璁惧椋庨櫓
List<MesProTaskDO> tasks = taskMapper.selectListByWorkOrderId(workOrderId);
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/indicatorresult/MesQcProductReportWordBuilder.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcProductReportWordBuilder.java
index bee442a..1fca7f8 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcProductReportWordBuilder.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcProductReportWordBuilder.java
@@ -18,7 +18,7 @@
* 浜у搧妫�楠屽崟锛堢焊璐�"脳脳浜у搧璐ㄩ噺妫�楠屽崟"鐗堝紡锛塛ord 鏋勫缓鍣�
*
* 鐗堝紡锛氭爣棰橈紙鍏徃 + 浜у搧妫�楠屽崟锛夆啋 琛ㄥご淇℃伅 5 琛� 鈫� 妫�楠岄」鐩�/妫�楠岀粨鏋� 涓ゅ垪鐭╅樀 鈫�
- * 鍒ゅ畾缁撹/璐ㄦ涓撶敤绔狅紙鐣欑┖锛屾墦鍗板悗鎵嬪~锛夆啋 澶囨敞 鈫� 妫�楠�/澶嶆牳/鎵瑰噯绛惧瓧琛屻��
+ * 鍒ゅ畾缁撹锛堣嚜鍔ㄥ甫鍑烘楠岀粨鏋滐級/璐ㄦ涓撶敤绔狅紙鐣欑┖鐩栫珷锛夆啋 澶囨敞 鈫� 妫�楠�/澶嶆牳/鎵瑰噯绛惧瓧琛屻��
* 涓嶅惈鎶�鏈寚鏍囧垪锛涘垎缁勯」涓嶅睍绀猴紝褰曞叆椤瑰钩閾猴紱骞宠娴嬮噺澶氬�奸】鍙峰悎骞躲��
*/
public class MesQcProductReportWordBuilder {
@@ -51,7 +51,7 @@
writeTitle(doc, report);
writeHeaderTable(doc, report);
writeItemTable(doc, report);
- writeConclusionTable(doc);
+ writeConclusionTable(doc, report);
writeRemarkTable(doc, report);
writeSignLine(doc);
doc.write(out);
@@ -150,12 +150,14 @@
.orElse(EMPTY);
}
- // ========== 鍒ゅ畾缁撹 / 璐ㄦ涓撶敤绔狅紙鐣欑┖鍚庡~锛� ==========
+ // ========== 鍒ゅ畾缁撹 / 璐ㄦ涓撶敤绔� ==========
- private static XWPFTable writeConclusionTable(XWPFDocument doc) {
+ /** 鍒ゅ畾缁撹鑷姩甯﹀嚭妫�楠岀粨鏋滄枃妗堬紱璐ㄦ涓撶敤绔犵暀绌猴紝鎵撳嵃鍚庝汉宸ョ洊绔� */
+ private static XWPFTable writeConclusionTable(XWPFDocument doc, MesQcQcReportRespVO report) {
XWPFTable table = createTable(doc);
- XWPFTableRow row = addRow(table, valueLeftSpan("鍒ゅ畾缁撹锛�", 2), valueLeftSpan("璐ㄦ涓撶敤绔狅細", 2));
- // 棰勭暀鎵嬪啓/鐩栫珷楂樺害
+ String conclusion = notBlank(report.getCheckResultText()) ? report.getCheckResultText() : "";
+ XWPFTableRow row = addRow(table, valueLeftSpan("鍒ゅ畾缁撹锛�" + conclusion, 2), valueLeftSpan("璐ㄦ涓撶敤绔狅細", 2));
+ // 棰勭暀鐩栫珷楂樺害
setRowHeight(row, 2550);
return table;
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcReportServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcReportServiceImpl.java
index e6245ab..5280cde 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcReportServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcReportServiceImpl.java
@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.mes.service.qc.indicatorresult;
import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils;
import cn.iocoder.yudao.module.mes.controller.admin.qc.indicatorresult.vo.MesQcQcReportRespVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO;
@@ -14,6 +15,7 @@
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.enums.DictTypeConstants;
import cn.iocoder.yudao.module.mes.enums.qc.MesQcIndicatorItemTypeEnum;
import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
@@ -231,10 +233,23 @@
report.setApproveName(userMap.get(report.getApproveUserId()).getNickname());
}
}
+ report.setCheckResultText(resolveCheckResultText(qcType, report.getCheckResult()));
return report;
}
/**
+ * 妫�娴嬬粨鏋滄枃妗堬細OQC 鎸変骇鍝佺瓑绾у垽瀹氾紙mes_oqc_check_result锛夛紝鍏朵綑璧伴�氱敤妫�娴嬬粨鏋滃瓧鍏革紙mes_qc_check_result锛�
+ */
+ private String resolveCheckResultText(Integer qcType, Integer checkResult) {
+ if (checkResult == null) {
+ return null;
+ }
+ String dictType = Objects.equals(qcType, MesQcTypeEnum.OQC.getType())
+ ? DictTypeConstants.MES_OQC_CHECK_RESULT : DictTypeConstants.MES_QC_CHECK_RESULT;
+ return DictFrameworkUtils.parseDictDataLabel(dictType, String.valueOf(checkResult));
+ }
+
+ /**
* 缁勮鎶ュ憡妫�楠岄」鏍戯紱椤哄甫鏀堕泦鍏ㄥ眬 measureNos 鍒楀ご
*/
private List<MesQcQcReportRespVO.ReportItem> buildReportItems(
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 fcea450..1096ea4 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
@@ -10,10 +10,6 @@
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;
@@ -23,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;
@@ -39,6 +28,7 @@
import cn.iocoder.yudao.module.mes.controller.admin.qc.ncr.vo.MesQcNcrSaveReqVO;
import cn.iocoder.yudao.module.mes.service.qc.ncr.MesQcNcrService;
import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@@ -65,14 +55,6 @@
@Slf4j
public class MesQcIpqcServiceImpl implements MesQcIpqcService {
- /**
- * IPQC 淇濆瓨鏁版嵁鏍¢獙涓婁笅鏂�
- *
- * @param workstation 宸ヤ綅
- * @param task 鐢熶骇浠诲姟锛堝彲閫夛紝鎸囧畾 taskId 鏃堕潪绌猴級
- */
- private record SaveDataContext(MesMdWorkstationDO workstation, MesProTaskDO task) {}
-
@Resource
private MesQcIpqcMapper ipqcMapper;
@@ -85,25 +67,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;
@@ -121,19 +85,18 @@
@Resource
private AdminUserApi adminUserApi;
+ @Resource
+ private MdmItemApi mdmItemApi;
+
@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 绫诲瀷鏌ユ壘鍙敤璐ㄦ鏂规锛堟敮鎸佸墠绔樉寮忔寚瀹氾級
- // 宸ュ崟浜у搧/浠诲姟鐗╂枡鏄� MES 鐗╂枡锛岀敱妯℃澘鏈嶅姟鍐呴儴杞崲涓� MDM 鐗╂枡鍚庡尮閰嶏紝鏁呬紶宸ュ崟/浠诲姟 ID
+ validateIpqcSaveData(createReqVO);
+ // 1.2 鏍规嵁浜у搧鐗╂枡 + IPQC 绫诲瀷鏌ユ壘鍙敤璐ㄦ鏂规锛堟敮鎸佸墠绔樉寮忔寚瀹氾級
+ // 鐗╂枡 ID 鏉ヨ嚜 MDM锛屾ā鏉挎湇鍔$洿鎺ユ寜 MDM 鐗╂枡鍖归厤
List<MesQcTemplateItemDO> templateItems = templateItemService.getTemplateItemList(
- null, MesQcTypeEnum.IPQC.getType(), createReqVO.getWorkOrderId(), createReqVO.getTaskId());
+ createReqVO.getItemId(), MesQcTypeEnum.IPQC.getType(), null, null);
if (CollUtil.isEmpty(templateItems)) {
throw exception(QC_NO_TEMPLATE);
}
@@ -147,14 +110,12 @@
}
}
Long templateId = templateItem.getTemplateId();
- // 1.5 鑾峰彇鏉ユ簮鍗曟嵁缂栧彿
+ // 1.3 鑾峰彇鏉ユ簮鍗曟嵁缂栧彿
String sourceDocCode = validateAndGetSourceDocCode(
createReqVO.getSourceDocType(), createReqVO.getSourceDocId(), createReqVO.getSourceLineId());
// 2. 鎻掑叆涓昏〃
MesQcIpqcDO ipqc = BeanUtils.toBean(createReqVO, MesQcIpqcDO.class)
- .setItemId(itemId)
- .setProcessId(getProcessId(itemId, ctx.workstation().getProcessId()))
.setTemplateId(templateId)
.setSourceDocCode(sourceDocCode)
.setStatus(MesQcStatusEnum.DRAFT.getStatus());
@@ -177,60 +138,23 @@
// 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());
+ // 鏍¢獙鐗╂枡銆佹娴嬩汉鍛樺瓨鍦�
+ // 娉細鐗╂枡 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
@@ -291,21 +215,8 @@
// 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());
+ log.warn("[writeBackSourceDoc] IPQC({}) 鏈缃潵婧愭姤宸ワ紝璺宠繃鍥炲啓", ipqc.getId());
return;
}
@@ -389,33 +300,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/wm/productsales/MesWmProductSalesLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineServiceImpl.java
index 30303e7..247a487 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineServiceImpl.java
@@ -10,7 +10,7 @@
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesLineMapper;
-import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum;
+import cn.iocoder.yudao.module.mes.enums.qc.MesQcOqcCheckResultEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
@@ -232,8 +232,8 @@
@Override
@Transactional(rollbackFor = Exception.class)
public void updateProductSalesLineWhenOqcFinish(Long id, Long oqcId, Integer checkResult) {
- // 1. 鏇存柊琛岀殑 oqcId + qualityStatus
- Integer qualityStatus = Objects.equals(checkResult, MesQcCheckResultEnum.QUALIFIED.getType())
+ // 1. 鏇存柊琛岀殑 oqcId + qualityStatus锛�1鍨�/2鍨嬫斁琛岋紝搴熷搧鍒や笉鍚堟牸锛�
+ Integer qualityStatus = MesQcOqcCheckResultEnum.canShip(checkResult)
? MesWmQualityStatusEnum.PASS.getStatus() : MesWmQualityStatusEnum.FAIL.getStatus();
productSalesLineMapper.updateById(new MesWmProductSalesLineDO()
.setId(id).setOqcId(oqcId).setQualityStatus(qualityStatus));
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..7928816 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
@@ -22,6 +22,7 @@
n.arrival_date AS recordTime,
${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IQC.type} AS qcType,
l.item_id AS itemId,
+ NULL AS batchCode,
l.arrival_quantity AS quantity,
n.vendor_id AS vendorId,
NULL AS workOrderId,
@@ -47,6 +48,7 @@
r.receipt_date AS recordTime,
${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IQC.type} AS qcType,
rl.item_id AS itemId,
+ NULL AS batchCode,
rl.quantity AS quantity,
r.vendor_id AS vendorId,
NULL AS workOrderId,
@@ -72,6 +74,7 @@
pf.feedback_time AS recordTime,
${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IPQC.type} AS qcType,
ppl.item_id AS itemId,
+ ppl.batch_code AS batchCode,
ppl.quantity AS quantity,
NULL AS vendorId,
pf.work_order_id AS workOrderId,
@@ -97,6 +100,7 @@
s.sales_date AS recordTime,
${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@OQC.type} AS qcType,
sl.item_id AS itemId,
+ NULL AS batchCode,
sl.quantity AS quantity,
NULL AS vendorId,
NULL AS workOrderId,
@@ -122,6 +126,7 @@
ri.return_date AS recordTime,
${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@RQC.type} AS qcType,
ril.item_id AS itemId,
+ NULL AS batchCode,
ril.quantity AS quantity,
NULL AS vendorId,
ri.work_order_id AS workOrderId,
@@ -148,6 +153,7 @@
r.return_date AS recordTime,
${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@RQC.type} AS qcType,
rl.item_id AS itemId,
+ NULL AS batchCode,
rl.quantity AS quantity,
NULL AS vendorId,
NULL AS workOrderId,
diff --git a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcProductReportWordBuilderTest.java b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcProductReportWordBuilderTest.java
index 9de4db1..f41d159 100644
--- a/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcProductReportWordBuilderTest.java
+++ b/yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/indicatorresult/MesQcProductReportWordBuilderTest.java
@@ -54,9 +54,9 @@
assertEquals("10.023銆�10.115", itemTable.getRow(2).getCell(1).getText().trim());
assertEquals("/", itemTable.getRow(3).getCell(1).getText().trim());
- // 鍒ゅ畾缁撹/璐ㄦ涓撶敤绔犵暀绌�
+ // 鍒ゅ畾缁撹甯﹀嚭妫�楠岀粨鏋滐紱璐ㄦ涓撶敤绔犵暀绌哄緟鐩栫珷
assertTrue(itemTable.getRow(2).getCell(0).getText().contains("璇曟牱璐ㄩ噺 m /g"));
- assertEquals("鍒ゅ畾缁撹锛�", tables.get(2).getRow(0).getCell(0).getText().trim());
+ assertEquals("鍒ゅ畾缁撹锛�1鍨�", tables.get(2).getRow(0).getCell(0).getText().trim());
assertEquals("璐ㄦ涓撶敤绔狅細", tables.get(2).getRow(0).getCell(1).getText().trim());
// 澶囨敞榛樿鏂囨
@@ -80,7 +80,8 @@
.setSamplingTime(LocalDateTime.of(2026, 1, 6, 9, 0))
.setInspectDate(LocalDateTime.of(2026, 1, 6, 15, 0))
.setDocCreateTime(LocalDateTime.of(2026, 1, 6, 8, 0))
- .setInspectorName("鏉庡崥").setAuditName("鍛ㄤ簹娲�").setApproveName("鍖呯繝钀�");
+ .setInspectorName("鏉庡崥").setAuditName("鍛ㄤ簹娲�").setApproveName("鍖呯繝钀�")
+ .setCheckResult(1).setCheckResultText("1鍨�");
MesQcQcReportRespVO.ReportItem appearance = new MesQcQcReportRespVO.ReportItem();
appearance.setIndicatorName("澶栬").setItemType(1).setSortOrder(10);
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..85bf379 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
@@ -3,30 +3,23 @@
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
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;
import cn.iocoder.yudao.module.mes.dal.mysql.qc.ipqc.MesQcIpqcMapper;
import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
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.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.qc.template.MesQcTemplateService;
import cn.iocoder.yudao.module.mes.service.wm.productproduce.MesWmProductProduceLineService;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
@@ -34,11 +27,16 @@
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import java.math.BigDecimal;
+import java.util.Collections;
+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;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.*;
/**
@@ -58,13 +56,9 @@
@MockitoBean
private MesQcTemplateItemService templateItemService;
@MockitoBean
+ private MesQcTemplateService templateService;
+ @MockitoBean
private MesQcIpqcLineService ipqcLineService;
- @MockitoBean
- private MesProWorkOrderService workOrderService;
- @MockitoBean
- private MesMdWorkstationService workstationService;
- @MockitoBean
- private MesMdItemService itemService;
@MockitoBean
private MesQcDefectRecordService defectRecordService;
@MockitoBean
@@ -72,15 +66,15 @@
@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;
+ @MockitoBean
+ private MdmItemApi mdmItemApi;
+
+ // ==================== finishIpqc 鍥炲啓鏉ユ簮鍗曟嵁 ====================
@Test
public void testFinishIpqc_writeBack_feedback() {
@@ -89,9 +83,6 @@
Long sourceLineId = randomLongId();
BigDecimal qualifiedQty = BigDecimal.valueOf(80);
BigDecimal unqualifiedQty = BigDecimal.valueOf(20);
- BigDecimal laborScrapQty = BigDecimal.valueOf(5);
- BigDecimal materialScrapQty = BigDecimal.valueOf(10);
- BigDecimal otherScrapQty = BigDecimal.valueOf(5);
MesQcIpqcDO ipqc = randomPojo(MesQcIpqcDO.class, o -> {
o.setStatus(MesQcStatusEnum.DRAFT.getStatus());
@@ -101,9 +92,9 @@
o.setSourceLineId(sourceLineId);
o.setQualifiedQuantity(qualifiedQty);
o.setUnqualifiedQuantity(unqualifiedQty);
- o.setLaborScrapQuantity(laborScrapQty);
- o.setMaterialScrapQuantity(materialScrapQty);
- o.setOtherScrapQuantity(otherScrapQty);
+ o.setLaborScrapQuantity(BigDecimal.valueOf(5));
+ o.setMaterialScrapQuantity(BigDecimal.valueOf(10));
+ o.setOtherScrapQuantity(BigDecimal.valueOf(5));
});
ipqcMapper.insert(ipqc);
@@ -124,6 +115,8 @@
any(BigDecimal.class),
any(BigDecimal.class),
any(BigDecimal.class));
+ // 鏂█ 3锛氫笉鍚堟牸鏁伴噺 > 0锛岃嚜鍔ㄥ垱寤� NCR
+ verify(ncrService).createNcr(any());
}
@Test
@@ -161,13 +154,14 @@
@Test
public void testFinishIpqc_writeBack_noSourceDoc() {
- // 鍑嗗鏁版嵁锛歴ourceDocType 涓虹┖锛屼笉闇�瑕佸洖鍐�
+ // 鍑嗗鏁版嵁锛氭棤鏉ユ簮鍗曟嵁锛堟墜宸ュ垱寤虹殑 IPQC锛夛紝鐩存帴瀹屾垚锛屼笉鍥炲啓
MesQcIpqcDO ipqc = randomPojo(MesQcIpqcDO.class, o -> {
o.setStatus(MesQcStatusEnum.DRAFT.getStatus());
o.setCheckResult(1);
o.setSourceDocType(null);
o.setSourceDocId(null);
o.setSourceLineId(null);
+ o.setUnqualifiedQuantity(BigDecimal.ZERO);
});
ipqcMapper.insert(ipqc);
@@ -181,38 +175,6 @@
// 鏂█ 2锛氫笉搴旇璋冪敤 feedbackService
verify(feedbackService, never()).updateProFeedbackWhenIpqcFinish(
anyLong(), anyLong(), any(), any(), any(), any(), any());
- }
-
- @Test
- public void testFinishIpqc_writeBack_sourceDocTypeDirtyData() {
- // 鍑嗗鏁版嵁锛歴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);
- });
- ipqcMapper.insert(ipqc);
-
- // 璋冪敤锛屽苟鏂█寮傚父
- assertThrows(IllegalArgumentException.class, () -> ipqcService.finishIpqc(ipqc.getId()));
- }
-
- @Test
- public void testFinishIpqc_writeBack_unknownSourceDocType() {
- // 鍑嗗鏁版嵁锛歴ourceDocType 鏃犳硶璇嗗埆
- MesQcIpqcDO ipqc = randomPojo(MesQcIpqcDO.class, o -> {
- o.setStatus(MesQcStatusEnum.DRAFT.getStatus());
- o.setCheckResult(1);
- o.setSourceDocType(99999); // 鏃犳硶璇嗗埆鐨勭被鍨�
- o.setSourceDocId(randomLongId());
- o.setSourceLineId(null);
- });
- ipqcMapper.insert(ipqc);
-
- // 璋冪敤锛屽苟鏂█寮傚父
- assertThrows(IllegalArgumentException.class, () -> ipqcService.finishIpqc(ipqc.getId()));
}
@Test
@@ -242,162 +204,61 @@
assertThrows(Exception.class, () -> ipqcService.finishIpqc(ipqc.getId()));
}
- // ==================== processId 鎺ㄥ琛屼负娴嬭瘯 ====================
+ // ==================== createIpqc 鐗╂枡 / 鎵瑰彿 / 妯℃澘鍖归厤 ====================
/**
- * 宸ヤ綅鏈夊伐搴� + 璇ュ伐搴忓湪浜у搧宸ヨ壓璺嚎涓� 鈫� processId 搴旇琚缃负宸ヤ綅宸ュ簭
+ * 鎵嬪伐鍒涘缓锛氱墿鏂欐潵鑷� MDM锛屾ā鏉挎寜 MDM 鐗╂枡 ID 鍖归厤锛涙壒鍙枫�佺墿鏂欏潎钀藉簱
*/
@Test
- public void testCreateIpqc_processId_workstationHasProcess() {
+ public void testCreateIpqc_success() {
// 鍑嗗鍙傛暟
- Long workstationId = randomLongId();
- Long workOrderId = randomLongId();
- Long productId = randomLongId();
- Long processId = randomLongId();
- Long routeId = randomLongId();
+ Long itemId = randomLongId();
Long templateId = randomLongId();
+ MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-TEST-001");
+ reqVO.setItemId(itemId);
+ reqVO.setBatchCode("BC20250101");
- MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
- reqVO.setCode("IPQC-TEST-001");
- reqVO.setWorkstationId(workstationId);
- reqVO.setWorkOrderId(workOrderId);
- 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());
+ // mock锛氭寜 MDM 鐗╂枡 ID 鍖归厤鍒拌川妫�鏂规
+ mockTemplate(templateId);
// 璋冪敤
Long ipqcId = ipqcService.createIpqc(reqVO);
- // 鏂█锛歱rocessId 搴旇鏄伐浣嶅伐搴�
+ // 鏂█ 1锛氭壒鍙枫�佺墿鏂欍�佹柟妗堝潎钀藉簱
MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
- assertEquals(processId, ipqc.getProcessId());
+ assertNotNull(ipqc);
+ assertEquals("BC20250101", ipqc.getBatchCode());
+ assertEquals(itemId, ipqc.getItemId());
+ assertEquals(templateId, ipqc.getTemplateId());
+ assertEquals(MesQcStatusEnum.DRAFT.getStatus(), ipqc.getStatus());
+ assertNull(ipqc.getSourceDocCode());
+
+ // 鏂█ 2锛氭ā鏉挎寜 MDM 鐗╂枡 ID 鍖归厤锛屼笉鍐嶄緷璧栧伐鍗�/浠诲姟
+ verify(templateItemService).getTemplateItemList(
+ eq(itemId), eq(MesQcTypeEnum.IPQC.getType()), isNull(), isNull());
+ // 鏂█ 3锛氱墿鏂欏瓨鍦ㄦ�ф牎楠岃蛋 MDM
+ verify(mdmItemApi).validateItemExists(itemId);
}
/**
- * 宸ヤ綅娌℃湁宸ュ簭锛坧rocessId=null锛夆啋 processId 搴旇鐣� null锛堜笉鍥為��鍒颁换鍔″伐搴忥級
+ * 鐗╂枡鏈尮閰嶅埌浠讳綍璐ㄦ鏂规 鈫� 鍒涘缓澶辫触
*/
@Test
- public void testCreateIpqc_processId_workstationNoProcess_shouldBeNull() {
+ public void testCreateIpqc_noTemplate() {
// 鍑嗗鍙傛暟
- Long workstationId = randomLongId();
- Long workOrderId = randomLongId();
- Long productId = randomLongId();
- Long taskId = randomLongId();
- Long templateId = randomLongId();
+ MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-TEST-002");
+ reqVO.setItemId(randomLongId());
- MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
- reqVO.setCode("IPQC-TEST-002");
- reqVO.setWorkstationId(workstationId);
- reqVO.setWorkOrderId(workOrderId);
- reqVO.setTaskId(taskId); // 鏁呮剰浼犲叆 taskId锛岄獙璇佷笉浼氬洖閫�
- reqVO.setInspectorUserId(randomLongId());
+ // mock锛氭棤鍖归厤鏂规
+ when(templateItemService.getTemplateItemList(any(), any(), any(), any()))
+ .thenReturn(Collections.emptyList());
- // 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);
-
- // 璋冪敤
- Long ipqcId = ipqcService.createIpqc(reqVO);
-
- // 鏂█锛歱rocessId 搴旇鏄� null锛屽嵆浣夸紶鍏ヤ簡 taskId 涔熶笉搴旇鍥為��
- MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
- assertNull(ipqc.getProcessId(),
- "宸ヤ綅鏃犲伐搴忔椂 processId 搴斾负 null锛屼笉搴斿洖閫�鍒颁换鍔″伐搴�");
- // 鏂█锛氫笉搴旇璇诲彇浠诲姟鐨� processId
- verify(routeProductService, never()).getRouteProductByItemId(any());
+ // 璋冪敤锛屾柇瑷�寮傚父
+ ServiceException ex = assertThrows(ServiceException.class, () -> ipqcService.createIpqc(reqVO));
+ assertEquals(QC_NO_TEMPLATE.getCode(), ex.getCode());
}
- /**
- * 宸ヤ綅鏈夊伐搴忎絾璇ュ伐搴忎笉鍦ㄤ骇鍝佸伐鑹鸿矾绾夸腑 鈫� processId 搴旇鐣� null
- */
- @Test
- public void testCreateIpqc_processId_processNotInRoute() {
- // 鍑嗗鍙傛暟
- Long workstationId = randomLongId();
- Long workOrderId = randomLongId();
- Long productId = randomLongId();
- Long processId = randomLongId();
- Long routeId = randomLongId();
- Long templateId = randomLongId();
-
- MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
- reqVO.setCode("IPQC-TEST-003");
- reqVO.setWorkstationId(workstationId);
- reqVO.setWorkOrderId(workOrderId);
- 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(null);
-
- // 璋冪敤
- Long ipqcId = ipqcService.createIpqc(reqVO);
-
- // 鏂█锛歱rocessId 搴旇鏄� null
- MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
- assertNull(ipqc.getProcessId());
- }
-
- // ==================== sourceLineId 鏍¢獙娴嬭瘯 ====================
+ // ==================== createIpqc sourceLineId 鏍¢獙 ====================
/**
* sourceDocType=PRO_FEEDBACK 鏃� sourceLineId 涓虹┖ 鈫� 鍒涘缓澶辫触
@@ -405,34 +266,15 @@
@Test
public void testCreateIpqc_sourceLineId_required() {
// 鍑嗗鍙傛暟
- Long workstationId = randomLongId();
- Long workOrderId = randomLongId();
- Long productId = 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());
+ MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-SL-001");
+ reqVO.setItemId(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);
+ mockTemplate(randomLongId());
when(feedbackService.validateFeedbackExists(feedbackId)).thenReturn(new MesProFeedbackDO());
// 璋冪敤锛屾柇瑷�寮傚父
@@ -446,35 +288,16 @@
@Test
public void testCreateIpqc_sourceLineId_notBelong() {
// 鍑嗗鍙傛暟
- Long workstationId = randomLongId();
- Long workOrderId = randomLongId();
- Long productId = 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());
+ MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-SL-002");
+ reqVO.setItemId(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);
+ mockTemplate(randomLongId());
when(feedbackService.validateFeedbackExists(feedbackId)).thenReturn(new MesProFeedbackDO());
// mock锛氫骇鍑鸿瀛樺湪浣� feedbackId 涓嶅尮閰�
MesWmProductProduceLineDO line = new MesWmProductProduceLineDO();
@@ -494,35 +317,16 @@
@Test
public void testCreateIpqc_sourceLineId_notPending() {
// 鍑嗗鍙傛暟
- Long workstationId = randomLongId();
- Long workOrderId = randomLongId();
- Long productId = 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());
+ MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-SL-003");
+ reqVO.setItemId(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);
+ mockTemplate(randomLongId());
when(feedbackService.validateFeedbackExists(feedbackId)).thenReturn(new MesProFeedbackDO());
// mock锛氫骇鍑鸿瀛樺湪涓斿綊灞炴纭紝浣嗕笉鏄� PENDING 鐘舵��
MesWmProductProduceLineDO line = new MesWmProductProduceLineDO();
@@ -537,40 +341,24 @@
}
/**
- * sourceLineId 鏍¢獙鍏ㄩ儴閫氳繃 鈫� 鍒涘缓鎴愬姛
+ * sourceLineId 鏍¢獙鍏ㄩ儴閫氳繃 鈫� 鍒涘缓鎴愬姛锛屾潵婧愬崟鎹紪鍙峰洖鍐�
*/
@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());
+ MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-SL-004");
+ reqVO.setItemId(itemId);
+ reqVO.setBatchCode("BC20250101");
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);
+ mockTemplate(templateId);
MesProFeedbackDO feedback = new MesProFeedbackDO();
feedback.setId(feedbackId);
feedback.setCode("FB-001");
@@ -585,12 +373,65 @@
// 璋冪敤
Long ipqcId = ipqcService.createIpqc(reqVO);
- // 鏂█锛氬垱寤烘垚鍔燂紝sourceDocCode 鍥炲啓
+ // 鏂█锛氬垱寤烘垚鍔燂紝鏉ユ簮鍗曟嵁瀛楁钀藉簱
MesQcIpqcDO ipqc = ipqcMapper.selectById(ipqcId);
assertNotNull(ipqc);
assertEquals(feedbackId, ipqc.getSourceDocId());
assertEquals(sourceLineId, ipqc.getSourceLineId());
assertEquals("FB-001", ipqc.getSourceDocCode());
+ assertEquals("BC20250101", ipqc.getBatchCode());
+ assertEquals(itemId, ipqc.getItemId());
+ }
+
+ /**
+ * 鏈煡鏉ユ簮鍗曟嵁绫诲瀷 鈫� 鍒涘缓澶辫触
+ */
+ @Test
+ public void testCreateIpqc_sourceDocTypeUnknown() {
+ // 鍑嗗鍙傛暟
+ MesQcIpqcSaveReqVO reqVO = buildReqVO("IPQC-SL-005");
+ reqVO.setItemId(randomLongId());
+ reqVO.setSourceDocType(99999); // 鏃犳硶璇嗗埆鐨勭被鍨�
+ reqVO.setSourceDocId(randomLongId());
+
+ // mock
+ mockTemplate(randomLongId());
+
+ // 璋冪敤锛屾柇瑷�寮傚父
+ ServiceException ex = assertThrows(ServiceException.class, () -> ipqcService.createIpqc(reqVO));
+ assertEquals(QC_IPQC_SOURCE_DOC_TYPE_UNKNOWN.getCode(), ex.getCode());
+ }
+
+ // ==================== 杈呭姪鏂规硶 ====================
+
+ /**
+ * 鏋勯�犱竴涓弧瓒冲繀濉」鐨勮繃绋嬫楠屽崟璇锋眰锛堜笉鍚潵婧愬崟鎹級
+ */
+ private MesQcIpqcSaveReqVO buildReqVO(String code) {
+ MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO();
+ reqVO.setCode(code);
+ reqVO.setName(code + "-鍚嶇О");
+ reqVO.setType(1);
+ reqVO.setBatchCode("BC-" + code);
+ reqVO.setCheckQuantity(BigDecimal.valueOf(100));
+ reqVO.setQualifiedQuantity(BigDecimal.valueOf(95));
+ reqVO.setUnqualifiedQuantity(BigDecimal.valueOf(5));
+ reqVO.setLaborScrapQuantity(BigDecimal.ZERO);
+ reqVO.setMaterialScrapQuantity(BigDecimal.ZERO);
+ reqVO.setOtherScrapQuantity(BigDecimal.ZERO);
+ reqVO.setInspectorUserId(randomLongId());
+ return reqVO;
+ }
+
+ /**
+ * mock锛氭寜 MDM 鐗╂枡 ID + IPQC 绫诲瀷鍖归厤鍒版寚瀹氳川妫�鏂规
+ */
+ private void mockTemplate(Long templateId) {
+ MesQcTemplateItemDO templateItem = new MesQcTemplateItemDO();
+ templateItem.setTemplateId(templateId);
+ List<MesQcTemplateItemDO> templateItems = Collections.singletonList(templateItem);
+ when(templateItemService.getTemplateItemList(any(), eq(MesQcTypeEnum.IPQC.getType()), isNull(), isNull()))
+ .thenReturn(templateItems);
}
}
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 fd73613..716210e 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,
@@ -263,6 +260,11 @@
"inspect_date" timestamp DEFAULT NULL,
"inspector_user_id" bigint DEFAULT NULL,
"status" tinyint DEFAULT NULL,
+ "sampling_location" varchar(255) DEFAULT NULL,
+ "certificate_no" varchar(100) DEFAULT NULL,
+ "execute_standard" varchar(100) DEFAULT NULL,
+ "audit_user_id" bigint DEFAULT NULL,
+ "approve_user_id" bigint DEFAULT NULL,
"remark" varchar(500) DEFAULT NULL,
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
--
Gitblit v1.9.3