feat(mes,crm): 新增质检单批量导入、检测结果台账与开票导入
从 dev_business 移植三块能力,并按英泽防锈分支的既有结构做适配,不改动原有逻辑。
MES 质检批量导入(IQC / IPQC / OQC)
- 各列表新增「下载导入模板」与「导入」两个接口,纯新增不做更新覆盖
- 逐行解析、部分成功:失败行进 failureList(含行号与可执行动作),整行留空自动跳过
- 编号留空自动生成;物料/供应商/客户按编码或名称精确匹配;质检方案留空按物料+检验类型自动匹配
- 本次导入内重复行与库内同业务键单据均拦截,提示含具体维度、双方实际值与下一步动作
- IQC 原样移植;IPQC 按批号模型重写(必填批号,去重键=物料+批号+检验类型+检测日期);
OQC 随本分支放宽(客户/出货数量/出货日期可空,客户留空时不校验客户数据权限)
MES 检测结果台账
- 跨 IQC / IPQC / OQC / RQC 统一分页查询与 Excel 导出,一行一个检测项
- 物料与计量单位解析改用 MdmItemApi / MdmUnitMeasureApi,与分支既有写法一致
- IPQC 批次号取批号(原为空),并同步 VO 描述
CRM 开票导入
- 开票列表新增模板下载与导入接口,合同编号匹配已审核合同并自动带入客户
- 同一合同下按「合同+发票号码」或「合同+金额+抬头+日期」判重
- CrmContractService 纯新增 getContractByNo;发票金额校验中的剩余额度计算抽为
getRemainingInvoicePrice 复用,行为等价
菜单与文档
- 新增三个 ID 自适应的幂等菜单脚本(按权限码反查父菜单与角色,可反复执行)
- 新增三份前端联调方案文档;同步更新 docs/project-business 业务可视化增量
Co-Authored-By: Claude Code <noreply@anthropic.com>
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # CRM å¼ç¥¨å¯¼å
¥ - å端èè°æ¹æ¡ |
| | | |
| | | > éæ±ï¼å¼ç¥¨ç®¡çå表å¢å ã导å
¥ãæé®ï¼ä½äºãæ°å¢å¼ç¥¨ç³è¯·ãä¸ã导åºãä¹é´ï¼ï¼ç¨äºææ¨¡æ¿æ¹é导å
¥å¼ç¥¨è®°å½ã |
| | | > åèå®ç°ï¼ååå表ç导å
¥å¼¹çªï¼`views/crm/contract/modules/import-form.vue`ï¼ï¼å¼ç¥¨å¯¼å
¥ä¸å
¶äº¤äºä¸è´ã |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - ä¿®æ¹ï¼`views/crm/invoice/index.vue`ï¼å¼ç¥¨å表工å
·æ ï¼ |
| | | - æ°å¢ï¼å¯¼å
¥å¼¹çªç»ä»¶ï¼å»ºè®® `views/crm/invoice/modules/import-form.vue`ï¼ |
| | | - ä¿®æ¹ï¼`src/api/crm/invoice/index.ts`ï¼æ°å¢ 2 个æ¥å£ï¼ |
| | | |
| | | ## ä¸å¡æµç¨ä¸æ°æ®å¸¦å
¥ |
| | | |
| | | 1. ååï¼å·²å®¡æ ¸éè¿ï¼-> å¼ç¥¨å¯¼å
¥ï¼æ¨¡æ¿ä¸å¡«åãååç¼å·ãï¼å端æç¼å·å¹é
ååï¼**客æ·èªå¨åååæå±å®¢æ·**ï¼æ é卿¨¡æ¿ä¸å¡«åå®¢æ· |
| | | 2. 导å
¥æå -> å¼ç¥¨åè¡¨ï¼æ°å¢çå¼ç¥¨ä¸ºãæªæäº¤ãç¶æï¼å¯å¨å表ä¸ç»§ç»ç¼è¾ãä¸ä¼ å票éä»¶ãæäº¤å®¡æ¹ |
| | | 3. 导å
¥çè´è´£äºº = å½åç»å½ç¨æ·ï¼ååå导å
¥ï¼ï¼å¯¼å
¥åå½åç¨æ·å³å¯å¨ãæè´è´£çãä¸çå° |
| | | |
| | | ## API |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | `/crm/invoice/get-import-template` | ä¸è½½å¯¼å
¥æ¨¡æ¿ï¼è¿å xls æä»¶æµï¼ | |
| | | | POST | `/crm/invoice/import` | 导å
¥å¼ç¥¨ï¼multipart ä¸ä¼ Excelï¼ | |
| | | |
| | | **æéç ï¼** 两个æ¥å£åè¦æ± `crm:invoice:import`ï¼æé®ç± `docs/sql/crm_invoice_import_menu.sql` èæ¬ææéç èªéåºå建ï¼è¥é管ç -> å¼ç¥¨ç®¡ç -> å¼ç¥¨å¯¼å
¥ï¼ç¶èåè·éå¼ç¥¨ç®¡çã导åºãæé®ãè§è²ææåæ ·è·éã导åºãæé®å·²æè§è²ï¼ã |
| | | |
| | | **请æ±åæ°ï¼POST /crm/invoice/importï¼ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | file | MultipartFile | æ¯ | ä»
æ¯æ xlsãxlsx | |
| | | |
| | | **模æ¿åï¼ä¸è½½ç模æ¿å·²å«è¡¨å¤´ä¸ä¸è¡ç¤ºä¾ï¼ï¼** |
| | | |
| | | | åå | å¿
å¡« | 说æ | |
| | | |------|------|------| |
| | | | å¼ç¥¨ç¼å· | å¦ | ç空åç³»ç»èªå¨çæï¼KP+æ¥æ+6ä½åºå·ï¼ï¼å¡«åæ¶ä¸å¯ä¸ç³»ç»ä¸å·²æå¼ç¥¨ç¼å·éå¤ | |
| | | | ååç¼å· | æ¯ | éä¸ç³»ç»ä¸**å·²å®¡æ ¸éè¿**çååç¼å·ä¸è´ï¼å®¢æ·ç±ååèªå¨å¸¦å
¥ | |
| | | | å票类å | æ¯ | å¡«ååå
¸ `crm_invoice_type` çåç§°ï¼å¢å¼ç¨ä¸ç¨å票 / å¢å¼ç¨æ®éå票 / çµåå票 | |
| | | | å票å·ç | å¦ | å票票é¢å·ç | |
| | | | å票æ¬å¤´ | å¦ | å票æ¬å¤´ | |
| | | | å¼ç¥¨éé¢(å
) | æ¯ | éå¤§äº 0ï¼ä¸ä¸è¶
è¿è¯¥ååå©ä½å¯å¼ç¥¨éé¢ | |
| | | | å¼ç¥¨æ¥æ | å¦ | æ ¼å¼ `2026-01-01 10:00:00` æ `2026-01-01`ï¼ç空åå½åæ¶é´ | |
| | | | 夿³¨ | å¦ | 夿³¨ | |
| | | |
| | | **ååºï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "createList": ["KP20260924000001", "KP20260924000002"], |
| | | "failureList": { |
| | | "第 4 è¡": "ååç¼å·ä¸åå¨ï¼HT9999ã请å
å¨ãCRM åå管çãä¸å建æå¯¼å
¥è¯¥ååï¼ç¼å·é䏿¨¡æ¿å®å
¨ä¸è´ï¼ï¼æä¿®æ¹æ¨¡æ¿ä¸çååç¼å·å鿰坼å
¥" |
| | | } |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | createList | String[] | 导å
¥æåçå¼ç¥¨ç¼å·æ°ç» | |
| | | | failureList | Map | 导å
¥å¤±è´¥éåï¼key 为ãå票å·ç xxxãæã第 N è¡ãï¼N 为 Excel è¡å·ï¼å«è¡¨å¤´ï¼ï¼value 为失败åå | |
| | | |
| | | ## åæ®µå±ç¤ºè§å |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | 导å
¥æé® | å¼ç¥¨å表工å
·æ | ä½ç½®å¨ãæ°å¢å¼ç¥¨ç³è¯·ãä¸ã导åºãä¹é´ï¼æéç `crm:invoice:import` | |
| | | | ä¸è½½å¯¼å
¥æ¨¡æ¿æé® | 导å
¥å¼¹çªå·¦ä¸è§ | ååå导å
¥å¼¹çªç `prepend-footer` ä½ç½® | |
| | | | æ°å¢æ¡æ° | 导å
¥å¼¹çªç»æåº | å `createList.length`ï¼ææ¡å¦ãæ°å¢ï¼N æ¡ã | |
| | | | 失败æç» | 导å
¥å¼¹çªç»æåº | éå `failureList`ï¼éæ¡å±ç¤ºãkeyï¼valueãï¼å¯æ»å¨ | |
| | | | 导å
¥æ¨¡æ¿è¯´æ | 导å
¥å¼¹çªå
ç°è²æç¤ºåº | å¿
å¡«åï¼ååç¼å·ãå票类åãå¼ç¥¨éé¢ï¼ååå¿
须为ãå®¡æ ¸éè¿ãï¼è´è´£äºº = å½åç»å½ç¨æ·ï¼ç¶æä¸ºãæªæäº¤ã | |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | ååç¶æ | åªæãå®¡æ ¸éè¿ãçååæè½å¯¼å
¥å¼ç¥¨ï¼æªæäº¤/审æ¹ä¸/ä¸éè¿çåå该è¡å¯¼å
¥å¤±è´¥ | |
| | | | å¼ç¥¨éé¢ä¸é | åè¡éé¢ä¸å¾è¶
è¿ãååéé¢ â å·²å¼ç¥¨ï¼å®¡æ¹ä¸ + å®¡æ ¸éè¿ï¼ãçå©ä½é¢åº¦ï¼è¶
åºå该è¡å¤±è´¥ï¼æç¤ºä¸ç»åºå©ä½é¢åº¦ä¸æ¬æ¬¡éé¢ | |
| | | | éå¤ç¼å· | 模æ¿ä¸å¡«åçå¼ç¥¨ç¼å·å¨ç³»ç»ä¸å·²å卿¶è¯¥è¡å¤±è´¥ | |
| | | | éå¤å¯¼å
¥æ¦æª | åä¸ååä¸ï¼å¡«äºãå票å·ç ãæ¶æãåå + å票å·ç ãå¤éï¼æªå¡«å票å·ç æ¶æãåå + å¼ç¥¨éé¢ + å票æ¬å¤´ + å¼ç¥¨æ¥æãå¤éï¼å¼ç¥¨æ¥æç空å䏿¯è¾è¯¥ç»´åº¦ï¼ãå䏿件å
éå¤ãæä¸ç³»ç»å
å·²æå¼ç¥¨éå¤é½ä¼å¤±è´¥å¹¶æåºéå¤çåå· | |
| | | | é¨åæå | éè¡å¯¼å
¥ï¼å¤±è´¥è¡ä¸å½±åæåè¡ï¼å䏿件å
ä¸ä¼æ´ä½åæ»ï¼ | |
| | | | æ°æ®æé | 导å
¥çå¼ç¥¨è´è´£äºº = å½åç»å½ç¨æ·ï¼èªå¨åå»ºæ°æ®æéï¼æ éå端å¤ç | |
| | | | ä¸ãæ°å»ºå¼ç¥¨ç³è¯·ãçå·®å¼ | 导å
¥ä¸äº§çéä»¶ï¼å¯¼å
¥çå¼ç¥¨é»è®¤ãæªæäº¤ãï¼éå¨å表ä¸ç¼è¾ä¸ä¼ å票éä»¶ååæäº¤å®¡æ¹ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - 模æ¿ãå票类åãå¡«**åç§°**ï¼å¦ å¢å¼ç¨ä¸ç¨å票ï¼ï¼ä¹å
¼å®¹å¡«æ°åï¼1/2/3ï¼ï¼å¡«éæ¶å¤±è´¥åå ä¼ååºå¯é项 |
| | | - 导å
¥å¼¹çªçè¿åº¦æ¡/ç»æåºäº¤äºå¯ç´æ¥å¤ç¨åå导å
¥çå®ç°ï¼`import-form.vue`ï¼ |
| | | - å端æé®ç `auth` éä½¿ç¨æ°çæéç `crm:invoice:import`ï¼æ§è¡ `docs/sql/crm_invoice_import_menu.sql` åéæ°ç»å½ä»¥å·æ°èå䏿éç¼åï¼èªå»ºè§è²è¥ä¸å¨å¼ç¥¨ç®¡çã导åºãæé®çææèå´å
ï¼éå¨ãè§è²ç®¡çãä¸å¦è¡å¾éãå¼ç¥¨å¯¼å
¥ã |
| | | - 空è¡ä¼è¢«èªå¨è·³è¿ï¼ä¸ç®å¤±è´¥ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # MES è´¨æ£åæ¹é导å
¥ - å端èè°æ¹æ¡ |
| | | |
| | | > éæ±ï¼æ¥ææ£éªï¼IQCï¼ãè¿ç¨æ£éªï¼IPQCï¼ãåºè´§æ£éªï¼OQCï¼ä¸ä¸ªå表åå¢å ãæ¹é导å
¥ãæé®ï¼ä½ç½®å¨ãæ°å¢ãä¸ã导åºãä¹é´ï¼ç¨äºææ¨¡æ¿æ¹é导å
¥æ£éªåã |
| | | > åèå®ç°ï¼ç°æå模å导å
¥å¼¹çªï¼å¦ `views/mes/md/item/modules/import-form.vue`ã`views/crm/contract/modules/import-form.vue`ï¼ï¼äº¤äºä¸ç»æåºå±ç¤ºå¯ç´æ¥æ²¿ç¨ã |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - ä¿®æ¹ï¼`views/mes/qc/iqc/index.vue`ï¼æ¥ææ£éªåå表工å
·æ + 导å
¥å¼¹çªï¼ |
| | | - ä¿®æ¹ï¼`views/mes/qc/ipqc/index.vue`ï¼è¿ç¨æ£éªåå表工å
·æ + 导å
¥å¼¹çªï¼ |
| | | - ä¿®æ¹ï¼`views/mes/qc/oqc/index.vue`ï¼åºè´§æ£éªåå表工å
·æ + 导å
¥å¼¹çªï¼ |
| | | - æ°å¢ï¼ä¸ä¸ªå¯¼å
¥å¼¹çªç»ä»¶ï¼å»ºè®® `views/mes/qc/{iqc|ipqc|oqc}/modules/import-form.vue`ï¼ |
| | | - ä¿®æ¹ï¼`src/api/mes/qc/{iqc|ipqc|oqc}/index.ts`ï¼åæ°å¢ 2 个æ¥å£ï¼ |
| | | |
| | | ## ä¸å¡æµç¨ä¸æ°æ®å¸¦å
¥ |
| | | |
| | | 1. ä¸è½½æ¨¡æ¿ -> å¡«å -> 导å
¥ï¼**ä¸è¡ = ä¸å¼ æ£éªå**ãç©æãä¾åºå/客æ·ãè´¨æ£æ¹æ¡åæãç¼ç / åç§°ãå¹é
ç³»ç»ä¸å·²ææ°æ®ï¼æ éå¡«å ID |
| | | 2. 产åç©æ -> è¿ç¨æ£éªåï¼IPQCï¼ï¼æ¨¡æ¿å¡«åã产åç©æç¼ç ã+ãæ¹å·ãï¼äºè
齿¯å¿
å¡«ï¼è¿ç¨æ£éªåæ **ç©æ + æ¹å·** è®°å½ï¼**模æ¿ä¸å¡«å·¥å / å·¥ä½ / å·¥åº** |
| | | 3. è´¨æ£æ¹æ¡ -> æ£éªè¡ï¼å¯¼å
¥æååç±å端æç©æ + æ£éªç±»åå¹é
è´¨æ£æ¹æ¡ï¼å¹¶èªå¨çææ£éªè¡ï¼æ£éªææ ï¼ï¼å端æ éé¢å¤è°ç¨ |
| | | 4. 导å
¥æå -> åè¡¨ï¼æ°å¢åæ®ç¶æä¸ºãå¾
æ£éªãï¼è稿ï¼ï¼å¯å¨å表ä¸ç¼è¾ãå½å
¥æ£æµç»æã宿æ£éª |
| | | 5. æ£æµäººåç空 = å½åç»å½ç¨æ·ï¼å¡«åæ¶æå§åå¹é
ç³»ç»ç¨æ· |
| | | |
| | | ## API |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | `/mes/qc/iqc/get-import-template` | ä¸è½½æ¥ææ£éªå导å
¥æ¨¡æ¿ï¼è¿å xls æä»¶æµï¼ | |
| | | | POST | `/mes/qc/iqc/import` | 导å
¥æ¥ææ£éªåï¼multipart ä¸ä¼ Excelï¼ | |
| | | | GET | `/mes/qc/ipqc/get-import-template` | ä¸è½½è¿ç¨æ£éªå导å
¥æ¨¡æ¿ï¼è¿å xls æä»¶æµï¼ | |
| | | | POST | `/mes/qc/ipqc/import` | 导å
¥è¿ç¨æ£éªåï¼multipart ä¸ä¼ Excelï¼ | |
| | | | GET | `/mes/qc/oqc/get-import-template` | ä¸è½½åºè´§æ£éªå导å
¥æ¨¡æ¿ï¼è¿å xls æä»¶æµï¼ | |
| | | | POST | `/mes/qc/oqc/import` | 导å
¥åºè´§æ£éªåï¼multipart ä¸ä¼ Excelï¼ | |
| | | |
| | | **æéç ï¼** `mes:qc-iqc:import` / `mes:qc-ipqc:import` / `mes:qc-oqc:import`ï¼èå䏿é®ç± `docs/sql/mes_qc_import_menu.sql` èæ¬ææéç èªéåºå建ï¼å·²è·é忣éªåãæ¥è¯¢ãæé®çè§è²ææï¼èªå»ºè§è²éå¨ãè§è²ç®¡çãä¸å¾éå¯¹åºæé®ï¼ã |
| | | |
| | | **请æ±åæ°ï¼POST .../importï¼ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | file | MultipartFile | æ¯ | ä»
æ¯æ xlsãxlsxï¼æ `updateSupport` åæ°ï¼å¯¼å
¥ä¸º**纯æ°å¢**ï¼ä¸åæ´æ°è¦ç | |
| | | |
| | | **ååºï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "createList": ["IQC20260924000001", "IQC20260924000002"], |
| | | "failureList": { |
| | | "第 4 è¡": "ç©æä¸åå¨ï¼WL9999ã请å
å¨ãç©æç®¡çãä¸ç»´æ¤è¯¥ç©æï¼ç¼ç é䏿¨¡æ¿å®å
¨ä¸è´ï¼ï¼æä¿®æ¹æ¨¡æ¿ä¸ç产åç©æç¼ç å鿰坼å
¥" |
| | | } |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | createList | String[] | 导å
¥æåçæ£éªåç¼å·æ°ç»ï¼æ¨¡æ¿æªå¡«ç¼å·æ¶è¿åç³»ç»èªå¨çæçç¼å·ï¼å¯ç¨äºæç¤º/è·³è½¬ï¼ | |
| | | | failureList | Map | 导å
¥å¤±è´¥éåï¼key ä¸ºãæ£éªåç¼å· Xãæã第 N è¡ãï¼N 为 Excel è¡å·ï¼å«è¡¨å¤´è¡ï¼ï¼value 为失败åå | |
| | | |
| | | ## 模æ¿åï¼ä¸è½½ç模æ¿å·²å«è¡¨å¤´ä¸ä¸è¡ç¤ºä¾ï¼ |
| | | |
| | | ### æ¥ææ£éªåï¼IQCï¼ |
| | | |
| | | | åå | å¿
å¡« | 说æ | |
| | | |------|------|------| |
| | | | æ£éªåç¼å· | å¦ | ç空åç³»ç»èªå¨çæï¼å¡«åæ¶ä¸å¯ä¸ç³»ç»ä¸å·²æç¼å·éå¤ | |
| | | | æ£éªååç§° | æ¯ | æ£éªååç§° | |
| | | | 产åç©æç¼ç | æ¯ | éä¸ãç©æç®¡çãä¸çç©æç¼ç ä¸è´ | |
| | | | ä¾åºååç§° | å¦ | éä¸ãä¾åºå管çãä¸çåç§°ä¸è´ï¼ç空åè¯¥åæ ä¾åºå | |
| | | | ä¾åºåæ¹æ¬¡å· | å¦ | ä¾åºåæ¹æ¬¡å· | |
| | | | è´¨æ£æ¹æ¡ | å¦ | å¡«æ¹æ¡åç§°ï¼ç空åå端æç©æèªå¨å¹é
IQC æ¹æ¡ | |
| | | | æ¬æ¬¡æ¥æ¶æ°é | å¦ | ç空èªå¨ = åæ ¼åæ°é + ä¸åæ ¼åæ°éï¼å¡«ååå¿
é¡»ä¸ä¹ç¸ç | |
| | | | åæ ¼åæ°é | æ¯ | ä¸è½å°äº 0 | |
| | | | ä¸åæ ¼åæ°é | æ¯ | ä¸è½å°äº 0 | |
| | | | æ£æµç»æ | å¦ | åå
¸ `mes_qc_check_result` åç§°ï¼æ ¡éªéè¿ / æ ¡éªä¸éè¿ | |
| | | | æ£æµäººå | å¦ | ç¨æ·å§åï¼ç空åå½åç»å½ç¨æ· | |
| | | | æ£æµæ¥æ | æ¯ | æ ¼å¼ `2026-01-01 10:00:00` æ `2026-01-01` | |
| | | | æ¥ææ¥æ | æ¯ | æ ¼å¼ `2026-01-01 10:00:00` æ `2026-01-01` | |
| | | | 夿³¨ | å¦ | 夿³¨ | |
| | | |
| | | ### è¿ç¨æ£éªåï¼IPQCï¼ |
| | | |
| | | | åå | å¿
å¡« | 说æ | |
| | | |------|------|------| |
| | | | æ£éªåç¼å· | å¦ | ç空åç³»ç»èªå¨çæï¼å¡«åæ¶ä¸å¯éå¤ | |
| | | | æ£éªååç§° | æ¯ | æ£éªååç§° | |
| | | | æ£éªç±»å | æ¯ | åå
¸ `mes_ipqc_type` åç§°ï¼èªå¶å·¥åºæ£éª / 馿£ / å·¡æ£ / èªæ£ / æåæ£éª | |
| | | | 产åç©æç¼ç | æ¯ | éä¸ãç©æç®¡çãä¸çç©æç¼ç ä¸è´ï¼**æ¬åæ¯è¿ç¨æ£éªæãç©æ + æ¹å·ãè®°å½ï¼ä¸å¡«å·¥å/å·¥ä½** | |
| | | | æ¹å· | æ¯ | è¿ç¨æ£éªçæ¹å·ï¼æé¿ 100 å符 | |
| | | | è´¨æ£æ¹æ¡ | å¦ | å¡«æ¹æ¡åç§°ï¼ç空åå端æç©æèªå¨å¹é
IPQC æ¹æ¡ | |
| | | | æ£æµæ°é | å¦ | ç空èªå¨ = åæ ¼åæ°é + ä¸åæ ¼åæ°éï¼å¡«ååå¿
é¡»ä¸ä¹ç¸ç | |
| | | | åæ ¼åæ°é | æ¯ | ä¸è½å°äº 0 | |
| | | | ä¸åæ ¼åæ°é | æ¯ | ä¸è½å°äº 0 | |
| | | | å·¥åºæ°é | å¦ | ç空æ 0ï¼ä¸æåºãå
¶ä»åºåä¹åä¸å¾è¶
è¿ä¸åæ ¼åæ°é | |
| | | | æåºæ°é | å¦ | ç空æ 0 | |
| | | | å
¶ä»åºåæ°é | å¦ | ç空æ 0 | |
| | | | æ£æµç»æ | å¦ | åå
¸ `mes_qc_check_result` åç§° | |
| | | | æ£æµäººå | å¦ | ç¨æ·å§åï¼ç空åå½åç»å½ç¨æ· | |
| | | | æ£æµæ¥æ | å¦ | æ ¼å¼ `2026-01-01 10:00:00` æ `2026-01-01`ï¼ç空åä¸å¡« | |
| | | | 夿³¨ | å¦ | 夿³¨ | |
| | | |
| | | ### åºè´§æ£éªåï¼OQCï¼ |
| | | |
| | | | åå | å¿
å¡« | 说æ | |
| | | |------|------|------| |
| | | | æ£éªåç¼å· | å¦ | ç空åç³»ç»èªå¨çæï¼å¡«åæ¶ä¸å¯éå¤ | |
| | | | æ£éªååç§° | æ¯ | æ£éªååç§° | |
| | | | 产åç©æç¼ç | æ¯ | éä¸ãç©æç®¡çãä¸çç©æç¼ç ä¸è´ | |
| | | | 客æ·åç§° | å¦ | éä¸ãCRM 客æ·ç®¡çãä¸çåç§°ä¸è´ï¼ç空表示该åä¸å±äºä»»ä½å®¢æ·ã**å¡«åæ¶**å¿
é¡»å¨å½åç»å½ç¨æ·çå®¢æ·æ°æ®æéèå´å
| |
| | | | æ¹æ¬¡å· | å¦ | æ¹æ¬¡å· | |
| | | | è´¨æ£æ¹æ¡ | å¦ | å¡«æ¹æ¡åç§°ï¼ç空åå端æç©æèªå¨å¹é
OQC æ¹æ¡ | |
| | | | æ¬æ¬¡åºè´§æ°é | å¦ | å¡«åæ¶ä¸è½å°äº 0ï¼ç空表示æªå¡«å | |
| | | | æ£æµæ°é | å¦ | ç空èªå¨ = åæ ¼åæ°é + ä¸åæ ¼åæ°éï¼å¡«ååå¿
é¡»ä¸ä¹ç¸ç | |
| | | | åæ ¼åæ°é | æ¯ | ä¸è½å°äº 0 | |
| | | | ä¸åæ ¼åæ°é | æ¯ | ä¸è½å°äº 0 | |
| | | | æ£æµç»æ | å¦ | åå
¸ `mes_qc_check_result` åç§° | |
| | | | æ£æµäººå | å¦ | ç¨æ·å§åï¼ç空åå½åç»å½ç¨æ· | |
| | | | æ£æµæ¥æ | æ¯ | æ ¼å¼ `2026-01-01 10:00:00` æ `2026-01-01` | |
| | | | åºè´§æ¥æ | å¦ | æ ¼å¼ `2026-01-01 10:00:00` æ `2026-01-01`ï¼ç空表示æªå¡«å | |
| | | | 夿³¨ | å¦ | 夿³¨ | |
| | | |
| | | ## åæ®µå±ç¤ºè§å |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | æ¹é导å
¥æé® | ä¸ä¸ªå表工å
·æ | ä½ç½®å¨ãæ°å¢ãä¸ã导åºãä¹é´ï¼å³æ¸²æé¡ºåºï¼æ°å¢ -> æ¹é导å
¥ -> 导åºï¼ï¼æéç `mes:qc-{iqc|ipqc|oqc}:import` | |
| | | | ä¸è½½å¯¼å
¥æ¨¡æ¿æé® | 导å
¥å¼¹çªå
| åå
¶å®æ¨¡å导å
¥å¼¹çªçä½ç½®ï¼æ¨¡æ¿ä¸è½½æé®æ¾å¼¹çªå·¦ä¸è§ï¼ | |
| | | | æ°å¢æ¡æ° | 导å
¥å¼¹çªç»æåº | å `createList.length`ï¼ææ¡å¦ãæ°å¢ï¼N æ¡ã | |
| | | | 失败æç» | 导å
¥å¼¹çªç»æåº | éå `failureList`ï¼éæ¡å±ç¤ºãkeyï¼valueãï¼å¯æ»å¨ | |
| | | | 导å
¥è¯´æ | 导å
¥å¼¹çªå
ç°è²æç¤ºåº | æç¤ºå¿
å¡«åãæ°éå
³ç³»ï¼åæ ¼ + ä¸åæ ¼ = æ£æµ/æ¥æ¶æ°éï¼ãç¶æä¸ºãå¾
æ£éªããæ£æµäººåç空åå½åç»å½ç¨æ· | |
| | | | æç¤ºè¯è¡¥å
| 导å
¥å¼¹çªæåæç¤º | 导å
¥æåå建议æç¤ºãæ°å¢æ£éªå为ãå¾
æ£éªãç¶æï¼è¯·å¨å表ä¸ç¼è¾å¹¶å½å
¥æ£æµç»æã | |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | 导å
¥æ¹å¼ | 纯æ°å¢ï¼ä¸æ´æ°å·²ææ£éªåï¼`updateSupport` åæ°ä¸åå¨ | |
| | | | ç¼å·çæ | ãæ£éªåç¼å·ãç空ç±å端æç¼ç è§åèªå¨çæï¼IQC / IPQC / OQC åèªåç¼ï¼ï¼å¡«åæ¶ä¸ç³»ç»ä¸å·²æç¼å·éå¤å该è¡å¤±è´¥ | |
| | | | è´¨æ£æ¹æ¡å¹é
| ãè´¨æ£æ¹æ¡ãç空æ¶å端æç©æ + æ£éªç±»åèªå¨å¹é
ï¼è¥è¯¥ç©ææªé
置对åºç±»åçæ¹æ¡ï¼è¯¥è¡å¤±è´¥å¹¶æç¤ºéé
ç½®æ¹æ¡çç©æä¸å
¥å£ | |
| | | | æ°éå
³ç³» | åæ ¼åæ°é + ä¸åæ ¼åæ°é å¿
é¡»çäºãæ£æµæ°éãï¼IPQC/OQCï¼æãæ¬æ¬¡æ¥æ¶æ°éãï¼IQCï¼ï¼ç空æ¶èªå¨å两è
ä¹åï¼å¡«åä¸ç¸çæ¶è¯¥è¡å¤±è´¥å¹¶ç»åºä¸¤è¾¹çå®é
å¼ | |
| | | | IPQC åºåæ°é | å·¥åº + æåº + å
¶ä»åºå ä¹åä¸å¾è¶
è¿ä¸åæ ¼åæ°éï¼è¶
åºè¯¥è¡å¤±è´¥ï¼ä¸åçç©ºåæ 0 å¤ç | |
| | | | IPQC è®°å½ç»´åº¦ | 以ã产åç©æç¼ç + æ¹å·ãè¯å«ä¸æ¡è¿ç¨æ£éªè®°å½ï¼æ¹å·å¿
å¡« | |
| | | | ç¶æ | 导å
¥åçæ£éªåç»ä¸ä¸ºãå¾
æ£éªãï¼è稿ï¼ï¼ä¸ç´æ¥å®æ | |
| | | | æ£éªè¡çæ | ç±å端æå¹é
å°çè´¨æ£æ¹æ¡èªå¨çææ£éªè¡ï¼æ£éªææ ï¼ï¼æ éå端é¢å¤å¤ç | |
| | | | OQC å®¢æ·æ°æ®æé | ã客æ·åç§°ãå¡«åæ¶å¿
é¡»å¨å½åç»å½ç¨æ·çå¯è§å®¢æ·èå´å
ï¼å¦å该è¡å¤±è´¥ï¼å¦å导å
¥åå表ä¸ä¹çä¸å°è¯¥åï¼ï¼ç空å䏿 ¡éªï¼å¯¼å
¥åä¸åå®¢æ·æé鮿¡ | |
| | | | é¨åæå | éè¡å¯¼å
¥ï¼å¤±è´¥è¡ä¸å½±åæåè¡ï¼å䏿件å
ä¸ä¼æ´ä½åæ»ï¼ï¼å
¨é¨è¡ä¸ºç©ºæ¶è¿åç©ºç»æ | |
| | | | ç©ºè¡ | æ´è¡ä¸ºç©ºçè®°å½èªå¨è·³è¿ï¼ä¸è®°ä¸ºå¤±è´¥ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - ãæ£éªç±»åããæ£æµç»æãçåå
¸åå¡«**åç§°**ï¼å¦ 馿£ãæ ¡éªéè¿ï¼ï¼ä¹å
¼å®¹å¡«æ°åï¼1/2ï¼ï¼å¡«éæ¶å¤±è´¥åå ä¼ååºå¯éå¼ |
| | | - ãè´¨æ£æ¹æ¡ãåå¡«çæ¯**æ¹æ¡åç§°**ï¼ä¸æ¯æ¹æ¡ç¼ç ï¼ç空å³ä¸ºãèªå¨å¹é
ãï¼æ¯æ¨èç¨æ³ |
| | | - IPQC çãæ£éªç±»åãã产åç©æç¼ç ããæ¹å·ã齿¯**å¿
å¡«**åï¼ä¸æ¹æ¡çæ£éªç±»åé䏿£éªåçç±»åå¯å¹é
ï¼å¦åå¯è½æç¤ºæªé
ç½®æ¹æ¡ |
| | | - ãæ£æµäººåãç空åå½åç»å½ç¨æ·ï¼å¡«åå§åæ¶è¥åå¨ååç¨æ·ï¼ä¼åå¹é
å°çç¬¬ä¸æ¡ï¼å»ºè®®å¡«å§åå
¨ç§° |
| | | - ä¸ä¸ªå表ç导å
¥äºä¸å½±åï¼æéç åèªç¬ç«ï¼èªå»ºè§è²éå¨ãè§è²ç®¡çãä¸å¾é对åºçãXXæ£éªå¯¼å
¥ãæé®åæå¯è§è¯¥æé® |
| | | - 导å
¥å¼¹çªçè¿åº¦æ¡ / ç»æåº / 模æ¿ä¸è½½äº¤äºå¯ç´æ¥å¤ç¨ç°æ `import-form.vue` å®ç° |
| | | - æ¥æåæ¯æ `yyyy-MM-dd HH:mm:ss` ä¸ `yyyy-MM-dd` ä¸¤ç§æ ¼å¼ï¼IQC çæ£æµ/æ¥ææ¥æãOQC çæ£æµæ¥æä¸ºå¿
å¡«ï¼IPQC çæ£æµæ¥æãOQC çåºè´§æ¥æå¯ç空 |
| | |
| | | {"stage": "èå¨", "action": "审æ¹éè¿æå·¥åºæ è®°: åå²âèªå¨ç©ææ¶èæ£çº¿è¾¹åº(å
许è´åºå)ï¼è´¨æ£â产åºå¾
æ£è¡ç IPQCï¼å
³é®éæ£âç´æ¥äº§åºå
¥åº", "roles": ["ç³»ç»èªå¨"]}, |
| | | {"stage": "å®å·¥", "action": "ä»
æ«éå·¥åºååå·¥åå·²ç产æ°éï¼è¾¾æ èªå¨å®æï¼MPS ç´¯è®¡å¤æå®æå¹¶åäºä»¶ç»éå®è®¢å", "roles": ["ç³»ç»èªå¨"]}]}, |
| | | {"id": "quality", "name": "è´¨éæµç¨", "mermaid": "mermaid/05-quality-flow.mmd", "color": "#e06c6c", |
| | | "summary": "å鿣éªé¸å£(IQC/IPQC/OQC/RQCï¼äºæ 0â4) + å¤å®åæ(åæ ¼/ç¹é/éè´§/æ¥åº) + NCR è¯å®¡å¤ç½®å
³éï¼AI æä¾å¤å®å»ºè®®ï¼NCR å½åä»
å°è´¦ä¸è§¦åè¿å·¥åï¼æ£éªåå¯ç±æºè½è´¨æ£æ¥åå¹³å°ä¸é®åºä»¶ï¼generate-from-qcï¼æ°æ®ä» MES åï¼äºéæ ¡éªå渲æè½åºï¼ã", |
| | | "summary": "å鿣éªé¸å£(IQC/IPQC/OQC/RQCï¼äºæ 0â4) + å¤å®åæ(åæ ¼/ç¹é/éè´§/æ¥åº) + NCR è¯å®¡å¤ç½®å
³éï¼IQC/IPQC/OQC æ¯æ Excel æ¹é导å
¥(纯æ°å¢ãéè¡é¨åæåãæä¸å¡é®å»é)ï¼å¹¶æä¾è·¨åç±»çæ£æµç»æå°è´¦æ¥è¯¢ä¸å¯¼åºï¼AI æä¾å¤å®å»ºè®®ï¼NCR å½åä»
å°è´¦ä¸è§¦åè¿å·¥åï¼æ£éªåå¯ç±æºè½è´¨æ£æ¥åå¹³å°ä¸é®åºä»¶ï¼generate-from-qcï¼æ°æ®ä» MES åï¼äºéæ ¡éªå渲æè½åºï¼ã", |
| | | "steps": [ |
| | | {"stage": "æ¥æ", "action": "å°è´§éç¥/å¤åå
¥åºâIQCï¼ç»è®ºå忍è¿å¾
å
¥åºæè§¦åéè´§", "roles": ["IQC è´¨æ£å"]}, |
| | | {"stage": "è¿ç¨", "action": "æ¥å·¥è´¨æ£å·¥åºäº§åºè¡âIPQCï¼åæ ¼æè¡å
¥åºãä¸åæ ¼çæ NCR", "roles": ["IPQC è´¨æ£å"]}, |
| | | {"stage": "åºè´§", "action": "éå®åºåºæäº¤âOQCï¼å®æååºåºåè¿å
¥å¾
æ£è´§", "roles": ["OQC è´¨æ£å"]}, |
| | | {"stage": "éè´§", "action": "éæ/éå®éè´§/å®åéè´§âRQCï¼ç»è®ºåè°åæ®ä¸å®å", "roles": ["RQC è´¨æ£å"]}, |
| | | {"stage": "导å
¥", "action": "IQC/IPQC/OQC ä¸åè¡¨åæ¯æ Excel æ¹é导å
¥(æé®å¨ãæ°å¢ãä¸ã导åºãä¹é´ï¼çº¯æ°å¢ä¸åæ´æ°è¦ç)ï¼ä¸è¡ä¸å¼ åï¼ç¼å·ç空èªå¨çæï¼è´¨æ£æ¹æ¡ç空æç©æ+æ£éªç±»åèªå¨å¹é
ï¼æ£æµäººåç空åå½åç»å½ç¨æ·ï¼ç©æ/ä¾åºå/å®¢æ·æç¼ç æå称精确å¹é
(IQC ä¾åºåä¸ä¾åºåæ¹æ¬¡å¯ç空ãOQC 客æ·å¯ç空ä¸ç空ä¸åå®¢æ·æ°æ®æé鮿¡)ï¼åæ ¼+ä¸åæ ¼=æ£æµ/æ¥æ¶æ°éãIPQC å·¥åº+æåº+å
¶ä»åºåâ¤ä¸åæ ¼(ä¸åç空æ0)ï¼OQC å¡«å®¢æ·æ¶é¡»å¨æ¬äººå®¢æ·æ°æ®æéå
ï¼éè¡å¯¼å
¥é¨åæåï¼å¤±è´¥è¡è¿ failureList 带è¡å·ä¸å¯æ§è¡å¨ä½ï¼æååä¸å¾å¾
æ£éª0ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ï¼æä»¶å
éå¤è¡ä¸åºå
å·²åå¨åä¸å¡é®åæ®(IQC ç©æ+ä¾åºå+ä¾åºåæ¹æ¬¡+æ¥ææ¥æãIPQC ç©æ+æ¹å·+æ£éªç±»å+æ£æµæ¥æãOQC ç©æ+客æ·+æ¹æ¬¡å·+åºè´§æ¥æ)åæè¯¥è¡ï¼æç¤ºå«ç»´åº¦ãåæ¹å®é
å¼ä¸ãå
å é¤è¯¥åæ®åéè¯ãå¨ä½", "roles": ["è´¨æ£å", "IQC è´¨æ£å", "IPQC è´¨æ£å", "OQC è´¨æ£å"]}, |
| | | {"stage": "å°è´¦", "action": "æ£æµç»æå°è´¦ï¼è·¨ IQC/IPQC/OQC/RQC åç±»æ£éªåç»ä¸æ¥è¯¢(åç±»+æ£æµæ¥æåºé´+æ£éªåå·+ç©æ+æ¹æ¬¡å·+æ£æµç»æ+æ£æµäºº)ï¼ä¸è¡ä¸ä¸ªæ£æµé¡¹ç»æï¼å¤å®ä¾æ®ç±æ åå¼ä¸ä¸ä¸éæ¼è£
ï¼æ¹æ¬¡å·æç±»å忥æº(IQC åä¾åºåæ¹æ¬¡å·ï¼IPQC/OQC/RQC åæ¹å·)ï¼åå¥çéæ¡ä»¶ç´æ¥å¯¼åº Excel å°è´¦ç¨äºæå°åæ¡£ï¼æªå½æ£æµé¡¹çåä»ä¿çä¸è¡ä¸æ¼å", "roles": ["è´¨æ£å", "è´¨éå·¥ç¨å¸"]}, |
| | | {"stage": "ä¸åæ ¼", "action": "NCR: å¾
è¯å®¡âè¯å®¡âå¤ç½®(éè´§/æ¥åº/è¿å·¥/è®©æ¥æ¥æ¶/é级)âå
³é", "roles": ["è´¨éå·¥ç¨å¸"]}, |
| | | {"stage": "åºä»¶", "action": "两æ¡åºä»¶å
¥å£ï¼â éç¨ generate/preview(è°ç¨æ¹èªå¸¦ä¸ä¸æ) 渲æ HTML å¹¶å»ç»æ°æ®å¿«ç
§ï¼ç¼å· QR+æ¥æ+4使µæ°´æå¤©ç¬ç«ï¼preview åªæ¸²æä¸è½åºä¸æ¶èç¼å·ï¼regenerate ç¨å»ç»å¿«ç
§éæ¸²ä¸æ°æ®ä¸ç¼å·ä¸åå¹¶ä½åºå·²å½æ¡£ PDFï¼å¯¼åº PDF ç±åç«¯è° Chromium æå°å®ä¾å·²åç HTML å彿¡£éä»¶ä¸å¿ï¼â¡generate-from-qc ç±è´¨æ£åç´æ¥åºä»¶(æ°æ®ç» MesQcReportApi ä» MES åï¼åç«¯ä¸æ¼ä¸ä¸æ)ï¼åºä»¶åäºéæ ¡éªæä¸å¡ä¼å
çº§åªæ¥ç¬¬ä¸å¤ï¼ç±»åéæ³/åæ®ä¸åå¨/æªå®ææ£éª/æªå¡«å¤å®/模æ¿ç±»åä¸ç¬¦/æ å¯ç¨æ£éªé¡¹ï¼æ¥å头å¦å¸¦åæ®åå¤å® qcResult+qcResultText ä¸å¼æå¤å®å¹¶åï¼ååºå undecidableCount å¾
å¤å®é¡¹æ°ä¸ warnings(åç»æ é¢è·³è¿/ææ å·²å /æªå½å®æµå¼/æ ·åè¶
3)ï¼åä¸å¼ åæ®å¯åå¤åºå¤ä»½", "roles": ["è´¨æ£å"]}, |
| | | {"stage": "建模æ¿", "action": "AI 导å
¥ï¼ä¸ä¼ æ¢ææ£éªæ¥åæä»¶(æ«æä»¶/ç
§çãçµåç PDFãWord/Excel) â è¯å«ææ¨¡æ¿è稿(ä¸è½åº) â 人工å¨è®¾è®¡å¨ç¡®è®¤è°æ´åä¿åä¸ºçæ¬ï¼.doc/.xls æ§æ ¼å¼ä¸æ¯æ", "roles": ["è´¨æ£å", "è´¨éå·¥ç¨å¸"]}]}, |
| | |
| | | {"key": "crm", "name": "éå®ç®¡çï¼å®¢æ·å
³ç³»ï¼", "color": "#4f9cff", "tag": "CRM", "flow": "sales", |
| | | "positioning": "éå®å端ï¼ä»çº¿ç´¢å°å款ç客æ·ç»è¥", |
| | | "problem": "客æ·èµäº§æ²æ·ãåæºè½¬åãåå审æ¹ä¸å¼ç¥¨å款管æ§", |
| | | "features": ["线索转å客æ·", "å
¬æµ·æ± ä¸é¢åä¸é", "è系人", "åæºèªå®ä¹é¶æ®µ", "è·è¿è®°å½", "æ¥ä»·å(AI OCR)", "åå(BPM审æ¹âçæéå®è®¢å)", "å¼ç¥¨(BPM)â忬¾(å
å¼ç¥¨æ ¡éª)", "忬¾è®¡å", "éå®ç®æ ", "æ°æ®æéä¸çº§(è´è´£äºº/åªè¯»/读å)"], |
| | | "features": ["线索转å客æ·", "å
¬æµ·æ± ä¸é¢åä¸é", "è系人", "åæºèªå®ä¹é¶æ®µ", "è·è¿è®°å½", "æ¥ä»·å(AI OCR)", "åå(BPM审æ¹âçæéå®è®¢å)", "å¼ç¥¨(BPM审æ¹Â·æ¯æExcel导å
¥Â·ååååå票å·ç /åé颿¬å¤´æ¥æä¸å¯éå¤å¯¼å
¥)â忬¾(å
å¼ç¥¨æ ¡éª)", "忬¾è®¡å", "éå®ç®æ ", "æ°æ®æéä¸çº§(è´è´£äºº/åªè¯»/读å)"], |
| | | "objects": ["线索", "客æ·", "è系人", "åæº", "æ¥ä»·å", "åå", "å票", "忬¾", "éå®ç®æ "], |
| | | "roles": ["éå®å
å¤", "éå®ç»ç", "è´¢å¡(å¼ç¥¨å款)"], |
| | | "upstream": ["ä¸»æ°æ®(ç©æ)"], "downstream": ["è¿éå(éå®è®¢å)", "å®å(客æ·)", "AI(æ¥ä»·OCR)"], |
| | |
| | | {"name": "åæº", "module": "éå®ç®¡ç", "table": "crm_business", "doc": "é宿ºä¼ï¼DB é
ç½®å¼é¶æ®µæ¨è¿ï¼ç»ææ: èµ¢/è¾/æ æ", "upstream": ["客æ·"], "downstream": ["æ¥ä»·å", "åå"], "keywords": "åæº business èµ¢å è¾å é¶æ®µ"}, |
| | | {"name": "æ¥ä»·å", "module": "éå®ç®¡ç", "table": "crm_sale_quotation", "doc": "QTç¼å·ï¼é MDM ç©ææ¥ä»·ï¼AI OCR å½å
¥ï¼è稿â已转åå", "upstream": ["åæº"], "downstream": ["åå"], "keywords": "æ¥ä»· quotation QT"}, |
| | | {"name": "åå", "module": "éå®ç®¡ç", "table": "crm_contract", "doc": "HTç¼å·ï¼BPM 审æ¹(0è稿/10审æ¹ä¸/20éè¿/30驳å/40åæ¶/50ä½åº)ï¼éè¿åå¯çæéå®è®¢å", "upstream": ["æ¥ä»·å"], "downstream": ["éå®è®¢å", "忬¾è®¡å", "å¼ç¥¨"], "keywords": "åå contract 审æ¹"}, |
| | | {"name": "å票", "module": "éå®ç®¡ç", "table": "crm_invoice", "doc": "KPç¼å·ï¼BPM 审æ¹ï¼ç´¯è®¡å¼ç¥¨â¤ååé¢ï¼éä»¶å¿
ä¼ ", "upstream": ["åå"], "downstream": ["忬¾"], "keywords": "å¼ç¥¨ å票 invoice"}, |
| | | {"name": "å票", "module": "éå®ç®¡ç", "table": "crm_invoice", "doc": "KPç¼å·ï¼å¯ç空èªå¨çæãç³»ç»å
å¯ä¸ï¼ï¼BPM 审æ¹ï¼ç´¯è®¡å¼ç¥¨â¤ååé¢ï¼éä»¶å¿
ä¼ ï¼æ¯æ Excel 导å
¥ï¼çº¯æ°å¢ï¼ååé¡»å®¡æ ¸éè¿ä¸æ¬æ¬¡éé¢â¤ååå©ä½å¯å¼ç¥¨é¢ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ââåååä¸å票å·ç ç¸åãæå票å·ç ç空æ¶å¼ç¥¨éé¢+å票æ¬å¤´+å¼ç¥¨æ¥æç¸åå³å¤éå¤ï¼æä»¶å
éå¤è¡ä¸åºå
å·²æåé½æè¯¥è¡å¹¶åæ¾åæ¹å®é
å¼ï¼", "upstream": ["åå", "Excel 导å
¥"], "downstream": ["忬¾"], "keywords": "å¼ç¥¨ å票 invoice 导å
¥ å»é"}, |
| | | {"name": "忬¾", "module": "éå®ç®¡ç", "table": "crm_receivable", "doc": "HKç¼å·ï¼å建å³å®¡æ¹ä¸(æå¨å®¡æ ¸)ï¼å¼ºå¶å
å¼ç¥¨ï¼éé¢åæ ¡éª", "upstream": ["åå", "å票"], "downstream": ["æ¶æ¬¾å(å
³è)"], "keywords": "忬¾ æ¶æ¬¾è®¡å receivable"}, |
| | | {"name": "éå®ç®æ ", "module": "éå®ç®¡ç", "table": "crm_sales_target", "doc": "å¹´/å£/æÃ个人/é¨é¨/产å维度çåå忬¾çç®æ ", "upstream": [], "downstream": ["ä¸ç»©ç»è®¡"], "keywords": "ç®æ target ä¸ç»©"}, |
| | | {"name": "ä¾åºå", "module": "ä¾åºå管ç", "table": "srm_supplier", "doc": "ä¾åºåæ¡£æ¡ï¼æ§ç
§/ç¨å·/é¶è¡/è系人ï¼ERP ä¸ MES å
±ç¨", "upstream": ["åå
¥ç³è¯·"], "downstream": ["éè´è®¢å", "å°è´§éç¥", "ä¾åºåéè´§", "绩æè¯ä»·"], "keywords": "ä¾åºå supplier vendor"}, |
| | |
| | | {"name": "çç¹ä»»å¡", "module": "ä»å¨", "table": "mes_wm_stock_taking_task", "doc": "éæ/卿çç¹ï¼è¡ç»æ:æ£å¸¸/çç(ADJUST_IN)/çäº(ADJUST_OUT)ï¼å¯å»ç»åºåãç²ç", "upstream": ["åºåå°è´¦"], "downstream": ["åºåå°è´¦(è°æ´)"], "keywords": "çç¹ çç çäº stock taking"}, |
| | | {"name": "åºåå°è´¦", "module": "ä»å¨", "table": "mes_wm_material_stock", "doc": "ç©æÃä»åºÃåºåºÃåºä½Ãæ¹æ¬¡Ãä¾åºåå
å
ç»ï¼æ°é/å»ç»/å ç¨/å¨éåé", "upstream": ["å
¨é¨å
¥åºå"], "downstream": ["å
¨é¨åºåºå", "äºå¡æµæ°´"], "keywords": "åºå å°è´¦ stock å¯ç¨é"}, |
| | | {"name": "æ¹æ¬¡", "module": "ä»å¨", "table": "mes_wm_batch", "doc": "å
³èç©æ/å·¥å/ä¾åºå/客æ·/è´¨éç¶æï¼SN ç 嫿¹æ¬¡ uuidï¼æ¡ç æ¯æ18ç§ä¸å¡å¯¹è±¡", "upstream": ["å
¥åºåæ®"], "downstream": ["åºåå°è´¦"], "keywords": "æ¹æ¬¡ batch SN æ¡ç 追溯"}, |
| | | {"name": "IQCæ¥ææ£éª", "module": "è´¨é", "table": "mes_qc_iqc", "doc": "å°è´§éç¥/å¤åå
¥åºè§¦åï¼è稿0â宿4ï¼ç»è®ºå忥æºåæ®ï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§", "upstream": ["å°è´§éç¥", "å¤åå
¥åº"], "downstream": ["éè´å
¥åº", "ä¾åºåéè´§", "NCR", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "IQC æ¥ææ£éª åºæ¥å"}, |
| | | {"name": "IPQCè¿ç¨æ£éª", "module": "è´¨é", "table": "mes_qc_ipqc", "doc": "æ¥å·¥è´¨æ£å·¥åºäº§åºè¡è§¦åï¼å®æåè°æ¨è¿æ¥å·¥ä¸äº§åºå
¥åºï¼è¡¨ååªçãæ¥æºåæ® + 产åç©æ(å端æé MDM ç©æ) + æ¹å·(å¿
å¡«) + æ°é + æ£éªä¿¡æ¯ãï¼å·²å»ç产订å/ç产任å¡/å·¥ä½/å·¥åºï¼æ¹å·éæ¥åè½æ¬¾ï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§", "upstream": ["æ¥å·¥"], "downstream": ["产åºå
¥åº", "NCR", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "IPQC è¿ç¨æ£éª å·¡æ£ åºæ¥å æ¹å· batchCode MDMç©æ"}, |
| | | {"name": "OQCåºè´§æ£éª", "module": "è´¨é", "table": "mes_qc_oqc", "doc": "éå®åºåºæäº¤è§¦åï¼å®ææ¨è¿åºåºåå¾
æ£è´§ï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§", "upstream": ["éå®åºåºå"], "downstream": ["éå®åºåºå(æ¨è¿)", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "OQC åºè´§æ£éª åºåæ£éª åºæ¥å"}, |
| | | {"name": "IQCæ¥ææ£éª", "module": "è´¨é", "table": "mes_qc_iqc", "doc": "å°è´§éç¥/å¤åå
¥åºè§¦åï¼è稿0â宿4ï¼ç»è®ºå忥æºåæ®ï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§ï¼æ¯æ Excel æ¹é导å
¥ï¼å·¥å
·æ ãæ¹é导å
¥ãï¼çº¯æ°å¢ã导å
¥å为è稿å¾
æ£éªãç¼å·å¯ç空èªå¨çæãè´¨æ£æ¹æ¡ç空æç©æèªå¨å¹é
ï¼ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ï¼ç©æ+ä¾åºå+ä¾åºåæ¹æ¬¡+æ¥ææ¥æï¼æä»¶å
éå¤è¡ä¸åºå
å·²æåé½æè¯¥è¡å¹¶åæ¾åæ¹å®é
å¼ï¼", "upstream": ["å°è´§éç¥", "å¤åå
¥åº", "Excel æ¹é导å
¥"], "downstream": ["éè´å
¥åº", "ä¾åºåéè´§", "NCR", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "IQC æ¥ææ£éª åºæ¥å æ¹é导å
¥ 导å
¥æ¨¡æ¿"}, |
| | | {"name": "IPQCè¿ç¨æ£éª", "module": "è´¨é", "table": "mes_qc_ipqc", "doc": "æ¥å·¥è´¨æ£å·¥åºäº§åºè¡è§¦åï¼å®æåè°æ¨è¿æ¥å·¥ä¸äº§åºå
¥åºï¼è¡¨ååªçãæ¥æºåæ® + 产åç©æ(å端æé MDM ç©æ) + æ¹å·(å¿
å¡«) + æ°é + æ£éªä¿¡æ¯ãï¼å·²å»ç产订å/ç产任å¡/å·¥ä½/å·¥åºï¼æ¹å·éæ¥åè½æ¬¾ï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§ï¼æ¯æ Excel æ¹é导å
¥ï¼æ¨¡æ¿æã产åç©æç¼ç + æ¹å·(å¿
å¡«) + æ£éªç±»åãå¡«åï¼ä¸å¡«å·¥å/å·¥ä½ï¼å·¥åº+æåº+å
¶ä»åºåä¸å¾è¶
è¿ä¸åæ ¼åæ°éï¼ä¸åç空æ 0ï¼ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ï¼ç©æ+æ¹å·+æ£éªç±»å+æ£æµæ¥æï¼æä»¶å
éå¤è¡ä¸åºå
å·²æåé½æè¯¥è¡ï¼", "upstream": ["æ¥å·¥", "Excel æ¹é导å
¥"], "downstream": ["产åºå
¥åº", "NCR", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "IPQC è¿ç¨æ£éª å·¡æ£ åºæ¥å æ¹å· batchCode MDMç©æ æ¹é导å
¥ 导å
¥æ¨¡æ¿"}, |
| | | {"name": "OQCåºè´§æ£éª", "module": "è´¨é", "table": "mes_qc_oqc", "doc": "éå®åºåºæäº¤è§¦åï¼å®ææ¨è¿åºåºåå¾
æ£è´§ï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§ï¼æ¯æ Excel æ¹é导å
¥ï¼å®¢æ·åç§°/æ¬æ¬¡åºè´§æ°é/åºè´§æ¥æåå¯ç空ï¼ç空å³è¯¥åä¸å±ä»»ä½å®¢æ·ãä¸åå®¢æ·æ°æ®æé鮿¡ï¼å¡«å®¢æ·æ¶é¡»å¨æ¬äººå®¢æ·æ°æ®æéå
ï¼ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ï¼ç©æ+客æ·+æ¹æ¬¡å·+åºè´§æ¥æï¼æä»¶å
éå¤è¡ä¸åºå
å·²æåé½æè¯¥è¡ï¼", "upstream": ["éå®åºåºå", "Excel æ¹é导å
¥"], "downstream": ["éå®åºåºå(æ¨è¿)", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "OQC åºè´§æ£éª åºåæ£éª åºæ¥å æ¹é导å
¥ 导å
¥æ¨¡æ¿"}, |
| | | {"name": "RQCéè´§æ£éª", "module": "è´¨é", "table": "mes_qc_rqc", "doc": "ç产éæ/éå®éè´§/å®åé货触åï¼ç»è®ºåè°å®åï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§ãæªè¾å·²ç»ä¸ä¸ºãéè´§æ£éªãï¼åèåç¶é¡¹ä¸ mes_qc_type åå
¸åãéææ£éªãï¼ä¸å端æä¸¾/表注é/èåæéå项ä¸ä¸è´ï¼RQC ä¸è
é½è¦çï¼æ
åãéè´§æ£éªãï¼", "upstream": ["éæ", "éè´§"], "downstream": ["éè´§å
¥åº", "å®ååè°", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "RQC éè´§æ£éª éææ£éª åºæ¥å"}, |
| | | {"name": "NCRä¸åæ ¼å", "module": "è´¨é", "table": "mes_qc_ncr", "doc": "å¾
è¯å®¡0âå·²è¯å®¡6âå·²å¤ç½®7âå·²å
³é8ï¼å¤ç½®:éè´§/æ¥åº/è¿å·¥/è®©æ¥æ¥æ¶/é级", "upstream": ["IQC/IPQC/OQC/RQC"], "downstream": ["éè´§/æ¥åº/è¿å·¥(å°è´¦)"], "keywords": "NCR ä¸åæ ¼ å¤ç½® ç¹é æ¥åº"}, |
| | | {"name": "设å¤", "module": "设å¤", "table": "mes_dv_machinery", "doc": "å°è´¦ç¶æ:åæº/ç产ä¸/ä¿å
»ä¸ï¼ç¹æ£Â·ä¿å
»Â·ç»´ä¿®å·¥åï¼AI é£é©é¢æµæ¶è´¹å
¶æ°æ®", "upstream": [], "downstream": ["ç¹æ£", "ç»´ä¿®", "ç产é£é©é¢æµ"], "keywords": "è®¾å¤ ç¹æ£ ä¿å
» ç»´ä¿® machinery"}, |
| | |
| | | {"key": "crm", "name": "éå®ç®¡çï¼å®¢æ·å
³ç³»ï¼", "color": "#4f9cff", "tag": "CRM", "flow": "sales", |
| | | "positioning": "éå®å端ï¼ä»çº¿ç´¢å°å款ç客æ·ç»è¥", |
| | | "problem": "客æ·èµäº§æ²æ·ãåæºè½¬åãåå审æ¹ä¸å¼ç¥¨å款管æ§", |
| | | "features": ["线索转å客æ·", "å
¬æµ·æ± ä¸é¢åä¸é", "è系人", "åæºèªå®ä¹é¶æ®µ", "è·è¿è®°å½", "æ¥ä»·å(AI OCR)", "åå(BPM审æ¹âçæéå®è®¢å)", "å¼ç¥¨(BPM)â忬¾(å
å¼ç¥¨æ ¡éª)", "忬¾è®¡å", "éå®ç®æ ", "æ°æ®æéä¸çº§(è´è´£äºº/åªè¯»/读å)"], |
| | | "features": ["线索转å客æ·", "å
¬æµ·æ± ä¸é¢åä¸é", "è系人", "åæºèªå®ä¹é¶æ®µ", "è·è¿è®°å½", "æ¥ä»·å(AI OCR)", "åå(BPM审æ¹âçæéå®è®¢å)", "å¼ç¥¨(BPM审æ¹Â·æ¯æExcel导å
¥Â·ååååå票å·ç /åé颿¬å¤´æ¥æä¸å¯éå¤å¯¼å
¥)â忬¾(å
å¼ç¥¨æ ¡éª)", "忬¾è®¡å", "éå®ç®æ ", "æ°æ®æéä¸çº§(è´è´£äºº/åªè¯»/读å)"], |
| | | "objects": ["线索", "客æ·", "è系人", "åæº", "æ¥ä»·å", "åå", "å票", "忬¾", "éå®ç®æ "], |
| | | "roles": ["éå®å
å¤", "éå®ç»ç", "è´¢å¡(å¼ç¥¨å款)"], |
| | | "upstream": ["ä¸»æ°æ®(ç©æ)"], "downstream": ["è¿éå(éå®è®¢å)", "å®å(客æ·)", "AI(æ¥ä»·OCR)"], |
| | |
| | | {"name": "åæº", "module": "éå®ç®¡ç", "table": "crm_business", "doc": "é宿ºä¼ï¼DB é
ç½®å¼é¶æ®µæ¨è¿ï¼ç»ææ: èµ¢/è¾/æ æ", "upstream": ["客æ·"], "downstream": ["æ¥ä»·å", "åå"], "keywords": "åæº business èµ¢å è¾å é¶æ®µ"}, |
| | | {"name": "æ¥ä»·å", "module": "éå®ç®¡ç", "table": "crm_sale_quotation", "doc": "QTç¼å·ï¼é MDM ç©ææ¥ä»·ï¼AI OCR å½å
¥ï¼è稿â已转åå", "upstream": ["åæº"], "downstream": ["åå"], "keywords": "æ¥ä»· quotation QT"}, |
| | | {"name": "åå", "module": "éå®ç®¡ç", "table": "crm_contract", "doc": "HTç¼å·ï¼BPM 审æ¹(0è稿/10审æ¹ä¸/20éè¿/30驳å/40åæ¶/50ä½åº)ï¼éè¿åå¯çæéå®è®¢å", "upstream": ["æ¥ä»·å"], "downstream": ["éå®è®¢å", "忬¾è®¡å", "å¼ç¥¨"], "keywords": "åå contract 审æ¹"}, |
| | | {"name": "å票", "module": "éå®ç®¡ç", "table": "crm_invoice", "doc": "KPç¼å·ï¼BPM 审æ¹ï¼ç´¯è®¡å¼ç¥¨â¤ååé¢ï¼éä»¶å¿
ä¼ ", "upstream": ["åå"], "downstream": ["忬¾"], "keywords": "å¼ç¥¨ å票 invoice"}, |
| | | {"name": "å票", "module": "éå®ç®¡ç", "table": "crm_invoice", "doc": "KPç¼å·ï¼å¯ç空èªå¨çæãç³»ç»å
å¯ä¸ï¼ï¼BPM 审æ¹ï¼ç´¯è®¡å¼ç¥¨â¤ååé¢ï¼éä»¶å¿
ä¼ ï¼æ¯æ Excel 导å
¥ï¼çº¯æ°å¢ï¼ååé¡»å®¡æ ¸éè¿ä¸æ¬æ¬¡éé¢â¤ååå©ä½å¯å¼ç¥¨é¢ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ââåååä¸å票å·ç ç¸åãæå票å·ç ç空æ¶å¼ç¥¨éé¢+å票æ¬å¤´+å¼ç¥¨æ¥æç¸åå³å¤éå¤ï¼æä»¶å
éå¤è¡ä¸åºå
å·²æåé½æè¯¥è¡å¹¶åæ¾åæ¹å®é
å¼ï¼", "upstream": ["åå", "Excel 导å
¥"], "downstream": ["忬¾"], "keywords": "å¼ç¥¨ å票 invoice 导å
¥ å»é"}, |
| | | {"name": "忬¾", "module": "éå®ç®¡ç", "table": "crm_receivable", "doc": "HKç¼å·ï¼å建å³å®¡æ¹ä¸(æå¨å®¡æ ¸)ï¼å¼ºå¶å
å¼ç¥¨ï¼éé¢åæ ¡éª", "upstream": ["åå", "å票"], "downstream": ["æ¶æ¬¾å(å
³è)"], "keywords": "忬¾ æ¶æ¬¾è®¡å receivable"}, |
| | | {"name": "éå®ç®æ ", "module": "éå®ç®¡ç", "table": "crm_sales_target", "doc": "å¹´/å£/æÃ个人/é¨é¨/产å维度çåå忬¾çç®æ ", "upstream": [], "downstream": ["ä¸ç»©ç»è®¡"], "keywords": "ç®æ target ä¸ç»©"}, |
| | | {"name": "ä¾åºå", "module": "ä¾åºå管ç", "table": "srm_supplier", "doc": "ä¾åºåæ¡£æ¡ï¼æ§ç
§/ç¨å·/é¶è¡/è系人ï¼ERP ä¸ MES å
±ç¨", "upstream": ["åå
¥ç³è¯·"], "downstream": ["éè´è®¢å", "å°è´§éç¥", "ä¾åºåéè´§", "绩æè¯ä»·"], "keywords": "ä¾åºå supplier vendor"}, |
| | |
| | | {"name": "çç¹ä»»å¡", "module": "ä»å¨", "table": "mes_wm_stock_taking_task", "doc": "éæ/卿çç¹ï¼è¡ç»æ:æ£å¸¸/çç(ADJUST_IN)/çäº(ADJUST_OUT)ï¼å¯å»ç»åºåãç²ç", "upstream": ["åºåå°è´¦"], "downstream": ["åºåå°è´¦(è°æ´)"], "keywords": "çç¹ çç çäº stock taking"}, |
| | | {"name": "åºåå°è´¦", "module": "ä»å¨", "table": "mes_wm_material_stock", "doc": "ç©æÃä»åºÃåºåºÃåºä½Ãæ¹æ¬¡Ãä¾åºåå
å
ç»ï¼æ°é/å»ç»/å ç¨/å¨éåé", "upstream": ["å
¨é¨å
¥åºå"], "downstream": ["å
¨é¨åºåºå", "äºå¡æµæ°´"], "keywords": "åºå å°è´¦ stock å¯ç¨é"}, |
| | | {"name": "æ¹æ¬¡", "module": "ä»å¨", "table": "mes_wm_batch", "doc": "å
³èç©æ/å·¥å/ä¾åºå/客æ·/è´¨éç¶æï¼SN ç 嫿¹æ¬¡ uuidï¼æ¡ç æ¯æ18ç§ä¸å¡å¯¹è±¡", "upstream": ["å
¥åºåæ®"], "downstream": ["åºåå°è´¦"], "keywords": "æ¹æ¬¡ batch SN æ¡ç 追溯"}, |
| | | {"name": "IQCæ¥ææ£éª", "module": "è´¨é", "table": "mes_qc_iqc", "doc": "å°è´§éç¥/å¤åå
¥åºè§¦åï¼è稿0â宿4ï¼ç»è®ºå忥æºåæ®ï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§", "upstream": ["å°è´§éç¥", "å¤åå
¥åº"], "downstream": ["éè´å
¥åº", "ä¾åºåéè´§", "NCR", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "IQC æ¥ææ£éª åºæ¥å"}, |
| | | {"name": "IPQCè¿ç¨æ£éª", "module": "è´¨é", "table": "mes_qc_ipqc", "doc": "æ¥å·¥è´¨æ£å·¥åºäº§åºè¡è§¦åï¼å®æåè°æ¨è¿æ¥å·¥ä¸äº§åºå
¥åºï¼è¡¨ååªçãæ¥æºåæ® + 产åç©æ(å端æé MDM ç©æ) + æ¹å·(å¿
å¡«) + æ°é + æ£éªä¿¡æ¯ãï¼å·²å»ç产订å/ç产任å¡/å·¥ä½/å·¥åºï¼æ¹å·éæ¥åè½æ¬¾ï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§", "upstream": ["æ¥å·¥"], "downstream": ["产åºå
¥åº", "NCR", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "IPQC è¿ç¨æ£éª å·¡æ£ åºæ¥å æ¹å· batchCode MDMç©æ"}, |
| | | {"name": "OQCåºè´§æ£éª", "module": "è´¨é", "table": "mes_qc_oqc", "doc": "éå®åºåºæäº¤è§¦åï¼å®ææ¨è¿åºåºåå¾
æ£è´§ï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§", "upstream": ["éå®åºåºå"], "downstream": ["éå®åºåºå(æ¨è¿)", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "OQC åºè´§æ£éª åºåæ£éª åºæ¥å"}, |
| | | {"name": "IQCæ¥ææ£éª", "module": "è´¨é", "table": "mes_qc_iqc", "doc": "å°è´§éç¥/å¤åå
¥åºè§¦åï¼è稿0â宿4ï¼ç»è®ºå忥æºåæ®ï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§ï¼æ¯æ Excel æ¹é导å
¥ï¼å·¥å
·æ ãæ¹é导å
¥ãï¼çº¯æ°å¢ã导å
¥å为è稿å¾
æ£éªãç¼å·å¯ç空èªå¨çæãè´¨æ£æ¹æ¡ç空æç©æèªå¨å¹é
ï¼ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ï¼ç©æ+ä¾åºå+ä¾åºåæ¹æ¬¡+æ¥ææ¥æï¼æä»¶å
éå¤è¡ä¸åºå
å·²æåé½æè¯¥è¡å¹¶åæ¾åæ¹å®é
å¼ï¼", "upstream": ["å°è´§éç¥", "å¤åå
¥åº", "Excel æ¹é导å
¥"], "downstream": ["éè´å
¥åº", "ä¾åºåéè´§", "NCR", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "IQC æ¥ææ£éª åºæ¥å æ¹é导å
¥ 导å
¥æ¨¡æ¿"}, |
| | | {"name": "IPQCè¿ç¨æ£éª", "module": "è´¨é", "table": "mes_qc_ipqc", "doc": "æ¥å·¥è´¨æ£å·¥åºäº§åºè¡è§¦åï¼å®æåè°æ¨è¿æ¥å·¥ä¸äº§åºå
¥åºï¼è¡¨ååªçãæ¥æºåæ® + 产åç©æ(å端æé MDM ç©æ) + æ¹å·(å¿
å¡«) + æ°é + æ£éªä¿¡æ¯ãï¼å·²å»ç产订å/ç产任å¡/å·¥ä½/å·¥åºï¼æ¹å·éæ¥åè½æ¬¾ï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§ï¼æ¯æ Excel æ¹é导å
¥ï¼æ¨¡æ¿æã产åç©æç¼ç + æ¹å·(å¿
å¡«) + æ£éªç±»åãå¡«åï¼ä¸å¡«å·¥å/å·¥ä½ï¼å·¥åº+æåº+å
¶ä»åºåä¸å¾è¶
è¿ä¸åæ ¼åæ°éï¼ä¸åç空æ 0ï¼ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ï¼ç©æ+æ¹å·+æ£éªç±»å+æ£æµæ¥æï¼æä»¶å
éå¤è¡ä¸åºå
å·²æåé½æè¯¥è¡ï¼", "upstream": ["æ¥å·¥", "Excel æ¹é导å
¥"], "downstream": ["产åºå
¥åº", "NCR", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "IPQC è¿ç¨æ£éª å·¡æ£ åºæ¥å æ¹å· batchCode MDMç©æ æ¹é导å
¥ 导å
¥æ¨¡æ¿"}, |
| | | {"name": "OQCåºè´§æ£éª", "module": "è´¨é", "table": "mes_qc_oqc", "doc": "éå®åºåºæäº¤è§¦åï¼å®ææ¨è¿åºåºåå¾
æ£è´§ï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§ï¼æ¯æ Excel æ¹é导å
¥ï¼å®¢æ·åç§°/æ¬æ¬¡åºè´§æ°é/åºè´§æ¥æåå¯ç空ï¼ç空å³è¯¥åä¸å±ä»»ä½å®¢æ·ãä¸åå®¢æ·æ°æ®æé鮿¡ï¼å¡«å®¢æ·æ¶é¡»å¨æ¬äººå®¢æ·æ°æ®æéå
ï¼ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ï¼ç©æ+客æ·+æ¹æ¬¡å·+åºè´§æ¥æï¼æä»¶å
éå¤è¡ä¸åºå
å·²æåé½æè¯¥è¡ï¼", "upstream": ["éå®åºåºå", "Excel æ¹é导å
¥"], "downstream": ["éå®åºåºå(æ¨è¿)", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "OQC åºè´§æ£éª åºåæ£éª åºæ¥å æ¹é导å
¥ 导å
¥æ¨¡æ¿"}, |
| | | {"name": "RQCéè´§æ£éª", "module": "è´¨é", "table": "mes_qc_rqc", "doc": "ç产éæ/éå®éè´§/å®åé货触åï¼ç»è®ºåè°å®åï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§ãæªè¾å·²ç»ä¸ä¸ºãéè´§æ£éªãï¼åèåç¶é¡¹ä¸ mes_qc_type åå
¸åãéææ£éªãï¼ä¸å端æä¸¾/表注é/èåæéå项ä¸ä¸è´ï¼RQC ä¸è
é½è¦çï¼æ
åãéè´§æ£éªãï¼", "upstream": ["éæ", "éè´§"], "downstream": ["éè´§å
¥åº", "å®ååè°", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "RQC éè´§æ£éª éææ£éª åºæ¥å"}, |
| | | {"name": "NCRä¸åæ ¼å", "module": "è´¨é", "table": "mes_qc_ncr", "doc": "å¾
è¯å®¡0âå·²è¯å®¡6âå·²å¤ç½®7âå·²å
³é8ï¼å¤ç½®:éè´§/æ¥åº/è¿å·¥/è®©æ¥æ¥æ¶/é级", "upstream": ["IQC/IPQC/OQC/RQC"], "downstream": ["éè´§/æ¥åº/è¿å·¥(å°è´¦)"], "keywords": "NCR ä¸åæ ¼ å¤ç½® ç¹é æ¥åº"}, |
| | | {"name": "设å¤", "module": "设å¤", "table": "mes_dv_machinery", "doc": "å°è´¦ç¶æ:åæº/ç产ä¸/ä¿å
»ä¸ï¼ç¹æ£Â·ä¿å
»Â·ç»´ä¿®å·¥åï¼AI é£é©é¢æµæ¶è´¹å
¶æ°æ®", "upstream": [], "downstream": ["ç¹æ£", "ç»´ä¿®", "ç产é£é©é¢æµ"], "keywords": "è®¾å¤ ç¹æ£ ä¿å
» ç»´ä¿® machinery"}, |
| | |
| | | {"stage": "èå¨", "action": "审æ¹éè¿æå·¥åºæ è®°: åå²âèªå¨ç©ææ¶èæ£çº¿è¾¹åº(å
许è´åºå)ï¼è´¨æ£â产åºå¾
æ£è¡ç IPQCï¼å
³é®éæ£âç´æ¥äº§åºå
¥åº", "roles": ["ç³»ç»èªå¨"]}, |
| | | {"stage": "å®å·¥", "action": "ä»
æ«éå·¥åºååå·¥åå·²ç产æ°éï¼è¾¾æ èªå¨å®æï¼MPS ç´¯è®¡å¤æå®æå¹¶åäºä»¶ç»éå®è®¢å", "roles": ["ç³»ç»èªå¨"]}]}, |
| | | {"id": "quality", "name": "è´¨éæµç¨", "mermaid": "mermaid/05-quality-flow.mmd", "color": "#e06c6c", |
| | | "summary": "å鿣éªé¸å£(IQC/IPQC/OQC/RQCï¼äºæ 0â4) + å¤å®åæ(åæ ¼/ç¹é/éè´§/æ¥åº) + NCR è¯å®¡å¤ç½®å
³éï¼AI æä¾å¤å®å»ºè®®ï¼NCR å½åä»
å°è´¦ä¸è§¦åè¿å·¥åï¼æ£éªåå¯ç±æºè½è´¨æ£æ¥åå¹³å°ä¸é®åºä»¶ï¼generate-from-qcï¼æ°æ®ä» MES åï¼äºéæ ¡éªå渲æè½åºï¼ã", |
| | | "summary": "å鿣éªé¸å£(IQC/IPQC/OQC/RQCï¼äºæ 0â4) + å¤å®åæ(åæ ¼/ç¹é/éè´§/æ¥åº) + NCR è¯å®¡å¤ç½®å
³éï¼IQC/IPQC/OQC æ¯æ Excel æ¹é导å
¥(纯æ°å¢ãéè¡é¨åæåãæä¸å¡é®å»é)ï¼å¹¶æä¾è·¨åç±»çæ£æµç»æå°è´¦æ¥è¯¢ä¸å¯¼åºï¼AI æä¾å¤å®å»ºè®®ï¼NCR å½åä»
å°è´¦ä¸è§¦åè¿å·¥åï¼æ£éªåå¯ç±æºè½è´¨æ£æ¥åå¹³å°ä¸é®åºä»¶ï¼generate-from-qcï¼æ°æ®ä» MES åï¼äºéæ ¡éªå渲æè½åºï¼ã", |
| | | "steps": [ |
| | | {"stage": "æ¥æ", "action": "å°è´§éç¥/å¤åå
¥åºâIQCï¼ç»è®ºå忍è¿å¾
å
¥åºæè§¦åéè´§", "roles": ["IQC è´¨æ£å"]}, |
| | | {"stage": "è¿ç¨", "action": "æ¥å·¥è´¨æ£å·¥åºäº§åºè¡âIPQCï¼åæ ¼æè¡å
¥åºãä¸åæ ¼çæ NCR", "roles": ["IPQC è´¨æ£å"]}, |
| | | {"stage": "åºè´§", "action": "éå®åºåºæäº¤âOQCï¼å®æååºåºåè¿å
¥å¾
æ£è´§", "roles": ["OQC è´¨æ£å"]}, |
| | | {"stage": "éè´§", "action": "éæ/éå®éè´§/å®åéè´§âRQCï¼ç»è®ºåè°åæ®ä¸å®å", "roles": ["RQC è´¨æ£å"]}, |
| | | {"stage": "导å
¥", "action": "IQC/IPQC/OQC ä¸åè¡¨åæ¯æ Excel æ¹é导å
¥(æé®å¨ãæ°å¢ãä¸ã导åºãä¹é´ï¼çº¯æ°å¢ä¸åæ´æ°è¦ç)ï¼ä¸è¡ä¸å¼ åï¼ç¼å·ç空èªå¨çæï¼è´¨æ£æ¹æ¡ç空æç©æ+æ£éªç±»åèªå¨å¹é
ï¼æ£æµäººåç空åå½åç»å½ç¨æ·ï¼ç©æ/ä¾åºå/å®¢æ·æç¼ç æå称精确å¹é
(IQC ä¾åºåä¸ä¾åºåæ¹æ¬¡å¯ç空ãOQC 客æ·å¯ç空ä¸ç空ä¸åå®¢æ·æ°æ®æé鮿¡)ï¼åæ ¼+ä¸åæ ¼=æ£æµ/æ¥æ¶æ°éãIPQC å·¥åº+æåº+å
¶ä»åºåâ¤ä¸åæ ¼(ä¸åç空æ0)ï¼OQC å¡«å®¢æ·æ¶é¡»å¨æ¬äººå®¢æ·æ°æ®æéå
ï¼éè¡å¯¼å
¥é¨åæåï¼å¤±è´¥è¡è¿ failureList 带è¡å·ä¸å¯æ§è¡å¨ä½ï¼æååä¸å¾å¾
æ£éª0ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ï¼æä»¶å
éå¤è¡ä¸åºå
å·²åå¨åä¸å¡é®åæ®(IQC ç©æ+ä¾åºå+ä¾åºåæ¹æ¬¡+æ¥ææ¥æãIPQC ç©æ+æ¹å·+æ£éªç±»å+æ£æµæ¥æãOQC ç©æ+客æ·+æ¹æ¬¡å·+åºè´§æ¥æ)åæè¯¥è¡ï¼æç¤ºå«ç»´åº¦ãåæ¹å®é
å¼ä¸ãå
å é¤è¯¥åæ®åéè¯ãå¨ä½", "roles": ["è´¨æ£å", "IQC è´¨æ£å", "IPQC è´¨æ£å", "OQC è´¨æ£å"]}, |
| | | {"stage": "å°è´¦", "action": "æ£æµç»æå°è´¦ï¼è·¨ IQC/IPQC/OQC/RQC åç±»æ£éªåç»ä¸æ¥è¯¢(åç±»+æ£æµæ¥æåºé´+æ£éªåå·+ç©æ+æ¹æ¬¡å·+æ£æµç»æ+æ£æµäºº)ï¼ä¸è¡ä¸ä¸ªæ£æµé¡¹ç»æï¼å¤å®ä¾æ®ç±æ åå¼ä¸ä¸ä¸éæ¼è£
ï¼æ¹æ¬¡å·æç±»å忥æº(IQC åä¾åºåæ¹æ¬¡å·ï¼IPQC/OQC/RQC åæ¹å·)ï¼åå¥çéæ¡ä»¶ç´æ¥å¯¼åº Excel å°è´¦ç¨äºæå°åæ¡£ï¼æªå½æ£æµé¡¹çåä»ä¿çä¸è¡ä¸æ¼å", "roles": ["è´¨æ£å", "è´¨éå·¥ç¨å¸"]}, |
| | | {"stage": "ä¸åæ ¼", "action": "NCR: å¾
è¯å®¡âè¯å®¡âå¤ç½®(éè´§/æ¥åº/è¿å·¥/è®©æ¥æ¥æ¶/é级)âå
³é", "roles": ["è´¨éå·¥ç¨å¸"]}, |
| | | {"stage": "åºä»¶", "action": "两æ¡åºä»¶å
¥å£ï¼â éç¨ generate/preview(è°ç¨æ¹èªå¸¦ä¸ä¸æ) 渲æ HTML å¹¶å»ç»æ°æ®å¿«ç
§ï¼ç¼å· QR+æ¥æ+4使µæ°´æå¤©ç¬ç«ï¼preview åªæ¸²æä¸è½åºä¸æ¶èç¼å·ï¼regenerate ç¨å»ç»å¿«ç
§éæ¸²ä¸æ°æ®ä¸ç¼å·ä¸åå¹¶ä½åºå·²å½æ¡£ PDFï¼å¯¼åº PDF ç±åç«¯è° Chromium æå°å®ä¾å·²åç HTML å彿¡£éä»¶ä¸å¿ï¼â¡generate-from-qc ç±è´¨æ£åç´æ¥åºä»¶(æ°æ®ç» MesQcReportApi ä» MES åï¼åç«¯ä¸æ¼ä¸ä¸æ)ï¼åºä»¶åäºéæ ¡éªæä¸å¡ä¼å
çº§åªæ¥ç¬¬ä¸å¤ï¼ç±»åéæ³/åæ®ä¸åå¨/æªå®ææ£éª/æªå¡«å¤å®/模æ¿ç±»åä¸ç¬¦/æ å¯ç¨æ£éªé¡¹ï¼æ¥å头å¦å¸¦åæ®åå¤å® qcResult+qcResultText ä¸å¼æå¤å®å¹¶åï¼ååºå undecidableCount å¾
å¤å®é¡¹æ°ä¸ warnings(åç»æ é¢è·³è¿/ææ å·²å /æªå½å®æµå¼/æ ·åè¶
3)ï¼åä¸å¼ åæ®å¯åå¤åºå¤ä»½", "roles": ["è´¨æ£å"]}, |
| | | {"stage": "建模æ¿", "action": "AI 导å
¥ï¼ä¸ä¼ æ¢ææ£éªæ¥åæä»¶(æ«æä»¶/ç
§çãçµåç PDFãWord/Excel) â è¯å«ææ¨¡æ¿è稿(ä¸è½åº) â 人工å¨è®¾è®¡å¨ç¡®è®¤è°æ´åä¿åä¸ºçæ¬ï¼.doc/.xls æ§æ ¼å¼ä¸æ¯æ", "roles": ["è´¨æ£å", "è´¨éå·¥ç¨å¸"]}]}, |
| | |
| | | T2[æ¥å·¥è´¨æ£å·¥åºéè¿å产åºè¡] --> A2[IPQC è¿ç¨æ£éªÂ·è稿0â宿4] |
| | | T3[éå®åºåºåæäº¤] --> A3[OQC åºè´§æ£éªÂ·è稿0â宿4] |
| | | T4[ç产éæå æ éå®éè´§å æ å®åéè´§] --> A4[RQC éè´§æ£éªÂ·è稿0â宿4] |
| | | T5[Excel æ¹é导å
¥Â·IQC IPQC OQC ä¸å表åä¸ä¸ªå
¥å£Â·æé®å¨æ°å¢ä¸å¯¼åºä¹é´] --> IMP{导å
¥é¸é¨Â·éè¡è§£æÂ·å¤±è´¥è¡äºä¸å½±å} |
| | | IMP -->|ç¼å·ç空èªå¨çæÂ·ç¼å·é夿å䏿¹æ°æ®éå¤åæè¯¥è¡| A1 |
| | | IMP --> A2 |
| | | IMP --> A3 |
| | | IMP -.->|å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥Â·IQC ç©æ+ä¾åºå+ä¾åºåæ¹æ¬¡+æ¥ææ¥æ / IPQC ç©æ+æ¹å·+æ£éªç±»å+æ£æµæ¥æ / OQC ç©æ+客æ·+æ¹æ¬¡å·+åºè´§æ¥æÂ·æä»¶å
éå¤è¡ä¸åºå
å·²æå齿并忾忹å®é
å¼| IMPDUP[导å
¥å»é·æä¸å¡é®] |
| | | IMP -.->|ç©ææç¼ç ä¾åºåä¸å®¢æ·æåç§° 精确å¹é
Â·æ¹æ¡ç空æç©æ+æ£éªç±»åèªå¨å¹é
| IMPR[å¼ç¨è§£æÂ·QC_NO_TEMPLATE è¡¥ç©æä¸å¯æ§è¡å¨ä½] |
| | | IMP -.->|åæ ¼+ä¸åæ ¼ å¿
é¡»çäº æ£æµææ¥æ¶æ°é·ä¸ççåæè¯¥è¡| IMPQ[æ°éå
³ç³»æ ¡éªÂ·ä¸¤ä¾§å®é
å¼é½åæ¾] |
| | | IMP -.->|IPQC å·¥åº+æåº+å
¶ä»åºå ä¸å¾è¶
è¿ä¸åæ ¼åæ°é·ä¸åç空æ0| IMPQ |
| | | IMP -.->|OQC å¡«å®¢æ·æ¶æ ¡éªå¨æ¬äººæ°æ®æéå
·ç空åä¸å±äºä»»ä½å®¢æ·Â·ä¸å鮿¡| IMPP[æ°æ®æéåç½®æ ¡éª] |
| | | IMP -.->|æ£æµäººåç空=å½åç»å½ç¨æ·Â·IQC æ£æµä¸æ¥ææ¥æãOQC æ£æµæ¥æå¿
填·IPQC æ£æµæ¥æä¸ OQC åºè´§æ¥æå¯ç空| IMPD[人å䏿¥æ] |
| | | IMP --> IMR[ååº createList æåç¼å· + failureList è¡å·âåå ·æ´è¡ç©ºèªå¨è·³è¿] |
| | | IMR -.->|导å
¥åä¸å¾å¾
æ£éª0·ä¸èµ°æ¥æºåæ®åå·ä¸çæNCR| IMRNOTE[ä¸è§¦åå¼å»ºåçåºå«Â·finish æå¤å®ä¸åå] |
| | | A1 -->|å°è´¦ UNION ALL| LG[æ£æµç»æå°è´¦Â·è·¨ IQC IPQC OQC RQC ç»ä¸æ¥è¯¢ä¸å¯¼åº] |
| | | A2 -->|å°è´¦ UNION ALL| LG |
| | | A3 -->|å°è´¦ UNION ALL| LG |
| | | A4 -->|å°è´¦ UNION ALL| LG |
| | | LG -->|ä¸è¡ä¸ä¸ªæ£æµé¡¹Â·æªå½ç»æä¹ä¿çä¸è¡ä¸æ¼å| LGF[æ¹æ¬¡å·æç±»å忥æºÂ·IQC ä¾åºåæ¹æ¬¡å· / IPQC OQC RQC æ¹å·] |
| | | LG -->|å¤å®ä¾æ®ç±æ åå¼ä¸ä¸ä¸éæ¼è£
| LGB[åä¸å¥çéæ¡ä»¶å¯¼åº Excel å°è´¦Â·åªè¯»é¡µä¸æä¾å¢å æ¹] |
| | | LG -->|æéç | LGPERM["mes:qc-inspection-ledger:query æ¥è¯¢Â·:export 导åºÂ·èåæè´¨é管çç®å½"] |
| | | A1 --> R{æ£éªå¤å® MesQcCheckResultEnum} |
| | | A2 --> R |
| | | A3 --> R |
| | |
| | | RCTX --> RCITEM[æ£éªé¡¹=æ ·åÃææ 交åå±å¼Â·å
¨ææ è¿ä¸è¿æ»¤Â·å¤æ ·åæ¶æ ·åå·æè¿ remark] |
| | | RCTX --> RCQC[æºå¸¦åæ®åå¤å® qcResult æ°Â·qcResultText ä¸æÂ·ä¸å¼æå¤å®å¹¶åäºä¸è¦ç] |
| | | MESMAP -->|åç»é¡¹ item_type=2 ä¸å®çå项æ parent_id è¿å两å±Â·å½å±ä¸ç type ä¹ä¸çè¡åº| RCTXG |
| | | RCTXG["åç»è¿å·ç»å¤´è¡èç»åä¸ formula_text å
¬å¼Â·ç»å
第ä¸è¡è span=è¯¥ç»æ»è¡æ°Â·åç»å
¶ä½è¡ span=1 ä¸ hidden 让ä½Â·åªåå¹¶æ£éªé¡¹ç®ä¸å"] --- RCTX |
| | | RCTXG["åç»è¿å·ç»å¤´è¡èç»åä¸ formula_text å
¬å¼Â·ç»å
第ä¸è¡è span=è¯¥ç»æ»è¡æ°Â·åç»å
¶ä½è¡ span=1 ä¸ hidden 让ä½Â·åå¹¶çæ¯æ¨¡æ¿ columns é带 # çé£ä¸åï¼é»è®¤å峿£éªé¡¹ç®ï¼Â·åå¹¶è¡æ°æ¯æ¬å该ç»å®é
è¡æ°èéä¸»æ°æ®å项æ°Â·è¯¥ç»æ¬åæ å项è¡åä¸åå¹¶"] --- RCTX |
| | | MESMAP -.->|åç»é¡¹æ¬å没æå±äºå®çå项 / ç»å¤´æ¬å没æè¡ç±å端补ä¸è¡| RCWARN |
| | | MESMAP -.->|ææ å·²å / æªå½å®æµå¼ï¼ç»å¤´éç¹è¡æå®ä¹æ å¼Â·ä¸æ¥ï¼ / æ ·åè¶
3 ä¸ªÂ·è¿ warnings| RCWARN |
| | | RCWARN[warnings 软æç¤ºÂ·ä¸è½åºÂ·äºåçä¸å°éèªè¡çç] --- RCTX |
| | |
| | | T2[æ¥å·¥è´¨æ£å·¥åºéè¿å产åºè¡] --> A2[IPQC è¿ç¨æ£éªÂ·è稿0â宿4] |
| | | T3[éå®åºåºåæäº¤] --> A3[OQC åºè´§æ£éªÂ·è稿0â宿4] |
| | | T4[ç产éæå æ éå®éè´§å æ å®åéè´§] --> A4[RQC éè´§æ£éªÂ·è稿0â宿4] |
| | | T5[Excel æ¹é导å
¥Â·IQC IPQC OQC ä¸å表åä¸ä¸ªå
¥å£Â·æé®å¨æ°å¢ä¸å¯¼åºä¹é´] --> IMP{导å
¥é¸é¨Â·éè¡è§£æÂ·å¤±è´¥è¡äºä¸å½±å} |
| | | IMP -->|ç¼å·ç空èªå¨çæÂ·ç¼å·é夿å䏿¹æ°æ®éå¤åæè¯¥è¡| A1 |
| | | IMP --> A2 |
| | | IMP --> A3 |
| | | IMP -.->|å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥Â·IQC ç©æ+ä¾åºå+ä¾åºåæ¹æ¬¡+æ¥ææ¥æ / IPQC ç©æ+æ¹å·+æ£éªç±»å+æ£æµæ¥æ / OQC ç©æ+客æ·+æ¹æ¬¡å·+åºè´§æ¥æÂ·æä»¶å
éå¤è¡ä¸åºå
å·²æå齿并忾忹å®é
å¼| IMPDUP[导å
¥å»é·æä¸å¡é®] |
| | | IMP -.->|ç©ææç¼ç ä¾åºåä¸å®¢æ·æåç§° 精确å¹é
Â·æ¹æ¡ç空æç©æ+æ£éªç±»åèªå¨å¹é
| IMPR[å¼ç¨è§£æÂ·QC_NO_TEMPLATE è¡¥ç©æä¸å¯æ§è¡å¨ä½] |
| | | IMP -.->|åæ ¼+ä¸åæ ¼ å¿
é¡»çäº æ£æµææ¥æ¶æ°é·ä¸ççåæè¯¥è¡| IMPQ[æ°éå
³ç³»æ ¡éªÂ·ä¸¤ä¾§å®é
å¼é½åæ¾] |
| | | IMP -.->|IPQC å·¥åº+æåº+å
¶ä»åºå ä¸å¾è¶
è¿ä¸åæ ¼åæ°é·ä¸åç空æ0| IMPQ |
| | | IMP -.->|OQC å¡«å®¢æ·æ¶æ ¡éªå¨æ¬äººæ°æ®æéå
·ç空åä¸å±äºä»»ä½å®¢æ·Â·ä¸å鮿¡| IMPP[æ°æ®æéåç½®æ ¡éª] |
| | | IMP -.->|æ£æµäººåç空=å½åç»å½ç¨æ·Â·IQC æ£æµä¸æ¥ææ¥æãOQC æ£æµæ¥æå¿
填·IPQC æ£æµæ¥æä¸ OQC åºè´§æ¥æå¯ç空| IMPD[人å䏿¥æ] |
| | | IMP --> IMR[ååº createList æåç¼å· + failureList è¡å·âåå ·æ´è¡ç©ºèªå¨è·³è¿] |
| | | IMR -.->|导å
¥åä¸å¾å¾
æ£éª0·ä¸èµ°æ¥æºåæ®åå·ä¸çæNCR| IMRNOTE[ä¸è§¦åå¼å»ºåçåºå«Â·finish æå¤å®ä¸åå] |
| | | A1 -->|å°è´¦ UNION ALL| LG[æ£æµç»æå°è´¦Â·è·¨ IQC IPQC OQC RQC ç»ä¸æ¥è¯¢ä¸å¯¼åº] |
| | | A2 -->|å°è´¦ UNION ALL| LG |
| | | A3 -->|å°è´¦ UNION ALL| LG |
| | | A4 -->|å°è´¦ UNION ALL| LG |
| | | LG -->|ä¸è¡ä¸ä¸ªæ£æµé¡¹Â·æªå½ç»æä¹ä¿çä¸è¡ä¸æ¼å| LGF[æ¹æ¬¡å·æç±»å忥æºÂ·IQC ä¾åºåæ¹æ¬¡å· / IPQC OQC RQC æ¹å·] |
| | | LG -->|å¤å®ä¾æ®ç±æ åå¼ä¸ä¸ä¸éæ¼è£
| LGB[åä¸å¥çéæ¡ä»¶å¯¼åº Excel å°è´¦Â·åªè¯»é¡µä¸æä¾å¢å æ¹] |
| | | LG -->|æéç | LGPERM["mes:qc-inspection-ledger:query æ¥è¯¢Â·:export 导åºÂ·èåæè´¨é管çç®å½"] |
| | | A1 --> R{æ£éªå¤å® MesQcCheckResultEnum} |
| | | A2 --> R |
| | | A3 --> R |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # è´¨é管ç - æ£æµç»æå°è´¦ï¼åç±» / æ¶é´åºé´çé + 导åºï¼ - å端èè°æ¹æ¡ |
| | | |
| | | > æ¬æ¬¡è§£å³ä¸¤ä»¶äºï¼ |
| | | > 1. **ç´æ¥å±ç¤º**ï¼åç±»æ£éªåï¼IQC/IPQC/OQC/RQCï¼å表æ¥å£**å·²ç»è¿å**æ£éªé¡¹å®æµç»ææ±æ»å段 `indicatorResultSummary`ï¼ä½å端å表æªå±ç¤º â å端å ä¸åå³å¯ï¼**å端æ éæ¹å¨**ã |
| | | > 2. **çéå±ç¤º + 导åºå°è´¦**ï¼æ°å¢è·¨åç±»çãæ£æµç»æå°è´¦ãæ¥è¯¢ä¸å¯¼åºæ¥å£ï¼åç±» + æ£æµæ¥æåºé´ + ç©æ/æ¹æ¬¡/æ£æµç»æ/æ£æµäººçéï¼ï¼ä¸è¡ä¸ä¸ªæ£æµé¡¹ç»æï¼ç¨äºæ¥è¯¢ãæå°ãåæ¡£ã |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - **æ°å¢**ï¼æ£æµç»æå°è´¦é¡µ `views/mes/qc/ledger/index.vue`ï¼èåç± `docs/sql/qc_inspection_ledger_menu.sql` èæ¬ææéç èªéåºå建ï¼è´¨é管ç â æ£æµç»æå°è´¦ï¼path `inspection-ledger`ï¼component `mes/qc/ledger/index`ï¼ |
| | | - **åæ´ï¼ç¨äºãç´æ¥å±ç¤ºãï¼**ï¼æ¥ææ£éª / è¿ç¨æ£éª / åºè´§æ£éª / éè´§æ£éª å个å表页æ°å¢ãæ£æµç»æï¼æ£éªé¡¹ï¼ãå |
| | | |
| | | ## éæ±ç¹ä¸è½ç¹å¯¹ç
§ |
| | | |
| | | | éæ± | è½ç¹ | |
| | | |------|------| |
| | | | æ£æµç»æå¨çé¢ä¸ç´æ¥å±ç¤º | åç±»æ£éªåå表 API å·²è¿å `indicatorResultSummary`ï¼å端å表å åï¼æ éå端æ¹å¨ï¼ | |
| | | | æ¯æçéå±ç¤º | æ°å¢å°è´¦é¡µï¼åç±» + æ£æµæ¥æåºé´ + æ£éªåå· + ç©æ + æ¹æ¬¡å· + æ£æµç»æ + æ£æµäºº | |
| | | | æåç±»çé | åæ° `qcType`ï¼1 æ¥ææ£éª / 2 è¿ç¨æ£éª / 3 åºè´§æ£éª / 4 éè´§æ£éªï¼ï¼ä¸ä¼ 为å
¨é¨ | |
| | | | ææ¶é´åºé´çé | åæ° `inspectDate`ï¼æãæ£æµæ¥æãè¿æ»¤ï¼ | |
| | | | 导åºä¸ºå°è´¦ | `GET /mes/qc/inspection-ledger/export-excel`ï¼ä¸å表åä¸å¥çéåæ° | |
| | | |
| | | ## ä¸å¡æµç¨ä¸æ°æ®å¸¦å
¥ |
| | | |
| | | 1. ç¨æ·å¨å°è´¦é¡µè®¾ç½®ç鿡件ï¼åç±»ãæ£æµæ¥æåºé´çï¼â å表å页å±ç¤ºï¼ä¸è¡ä¸ä¸ªæ£æµé¡¹ç»æã |
| | | 2. åä¸å¥çéåæ°ç´æ¥ä¼ ç»å¯¼åºæ¥å£ â çæ Excel å°è´¦ï¼æä»¶åãæ£æµç»æå°è´¦.xlsãï¼ï¼ç¨äºæå°ä¸åæ¡£ã |
| | | 3. æ£éªåæªå½å
¥æ£éªç»ææ¶ï¼è¯¥åä»ä¼åºç°å¨å°è´¦ä¸ï¼æ£æµé¡¹ç¸å
³å为空ï¼ï¼ä¸ä¼æ¼åã |
| | | 4. å°è´¦çãæ¹æ¬¡å·ãåææ£éªç±»ååä¸åæ¥æºï¼æ¥ææ£éªå**ä¾åºåæ¹æ¬¡å·**ï¼è¿ç¨æ£éªãåºè´§æ£éªãéè´§æ£éªååèªç**æ¹æ¬¡å·**ã |
| | | |
| | | ## API |
| | | |
| | | ### 1. å°è´¦å页 |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | `/admin-api/mes/qc/inspection-ledger/page` | æ£æµç»æå°è´¦å页ï¼åç±»æ£éªåç»ä¸æ¥è¯¢ï¼ | |
| | | |
| | | **请æ±åæ°ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | qcType | Integer | å¦ | åç±»ï¼æ£éªç±»åï¼ï¼1 æ¥ææ£éª / 2 è¿ç¨æ£éª / 3 åºè´§æ£éª / 4 éè´§æ£éªï¼ä¸ä¼ 为å
¨é¨ | |
| | | | inspectDate[0] | String | å¦ | æ£æµæ¥æå¼å§ï¼æ ¼å¼ yyyy-MM-dd HH:mm:ss | |
| | | | inspectDate[1] | String | å¦ | æ£æµæ¥æç»æï¼æ ¼å¼ yyyy-MM-dd HH:mm:ss | |
| | | | code | String | å¦ | æ£éªåç¼å·ï¼æ¨¡ç³å¹é
| |
| | | | itemId | Long | å¦ | ç©æç¼å· | |
| | | | batchNo | String | å¦ | æ¹æ¬¡å·ï¼æ¨¡ç³å¹é
ï¼æ¥ææ£éªåä¾åºåæ¹æ¬¡å·ï¼è¿ç¨/åºè´§/éè´§æ£éªåæ¹æ¬¡å·ï¼ | |
| | | | checkResult | Integer | å¦ | æ£æµç»æï¼åå
¸ `mes_qc_check_result` | |
| | | | inspectorUserId | Long | å¦ | æ£æµäººåç¼å· | |
| | | | pageNo / pageSize | Integer | å¦ | å页忰 | |
| | | |
| | | > `inspectDate` ä¸ç°æåç±»æ£éªåå表çä¼ åæ¹å¼ä¸è´ï¼åä¸å¥ RangePicker åæ°å¯¹è±¡å¯ç´æ¥å¤ç¨ï¼ã |
| | | |
| | | **ååºå段ï¼** |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | qcType | Integer | åç±»ï¼æ£éªç±»åï¼ï¼åå
¸ `mes_qc_type` | |
| | | | qcId | Long | æ£éªå IDï¼å¯è·³è½¬å°å¯¹åºæ£éªå详æ
ï¼ | |
| | | | code | String | æ£éªåç¼å· | |
| | | | name | String | æ£éªååç§° | |
| | | | status | Integer | åæ®ç¶æï¼åå
¸ `mes_order_status` | |
| | | | itemId / itemCode / itemName / itemSpecification / unitName | - | ç©æä¿¡æ¯ï¼ç¼ç ãåç§°ãè§æ ¼åå·ã计éåä½ï¼ååèª MDM ç©æï¼ | |
| | | | batchNo | String | æ¹æ¬¡å· | |
| | | | checkQuantity / qualifiedQuantity / unqualifiedQuantity | BigDecimal | æ£æµæ°é / åæ ¼æ°é / ä¸åæ ¼æ°é | |
| | | | checkResult | Integer | æ£æµç»æï¼åå
¸ `mes_qc_check_result` | |
| | | | inspectDate | String (LocalDateTime) | æ£æµæ¥æ | |
| | | | inspectorUserId / inspectorName | - | æ£æµäººå | |
| | | | indicatorId / indicatorName | - | æ£æµé¡¹ç¼å· / åç§° | |
| | | | indicatorValue | String | æ£æµå¼ï¼å®æµå¼ï¼åæ ·åç¬¦ä¸²ï¼ | |
| | | | indicatorRemark | String | æ£æµé¡¹å¤æ³¨ | |
| | | | judgementBasis | String | å¤å®ä¾æ®ï¼å¦ `10~20`ã`â¤20`ã`â¥10`ã`æ åå¼ 15`ï¼æ æ³æ¼è£
æ¶ä¸ºç©º | |
| | | | standardValue / minThreshold / maxThreshold | BigDecimal | å¤å®ä¾æ®åå§å¼ï¼å端å±ç¤ºç¨ `judgementBasis` å³å¯ï¼ | |
| | | | remark | String | æ£éªå夿³¨ | |
| | | |
| | | **ååºç¤ºä¾ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "list": [ |
| | | { |
| | | "qcType": 1, |
| | | "qcId": 123, |
| | | "code": "IQC1789019053513", |
| | | "name": "AN1789019053466-ç©ææ£éª", |
| | | "status": 0, |
| | | "itemId": 28, |
| | | "itemCode": "WL0001", |
| | | "itemName": "ç©æA", |
| | | "itemSpecification": "100mm*50mm", |
| | | "unitName": "个", |
| | | "batchNo": "VB20260101", |
| | | "checkQuantity": 99, |
| | | "qualifiedQuantity": 99, |
| | | "unqualifiedQuantity": 0, |
| | | "checkResult": 1, |
| | | "inspectDate": "2026-09-10 00:00:00", |
| | | "inspectorUserId": 111, |
| | | "inspectorName": "å¼ ä¸", |
| | | "indicatorId": 2, |
| | | "indicatorName": "温度", |
| | | "indicatorValue": "15", |
| | | "indicatorRemark": null, |
| | | "judgementBasis": "10~20", |
| | | "remark": null |
| | | } |
| | | ], |
| | | "total": 5 |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ### 2. å°è´¦å¯¼åº |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | `/admin-api/mes/qc/inspection-ledger/export-excel` | å¯¼åºæ£æµç»æå°è´¦ Excelï¼åæ°ä¸å页æ¥å£å®å
¨ä¸è´ | |
| | | |
| | | **导åºåï¼** åç±» / æ£éªåç¼å· / æ£éªååç§° / ç©æç¼ç / ç©æåç§° / è§æ ¼åå· / æ¹æ¬¡å· / æ£æµé¡¹ / æ£æµå¼ / å¤å®ä¾æ® / æ£æµç»æ / æ£æµæ°é / åæ ¼æ°é / ä¸åæ ¼æ°é / æ£æµäººå / æ£æµæ¥æ / åæ®ç¶æ / 夿³¨ã |
| | | |
| | | ## æéä¸èå |
| | | |
| | | | èå | æéç | 说æ | |
| | | |------|--------|------| |
| | | | è´¨é管ç â æ£æµç»æå°è´¦ | â | type=2ï¼component `mes/qc/ledger/index` | |
| | | | æ£æµç»æå°è´¦æ¥è¯¢ | `mes:qc-inspection-ledger:query` | 页é¢å è½½ãå页æ¥è¯¢ | |
| | | | æ£æµç»æå°è´¦å¯¼åº | `mes:qc-inspection-ledger:export` | å¯¼åºæé® | |
| | | |
| | | èå䏿é®ç± `docs/sql/qc_inspection_ledger_menu.sql` å建ï¼**èå ID èªéåº**ï¼ä¸åæ» IDï¼ç¶èåè·éãæ¥ææ£éªæ¥è¯¢ãæé®æå¨çæ£éªåèåï¼è§è²ææè·éãæ¥ææ£éªæ¥è¯¢ãæé®å·²æçè§è²ï¼ãæ§è¡èæ¬åééæ°ç»å½ä»¥å·æ°èå䏿éç¼åãå端建好 `views/mes/qc/ledger/index.vue` åèåå³å¯ç¨ã |
| | | |
| | | ## åæ®µå±ç¤ºè§å |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | åç±» | å°è´¦å表åãçé项 | ç¨ `CellDict` + `DICT_TYPE.MES_QC_TYPE` 渲æ | |
| | | | æ£æµç»æ | å°è´¦å表åãçé项 | ç¨ `CellDict` + `DICT_TYPE.MES_QC_CHECK_RESULT` | |
| | | | æ£æµé¡¹ / æ£æµå¼ / å¤å®ä¾æ® | å°è´¦å表å | ä¸è¡ä¸ä¸ªæ£æµé¡¹ï¼æ£éªåæªå½å
¥ç»ææ¶ä¸ºç©º | |
| | | | åæ®ç¶æ | å°è´¦å表å | `DICT_TYPE.MES_ORDER_STATUS` | |
| | | | æ¹æ¬¡å· | å°è´¦å表å | æ¥ææ£éªä¸ºä¾åºåæ¹æ¬¡å·ï¼è¿ç¨/åºè´§/éè´§æ£éªä¸ºæ¹æ¬¡å· | |
| | | | æ£æµç»æï¼æ£éªé¡¹ï¼ | åç±»æ£éªåå表å | ç´æ¥æ¸²æ `indicatorResultSummary`ï¼å¦ `温度:15ï¼çµé»:1`ï¼ï¼å宽建议 200+ï¼å
容è¿é¿å¯æ¢è¡æçç¥å·æ¬æµ® | |
| | | | æ£æµæ¥æåºé´ | å°è´¦é¡µçéåº | RangePickerï¼valueFormat `YYYY-MM-DD HH:mm:ss` | |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | åç±»ä¸é | åç±»æ£éªåä¸èµ·æ¥è¯¢ï¼ææ£æµæ¥æååºãåæ¥æææ£éªå ID ååº | |
| | | | æ¶é´åºé´ | æãæ£æµæ¥æãéåºé´è¿æ»¤ï¼åªä¼ å¼å§æåªä¼ ç»æåå¯ | |
| | | | ä¸è¡ä¸æ£æµé¡¹ | ä¸å¼ æ£éªåå½å
¥å¤ä¸ªæ£æµé¡¹ç»ææ¶å±å¼ä¸ºå¤è¡ï¼å
¶ä½å段éå¤ï¼ | |
| | | | æ£éªåæªå½å
¥æ£æµé¡¹ | 该åä¿çä¸è¡ï¼æ£æµé¡¹ / æ£æµå¼ / å¤å®ä¾æ®ä¸ºç©º | |
| | | | å¤å®ä¾æ® | ç±æ£éªåè¡çæ åå¼ä¸è¯¯å·®ä¸ä¸éæ¼è£
ï¼ä¸ä¸é齿 â `ä¸é~ä¸é`ï¼ä»
ä¸é â `â¤ä¸é`ï¼ä»
ä¸é â `â¥ä¸é`ï¼ä»
æ åå¼ â `æ åå¼ å¼`ï¼é½æ²¡æå为空 | |
| | | | é»è¾å é¤ | å·²å é¤çæ£éªåä¸åºç°å¨å°è´¦ï¼å·²å é¤çæ£æµé¡¹ä»å±ç¤ºå
¶åå²åç§°ï¼ä¿è¯åå²å°è´¦å¯è¯» | |
| | | | 导åºèå´ | 导åºéµå¾ªå½åç鿡件ï¼ä¸éæ¶é´å导åºå
¨é¨ç¬¦åå
¶å®æ¡ä»¶çè®°å½ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - æ¬æ¬¡å端æ°å¢äºé¡µé¢æ¥å£ä¸èåï¼**ééå¯å端æå¡**åæ°æ¥å£æå¯ç¨ï¼å¹¶æ§è¡ `docs/sql/qc_inspection_ledger_menu.sql` åéæ°ç»å½ä»¥å·æ°èå䏿éç¼åã |
| | | - å°è´¦æ¥å£ç `qcId` + `qcType` å¯å®ä½å°åå§æ£éªåï¼è¥éè¦ç¹å»è·³è½¬ï¼è¯·æå类跳å°å¯¹åºé¡µé¢ï¼æ¥ææ£éª / è¿ç¨æ£éª / åºè´§æ£éª / éè´§æ£éªï¼ã |
| | | - å°è´¦çãæ£æµç»æãåä¸åç±»æ£éªåå表çãæ£æµç»æãåå£å¾ä¸è´ï¼å忣éªåå¤´çæ£æµç»è®ºï¼åå
¸ `mes_qc_check_result`ï¼ã |
| | | - åç±»æ£éªåå表æ°å¢çãæ£æµç»æï¼æ£éªé¡¹ï¼ãåç´æ¥ä½¿ç¨å·²æå段 `indicatorResultSummary`ï¼ä¸éè¦æ°æ¥å£ï¼å¯¼åºæ¶è¯¥å
容已å
å«å¨ãæ£éªææ ãåä¸ã |
| | | - å°è´¦ä¸ºåªè¯»é¡µé¢ï¼ä¸æä¾æ°å¢ / ä¿®æ¹ / å 餿ä½ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ============================================================ |
| | | -- CRM å¼ç¥¨å¯¼å
¥ èå䏿鮿é |
| | | -- |
| | | -- èæ¯ï¼å¼ç¥¨ç®¡çæ°å¢ Excel æ¹é导å
¥è½å |
| | | -- ï¼å端æ¥å£ GET /crm/invoice/get-import-template ä¸ POST /crm/invoice/importï¼ï¼ |
| | | -- éè¦å¨å¼ç¥¨å表页æ´é²ã导å
¥ãæé®æéï¼å¦åå端æé®ä¼è¢« @PreAuthorize æ¦æªã |
| | | -- |
| | | -- æ°å¢æé®æéï¼crm:invoice:importï¼å¼ç¥¨å表ã导å
¥ãæé®ï¼ |
| | | -- |
| | | -- ID èªéåºï¼æ¬èæ¬ä¸åæ»èå ID |
| | | -- â èå ID ç± system_menu èªå¢åé
ï¼ä¸æå® id åï¼ï¼ |
| | | -- â¡ ç¶èåææéç 忥å¼ç¥¨ç®¡çèåï¼crm:invoice:export -> å
¶ parent_idï¼ï¼ |
| | | -- æ¥ä¸å°æ¶ä¾æ¬¡åé crm:invoice:queryãåç§°ãå¼ç¥¨ç®¡çãç type=2 èåï¼ |
| | | -- ⢠è§è²ææè·éå¼ç¥¨ç®¡çã导åºãæé®å·²æçè§è²ï¼ä¸åæ» role_idã |
| | | -- |
| | | -- å¹çï¼ææéç å
å åæï¼å¯é夿§è¡ã |
| | | -- |
| | | -- æ§è¡æ¹å¼ï¼PowerShellï¼é¿å
䏿乱ç ï¼ï¼ |
| | | -- mysql -uroot -p1234 --default-character-set=utf8mb4 ruoyi-vue-pro < docs/sql/crm_invoice_import_menu.sql |
| | | -- ============================================================ |
| | | |
| | | SET NAMES utf8mb4; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 0. å¹çæ¸
ç |
| | | -- ------------------------------------------------------------ |
| | | DELETE rm FROM `system_role_menu` rm |
| | | JOIN `system_menu` m ON rm.`menu_id` = m.`id` |
| | | WHERE m.`permission` = 'crm:invoice:import'; |
| | | |
| | | DELETE FROM `system_menu` WHERE `permission` = 'crm:invoice:import'; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 1. ç¶èåï¼å¼ç¥¨ç®¡çèåï¼type=2ï¼ |
| | | -- ------------------------------------------------------------ |
| | | SET @invoice_menu_id = COALESCE( |
| | | (SELECT `parent_id` FROM `system_menu` WHERE `permission` = 'crm:invoice:export' AND `deleted` = b'0' LIMIT 1), |
| | | (SELECT `parent_id` FROM `system_menu` WHERE `permission` = 'crm:invoice:query' AND `deleted` = b'0' LIMIT 1), |
| | | (SELECT `id` FROM `system_menu` WHERE `name` = 'å¼ç¥¨ç®¡ç' AND `type` = 2 AND `deleted` = b'0' LIMIT 1)); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 2. æ°å¢æé®ï¼èå ID èªå¢ï¼ |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_menu` (`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT 'å¼ç¥¨å¯¼å
¥', 'crm:invoice:import', 3, 5, @invoice_menu_id, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0' |
| | | WHERE @invoice_menu_id IS NOT NULL; |
| | | SET @menu_invoice_import = IF(ROW_COUNT() > 0, LAST_INSERT_ID(), NULL); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 3. ææï¼è·éå¼ç¥¨ç®¡çã导åºãæé®å·²æçè§è²ï¼å
åºãæ¥è¯¢ãæé®ï¼ |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, @menu_invoice_import, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | WHERE rm.`menu_id` = COALESCE( |
| | | (SELECT `id` FROM `system_menu` WHERE `permission` = 'crm:invoice:export' AND `deleted` = b'0' LIMIT 1), |
| | | (SELECT `id` FROM `system_menu` WHERE `permission` = 'crm:invoice:query' AND `deleted` = b'0' LIMIT 1)) |
| | | AND rm.`deleted` = b'0' |
| | | AND @menu_invoice_import IS NOT NULL; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 4. æ ¡éªï¼èååºè¿å 1 è¡ï¼ææè¡æ°ä¸ãå¼ç¥¨ç®¡ç导åºãæé®ä¸è´ |
| | | -- ------------------------------------------------------------ |
| | | SELECT 'èå crm:invoice:import ' AS item, COUNT(*) AS cnt |
| | | FROM `system_menu` WHERE `permission` = 'crm:invoice:import' AND `deleted` = b'0' |
| | | UNION ALL SELECT 'ææ / å¼ç¥¨å¯¼åºææ ', CONCAT( |
| | | (SELECT COUNT(*) FROM `system_role_menu` rm JOIN `system_menu` m ON rm.`menu_id` = m.`id` |
| | | WHERE m.`permission` = 'crm:invoice:import' AND rm.`deleted` = b'0'), ' / ', |
| | | (SELECT COUNT(*) FROM `system_role_menu` rm JOIN `system_menu` m ON rm.`menu_id` = m.`id` |
| | | WHERE m.`permission` = 'crm:invoice:export' AND rm.`deleted` = b'0')); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ============================================================ |
| | | -- MES è´¨æ£åæ¹é导å
¥ èå䏿鮿é |
| | | -- |
| | | -- èæ¯ï¼æ¥ææ£éªï¼IQCï¼ãè¿ç¨æ£éªï¼IPQCï¼ãåºè´§æ£éªï¼OQCï¼åèªæ°å¢ãæ¹é导å
¥ãè½å |
| | | -- ï¼å端æ¥å£ GET /mes/qc/{iqc|ipqc|oqc}/get-import-template ä¸ POST .../importï¼ï¼ |
| | | -- éè¦å¨å¯¹åºå表页æ´é²æé®æéï¼å¦åå端æé®ä¼è¢« @PreAuthorize æ¦æªã |
| | | -- |
| | | -- æ°å¢æé®æéï¼ |
| | | -- mes:qc-iqc:import æ¥ææ£éªåè¡¨ãæ¹é导å
¥ãæé® |
| | | -- mes:qc-ipqc:import è¿ç¨æ£éªåè¡¨ãæ¹é导å
¥ãæé® |
| | | -- mes:qc-oqc:import åºè´§æ£éªåè¡¨ãæ¹é导å
¥ãæé® |
| | | -- |
| | | -- ID èªéåºï¼æ¬èæ¬ä¸åæ»èå ID |
| | | -- â èå ID ç± system_menu èªå¢åé
ï¼ä¸æå® id åï¼ï¼ |
| | | -- â¡ ç¶èåææéç åæ¥è¯¥æ¨¡åãæ¥è¯¢ãæé®æå¨èåï¼mes:qc-iqc:query çï¼ï¼ |
| | | -- æ¥ä¸å°æ¶ä¾æ¬¡åéå°ã导åºãæé®æå¨èåãåå type=2 èåï¼ |
| | | -- ⢠è§è²ææè·é忍¡åãæ¥è¯¢ãæé®å·²æçè§è²ï¼ä¸åæ» role_idã |
| | | -- å æ¤èæ¬å¯å¨ä»»ä½åºç»æä¸è´çå®ä¾ä¸ç´æ¥æ§è¡ã |
| | | -- |
| | | -- å¹çï¼ææéç å
å åæï¼å¯é夿§è¡ã |
| | | -- |
| | | -- æ§è¡æ¹å¼ï¼PowerShellï¼é¿å
䏿èååä¹±ç ï¼ï¼ |
| | | -- mysql -uroot -p1234 --default-character-set=utf8mb4 ruoyi-vue-pro < docs/sql/mes_qc_import_menu.sql |
| | | -- ============================================================ |
| | | |
| | | SET NAMES utf8mb4; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 0. å¹çæ¸
çï¼å 餿¢æå¯¼å
¥æé®åå
¶è§è²ææ |
| | | -- ------------------------------------------------------------ |
| | | DELETE rm FROM `system_role_menu` rm |
| | | JOIN `system_menu` m ON rm.`menu_id` = m.`id` |
| | | WHERE m.`permission` IN ('mes:qc-iqc:import', 'mes:qc-ipqc:import', 'mes:qc-oqc:import'); |
| | | |
| | | DELETE FROM `system_menu` |
| | | WHERE `permission` IN ('mes:qc-iqc:import', 'mes:qc-ipqc:import', 'mes:qc-oqc:import'); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 1. ç¶èåï¼åæ£éªåå表页æå¨èåï¼type=2ï¼ |
| | | -- ------------------------------------------------------------ |
| | | SET @iqc_parent = COALESCE( |
| | | (SELECT `parent_id` FROM `system_menu` WHERE `permission` = 'mes:qc-iqc:query' AND `deleted` = b'0' LIMIT 1), |
| | | (SELECT `parent_id` FROM `system_menu` WHERE `permission` = 'mes:qc-iqc:export' AND `deleted` = b'0' LIMIT 1)); |
| | | |
| | | SET @ipqc_parent = COALESCE( |
| | | (SELECT `parent_id` FROM `system_menu` WHERE `permission` = 'mes:qc-ipqc:query' AND `deleted` = b'0' LIMIT 1), |
| | | (SELECT `parent_id` FROM `system_menu` WHERE `permission` = 'mes:qc-ipqc:export' AND `deleted` = b'0' LIMIT 1)); |
| | | |
| | | SET @oqc_parent = COALESCE( |
| | | (SELECT `parent_id` FROM `system_menu` WHERE `permission` = 'mes:qc-oqc:query' AND `deleted` = b'0' LIMIT 1), |
| | | (SELECT `parent_id` FROM `system_menu` WHERE `permission` = 'mes:qc-oqc:export' AND `deleted` = b'0' LIMIT 1)); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 2. æ°å¢æé®ï¼èå ID èªå¢ï¼ |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_menu` (`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT 'æ¥ææ£éªå¯¼å
¥', 'mes:qc-iqc:import', 3, 6, @iqc_parent, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0' |
| | | WHERE @iqc_parent IS NOT NULL; |
| | | SET @menu_iqc_import = IF(ROW_COUNT() > 0, LAST_INSERT_ID(), NULL); |
| | | |
| | | INSERT INTO `system_menu` (`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT 'è¿ç¨æ£éªå¯¼å
¥', 'mes:qc-ipqc:import', 3, 6, @ipqc_parent, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0' |
| | | WHERE @ipqc_parent IS NOT NULL; |
| | | SET @menu_ipqc_import = IF(ROW_COUNT() > 0, LAST_INSERT_ID(), NULL); |
| | | |
| | | INSERT INTO `system_menu` (`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT 'åºè´§æ£éªå¯¼å
¥', 'mes:qc-oqc:import', 3, 6, @oqc_parent, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0' |
| | | WHERE @oqc_parent IS NOT NULL; |
| | | SET @menu_oqc_import = IF(ROW_COUNT() > 0, LAST_INSERT_ID(), NULL); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 3. ææï¼è·é忍¡åãæ¥è¯¢ãæé®å·²æçè§è²ï¼åæ¶å
åºè¶
级管çåè§è² 1ï¼ |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, @menu_iqc_import, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | WHERE rm.`menu_id` = (SELECT `id` FROM `system_menu` WHERE `permission` = 'mes:qc-iqc:query' AND `deleted` = b'0' LIMIT 1) |
| | | AND rm.`deleted` = b'0' |
| | | AND @menu_iqc_import IS NOT NULL; |
| | | |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, @menu_ipqc_import, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | WHERE rm.`menu_id` = (SELECT `id` FROM `system_menu` WHERE `permission` = 'mes:qc-ipqc:query' AND `deleted` = b'0' LIMIT 1) |
| | | AND rm.`deleted` = b'0' |
| | | AND @menu_ipqc_import IS NOT NULL; |
| | | |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, @menu_oqc_import, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | WHERE rm.`menu_id` = (SELECT `id` FROM `system_menu` WHERE `permission` = 'mes:qc-oqc:query' AND `deleted` = b'0' LIMIT 1) |
| | | AND rm.`deleted` = b'0' |
| | | AND @menu_oqc_import IS NOT NULL; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 4. æ ¡éªï¼åºåèªè¿å 1 è¡èåï¼è§è²ææè¡æ°ä¸å模åãæ¥è¯¢ãæé®ä¸è´ |
| | | -- ------------------------------------------------------------ |
| | | SELECT 'èå mes:qc-iqc:import ' AS item, COUNT(*) AS cnt FROM `system_menu` WHERE `permission` = 'mes:qc-iqc:import' AND `deleted` = b'0' |
| | | UNION ALL SELECT 'èå mes:qc-ipqc:import', COUNT(*) FROM `system_menu` WHERE `permission` = 'mes:qc-ipqc:import' AND `deleted` = b'0' |
| | | UNION ALL SELECT 'èå mes:qc-oqc:import ', COUNT(*) FROM `system_menu` WHERE `permission` = 'mes:qc-oqc:import' AND `deleted` = b'0' |
| | | UNION ALL SELECT 'IQC ææ / æ¥è¯¢ææ ', CONCAT( |
| | | (SELECT COUNT(*) FROM `system_role_menu` rm JOIN `system_menu` m ON rm.`menu_id` = m.`id` |
| | | WHERE m.`permission` = 'mes:qc-iqc:import' AND rm.`deleted` = b'0'), ' / ', |
| | | (SELECT COUNT(*) FROM `system_role_menu` rm JOIN `system_menu` m ON rm.`menu_id` = m.`id` |
| | | WHERE m.`permission` = 'mes:qc-iqc:query' AND rm.`deleted` = b'0')) |
| | | UNION ALL SELECT 'IPQC ææ / æ¥è¯¢ææ ', CONCAT( |
| | | (SELECT COUNT(*) FROM `system_role_menu` rm JOIN `system_menu` m ON rm.`menu_id` = m.`id` |
| | | WHERE m.`permission` = 'mes:qc-ipqc:import' AND rm.`deleted` = b'0'), ' / ', |
| | | (SELECT COUNT(*) FROM `system_role_menu` rm JOIN `system_menu` m ON rm.`menu_id` = m.`id` |
| | | WHERE m.`permission` = 'mes:qc-ipqc:query' AND rm.`deleted` = b'0')) |
| | | UNION ALL SELECT 'OQC ææ / æ¥è¯¢ææ ', CONCAT( |
| | | (SELECT COUNT(*) FROM `system_role_menu` rm JOIN `system_menu` m ON rm.`menu_id` = m.`id` |
| | | WHERE m.`permission` = 'mes:qc-oqc:import' AND rm.`deleted` = b'0'), ' / ', |
| | | (SELECT COUNT(*) FROM `system_role_menu` rm JOIN `system_menu` m ON rm.`menu_id` = m.`id` |
| | | WHERE m.`permission` = 'mes:qc-oqc:query' AND rm.`deleted` = b'0')); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ============================================================ |
| | | -- è´¨é管ç - æ£æµç»æå°è´¦ èå䏿é |
| | | -- |
| | | -- èæ¯ï¼è´¨æ£å模åï¼IQC/IPQC/OQC/RQCï¼çæ£æµç»æåå
忣å¨åèªå表å
ï¼ |
| | | -- 缺å°è·¨ç±»åçç»ä¸æ¥è¯¢ä¸å°è´¦å¯¼åºãæ¬æ¬¡æ°å¢ãæ£æµç»æå°è´¦ã页é¢ï¼ |
| | | -- ææ£éªç±»å + æ£æµæ¥æåºé´ + ç©æ/æ¹æ¬¡/æ£æµç»æ/æ£æµäººçéï¼ |
| | | -- åè¡¨ç´æ¥å±ç¤ºæ£æµé¡¹å®æµç»æï¼å¹¶æ¯æå¯¼åº Excel å°è´¦ç¨äºæ¥è¯¢ãæå°ãåæ¡£ã |
| | | -- |
| | | -- æ°å¢èå䏿é®ï¼ |
| | | -- â èåãæ£æµç»æå°è´¦ã type=2ï¼component=mes/qc/ledger/index |
| | | -- â¡ æé®ãæ£æµç»æå°è´¦æ¥è¯¢ã= mes:qc-inspection-ledger:query |
| | | -- ⢠æé®ãæ£æµç»æå°è´¦å¯¼åºã= mes:qc-inspection-ledger:export |
| | | -- |
| | | -- ID èªéåºï¼æ¬èæ¬ä¸åæ»èå ID |
| | | -- â èå ID ç± system_menu èªå¢åé
ï¼ä¸æå® id åï¼ï¼ |
| | | -- â¡ ç¶èå = ãæ¥ææ£éªæ¥è¯¢ã(mes:qc-iqc:query) æå¨æ£éªåèåçä¸çº§ï¼å³è´¨é管çç®å½ï¼ï¼ |
| | | -- æ¥ä¸å°æ¶åé为åç§°ãè´¨é管çããtype=1 çç®å½ï¼ |
| | | -- ⢠è§è²ææè·éãæ¥ææ£éªæ¥è¯¢ãæé®å·²æçè§è²ï¼ä¸åæ» role_idã |
| | | -- |
| | | -- å¹çï¼ææéç / åç§°å
å åæï¼å¯é夿§è¡ã |
| | | -- |
| | | -- æ§è¡æ¹å¼ï¼PowerShellï¼é¿å
䏿乱ç ï¼ï¼ |
| | | -- mysql -uroot -p1234 --default-character-set=utf8mb4 ruoyi-vue-pro < docs/sql/qc_inspection_ledger_menu.sql |
| | | -- ============================================================ |
| | | |
| | | SET NAMES utf8mb4; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 0. å¹çæ¸
ç |
| | | -- ------------------------------------------------------------ |
| | | DELETE rm FROM `system_role_menu` rm |
| | | JOIN `system_menu` m ON rm.`menu_id` = m.`id` |
| | | WHERE m.`permission` IN ('mes:qc-inspection-ledger:query', 'mes:qc-inspection-ledger:export') |
| | | OR (m.`name` = 'æ£æµç»æå°è´¦' AND m.`type` = 2); |
| | | |
| | | DELETE FROM `system_menu` |
| | | WHERE `permission` IN ('mes:qc-inspection-ledger:query', 'mes:qc-inspection-ledger:export') |
| | | OR (`name` = 'æ£æµç»æå°è´¦' AND `type` = 2); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 1. ç¶èåï¼è´¨é管çç®å½ |
| | | -- æ¥ææ£éªæ¥è¯¢æé® -> æ¥ææ£éªèå(type=2) -> è´¨é管çç®å½(type=1) |
| | | -- ------------------------------------------------------------ |
| | | SET @iqc_menu_id = (SELECT `parent_id` FROM `system_menu` |
| | | WHERE `permission` = 'mes:qc-iqc:query' AND `deleted` = b'0' LIMIT 1); |
| | | SET @qc_dir_id = COALESCE( |
| | | (SELECT `parent_id` FROM `system_menu` WHERE `id` = @iqc_menu_id), |
| | | (SELECT `id` FROM `system_menu` WHERE `name` = 'è´¨é管ç' AND `type` = 1 AND `deleted` = b'0' LIMIT 1)); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 2. èåï¼æ£æµç»æå°è´¦ï¼type=2ï¼ |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_menu` (`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT 'æ£æµç»æå°è´¦', '', 2, 14, @qc_dir_id, 'inspection-ledger', 'ep:document', 'mes/qc/ledger/index', 'MesQcInspectionLedger', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0' |
| | | WHERE @qc_dir_id IS NOT NULL; |
| | | SET @menu_ledger = IF(ROW_COUNT() > 0, LAST_INSERT_ID(), NULL); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 3. æé®ï¼æ¥è¯¢ / å¯¼åº |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_menu` (`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT 'æ£æµç»æå°è´¦æ¥è¯¢', 'mes:qc-inspection-ledger:query', 3, 1, @menu_ledger, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0' |
| | | WHERE @menu_ledger IS NOT NULL; |
| | | SET @menu_ledger_query = IF(ROW_COUNT() > 0, LAST_INSERT_ID(), NULL); |
| | | |
| | | INSERT INTO `system_menu` (`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT 'æ£æµç»æå°è´¦å¯¼åº', 'mes:qc-inspection-ledger:export', 3, 2, @menu_ledger, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0' |
| | | WHERE @menu_ledger IS NOT NULL; |
| | | SET @menu_ledger_export = IF(ROW_COUNT() > 0, LAST_INSERT_ID(), NULL); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 4. ææï¼è·éãæ¥ææ£éªæ¥è¯¢ãæé®å·²æçè§è² |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, t.`menu_id`, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | JOIN (SELECT @menu_ledger AS `menu_id` |
| | | UNION ALL SELECT @menu_ledger_query |
| | | UNION ALL SELECT @menu_ledger_export) t |
| | | WHERE rm.`menu_id` = @iqc_menu_id |
| | | AND rm.`deleted` = b'0' |
| | | AND t.`menu_id` IS NOT NULL; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- 5. æ ¡éªï¼èå 3 è¡ï¼ææè¡æ° = 3 Ã ãæ¥ææ£éªæ¥è¯¢ãçè§è²æ° |
| | | -- ------------------------------------------------------------ |
| | | SELECT 'èå æ£æµç»æå°è´¦ ' AS item, COUNT(*) AS cnt FROM `system_menu` |
| | | WHERE `name` = 'æ£æµç»æå°è´¦' AND `type` = 2 AND `deleted` = b'0' |
| | | UNION ALL SELECT 'æé® æ¥è¯¢/å¯¼åº ', COUNT(*) FROM `system_menu` |
| | | WHERE `permission` IN ('mes:qc-inspection-ledger:query', 'mes:qc-inspection-ledger:export') AND `deleted` = b'0' |
| | | UNION ALL SELECT 'ææ 3 个èå ', COUNT(*) FROM `system_role_menu` |
| | | WHERE `menu_id` IN (@menu_ledger, @menu_ledger_query, @menu_ledger_export) AND `deleted` = b'0' |
| | | UNION ALL SELECT 'å¯¹æ¯ æ¥ææ£éªæ¥è¯¢ææè¡æ° ', COUNT(*) FROM `system_role_menu` rm JOIN `system_menu` m ON rm.`menu_id` = m.`id` |
| | | WHERE m.`permission` = 'mes:qc-iqc:query' AND rm.`deleted` = b'0'; |
| | |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.contract.CrmContractRespVO; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceImportExcelVO; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceImportRespVO; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoicePageReqVO; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceRespVO; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceSaveReqVO; |
| | |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | |
| | | buildInvoiceDetailList(list)); |
| | | } |
| | | |
| | | @GetMapping("/get-import-template") |
| | | @Operation(summary = "è·å¾å¯¼å
¥å¼ç¥¨æ¨¡æ¿") |
| | | @PreAuthorize("@ss.hasPermission('crm:invoice:import')") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | List<CrmInvoiceImportExcelVO> list = Collections.singletonList( |
| | | CrmInvoiceImportExcelVO.builder() |
| | | .contractNo("HT20260101000001").invoiceType("å¢å¼ç¨ä¸ç¨å票") |
| | | .invoiceNo("02564178").invoiceTitle("示ä¾å®¢æ·æéå
¬å¸").price(new BigDecimal("10000.00")) |
| | | .invoiceTime("2026-01-01 10:00:00").remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢") |
| | | .build()); |
| | | ExcelUtils.write(response, "å¼ç¥¨å¯¼å
¥æ¨¡æ¿.xls", "å¼ç¥¨", CrmInvoiceImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | | @Operation(summary = "导å
¥å¼ç¥¨") |
| | | @PreAuthorize("@ss.hasPermission('crm:invoice:import')") |
| | | public CommonResult<CrmInvoiceImportRespVO> importInvoiceExcel(@RequestParam("file") MultipartFile file) throws Exception { |
| | | List<CrmInvoiceImportExcelVO> list = ExcelUtils.read(file, CrmInvoiceImportExcelVO.class); |
| | | return success(invoiceService.importInvoiceList(list)); |
| | | } |
| | | |
| | | private List<CrmInvoiceRespVO> buildInvoiceDetailList(List<CrmInvoiceDO> invoiceList) { |
| | | if (CollUtil.isEmpty(invoiceList)) { |
| | | return Collections.emptyList(); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice; |
| | | |
| | | import cn.idev.excel.annotation.ExcelProperty; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * 管çåå° - å¼ç¥¨å¯¼å
¥ Excel VO |
| | | * |
| | | * 说æï¼ä¸è¡ = ä¸å¼ å¼ç¥¨è®°å½ãâååç¼å·â为å¿
å¡«ï¼éä¸ç³»ç»ä¸å·²å®¡æ ¸éè¿çååç¼å·ä¸è´ã |
| | | * 客æ·ãè´è´£äººã审æ¹ç¶æç±ç³»ç»å¤çï¼å®¢æ·åååæå±å®¢æ·ï¼è´è´£äºº = å½åç»å½ç¨æ·ï¼å®¡æ¹ç¶æ = æªæäº¤ã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Schema(description = "管çåå° - å¼ç¥¨å¯¼å
¥ Excel VO") |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class CrmInvoiceImportExcelVO { |
| | | |
| | | @ExcelProperty("å¼ç¥¨ç¼å·") |
| | | @Schema(description = "å¼ç¥¨ç¼å·ï¼ç空åèªå¨çæ", example = "KP20260101000001") |
| | | private String no; |
| | | |
| | | @ExcelProperty("ååç¼å·") |
| | | @Schema(description = "ååç¼å·ï¼éä¸ç³»ç»ä¸å·²å®¡æ ¸éè¿çååç¼å·ä¸è´", requiredMode = Schema.RequiredMode.REQUIRED, example = "HT20260101000001") |
| | | private String contractNo; |
| | | |
| | | @ExcelProperty("å票类å") |
| | | @Schema(description = "å票类åï¼å¡«ååå
¸ crm_invoice_type çåç§°ï¼å¦ å¢å¼ç¨ä¸ç¨å票", requiredMode = Schema.RequiredMode.REQUIRED, example = "å¢å¼ç¨ä¸ç¨å票") |
| | | private String invoiceType; |
| | | |
| | | @ExcelProperty("å票å·ç ") |
| | | @Schema(description = "å票å·ç ", example = "02564178") |
| | | private String invoiceNo; |
| | | |
| | | @ExcelProperty("å票æ¬å¤´") |
| | | @Schema(description = "å票æ¬å¤´", example = "XXç§ææéå
¬å¸") |
| | | private String invoiceTitle; |
| | | |
| | | @ExcelProperty("å¼ç¥¨éé¢(å
)") |
| | | @Schema(description = "å¼ç¥¨éé¢ï¼éå¤§äº 0 ä¸ä¸è¶
è¿ååå©ä½å¯å¼ç¥¨éé¢", requiredMode = Schema.RequiredMode.REQUIRED, example = "10000.00") |
| | | private BigDecimal price; |
| | | |
| | | @ExcelProperty("å¼ç¥¨æ¥æ") |
| | | @Schema(description = "å¼ç¥¨æ¥æï¼æ ¼å¼å¦ 2026-01-01 10:00:00ï¼ç空åå½åæ¶é´", example = "2026-01-01 10:00:00") |
| | | private String invoiceTime; |
| | | |
| | | @ExcelProperty("夿³¨") |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 管çåå° - å¼ç¥¨å¯¼å
¥ Response VO |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Schema(description = "管çåå° - å¼ç¥¨å¯¼å
¥ Response VO") |
| | | @Data |
| | | @Builder |
| | | public class CrmInvoiceImportRespVO { |
| | | |
| | | @Schema(description = "å建æåçå¼ç¥¨ç¼å·æ°ç»", example = "KP20260101000001") |
| | | private List<String> createList; |
| | | |
| | | @Schema(description = "导å
¥å¤±è´¥éåï¼key 为è¡å·æå票å·ç ï¼value 为失败åå ") |
| | | private Map<String, String> failureList; |
| | | |
| | | } |
| | |
| | | return selectCount(CrmInvoiceDO::getContractId, contractId); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ååä¸çå
¨é¨å¼ç¥¨ï¼å¯¼å
¥å»éç¨ï¼ |
| | | */ |
| | | default List<CrmInvoiceDO> selectListByContractId(Long contractId) { |
| | | return selectList(new LambdaQueryWrapperX<CrmInvoiceDO>() |
| | | .eq(CrmInvoiceDO::getContractId, contractId) |
| | | .orderByAsc(CrmInvoiceDO::getId)); |
| | | } |
| | | |
| | | } |
| | |
| | | CrmContractDO getContract(Long id); |
| | | |
| | | /** |
| | | * è·å¾ååï¼åºäºååç¼å· |
| | | * |
| | | * @param no ååç¼å· |
| | | * @return åå |
| | | */ |
| | | CrmContractDO getContractByNo(String no); |
| | | |
| | | /** |
| | | * æ ¡éªå忝å¦åæ³ |
| | | * |
| | | * @param id ç¼å· |
| | |
| | | } |
| | | |
| | | @Override |
| | | public CrmContractDO getContractByNo(String no) { |
| | | return contractMapper.selectByNo(no); |
| | | } |
| | | |
| | | @Override |
| | | public CrmContractDO validateContract(Long id) { |
| | | return validateContractExists(id); |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.crm.service.invoice; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceImportExcelVO; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceImportRespVO; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoicePageReqVO; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceSaveReqVO; |
| | | import cn.iocoder.yudao.module.crm.dal.dataobject.invoice.CrmInvoiceDO; |
| | |
| | | Long createInvoice(@Valid CrmInvoiceSaveReqVO createReqVO); |
| | | |
| | | /** |
| | | * 导å
¥å¼ç¥¨ |
| | | * |
| | | * @param importList 导å
¥çå¼ç¥¨å表 |
| | | * @return 导å
¥ç»æ |
| | | */ |
| | | CrmInvoiceImportRespVO importInvoiceList(List<CrmInvoiceImportExcelVO> importList); |
| | | |
| | | /** |
| | | * æ´æ°å¼ç¥¨ |
| | | * |
| | | * @param updateReqVO æ´æ°ä¿¡æ¯ |
| | |
| | | import cn.hutool.core.lang.Assert; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| | | import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; |
| | | import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi; |
| | | import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceImportExcelVO; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceImportRespVO; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoicePageReqVO; |
| | | import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceSaveReqVO; |
| | | import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO; |
| | |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.HashMap; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | | import static cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_INVOICE_TYPE; |
| | | import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*; |
| | | import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*; |
| | | import static cn.iocoder.yudao.module.crm.util.CrmAuditStatusUtils.convertBpmResultToAuditStatus; |
| | |
| | | return invoice.getId(); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public CrmInvoiceImportRespVO importInvoiceList(List<CrmInvoiceImportExcelVO> importList) { |
| | | CrmInvoiceImportRespVO respVO = CrmInvoiceImportRespVO.builder() |
| | | .createList(new ArrayList<>()) |
| | | .failureList(new LinkedHashMap<>()) |
| | | .build(); |
| | | if (CollUtil.isEmpty(importList)) { |
| | | return respVO; |
| | | } |
| | | |
| | | Map<String, Integer> firstRowNoByKey = new HashMap<>(); |
| | | for (int i = 0; i < importList.size(); i++) { |
| | | CrmInvoiceImportExcelVO row = importList.get(i); |
| | | if (isImportRowEmpty(row)) { |
| | | continue; // è·³è¿ç©ºè¡ |
| | | } |
| | | String label = StrUtil.isNotBlank(row.getInvoiceNo()) ? "å票å·ç " + row.getInvoiceNo().trim() |
| | | : "第 " + (i + 2) + " è¡"; |
| | | String importKey = buildInvoiceImportKey(row); |
| | | try { |
| | | Integer firstRowNo = firstRowNoByKey.get(importKey); |
| | | if (firstRowNo != null) { |
| | | throw duplicateRowException(firstRowNo, buildInvoiceKeyDesc(row)); |
| | | } |
| | | respVO.getCreateList().add(createInvoiceByImport(row)); |
| | | firstRowNoByKey.putIfAbsent(importKey, i + 2); |
| | | } catch (Exception ex) { |
| | | respVO.getFailureList().put(label, resolveImportErrorMessage(ex)); |
| | | } |
| | | } |
| | | return respVO; |
| | | } |
| | | |
| | | private boolean isImportRowEmpty(CrmInvoiceImportExcelVO row) { |
| | | return row == null || (StrUtil.isBlank(row.getNo()) && StrUtil.isBlank(row.getContractNo()) |
| | | && StrUtil.isBlank(row.getInvoiceType()) && StrUtil.isBlank(row.getInvoiceNo()) |
| | | && StrUtil.isBlank(row.getInvoiceTitle()) && row.getPrice() == null |
| | | && StrUtil.isBlank(row.getInvoiceTime()) && StrUtil.isBlank(row.getRemark())); |
| | | } |
| | | |
| | | /** |
| | | * 便®å¯¼å
¥æ°æ®å建ä¸å¼ å¼ç¥¨ã客æ·åååæå±å®¢æ·ï¼è´è´£äºº=å½åç»å½ç¨æ·ï¼å®¡æ¹ç¶æ=æªæäº¤ã |
| | | */ |
| | | private String createInvoiceByImport(CrmInvoiceImportExcelVO row) { |
| | | // 1. ååæ ¡éª |
| | | if (StrUtil.isBlank(row.getContractNo())) { |
| | | throw new IllegalArgumentException("ååç¼å·ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çãååç¼å·ãå"); |
| | | } |
| | | CrmContractDO contract = contractService.getContractByNo(row.getContractNo().trim()); |
| | | if (contract == null) { |
| | | throw new IllegalArgumentException("ååç¼å·ä¸åå¨ï¼" + row.getContractNo().trim() |
| | | + "ã请å
å¨ãCRM åå管çãä¸å建æå¯¼å
¥è¯¥ååï¼ç¼å·é䏿¨¡æ¿å®å
¨ä¸è´ï¼ï¼æä¿®æ¹æ¨¡æ¿ä¸çååç¼å·å鿰坼å
¥"); |
| | | } |
| | | if (ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.APPROVE.getStatus())) { |
| | | throw new IllegalArgumentException("åå[" + contract.getNo() + "]å½åç¶æä¸ºã" |
| | | + CrmAuditStatusEnum.getNameByStatus(contract.getAuditStatus()) + "ãï¼åªæãå®¡æ ¸éè¿ãçååæè½å¼ç¥¨ã" |
| | | + "请å
å¨ãCRM åå管çãä¸å®æè¯¥åå审æ¹ï¼ææ¹ç¨å
¶ä»å·²å®¡æ ¸éè¿çååç¼å·å鿰坼å
¥"); |
| | | } |
| | | |
| | | // 2. å¼ç¥¨é颿 ¡éª |
| | | if (row.getPrice() == null) { |
| | | throw new IllegalArgumentException("å¼ç¥¨éé¢ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çãå¼ç¥¨éé¢(å
)ãå"); |
| | | } |
| | | if (row.getPrice().compareTo(BigDecimal.ZERO) <= 0) { |
| | | throw new IllegalArgumentException("å¼ç¥¨éé¢å¿
é¡»å¤§äº 0ï¼å½å为 " |
| | | + row.getPrice().stripTrailingZeros().toPlainString() + "ãè¯·ä¿®æ¹æ¨¡æ¿ä¸çãå¼ç¥¨éé¢(å
)ãå鿰坼å
¥"); |
| | | } |
| | | BigDecimal remainingInvoicePrice = getRemainingInvoicePrice(contract, null); |
| | | if (row.getPrice().compareTo(remainingInvoicePrice) > 0) { |
| | | throw new IllegalArgumentException("å¼ç¥¨éé¢è¶
è¿ååå©ä½å¯å¼ç¥¨éé¢ï¼åå[" + contract.getNo() |
| | | + "]å©ä½å¯å¼ç¥¨éé¢ " + remainingInvoicePrice.stripTrailingZeros().toPlainString() + " å
ï¼æ¬æ¬¡å¯¼å
¥éé¢ " |
| | | + row.getPrice().stripTrailingZeros().toPlainString() |
| | | + " å
ãè¯·è°æ´æ¨¡æ¿ä¸çãå¼ç¥¨éé¢(å
)ãï¼æå
å¨ç³»ç»ä¸æ ¸å¯¹å·²å¼ç¥¨éé¢å鿰坼å
¥"); |
| | | } |
| | | |
| | | // 3. åç¥¨ç±»åæ ¡éª |
| | | Integer invoiceType = resolveInvoiceType(row.getInvoiceType()); |
| | | |
| | | // 4. å¼ç¥¨ç¼å·ï¼å¡«åå使ç¨ï¼ç空åèªå¨çæ |
| | | String no = StrUtil.isNotBlank(row.getNo()) ? row.getNo().trim() |
| | | : noRedisDAO.generate(CrmNoRedisDAO.INVOICE_PREFIX); |
| | | if (invoiceMapper.selectByNo(no) != null) { |
| | | throw new IllegalArgumentException("å¼ç¥¨ç¼å·å·²åå¨ï¼" + no |
| | | + "ãè¯·ä¿®æ¹æ¨¡æ¿ä¸çå¼ç¥¨ç¼å·ï¼æå
å¨ç³»ç»ä¸å é¤è¯¥ç¼å·çå¼ç¥¨å鿰坼å
¥"); |
| | | } |
| | | |
| | | // 5. å»éï¼åä¸ååä¸ï¼å票å·ç ï¼çç©ºæ¶æå¼ç¥¨éé¢ãå票æ¬å¤´ãå¼ç¥¨æ¥æï¼ç¸åçå¼ç¥¨ä¸å¯éå¤å¯¼å
¥ |
| | | // å¼ç¥¨æ¥æç空æ¶è§ä½ä¸æ¯è¾è¯¥ç»´åº¦ï¼æ
æâæ¯å¦å¡«åâä¼ nullï¼ä¸è½ç¨ parseImportDateTime ç now() å
åºå¼ |
| | | LocalDateTime invoiceTime = parseImportDateTime(row.getInvoiceTime()); |
| | | CrmInvoiceDO duplicate = findDuplicateInvoice(contract.getId(), row, |
| | | StrUtil.isNotBlank(row.getInvoiceTime()) ? invoiceTime : null); |
| | | if (duplicate != null) { |
| | | throw duplicateExistingException(buildInvoiceKeyDesc(row), duplicate.getNo()); |
| | | } |
| | | |
| | | // 6. ä¿åå¼ç¥¨ |
| | | CrmInvoiceDO invoice = new CrmInvoiceDO().setNo(no).setCustomerId(contract.getCustomerId()) |
| | | .setContractId(contract.getId()).setOwnerUserId(getLoginUserId()).setInvoiceType(invoiceType) |
| | | .setInvoiceNo(row.getInvoiceNo()).setInvoiceTitle(row.getInvoiceTitle()).setPrice(row.getPrice()) |
| | | .setInvoiceTime(invoiceTime).setRemark(row.getRemark()) |
| | | .setAuditStatus(CrmAuditStatusEnum.DRAFT.getStatus()); |
| | | invoiceMapper.insert(invoice); |
| | | |
| | | // 7. åå»ºæ°æ®æéï¼å¦åå½åç¨æ·çä¸å°è¯¥å¼ç¥¨ï¼ |
| | | permissionService.createPermission(new CrmPermissionCreateReqBO().setBizType(CrmBizTypeEnum.CRM_INVOICE.getType()) |
| | | .setBizId(invoice.getId()).setUserId(invoice.getOwnerUserId()) |
| | | .setLevel(CrmPermissionLevelEnum.OWNER.getLevel())); |
| | | return invoice.getNo(); |
| | | } |
| | | |
| | | private Integer resolveInvoiceType(String text) { |
| | | List<String> labelList = DictFrameworkUtils.getDictDataLabelList(CRM_INVOICE_TYPE); |
| | | if (StrUtil.isBlank(text)) { |
| | | throw new IllegalArgumentException("å票类åä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çãå票类åãåï¼å¯éå¼ï¼" |
| | | + String.join("ã", labelList)); |
| | | } |
| | | String value = text.trim(); |
| | | if (value.matches("\\d+") && DictFrameworkUtils.getDictDataValueList(CRM_INVOICE_TYPE).contains(value)) { |
| | | return Integer.valueOf(value); |
| | | } |
| | | String parsedValue = DictFrameworkUtils.parseDictDataValue(CRM_INVOICE_TYPE, value); |
| | | if (parsedValue == null) { |
| | | throw new IllegalArgumentException("å票类åä¸åå¨ï¼" + value + "ãæ¨¡æ¿ä¸ãå票类åã请填å以ä¸ä¹ä¸ï¼" |
| | | + String.join("ã", labelList)); |
| | | } |
| | | return Integer.valueOf(parsedValue); |
| | | } |
| | | |
| | | private LocalDateTime parseImportDateTime(String text) { |
| | | if (StrUtil.isBlank(text)) { |
| | | return LocalDateTime.now(); |
| | | } |
| | | String value = text.trim(); |
| | | for (String pattern : new String[]{"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd HH:mm:ss"}) { |
| | | try { |
| | | return LocalDateTime.parse(value, DateTimeFormatter.ofPattern(pattern)); |
| | | } catch (Exception ignored) { |
| | | // ç»§ç»å°è¯ä¸ä¸ä¸ªæ ¼å¼ |
| | | } |
| | | } |
| | | for (String pattern : new String[]{"yyyy-MM-dd", "yyyy/M/d"}) { |
| | | try { |
| | | return java.time.LocalDate.parse(value, DateTimeFormatter.ofPattern(pattern)).atStartOfDay(); |
| | | } catch (Exception ignored) { |
| | | // ç»§ç»å°è¯ä¸ä¸ä¸ªæ ¼å¼ |
| | | } |
| | | } |
| | | throw new IllegalArgumentException("å¼ç¥¨æ¥ææ ¼å¼ä¸æ£ç¡®ï¼" + text + "ï¼ç¤ºä¾ 2026-01-01 10:00:00"); |
| | | } |
| | | |
| | | private String resolveImportErrorMessage(Exception ex) { |
| | | if (ex instanceof cn.iocoder.yudao.framework.common.exception.ServiceException serviceException) { |
| | | return serviceException.getMessage(); |
| | | } |
| | | return StrUtil.blankToDefault(ex.getMessage(), "导å
¥å¤±è´¥"); |
| | | } |
| | | |
| | | /** |
| | | * 导å
¥å»éé®ï¼å票å·ç 填忶以 åå + å票å·ç 为åï¼çç©ºæ¶æ¯è¾ åå + å¼ç¥¨éé¢ + å票æ¬å¤´ + å¼ç¥¨æ¥æ |
| | | */ |
| | | private String buildInvoiceImportKey(CrmInvoiceImportExcelVO row) { |
| | | if (StrUtil.isNotBlank(row.getInvoiceNo())) { |
| | | return "no|" + StrUtil.trimToEmpty(row.getContractNo()) + "|" + row.getInvoiceNo().trim(); |
| | | } |
| | | return "amt|" + StrUtil.trimToEmpty(row.getContractNo()) + "|" |
| | | + (row.getPrice() == null ? "" : row.getPrice().stripTrailingZeros().toPlainString()) + "|" |
| | | + StrUtil.trimToEmpty(row.getInvoiceTitle()) + "|" + StrUtil.trimToEmpty(row.getInvoiceTime()); |
| | | } |
| | | |
| | | private String buildInvoiceKeyDesc(CrmInvoiceImportExcelVO row) { |
| | | if (StrUtil.isNotBlank(row.getInvoiceNo())) { |
| | | return "ååç¼å·[" + StrUtil.trimToEmpty(row.getContractNo()) + "]ãå票å·ç [" + row.getInvoiceNo().trim() + "]"; |
| | | } |
| | | return "ååç¼å·[" + StrUtil.trimToEmpty(row.getContractNo()) + "]ãå¼ç¥¨éé¢[" |
| | | + (row.getPrice() == null ? "æªå¡«å" : row.getPrice().stripTrailingZeros().toPlainString() + " å
") |
| | | + "]ãå票æ¬å¤´[" + StrUtil.blankToDefault(StrUtil.trimToNull(row.getInvoiceTitle()), "æªå¡«å") + "]" |
| | | + (StrUtil.isBlank(row.getInvoiceTime()) ? "" : "ãå¼ç¥¨æ¥æ[" + row.getInvoiceTime().trim() + "]"); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢åååä¸ä¸å¡æ°æ®å®å
¨ç¸åçå¼ç¥¨ |
| | | */ |
| | | private CrmInvoiceDO findDuplicateInvoice(Long contractId, CrmInvoiceImportExcelVO row, LocalDateTime invoiceTime) { |
| | | for (CrmInvoiceDO old : invoiceMapper.selectListByContractId(contractId)) { |
| | | if (StrUtil.isNotBlank(row.getInvoiceNo())) { |
| | | if (StrUtil.equals(StrUtil.trimToEmpty(old.getInvoiceNo()), row.getInvoiceNo().trim())) { |
| | | return old; |
| | | } |
| | | continue; |
| | | } |
| | | // å票å·ç ç空æ¶ï¼æ¯è¾å¼ç¥¨éé¢ãå票æ¬å¤´ï¼å¼ç¥¨æ¥æç空å䏿¯è¾è¯¥ç»´åº¦ |
| | | if (old.getPrice().compareTo(row.getPrice()) != 0 |
| | | || !StrUtil.equals(StrUtil.trimToEmpty(old.getInvoiceTitle()), |
| | | StrUtil.trimToEmpty(row.getInvoiceTitle()))) { |
| | | continue; |
| | | } |
| | | if (invoiceTime != null && !invoiceTime.equals(old.getInvoiceTime())) { |
| | | continue; |
| | | } |
| | | return old; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private IllegalArgumentException duplicateRowException(int firstRowNo, String keyDesc) { |
| | | return new IllegalArgumentException("æ£æµå°éå¤å¯¼å
¥ï¼æ¬æ¬¡å¯¼å
¥ç第 " + firstRowNo |
| | | + " è¡ä¸å½åè¡çæ°æ®å®å
¨ç¸åï¼" + keyDesc + "ï¼ã请å 餿¨¡æ¿ä¸éå¤çè¡å鿰坼å
¥"); |
| | | } |
| | | |
| | | private IllegalArgumentException duplicateExistingException(String keyDesc, String existingNo) { |
| | | return new IllegalArgumentException("æ£æµå°éå¤å¯¼å
¥ï¼" + keyDesc + " ä¸å·²æå¼ç¥¨åã" + existingNo |
| | | + "ãå®å
¨ç¸åï¼å¯è½æ¯æ¬æ¬¡å¯¼å
¥åé¢çè¡ï¼ä¹å¯è½æ¯ç³»ç»ä¸å·²æåæ®ï¼ã请å¿éå¤å¯¼å
¥ï¼å¦ç¡®é鿰坼å
¥ï¼è¯·å
å¨ãè¥é管ç-å¼ç¥¨ç®¡çãä¸å é¤è¯¥å¼ç¥¨ååéè¯"); |
| | | } |
| | | |
| | | private void validateInvoicePriceExceedsLimit(CrmInvoiceSaveReqVO reqVO) { |
| | | // 1. 计ç®å©ä½å¯å¼ç¥¨éé¢ï¼ä¸å
æ¬ reqVO èªèº«ï¼å®¡æ¹ä¸ä¹å ç¨é¢åº¦ï¼é²æ¢ç´¯è®¡å¼ç¥¨è¶
è¿ååéé¢ï¼ |
| | | CrmContractDO contract = contractService.validateContract(reqVO.getContractId()); |
| | | List<CrmInvoiceDO> invoices = invoiceMapper.selectListByContractIdAndStatus(reqVO.getContractId(), |
| | | List.of(CrmAuditStatusEnum.APPROVE.getStatus(), CrmAuditStatusEnum.PROCESS.getStatus())); |
| | | if (reqVO.getId() != null) { |
| | | invoices.removeIf(invoice -> ObjectUtil.equal(invoice.getId(), reqVO.getId())); |
| | | } |
| | | BigDecimal notInvoicePrice = contract.getTotalPrice().subtract( |
| | | CollectionUtils.getSumValue(invoices, CrmInvoiceDO::getPrice, BigDecimal::add, BigDecimal.ZERO)); |
| | | BigDecimal notInvoicePrice = getRemainingInvoicePrice(contract, reqVO.getId()); |
| | | // 2. æ ¡éªé颿¯å¦è¶
è¿ |
| | | if (reqVO.getPrice().compareTo(notInvoicePrice) > 0) { |
| | | throw exception(INVOICE_CREATE_FAIL_PRICE_EXCEEDS_LIMIT, notInvoicePrice); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 计ç®ååå©ä½å¯å¼ç¥¨éé¢ï¼å®¡æ¹ä¸ãå®¡æ ¸éè¿çå¼ç¥¨å ç¨é¢åº¦ï¼ |
| | | * |
| | | * @param contract åå |
| | | * @param excludeInvoiceId éæé¤çå¼ç¥¨ç¼å·ï¼å¯ä¸ºç©º |
| | | */ |
| | | private BigDecimal getRemainingInvoicePrice(CrmContractDO contract, Long excludeInvoiceId) { |
| | | List<CrmInvoiceDO> invoices = invoiceMapper.selectListByContractIdAndStatus(contract.getId(), |
| | | List.of(CrmAuditStatusEnum.APPROVE.getStatus(), CrmAuditStatusEnum.PROCESS.getStatus())); |
| | | if (excludeInvoiceId != null) { |
| | | invoices.removeIf(invoice -> ObjectUtil.equal(invoice.getId(), excludeInvoiceId)); |
| | | } |
| | | return contract.getTotalPrice().subtract( |
| | | CollectionUtils.getSumValue(invoices, CrmInvoiceDO::getPrice, BigDecimal::add, BigDecimal.ZERO)); |
| | | } |
| | | |
| | | private void validateRelationDataExists(CrmInvoiceSaveReqVO reqVO) { |
| | | if (reqVO.getOwnerUserId() != null) { |
| | | adminUserApi.validateUser(reqVO.getOwnerUserId()); // æ ¡éªè´è´£äººåå¨ |
| | |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcQualityExportVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicatorresult.MesQcIndicatorResultDO; |
| | |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | |
| | | ExcelUtils.write(response, "è¿ç¨æ£éªå.xls", "æ°æ®", MesQcQualityExportVO.class, exportList); |
| | | } |
| | | |
| | | @GetMapping("/get-import-template") |
| | | @Operation(summary = "è·å¾å¯¼å
¥è¿ç¨æ£éªå模æ¿") |
| | | @PreAuthorize("@ss.hasPermission('mes:qc-ipqc:import')") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | List<MesQcIpqcImportExcelVO> list = Collections.singletonList( |
| | | MesQcIpqcImportExcelVO.builder() |
| | | .name("示ä¾-ç©æAè¿ç¨æ£éª").type("馿£").itemCode("WL0001").batchCode("BC20260101") |
| | | .templateName("").checkQuantity(new BigDecimal("100")) |
| | | .qualifiedQuantity(new BigDecimal("95")).unqualifiedQuantity(new BigDecimal("5")) |
| | | .laborScrapQuantity(new BigDecimal("2")).materialScrapQuantity(new BigDecimal("2")) |
| | | .otherScrapQuantity(new BigDecimal("1")).checkResult("æ ¡éªéè¿").inspectorName("") |
| | | .inspectDate("2026-01-01 10:00:00").remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢") |
| | | .build()); |
| | | ExcelUtils.write(response, "è¿ç¨æ£éªå导å
¥æ¨¡æ¿.xls", "è¿ç¨æ£éª", MesQcIpqcImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | | @Operation(summary = "导å
¥è¿ç¨æ£éªå") |
| | | @PreAuthorize("@ss.hasPermission('mes:qc-ipqc:import')") |
| | | public CommonResult<MesQcImportRespVO> importIpqcExcel(@RequestParam("file") MultipartFile file) throws Exception { |
| | | List<MesQcIpqcImportExcelVO> list = ExcelUtils.read(file, MesQcIpqcImportExcelVO.class); |
| | | return success(ipqcService.importIpqcList(list)); |
| | | } |
| | | |
| | | // ==================== æ¼æ¥ VO ==================== |
| | | |
| | | private List<MesQcIpqcRespVO> buildIpqcRespVOList(List<MesQcIpqcDO> list) { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo; |
| | | |
| | | import cn.idev.excel.annotation.ExcelProperty; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * 管çåå° - è¿ç¨æ£éªå导å
¥ Excel VO |
| | | * |
| | | * 说æï¼ä¸è¡ = ä¸å¼ è¿ç¨æ£éªåã产åç©ææç©æç¼ç å¹é
ç³»ç»å·²ææ°æ®ï¼ç©ææ¥èª MDMï¼ï¼æ¹å·å¿
å¡«ï¼ |
| | | * è´¨æ£æ¹æ¡æåç§°å¹é
ç³»ç»å·²ææ°æ®ï¼æ£æµäººåç空åå½åç»å½ç¨æ·ï¼æ£éªåç¼å·ç空èªå¨çæï¼ç¶æåºå®ä¸ºãå¾
æ£éªãã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Schema(description = "管çåå° - è¿ç¨æ£éªå导å
¥ Excel VO") |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class MesQcIpqcImportExcelVO { |
| | | |
| | | @ExcelProperty("æ£éªåç¼å·") |
| | | @Schema(description = "æ£éªåç¼å·ï¼ç空åèªå¨çæ", example = "IPQC20260101000001") |
| | | private String code; |
| | | |
| | | @ExcelProperty("æ£éªååç§°") |
| | | @Schema(description = "æ£éªååç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "XXæ¹å·è¿ç¨æ£éª") |
| | | private String name; |
| | | |
| | | @ExcelProperty("æ£éªç±»å") |
| | | @Schema(description = "æ£éªç±»åï¼å¡«ååå
¸ mes_ipqc_type çåç§°ï¼å¦ 馿£", requiredMode = Schema.RequiredMode.REQUIRED, example = "馿£") |
| | | private String type; |
| | | |
| | | @ExcelProperty("产åç©æç¼ç ") |
| | | @Schema(description = "产åç©æç¼ç ï¼éä¸ç©æç®¡çä¸çç¼ç ä¸è´", requiredMode = Schema.RequiredMode.REQUIRED, example = "WL001") |
| | | private String itemCode; |
| | | |
| | | @ExcelProperty("æ¹å·") |
| | | @Schema(description = "æ¹å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "BC20260101") |
| | | private String batchCode; |
| | | |
| | | @ExcelProperty("è´¨æ£æ¹æ¡") |
| | | @Schema(description = "è´¨æ£æ¹æ¡åç§°ï¼ç空åæç©æèªå¨å¹é
", example = "è¿ç¨æ£éªéç¨æ¹æ¡") |
| | | private String templateName; |
| | | |
| | | @ExcelProperty("æ£æµæ°é") |
| | | @Schema(description = "æ£æµæ°éï¼ç空é»è®¤çäºåæ ¼åæ°éä¸ä¸åæ ¼åæ°éä¹å", example = "100") |
| | | private BigDecimal checkQuantity; |
| | | |
| | | @ExcelProperty("åæ ¼åæ°é") |
| | | @Schema(description = "åæ ¼åæ°éï¼ä¸è½å°äº 0", requiredMode = Schema.RequiredMode.REQUIRED, example = "95") |
| | | private BigDecimal qualifiedQuantity; |
| | | |
| | | @ExcelProperty("ä¸åæ ¼åæ°é") |
| | | @Schema(description = "ä¸åæ ¼åæ°éï¼ä¸è½å°äº 0", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") |
| | | private BigDecimal unqualifiedQuantity; |
| | | |
| | | @ExcelProperty("å·¥åºæ°é") |
| | | @Schema(description = "å·¥åºæ°éï¼ä¸è½å°äº 0ï¼ç空æ 0 å¤ç", example = "2") |
| | | private BigDecimal laborScrapQuantity; |
| | | |
| | | @ExcelProperty("æåºæ°é") |
| | | @Schema(description = "æåºæ°éï¼ä¸è½å°äº 0ï¼ç空æ 0 å¤ç", example = "2") |
| | | private BigDecimal materialScrapQuantity; |
| | | |
| | | @ExcelProperty("å
¶ä»åºåæ°é") |
| | | @Schema(description = "å
¶ä»åºåæ°éï¼ä¸è½å°äº 0ï¼ç空æ 0 å¤ç", example = "1") |
| | | private BigDecimal otherScrapQuantity; |
| | | |
| | | @ExcelProperty("æ£æµç»æ") |
| | | @Schema(description = "æ£æµç»æï¼å¡«ååå
¸ mes_qc_check_result çåç§°ï¼å¦ æ ¡éªéè¿", example = "æ ¡éªéè¿") |
| | | private String checkResult; |
| | | |
| | | @ExcelProperty("æ£æµäººå") |
| | | @Schema(description = "æ£æµäººåå§åï¼ç空åå½åç»å½ç¨æ·", example = "å¼ ä¸") |
| | | private String inspectorName; |
| | | |
| | | @ExcelProperty("æ£æµæ¥æ") |
| | | @Schema(description = "æ£æµæ¥æï¼æ ¼å¼å¦ 2026-01-01 10:00:00ï¼ç空表示æªå¡«å", example = "2026-01-01 10:00:00") |
| | | private String inspectDate; |
| | | |
| | | @ExcelProperty("夿³¨") |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcQualityExportVO; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | |
| | | ExcelUtils.write(response, "æ¥ææ£éªå.xls", "æ°æ®", MesQcQualityExportVO.class, exportList); |
| | | } |
| | | |
| | | @GetMapping("/get-import-template") |
| | | @Operation(summary = "è·å¾å¯¼å
¥æ¥ææ£éªå模æ¿") |
| | | @PreAuthorize("@ss.hasPermission('mes:qc-iqc:import')") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | List<MesQcIqcImportExcelVO> list = Collections.singletonList( |
| | | MesQcIqcImportExcelVO.builder() |
| | | .name("示ä¾-ç©æAæ¥ææ£éª").itemCode("WL0001").vendorName("示ä¾ä¾åºåæéå
¬å¸") |
| | | .vendorBatch("VB20260101").templateName("") |
| | | .receivedQuantity(new BigDecimal("100")).qualifiedQuantity(new BigDecimal("99")) |
| | | .unqualifiedQuantity(new BigDecimal("1")).checkResult("æ ¡éªéè¿").inspectorName("") |
| | | .inspectDate("2026-01-01 10:00:00").receiveDate("2026-01-01 09:00:00") |
| | | .remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢") |
| | | .build()); |
| | | ExcelUtils.write(response, "æ¥ææ£éªå导å
¥æ¨¡æ¿.xls", "æ¥ææ£éª", MesQcIqcImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | | @Operation(summary = "导å
¥æ¥ææ£éªå") |
| | | @PreAuthorize("@ss.hasPermission('mes:qc-iqc:import')") |
| | | public CommonResult<MesQcImportRespVO> importIqcExcel(@RequestParam("file") MultipartFile file) throws Exception { |
| | | List<MesQcIqcImportExcelVO> list = ExcelUtils.read(file, MesQcIqcImportExcelVO.class); |
| | | return success(iqcService.importIqcList(list)); |
| | | } |
| | | |
| | | // ==================== æ¼æ¥ VO ==================== |
| | | |
| | | private List<MesQcIqcRespVO> buildIqcRespVOList(List<MesQcIqcDO> list) { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo; |
| | | |
| | | import cn.idev.excel.annotation.ExcelProperty; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * 管çåå° - æ¥ææ£éªå导å
¥ Excel VO |
| | | * |
| | | * 说æï¼ä¸è¡ = ä¸å¼ æ¥ææ£éªåãç©æãä¾åºåãè´¨æ£æ¹æ¡åæåç§°/ç¼ç å¹é
ç³»ç»å·²ææ°æ®ï¼ |
| | | * æ£æµäººåç空åå½åç»å½ç¨æ·ï¼æ£éªåç¼å·ç空èªå¨çæï¼ç¶æåºå®ä¸ºãå¾
æ£éªãã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Schema(description = "管çåå° - æ¥ææ£éªå导å
¥ Excel VO") |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class MesQcIqcImportExcelVO { |
| | | |
| | | @ExcelProperty("æ£éªåç¼å·") |
| | | @Schema(description = "æ£éªåç¼å·ï¼ç空åèªå¨çæ", example = "IQC20260101000001") |
| | | private String code; |
| | | |
| | | @ExcelProperty("æ£éªååç§°") |
| | | @Schema(description = "æ£éªååç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "ç©æAæ¥ææ£éª") |
| | | private String name; |
| | | |
| | | @ExcelProperty("产åç©æç¼ç ") |
| | | @Schema(description = "产åç©æç¼ç ï¼éä¸ç©æç®¡çä¸çç¼ç ä¸è´", requiredMode = Schema.RequiredMode.REQUIRED, example = "WL001") |
| | | private String itemCode; |
| | | |
| | | @ExcelProperty("ä¾åºååç§°") |
| | | @Schema(description = "ä¾åºååç§°ï¼éä¸ä¾åºå管çä¸çåç§°ä¸è´", example = "示ä¾ä¾åºåæéå
¬å¸") |
| | | private String vendorName; |
| | | |
| | | @ExcelProperty("ä¾åºåæ¹æ¬¡å·") |
| | | @Schema(description = "ä¾åºåæ¹æ¬¡å·", example = "VB20260101") |
| | | private String vendorBatch; |
| | | |
| | | @ExcelProperty("è´¨æ£æ¹æ¡") |
| | | @Schema(description = "è´¨æ£æ¹æ¡åç§°ï¼ç空åæç©æèªå¨å¹é
", example = "æ¥ææ£éªéç¨æ¹æ¡") |
| | | private String templateName; |
| | | |
| | | @ExcelProperty("æ¬æ¬¡æ¥æ¶æ°é") |
| | | @Schema(description = "æ¬æ¬¡æ¥æ¶æ°éï¼ç空é»è®¤çäºåæ ¼åæ°éä¸ä¸åæ ¼åæ°éä¹å", example = "100") |
| | | private BigDecimal receivedQuantity; |
| | | |
| | | @ExcelProperty("åæ ¼åæ°é") |
| | | @Schema(description = "åæ ¼åæ°éï¼ä¸è½å°äº 0", requiredMode = Schema.RequiredMode.REQUIRED, example = "99") |
| | | private BigDecimal qualifiedQuantity; |
| | | |
| | | @ExcelProperty("ä¸åæ ¼åæ°é") |
| | | @Schema(description = "ä¸åæ ¼åæ°éï¼ä¸è½å°äº 0", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private BigDecimal unqualifiedQuantity; |
| | | |
| | | @ExcelProperty("æ£æµç»æ") |
| | | @Schema(description = "æ£æµç»æï¼å¡«ååå
¸ mes_qc_check_result çåç§°ï¼å¦ æ ¡éªéè¿", example = "æ ¡éªéè¿") |
| | | private String checkResult; |
| | | |
| | | @ExcelProperty("æ£æµäººå") |
| | | @Schema(description = "æ£æµäººåå§åï¼ç空åå½åç»å½ç¨æ·", example = "å¼ ä¸") |
| | | private String inspectorName; |
| | | |
| | | @ExcelProperty("æ£æµæ¥æ") |
| | | @Schema(description = "æ£æµæ¥æï¼æ ¼å¼å¦ 2026-01-01 10:00:00", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-01-01 10:00:00") |
| | | private String inspectDate; |
| | | |
| | | @ExcelProperty("æ¥ææ¥æ") |
| | | @Schema(description = "æ¥ææ¥æï¼æ ¼å¼å¦ 2026-01-01 10:00:00", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-01-01 10:00:00") |
| | | private String receiveDate; |
| | | |
| | | @ExcelProperty("夿³¨") |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.qc.ledger; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; |
| | | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo.MesQcInspectionLedgerExportVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo.MesQcInspectionLedgerPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo.MesQcInspectionLedgerRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcQualityExportVO; |
| | | import cn.iocoder.yudao.module.mes.enums.DictTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.qc.ledger.MesQcInspectionLedgerService; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import jakarta.annotation.Resource; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import jakarta.validation.Valid; |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.GetMapping; |
| | | import org.springframework.web.bind.annotation.RequestMapping; |
| | | import org.springframework.web.bind.annotation.RestController; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Objects; |
| | | |
| | | import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | | |
| | | @Tag(name = "管çåå° - MES æ£æµç»æå°è´¦") |
| | | @RestController |
| | | @RequestMapping("/mes/qc/inspection-ledger") |
| | | @Validated |
| | | public class MesQcInspectionLedgerController { |
| | | |
| | | @Resource |
| | | private MesQcInspectionLedgerService ledgerService; |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾æ£æµç»æå°è´¦å页ï¼åç±»æ£éªåç»ä¸æ¥è¯¢ï¼") |
| | | @PreAuthorize("@ss.hasPermission('mes:qc-inspection-ledger:query')") |
| | | public CommonResult<PageResult<MesQcInspectionLedgerRespVO>> getInspectionLedgerPage( |
| | | @Valid MesQcInspectionLedgerPageReqVO pageReqVO) { |
| | | return success(ledgerService.getInspectionLedgerPage(pageReqVO)); |
| | | } |
| | | |
| | | @GetMapping("/export-excel") |
| | | @Operation(summary = "å¯¼åºæ£æµç»æå°è´¦ Excel") |
| | | @PreAuthorize("@ss.hasPermission('mes:qc-inspection-ledger:export')") |
| | | @ApiAccessLog(operateType = EXPORT) |
| | | public void exportInspectionLedgerExcel(@Valid MesQcInspectionLedgerPageReqVO pageReqVO, |
| | | HttpServletResponse response) throws IOException { |
| | | pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); |
| | | List<MesQcInspectionLedgerRespVO> list = ledgerService.getInspectionLedgerPage(pageReqVO).getList(); |
| | | ExcelUtils.write(response, "æ£æµç»æå°è´¦.xls", "æ£æµç»æå°è´¦", |
| | | MesQcInspectionLedgerExportVO.class, buildExportList(list)); |
| | | } |
| | | |
| | | private List<MesQcInspectionLedgerExportVO> buildExportList(List<MesQcInspectionLedgerRespVO> list) { |
| | | if (CollUtil.isEmpty(list)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | List<MesQcInspectionLedgerExportVO> exportList = new ArrayList<>(list.size()); |
| | | for (MesQcInspectionLedgerRespVO vo : list) { |
| | | MesQcInspectionLedgerExportVO export = new MesQcInspectionLedgerExportVO(); |
| | | export.setQcTypeName(qcTypeName(vo.getQcType())); |
| | | export.setCode(vo.getCode()); |
| | | export.setName(vo.getName()); |
| | | export.setItemCode(vo.getItemCode()); |
| | | export.setItemName(vo.getItemName()); |
| | | export.setItemSpecification(vo.getItemSpecification()); |
| | | export.setBatchNo(vo.getBatchNo()); |
| | | export.setIndicatorName(vo.getIndicatorName()); |
| | | export.setIndicatorValue(vo.getIndicatorValue()); |
| | | export.setJudgementBasis(vo.getJudgementBasis()); |
| | | export.setCheckResultText(parseDictLabel(DictTypeConstants.MES_QC_CHECK_RESULT, vo.getCheckResult())); |
| | | export.setCheckQuantity(MesQcQualityExportVO.formatDecimal(vo.getCheckQuantity())); |
| | | export.setQualifiedQuantity(MesQcQualityExportVO.formatDecimal(vo.getQualifiedQuantity())); |
| | | export.setUnqualifiedQuantity(MesQcQualityExportVO.formatDecimal(vo.getUnqualifiedQuantity())); |
| | | export.setInspectorName(vo.getInspectorName()); |
| | | export.setInspectDate(MesQcQualityExportVO.formatDateTime(vo.getInspectDate())); |
| | | export.setStatusText(parseDictLabel(DictTypeConstants.MES_ORDER_STATUS, vo.getStatus())); |
| | | export.setRemark(vo.getRemark()); |
| | | exportList.add(export); |
| | | } |
| | | return exportList; |
| | | } |
| | | |
| | | private static String qcTypeName(Integer qcType) { |
| | | for (MesQcTypeEnum e : MesQcTypeEnum.values()) { |
| | | if (Objects.equals(e.getType(), qcType)) { |
| | | return e.getName(); |
| | | } |
| | | } |
| | | return ""; |
| | | } |
| | | |
| | | private static String parseDictLabel(String dictType, Integer value) { |
| | | if (value == null) { |
| | | return ""; |
| | | } |
| | | String label = DictFrameworkUtils.parseDictDataLabel(dictType, String.valueOf(value)); |
| | | return StrUtil.nullToEmpty(label); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo; |
| | | |
| | | import cn.idev.excel.annotation.ExcelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * MES æ£æµç»æå°è´¦å¯¼åº Excel VO |
| | | * |
| | | * <p>ä¸è¡ = ä¸ä¸ªæ£æµé¡¹ç»æï¼æ£éªåæªå½å
¥æ£æµé¡¹æ¶è¯¥åå ä¸è¡ï¼æ£æµé¡¹ç¸å
³å为空ï¼ï¼ç¨äºæ¥è¯¢ãæå°ä¸åæ¡£ã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Data |
| | | public class MesQcInspectionLedgerExportVO { |
| | | |
| | | @ExcelProperty("åç±»") |
| | | private String qcTypeName; |
| | | |
| | | @ExcelProperty("æ£éªåç¼å·") |
| | | private String code; |
| | | |
| | | @ExcelProperty("æ£éªååç§°") |
| | | private String name; |
| | | |
| | | @ExcelProperty("ç©æç¼ç ") |
| | | private String itemCode; |
| | | |
| | | @ExcelProperty("ç©æåç§°") |
| | | private String itemName; |
| | | |
| | | @ExcelProperty("è§æ ¼åå·") |
| | | private String itemSpecification; |
| | | |
| | | @ExcelProperty("æ¹æ¬¡å·") |
| | | private String batchNo; |
| | | |
| | | @ExcelProperty("æ£æµé¡¹") |
| | | private String indicatorName; |
| | | |
| | | @ExcelProperty("æ£æµå¼") |
| | | private String indicatorValue; |
| | | |
| | | @ExcelProperty("å¤å®ä¾æ®") |
| | | private String judgementBasis; |
| | | |
| | | @ExcelProperty("æ£æµç»æ") |
| | | private String checkResultText; |
| | | |
| | | @ExcelProperty("æ£æµæ°é") |
| | | private String checkQuantity; |
| | | |
| | | @ExcelProperty("åæ ¼æ°é") |
| | | private String qualifiedQuantity; |
| | | |
| | | @ExcelProperty("ä¸åæ ¼æ°é") |
| | | private String unqualifiedQuantity; |
| | | |
| | | @ExcelProperty("æ£æµäººå") |
| | | private String inspectorName; |
| | | |
| | | @ExcelProperty("æ£æµæ¥æ") |
| | | private String inspectDate; |
| | | |
| | | @ExcelProperty("åæ®ç¶æ") |
| | | private String statusText; |
| | | |
| | | @ExcelProperty("夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | 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) |
| | | public class MesQcInspectionLedgerPageReqVO extends PageParam { |
| | | |
| | | @Schema(description = "åç±»ï¼æ£éªç±»åï¼ï¼1 æ¥ææ£éª / 2 è¿ç¨æ£éª / 3 åºè´§æ£éª / 4 éè´§æ£éªï¼ä¸ä¼ 为å
¨é¨", example = "1") |
| | | private Integer qcType; |
| | | |
| | | @Schema(description = "æ£æµæ¥æåºé´ï¼ä¼ [å¼å§æ¶é´, ç»ææ¶é´]", |
| | | example = "[\"2026-01-01 00:00:00\", \"2026-12-31 23:59:59\"]") |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] inspectDate; |
| | | |
| | | @Schema(description = "æ£éªåç¼å·ï¼æ¨¡ç³å¹é
ï¼", example = "IQC1787563511197") |
| | | private String code; |
| | | |
| | | @Schema(description = "ç©æç¼å·", example = "28") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "æ¹æ¬¡å·ï¼æ¨¡ç³å¹é
ï¼æ¥ææ£éªåä¾åºåæ¹æ¬¡å·ï¼è¿ç¨/åºè´§/éè´§æ£éªåæ¹æ¬¡å·ï¼", example = "20260920a") |
| | | private String batchNo; |
| | | |
| | | @Schema(description = "æ£æµç»æ", example = "1") |
| | | private Integer checkResult; |
| | | |
| | | @Schema(description = "æ£æµäººåç¼å·", example = "1") |
| | | private Long inspectorUserId; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - MES æ£æµç»æå°è´¦ Response VO") |
| | | @Data |
| | | public class MesQcInspectionLedgerRespVO { |
| | | |
| | | // ========== æ£éªå ========== |
| | | |
| | | @Schema(description = "åç±»ï¼æ£éªç±»åï¼ï¼1 æ¥ææ£éª / 2 è¿ç¨æ£éª / 3 åºè´§æ£éª / 4 éè´§æ£éªï¼åå
¸ mes_qc_type", example = "1") |
| | | private Integer qcType; |
| | | |
| | | @Schema(description = "æ£éªå ID", example = "1") |
| | | private Long qcId; |
| | | |
| | | @Schema(description = "æ£éªåç¼å·", example = "IQC1787563511197") |
| | | private String code; |
| | | |
| | | @Schema(description = "æ£éªååç§°", example = "AN1787563511157-ç©ææ£éª") |
| | | private String name; |
| | | |
| | | @Schema(description = "åæ®ç¶æï¼åå
¸ mes_order_status", example = "4") |
| | | private Integer status; |
| | | |
| | | // ========== ç©æ ========== |
| | | |
| | | @Schema(description = "ç©æç¼å·", example = "28") |
| | | private Long itemId; |
| | | |
| | | @Schema(description = "ç©æç¼ç ", example = "WL0001") |
| | | private String itemCode; |
| | | |
| | | @Schema(description = "ç©æåç§°", example = "ç©æA") |
| | | private String itemName; |
| | | |
| | | @Schema(description = "è§æ ¼åå·", example = "100mm*50mm") |
| | | private String itemSpecification; |
| | | |
| | | @Schema(description = "计éåä½åç§°", example = "个") |
| | | private String unitName; |
| | | |
| | | @Schema(description = "æ¹æ¬¡å·ï¼æ¥ææ£éªåä¾åºåæ¹æ¬¡å·ï¼è¿ç¨/åºè´§/éè´§æ£éªåæ¹æ¬¡å·ï¼", example = "20260920a") |
| | | private String batchNo; |
| | | |
| | | // ========== æ°éä¸ç»æ ========== |
| | | |
| | | @Schema(description = "æ£æµæ°é", example = "100.00") |
| | | private BigDecimal checkQuantity; |
| | | |
| | | @Schema(description = "åæ ¼æ°é", example = "99.00") |
| | | private BigDecimal qualifiedQuantity; |
| | | |
| | | @Schema(description = "ä¸åæ ¼æ°é", example = "1.00") |
| | | private BigDecimal unqualifiedQuantity; |
| | | |
| | | @Schema(description = "æ£æµç»æï¼åå
¸ mes_qc_check_result", example = "1") |
| | | private Integer checkResult; |
| | | |
| | | @Schema(description = "æ£æµæ¥æ") |
| | | private LocalDateTime inspectDate; |
| | | |
| | | @Schema(description = "æ£æµäººåç¼å·", example = "1") |
| | | private Long inspectorUserId; |
| | | |
| | | @Schema(description = "æ£æµäººåæµç§°", example = "å¼ ä¸") |
| | | private String inspectorName; |
| | | |
| | | // ========== æ£æµé¡¹ç»æï¼ä¸æ¡æç»ä¸è¡ï¼æ£éªåæªå½å
¥æ£æµé¡¹æ¶è¯¥ç»åæ®µä¸ºç©ºï¼ ========== |
| | | |
| | | @Schema(description = "æ£æµé¡¹ç¼å·", example = "2") |
| | | private Long indicatorId; |
| | | |
| | | @Schema(description = "æ£æµé¡¹åç§°", example = "é¿åº¦") |
| | | private String indicatorName; |
| | | |
| | | @Schema(description = "æ£æµå¼", example = "15") |
| | | private String indicatorValue; |
| | | |
| | | @Schema(description = "æ£æµé¡¹å¤æ³¨", example = "æ½æ£") |
| | | private String indicatorRemark; |
| | | |
| | | @Schema(description = "å¤å®ä¾æ®ï¼ç±æ£æµé¡¹æ åå¼/误差ä¸ä¸éæ¼è£
", example = "10~20") |
| | | private String judgementBasis; |
| | | |
| | | @Schema(description = "æ£æµé¡¹æ åå¼ï¼å¤å®ä¾æ®åå§å¼ï¼å端å±ç¤ºç¨ judgementBasis å³å¯ï¼", example = "15") |
| | | private BigDecimal standardValue; |
| | | |
| | | @Schema(description = "æ£æµé¡¹è¯¯å·®ä¸éï¼å¤å®ä¾æ®åå§å¼ï¼", example = "10") |
| | | private BigDecimal minThreshold; |
| | | |
| | | @Schema(description = "æ£æµé¡¹è¯¯å·®ä¸éï¼å¤å®ä¾æ®åå§å¼ï¼", example = "20") |
| | | private BigDecimal maxThreshold; |
| | | |
| | | @Schema(description = "æ£éªå夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcQualityExportVO; |
| | | import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi; |
| | | import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO; |
| | |
| | | import org.springframework.security.access.prepost.PreAuthorize; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.HashMap; |
| | |
| | | ExcelUtils.write(response, "åºè´§æ£éªå.xls", "æ°æ®", MesQcQualityExportVO.class, exportList); |
| | | } |
| | | |
| | | @GetMapping("/get-import-template") |
| | | @Operation(summary = "è·å¾å¯¼å
¥åºè´§æ£éªå模æ¿") |
| | | @PreAuthorize("@ss.hasPermission('mes:qc-oqc:import')") |
| | | public void importTemplate(HttpServletResponse response) throws IOException { |
| | | List<MesQcOqcImportExcelVO> list = Collections.singletonList( |
| | | MesQcOqcImportExcelVO.builder() |
| | | .name("示ä¾-ç©æAåºè´§æ£éª").itemCode("WL0001").clientName("示ä¾å®¢æ·æéå
¬å¸") |
| | | .batchCode("BC20260101").templateName("") |
| | | .outQuantity(new BigDecimal("100")).checkQuantity(new BigDecimal("10")) |
| | | .qualifiedQuantity(new BigDecimal("9")).unqualifiedQuantity(new BigDecimal("1")) |
| | | .checkResult("æ ¡éªéè¿").inspectorName("").inspectDate("2026-01-01 10:00:00") |
| | | .outDate("2026-01-01 09:00:00").remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢") |
| | | .build()); |
| | | ExcelUtils.write(response, "åºè´§æ£éªå导å
¥æ¨¡æ¿.xls", "åºè´§æ£éª", MesQcOqcImportExcelVO.class, list); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | | @Operation(summary = "导å
¥åºè´§æ£éªå") |
| | | @PreAuthorize("@ss.hasPermission('mes:qc-oqc:import')") |
| | | public CommonResult<MesQcImportRespVO> importOqcExcel(@RequestParam("file") MultipartFile file) throws Exception { |
| | | List<MesQcOqcImportExcelVO> list = ExcelUtils.read(file, MesQcOqcImportExcelVO.class); |
| | | return success(oqcService.importOqcList(list)); |
| | | } |
| | | |
| | | // ==================== æ¼æ¥ VO ==================== |
| | | |
| | | private List<MesQcOqcRespVO> buildOqcRespVOList(List<MesQcOqcDO> list) { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo; |
| | | |
| | | import cn.idev.excel.annotation.ExcelProperty; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * 管çåå° - åºè´§æ£éªå导å
¥ Excel VO |
| | | * |
| | | * 说æï¼ä¸è¡ = ä¸å¼ åºè´§æ£éªåãç©æã客æ·ãè´¨æ£æ¹æ¡æç¼ç /åç§°å¹é
ç³»ç»å·²ææ°æ®ï¼ |
| | | * æ£æµäººåç空åå½åç»å½ç¨æ·ï¼æ£éªåç¼å·ç空èªå¨çæï¼ç¶æåºå®ä¸ºãå¾
æ£éªãã |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Schema(description = "管çåå° - åºè´§æ£éªå导å
¥ Excel VO") |
| | | @Data |
| | | @Builder |
| | | @AllArgsConstructor |
| | | @NoArgsConstructor |
| | | public class MesQcOqcImportExcelVO { |
| | | |
| | | @ExcelProperty("æ£éªåç¼å·") |
| | | @Schema(description = "æ£éªåç¼å·ï¼ç空åèªå¨çæ", example = "OQC20260101000001") |
| | | private String code; |
| | | |
| | | @ExcelProperty("æ£éªååç§°") |
| | | @Schema(description = "æ£éªååç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "ç©æAåºè´§æ£éª") |
| | | private String name; |
| | | |
| | | @ExcelProperty("产åç©æç¼ç ") |
| | | @Schema(description = "产åç©æç¼ç ï¼éä¸ç©æç®¡çä¸çç¼ç ä¸è´", requiredMode = Schema.RequiredMode.REQUIRED, example = "WL001") |
| | | private String itemCode; |
| | | |
| | | @ExcelProperty("客æ·åç§°") |
| | | @Schema(description = "客æ·åç§°ï¼éä¸ CRM 客æ·ç®¡çä¸çåç§°ä¸è´ï¼ç空表示ä¸å±äºä»»ä½å®¢æ·", example = "示ä¾å®¢æ·æéå
¬å¸") |
| | | private String clientName; |
| | | |
| | | @ExcelProperty("æ¹æ¬¡å·") |
| | | @Schema(description = "æ¹æ¬¡å·", example = "BC20260101") |
| | | private String batchCode; |
| | | |
| | | @ExcelProperty("è´¨æ£æ¹æ¡") |
| | | @Schema(description = "è´¨æ£æ¹æ¡åç§°ï¼ç空åæç©æèªå¨å¹é
", example = "åºè´§æ£éªéç¨æ¹æ¡") |
| | | private String templateName; |
| | | |
| | | @ExcelProperty("æ¬æ¬¡åºè´§æ°é") |
| | | @Schema(description = "æ¬æ¬¡åºè´§æ°éï¼ç空表示æªå¡«åï¼å¡«åæ¶ä¸è½å°äº 0", example = "100") |
| | | private BigDecimal outQuantity; |
| | | |
| | | @ExcelProperty("æ£æµæ°é") |
| | | @Schema(description = "æ£æµæ°éï¼ç空é»è®¤çäºåæ ¼åæ°éä¸ä¸åæ ¼åæ°éä¹å", example = "10") |
| | | private BigDecimal checkQuantity; |
| | | |
| | | @ExcelProperty("åæ ¼åæ°é") |
| | | @Schema(description = "åæ ¼åæ°éï¼ä¸è½å°äº 0", requiredMode = Schema.RequiredMode.REQUIRED, example = "9") |
| | | private BigDecimal qualifiedQuantity; |
| | | |
| | | @ExcelProperty("ä¸åæ ¼åæ°é") |
| | | @Schema(description = "ä¸åæ ¼åæ°éï¼ä¸è½å°äº 0", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| | | private BigDecimal unqualifiedQuantity; |
| | | |
| | | @ExcelProperty("æ£æµç»æ") |
| | | @Schema(description = "æ£æµç»æï¼å¡«ååå
¸ mes_qc_check_result çåç§°ï¼å¦ æ ¡éªéè¿", example = "æ ¡éªéè¿") |
| | | private String checkResult; |
| | | |
| | | @ExcelProperty("æ£æµäººå") |
| | | @Schema(description = "æ£æµäººåå§åï¼ç空åå½åç»å½ç¨æ·", example = "å¼ ä¸") |
| | | private String inspectorName; |
| | | |
| | | @ExcelProperty("æ£æµæ¥æ") |
| | | @Schema(description = "æ£æµæ¥æï¼æ ¼å¼å¦ 2026-01-01 10:00:00", requiredMode = Schema.RequiredMode.REQUIRED, example = "2026-01-01 10:00:00") |
| | | private String inspectDate; |
| | | |
| | | @ExcelProperty("åºè´§æ¥æ") |
| | | @Schema(description = "åºè´§æ¥æï¼æ ¼å¼å¦ 2026-01-01 10:00:00ï¼ç空表示æªå¡«å", example = "2026-01-01 10:00:00") |
| | | private String outDate; |
| | | |
| | | @ExcelProperty("夿³¨") |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.qc.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Builder; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * 管çåå° - è´¨æ£å导å
¥ Response VOï¼IQC / IPQC / OQC å
±ç¨ï¼ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Schema(description = "管çåå° - è´¨æ£å导å
¥ Response VO") |
| | | @Data |
| | | @Builder |
| | | public class MesQcImportRespVO { |
| | | |
| | | @Schema(description = "导å
¥æåçæ£éªåç¼å·æ°ç»", example = "IQC20260101000001") |
| | | private List<String> createList; |
| | | |
| | | @Schema(description = "导å
¥å¤±è´¥éåï¼key ä¸ºè¡æ è¯ï¼æ£éªåç¼å·æç¬¬ N è¡ï¼ï¼value 为失败åå ") |
| | | private Map<String, String> failureList; |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.ipqc.MesQcIpqcDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | .orderByDesc(MesQcIpqcDO::getId)); |
| | | } |
| | | |
| | | /** |
| | | * æå¯¼å
¥å»é鮿¥è¯¢ï¼åä¸ ç©æ + æ¹å· + æ£éªç±»å + æ£æµæ¥æ è§ä¸ºå䏿¹è¿ç¨æ£éªæ°æ® |
| | | */ |
| | | default List<MesQcIpqcDO> selectListByImportKey(Long itemId, String batchCode, Integer type, |
| | | LocalDateTime inspectDate) { |
| | | return selectList(new LambdaQueryWrapperX<MesQcIpqcDO>() |
| | | .eq(MesQcIpqcDO::getItemId, itemId) |
| | | .eq(MesQcIpqcDO::getBatchCode, batchCode) |
| | | .eq(MesQcIpqcDO::getType, type) |
| | | .eq(inspectDate != null, MesQcIpqcDO::getInspectDate, inspectDate) |
| | | .isNull(inspectDate == null, MesQcIpqcDO::getInspectDate) |
| | | .orderByAsc(MesQcIpqcDO::getId)); |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * MES æ¥ææ£éªåï¼IQCï¼ Mapper |
| | | * |
| | |
| | | return selectCount(MesQcIqcDO::getVendorId, vendorId); |
| | | } |
| | | |
| | | /** |
| | | * æå¯¼å
¥å»é鮿¥è¯¢ï¼åä¸ ç©æ + ä¾åºå + ä¾åºåæ¹æ¬¡ + æ¥ææ¥æ è§ä¸ºå䏿¹æ¥ææ°æ® |
| | | */ |
| | | default List<MesQcIqcDO> selectListByImportKey(Long itemId, Long vendorId, String vendorBatch, |
| | | LocalDateTime receiveDate) { |
| | | return selectList(new LambdaQueryWrapperX<MesQcIqcDO>() |
| | | .eq(MesQcIqcDO::getItemId, itemId) |
| | | .eq(vendorId != null, MesQcIqcDO::getVendorId, vendorId) |
| | | .isNull(vendorId == null, MesQcIqcDO::getVendorId) |
| | | .eq(vendorBatch != null, MesQcIqcDO::getVendorBatch, vendorBatch) |
| | | .isNull(vendorBatch == null, MesQcIqcDO::getVendorBatch) |
| | | .eq(MesQcIqcDO::getReceiveDate, receiveDate) |
| | | .orderByAsc(MesQcIqcDO::getId)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.qc.ledger; |
| | | |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo.MesQcInspectionLedgerPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo.MesQcInspectionLedgerRespVO; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | /** |
| | | * MES æ£æµç»æå°è´¦ Mapper |
| | | * |
| | | * ä½¿ç¨ UNION ALL SQL ä»åç±»æ£éªåï¼IQC/IPQC/OQC/RQCï¼æåæ£éªåï¼åå
³èæ£éªç»ææç»ä¸æ£æµé¡¹ï¼ä¸è¡ä¸ä¸ªæ£æµé¡¹ç»æ |
| | | */ |
| | | @Mapper |
| | | public interface MesQcInspectionLedgerMapper { |
| | | |
| | | IPage<MesQcInspectionLedgerRespVO> selectInspectionLedgerPage(IPage<MesQcInspectionLedgerRespVO> page, |
| | | @Param("reqVO") MesQcInspectionLedgerPageReqVO reqVO); |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.oqc.MesQcOqcDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.time.LocalDateTime; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | return selectOne(MesQcOqcDO::getCode, code); |
| | | } |
| | | |
| | | /** |
| | | * æå¯¼å
¥å»é鮿¥è¯¢ï¼åä¸ ç©æ + å®¢æ· + æ¹æ¬¡å· + åºè´§æ¥æ è§ä¸ºå䏿¹åºè´§æ£éªæ°æ® |
| | | * |
| | | * 客æ·ä¸åºè´§æ¥æå¨æ¬åæ¯å¯ä¸ºç©ºï¼æ
ä¸ä¸ªå¯ç©ºç»´åº¦åå空å¼å®å
¨æ¯è¾ï¼null æ¯ nullï¼ã |
| | | */ |
| | | default List<MesQcOqcDO> selectListByImportKey(Long itemId, Long clientId, String batchCode, |
| | | LocalDateTime outDate) { |
| | | return selectList(new LambdaQueryWrapperX<MesQcOqcDO>() |
| | | .eq(MesQcOqcDO::getItemId, itemId) |
| | | .eq(clientId != null, MesQcOqcDO::getClientId, clientId) |
| | | .isNull(clientId == null, MesQcOqcDO::getClientId) |
| | | .eq(batchCode != null, MesQcOqcDO::getBatchCode, batchCode) |
| | | .isNull(batchCode == null, MesQcOqcDO::getBatchCode) |
| | | .eq(outDate != null, MesQcOqcDO::getOutDate, outDate) |
| | | .isNull(outDate == null, MesQcOqcDO::getOutDate) |
| | | .orderByAsc(MesQcOqcDO::getId)); |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.qc.imports; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| | | import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; |
| | | import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi; |
| | | import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateDO; |
| | | import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; |
| | | import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateService; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.SrmSupplierApi; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | import java.util.Set; |
| | | |
| | | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; |
| | | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.QC_NO_TEMPLATE; |
| | | |
| | | /** |
| | | * MES è´¨æ£å导å
¥è¾
å©ç±» |
| | | * |
| | | * è´è´£æ Excel ä¸ç人类å¯è¯»å¼ï¼ç©æç¼ç ãä¾åºååç§°ã客æ·åç§°ãè´¨æ£æ¹æ¡åç§°ãæ£æµäººåå§åçï¼ |
| | | * è§£æä¸ºç³»ç»ç¼å·ï¼å¹¶ç»ä¸å¤çåå
¸ãæ¥æãéè¯¯ææ¡ã |
| | | * åç©æ/ä¾åºå/客æ·/æ¹æ¡æ å°å¨ {@link #startImport()} å馿¬¡ä½¿ç¨æ¶ä¸æ¬¡æ§å è½½ï¼é¿å
éè¡æ¥è¯¢ã |
| | | */ |
| | | @Component |
| | | public class MesQcImportHelper { |
| | | |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | @Resource |
| | | private SrmSupplierApi srmSupplierApi; |
| | | @Resource |
| | | private CrmCustomerApi crmCustomerApi; |
| | | @Resource |
| | | private MesQcTemplateService templateService; |
| | | @Resource |
| | | private MesMdAutoCodeRecordService autoCodeRecordService; |
| | | |
| | | /** è´¨æ£æ¹æ¡åç§° -> ç¼å·ï¼å¯è½éåï¼å½ä¸å¤ä¸ªæ¶å第ä¸ä¸ªï¼ */ |
| | | private Map<String, Long> templateNameMap; |
| | | /** ä¾åºååç§° -> ç¼å· */ |
| | | private Map<String, Long> supplierNameMap; |
| | | /** 客æ·åç§° -> ç¼å· */ |
| | | private Map<String, Long> customerNameMap; |
| | | /** å½åç»å½ç¨æ·å¯è§ç客æ·ç¼å·ï¼null 表示ä¸éå¶ */ |
| | | private Set<Long> permittedClientIds; |
| | | private boolean clientPermissionLoaded; |
| | | |
| | | /** |
| | | * å¼å§ä¸æ¬¡å¯¼å
¥ï¼æ¸
空ä¸ä¸æ¬¡å¯¼å
¥çç¼åï¼ä¿è¯æ°å»ºçä¾åºå/客æ·/æ¹æ¡æ¬æ¬¡å³å¯å½ä¸ |
| | | */ |
| | | public void startImport() { |
| | | templateNameMap = null; |
| | | supplierNameMap = null; |
| | | customerNameMap = null; |
| | | permittedClientIds = null; |
| | | clientPermissionLoaded = false; |
| | | } |
| | | |
| | | /** |
| | | * çææ£éªåç¼å·ï¼å¦ IQC20260101000001 |
| | | */ |
| | | public String generateCode(String ruleCode) { |
| | | return autoCodeRecordService.generateAutoCode(ruleCode); |
| | | } |
| | | |
| | | /** |
| | | * è§£ææ£æµäººåï¼ç空åå½åç»å½ç¨æ·ï¼å¡«åæ¶æå§åï¼æµç§°ï¼ç²¾ç¡®å¹é
ï¼åä¸å°åç¨æ¨¡ç³å¹é
çç¬¬ä¸æ¡ |
| | | */ |
| | | public Long resolveInspectorUserId(String nickname) { |
| | | if (StrUtil.isBlank(nickname)) { |
| | | return getLoginUserId(); |
| | | } |
| | | List<AdminUserRespDTO> users = adminUserApi.getUserListByNickname(nickname.trim()); |
| | | if (CollUtil.isEmpty(users)) { |
| | | throw new IllegalArgumentException("æ£æµäººåä¸åå¨ï¼" + nickname.trim() |
| | | + "ã请å¨ãæ£æµäººåãåå¡«åç³»ç»å
çç¨æ·å§åï¼å¯å¨ãç³»ç»ç®¡ç-ç¨æ·ç®¡çã䏿 ¸å¯¹ï¼ï¼æç空使ç¨å½åç»å½ç¨æ·"); |
| | | } |
| | | return users.stream().filter(user -> nickname.trim().equals(user.getNickname())) |
| | | .map(AdminUserRespDTO::getId).findFirst().orElseGet(() -> users.get(0).getId()); |
| | | } |
| | | |
| | | /** |
| | | * è§£æäº§åç©æç¼å·ï¼åºäºç©æç¼ç |
| | | */ |
| | | public Long resolveItemId(String itemCode) { |
| | | if (StrUtil.isBlank(itemCode)) { |
| | | throw new IllegalArgumentException("产åç©æç¼ç ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çã产åç©æç¼ç ãå"); |
| | | } |
| | | MdmItemRespDTO item = mdmItemApi.getItemByCode(itemCode.trim()).getCheckedData(); |
| | | if (item == null) { |
| | | throw new IllegalArgumentException("ç©æä¸åå¨ï¼" + itemCode.trim() |
| | | + "ã请å
å¨ãç©æç®¡çãä¸ç»´æ¤è¯¥ç©æï¼ç¼ç é䏿¨¡æ¿å®å
¨ä¸è´ï¼ï¼æä¿®æ¹æ¨¡æ¿ä¸ç产åç©æç¼ç å鿰坼å
¥"); |
| | | } |
| | | return item.getId(); |
| | | } |
| | | |
| | | /** |
| | | * è§£æè´¨æ£æ¹æ¡ç¼å·ï¼åºäºæ¹æ¡åç§°ï¼ç空è¿å nullï¼ç±ç³»ç»æç©æ+æ£éªç±»åèªå¨å¹é
ï¼ |
| | | */ |
| | | public Long resolveTemplateId(String templateName) { |
| | | if (StrUtil.isBlank(templateName)) { |
| | | return null; |
| | | } |
| | | if (templateNameMap == null) { |
| | | templateNameMap = new HashMap<>(); |
| | | List<MesQcTemplateDO> templates = templateService.getTemplateList(); |
| | | if (CollUtil.isNotEmpty(templates)) { |
| | | templates.forEach(template -> { |
| | | if (StrUtil.isNotBlank(template.getName())) { |
| | | templateNameMap.putIfAbsent(template.getName().trim(), template.getId()); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | Long templateId = templateNameMap.get(templateName.trim()); |
| | | if (templateId == null) { |
| | | throw new IllegalArgumentException("è´¨æ£æ¹æ¡ä¸åå¨ï¼" + templateName.trim() |
| | | + "ã请å¨ãè´¨æ£ç®¡ç-è´¨æ£æ¹æ¡ã䏿 ¸å¯¹æ¹æ¡åç§°ï¼æç空该åç±ç³»ç»æç©æèªå¨å¹é
æ¹æ¡å鿰坼å
¥"); |
| | | } |
| | | return templateId; |
| | | } |
| | | |
| | | /** |
| | | * è§£æä¾åºåç¼å·ï¼åºäºä¾åºååç§°ï¼ç空è¿å null |
| | | */ |
| | | public Long resolveVendorId(String vendorName) { |
| | | if (StrUtil.isBlank(vendorName)) { |
| | | return null; |
| | | } |
| | | if (supplierNameMap == null) { |
| | | supplierNameMap = new HashMap<>(); |
| | | List<SrmSupplierRespDTO> suppliers = srmSupplierApi.getSupplierSimpleList().getCheckedData(); |
| | | if (CollUtil.isNotEmpty(suppliers)) { |
| | | suppliers.forEach(supplier -> { |
| | | if (StrUtil.isNotBlank(supplier.getName())) { |
| | | supplierNameMap.putIfAbsent(supplier.getName().trim(), supplier.getId()); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | Long vendorId = supplierNameMap.get(vendorName.trim()); |
| | | if (vendorId == null) { |
| | | throw new IllegalArgumentException("ä¾åºåä¸å卿æªéè¿åå
¥å®¡æ¹ï¼" + vendorName.trim() |
| | | + "ã请å¨ãä¾åºå管çã䏿 ¸å¯¹ä¾åºååç§°ï¼åç§°é䏿¨¡æ¿å®å
¨ä¸è´ï¼ï¼æç空该åå鿰坼å
¥"); |
| | | } |
| | | return vendorId; |
| | | } |
| | | |
| | | /** |
| | | * è§£æå®¢æ·ç¼å·ï¼åºäºå®¢æ·åç§°ï¼ç空è¿å null |
| | | * |
| | | * æ¬åæ¯çåºè´§æ£éªåä¸å¼ºå¶å
³è客æ·ï¼å®¢æ·å¯ç©ºï¼ï¼æ
æ¤å¤çç©ºä¸æ¥éã |
| | | */ |
| | | public Long resolveClientId(String clientName) { |
| | | if (StrUtil.isBlank(clientName)) { |
| | | return null; |
| | | } |
| | | if (customerNameMap == null) { |
| | | customerNameMap = new HashMap<>(); |
| | | List<CrmCustomerRespDTO> customers = crmCustomerApi.getCustomerSimpleList(); |
| | | if (CollUtil.isNotEmpty(customers)) { |
| | | customers.forEach(customer -> { |
| | | if (StrUtil.isNotBlank(customer.getName())) { |
| | | customerNameMap.putIfAbsent(customer.getName().trim(), customer.getId()); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | Long clientId = customerNameMap.get(clientName.trim()); |
| | | if (clientId == null) { |
| | | throw new IllegalArgumentException("客æ·ä¸åå¨ï¼" + clientName.trim() |
| | | + "ã请å
å¨ãCRM 客æ·ç®¡çãä¸å建该客æ·ï¼åç§°é䏿¨¡æ¿å®å
¨ä¸è´ï¼ï¼æä¿®æ¹æ¨¡æ¿ä¸ç客æ·åç§°å鿰坼å
¥"); |
| | | } |
| | | return clientId; |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªå®¢æ·å¨å½åç»å½ç¨æ·çå¯è§èå´å
|
| | | * |
| | | * åºè´§æ£éªåå表æå®¢æ·æ°æ®æéè¿æ»¤ï¼æéå¤ç客æ·å¯¼å
¥åæ¬äººå¨å表ä¸çä¸å°è¯¥åæ®ï¼å æ¤æåæ¦æªã |
| | | */ |
| | | public void validateClientPermission(Long clientId, String clientName) { |
| | | if (!clientPermissionLoaded) { |
| | | List<Long> permittedIds = crmCustomerApi.getPermittedCustomerIds(); |
| | | permittedClientIds = permittedIds == null ? null : new HashSet<>(permittedIds); |
| | | clientPermissionLoaded = true; |
| | | } |
| | | if (permittedClientIds == null || permittedClientIds.contains(clientId)) { |
| | | return; |
| | | } |
| | | throw new IllegalArgumentException("客æ·[" + clientName + "]ä¸å¨æ¨çæ°æ®æéèå´å
ï¼" |
| | | + "导å
¥åæ¨å°æ æ³å¨ãåºè´§æ£éªãå表ä¸çå°è¯¥æ£éªåã请æ¹ç¨æ¨è´è´£ç客æ·ï¼å¯å¨ãCRM 客æ·ç®¡ç-æè´è´£çã䏿¥çï¼ï¼" |
| | | + "æè系管çå为æ¨å¼é该客æ·çæéå鿰坼å
¥"); |
| | | } |
| | | |
| | | /** |
| | | * è§£æåå
¸å¼ï¼æ¯æå¡«ååå
¸åç§°ï¼å¦ æ ¡éªéè¿ï¼æåå
¸å¼ï¼å¦ 1ï¼ |
| | | * |
| | | * @param text Excel åå
æ ¼å
容 |
| | | * @param dictType åå
¸ç±»å |
| | | * @param fieldLabel ååï¼ç¨äºé误æç¤º |
| | | * @param required æ¯å¦å¿
å¡« |
| | | */ |
| | | public Integer resolveDictValue(String text, String dictType, String fieldLabel, boolean required) { |
| | | List<String> labelList = DictFrameworkUtils.getDictDataLabelList(dictType); |
| | | if (StrUtil.isBlank(text)) { |
| | | if (required) { |
| | | throw new IllegalArgumentException(fieldLabel + "ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çã" + fieldLabel |
| | | + "ãåï¼å¯éå¼ï¼" + String.join("ã", labelList)); |
| | | } |
| | | return null; |
| | | } |
| | | String value = text.trim(); |
| | | if (value.matches("\\d+") && DictFrameworkUtils.getDictDataValueList(dictType).contains(value)) { |
| | | return Integer.valueOf(value); |
| | | } |
| | | String parsedValue = DictFrameworkUtils.parseDictDataValue(dictType, value); |
| | | if (parsedValue == null) { |
| | | throw new IllegalArgumentException(fieldLabel + "ä¸åå¨ï¼" + value + "ãæ¨¡æ¿ä¸ã" + fieldLabel |
| | | + "ã请填å以ä¸ä¹ä¸ï¼" + String.join("ã", labelList)); |
| | | } |
| | | return Integer.valueOf(parsedValue); |
| | | } |
| | | |
| | | /** |
| | | * è§£ææ°éï¼å¿
å¡«æ¶ä¸è½ä¸ºç©ºï¼ä¸ä¸è½å°äº 0 |
| | | */ |
| | | public BigDecimal resolveQuantity(BigDecimal value, String fieldLabel, boolean required) { |
| | | if (value == null) { |
| | | if (required) { |
| | | throw new IllegalArgumentException(fieldLabel + "ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çã" + fieldLabel + "ãå"); |
| | | } |
| | | return null; |
| | | } |
| | | if (value.compareTo(BigDecimal.ZERO) < 0) { |
| | | throw new IllegalArgumentException(fieldLabel + "ä¸è½å°äº 0ï¼å½å为 " + value.stripTrailingZeros().toPlainString() |
| | | + "ãè¯·ä¿®æ¹æ¨¡æ¿å鿰坼å
¥"); |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªãå计æ°é = åæ ¼åæ°é + ä¸åæ ¼åæ°éã |
| | | * |
| | | * @param total å计æ°éï¼å计åç空æ¶ä¼ nullï¼ç±åæ ¼ + ä¸åæ ¼ èªå¨æ¨ç®ï¼ |
| | | * @param qualified åæ ¼åæ°é |
| | | * @param unqualified ä¸åæ ¼åæ°é |
| | | * @param totalFieldLabel å计åçååï¼å¦ãæ¬æ¬¡æ¥æ¶æ°éã |
| | | */ |
| | | public BigDecimal resolveCheckQuantity(BigDecimal total, BigDecimal qualified, BigDecimal unqualified, |
| | | String totalFieldLabel) { |
| | | BigDecimal sum = qualified.add(unqualified); |
| | | if (total == null) { |
| | | return sum; |
| | | } |
| | | if (total.compareTo(sum) != 0) { |
| | | throw new IllegalArgumentException(totalFieldLabel + "å¿
é¡»çäºåæ ¼åæ°éä¸ä¸åæ ¼åæ°éä¹åï¼åæ ¼åæ°é " |
| | | + qualified.stripTrailingZeros().toPlainString() + " + ä¸åæ ¼åæ°é " |
| | | + unqualified.stripTrailingZeros().toPlainString() + " = " + sum.stripTrailingZeros().toPlainString() |
| | | + "ï¼èã" + totalFieldLabel + "ãå¡«åçæ¯ " + total.stripTrailingZeros().toPlainString() |
| | | + "ãè¯·ä¿®æ¹æ¨¡æ¿ä¸çæ°éåï¼æå°è¯¥åç空ç±ç³»ç»èªå¨å计å鿰坼å
¥"); |
| | | } |
| | | return total; |
| | | } |
| | | |
| | | /** |
| | | * è§£ææ¥ææ¶é´ï¼æ¯æ 2026-01-01 10:00:00 / 2026-01-01 10:00 / 2026-01-01 / 2026/1/1ï¼ç空è¿å null |
| | | */ |
| | | public LocalDateTime parseDateTime(String text, String fieldLabel) { |
| | | if (StrUtil.isBlank(text)) { |
| | | return null; |
| | | } |
| | | String value = text.trim(); |
| | | for (String pattern : new String[]{"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd HH:mm:ss"}) { |
| | | try { |
| | | return LocalDateTime.parse(value, DateTimeFormatter.ofPattern(pattern)); |
| | | } catch (Exception ignored) { |
| | | // ç»§ç»å°è¯ä¸ä¸ä¸ªæ ¼å¼ |
| | | } |
| | | } |
| | | for (String pattern : new String[]{"yyyy-MM-dd", "yyyy/M/d"}) { |
| | | try { |
| | | return java.time.LocalDate.parse(value, DateTimeFormatter.ofPattern(pattern)).atStartOfDay(); |
| | | } catch (Exception ignored) { |
| | | // ç»§ç»å°è¯ä¸ä¸ä¸ªæ ¼å¼ |
| | | } |
| | | } |
| | | throw new IllegalArgumentException(fieldLabel + "æ ¼å¼ä¸æ£ç¡®ï¼" + text + "ï¼ç¤ºä¾ 2026-01-01 10:00:00"); |
| | | } |
| | | |
| | | /** |
| | | * è§£æå¿
å¡«çæ¥ææ¶é´ï¼ç空æ¥é |
| | | */ |
| | | public LocalDateTime parseRequiredDateTime(String text, String fieldLabel) { |
| | | LocalDateTime value = parseDateTime(text, fieldLabel); |
| | | if (value == null) { |
| | | throw new IllegalArgumentException(fieldLabel + "ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çã" + fieldLabel |
| | | + "ãåï¼ç¤ºä¾ 2026-01-01 10:00:00"); |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | /** |
| | | * ç©ææªé
ç½®è´¨æ£æ¹æ¡æ¶ï¼è¡¥å
ç©æä¸æ£éªç±»åä¸ä¸æåæåºï¼å
¶ä½å¼å¸¸åæ ·æåº |
| | | */ |
| | | public static void rethrowTemplateError(ServiceException ex, String itemCode, String qcTypeLabel) { |
| | | if (Objects.equals(ex.getCode(), QC_NO_TEMPLATE.getCode())) { |
| | | throw new IllegalArgumentException("ç©æ[" + StrUtil.blankToDefault(itemCode, "æªç¥") + "]æªé
ç½®" |
| | | + qcTypeLabel + "çè´¨æ£æ¹æ¡ã请å¨ãè´¨æ£ç®¡ç-è´¨æ£æ¹æ¡ãä¸ä¸ºè¯¥ç©æé
ç½®" + qcTypeLabel |
| | | + "æ¹æ¡ï¼æå¨æ¨¡æ¿çãè´¨æ£æ¹æ¡ãåå¡«åè¯¥ç©æå·²é
ç½®çæ¹æ¡åç§°å鿰坼å
¥"); |
| | | } |
| | | throw ex; |
| | | } |
| | | |
| | | /** |
| | | * åè¡å¯¼å
¥å¤±è´¥æ¶çæç¤ºææ¡ |
| | | */ |
| | | public static String resolveImportErrorMessage(Exception ex) { |
| | | if (ex instanceof cn.iocoder.yudao.framework.common.exception.ServiceException serviceException) { |
| | | return serviceException.getMessage(); |
| | | } |
| | | return StrUtil.blankToDefault(ex.getMessage(), "导å
¥å¤±è´¥"); |
| | | } |
| | | |
| | | /** |
| | | * é夿°æ®æç¤ºä¸çåå¼å±ç¤ºï¼ç空æ¾ç¤ºä¸ºãæªå¡«åã |
| | | */ |
| | | public static String describeImportValue(String value) { |
| | | return StrUtil.isBlank(value) ? "æªå¡«å" : value.trim(); |
| | | } |
| | | |
| | | /** |
| | | * åä¸ä»½æ¨¡æ¿å
åºç°é夿°æ®æ¶çæç¤º |
| | | */ |
| | | public static IllegalArgumentException duplicateRowException(int firstRowNo, String keyDesc) { |
| | | return new IllegalArgumentException("æ£æµå°éå¤å¯¼å
¥ï¼æ¬æ¬¡å¯¼å
¥ç第 " + firstRowNo |
| | | + " è¡ä¸å½åè¡çæ°æ®å®å
¨ç¸åï¼" + keyDesc + "ï¼ã请å 餿¨¡æ¿ä¸éå¤çè¡å鿰坼å
¥"); |
| | | } |
| | | |
| | | /** |
| | | * ä¸ç³»ç»ä¸å·²æåæ®é夿¶çæç¤º |
| | | */ |
| | | public static IllegalArgumentException duplicateExistingException(String keyDesc, String docLabel, |
| | | String existingCode, String menuPath) { |
| | | return new IllegalArgumentException("æ£æµå°éå¤å¯¼å
¥ï¼" + keyDesc + " ä¸å·²æ" + docLabel + "ã" + existingCode |
| | | + "ãå®å
¨ç¸åï¼å¯è½æ¯æ¬æ¬¡å¯¼å
¥åé¢çè¡ï¼ä¹å¯è½æ¯ç³»ç»ä¸å·²æåæ®ï¼ã请å¿éå¤å¯¼å
¥ï¼å¦ç¡®é鿰坼å
¥ï¼è¯·å
å¨ã" |
| | | + menuPath + "ãä¸å é¤è¯¥" + docLabel + "åéè¯"); |
| | | } |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.mes.service.qc.ipqc; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.ipqc.MesQcIpqcDO; |
| | | import jakarta.validation.Valid; |
| | |
| | | */ |
| | | void recalculateDefectStats(Long ipqcId, List<MesQcDefectRecordDO> records); |
| | | |
| | | /** |
| | | * æ¹é导å
¥è¿ç¨æ£éªå |
| | | * |
| | | * @param importList 导å
¥è¡å表 |
| | | * @return 导å
¥ç»æï¼æåç¼å·å表 + éè¡å¤±è´¥åå ï¼ |
| | | */ |
| | | MesQcImportRespVO importIpqcList(List<MesQcIpqcImportExcelVO> importList); |
| | | |
| | | } |
| | |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productproduce.MesWmProductProduceLineDO; |
| | | import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ipqc.vo.MesQcIpqcSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.ipqc.MesQcIpqcDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.qc.ipqc.MesQcIpqcMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.DictTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.service.pro.feedback.MesProFeedbackService; |
| | | import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService; |
| | | import cn.iocoder.yudao.module.mes.service.qc.imports.MesQcImportHelper; |
| | | import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService; |
| | | import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ncr.vo.MesQcNcrSaveReqVO; |
| | |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | |
| | | |
| | | @Resource |
| | | private MesQcIpqcMapper ipqcMapper; |
| | | |
| | | @Resource |
| | | private MesQcImportHelper qcImportHelper; |
| | | |
| | | @Resource |
| | | private MesQcTemplateItemService templateItemService; |
| | |
| | | ipqcMapper.updateById(updateIpqc); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public MesQcImportRespVO importIpqcList(List<MesQcIpqcImportExcelVO> importList) { |
| | | MesQcImportRespVO respVO = MesQcImportRespVO.builder() |
| | | .createList(new ArrayList<>()).failureList(new LinkedHashMap<>()).build(); |
| | | if (CollUtil.isEmpty(importList)) { |
| | | return respVO; |
| | | } |
| | | qcImportHelper.startImport(); |
| | | Map<String, Integer> firstRowNoByKey = new HashMap<>(); |
| | | for (int i = 0; i < importList.size(); i++) { |
| | | MesQcIpqcImportExcelVO row = importList.get(i); |
| | | if (isImportRowEmpty(row)) { |
| | | continue; // è·³è¿ç©ºè¡ |
| | | } |
| | | String label = StrUtil.isNotBlank(row.getCode()) ? "æ£éªåç¼å· " + row.getCode().trim() |
| | | : "第 " + (i + 2) + " è¡"; |
| | | String importKey = buildImportKey(row); |
| | | try { |
| | | Integer firstRowNo = firstRowNoByKey.get(importKey); |
| | | if (firstRowNo != null) { |
| | | throw MesQcImportHelper.duplicateRowException(firstRowNo, buildImportKeyDesc(row)); |
| | | } |
| | | respVO.getCreateList().add(createIpqcByImport(row)); |
| | | firstRowNoByKey.putIfAbsent(importKey, i + 2); |
| | | } catch (Exception ex) { |
| | | respVO.getFailureList().put(label, MesQcImportHelper.resolveImportErrorMessage(ex)); |
| | | } |
| | | } |
| | | return respVO; |
| | | } |
| | | |
| | | private boolean isImportRowEmpty(MesQcIpqcImportExcelVO row) { |
| | | return row == null || (StrUtil.isBlank(row.getCode()) && StrUtil.isBlank(row.getName()) |
| | | && StrUtil.isBlank(row.getType()) && StrUtil.isBlank(row.getItemCode()) |
| | | && StrUtil.isBlank(row.getBatchCode()) && StrUtil.isBlank(row.getTemplateName()) |
| | | && row.getCheckQuantity() == null && row.getQualifiedQuantity() == null |
| | | && row.getUnqualifiedQuantity() == null && row.getLaborScrapQuantity() == null |
| | | && row.getMaterialScrapQuantity() == null && row.getOtherScrapQuantity() == null |
| | | && StrUtil.isBlank(row.getCheckResult()) && StrUtil.isBlank(row.getInspectorName()) |
| | | && StrUtil.isBlank(row.getInspectDate()) && StrUtil.isBlank(row.getRemark())); |
| | | } |
| | | |
| | | /** |
| | | * 便®å¯¼å
¥è¡å建ä¸å¼ è¿ç¨æ£éªåï¼ç©ææäº§åç©æç¼ç å¹é
ï¼æ¹å·å¿
å¡«ï¼ç¶æä¸ºãå¾
æ£éªãï¼æ£éªè¡ç±è´¨æ£æ¹æ¡èªå¨çæ |
| | | * |
| | | * @return æ£éªåç¼å· |
| | | */ |
| | | private String createIpqcByImport(MesQcIpqcImportExcelVO row) { |
| | | MesQcIpqcSaveReqVO reqVO = new MesQcIpqcSaveReqVO(); |
| | | // 1. æ£éªåç¼å·ï¼å¡«åå使ç¨ï¼ç空èªå¨çæ |
| | | String code = StrUtil.isNotBlank(row.getCode()) ? row.getCode().trim() |
| | | : qcImportHelper.generateCode(MesMdAutoCodeRuleCodeEnum.QC_IPQC_CODE.getCode()); |
| | | if (ipqcMapper.selectByCode(code) != null) { |
| | | throw new IllegalArgumentException("æ£éªåç¼å·å·²åå¨ï¼" + code |
| | | + "ãè¯·ä¿®æ¹æ¨¡æ¿ä¸çãæ£éªåç¼å·ãï¼æå
å¨ç³»ç»ä¸å é¤è¯¥ç¼å·çæ£éªåå鿰坼å
¥"); |
| | | } |
| | | reqVO.setCode(code); |
| | | // 2. åç§°ãæ£éªç±»åã产åç©æãæ¹å·ãè´¨æ£æ¹æ¡ |
| | | if (StrUtil.isBlank(row.getName())) { |
| | | throw new IllegalArgumentException("æ£éªååç§°ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çãæ£éªååç§°ãå"); |
| | | } |
| | | reqVO.setName(row.getName().trim()); |
| | | reqVO.setType(qcImportHelper.resolveDictValue(row.getType(), |
| | | DictTypeConstants.MES_IPQC_TYPE, "æ£éªç±»å", true)); |
| | | reqVO.setItemId(qcImportHelper.resolveItemId(row.getItemCode())); |
| | | if (StrUtil.isBlank(row.getBatchCode())) { |
| | | throw new IllegalArgumentException("æ¹å·ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çãæ¹å·ãå"); |
| | | } |
| | | reqVO.setBatchCode(row.getBatchCode().trim()); |
| | | reqVO.setTemplateId(qcImportHelper.resolveTemplateId(row.getTemplateName())); |
| | | // 3. æ°éï¼åæ ¼å + ä¸åæ ¼å å¿
é¡»çäºæ£æµæ°éï¼æ£æµæ°éç空åèªå¨å计ï¼ï¼å·¥åº/æåº/å
¶ä»åºç空æ 0 |
| | | BigDecimal qualified = qcImportHelper.resolveQuantity(row.getQualifiedQuantity(), "åæ ¼åæ°é", true); |
| | | BigDecimal unqualified = qcImportHelper.resolveQuantity(row.getUnqualifiedQuantity(), "ä¸åæ ¼åæ°é", true); |
| | | reqVO.setQualifiedQuantity(qualified); |
| | | reqVO.setUnqualifiedQuantity(unqualified); |
| | | reqVO.setCheckQuantity(qcImportHelper.resolveCheckQuantity( |
| | | row.getCheckQuantity(), qualified, unqualified, "æ£æµæ°é")); |
| | | BigDecimal laborScrap = qcImportHelper.resolveQuantity(row.getLaborScrapQuantity(), "å·¥åºæ°é", false); |
| | | BigDecimal materialScrap = qcImportHelper.resolveQuantity(row.getMaterialScrapQuantity(), "æåºæ°é", false); |
| | | BigDecimal otherScrap = qcImportHelper.resolveQuantity(row.getOtherScrapQuantity(), "å
¶ä»åºåæ°é", false); |
| | | laborScrap = laborScrap != null ? laborScrap : BigDecimal.ZERO; |
| | | materialScrap = materialScrap != null ? materialScrap : BigDecimal.ZERO; |
| | | otherScrap = otherScrap != null ? otherScrap : BigDecimal.ZERO; |
| | | validateScrapQuantity(unqualified, laborScrap, materialScrap, otherScrap); |
| | | reqVO.setLaborScrapQuantity(laborScrap); |
| | | reqVO.setMaterialScrapQuantity(materialScrap); |
| | | reqVO.setOtherScrapQuantity(otherScrap); |
| | | // 4. æ£éªä¿¡æ¯ |
| | | reqVO.setCheckResult(qcImportHelper.resolveDictValue(row.getCheckResult(), |
| | | DictTypeConstants.MES_QC_CHECK_RESULT, "æ£æµç»æ", false)); |
| | | reqVO.setInspectorUserId(qcImportHelper.resolveInspectorUserId(row.getInspectorName())); |
| | | reqVO.setInspectDate(qcImportHelper.parseDateTime(row.getInspectDate(), "æ£æµæ¥æ")); |
| | | reqVO.setRemark(StrUtil.trimToNull(row.getRemark())); |
| | | // 5. å»éï¼åä¸ ç©æ + æ¹å· + æ£éªç±»å + æ£æµæ¥æ çè¿ç¨æ£éªåä¸å¯éå¤å¯¼å
¥ |
| | | MesQcIpqcDO duplicate = CollUtil.getFirst(ipqcMapper.selectListByImportKey(reqVO.getItemId(), |
| | | reqVO.getBatchCode(), reqVO.getType(), reqVO.getInspectDate())); |
| | | if (duplicate != null) { |
| | | throw MesQcImportHelper.duplicateExistingException(buildImportKeyDesc(row), "è¿ç¨æ£éªå", |
| | | duplicate.getCode(), "è´¨é管ç-è¿ç¨æ£éª"); |
| | | } |
| | | // 6. å¤ç¨å建é»è¾ï¼æ ¡éªç©æ/人åãæç©æå¹é
è´¨æ£æ¹æ¡ãçææ£éªè¡ |
| | | try { |
| | | createIpqc(reqVO); |
| | | } catch (ServiceException ex) { |
| | | MesQcImportHelper.rethrowTemplateError(ex, row.getItemCode(), "è¿ç¨æ£éª(IPQC)"); |
| | | } |
| | | return code; |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éª å·¥åº + æåº + å
¶ä»åºå ä¸è¶
è¿ä¸åæ ¼åæ°é |
| | | */ |
| | | private void validateScrapQuantity(BigDecimal unqualified, BigDecimal laborScrap, |
| | | BigDecimal materialScrap, BigDecimal otherScrap) { |
| | | BigDecimal scrapSum = laborScrap.add(materialScrap).add(otherScrap); |
| | | if (scrapSum.compareTo(unqualified) <= 0) { |
| | | return; |
| | | } |
| | | throw new IllegalArgumentException("å·¥åºãæåºãå
¶ä»åºåæ°éä¹åä¸è½è¶
è¿ä¸åæ ¼åæ°éï¼ä¸åæ ¼åæ°é为 " |
| | | + unqualified.stripTrailingZeros().toPlainString() + "ï¼è å·¥åº " + laborScrap.stripTrailingZeros().toPlainString() |
| | | + " + æåº " + materialScrap.stripTrailingZeros().toPlainString() + " + å
¶ä»åºå " |
| | | + otherScrap.stripTrailingZeros().toPlainString() + " = " + scrapSum.stripTrailingZeros().toPlainString() |
| | | + "ãè¯·ä¿®æ¹æ¨¡æ¿ä¸çåºåæ°éæä¸åæ ¼åæ°éå鿰坼å
¥"); |
| | | } |
| | | |
| | | /** |
| | | * 导å
¥å»éé®ï¼åä¸ ç©æ + æ¹å· + æ£éªç±»å + æ£æµæ¥æ è§ä¸ºå䏿¹è¿ç¨æ£éªæ°æ® |
| | | */ |
| | | private String buildImportKey(MesQcIpqcImportExcelVO row) { |
| | | return String.join("|", StrUtil.trimToEmpty(row.getItemCode()), StrUtil.trimToEmpty(row.getBatchCode()), |
| | | StrUtil.trimToEmpty(row.getType()), StrUtil.trimToEmpty(row.getInspectDate())); |
| | | } |
| | | |
| | | private String buildImportKeyDesc(MesQcIpqcImportExcelVO row) { |
| | | return "ç©æ[" + MesQcImportHelper.describeImportValue(row.getItemCode()) |
| | | + "]ãæ¹å·[" + MesQcImportHelper.describeImportValue(row.getBatchCode()) |
| | | + "]ãæ£éªç±»å[" + MesQcImportHelper.describeImportValue(row.getType()) |
| | | + "]ãæ£æµæ¥æ[" + MesQcImportHelper.describeImportValue(row.getInspectDate()) + "]"; |
| | | } |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.mes.service.qc.iqc; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO; |
| | |
| | | */ |
| | | Long createIqcFromArrivalNotice(Long noticeId, MesWmArrivalNoticeLineDO line, String noticeCode, Long vendorId); |
| | | |
| | | /** |
| | | * æ¹é导å
¥æ¥ææ£éªå |
| | | * |
| | | * @param importList 导å
¥è¡å表 |
| | | * @return 导å
¥ç»æï¼æåç¼å·å表 + éè¡å¤±è´¥åå ï¼ |
| | | */ |
| | | MesQcImportRespVO importIqcList(List<MesQcIqcImportExcelVO> importList); |
| | | |
| | | } |
| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.iqc.vo.MesQcIqcSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.iqc.MesQcIqcDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.qc.iqc.MesQcIqcMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.DictTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService; |
| | | import cn.iocoder.yudao.module.mes.service.qc.imports.MesQcImportHelper; |
| | | import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService; |
| | | import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeService; |
| | |
| | | @Resource |
| | | @Lazy |
| | | private MesQcNcrService ncrService; |
| | | |
| | | @Resource |
| | | private MesQcImportHelper qcImportHelper; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | return "ç©æID:" + itemId; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public MesQcImportRespVO importIqcList(List<MesQcIqcImportExcelVO> importList) { |
| | | MesQcImportRespVO respVO = MesQcImportRespVO.builder() |
| | | .createList(new ArrayList<>()).failureList(new LinkedHashMap<>()).build(); |
| | | if (CollUtil.isEmpty(importList)) { |
| | | return respVO; |
| | | } |
| | | qcImportHelper.startImport(); |
| | | Map<String, Integer> firstRowNoByKey = new HashMap<>(); |
| | | for (int i = 0; i < importList.size(); i++) { |
| | | MesQcIqcImportExcelVO row = importList.get(i); |
| | | if (isImportRowEmpty(row)) { |
| | | continue; // è·³è¿ç©ºè¡ |
| | | } |
| | | String label = StrUtil.isNotBlank(row.getCode()) ? "æ£éªåç¼å· " + row.getCode().trim() |
| | | : "第 " + (i + 2) + " è¡"; |
| | | String importKey = buildImportKey(row); |
| | | try { |
| | | Integer firstRowNo = firstRowNoByKey.get(importKey); |
| | | if (firstRowNo != null) { |
| | | throw MesQcImportHelper.duplicateRowException(firstRowNo, buildImportKeyDesc(row)); |
| | | } |
| | | respVO.getCreateList().add(createIqcByImport(row)); |
| | | firstRowNoByKey.putIfAbsent(importKey, i + 2); |
| | | } catch (Exception ex) { |
| | | respVO.getFailureList().put(label, MesQcImportHelper.resolveImportErrorMessage(ex)); |
| | | } |
| | | } |
| | | return respVO; |
| | | } |
| | | |
| | | private boolean isImportRowEmpty(MesQcIqcImportExcelVO row) { |
| | | return row == null || (StrUtil.isBlank(row.getCode()) && StrUtil.isBlank(row.getName()) |
| | | && StrUtil.isBlank(row.getItemCode()) && StrUtil.isBlank(row.getVendorName()) |
| | | && StrUtil.isBlank(row.getVendorBatch()) && StrUtil.isBlank(row.getTemplateName()) |
| | | && row.getReceivedQuantity() == null && row.getQualifiedQuantity() == null |
| | | && row.getUnqualifiedQuantity() == null && StrUtil.isBlank(row.getCheckResult()) |
| | | && StrUtil.isBlank(row.getInspectorName()) && StrUtil.isBlank(row.getInspectDate()) |
| | | && StrUtil.isBlank(row.getReceiveDate()) && StrUtil.isBlank(row.getRemark())); |
| | | } |
| | | |
| | | /** |
| | | * 便®å¯¼å
¥è¡å建ä¸å¼ æ¥ææ£éªåï¼ç¶æä¸ºãå¾
æ£éªãï¼æ£éªè¡ç±è´¨æ£æ¹æ¡èªå¨çæ |
| | | * |
| | | * @return æ£éªåç¼å· |
| | | */ |
| | | private String createIqcByImport(MesQcIqcImportExcelVO row) { |
| | | MesQcIqcSaveReqVO reqVO = new MesQcIqcSaveReqVO(); |
| | | // 1. æ£éªåç¼å·ï¼å¡«åå使ç¨ï¼ç空èªå¨çæ |
| | | String code = StrUtil.isNotBlank(row.getCode()) ? row.getCode().trim() |
| | | : qcImportHelper.generateCode(MesMdAutoCodeRuleCodeEnum.QC_IQC_CODE.getCode()); |
| | | if (iqcMapper.selectByCode(code) != null) { |
| | | throw new IllegalArgumentException("æ£éªåç¼å·å·²åå¨ï¼" + code |
| | | + "ãè¯·ä¿®æ¹æ¨¡æ¿ä¸çãæ£éªåç¼å·ãï¼æå
å¨ç³»ç»ä¸å é¤è¯¥ç¼å·çæ£éªåå鿰坼å
¥"); |
| | | } |
| | | reqVO.setCode(code); |
| | | // 2. åç§°ãç©æãä¾åºåãè´¨æ£æ¹æ¡ |
| | | if (StrUtil.isBlank(row.getName())) { |
| | | throw new IllegalArgumentException("æ£éªååç§°ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çãæ£éªååç§°ãå"); |
| | | } |
| | | reqVO.setName(row.getName().trim()); |
| | | reqVO.setItemId(qcImportHelper.resolveItemId(row.getItemCode())); |
| | | reqVO.setVendorId(qcImportHelper.resolveVendorId(row.getVendorName())); |
| | | reqVO.setVendorBatch(StrUtil.trimToNull(row.getVendorBatch())); |
| | | reqVO.setTemplateId(qcImportHelper.resolveTemplateId(row.getTemplateName())); |
| | | // 3. æ°éï¼åæ ¼å + ä¸åæ ¼å å¿
é¡»çäºæ¬æ¬¡æ¥æ¶æ°éï¼æ¥æ¶æ°éç空åèªå¨åè®¡ï¼ |
| | | BigDecimal qualified = qcImportHelper.resolveQuantity(row.getQualifiedQuantity(), "åæ ¼åæ°é", true); |
| | | BigDecimal unqualified = qcImportHelper.resolveQuantity(row.getUnqualifiedQuantity(), "ä¸åæ ¼åæ°é", true); |
| | | reqVO.setQualifiedQuantity(qualified); |
| | | reqVO.setUnqualifiedQuantity(unqualified); |
| | | reqVO.setReceivedQuantity(qcImportHelper.resolveCheckQuantity( |
| | | row.getReceivedQuantity(), qualified, unqualified, "æ¬æ¬¡æ¥æ¶æ°é")); |
| | | // 4. æ£éªä¿¡æ¯ |
| | | reqVO.setCheckResult(qcImportHelper.resolveDictValue(row.getCheckResult(), |
| | | DictTypeConstants.MES_QC_CHECK_RESULT, "æ£æµç»æ", false)); |
| | | reqVO.setInspectorUserId(qcImportHelper.resolveInspectorUserId(row.getInspectorName())); |
| | | reqVO.setInspectDate(qcImportHelper.parseRequiredDateTime(row.getInspectDate(), "æ£æµæ¥æ")); |
| | | reqVO.setReceiveDate(qcImportHelper.parseRequiredDateTime(row.getReceiveDate(), "æ¥ææ¥æ")); |
| | | reqVO.setRemark(StrUtil.trimToNull(row.getRemark())); |
| | | // 5. å»éï¼åä¸ ç©æ + ä¾åºå + ä¾åºåæ¹æ¬¡ + æ¥ææ¥æ çæ¥ææ£éªåä¸å¯éå¤å¯¼å
¥ |
| | | MesQcIqcDO duplicate = CollUtil.getFirst(iqcMapper.selectListByImportKey(reqVO.getItemId(), reqVO.getVendorId(), |
| | | reqVO.getVendorBatch(), reqVO.getReceiveDate())); |
| | | if (duplicate != null) { |
| | | throw MesQcImportHelper.duplicateExistingException(buildImportKeyDesc(row), "æ¥ææ£éªå", |
| | | duplicate.getCode(), "è´¨é管ç-æ¥ææ£éª"); |
| | | } |
| | | // 6. å¤ç¨å建é»è¾ï¼æ ¡éªç©æ/ä¾åºå/人åãæç©æå¹é
è´¨æ£æ¹æ¡ãçææ£éªè¡ |
| | | try { |
| | | createIqc(reqVO); |
| | | } catch (ServiceException ex) { |
| | | MesQcImportHelper.rethrowTemplateError(ex, row.getItemCode(), "æ¥ææ£éª(IQC)"); |
| | | } |
| | | return code; |
| | | } |
| | | |
| | | /** |
| | | * 导å
¥å»éé®ï¼åä¸ ç©æ + ä¾åºå + ä¾åºåæ¹æ¬¡ + æ¥ææ¥æ è§ä¸ºå䏿¹æ¥ææ°æ® |
| | | */ |
| | | private String buildImportKey(MesQcIqcImportExcelVO row) { |
| | | return String.join("|", StrUtil.trimToEmpty(row.getItemCode()), StrUtil.trimToEmpty(row.getVendorName()), |
| | | StrUtil.trimToEmpty(row.getVendorBatch()), StrUtil.trimToEmpty(row.getReceiveDate())); |
| | | } |
| | | |
| | | private String buildImportKeyDesc(MesQcIqcImportExcelVO row) { |
| | | return "ç©æ[" + MesQcImportHelper.describeImportValue(row.getItemCode()) |
| | | + "]ãä¾åºå[" + MesQcImportHelper.describeImportValue(row.getVendorName()) |
| | | + "]ãä¾åºåæ¹æ¬¡[" + MesQcImportHelper.describeImportValue(row.getVendorBatch()) |
| | | + "]ãæ¥ææ¥æ[" + MesQcImportHelper.describeImportValue(row.getReceiveDate()) + "]"; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.qc.ledger; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo.MesQcInspectionLedgerPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo.MesQcInspectionLedgerRespVO; |
| | | |
| | | /** |
| | | * MES æ£æµç»æå°è´¦ Service æ¥å£ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | public interface MesQcInspectionLedgerService { |
| | | |
| | | /** |
| | | * è·å¾æ£æµç»æå°è´¦å页ï¼åç±»æ£éªåç»ä¸æ¥è¯¢ï¼ä¸è¡ä¸ä¸ªæ£æµé¡¹ç»æï¼ |
| | | * |
| | | * @param pageReqVO å页æ¥è¯¢ |
| | | * @return å°è´¦å页 |
| | | */ |
| | | PageResult<MesQcInspectionLedgerRespVO> getInspectionLedgerPage(MesQcInspectionLedgerPageReqVO pageReqVO); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.qc.ledger; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo.MesQcInspectionLedgerPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo.MesQcInspectionLedgerRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcQualityExportVO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.qc.ledger.MesQcInspectionLedgerMapper; |
| | | import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi; |
| | | import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.MdmUnitMeasureApi; |
| | | import cn.iocoder.yudao.module.mdm.api.unit.dto.MdmUnitMeasureRespDTO; |
| | | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| | | import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import jakarta.annotation.Resource; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; |
| | | |
| | | /** |
| | | * MES æ£æµç»æå°è´¦ Service å®ç°ç±» |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Service |
| | | @Validated |
| | | public class MesQcInspectionLedgerServiceImpl implements MesQcInspectionLedgerService { |
| | | |
| | | @Resource |
| | | private MesQcInspectionLedgerMapper ledgerMapper; |
| | | |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | @Resource |
| | | private MdmUnitMeasureApi mdmUnitMeasureApi; |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | | |
| | | @Override |
| | | public PageResult<MesQcInspectionLedgerRespVO> getInspectionLedgerPage(MesQcInspectionLedgerPageReqVO pageReqVO) { |
| | | // å页æ¥è¯¢ï¼åç±»æ£éªå UNION ALLï¼ |
| | | IPage<MesQcInspectionLedgerRespVO> page = MyBatisUtils.buildPage(pageReqVO); |
| | | ledgerMapper.selectInspectionLedgerPage(page, pageReqVO); |
| | | List<MesQcInspectionLedgerRespVO> list = page.getRecords(); |
| | | if (CollUtil.isEmpty(list)) { |
| | | return PageResult.empty(page.getTotal()); |
| | | } |
| | | // æ¹éæ¥è¯¢ç©æã计éåä½ãæ£æµäººåï¼å¹¶æ¼è£
å¤å®ä¾æ®ï¼ç©æä¸è®¡éåä½åæ¥èª MDMï¼ |
| | | Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(convertSet(list, MesQcInspectionLedgerRespVO::getItemId)); |
| | | Map<Long, MdmUnitMeasureRespDTO> unitMeasureMap = mdmUnitMeasureApi.getUnitMeasureMap( |
| | | convertSet(itemMap.values(), MdmItemRespDTO::getUnitMeasureId)); |
| | | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap( |
| | | convertSet(list, MesQcInspectionLedgerRespVO::getInspectorUserId)); |
| | | for (MesQcInspectionLedgerRespVO vo : list) { |
| | | findAndThen(itemMap, vo.getItemId(), item -> { |
| | | vo.setItemCode(item.getCode()); |
| | | vo.setItemName(item.getName()); |
| | | vo.setItemSpecification(item.getSpecification()); |
| | | findAndThen(unitMeasureMap, item.getUnitMeasureId(), unit -> vo.setUnitName(unit.getName())); |
| | | }); |
| | | findAndThen(userMap, vo.getInspectorUserId(), user -> vo.setInspectorName(user.getNickname())); |
| | | vo.setJudgementBasis(MesQcQualityExportVO.buildRangeText( |
| | | vo.getStandardValue(), vo.getMinThreshold(), vo.getMaxThreshold())); |
| | | } |
| | | return new PageResult<>(list, page.getTotal()); |
| | | } |
| | | |
| | | } |
| | |
| | | package cn.iocoder.yudao.module.mes.service.qc.oqc; |
| | | |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.oqc.MesQcOqcDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO; |
| | |
| | | */ |
| | | Long createOqcFromProductSales(Long salesId, MesWmProductSalesLineDO line, String salesCode, Long clientId); |
| | | |
| | | /** |
| | | * æ¹é导å
¥åºè´§æ£éªå |
| | | * |
| | | * @param importList 导å
¥è¡å表 |
| | | * @return 导å
¥ç»æï¼æåç¼å·å表 + éè¡å¤±è´¥åå ï¼ |
| | | */ |
| | | MesQcImportRespVO importOqcList(List<MesQcOqcImportExcelVO> importList); |
| | | |
| | | } |
| | |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| | | 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.qc.oqc.vo.MesQcOqcImportExcelVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.oqc.vo.MesQcOqcSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.qc.vo.MesQcImportRespVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.defectrecord.MesQcDefectRecordDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.oqc.MesQcOqcDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.qc.oqc.MesQcOqcMapper; |
| | | import cn.iocoder.yudao.module.mes.enums.DictTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService; |
| | | import cn.iocoder.yudao.module.mes.service.qc.imports.MesQcImportHelper; |
| | | import cn.iocoder.yudao.module.mes.service.qc.indicatorresult.MesQcIndicatorResultService; |
| | | import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateItemService; |
| | | import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesLineService; |
| | |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| | |
| | | |
| | | @Resource |
| | | private MesQcOqcMapper oqcMapper; |
| | | |
| | | @Resource |
| | | private MesQcImportHelper qcImportHelper; |
| | | |
| | | @Resource |
| | | private MesQcTemplateItemService templateItemService; |
| | |
| | | return "ç©æID:" + itemId; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public MesQcImportRespVO importOqcList(List<MesQcOqcImportExcelVO> importList) { |
| | | MesQcImportRespVO respVO = MesQcImportRespVO.builder() |
| | | .createList(new ArrayList<>()).failureList(new LinkedHashMap<>()).build(); |
| | | if (CollUtil.isEmpty(importList)) { |
| | | return respVO; |
| | | } |
| | | qcImportHelper.startImport(); |
| | | Map<String, Integer> firstRowNoByKey = new HashMap<>(); |
| | | for (int i = 0; i < importList.size(); i++) { |
| | | MesQcOqcImportExcelVO row = importList.get(i); |
| | | if (isImportRowEmpty(row)) { |
| | | continue; // è·³è¿ç©ºè¡ |
| | | } |
| | | String label = StrUtil.isNotBlank(row.getCode()) ? "æ£éªåç¼å· " + row.getCode().trim() |
| | | : "第 " + (i + 2) + " è¡"; |
| | | String importKey = buildImportKey(row); |
| | | try { |
| | | Integer firstRowNo = firstRowNoByKey.get(importKey); |
| | | if (firstRowNo != null) { |
| | | throw MesQcImportHelper.duplicateRowException(firstRowNo, buildImportKeyDesc(row)); |
| | | } |
| | | respVO.getCreateList().add(createOqcByImport(row)); |
| | | firstRowNoByKey.putIfAbsent(importKey, i + 2); |
| | | } catch (Exception ex) { |
| | | respVO.getFailureList().put(label, MesQcImportHelper.resolveImportErrorMessage(ex)); |
| | | } |
| | | } |
| | | return respVO; |
| | | } |
| | | |
| | | private boolean isImportRowEmpty(MesQcOqcImportExcelVO row) { |
| | | return row == null || (StrUtil.isBlank(row.getCode()) && StrUtil.isBlank(row.getName()) |
| | | && StrUtil.isBlank(row.getItemCode()) && StrUtil.isBlank(row.getClientName()) |
| | | && StrUtil.isBlank(row.getBatchCode()) && StrUtil.isBlank(row.getTemplateName()) |
| | | && row.getOutQuantity() == null && row.getCheckQuantity() == null |
| | | && row.getQualifiedQuantity() == null && row.getUnqualifiedQuantity() == null |
| | | && StrUtil.isBlank(row.getCheckResult()) && StrUtil.isBlank(row.getInspectorName()) |
| | | && StrUtil.isBlank(row.getInspectDate()) && StrUtil.isBlank(row.getOutDate()) |
| | | && StrUtil.isBlank(row.getRemark())); |
| | | } |
| | | |
| | | /** |
| | | * 便®å¯¼å
¥è¡å建ä¸å¼ åºè´§æ£éªåï¼ç¶æä¸ºãå¾
æ£éªãï¼æ£éªè¡ç±è´¨æ£æ¹æ¡èªå¨çæ |
| | | * |
| | | * æ¬åæ¯çåºè´§æ£éªåä¸å¼ºå¶å
³è客æ·ãä¸å¼ºå¶å¡«ååºè´§æ°éä¸åºè´§æ¥æï¼æ
è¿ä¸åçç©ºä¸æ¥éã |
| | | * |
| | | * @return æ£éªåç¼å· |
| | | */ |
| | | private String createOqcByImport(MesQcOqcImportExcelVO row) { |
| | | MesQcOqcSaveReqVO reqVO = new MesQcOqcSaveReqVO(); |
| | | // 1. æ£éªåç¼å·ï¼å¡«åå使ç¨ï¼ç空èªå¨çæ |
| | | String code = StrUtil.isNotBlank(row.getCode()) ? row.getCode().trim() |
| | | : qcImportHelper.generateCode(MesMdAutoCodeRuleCodeEnum.QC_OQC_CODE.getCode()); |
| | | if (oqcMapper.selectByCode(code) != null) { |
| | | throw new IllegalArgumentException("æ£éªåç¼å·å·²åå¨ï¼" + code |
| | | + "ãè¯·ä¿®æ¹æ¨¡æ¿ä¸çãæ£éªåç¼å·ãï¼æå
å¨ç³»ç»ä¸å é¤è¯¥ç¼å·çæ£éªåå鿰坼å
¥"); |
| | | } |
| | | reqVO.setCode(code); |
| | | // 2. åç§°ãç©æã客æ·ãæ¹æ¬¡ãè´¨æ£æ¹æ¡ |
| | | if (StrUtil.isBlank(row.getName())) { |
| | | throw new IllegalArgumentException("æ£éªååç§°ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çãæ£éªååç§°ãå"); |
| | | } |
| | | reqVO.setName(row.getName().trim()); |
| | | reqVO.setItemId(qcImportHelper.resolveItemId(row.getItemCode())); |
| | | Long clientId = qcImportHelper.resolveClientId(row.getClientName()); |
| | | if (clientId != null) { |
| | | // æªå¡«å®¢æ·æ¶ä¸æ ¡éªæ°æ®æéï¼åæ®ä¸å±äºä»»ä½å®¢æ·ï¼ |
| | | qcImportHelper.validateClientPermission(clientId, row.getClientName().trim()); |
| | | } |
| | | reqVO.setClientId(clientId); |
| | | reqVO.setBatchCode(StrUtil.trimToNull(row.getBatchCode())); |
| | | reqVO.setTemplateId(qcImportHelper.resolveTemplateId(row.getTemplateName())); |
| | | // 3. æ°éï¼åæ ¼å + ä¸åæ ¼å å¿
é¡»çäºæ£æµæ°éï¼æ£æµæ°éç空åèªå¨å计ï¼ï¼åºè´§æ°éå¯ç空 |
| | | reqVO.setOutQuantity(qcImportHelper.resolveQuantity(row.getOutQuantity(), "æ¬æ¬¡åºè´§æ°é", false)); |
| | | BigDecimal qualified = qcImportHelper.resolveQuantity(row.getQualifiedQuantity(), "åæ ¼åæ°é", true); |
| | | BigDecimal unqualified = qcImportHelper.resolveQuantity(row.getUnqualifiedQuantity(), "ä¸åæ ¼åæ°é", true); |
| | | reqVO.setQualifiedQuantity(qualified); |
| | | reqVO.setUnqualifiedQuantity(unqualified); |
| | | reqVO.setCheckQuantity(qcImportHelper.resolveCheckQuantity( |
| | | row.getCheckQuantity(), qualified, unqualified, "æ£æµæ°é")); |
| | | // 4. æ£éªä¿¡æ¯ |
| | | reqVO.setCheckResult(qcImportHelper.resolveDictValue(row.getCheckResult(), |
| | | DictTypeConstants.MES_QC_CHECK_RESULT, "æ£æµç»æ", false)); |
| | | reqVO.setInspectorUserId(qcImportHelper.resolveInspectorUserId(row.getInspectorName())); |
| | | reqVO.setInspectDate(qcImportHelper.parseRequiredDateTime(row.getInspectDate(), "æ£æµæ¥æ")); |
| | | reqVO.setOutDate(qcImportHelper.parseDateTime(row.getOutDate(), "åºè´§æ¥æ")); |
| | | reqVO.setRemark(StrUtil.trimToNull(row.getRemark())); |
| | | // 5. å»éï¼åä¸ ç©æ + å®¢æ· + æ¹æ¬¡å· + åºè´§æ¥æ çåºè´§æ£éªåä¸å¯éå¤å¯¼å
¥ |
| | | MesQcOqcDO duplicate = CollUtil.getFirst(oqcMapper.selectListByImportKey(reqVO.getItemId(), reqVO.getClientId(), |
| | | reqVO.getBatchCode(), reqVO.getOutDate())); |
| | | if (duplicate != null) { |
| | | throw MesQcImportHelper.duplicateExistingException(buildImportKeyDesc(row), "åºè´§æ£éªå", |
| | | duplicate.getCode(), "è´¨é管ç-åºè´§æ£éª"); |
| | | } |
| | | // 6. å¤ç¨å建é»è¾ï¼æ ¡éªç©æ/人åãæç©æå¹é
è´¨æ£æ¹æ¡ãçææ£éªè¡ |
| | | try { |
| | | createOqc(reqVO); |
| | | } catch (ServiceException ex) { |
| | | MesQcImportHelper.rethrowTemplateError(ex, row.getItemCode(), "åºè´§æ£éª(OQC)"); |
| | | } |
| | | return code; |
| | | } |
| | | |
| | | /** |
| | | * 导å
¥å»éé®ï¼åä¸ ç©æ + å®¢æ· + æ¹æ¬¡å· + åºè´§æ¥æ è§ä¸ºå䏿¹åºè´§æ£éªæ°æ® |
| | | */ |
| | | private String buildImportKey(MesQcOqcImportExcelVO row) { |
| | | return String.join("|", StrUtil.trimToEmpty(row.getItemCode()), StrUtil.trimToEmpty(row.getClientName()), |
| | | StrUtil.trimToEmpty(row.getBatchCode()), StrUtil.trimToEmpty(row.getOutDate())); |
| | | } |
| | | |
| | | private String buildImportKeyDesc(MesQcOqcImportExcelVO row) { |
| | | return "ç©æ[" + MesQcImportHelper.describeImportValue(row.getItemCode()) |
| | | + "]ã客æ·[" + MesQcImportHelper.describeImportValue(row.getClientName()) |
| | | + "]ãæ¹æ¬¡å·[" + MesQcImportHelper.describeImportValue(row.getBatchCode()) |
| | | + "]ãåºè´§æ¥æ[" + MesQcImportHelper.describeImportValue(row.getOutDate()) + "]"; |
| | | } |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| | | <mapper namespace="cn.iocoder.yudao.module.mes.dal.mysql.qc.ledger.MesQcInspectionLedgerMapper"> |
| | | |
| | | <!-- |
| | | æ£æµç»æå°è´¦æ¥è¯¢ï¼åç±»æ£éªå UNION ALLï¼ |
| | | ä¸è¡ = ä¸ä¸ªæ£æµé¡¹ç»æï¼æ£éªåæªå½å
¥æ£éªç»ææ¶è¯¥åå ä¸è¡ï¼æ£æµé¡¹ç¸å
³å为空ï¼LEFT JOIN ä¿è¯ä¸ä¸¢åï¼ã |
| | | 说æï¼æ£éªç»æçå
³èé®ä¸º (qc_id, qc_type)ï¼qc_id ä¸ºåæ£éªåèªèº«ç idï¼éæç±»åè¿æ»¤ qc_typeï¼å¦åä¸åç±»åç id ä¼ä¸²åã |
| | | 说æï¼æ£æµé¡¹åç§°ä¸åé»è¾å é¤è¿æ»¤ï¼å·²åç¨/å é¤çæ£æµé¡¹ä»å±ç¤ºåå²å°è´¦åç§°ã |
| | | --> |
| | | <select id="selectInspectionLedgerPage" resultType="cn.iocoder.yudao.module.mes.controller.admin.qc.ledger.vo.MesQcInspectionLedgerRespVO"> |
| | | SELECT * FROM ( |
| | | <!-- 1. æ¥ææ£éªï¼IQCï¼ï¼æ¹æ¬¡åä¾åºåæ¹æ¬¡å· --> |
| | | SELECT |
| | | ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IQC.type} AS qcType, |
| | | q.id AS qcId, |
| | | q.code AS code, |
| | | q.name AS name, |
| | | q.status AS status, |
| | | q.item_id AS itemId, |
| | | q.vendor_batch AS batchNo, |
| | | q.check_quantity AS checkQuantity, |
| | | q.qualified_quantity AS qualifiedQuantity, |
| | | q.unqualified_quantity AS unqualifiedQuantity, |
| | | q.check_result AS checkResult, |
| | | q.inspect_date AS inspectDate, |
| | | q.inspector_user_id AS inspectorUserId, |
| | | q.remark AS remark, |
| | | d.indicator_id AS indicatorId, |
| | | i.name AS indicatorName, |
| | | d.value AS indicatorValue, |
| | | d.remark AS indicatorRemark, |
| | | l.standard_value AS standardValue, |
| | | l.min_threshold AS minThreshold, |
| | | l.max_threshold AS maxThreshold |
| | | FROM mes_qc_iqc q |
| | | LEFT JOIN mes_qc_indicator_result r ON r.qc_id = q.id |
| | | AND r.qc_type = ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IQC.type} |
| | | AND r.deleted = 0 |
| | | LEFT JOIN mes_qc_indicator_result_detail d ON d.result_id = r.id AND d.deleted = 0 |
| | | LEFT JOIN mes_qc_indicator i ON i.id = d.indicator_id |
| | | LEFT JOIN mes_qc_iqc_line l ON l.iqc_id = q.id AND l.indicator_id = d.indicator_id AND l.deleted = 0 |
| | | WHERE q.deleted = 0 |
| | | |
| | | UNION ALL |
| | | |
| | | <!-- 2. è¿ç¨æ£éªï¼IPQCï¼ï¼æ¹æ¬¡å·åè¿ç¨çæ¹å· --> |
| | | SELECT |
| | | ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IPQC.type} AS qcType, |
| | | q.id AS qcId, |
| | | q.code AS code, |
| | | q.name AS name, |
| | | q.status AS status, |
| | | q.item_id AS itemId, |
| | | q.batch_code AS batchNo, |
| | | q.check_quantity AS checkQuantity, |
| | | q.qualified_quantity AS qualifiedQuantity, |
| | | q.unqualified_quantity AS unqualifiedQuantity, |
| | | q.check_result AS checkResult, |
| | | q.inspect_date AS inspectDate, |
| | | q.inspector_user_id AS inspectorUserId, |
| | | q.remark AS remark, |
| | | d.indicator_id AS indicatorId, |
| | | i.name AS indicatorName, |
| | | d.value AS indicatorValue, |
| | | d.remark AS indicatorRemark, |
| | | l.standard_value AS standardValue, |
| | | l.min_threshold AS minThreshold, |
| | | l.max_threshold AS maxThreshold |
| | | FROM mes_qc_ipqc q |
| | | LEFT JOIN mes_qc_indicator_result r ON r.qc_id = q.id |
| | | AND r.qc_type = ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IPQC.type} |
| | | AND r.deleted = 0 |
| | | LEFT JOIN mes_qc_indicator_result_detail d ON d.result_id = r.id AND d.deleted = 0 |
| | | LEFT JOIN mes_qc_indicator i ON i.id = d.indicator_id |
| | | LEFT JOIN mes_qc_ipqc_line l ON l.ipqc_id = q.id AND l.indicator_id = d.indicator_id AND l.deleted = 0 |
| | | WHERE q.deleted = 0 |
| | | |
| | | UNION ALL |
| | | |
| | | <!-- 3. åºè´§æ£éªï¼OQCï¼ï¼æ¹æ¬¡åæ¹æ¬¡å· --> |
| | | SELECT |
| | | ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@OQC.type} AS qcType, |
| | | q.id AS qcId, |
| | | q.code AS code, |
| | | q.name AS name, |
| | | q.status AS status, |
| | | q.item_id AS itemId, |
| | | q.batch_code AS batchNo, |
| | | q.check_quantity AS checkQuantity, |
| | | q.qualified_quantity AS qualifiedQuantity, |
| | | q.unqualified_quantity AS unqualifiedQuantity, |
| | | q.check_result AS checkResult, |
| | | q.inspect_date AS inspectDate, |
| | | q.inspector_user_id AS inspectorUserId, |
| | | q.remark AS remark, |
| | | d.indicator_id AS indicatorId, |
| | | i.name AS indicatorName, |
| | | d.value AS indicatorValue, |
| | | d.remark AS indicatorRemark, |
| | | l.standard_value AS standardValue, |
| | | l.min_threshold AS minThreshold, |
| | | l.max_threshold AS maxThreshold |
| | | FROM mes_qc_oqc q |
| | | LEFT JOIN mes_qc_indicator_result r ON r.qc_id = q.id |
| | | AND r.qc_type = ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@OQC.type} |
| | | AND r.deleted = 0 |
| | | LEFT JOIN mes_qc_indicator_result_detail d ON d.result_id = r.id AND d.deleted = 0 |
| | | LEFT JOIN mes_qc_indicator i ON i.id = d.indicator_id |
| | | LEFT JOIN mes_qc_oqc_line l ON l.oqc_id = q.id AND l.indicator_id = d.indicator_id AND l.deleted = 0 |
| | | WHERE q.deleted = 0 |
| | | |
| | | UNION ALL |
| | | |
| | | <!-- 4. éè´§æ£éªï¼RQCï¼ï¼æ¹æ¬¡åæ¹æ¬¡å· --> |
| | | SELECT |
| | | ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@RQC.type} AS qcType, |
| | | q.id AS qcId, |
| | | q.code AS code, |
| | | q.name AS name, |
| | | q.status AS status, |
| | | q.item_id AS itemId, |
| | | q.batch_code AS batchNo, |
| | | q.check_quantity AS checkQuantity, |
| | | q.qualified_quantity AS qualifiedQuantity, |
| | | q.unqualified_quantity AS unqualifiedQuantity, |
| | | q.check_result AS checkResult, |
| | | q.inspect_date AS inspectDate, |
| | | q.inspector_user_id AS inspectorUserId, |
| | | q.remark AS remark, |
| | | d.indicator_id AS indicatorId, |
| | | i.name AS indicatorName, |
| | | d.value AS indicatorValue, |
| | | d.remark AS indicatorRemark, |
| | | l.standard_value AS standardValue, |
| | | l.min_threshold AS minThreshold, |
| | | l.max_threshold AS maxThreshold |
| | | FROM mes_qc_rqc q |
| | | LEFT JOIN mes_qc_indicator_result r ON r.qc_id = q.id |
| | | AND r.qc_type = ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@RQC.type} |
| | | AND r.deleted = 0 |
| | | LEFT JOIN mes_qc_indicator_result_detail d ON d.result_id = r.id AND d.deleted = 0 |
| | | LEFT JOIN mes_qc_indicator i ON i.id = d.indicator_id |
| | | LEFT JOIN mes_qc_rqc_line l ON l.rqc_id = q.id AND l.indicator_id = d.indicator_id AND l.deleted = 0 |
| | | WHERE q.deleted = 0 |
| | | ) t |
| | | <where> |
| | | <if test="reqVO.qcType != null"> |
| | | AND t.qcType = #{reqVO.qcType} |
| | | </if> |
| | | <if test="reqVO.inspectDate != null and reqVO.inspectDate.length > 0 and reqVO.inspectDate[0] != null"> |
| | | AND t.inspectDate >= #{reqVO.inspectDate[0]} |
| | | </if> |
| | | <if test="reqVO.inspectDate != null and reqVO.inspectDate.length > 1 and reqVO.inspectDate[1] != null"> |
| | | AND t.inspectDate <= #{reqVO.inspectDate[1]} |
| | | </if> |
| | | <if test="reqVO.code != null and reqVO.code != ''"> |
| | | AND t.code LIKE CONCAT('%', #{reqVO.code}, '%') |
| | | </if> |
| | | <if test="reqVO.itemId != null"> |
| | | AND t.itemId = #{reqVO.itemId} |
| | | </if> |
| | | <if test="reqVO.batchNo != null and reqVO.batchNo != ''"> |
| | | AND t.batchNo LIKE CONCAT('%', #{reqVO.batchNo}, '%') |
| | | </if> |
| | | <if test="reqVO.checkResult != null"> |
| | | AND t.checkResult = #{reqVO.checkResult} |
| | | </if> |
| | | <if test="reqVO.inspectorUserId != null"> |
| | | AND t.inspectorUserId = #{reqVO.inspectorUserId} |
| | | </if> |
| | | </where> |
| | | ORDER BY t.inspectDate DESC, t.qcId DESC, t.qcType ASC |
| | | </select> |
| | | |
| | | </mapper> |