From 536774eea8902efc088c5b904ff75bbe0af33418 Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期五, 17 七月 2026 09:09:42 +0800
Subject: [PATCH] 工作台
---
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemService.java | 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/MesWmProductIssueSaveReqVO.java | 7
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemSaveReqVO.java | 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderParamRecordService.java | 67 +
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java | 5
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnissue/MesWmReturnIssueMapper.java | 1
yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/item/dto/MesMdItemSyncReqDTO.java | 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskIssueService.java | 8
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/paramrecord/MesProWorkOrderParamRecordPageReqVO.java | 30
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueController.java | 8
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/MesWmProductIssueRespVO.java | 6
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/workorder/MesProWorkOrderParamRecordDetailDO.java | 70 +
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/item/MesMdItemTypeMapper.java | 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueLineDO.java | 7
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/paramrecord/MesProWorkOrderParamRecordSaveReqVO.java | 46
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/item/MesMdItemApiImpl.java | 4
docs/product_issue_task_integration.md | 255 ++++
docs/mes_compliance_gap_analysis.md | 242 ++++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/line/MesWmProductIssueLineSaveReqVO.java | 3
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/line/MesWmReturnIssueLineSaveReqVO.java | 3
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java | 59
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java | 8
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueSaveReqVO.java | 7
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java | 112 +
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java | 34
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueRespVO.java | 9
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/feedback/MesProFeedbackMapper.java | 24
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productissue/MesWmProductIssueLineDO.java | 7
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java | 32
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/MesProWorkOrderParamRecordController.java | 124 ++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java | 75 +
yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemServiceImpl.java | 29
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueDO.java | 7
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/paramrecord/MesProWorkOrderParamRecordRespVO.java | 76 +
docs/work_order_param_record_integration.md | 413 +++++++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productissue/MesWmProductIssueLineMapper.java | 4
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssuePageReqVO.java | 3
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/line/MesWmReturnIssueLineRespVO.java | 9
yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemSaveReqVO.java | 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/workorder/MesProWorkOrderParamRecordMapper.java | 36
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueController.java | 8
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/task/MesProTaskIssueMapper.java | 12
docs/production_data_cleanup.md | 244 ++++
yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemSyncReqDTO.java | 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/line/MesWmProductIssueLineRespVO.java | 11
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/item/MesMdItemDO.java | 6
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackSaveReqVO.java | 15
.claude/settings.local.json | 6
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productissue/MesWmProductIssueMapper.java | 1
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/workorder/MesProWorkOrderParamRecordDO.java | 62 +
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productissue/MesWmProductIssueDO.java | 2
docs/mes_auto_code_rule_init.sql | 255 ++++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemServiceImpl.java | 18
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderParamRecordServiceImpl.java | 204 +++
docs/production_feedback_integration.md | 599 ++++++++++
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/workorder/MesProWorkOrderParamRecordDetailMapper.java | 36
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskIssueServiceImpl.java | 5
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackPageReqVO.java | 6
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueLineServiceImpl.java | 2
59 files changed, 3,218 insertions(+), 116 deletions(-)
diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index ef2c24a..f29b770 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -31,7 +31,11 @@
"Bash(/tmp/fix_controller.sh)",
"Bash(chmod +x /tmp/fix2.sh)",
"Bash(/tmp/fix2.sh)",
- "Bash(\"E:/soft/IntelliJ IDEA 2025.3.4/plugins/maven/lib/maven3/bin/mvn.cmd\" -DskipTests=true -q compile -pl yudao-module-mdm-api,yudao-module-mdm,yudao-module-mes -am)"
+ "Bash(\"E:/soft/IntelliJ IDEA 2025.3.4/plugins/maven/lib/maven3/bin/mvn.cmd\" -DskipTests=true -q compile -pl yudao-module-mdm-api,yudao-module-mdm,yudao-module-mes -am)",
+ "Bash(JAVA_HOME=\"C:/Program Files/Java/jdk-25\" mvn compile -pl yudao-module-mes -am -q -Dsource=25)",
+ "Read(//c/Program Files/Java//**)",
+ "Read(//d/Program Files/**)",
+ "Bash(where java *)"
],
"deny": [
"Bash(rm -rf *)",
diff --git a/docs/mes_auto_code_rule_init.sql b/docs/mes_auto_code_rule_init.sql
new file mode 100644
index 0000000..e817cc9
--- /dev/null
+++ b/docs/mes_auto_code_rule_init.sql
@@ -0,0 +1,255 @@
+-- ============================================================
+-- MES 缂栫爜瑙勫垯鍒濆鍖栨暟鎹�
+-- 鍖呭惈锛歮es_md_auto_code_rule锛堣鍒欎富琛級+ mes_md_auto_code_part锛堣鍒欏垎娈电粍鎴愶級
+-- 鍒嗘绫诲瀷锛�1=杈撳叆瀛楃, 2=褰撳墠鏃ユ湡, 3=鍥哄畾瀛楃, 4=娴佹按鍙�
+-- 寰幆鏂瑰紡锛�1=鎸夊勾, 2=鎸夋湀, 3=鎸夊ぉ, 4=鎸夊皬鏃�, 5=鎸夊垎閽�, 10=鎸変紶鍏ュ瓧绗�
+-- 琛ラ綈鏂瑰紡锛�1=宸﹁ˉ榻�, 2=鍙宠ˉ榻�
+-- ============================================================
+
+-- ==================== 1. 缂栫爜瑙勫垯涓昏〃 ====================
+
+INSERT INTO mes_md_auto_code_rule (id, code, name, description, max_length, padded, padded_char, padded_method, status, remark, creator, updater) VALUES
+-- 鍩虹鏁版嵁
+(1, 'MD_ITEM_TYPE_CODE', '鐗╂枡鍒嗙被缂栫爜', '鐗╂枡鍒嗙被鑷姩缂栫爜', 6, 1, '0', 1, 0, NULL, '1', '1'),
+(2, 'MD_ITEM_CODE', '鐗╂枡缂栫爜', '鐗╂枡鑷姩缂栫爜', 17, 1, '0', 1, 0, NULL, '1', '1'),
+(3, 'MD_VENDOR_CODE', '渚涘簲鍟嗙紪鐮�', '渚涘簲鍟嗚嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(4, 'MD_CLIENT_CODE', '瀹㈡埛缂栫爜', '瀹㈡埛鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(5, 'MD_WORKSTATION_CODE', '宸ヤ綔绔欑紪鐮�', '宸ヤ綔绔欒嚜鍔ㄧ紪鐮�', 6, 1, '0', 1, 0, NULL, '1', '1'),
+(6, 'MD_WORKSHOP_CODE', '杞﹂棿缂栫爜', '杞﹂棿鑷姩缂栫爜', 6, 1, '0', 1, 0, NULL, '1', '1'),
+(7, 'TM_TOOL_TYPE_CODE', '宸ュ叿绫诲瀷缂栫爜', '宸ュ叿绫诲瀷鑷姩缂栫爜', 6, 1, '0', 1, 0, NULL, '1', '1'),
+-- 浠撳偍鐗╂祦
+(10, 'WM_WAREHOUSE_CODE', '浠撳簱缂栫爜', '浠撳簱鑷姩缂栫爜', 6, 1, '0', 1, 0, NULL, '1', '1'),
+(11, 'WM_LOCATION_CODE', '搴撳尯缂栫爜', '搴撳尯鑷姩缂栫爜', 6, 1, '0', 1, 0, NULL, '1', '1'),
+(12, 'WM_AREA_CODE', '搴撲綅缂栫爜', '搴撲綅鑷姩缂栫爜', 6, 1, '0', 1, 0, NULL, '1', '1'),
+(13, 'WM_ARRIVAL_NOTICE_CODE', '鍒拌揣閫氱煡鍗曠紪鐮�', '鍒拌揣閫氱煡鍗曡嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(14, 'WM_ITEM_RECEIPT_CODE', '閲囪喘鍏ュ簱鍗曠紪鐮�', '閲囪喘鍏ュ簱鍗曡嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(15, 'WM_RETURN_VENDOR_CODE', '閲囪喘閫�璐у崟缂栫爜', '閲囪喘閫�璐у崟鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(16, 'WM_RETURN_ISSUE_CODE', '鐢熶骇閫�鏂欏崟缂栫爜', '鐢熶骇閫�鏂欏崟鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(17, 'WM_SN_CODE', 'SN鐮�', 'SN鐮佽嚜鍔ㄧ紪鐮�', 18, 1, '0', 1, 0, NULL, '1', '1'),
+(18, 'WM_PACKAGE_CODE', '瑁呯鍗曠紪鐮�', '瑁呯鍗曡嚜鍔ㄧ紪鐮�', 17, 1, '0', 1, 0, NULL, '1', '1'),
+(19, 'WM_BATCH_CODE', '鎵规缂栫爜', '鎵规鑷姩缂栫爜', 17, 1, '0', 1, 0, NULL, '1', '1'),
+(20, 'WM_PRODUCT_SALES_CODE', '閿�鍞嚭搴撳崟缂栫爜', '閿�鍞嚭搴撳崟鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(21, 'WM_MISC_RECEIPT_CODE', '鏉傞」鍏ュ簱鍗曠紪鐮�', '鏉傞」鍏ュ簱鍗曡嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(22, 'WM_MISC_ISSUE_CODE', '鏉傞」鍑哄簱鍗曠紪鐮�', '鏉傞」鍑哄簱鍗曡嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(23, 'WM_STOCK_TAKING_PLAN_CODE','鐩樼偣鏂规缂栫爜', '鐩樼偣鏂规鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(24, 'WM_STOCK_TAKING_CODE', '鐩樼偣浠诲姟缂栫爜', '鐩樼偣浠诲姟鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(25, 'TRANSFER_CODE', '杞Щ璋冩嫧鍗曠紪鐮�', '杞Щ璋冩嫧鍗曡嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(26, 'WM_OUTSOURCE_ISSUE_CODE','澶栧崗鍙戞枡鍗曠紪鐮�', '澶栧崗鍙戞枡鍗曡嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(27, 'WM_OUTSOURCE_RECEIPT_CODE','澶栧崗鍏ュ簱鍗曠紪鐮�', '澶栧崗鍏ュ簱鍗曡嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(28, 'WM_SALES_NOTICE_CODE', '鍙戣揣閫氱煡鍗曠紪鐮�', '鍙戣揣閫氱煡鍗曡嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(29, 'WM_RETURN_SALES_CODE', '閿�鍞��璐у崟缂栫爜', '閿�鍞��璐у崟鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+-- 鐢熶骇
+(30, 'PRO_WORK_ORDER_CODE', '鐢熶骇宸ュ崟缂栫爜', '鐢熶骇宸ュ崟鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(31, 'PRO_TASK_CODE', '鐢熶骇浠诲姟缂栫爜', '鐢熶骇浠诲姟鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(32, 'PRO_ROUTE_CODE', '宸ヨ壓璺嚎缂栫爜', '宸ヨ壓璺嚎鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(33, 'PRO_FEEDBACK_CODE', '鐢熶骇鎶ュ伐鍗曠紪鐮�', '鐢熶骇鎶ュ伐鍗曡嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+-- 璐ㄦ
+(40, 'QC_IQC_CODE', '鏉ユ枡妫�楠屽崟缂栫爜', '鏉ユ枡妫�楠屽崟鑷姩缂栫爜', 16, 1, '0', 1, 0, NULL, '1', '1'),
+(41, 'QC_IPQC_CODE', '杩囩▼妫�楠屽崟缂栫爜', '杩囩▼妫�楠屽崟鑷姩缂栫爜', 17, 1, '0', 1, 0, NULL, '1', '1'),
+(42, 'QC_OQC_CODE', '鍑鸿揣妫�楠屽崟缂栫爜', '鍑鸿揣妫�楠屽崟鑷姩缂栫爜', 17, 1, '0', 1, 0, NULL, '1', '1'),
+(43, 'QC_RQC_CODE', '閫�璐ф楠屽崟缂栫爜', '閫�璐ф楠屽崟鑷姩缂栫爜', 17, 1, '0', 1, 0, NULL, '1', '1'),
+(44, 'QC_DEFECT_CODE', '缂洪櫡绫诲瀷缂栫爜', '缂洪櫡绫诲瀷鑷姩缂栫爜', 6, 1, '0', 1, 0, NULL, '1', '1'),
+(45, 'QC_INDICATOR_RESULT_CODE','鏍峰搧妫�楠岀粨鏋滅紪鐮�', '鏍峰搧妫�楠岀粨鏋滆嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+-- 璁惧
+(50, 'DV_MACHINERY_CODE', '璁惧缂栫爜', '璁惧鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(51, 'DV_MACHINERY_TYPE_CODE', '璁惧绫诲瀷缂栫爜', '璁惧绫诲瀷鑷姩缂栫爜', 6, 1, '0', 1, 0, NULL, '1', '1'),
+(52, 'DV_SUBJECT_CODE', '鐐规淇濆吇椤圭洰缂栫爜', '鐐规淇濆吇椤圭洰鑷姩缂栫爜', 6, 1, '0', 1, 0, NULL, '1', '1'),
+(53, 'DV_REPAIR_CODE', '缁翠慨鍗曠紪鐮�', '缁翠慨鍗曡嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+-- 宸ヨ壓鏂囨。
+(60, 'PD_DOCUMENT_AUDIT_CODE', '璧勬枡瀹℃牳鍗曠紪鐮�', '璧勬枡瀹℃牳鍗曡嚜鍔ㄧ紪鐮�', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(61, 'PD_ARCHIVE_CODE', '褰掓。鍙拌处缂栫爜', '褰掓。鍙拌处鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(62, 'PD_PROCESS_PARAM_CODE', '宸ヨ壓鍙傛暟缂栫爜', '宸ヨ壓鍙傛暟鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1'),
+(63, 'PD_PROCESS_PARAM_TEMPLATE_CODE', '宸ヨ壓鍙傛暟妯℃澘缂栫爜', '宸ヨ壓鍙傛暟妯℃澘鑷姩缂栫爜', 15, 1, '0', 1, 0, NULL, '1', '1');
+
+
+-- ==================== 2. 缂栫爜瑙勫垯鍒嗘缁勬垚 ====================
+--
+-- 闀垮害瀵圭収锛�
+-- 鍥哄畾瀛楃(IT_) = 3, 鏃ユ湡(yyyyMMdd) = 8, 娴佹按鍙�(001) = 3
+-- 渚�: IT_001 = 3+3 = 6 鈫� max_length=6
+-- 渚�: ITEM_20260716_001 = 6+8+3 = 17 鈫� max_length=17
+-- 渚�: WO_20260716_001 = 3+8+3 = 14 鈫� max_length=15 (鐣欎綑閲�)
+--
+
+INSERT INTO mes_md_auto_code_part (rule_id, sort, type, length, date_format, fix_character, serial_start_no, serial_step, cycle_flag, cycle_method, remark, creator, updater) VALUES
+-- ===== 鍩虹鏁版嵁 =====
+-- 1. 鐗╂枡鍒嗙被锛欼T_001 = 3+3=6
+(1, 1, 3, 3, NULL, 'IT_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(1, 2, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 2. 鐗╂枡锛欼TEM_20260716001 = 6+8+3=17
+(2, 1, 3, 6, NULL, 'ITEM_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(2, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(2, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 3. 渚涘簲鍟嗭細VND_20260716001 = 4+8+3=15
+(3, 1, 3, 4, NULL, 'VND_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(3, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(3, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 4. 瀹㈡埛锛欳LT_20260716001 = 4+8+3=15
+(4, 1, 3, 4, NULL, 'CLT_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(4, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(4, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 5. 宸ヤ綔绔欙細WS_001 = 3+3=6
+(5, 1, 3, 3, NULL, 'WS_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(5, 2, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 6. 杞﹂棿锛歐P_001 = 3+3=6
+(6, 1, 3, 3, NULL, 'WP_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(6, 2, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 7. 宸ュ叿绫诲瀷锛歍L_001 = 3+3=6
+(7, 1, 3, 3, NULL, 'TL_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(7, 2, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+
+-- ===== 浠撳偍鐗╂祦 =====
+-- 10. 浠撳簱锛歐H_001 = 3+3=6
+(10, 1, 3, 3, NULL, 'WH_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(10, 2, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 11. 搴撳尯锛歀C_001 = 3+3=6
+(11, 1, 3, 3, NULL, 'LC_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(11, 2, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 12. 搴撲綅锛欰R_001 = 3+3=6
+(12, 1, 3, 3, NULL, 'AR_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(12, 2, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 13. 鍒拌揣閫氱煡锛欰N_20260716001 = 3+8+3=14鈫�15
+(13, 1, 3, 3, NULL, 'AN_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(13, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(13, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 14. 閲囪喘鍏ュ簱锛欼R_20260716001 = 3+8+3=14鈫�15
+(14, 1, 3, 3, NULL, 'IR_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(14, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(14, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 15. 閲囪喘閫�璐э細RV_20260716001 = 3+8+3=14鈫�15
+(15, 1, 3, 3, NULL, 'RV_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(15, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(15, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 16. 鐢熶骇閫�鏂欙細RI_20260716001 = 3+8+3=14鈫�15
+(16, 1, 3, 3, NULL, 'RI_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(16, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(16, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 17. SN鐮侊細SN_20260716000001 = 3+8+4+3=18
+(17, 1, 3, 3, NULL, 'SN_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(17, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(17, 3, 4, 4, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 18. 瑁呯锛歅K_20260716001 = 3+8+3=14鈫�17
+(18, 1, 3, 3, NULL, 'PK_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(18, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(18, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 19. 鎵规锛欱T_20260716001 = 3+8+3=14鈫�17
+(19, 1, 3, 3, NULL, 'BT_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(19, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(19, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 20. 閿�鍞嚭搴擄細SL_20260716001 = 3+8+3=14鈫�15
+(20, 1, 3, 3, NULL, 'SL_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(20, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(20, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 21. 鏉傞」鍏ュ簱锛歁I_20260716001 = 3+8+3=14鈫�15
+(21, 1, 3, 3, NULL, 'MI_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(21, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(21, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 22. 鏉傞」鍑哄簱锛歁O_20260716001 = 3+8+3=14鈫�15
+(22, 1, 3, 3, NULL, 'MO_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(22, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(22, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 23. 鐩樼偣鏂规锛歋P_20260716001 = 3+8+3=14鈫�15
+(23, 1, 3, 3, NULL, 'SP_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(23, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(23, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 24. 鐩樼偣浠诲姟锛歋T_20260716001 = 3+8+3=14鈫�15
+(24, 1, 3, 3, NULL, 'ST_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(24, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(24, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 25. 璋冩嫧锛歍F_20260716001 = 3+8+3=14鈫�15
+(25, 1, 3, 3, NULL, 'TF_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(25, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(25, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 26. 澶栧崗鍙戞枡锛歄I_20260716001 = 3+8+3=14鈫�15
+(26, 1, 3, 3, NULL, 'OI_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(26, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(26, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 27. 澶栧崗鍏ュ簱锛歄R_20260716001 = 3+8+3=14鈫�15
+(27, 1, 3, 3, NULL, 'OR_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(27, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(27, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 28. 鍙戣揣閫氱煡锛歋N_20260716001 = 3+8+3=14鈫�15
+(28, 1, 3, 3, NULL, 'SN_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(28, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(28, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 29. 閿�鍞��璐э細RS_20260716001 = 3+8+3=14鈫�15
+(29, 1, 3, 3, NULL, 'RS_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(29, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(29, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+
+-- ===== 鐢熶骇 =====
+-- 30. 宸ュ崟锛歐O_20260716001 = 3+8+3=14鈫�15
+(30, 1, 3, 3, NULL, 'WO_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(30, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(30, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 31. 浠诲姟锛歍K_20260716001 = 3+8+3=14鈫�15
+(31, 1, 3, 3, NULL, 'TK_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(31, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(31, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 32. 宸ヨ壓璺嚎锛歊T_20260716001 = 3+8+3=14鈫�15
+(32, 1, 3, 3, NULL, 'RT_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(32, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(32, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 33. 鎶ュ伐锛欶B_20260716001 = 3+8+3=14鈫�15
+(33, 1, 3, 3, NULL, 'FB_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(33, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(33, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+
+-- ===== 璐ㄦ =====
+-- 40. 鏉ユ枡妫�楠岋細IQC_20260716001 = 4+8+3=15鈫�16
+(40, 1, 3, 4, NULL, 'IQC_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(40, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(40, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 41. 杩囩▼妫�楠岋細IPQC_20260716001 = 5+8+3=16鈫�17
+(41, 1, 3, 5, NULL, 'IPQC_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(41, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(41, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 42. 鍑鸿揣妫�楠岋細OQC_20260716001 = 4+8+3=15鈫�17
+(42, 1, 3, 4, NULL, 'OQC_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(42, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(42, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 43. 閫�璐ф楠岋細RQC_20260716001 = 4+8+3=15鈫�17
+(43, 1, 3, 4, NULL, 'RQC_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(43, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(43, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 44. 缂洪櫡锛欴F_001 = 3+3=6
+(44, 1, 3, 3, NULL, 'DF_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(44, 2, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 45. 妫�楠岀粨鏋滐細IR_20260716001 = 3+8+3=14鈫�15
+(45, 1, 3, 3, NULL, 'IR_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(45, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(45, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+
+-- ===== 璁惧 =====
+-- 50. 璁惧锛歁C_20260716001 = 3+8+3=14鈫�15
+(50, 1, 3, 3, NULL, 'MC_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(50, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(50, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 51. 璁惧绫诲瀷锛歁T_001 = 3+3=6
+(51, 1, 3, 3, NULL, 'MT_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(51, 2, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 52. 鐐规淇濆吇锛歋J_001 = 3+3=6
+(52, 1, 3, 3, NULL, 'SJ_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(52, 2, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 53. 缁翠慨锛歊P_20260716001 = 3+8+3=14鈫�15
+(53, 1, 3, 3, NULL, 'RP_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(53, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(53, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+
+-- ===== 宸ヨ壓鏂囨。 =====
+-- 60. 璧勬枡瀹℃牳锛欴A_20260716001 = 3+8+3=14鈫�15
+(60, 1, 3, 3, NULL, 'DA_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(60, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(60, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 61. 褰掓。锛欰C_20260716001 = 3+8+3=14鈫�15
+(61, 1, 3, 3, NULL, 'AC_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(61, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(61, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 62. 宸ヨ壓鍙傛暟锛歅P_20260716001 = 3+8+3=14鈫�15
+(62, 1, 3, 3, NULL, 'PP_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(62, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(62, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1'),
+-- 63. 宸ヨ壓鍙傛暟妯℃澘锛歅T_20260716001 = 3+8+3=14鈫�15
+(63, 1, 3, 3, NULL, 'PT_', NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(63, 2, 2, 8, 'yyyyMMdd', NULL, NULL, NULL, NULL, NULL, NULL, '1', '1'),
+(63, 3, 4, 3, NULL, NULL, 1, 1, 1, 3, NULL, '1', '1');
diff --git a/docs/mes_compliance_gap_analysis.md b/docs/mes_compliance_gap_analysis.md
new file mode 100644
index 0000000..b3eac21
--- /dev/null
+++ b/docs/mes_compliance_gap_analysis.md
@@ -0,0 +1,242 @@
+# MES 鐢熶骇绠℃帶鏍告煡 - 鍔熻兘绗﹀悎鎬у垎鏋�
+
+## 鏍告煡瑕佹眰涓庣幇鏈夊姛鑳藉鐓�
+
+---
+
+### 瑕佹眰1锛氫俊鎭寲绯荤粺閮ㄧ讲涓庤繍琛�
+
+> 鏍告煡浼佷笟鏄惁閮ㄧ讲鐢熶骇绠℃帶鐩稿叧淇℃伅鍖栫郴缁燂紝濡侻ES鍒堕�犳墽琛岀郴缁熴�佺敓浜х鐞嗕笓鐢ㄦā鍧楃瓑锛岀‘璁ょ郴缁熷凡姝e紡鎶曞叆浣跨敤涓斿浜庢甯歌繍琛岀姸鎬併��
+
+**绗﹀悎搴︼細鉁� 绗﹀悎**
+
+| 鏍告煡椤� | 鐜扮姸 | 璇存槑 |
+|--------|------|------|
+| MES绯荤粺閮ㄧ讲 | 鉁� 宸查儴缃� | 椤圭洰鍖呭惈瀹屾暣鐨� `yudao-module-mes` 妯″潡 |
+| 鐢熶骇绠$悊涓撶敤妯″潡 | 鉁� 宸插叿澶� | 鍖呭惈宸ュ崟绠$悊銆佺敓浜т换鍔°�佹姤宸ャ�佹帓浜х瓑瀛愭ā鍧� |
+| 绯荤粺杩愯鐘舵�� | 鉁� 姝e父 | 绯荤粺鍙甯哥紪璇戣繍琛岋紝鏁版嵁搴撹〃鍜屾暟鎹凡灏辩华 |
+
+---
+
+### 瑕佹眰2锛氱敓浜у伐鍗曠鐞嗗埗搴︿笌绯荤粺娴佺▼鍖归厤
+
+> 鏍告煡浼佷笟鏄惁鍒跺畾鐢熶骇宸ュ崟绠$悊鐩稿叧鍒跺害鏂囦欢锛屽寘鎷敓浜у伐鍗曠鐞嗗埗搴︺�佺敓浜ц繘搴﹁窡韪粏鍒欍�佺墿鏂欓鐢�/鑰楃敤绠$悊瑙勫畾绛夛紝纭鍒跺害涓槑纭簡宸ュ崟鍒涘缓銆佹淳宸ャ�佹姤宸ャ�佹牳閿�銆佸綊妗g瓑鍏ㄦ祦绋嬭鑼冿紝涓斿埗搴﹁姹備笌淇℃伅鍖栫郴缁熸搷浣滄祦绋嬬浉鍖归厤銆�
+
+**绗﹀悎搴︼細鈿狅笍 閮ㄥ垎绗﹀悎锛堢郴缁熸祦绋嬪熀鏈鐩栵紝浣嗙己灏戞牳閿�鍜屽綊妗g幆鑺傦級**
+
+| 鏍告煡椤� | 鐜扮姸 | 璇存槑 |
+|--------|------|------|
+| 宸ュ崟鍒涘缓 | 鉁� 宸插疄鐜� | `POST /mes/pro/work-order/create`锛岃崏绋跨姸鎬� |
+| 宸ュ崟纭(瀹℃壒) | 鉁� 宸插疄鐜� | `PUT /mes/pro/work-order/confirm`锛岃崏绋库啋宸茬‘璁� |
+| 娲惧伐(鎺掍骇) | 鉁� 宸插疄鐜� | 鐢熶骇浠诲姟(Task)浠庡伐鍗曟淳鐢燂紝鍚伐浣滅珯銆佸伐搴忋�佹帓浜ф暟閲� |
+| 鎶ュ伐 | 鉁� 宸插疄鐜� | `POST /mes/pro-feedback/create`锛屾敮鎸佽嚜琛屾姤宸ュ拰缁熶竴鎶ュ伐 |
+| 鎶ュ伐鎻愪氦 | 鉁� 宸插疄鐜� | `PUT /mes/pro-feedback/submit`锛岃崏绋库啋瀹℃壒涓� |
+| 鎶ュ伐瀹℃壒 | 鉁� 宸插疄鐜� | `PUT /mes/pro-feedback/approve`锛岃Е鍙戝叆搴�/鎵f枡 |
+| 鐗╂枡棰嗙敤 | 鉁� 宸插疄鐜� | 鐢熶骇鍙戞枡(ProductIssue)妯″潡锛屽叧鑱斿伐鍗� |
+| 鐗╂枡鑰楃敤(鍊掑啿) | 鉁� 宸插疄鐜� | 鎶ュ伐瀹℃壒鏃惰嚜鍔ㄦ寜BOM鎵f枡(ItemConsume) |
+| 鎴愬搧鍏ュ簱 | 鉁� 宸插疄鐜� | 鐢熶骇浜у嚭(ProductProduce)妯″潡锛屽鎵瑰悗鑷姩鍏ュ簱 |
+| **宸ュ崟鏍搁攢** | 鉂� **缂哄け** | 鏃犲伐鍗曟牳閿�鍔熻兘锛屾棤娉曞宸ュ崟杩涜鐗╂枡/浜ч噺鐨勬渶缁堝璐︽牳閿� |
+| **宸ュ崟褰掓。** | 鉂� **缂哄け** | 鏃犲伐鍗曞綊妗e姛鑳斤紝宸插畬鎴�/宸插彇娑堢殑宸ュ崟鏃犲綊妗g姸鎬佸拰褰掓。鎿嶄綔 |
+| 鍒跺害鏂囦欢绠$悊 | 鉂� 涓嶅睘浜庣郴缁熻寖鍥� | 鍒跺害鏂囦欢涓虹嚎涓嬬鐞嗭紝绯荤粺涓嶆彁渚涘埗搴︽枃浠剁鐞嗗姛鑳� |
+
+**绯荤粺鎿嶄綔娴佺▼锛�**
+
+```
+宸ュ崟鍒涘缓(鑽夌) 鈫� 宸ュ崟纭(宸茬‘璁�) 鈫� 娲惧伐/鎺掍骇(鐢熸垚浠诲姟)
+ 鈫� 鎶ュ伐(鑽夌) 鈫� 鎻愪氦(瀹℃壒涓�) 鈫� 瀹℃壒閫氳繃(宸插畬鎴�)
+ 鈫� 鑷姩鍏ュ簱(鍏抽敭宸ュ簭) / 鑷姩鎵f枡(鍊掑啿宸ュ簭)
+ 鈫� 宸ュ崟瀹屽伐(宸插畬鎴�) / 宸ュ崟鍙栨秷(宸插彇娑�)
+
+缂哄け鐜妭锛氬伐鍗曟牳閿� 鈫� 宸ュ崟褰掓。
+```
+
+---
+
+### 瑕佹眰3锛氬伐鍗曞叏鐢熷懡鍛ㄦ湡绾夸笂绠$悊鑳藉姏
+
+> 鐜板満婕旂ず淇℃伅鍖栫郴缁熺殑鐢熶骇宸ュ崟鏍稿績鍔熻兘锛岀敱浼佷笟鎿嶄綔浜哄憳渚濇婕旂ず宸ュ崟鍒涘缓銆佸鎵广�佷笅鍙戙�佽繘搴︽洿鏂般�佸畬宸ョ‘璁ょ殑鍏ㄦ祦绋嬫搷浣滐紝鏍稿疄绯荤粺鍏峰宸ュ崟鍏ㄧ敓鍛藉懆鏈熺嚎涓婄鐞嗚兘鍔涳紝鍚勭幆鑺傛搷浣滆妭鐐规竻鏅般�佸彲杩芥函銆�
+
+**绗﹀悎搴︼細鈿狅笍 閮ㄥ垎绗﹀悎锛堟牳蹇冩祦绋嬪叿澶囷紝浣嗗伐鍗曠骇缂哄皯"涓嬪彂"鐜妭锛岃繘搴︽洿鏂颁緷璧栨姤宸ラ棿鎺ュ疄鐜帮級**
+
+| 鏍告煡椤� | 鐜扮姸 | 璇存槑 |
+|--------|------|------|
+| 宸ュ崟鍒涘缓 | 鉁� 宸插疄鐜� | 鍒涘缓宸ュ崟 + 鑷姩鐢熸垚BOM + 鑷姩鐢熸垚鏉$爜 |
+| 宸ュ崟瀹℃壒(纭) | 鉁� 宸插疄鐜� | confirmWorkOrder锛岃崏绋库啋宸茬‘璁� |
+| **宸ュ崟涓嬪彂** | 鈿狅笍 **寮卞寲** | 宸ュ崟纭鍚庡嵆鍙帓浜�/鎶ュ伐锛屾棤鐙珛鐨�"涓嬪彂"鎿嶄綔鍜岀姸鎬侊紝纭鍗崇敓鏁� |
+| 杩涘害鏇存柊 | 鉁� 宸插疄鐜� | 閫氳繃鎶ュ伐瀹℃壒鍚庤嚜鍔ㄧ疮鍔� `quantityProduced`锛岄棿鎺ユ洿鏂拌繘搴� |
+| 瀹屽伐纭 | 鉁� 宸插疄鐜� | finishWorkOrder锛岀骇鑱斿畬鎴愭墍鏈変换鍔� |
+| 鍚勭幆鑺傚彲杩芥函 | 鈿狅笍 閮ㄥ垎鍏峰 | 璇﹁瑕佹眰4鍒嗘瀽 |
+
+**宸ュ崟鐘舵�佹祦杞紙鐜版湁锛夛細**
+
+```
+鑽夌(0) 鈫� 宸茬‘璁�(1) 鈫� 宸插畬鎴�(2)
+ 鈫� 宸插彇娑�(3)
+
+缂哄け锛氬凡纭 鈫� 宸蹭笅鍙�(鏈疄鐜扮嫭绔嬩笅鍙戠幆鑺�)
+```
+
+---
+
+### 瑕佹眰4锛氬伐鍗曟搷浣滅棔杩瑰畬鏁存�т笌鍙拷婧��
+
+> 鎶芥煡绯荤粺鍐呰繎鏈熺敓浜у伐鍗曟暟鎹紝鎸夊紑宸ヤ腑銆佸伐搴忓畬宸ャ�佹暣浣撳畬宸ャ�佸紓甯稿仠宸ュ洓绉嶇姸鎬佸垎绫绘娊鏌ワ紝鏍稿疄姣忕瑪宸ュ崟鐨勫悇鐜妭鎿嶄綔鐥曡抗瀹屾暣锛屽寘鍚搷浣滀汉銆佹搷浣滄椂闂淬�佹搷浣滃唴瀹圭瓑淇℃伅锛屽伐鍗曠姸鎬佹洿鏂板強鏃躲�佸噯纭��
+
+**绗﹀悎搴︼細鈿狅笍 閮ㄥ垎绗﹀悎锛堝熀纭�瀹¤淇℃伅鍏峰锛屼絾鎿嶄綔鐥曡抗涓嶅瀹屾暣锛屽洓绉嶇姸鎬佸垎绫讳笉瀹屾暣锛�**
+
+| 鏍告煡椤� | 鐜扮姸 | 璇存槑 |
+|--------|------|------|
+| 鍒涘缓浜�/鍒涘缓鏃堕棿 | 鉁� 宸插叿澶� | BaseDO 鐨� `creator`銆乣create_time` 瀛楁 |
+| 鏇存柊浜�/鏇存柊鏃堕棿 | 鉁� 宸插叿澶� | BaseDO 鐨� `updater`銆乣update_time` 瀛楁 |
+| 鎶ュ伐浜� | 鉁� 宸插叿澶� | FeedbackDO 鐨� `feedbackUserId` + `feedbackTime` |
+| 瀹℃壒浜� | 鉁� 宸插叿澶� | FeedbackDO 鐨� `approveUserId` |
+| 瀹屽伐鏃堕棿 | 鉁� 宸插叿澶� | WorkOrderDO 鐨� `finishDate` |
+| 鍙栨秷鏃堕棿 | 鉁� 宸插叿澶� | WorkOrderDO 鐨� `cancelDate` |
+| 绯荤粺鎿嶄綔鏃ュ織 | 鉁� 宸插叿澶� | `system_operate_log` 琛紝璁板綍鎵�鏈堿PI璇锋眰鐨勬搷浣滀汉銆佹椂闂淬�乁RL銆両P绛� |
+| **宸ュ崟绾ф搷浣滄椂闂寸嚎** | 鉂� **缂哄け** | 鏃犲伐鍗曚笓灞炵殑鎿嶄綔鍘嗗彶琛紝鏃犳硶鎸夊伐鍗旾D鏌ヨ"璋佸湪浠�涔堟椂闂村仛浜嗕粈涔堟搷浣�"鐨勬椂闂寸嚎 |
+| **瀹℃壒浜鸿嚜鍔ㄨ褰�** | 鉂� **缂哄け** | 鎶ュ伐瀹℃壒鏃舵湭鑷姩濉厖 `approveUserId` 涓哄綋鍓嶇櫥褰曠敤鎴� |
+| **鐘舵�佸垎绫伙細寮�宸ヤ腑** | 鈿狅笍 瀵瑰簲宸ュ崟"宸茬‘璁�" | 浣�"宸茬‘璁�"涓嶇瓑浜�"寮�宸ヤ腑"锛岀己灏戞槑纭殑寮�宸ョ姸鎬� |
+| **鐘舵�佸垎绫伙細宸ュ簭瀹屽伐** | 鈿狅笍 闂存帴鍙煡 | 鎶ュ伐鐘舵��=宸插畬鎴愪唬琛ㄥ伐搴忓畬宸ワ紝浣嗘棤"宸ュ簭瀹屽伐"鐨勫伐鍗曠骇鐘舵�� |
+| **鐘舵�佸垎绫伙細鏁翠綋瀹屽伐** | 鉁� 宸插叿澶� | 宸ュ崟鐘舵��=宸插畬鎴�(2) |
+| **鐘舵�佸垎绫伙細寮傚父鍋滃伐** | 鉂� **缂哄け** | 宸ュ崟鏃�"寮傚父鍋滃伐"鐘舵�侊紝璇﹁瑕佹眰6鍒嗘瀽 |
+
+---
+
+### 瑕佹眰5锛氱郴缁熸暟鎹笌瀹為檯鐢熶骇鎵ц璧勬枡鏍稿
+
+> 鏍稿绯荤粺鍐呭伐鍗曟暟鎹笌瀹為檯鐢熶骇鎵ц璧勬枡锛屽寘鎷墿鏂欓鐢ㄥ崟銆佺敓浜ц繘搴︽棩鎶ヨ〃銆佹垚鍝佸叆搴撳崟銆佽澶囪繍琛岃褰曠瓑锛岀‘璁ゅ伐鍗曚腑鐨勪骇閲忋�佺墿鏂欒�楃敤銆佺敓浜у伐鏈熺瓑鏁版嵁涓庡疄闄呬竴鑷达紝鍋忓樊鐜囧湪鍚堢悊鑼冨洿鍐呫��
+
+**绗﹀悎搴︼細鈿狅笍 閮ㄥ垎绗﹀悎锛堟暟鎹叧鑱旈摼璺瓨鍦紝浣嗙己灏戞牳瀵�/瀵硅处宸ュ叿鍜屽亸宸垎鏋愯兘鍔涳級**
+
+| 鏍告煡椤� | 鐜扮姸 | 璇存槑 |
+|--------|------|------|
+| 鐗╂枡棰嗙敤鍗� | 鉁� 宸插叿澶� | 鐢熶骇鍙戞枡(ProductIssue)妯″潡锛屽叧鑱� workOrderId |
+| 鐗╂枡鑰楃敤璁板綍 | 鉁� 宸插叿澶� | 鐗╂枡娑堣��(ItemConsume)妯″潡锛屾姤宸ュ鎵规椂鑷姩鐢熸垚锛屽叧鑱� feedbackId |
+| 鎴愬搧鍏ュ簱鍗� | 鉁� 宸插叿澶� | 鐢熶骇浜у嚭(ProductProduce)妯″潡锛屾姤宸ュ鎵规椂鑷姩鐢熸垚锛屽叧鑱� feedbackId |
+| 浜ч噺鏁版嵁 | 鉁� 宸插叿澶� | 宸ュ崟 `quantityProduced`锛屼换鍔� `producedQuantity`/`qualifyQuantity`/`unqualifyQuantity` |
+| 鐢熶骇宸ユ湡 | 鉁� 宸插叿澶� | 浠诲姟 `startTime`/`endTime`/`duration`锛屽伐鍗� `requestDate`/`finishDate` |
+| 璁惧杩愯璁板綍 | 鉁� 宸插叿澶� | 璁惧缁翠慨/鐐规/淇濆吇璁板綍妯″潡(DvRepair/DvCheckRecord/DvMaintenRecord) |
+| **宸ュ崟-鐗╂枡瀵硅处** | 鉂� **缂哄け** | 鏃犲伐鍗曠墿鏂欐牳閿�/瀵硅处鍔熻兘锛屾棤娉曡嚜鍔ㄦ瘮瀵笲OM闇�姹傞噺 vs 瀹為檯棰嗙敤閲� vs 瀹為檯鑰楃敤閲� |
+| **宸ュ崟-浜ч噺瀵硅处** | 鉂� **缂哄け** | 鏃犲伐鍗曚骇閲忔牳閿�鍔熻兘锛屾棤娉曡嚜鍔ㄦ瘮瀵瑰伐鍗曟暟閲� vs 鎶ュ伐鍚堣 vs 鍏ュ簱鍚堣 |
+| **鍋忓樊鐜囧垎鏋�** | 鉂� **缂哄け** | 鏃犲亸宸巼璁$畻鍜岄璀﹀姛鑳� |
+| **鐢熶骇杩涘害鏃ユ姤琛�** | 鉂� **缂哄け** | 鏃犳寜鏃ユ眹鎬荤敓浜ц繘搴︾殑鎶ヨ〃鍔熻兘 |
+
+---
+
+### 瑕佹眰6锛氬伐鍗曞紓甯哥鐞嗚兘鍔�
+
+> 鏍告煡绯荤粺鐨勫伐鍗曞紓甯哥鐞嗚兘鍔涳紝鎶芥煡绯荤粺鍐呭紓甯稿仠宸ュ伐鍗曠殑澶勭悊璁板綍锛屾牳瀹炴槸鍚﹀寘鍚紓甯稿師鍥犲垎鏋愩�佸鐞嗘帾鏂姐�佸宸ユ椂闂寸瓑淇℃伅锛屽紓甯稿伐鍗曞疄鐜伴棴鐜鐞嗭紝鏃犻暱鏈熸湭澶勭悊鐨勬儏鍐点��
+
+**绗﹀悎搴︼細鈿狅笍 閮ㄥ垎绗﹀悎锛堟湁瀹夌伅鍛煎彨璁板綍锛屼絾宸ュ崟绾у紓甯稿仠宸ョ鐞嗕弗閲嶄笉瓒筹級**
+
+| 鏍告煡椤� | 鐜扮姸 | 璇存槑 |
+|--------|------|------|
+| 瀹夌伅鍛煎彨璁板綍 | 鉁� 宸插叿澶� | AndonRecord 妯″潡锛岃褰曞懠鍙師鍥犮�佺骇鍒�佸缃姸鎬併�佸缃汉銆佸缃椂闂� |
+| 瀹夌伅鍏宠仈宸ュ崟 | 鉁� 宸插叿澶� | AndonRecordDO 鍏宠仈 workOrderId |
+| 瀹夌伅闂幆绠$悊 | 鈿狅笍 閮ㄥ垎鍏峰 | 鏈�"鏈缃啋宸插缃�"鐘舵�佹祦杞紝浣嗘棤瓒呮椂棰勮鍜屽崌绾ф満鍒� |
+| **宸ュ崟"寮傚父鍋滃伐"鐘舵��** | 鉂� **缂哄け** | 宸ュ崟鐘舵�佷粎鏈夛細鑽夌/宸茬‘璁�/宸插畬鎴�/宸插彇娑堬紝鏃�"寮傚父鍋滃伐"鐘舵�� |
+| **宸ュ崟鏆傚仠/鎸傝捣鎿嶄綔** | 鉂� **缂哄け** | 鏃� pauseWorkOrder / suspendWorkOrder 鎺ュ彛 |
+| **宸ュ崟鎭㈠/澶嶅伐鎿嶄綔** | 鉂� **缂哄け** | 鏃� resumeWorkOrder 鎺ュ彛鍜屽宸ユ椂闂磋褰� |
+| **寮傚父鍘熷洜鍒嗘瀽** | 鉂� **缂哄け** | 瀹夌伅璁板綍浠呮湁 reason 瀛楁(鍛煎彨鍘熷洜)锛屾棤缁撴瀯鍖栫殑寮傚父鍘熷洜鍒嗘瀽(濡傝澶囨晠闅�/鐗╂枡鐭己/璐ㄩ噺寮傚父绛夊垎绫�) |
+| **澶勭悊鎺柦璁板綍** | 鉂� **缂哄け** | 瀹夌伅璁板綍浠呮湁 remark 瀛楁(澶囨敞)锛屾棤缁撴瀯鍖栫殑澶勭悊鎺柦璁板綍 |
+| **澶嶅伐鏃堕棿璁板綍** | 鉂� **缂哄け** | 鏃犲仠宸ュ紑濮嬫椂闂淬�佸仠宸ョ粨鏉熸椂闂淬�佸仠宸ユ椂闀跨瓑瀛楁 |
+| **闀挎湡鏈鐞嗛璀�** | 鉂� **缂哄け** | 鏃犲紓甯歌秴鏃堕璀︽満鍒讹紝鏃犳硶鍙戠幇闀挎湡鏈鐞嗙殑寮傚父宸ュ崟 |
+| **寮傚父闂幆绠$悊** | 鉂� **缂哄け** | 宸ュ崟鏃犳硶浠�"寮傚父鍋滃伐"鎭㈠鍒�"鐢熶骇涓�"锛屾棤闂幆娴佺▼ |
+
+---
+
+## 缂哄け鍔熻兘姹囨��
+
+### 馃敶 涓ラ噸缂哄け锛堢洿鎺ュ奖鍝嶆牳鏌ラ�氳繃锛�
+
+| # | 缂哄け鍔熻兘 | 瀵瑰簲瑕佹眰 | 璇存槑 |
+|---|---------|---------|------|
+| 1 | **宸ュ崟寮傚父鍋滃伐鐘舵�佷笌闂幆绠$悊** | 瑕佹眰4銆�6 | 宸ュ崟鏃�"寮傚父鍋滃伐"鐘舵�侊紝鏃犳殏鍋�/澶嶅伐鎿嶄綔锛屾棤娉曞疄鐜板紓甯稿伐鍗曢棴鐜鐞� |
+| 2 | **宸ュ崟鎿嶄綔鍘嗗彶鏃堕棿绾�** | 瑕佹眰4 | 鏃犲伐鍗曚笓灞炴搷浣滃巻鍙茶〃锛屾棤娉曟寜宸ュ崟鏌ヨ瀹屾暣鐨勬搷浣滅棔杩规椂闂寸嚎 |
+| 3 | **瀹℃壒浜鸿嚜鍔ㄨ褰�** | 瑕佹眰4 | 鎶ュ伐瀹℃壒鏃舵湭鑷姩濉厖瀹℃壒浜轰负褰撳墠鐧诲綍鐢ㄦ埛 |
+
+### 馃煛 涓害缂哄け锛堝奖鍝嶆牳鏌ヨ川閲忎絾涓嶈嚧鍛斤級
+
+| # | 缂哄け鍔熻兘 | 瀵瑰簲瑕佹眰 | 璇存槑 |
+|---|---------|---------|------|
+| 4 | **宸ュ崟涓嬪彂鐜妭** | 瑕佹眰3 | 宸ュ崟鏃犵嫭绔嬬殑"涓嬪彂"鎿嶄綔鍜岀姸鎬侊紝纭鍗崇敓鏁堬紝缂哄皯涓嬪彂鑺傜偣 |
+| 5 | **宸ュ崟鏍搁攢鍔熻兘** | 瑕佹眰2 | 鏃犲伐鍗曠墿鏂�/浜ч噺鐨勬渶缁堝璐︽牳閿� |
+| 6 | **宸ュ崟褰掓。鍔熻兘** | 瑕佹眰2 | 鏃犲伐鍗曞綊妗g姸鎬佸拰褰掓。鎿嶄綔 |
+| 7 | **宸ュ崟-鐗╂枡瀵硅处** | 瑕佹眰5 | 鏃犳硶鑷姩姣斿BOM闇�姹傞噺 vs 瀹為檯棰嗙敤閲� vs 瀹為檯鑰楃敤閲� |
+| 8 | **宸ュ崟-浜ч噺瀵硅处** | 瑕佹眰5 | 鏃犳硶鑷姩姣斿宸ュ崟鏁伴噺 vs 鎶ュ伐鍚堣 vs 鍏ュ簱鍚堣 |
+| 9 | **寮傚父鍘熷洜缁撴瀯鍖栧垎鏋�** | 瑕佹眰6 | 瀹夌伅璁板綍浠呮湁鏂囨湰鍘熷洜锛屾棤寮傚父鍒嗙被(璁惧鏁呴殰/鐗╂枡鐭己/璐ㄩ噺寮傚父绛�) |
+| 10 | **澶勭悊鎺柦缁撴瀯鍖栬褰�** | 瑕佹眰6 | 瀹夌伅璁板綍浠呮湁澶囨敞锛屾棤澶勭悊鎺柦銆佸宸ユ椂闂寸瓑缁撴瀯鍖栧瓧娈� |
+
+### 馃煝 杞诲害缂哄け锛堥敠涓婃坊鑺憋級
+
+| # | 缂哄け鍔熻兘 | 瀵瑰簲瑕佹眰 | 璇存槑 |
+|---|---------|---------|------|
+| 11 | **鍋忓樊鐜囧垎鏋愪笌棰勮** | 瑕佹眰5 | 鏃犲亸宸巼璁$畻鍜岄璀﹀姛鑳� |
+| 12 | **鐢熶骇杩涘害鏃ユ姤琛�** | 瑕佹眰5 | 鏃犳寜鏃ユ眹鎬荤敓浜ц繘搴︾殑鎶ヨ〃 |
+| 13 | **寮傚父瓒呮椂棰勮** | 瑕佹眰6 | 鏃犻暱鏈熸湭澶勭悊寮傚父鐨勯璀︽満鍒� |
+| 14 | **寮�宸ヤ腑/宸ュ簭瀹屽伐鐨勫伐鍗曠骇鐘舵��** | 瑕佹眰4 | 宸ュ崟鐘舵�佺矑搴︿笉澶燂紝鏃犳硶鐩存帴鎸�"寮�宸ヤ腑""宸ュ簭瀹屽伐"鍒嗙被 |
+| 15 | **宸ュ崟鑷姩瀹屽伐** | 瑕佹眰3 | 宸ュ崟鍦� quantityProduced >= quantity 鏃朵笉浼氳嚜鍔ㄨ浆涓哄凡瀹屾垚锛岄渶鎵嬪姩 finish |
+| 16 | **浠诲姟"杩涜涓�"鐘舵��** | 瑕佹眰4 | 浠诲姟浠呮湁鑽夌/宸插畬鎴�/宸插彇娑堬紝鏃�"杩涜涓�/鐢熶骇涓�"鐘舵�侊紝鏃犳硶鍖哄垎"宸叉帓浜у緟鐢熶骇"鍜�"姝e湪鐢熶骇" |
+| 17 | **宸ュ崟澶氱骇瀹℃壒** | 瑕佹眰3 | 宸ュ崟纭鏄崟姝ユ搷浣�(鑽夌鈫掑凡纭)锛屾棤BPM宸ヤ綔娴佸绾у鎵� |
+| 18 | **quantityScheduled/quantityChanged 瀛楁** | 瑕佹眰5 | 宸ュ崟DO涓瓨鍦ㄤ絾浠庢湭琚洿鏂帮紝灞炰簬姝诲瓧娈� |
+
+---
+
+## 寤鸿浼樺厛琛ュ厖鐨勫姛鑳斤紙鎸変紭鍏堢骇鎺掑簭锛�
+
+### P0 - 蹇呴』琛ュ厖锛堟牳鏌ョ‖浼わ級
+
+**1. 宸ュ崟寮傚父鍋滃伐闂幆绠$悊**
+
+- 宸ュ崟鏂板鐘舵�侊細`SUSPENDED(4, "寮傚父鍋滃伐")`
+- 鏂板鎺ュ彛锛歚PUT /mes/pro/work-order/suspend` 鈥� 鏆傚仠宸ュ崟锛堝凡纭鈫掑紓甯稿仠宸ワ級锛岃褰曞仠宸ュ師鍥犮�佸仠宸ユ椂闂�
+- 鏂板鎺ュ彛锛歚PUT /mes/pro/work-order/resume` 鈥� 鎭㈠宸ュ崟锛堝紓甯稿仠宸モ啋宸茬‘璁わ級锛岃褰曞宸ユ椂闂淬�佸鐞嗘帾鏂�
+- 宸ュ崟DO鏂板瀛楁锛歚suspendDate`(鍋滃伐鏃堕棿)銆乣resumeDate`(澶嶅伐鏃堕棿)銆乣suspendReason`(鍋滃伐鍘熷洜)銆乣resumeMeasure`(澶嶅伐鎺柦)
+- 浠诲姟鍚屾鏀寔鏆傚仠/鎭㈠
+
+**2. 宸ュ崟鎿嶄綔鍘嗗彶璁板綍**
+
+- 鏂板琛� `mes_pro_work_order_log`锛岃褰曞伐鍗曞叏鐢熷懡鍛ㄦ湡鎿嶄綔
+- 瀛楁锛歸orkOrderId銆乷peration(鍒涘缓/纭/涓嬪彂/瀹屽伐/鍙栨秷/鏆傚仠/鎭㈠)銆乷peratorId銆乷perateTime銆乺emark
+- 鏂板鎺ュ彛锛歚GET /mes/pro/work-order/log` 鈥� 鏌ヨ宸ュ崟鎿嶄綔鍘嗗彶鏃堕棿绾�
+- 鍦ㄥ伐鍗曞悇鐘舵�佸彉鏇存搷浣滀腑鑷姩鍐欏叆鎿嶄綔璁板綍
+- **蹇嵎鏂规**锛氭鏋跺凡鏈� `@LogRecord`锛坢zt-biz-log锛�+ `system_operate_log` 琛紙鏀寔 `bizId` 鎸変笟鍔D鏌ヨ锛夛紝CRM/System 妯″潡宸插湪鐢紝MES 妯″潡浠呴渶鍦ㄥ伐鍗� Service 鏂规硶涓婂姞 `@LogRecord` 娉ㄨВ鍗冲彲瀹炵幇鍩虹鎿嶄綔鏃ュ織璁板綍锛屾棤闇�鏂板缓琛�
+
+**3. 鎶ュ伐瀹℃壒鑷姩璁板綍瀹℃壒浜�**
+
+- `approveFeedback` 鏂规硶涓嚜鍔ㄨ缃� `approveUserId = getLoginUserId()`
+
+**4. 宸ュ崟鐘舵�佽浆鎹㈣褰�"璋佹搷浣�"**
+
+- 宸ュ崟DO鏂板瀛楁锛歚confirmUserId`(纭浜�)銆乣finishUserId`(瀹屽伐浜�)銆乣cancelUserId`(鍙栨秷浜�)
+- 鍚勭姸鎬佸彉鏇存柟娉曚腑鑷姩濉厖褰撳墠鐧诲綍鐢ㄦ埛ID
+
+### P1 - 寤鸿琛ュ厖锛堟彁鍗囨牳鏌ヨ川閲忥級
+
+**4. 宸ュ崟涓嬪彂鐜妭**
+
+- 宸ュ崟鏂板鐘舵�侊細`ISSUED(2, "宸蹭笅鍙�")`锛堝湪宸茬‘璁ゅ拰宸插畬鎴愪箣闂达級
+- 鏂板鎺ュ彛锛歚PUT /mes/pro/work-order/issue` 鈥� 涓嬪彂宸ュ崟锛堝凡纭鈫掑凡涓嬪彂锛�
+- 璋冩暣瀹屽伐纭鍓嶇疆鏉′欢锛氬凡涓嬪彂鈫掑凡瀹屾垚
+
+**5. 宸ュ崟鏍搁攢涓庡綊妗�**
+
+- 宸ュ崟鏂板鐘舵�侊細`SETTLED(5, "宸叉牳閿�")`銆乣ARCHIVED(6, "宸插綊妗�")`
+- 鏍搁攢锛氭瘮瀵瑰伐鍗旴OM闇�姹傞噺 vs 瀹為檯娑堣�楅噺锛屽伐鍗曟暟閲� vs 鍏ュ簱鏁伴噺锛岀敓鎴愭牳閿�鎶ュ憡
+- 褰掓。锛氭牳閿�閫氳繃鍚庡綊妗o紝褰掓。鍚庡彧璇讳笉鍙慨鏀�
+
+**6. 寮傚父璁板綍缁撴瀯鍖栧寮�**
+
+- 瀹夌伅璁板綍鏂板瀛楁锛歚exceptionType`(寮傚父鍒嗙被锛氳澶囨晠闅�/鐗╂枡鐭己/璐ㄩ噺寮傚父/浜哄憳涓嶈冻/鍏朵粬)銆乣handleMeasure`(澶勭悊鎺柦)銆乣downtimeStart`(鍋滃伐寮�濮嬫椂闂�)銆乣downtimeEnd`(鍋滃伐缁撴潫鏃堕棿)銆乣downtimeDuration`(鍋滃伐鏃堕暱)
+- 鏂板寮傚父瓒呮椂棰勮锛氭湭澶勭疆瓒呰繃N灏忔椂鑷姩鍗囩骇閫氱煡
+
+**7. 浠诲姟鐘舵�佸寮�**
+
+- 浠诲姟鏂板鐘舵�侊細`IN_PROGRESS(1, "杩涜涓�")`锛屽湪鑽夌鍜屽凡瀹屾垚涔嬮棿
+- 鎶ュ伐鎻愪氦/瀹℃壒鏃惰嚜鍔ㄥ皢浠诲姟浠庤崏绋库啋杩涜涓�
+- 涓庡伐鍗曠姸鎬佽仈鍔細宸ュ崟鏆傚仠鏃朵换鍔″悓姝ユ殏鍋�
+
+**8. 宸ュ崟鑷姩瀹屽伐**
+
+- 褰撳伐鍗曟墍鏈変换鍔″潎宸插畬宸ワ紝鎴� `quantityProduced >= quantity` 鏃讹紝鎻愮ず鐢ㄦ埛鍙畬宸ワ紙鍙�夎嚜鍔ㄥ畬宸ワ級
+- 淇 `quantityScheduled` 鍜� `quantityChanged` 姝诲瓧娈碉細鎺掍骇鏃舵洿鏂� quantityScheduled锛岃皟鏁存暟閲忔椂鏇存柊 quantityChanged
diff --git a/docs/product_issue_task_integration.md b/docs/product_issue_task_integration.md
new file mode 100644
index 0000000..8a0e173
--- /dev/null
+++ b/docs/product_issue_task_integration.md
@@ -0,0 +1,255 @@
+# 鐢熶骇棰嗘枡/閫�鏂欏叧鑱� Task - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- 鐢熶骇棰嗘枡鍑哄簱鍗曞垪琛ㄩ〉 / 鏂板缂栬緫椤� / 琛岀鐞嗛〉
+- 鐢熶骇閫�鏂欏崟鍒楄〃椤� / 鏂板缂栬緫椤� / 琛岀鐞嗛〉
+- 鐢熶骇浠诲姟鍒楄〃椤碉紙閫夋嫨 task 鐢級
+
+## 涓氬姟娴佺▼涓庢暟鎹甫鍏�
+
+### 棰嗘枡娴佺▼
+1. **鏂板棰嗘枡鍑哄簱鍗�**锛氶�夋嫨 Task 鈫� 宸ュ崟(workOrderId)銆佸伐浣滅珯(workstationId) 浠� Task 鑷姩甯﹀叆
+2. **鏂板棰嗘枡鍑哄簱鍗曡**锛氳鍙�夊~ taskId锛岄粯璁ゅ彇涓昏〃鐨� taskId
+3. **瀹屾垚棰嗘枡鍑哄簱**锛氱郴缁熻嚜鍔ㄥ垱寤轰换鍔℃姇鏂欒褰�(mes_pro_task_issue)锛宨ssuedQuantity = availableQuantity = 琛屾暟閲�
+4. **鍙栨秷棰嗘枡鍑哄簱**锛氱郴缁熻嚜鍔ㄥ垹闄ら�氳繃璇ラ鏂欏崟鍒涘缓鐨勪换鍔℃姇鏂欒褰�
+
+### 閫�鏂欐祦绋�
+1. **鏂板閫�鏂欏崟**锛氶�夋嫨 Task 鈫� 宸ュ崟(workOrderId)銆佸伐浣滅珯(workstationId) 浠� Task 鑷姩甯﹀叆
+2. **鏂板閫�鏂欏崟琛�**锛氳鍙�夊~ taskId锛岄粯璁ゅ彇涓昏〃鐨� taskId
+3. **瀹屾垚閫�鏂�**锛氱郴缁熻嚜鍔ㄦ墸鍑忎换鍔℃姇鏂欒褰曠殑 issuedQuantity 鍜� availableQuantity
+4. **鍙栨秷閫�鏂�**锛氭棤棰濆鎿嶄綔锛堥��鏂欐湭瀹屾垚鏃朵笉褰卞搷鎶曟枡璁板綍锛�
+
+### 棰嗘枡 鈫� 閫�鏂欓棴鐜�
+
+```
+棰嗘枡瀹屾垚 鈫� task_issue: issued=100, available=100, used=0
+閫�鏂欏畬鎴� 鈫� task_issue: issued=80, available=80, used=0 (閫�浜�20)
+```
+
+---
+
+## 涓�銆侀鏂欏嚭搴撳崟 API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /mes/wm/product-issue/create | 鍒涘缓棰嗘枡鍑哄簱鍗� |
+| PUT | /mes/wm/product-issue/update | 淇敼棰嗘枡鍑哄簱鍗� |
+| GET | /mes/wm/product-issue/get | 鑾峰緱棰嗘枡鍑哄簱鍗� |
+| GET | /mes/wm/product-issue/page | 鑾峰緱棰嗘枡鍑哄簱鍗曞垎椤� |
+| PUT | /mes/wm/product-issue/submit | 鎻愪氦棰嗘枡鍑哄簱鍗� |
+| PUT | /mes/wm/product-issue/stock | 鎵ц鎷h揣 |
+| PUT | /mes/wm/product-issue/finish | 瀹屾垚棰嗘枡鍑哄簱锛堣嚜鍔ㄥ垱寤烘姇鏂欒褰曪級 |
+| PUT | /mes/wm/product-issue/cancel | 鍙栨秷棰嗘枡鍑哄簱锛堣嚜鍔ㄥ垹闄ゆ姇鏂欒褰曪級 |
+| POST | /mes/wm/product-issue-line/create | 鍒涘缓棰嗘枡鍑哄簱鍗曡 |
+| PUT | /mes/wm/product-issue-line/update | 淇敼棰嗘枡鍑哄簱鍗曡 |
+
+### 鍒涘缓/淇敼棰嗘枡鍑哄簱鍗� - 璇锋眰鍙傛暟鍙樻洿
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| taskId | Long | **鏄紙鏂板蹇呭~锛�** | 鐢熶骇浠诲姟 ID锛屼互 task 涓轰富 |
+| workOrderId | Long | **鍚︼紙鍘熷繀濉敼涓洪�夊~锛�** | 鐢熶骇宸ュ崟 ID锛屼粠 task 鑷姩甯﹀叆 |
+| workstationId | Long | 鍚� | 宸ヤ綔绔� ID锛屼粠 task 鑷姩甯﹀叆 |
+| requiredTime | LocalDateTime | 鏄� | 闇�姹傛椂闂� |
+
+**璇锋眰绀轰緥锛�**
+
+```json
+{
+ "code": "ISSUE20260716001",
+ "name": "鐢熶骇棰嗘枡",
+ "taskId": 1,
+ "requiredTime": "2026-07-16 10:00:00",
+ "remark": ""
+}
+```
+
+**鍝嶅簲锛�** `{ "code": 0, "data": 1 }`
+
+### 棰嗘枡鍑哄簱鍗� - 鍝嶅簲瀛楁鏂板
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| taskId | Long | 鐢熶骇浠诲姟 ID |
+| taskCode | String | **鏂板** 鐢熶骇浠诲姟缂栫爜 |
+| taskName | String | **鏂板** 鐢熶骇浠诲姟鍚嶇О |
+| requiredTime | LocalDateTime | 闇�姹傛椂闂� |
+
+**鍝嶅簲绀轰緥锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "id": 1,
+ "code": "ISSUE20260716001",
+ "name": "鐢熶骇棰嗘枡",
+ "taskId": 1,
+ "taskCode": "TASK001",
+ "taskName": "娉ㄥ浠诲姟",
+ "workOrderId": 10,
+ "workOrderCode": "WO001",
+ "workstationId": 5,
+ "workstationName": "瑁呴厤宸ヤ綔绔�",
+ "clientCode": "C001",
+ "clientName": "鏌愭煇瀹㈡埛",
+ "issueDate": null,
+ "requiredTime": "2026-07-16 10:00:00",
+ "status": 0,
+ "remark": "",
+ "createTime": "2026-07-16 10:00:00"
+ }
+}
+```
+
+### 棰嗘枡鍑哄簱鍗曡 - 璇锋眰/鍝嶅簲瀛楁鏂板
+
+| 瀛楁 | 绫诲瀷 | 璇锋眰 | 鍝嶅簲 | 璇存槑 |
+|------|------|------|------|------|
+| taskId | Long | 閫夊~ | - | 鐢熶骇浠诲姟 ID锛岄粯璁ゅ彇涓昏〃鐨� taskId |
+| taskCode | String | - | 鏂板 | 鐢熶骇浠诲姟缂栫爜 |
+| taskName | String | - | 鏂板 | 鐢熶骇浠诲姟鍚嶇О |
+
+---
+
+## 浜屻�侀��鏂欏崟 API
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /mes/wm/return-issue/create | 鍒涘缓閫�鏂欏崟 |
+| PUT | /mes/wm/return-issue/update | 淇敼閫�鏂欏崟 |
+| GET | /mes/wm/return-issue/get | 鑾峰緱閫�鏂欏崟 |
+| GET | /mes/wm/return-issue/page | 鑾峰緱閫�鏂欏崟鍒嗛〉 |
+| PUT | /mes/wm/return-issue/submit | 鎻愪氦閫�鏂欏崟 |
+| PUT | /mes/wm/return-issue/stock | 鍏ュ簱涓婃灦 |
+| PUT | /mes/wm/return-issue/finish | 瀹屾垚閫�鏂欙紙鑷姩鎵e噺鎶曟枡璁板綍鍙敤閲忥級 |
+| PUT | /mes/wm/return-issue/cancel | 鍙栨秷閫�鏂� |
+| POST | /mes/wm/return-issue-line/create | 鍒涘缓閫�鏂欏崟琛� |
+| PUT | /mes/wm/return-issue-line/update | 淇敼閫�鏂欏崟琛� |
+
+### 鍒涘缓/淇敼閫�鏂欏崟 - 璇锋眰鍙傛暟鍙樻洿
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| taskId | Long | **鏄紙鏂板蹇呭~锛�** | 鐢熶骇浠诲姟 ID锛屼互 task 涓轰富 |
+| workOrderId | Long | **鍚︼紙鍘熷繀濉敼涓洪�夊~锛�** | 鐢熶骇宸ュ崟 ID锛屼粠 task 鑷姩甯﹀叆 |
+| workstationId | Long | 鍚� | 宸ヤ綔绔� ID锛屼粠 task 鑷姩甯﹀叆 |
+
+**璇锋眰绀轰緥锛�**
+
+```json
+{
+ "code": "RI20260716001",
+ "name": "鐢熶骇閫�鏂�",
+ "taskId": 1,
+ "type": 1,
+ "remark": ""
+}
+```
+
+**鍝嶅簲锛�** `{ "code": 0, "data": 1 }`
+
+### 閫�鏂欏崟 - 鍝嶅簲瀛楁鏂板
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| taskId | Long | **鏂板** 鐢熶骇浠诲姟 ID |
+| taskCode | String | **鏂板** 鐢熶骇浠诲姟缂栫爜 |
+| taskName | String | **鏂板** 鐢熶骇浠诲姟鍚嶇О |
+
+**鍝嶅簲绀轰緥锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "id": 1,
+ "code": "RI20260716001",
+ "name": "鐢熶骇閫�鏂�",
+ "taskId": 1,
+ "taskCode": "TASK001",
+ "taskName": "娉ㄥ浠诲姟",
+ "workOrderId": 10,
+ "workOrderCode": "WO001",
+ "workstationId": 5,
+ "workstationName": "瑁呴厤宸ヤ綔绔�",
+ "type": 1,
+ "returnDate": null,
+ "status": 0,
+ "remark": "",
+ "createTime": "2026-07-16 10:00:00"
+ }
+}
+```
+
+### 閫�鏂欏崟琛� - 璇锋眰/鍝嶅簲瀛楁鏂板
+
+| 瀛楁 | 绫诲瀷 | 璇锋眰 | 鍝嶅簲 | 璇存槑 |
+|------|------|------|------|------|
+| taskId | Long | 閫夊~ | - | 鐢熶骇浠诲姟 ID锛岄粯璁ゅ彇涓昏〃鐨� taskId |
+| taskCode | String | - | 鏂板 | 鐢熶骇浠诲姟缂栫爜 |
+| taskName | String | - | 鏂板 | 鐢熶骇浠诲姟鍚嶇О |
+
+### 閫�鏂欏崟鍒嗛〉 - 璇锋眰鍙傛暟鏂板
+
+| 鍙傛暟 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| taskId | Long | **鏂板** 鎸夌敓浜т换鍔� ID 杩囨护 |
+
+---
+
+## 瀛楁灞曠ず瑙勫垯
+
+### 棰嗘枡鍑哄簱鍗�
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| taskId | 鏂板/缂栬緫琛ㄥ崟 | 蹇呭~锛岄�夋嫨 Task 涓嬫媺妗� |
+| taskCode | 鍒楄〃銆佽鎯� | 浠� Task 鑷姩甯﹀叆灞曠ず |
+| taskName | 鍒楄〃銆佽鎯� | 浠� Task 鑷姩甯﹀叆灞曠ず |
+| workOrderId | 鏂板/缂栬緫琛ㄥ崟 | 閫夊~锛岄�夋嫨 Task 鍚庤嚜鍔ㄥ~鍏ワ紝鍙墜鍔ㄤ慨鏀� |
+| workOrderCode | 鍒楄〃銆佽鎯� | 浠庡伐鍗曡嚜鍔ㄥ甫鍏ュ睍绀� |
+| workstationId | 鏂板/缂栬緫琛ㄥ崟 | 閫夊~锛岄�夋嫨 Task 鍚庤嚜鍔ㄥ~鍏ワ紝鍙墜鍔ㄤ慨鏀� |
+| workstationName | 鍒楄〃銆佽鎯� | 浠庡伐浣滅珯鑷姩甯﹀叆灞曠ず |
+| requiredTime | 鏂板/缂栬緫琛ㄥ崟銆佽鎯� | 蹇呭~锛岄渶姹傛椂闂� |
+| 琛岀骇 taskId | 琛屾柊澧�/缂栬緫琛ㄥ崟 | 閫夊~锛岄粯璁ゅ彇涓昏〃 taskId |
+
+### 閫�鏂欏崟
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| taskId | 鏂板/缂栬緫琛ㄥ崟 | 蹇呭~锛岄�夋嫨 Task 涓嬫媺妗� |
+| taskCode | 鍒楄〃銆佽鎯� | 浠� Task 鑷姩甯﹀叆灞曠ず |
+| taskName | 鍒楄〃銆佽鎯� | 浠� Task 鑷姩甯﹀叆灞曠ず |
+| workOrderId | 鏂板/缂栬緫琛ㄥ崟 | 閫夊~锛岄�夋嫨 Task 鍚庤嚜鍔ㄥ~鍏ワ紝鍙墜鍔ㄤ慨鏀� |
+| workOrderCode | 鍒楄〃銆佽鎯� | 浠庡伐鍗曡嚜鍔ㄥ甫鍏ュ睍绀� |
+| workstationId | 鏂板/缂栬緫琛ㄥ崟 | 閫夊~锛岄�夋嫨 Task 鍚庤嚜鍔ㄥ~鍏ワ紝鍙墜鍔ㄤ慨鏀� |
+| workstationName | 鍒楄〃銆佽鎯� | 浠庡伐浣滅珯鑷姩甯﹀叆灞曠ず |
+| 琛岀骇 taskId | 琛屾柊澧�/缂栬緫琛ㄥ崟 | 閫夊~锛岄粯璁ゅ彇涓昏〃 taskId |
+
+---
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 鏂板棰嗘枡/閫�鏂欏崟 | taskId 蹇呭~锛涢�夋嫨 task 鍚庤嚜鍔ㄥ甫鍏� workOrderId 鍜� workstationId |
+| 淇敼棰嗘枡/閫�鏂欏崟 | taskId 蹇呭~锛涘悓鏂板瑙勫垯 |
+| 棰嗘枡鍑哄簱瀹屾垚 | 绯荤粺鑷姩鎸夎鍒涘缓 mes_pro_task_issue 鎶曟枡璁板綍锛宻ourceDocType=PRODUCT_ISSUE |
+| 鍙栨秷棰嗘枡鍑哄簱 | 绯荤粺鑷姩鍒犻櫎閫氳繃璇ラ鏂欏崟鍒涘缓鐨勬姇鏂欒褰� |
+| 閫�鏂欏畬鎴� | 绯荤粺鑷姩鎵e噺瀵瑰簲 task_issue 鐨� issuedQuantity 鍜� availableQuantity |
+| 琛岀骇 taskId | 琛岀殑 taskId 浼樺厛浜庝富琛ㄧ殑 taskId锛涘鏋滆涓虹┖鍒欏彇涓昏〃鐨� |
+| 鎶曟枡璁板綍鍖归厤 | 閫�鏂欐墸鍑忔椂锛屾寜 taskId + itemId + sourceDocType=PRODUCT_ISSUE 鍖归厤鎶曟枡璁板綍 |
+
+---
+
+## 娉ㄦ剰浜嬮」
+
+- **浠� task 涓轰富**锛氬垱寤洪鏂�/閫�鏂欏崟鏃讹紝蹇呴』鍏堥�夋嫨 task锛屽伐鍗曞拰宸ヤ綔绔欎粠 task 鑷姩甯﹀叆
+- **workOrderId 涓嶅啀鏄繀濉�**锛氬墠绔〃鍗曚腑 workOrderId 鏀逛负閫夊~锛岄�夋嫨 task 鍚庤嚜鍔ㄥ~鍏�
+- **琛岀骇 taskId**锛氳琛ㄦ柊澧� taskId 瀛楁锛屽墠绔缂栬緫鏃跺彲閫夋嫨涓嶅悓鐨� task锛堥粯璁ゅ彇涓昏〃鐨勶級
+- **鎶曟枡璁板綍鑷姩绠$悊**锛氶鏂欏畬鎴愯嚜鍔ㄥ垱寤烘姇鏂欒褰曪紝閫�鏂欏畬鎴愯嚜鍔ㄦ墸鍑忔姇鏂欏彲鐢ㄩ噺锛屽墠绔棤闇�棰濆鎿嶄綔
+- **鍒嗛〉鏌ヨ鏀寔 taskId**锛氶鏂欏嚭搴撳崟鍜岄��鏂欏崟鍒嗛〉鎺ュ彛鍧囨敮鎸佹寜 taskId 杩囨护鏌ヨ
+- **棰嗘枡鍙栨秷**锛氬彇娑堥鏂欐椂锛屽彧鏈夐�氳繃璇ラ鏂欏崟鍒涘缓鐨勬姇鏂欒褰曚細琚垹闄わ紙鎸� sourceDocType + sourceDocId 鍖归厤锛�
+- **閫�鏂欐墸鍑�**锛氶��鏂欐墸鍑忔姇鏂欒褰曟椂锛宨ssuedQuantity 鍜� availableQuantity 鏈�浣庝负 0锛屼笉浼氬嚭鐜拌礋鏁�
diff --git a/docs/production_data_cleanup.md b/docs/production_data_cleanup.md
new file mode 100644
index 0000000..d1eac8e
--- /dev/null
+++ b/docs/production_data_cleanup.md
@@ -0,0 +1,244 @@
+# MES 涓氬姟鏁版嵁娓呯悊 SQL
+
+## 娓呯悊鑼冨洿
+
+娓呯悊 MES 妯″潡鍏ㄩ儴涓氬姟鏁版嵁锛屼繚鐣欑郴缁熼厤缃被鏁版嵁銆傛寜渚濊禆椤哄簭鎵ц銆�
+
+### 娓呯悊鍒嗙被
+
+| 鍒嗙被 | 娑夊強琛� | 璇存槑 |
+|------|--------|------|
+| 搴撳瓨浜嬪姟/鍗犵敤 | transaction, stock_reserve | 鐢熶骇鐩稿叧 biz_type |
+| 鐗╂枡娑堣�楀崟 | item_consume + 琛�/鏄庣粏 | 鍊掑啿娑堣�楄褰� |
+| 浜у嚭鍗�/鍏ュ簱鍗� | product_produce, product_receipt + 琛�/鏄庣粏 | 鐢熶骇浜у嚭 |
+| 閫�鏂欏崟 | return_issue + 琛�/鏄庣粏 | 鐢熶骇閫�鏂� |
+| 棰嗘枡鍑哄簱鍗� | product_issue + 琛�/鏄庣粏 | 鐢熶骇棰嗘枡 |
+| 璐ㄦ鍗� | ipqc, rqc, iqc, oqc + 琛�/缂洪櫡/鎸囨爣 | 璐ㄦ璁板綍 |
+| 鎶ュ伐 | feedback | 鐢熶骇鎶ュ伐 |
+| 浠诲姟鎶曟枡 | task_issue | 鎶曟枡璁板綍 |
+| 鐢熶骇浠诲姟 | task | 鎺掍骇浠诲姟 |
+| 宸ュ崟 | work_order + bom + 鍙傛暟璁板綍 | 鐢熶骇宸ュ崟 |
+| 娴佽浆鍗� | card + 宸ュ簭璁板綍 | 鐢熶骇娴佽浆鍗� |
+| 瀹夌伅 | andon_config, andon_record | 瀹夌伅鍛煎彨 |
+| 涓婁笅宸� | work_record, work_record_log | 宸ヤ綔绔欑粦瀹�/涓婁笅宸� |
+| 宸ヨ壓璺嚎 | route + 宸ュ簭/浜у搧/BOM | 宸ヨ壓璺嚎鍙婂叧鑱� |
+| 宸ュ簭 | process + 鍐呭 | 鐢熶骇宸ュ簭 |
+| 浜у搧BOM/SIP/SOP | product_bom, product_sip, product_sop | 浜у搧鏂囨。 |
+| 鐗╂枡 | item + 鍒嗙被/鎵规閰嶇疆 | MES 鐗╂枡 |
+| 璁¢噺鍗曚綅 | unit_measure | MES 璁¢噺鍗曚綅 |
+| 瀹㈡埛/渚涘簲鍟� | client, vendor | MES 瀹㈡埛/渚涘簲鍟� |
+| 杞﹂棿/宸ヤ綔绔� | workshop, workstation + 璧勬簮 | MES 杞﹂棿/宸ヤ綔绔� |
+| 缂栫爜瑙勫垯 | auto_code_rule + 缁勬垚/璁板綍 | 缂栫爜瑙勫垯 |
+
+## 褰撳墠鏁版嵁閲�
+
+| 琛� | 璁板綍鏁� | 琛� | 璁板綍鏁� |
+|----|--------|----|--------|
+| mes_pro_work_order | 2 | mes_pro_task | 3 |
+| mes_pro_feedback | 13 | mes_pro_task_issue | 0 |
+| mes_pro_process | 6 | mes_pro_route | 2 |
+| mes_pro_route_process | 5 | mes_pro_route_product | 2 |
+| mes_pro_route_product_bom | 6 | mes_pro_work_order_bom | 3 |
+| mes_wm_product_issue | 4 | mes_wm_return_issue | 3 |
+| mes_wm_item_consume | 5 | mes_wm_transaction(鐢熶骇) | 9 |
+| mes_wm_stock_reserve | 1 | mes_md_item | 9 |
+| mes_md_product_bom | 11 | mes_md_workstation | 1 |
+| mes_md_unit_measure | 2 | mes_md_item_type | 5 |
+
+## 娓呯悊 SQL
+
+```sql
+-- ============================================================
+-- MES 鍏ㄩ儴涓氬姟鏁版嵁娓呯悊鑴氭湰
+-- 鎵ц鍓嶈纭锛氳繖浜涙暟鎹彲浠ュ垹闄わ紝涓嶅彲鎭㈠锛�
+-- ============================================================
+
+-- ==================== 1. 搴撳瓨鍗犵敤锛堢敓浜х浉鍏筹級 ====================
+DELETE FROM mes_wm_stock_reserve
+WHERE biz_type IN (4, 5); -- 4=鐢熶骇棰嗘枡, 5=鐢熶骇浜у嚭
+
+-- ==================== 2. 搴撳瓨浜嬪姟娴佹按锛堢敓浜х浉鍏� biz_type锛� ====================
+-- 116=鐢熶骇棰嗘枡, 117=鐢熶骇閫�鏂�, 118=鐢熶骇鍏ュ簱, 123=鐢熶骇娑堣��, 124=浜у搧浜у嚭
+DELETE FROM mes_wm_transaction
+WHERE biz_type IN (116, 117, 118, 123, 124);
+
+-- ==================== 3. 鐗╂枡娑堣�楀崟 ====================
+DELETE FROM mes_wm_item_consume_detail;
+DELETE FROM mes_wm_item_consume_line;
+DELETE FROM mes_wm_item_consume;
+
+-- ==================== 4. 鐢熶骇浜у嚭鍗� ====================
+DELETE FROM mes_wm_product_produce_detail;
+DELETE FROM mes_wm_product_produce_line;
+DELETE FROM mes_wm_product_produce;
+
+-- ==================== 5. 鐢熶骇鍏ュ簱鍗� ====================
+DELETE FROM mes_wm_product_receipt_detail;
+DELETE FROM mes_wm_product_receipt_line;
+DELETE FROM mes_wm_product_receipt;
+
+-- ==================== 6. 鐢熶骇閫�鏂欏崟 ====================
+DELETE FROM mes_wm_return_issue_detail;
+DELETE FROM mes_wm_return_issue_line;
+DELETE FROM mes_wm_return_issue;
+
+-- ==================== 7. 鐢熶骇棰嗘枡鍑哄簱鍗� ====================
+DELETE FROM mes_wm_product_issue_detail;
+DELETE FROM mes_wm_product_issue_line;
+DELETE FROM mes_wm_product_issue;
+
+-- ==================== 8. 璐ㄦ璁板綍 ====================
+DELETE FROM mes_qc_indicator_result_detail;
+DELETE FROM mes_qc_indicator_result;
+DELETE FROM mes_qc_defect_record;
+DELETE FROM mes_qc_ipqc_line;
+DELETE FROM mes_qc_ipqc;
+DELETE FROM mes_qc_rqc_line;
+DELETE FROM mes_qc_rqc;
+DELETE FROM mes_qc_iqc_line;
+DELETE FROM mes_qc_iqc;
+DELETE FROM mes_qc_oqc_line;
+DELETE FROM mes_qc_oqc;
+
+-- ==================== 9. 鐢熶骇鎶ュ伐 ====================
+DELETE FROM mes_pro_feedback;
+
+-- ==================== 10. 浠诲姟鎶曟枡璁板綍 ====================
+DELETE FROM mes_pro_task_issue;
+
+-- ==================== 11. 鐢熶骇浠诲姟 ====================
+DELETE FROM mes_pro_task;
+
+-- ==================== 12. 宸ュ崟鍙傛暟璁板綍 ====================
+DELETE FROM mes_pro_work_order_param_record_detail;
+DELETE FROM mes_pro_work_order_param_record;
+
+-- ==================== 13. 宸ュ崟 BOM ====================
+DELETE FROM mes_pro_work_order_bom;
+
+-- ==================== 14. 鐢熶骇宸ュ崟 ====================
+DELETE FROM mes_pro_work_order;
+
+-- ==================== 15. 娴佽浆鍗� ====================
+DELETE FROM mes_pro_card_process;
+DELETE FROM mes_pro_card;
+
+-- ==================== 16. 瀹夌伅 ====================
+DELETE FROM mes_pro_andon_record;
+DELETE FROM mes_pro_andon_config;
+
+-- ==================== 17. 涓婁笅宸ヨ褰� ====================
+DELETE FROM mes_pro_work_record_log;
+DELETE FROM mes_pro_work_record;
+
+-- ==================== 18. 宸ヨ壓璺嚎浜у搧 BOM ====================
+DELETE FROM mes_pro_route_product_bom;
+
+-- ==================== 19. 宸ヨ壓璺嚎浜у搧 ====================
+DELETE FROM mes_pro_route_product;
+
+-- ==================== 20. 宸ヨ壓璺嚎宸ュ簭 ====================
+DELETE FROM mes_pro_route_process;
+
+-- ==================== 21. 宸ヨ壓璺嚎 ====================
+DELETE FROM mes_pro_route;
+
+-- ==================== 22. 宸ュ簭鍐呭 ====================
+DELETE FROM mes_pro_process_content;
+
+-- ==================== 23. 鐢熶骇宸ュ簭 ====================
+DELETE FROM mes_pro_process;
+
+-- ==================== 24. 浜у搧 SOP ====================
+DELETE FROM mes_md_product_sop;
+
+-- ==================== 25. 浜у搧 SIP ====================
+DELETE FROM mes_md_product_sip;
+
+-- ==================== 26. 浜у搧 BOM ====================
+DELETE FROM mes_md_product_bom;
+
+-- ==================== 27. 鐗╂枡鎵规閰嶇疆 ====================
+DELETE FROM mes_md_item_batch_config;
+
+-- ==================== 28. MES 鐗╂枡 ====================
+DELETE FROM mes_md_item;
+
+-- ==================== 29. 鐗╂枡鍒嗙被 ====================
+DELETE FROM mes_md_item_type;
+
+-- ==================== 30. 璁¢噺鍗曚綅 ====================
+DELETE FROM mes_md_unit_measure;
+
+-- ==================== 31. 瀹㈡埛 ====================
+DELETE FROM mes_md_client;
+
+-- ==================== 32. 渚涘簲鍟� ====================
+DELETE FROM mes_md_vendor;
+
+-- ==================== 33. 宸ヤ綔绔欒祫婧� ====================
+DELETE FROM mes_md_workstation_machine;
+DELETE FROM mes_md_workstation_tool;
+DELETE FROM mes_md_workstation_worker;
+
+-- ==================== 34. 宸ヤ綔绔� ====================
+DELETE FROM mes_md_workstation;
+
+-- ==================== 35. 杞﹂棿 ====================
+DELETE FROM mes_md_workshop;
+
+-- ==================== 36. 璐ㄦ鏂规 ====================
+DELETE FROM mes_qc_template_indicator;
+DELETE FROM mes_qc_template_item;
+DELETE FROM mes_qc_template;
+
+-- ==================== 37. 缂洪櫡绫诲瀷 ====================
+DELETE FROM mes_qc_defect;
+
+-- ==================== 38. 璐ㄦ鎸囨爣 ====================
+DELETE FROM mes_qc_indicator;
+
+-- ==================== 39. 缂栫爜瑙勫垯 ====================
+DELETE FROM mes_md_auto_code_record;
+DELETE FROM mes_md_auto_code_part;
+DELETE FROM mes_md_auto_code_rule;
+```
+
+## 楠岃瘉 SQL
+
+```sql
+-- 楠岃瘉娓呯悊缁撴灉锛岄鏈熷叏閮ㄤ负 0
+SELECT 'mes_pro_work_order' as tbl, COUNT(*) as cnt FROM mes_pro_work_order WHERE deleted=0
+UNION ALL SELECT 'mes_pro_task', COUNT(*) FROM mes_pro_task WHERE deleted=0
+UNION ALL SELECT 'mes_pro_feedback', COUNT(*) FROM mes_pro_feedback WHERE deleted=0
+UNION ALL SELECT 'mes_pro_task_issue', COUNT(*) FROM mes_pro_task_issue WHERE deleted=0
+UNION ALL SELECT 'mes_pro_process', COUNT(*) FROM mes_pro_process WHERE deleted=0
+UNION ALL SELECT 'mes_pro_route', COUNT(*) FROM mes_pro_route WHERE deleted=0
+UNION ALL SELECT 'mes_pro_route_process', COUNT(*) FROM mes_pro_route_process WHERE deleted=0
+UNION ALL SELECT 'mes_pro_route_product', COUNT(*) FROM mes_pro_route_product WHERE deleted=0
+UNION ALL SELECT 'mes_pro_route_product_bom', COUNT(*) FROM mes_pro_route_product_bom WHERE deleted=0
+UNION ALL SELECT 'mes_wm_product_issue', COUNT(*) FROM mes_wm_product_issue WHERE deleted=0
+UNION ALL SELECT 'mes_wm_return_issue', COUNT(*) FROM mes_wm_return_issue WHERE deleted=0
+UNION ALL SELECT 'mes_wm_item_consume', COUNT(*) FROM mes_wm_item_consume WHERE deleted=0
+UNION ALL SELECT 'mes_wm_product_produce', COUNT(*) FROM mes_wm_product_produce WHERE deleted=0
+UNION ALL SELECT 'mes_wm_product_receipt', COUNT(*) FROM mes_wm_product_receipt WHERE deleted=0
+UNION ALL SELECT 'mes_md_item', COUNT(*) FROM mes_md_item WHERE deleted=0
+UNION ALL SELECT 'mes_md_item_type', COUNT(*) FROM mes_md_item_type WHERE deleted=0
+UNION ALL SELECT 'mes_md_product_bom', COUNT(*) FROM mes_md_product_bom WHERE deleted=0
+UNION ALL SELECT 'mes_md_unit_measure', COUNT(*) FROM mes_md_unit_measure WHERE deleted=0
+UNION ALL SELECT 'mes_md_client', COUNT(*) FROM mes_md_client WHERE deleted=0
+UNION ALL SELECT 'mes_md_vendor', COUNT(*) FROM mes_md_vendor WHERE deleted=0
+UNION ALL SELECT 'mes_md_workstation', COUNT(*) FROM mes_md_workstation WHERE deleted=0
+UNION ALL SELECT 'mes_md_workshop', COUNT(*) FROM mes_md_workshop WHERE deleted=0
+UNION ALL SELECT 'mes_wm_stock_reserve(鐢熶骇)', COUNT(*) FROM mes_wm_stock_reserve WHERE deleted=0 AND biz_type IN (4, 5)
+UNION ALL SELECT 'mes_wm_transaction(鐢熶骇)', COUNT(*) FROM mes_wm_transaction WHERE deleted=0 AND biz_type IN (116, 117, 118, 123, 124);
+```
+
+## 娉ㄦ剰浜嬮」
+
+- 浠ヤ笂 SQL 浣跨敤鐗╃悊鍒犻櫎锛圖ELETE锛夛紝**鎵ц鍚庝笉鍙仮澶�**
+- 鎵ц椤哄簭寰堥噸瑕侊細鍏堝垹瀛愯〃/鏄庣粏锛屽啀鍒犱富琛紝閬垮厤澶栭敭绾︽潫鎶ラ敊
+- **搴撳瓨璁板綍(mes_wm_material_stock)涓嶆竻鐞�**锛氭竻鐞嗕簨鍔℃祦姘村悗锛屽簱瀛樺彴璐﹀彲鑳芥湁娈嬬暀鏁伴噺锛屽闇�閲嶇疆闇�鍗曠嫭澶勭悊
+- **浠撳簱/搴撳尯/搴撲綅(mes_wm_warehouse 绛�)涓嶆竻鐞�**锛氬熀纭�璁炬柦鏁版嵁淇濈暀
+- **鎵规(mes_wm_batch)涓嶆竻鐞�**锛氭壒娆″熀纭�鏁版嵁淇濈暀
+- **閲囪喘/閿�鍞�/璋冩嫧绛夊叾浠栦笟鍔℃暟鎹笉娓呯悊**锛氬彧娓呯悊 MES 鐢熶骇鐩稿叧
diff --git a/docs/production_feedback_integration.md b/docs/production_feedback_integration.md
new file mode 100644
index 0000000..b1171a9
--- /dev/null
+++ b/docs/production_feedback_integration.md
@@ -0,0 +1,599 @@
+# 鐢熶骇鎶ュ伐 - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- 寰呮姤宸ュ彴璐︼紙鎶ュ伐鍏ュ彛锛屾寜宸ュ簭绛涢�変换鍔★紝閫夋嫨浠诲姟杩涜鎶ュ伐锛�
+- 鐢熶骇鎶ュ伐锛堟柊澧�/缂栬緫鎶ュ伐鍗曪級
+- 鎶ュ伐瀹℃壒锛堝鎵�/椹冲洖鎿嶄綔锛�
+- 鎶ュ伐璇︽儏锛堟煡鐪嬫姤宸ヤ俊鎭� + 杩芥函浜у嚭/娑堣��/璐ㄦ锛�
+
+## 涓氬姟娴佺▼涓庢暟鎹甫鍏�
+
+```
+1. 寰呮姤宸ュ彴璐�(鎸夊伐搴忕瓫閫�) 鈫� 閫夋嫨浠诲姟 鈫� 鎶ュ伐
+ 閫夋嫨浠诲姟鍚庯紝鑷姩甯﹀叆锛歵askId銆亀orkOrderId銆乺outeId銆乸rocessId銆�
+ workstationId銆乮temId銆乻cheduledQuantity(鎺掍骇鏁伴噺)
+
+2. 濉啓鎶ュ伐 鈫� 淇濆瓨(鑽夌) 鈫� 鎻愪氦(瀹℃壒涓�) 鈫� 瀹℃壒閫氳繃(宸插畬鎴�/寰呮楠�)
+ - 璐ㄦ宸ュ簭锛氬彧闇�濉姤宸ユ暟閲忥紝鍚堟牸/涓嶅悎鏍肩敱璐ㄦ缁撴灉鍥炲~
+ - 闈炶川妫�宸ュ簭锛氶渶濉悎鏍煎搧 + 涓嶈壇鍝佹暟閲�
+
+3. 瀹℃壒椹冲洖 鈫� 閫�鍥炶崏绋� 鈫� 淇敼鍚庨噸鏂版彁浜�
+```
+
+## 鐘舵�佹祦杞�
+
+### 鐢熶骇浠诲姟鐘舵��
+
+| 鐘舵�佸�� | 鐘舵�佸悕 | 璇存槑 |
+|--------|--------|------|
+| 0 | 鑽夌(杩涜涓�) | 鍙姤宸� |
+| 4 | 宸插畬鎴� | 涓嶅彲鎶ュ伐 |
+| 5 | 宸插彇娑� | 涓嶅彲鎶ュ伐 |
+
+### 鐢熶骇鎶ュ伐鐘舵��
+
+| 鐘舵�佸�� | 鐘舵�佸悕 | 鍙墽琛屾搷浣� | 璇存槑 |
+|--------|--------|-----------|------|
+| 0 | 鑽夌 | 缂栬緫銆佸垹闄ゃ�佹彁浜� | 鍒濆鐘舵�� |
+| 2 | 瀹℃壒涓� | 瀹℃壒銆侀┏鍥� | 宸叉彁浜ゅ緟瀹℃壒 |
+| 3 | 寰呮楠� | 鈥� | 鍏抽敭+璐ㄦ宸ュ簭瀹℃壒鍚庤繘鍏ワ紝绛塈PQC鍥炶皟 |
+| 4 | 宸插畬鎴� | 鈥� | 鏈�缁堢姸鎬� |
+
+---
+
+## API
+
+### 涓�銆佸緟鎶ュ伐鍙拌处鎺ュ彛
+
+#### 1.1 寰呮姤宸ュ彴璐︼紙鍒嗛〉锛�
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/pro/task/pending-feedback-page | 宸叉帓浜т笖浠嶆湁寰呮姤宸ラ噺鐨勪换鍔� |
+
+**璇存槑锛�** 姝ゆ帴鍙d粎杩斿洖鐘舵��=杩涜涓�(0)涓� `quantity - produced_quantity > 0` 鐨勪换鍔★紝鏄姤宸ラ〉闈㈢殑鍏ュ彛鏁版嵁婧愩��
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| processId | Long | 鍚� | 宸ュ簭缂栧彿锛堟寜宸ュ簭绛涢�変换鍔★級 |
+| routeId | Long | 鍚� | 宸ヨ壓璺嚎缂栧彿 |
+| workOrderId | Long | 鍚� | 鐢熶骇宸ュ崟缂栧彿 |
+| workstationId | Long | 鍚� | 宸ヤ綔绔欑紪鍙� |
+| code | String | 鍚� | 浠诲姟缂栫爜锛堟ā绯婂尮閰嶏級 |
+| name | String | 鍚� | 浠诲姟鍚嶇О锛堟ā绯婂尮閰嶏級 |
+| checkFlag | Boolean | 鍚� | 鏄惁璐ㄦ宸ュ簭 |
+| createTime | String[] | 鍚� | 鍒涘缓鏃堕棿鑼冨洿 |
+| pageNo | Integer | 鏄� | 椤电爜锛堥粯璁�1锛� |
+| pageSize | Integer | 鏄� | 姣忛〉鏉℃暟锛堥粯璁�10锛� |
+
+**鍝嶅簲瀛楁锛�**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| id | Long | 浠诲姟缂栧彿 |
+| code | String | 浠诲姟缂栫爜 |
+| name | String | 浠诲姟鍚嶇О |
+| workOrderId | Long | 宸ュ崟缂栧彿 |
+| workOrderCode | String | 宸ュ崟缂栫爜 |
+| workOrderName | String | 宸ュ崟鍚嶇О |
+| workstationId | Long | 宸ヤ綔绔欑紪鍙� |
+| workstationCode | String | 宸ヤ綔绔欑紪鐮� |
+| workstationName | String | 宸ヤ綔绔欏悕绉� |
+| routeId | Long | 宸ヨ壓璺嚎缂栧彿 |
+| processId | Long | 宸ュ簭缂栧彿 |
+| processName | String | 宸ュ簭鍚嶇О |
+| itemId | Long | 浜у搧鐗╂枡缂栧彿 |
+| itemCode | String | 鐗╂枡缂栫爜 |
+| itemName | String | 鐗╂枡鍚嶇О |
+| itemSpecification | String | 瑙勬牸鍨嬪彿 |
+| unitMeasureName | String | 璁¢噺鍗曚綅 |
+| quantity | BigDecimal | 鎺掍骇鏁伴噺 |
+| producedQuantity | BigDecimal | 宸茬敓浜ф暟閲� |
+| qualifyQuantity | BigDecimal | 鍚堟牸鍝佹暟閲� |
+| unqualifyQuantity | BigDecimal | 涓嶈壇鍝佹暟閲� |
+| pendingQuantity | BigDecimal | 寰呮姤宸ユ暟閲忥紙= 鎺掍骇 - 宸茬敓浜э級 |
+| inTransitQuantity | BigDecimal | 鍦ㄩ�旀姤宸ユ暟閲忥紙鑽夌/瀹℃壒涓�/寰呮楠岀姸鎬佺殑鎶ュ伐閲忓悎璁★級 |
+| reportableQuantity | BigDecimal | 鍙姤宸ユ暟閲忥紙= 鎺掍骇 - 宸茬敓浜� - 鍦ㄩ�旓級 |
+| feedbackRate | BigDecimal | 鎶ュ伐瀹屾垚鐜�(%)锛屽 50.00 琛ㄧず 50% |
+| checkFlag | Boolean | 鏄惁璐ㄦ宸ュ簭 |
+| clientId | Long | 瀹㈡埛缂栧彿 |
+| clientName | String | 瀹㈡埛鍚嶇О |
+| startTime | LocalDateTime | 寮�濮嬬敓浜ф椂闂� |
+| endTime | LocalDateTime | 缁撴潫鐢熶骇鏃堕棿 |
+| duration | Integer | 鐢熶骇鏃堕暱锛堝伐浣滄棩锛� |
+| requestDate | LocalDateTime | 闇�姹傛棩鏈� |
+| status | Integer | 浠诲姟鐘舵�� |
+| remark | String | 澶囨敞 |
+| createTime | LocalDateTime | 鍒涘缓鏃堕棿 |
+
+**鍝嶅簲绀轰緥锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "list": [
+ {
+ "id": 1,
+ "code": "PT202503150001",
+ "name": "娉ㄥ浠诲姟",
+ "workOrderId": 10,
+ "workOrderCode": "MO202503120008",
+ "workOrderName": "鍗氫笘铻轰笣鍒�",
+ "workstationId": 5,
+ "workstationCode": "WS-001",
+ "workstationName": "娉ㄥ宸ヤ綔绔�",
+ "routeId": 3,
+ "processId": 7,
+ "processName": "娉ㄥ",
+ "itemId": 75,
+ "itemCode": "I-075",
+ "itemName": "鍗氫笘铻轰笣鍒�",
+ "itemSpecification": "涓�瀛楀瀷",
+ "unitMeasureName": "涓�",
+ "quantity": 5000.00,
+ "producedQuantity": 2000.00,
+ "qualifyQuantity": 1950.00,
+ "unqualifyQuantity": 50.00,
+ "pendingQuantity": 3000.00,
+ "inTransitQuantity": 500.00,
+ "reportableQuantity": 2500.00,
+ "feedbackRate": 40.00,
+ "checkFlag": true,
+ "status": 0,
+ "createTime": "2025-03-15 10:00:00"
+ }
+ ],
+ "total": 1
+ }
+}
+```
+
+---
+
+#### 1.2 鏌ヨ浠诲姟璇︽儏
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/pro/task/get | 鏍规嵁ID鑾峰彇浠诲姟璇︽儏 |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 浠诲姟缂栧彿 |
+
+**鍝嶅簲瀛楁锛�** 鍚� 1.1 鍝嶅簲瀛楁锛堝崟鏉″璞★紝闈炲垎椤碉級
+
+**鍝嶅簲绀轰緥锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "id": 1,
+ "code": "PT202503150001",
+ "reportableQuantity": 2500.00,
+ "checkFlag": true
+ }
+}
+```
+
+---
+
+### 浜屻�佺敓浜ф姤宸ユ帴鍙�
+
+#### 2.1 鍒涘缓鎶ュ伐
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /mes/pro-feedback/create | 鏂板缓鎶ュ伐鍗曪紙鐘舵��=鑽夌锛� |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| code | String | 鏄� | 鎶ュ伐鍗曠紪鍙� |
+| type | Integer | 鏄� | 鎶ュ伐绫诲瀷锛�1=鑷鎶ュ伐锛�2=缁熶竴鎶ュ伐 |
+| workstationId | Long | 鏄� | 宸ヤ綔绔欑紪鍙� |
+| routeId | Long | 鏄� | 宸ヨ壓璺嚎缂栧彿 |
+| processId | Long | 鏄� | 宸ュ簭缂栧彿 |
+| workOrderId | Long | 鏄� | 鐢熶骇宸ュ崟缂栧彿 |
+| taskId | Long | 鏄� | 鐢熶骇浠诲姟缂栧彿 |
+| itemId | Long | 鏄� | 浜у搧鐗╂枡缂栧彿 |
+| feedbackQuantity | BigDecimal | 鏄� | 鏈鎶ュ伐鏁伴噺锛堝繀椤� > 0锛� |
+| feedbackUserId | Long | 鏄� | 鎶ュ伐浜虹紪鍙� |
+| feedbackTime | LocalDateTime | 鏄� | 鎶ュ伐鏃堕棿 |
+| approveUserId | Long | 鏄� | 瀹℃牳浜虹紪鍙� |
+| qualifiedQuantity | BigDecimal | 鏉′欢蹇呭~ | 鍚堟牸鍝佹暟閲忥紙闈炶川妫�宸ュ簭蹇呭~锛� |
+| unqualifiedQuantity | BigDecimal | 鏉′欢蹇呭~ | 涓嶈壇鍝佹暟閲忥紙闈炶川妫�宸ュ簭蹇呭~锛� |
+| uncheckQuantity | BigDecimal | 鍚� | 寰呮娴嬫暟閲� |
+| laborScrapQuantity | BigDecimal | 鍚� | 宸ュ簾鏁伴噺 |
+| materialScrapQuantity | BigDecimal | 鍚� | 鏂欏簾鏁伴噺 |
+| otherScrapQuantity | BigDecimal | 鍚� | 鍏朵粬搴熷搧鏁伴噺 |
+| scheduledQuantity | BigDecimal | 鍚� | 鎺掍骇鏁伴噺 |
+| expireDate | LocalDateTime | 鍚� | 杩囨湡鏃ユ湡 |
+| lotNumber | String | 鍚� | 鐢熶骇鎵瑰彿 |
+| remark | String | 鍚� | 澶囨敞 |
+
+**鍝嶅簲锛�** `Long`锛堟姤宸ヨ褰旾D锛�
+
+```json
+{
+ "code": 0,
+ "data": 1024
+}
+```
+
+**鏁版嵁甯﹀叆璇存槑锛�**
+
+浠庡緟鎶ュ伐鍙拌处閫夋嫨浠诲姟鍚庯紝浠ヤ笅瀛楁鑷姩甯﹀叆鎶ュ伐琛ㄥ崟锛屾棤闇�鐢ㄦ埛鎵嬪姩濉啓锛�
+
+| 鎶ュ伐琛ㄥ崟瀛楁 | 鏁版嵁鏉ユ簮 | 鏉ユ簮瀛楁 |
+|-------------|---------|---------|
+| taskId | 浠诲姟 | id |
+| workOrderId | 浠诲姟 | workOrderId |
+| routeId | 浠诲姟 | routeId |
+| processId | 浠诲姟 | processId | 浠诲姟 | processId |
+| workstationId | 浠诲姟 | workstationId |
+| itemId | 浠诲姟 | itemId |
+| scheduledQuantity | 浠诲姟 | quantity锛堟帓浜ф暟閲忥級 |
+
+鐢ㄦ埛闇�鎵嬪姩濉啓锛氭姤宸ユ暟閲忋�佸悎鏍�/涓嶈壇鍝佹暟閲忋�佹姤宸ヤ汉銆佹姤宸ユ椂闂淬�佸鏍镐汉绛夈��
+
+---
+
+#### 2.2 鏇存柊鎶ュ伐
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| PUT | /mes/pro-feedback/update | 淇敼鎶ュ伐鍗曪紙浠呰崏绋跨姸鎬佸彲淇敼锛� |
+
+**璇锋眰鍙傛暟锛�** 鍚� 2.1锛堥渶棰濆浼� id锛�
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 鎶ュ伐缂栧彿 |
+
+**鍝嶅簲锛�** `{ "code": 0, "data": true }`
+
+---
+
+#### 2.3 鎻愪氦鎶ュ伐
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| PUT | /mes/pro-feedback/submit | 鑽夌 鈫� 瀹℃壒涓� |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 鎶ュ伐缂栧彿 |
+
+**鍝嶅簲锛�** `{ "code": 0, "data": true }`
+
+**鐘舵�佸彉鍖栵細** 鑽夌(0) 鈫� 瀹℃壒涓�(2)
+
+---
+
+#### 2.4 瀹℃壒鎶ュ伐
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| PUT | /mes/pro-feedback/approve | 瀹℃壒閫氳繃锛岃Е鍙戝叆搴�/鎵f枡/璐ㄦ |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 鎶ュ伐缂栧彿 |
+
+**鍝嶅簲锛�**
+
+```json
+{
+ "code": 0,
+ "data": true // true=瀹℃壒瀹屾垚(宸插叆搴�)锛宖alse=杩涘叆寰呮楠�(绛夎川妫�鍥炶皟)
+}
+```
+
+**鐘舵�佸彉鍖栵細**
+
+| 鍦烘櫙 | 鐘舵�佸彉鍖� | 杩斿洖鍊� |
+|------|---------|--------|
+| 闈炲叧閿伐搴� | 瀹℃壒涓�(2) 鈫� 宸插畬鎴�(4) | true |
+| 鍏抽敭+闈炶川妫�宸ュ簭 | 瀹℃壒涓�(2) 鈫� 宸插畬鎴�(4)锛屽悓鏃跺叆搴� | true |
+| 鍏抽敭+璐ㄦ宸ュ簭 | 瀹℃壒涓�(2) 鈫� 寰呮楠�(3)锛岀瓑IPQC鍥炶皟 | false |
+
+---
+
+#### 2.5 椹冲洖鎶ュ伐
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| PUT | /mes/pro-feedback/reject | 瀹℃壒涓� 鈫� 鑽夌 |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 鎶ュ伐缂栧彿 |
+
+**鍝嶅簲锛�** `{ "code": 0, "data": true }`
+
+**鐘舵�佸彉鍖栵細** 瀹℃壒涓�(2) 鈫� 鑽夌(0)
+
+---
+
+#### 2.6 鏌ヨ鎶ュ伐璇︽儏
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/pro-feedback/get | 鑾峰彇鍗曟潯鎶ュ伐璇︽儏 |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 鎶ュ伐缂栧彿 |
+
+**鍝嶅簲瀛楁锛�**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| id | Long | 缂栧彿 |
+| code | String | 鎶ュ伐鍗曠紪鍙� |
+| type | Integer | 鎶ュ伐绫诲瀷锛�1=鑷鎶ュ伐锛�2=缁熶竴鎶ュ伐 |
+| channel | String | 鎶ュ伐閫斿緞 |
+| feedbackTime | LocalDateTime | 鎶ュ伐鏃堕棿 |
+| workstationId | Long | 宸ヤ綔绔欑紪鍙� |
+| workstationCode | String | 宸ヤ綔绔欑紪鐮� |
+| workstationName | String | 宸ヤ綔绔欏悕绉� |
+| routeId | Long | 宸ヨ壓璺嚎缂栧彿 |
+| routeCode | String | 宸ヨ壓璺嚎缂栫爜 |
+| processId | Long | 宸ュ簭缂栧彿 |
+| processCode | String | 宸ュ簭缂栫爜 |
+| processName | String | 宸ュ簭鍚嶇О |
+| checkFlag | Boolean | 鏄惁闇�瑕佹楠� |
+| workOrderId | Long | 宸ュ崟缂栧彿 |
+| workOrderCode | String | 宸ュ崟缂栫爜 |
+| workOrderName | String | 宸ュ崟鍚嶇О |
+| taskId | Long | 浠诲姟缂栧彿 |
+| taskCode | String | 浠诲姟缂栫爜 |
+| itemId | Long | 鐗╂枡缂栧彿 |
+| itemCode | String | 鐗╂枡缂栫爜 |
+| itemName | String | 鐗╂枡鍚嶇О |
+| itemSpecification | String | 瑙勬牸鍨嬪彿 |
+| unitMeasureId | Long | 鍗曚綅缂栧彿 |
+| unitMeasureName | String | 鍗曚綅鍚嶇О |
+| scheduledQuantity | BigDecimal | 鎺掍骇鏁伴噺 |
+| feedbackQuantity | BigDecimal | 鎶ュ伐鏁伴噺 |
+| qualifiedQuantity | BigDecimal | 鍚堟牸鍝佹暟閲� |
+| unqualifiedQuantity | BigDecimal | 涓嶈壇鍝佹暟閲� |
+| uncheckQuantity | BigDecimal | 寰呮娴嬫暟閲� |
+| laborScrapQuantity | BigDecimal | 宸ュ簾鏁伴噺 |
+| materialScrapQuantity | BigDecimal | 鏂欏簾鏁伴噺 |
+| otherScrapQuantity | BigDecimal | 鍏朵粬搴熷搧鏁伴噺 |
+| feedbackUserId | Long | 鎶ュ伐浜虹紪鍙� |
+| feedbackUserNickname | String | 鎶ュ伐浜烘樀绉� |
+| approveUserId | Long | 瀹℃牳浜虹紪鍙� |
+| approveUserNickname | String | 瀹℃牳浜烘樀绉� |
+| status | Integer | 鐘舵�� |
+| remark | String | 澶囨敞 |
+| createTime | LocalDateTime | 鍒涘缓鏃堕棿 |
+
+---
+
+#### 2.7 鎶ュ伐鍒嗛〉鏌ヨ
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/pro-feedback/page | 鍒嗛〉鏌ヨ鎶ュ伐鍒楄〃 |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| code | String | 鍚� | 鎶ュ伐鍗曠紪鍙凤紙妯$硦鍖归厤锛� |
+| type | Integer | 鍚� | 鎶ュ伐绫诲瀷 |
+| workOrderId | Long | 鍚� | 鐢熶骇宸ュ崟缂栧彿 |
+| taskId | Long | 鍚� | 鐢熶骇浠诲姟缂栧彿锛堢簿纭尮閰嶏級 |
+| taskCode | String | 鍚� | 鐢熶骇浠诲姟缂栫爜锛堟ā绯婂尮閰嶏紝濡� "PT202503"锛� |
+| status | Integer | 鍚� | 鐘舵�� |
+| itemId | Long | 鍚� | 浜у搧鐗╂枡缂栧彿 |
+| feedbackUserId | Long | 鍚� | 鎶ュ伐浜虹紪鍙� |
+| creator | String | 鍚� | 璁板綍浜虹紪鍙� |
+| feedbackTime | String[] | 鍚� | 鎶ュ伐鏃堕棿鑼冨洿 |
+| pageNo | Integer | 鏄� | 椤电爜 |
+| pageSize | Integer | 鏄� | 姣忛〉鏉℃暟 |
+
+**鍝嶅簲瀛楁锛�** 鍚� 2.6锛堝垎椤靛垪琛級
+
+**鏌ヨ璇存槑锛�**
+
+| 鍦烘櫙 | 鐢ㄦ硶 | 绀轰緥 |
+|------|------|------|
+| 鎸変换鍔$紪鐮佹ā绯婃煡璇� | 浼� taskCode | `taskCode=PT202503` 鍖归厤 PT202503150001銆丳T202503150002 绛� |
+| 鎸変换鍔D绮剧‘鏌ヨ | 浼� taskId | `taskId=1024` |
+| 鍚屾椂浼� taskId 鍜� taskCode | taskId 浼樺厛绮剧‘鍖归厤锛宼askCode 棰濆妯$硦杩囨护 | 涓�鑸笉鍚屾椂浼� |
+| 涓嶄紶浠诲姟鐩稿叧鍙傛暟 | 鏌ヨ鎵�鏈夋姤宸� | 鈥� |
+
+---
+
+#### 2.8 鎸変换鍔℃煡璇㈡姤宸ュ巻鍙�
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/pro-feedback/list-by-task | 鏌ヨ鏌愪换鍔′笅鎵�鏈夋姤宸ヨ褰� |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| taskId | Long | 鏄� | 浠诲姟缂栧彿 |
+
+**鍝嶅簲瀛楁锛�** `List<MesProFeedbackRespVO>`锛堝悓 2.6 瀛楁锛屾暟缁勫舰寮忥級
+
+**璇存槑锛�** 杩斿洖璇ヤ换鍔′笅鎵�鏈夌姸鎬佺殑鎶ュ伐璁板綍锛堣崏绋�/瀹℃壒涓�/寰呮楠�/宸插畬鎴愶級锛岀敤浜庡湪浠诲姟璇︽儏涓睍绀烘姤宸ュ巻鍙层��
+
+---
+
+#### 2.9 鎶ュ伐杩芥函淇℃伅
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/pro-feedback/trace/{id} | 鎶ュ伐 + 浜у嚭 + 娑堣�� + IPQC妫�楠� |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 鎶ュ伐缂栧彿锛堣矾寰勫弬鏁帮級 |
+
+**鍝嶅簲瀛楁锛�**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| feedback | MesProFeedbackRespVO | 鎶ュ伐淇℃伅锛堝悓 2.6 瀛楁锛� |
+| productProduce | Object | 鐢熶骇浜у嚭鍗曪紙鍏抽敭宸ュ簭鎵嶆湁锛屽惁鍒� null锛� |
+| productProduceLines | Array | 浜у嚭鏄庣粏琛岋紙鎸夊悎鏍�/涓嶅悎鏍�/寰呮楠屾媶琛岋級 |
+| itemConsume | Object | 鐗╂枡娑堣�楀崟锛堝�掑啿宸ュ簭鎵嶆湁锛屽惁鍒� null锛� |
+| itemConsumeLines | Array | 娑堣�楁槑缁嗚锛堟寜 BOM 鐗╂枡鎷嗚锛� |
+| ipqcList | Array | IPQC 杩囩▼妫�楠屽崟鍒楄〃锛堝叧閿�+闇�妫�楠屽伐搴忔墠鏈夛級 |
+
+**鍝嶅簲绀轰緥锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "feedback": {
+ "id": 1024,
+ "code": "FB202503160001",
+ "status": 4,
+ "feedbackQuantity": 500.00,
+ "qualifiedQuantity": 490.00,
+ "unqualifiedQuantity": 10.00
+ },
+ "productProduce": {
+ "id": 50,
+ "code": "PP202503160001"
+ },
+ "productProduceLines": [
+ { "id": 101, "qualityStatus": 1, "quantity": 490.00 },
+ { "id": 102, "qualityStatus": 2, "quantity": 10.00 }
+ ],
+ "itemConsume": null,
+ "itemConsumeLines": [],
+ "ipqcList": []
+ }
+}
+```
+
+---
+
+#### 2.10 鍒犻櫎鎶ュ伐
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| DELETE | /mes/pro-feedback/delete | 鍒犻櫎鎶ュ伐锛堜粎鑽夌鐘舵�佸彲鍒犻櫎锛� |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 鎶ュ伐缂栧彿 |
+
+**鍝嶅簲锛�** `{ "code": 0, "data": true }`
+
+---
+
+## 瀛楁灞曠ず瑙勫垯
+
+### 寰呮姤宸ュ彴璐﹀垪琛�
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| code | 鍒楄〃 | 浠诲姟缂栫爜 |
+| workOrderCode + workOrderName | 鍒楄〃 | 宸ュ崟缂栫爜+鍚嶇О |
+| workstationName | 鍒楄〃 | 宸ヤ綔绔� |
+| processName | 鍒楄〃 | 宸ュ簭鍚嶇О |
+| itemCode + itemName | 鍒楄〃 | 鐗╂枡缂栫爜+鍚嶇О |
+| quantity | 鍒楄〃 | 鎺掍骇鏁伴噺 |
+| producedQuantity | 鍒楄〃 | 宸茬敓浜ф暟閲� |
+| reportableQuantity | 鍒楄〃 | 鍙姤宸ユ暟閲忥紙楂樹寒鏄剧ず锛� |
+| feedbackRate | 鍒楄〃 | 鎶ュ伐瀹屾垚鐜�(%) |
+| checkFlag | 鍒楄〃 | 鏄惁璐ㄦ锛堟爣绛惧睍绀猴級 |
+
+### 鎶ュ伐琛ㄥ崟
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| taskId 鈫� taskCode | 琛ㄥ崟锛堝彧璇伙級 | 浠庝换鍔¤嚜鍔ㄥ甫鍏� |
+| workOrderId 鈫� workOrderCode + workOrderName | 琛ㄥ崟锛堝彧璇伙級 | 浠庝换鍔¤嚜鍔ㄥ甫鍏� |
+| processId 鈫� processName | 琛ㄥ崟锛堝彧璇伙級 | 浠庝换鍔¤嚜鍔ㄥ甫鍏� |
+| workstationId 鈫� workstationName | 琛ㄥ崟锛堝彧璇伙級 | 浠庝换鍔¤嚜鍔ㄥ甫鍏� |
+| itemId 鈫� itemCode + itemName | 琛ㄥ崟锛堝彧璇伙級 | 浠庝换鍔¤嚜鍔ㄥ甫鍏� |
+| scheduledQuantity | 琛ㄥ崟锛堝彧璇伙級 | 鎺掍骇鏁伴噺锛屼粠浠诲姟甯﹀叆 |
+| feedbackQuantity | 琛ㄥ崟锛堝彲缂栬緫锛� | 鏈鎶ュ伐鏁伴噺锛屽繀濉� |
+| qualifiedQuantity | 琛ㄥ崟锛堟潯浠跺彲缂栬緫锛� | 闈炶川妫�宸ュ簭蹇呭~锛涜川妫�宸ュ簭闅愯棌鎴栫鐢� |
+| unqualifiedQuantity | 琛ㄥ崟锛堟潯浠跺彲缂栬緫锛� | 闈炶川妫�宸ュ簭蹇呭~锛涜川妫�宸ュ簭闅愯棌鎴栫鐢� |
+| feedbackUserId 鈫� feedbackUserNickname | 琛ㄥ崟锛堝彲缂栬緫锛� | 鎶ュ伐浜猴紝閫夋嫨鐢ㄦ埛 |
+| feedbackTime | 琛ㄥ崟锛堝彲缂栬緫锛� | 鎶ュ伐鏃堕棿锛岄粯璁ゅ綋鍓嶆椂闂� |
+| approveUserId 鈫� approveUserNickname | 琛ㄥ崟锛堝彲缂栬緫锛� | 瀹℃牳浜猴紝閫夋嫨鐢ㄦ埛 |
+| remark | 琛ㄥ崟锛堝彲缂栬緫锛� | 澶囨敞 |
+
+### 鎶ュ伐鍒楄〃
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| code | 鍒楄〃 | 鎶ュ伐鍗曠紪鍙� |
+| workOrderCode | 鍒楄〃 | 宸ュ崟缂栫爜 |
+| taskCode | 鍒楄〃 | 浠诲姟缂栫爜 |
+| processName | 鍒楄〃 | 宸ュ簭 |
+| itemName | 鍒楄〃 | 鐗╂枡 |
+| feedbackQuantity | 鍒楄〃 | 鎶ュ伐鏁伴噺 |
+| qualifiedQuantity | 鍒楄〃 | 鍚堟牸鍝� |
+| unqualifiedQuantity | 鍒楄〃 | 涓嶈壇鍝� |
+| feedbackUserNickname | 鍒楄〃 | 鎶ュ伐浜� |
+| approveUserNickname | 鍒楄〃 | 瀹℃牳浜� |
+| status | 鍒楄〃 | 鐘舵�侊紙瀛楀吀鏍囩锛屼笉鍚岀姸鎬佷笉鍚岄鑹诧級 |
+| feedbackTime | 鍒楄〃 | 鎶ュ伐鏃堕棿 |
+
+**鎼滅储鏉′欢锛�**
+
+| 瀛楁 | 鎺т欢绫诲瀷 | 璇存槑 |
+|------|---------|------|
+| taskCode | 杈撳叆妗� | 鐢熶骇浠诲姟缂栫爜锛堟ā绯婂尮閰嶏紝涓昏鎼滅储鏉′欢锛� |
+| code | 杈撳叆妗� | 鎶ュ伐鍗曠紪鍙凤紙妯$硦鍖归厤锛� |
+| status | 涓嬫媺閫夋嫨 | 鐘舵�佺瓫閫� |
+| feedbackTime | 鏃ユ湡鑼冨洿 | 鎶ュ伐鏃堕棿鑼冨洿 |
+
+---
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 鎶ュ伐鏁伴噺涓婇檺 | 鎶ュ伐鏁伴噺涓嶅簲瓒呰繃浠诲姟鐨� `reportableQuantity`锛堝彲鎶ュ伐鏁伴噺锛夛紝鍓嶇搴斿仛鏍¢獙鎻愮ず |
+| 璐ㄦ宸ュ簭鎶ュ伐 | checkFlag=true 鏃讹紝鍙渶濉姤宸ユ暟閲忥紝鍚堟牸/涓嶅悎鏍兼暟閲忕敱璐ㄦ缁撴灉鍥炲~锛屽墠绔簲闅愯棌鎴栫鐢ㄥ悎鏍�/涓嶈壇鍝佽緭鍏� |
+| 闈炶川妫�宸ュ簭鎶ュ伐 | checkFlag=false 鏃讹紝鍚堟牸鍝� + 涓嶈壇鍝佹暟閲忓繀椤� > 0锛屽墠绔簲鏍¢獙 |
+| 鑽夌鐘舵�佹搷浣� | 浠呰崏绋�(0)鐘舵�佸彲缂栬緫銆佸垹闄� |
+| 瀹℃壒涓姸鎬佹搷浣� | 浠呭鎵逛腑(2)鐘舵�佸彲瀹℃壒銆侀┏鍥� |
+| 寰呮楠岀姸鎬� | 寰呮楠�(3)鐘舵�佷笉鍙搷浣滐紝绛塈PQC璐ㄦ瀹屾垚鍚庣郴缁熻嚜鍔ㄥ洖璋冩洿鏂颁负宸插畬鎴�(4) |
+| 瀹℃壒杩斿洖鍊� | approve 鎺ュ彛杩斿洖 true=宸插畬鎴愶紝false=寰呮楠岋紝鍓嶇搴旀牴鎹繑鍥炲�煎睍绀轰笉鍚屾彁绀� |
+| 浠诲姟鏁版嵁甯﹀叆 | 浠庡緟鎶ュ伐鍙拌处閫夋嫨浠诲姟鍚庯紝7涓瓧娈佃嚜鍔ㄥ甫鍏ユ姤宸ヨ〃鍗曪紙瑙佹暟鎹甫鍏ヨ鏄庯級锛岀敤鎴蜂笉鍙慨鏀� |
+
+## 娉ㄦ剰浜嬮」
+
+- 鎶ュ伐鍗曠紪鍙�(code)鐢卞墠绔敓鎴愭垨璋冪敤鑷姩缂栫爜鎺ュ彛鑾峰彇锛屽垱寤烘椂蹇呬紶
+- 鎶ュ伐绫诲瀷(type)瀛楁锛�1=鑷鎶ュ伐锛�2=缁熶竴鎶ュ伐锛屽墠绔牴鎹笟鍔″満鏅�夋嫨
+- 瀹℃壒鏄畝鍗曟潈闄愭帶鍒讹紙`mes:pro-feedback:approve`锛夛紝闈濨PM宸ヤ綔娴侊紝鏈夋潈闄愮殑鐢ㄦ埛鐩存帴鐐瑰嚮瀹℃壒鍗冲彲
+- 瀹℃壒閫氳繃鍚庝細鑷姩瑙﹀彂锛氬�掑啿鎵f枡锛堝�掑啿宸ュ簭锛夈�佷骇鍑哄叆搴擄紙鍏抽敭宸ュ簭锛夛紝杩欎簺鏄悗绔嚜鍔ㄥ鐞嗙殑锛屽墠绔棤闇�棰濆鎿嶄綔
+- 寰呮楠岀姸鎬佺殑鎶ュ伐鍗曪紝鍏跺悎鏍�/涓嶅悎鏍兼暟閲忎細鍦↖PQC璐ㄦ瀹屾垚鍚庣敱鍚庣鑷姩鍥炲~锛屽墠绔棤闇�鎵嬪姩鏇存柊
+- 寰呮姤宸ュ彴璐︾殑 `reportableQuantity` 宸叉墸闄ゅ湪閫旀姤宸ラ噺锛屽墠绔彲鐩存帴鐢ㄦ鍊煎仛鎶ュ伐鏁伴噺涓婇檺鏍¢獙
+- 鍒犻櫎鎿嶄綔浠呰崏绋跨姸鎬佸彲鐢紝瀹℃壒涓�/寰呮楠�/宸插畬鎴愮姸鎬佷笉鍙垹闄�
diff --git a/docs/work_order_param_record_integration.md b/docs/work_order_param_record_integration.md
new file mode 100644
index 0000000..548379b
--- /dev/null
+++ b/docs/work_order_param_record_integration.md
@@ -0,0 +1,413 @@
+# 宸ュ崟鐢熶骇鍙傛暟璁板綍 - 鍓嶇鑱旇皟鏂规
+
+## 娑夊強椤甸潰
+
+- 宸ュ崟璇︽儏锛堟柊澧�"鍙傛暟璁板綍"Tab锛屾煡鐪�/绠$悊宸ュ崟鐨勫弬鏁拌褰曪級
+- 鍙傛暟璁板綍鏂板/缂栬緫寮圭獥锛堥�夋嫨鍙傛暟妯℃澘锛屽~鍐欏弬鏁板�硷級
+
+## 涓氬姟娴佺▼涓庢暟鎹甫鍏�
+
+```
+1. 杩涘叆宸ュ崟璇︽儏 鈫� 鍒囨崲鍒�"鍙傛暟璁板綍"Tab 鈫� 鏌ョ湅璇ュ伐鍗曟墍鏈夊弬鏁拌褰�
+2. 鐐瑰嚮"鏂板鍙傛暟璁板綍" 鈫� 寮圭獥閫夋嫨鍙傛暟妯℃澘 鈫� 鑷姩鍔犺浇妯℃澘涓嬬殑鍙傛暟鍒楄〃锛堝弬鏁板悕銆佸崟浣嶃�佹槸鍚﹀繀濉級
+3. 濉啓鍚勫弬鏁板�� 鈫� 淇濆瓨锛堜竴鏉¤褰� = 妯℃澘 + 鎵�鏈夊弬鏁扮殑濉啓鍊硷級
+4. 鍚屼竴宸ュ崟鍙娆℃柊澧炲弬鏁拌褰曪紙姣忕彮娆�/姣忔壒娆¤褰曚竴娆★級
+5. 缂栬緫鏃跺彧鑳戒慨鏀瑰~鍐欏�煎拰澶囨敞锛屼笉鑳芥洿鎹㈡ā鏉�
+6. 鍒犻櫎璁板綍鏃舵暣鏉¤褰曪紙鍚墍鏈夊弬鏁版槑缁嗭級涓�璧峰垹闄�
+```
+
+## 鏁版嵁妯″瀷璇存槑
+
+```
+鍙傛暟璁板綍锛堜富琛級 鍙傛暟璁板綍鏄庣粏
+鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹� 鈹屸攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+鈹� id: 1 鈹� 鈹� id: 101 鈹�
+鈹� workOrderId: 10 鈹傗攢鈹�1:N鈹�鈹�鈫掆攤 recordId: 1 鈹�
+鈹� templateId: 2 鈹� 鈹� paramName: 娓╁害 鈹�
+鈹� templateCode: CSMB002鈹� 鈹� paramType: 2 (鏁板��) 鈹�
+鈹� templateName: 娉ㄥ妯℃澘鈹� 鈹� unitMeasureName: 鈩� 鈹�
+鈹� recordNo: BATCH-001 鈹� 鈹� paramValue: 200 鈹�
+鈹� remark: 棣栦欢璁板綍 鈹� 鈹溾攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹� 鈹� id: 102 鈹�
+ 鈹� recordId: 1 鈹�
+ 鈹� paramName: 鍘嬪姏 鈹�
+ 鈹� paramType: 2 (鏁板��) 鈹�
+ 鈹� unitMeasureName: MPa 鈹�
+ 鈹� paramValue: 50 鈹�
+ 鈹斺攢鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�鈹�
+```
+
+---
+
+## API
+
+### 涓�銆佸弬鏁版ā鏉挎帴鍙o紙宸叉湁锛岀敤浜庝笅鎷夐�夋嫨锛�
+
+#### 1.1 鑾峰彇鍙傛暟妯℃澘绮剧畝鍒楄〃
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/pd/process-param-template/page | 鑾峰彇鍙傛暟妯℃澘鍒嗛〉鍒楄〃 |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| pageNo | Integer | 鏄� | 椤电爜 |
+| pageSize | Integer | 鏄� | 姣忛〉鏉℃暟锛堝缓璁� 100锛岀敤浜庝笅鎷夛級 |
+
+**鍝嶅簲瀛楁锛堝叧閿瓧娈碉級锛�**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| id | Long | 妯℃澘缂栧彿 |
+| templateCode | String | 妯℃澘缂栫爜 |
+| templateName | String | 妯℃澘鍚嶇О |
+| templateType | Integer | 妯℃澘绫诲瀷 |
+
+---
+
+#### 1.2 鑾峰彇鍙傛暟妯℃澘璇︽儏锛堝惈鏄庣粏锛岀敤浜庡姞杞藉弬鏁板垪琛級
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/pd/process-param-template/get | 鑾峰彇妯℃澘 + 鍙傛暟鏄庣粏 |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 妯℃澘缂栧彿 |
+
+**鍝嶅簲绀轰緥锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "id": 2,
+ "templateCode": "CSMB202607100002",
+ "templateName": "娉ㄥ鍙傛暟妯℃澘",
+ "templateType": 1,
+ "details": [
+ {
+ "id": 3,
+ "paramCode": "TEMP",
+ "paramName": "娓╁害",
+ "paramType": 2,
+ "unitMeasureId": 5,
+ "unitMeasureName": "鈩�",
+ "required": true
+ },
+ {
+ "id": 4,
+ "paramCode": "PRESS",
+ "paramName": "鍘嬪姏",
+ "paramType": 2,
+ "unitMeasureId": 8,
+ "unitMeasureName": "MPa",
+ "required": true
+ },
+ {
+ "id": 5,
+ "paramCode": "TIME",
+ "paramName": "淇濆帇鏃堕棿",
+ "paramType": 2,
+ "unitMeasureId": 12,
+ "unitMeasureName": "s",
+ "required": false
+ }
+ ]
+ }
+}
+```
+
+**鏁版嵁甯﹀叆璇存槑锛�** 閫夋嫨妯℃澘鍚庯紝灏� `details` 鍒楄〃娓叉煋涓鸿〃鍗曡锛屾瘡琛屽睍绀哄弬鏁板悕 + 鍗曚綅 + 杈撳叆妗嗭紝`required=true` 鐨勫弬鏁版爣璁板繀濉��
+
+---
+
+### 浜屻�佸伐鍗曞弬鏁拌褰曟帴鍙�
+
+#### 2.1 鍒涘缓鍙傛暟璁板綍
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| POST | /mes/pro/work-order-param-record/create | 涓哄伐鍗曞垱寤轰竴鏉″弬鏁拌褰� |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| workOrderId | Long | 鏄� | 宸ュ崟缂栧彿锛圲RL 鍙傛暟锛� |
+| templateId | Long | 鏄� | 鍙傛暟妯℃澘缂栧彿 |
+| recordNo | String | 鍚� | 璁板綍搴忓彿/鎵规鍙� |
+| remark | String | 鍚� | 澶囨敞 |
+| details | Array | 鏄� | 鍙傛暟鏄庣粏鍒楄〃 |
+| details[].templateDetailId | Long | 鏄� | 妯℃澘鏄庣粏缂栧彿锛堟潵鑷ā鏉胯鎯呯殑 details[].id锛� |
+| details[].paramValue | String | 鏉′欢蹇呭~ | 鍙傛暟鍊硷紙蹇呭~鍙傛暟涓嶈兘涓虹┖锛� |
+
+**璇锋眰绀轰緥锛�**
+
+```
+POST /mes/pro/work-order-param-record/create?workOrderId=10
+
+{
+ "templateId": 2,
+ "recordNo": "BATCH-001",
+ "remark": "棣栦欢璁板綍",
+ "details": [
+ { "templateDetailId": 3, "paramValue": "200" },
+ { "templateDetailId": 4, "paramValue": "50" },
+ { "templateDetailId": 5, "paramValue": "30" }
+ ]
+}
+```
+
+**鍝嶅簲锛�**
+
+```json
+{
+ "code": 0,
+ "data": 1024
+}
+```
+
+**鎺ュ彛璋冪敤鏃跺簭锛�**
+
+```
+1. 鐢ㄦ埛鐐瑰嚮"鏂板鍙傛暟璁板綍"
+2. 璋冪敤 GET /mes/pd/process-param-template/page 鑾峰彇妯℃澘涓嬫媺鍒楄〃
+3. 鐢ㄦ埛閫夋嫨妯℃澘
+4. 璋冪敤 GET /mes/pd/process-param-template/get?id=xxx 鑾峰彇妯℃澘鍙傛暟鏄庣粏
+5. 鍓嶇灏� details 娓叉煋涓鸿〃鍗曪紙鍙傛暟鍚� + 鍗曚綅 + 杈撳叆妗嗭級
+6. 鐢ㄦ埛濉啓鍙傛暟鍊�
+7. 璋冪敤 POST /mes/pro/work-order-param-record/create 鎻愪氦
+```
+
+---
+
+#### 2.2 鏇存柊鍙傛暟璁板綍
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| PUT | /mes/pro/work-order-param-record/update | 鏇存柊鍙傛暟璁板綍锛堜粎淇敼濉啓鍊硷紝涓嶈兘鎹㈡ā鏉匡級 |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 璁板綍缂栧彿 |
+| templateId | Long | 鏄� | 鍙傛暟妯℃澘缂栧彿锛堝繀椤讳笌鍒涘缓鏃朵竴鑷达紝鍚﹀垯鎶ラ敊锛� |
+| recordNo | String | 鍚� | 璁板綍搴忓彿/鎵规鍙� |
+| remark | String | 鍚� | 澶囨敞 |
+| details | Array | 鏄� | 鍙傛暟鏄庣粏鍒楄〃 |
+| details[].templateDetailId | Long | 鏄� | 妯℃澘鏄庣粏缂栧彿 |
+| details[].paramValue | String | 鏉′欢蹇呭~ | 鍙傛暟鍊� |
+
+**璇锋眰绀轰緥锛�**
+
+```json
+{
+ "id": 1024,
+ "templateId": 2,
+ "recordNo": "BATCH-001",
+ "remark": "棣栦欢璁板綍锛堝凡淇锛�",
+ "details": [
+ { "templateDetailId": 3, "paramValue": "210" },
+ { "templateDetailId": 4, "paramValue": "52" },
+ { "templateDetailId": 5, "paramValue": "28" }
+ ]
+}
+```
+
+**鍝嶅簲锛�** `{ "code": 0, "data": true }`
+
+**涓氬姟瑙勫垯锛�** 涓嶅厑璁告洿鎹㈡ā鏉匡紙templateId 蹇呴』涓庡師璁板綍涓�鑷达級锛屽闇�鎹㈡ā鏉胯鍒犻櫎鍚庨噸鏂板垱寤恒��
+
+---
+
+#### 2.3 鍒犻櫎鍙傛暟璁板綍
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| DELETE | /mes/pro/work-order-param-record/delete | 鍒犻櫎鍙傛暟璁板綍锛堢骇鑱斿垹闄ゆ槑缁嗭級 |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 璁板綍缂栧彿 |
+
+**鍝嶅簲锛�** `{ "code": 0, "data": true }`
+
+---
+
+#### 2.4 鑾峰彇鍙傛暟璁板綍璇︽儏
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/pro/work-order-param-record/get | 鑾峰彇鍗曟潯璁板綍锛堝惈鏄庣粏锛� |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| id | Long | 鏄� | 璁板綍缂栧彿 |
+
+**鍝嶅簲瀛楁锛�**
+
+| 瀛楁 | 绫诲瀷 | 璇存槑 |
+|------|------|------|
+| id | Long | 璁板綍缂栧彿 |
+| workOrderId | Long | 宸ュ崟缂栧彿 |
+| templateId | Long | 妯℃澘缂栧彿 |
+| templateCode | String | 妯℃澘缂栫爜锛堝揩鐓э級 |
+| templateName | String | 妯℃澘鍚嶇О锛堝揩鐓э級 |
+| recordNo | String | 璁板綍搴忓彿 |
+| remark | String | 澶囨敞 |
+| createTime | LocalDateTime | 鍒涘缓鏃堕棿 |
+| details | Array | 鍙傛暟鏄庣粏鍒楄〃 |
+| details[].id | Long | 鏄庣粏缂栧彿 |
+| details[].templateDetailId | Long | 妯℃澘鏄庣粏缂栧彿 |
+| details[].paramCode | String | 鍙傛暟缂栫爜 |
+| details[].paramName | String | 鍙傛暟鍚嶇О |
+| details[].paramType | Integer | 鍙傛暟绫诲瀷 |
+| details[].unitMeasureId | Long | 璁¢噺鍗曚綅缂栧彿 |
+| details[].unitMeasureName | String | 璁¢噺鍗曚綅鍚嶇О |
+| details[].paramValue | String | 鍙傛暟鍊� |
+| details[].remark | String | 澶囨敞 |
+
+**鍝嶅簲绀轰緥锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "id": 1024,
+ "workOrderId": 10,
+ "templateId": 2,
+ "templateCode": "CSMB202607100002",
+ "templateName": "娉ㄥ鍙傛暟妯℃澘",
+ "recordNo": "BATCH-001",
+ "remark": "棣栦欢璁板綍",
+ "createTime": "2026-07-15 14:30:00",
+ "details": [
+ { "id": 101, "templateDetailId": 3, "paramCode": "TEMP", "paramName": "娓╁害", "paramType": 2, "unitMeasureName": "鈩�", "paramValue": "200" },
+ { "id": 102, "templateDetailId": 4, "paramCode": "PRESS", "paramName": "鍘嬪姏", "paramType": 2, "unitMeasureName": "MPa", "paramValue": "50" },
+ { "id": 103, "templateDetailId": 5, "paramCode": "TIME", "paramName": "淇濆帇鏃堕棿", "paramType": 2, "unitMeasureName": "s", "paramValue": "30" }
+ ]
+ }
+}
+```
+
+---
+
+#### 2.5 鎸夊伐鍗曞垎椤垫煡璇㈠弬鏁拌褰�
+
+| 鏂规硶 | 璺緞 | 璇存槑 |
+|------|------|------|
+| GET | /mes/pro/work-order-param-record/page-by-work-order | 鎸夊伐鍗曟煡璇㈠弬鏁拌褰曞垎椤� |
+
+**璇锋眰鍙傛暟锛�**
+
+| 鍙傛暟 | 绫诲瀷 | 蹇呭~ | 璇存槑 |
+|------|------|------|------|
+| workOrderId | Long | 鏄� | 宸ュ崟缂栧彿锛圲RL 鍙傛暟锛� |
+| recordNo | String | 鍚� | 璁板綍搴忓彿锛堟ā绯婂尮閰嶏級 |
+| templateName | String | 鍚� | 妯℃澘鍚嶇О锛堟ā绯婂尮閰嶏級 |
+| createTime | String[] | 鍚� | 鍒涘缓鏃堕棿鑼冨洿 |
+| pageNo | Integer | 鏄� | 椤电爜 |
+| pageSize | Integer | 鏄� | 姣忛〉鏉℃暟 |
+
+**鍝嶅簲瀛楁锛�** 鍚� 2.4锛堝垎椤靛垪琛紝姣忔潯璁板綍鍚� details 鏄庣粏锛�
+
+**鍝嶅簲绀轰緥锛�**
+
+```json
+{
+ "code": 0,
+ "data": {
+ "list": [
+ {
+ "id": 1024,
+ "templateName": "娉ㄥ鍙傛暟妯℃澘",
+ "recordNo": "BATCH-001",
+ "createTime": "2026-07-15 14:30:00",
+ "details": [
+ { "paramName": "娓╁害", "unitMeasureName": "鈩�", "paramValue": "200" },
+ { "paramName": "鍘嬪姏", "unitMeasureName": "MPa", "paramValue": "50" },
+ { "paramName": "淇濆帇鏃堕棿", "unitMeasureName": "s", "paramValue": "30" }
+ ]
+ },
+ {
+ "id": 1025,
+ "templateName": "娉ㄥ鍙傛暟妯℃澘",
+ "recordNo": "BATCH-002",
+ "createTime": "2026-07-15 22:15:00",
+ "details": [
+ { "paramName": "娓╁害", "unitMeasureName": "鈩�", "paramValue": "210" },
+ { "paramName": "鍘嬪姏", "unitMeasureName": "MPa", "paramValue": "52" },
+ { "paramName": "淇濆帇鏃堕棿", "unitMeasureName": "s", "paramValue": "28" }
+ ]
+ }
+ ],
+ "total": 2
+ }
+}
+```
+
+---
+
+## 瀛楁灞曠ず瑙勫垯
+
+### 鍙傛暟璁板綍鍒楄〃锛堝伐鍗曡鎯� Tab锛�
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| recordNo | 鍒楄〃 | 璁板綍搴忓彿/鎵规鍙� |
+| templateName | 鍒楄〃 | 鍙傛暟妯℃澘鍚嶇О |
+| 鍚勫弬鏁板�� | 鍒楄〃锛堝睍寮�琛屾垨鏍囩寮忥級 | 鏄剧ず"鍙傛暟鍚�: 鍊� 鍗曚綅"锛屽"娓╁害: 200 鈩�" |
+| createTime | 鍒楄〃 | 璁板綍鏃堕棿 |
+| 鎿嶄綔鍒� | 鍒楄〃 | 缂栬緫銆佸垹闄ゆ寜閽� |
+
+**鍒楄〃灞曠ず寤鸿锛�** 姣忔潯璁板綍鍙睍寮�鏌ョ湅鎵�鏈夊弬鏁版槑缁嗭紝鎴栧湪鍒楄〃涓敤鏍囩寮忓睍绀哄叧閿弬鏁板�笺��
+
+### 鍙傛暟璁板綍鏂板/缂栬緫寮圭獥
+
+| 瀛楁 | 灞曠ず浣嶇疆 | 璇存槑 |
+|------|----------|------|
+| templateId | 寮圭獥椤堕儴锛堜笅鎷夐�夋嫨锛� | 鏂板鏃跺彲閫夛紝缂栬緫鏃跺彧璇� |
+| recordNo | 寮圭獥锛堣緭鍏ユ锛� | 璁板綍搴忓彿/鎵规鍙� |
+| 鍙傛暟鏄庣粏鍒楄〃 | 寮圭獥涓讳綋锛堝姩鎬佽〃鍗曪級 | 鏍规嵁妯℃澘鍔犺浇锛岃涓嬫柟 |
+| remark | 寮圭獥搴曢儴锛堟枃鏈煙锛� | 澶囨敞 |
+
+**鍙傛暟鏄庣粏鍔ㄦ�佽〃鍗曪細** 閫夋嫨妯℃澘鍚庯紝鑷姩鍔犺浇鍙傛暟鍒楄〃娓叉煋涓鸿〃鍗曡锛�
+
+| 妯℃澘瀛楁 | 琛ㄥ崟灞曠ず | 璇存槑 |
+|---------|---------|------|
+| paramName | 鏍囩鏂囨湰 | 濡�"娓╁害" |
+| unitMeasureName | 鏍囩鍚庣紑 | 濡�"鈩�"锛屾樉绀哄湪杈撳叆妗嗗彸渚� |
+| required | 蹇呭~鏍囪 | required=true 鏃跺姞绾㈣壊鏄熷彿 |
+| paramType | 杈撳叆鎺т欢绫诲瀷 | 1=鏂囨湰妗嗭紝2=鏁板瓧妗嗭紝3=寮�鍏筹紝4=鏃ユ湡閫夋嫨鍣� |
+| paramValue | 杈撳叆妗� | 鐢ㄦ埛濉啓鐨勫弬鏁板�� |
+
+---
+
+## 涓氬姟瑙勫垯璇存槑
+
+| 鍦烘櫙 | 瑙勫垯 |
+|------|------|
+| 閫夋嫨妯℃澘鍚庡姞杞藉弬鏁� | 璋冪敤妯℃澘璇︽儏鎺ュ彛锛屽皢 details 娓叉煋涓鸿〃鍗曡 |
+| 蹇呭~鍙傛暟鏍¢獙 | required=true 鐨勫弬鏁帮紝paramValue 涓嶈兘涓虹┖锛屽惁鍒欐彁浜ゆ椂鎶ラ敊 |
+| 涓嶅厑璁告洿鎹㈡ā鏉� | 缂栬緫鏃� templateId 蹇呴』涓庡垱寤烘椂涓�鑷达紝濡傞渶鎹㈡ā鏉胯鍒犻櫎鍚庨噸鏂板垱寤� |
+| 澶氭璁板綍 | 鍚屼竴宸ュ崟鍙垱寤哄鏉″弬鏁拌褰曪紙鍚屼竴妯℃澘涔熷彲澶氭璁板綍锛� |
+| 蹇収鏈哄埗 | 璁板綍鏃跺揩鐓фā鏉跨殑鍙傛暟瀹氫箟锛屽悗缁ā鏉垮彉鏇翠笉褰卞搷宸茶褰曠殑鏁版嵁 |
+| 鍒犻櫎绾ц仈 | 鍒犻櫎璁板綍鏃讹紝璇ヨ褰曚笅鎵�鏈夊弬鏁版槑缁嗕竴璧峰垹闄� |
+
+## 娉ㄦ剰浜嬮」
+
+- 鍙傛暟绫诲瀷(paramType)瀛楀吀锛�1=鏂囨湰锛�2=鏁板�硷紝3=甯冨皵锛�4=鏃ユ湡锛屽墠绔彲鏍规嵁绫诲瀷娓叉煋涓嶅悓鐨勮緭鍏ユ帶浠�
+- 鏂板鏃跺厛閫夋ā鏉垮啀濉�硷紝寤鸿妯℃澘閫夋嫨鍚庣珛鍗宠皟鐢ㄦā鏉胯鎯呮帴鍙e姞杞藉弬鏁板垪琛�
+- 缂栬緫鏃舵ā鏉垮瓧娈电疆鐏颁笉鍙慨鏀癸紝鍙兘淇敼 paramValue 鍜� recordNo銆乺emark
+- 宸ュ崟鍙傛暟璁板綍鐨勬潈闄愬鐢ㄥ伐鍗曟潈闄愶細鍒涘缓/淇敼/鍒犻櫎鐢� `mes:pro-work-order:update`锛屾煡璇㈢敤 `mes:pro-work-order:query`
+- 鍚屼竴妯℃澘鍦ㄥ悓宸ュ崟涓嬪彲鍒涘缓澶氭璁板綍锛堝姣忕彮娆�/姣忔壒娆¤褰曚竴娆★級锛岄�氳繃 recordNo 鍖哄垎
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemSyncReqDTO.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemSyncReqDTO.java
index 8590df5..3184139 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemSyncReqDTO.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/api/item/dto/MdmItemSyncReqDTO.java
@@ -24,7 +24,7 @@
private String specification;
@Schema(description = "鐗╂枡绫诲瀷锛�1鍘熸枡, 2鍗婃垚鍝�, 3鎴愬搧, 4杈呮枡", example = "1")
- private Integer itemType;
+ private Long itemType;
@Schema(description = "璁¢噺鍗曚綅ID", example = "1")
private Long unitMeasureId;
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemSaveReqVO.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemSaveReqVO.java
index 4a41bfa..de0c38d 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemSaveReqVO.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/controller/admin/item/vo/MdmItemSaveReqVO.java
@@ -113,4 +113,6 @@
@Schema(description = "璐ㄩ噺鐘舵�佸繀濉�", example = "false")
private Boolean qualityStatusFlag;
+ private Long mdmItemId;
+
}
\ No newline at end of file
diff --git a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemServiceImpl.java b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemServiceImpl.java
index e210590..bea2631 100644
--- a/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemServiceImpl.java
+++ b/yudao-module-mdm/src/main/java/cn/iocoder/yudao/module/mdm/service/item/MdmItemServiceImpl.java
@@ -2,8 +2,10 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemPageReqVO;
import cn.iocoder.yudao.module.mdm.controller.admin.item.vo.MdmItemSaveReqVO;
import cn.iocoder.yudao.module.mdm.dal.dataobject.category.MdmItemCategoryDO;
@@ -15,8 +17,12 @@
import cn.iocoder.yudao.module.mdm.service.category.MdmItemCategoryService;
import cn.iocoder.yudao.module.mdm.service.unit.MdmUnitMeasureService;
import cn.iocoder.yudao.module.mes.api.item.MesMdItemApi;
+import cn.iocoder.yudao.module.mes.api.item.MesMdItemTypeApi;
import cn.iocoder.yudao.module.mes.api.item.dto.MesMdItemSyncReqDTO;
+import cn.iocoder.yudao.module.mes.api.item.dto.MesMdItemTypeRespDTO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -54,6 +60,10 @@
@Resource
private MdmItemBatchConfigMapper itemBatchConfigMapper;
+ @Resource
+ private MesMdItemTypeApi mesMdItemTypeApi;
+
+
@Override
@Transactional(rollbackFor = Exception.class)
public Long createItem(MdmItemSaveReqVO createReqVO) {
@@ -68,6 +78,7 @@
saveBatchConfig(item.getId(), createReqVO);
// 鍚屾鍒� MES锛堝嬀閫� syncMes 鏃讹級
+ createReqVO.setId(item.getId());
if (Boolean.TRUE.equals(createReqVO.getSyncMes())) {
syncItemToMes(createReqVO);
}
@@ -120,25 +131,13 @@
// 瑙f瀽鍒嗙被 id -> code锛堜娇鐢� MDM 鏈湴鍒嗙被鏈嶅姟锛�
String itemTypeCode = null;
if (reqVO.getCategoryId() != null) {
- MdmItemCategoryDO category = itemCategoryService.getItemCategory(reqVO.getCategoryId());
- if (category != null) {
- itemTypeCode = category.getCode();
- }
- } else if (reqVO.getItemType() != null) {
- // 鏍规嵁 itemType 鏌ユ壘瀵瑰簲鍒嗙被缂栫爜
- // itemType: 1鍘熸枡, 2鍗婃垚鍝�, 3鎴愬搧, 4杈呮枡
- String itemTypeName = convertItemTypeToName(reqVO.getItemType());
- List<MdmItemCategoryDO> categories = itemCategoryService.getItemCategoryList(
- itemCategoryService.getItemCategoryChildrenList(null).stream().map(MdmItemCategoryDO::getId).collect(Collectors.toSet()));
- itemTypeCode = categories.stream()
- .filter(c -> c.getName() != null && c.getName().equals(itemTypeName))
- .findFirst()
- .map(MdmItemCategoryDO::getCode)
- .orElse(null);
+ CommonResult<MesMdItemTypeRespDTO> itemType = mesMdItemTypeApi.getItemType(reqVO.getCategoryId());
+ itemTypeCode = itemType.getData().getCode();
}
// 缁勮鍚屾 DTO
MesMdItemSyncReqDTO syncReqDTO = new MesMdItemSyncReqDTO();
syncReqDTO.setCode(reqVO.getCode());
+ syncReqDTO.setMdmItemId(reqVO.getId());
syncReqDTO.setName(reqVO.getName());
syncReqDTO.setSpecification(reqVO.getSpecification());
syncReqDTO.setUnitCode(unitCode);
diff --git a/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/item/dto/MesMdItemSyncReqDTO.java b/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/item/dto/MesMdItemSyncReqDTO.java
index 706ebc9..0341052 100644
--- a/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/item/dto/MesMdItemSyncReqDTO.java
+++ b/yudao-module-mes-api/src/main/java/cn/iocoder/yudao/module/mes/api/item/dto/MesMdItemSyncReqDTO.java
@@ -65,4 +65,6 @@
@Schema(description = "璐ㄩ噺鐘舵�佸繀濉�", example = "false")
private Boolean qualityStatusFlag;
+ private Long mdmItemId;
+
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/item/MesMdItemApiImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/item/MesMdItemApiImpl.java
index 8be526a..8ff44ef 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/item/MesMdItemApiImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/api/item/MesMdItemApiImpl.java
@@ -47,7 +47,7 @@
MesMdItemSaveReqVO saveReqVO = buildSaveReqVO(syncReqDTO);
Long itemId = itemService.createItem(saveReqVO);
// 鍚屾鎵规閰嶇疆
- saveBatchConfig(itemId, syncReqDTO);
+// saveBatchConfig(itemId, syncReqDTO);
return itemId;
}
@@ -66,7 +66,7 @@
itemId = existItem.getId();
}
// 鍚屾鎵规閰嶇疆
- saveBatchConfig(itemId, syncReqDTO);
+// saveBatchConfig(itemId, syncReqDTO);
}
/**
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemSaveReqVO.java
index 7155ca9..e6ac294 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemSaveReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/md/item/vo/MesMdItemSaveReqVO.java
@@ -54,4 +54,6 @@
@Schema(description = "鏄惁鍚屾鍒� MDM", example = "true")
private Boolean syncMdm;
+ private Long mdmItemId;
+
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackPageReqVO.java
index 8a8470e..12072df 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackPageReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackPageReqVO.java
@@ -29,6 +29,12 @@
@Schema(description = "鐘舵��", example = "0")
private Integer status;
+ @Schema(description = "鐢熶骇浠诲姟缂栧彿", example = "1")
+ private Long taskId;
+
+ @Schema(description = "鐢熶骇浠诲姟缂栫爜锛堟ā绯婂尮閰嶏級", example = "PT202503")
+ private String taskCode;
+
@Schema(description = "鎶ュ伐鏃堕棿")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] feedbackTime;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackSaveReqVO.java
index e4c8a15..35a5f3c 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackSaveReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/feedback/vo/MesProFeedbackSaveReqVO.java
@@ -22,28 +22,23 @@
@NotNull(message = "鎶ュ伐绫诲瀷涓嶈兘涓虹┖")
private Integer type;
- @Schema(description = "宸ヤ綔绔欑紪鍙�", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
- @NotNull(message = "宸ヤ綔绔欎笉鑳戒负绌�")
+ @Schema(description = "宸ヤ綔绔欑紪鍙�", example = "1")
private Long workstationId;
- @Schema(description = "宸ヨ壓璺嚎缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
- @NotNull(message = "宸ヨ壓璺嚎涓嶈兘涓虹┖")
+ @Schema(description = "宸ヨ壓璺嚎缂栧彿", example = "1")
private Long routeId;
- @Schema(description = "宸ュ簭缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
- @NotNull(message = "宸ュ簭涓嶈兘涓虹┖")
+ @Schema(description = "宸ュ簭缂栧彿", example = "1")
private Long processId;
- @Schema(description = "鐢熶骇宸ュ崟缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
- @NotNull(message = "鐢熶骇宸ュ崟涓嶈兘涓虹┖")
+ @Schema(description = "鐢熶骇宸ュ崟缂栧彿", example = "1")
private Long workOrderId;
@Schema(description = "鐢熶骇浠诲姟缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "鐢熶骇浠诲姟涓嶈兘涓虹┖")
private Long taskId;
- @Schema(description = "浜у搧鐗╂枡缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
- @NotNull(message = "浜у搧鐗╂枡涓嶈兘涓虹┖")
+ @Schema(description = "浜у搧鐗╂枡缂栧彿", example = "100")
private Long itemId;
@Schema(description = "杩囨湡鏃ユ湡")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/MesProWorkOrderParamRecordController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/MesProWorkOrderParamRecordController.java
new file mode 100644
index 0000000..00d6c97
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/MesProWorkOrderParamRecordController.java
@@ -0,0 +1,124 @@
+package cn.iocoder.yudao.module.mes.controller.admin.pro.workorder;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.ListUtil;
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.paramrecord.MesProWorkOrderParamRecordPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.paramrecord.MesProWorkOrderParamRecordRespVO;
+import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.paramrecord.MesProWorkOrderParamRecordSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderParamRecordDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderParamRecordDetailDO;
+import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderParamRecordDetailMapper;
+import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
+import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderParamRecordService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
+
+@Tag(name = "绠$悊鍚庡彴 - MES 鐢熶骇宸ュ崟鍙傛暟璁板綍")
+@RestController
+@RequestMapping("/mes/pro/work-order-param-record")
+@Validated
+public class MesProWorkOrderParamRecordController {
+
+ @Resource
+ private MesProWorkOrderParamRecordService paramRecordService;
+ @Resource
+ private MesProWorkOrderParamRecordDetailMapper paramRecordDetailMapper;
+ @Resource
+ private MesMdUnitMeasureService unitMeasureService;
+
+ @PostMapping("/create")
+ @Operation(summary = "鍒涘缓宸ュ崟鍙傛暟璁板綍")
+ @PreAuthorize("@ss.hasPermission('mes:pro-work-order:update')")
+ public CommonResult<Long> createParamRecord(@RequestParam("workOrderId") Long taskId,
+ @Valid @RequestBody MesProWorkOrderParamRecordSaveReqVO createReqVO) {
+ return success(paramRecordService.createParamRecord(taskId, createReqVO));
+ }
+
+ @PutMapping("/update")
+ @Operation(summary = "鏇存柊宸ュ崟鍙傛暟璁板綍")
+ @PreAuthorize("@ss.hasPermission('mes:pro-work-order:update')")
+ public CommonResult<Boolean> updateParamRecord(@Valid @RequestBody MesProWorkOrderParamRecordSaveReqVO updateReqVO) {
+ paramRecordService.updateParamRecord(updateReqVO);
+ return success(true);
+ }
+
+ @DeleteMapping("/delete")
+ @Operation(summary = "鍒犻櫎宸ュ崟鍙傛暟璁板綍")
+ @Parameter(name = "id", description = "缂栧彿", required = true)
+ @PreAuthorize("@ss.hasPermission('mes:pro-work-order:update')")
+ public CommonResult<Boolean> deleteParamRecord(@RequestParam("id") Long id) {
+ paramRecordService.deleteParamRecord(id);
+ return success(true);
+ }
+
+ @GetMapping("/get")
+ @Operation(summary = "鑾峰緱宸ュ崟鍙傛暟璁板綍")
+ @Parameter(name = "id", description = "缂栧彿", required = true, example = "1024")
+ @PreAuthorize("@ss.hasPermission('mes:pro-work-order:query')")
+ public CommonResult<MesProWorkOrderParamRecordRespVO> getParamRecord(@RequestParam("id") Long id) {
+ MesProWorkOrderParamRecordDO record = paramRecordService.getParamRecord(id);
+ if (record == null) {
+ return success(null);
+ }
+ return success(buildRecordRespVOList(ListUtil.of(record)).get(0));
+ }
+
+ @GetMapping("/page-by-work-order")
+ @Operation(summary = "鎸夊伐鍗曡幏寰楀弬鏁拌褰曞垎椤�")
+ @PreAuthorize("@ss.hasPermission('mes:pro-work-order:query')")
+ public CommonResult<PageResult<MesProWorkOrderParamRecordRespVO>> getParamRecordPageByWorkOrderId(
+ @RequestParam("taskId") Long taskId,
+ @Valid MesProWorkOrderParamRecordPageReqVO pageReqVO) {
+ PageResult<MesProWorkOrderParamRecordDO> pageResult =
+ paramRecordService.getParamRecordPageByWorkOrderId(taskId, pageReqVO);
+ return success(new PageResult<>(buildRecordRespVOList(pageResult.getList()), pageResult.getTotal()));
+ }
+
+ // ==================== 鎷兼帴 VO ====================
+
+ private List<MesProWorkOrderParamRecordRespVO> buildRecordRespVOList(List<MesProWorkOrderParamRecordDO> list) {
+ if (CollUtil.isEmpty(list)) {
+ return Collections.emptyList();
+ }
+ // 1. 鎵归噺鑾峰彇鎵�鏈夎褰曠殑鏄庣粏
+ List<MesProWorkOrderParamRecordDetailDO> allDetails = paramRecordDetailMapper.selectListByRecordIds(
+ convertSet(list, MesProWorkOrderParamRecordDO::getId));
+ Map<Long, List<MesProWorkOrderParamRecordDetailDO>> detailMap = allDetails.stream()
+ .collect(Collectors.groupingBy(MesProWorkOrderParamRecordDetailDO::getRecordId));
+
+ // 2. 鎵归噺鑾峰彇璁¢噺鍗曚綅
+ Set<Long> unitMeasureIds = convertSet(allDetails, MesProWorkOrderParamRecordDetailDO::getUnitMeasureId);
+ Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(unitMeasureIds);
+
+ // 3. 鎷兼帴 VO
+ return BeanUtils.toBean(list, MesProWorkOrderParamRecordRespVO.class, vo -> {
+ List<MesProWorkOrderParamRecordDetailDO> details = detailMap.get(vo.getId());
+ if (CollUtil.isNotEmpty(details)) {
+ List<MesProWorkOrderParamRecordRespVO.DetailResp> detailResps = BeanUtils.toBean(
+ details, MesProWorkOrderParamRecordRespVO.DetailResp.class,
+ detailResp -> MapUtils.findAndThen(unitMeasureMap, detailResp.getUnitMeasureId(),
+ unit -> detailResp.setUnitMeasureName(unit.getName()))
+ );
+ vo.setDetails(detailResps);
+ }
+ });
+ }
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/paramrecord/MesProWorkOrderParamRecordPageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/paramrecord/MesProWorkOrderParamRecordPageReqVO.java
new file mode 100644
index 0000000..1364cd2
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/paramrecord/MesProWorkOrderParamRecordPageReqVO.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.paramrecord;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "绠$悊鍚庡彴 - MES 鐢熶骇宸ュ崟鍙傛暟璁板綍鍒嗛〉 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MesProWorkOrderParamRecordPageReqVO extends PageParam {
+
+ @Schema(description = "璁板綍搴忓彿/鎵规鍙�", example = "BATCH-001")
+ private String recordNo;
+
+ @Schema(description = "妯℃澘鍚嶇О", example = "娉ㄥ鍙傛暟妯℃澘")
+ private String templateName;
+
+ @Schema(description = "鍒涘缓鏃堕棿")
+ @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+ private LocalDateTime[] createTime;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/paramrecord/MesProWorkOrderParamRecordRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/paramrecord/MesProWorkOrderParamRecordRespVO.java
new file mode 100644
index 0000000..03d5673
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/paramrecord/MesProWorkOrderParamRecordRespVO.java
@@ -0,0 +1,76 @@
+package cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.paramrecord;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Schema(description = "绠$悊鍚庡彴 - MES 鐢熶骇宸ュ崟鍙傛暟璁板綍 Response VO")
+@Data
+public class MesProWorkOrderParamRecordRespVO {
+
+ @Schema(description = "缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long id;
+
+ @Schema(description = "鐢熶骇璁㈠崟缂栧彿", example = "1")
+ private Long workOrderId;
+
+ @Schema(description = "鐢熶骇宸ュ崟缂栧彿")
+ private Long taskId;
+
+ @Schema(description = "鍙傛暟妯℃澘缂栧彿", example = "1")
+ private Long templateId;
+
+ @Schema(description = "妯℃澘缂栫爜", example = "CSMB001")
+ private String templateCode;
+
+ @Schema(description = "妯℃澘鍚嶇О", example = "娉ㄥ鍙傛暟妯℃澘")
+ private String templateName;
+
+ @Schema(description = "璁板綍搴忓彿/鎵规鍙�", example = "BATCH-001")
+ private String recordNo;
+
+ @Schema(description = "澶囨敞", example = "澶囨敞")
+ private String remark;
+
+ @Schema(description = "鍒涘缓鏃堕棿", requiredMode = Schema.RequiredMode.REQUIRED)
+ private LocalDateTime createTime;
+
+ @Schema(description = "鍙傛暟鏄庣粏鍒楄〃")
+ private List<DetailResp> details;
+
+ @Schema(description = "鍙傛暟鏄庣粏鍝嶅簲")
+ @Data
+ public static class DetailResp {
+
+ @Schema(description = "缂栧彿", example = "1024")
+ private Long id;
+
+ @Schema(description = "妯℃澘鏄庣粏缂栧彿", example = "1")
+ private Long templateDetailId;
+
+ @Schema(description = "鍙傛暟缂栫爜", example = "TEMP")
+ private String paramCode;
+
+ @Schema(description = "鍙傛暟鍚嶇О", example = "娓╁害")
+ private String paramName;
+
+ @Schema(description = "鍙傛暟绫诲瀷", example = "1")
+ private Integer paramType;
+
+ @Schema(description = "璁¢噺鍗曚綅缂栧彿", example = "1")
+ private Long unitMeasureId;
+
+ @Schema(description = "璁¢噺鍗曚綅鍚嶇О", example = "鈩�")
+ private String unitMeasureName;
+
+ @Schema(description = "鍙傛暟鍊�", example = "200")
+ private String paramValue;
+
+ @Schema(description = "澶囨敞", example = "澶囨敞")
+ private String remark;
+
+ }
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/paramrecord/MesProWorkOrderParamRecordSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/paramrecord/MesProWorkOrderParamRecordSaveReqVO.java
new file mode 100644
index 0000000..515a442
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/pro/workorder/vo/paramrecord/MesProWorkOrderParamRecordSaveReqVO.java
@@ -0,0 +1,46 @@
+package cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.paramrecord;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.util.List;
+
+@Schema(description = "绠$悊鍚庡彴 - MES 鐢熶骇宸ュ崟鍙傛暟璁板綍鏂板/淇敼 Request VO")
+@Data
+public class MesProWorkOrderParamRecordSaveReqVO {
+
+ @Schema(description = "缂栧彿锛堜慨鏀规椂蹇呬紶锛�", example = "1024")
+ private Long id;
+
+ @Schema(description = "鍙傛暟妯℃澘缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "鍙傛暟妯℃澘涓嶈兘涓虹┖")
+ private Long templateId;
+
+ @Schema(description = "璁板綍搴忓彿/鎵规鍙�", example = "BATCH-001")
+ private String recordNo;
+
+ @Schema(description = "鍙傛暟鏄庣粏鍒楄〃", requiredMode = Schema.RequiredMode.REQUIRED)
+ @NotEmpty(message = "鍙傛暟鏄庣粏涓嶈兘涓虹┖")
+ @Valid
+ private List<DetailItem> details;
+
+ @Schema(description = "澶囨敞", example = "澶囨敞")
+ private String remark;
+
+ @Schema(description = "鍙傛暟鏄庣粏椤�")
+ @Data
+ public static class DetailItem {
+
+ @Schema(description = "妯℃澘鏄庣粏缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "妯℃澘鏄庣粏缂栧彿涓嶈兘涓虹┖")
+ private Long templateDetailId;
+
+ @Schema(description = "鍙傛暟鍊�", example = "200")
+ private String paramValue;
+
+ }
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueController.java
index 4836c4a..04e4ba3 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueController.java
@@ -13,10 +13,12 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.MesWmProductIssueSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDO;
import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
+import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import cn.iocoder.yudao.module.mes.service.wm.productissue.MesWmProductIssueService;
import io.swagger.v3.oas.annotations.Operation;
@@ -50,6 +52,8 @@
private MesMdWorkstationService workstationService;
@Resource
private MesProWorkOrderService workOrderService;
+ @Resource
+ private MesProTaskService taskService;
@Resource
private MesMdClientService clientService;
@@ -165,12 +169,16 @@
convertSet(list, MesWmProductIssueDO::getWorkstationId));
Map<Long, MesProWorkOrderDO> workOrderMap = workOrderService.getWorkOrderMap(
convertSet(list, MesWmProductIssueDO::getWorkOrderId));
+ Map<Long, MesProTaskDO> taskMap = taskService.getTaskMap(
+ convertSet(list, MesWmProductIssueDO::getTaskId));
Map<Long, MesMdClientDO> clientMap = clientService.getClientMap(
convertSet(workOrderMap.values(), MesProWorkOrderDO::getClientId));
// 2. 鏋勫缓缁撴灉
return BeanUtils.toBean(list, MesWmProductIssueRespVO.class, vo -> {
MapUtils.findAndThen(workstationMap, vo.getWorkstationId(),
workstation -> vo.setWorkstationName(workstation.getName()));
+ MapUtils.findAndThen(taskMap, vo.getTaskId(), task ->
+ vo.setTaskCode(task.getCode()).setTaskName(task.getName()));
MapUtils.findAndThen(workOrderMap, vo.getWorkOrderId(), workOrder -> {
vo.setWorkOrderCode(workOrder.getCode());
MapUtils.findAndThen(clientMap, workOrder.getClientId(), client ->
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java
index 29093f9..a9ec67c 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/MesWmProductIssueLineController.java
@@ -8,13 +8,13 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.line.MesWmProductIssueLineSaveReqVO;
-import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
-import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
-
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueLineDO;
-import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
-import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
-
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
+import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
+import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
import cn.iocoder.yudao.module.mes.service.wm.productissue.MesWmProductIssueLineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -28,7 +28,6 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -42,9 +41,11 @@
@Resource
private MesWmProductIssueLineService issueLineService;
@Resource
- private MdmItemApi mdmItemApi;
+ private MesMdItemService mdmItemService;
@Resource
- private MdmUnitMeasureApi mdmUnitMeasureApi;
+ private MesMdUnitMeasureService unitMeasureService;
+ @Resource
+ private MesProTaskService taskService;
@PostMapping("/create")
@Operation(summary = "鍒涘缓棰嗘枡鍑哄簱鍗曡")
@@ -108,18 +109,21 @@
return Collections.emptyList();
}
// 1. 鑾峰緱鍏宠仈鏁版嵁
- Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
+ Map<Long, MesMdItemDO> itemMap = mdmItemService.getItemMap(
convertSet(list, MesWmProductIssueLineDO::getItemId));
- Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
- convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
- .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
+ Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
+ convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
+ Map<Long, MesProTaskDO> taskMap = taskService.getTaskMap(
+ convertSet(list, MesWmProductIssueLineDO::getTaskId));
// 2. 鏋勫缓缁撴灉
return BeanUtils.toBean(list, MesWmProductIssueLineRespVO.class, vo -> {
MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
- vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification());
+ vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()).setMdmItemId(item.getMdmItemId());
MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
- unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName()));
+ unit -> vo.setUnitMeasureName(unit.getName()));
});
+ MapUtils.findAndThen(taskMap, vo.getTaskId(), task ->
+ vo.setTaskCode(task.getCode()).setTaskName(task.getName()));
});
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/MesWmProductIssueRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/MesWmProductIssueRespVO.java
index 3558350..e6b4ca3 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/MesWmProductIssueRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/MesWmProductIssueRespVO.java
@@ -39,6 +39,12 @@
@Schema(description = "鐢熶骇浠诲姟 ID", example = "1")
private Long taskId;
+ @Schema(description = "鐢熶骇浠诲姟缂栫爜", example = "TASK001")
+ private String taskCode;
+
+ @Schema(description = "鐢熶骇浠诲姟鍚嶇О", example = "娉ㄥ浠诲姟")
+ private String taskName;
+
@Schema(description = "棰嗘枡鏃ユ湡")
private LocalDateTime issueDate;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/MesWmProductIssueSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/MesWmProductIssueSaveReqVO.java
index 7dbec27..b84e0ea 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/MesWmProductIssueSaveReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/MesWmProductIssueSaveReqVO.java
@@ -22,8 +22,11 @@
@NotBlank(message = "棰嗘枡鍗曞悕绉颁笉鑳戒负绌�")
private String name;
- @Schema(description = "鐢熶骇宸ュ崟 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
- @NotNull(message = "鐢熶骇宸ュ崟 ID 涓嶈兘涓虹┖")
+ @Schema(description = "鐢熶骇浠诲姟 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "鐢熶骇浠诲姟 ID 涓嶈兘涓虹┖")
+ private Long taskId;
+
+ @Schema(description = "鐢熶骇宸ュ崟 ID", example = "1")
private Long workOrderId;
@Schema(description = "宸ヤ綔绔� ID", example = "1")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/line/MesWmProductIssueLineRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/line/MesWmProductIssueLineRespVO.java
index f21b4b7..dd79b0e 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/line/MesWmProductIssueLineRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/line/MesWmProductIssueLineRespVO.java
@@ -16,6 +16,15 @@
@Schema(description = "棰嗘枡鍗旾D", example = "1")
private Long issueId;
+ @Schema(description = "鐢熶骇浠诲姟ID", example = "1")
+ private Long taskId;
+
+ @Schema(description = "鐢熶骇浠诲姟缂栫爜", example = "TASK001")
+ private String taskCode;
+
+ @Schema(description = "鐢熶骇浠诲姟鍚嶇О", example = "娉ㄥ浠诲姟")
+ private String taskName;
+
@Schema(description = "鐗╂枡ID", example = "1")
private Long itemId;
@@ -43,4 +52,6 @@
@Schema(description = "鍒涘缓鏃堕棿")
private LocalDateTime createTime;
+ private Long mdmItemId;
+
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/line/MesWmProductIssueLineSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/line/MesWmProductIssueLineSaveReqVO.java
index 314b2b4..3b369a2 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/line/MesWmProductIssueLineSaveReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productissue/vo/line/MesWmProductIssueLineSaveReqVO.java
@@ -18,6 +18,9 @@
@NotNull(message = "棰嗘枡鍗旾D涓嶈兘涓虹┖")
private Long issueId;
+ @Schema(description = "鐢熶骇浠诲姟ID", example = "1")
+ private Long taskId;
+
@Schema(description = "鐗╂枡ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "鐗╂枡ID涓嶈兘涓虹┖")
private Long itemId;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueController.java
index c581503..cef9968 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueController.java
@@ -12,9 +12,11 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.MesWmReturnIssueRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.MesWmReturnIssueSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueDO;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
+import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
import cn.iocoder.yudao.module.mes.service.wm.returnissue.MesWmReturnIssueService;
import io.swagger.v3.oas.annotations.Operation;
@@ -48,6 +50,8 @@
private MesMdWorkstationService workstationService;
@Resource
private MesProWorkOrderService workOrderService;
+ @Resource
+ private MesProTaskService taskService;
@PostMapping("/create")
@Operation(summary = "鍒涘缓鐢熶骇閫�鏂欏崟")
@@ -153,10 +157,14 @@
convertSet(list, MesWmReturnIssueDO::getWorkstationId));
Map<Long, MesProWorkOrderDO> workOrderMap = workOrderService.getWorkOrderMap(
convertSet(list, MesWmReturnIssueDO::getWorkOrderId));
+ Map<Long, MesProTaskDO> taskMap = taskService.getTaskMap(
+ convertSet(list, MesWmReturnIssueDO::getTaskId));
// 2. 鏋勫缓缁撴灉
return BeanUtils.toBean(list, MesWmReturnIssueRespVO.class, vo -> {
MapUtils.findAndThen(workstationMap, vo.getWorkstationId(),
workstation -> vo.setWorkstationName(workstation.getName()));
+ MapUtils.findAndThen(taskMap, vo.getTaskId(), task ->
+ vo.setTaskCode(task.getCode()).setTaskName(task.getName()));
MapUtils.findAndThen(workOrderMap, vo.getWorkOrderId(),
workOrder -> vo.setWorkOrderCode(workOrder.getCode()));
});
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java
index 58423bc..23aa6e7 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java
@@ -8,13 +8,13 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWmReturnIssueLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWmReturnIssueLineRespVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWmReturnIssueLineSaveReqVO;
-import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
-import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
-
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO;
-import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi;
-import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO;
-
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
+import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService;
+import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
import cn.iocoder.yudao.module.mes.service.wm.returnissue.MesWmReturnIssueLineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
@@ -28,7 +28,6 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@@ -42,9 +41,11 @@
@Resource
private MesWmReturnIssueLineService issueLineService;
@Resource
- private MdmItemApi mdmItemApi;
+ private MesMdItemService mdmItemService;
@Resource
- private MdmUnitMeasureApi mdmUnitMeasureApi;
+ private MesMdUnitMeasureService unitMeasureService;
+ @Resource
+ private MesProTaskService taskService;
@PostMapping("/create")
@Operation(summary = "鍒涘缓鐢熶骇閫�鏂欏崟琛�")
@@ -108,18 +109,21 @@
return Collections.emptyList();
}
// 1. 鑾峰緱鍏宠仈鏁版嵁
- Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
+ Map<Long, MesMdItemDO> itemMap = mdmItemService.getItemMap(
convertSet(list, MesWmReturnIssueLineDO::getItemId));
- Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureList(
- convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)).getCheckedData()
- .stream().collect(Collectors.toMap(MdmUnitMeasureRespDTO::getId, e -> e));
+ Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
+ convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
+ Map<Long, MesProTaskDO> taskMap = taskService.getTaskMap(
+ convertSet(list, MesWmReturnIssueLineDO::getTaskId));
// 2. 鏋勫缓缁撴灉
return BeanUtils.toBean(list, MesWmReturnIssueLineRespVO.class, vo -> {
MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification());
MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
- unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName()));
+ unit -> vo.setUnitMeasureName(unit.getName()));
});
+ MapUtils.findAndThen(taskMap, vo.getTaskId(), task ->
+ vo.setTaskCode(task.getCode()).setTaskName(task.getName()));
});
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssuePageReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssuePageReqVO.java
index c27eca8..02fd583 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssuePageReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssuePageReqVO.java
@@ -22,6 +22,9 @@
@Schema(description = "鐢熶骇宸ュ崟 ID", example = "1")
private Long workOrderId;
+ @Schema(description = "鐢熶骇浠诲姟 ID", example = "1")
+ private Long taskId;
+
@Schema(description = "閫�鏂欑被鍨�", example = "1")
private Integer type;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueRespVO.java
index 5650522..04357e9 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueRespVO.java
@@ -24,6 +24,15 @@
@Schema(description = "鐢熶骇宸ュ崟缂栧彿", requiredMode = Schema.RequiredMode.REQUIRED, example = "WO20250226001")
private String workOrderCode;
+ @Schema(description = "鐢熶骇浠诲姟 ID", example = "1")
+ private Long taskId;
+
+ @Schema(description = "鐢熶骇浠诲姟缂栫爜", example = "TASK001")
+ private String taskCode;
+
+ @Schema(description = "鐢熶骇浠诲姟鍚嶇О", example = "娉ㄥ浠诲姟")
+ private String taskName;
+
@Schema(description = "宸ヤ綔绔� ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Long workstationId;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueSaveReqVO.java
index 3ad2d5c..891141c 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueSaveReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/MesWmReturnIssueSaveReqVO.java
@@ -22,8 +22,11 @@
@NotBlank(message = "閫�鏂欏崟鍚嶇О涓嶈兘涓虹┖")
private String name;
- @Schema(description = "鐢熶骇宸ュ崟 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
- @NotNull(message = "鐢熶骇宸ュ崟 ID 涓嶈兘涓虹┖")
+ @Schema(description = "鐢熶骇浠诲姟 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+ @NotNull(message = "鐢熶骇浠诲姟 ID 涓嶈兘涓虹┖")
+ private Long taskId;
+
+ @Schema(description = "鐢熶骇宸ュ崟 ID", example = "1")
private Long workOrderId;
@Schema(description = "宸ヤ綔绔� ID", example = "1")
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/line/MesWmReturnIssueLineRespVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/line/MesWmReturnIssueLineRespVO.java
index ccbe46b..3962f79 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/line/MesWmReturnIssueLineRespVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/line/MesWmReturnIssueLineRespVO.java
@@ -16,6 +16,15 @@
@Schema(description = "閫�鏂欏崟 ID", example = "1")
private Long issueId;
+ @Schema(description = "鐢熶骇浠诲姟 ID", example = "1")
+ private Long taskId;
+
+ @Schema(description = "鐢熶骇浠诲姟缂栫爜", example = "TASK001")
+ private String taskCode;
+
+ @Schema(description = "鐢熶骇浠诲姟鍚嶇О", example = "娉ㄥ浠诲姟")
+ private String taskName;
+
@Schema(description = "鐗╂枡 ID", example = "1")
private Long itemId;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/line/MesWmReturnIssueLineSaveReqVO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/line/MesWmReturnIssueLineSaveReqVO.java
index 3403b2a..39822f9 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/line/MesWmReturnIssueLineSaveReqVO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/line/MesWmReturnIssueLineSaveReqVO.java
@@ -18,6 +18,9 @@
@NotNull(message = "閫�鏂欏崟 ID 涓嶈兘涓虹┖")
private Long issueId;
+ @Schema(description = "鐢熶骇浠诲姟 ID", example = "1")
+ private Long taskId;
+
@Schema(description = "鐗╂枡 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "鐗╂枡 ID 涓嶈兘涓虹┖")
private Long itemId;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/item/MesMdItemDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/item/MesMdItemDO.java
index c1a969c..f916775 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/item/MesMdItemDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/md/item/MesMdItemDO.java
@@ -30,6 +30,12 @@
@TableId
private Long id;
/**
+ * MDM 鐗╂枡 ID
+ *
+ * 鍏宠仈 mdm_item.id
+ */
+ private Long mdmItemId;
+ /**
* 鐗╂枡缂栫爜
*/
private String code;
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/workorder/MesProWorkOrderParamRecordDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/workorder/MesProWorkOrderParamRecordDO.java
new file mode 100644
index 0000000..b9f8cba
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/workorder/MesProWorkOrderParamRecordDO.java
@@ -0,0 +1,62 @@
+package cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pd.processparamtemplate.MesPdProcessParamTemplateDO;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+/**
+ * MES 鐢熶骇宸ュ崟鍙傛暟璁板綍 DO
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+@TableName("mes_pro_work_order_param_record")
+@KeySequence("mes_pro_work_order_param_record_seq")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class MesProWorkOrderParamRecordDO extends BaseDO {
+
+ /**
+ * 缂栧彿
+ */
+ @TableId
+ private Long id;
+ /**
+ * 鐢熶骇宸ュ崟缂栧彿
+ *
+ * 鍏宠仈 {@link MesProWorkOrderDO#getId()}
+ */
+ private Long workOrderId;
+
+
+ private Long taskId;
+ /**
+ * 鍙傛暟妯℃澘缂栧彿
+ *
+ * 鍏宠仈 {@link MesPdProcessParamTemplateDO#getId()}
+ */
+ private Long templateId;
+ /**
+ * 妯℃澘缂栫爜锛堝揩鐓э級
+ */
+ private String templateCode;
+ /**
+ * 妯℃澘鍚嶇О锛堝揩鐓э級
+ */
+ private String templateName;
+ /**
+ * 璁板綍搴忓彿/鎵规鍙�
+ */
+ private String recordNo;
+ /**
+ * 澶囨敞
+ */
+ private String remark;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/workorder/MesProWorkOrderParamRecordDetailDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/workorder/MesProWorkOrderParamRecordDetailDO.java
new file mode 100644
index 0000000..08b98a0
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/pro/workorder/MesProWorkOrderParamRecordDetailDO.java
@@ -0,0 +1,70 @@
+package cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pd.processparamtemplate.MesPdProcessParamTemplateDetailDO;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+/**
+ * MES 鐢熶骇宸ュ崟鍙傛暟璁板綍鏄庣粏 DO
+ *
+ * 蹇収琛細璁板綍鏃跺揩鐓фā鏉垮弬鏁板畾涔夛紝鍚庣画妯℃澘鍙樻洿涓嶅奖鍝嶅凡璁板綍鐨勬暟鎹��
+ * template_detail_id 浠呬綔婧簮锛屼笉浠庢ā鏉挎槑缁嗕富琛ㄨ鍙栨樉绀哄�笺��
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+@TableName("mes_pro_work_order_param_record_detail")
+@KeySequence("mes_pro_work_order_param_record_detail_seq")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class MesProWorkOrderParamRecordDetailDO extends BaseDO {
+
+ /**
+ * 缂栧彿
+ */
+ @TableId
+ private Long id;
+ /**
+ * 鍙傛暟璁板綍缂栧彿
+ *
+ * 鍏宠仈 {@link MesProWorkOrderParamRecordDO#getId()}
+ */
+ private Long recordId;
+ /**
+ * 妯℃澘鏄庣粏缂栧彿锛堜粎浣滄函婧愶級
+ *
+ * 鍏宠仈 {@link MesPdProcessParamTemplateDetailDO#getId()}
+ */
+ private Long templateDetailId;
+ /**
+ * 鍙傛暟缂栫爜锛堝揩鐓э級
+ */
+ private String paramCode;
+ /**
+ * 鍙傛暟鍚嶇О锛堝揩鐓э級
+ */
+ private String paramName;
+ /**
+ * 鍙傛暟绫诲瀷锛堝揩鐓э級
+ */
+ private Integer paramType;
+ /**
+ * 璁¢噺鍗曚綅缂栧彿锛堝揩鐓э級
+ */
+ private Long unitMeasureId;
+ /**
+ * 鍙傛暟鍊�
+ */
+ private String paramValue;
+ /**
+ * 澶囨敞
+ */
+ private String remark;
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productissue/MesWmProductIssueDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productissue/MesWmProductIssueDO.java
index b6de8d9..7aa3254 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productissue/MesWmProductIssueDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productissue/MesWmProductIssueDO.java
@@ -51,14 +51,12 @@
* 鍏宠仈 {@link MesProWorkOrderDO#getId()}
*/
private Long workOrderId;
- // TODO @鑺嬭壙锛氥�愮枒闂紝涓嶈鍔ㄣ�戣繖涓瓧娈电殑鏉ユ簮锛�
/**
* 鐢熶骇浠诲姟 ID
*
* 鍏宠仈 {@link MesProTaskDO#getId()}
*/
private Long taskId;
- // TODO @鑺嬭壙锛氥�愮枒闂紝涓嶈鍔ㄣ�戣繖涓瓧娈电殑鏇存柊鏃堕棿锛�
/**
* 棰嗘枡鏃ユ湡
*/
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productissue/MesWmProductIssueLineDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productissue/MesWmProductIssueLineDO.java
index 89d8d6a..e789f1d 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productissue/MesWmProductIssueLineDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productissue/MesWmProductIssueLineDO.java
@@ -2,6 +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.pro.task.MesProTaskDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -34,6 +35,12 @@
*/
private Long issueId;
/**
+ * 鐢熶骇浠诲姟 ID
+ *
+ * 鍏宠仈 {@link MesProTaskDO#getId()}
+ */
+ private Long taskId;
+ /**
* 鐗╂枡 ID
*
* 鍏宠仈 {@link MesMdItemDO#getId()}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueDO.java
index dc08306..c3330e9 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueDO.java
@@ -2,6 +2,7 @@
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnIssueStatusEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
@@ -45,6 +46,12 @@
*/
private Long workOrderId;
/**
+ * 鐢熶骇浠诲姟 ID
+ *
+ * 鍏宠仈 {@link MesProTaskDO#getId()}
+ */
+ private Long taskId;
+ /**
* 宸ヤ綔绔� ID
*
* 鍏宠仈 {@link MesMdWorkstationDO#getId()}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueLineDO.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueLineDO.java
index 1a7a787..11c07fa 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueLineDO.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueLineDO.java
@@ -2,6 +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.pro.task.MesProTaskDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.qc.rqc.MesQcRqcDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
@@ -38,6 +39,12 @@
*/
private Long issueId;
/**
+ * 鐢熶骇浠诲姟 ID
+ *
+ * 鍏宠仈 {@link MesProTaskDO#getId()}
+ */
+ private Long taskId;
+ /**
* 搴撳瓨璁板綍 ID
*
* 鍏宠仈 {@link MesWmMaterialStockDO#getId()}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/item/MesMdItemTypeMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/item/MesMdItemTypeMapper.java
index 2ff6a59..a6b4b7a 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/item/MesMdItemTypeMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/md/item/MesMdItemTypeMapper.java
@@ -32,7 +32,7 @@
}
default MesMdItemTypeDO selectByCode(String code) {
- return selectOne(MesMdItemTypeDO::getName, code);
+ return selectOne(MesMdItemTypeDO::getCode, code);
}
default Long selectCountByParentId(Long parentId) {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/feedback/MesProFeedbackMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/feedback/MesProFeedbackMapper.java
index b40c765..e35fee0 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/feedback/MesProFeedbackMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/feedback/MesProFeedbackMapper.java
@@ -1,10 +1,13 @@
package cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback;
+import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackPageReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
@@ -19,10 +22,31 @@
public interface MesProFeedbackMapper extends BaseMapperX<MesProFeedbackDO> {
default PageResult<MesProFeedbackDO> selectPage(MesProFeedbackPageReqVO reqVO) {
+ // 褰撴寜浠诲姟缂栫爜妯$硦鏌ヨ鏃讹紝闇�瑕� JOIN 浠诲姟琛�
+ if (StrUtil.isNotBlank(reqVO.getTaskCode())) {
+ MPJLambdaWrapperX<MesProFeedbackDO> query = new MPJLambdaWrapperX<>();
+ query.selectAll(MesProFeedbackDO.class);
+ query.leftJoin(MesProTaskDO.class, on -> on
+ .eq(MesProTaskDO::getId, MesProFeedbackDO::getTaskId));
+ query.like(MesProTaskDO::getCode, reqVO.getTaskCode());
+ query.likeIfPresent(MesProFeedbackDO::getCode, reqVO.getCode())
+ .eqIfPresent(MesProFeedbackDO::getType, reqVO.getType())
+ .eqIfPresent(MesProFeedbackDO::getWorkOrderId, reqVO.getWorkOrderId())
+ .eqIfPresent(MesProFeedbackDO::getTaskId, reqVO.getTaskId())
+ .eqIfPresent(MesProFeedbackDO::getStatus, reqVO.getStatus())
+ .betweenIfPresent(MesProFeedbackDO::getFeedbackTime, reqVO.getFeedbackTime())
+ .eqIfPresent(MesProFeedbackDO::getItemId, reqVO.getItemId())
+ .eqIfPresent(MesProFeedbackDO::getFeedbackUserId, reqVO.getFeedbackUserId())
+ .eqIfPresent(MesProFeedbackDO::getCreator, reqVO.getCreator())
+ .orderByDesc(MesProFeedbackDO::getId);
+ return selectPage(reqVO, query);
+ }
+ // 涓嶆秹鍙婁换鍔$紪鐮佹煡璇㈡椂锛岃蛋鏅�氭煡璇�
return selectPage(reqVO, new LambdaQueryWrapperX<MesProFeedbackDO>()
.likeIfPresent(MesProFeedbackDO::getCode, reqVO.getCode())
.eqIfPresent(MesProFeedbackDO::getType, reqVO.getType())
.eqIfPresent(MesProFeedbackDO::getWorkOrderId, reqVO.getWorkOrderId())
+ .eqIfPresent(MesProFeedbackDO::getTaskId, reqVO.getTaskId())
.eqIfPresent(MesProFeedbackDO::getStatus, reqVO.getStatus())
.betweenIfPresent(MesProFeedbackDO::getFeedbackTime, reqVO.getFeedbackTime())
.eqIfPresent(MesProFeedbackDO::getItemId, reqVO.getItemId())
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/task/MesProTaskIssueMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/task/MesProTaskIssueMapper.java
index 9c62c44..a398fdd 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/task/MesProTaskIssueMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/task/MesProTaskIssueMapper.java
@@ -37,4 +37,16 @@
.orderByDesc(MesProTaskIssueDO::getId));
}
+ default List<MesProTaskIssueDO> selectListBySourceDoc(String sourceDocType, Long sourceDocId) {
+ return selectList(new LambdaQueryWrapperX<MesProTaskIssueDO>()
+ .eq(MesProTaskIssueDO::getSourceDocType, sourceDocType)
+ .eq(MesProTaskIssueDO::getSourceDocId, sourceDocId));
+ }
+
+ default void deleteBySourceDoc(String sourceDocType, Long sourceDocId) {
+ delete(new LambdaQueryWrapperX<MesProTaskIssueDO>()
+ .eq(MesProTaskIssueDO::getSourceDocType, sourceDocType)
+ .eq(MesProTaskIssueDO::getSourceDocId, sourceDocId));
+ }
+
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/workorder/MesProWorkOrderParamRecordDetailMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/workorder/MesProWorkOrderParamRecordDetailMapper.java
new file mode 100644
index 0000000..d50f9d6
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/workorder/MesProWorkOrderParamRecordDetailMapper.java
@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder;
+
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderParamRecordDetailDO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * MES 鐢熶骇宸ュ崟鍙傛暟璁板綍鏄庣粏 Mapper
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+@Mapper
+public interface MesProWorkOrderParamRecordDetailMapper extends BaseMapperX<MesProWorkOrderParamRecordDetailDO> {
+
+ default List<MesProWorkOrderParamRecordDetailDO> selectListByRecordId(Long recordId) {
+ return selectList(new LambdaQueryWrapperX<MesProWorkOrderParamRecordDetailDO>()
+ .eq(MesProWorkOrderParamRecordDetailDO::getRecordId, recordId)
+ .orderByAsc(MesProWorkOrderParamRecordDetailDO::getId));
+ }
+
+ default List<MesProWorkOrderParamRecordDetailDO> selectListByRecordIds(Collection<Long> recordIds) {
+ return selectList(new LambdaQueryWrapperX<MesProWorkOrderParamRecordDetailDO>()
+ .in(MesProWorkOrderParamRecordDetailDO::getRecordId, recordIds)
+ .orderByAsc(MesProWorkOrderParamRecordDetailDO::getId));
+ }
+
+ default void deleteByRecordId(Long recordId) {
+ delete(new LambdaQueryWrapperX<MesProWorkOrderParamRecordDetailDO>()
+ .eq(MesProWorkOrderParamRecordDetailDO::getRecordId, recordId));
+ }
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/workorder/MesProWorkOrderParamRecordMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/workorder/MesProWorkOrderParamRecordMapper.java
new file mode 100644
index 0000000..b80cccc
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/pro/workorder/MesProWorkOrderParamRecordMapper.java
@@ -0,0 +1,36 @@
+package cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.paramrecord.MesProWorkOrderParamRecordPageReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderParamRecordDO;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * MES 鐢熶骇宸ュ崟鍙傛暟璁板綍 Mapper
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+@Mapper
+public interface MesProWorkOrderParamRecordMapper extends BaseMapperX<MesProWorkOrderParamRecordDO> {
+
+ default PageResult<MesProWorkOrderParamRecordDO> selectPageByWorkOrderId(Long taskId,
+ MesProWorkOrderParamRecordPageReqVO pageReqVO) {
+ return selectPage(pageReqVO, new LambdaQueryWrapperX<MesProWorkOrderParamRecordDO>()
+ .eq(MesProWorkOrderParamRecordDO::getTaskId, taskId)
+ .likeIfPresent(MesProWorkOrderParamRecordDO::getRecordNo, pageReqVO.getRecordNo())
+ .likeIfPresent(MesProWorkOrderParamRecordDO::getTemplateName, pageReqVO.getTemplateName())
+ .betweenIfPresent(MesProWorkOrderParamRecordDO::getCreateTime, pageReqVO.getCreateTime())
+ .orderByDesc(MesProWorkOrderParamRecordDO::getId));
+ }
+
+ default List<MesProWorkOrderParamRecordDO> selectListByWorkOrderId(Long workOrderId) {
+ return selectList(new LambdaQueryWrapperX<MesProWorkOrderParamRecordDO>()
+ .eq(MesProWorkOrderParamRecordDO::getWorkOrderId, workOrderId)
+ .orderByDesc(MesProWorkOrderParamRecordDO::getId));
+ }
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productissue/MesWmProductIssueLineMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productissue/MesWmProductIssueLineMapper.java
index 265e21e..1d3ae22 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productissue/MesWmProductIssueLineMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productissue/MesWmProductIssueLineMapper.java
@@ -21,6 +21,10 @@
.orderByDesc(MesWmProductIssueLineDO::getId));
}
+ default List<MesWmProductIssueLineDO> selectListByTaskId(Long taskId) {
+ return selectList(MesWmProductIssueLineDO::getTaskId, taskId);
+ }
+
default List<MesWmProductIssueLineDO> selectListByIssueId(Long issueId) {
return selectList(MesWmProductIssueLineDO::getIssueId, issueId);
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productissue/MesWmProductIssueMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productissue/MesWmProductIssueMapper.java
index dd18e43..7634eaf 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productissue/MesWmProductIssueMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productissue/MesWmProductIssueMapper.java
@@ -19,6 +19,7 @@
.likeIfPresent(MesWmProductIssueDO::getName, reqVO.getName())
.eqIfPresent(MesWmProductIssueDO::getWorkstationId, reqVO.getWorkstationId())
.eqIfPresent(MesWmProductIssueDO::getWorkOrderId, reqVO.getWorkOrderId())
+ .eqIfPresent(MesWmProductIssueDO::getTaskId, reqVO.getTaskId())
.eqIfPresent(MesWmProductIssueDO::getStatus, reqVO.getStatus())
.betweenIfPresent(MesWmProductIssueDO::getIssueDate, reqVO.getIssueDate())
.orderByDesc(MesWmProductIssueDO::getId));
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnissue/MesWmReturnIssueMapper.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnissue/MesWmReturnIssueMapper.java
index f2d561b..1dab867 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnissue/MesWmReturnIssueMapper.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnissue/MesWmReturnIssueMapper.java
@@ -19,6 +19,7 @@
.likeIfPresent(MesWmReturnIssueDO::getName, reqVO.getName())
.eqIfPresent(MesWmReturnIssueDO::getWorkstationId, reqVO.getWorkstationId())
.eqIfPresent(MesWmReturnIssueDO::getWorkOrderId, reqVO.getWorkOrderId())
+ .eqIfPresent(MesWmReturnIssueDO::getTaskId, reqVO.getTaskId())
.eqIfPresent(MesWmReturnIssueDO::getType, reqVO.getType())
.orderByDesc(MesWmReturnIssueDO::getId));
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
index f89cf62..6b5c000 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -265,6 +265,13 @@
ErrorCode PRO_WORK_ORDER_PRODUCT_MISMATCH = new ErrorCode(1_040_502_005, "褰撳墠浜у搧鐗╂枡涓庣敓浜у伐鍗曚骇鍝佷笉涓�鑷�");
ErrorCode PRO_WORK_ORDER_BOM_NOT_EXISTS = new ErrorCode(1_040_502_100, "鐢熶骇宸ュ崟BOM涓嶅瓨鍦�");
+ // ========== MES 鐢熶骇绠$悊-鐢熶骇宸ュ崟鍙傛暟璁板綍锛�1-040-502-200锛� ==========
+ ErrorCode PRO_WORK_ORDER_PARAM_RECORD_NOT_EXISTS = new ErrorCode(1_040_502_200, "宸ュ崟鍙傛暟璁板綍涓嶅瓨鍦�");
+ ErrorCode PRO_WORK_ORDER_PARAM_RECORD_TEMPLATE_NO_DETAIL = new ErrorCode(1_040_502_201, "鍙傛暟妯℃澘娌℃湁鏄庣粏锛屾棤娉曞垱寤鸿褰�");
+ ErrorCode PRO_WORK_ORDER_PARAM_RECORD_DETAIL_NOT_IN_TEMPLATE = new ErrorCode(1_040_502_202, "鍙傛暟鏄庣粏涓嶅睘浜庢墍閫夋ā鏉�");
+ ErrorCode PRO_WORK_ORDER_PARAM_RECORD_REQUIRED_PARAM_MISSING = new ErrorCode(1_040_502_203, "蹇呭~鍙傛暟銆恵}銆戞湭濉啓");
+ ErrorCode PRO_WORK_ORDER_PARAM_RECORD_TEMPLATE_NOT_CHANGE = new ErrorCode(1_040_502_204, "涓嶅厑璁告洿鎹㈠弬鏁版ā鏉匡紝璇峰垹闄ゅ悗閲嶆柊鍒涘缓");
+
// ========== MES 鐢熶骇绠$悊-鐢熶骇浠诲姟锛�1-040-503-000锛� ==========
ErrorCode PRO_TASK_NOT_EXISTS = new ErrorCode(1_040_503_000, "鐢熶骇浠诲姟涓嶅瓨鍦�");
ErrorCode PRO_TASK_ALREADY_FINISHED = new ErrorCode(1_040_503_001, "鐢熶骇浠诲姟宸插畬鎴愭垨宸插彇娑堬紝涓嶈兘缁х画鎿嶄綔");
@@ -508,6 +515,7 @@
ErrorCode WM_PRODUCT_ISSUE_DETAIL_ITEM_MISMATCH = new ErrorCode(1_040_708_201, "鎷h揣鏄庣粏鐨勭墿鏂欎笌棰嗘枡鍗曡鐨勭墿鏂欎笉涓�鑷�");
ErrorCode WM_PRODUCT_ISSUE_DETAIL_LINE_NOT_MATCH = new ErrorCode(1_040_708_202, "鎷h揣鏄庣粏涓嶅睘浜庢寚瀹氱殑棰嗘枡鍑哄簱鍗�");
ErrorCode WM_PRODUCT_ISSUE_NO_DETAIL = new ErrorCode(1_040_708_203, "棰嗘枡鍑哄簱鍗曟病鏈夋嫞璐ф槑缁嗭紝鏃犳硶鎵ц棰嗗嚭");
+ ErrorCode WM_PRODUCT_ISSUE_TASK_NOT_EXISTS = new ErrorCode(1_040_708_204, "鐢熶骇浠诲姟涓嶅瓨鍦�");
// ========== MES 浠撳簱绠$悊-鐢熶骇鍏ュ簱鍗曪紙1-040-709-000锛� ==========
ErrorCode WM_PRODUCT_PRODUCE_NOT_EXISTS = new ErrorCode(1_040_709_000, "鐢熶骇鍏ュ簱鍗曚笉瀛樺湪");
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java
index 1102aef..9067574 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/item/MesMdItemServiceImpl.java
@@ -396,12 +396,13 @@
*/
private void syncItemToMdm(MesMdItemDO item, MesMdItemSaveReqVO saveReqVO) {
// 1. 鑾峰彇鐗╂枡绫诲瀷瀵瑰簲鐨� itemType
- Integer itemType = null;
+ Long itemType = null;
if (item.getItemTypeId() != null) {
MesMdItemTypeDO itemTypeDO = itemTypeService.getItemType(item.getItemTypeId());
if (itemTypeDO != null) {
// MES: ITEM=鐗╂枡, PRODUCT=浜у搧 -> MDM: 1=鍘熸枡, 2=鍗婃垚鍝�, 3=鎴愬搧, 4=杈呮枡
- itemType = convertMesItemTypeToMdm(itemTypeDO.getItemOrProduct(), itemTypeDO.getName());
+// itemType = convertMesItemTypeToMdm(itemTypeDO.getItemOrProduct(), itemTypeDO.getName());
+ itemType = itemTypeDO.getId();
}
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemService.java
index 0a58be5..9c9646b 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemService.java
@@ -30,7 +30,7 @@
* @return 鐗╂枡
*/
MesMdmItemDO validateItemExists(Long id);
-
+ MesMdmItemDO mesValidateItemExists(Long id);
/**
* 鏍¢獙鐗╂枡瀛樺湪涓斿惎鐢�
*
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemServiceImpl.java
index 913af25..78f787e 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/mdm/MesMdmItemServiceImpl.java
@@ -1,8 +1,11 @@
package cn.iocoder.yudao.module.mes.service.mdm;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
import cn.iocoder.yudao.module.mes.dal.mysql.mdm.MesMdmItemMapper;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import jakarta.annotation.Resource;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@@ -25,6 +28,8 @@
@Resource
private MesMdmItemMapper mesMdmItemMapper;
+ @Autowired
+ private MesMdItemService mesMdItemService;
@Override
public MesMdmItemDO getItem(Long id) {
@@ -41,6 +46,19 @@
}
@Override
+ public MesMdmItemDO mesValidateItemExists(Long itemId) {
+ MesMdItemDO mesItem = mesMdItemService.getItem(itemId);
+ if (mesItem == null) {
+ throw exception(MD_ITEM_NOT_EXISTS);
+ }
+ MesMdmItemDO item = mesMdmItemMapper.selectById(mesItem.getMdmItemId());
+ if (item == null) {
+ throw exception(MD_ITEM_NOT_EXISTS);
+ }
+ return item;
+ }
+
+ @Override
public MesMdmItemDO validateItemExistsAndEnable(Long id) {
MesMdmItemDO item = validateItemExists(id);
if (item.getStatus() != null && item.getStatus() == 1) {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
index 71f0852..d704d07 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
@@ -6,7 +6,6 @@
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO;
import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
@@ -20,7 +19,6 @@
import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper;
import cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
-import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProcessService;
import cn.iocoder.yudao.module.mes.service.pro.route.MesProRouteProductBomService;
import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
@@ -60,8 +58,6 @@
private MesProRouteProcessService routeProcessService;
@Resource
private MesProRouteProductBomService routeProductBomService;
- @Resource
- private MesMdWorkstationService workstationService;
@Resource
@Lazy // 閬垮厤寰幆渚濊禆
private MesProTaskService taskService;
@@ -205,6 +201,12 @@
MesWmProductProduceDO produce = productProduceService.generateProductProduce(feedback, false);
productProduceService.finishProductProduce(produce.getId());
updateTaskAndWorkOrderByFeedback(feedback);
+ } else {
+ // 4.3 闈炲叧閿伐搴忥細鍙洿鏂颁换鍔$殑宸茬敓浜ф暟閲忥紙宸ュ崟涓嶆洿鏂帮紝宸ュ崟鍙湅鍏抽敭宸ュ簭浜у嚭锛�
+ taskService.updateProducedQuantity(feedback.getTaskId(),
+ feedback.getFeedbackQuantity(),
+ ObjectUtil.defaultIfNull(feedback.getQualifiedQuantity(), BigDecimal.ZERO),
+ ObjectUtil.defaultIfNull(feedback.getUnqualifiedQuantity(), BigDecimal.ZERO));
}
// 5. 闈炲叧閿伐搴� / 鍏抽敭闈炶川妫�宸ュ簭锛氱洿鎺ュ畬鎴愶紙娓呴浂 uncheckQuantity 闃叉 !key+check 鐣欒剰鏁版嵁锛�
@@ -277,23 +279,30 @@
/**
* 鏍¢獙鎶ュ伐鍗曠殑涓氬姟鏁版嵁锛堝垱寤� & 淇敼鍏辩敤锛�
*
+ * <p>浠ョ敓浜т换鍔′负鏍稿績锛氬墠绔彧闇�浼� taskId锛寃orkOrderId銆乺outeId銆乸rocessId銆乮temId銆亀orkstationId
+ * 浠庝换鍔¤嚜鍔ㄥ~鍏咃紝鏃犻渶鍓嶇閲嶅浼犲叆銆�
+ *
* @param reqVO 鎶ュ伐璇锋眰
* @return 鍏宠仈鐨勭敓浜т换鍔�
*/
private MesProTaskDO validateFeedbackData(MesProFeedbackSaveReqVO reqVO) {
- // 1. 鏍¢獙宸ヤ綔绔欏瓨鍦�
- MesMdWorkstationDO workstation = workstationService.validateWorkstationExists(reqVO.getWorkstationId());
- if (ObjUtil.notEqual(workstation.getProcessId(), reqVO.getProcessId())) {
- throw exception(PRO_WORKSTATION_PROCESS_MISMATCH);
- }
+ // 1. 鏍¢獙浠诲姟瀛樺湪涓旀湭缁堟��
+ MesProTaskDO task = taskService.validateTaskNotFinished(reqVO.getTaskId());
- // 2.1 鏍¢獙宸ヨ壓璺嚎 + 宸ュ簭閰嶇疆鏈夋晥
+ // 2. 浠庝换鍔¤嚜鍔ㄥ~鍏呭叧鑱斿瓧娈碉紙鍓嶇鏃犻渶浼犲叆锛屽悗绔粺涓�浠庝换鍔¤幏鍙栵級
+ reqVO.setWorkOrderId(task.getWorkOrderId());
+ reqVO.setRouteId(task.getRouteId());
+ reqVO.setProcessId(task.getProcessId());
+ reqVO.setItemId(task.getItemId());
+ reqVO.setWorkstationId(task.getWorkstationId());
+
+ // 3. 鏍¢獙宸ヨ壓璺嚎 + 宸ュ簭閰嶇疆鏈夋晥
MesProRouteProcessDO routeProcess = routeProcessService.getRouteProcessByRouteIdAndProcessId(
- reqVO.getRouteId(), reqVO.getProcessId());
+ task.getRouteId(), task.getProcessId());
if (routeProcess == null) {
throw exception(PRO_FEEDBACK_ROUTE_PROCESS_INVALID);
}
- // 2.2 鏍¢獙鏁伴噺
+ // 4.1 鏍¢獙鏁伴噺
boolean checkFlag = Boolean.TRUE.equals(routeProcess.getCheckFlag());
if (checkFlag) {
// 闇�瑕佹楠岋細鍙渶濉姤宸ユ暟閲忥紝涓斿繀椤� > 0
@@ -310,33 +319,7 @@
}
}
- // 3. 鏍¢獙宸ュ崟宸茬‘璁�
- MesProWorkOrderDO workOrder = workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId());
- if (ObjUtil.notEqual(workOrder.getProductId(), reqVO.getItemId())) {
- throw exception(PRO_WORK_ORDER_PRODUCT_MISMATCH);
- }
-
- // 4. 鏍¢獙浠诲姟瀛樺湪涓旀湭缁堟�侊紙宸插畬鎴�/宸插彇娑堬級锛屽苟杩斿洖浠诲姟鐢ㄤ簬鍐椾綑 itemId
- MesProTaskDO task = taskService.validateTaskNotFinished(reqVO.getTaskId());
- validateTaskRelation(task, workstation, workOrder, reqVO);
return task;
- }
-
- private void validateTaskRelation(MesProTaskDO task, MesMdWorkstationDO workstation,
- MesProWorkOrderDO workOrder, MesProFeedbackSaveReqVO 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);
- }
- if (ObjUtil.notEqual(task.getRouteId(), reqVO.getRouteId())
- || ObjUtil.notEqual(task.getProcessId(), reqVO.getProcessId())) {
- throw exception(PRO_TASK_ROUTE_PROCESS_MISMATCH);
- }
- if (ObjUtil.notEqual(task.getItemId(), reqVO.getItemId())) {
- throw exception(PRO_TASK_ITEM_MISMATCH);
- }
}
@Override
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskIssueService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskIssueService.java
index 2c52261..e538395 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskIssueService.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskIssueService.java
@@ -69,4 +69,12 @@
*/
Long getTaskIssueCountByUnitMeasureId(Long unitMeasureId);
+ /**
+ * 鏍规嵁鏉ユ簮鍗曟嵁鍒犻櫎鎶曟枡璁板綍
+ *
+ * @param sourceDocType 鏉ユ簮鍗曟嵁绫诲瀷
+ * @param sourceDocId 鏉ユ簮鍗曟嵁缂栧彿
+ */
+ void deleteTaskIssueBySourceDoc(String sourceDocType, Long sourceDocId);
+
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskIssueServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskIssueServiceImpl.java
index 5104a79..70bb36a 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskIssueServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/task/MesProTaskIssueServiceImpl.java
@@ -88,6 +88,11 @@
return taskIssueMapper.selectCountByUnitMeasureId(unitMeasureId);
}
+ @Override
+ public void deleteTaskIssueBySourceDoc(String sourceDocType, Long sourceDocId) {
+ taskIssueMapper.deleteBySourceDoc(sourceDocType, sourceDocId);
+ }
+
private void validateTaskIssueExists(Long id) {
if (taskIssueMapper.selectById(id) == null) {
throw exception(PRO_TASK_ISSUE_NOT_EXISTS);
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderParamRecordService.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderParamRecordService.java
new file mode 100644
index 0000000..2e1962b
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderParamRecordService.java
@@ -0,0 +1,67 @@
+package cn.iocoder.yudao.module.mes.service.pro.workorder;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.paramrecord.MesProWorkOrderParamRecordPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.paramrecord.MesProWorkOrderParamRecordSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderParamRecordDO;
+import jakarta.validation.Valid;
+
+import java.util.List;
+
+/**
+ * MES 鐢熶骇宸ュ崟鍙傛暟璁板綍 Service 鎺ュ彛
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+public interface MesProWorkOrderParamRecordService {
+
+ /**
+ * 鍒涘缓宸ュ崟鍙傛暟璁板綍
+ *
+ * @param workOrderId 宸ュ崟缂栧彿
+ * @param createReqVO 鍒涘缓淇℃伅
+ * @return 璁板綍缂栧彿
+ */
+ Long createParamRecord(Long workOrderId, @Valid MesProWorkOrderParamRecordSaveReqVO createReqVO);
+
+ /**
+ * 鏇存柊宸ュ崟鍙傛暟璁板綍锛堜粎鏇存柊濉啓鍊硷紝涓嶆崲妯℃澘锛�
+ *
+ * @param updateReqVO 鏇存柊淇℃伅
+ */
+ void updateParamRecord(@Valid MesProWorkOrderParamRecordSaveReqVO updateReqVO);
+
+ /**
+ * 鍒犻櫎宸ュ崟鍙傛暟璁板綍
+ *
+ * @param id 璁板綍缂栧彿
+ */
+ void deleteParamRecord(Long id);
+
+ /**
+ * 鑾峰緱宸ュ崟鍙傛暟璁板綍
+ *
+ * @param id 璁板綍缂栧彿
+ * @return 鍙傛暟璁板綍
+ */
+ MesProWorkOrderParamRecordDO getParamRecord(Long id);
+
+ /**
+ * 鑾峰緱宸ュ崟鍙傛暟璁板綍鍒嗛〉
+ *
+ * @param workOrderId 宸ュ崟缂栧彿
+ * @param pageReqVO 鍒嗛〉鏌ヨ
+ * @return 鍙傛暟璁板綍鍒嗛〉
+ */
+ PageResult<MesProWorkOrderParamRecordDO> getParamRecordPageByWorkOrderId(Long taskId,
+ MesProWorkOrderParamRecordPageReqVO pageReqVO);
+
+ /**
+ * 鑾峰緱宸ュ崟鍙傛暟璁板綍鍒楄〃
+ *
+ * @param workOrderId 宸ュ崟缂栧彿
+ * @return 鍙傛暟璁板綍鍒楄〃
+ */
+ List<MesProWorkOrderParamRecordDO> getParamRecordListByWorkOrderId(Long workOrderId);
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderParamRecordServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderParamRecordServiceImpl.java
new file mode 100644
index 0000000..aff5d5a
--- /dev/null
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/workorder/MesProWorkOrderParamRecordServiceImpl.java
@@ -0,0 +1,204 @@
+package cn.iocoder.yudao.module.mes.service.pro.workorder;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.paramrecord.MesProWorkOrderParamRecordPageReqVO;
+import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.paramrecord.MesProWorkOrderParamRecordSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pd.processparamtemplate.MesPdProcessParamTemplateDetailDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pd.processparamtemplate.MesPdProcessParamTemplateDO;
+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.workorder.MesProWorkOrderParamRecordDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderParamRecordDetailDO;
+import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderParamRecordDetailMapper;
+import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderParamRecordMapper;
+import cn.iocoder.yudao.module.mes.service.pd.processparamtemplate.MesPdProcessParamTemplateService;
+import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskService;
+import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService;
+import jakarta.annotation.Resource;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
+
+/**
+ * MES 鐢熶骇宸ュ崟鍙傛暟璁板綍 Service 瀹炵幇绫�
+ *
+ * @author 鑺嬮亾婧愮爜
+ */
+@Service
+@Validated
+public class MesProWorkOrderParamRecordServiceImpl implements MesProWorkOrderParamRecordService {
+
+ @Resource
+ private MesProWorkOrderParamRecordMapper paramRecordMapper;
+ @Resource
+ private MesProWorkOrderParamRecordDetailMapper paramRecordDetailMapper;
+ @Resource
+ private MesProWorkOrderService workOrderService;
+ @Resource
+ private MesPdProcessParamTemplateService templateService;
+ @Autowired
+ private MesProTaskService mesProTaskService;
+ @Autowired
+ private MesProWorkOrderService mesProWorkOrderService;
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Long createParamRecord(Long taskId, MesProWorkOrderParamRecordSaveReqVO createReqVO) {
+ // 1. 鏍¢獙宸ュ崟瀛樺湪
+
+ // 2. 鏍¢獙妯℃澘瀛樺湪锛岃幏鍙栨ā鏉夸俊鎭� + 鏄庣粏鍒楄〃
+ MesPdProcessParamTemplateDO template = templateService.validateProcessParamTemplateExists(createReqVO.getTemplateId());
+ List<MesPdProcessParamTemplateDetailDO> templateDetails =
+ templateService.getProcessParamTemplateDetailListByTemplateId(createReqVO.getTemplateId());
+ if (CollUtil.isEmpty(templateDetails)) {
+ throw exception(PRO_WORK_ORDER_PARAM_RECORD_TEMPLATE_NO_DETAIL);
+ }
+
+ // 3. 鏋勫缓鏄庣粏 templateDetailId 鈫� templateDetail 鐨勬槧灏勶紝鐢ㄤ簬蹇収
+ Map<Long, MesPdProcessParamTemplateDetailDO> detailMap = templateDetails.stream()
+ .collect(Collectors.toMap(MesPdProcessParamTemplateDetailDO::getId, d -> d));
+
+ // 4. 鏍¢獙蹇呭~鍙傛暟閮芥湁鍊�
+ for (MesProWorkOrderParamRecordSaveReqVO.DetailItem item : createReqVO.getDetails()) {
+ MesPdProcessParamTemplateDetailDO templateDetail = detailMap.get(item.getTemplateDetailId());
+ if (templateDetail == null) {
+ throw exception(PRO_WORK_ORDER_PARAM_RECORD_DETAIL_NOT_IN_TEMPLATE);
+ }
+ if (Boolean.TRUE.equals(templateDetail.getRequired())
+ && (item.getParamValue() == null || item.getParamValue().isBlank())) {
+ throw exception(PRO_WORK_ORDER_PARAM_RECORD_REQUIRED_PARAM_MISSING, templateDetail.getParamName());
+ }
+ }
+ MesProTaskDO task = mesProTaskService.getTask(taskId);
+ MesProWorkOrderDO workOrder = mesProWorkOrderService.getWorkOrder(task.getWorkOrderId());
+ // 5. 鎻掑叆涓昏〃锛堝揩鐓фā鏉跨紪鐮併�佸悕绉帮級
+ MesProWorkOrderParamRecordDO record = MesProWorkOrderParamRecordDO.builder()
+ .workOrderId(workOrder.getId())
+ .taskId(taskId)
+ .templateId(template.getId())
+ .templateCode(template.getTemplateCode())
+ .templateName(template.getTemplateName())
+ .recordNo(createReqVO.getRecordNo())
+ .remark(createReqVO.getRemark())
+ .build();
+ paramRecordMapper.insert(record);
+
+ // 6. 鎻掑叆鏄庣粏琛紙蹇収鍙傛暟瀹氫箟 + 鐢ㄦ埛濉啓鍊硷級
+ List<MesProWorkOrderParamRecordDetailDO> detailDOs = createReqVO.getDetails().stream()
+ .map(item -> {
+ MesPdProcessParamTemplateDetailDO templateDetail = detailMap.get(item.getTemplateDetailId());
+ return MesProWorkOrderParamRecordDetailDO.builder()
+ .recordId(record.getId())
+ .templateDetailId(templateDetail.getId())
+ .paramCode(templateDetail.getParamCode())
+ .paramName(templateDetail.getParamName())
+ .paramType(templateDetail.getParamType())
+ .unitMeasureId(templateDetail.getUnitMeasureId())
+ .paramValue(item.getParamValue())
+ .build();
+ }).toList();
+ paramRecordDetailMapper.insertBatch(detailDOs);
+
+ return record.getId();
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void updateParamRecord(MesProWorkOrderParamRecordSaveReqVO updateReqVO) {
+ // 1. 鏍¢獙瀛樺湪
+ MesProWorkOrderParamRecordDO record = validateParamRecordExists(updateReqVO.getId());
+
+ // 2. 鏍¢獙妯℃澘鏈彉鏇达紙涓嶅厑璁告崲妯℃澘锛屽彧鑳戒慨鏀瑰~鍐欏�硷級
+ if (!record.getTemplateId().equals(updateReqVO.getTemplateId())) {
+ throw exception(PRO_WORK_ORDER_PARAM_RECORD_TEMPLATE_NOT_CHANGE);
+ }
+
+ // 3. 鑾峰彇妯℃澘鏄庣粏锛屾牎楠屽繀濉弬鏁�
+ List<MesPdProcessParamTemplateDetailDO> templateDetails =
+ templateService.getProcessParamTemplateDetailListByTemplateId(record.getTemplateId());
+ Map<Long, MesPdProcessParamTemplateDetailDO> detailMap = templateDetails.stream()
+ .collect(Collectors.toMap(MesPdProcessParamTemplateDetailDO::getId, d -> d));
+
+ for (MesProWorkOrderParamRecordSaveReqVO.DetailItem item : updateReqVO.getDetails()) {
+ MesPdProcessParamTemplateDetailDO templateDetail = detailMap.get(item.getTemplateDetailId());
+ if (templateDetail == null) {
+ throw exception(PRO_WORK_ORDER_PARAM_RECORD_DETAIL_NOT_IN_TEMPLATE);
+ }
+ if (Boolean.TRUE.equals(templateDetail.getRequired())
+ && (item.getParamValue() == null || item.getParamValue().isBlank())) {
+ throw exception(PRO_WORK_ORDER_PARAM_RECORD_REQUIRED_PARAM_MISSING, templateDetail.getParamName());
+ }
+ }
+
+ // 4. 鏇存柊涓昏〃
+ MesProWorkOrderParamRecordDO updateObj = new MesProWorkOrderParamRecordDO();
+ updateObj.setId(updateReqVO.getId());
+ updateObj.setRecordNo(updateReqVO.getRecordNo());
+ updateObj.setRemark(updateReqVO.getRemark());
+ paramRecordMapper.updateById(updateObj);
+
+ // 5. 鍒犻櫎鏃ф槑缁� + 鎻掑叆鏂版槑缁�
+ paramRecordDetailMapper.deleteByRecordId(record.getId());
+ List<MesProWorkOrderParamRecordDetailDO> detailDOs = updateReqVO.getDetails().stream()
+ .map(item -> {
+ MesPdProcessParamTemplateDetailDO templateDetail = detailMap.get(item.getTemplateDetailId());
+ return MesProWorkOrderParamRecordDetailDO.builder()
+ .recordId(record.getId())
+ .templateDetailId(templateDetail.getId())
+ .paramCode(templateDetail.getParamCode())
+ .paramName(templateDetail.getParamName())
+ .paramType(templateDetail.getParamType())
+ .unitMeasureId(templateDetail.getUnitMeasureId())
+ .paramValue(item.getParamValue())
+ .build();
+ }).toList();
+ paramRecordDetailMapper.insertBatch(detailDOs);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void deleteParamRecord(Long id) {
+ // 1. 鏍¢獙瀛樺湪
+ validateParamRecordExists(id);
+ // 2. 鍒犻櫎涓昏〃 + 鏄庣粏
+ paramRecordMapper.deleteById(id);
+ paramRecordDetailMapper.deleteByRecordId(id);
+ }
+
+ @Override
+ public MesProWorkOrderParamRecordDO getParamRecord(Long id) {
+ return paramRecordMapper.selectById(id);
+ }
+
+ @Override
+ public PageResult<MesProWorkOrderParamRecordDO> getParamRecordPageByWorkOrderId(Long taskId,
+ MesProWorkOrderParamRecordPageReqVO pageReqVO) {
+ return paramRecordMapper.selectPageByWorkOrderId(taskId, pageReqVO);
+ }
+
+ @Override
+ public List<MesProWorkOrderParamRecordDO> getParamRecordListByWorkOrderId(Long workOrderId) {
+ return paramRecordMapper.selectListByWorkOrderId(workOrderId);
+ }
+
+ // ==================== 鏍¢獙鏂规硶 ====================
+
+ private MesProWorkOrderParamRecordDO validateParamRecordExists(Long id) {
+ MesProWorkOrderParamRecordDO record = paramRecordMapper.selectById(id);
+ if (record == null) {
+ throw exception(PRO_WORK_ORDER_PARAM_RECORD_NOT_EXISTS);
+ }
+ return record;
+ }
+
+}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueLineServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueLineServiceImpl.java
index b264b98..4ed4684 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueLineServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueLineServiceImpl.java
@@ -114,7 +114,7 @@
// 鏍¢獙鐗╂枡鍦ㄥ伐鍗� BOM 涓�
validateItemInWorkOrderBom(reqVO.getIssueId(), reqVO.getItemId());
// 鏍¢獙鐗╂枡瀛樺湪
- mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
+ mdmItemService.mesValidateItemExists(reqVO.getItemId());
}
private void validateItemInWorkOrderBom(Long issueId, Long itemId) {
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
index b193252..0856972 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productissue/MesWmProductIssueServiceImpl.java
@@ -8,15 +8,22 @@
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.MesWmProductIssuePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.MesWmProductIssueSaveReqVO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueLineDO;
+import cn.iocoder.yudao.module.mes.dal.mysql.pro.task.MesProTaskIssueMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productissue.MesWmProductIssueMapper;
import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductIssueStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmStockReserveBizTypeEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
+import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
+import cn.iocoder.yudao.module.mes.service.pro.task.MesProTaskIssueService;
+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.wm.stockreserve.MesWmStockReserveService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.MesWmTransactionService;
@@ -35,6 +42,7 @@
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
+import java.util.Map;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
@@ -58,6 +66,14 @@
@Resource
private MesProWorkOrderService workOrderService;
@Resource
+ private MesProTaskService taskService;
+ @Resource
+ private MesProTaskIssueService taskIssueService;
+ @Resource
+ private MesProTaskIssueMapper taskIssueMapper;
+ @Resource
+ private MesMdItemService mdmItemService;
+ @Resource
private MesWmTransactionService wmTransactionService;
@Resource
private MesWmWarehouseService warehouseService;
@@ -74,7 +90,16 @@
// 1. 鏍¢獙鍏宠仈鏁版嵁
validateProductIssueSaveData(createReqVO);
- // 2. 鎻掑叆涓昏〃
+ // 2. 浠� task 鑷姩甯﹀叆 workOrderId 鍜� workstationId
+ MesProTaskDO task = taskService.validateTaskExists(createReqVO.getTaskId());
+ if (createReqVO.getWorkOrderId() == null) {
+ createReqVO.setWorkOrderId(task.getWorkOrderId());
+ }
+ if (createReqVO.getWorkstationId() == null) {
+ createReqVO.setWorkstationId(task.getWorkstationId());
+ }
+
+ // 3. 鎻掑叆涓昏〃
MesWmProductIssueDO issue = BeanUtils.toBean(createReqVO, MesWmProductIssueDO.class);
issue.setStatus(MesWmProductIssueStatusEnum.PREPARE.getStatus());
issueMapper.insert(issue);
@@ -89,7 +114,16 @@
// 1.2 鏍¢獙鍏宠仈鏁版嵁
validateProductIssueSaveData(updateReqVO);
- // 2. 鏇存柊涓昏〃
+ // 2. 浠� task 鑷姩甯﹀叆 workOrderId 鍜� workstationId
+ MesProTaskDO task = taskService.validateTaskExists(updateReqVO.getTaskId());
+ if (updateReqVO.getWorkOrderId() == null) {
+ updateReqVO.setWorkOrderId(task.getWorkOrderId());
+ }
+ if (updateReqVO.getWorkstationId() == null) {
+ updateReqVO.setWorkstationId(task.getWorkstationId());
+ }
+
+ // 3. 鏇存柊涓昏〃
MesWmProductIssueDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductIssueDO.class);
issueMapper.updateById(updateObj);
}
@@ -192,7 +226,10 @@
// 3. 閬嶅巻鎵�鏈夋槑缁嗭紝鍒涘缓搴撳瓨浜嬪姟锛堟墸鍑忓簱瀛� + 璁板綍娴佹按锛�
createTransactionList(issue);
- // 4. 鏇存柊鍑哄簱鍗曠姸鎬� + 棰嗘枡鏃ユ湡
+ // 4. 鑷姩鍒涘缓浠诲姟鎶曟枡璁板綍
+ createTaskIssueRecords(issue);
+
+ // 5. 鏇存柊鍑哄簱鍗曠姸鎬� + 棰嗘枡鏃ユ湡
issueMapper.updateById(new MesWmProductIssueDO()
.setId(id).setStatus(MesWmProductIssueStatusEnum.FINISHED.getStatus())
.setIssueDate(LocalDateTime.now()));
@@ -227,6 +264,64 @@
}
}
+ /**
+ * 棰嗘枡鍑哄簱瀹屾垚鏃讹紝鑷姩鍒涘缓浠诲姟鎶曟枡璁板綍
+ * 鎸夎閬嶅巻锛屾瘡琛屽垱寤轰竴鏉� task_issue 璁板綍
+ */
+ private void createTaskIssueRecords(MesWmProductIssueDO issue) {
+ List<MesWmProductIssueLineDO> lines = issueLineService.getProductIssueLineListByIssueId(issue.getId());
+ if (CollUtil.isEmpty(lines)) {
+ return;
+ }
+
+ // 鎵归噺鏌ヨ鐗╂枡淇℃伅锛堣幏鍙� unitMeasureId锛�
+ Map<Long, MesMdItemDO> itemMap = mdmItemService.getItemMap(
+ CollectionUtils.convertSet(lines, MesWmProductIssueLineDO::getItemId));
+
+ // 鑾峰彇鏄庣粏鍒楄〃锛岀敤浜庢彁鍙� batchCode
+ List<MesWmProductIssueDetailDO> details = issueDetailService.getProductIssueDetailListByIssueId(issue.getId());
+ Map<Long, List<MesWmProductIssueDetailDO>> detailMapByLineId = CollectionUtils.convertMultiMap(
+ details, MesWmProductIssueDetailDO::getLineId);
+
+ for (MesWmProductIssueLineDO line : lines) {
+ // 琛岀殑 taskId 浼樺厛锛屽惁鍒欏彇涓昏〃鐨� taskId
+ Long taskId = line.getTaskId() != null ? line.getTaskId() : issue.getTaskId();
+ if (taskId == null) {
+ continue;
+ }
+
+ // 鑾峰彇鐗╂枡鍗曚綅
+ MesMdItemDO item = itemMap.get(line.getItemId());
+ Long unitMeasureId = item != null ? item.getUnitMeasureId() : null;
+
+ // 鑾峰彇鎵规鍙凤細鍙栬琛岀涓�涓槑缁嗙殑 batchCode
+ String batchCode = null;
+ List<MesWmProductIssueDetailDO> lineDetails = detailMapByLineId.get(line.getId());
+ if (CollUtil.isNotEmpty(lineDetails)) {
+ MesWmProductIssueDetailDO firstDetail = lineDetails.get(0);
+ batchCode = firstDetail.getBatchCode();
+ }
+
+ // 鍒涘缓浠诲姟鎶曟枡璁板綍
+ MesProTaskIssueDO taskIssue = MesProTaskIssueDO.builder()
+ .taskId(taskId)
+ .workOrderId(issue.getWorkOrderId())
+ .workstationId(issue.getWorkstationId())
+ .sourceDocType("PRODUCT_ISSUE")
+ .sourceDocId(issue.getId())
+ .sourceLineId(line.getId())
+ .sourceDocCode(issue.getCode())
+ .batchCode(batchCode)
+ .itemId(line.getItemId())
+ .unitMeasureId(unitMeasureId)
+ .issuedQuantity(line.getQuantity())
+ .availableQuantity(line.getQuantity()) // 鍒濆鍏ㄥ彲鐢�
+ .usedQuantity(BigDecimal.ZERO)
+ .build();
+ taskIssueMapper.insert(taskIssue);
+ }
+ }
+
@Override
@Transactional(rollbackFor = Exception.class)
public void cancelProductIssue(Long id) {
@@ -241,6 +336,9 @@
// 閲婃斁搴撳瓨鍗犵敤
stockReserveService.releaseReserve(MesWmStockReserveBizTypeEnum.PRODUCT_ISSUE.getType(), id);
+
+ // 鍒犻櫎閫氳繃璇ラ鏂欏崟鍒涘缓鐨勪换鍔℃姇鏂欒褰�
+ taskIssueService.deleteTaskIssueBySourceDoc("PRODUCT_ISSUE", id);
// 鍙栨秷
issueMapper.updateById(new MesWmProductIssueDO()
@@ -300,7 +398,13 @@
*/
private void validateProductIssueSaveData(MesWmProductIssueSaveReqVO reqVO) {
validateCodeUnique(reqVO.getId(), reqVO.getCode());
- workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId());
+ // 鏍¢獙 task 瀛樺湪
+ MesProTaskDO task = taskService.validateTaskExists(reqVO.getTaskId());
+ // 鏍¢獙 task 鍏宠仈鐨勫伐鍗曞凡纭
+ Long workOrderId = reqVO.getWorkOrderId() != null ? reqVO.getWorkOrderId() : task.getWorkOrderId();
+ if (workOrderId != null) {
+ workOrderService.validateWorkOrderConfirmed(workOrderId);
+ }
if (reqVO.getWorkstationId() != null) {
workstationService.validateWorkstationExistsAndEnable(reqVO.getWorkstationId());
}
diff --git a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java
index 41d05d5..529c4df 100644
--- a/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java
+++ b/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java
@@ -10,9 +10,12 @@
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.MesWmReturnIssuePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.MesWmReturnIssueSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.mdm.MesMdmItemDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO;
+import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO;
+import cn.iocoder.yudao.module.mes.dal.mysql.pro.task.MesProTaskIssueMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnissue.MesWmReturnIssueMapper;
import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
@@ -20,6 +23,7 @@
import cn.iocoder.yudao.module.mes.enums.wm.MesWmTransactionTypeEnum;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService;
+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.wm.transaction.MesWmTransactionService;
import cn.iocoder.yudao.module.mes.service.wm.transaction.dto.MesWmTransactionSaveReqDTO;
@@ -61,6 +65,10 @@
@Resource
private MesProWorkOrderService workOrderService;
@Resource
+ private MesProTaskService taskService;
+ @Resource
+ private MesProTaskIssueMapper taskIssueMapper;
+ @Resource
private MesMdmItemService mdmItemService;
@Resource
private MesWmTransactionService wmTransactionService;
@@ -77,7 +85,16 @@
// 1. 鏍¢獙鍏宠仈鏁版嵁
validateReturnIssueSaveData(createReqVO);
- // 2. 鎻掑叆涓昏〃
+ // 2. 浠� task 鑷姩甯﹀叆 workOrderId 鍜� workstationId
+ MesProTaskDO task = taskService.validateTaskExists(createReqVO.getTaskId());
+ if (createReqVO.getWorkOrderId() == null) {
+ createReqVO.setWorkOrderId(task.getWorkOrderId());
+ }
+ if (createReqVO.getWorkstationId() == null) {
+ createReqVO.setWorkstationId(task.getWorkstationId());
+ }
+
+ // 3. 鎻掑叆涓昏〃
MesWmReturnIssueDO issue = BeanUtils.toBean(createReqVO, MesWmReturnIssueDO.class);
issue.setStatus(MesWmReturnIssueStatusEnum.PREPARE.getStatus());
issueMapper.insert(issue);
@@ -92,11 +109,20 @@
// 1.2 鏍¢獙鍏宠仈鏁版嵁
validateReturnIssueSaveData(updateReqVO);
- // 2. 鏇存柊涓昏〃
+ // 2. 浠� task 鑷姩甯﹀叆 workOrderId 鍜� workstationId
+ MesProTaskDO task = taskService.validateTaskExists(updateReqVO.getTaskId());
+ if (updateReqVO.getWorkOrderId() == null) {
+ updateReqVO.setWorkOrderId(task.getWorkOrderId());
+ }
+ if (updateReqVO.getWorkstationId() == null) {
+ updateReqVO.setWorkstationId(task.getWorkstationId());
+ }
+
+ // 3. 鏇存柊涓昏〃
MesWmReturnIssueDO updateObj = BeanUtils.toBean(updateReqVO, MesWmReturnIssueDO.class);
issueMapper.updateById(updateObj);
- // 3. 閫�鏂欑被鍨嬪彉鏇存椂锛屽埛鏂版墍鏈夎鐨勮川閲忕姸鎬�
+ // 4. 閫�鏂欑被鍨嬪彉鏇存椂锛屽埛鏂版墍鏈夎鐨勮川閲忕姸鎬�
if (ObjUtil.notEqual(oldIssue.getType(), updateReqVO.getType())) {
issueLineService.updateReturnIssueQualityStatusByIssueId(updateReqVO.getId(), updateReqVO.getType());
}
@@ -192,7 +218,10 @@
// 2. 閬嶅巻鎵�鏈夋槑缁嗭紝鍒涘缓搴撳瓨浜嬪姟锛堝鍔犲簱瀛� + 璁板綍娴佹按锛�
createTransactionList(issue);
- // 3. 鏇存柊閫�鏂欏崟鐘舵��
+ // 3. 鎵e噺浠诲姟鎶曟枡璁板綍鐨勫彲鐢ㄩ噺
+ updateTaskIssueOnReturn(issue);
+
+ // 4. 鏇存柊閫�鏂欏崟鐘舵��
issueMapper.updateById(new MesWmReturnIssueDO()
.setId(id).setStatus(MesWmReturnIssueStatusEnum.FINISHED.getStatus()));
}
@@ -224,6 +253,36 @@
.setBizType(MesBizTypeConstants.WM_RETURN_ISSUE).setBizId(issue.getId())
.setBizCode(issue.getCode()).setBizLineId(detail.getLineId())
.setRelatedTransactionId(outTransactionId)); // 鍏宠仈鍑哄簱浜嬪姟
+ }
+ }
+
+ /**
+ * 閫�鏂欏畬鎴愭椂锛屾墸鍑忎换鍔℃姇鏂欒褰曠殑鍙敤閲�
+ * 鎸夎閬嶅巻锛屾壘鍒板搴旂殑 task_issue 璁板綍锛屾墸鍑� availableQuantity銆乮ssuedQuantity
+ */
+ private void updateTaskIssueOnReturn(MesWmReturnIssueDO issue) {
+ List<MesWmReturnIssueLineDO> lines = issueLineService.getReturnIssueLineListByIssueId(issue.getId());
+ if (CollUtil.isEmpty(lines)) {
+ return;
+ }
+ for (MesWmReturnIssueLineDO line : lines) {
+ Long taskId = line.getTaskId() != null ? line.getTaskId() : issue.getTaskId();
+ if (taskId == null) {
+ continue;
+ }
+ // 鏌ユ壘璇� task + item + 鏉ユ簮涓洪鏂欏嚭搴撳崟 鐨勬姇鏂欒褰�
+ List<MesProTaskIssueDO> taskIssues = taskIssueMapper.selectListByTaskId(taskId);
+ MesProTaskIssueDO matchedIssue = CollUtil.findOne(taskIssues,
+ ti -> ti.getItemId().equals(line.getItemId())
+ && "PRODUCT_ISSUE".equals(ti.getSourceDocType()));
+ if (matchedIssue != null) {
+ // 鎵e噺鎶曟枡閲忓拰鍙敤閲�
+ BigDecimal newIssuedQty = matchedIssue.getIssuedQuantity().subtract(line.getQuantity());
+ BigDecimal newAvailableQty = matchedIssue.getAvailableQuantity().subtract(line.getQuantity());
+ matchedIssue.setIssuedQuantity(newIssuedQty.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : newIssuedQty);
+ matchedIssue.setAvailableQuantity(newAvailableQty.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : newAvailableQty);
+ taskIssueMapper.updateById(matchedIssue);
+ }
}
}
@@ -289,7 +348,13 @@
*/
private void validateReturnIssueSaveData(MesWmReturnIssueSaveReqVO reqVO) {
validateCodeUnique(reqVO.getId(), reqVO.getCode());
- workOrderService.validateWorkOrderConfirmed(reqVO.getWorkOrderId());
+ // 鏍¢獙 task 瀛樺湪
+ MesProTaskDO task = taskService.validateTaskExists(reqVO.getTaskId());
+ // 鏍¢獙 task 鍏宠仈鐨勫伐鍗曞凡纭
+ Long workOrderId = reqVO.getWorkOrderId() != null ? reqVO.getWorkOrderId() : task.getWorkOrderId();
+ if (workOrderId != null) {
+ workOrderService.validateWorkOrderConfirmed(workOrderId);
+ }
if (reqVO.getWorkstationId() != null) {
workstationService.validateWorkstationExistsAndEnable(reqVO.getWorkstationId());
}
--
Gitblit v1.9.3