feat: CRM 发票/合同导入、MES 质检批量导入与检测台账、回款与报价校验、权限码细化
- CRM:发票批量导入、合同导入字段调整、回款必填校验、报价单号可选(留空自动生成/保持原值)
- MES:IQC/IPQC/OQC/RQC 批量导入(导入助手 + 响应 VO)、检测结果台账、物料列表按分类排序、工作站按名称查询
- HRM:考勤/薪酬接口权限码拆分细化、节假日查询条件调整与提示信息带参
- framework:ExcelUtils 新增 readFlat(纵向合并单元格拉平读取),支撑批量导入
- docs:业务可视化更新、联调文档与初始化/菜单 SQL(含合并初始化脚本 config_export_all_20260928.sql)
- 不含本地配置 application-local.yaml
| | |
| | | <!-- 产åæç»è¡¨æ ¼ --> |
| | | <el-table-column prop="itemCode" label="ç©æç¼ç " /> |
| | | <el-table-column prop="itemName" label="ç©æåç§°" /> |
| | | <el-table-column prop="itemBarCode" label="ç©ææ¡ç " /> |
| | | <el-table-column prop="barCode" label="ç©ææ¡ç " /> |
| | | <el-table-column prop="itemUnitName" label="åä½" /> |
| | | <el-table-column prop="itemPrice" label="åä»·" /> |
| | | <el-table-column prop="contractPrice" label="ååä»·" /> |
| | |
| | | 2. **ä»·æ ¼å¯ä¿®æ¹**ï¼`contractPrice` é»è®¤çäºç©æåä»·ï¼ä½å¯ä»¥æå¨ä¿®æ¹ |
| | | 3. **è¿æ¸¡æ**ï¼åç«¯ææ¶å
¼å®¹ `productId` å `sellingPrice` åæ®µï¼ä½åç»ä¼ç§»é¤å
¼å®¹é»è¾ |
| | | 4. **å
¶ä»æ¨¡ååæ¥ä¿®æ¹**ï¼é宿¥ä»·åä¹ä½¿ç¨ MDM ç©æï¼å段ä¸ååä¸è´ |
| | | |
| | | --- |
| | | |
| | | # 2026-09-24 å¢éï¼åå产åæç»æ¾ç¤ºå段补å
¨ + å é¤ååçº§èæ¸
çæç» |
| | | |
| | | ## ä¸ãæ¾ç¤ºå段补å
¨ |
| | | |
| | | ### èæ¯ |
| | | |
| | | åå详æ
æ¥å£æ¤åæªè§£æäº§åæç»ç计éåä½åç§°ï¼æ¡ç åæ®µåä¸å端åç»å®ä¸ä¸è´ï¼å¯¼è´ä»¥ä¸ä½ç½® **åä½åãç©ææ¡ç åæä¸ºç©º**ï¼åæºæ¥å£ä¸ç´æ£å¸¸è¿åï¼æ¬æ¬¡å¯¹é½åæºåæ³ï¼ï¼ |
| | | |
| | | - åå详æ
âã产åã页ç¾ï¼`ProductDetailsList` å
±ç¨ç»ä»¶ï¼ |
| | | - åå审æ¹é¡µ â 产åæç»è¡¨ |
| | | - ç¼è¾ååå¼¹çª â 产åè¡¨æ ¼ï¼å·²ä¿åè¡æ¬¡çè§æ ¼åå·åæ ·ä¸ºç©ºï¼ |
| | | |
| | | ### æ¶åçæ¥å£ |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | /crm/contract/get | è·å¾åå详æ
ï¼å«äº§åæç»ï¼ï¼æ¬æ¬¡åæ´ä»
影忤æ¥å£ | |
| | | |
| | | > `/crm/contract/page`ã`/crm/contract/page-by-customer`ã`/crm/contract/page-by-business`ãå¯¼åº Excel å**ä¸å«**产åæç»ï¼ä¸åå½±åã |
| | | |
| | | ### ååºåæ®µåæ´ï¼data.products[]ï¼ |
| | | |
| | | | åæ®µ | ç±»å | åæ´ | 说æ | |
| | | |------|------|------|------| |
| | | | itemUnitName | String | è¡¥å
¨åå¼ | 计éåä½åç§°ï¼æ `itemUnitId` è§£æï¼å¦ãç±³ãã个ãï¼ï¼æ¤åæä¸º null | |
| | | | barCode | String | **åæ®µæ´å** | ç©ææ¡ç ï¼ååæ®µå `itemBarCode` æ¹ä¸º `barCode`ï¼ä¸åæºæ¥å£åå端产åæç»å表åç»å®ï¼field: 'barCode'ï¼ä¸è´ | |
| | | | itemSpecification | String | æ°å¢ | è§æ ¼åå·ï¼åèª MDM ç©æï¼ä¸åæºæ¥å£ä¸è´ | |
| | | | itemBarCode | - | å·²ç§»é¤ | åç«¯å¦æå¼ç¨è¯·æ¹ç¨ `barCode` | |
| | | |
| | | **ååºç¤ºä¾ï¼èéï¼ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": { |
| | | "id": 19, |
| | | "no": "WTJC2025120501", |
| | | "products": [ |
| | | { |
| | | "id": 42, |
| | | "itemId": 38, |
| | | "itemCode": "PHC300AB70-4.5", |
| | | "itemName": "PHC300AB70-4.5", |
| | | "barCode": null, |
| | | "itemSpecification": null, |
| | | "itemUnitId": 3, |
| | | "itemUnitName": "ç±³", |
| | | "itemPrice": 68.000000, |
| | | "contractPrice": 68.000000, |
| | | "count": 179208.000000, |
| | | "totalPrice": 12186144.000000 |
| | | } |
| | | ] |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | ### åæ®µå±ç¤ºè§å |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | itemUnitName | åå详æ
产å页ç¾ã审æ¹é¡µäº§å表ãç¼è¾å¼¹çªäº§å表 | åä½åï¼åå¼ MDM 计éåä½åç§° | |
| | | | barCode | åå详æ
产å页ç¾ï¼ç©ææ¡ç åï¼ | ä¸åæºäº§åå表åç»å®å段ä¸è´ | |
| | | | itemSpecification | ç¼è¾å¼¹çªäº§åè¡¨æ ¼ | 详æ
页产åé¡µç¾æ æ¤å | |
| | | |
| | | ### ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | åä½åç§°æ¥æº | ç± MDM 计éåä½è¡¨æäº§åæç»ç itemUnitId è§£æï¼å¯¼å
¥çååï¼itemUnitId åèªç©æä¸»æ°æ®ç计éåä½ | |
| | | | æ¡ç åå¼ | åèª MDM ç©ææ¡£æ¡çæ¡ç ï¼ç©ææªç»´æ¤æ¡ç æ¶ä¸ºç©ºï¼å±æ£å¸¸ | |
| | | | è§æ ¼åå·åå¼ | åèª MDM ç©ææ¡£æ¡çè§æ ¼åå·ï¼æªç»´æ¤æ¶ä¸ºç©º | |
| | | | ç¼è¾åååä¿å | 产åæç»åä¼ æ¶ barCode / itemSpecification / itemUnitName å±äºå±ç¤ºå段ï¼å端ä¸è½åºï¼ç±æ¥å£æ¯æ¬¡æ itemId / itemUnitId 宿¶è§£æï¼ä¸å½±åä¿åç»æ | |
| | | |
| | | ### 注æäºé¡¹ |
| | | |
| | | - æ¬æ¬¡ä¸º**ååºå段ååæ´**ï¼itemBarCode â barCodeï¼ãå端类å声æ `CrmContractApi.ContractProduct.itemBarCode` å»ºè®®åæ¥æ¹ä¸º `barCode`ï¼ä»
ç±»å声æï¼è¿è¡æ¶ä¸è¯»è¯¥å段ï¼ä¸æ¹ä¹ä¸æ¥éï¼ã |
| | | - å端页é¢ä»£ç **æ éæ¹å¨**ï¼åä½åãæ¡ç åãè§æ ¼åå·åç»å®åæ®µå·²ä¸æ¬æ¬¡è¿åä¸è´ã |
| | | - ååã产åã页ç¾ã审æ¹é¡µäº§å表å¤ç¨åä¸åå®ä¹ï¼ä¿®å¤åä¸å¤åæ¶çæã |
| | | |
| | | --- |
| | | |
| | | ## äºãå é¤ååçº§èæ¸
ç产åæç» |
| | | |
| | | ### èæ¯ |
| | | |
| | | `DELETE /crm/contract/delete` æ¤ååªå é¤ååä¸»è¡¨ãæ¥ä»·åå¼ç¨ä¸æ°æ®æéï¼**æªå é¤ `crm_contract_product` 产åæç»**ï¼å¯¼è´å é¤åååæç»æä¸ºå¤å¿æ°æ®ï¼è¡¨å
deleted=0 ä½ååå·²ä¸åå¨ï¼ã |
| | | |
| | | ### åæ´åè¡ä¸º |
| | | |
| | | | æä½ | å½±åæ°æ® | |
| | | |------|----------| |
| | | | å é¤åå | åå主表ï¼é»è¾å é¤ï¼+ 产åæç»ï¼é»è¾å é¤ï¼+ æ¥ä»·åå¼ç¨è§£é¤ + æ°æ®æéå é¤ | |
| | | |
| | | ### 注æäºé¡¹ |
| | | |
| | | - 级èå é¤ä¸º**é»è¾å é¤**ï¼deleted=1ï¼ï¼ä¸åå主表å£å¾ä¸è´ï¼å岿°æ®ä»å¯è¿½æº¯ã |
| | | - ååå·²è¢«åæ¬¾å¼ç¨æ¶ä¾æ§ç¦æ¢å é¤ï¼åææ ¡éªä¸åï¼ã |
| | | - åå²éççå¤å¿æç»ï¼æ¬æ¬¡ä¿®å¤åå é¤äº§ççï¼ä¸ä¼èªå¨æ¸
çï¼å¦éæ¸
ç请æ contract_id æ ¸å¯¹åæå·¥å¤çã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 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`ï¼èåå·²æ°å¢ï¼è¥é管ç -> å¼ç¥¨ç®¡ç -> å¼ç¥¨å¯¼å
¥ï¼å¹¶å·²æäºå¼ç¥¨ç®¡çç°æè§è²ï¼ã |
| | | |
| | | **请æ±åæ°ï¼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`ï¼è¯¥èåæéå·²æäºè§è² 2/155/160/161/162ï¼å
¶ä½èªå»ºè§è²éå¨ãè§è²ç®¡çãä¸å¾éãå¼ç¥¨å¯¼å
¥ãååä½¿ç¨ |
| | | - 空è¡ä¼è¢«èªå¨è·³è¿ï¼ä¸ç®å¤±è´¥ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # CRM é宿¥ä»·å - æ¥ä»·åå·æ¯æèªå®ä¹ï¼å端èè°æ¹æ¡ï¼ |
| | | |
| | | > **è°æ´å
容**ï¼æ¥ä»·åçãæ¥ä»·åå·ãç±ãç³»ç»èªå¨çæãä¸å¯ç¼è¾ãæ¹ä¸º**æ¯æç¨æ·èªå®ä¹**ï¼ |
| | | > æ°å¢æ¶ç空 = ç³»ç»èªå¨çæï¼å¡«å = 使ç¨ç¨æ·å¡«åçç¼å·ï¼éå
¨åºå¯ä¸ï¼ã |
| | | > ä¿®æ¹æ¶ç空 = ä¿æåç¼å·ä¸åï¼å¡«å = æ¿æ¢ä¸ºæ°ç¼å·ï¼éå
¨åºå¯ä¸ï¼ã |
| | | > å端éæè¯¥è¾å
¥æ¡æ¾å¼ç¼è¾ï¼å¹¶ææç¤ºææ¡æ¹ä¸ºãæ¥ä»·åå·èªå®ä¹ãã |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - `views/crm/saleQuotation/index.vue` â æ¥ä»·åå表页ï¼å表å±ç¤ºçæ¥ä»·åå·æ¥æºä¸åï¼æ éæ¹å¨ï¼ |
| | | - `views/crm/saleQuotation/modules/form.vue` â æ¥ä»·åæ°å¢/ç¼è¾å¼¹çªï¼**æ¬æ¬¡æ¹å¨ä¸»ä½**ï¼ |
| | | - `views/crm/saleQuotation/data.ts` â 表ååæ®µé
ç½®ï¼**æ¬æ¬¡æ¹å¨ä¸»ä½**ï¼ |
| | | |
| | | ## ä¸å¡æµç¨ä¸æ°æ®å¸¦å
¥ |
| | | |
| | | 1. **æ°å¢æ¥ä»·å**ï¼æå¼å¼¹çª â æ¥ä»·åå·è¾å
¥æ¡é»è®¤ä¸ºç©º â ç¨æ·å¯å¡«èªå®ä¹ç¼å·ï¼ä¹å¯ä¸å¡« â æäº¤æ¶æ `no` åæ ·å¸¦ç»å端ãä¸å¡«ç±å端æç¼ç è§åèªå¨çæã |
| | | 2. **ç¼è¾æ¥ä»·å**ï¼æå¼å¼¹çª â è°ç¨ `GET /crm/sale-quotation/get?id=` å填表å â æ¥ä»·åå·è¾å
¥æ¡æ¾ç¤º**åç¼å·**ï¼å¯ä¿®æ¹ï¼â æäº¤æ¶æ `no` åæ ·å¸¦ç»å端ãä¸å¡«ï¼æ¸
空ï¼è¡¨ç¤ºä¿æåç¼å·ä¸åã |
| | | 3. **ä¿åæåå**ï¼åè¡¨å·æ°ï¼å±ç¤ºå端æç»è¿åçæ¥ä»·åå·ï¼èªå®ä¹ç¼å·æèªå¨çæç¼å·ï¼ã |
| | | |
| | | ## API |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | POST | `/admin-api/crm/sale-quotation/create` | æ°å¢æ¥ä»·åï¼è¯·æ±ä½æ°å¢éå¡« `no` | |
| | | | PUT | `/admin-api/crm/sale-quotation/update` | ä¿®æ¹æ¥ä»·åï¼è¯·æ±ä½æ°å¢éå¡« `no` | |
| | | | GET | `/admin-api/crm/sale-quotation/get` | åå¡«ç¼è¾è¡¨åï¼`no` å·²å¨ååºä¸ï¼ | |
| | | |
| | | **请æ±åæ°æ°å¢ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | no | String | å¦ | æ¥ä»·åå·ãé¿åº¦ ⤠32 åç¬¦ï¼æ°å¢ç空ç±ç³»ç»èªå¨çæï¼ä¿®æ¹çç©ºä¿æåå¼ãå¡«åæ¶åç«¯æ ¡éªå
¨åºå¯ä¸ | |
| | | |
| | | **请æ±ç¤ºä¾ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "no": "BJ-2026-001", |
| | | "name": "æ¥ä»·åA", |
| | | "customerId": 18336, |
| | | "ownerUserId": 17144, |
| | | "quotationTime": "2026-09-01 00:00:00", |
| | | "items": [ |
| | | { "itemId": 20529, "quotationPrice": 123.00, "count": 10, "taxPercent": 13.00 } |
| | | ] |
| | | } |
| | | ``` |
| | | |
| | | **é误æç¤ºï¼å端已ç»åºå¯æ§è¡ææ¡ï¼ï¼** |
| | | |
| | | | åºæ¯ | æç¤º | |
| | | |------|------| |
| | | | ç¼å·å·²è¢«å ç¨ï¼å«å·²å é¤çæ¥ä»·åå ç¨ï¼ | æ¥ä»·åå·ãå¡«åå¼ã已被å ç¨ï¼ä¸è½éå¤ä½¿ç¨ã请æ¢ä¸ä¸ªç¼å·ï¼ææ¸
空ç¼å·ç±ç³»ç»èªå¨çæï¼å·²å é¤çæ¥ä»·åä¹ä¼å ç¨å
¶åç¼å·ï¼ | |
| | | | ç¼å·è¶
é¿ | æ¥ä»·åå·é¿åº¦ä¸è½è¶
è¿ 32 个å符 | |
| | | |
| | | ## å端修æ¹ç¹ï¼ä»
说æï¼ä¸å«ä»£ç ï¼ |
| | | |
| | | 1. `data.ts` ä¸ãæ¥ä»·åå·ãåæ®µé
ç½®ï¼ |
| | | - 廿è¾å
¥æ¡çç¦ç¨ï¼å为ä¿åæ¶èªå¨çæãä¸å¯ç¼è¾ï¼ï¼æ¹ä¸ºå¯ç¼è¾ã |
| | | - æç¤ºææ¡ç±ãä¿åæ¶èªå¨çæãæ¹ä¸ºã**æ¥ä»·åå·èªå®ä¹**ãï¼å¹¶è¡¥å
ãç空ç±ç³»ç»èªå¨çæãç说æã |
| | | - æ ¡éªè§åï¼éå¿
å¡«ï¼å¯å é¿åº¦ä¸é 32 çå端æç¤ºï¼é¿å
æäº¤å被åç«¯æ¦æªã |
| | | 2. `modules/form.vue`ï¼ |
| | | - æ°å¢/ç¼è¾å¼¹çªæå¼æ¶ï¼æ¥ä»·åå·è¾å
¥æ¡å
è®¸ç¨æ·è¾å
¥ã |
| | | - ç¼è¾æåå¡«é»è¾ä¸åï¼`GET /crm/sale-quotation/get` å·²è¿å `no`ï¼ä¼ä¸å¹¶åå¡«å°è¡¨åã |
| | | - æäº¤é»è¾ä¸åï¼ç´æ¥æè¡¨åå¼ï¼å« `no`ï¼æäº¤ç» create/update æ¥å£ãç¨æ·æªå¡«åæ¶æäº¤ç©ºå¼å³å¯ï¼å端æãç空ãè¯ä¹å¤çï¼ï¼æ éå端èªè¡çæç¼å·ã |
| | | |
| | | ## åæ®µå±ç¤ºè§å |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | æ¥ä»·åå· | å表åã详æ
ã表åè¾å
¥æ¡ | å端è¿åçæç»ç¼å·ï¼èªå®ä¹æèªå¨çæï¼ | |
| | | | æ¥ä»·åå·ï¼è¾å
¥æ¡æç¤ºï¼ | æ°å¢/ç¼è¾è¡¨å | ãæ¥ä»·åå·èªå®ä¹ãï¼æç¤ºç空ç±ç³»ç»çæ | |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | æ°å¢ï¼ç¼å·ç空 | å端æç¼ç è§åï¼`BJ` + æ¥æ + åºå·ï¼èªå¨çæ | |
| | | | æ°å¢ï¼å¡«åç¼å· | 使ç¨ç¨æ·å¡«åçç¼å·ï¼éå
¨åºå¯ä¸ | |
| | | | ä¿®æ¹ï¼ç¼å·ç空 | ä¿æåç¼å·ä¸åï¼ä¸ä¼è¢«æ¸
ç©ºï¼ | |
| | | | ä¿®æ¹ï¼å¡«åç¼å· | æ ¡éªå¯ä¸åæ¿æ¢ï¼ä¸åç¼å·ç¸åè§ä¸ºæªåæ´ï¼å
许ä¿å | |
| | | | ç¼å·å¯ä¸æ§èå´ | è¦ç**åå²å·²å é¤**çæ¥ä»·åï¼æ°æ®åºå¯ä¸ç´¢å¼ä¸å«é»è¾å 餿 è®°ï¼ï¼å 餿¥ä»·ååå
¶ç¼å·ä¸å¯åè¢«ä½¿ç¨ | |
| | | | ç¼å·ååç©ºæ ¼ | å端æäº¤åä¼åé¦å°¾å»ç©ºæ ¼å¤çï¼çº¯ç©ºæ ¼çåç空 | |
| | | | éèç¨¿ç¶æ | æ¥ä»·å䏿¦æäº¤/转ååï¼ä¸å
许修æ¹ï¼å«ç¼å·ï¼ï¼ç»´æåæéå¶ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - ãç空ãä¸ãå¡«ååå é¤å
容ãå¨å端æ¯åä¸è¯ä¹ï¼ä¿æ/èªå¨çæï¼ï¼å端æ éåºåã |
| | | - ç¼å·å»ºè®®ä½¿ç¨åæ¯ãæ°åãçæ¨ªçº¿ç»åï¼é¿å
使ç¨ç¹æ®å符ï¼ä¾¿äºåç»æå°ä¸æ£ç´¢ï¼å端ä»
åé¿åº¦ä¸å¯ä¸æ§æ ¡éªã |
| | | - ç¼è¾æè¥åæ¥ä»·åç±ç³»ç»èªå¨çæç¼å·ï¼ç¨æ·å¯ç´æ¥æ¹æèªå®ä¹ç¼å·ï¼æ¹ååç¼å·ä¸ä¼è¢«éæ¾ï¼ä»å ç¨ã |
| | | - æ¥ä»·åå·ä¼å¸¦å
¥ã转ååãçæçåå夿³¨ï¼`ç±æ¥ä»·å[xxx]çæ`ï¼ï¼è¥ä¿®æ¹ç¼å·é注æåå²åå夿³¨ä¸ä¿ççæ¯æ§ç¼å·ã |
| | | - æ¬æ¬¡ä»
å端æ¾å¼ `no` åæ®µä¸å¯ä¸æ§æ ¡éªï¼å端æ¾å¼è¾å
¥æ¡å³å¯çæï¼æ éå
¶ä»æ¥å£é
åã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # HRM èå¤è忥é
ç½® - å端èè°æ¹æ¡ |
| | | |
| | | > é对ãèåæ¥è®¾ç½®æé®é¢ãçä¿®å¤è¯´æãé®é¢åºå¨**å端**ï¼æéç ä¸å端/èåä¸ä¸è´ã缺åå
¸ãæç´¢åæ°ä¸å¹é
ã |
| | | > ä¿®å¤å**å端ä¸éè¦æ¹ä»»ä½ä»£ç **ï¼é¡µé¢å³å¯æ£å¸¸æå¼ãæç´¢ãæ°å¢ãç¼è¾ã导åºã |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - `views/hrm/attendance/holiday/index.vue`ï¼èå¤ Â· è忥é
ç½®ï¼èåãè忥é
ç½®ãï¼ |
| | | - å
³èå½±å页é¢ï¼æç管çãè夿å¡ãèå¤ç»è®¡ï¼é½ä¾èµåä¸ä»½èåæ¥æ°æ®ï¼ |
| | | |
| | | ## API |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | `/hrm/attendance/holiday/page` | å页æ¥è¯¢ï¼åæ°æä¸è¡¨ä¿®æ£ï¼ | |
| | | | GET | `/hrm/attendance/holiday/get` | 详æ
ï¼idï¼ | |
| | | | POST | `/hrm/attendance/holiday/create` | æ°å¢ | |
| | | | PUT | `/hrm/attendance/holiday/update` | ä¿®æ¹ | |
| | | | DELETE | `/hrm/attendance/holiday/delete` | å é¤ï¼idï¼ | |
| | | | GET | `/hrm/attendance/holiday/export-excel` | 导åºï¼ä¸å页ååæ°ï¼ | |
| | | |
| | | **请æ±åæ°ï¼å页 / 导åºï¼æ¬æ¬¡ä¿®æ£ç¹å¨ãåæ´ãåï¼ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | åæ´ | |
| | | |------|------|------|------|------| |
| | | | name | String | å¦ | è忥åç§°ï¼æ¨¡ç³å¹é
| ä¸å | |
| | | | type | Integer | å¦ | ç±»åï¼1-伿¯æ¥ï¼2-工使¥ | ä¸å | |
| | | | isLegal | Integer | å¦ | æ¯å¦æ³å®è忥ï¼0-å¦ï¼1-æ¯ | **æ°å¢æ¯æ**ï¼æ¤ååç«¯ä¼ äºè¢«å端忽ç¥ï¼ | |
| | | | date | Array | å¦ | æ¥æåºé´ï¼æ ¼å¼ `[å¼å§æ¥æ, ç»ææ¥æ]`ï¼å¦ `["2026-01-01","2026-12-31"]` | **æ°å¢æ¯æ**ï¼å代åå
ç `startDate`/`endDate` | |
| | | | pageNo / pageSize | Integer | å¦ | å页忰 | ä¸å | |
| | | |
| | | > å端æç´¢è¡¨åçãæ¥æãåºé´æ§ä»¶å½åæäº¤çåæ®µåå°±æ¯ `date`ï¼éå¤åæ°å½¢å¼ï¼ï¼ä¿®å¤åä¸å端ä¸è´ï¼**æ éæ¹å¨**ã |
| | | |
| | | **æéç ï¼æ¬æ¬¡ä¿®æ£ï¼å端æ éæ¹å¨ï¼ï¼** |
| | | |
| | | | æ¥å£ | ä¿®å¤åï¼ä¸åå¨ï¼å¿
ç¶ 403ï¼ | ä¿®å¤åï¼ä¸èåèç¹ä¸è´ï¼ | |
| | | |------|--------------------------|------------------------| |
| | | | æ°å¢ | `hrm:attendance:create` | `hrm:attendance-holiday:create` | |
| | | | ä¿®æ¹ | `hrm:attendance:update` | `hrm:attendance-holiday:update` | |
| | | | å é¤ | `hrm:attendance:delete` | `hrm:attendance-holiday:delete` | |
| | | | 详æ
/ å页 | `hrm:attendance:query` | `hrm:attendance-holiday:query`ï¼**èå䏿°å¢è¯¥æé®èç¹**ï¼ | |
| | | | å¯¼åº | `hrm:attendance:export` | `hrm:attendance-holiday:export` | |
| | | |
| | | ## åå
¸ï¼æ¬æ¬¡æ°å¢ï¼é¡µé¢èªå¨çæï¼ |
| | | |
| | | | åå
¸ç±»å | å¼ | æ¾ç¤º | é¢è² | |
| | | |----------|-----|------|------| |
| | | | `hrm_holiday_type` | 1 | 伿¯æ¥ | successï¼ç»¿ï¼ | |
| | | | `hrm_holiday_type` | 2 | 工使¥ | primaryï¼èï¼ | |
| | | |
| | | ä¿®å¤å该åå
¸ä¸åå¨ï¼å¯¼è´ãç±»åãåéæ²¡æä»»ä½é项ãå表ãç±»åãåæ¾ç¤ºç©ºç½ï¼ä¸ç±»å为å¿
éï¼æ°å¢/ç¼è¾**ç¹ä¿åå¿
ç¶æ ¡éªå¤±è´¥**ã |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | æ¥æå¯ä¸ | ä¸ä¸ªæ¥æåªè½æä¸æ¡é
ç½®ï¼é夿°å¢ä¼æç¤ºãæ¥æãxxxãå·²åå¨è忥é
ç½®â¦è¯·æ¹ä¸ºç¼è¾è¯¥æ¥æçè®°å½ï¼æå
å é¤åè®°å½åæ°å¢ã | |
| | | | ä¿®æ¹æ¥æ | ä¿®æ¹è®°å½æ¶å
è®¸æ¹æ¥æï¼æ¹åçæ¥æè¥å·²è¢«å ç¨ï¼åæ ·æä¸ä¸æ¡æç¤º | |
| | | | ç±»åå«ä¹ | 1-伿¯æ¥ï¼å½å¤©ä¸ä¸çï¼æ³å®è忥åºåæ¶å¾éãæ³å®è忥ãï¼ï¼2-工使¥ï¼å½å¤©ä¸çï¼å¸¸ç¨äºè°ä¼è¡¥çï¼ | |
| | | | æªé
ç½®çæ¥æ | ä¸è½åºãä¸åä¸ãè忥ãå表ï¼ç³»ç»å¤å®å·¥ä½æ¥æ¶æãå¨ä¸è³å¨äºç®å·¥ä½æ¥ã卿«ç®ä¼æ¯æ¥ãå
åº | |
| | | | ãæ³å®è忥ã | ä»
使 è®°ä¸çéï¼ä¸å½±åæ¯å¦ä¸ççå¤å® | |
| | | | æ°æ®å¼ç¨ | æç计åãè夿å¡ãèå¤ç»è®¡å读åè¿å¼ 表ï¼é
置为ã工使¥ãç卿«ä¼æ£å¸¸çæåºå¤è¦æ± | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - å端代ç åæ´éè¦**éå¯å端æå¡**ï¼èåä¸åå
¸åæ´å·²ç´æ¥åå
¥æ°æ®åºï¼**ç¸å
³è§è²ééæ°ç»å½**ï¼æå·æ°æéç¼åï¼åæ°çãè忥é
ç½®æ¥è¯¢ãæé®æéæçæ |
| | | - æ¬æ¬¡ä¿®å¤åè¯¥è¡¨é¿æä¸º 0 è¡ï¼ä¿å被å端å¿
å¡«æ ¡éªä¸å端 403 åéå µæ»ï¼ï¼é¡µé¢æ¤åå½å
¥ä¸ä¸ä»»ä½æ°æ® |
| | | - `startDate` / `endDate` 两个æ§åæ°å·²ç§»é¤ï¼å¦ä»æå
¶å®è°ç¨æ¹å¨ä½¿ç¨ï¼éæ¹ç¨ `date` æ°ç» |
| | | - åä¸ä¸ªãæéç ä¸èåä¸ä¸è´ãç缺é·å¨ HRM èå¤çå¦å¤ 4 个页é¢ï¼èå¤è§å `hrm:attendance-rule:*`ãèå¤è®°å½ `hrm:attendance-record:*`ãèå¤ç»è®¡ `hrm:attendance-summary:*`ãèå¤å¼å¸¸ `hrm:attendance-exception:*`ï¼åæ ·åå¨ï¼**æ¬æ¬¡æªä¸å¹¶ä¿®æ¹**ï¼éè¦æ¶å¯æåæ ·æ¹å¼å¯¹é½ |
| | | - 导åºä¸å页å
±ç¨åä¸å¥æ¥è¯¢åæ°ï¼ä¿®å¤å导åºä¼å¸¦ä¸é¡µé¢ä¸å·²éçç鿡件 |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # MES ç©æç®¡çå表æåº - å端èè°æ¹æ¡ |
| | | |
| | | > éæ±ï¼ç©æç®¡çå表çæåºä¸æ¸
æ°ï¼åå
æå建å
åååºï¼åä¸åç±»çç©æè¢«ææ£ï¼ï¼æ¹ä¸ºæãç©æåç±»ãå½ç±»æåºã |
| | | > æ¬æ¬¡ä»
è°æ´å端é»è®¤æåºï¼**æ¥å£è·¯å¾ã请æ±åæ°ãååºç»æåæªåå**ï¼åç«¯ä¸æ¹ä¹è½ç«å³çæã |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - `views/mes/md/item/index.vue`ï¼ç©æç®¡çåè¡¨ï¼ |
| | | - ç©æéæ©å¼¹çªï¼å¤ç¨åä¸å页æ¥å£ `/mes/md/item/page`ï¼æåºåæ¥çæï¼ |
| | | |
| | | ## API |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | GET | `/mes/md/item/page` | ç©æäº§ååé¡µï¼æåºè§åè§ä¸ï¼æ åæ°ååï¼ | |
| | | |
| | | **请æ±åæ°ï¼** æ æ°å¢ãæ å é¤ã |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | code | String | å¦ | ç©æç¼ç ï¼æ¨¡ç³å¹é
| |
| | | | name | String | å¦ | ç©æåç§°ï¼æ¨¡ç³å¹é
| |
| | | | itemTypeId | Long | å¦ | ç©æåç±»ç¼å·ï¼**å«å
¶ææååç±»**ï¼å端æç´¢è¡¨åå½åæªæä¾è¯¥çé项ï¼å¯æéè¡¥å
ï¼ | |
| | | | status | Integer | å¦ | ç¶æ | |
| | | |
| | | ## æåºè§å |
| | | |
| | | å表é»è®¤æåºï¼ç±å端ç»ä¸ç»åºï¼å端æ éä¼ æåºåæ°ï¼ï¼ |
| | | |
| | | | ä¼å
级 | æåºå段 | æ¹å | 说æ | |
| | | |--------|----------|------|------| |
| | | | 1 | ç©æåç±»çãæ¾ç¤ºæåºã | ååº | åç±»ä¹é´æå类管çéç»´æ¤çæ¾ç¤ºæåº | |
| | | | 2 | ç©æåç±»ç¼ç | ååº | æ¾ç¤ºæåºç¸åçåç±»ï¼æåç±»ç¼ç | |
| | | | 3 | ç©æç¼ç | ååº | åä¸åç±»å
é¨ï¼æç©æç¼ç | |
| | | |
| | | ææï¼**åä¸ç©æåç±»çç©æå¨å表ä¸è¿ç»æç»åºç°**ï¼å类顺åºå¯é¢æãå¯è°æ´ï¼ä¸åéå建æ¶é´æ£è½ã |
| | | |
| | | ## åæ®µå±ç¤ºè§å |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | ç©æåç±» | å表åãç©æåç±»ã | å·²å±ç¤ºï¼æ¬æ¬¡ä¸æ¹å段ï¼ä»
让åä¸åç±»çè®°å½ç¸é» | |
| | | | ç©æåç§°ãç©æç¼ç | å表å | ä»
å±ç¤ºï¼æªå å端ç¹å»æåºï¼æ¬æ¬¡æ¹å¨åªè°æ´é»è®¤é¡ºåºï¼ä¸å«åç¹å»æåºè½å | |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | é»è®¤æåº | åç±»æ¾ç¤ºæåº â åç±»ç¼ç â ç©æç¼ç | |
| | | | è°æ´é¡ºåº | å¨ãç©æåç±»ãä¸ä¿®æ¹åç±»çãæ¾ç¤ºæåºãï¼ç©æå表ç顺åºéä¹ååï¼æ 鿹代ç | |
| | | | æªè®¾ç½®åç±»çç©æ | å类为空ï¼å«å类被å é¤ï¼çç©ææå¨æåé¢ï¼ä¾¿äºåç°æªå½ç±»æ°æ® | |
| | | | åç±»çé | æåç±»çéæ¶å
å«å
¶ååç±»ï¼æåºè§åä¸å | |
| | | | å
¶å®æ¥è¯¢æ¡ä»¶ | ç¼ç / åç§° / ç¶æçéä¸å½±åæåºè§å | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - æ¬æ¬¡æ¯å端é»è®¤æåºååï¼**åç«¯ä¸æ¹ä»£ç å³å¯çå°ææ**ï¼ééå¯å端æå¡çæ |
| | | - 忥æãå建æ¶é´ååºãçæåºå·²åæ¶ï¼å¦éæ¢å¤ãææ°åå»ºçææåãï¼æéè¦ç¹å»è¡¨å¤´æåºï¼å±æ°å¢è½åï¼éå端é
åè°æ´ï¼å½å该åé¡µèµ°çæ¯è表æ¥è¯¢ï¼æ¡æ¶å±çå端æåºå段ä¸ä¼èªå¨çæï¼ |
| | | - ç©æéæ©å¼¹çªï¼éæ©ç©ææ¶å¼¹åºçå表ï¼ä¸ç©æç®¡çå表å
±ç¨å䏿¥å£ï¼æåºä¸èµ·ååï¼å±äºé¢æ |
| | | - åç±»çãæ¾ç¤ºæåºã为空çåç±»ä¼æå¨è®¾ç½®äºæåºçåç±»ä¹å |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 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`ï¼èåå·²æ°å¢ï¼è´¨æ£ç®¡ç -> æ¥ææ£éª/è¿ç¨æ£éª/åºè´§æ£éª -> ãæ¥ææ£éªå¯¼å
¥ / è¿ç¨æ£éªå¯¼å
¥ / åºè´§æ£éªå¯¼å
¥ãï¼å·²æäºæ¥æ/è¿ç¨/åºè´§æ£éªç°æè§è²ï¼ã |
| | | |
| | | **请æ±åæ°ï¼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` åç§°ï¼èªå¶å·¥åºæ£éª / 馿£ / å·¡æ£ / èªæ£ / æåæ£éª | |
| | | | ç产工åå· | æ¯ | éä¸ãç产管ç-ç产工åãä¸çå·¥åå·ä¸è´ï¼**产åç©æç±å·¥åæ¨å¯¼ï¼æ¨¡æ¿ä¸å¡«ç©æ** | |
| | | | å·¥ä½åç§° | æ¯ | éä¸ãåºç¡æ°æ®-å·¥ä½ç®¡çãä¸çåç§°ä¸è´ | |
| | | | è´¨æ£æ¹æ¡ | å¦ | å¡«æ¹æ¡åç§°ï¼ç空åå端æç©æèªå¨å¹é
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 åºåæ°é | å·¥åº + æåº + å
¶ä»åºå ä¹åä¸å¾è¶
è¿ä¸åæ ¼åæ°éï¼è¶
åºè¯¥è¡å¤±è´¥ | |
| | | | IPQC ç©ææ¥æº | 产åç©æç±ãç产工åå·ãæ¨å¯¼ï¼æ¨¡æ¿ä¸æä¾ç©æåï¼å·¥åä¸å卿æªç¡®è®¤æ¶è¯¥è¡å¤±è´¥ | |
| | | | ç¶æ | 导å
¥åçæ£éªåç»ä¸ä¸ºãå¾
æ£éªãï¼è稿ï¼ï¼ä¸ç´æ¥å®æ | |
| | | | æ£éªè¡çæ | ç±å端æå¹é
å°çè´¨æ£æ¹æ¡èªå¨çææ£éªè¡ï¼æ£éªææ ï¼ï¼æ éå端é¢å¤å¤ç | |
| | | | OQC å®¢æ·æ°æ®æé | ã客æ·åç§°ãå¿
é¡»å¨å½åç»å½ç¨æ·çå¯è§å®¢æ·èå´å
ï¼å¦å该è¡å¤±è´¥ï¼å¦å导å
¥åå表ä¸ä¹çä¸å°è¯¥åï¼ | |
| | | | é¨åæå | éè¡å¯¼å
¥ï¼å¤±è´¥è¡ä¸å½±åæåè¡ï¼å䏿件å
ä¸ä¼æ´ä½åæ»ï¼ï¼å
¨é¨è¡ä¸ºç©ºæ¶è¿åç©ºç»æ | |
| | | | ç©ºè¡ | æ´è¡ä¸ºç©ºçè®°å½èªå¨è·³è¿ï¼ä¸è®°ä¸ºå¤±è´¥ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - ãæ£éªç±»åããæ£æµç»æãçåå
¸åå¡«**åç§°**ï¼å¦ 馿£ãæ ¡éªéè¿ï¼ï¼ä¹å
¼å®¹å¡«æ°åï¼1/2ï¼ï¼å¡«éæ¶å¤±è´¥åå ä¼ååºå¯éå¼ |
| | | - ãè´¨æ£æ¹æ¡ãåå¡«çæ¯**æ¹æ¡åç§°**ï¼ä¸æ¯æ¹æ¡ç¼ç ï¼ç空å³ä¸ºãèªå¨å¹é
ãï¼æ¯æ¨èç¨æ³ |
| | | - IPQC çãæ£éªç±»åãæ¯**å¿
å¡«**åï¼ä¸æ¹æ¡çæ£éªç±»åé䏿£éªåçç±»åå¯å¹é
ï¼å¦åå¯è½æç¤ºæªé
ç½®æ¹æ¡ |
| | | - ãæ£æµäººåãç空åå½åç»å½ç¨æ·ï¼å¡«åå§åæ¶è¥åå¨ååç¨æ·ï¼ä¼åå¹é
å°çç¬¬ä¸æ¡ï¼å»ºè®®å¡«å§åå
¨ç§° |
| | | - ä¸ä¸ªå表ç导å
¥äºä¸å½±åï¼æéç åèªç¬ç«ï¼èªå»ºè§è²éå¨ãè§è²ç®¡çãä¸å¾é对åºçãXXæ£éªå¯¼å
¥ãæé®åæå¯è§è¯¥æé® |
| | | - 导å
¥å¼¹çªçè¿åº¦æ¡ / ç»æåº / 模æ¿ä¸è½½äº¤äºå¯ç´æ¥å¤ç¨ç°æ `import-form.vue` å®ç° |
| | | - æ¥æåæ¯æ `yyyy-MM-dd HH:mm:ss` ä¸ `yyyy-MM-dd` ä¸¤ç§æ ¼å¼ï¼IQC çæ£æµ/æ¥ææ¥æãOQC çæ£æµ/åºè´§æ¥æä¸ºå¿
å¡«ï¼IPQC çæ£æµæ¥æå¯ç空 |
| | |
| | | "steps": [ |
| | | {"stage": "è·å®¢", "action": "线索转å客æ·ã建è系人ãç«é¡¹åæº", "roles": ["éå®å
å¤"]}, |
| | | {"stage": "æ¥ä»·", "action": "åæºèµ¢åå建æ¥ä»·å(AI OCR é¢å¡«)ï¼è½¬åå", "roles": ["éå®å
å¤"]}, |
| | | {"stage": "ç¾çº¦", "action": "ååæäº¤ BPM 审æ¹(å¯éæµç¨å®ä¹)ï¼éè¿=20", "roles": ["éå®", "审æ¹äºº"]}, |
| | | {"stage": "ç¾çº¦", "action": "å忥æºï¼æå·¥æ°å»º / æ¥ä»·å转å
¥ / Excel 导å
¥(ä¸ååå¤äº§åæç»è¡)ï¼æäº¤ BPM 审æ¹(å¯éæµç¨å®ä¹)ï¼éè¿=20", "roles": ["éå®", "审æ¹äºº"]}, |
| | | {"stage": "æ¥å", "action": "ååä¸é®çæéå®è®¢å(XSDD)ï¼éå®è®¢ååèµ° BPMï¼å®¡æ¹éè¿èªå¨ä¸º needProduction æç»å建 MPS", "roles": ["éå®", "计åå"]}, |
| | | {"stage": "交ä»", "action": "åè´§éç¥å®¡æ ¸(å ç¨)â éå®åºåº OQC â åè¿ â åºåºååé¨å/å
¨é¨åºåº", "roles": ["ä»ç®¡", "è´¨æ£"]}, |
| | | {"stage": "忬¾", "action": "å¼ç¥¨ BPM(累计â¤ååé¢) â 忬¾å¼ºå¶å
å¼ç¥¨(累计â¤ååå©ä½ä¸å¼ç¥¨å©ä½)", "roles": ["è´¢å¡", "éå®"]}]}, |
| | |
| | | {"stage": "è¿ç¨", "action": "æ¥å·¥è´¨æ£å·¥åºäº§åºè¡âIPQCï¼åæ ¼æè¡å
¥åºãä¸åæ ¼çæ NCR", "roles": ["IPQC è´¨æ£å"]}, |
| | | {"stage": "åºè´§", "action": "éå®åºåºæäº¤âOQCï¼å®æååºåºåè¿å
¥å¾
æ£è´§", "roles": ["OQC è´¨æ£å"]}, |
| | | {"stage": "éè´§", "action": "éæ/éå®éè´§/å®åéè´§âRQCï¼ç»è®ºåè°åæ®ä¸å®å", "roles": ["RQC è´¨æ£å"]}, |
| | | {"stage": "导å
¥", "action": "IQC/IPQC/OQC ä¸åè¡¨åæ¯æ Excel æ¹é导å
¥(æé®å¨ãæ°å¢ãä¸ã导åºãä¹é´ï¼çº¯æ°å¢ä¸åæ´æ°è¦ç)ï¼ä¸è¡ä¸å¼ åï¼ç¼å·ç空èªå¨çæï¼è´¨æ£æ¹æ¡ç空æç©æ+æ£éªç±»åèªå¨å¹é
ï¼æ£æµäººåç空åå½åç»å½ç¨æ·ï¼ç©æ/ä¾åºå/客æ·/å·¥å/工使ç¼ç æå称精确å¹é
(IPQC ç©æç±å·¥åæ¨å¯¼ï¼æ¨¡æ¿ä¸å¡«)ï¼åæ ¼+ä¸åæ ¼=æ£æµ/æ¥æ¶æ°éãIPQC å·¥åº+æåº+å
¶ä»åºåâ¤ä¸åæ ¼ãOQC 客æ·é¡»å¨æ¬äººæ°æ®æéå
ï¼éè¡å¯¼å
¥é¨åæåï¼å¤±è´¥è¡è¿ failureList 带è¡å·ä¸å¯æ§è¡å¨ä½ï¼æååä¸å¾å¾
æ£éª0ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ï¼æä»¶å
éå¤è¡ä¸åºå
å·²åå¨åä¸å¡é®åæ®ï¼IQC ç©æ+ä¾åºå+ä¾åºåæ¹æ¬¡+æ¥ææ¥æãIPQC ç产工å+æ£éªç±»å+å·¥ä½+æ£æµæ¥æãOQC ç©æ+客æ·+æ¹æ¬¡å·+åºè´§æ¥æï¼åæè¯¥è¡ï¼æç¤ºå«ç»´åº¦ãåæ¹å®é
å¼ä¸ãå
å é¤è¯¥åæ®åéè¯ãå¨ä½", "roles": ["è´¨æ£å", "IQC è´¨æ£å", "IPQC è´¨æ£å", "OQC è´¨æ£å"]}, |
| | | {"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审æ¹âçæéå®è®¢åÂ·æ¯æExcel导å
¥)", "å¼ç¥¨(BPM审æ¹Â·æ¯æExcel导å
¥Â·å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥)â忬¾(å
å¼ç¥¨æ ¡éª)", "忬¾è®¡å", "éå®ç®æ ", "æ°æ®æéä¸çº§(è´è´£äºº/åªè¯»/读å)"], |
| | | "objects": ["线索", "客æ·", "è系人", "åæº", "æ¥ä»·å", "åå", "å票", "忬¾", "éå®ç®æ "], |
| | | "roles": ["éå®å
å¤", "éå®ç»ç", "è´¢å¡(å¼ç¥¨å款)"], |
| | | "upstream": ["ä¸»æ°æ®(ç©æ)"], "downstream": ["è¿éå(éå®è®¢å)", "å®å(客æ·)", "AI(æ¥ä»·OCR)"], |
| | |
| | | {"name": "è系人", "module": "éå®ç®¡ç", "table": "crm_contact", "doc": "客æ·ä¸è系人ï¼ä¸åæºå¤å¯¹å¤", "upstream": ["客æ·"], "downstream": ["åæº"], "keywords": "è系人 contact"}, |
| | | {"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_contract", "doc": "HTç¼å·ï¼BPM 审æ¹(0è稿/10审æ¹ä¸/20éè¿/30驳å/40åæ¶/50ä½åº)ï¼éè¿åå¯çæéå®è®¢åï¼æ¯æ Excel 导å
¥ï¼ä¸ååå¤äº§åæç»è¡ãåå¹¶åå
æ ¼èªå¨æå¹³ï¼å®¢æ·ä¸ç©ææåç§°/ç¼ç æ ¡éªï¼ï¼äº§åæç»å¸¦åºç©æåç§°/ç¼ç /æ¡ç /è§æ ¼åå·/计éåä½ï¼å é¤ååæ¶è¿å¸¦å é¤äº§åæç»ï¼ä¸çå¤å¿æ°æ®", "upstream": ["æ¥ä»·å"], "downstream": ["éå®è®¢å", "忬¾è®¡å", "å¼ç¥¨"], "keywords": "åå contract å®¡æ¹ å¯¼å
¥"}, |
| | | {"name": "å票", "module": "éå®ç®¡ç", "table": "crm_invoice", "doc": "KPç¼å·ï¼å¯ç空èªå¨çæãç³»ç»å
å¯ä¸ï¼ï¼BPM 审æ¹ï¼ç´¯è®¡å¼ç¥¨â¤ååé¢ï¼éä»¶å¿
ä¼ ï¼æ¯æ Excel 导å
¥ï¼ä»
æ°å¢ä¸æ´æ°ï¼ååé¡»å®¡æ ¸éè¿ä¸æ¬æ¬¡éé¢â¤ååå©ä½å¯å¼ç¥¨é¢ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ââåååä¸å票å·ç ç¸åãæå票å·ç ç空æ¶å¼ç¥¨éé¢+å票æ¬å¤´+å¼ç¥¨æ¥æç¸åå³å¤éå¤ï¼æä»¶å
éå¤è¡ä¸åºå
å·²æåé½æè¯¥è¡å¹¶åæ¾ç»´åº¦ä¸å®é
å¼ï¼", "upstream": ["åå"], "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": "æ¥å·¥è´¨æ£å·¥åºäº§åºè¡è§¦åï¼å®æåè°æ¨è¿æ¥å·¥ä¸äº§åºå
¥åºï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§", "upstream": ["æ¥å·¥"], "downstream": ["产åºå
¥åº", "NCR", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "IPQC è¿ç¨æ£éª å·¡æ£ åºæ¥å"}, |
| | | {"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": "æ¥å·¥è´¨æ£å·¥åºäº§åºè¡è§¦åï¼å®æåè°æ¨è¿æ¥å·¥ä¸äº§åºå
¥åºï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§ï¼æ¯æ Excel æ¹é导å
¥ï¼äº§åç©æç±çäº§å·¥åæ¨å¯¼ï¼æ¨¡æ¿ä¸å¡«ç©æï¼å·¥åº+æåº+å
¶ä»åºåä¸å¾è¶
è¿ä¸åæ ¼åæ°éï¼ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ï¼ç产工å+æ£éªç±»å+å·¥ä½+æ£æµæ¥æï¼æä»¶å
éå¤è¡ä¸åºå
å·²æåé½æè¯¥è¡ï¼", "upstream": ["æ¥å·¥", "Excel æ¹é导å
¥"], "downstream": ["产åºå
¥åº", "NCR", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "IPQC è¿ç¨æ£éª å·¡æ£ åºæ¥å æ¹é导å
¥ 导å
¥æ¨¡æ¿"}, |
| | | {"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审æ¹âçæéå®è®¢åÂ·æ¯æExcel导å
¥)", "å¼ç¥¨(BPM审æ¹Â·æ¯æExcel导å
¥Â·å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥)â忬¾(å
å¼ç¥¨æ ¡éª)", "忬¾è®¡å", "éå®ç®æ ", "æ°æ®æéä¸çº§(è´è´£äºº/åªè¯»/读å)"], |
| | | "objects": ["线索", "客æ·", "è系人", "åæº", "æ¥ä»·å", "åå", "å票", "忬¾", "éå®ç®æ "], |
| | | "roles": ["éå®å
å¤", "éå®ç»ç", "è´¢å¡(å¼ç¥¨å款)"], |
| | | "upstream": ["ä¸»æ°æ®(ç©æ)"], "downstream": ["è¿éå(éå®è®¢å)", "å®å(客æ·)", "AI(æ¥ä»·OCR)"], |
| | |
| | | {"name": "è系人", "module": "éå®ç®¡ç", "table": "crm_contact", "doc": "客æ·ä¸è系人ï¼ä¸åæºå¤å¯¹å¤", "upstream": ["客æ·"], "downstream": ["åæº"], "keywords": "è系人 contact"}, |
| | | {"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_contract", "doc": "HTç¼å·ï¼BPM 审æ¹(0è稿/10审æ¹ä¸/20éè¿/30驳å/40åæ¶/50ä½åº)ï¼éè¿åå¯çæéå®è®¢åï¼æ¯æ Excel 导å
¥ï¼ä¸ååå¤äº§åæç»è¡ãåå¹¶åå
æ ¼èªå¨æå¹³ï¼å®¢æ·ä¸ç©ææåç§°/ç¼ç æ ¡éªï¼ï¼äº§åæç»å¸¦åºç©æåç§°/ç¼ç /æ¡ç /è§æ ¼åå·/计éåä½ï¼å é¤ååæ¶è¿å¸¦å é¤äº§åæç»ï¼ä¸çå¤å¿æ°æ®", "upstream": ["æ¥ä»·å"], "downstream": ["éå®è®¢å", "忬¾è®¡å", "å¼ç¥¨"], "keywords": "åå contract å®¡æ¹ å¯¼å
¥"}, |
| | | {"name": "å票", "module": "éå®ç®¡ç", "table": "crm_invoice", "doc": "KPç¼å·ï¼å¯ç空èªå¨çæãç³»ç»å
å¯ä¸ï¼ï¼BPM 审æ¹ï¼ç´¯è®¡å¼ç¥¨â¤ååé¢ï¼éä»¶å¿
ä¼ ï¼æ¯æ Excel 导å
¥ï¼ä»
æ°å¢ä¸æ´æ°ï¼ååé¡»å®¡æ ¸éè¿ä¸æ¬æ¬¡éé¢â¤ååå©ä½å¯å¼ç¥¨é¢ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ââåååä¸å票å·ç ç¸åãæå票å·ç ç空æ¶å¼ç¥¨éé¢+å票æ¬å¤´+å¼ç¥¨æ¥æç¸åå³å¤éå¤ï¼æä»¶å
éå¤è¡ä¸åºå
å·²æåé½æè¯¥è¡å¹¶åæ¾ç»´åº¦ä¸å®é
å¼ï¼", "upstream": ["åå"], "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": "æ¥å·¥è´¨æ£å·¥åºäº§åºè¡è§¦åï¼å®æåè°æ¨è¿æ¥å·¥ä¸äº§åºå
¥åºï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§", "upstream": ["æ¥å·¥"], "downstream": ["产åºå
¥åº", "NCR", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "IPQC è¿ç¨æ£éª å·¡æ£ åºæ¥å"}, |
| | | {"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": "æ¥å·¥è´¨æ£å·¥åºäº§åºè¡è§¦åï¼å®æåè°æ¨è¿æ¥å·¥ä¸äº§åºå
¥åºï¼è¡æä½ãåºæ¥åãä»
å¨å·²å®ææ¶å¯è§ï¼æ¯æ Excel æ¹é导å
¥ï¼äº§åç©æç±çäº§å·¥åæ¨å¯¼ï¼æ¨¡æ¿ä¸å¡«ç©æï¼å·¥åº+æåº+å
¶ä»åºåä¸å¾è¶
è¿ä¸åæ ¼åæ°éï¼ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ï¼ç产工å+æ£éªç±»å+å·¥ä½+æ£æµæ¥æï¼æä»¶å
éå¤è¡ä¸åºå
å·²æåé½æè¯¥è¡ï¼", "upstream": ["æ¥å·¥", "Excel æ¹é导å
¥"], "downstream": ["产åºå
¥åº", "NCR", "æ¥åå®ä¾(åºæ¥å)"], "keywords": "IPQC è¿ç¨æ£éª å·¡æ£ åºæ¥å æ¹é导å
¥ 导å
¥æ¨¡æ¿"}, |
| | | {"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"}, |
| | |
| | | "steps": [ |
| | | {"stage": "è·å®¢", "action": "线索转å客æ·ã建è系人ãç«é¡¹åæº", "roles": ["éå®å
å¤"]}, |
| | | {"stage": "æ¥ä»·", "action": "åæºèµ¢åå建æ¥ä»·å(AI OCR é¢å¡«)ï¼è½¬åå", "roles": ["éå®å
å¤"]}, |
| | | {"stage": "ç¾çº¦", "action": "ååæäº¤ BPM 审æ¹(å¯éæµç¨å®ä¹)ï¼éè¿=20", "roles": ["éå®", "审æ¹äºº"]}, |
| | | {"stage": "ç¾çº¦", "action": "å忥æºï¼æå·¥æ°å»º / æ¥ä»·å转å
¥ / Excel 导å
¥(ä¸ååå¤äº§åæç»è¡)ï¼æäº¤ BPM 审æ¹(å¯éæµç¨å®ä¹)ï¼éè¿=20", "roles": ["éå®", "审æ¹äºº"]}, |
| | | {"stage": "æ¥å", "action": "ååä¸é®çæéå®è®¢å(XSDD)ï¼éå®è®¢ååèµ° BPMï¼å®¡æ¹éè¿èªå¨ä¸º needProduction æç»å建 MPS", "roles": ["éå®", "计åå"]}, |
| | | {"stage": "交ä»", "action": "åè´§éç¥å®¡æ ¸(å ç¨)â éå®åºåº OQC â åè¿ â åºåºååé¨å/å
¨é¨åºåº", "roles": ["ä»ç®¡", "è´¨æ£"]}, |
| | | {"stage": "忬¾", "action": "å¼ç¥¨ BPM(累计â¤ååé¢) â 忬¾å¼ºå¶å
å¼ç¥¨(累计â¤ååå©ä½ä¸å¼ç¥¨å©ä½)", "roles": ["è´¢å¡", "éå®"]}]}, |
| | |
| | | {"stage": "è¿ç¨", "action": "æ¥å·¥è´¨æ£å·¥åºäº§åºè¡âIPQCï¼åæ ¼æè¡å
¥åºãä¸åæ ¼çæ NCR", "roles": ["IPQC è´¨æ£å"]}, |
| | | {"stage": "åºè´§", "action": "éå®åºåºæäº¤âOQCï¼å®æååºåºåè¿å
¥å¾
æ£è´§", "roles": ["OQC è´¨æ£å"]}, |
| | | {"stage": "éè´§", "action": "éæ/éå®éè´§/å®åéè´§âRQCï¼ç»è®ºåè°åæ®ä¸å®å", "roles": ["RQC è´¨æ£å"]}, |
| | | {"stage": "导å
¥", "action": "IQC/IPQC/OQC ä¸åè¡¨åæ¯æ Excel æ¹é导å
¥(æé®å¨ãæ°å¢ãä¸ã导åºãä¹é´ï¼çº¯æ°å¢ä¸åæ´æ°è¦ç)ï¼ä¸è¡ä¸å¼ åï¼ç¼å·ç空èªå¨çæï¼è´¨æ£æ¹æ¡ç空æç©æ+æ£éªç±»åèªå¨å¹é
ï¼æ£æµäººåç空åå½åç»å½ç¨æ·ï¼ç©æ/ä¾åºå/客æ·/å·¥å/工使ç¼ç æå称精确å¹é
(IPQC ç©æç±å·¥åæ¨å¯¼ï¼æ¨¡æ¿ä¸å¡«)ï¼åæ ¼+ä¸åæ ¼=æ£æµ/æ¥æ¶æ°éãIPQC å·¥åº+æåº+å
¶ä»åºåâ¤ä¸åæ ¼ãOQC 客æ·é¡»å¨æ¬äººæ°æ®æéå
ï¼éè¡å¯¼å
¥é¨åæåï¼å¤±è´¥è¡è¿ failureList 带è¡å·ä¸å¯æ§è¡å¨ä½ï¼æååä¸å¾å¾
æ£éª0ï¼å䏿¹æ°æ®ä¸å¯éå¤å¯¼å
¥ï¼æä»¶å
éå¤è¡ä¸åºå
å·²åå¨åä¸å¡é®åæ®ï¼IQC ç©æ+ä¾åºå+ä¾åºåæ¹æ¬¡+æ¥ææ¥æãIPQC ç产工å+æ£éªç±»å+å·¥ä½+æ£æµæ¥æãOQC ç©æ+客æ·+æ¹æ¬¡å·+åºè´§æ¥æï¼åæè¯¥è¡ï¼æç¤ºå«ç»´åº¦ãåæ¹å®é
å¼ä¸ãå
å é¤è¯¥åæ®åéè¯ãå¨ä½", "roles": ["è´¨æ£å", "IQC è´¨æ£å", "IPQC è´¨æ£å", "OQC è´¨æ£å"]}, |
| | | {"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": ["è´¨æ£å", "è´¨éå·¥ç¨å¸"]}]}, |
| | |
| | | E -->|è¾åææ æ| X[ç»æ] |
| | | F -->|转åå·带å
¥å®¢æ·äº§åææ£| G[åå HT·è稿0â审æ¹ä¸10] |
| | | D -->|ç´æ¥å»ºåå| G |
| | | Q[åå Excel 导å
¥Â·ä¸ååå¤äº§åæç»è¡] -->|æ¹é建è稿åå| G |
| | | G -->|BPM审æ¹éè¿20| H[çæ ERP éå®è®¢å XSDD] |
| | | H -->|æäº¤BPM| I[éå®è®¢å审æ¹Â·å®¡æ¹ä¸15âå·²å®¡æ ¸20] |
| | | I -->|æç»éç产·èªå¨å建| J[MES 主ç产计å MPS] |
| | |
| | | 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 å·¥åº+æåº+å
¶ä»åºå ä¸å¾è¶
è¿ä¸åæ ¼åæ°é| IMPQ |
| | | IMP -.->|OQC æ ¡éªå®¢æ·å¨æ¬äººæ°æ®æéå
·å¦å导å
¥åå表ä¹çä¸å°| IMPP[æ°æ®æéåç½®æ ¡éª] |
| | | IMP -.->|æ£æµäººåç空=å½åç»å½ç¨æ·Â·IQCæ£æµ/æ¥ææ¥æä¸OQCæ£æµ/åºè´§æ¥æå¿
å¡«| IMPD[人å䏿¥æ] |
| | | IMP --> IMR[ååº createList æåç¼å· + failureList è¡å·âåå ·æ´è¡ç©ºèªå¨è·³è¿] |
| | | IMR -.->|导å
¥åä¸å¾å¾
æ£éª0·ä¸èµ°æ¥æºåæ®åå·ä¸çæNCR| IMRNOTE[ä¸è§¦åå¼å»ºåçåºå«Â·finish æå¤å®ä¸åå] |
| | | 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 |
| | |
| | | E -->|è¾åææ æ| X[ç»æ] |
| | | F -->|转åå·带å
¥å®¢æ·äº§åææ£| G[åå HT·è稿0â审æ¹ä¸10] |
| | | D -->|ç´æ¥å»ºåå| G |
| | | Q[åå Excel 导å
¥Â·ä¸ååå¤äº§åæç»è¡] -->|æ¹é建è稿åå| G |
| | | G -->|BPM审æ¹éè¿20| H[çæ ERP éå®è®¢å XSDD] |
| | | H -->|æäº¤BPM| I[éå®è®¢å审æ¹Â·å®¡æ¹ä¸15âå·²å®¡æ ¸20] |
| | | I -->|æç»éç产·èªå¨å建| J[MES 主ç产计å MPS] |
| | |
| | | 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 å·¥åº+æåº+å
¶ä»åºå ä¸å¾è¶
è¿ä¸åæ ¼åæ°é| IMPQ |
| | | IMP -.->|OQC æ ¡éªå®¢æ·å¨æ¬äººæ°æ®æéå
·å¦å导å
¥åå表ä¹çä¸å°| IMPP[æ°æ®æéåç½®æ ¡éª] |
| | | IMP -.->|æ£æµäººåç空=å½åç»å½ç¨æ·Â·IQCæ£æµ/æ¥ææ¥æä¸OQCæ£æµ/åºè´§æ¥æå¿
å¡«| IMPD[人å䏿¥æ] |
| | | IMP --> IMR[ååº createList æåç¼å· + failureList è¡å·âåå ·æ´è¡ç©ºèªå¨è·³è¿] |
| | | IMR -.->|导å
¥åä¸å¾å¾
æ£éª0·ä¸èµ°æ¥æºåæ®åå·ä¸çæNCR| IMRNOTE[ä¸è§¦åå¼å»ºåçåºå«Â·finish æå¤å®ä¸åå] |
| | | A1 --> R{æ£éªå¤å® MesQcCheckResultEnum} |
| | | A2 --> R |
| | | A3 --> R |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # è´¨é管ç - æ£æµç»æå°è´¦ï¼åç±» / æ¶é´åºé´çé + 导åºï¼ - å端èè°æ¹æ¡ |
| | | |
| | | > æ¬æ¬¡è§£å³ä¸¤ä»¶äºï¼ |
| | | > 1. **ç´æ¥å±ç¤º**ï¼åç±»æ£éªåï¼IQC/IPQC/OQC/RQCï¼å表æ¥å£**å·²ç»è¿å**æ£éªé¡¹å®æµç»ææ±æ»å段 `indicatorResultSummary`ï¼ä½å端å表æªå±ç¤º â å端å ä¸åå³å¯ï¼**å端æ éæ¹å¨**ã |
| | | > 2. **çéå±ç¤º + 导åºå°è´¦**ï¼æ°å¢è·¨åç±»çãæ£æµç»æå°è´¦ãæ¥è¯¢ä¸å¯¼åºæ¥å£ï¼åç±» + æ£æµæ¥æåºé´ + ç©æ/æ¹æ¬¡/æ£æµç»æ/æ£æµäººçéï¼ï¼ä¸è¡ä¸ä¸ªæ£æµé¡¹ç»æï¼ç¨äºæ¥è¯¢ãæå°ãåæ¡£ã |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - **æ°å¢**ï¼æ£æµç»æå°è´¦é¡µ `views/mes/qc/ledger/index.vue`ï¼èåå·²ç±å端 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. æ£éªåæªå½å
¥æ£éªç»ææ¶ï¼è¯¥åä»ä¼åºç°å¨å°è´¦ä¸ï¼æ£æµé¡¹ç¸å
³å为空ï¼ï¼ä¸ä¼æ¼åã |
| | | |
| | | ## 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 | - | ç©æä¿¡æ¯ï¼ç¼ç ãåç§°ãè§æ ¼åå·ã计éåä½ï¼ | |
| | | | 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ï¼åæ°ä¸å页æ¥å£å®å
¨ä¸è´ | |
| | | |
| | | **导åºåï¼** åç±» / æ£éªåç¼å· / æ£éªååç§° / ç©æç¼ç / ç©æåç§° / è§æ ¼åå· / æ¹æ¬¡å· / æ£æµé¡¹ / æ£æµå¼ / å¤å®ä¾æ® / æ£æµç»æ / æ£æµæ°é / åæ ¼æ°é / ä¸åæ ¼æ°é / æ£æµäººå / æ£æµæ¥æ / åæ®ç¶æ / 夿³¨ã |
| | | |
| | | ## æéä¸èåï¼å·²ç±å端 SQL é
ç½®å®æï¼ |
| | | |
| | | | èå | æéç | 说æ | |
| | | |------|--------|------| |
| | | | è´¨é管ç â æ£æµç»æå°è´¦ | â | type=2ï¼component `mes/qc/ledger/index` | |
| | | | æ£æµç»æå°è´¦æ¥è¯¢ | `mes:qc-inspection-ledger:query` | 页é¢å è½½ãå页æ¥è¯¢ | |
| | | | æ£æµç»æå°è´¦å¯¼åº | `mes:qc-inspection-ledger:export` | å¯¼åºæé® | |
| | | |
| | | èåå·²ææç»ææææãæ¥ææ£éªæ¥è¯¢ãçè§è²ï¼å端建好 `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 ååº | |
| | | | æ¶é´åºé´ | æãæ£æµæ¥æãéåºé´è¿æ»¤ï¼åªä¼ å¼å§æåªä¼ ç»æåå¯ | |
| | | | ä¸è¡ä¸æ£æµé¡¹ | ä¸å¼ æ£éªåå½å
¥å¤ä¸ªæ£æµé¡¹ç»ææ¶å±å¼ä¸ºå¤è¡ï¼å
¶ä½å段éå¤ï¼ | |
| | | | æ£éªåæªå½å
¥æ£æµé¡¹ | 该åä¿çä¸è¡ï¼æ£æµé¡¹ / æ£æµå¼ / å¤å®ä¾æ®ä¸ºç©º | |
| | | | å¤å®ä¾æ® | ç±æ£éªåè¡çæ åå¼ä¸è¯¯å·®ä¸ä¸éæ¼è£
ï¼ä¸ä¸é齿 â `ä¸é~ä¸é`ï¼ä»
ä¸é â `â¤ä¸é`ï¼ä»
ä¸é â `â¥ä¸é`ï¼ä»
æ åå¼ â `æ åå¼ å¼`ï¼é½æ²¡æå为空 | |
| | | | é»è¾å é¤ | å·²å é¤çæ£éªåä¸åºç°å¨å°è´¦ï¼å·²å é¤çæ£æµé¡¹ä»å±ç¤ºå
¶åå²åç§°ï¼ä¿è¯åå²å°è´¦å¯è¯» | |
| | | | 导åºèå´ | 导åºéµå¾ªå½åç鿡件ï¼ä¸éæ¶é´å导åºå
¨é¨ç¬¦åå
¶å®æ¡ä»¶çè®°å½ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - æ¬æ¬¡å端æ°å¢äºé¡µé¢æ¥å£ä¸èåï¼**ééå¯å端æå¡**åæ°æ¥å£æå¯ç¨ï¼ç¸å
³è§è²ééæ°ç»å½ä»¥å·æ°èå䏿éç¼åã |
| | | - å°è´¦æ¥å£ç `qcId` + `qcType` å¯å®ä½å°åå§æ£éªåï¼è¥éè¦ç¹å»è·³è½¬ï¼è¯·æå类跳å°å¯¹åºé¡µé¢ï¼æ¥ææ£éª / è¿ç¨æ£éª / åºè´§æ£éª / éè´§æ£éªï¼ã |
| | | - å°è´¦çãæ£æµç»æãåä¸åç±»æ£éªåå表çãæ£æµç»æãåå£å¾ä¸è´ï¼å忣éªåå¤´çæ£æµç»è®ºï¼åå
¸ `mes_qc_check_result`ï¼ã |
| | | - åç±»æ£éªåå表æ°å¢çãæ£æµç»æï¼æ£éªé¡¹ï¼ãåç´æ¥ä½¿ç¨å·²æå段 `indicatorResultSummary`ï¼ä¸éè¦æ°æ¥å£ï¼å¯¼åºæ¶è¯¥å
容已å
å«å¨ãæ£éªææ ãåä¸ã |
| | | - å°è´¦ä¸ºåªè¯»é¡µé¢ï¼ä¸æä¾æ°å¢ / ä¿®æ¹ / å 餿ä½ã |
| | |
| | | # å¼ç¥¨ä¸å款å
³èï¼å
å¼ç¥¨å忬¾ï¼ - å端èè°æ¹æ¡ |
| | | |
| | | > **æ¬æ¬¡è°æ´ï¼ææ°ï¼**ï¼å款å建表åçãå
³èå¼ç¥¨ãä¸ã忬¾ææ°ãç±å¿
å¡«æ¹ä¸º**éå¡«**ï¼æ¯æãæªå
³èå¼ç¥¨ / æªå
³è忬¾è®¡åãç´æ¥å½å
¥å款ã |
| | | > å端已æ¾å¼ï¼`invoiceId` ä¸å强å¶ï¼ï¼å端é廿è¿ä¸¤ä¸ªå段çå¿
å¡«æ ¡éªï¼è¯¦è§ææ«ãæ¬æ¬¡è°æ´ãç« èã |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - 忬¾ç®¡çå表页 |
| | |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | POST | `/crm/receivable/create` | 请æ±ä½æ°å¢ `invoiceId`ï¼**å¿
å¡«**ï¼ | |
| | | | POST | `/crm/receivable/create` | 请æ±ä½æ°å¢ `invoiceId`ï¼**éå¡«**ï¼ | |
| | | | PUT | `/crm/receivable/update` | 请æ±ä½æ°å¢ `invoiceId`ï¼å¯ä¿®æ¹ï¼ | |
| | | |
| | | **请æ±åæ°æ°å¢ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | invoiceId | Long | æ¯ | å
³èçå¼ç¥¨ç¼å·ï¼å¿
须为审æ¹éè¿ä¸å·²ä¸ä¼ éä»¶çå¼ç¥¨ | |
| | | | invoiceId | Long | å¦ | å
³èçå¼ç¥¨ç¼å·ãå¡«åæ¶å¿
须为审æ¹éè¿ä¸å·²ä¸ä¼ éä»¶çå¼ç¥¨ï¼ä¸å¡«è¡¨ç¤ºè¯¥ç¬å款æä¸å
³èå¼ç¥¨ | |
| | | | planId | Long | å¦ | å
³èç忬¾è®¡åç¼å·ãä¸å¡«è¡¨ç¤ºä¸å ç¨åæ¬¾è®¡åææ° | |
| | | |
| | | ### 3. åæ´æ¥å£ï¼å款æ¥è¯¢ï¼ååºæ°å¢åæ®µï¼ |
| | | |
| | |
| | | | å©ä½å¯å款éé¢ | å¼ç¥¨å表åãå¼ç¥¨è¯¦æ
页 | å¼ç¥¨éé¢ - 该å¼ç¥¨å·²å款éé¢ | |
| | | | æ¯å¦å·²ä¸ä¼ éä»¶ | å¼ç¥¨å表å | è¾
å©å¤æå¼ç¥¨æ¯å¦å¯å款ï¼é审æ¹éè¿ + å·²ä¸ä¼ éä»¶ï¼ | |
| | | |
| | | ## æ¬æ¬¡è°æ´ï¼ãå
³èå¼ç¥¨ãã忬¾ææ°ãæ¹ä¸ºéå¡«ï¼ |
| | | |
| | | ### åæ´ç¹ |
| | | |
| | | | 项 | è°æ´å | è°æ´å | |
| | | |----|--------|--------| |
| | | | å
³èå¼ç¥¨ï¼invoiceIdï¼ | å¿
å¡«ï¼ä¸éæ æ³ä¿å | éå¡«ï¼ä¸éå³å½å
¥ä¸ç¬ä¸å
³èå¼ç¥¨ç忬¾ | |
| | | | 忬¾ææ°ï¼planIdï¼ | å¿
å¡«ï¼ä¸éæ æ³ä¿å | éå¡«ï¼ä¸éå³ä¸å ç¨åæ¬¾è®¡åææ° | |
| | | | ååï¼contractIdï¼ | å¿
å¡« | **ä»ä¸ºå¿
å¡«**ï¼éé¢ä¸éæ ¡éªä¾èµååï¼ | |
| | | | 忬¾éé¢ã忬¾æ¥æ | å¿
å¡« | **ä»ä¸ºå¿
å¡«** | |
| | | |
| | | ### åç«¯çæ¹å¨ç¹ï¼å»å¿
å¡«ï¼ |
| | | |
| | | - 忬¾å建/ç¼è¾è¡¨åçãå
³èå¼ç¥¨ãã忬¾ææ°ãä¸¤ä¸ªåæ®µï¼å»æå¿
å¡«æ ¡éªè§åå³å¯ï¼å
¶ä½èå¨é»è¾ï¼éåååå è½½å¼ç¥¨/ææ°é项ãéä¸å带å
¥å®¢æ·ä¸éé¢ï¼ä¿æä¸åã |
| | | - å»ºè®®åæ¶å¿
å¡«åï¼å段æç¤ºææ¡ç¸åºæ¹ä¸ºãå¯ä¸éã类表述ï¼é¿å
ç¨æ·è¯¯ä»¥ä¸ºæ¼å¡«ã |
| | | |
| | | ### ä¸å¡«æ¶çå端è¡ä¸º |
| | | |
| | | | åºæ¯ | è¡ä¸º | |
| | | |------|------| |
| | | | ä¸éå
³èå¼ç¥¨ | è·³è¿ãå¼ç¥¨æ¯å¦å®¡æ¹éè¿ / æ¯å¦å·²ä¸ä¼ éä»¶ / æ¯å¦ä¸ååä¸è´ãåãä¸è¶
è¿è¯¥å¼ç¥¨å©ä½å¯å款éé¢ãä¸¤ç»æ ¡éª | |
| | | | ä¸éå
³èå¼ç¥¨æ¶çéé¢ä¸é | ä»å**åå级**æ ¡éªçº¦æï¼ç´¯è®¡å款ä¸å¾è¶
è¿ååæ»éé¢ | |
| | | | ä¸é忬¾ææ° | 䏿´æ°ä»»ä½å款计åç已忬¾æ è®°ï¼å款计åå表ä¸è¯¥æä»æ¾ç¤ºæªå款 | |
| | | | ç¼è¾æ¢æå款 | æªæäº¤ invoiceId æ¶ä¿çåå
³èå
³ç³»ï¼ä¸ä¼å æ¼ä¼ è被æ¸
空ï¼ï¼å¦éè§£é¤å
³èï¼éæ¾å¼æ¸
ç©ºè¯¥åæ®µï¼å½åå端ç¼è¾æè¯¥å段为ç¦ç¨ï¼å¦éæ¯æè§£é¤éå¦è¡å¼æ¾ï¼ | |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - `invoiceId` 为å¿
å¡«ï¼å款å建/æ´æ°**å¿
é¡»**æºå¸¦ï¼å¦åè¿ååæ°æ ¡éªé误ã |
| | | - `invoiceId`ã`planId` å为**éå¡«**ï¼å¡«äºå¼ç¥¨å°±æå¼ç¥¨æ ¡éªï¼ä¸å¡«åªåååéé¢ä¸é约æã |
| | | - `invoice`ã`remainingInvoicePrice`ã`hasAttachment` å为å端计ç®çåªè¯»å段ï¼å端**ä¸è¦**æäº¤ã |
| | | - 忬¾éé¢å»ºè®®å¨éä¸å¼ç¥¨åé¢å¡«ä¸º `remainingInvoicePrice`ï¼é¿å
è¶
é被åç«¯æ¦æªã |
| | | - åé忬¾æ°æ®è¥æªå
³èå¼ç¥¨ï¼`invoiceId` 为空ï¼ï¼ç¼è¾æ¶ä¼è¢«è¦æ±éæ°éæ©åæ ¼å¼ç¥¨ã |
| | | - åé忬¾æ°æ®è¥æªå
³èå¼ç¥¨ï¼`invoiceId` 为空ï¼ï¼ç¼è¾ä¿åæ¶ä¸åè¢«è¦æ±è¡¥éå¼ç¥¨ã |
| | | - å¼ç¥¨å表å±ç¤º"å©ä½å¯å款éé¢"æ¶ï¼ææ¡å»ºè®®ç¨"å©ä½å¯å款éé¢ï¼å«å®¡æ¹ä¸ï¼"é¿å
æ§ä¹ï¼ä¸åå"å·²å¼ç¥¨éé¢ï¼å«å®¡æ¹ä¸ï¼"å£å¾ä¸è´ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ===================================================== |
| | | -- CRM å¼ç¥¨å¯¼å
¥ èå䏿鮿é |
| | | -- æ°å¢æé®æéï¼crm:invoice:importï¼å¼ç¥¨å表ã导å
¥ãæé®ï¼ |
| | | -- æè½½å° å¼ç¥¨ç®¡çèåï¼parent_id = 1063093ï¼ |
| | | -- ===================================================== |
| | | |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES (1075417, 'å¼ç¥¨å¯¼å
¥', 'crm:invoice:import', 3, 5, 1063093, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- ä¸å¼ç¥¨ç®¡çå
¶å®æé®ï¼å¯¼åºãæ°å»ºå¼ç¥¨çï¼æäºç¸åçè§è² |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES |
| | | (2, 1075417, '1', NOW(), '1', NOW(), b'0'), |
| | | (155, 1075417, '1', NOW(), '1', NOW(), b'0'), |
| | | (160, 1075417, '1', NOW(), '1', NOW(), b'0'), |
| | | (161, 1075417, '1', NOW(), '1', NOW(), b'0'), |
| | | (162, 1075417, '1', NOW(), '1', NOW(), b'0'); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # -*- coding: utf-8 -*- |
| | | """éæ°çæ docs/sql/config_export_all_20260928.sqlï¼å
¨ééçæï¼æ¿æ¢ 0918 çï¼ã |
| | | |
| | | é¶æ®µä¸ï¼å½åæºåº ruoyi-vue-pro å
¨åº 416 å¼ è¡¨ CREATE TABLE + 6 ç±»é
ç½®æ°æ®ï¼mysqldump åé¢éï¼ã |
| | | é¶æ®µäºï¼æ²¿ç¨ 0918 æä»¶çè·¨åºèº«ä»½/èå/OAuth2 补导段ï¼éåå¤ç¨ï¼ã |
| | | """ |
| | | import re |
| | | import subprocess |
| | | import sys |
| | | |
| | | MYSQL_BIN = r"D:\MySQL\mysql-8.0.31-winx64\bin" |
| | | DB = "ruoyi-vue-pro" |
| | | USER = "root" |
| | | PWD = "1234" |
| | | |
| | | BASE_DIR = r"D:\develop\XingRuan\MOM\mom-pro2-after\docs\sql" |
| | | SRC_0918 = BASE_DIR + r"\config_export_all_20260918.sql" |
| | | OUT = BASE_DIR + r"\config_export_all_20260928.sql" |
| | | |
| | | MYSQL = MYSQL_BIN + r"\mysql.exe" |
| | | MYSQLDUMP = MYSQL_BIN + r"\mysqldump.exe" |
| | | |
| | | COMMON = ["--default-character-set=utf8mb4", "--no-tablespaces", "--skip-comments", |
| | | "--skip-add-locks", "--skip-disable-keys", "--skip-triggers", |
| | | "--column-statistics=0", "--set-gtid-purged=OFF", "--single-transaction"] |
| | | |
| | | # ---------------- 6 ç±»é
置表ï¼è¡¨å, è¿æ»¤æ¡ä»¶ None=å
¨è¡¨ï¼ ---------------- |
| | | SECTIONS = [ |
| | | ("â ååå®¡æ¹æµç¨ï¼å¼æå
æ°æ®+å®ä¹ï¼ä»
æ¿æ´»æµç¨ï¼ååå²/è¿è¡/身份ï¼", [ |
| | | ("act_ge_property", None), |
| | | ("act_id_property", None), |
| | | ("act_re_procdef", "SUSPENSION_STATE_=1"), |
| | | ("act_re_deployment", "ID_ IN (SELECT DEPLOYMENT_ID_ FROM act_re_procdef WHERE SUSPENSION_STATE_=1)"), |
| | | ("act_ge_bytearray", |
| | | "DEPLOYMENT_ID_ IN (SELECT DEPLOYMENT_ID_ FROM act_re_procdef WHERE SUSPENSION_STATE_=1) " |
| | | "OR NAME_ IN ('source','source-extra')"), |
| | | ("act_re_model", None), |
| | | ("bpm_process_definition_info", "deleted=0"), |
| | | ]), |
| | | ("â¡ ååï¼ä¸å¡éä»¶é
ç½® + åç±» + 表å + æ©å±é
ç½®ï¼", [ |
| | | ("bpm_business_attach", "deleted=0"), |
| | | ("bpm_category", "deleted=0"), |
| | | ("bpm_form", "deleted=0"), |
| | | ("bpm_user_group", "deleted=0"), |
| | | ("bpm_process_listener", "deleted=0"), |
| | | ("bpm_process_expression", "deleted=0"), |
| | | ]), |
| | | ("⢠BI å³çå¤§å± / go-view", [ |
| | | ("bi_dashboard", "deleted=0"), |
| | | ("bi_chart_config", "deleted=0"), |
| | | ("bi_data_source_config", "deleted=0"), |
| | | ("bi_warehouse_coordinate", "deleted=0"), |
| | | ("report_go_view_project", "deleted=0"), |
| | | ]), |
| | | ("⣠MES ç¼ç è§åï¼åæµæ°´è®°å½ï¼", [ |
| | | ("mes_md_auto_code_rule", "deleted=0"), |
| | | ("mes_md_auto_code_part", "deleted=0"), |
| | | ]), |
| | | ("⤠系ç»é
ç½®ä¸»æ°æ®ï¼åå
¸/ç§æ·/å
¬å¸é
ç½®ï¼å身份/èå/æ¥å¿ï¼", [ |
| | | ("system_dict_type", "deleted=0"), |
| | | ("system_dict_data", "deleted=0"), |
| | | ("system_tenant", "deleted=0"), |
| | | ("system_tenant_package", "deleted=0"), |
| | | ("system_company_config", "deleted=0"), |
| | | ]), |
| | | ("⥠AI é
ç½®ï¼ä»
模å+keyï¼+ åºç¡è®¾æ½é
置管ç", [ |
| | | ("ai_model", "deleted=0"), |
| | | ("ai_api_key", "deleted=0"), |
| | | ("infra_config", "deleted=0"), |
| | | ("infra_job", "deleted=0"), |
| | | ("infra_file_config", "deleted=0"), |
| | | ("infra_data_source_config", "deleted=0"), |
| | | ("infra_codegen_table", "deleted=0"), |
| | | ("infra_codegen_column", "deleted=0"), |
| | | ]), |
| | | ] |
| | | |
| | | |
| | | def run(cmd): |
| | | p = subprocess.run(cmd, capture_output=True) |
| | | if p.returncode != 0: |
| | | sys.stderr.write("FAILED: %s\n%s\n" % (" ".join(cmd), p.stderr.decode("utf-8", "replace"))) |
| | | sys.exit(1) |
| | | return p.stdout.decode("utf-8") |
| | | |
| | | |
| | | def strip_mysqldump_noise(text): |
| | | out = [] |
| | | for line in text.splitlines(): |
| | | if line.startswith("/*!") or line.startswith("--"): |
| | | continue |
| | | out.append(line) |
| | | return out |
| | | |
| | | |
| | | def fetch_tables(): |
| | | sql = ("SELECT table_name FROM information_schema.tables " |
| | | "WHERE table_schema='%s' AND table_type='BASE TABLE' ORDER BY table_name" % DB) |
| | | out = run([MYSQL, "-u" + USER, "-p" + PWD, "--default-character-set=utf8mb4", "-N", "-B", "-e", sql]) |
| | | return [l.strip() for l in out.splitlines() if l.strip()] |
| | | |
| | | |
| | | def fetch_view_count(): |
| | | sql = ("SELECT COUNT(*) FROM information_schema.views WHERE table_schema='%s'" % DB) |
| | | out = run([MYSQL, "-u" + USER, "-p" + PWD, "--default-character-set=utf8mb4", "-N", "-B", "-e", sql]) |
| | | return int(out.strip()) |
| | | |
| | | |
| | | def dump_ddl(tables): |
| | | """䏿¬¡å¯¼åºå
¨é¨è¡¨ç»æï¼ååæ {表å: ddlå}ã""" |
| | | out = run([MYSQLDUMP, "-u" + USER, "-p" + PWD] + COMMON + ["--no-data", DB] + tables) |
| | | lines = strip_mysqldump_noise(out) |
| | | blocks = {} |
| | | cur = None |
| | | buf = [] |
| | | for line in lines: |
| | | m = re.match(r"^DROP TABLE IF EXISTS `([^`]+)`;", line) |
| | | if m: |
| | | if cur: |
| | | blocks[cur] = "\n".join(buf).rstrip() |
| | | cur = m.group(1) |
| | | buf = [line] |
| | | elif cur is not None: |
| | | buf.append(line) |
| | | if cur: |
| | | blocks[cur] = "\n".join(buf).rstrip() |
| | | return blocks |
| | | |
| | | |
| | | def dump_data(tables_filters): |
| | | """tables_filters: [(table, where)] ç¸å where çåç»è°ç¨ï¼è¿å {表å: insertè¯å¥}ã""" |
| | | groups = {} |
| | | for t, w in tables_filters: |
| | | if w is None: |
| | | groups.setdefault(None, []).append(t) |
| | | else: |
| | | groups.setdefault(w, []).append(t) |
| | | data = {} |
| | | for where, tables in groups.items(): |
| | | cmd = [MYSQLDUMP, "-u" + USER, "-p" + PWD] + COMMON + \ |
| | | ["--no-create-info", "--complete-insert", "--hex-blob", "--order-by-primary"] |
| | | if where is not None: |
| | | cmd.append("--where=" + where) |
| | | cmd.append(DB) |
| | | cmd += tables |
| | | out = run(cmd) |
| | | lines = strip_mysqldump_noise(out) |
| | | stmt_lines = [] |
| | | for line in lines: |
| | | if not line.strip(): |
| | | continue |
| | | if line.startswith("INSERT INTO "): |
| | | stmt_lines = [line] |
| | | elif stmt_lines: |
| | | stmt_lines.append(line) |
| | | else: |
| | | sys.stderr.write("UNEXPECTED line: %s\n" % line[:120]) |
| | | continue |
| | | stmt = "\n".join(stmt_lines) |
| | | if stmt.rstrip().endswith(";"): |
| | | m = re.match(r"^INSERT INTO `([^`]+)`", stmt) |
| | | data[m.group(1)] = stmt.rstrip() |
| | | stmt_lines = [] |
| | | return data |
| | | |
| | | |
| | | def fetch_counts(tables_filters): |
| | | parts = [] |
| | | for t, w in tables_filters: |
| | | parts.append("SELECT '%s' AS t, COUNT(*) AS c FROM `%s`%s" |
| | | % (t, t, (" WHERE " + w) if w else "")) |
| | | sql = " UNION ALL ".join(parts) |
| | | out = run([MYSQL, "-u" + USER, "-p" + PWD, "--default-character-set=utf8mb4", "-N", "-B", DB, "-e", sql]) |
| | | counts = {} |
| | | for line in out.splitlines(): |
| | | if not line.strip(): |
| | | continue |
| | | k, v = line.split("\t") |
| | | counts[k] = int(v) |
| | | return counts |
| | | |
| | | |
| | | def load_stage2_block(): |
| | | with open(SRC_0918, encoding="utf-8") as f: |
| | | lines = f.read().splitlines() |
| | | for i, line in enumerate(lines): |
| | | if "é¶æ®µäºï¼è¡¥å¯¼èº«ä»½" in line: |
| | | start = i - 1 # 䏿¹ =============== 横线 |
| | | return "\n".join(lines[start:]).rstrip() + "\n" |
| | | raise RuntimeError("0918 æä»¶æªæ¾å°é¶æ®µäºæ®µè½") |
| | | |
| | | |
| | | HEADER = """-- ======================================================================= |
| | | -- æä»¶ï¼config_export_all_20260928.sql |
| | | -- ç¨éï¼ruoyi-vue-proãå
¨åºè¡¨ç»æ + 6 ç±»é
ç½®æ°æ®ã导åºï¼ä¾åç»æå
¨æ°åºåå§å |
| | | -- é¶æ®µä¸ï¼å
¨åº {n_tables} å¼ è¡¨ CREATE TABLE + 6 ç±»é
ç½®æ°æ®ï¼åé¢éï¼èªå
å«ï¼ä¸ä¾èµæºåºå¨çº¿ï¼ |
| | | -- é¶æ®µäºï¼è·¨åºè¡¥å¯¼ èå/è§è²/ç¨æ·/OAuth2 çèº«ä»½æ°æ®ï¼æ§è¡æä»æºåºæ·è´ï¼ |
| | | -- æ¥æºåºï¼ruoyi-vue-pro |
| | | -- åºçº¿ï¼2026-09-18 çï¼419 å¼ è¡¨ï¼â æ¬æ¬¡ä¸º**å
¨ééçæ**ï¼ä¸ååºäºæ§æä»¶æè¡¥ä¸ï¼ï¼ |
| | | -- ç´æ¥æå½åæºåºææ°ç¶æé导ï¼ä¸æ¬¡æ§è¦ç 0918 ä¹åå
¨é¨ç»æä¸é
ç½®æ¼ç§»ã |
| | | -- æ¬æ¬¡åæ´ï¼ç¸å¯¹ 0918ï¼2026-09-28ï¼ï¼ |
| | | -- â è¡¨ç»æï¼419 â {n_tables} å¼ |
| | | -- - å é¤ 6 å¼ åå²å¤ä»½è¡¨ï¼bpm_bak_20260904_bytearray/category/deployment/model/procdef/procinfoï¼æºåºå·²æ ï¼ |
| | | -- + æ°å¢ 3 å¼ è¡¨ï¼after_sale_problemãafter_sale_visitãbpm_process_auto_approve_configï¼ä»
ç»æï¼æºåºæ æ°æ®ï¼ |
| | | -- + 10 å¼ è¡¨ DDL ä¸ 0918 ä¸åï¼ä»¥å½åæºåºä¸ºåï¼after_sale_ticketãmes_qc_indicatorãmes_qc_indicator_result_detailã |
| | | -- mes_qc_ipqcãmes_qc_iqcãmes_qc_oqcãmes_qc_rqcãmes_qc_templateãmes_qc_template_indicatorãmes_wm_return_issue_lineï¼ |
| | | -- â¡ é
ç½®æ°æ®ä»¥å½åæºåºä¸ºåé导ï¼ä¸å为 0918 声æå¼ â æ¬æ¬¡å¯¼åºå¼ï¼ï¼ |
| | | -- - system_dict_type 241â{n_dicttype}ãsystem_dict_data 1157â{n_dictdata}ï¼å« hrm_holiday_type èåæ¥ç±»åçæ°å¢åå
¸ï¼ |
| | | -- - system_company_config 0â1ãbi_chart_config 36â37ãbi_warehouse_coordinate 1â2ãai_api_key 1â3ãbpm_user_group 3â4 |
| | | -- - bpm_business_attach 11â4ãbpm_category 22â15ãbpm_form 4â3ãbpm_process_listener 1â0ï¼æºåºå·²å é¤çè¡ä¸å导åºï¼ |
| | | -- - ååæµç¨å®ä¹ææºåºå½å**æ¿æ´»**éåé导ï¼{n_procdef} 个æµç¨å®ä¹ + 对åºé¨ç½²/åèèµæº + è®¾è®¡ææ¨¡åï¼ |
| | | -- ⢠èå/æéèç¹ï¼è忥é
ç½® 6014/60141-60145ã忍¡å导å
¥æé® 1075311/1075417-1075420 çï¼ç±é¶æ®µäº |
| | | -- è·¨åºå
¨éæ·è´èªå¨æºå¸¦ï¼æ 鿹卿¬æä»¶æ°æ®æ®µï¼å¨æ¤ç»è®°ä»¥è¯´ææ¬çæä»¶ç¡®å®è¦çè¿äºåæ´ã |
| | | -- éªè¯ï¼{verify} |
| | | -- èå´ï¼å
¨åº BASE TABLE å
± {n_tables} å¼ ï¼å
¨é¨è¾åº CREATE TABLEï¼ |
| | | -- ä»
以ä¸é
ç½®ç±»è¡¨å¸¦æ°æ®(INSERT)ï¼å
¶ä½ä¸å¡/ç³»ç»/è¿è¡åå²è¡¨åªä¿çç©ºè¡¨ç»æï¼ |
| | | -- â ååå®¡æ¹æµç¨ï¼å¼æå
æ°æ®+å®ä¹ï¼ä»
æ¿æ´»æµç¨ï¼ååå²/è¿è¡/身份ï¼ï¼act_ge_propertyãact_id_propertyãact_re_procdefãact_re_deploymentãact_ge_bytearrayãact_re_modelãbpm_process_definition_info |
| | | -- â¡ ååï¼ä¸å¡éä»¶é
ç½® + åç±» + 表å + æ©å±é
ç½®ï¼ï¼bpm_business_attachãbpm_categoryãbpm_formãbpm_user_groupãbpm_process_listenerãbpm_process_expression |
| | | -- ⢠BI å³çå¤§å± / go-viewï¼bi_dashboardãbi_chart_configãbi_data_source_configãbi_warehouse_coordinateãreport_go_view_project |
| | | -- ⣠MES ç¼ç è§åï¼åæµæ°´è®°å½ï¼ï¼mes_md_auto_code_ruleãmes_md_auto_code_part |
| | | -- ⤠系ç»é
ç½®ä¸»æ°æ®ï¼åå
¸/ç§æ·/å
¬å¸é
ç½®ï¼å身份/èå/æ¥å¿ï¼ï¼system_dict_typeãsystem_dict_dataãsystem_tenantãsystem_tenant_packageãsystem_company_config |
| | | -- â 身份/æé类表ï¼system_users/role/menu/role_menu/user_role/dept/post/oauth2_clientï¼æ¤å¤ä»
å»ºç©ºè¡¨ç»æï¼æ°æ®ç±æä»¶æ«å°¾"é¶æ®µäº"è·¨åºè¡¥å¯¼ã |
| | | -- ⥠AI é
ç½®ï¼ä»
模å+keyï¼+ åºç¡è®¾æ½é
置管çï¼ai_modelãai_api_keyãinfra_configãinfra_jobãinfra_file_configãinfra_data_source_configãinfra_codegen_tableãinfra_codegen_column |
| | | -- è¿æ»¤ï¼ååæµç¨ä»
ä¿çæ¿æ´»(SUSPENSION_STATE_=1)å®ä¹åå
¶é¨ç½²èµæºï¼bpmn/png åèï¼ï¼ |
| | | -- è®¾è®¡ææ¨¡å act_re_model 䏿¨¡åæºç åèï¼NAME_=source/source-extraï¼ææºåºå
¨é导åºï¼å«ä¸ªå«å·²å 餿µç¨æ®ççæ¨¡åï¼ |
| | | -- æºåºå®é
åå¨å³ä¿çï¼ä¾æµç¨è®¾è®¡å¨æå¼ï¼ï¼è¿è¡æåéåèï¼var-*/hist.var-*ï¼ä¸å¾ä¸å¯¼åºï¼ |
| | | -- å
¶ä½é
置表ä»
导 deleted=0ï¼ç¼ç è§åå餿µæ°´è®°å½ mes_md_auto_code_recordã |
| | | -- â èæ¬å«å
¨åº DROP TABLE IF EXISTSï¼ä¼æé¤æ¬èæ¬å»ºè¡¨å¤çææè¡¨å é¤éå»ºï¼ |
| | | -- ä¸å¡è¡¨æ°æ®å°å
¨é¨æ¸
空ï¼ä»
å¯å¨å
¨æ°/å¯è¦ççç©ºåºæ§è¡ï¼ |
| | | -- ======================================================================= |
| | | """ |
| | | |
| | | VERIFY_PLACEHOLDER = "ï¼å¾
ç©ºåºæ´ä»½æ§è¡éªè¯ååå¡«ï¼è§æä»¶æ«å°¾çæå¤æ³¨ï¼" |
| | | |
| | | |
| | | def main(): |
| | | tables = fetch_tables() |
| | | views = fetch_view_count() |
| | | if views: |
| | | print("WARNING: æºåºåå¨ %d 个è§å¾ï¼æ¬çæå¨æªå¤ç" % views) |
| | | |
| | | ddl = dump_ddl(tables) |
| | | missing = [t for t in tables if t not in ddl] |
| | | extra = [t for t in ddl if t not in tables] |
| | | if missing or extra: |
| | | print("DDL éåä¸ä¸è´ missing=%s extra=%s" % (missing, extra)) |
| | | sys.exit(1) |
| | | print("tables=%d ddl_blocks=%d" % (len(tables), len(ddl))) |
| | | |
| | | all_cfg = [tf for _, tfs in SECTIONS for tf in tfs] |
| | | cfg_names = [t for t, _ in all_cfg] |
| | | counts = fetch_counts(all_cfg) |
| | | data = dump_data(all_cfg) |
| | | for t in cfg_names: |
| | | if counts.get(t, 0) > 0 and t not in data: |
| | | print("MISSING data for %s (count=%d)" % (t, counts[t])) |
| | | sys.exit(1) |
| | | print("config tables=%d, with data=%d" % (len(cfg_names), len(data))) |
| | | |
| | | rest = [t for t in tables if t not in set(cfg_names)] |
| | | print("rest tables=%d" % len(rest)) |
| | | |
| | | parts = [] |
| | | header = HEADER.format( |
| | | n_tables=len(tables), |
| | | n_dicttype=counts["system_dict_type"], |
| | | n_dictdata=counts["system_dict_data"], |
| | | n_procdef=counts["act_re_procdef"], |
| | | verify=VERIFY_PLACEHOLDER, |
| | | ) |
| | | parts.append(header) |
| | | parts.append("SET NAMES utf8mb4;\nSET FOREIGN_KEY_CHECKS = 0;\n" |
| | | "SET @OLD_SQL_MODE = @@SQL_MODE, SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO';\n\n") |
| | | |
| | | for title, tfs in SECTIONS: |
| | | parts.append("\n-- ***********************************************************************\n") |
| | | parts.append("-- %sï¼DDL + æ°æ®ï¼\n" % title) |
| | | parts.append("-- ***********************************************************************\n\n") |
| | | for t, w in tfs: |
| | | n = counts.get(t, 0) |
| | | parts.append("-- ============ 表ï¼%sï¼å¯¼åº %d è¡ï¼ ============\n" % (t, n)) |
| | | parts.append(ddl[t] + "\n") |
| | | if n > 0: |
| | | parts.append(data[t] + "\n") |
| | | parts.append("\n") |
| | | |
| | | parts.append("\n-- ***********************************************************************\n") |
| | | parts.append("-- å
¶ä½ %d å¼ è¡¨ï¼ä»
è¡¨ç»æï¼æ æ°æ®ï¼\n" % len(rest)) |
| | | parts.append("-- ***********************************************************************\n\n") |
| | | for t in rest: |
| | | parts.append("-- ============ 表ï¼%sï¼ä»
DDLï¼æ æ°æ®ï¼ ============\n" % t) |
| | | parts.append(ddl[t] + "\n\n") |
| | | |
| | | parts.append("\nSET FOREIGN_KEY_CHECKS = 1;\nSET SQL_MODE = @OLD_SQL_MODE;\n\n\n") |
| | | parts.append(load_stage2_block()) |
| | | |
| | | text = "".join(parts) |
| | | with open(OUT, "w", encoding="utf-8", newline="\n") as f: |
| | | f.write(text) |
| | | print("WROTE %s bytes=%d lines=%d" % (OUT, len(text.encode("utf-8")), text.count("\n"))) |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | main() |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ===================================================== |
| | | -- HRM èå¤è忥é
ç½® ä¿®å¤èæ¬ |
| | | -- |
| | | -- èæ¯ï¼è¯¥é¡µé¢ï¼èå 6014ãè忥é
ç½®ãï¼åå¨ä¸¤å¤ç¼ºå¤±ï¼å¯¼è´é¡µé¢ä¸å¯ç¨ï¼ |
| | | -- 1. 缺åå
¸ hrm_holiday_typeï¼å端ãç±»åãåéä¸å表ãç±»åãååä¸å°é项/ææ¬ï¼ |
| | | -- ä¸ç±»å为å¿
éï¼æ°å¢/ç¼è¾æ æ³ä¿åï¼hrm_attendance_holiday è¡¨é¿æ 0 è¡ï¼ã |
| | | -- 2. 缺æé®æé hrm:attendance-holiday:queryï¼å端 /pageã/get ä¾èµè¯¥æéç ï¼ |
| | | -- éè¶
管è§è²ï¼èåå·²ææï¼å æ æ¤æéç èå
¨é¨ 403ã |
| | | -- |
| | | -- å
å®¹ï¼ |
| | | -- â åå
¸ç±»å hrm_holiday_typeï¼1-伿¯æ¥ / 2-工使¥ï¼å¯¹åº HrmAttendanceHolidayTypeEnumï¼ |
| | | -- â¡ èåæé® 60141ãè忥é
ç½®æ¥è¯¢ã= hrm:attendance-holiday:query |
| | | -- â¢ å° 60141 æäºå·²æ¥æãè忥é
ç½®æ°å¢ã(60142) çå
¨é¨è§è² |
| | | -- |
| | | -- å¹çï¼å
å åæï¼å¯é夿§è¡ |
| | | -- æ§è¡æ¹å¼ï¼é¿å
䏿乱ç ï¼ï¼ |
| | | -- cmd /c "mysql -uroot -p1234 --default-character-set=utf8mb4 ruoyi-vue-pro < docs\sql\hrm_holiday_config_fix.sql" |
| | | -- ===================================================== |
| | | |
| | | SET NAMES utf8mb4; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- â åå
¸ï¼hrm_holiday_type |
| | | -- ------------------------------------------------------------ |
| | | DELETE FROM `system_dict_data` WHERE `dict_type` = 'hrm_holiday_type'; |
| | | DELETE FROM `system_dict_type` WHERE `type` = 'hrm_holiday_type'; |
| | | |
| | | INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES (1065500, 'HRM èåæ¥ç±»å', 'hrm_holiday_type', 0, '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES |
| | | (1065501, 1, '伿¯æ¥', '1', 'hrm_holiday_type', 0, 'success', '', '1', NOW(), '1', NOW(), b'0'), |
| | | (1065502, 2, '工使¥', '2', 'hrm_holiday_type', 0, 'primary', '', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- â¡ èåæé®ï¼è忥é
ç½®æ¥è¯¢ |
| | | -- ------------------------------------------------------------ |
| | | DELETE FROM `system_role_menu` WHERE `menu_id` = 60141; |
| | | DELETE FROM `system_menu` WHERE `id` = 60141; |
| | | |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES (60141, 'è忥é
ç½®æ¥è¯¢', 'hrm:attendance-holiday:query', 3, 1, 6014, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- ⢠ææï¼è·éãè忥é
ç½®æ°å¢ã(60142) çè§è² |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, 60141, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | WHERE rm.`menu_id` = 60142 AND rm.`deleted` = b'0'; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- æ ¡éª |
| | | -- ------------------------------------------------------------ |
| | | SELECT ' dict_type ' AS item, COUNT(*) AS cnt FROM `system_dict_type` WHERE `type` = 'hrm_holiday_type' |
| | | UNION ALL SELECT ' dict_data ', COUNT(*) FROM `system_dict_data` WHERE `dict_type` = 'hrm_holiday_type' |
| | | UNION ALL SELECT ' menu_60141', COUNT(*) FROM `system_menu` WHERE `id` = 60141 |
| | | UNION ALL SELECT ' roles ', COUNT(*) FROM `system_role_menu` WHERE `menu_id` = 60141 AND `deleted` = b'0'; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ===================================================== |
| | | -- MES è´¨æ£å导å
¥ èå䏿鮿é |
| | | -- æ°å¢æé®æéï¼ |
| | | -- mes:qc-iqc:import æ¥ææ£éªåè¡¨ãæ¹é导å
¥ãæé®ï¼parent_id = 5640ï¼ |
| | | -- mes:qc-ipqc:import è¿ç¨æ£éªåè¡¨ãæ¹é导å
¥ãæé®ï¼parent_id = 5650ï¼ |
| | | -- mes:qc-oqc:import åºè´§æ£éªåè¡¨ãæ¹é导å
¥ãæé®ï¼parent_id = 5660ï¼ |
| | | -- |
| | | -- æ§è¡æ¹å¼ï¼é¿å
䏿èååä¹±ç ï¼ï¼ |
| | | -- cmd /c "mysql -uroot -p1234 --default-character-set=utf8mb4 ruoyi-vue-pro < docs\sql\mes_qc_import_menu.sql" |
| | | -- ===================================================== |
| | | |
| | | SET NAMES utf8mb4; |
| | | |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES (1075418, 'æ¥ææ£éªå¯¼å
¥', 'mes:qc-iqc:import', 3, 6, 5640, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES (1075419, 'è¿ç¨æ£éªå¯¼å
¥', 'mes:qc-ipqc:import', 3, 6, 5650, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES (1075420, 'åºè´§æ£éªå¯¼å
¥', 'mes:qc-oqc:import', 3, 6, 5660, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- ä¸è´¨æ£æ£éªåå
¶å®æé®ï¼æ¥è¯¢/å建/æ´æ°/å é¤/导åºï¼æäºç¸åçè§è² |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES |
| | | (2, 1075418, '1', NOW(), '1', NOW(), b'0'), |
| | | (155, 1075418, '1', NOW(), '1', NOW(), b'0'), |
| | | (160, 1075418, '1', NOW(), '1', NOW(), b'0'), |
| | | (162, 1075418, '1', NOW(), '1', NOW(), b'0'), |
| | | (2, 1075419, '1', NOW(), '1', NOW(), b'0'), |
| | | (155, 1075419, '1', NOW(), '1', NOW(), b'0'), |
| | | (160, 1075419, '1', NOW(), '1', NOW(), b'0'), |
| | | (162, 1075419, '1', NOW(), '1', NOW(), b'0'), |
| | | (2, 1075420, '1', NOW(), '1', NOW(), b'0'), |
| | | (155, 1075420, '1', NOW(), '1', NOW(), b'0'), |
| | | (160, 1075420, '1', NOW(), '1', NOW(), b'0'), |
| | | (162, 1075420, '1', NOW(), '1', NOW(), b'0'); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ===================================================== |
| | | -- è´¨é管ç - æ£æµç»æå°è´¦ èå䏿é |
| | | -- |
| | | -- èæ¯ï¼è´¨æ£å模åï¼IQC/IPQC/OQC/RQCï¼çæ£æµç»æåå
忣å¨åèªå表å
ï¼ |
| | | -- 缺å°è·¨ç±»åçç»ä¸æ¥è¯¢ä¸å°å¸å¯¼åºãæ¬æ¬¡æ°å¢ãæ£æµç»æå°è´¦ã页é¢ï¼ |
| | | -- æåç±»ï¼æ£éªç±»åï¼+ æ£æµæ¥æåºé´ + ç©æ/æ¹æ¬¡/æ£æµç»æ/æ£æµäººçéï¼ |
| | | -- åè¡¨ç´æ¥å±ç¤ºæ£æµé¡¹å®æµç»æï¼å¹¶æ¯æå¯¼åº Excel å°è´¦ç¨äºæ¥è¯¢ãæå°ãåæ¡£ã |
| | | -- |
| | | -- å
å®¹ï¼ |
| | | -- â èå 1075421ãæ£æµç»æå°è´¦ã type=2ï¼component=mes/qc/ledger/index |
| | | -- â¡ æé® 1075422ãæ£æµç»æå°è´¦æ¥è¯¢ã= mes:qc-inspection-ledger:query |
| | | -- ⢠æé® 1075423ãæ£æµç»æå°è´¦å¯¼åºã= mes:qc-inspection-ledger:export |
| | | -- ⣠å°ä»¥ä¸ 3 个èåæäºå·²æ¥æãæ¥ææ£éªæ¥è¯¢ã(5641) çå
¨é¨è§è² |
| | | -- |
| | | -- å¹çï¼å
å åæï¼å¯é夿§è¡ |
| | | -- æ§è¡æ¹å¼ï¼é¿å
䏿乱ç ï¼ï¼ |
| | | -- cmd /c "mysql -uroot -p1234 --default-character-set=utf8mb4 ruoyi-vue-pro < docs\sql\qc_inspection_ledger_menu.sql" |
| | | -- ===================================================== |
| | | |
| | | SET NAMES utf8mb4; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- â èåï¼æ£æµç»æå°è´¦ |
| | | -- ------------------------------------------------------------ |
| | | DELETE FROM `system_role_menu` WHERE `menu_id` IN (1075421, 1075422, 1075423); |
| | | DELETE FROM `system_menu` WHERE `id` IN (1075421, 1075422, 1075423); |
| | | |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES (1075421, 'æ£æµç»æå°è´¦', '', 2, 14, 5500, 'inspection-ledger', 'ep:document', 'mes/qc/ledger/index', 'MesQcInspectionLedger', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- â¡ æé®ï¼æ¥è¯¢ / å¯¼åº |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES (1075422, 'æ£æµç»æå°è´¦æ¥è¯¢', 'mes:qc-inspection-ledger:query', 3, 1, 1075421, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1075423, 'æ£æµç»æå°è´¦å¯¼åº', 'mes:qc-inspection-ledger:export', 3, 2, 1075421, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- ⢠ææï¼è·éãæ¥ææ£éªæ¥è¯¢ã(5641) çè§è² |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, m.`id`, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | JOIN (SELECT 1075421 AS `id` UNION ALL SELECT 1075422 UNION ALL SELECT 1075423) m |
| | | WHERE rm.`menu_id` = 5641 AND rm.`deleted` = b'0'; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- æ ¡éª |
| | | -- ------------------------------------------------------------ |
| | | SELECT ' menu_1075421' AS item, COUNT(*) AS cnt FROM `system_menu` WHERE `id` = 1075421 |
| | | UNION ALL SELECT ' menu_1075422', COUNT(*) FROM `system_menu` WHERE `id` = 1075422 |
| | | UNION ALL SELECT ' menu_1075423', COUNT(*) FROM `system_menu` WHERE `id` = 1075423 |
| | | UNION ALL SELECT ' roles ', COUNT(*) FROM `system_role_menu` WHERE `menu_id` IN (1075421, 1075422, 1075423) AND `deleted` = b'0'; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- ===================================================== |
| | | -- èªå»ºè§è²ãçä¸å°æ°æ®ãä¿®å¤ï¼æéèç¹è¡¥é½ + è§è²èªå¨ç»§æ¿ |
| | | -- æ¥æï¼2026-09-24 |
| | | -- |
| | | -- èæ¯ï¼ |
| | | -- æ¡æ¶æéæ ¡éªï¼PermissionServiceImpl#hasAnyPermissionï¼ä¸ºä¸¥æ ¼æ¨¡å¼ï¼ |
| | | -- æ§å¶å¨ @PreAuthorize ä¸çæéæ è¯è¥å¨ system_menu ä¸ä¸åå¨ï¼é¤è¶
管å¤ä¸å¾å¤å®æ æéã |
| | | -- ææ¥åç°å
¨é¡¹ç®æ 141 个æ§å¶å¨æéæ è¯å¨ system_menu ä¸ç¼ºå¤±/å½åä¸å¹é
ï¼ |
| | | -- 导è´èªå»ºè§è²ï¼ä»¥åé¤è¶
管å¤çææè§è²ï¼æå¼é¡µé¢åæ¥å£ 403ãå表为空ââå³"çä¸å°æ°æ®"ã |
| | | -- ç³»ç»èªå¸¦ãè¶
级管çåãè§è²å 代ç ç´è¿å
¨é¨æéèæ£å¸¸ï¼ä¸¤è
对æ¯å³ç¨æ·åé¦çç°è±¡ã |
| | | -- |
| | | -- æ¬èæ¬å
å®¹ï¼ |
| | | -- â è¡¥é½ HRM/MES/ERP/CRM/SRM/BI/BPM 缺失çæé®æéèç¹ï¼type=3ï¼ |
| | | -- â¡ æ°å¢ HRMãèªèµç»æã页é¢èåï¼type=2ï¼æ¤ååç«¯é¡µé¢æ èåå
¥å£ï¼ |
| | | -- ⢠æ°èç¹èªå¨ææç»å·²ææå¯¹åºé¡µé¢èåçå
¨é¨è§è²ï¼åæ¥/ç»§æ¿æºå¶ï¼ |
| | | -- ⣠修æ£å®åãæ¥çå
¨é¨ãæ°æ®æéèç¹ï¼permission ç± aftersales:admin æ¹ä¸º aftersales:view-allï¼ |
| | | -- ä¸ AfterSalePermissionUtils#hasViewAllPermission çæ ¡éªæ è¯ä¸è´ï¼ |
| | | -- ⤠CRMãæ¥çå
¨é¨å®¢æ·ã(602583) ç»§æ¿ææï¼å·²ææ crm:customer:query çè§è²èªå¨è·å¾ |
| | | -- |
| | | -- é
å¥ä»£ç åæ´ï¼yudao-module-hrm 9 个æ§å¶å¨ @PreAuthorize æéæ è¯å·²å¯¹é½èåå½å |
| | | -- ï¼hrm:attendance:* â hrm:attendance-record/exception/rule/summary:*ï¼ |
| | | -- hrm:salary:* â hrm:salary-calculation/payment:*ï¼ |
| | | -- hrm:social-security:* â hrm:employee-social-security/social-security-scheme:*ï¼ |
| | | -- hrm:tax-rate:* â hrm:tax-rate-config:*ï¼ï¼ééæ°ç¼è¯å¹¶éå¯å端åçæã |
| | | -- |
| | | -- å¹çï¼å
å åæï¼å¯é夿§è¡ |
| | | -- æ§è¡æ¹å¼ï¼é¿å
䏿乱ç ï¼ï¼ |
| | | -- cmd /c "mysql -uroot -p1234 --default-character-set=utf8mb4 ruoyi-vue-pro < docs\sql\role_permission_sync_20260924.sql" |
| | | -- |
| | | -- æ§è¡åçææ¡ä»¶ï¼ |
| | | -- 1. éå¯åç«¯ï¼æ§å¶å¨åæ´ + èåç¼åï¼ |
| | | -- 2. æéç¼åå·æ°ï¼ä»»æè§è²å¨ãè§è²ç®¡ç â èåæéãéä¿å䏿¬¡ï¼è§¦åæéç¼åæ¸
空ï¼ï¼ |
| | | -- æéå¯ Redisï¼å¦åæ¤å 403 请æ±éçç"空æé"ç¼åä¼ç»§ç»æ¦æªï¼æ°æéæ è¯ä¸åå½±åï¼ |
| | | -- 3. ç®æ ç¨æ·éæ°ç»å½ï¼å·æ°ç»å½æä¸çæéåè¡¨ï¼ |
| | | -- ===================================================== |
| | | |
| | | SET NAMES utf8mb4; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- â æ¸
çæ§æ°æ®ï¼å¹çï¼ |
| | | -- ------------------------------------------------------------ |
| | | DELETE FROM `system_role_menu` WHERE `menu_id` BETWEEN 1080001 AND 1080078; |
| | | DELETE FROM `system_menu` WHERE `id` BETWEEN 1080001 AND 1080078; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- â¡ æ°å¢æé®æéèç¹ï¼type=3ï¼ |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | VALUES |
| | | -- HRM èå¤è®°å½ï¼6011ï¼ |
| | | (1080001, 'èå¤è®°å½æ¥è¯¢', 'hrm:attendance-record:query', 3, 10, 6011, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM èå¤å¼å¸¸ï¼6012ï¼ |
| | | (1080002, 'èå¤å¼å¸¸æ¥è¯¢', 'hrm:attendance-exception:query', 3, 10, 6012, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080003, 'èå¤å¼å¸¸ä¿®æ¹', 'hrm:attendance-exception:update', 3, 20, 6012, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080004, 'èå¤å¼å¸¸å é¤', 'hrm:attendance-exception:delete', 3, 30, 6012, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM èå¤è§åï¼6013ï¼ |
| | | (1080005, 'èå¤è§åæ¥è¯¢', 'hrm:attendance-rule:query', 3, 10, 6013, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM èå¤ç»è®¡ï¼6015ï¼ |
| | | (1080006, 'èå¤ç»è®¡æ¥è¯¢', 'hrm:attendance-summary:query', 3, 10, 6015, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM å çç³è¯·ï¼1065211ï¼ |
| | | (1080007, 'å çç³è¯·æ¥è¯¢', 'hrm:overtime:query', 3, 10, 1065211, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080008, 'å ç管ç', 'hrm:overtime:manage', 3, 20, 1065211, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM è°å²ç³è¯·ï¼6004ï¼ |
| | | (1080009, 'è°å²ç³è¯·æ¥è¯¢', 'hrm:transfer:query', 3, 10, 6004, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080010, 'è°å²ç³è¯·å¯¼åº', 'hrm:transfer:export', 3, 20, 6004, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM 离èç³è¯·ï¼6005ï¼ |
| | | (1080011, '离èç³è¯·æ¥è¯¢', 'hrm:resignation:query', 3, 10, 6005, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080012, '离èç³è¯·å¯¼åº', 'hrm:resignation:export', 3, 20, 6005, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080013, '离è交æ¥', 'hrm:resignation:handover', 3, 30, 6005, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM 请åç³è¯·ï¼6003ï¼ |
| | | (1080014, '请åç³è¯·å¯¼åº', 'hrm:leave:export', 3, 10, 6003, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM èªé
¬æ ¸ç®ï¼6021ï¼ |
| | | (1080015, 'èªé
¬æ ¸ç®æ¥è¯¢', 'hrm:salary-calculation:query', 3, 10, 6021, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080016, 'èªé
¬æ ¸ç®å é¤', 'hrm:salary-calculation:delete', 3, 20, 6021, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080017, 'èªé
¬æ ¸ç®ä¿å', 'hrm:salary-calculation:save', 3, 30, 6021, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM èªèµåæ¾ï¼6022ï¼ |
| | | (1080018, 'èªèµåæ¾æ¥è¯¢', 'hrm:salary-payment:query', 3, 10, 6022, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080019, 'èªèµåæ¾çæ', 'hrm:salary-payment:generate', 3, 20, 6022, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080020, 'èªèµåæ¾å é¤', 'hrm:salary-payment:delete', 3, 30, 6022, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM å工社ä¿å
¬ç§¯éæ¡£æ¡ï¼6023ï¼ |
| | | (1080021, 'åå·¥ç¤¾ä¿æ¥è¯¢', 'hrm:employee-social-security:query', 3, 10, 6023, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM 社ä¿å
¬ç§¯éæ¹æ¡ï¼602445ï¼ |
| | | (1080022, 'ç¤¾ä¿æ¹æ¡æ¥è¯¢', 'hrm:social-security-scheme:query', 3, 10, 602445, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM 个ç¨ç¨çé
ç½®ï¼6024ï¼ |
| | | (1080023, '个ç¨ç¨çæ¥è¯¢', 'hrm:tax-rate-config:query', 3, 10, 6024, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM åå·¥ååï¼1063105ï¼ |
| | | (1080024, 'åå·¥åå导å
¥', 'hrm:employee-contract:import', 3, 10, 1063105, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES 计éåä½ï¼602467ï¼ |
| | | (1080025, '计éå使¥è¯¢', 'mes:md-unit-measure:query', 3, 10, 602467, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080026, '计éå使°å¢', 'mes:md-unit-measure:create', 3, 20, 602467, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080027, '计éåä½ä¿®æ¹', 'mes:md-unit-measure:update', 3, 30, 602467, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080028, '计éåä½å é¤', 'mes:md-unit-measure:delete', 3, 40, 602467, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080029, '计éåä½å¯¼åº', 'mes:md-unit-measure:export', 3, 50, 602467, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080030, '计éåä½å¯¼å
¥', 'mdm:unit:import', 3, 60, 602467, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080031, '计éå使°æ®å¯¼åº', 'mdm:unit:export', 3, 70, 602467, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES ç©æåç±»ï¼5110ï¼ |
| | | (1080032, 'ç©æåç±»æ¥è¯¢', 'mdm:item-category:query', 3, 10, 5110, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080033, 'ç©æåç±»æ°å¢', 'mdm:item-category:create', 3, 20, 5110, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080034, 'ç©æå类修æ¹', 'mdm:item-category:update', 3, 30, 5110, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080035, 'ç©æåç±»å é¤', 'mdm:item-category:delete', 3, 40, 5110, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES 车é´è®¾ç½®ï¼5160ï¼ |
| | | (1080036, '车é´å¯¼åº', 'mes:md-workshop:export', 3, 10, 5160, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES åºç¡åæ°ï¼602474ï¼ |
| | | (1080037, 'åºç¡åæ°æ¥è¯¢', 'mes:pd-process-param:query', 3, 10, 602474, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080038, 'åºç¡åæ°æ°å¢', 'mes:pd-process-param:create', 3, 20, 602474, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080039, 'åºç¡åæ°ä¿®æ¹', 'mes:pd-process-param:update', 3, 30, 602474, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080040, 'åºç¡åæ°å é¤', 'mes:pd-process-param:delete', 3, 40, 602474, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080041, 'åºç¡åæ°å¯¼åº', 'mes:pd-process-param:export', 3, 50, 602474, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES åæ°æ¨¡æ¿ï¼602475ï¼ |
| | | (1080042, 'åæ°æ¨¡æ¿æ¥è¯¢', 'mes:pd-process-param-template:query', 3, 10, 602475, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080043, 'åæ°æ¨¡æ¿æ°å¢', 'mes:pd-process-param-template:create', 3, 20, 602475, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080044, 'åæ°æ¨¡æ¿ä¿®æ¹', 'mes:pd-process-param-template:update', 3, 30, 602475, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080045, 'åæ°æ¨¡æ¿å é¤', 'mes:pd-process-param-template:delete', 3, 40, 602475, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080046, 'åæ°æ¨¡æ¿å¯¼åº', 'mes:pd-process-param-template:export', 3, 50, 602475, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES ç产计åï¼602504ï¼ |
| | | (1080047, 'çäº§è®¡åæ¥è¯¢', 'mes:pro-mps:query', 3, 10, 602504, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES 计éå¨å
·ï¼5380ï¼ |
| | | (1080048, '计éå¨å
·å¯¼å
¥', 'mes:dv-metering:import', 3, 10, 5380, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES åºåç°æéï¼5786ï¼ |
| | | (1080049, 'åºåç°æé导å
¥', 'mes:wm-material-stock:import', 3, 10, 5786, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES å¤ååæï¼5881ï¼ |
| | | (1080050, 'å¤ååæå®æ', 'mes:wm-outsource-issue:finish', 3, 10, 5881, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES éè´éè´§ï¼5830ï¼ |
| | | (1080051, 'éè´éè´§å®æ', 'mes:wm-return-vendor:finish', 3, 10, 5830, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES çç¹ä»»å¡ï¼5957ï¼ |
| | | (1080052, 'çç¹ä»»å¡å®æ', 'mes:wm-stock-taking-task:finish', 3, 10, 5957, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES 产åå
¥åºï¼5819ï¼ |
| | | (1080053, '产åå
¥åºæ¥è¯¢', 'mes:wm-product-produce:query', 3, 10, 5819, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES åç±»æ£éªå宿 |
| | | (1080054, 'æ¥ææ£éªå®æ', 'mes:qc-iqc:finish', 3, 10, 5640, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080055, 'è¿ç¨æ£éªå®æ', 'mes:qc-ipqc:finish', 3, 10, 5650, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080056, 'åºè´§æ£éªå®æ', 'mes:qc-oqc:finish', 3, 10, 5660, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080057, 'éè´§æ£éªå®æ', 'mes:qc-rqc:finish', 3, 10, 5670, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- MES è´¨æ£ç®¡çï¼5500ï¼ï¼AI è¾
å©å¤å®ï¼ææèå´=åç±»æ£éªé¡µè§è²ï¼è§ â£ï¼ |
| | | (1080058, 'è´¨æ£ä¿®æ¹', 'mes:qc:update', 3, 50, 5500, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- ERP éè´ç³è¯·ï¼602498ï¼ |
| | | (1080059, 'éè´ç³è¯·æ¥è¯¢', 'erp:purchase-request:query', 3, 10, 602498, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080060, 'éè´ç³è¯·æäº¤', 'erp:purchase-request:submit', 3, 20, 602498, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080061, 'éè´ç³è¯·çæè®¢å', 'erp:purchase-request:generate-order', 3, 30, 602498, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- ERP éè´è®¢åï¼2666ï¼ |
| | | (1080062, 'éè´è®¢å导å
¥', 'erp:purchase-order:import', 3, 10, 2666, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- ERP éå®è®¢åï¼2638ï¼ |
| | | (1080063, 'éå®è®¢ååæ¶', 'erp:sale-order:cancel', 3, 10, 2638, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080064, 'éå®è®¢åå¯ç¨', 'erp:sale-order:enable', 3, 20, 2638, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080065, 'éå®è®¢å导å
¥', 'erp:sale-order:import', 3, 30, 2638, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- CRM å¼ç¥¨ç®¡çï¼1063093ï¼ |
| | | (1080066, 'å¼ç¥¨æ¥è¯¢', 'crm:invoice:query', 3, 10, 1063093, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- CRM é宿¥ä»·ï¼602512ï¼ |
| | | (1080067, 'æ¥ä»·åæ¥è¯¢', 'crm:sale-quotation:query', 3, 10, 602512, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080068, 'æ¥ä»·å导åº', 'crm:sale-quotation:export', 3, 20, 602512, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080069, 'æ¥ä»·å转åå', 'crm:sale-quotation:convert-contract', 3, 30, 602512, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- SRM æææ 管çï¼602545ï¼ |
| | | (1080070, 'ææ é
ç½®æ¥è¯¢', 'srm:tender-config:query', 3, 10, 602545, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080071, 'ææ é
置修æ¹', 'srm:tender-config:update', 3, 20, 602545, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- BI å³ç大å±ï¼1063000ï¼ç®å½ï¼ææèå´=å主é¢å¤§å±é¡µè§è²ï¼è§ â¤ï¼ |
| | | (1080072, '大屿¥è¯¢', 'bi:dashboard:query', 3, 10, 1063000, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- BPM OA éç¥å
¬åï¼602608ï¼ |
| | | (1080073, 'OAéç¥å
¬åæ¥è¯¢', 'bpm:oa-notice:query', 3, 10, 602608, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM èªèµç»æé¡µé¢èåï¼type=2ï¼åç«¯é¡µé¢æ¤åæ èåå
¥å£ï¼ |
| | | (1080074, 'èªèµç»æ', '', 2, 70, 6020, 'structure', 'ep:document', 'hrm/salary/structure/index', 'HrmSalaryStructure', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | -- HRM èªèµç»ææé®ï¼ç¶çº§ 1080074ï¼ |
| | | (1080075, 'èªèµç»ææ¥è¯¢', 'hrm:salary-structure:query', 3, 10, 1080074, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080076, 'èªèµç»ææ°å¢', 'hrm:salary-structure:create', 3, 20, 1080074, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080077, 'èªèµç»æä¿®æ¹', 'hrm:salary-structure:update', 3, 30, 1080074, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'), |
| | | (1080078, 'èªèµç»æå é¤', 'hrm:salary-structure:delete', 3, 40, 1080074, '', '', '', '', 0, b'1', b'1', b'1', '1', NOW(), '1', NOW(), b'0'); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- ⢠èªå¨ææï¼æ°èç¹ â å·²ææå¯¹åºç¶é¡µé¢èåçå
¨é¨è§è²ï¼åæ¥/ç»§æ¿æºå¶ï¼ |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, m.`id`, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | JOIN ( |
| | | SELECT 1080001 AS `id`, 6011 AS `parent` UNION ALL SELECT 1080002, 6012 UNION ALL SELECT 1080003, 6012 |
| | | UNION ALL SELECT 1080004, 6012 UNION ALL SELECT 1080005, 6013 UNION ALL SELECT 1080006, 6015 |
| | | UNION ALL SELECT 1080007, 1065211 UNION ALL SELECT 1080008, 1065211 |
| | | UNION ALL SELECT 1080009, 6004 UNION ALL SELECT 1080010, 6004 |
| | | UNION ALL SELECT 1080011, 6005 UNION ALL SELECT 1080012, 6005 UNION ALL SELECT 1080013, 6005 |
| | | UNION ALL SELECT 1080014, 6003 |
| | | UNION ALL SELECT 1080015, 6021 UNION ALL SELECT 1080016, 6021 UNION ALL SELECT 1080017, 6021 |
| | | UNION ALL SELECT 1080018, 6022 UNION ALL SELECT 1080019, 6022 UNION ALL SELECT 1080020, 6022 |
| | | UNION ALL SELECT 1080021, 6023 UNION ALL SELECT 1080022, 602445 UNION ALL SELECT 1080023, 6024 |
| | | UNION ALL SELECT 1080024, 1063105 |
| | | UNION ALL SELECT 1080025, 602467 UNION ALL SELECT 1080026, 602467 UNION ALL SELECT 1080027, 602467 |
| | | UNION ALL SELECT 1080028, 602467 UNION ALL SELECT 1080029, 602467 UNION ALL SELECT 1080030, 602467 |
| | | UNION ALL SELECT 1080031, 602467 |
| | | UNION ALL SELECT 1080032, 5110 UNION ALL SELECT 1080033, 5110 UNION ALL SELECT 1080034, 5110 |
| | | UNION ALL SELECT 1080035, 5110 |
| | | UNION ALL SELECT 1080036, 5160 |
| | | UNION ALL SELECT 1080037, 602474 UNION ALL SELECT 1080038, 602474 UNION ALL SELECT 1080039, 602474 |
| | | UNION ALL SELECT 1080040, 602474 UNION ALL SELECT 1080041, 602474 |
| | | UNION ALL SELECT 1080042, 602475 UNION ALL SELECT 1080043, 602475 UNION ALL SELECT 1080044, 602475 |
| | | UNION ALL SELECT 1080045, 602475 UNION ALL SELECT 1080046, 602475 |
| | | UNION ALL SELECT 1080047, 602504 UNION ALL SELECT 1080048, 5380 UNION ALL SELECT 1080049, 5786 |
| | | UNION ALL SELECT 1080050, 5881 UNION ALL SELECT 1080051, 5830 UNION ALL SELECT 1080052, 5957 |
| | | UNION ALL SELECT 1080053, 5819 |
| | | UNION ALL SELECT 1080054, 5640 UNION ALL SELECT 1080055, 5650 UNION ALL SELECT 1080056, 5660 |
| | | UNION ALL SELECT 1080057, 5670 |
| | | UNION ALL SELECT 1080059, 602498 UNION ALL SELECT 1080060, 602498 UNION ALL SELECT 1080061, 602498 |
| | | UNION ALL SELECT 1080062, 2666 |
| | | UNION ALL SELECT 1080063, 2638 UNION ALL SELECT 1080064, 2638 UNION ALL SELECT 1080065, 2638 |
| | | UNION ALL SELECT 1080066, 1063093 |
| | | UNION ALL SELECT 1080067, 602512 UNION ALL SELECT 1080068, 602512 UNION ALL SELECT 1080069, 602512 |
| | | UNION ALL SELECT 1080070, 602545 UNION ALL SELECT 1080071, 602545 |
| | | UNION ALL SELECT 1080073, 602608 |
| | | ) m ON rm.`menu_id` = m.`parent` |
| | | WHERE rm.`deleted` = b'0' |
| | | AND NOT EXISTS (SELECT 1 FROM `system_role_menu` x WHERE x.`role_id` = rm.`role_id` AND x.`menu_id` = m.`id` AND x.`deleted` = b'0'); |
| | | |
| | | -- èªèµç»æé¡µé¢èåï¼1080074ï¼ï¼ææç»å·²ææèªé
¬ç®¡çä¸ä»»ä¸é¡µé¢çè§è² |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, 1080074, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | WHERE rm.`menu_id` IN (6021, 6022, 6023, 6024, 602445, 602449) AND rm.`deleted` = b'0' |
| | | AND NOT EXISTS (SELECT 1 FROM `system_role_menu` x WHERE x.`role_id` = rm.`role_id` AND x.`menu_id` = 1080074 AND x.`deleted` = b'0'); |
| | | |
| | | -- èªèµç»ææé®ï¼1080075-1080078ï¼ï¼ææç»ææèªèµç»æé¡µé¢çè§è² |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, m.`id`, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | JOIN (SELECT 1080075 AS `id` UNION ALL SELECT 1080076 UNION ALL SELECT 1080077 UNION ALL SELECT 1080078) m |
| | | WHERE rm.`menu_id` = 1080074 AND rm.`deleted` = b'0' |
| | | AND NOT EXISTS (SELECT 1 FROM `system_role_menu` x WHERE x.`role_id` = rm.`role_id` AND x.`menu_id` = m.`id` AND x.`deleted` = b'0'); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- ⣠质æ£ä¿®æ¹ï¼mes:qc:updateï¼1080058ï¼ï¼ææç»ææåç±»æ£éªé¡µé¢çè§è² |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, 1080058, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | WHERE rm.`menu_id` IN (5640, 5650, 5660, 5670) AND rm.`deleted` = b'0' |
| | | AND NOT EXISTS (SELECT 1 FROM `system_role_menu` x WHERE x.`role_id` = rm.`role_id` AND x.`menu_id` = 1080058 AND x.`deleted` = b'0'); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- â¤ å¤§å±æ¥è¯¢ï¼bi:dashboard:queryï¼1080072ï¼ï¼ææç»ææä»»ä¸ä¸»é¢å¤§å±é¡µé¢çè§è² |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, 1080072, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | WHERE rm.`menu_id` IN (1063001, 1063002, 1063003, 1063004, 1063005) AND rm.`deleted` = b'0' |
| | | AND NOT EXISTS (SELECT 1 FROM `system_role_menu` x WHERE x.`role_id` = rm.`role_id` AND x.`menu_id` = 1080072 AND x.`deleted` = b'0'); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- ⥠CRMãæ¥çå
¨é¨å®¢æ·ãæ°æ®æéç»§æ¿ï¼å·²ææ crm:customer:query çè§è²èªå¨è·å¾ 602583 |
| | | -- ------------------------------------------------------------ |
| | | INSERT INTO `system_role_menu` (`role_id`, `menu_id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) |
| | | SELECT DISTINCT rm.`role_id`, 602583, '1', NOW(), '1', NOW(), b'0' |
| | | FROM `system_role_menu` rm |
| | | JOIN `system_menu` m ON m.`id` = rm.`menu_id` AND m.`deleted` = b'0' |
| | | WHERE m.`permission` = 'crm:customer:query' AND rm.`deleted` = b'0' |
| | | AND NOT EXISTS (SELECT 1 FROM `system_role_menu` x WHERE x.`role_id` = rm.`role_id` AND x.`menu_id` = 602583 AND x.`deleted` = b'0'); |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- ⦠å®åãæ¥çå
¨é¨ãæ°æ®æéèç¹ä¿®æ£ï¼permission ä¸åç«¯æ ¡éªæ è¯å¯¹é½ |
| | | -- ------------------------------------------------------------ |
| | | UPDATE `system_menu` |
| | | SET `permission` = 'aftersales:view-all', `updater` = '1', `update_time` = NOW() |
| | | WHERE `id` = 602595 AND `deleted` = b'0' AND `permission` <> 'aftersales:view-all'; |
| | | |
| | | -- ------------------------------------------------------------ |
| | | -- â§ æ ¡éª |
| | | -- ------------------------------------------------------------ |
| | | SELECT 'menu_nodes ' AS item, COUNT(*) AS cnt FROM `system_menu` WHERE `id` BETWEEN 1080001 AND 1080078 AND `deleted` = b'0'; |
| | | SELECT 'role_menu ' AS item, COUNT(*) AS cnt FROM `system_role_menu` WHERE `menu_id` BETWEEN 1080001 AND 1080078 AND `deleted` = b'0'; |
| | | SELECT 'view_all_602595' AS item, `permission` AS cnt FROM `system_menu` WHERE `id` = 602595; |
| | | SELECT 'crm_viewall ' AS item, COUNT(DISTINCT `role_id`) AS cnt FROM `system_role_menu` WHERE `menu_id` = 602583 AND `deleted` = b'0'; |
| | |
| | | |
| | | import cn.idev.excel.ExcelWriter; |
| | | import cn.idev.excel.FastExcelFactory; |
| | | import cn.idev.excel.annotation.ExcelProperty; |
| | | import cn.idev.excel.context.AnalysisContext; |
| | | import cn.idev.excel.converters.longconverter.LongStringConverter; |
| | | import cn.idev.excel.enums.CellExtraTypeEnum; |
| | | import cn.idev.excel.event.AnalysisEventListener; |
| | | import cn.idev.excel.metadata.CellExtra; |
| | | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; |
| | | import cn.iocoder.yudao.framework.excel.core.handler.ColumnWidthMatchStyleStrategy; |
| | | import cn.iocoder.yudao.framework.excel.core.handler.SelectSheetWriteHandler; |
| | |
| | | |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.lang.reflect.Field; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * Excel å·¥å
·ç±» |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 读å Excelï¼å¹¶æã纵ååå¹¶åå
æ ¼ãçå¼å¡«å
å°åå¹¶åºåå
çæ¯ä¸è¡ï¼å³æåå¹¶åå
æ ¼æå¹³ææ®éè¡¨æ ¼ã |
| | | * |
| | | * ä¾å¦ A2:A5 åå¹¶ãå¼ä¸º 100 æ¶ï¼è¯»åç»æä¸ç¬¬ 2~5 è¡ç该åå为 100ã |
| | | * å 为 Excel åªå¨åå¹¶åºåå·¦ä¸è§ä¿åå¼ï¼ç´æ¥è¯»åæ¶å
¶ä½è¡ä¸ºç©ºï¼ä¼å¯¼è´ãåä¸å¼ åçå¤è¡æç»ãæ æ³è¯å«ã |
| | | * 注æï¼åªå¤çååç纵ååå¹¶ï¼è¡¨å¤´è¡çåå¹¶ãè·¨åçæ¨ªååå¹¶ä¸å¤çã |
| | | * |
| | | * @param file æä»¶ |
| | | * @param head Excel head 头 |
| | | * @return æ°æ®å表 |
| | | */ |
| | | public static <T> List<T> readFlat(MultipartFile file, Class<T> head) throws IOException { |
| | | MergedCellFillReadListener<T> listener = new MergedCellFillReadListener<>(head); |
| | | // åè https://t.zsxq.com/zM77F å¸åï¼å¢å try å¤çï¼å
¼å®¹ windows åºæ¯ |
| | | try (InputStream inputStream = file.getInputStream()) { |
| | | FastExcelFactory.read(inputStream, head, listener) |
| | | .extraRead(CellExtraTypeEnum.MERGE) // é¢å¤è¯»ååå¹¶åå
æ ¼ä¿¡æ¯ |
| | | .autoCloseStream(false) // ä¸è¦èªå¨å
³éï¼äº¤ç» Servlet èªå·±å¤ç |
| | | .doReadAllSync(); |
| | | } |
| | | listener.fillMergedCell(); |
| | | return listener.getDataList(); |
| | | } |
| | | |
| | | /** |
| | | * åå¹¶åå
æ ¼å¡«å
ç读åçå¬å¨ï¼è¯»åè¿ç¨ä¸æ¶éè¡¨å¤´ãæ°æ®è¡ä¸åå¹¶åºåï¼è¯»å宿åæåå¹¶åå
æ ¼çå¼å¡«å
å°åå¹¶åºåå
çæ¯ä¸è¡ |
| | | */ |
| | | private static class MergedCellFillReadListener<T> extends AnalysisEventListener<T> { |
| | | |
| | | /** |
| | | * 表头ï¼key 为 sheet ç¼å·ï¼value 为ãåå· -> è¡¨å¤´ææ¬ã |
| | | */ |
| | | private final Map<Integer, Map<Integer, String>> sheetHeaderMap = new HashMap<>(); |
| | | /** |
| | | * æ°æ®è¡ï¼key 为ãsheet ç¼å· - è¡å·ãï¼value ä¸ºæ°æ®è¡ |
| | | */ |
| | | private final Map<String, T> rowDataMap = new HashMap<>(); |
| | | /** |
| | | * åå¹¶åºåï¼key 为 sheet ç¼å· |
| | | */ |
| | | private final Map<Integer, List<CellExtra>> sheetMergedCellMap = new HashMap<>(); |
| | | /** |
| | | * ãè¡¨å¤´ææ¬ -> åæ®µãï¼ç¨äºæåå¹¶åå
æ ¼çå¼å¡«å
ååæ®µ |
| | | */ |
| | | private final Map<String, Field> headerFieldMap = new HashMap<>(); |
| | | /** |
| | | * éå¤åºç°çè¡¨å¤´ææ¬ï¼æ æ³ç¡®å®å¡«å
å°åªä¸ªå段ï¼å¿½ç¥ |
| | | */ |
| | | private final Set<String> ambiguousHeaderSet = new HashSet<>(); |
| | | /** |
| | | * æ°æ®å表ï¼å³è¯»åç»æ |
| | | */ |
| | | private final List<T> dataList = new ArrayList<>(); |
| | | |
| | | private MergedCellFillReadListener(Class<T> head) { |
| | | for (Field field : head.getDeclaredFields()) { |
| | | ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); |
| | | if (excelProperty == null || excelProperty.value().length == 0 |
| | | || excelProperty.value()[0].trim().isEmpty()) { |
| | | continue; |
| | | } |
| | | String header = excelProperty.value()[0].trim(); |
| | | if (headerFieldMap.containsKey(header)) { |
| | | ambiguousHeaderSet.add(header); |
| | | continue; |
| | | } |
| | | field.setAccessible(true); |
| | | headerFieldMap.put(header, field); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) { |
| | | sheetHeaderMap.put(context.readSheetHolder().getSheetNo(), headMap); |
| | | } |
| | | |
| | | @Override |
| | | public void invoke(T data, AnalysisContext context) { |
| | | dataList.add(data); |
| | | rowDataMap.put(buildRowKey(context.readSheetHolder().getSheetNo(), |
| | | context.readRowHolder().getRowIndex()), data); |
| | | } |
| | | |
| | | @Override |
| | | public void extra(CellExtra extra, AnalysisContext context) { |
| | | if (extra.getType() == CellExtraTypeEnum.MERGE) { |
| | | sheetMergedCellMap.computeIfAbsent(context.readSheetHolder().getSheetNo(), k -> new ArrayList<>()) |
| | | .add(extra); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void doAfterAllAnalysed(AnalysisContext context) { |
| | | } |
| | | |
| | | /** |
| | | * æåå¹¶åå
æ ¼çå¼ï¼å¡«å
å°åå¹¶åºåå
çæ¯ä¸è¡ |
| | | */ |
| | | public void fillMergedCell() { |
| | | sheetMergedCellMap.forEach((sheetNo, mergedCellList) -> { |
| | | Map<Integer, String> headerMap = sheetHeaderMap.get(sheetNo); |
| | | if (headerMap == null) { |
| | | return; |
| | | } |
| | | mergedCellList.forEach(extra -> fillMergedCell(sheetNo, headerMap, extra)); |
| | | }); |
| | | } |
| | | |
| | | private void fillMergedCell(Integer sheetNo, Map<Integer, String> headerMap, CellExtra extra) { |
| | | // åªå¤çååç纵ååå¹¶ï¼è·¨åçæ¨ªååå¹¶ï¼å¦è¡¨å¤´åå¹¶ï¼ä¸å¤ç |
| | | if (extra.getFirstColumnIndex() == null || !extra.getFirstColumnIndex().equals(extra.getLastColumnIndex())) { |
| | | return; |
| | | } |
| | | // 表头è¡çåå¹¶ä¸å¤ç |
| | | if (extra.getFirstRowIndex() == null || extra.getFirstRowIndex() < 1) { |
| | | return; |
| | | } |
| | | String header = headerMap.get(extra.getFirstColumnIndex()); |
| | | Field field = header == null ? null : headerFieldMap.get(header); |
| | | if (field == null || ambiguousHeaderSet.contains(header)) { |
| | | return; |
| | | } |
| | | T sourceData = rowDataMap.get(buildRowKey(sheetNo, extra.getFirstRowIndex())); |
| | | if (sourceData == null) { |
| | | return; |
| | | } |
| | | try { |
| | | Object value = field.get(sourceData); |
| | | if (value == null) { |
| | | return; |
| | | } |
| | | for (int rowIndex = extra.getFirstRowIndex() + 1; rowIndex <= extra.getLastRowIndex(); rowIndex++) { |
| | | T targetData = rowDataMap.get(buildRowKey(sheetNo, rowIndex)); |
| | | if (targetData != null) { |
| | | field.set(targetData, value); |
| | | } |
| | | } |
| | | } catch (IllegalAccessException e) { |
| | | // åæ®µå·² setAccessibleï¼ç论ä¸ä¸ä¼åçï¼å³ä½¿åçä¹å¿½ç¥è¯¥åå¹¶åå
æ ¼ï¼ä¸å½±åå
¶å®æ°æ® |
| | | } |
| | | } |
| | | |
| | | private String buildRowKey(Integer sheetNo, Integer rowIndex) { |
| | | return sheetNo + "-" + rowIndex; |
| | | } |
| | | |
| | | public List<T> getDataList() { |
| | | return dataList; |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum; |
| | | 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.crm.service.business.CrmBusinessService; |
| | | import cn.iocoder.yudao.module.crm.service.contact.CrmContactService; |
| | | import cn.iocoder.yudao.module.crm.service.contract.CrmContractService; |
| | |
| | | |
| | | @Resource |
| | | private MdmItemApi mdmItemApi; |
| | | @Resource |
| | | private MdmUnitMeasureApi mdmUnitMeasureApi; |
| | | |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | |
| | | contractVO.setProducts(BeanUtils.toBean(businessProducts, CrmContractRespVO.Product.class, businessProductVO -> |
| | | MapUtils.findAndThen(itemMap, businessProductVO.getItemId(), |
| | | item -> businessProductVO.setItemCode(item.getCode()) |
| | | .setItemName(item.getName()).setItemBarCode(item.getBarCode())))); |
| | | .setItemName(item.getName()).setBarCode(item.getBarCode()) |
| | | .setItemSpecification(item.getSpecification())))); |
| | | // æ¼æ¥è®¡éåä½åç§° |
| | | Map<Long, MdmUnitMeasureRespDTO> unitMap = mdmUnitMeasureApi.getUnitMeasureMap( |
| | | convertSet(businessProducts, CrmContractProductDO::getItemUnitId)); |
| | | contractVO.getProducts().forEach(product -> MapUtils.findAndThen(unitMap, product.getItemUnitId(), |
| | | unit -> product.setItemUnitName(unit.getName()))); |
| | | return contractVO; |
| | | } |
| | | |
| | |
| | | .orderDate("2026-01-01 10:00:00").startTime("2026-01-01").endTime("2026-12-31") |
| | | .discountPercent(new BigDecimal("0")).depositPrice(new BigDecimal("0")) |
| | | .productCode("ITEM001").productName("示ä¾äº§åA") |
| | | .count(100).contractPrice(new BigDecimal("20.00")).remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢") |
| | | .count(new BigDecimal("100")).contractPrice(new BigDecimal("20.00")).remark("ç¤ºä¾æ°æ®ï¼å¯¼å
¥åè¯·æ¿æ¢") |
| | | .build()); |
| | | ExcelUtils.write(response, "åå导å
¥æ¨¡æ¿.xls", "åå", CrmContractImportExcelVO.class, list); |
| | | } |
| | |
| | | @Operation(summary = "导å
¥åå") |
| | | @PreAuthorize("@ss.hasPermission('crm:contract:import')") |
| | | public CommonResult<CrmContractImportRespVO> importContractExcel(@RequestParam("file") MultipartFile file) throws Exception { |
| | | List<CrmContractImportExcelVO> list = ExcelUtils.read(file, CrmContractImportExcelVO.class); |
| | | // readFlatï¼æçºµååå¹¶åå
æ ¼ï¼åä¸å¼ ååçå¤è¡æç»ï¼æå¹³ï¼å¦åé¤é¦è¡å¤çä¸»è¡¨åæ®µä¼è¯»ä¸å° |
| | | List<CrmContractImportExcelVO> list = ExcelUtils.readFlat(file, CrmContractImportExcelVO.class); |
| | | return success(contractService.importContractList(list)); |
| | | } |
| | | |
| | |
| | | * 管çåå° - åå导å
¥ Excel VO |
| | | * |
| | | * 说æï¼ä¸è¡ = 䏿¡äº§åæç»ï¼ç¸åâååç¼å·âçå¤è¡ä¼å并为ä¸å¼ ååï¼ä¸»è¡¨å段å该ç»é¦è¡ï¼ã |
| | | * ä¸»è¡¨åæ®µï¼ååç¼å·ãåååç§°ã客æ·åç§°ãæ¶é´ã夿³¨çï¼å¯ä»¥çºµååå¹¶åå
æ ¼å¡«åï¼è¯»åæ¶ä¼èªå¨å¡«å
å°åå¹¶åºåå
çæ¯ä¸è¡ã |
| | | * âååç¼å·âç空æ¶ï¼æ¯ä¸è¡ä¼åèªçæä¸å¼ æ°ååï¼åæ¡æç»ï¼ã |
| | | * è´è´£äººãååç¶æãéé¢ ç±ç³»ç»å¤çï¼è´è´£äºº = å½åç»å½ç¨æ·ï¼ç¶æ = æªæäº¤ï¼é颿æç»ä¸ä¼æ çèªå¨è®¡ç®ã |
| | | * |
| | |
| | | private String productName; |
| | | |
| | | @ExcelProperty("æ°é") |
| | | @Schema(description = "äº§åæ°é", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private Integer count; |
| | | @Schema(description = "äº§åæ°éï¼æ¯æå°æ°ï¼å¦ 53176.5ï¼", requiredMode = Schema.RequiredMode.REQUIRED) |
| | | private BigDecimal count; |
| | | |
| | | @ExcelProperty("åååä»·(å
)") |
| | | @Schema(description = "产ååååä»·ï¼ç空ååè¯¥ç©æçéå®ä»·") |
| | |
| | | @Schema(description = "ç©æåç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "ç©æA") |
| | | private String itemName; |
| | | @Schema(description = "ç©ææ¡ç ", example = "BAR001") |
| | | private String itemBarCode; |
| | | private String barCode; |
| | | @Schema(description = "è§æ ¼åå·", example = "M8*20") |
| | | private String itemSpecification; |
| | | @Schema(description = "计éåä½ç¼å·", example = "1") |
| | | private Long itemUnitId; |
| | | @Schema(description = "计éåä½åç§°", example = "个") |
| | |
| | | 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; |
| | | |
| | | } |
| | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotEmpty; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import jakarta.validation.constraints.Size; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Data; |
| | | import lombok.NoArgsConstructor; |
| | |
| | | @Schema(description = "æ¥ä»·åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430") |
| | | private Long id; |
| | | |
| | | @Schema(description = "æ¥ä»·åå·ï¼å¯ä¸å¡«ï¼æ°å¢æ¶ç空èªå¨çæï¼ä¿®æ¹æ¶çç©ºä¿æåå¼", example = "BJ20260901000001") |
| | | @Size(max = 32, message = "æ¥ä»·åå·é¿åº¦ä¸è½è¶
è¿ 32 个å符") |
| | | private String no; |
| | | |
| | | @Schema(description = "æ¥ä»·ååç§°", requiredMode = Schema.RequiredMode.REQUIRED, example = "æ¥ä»·åA") |
| | | @NotNull(message = "æ¥ä»·ååç§°ä¸è½ä¸ºç©º") |
| | | private String name; |
| | |
| | | @NotNull(message = "ååç¼å·ä¸è½ä¸ºç©º") |
| | | private Long contractId; |
| | | |
| | | @Schema(description = "å
³èçå¼ç¥¨ç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "25787") |
| | | @Schema(description = "å
³èçå¼ç¥¨ç¼å·ï¼å¯ä¸å¡«ï¼æªå¼ç¥¨å
忬¾ï¼", example = "25787") |
| | | @DiffLogField(name = "å
³èå¼ç¥¨", function = CrmInvoiceParseFunction.NAME) |
| | | @NotNull(message = "å
³èå¼ç¥¨ç¼å·ä¸è½ä¸ºç©º") |
| | | private Long invoiceId; |
| | | |
| | | @Schema(description = "忬¾è®¡åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| | | @DiffLogField(name = "åå", function = CrmReceivablePlanParseFunction.NAME) |
| | | @Schema(description = "忬¾è®¡åç¼å·ï¼å¯ä¸å¡«", example = "1024") |
| | | @DiffLogField(name = "忬¾è®¡å", function = CrmReceivablePlanParseFunction.NAME) |
| | | private Long planId; |
| | | |
| | | @Schema(description = "忬¾æ¹å¼", example = "2") |
| | |
| | | return selectCount(CrmInvoiceDO::getContractId, contractId); |
| | | } |
| | | |
| | | /** |
| | | * æ¥è¯¢ååä¸çå
¨é¨å¼ç¥¨ï¼å¯¼å
¥å»éç¨ï¼ |
| | | */ |
| | | default List<CrmInvoiceDO> selectListByContractId(Long contractId) { |
| | | return selectList(new LambdaQueryWrapperX<CrmInvoiceDO>() |
| | | .eq(CrmInvoiceDO::getContractId, contractId) |
| | | .orderByAsc(CrmInvoiceDO::getId)); |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.crm.enums.quotation.CrmSaleQuotationStatusEnum; |
| | | import cn.iocoder.yudao.module.crm.util.CrmPermissionUtils; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Select; |
| | | |
| | | import java.util.List; |
| | | |
| | |
| | | return selectOne(CrmSaleQuotationDO::getNo, no); |
| | | } |
| | | |
| | | /** |
| | | * ææ¥ä»·åå·æ¥è¯¢è®°å½ï¼ä¸è¿æ»¤é»è¾å é¤ï¼å«å·²å é¤è¡ï¼ |
| | | * ç¨äºèªå®ä¹åå·çå¯ä¸æ§é¢æ ¡éªï¼uk_no å¯ä¸ç´¢å¼è¦çå·²å é¤è¡ï¼éä¸èµ·å¤ææè½ç»åºå¯è¯»æç¤º |
| | | */ |
| | | @Select("SELECT * FROM crm_sale_quotation WHERE no = #{no} LIMIT 1") |
| | | CrmSaleQuotationDO selectAnyByNo(String no); |
| | | |
| | | default PageResult<CrmSaleQuotationDO> selectPage(CrmSaleQuotationPageReqVO pageReqVO, Long userId) { |
| | | return selectPage(pageReqVO, userId, null); |
| | | } |
| | |
| | | |
| | | // ========== é宿¥ä»· 1_020_015_000 ========== |
| | | ErrorCode SALE_QUOTATION_NOT_EXISTS = new ErrorCode(1_020_015_000, "é宿¥ä»·åä¸åå¨"); |
| | | ErrorCode SALE_QUOTATION_NO_EXISTS = new ErrorCode(1_020_015_001, "é宿¥ä»·åå·å·²åå¨"); |
| | | ErrorCode SALE_QUOTATION_NO_EXISTS = new ErrorCode(1_020_015_001, "æ¥ä»·åå·ã{}ã已被å ç¨ï¼ä¸è½éå¤ä½¿ç¨ã请æ¢ä¸ä¸ªç¼å·ï¼ææ¸
空ç¼å·ç±ç³»ç»èªå¨çæï¼å·²å é¤çæ¥ä»·åä¹ä¼å ç¨å
¶åç¼å·ï¼"); |
| | | ErrorCode SALE_QUOTATION_UPDATE_FAIL_NOT_DRAFT = new ErrorCode(1_020_015_002, "é宿¥ä»·å({})䏿¯èç¨¿ç¶æï¼æ æ³ä¿®æ¹"); |
| | | ErrorCode SALE_QUOTATION_DELETE_FAIL_NOT_DRAFT = new ErrorCode(1_020_015_003, "é宿¥ä»·å({})䏿¯èç¨¿ç¶æï¼æ æ³å é¤"); |
| | | ErrorCode SALE_QUOTATION_CONVERT_FAIL_NOT_DRAFT = new ErrorCode(1_020_015_004, "é宿¥ä»·å({})䏿¯èç¨¿ç¶æï¼æ æ³è½¬åå"); |
| | |
| | | CrmContractDO getContract(Long id); |
| | | |
| | | /** |
| | | * è·å¾ååï¼åºäºååç¼å· |
| | | * |
| | | * @param no ååç¼å· |
| | | * @return åå |
| | | */ |
| | | CrmContractDO getContractByNo(String no); |
| | | |
| | | /** |
| | | * æ ¡éªå忝å¦åæ³ |
| | | * |
| | | * @param id ç¼å· |
| | |
| | | CrmContractImportExcelVO head = rows.get(0); |
| | | // 1. 主表å¿
å¡« |
| | | if (StrUtil.isBlank(head.getName())) { |
| | | throw new IllegalArgumentException("åååç§°ä¸è½ä¸ºç©º"); |
| | | throw new IllegalArgumentException("åååç§°ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çãåååç§°ãåï¼" |
| | | + "è¥åä¸å¼ ååçå¤è¡ä½¿ç¨äºåå¹¶åå
æ ¼ï¼éå¡«åå¨åå¹¶åºåçé¦è¡"); |
| | | } |
| | | if (StrUtil.isBlank(head.getCustomerName())) { |
| | | throw new IllegalArgumentException("客æ·åç§°ä¸è½ä¸ºç©º"); |
| | | throw new IllegalArgumentException("客æ·åç§°ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çã客æ·åç§°ãåï¼" |
| | | + "è¥åä¸å¼ ååçå¤è¡ä½¿ç¨äºåå¹¶åå
æ ¼ï¼éå¡«åå¨åå¹¶åºåçé¦è¡"); |
| | | } |
| | | Long customerId = customerIdMap.get(head.getCustomerName().trim()); |
| | | if (customerId == null) { |
| | | throw new IllegalArgumentException("客æ·ä¸åå¨ï¼" + head.getCustomerName()); |
| | | throw new IllegalArgumentException("客æ·ä¸åå¨ï¼" + head.getCustomerName() |
| | | + "ã请å
å¨ãCRM 客æ·ç®¡çãä¸å建该客æ·ï¼åç§°é䏿¨¡æ¿å®å
¨ä¸è´ï¼ï¼æä¿®æ¹æ¨¡æ¿ä¸ç客æ·åç§°å鿰坼å
¥"); |
| | | } |
| | | customerService.validateCustomer(customerId); |
| | | |
| | | // 2. æç» |
| | | List<CrmContractSaveReqVO.Product> products = new ArrayList<>(); |
| | | List<CrmContractProductDO> productDOs = new ArrayList<>(); |
| | | for (CrmContractImportExcelVO row : rows) { |
| | | if (StrUtil.isBlank(row.getProductCode())) { |
| | | throw new IllegalArgumentException("产åç¼ç ä¸è½ä¸ºç©º"); |
| | | throw new IllegalArgumentException("产åç¼ç ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çã产åç¼ç ãå"); |
| | | } |
| | | CommonResult<MdmItemRespDTO> itemResult = mdmItemApi.getItemByCode(row.getProductCode().trim()); |
| | | MdmItemRespDTO item = itemResult == null ? null : itemResult.getData(); |
| | | if (item == null) { |
| | | throw new IllegalArgumentException("产åä¸åå¨ï¼" + row.getProductCode()); |
| | | throw new IllegalArgumentException("产åä¸åå¨ï¼" + row.getProductCode() |
| | | + "ã请å
å¨ãç©æç®¡çãä¸ç»´æ¤è¯¥ç©æï¼ç¼ç é䏿¨¡æ¿å®å
¨ä¸è´ï¼ï¼æä¿®æ¹æ¨¡æ¿ä¸ç产åç¼ç å鿰坼å
¥"); |
| | | } |
| | | if (row.getCount() == null || row.getCount() <= 0) { |
| | | throw new IllegalArgumentException("产å[" + row.getProductCode() + "]çæ°éå¿
é¡»ä¸ºæ£æ´æ°"); |
| | | if (row.getCount() == null) { |
| | | throw new IllegalArgumentException("产å[" + row.getProductCode() |
| | | + "]çæ°éä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çãæ°éãå"); |
| | | } |
| | | if (row.getCount().compareTo(BigDecimal.ZERO) <= 0) { |
| | | throw new IllegalArgumentException("产å[" + row.getProductCode() + "]çæ°éå¿
é¡»å¤§äº 0ï¼å½å为 " |
| | | + row.getCount().stripTrailingZeros().toPlainString() + "ãè¯·ä¿®æ¹æ¨¡æ¿å鿰坼å
¥"); |
| | | } |
| | | BigDecimal contractPrice = row.getContractPrice() != null ? row.getContractPrice() |
| | | : (item.getSalesPrice() != null ? item.getSalesPrice() : BigDecimal.ZERO); |
| | | CrmContractSaveReqVO.Product product = new CrmContractSaveReqVO.Product(); |
| | | CrmContractProductDO product = new CrmContractProductDO(); |
| | | product.setItemId(item.getId()); |
| | | product.setItemUnitId(item.getUnitMeasureId()); |
| | | product.setItemPrice(item.getSalesPrice() != null ? item.getSalesPrice() : contractPrice); |
| | | product.setContractPrice(contractPrice); |
| | | product.setCount(row.getCount()); |
| | | products.add(product); |
| | | product.setTotalPrice(MoneyUtils.priceMultiply(contractPrice, row.getCount())); |
| | | productDOs.add(product); |
| | | } |
| | | |
| | | // 3. ååç¼å· |
| | | String no = StrUtil.isNotBlank(head.getNo()) ? head.getNo().trim() |
| | | : noRedisDAO.generate(CrmNoRedisDAO.CONTRACT_NO_PREFIX); |
| | | if (contractMapper.selectByNo(no) != null) { |
| | | throw new IllegalArgumentException("ååç¼å·å·²åå¨ï¼" + no); |
| | | throw new IllegalArgumentException("ååç¼å·å·²åå¨ï¼" + no |
| | | + "ãè¯·ä¿®æ¹æ¨¡æ¿ä¸çååç¼å·ï¼æå
å¨ç³»ç»ä¸å é¤è¯¥ç¼å·çååå鿰坼å
¥"); |
| | | } |
| | | |
| | | // 4. ç»è£
主表ï¼è´è´£äºº=ç»å½ç¨æ·ï¼ç¶æ=æªæäº¤ï¼ |
| | |
| | | contract.setAuditStatus(CrmAuditStatusEnum.DRAFT.getStatus()); |
| | | |
| | | // 5. æç»è½åº + èªå¨ç®ä»· |
| | | List<CrmContractProductDO> productDOs = validateContractProducts(products); |
| | | calculateTotalPrice(contract, productDOs); |
| | | contractMapper.insert(contract); |
| | | productDOs.forEach(product -> product.setContractId(contract.getId())); |
| | |
| | | if (quotation != null) { |
| | | crmSaleQuotationService.clearContractReference(quotation.getId()); |
| | | } |
| | | // 2.2 å 餿°æ®æé |
| | | // 2.3 å é¤åå产åæç» |
| | | contractProductMapper.delete(CrmContractProductDO::getContractId, id); |
| | | // 2.4 å 餿°æ®æé |
| | | crmPermissionService.deletePermission(CrmBizTypeEnum.CRM_CONTRACT.getType(), id); |
| | | |
| | | // 3. è®°å½æä½æ¥å¿ä¸ä¸æ |
| | |
| | | } |
| | | |
| | | @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()); // æ ¡éªè´è´£äººåå¨ |
| | |
| | | package cn.iocoder.yudao.module.crm.service.quotation; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.number.MoneyUtils; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | |
| | | public Long createSaleQuotation(CrmSaleQuotationSaveReqVO createReqVO, Long userId) { |
| | | // 1.1 æ ¡éªç©æé¡¹çæææ§ |
| | | List<CrmSaleQuotationProductDO> quotationProducts = validateQuotationItems(createReqVO.getItems()); |
| | | // 1.2 çææ¥ä»·åå·ï¼å¹¶æ ¡éªå¯ä¸æ§ |
| | | String no = noRedisDAO.generate(CrmNoRedisDAO.SALE_QUOTATION_NO_PREFIX); |
| | | if (saleQuotationMapper.selectByNo(no) != null) { |
| | | throw exception(SALE_QUOTATION_NO_EXISTS); |
| | | } |
| | | // 1.2 ç¡®å®æ¥ä»·åå·ï¼å端填ååç¨èªå®ä¹åå·ï¼ç空åèªå¨çæï¼ï¼å¹¶æ ¡éªå¯ä¸æ§ |
| | | String customNo = StrUtil.trim(createReqVO.getNo()); |
| | | String no = StrUtil.isBlank(customNo) |
| | | ? noRedisDAO.generate(CrmNoRedisDAO.SALE_QUOTATION_NO_PREFIX) : customNo; |
| | | validateQuotationNoUnique(no, null); |
| | | // 1.3 æ ¡éªå
³èåæ®µ |
| | | validateRelationDataExists(createReqVO); |
| | | |
| | |
| | | // 1.4 æ ¡éªå
³èåæ®µ |
| | | validateRelationDataExists(updateReqVO); |
| | | |
| | | // 2.1 æ´æ°æ¥ä»·å |
| | | // 2.1 æ´æ°æ¥ä»·åï¼æ¥ä»·åå·çç©ºè¡¨ç¤ºä¿æåå¼ï¼å¡«ååæ ¡éªå¯ä¸æ§åæ¿æ¢ï¼ |
| | | CrmSaleQuotationDO updateObj = BeanUtils.toBean(updateReqVO, CrmSaleQuotationDO.class); |
| | | String no = StrUtil.trim(updateReqVO.getNo()); |
| | | if (StrUtil.isBlank(no)) { |
| | | updateObj.setNo(saleQuotation.getNo()); |
| | | } else { |
| | | validateQuotationNoUnique(no, saleQuotation.getId()); |
| | | updateObj.setNo(no); |
| | | } |
| | | calculateTotalPrice(updateObj, quotationProducts); |
| | | saleQuotationMapper.updateById(updateObj); |
| | | // 2.2 æ´æ°æ¥ä»·æç» |
| | |
| | | return saleQuotation; |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªæ¥ä»·åå·å¯ä¸ï¼å«å·²é»è¾å é¤çæ¥ä»·åï¼å uk_no å¯ä¸ç´¢å¼è¦çå·²å é¤è¡ï¼ |
| | | * |
| | | * @param no æ¥ä»·åå· |
| | | * @param selfId èªèº«ç¼å·ï¼ä¿®æ¹æ¶æé¤èªå·±ï¼æ°å¢ä¼ nullï¼ |
| | | */ |
| | | private void validateQuotationNoUnique(String no, Long selfId) { |
| | | CrmSaleQuotationDO exists = saleQuotationMapper.selectAnyByNo(no); |
| | | if (exists != null && !exists.getId().equals(selfId)) { |
| | | throw exception(SALE_QUOTATION_NO_EXISTS, no); |
| | | } |
| | | } |
| | | |
| | | private List<CrmSaleQuotationProductDO> validateQuotationItems(List<CrmSaleQuotationSaveReqVO.Item> list) { |
| | | // 1. æ ¡éªç©æåå¨ä¸å¯ç¨ |
| | | Set<Long> itemIds = convertSet(list, CrmSaleQuotationSaveReqVO.Item::getItemId); |
| | |
| | | * æ ¡éªå
³èå¼ç¥¨åæ ¼ï¼åå¨ã审æ¹éè¿ãå·²ä¸ä¼ å票éä»¶ã䏿éååä¸è´ |
| | | */ |
| | | private void validateInvoiceForReceivable(CrmReceivableSaveReqVO reqVO) { |
| | | // æªå
³èå¼ç¥¨æ¶ç´æ¥è·³è¿ï¼å
许å
忬¾åå¼ç¥¨ï¼ |
| | | if (reqVO.getInvoiceId() == null) { |
| | | return; |
| | | } |
| | | // 1. æ ¡éªå¼ç¥¨åå¨ |
| | | CrmInvoiceDO invoice = invoiceService.getInvoice(reqVO.getInvoiceId()); |
| | | if (invoice == null) { |
| | |
| | | * æ ¡éªç´¯è®¡å款éé¢ä¸è¶
è¿è¯¥å¼ç¥¨å©ä½å¯å款éé¢ï¼å
å¼ç¥¨å忬¾ï¼ |
| | | */ |
| | | private void validateReceivablePriceExceedsInvoiceRemaining(CrmReceivableSaveReqVO reqVO) { |
| | | // æªå
³èå¼ç¥¨æ¶ç´æ¥è·³è¿ï¼éé¢ä¸éä»ç±ååçº§æ ¡éª validateReceivablePriceExceedsLimit å
åºï¼ |
| | | if (reqVO.getInvoiceId() == null) { |
| | | return; |
| | | } |
| | | // 1. 计ç®è¯¥å¼ç¥¨ç´¯è®¡å款éé¢ï¼ä¸å«æ¬æ¬¡ï¼ç»è®¡å£å¾åååé颿 ¡éªï¼è稿 + 审æ¹ä¸ + 审æ¹éè¿ï¼ |
| | | CrmInvoiceDO invoice = invoiceService.getInvoice(reqVO.getInvoiceId()); |
| | | List<CrmReceivableDO> receivables = receivableMapper.selectListByInvoiceIdAndStatus(reqVO.getInvoiceId(), |
| | |
| | | ErrorCode ATTENDANCE_RULE_NOT_EXISTS = new ErrorCode(1_030_004_005, "èå¤è§åä¸åå¨"); |
| | | ErrorCode ATTENDANCE_RULE_NAME_EXISTS = new ErrorCode(1_030_004_006, "èå¤è§ååç§°å·²åå¨"); |
| | | ErrorCode ATTENDANCE_RULE_DEPT_EXISTS = new ErrorCode(1_030_004_007, "该é¨é¨å·²é
ç½®èå¤è§å"); |
| | | ErrorCode ATTENDANCE_HOLIDAY_NOT_EXISTS = new ErrorCode(1_030_004_008, "è忥é
ç½®ä¸åå¨"); |
| | | ErrorCode ATTENDANCE_HOLIDAY_DATE_EXISTS = new ErrorCode(1_030_004_009, "è¯¥æ¥æè忥é
置已åå¨"); |
| | | ErrorCode ATTENDANCE_HOLIDAY_NOT_EXISTS = new ErrorCode(1_030_004_008, "è忥é
ç½®ä¸åå¨ï¼ID={}ï¼ï¼å¯è½å·²è¢«ä»äººå é¤ãè¯·å·æ°å表åéè¯"); |
| | | ErrorCode ATTENDANCE_HOLIDAY_DATE_EXISTS = new ErrorCode(1_030_004_009, "æ¥æã{}ãå·²åå¨è忥é
ç½®ï¼ä¸è½é夿°å¢ã请æ¹ä¸ºç¼è¾è¯¥æ¥æçè®°å½ï¼å¯ç´æ¥ä¿®æ¹ç±»åä¸å¤æ³¨ï¼ï¼æå
å é¤åè®°å½åæ°å¢"); |
| | | ErrorCode ATTENDANCE_CLOCK_FAIL_NO_RULE = new ErrorCode(1_030_004_010, "æå¡å¤±è´¥ï¼æªæ¾å°èå¤è§å"); |
| | | ErrorCode ATTENDANCE_CLOCK_FAIL_HOLIDAY = new ErrorCode(1_030_004_011, "æå¡å¤±è´¥ï¼å½æ¥ä¸ºä¼æ¯æ¥"); |
| | | ErrorCode ATTENDANCE_CLOCK_FAIL_NOT_WORKDAY = new ErrorCode(1_030_004_012, "æå¡å¤±è´¥ï¼å½æ¥ä¸æ¯å·¥ä½æ¥"); |
| | |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "æ°å¢èå¤å¼å¸¸ç³è¯·") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:create')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-exception:create')") |
| | | public CommonResult<Long> createAttendanceException(@Valid @RequestBody HrmAttendanceExceptionSaveReqVO createReqVO) { |
| | | return success(attendanceExceptionService.createAttendanceException(createReqVO)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°èå¤å¼å¸¸ç³è¯·") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:update')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-exception:update')") |
| | | public CommonResult<Boolean> updateAttendanceException(@Valid @RequestBody HrmAttendanceExceptionSaveReqVO updateReqVO) { |
| | | attendanceExceptionService.updateAttendanceException(updateReqVO); |
| | | return success(true); |
| | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤èå¤å¼å¸¸ç³è¯·") |
| | | @Parameter(name = "id", description = "ç³è¯·ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:delete')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-exception:delete')") |
| | | public CommonResult<Boolean> deleteAttendanceException(@RequestParam("id") Long id) { |
| | | attendanceExceptionService.deleteAttendanceException(id); |
| | | return success(true); |
| | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾èå¤å¼å¸¸ç³è¯·") |
| | | @Parameter(name = "id", description = "ç³è¯·ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-exception:query')") |
| | | public CommonResult<HrmAttendanceExceptionRespVO> getAttendanceException(@RequestParam("id") Long id) { |
| | | HrmAttendanceExceptionDO attendanceException = attendanceExceptionService.getAttendanceException(id); |
| | | if (attendanceException == null) { |
| | |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾èå¤å¼å¸¸ç³è¯·å页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-exception:query')") |
| | | public CommonResult<PageResult<HrmAttendanceExceptionRespVO>> getAttendanceExceptionPage(@Valid HrmAttendanceExceptionPageReqVO pageReqVO) { |
| | | PageResult<HrmAttendanceExceptionDO> pageResult = attendanceExceptionService.getAttendanceExceptionPage(pageReqVO); |
| | | List<HrmAttendanceExceptionRespVO> list = BeanUtils.toBean(pageResult.getList(), HrmAttendanceExceptionRespVO.class); |
| | |
| | | |
| | | @PostMapping("/submit") |
| | | @Operation(summary = "æäº¤èå¤å¼å¸¸ç³è¯·") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:submit')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-exception:submit')") |
| | | public CommonResult<Boolean> submitAttendanceException( |
| | | @RequestParam("id") Long id, |
| | | @RequestParam("processDefinitionKey") String processDefinitionKey) { |
| | |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "æ°å¢è忥é
ç½®") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:create')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-holiday:create')") |
| | | public CommonResult<Long> createAttendanceHoliday(@Valid @RequestBody HrmAttendanceHolidaySaveReqVO createReqVO) { |
| | | return success(attendanceHolidayService.createAttendanceHoliday(createReqVO)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°è忥é
ç½®") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:update')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-holiday:update')") |
| | | public CommonResult<Boolean> updateAttendanceHoliday(@Valid @RequestBody HrmAttendanceHolidaySaveReqVO updateReqVO) { |
| | | attendanceHolidayService.updateAttendanceHoliday(updateReqVO); |
| | | return success(true); |
| | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤è忥é
ç½®") |
| | | @Parameter(name = "id", description = "è忥ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:delete')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-holiday:delete')") |
| | | public CommonResult<Boolean> deleteAttendanceHoliday(@RequestParam("id") Long id) { |
| | | attendanceHolidayService.deleteAttendanceHoliday(id); |
| | | return success(true); |
| | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾è忥é
ç½®") |
| | | @Parameter(name = "id", description = "è忥ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-holiday:query')") |
| | | public CommonResult<HrmAttendanceHolidayRespVO> getAttendanceHoliday(@RequestParam("id") Long id) { |
| | | HrmAttendanceHolidayDO attendanceHoliday = attendanceHolidayService.getAttendanceHoliday(id); |
| | | return success(BeanUtils.toBean(attendanceHoliday, HrmAttendanceHolidayRespVO.class)); |
| | |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾è忥é
ç½®å页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-holiday:query')") |
| | | public CommonResult<PageResult<HrmAttendanceHolidayRespVO>> getAttendanceHolidayPage(@Valid HrmAttendanceHolidayPageReqVO pageReqVO) { |
| | | PageResult<HrmAttendanceHolidayDO> pageResult = attendanceHolidayService.getAttendanceHolidayPage(pageReqVO); |
| | | return success(BeanUtils.toBean(pageResult, HrmAttendanceHolidayRespVO.class)); |
| | |
| | | |
| | | @GetMapping("/export-excel") |
| | | @Operation(summary = "导åºè忥é
ç½® Excel") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:export')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-holiday:export')") |
| | | @ApiAccessLog(operateType = EXPORT) |
| | | public void exportAttendanceHolidayExcel(@Valid HrmAttendanceHolidayPageReqVO pageReqVO, |
| | | HttpServletResponse response) throws IOException { |
| | |
| | | |
| | | @PostMapping("/clock-in") |
| | | @Operation(summary = "ä¸çæå¡") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:clock')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-record:clock')") |
| | | public CommonResult<HrmAttendanceRecordRespVO> clockIn(@RequestParam("location") String location) { |
| | | Long loginUserId = getLoginUserId(); |
| | | HrmEmployeeDO employee = employeeService.getEmployeeByUserId(loginUserId); |
| | |
| | | |
| | | @PostMapping("/clock-out") |
| | | @Operation(summary = "ä¸çæå¡") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:clock')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-record:clock')") |
| | | public CommonResult<HrmAttendanceRecordRespVO> clockOut(@RequestParam("location") String location) { |
| | | Long loginUserId = getLoginUserId(); |
| | | HrmEmployeeDO employee = employeeService.getEmployeeByUserId(loginUserId); |
| | |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾èå¤è®°å½å页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-record:query')") |
| | | public CommonResult<PageResult<HrmAttendanceRecordRespVO>> getAttendanceRecordPage(@Valid HrmAttendanceRecordPageReqVO pageReqVO) { |
| | | PageResult<HrmAttendanceRecordDO> pageResult = attendanceRecordService.getAttendanceRecordPage(pageReqVO); |
| | | // 转æ¢ä¸º VO |
| | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾èå¤è®°å½") |
| | | @Parameter(name = "id", description = "è®°å½ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-record:query')") |
| | | public CommonResult<HrmAttendanceRecordRespVO> getAttendanceRecord(@RequestParam("id") Long id) { |
| | | HrmAttendanceRecordDO attendanceRecord = attendanceRecordService.getAttendanceRecord(id); |
| | | if (attendanceRecord == null) { |
| | |
| | | |
| | | @GetMapping("/export-excel") |
| | | @Operation(summary = "导åºèå¤è®°å½ Excel") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:export')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-record:export')") |
| | | @ApiAccessLog(operateType = EXPORT) |
| | | public void exportAttendanceRecordExcel(@Valid HrmAttendanceRecordPageReqVO pageReqVO, |
| | | HttpServletResponse response) throws IOException { |
| | |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "æ°å¢èå¤è§å") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:create')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-rule:create')") |
| | | public CommonResult<Long> createAttendanceRule(@Valid @RequestBody HrmAttendanceRuleSaveReqVO createReqVO) { |
| | | return success(attendanceRuleService.createAttendanceRule(createReqVO)); |
| | | } |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°èå¤è§å") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:update')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-rule:update')") |
| | | public CommonResult<Boolean> updateAttendanceRule(@Valid @RequestBody HrmAttendanceRuleSaveReqVO updateReqVO) { |
| | | attendanceRuleService.updateAttendanceRule(updateReqVO); |
| | | return success(true); |
| | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤èå¤è§å") |
| | | @Parameter(name = "id", description = "è§åID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:delete')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-rule:delete')") |
| | | public CommonResult<Boolean> deleteAttendanceRule(@RequestParam("id") Long id) { |
| | | attendanceRuleService.deleteAttendanceRule(id); |
| | | return success(true); |
| | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾èå¤è§å") |
| | | @Parameter(name = "id", description = "è§åID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-rule:query')") |
| | | public CommonResult<HrmAttendanceRuleRespVO> getAttendanceRule(@RequestParam("id") Long id) { |
| | | HrmAttendanceRuleDO attendanceRule = attendanceRuleService.getAttendanceRule(id); |
| | | if (attendanceRule == null) { |
| | |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾èå¤è§åå页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-rule:query')") |
| | | public CommonResult<PageResult<HrmAttendanceRuleRespVO>> getAttendanceRulePage(@Valid HrmAttendanceRulePageReqVO pageReqVO) { |
| | | PageResult<HrmAttendanceRuleDO> pageResult = attendanceRuleService.getAttendanceRulePage(pageReqVO); |
| | | List<HrmAttendanceRuleRespVO> list = BeanUtils.toBean(pageResult.getList(), HrmAttendanceRuleRespVO.class); |
| | |
| | | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "è·å¾èå¤è§åå表") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-rule:query')") |
| | | public CommonResult<List<HrmAttendanceRuleRespVO>> getAttendanceRuleList() { |
| | | List<HrmAttendanceRuleDO> list = attendanceRuleService.getAttendanceRuleList(); |
| | | return success(BeanUtils.toBean(list, HrmAttendanceRuleRespVO.class)); |
| | |
| | | |
| | | @GetMapping("/export-excel") |
| | | @Operation(summary = "导åºèå¤è§å Excel") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:export')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-rule:export')") |
| | | @ApiAccessLog(operateType = EXPORT) |
| | | public void exportAttendanceRuleExcel(@Valid HrmAttendanceRulePageReqVO pageReqVO, |
| | | HttpServletResponse response) throws IOException { |
| | |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾èå¤ç»è®¡æ±æ»å页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-summary:query')") |
| | | public CommonResult<PageResult<HrmAttendanceSummaryRespVO>> getAttendanceSummaryPage(@Valid HrmAttendanceSummaryPageReqVO pageReqVO) { |
| | | PageResult<HrmAttendanceSummaryDO> pageResult = attendanceSummaryService.getAttendanceSummaryPage(pageReqVO); |
| | | List<HrmAttendanceSummaryRespVO> list = BeanUtils.toBean(pageResult.getList(), HrmAttendanceSummaryRespVO.class); |
| | |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾åå·¥æåº¦è夿±æ»") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-summary:query')") |
| | | public CommonResult<HrmAttendanceSummaryRespVO> getMonthlySummary( |
| | | @RequestParam("userId") Long userId, |
| | | @RequestParam("yearMonth") String yearMonth) { |
| | |
| | | @PostMapping("/generate") |
| | | @Operation(summary = "çææåº¦è夿±æ»") |
| | | @Parameter(name = "yearMonth", description = "å¹´æï¼æ ¼å¼ï¼yyyy-MM", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:calculate')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-summary:generate')") |
| | | public CommonResult<Boolean> generateMonthlySummary(@RequestParam("yearMonth") String yearMonth, |
| | | @RequestParam(value = "deptId", required = false) Long deptId, |
| | | @RequestParam(value = "userId", required = false) Long userId) { |
| | |
| | | |
| | | @GetMapping("/export-excel") |
| | | @Operation(summary = "导åºèå¤ç»è®¡æ±æ» Excel") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance:export')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:attendance-summary:export')") |
| | | @ApiAccessLog(operateType = EXPORT) |
| | | public void exportAttendanceSummaryExcel(@Valid HrmAttendanceSummaryPageReqVO pageReqVO, |
| | | HttpServletResponse response) throws IOException { |
| | |
| | | @Schema(description = "ç±»åï¼1-伿¯æ¥ï¼2-工使¥", example = "1") |
| | | private Integer type; |
| | | |
| | | @Schema(description = "å¼å§æ¥æ", example = "2024-01-01") |
| | | private LocalDate startDate; |
| | | @Schema(description = "æ¯å¦æ³å®è忥ï¼0-å¦ï¼1-æ¯", example = "1") |
| | | private Integer isLegal; |
| | | |
| | | @Schema(description = "ç»ææ¥æ", example = "2024-12-31") |
| | | private LocalDate endDate; |
| | | @Schema(description = "æ¥æåºé´ï¼ä¼ [å¼å§æ¥æ, ç»ææ¥æ]", example = "[\"2026-01-01\", \"2026-12-31\"]") |
| | | private LocalDate[] date; |
| | | |
| | | } |
| | |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建å工社ä¿å
¬ç§¯éæ¡£æ¡") |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security:create')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:employee-social-security:create')") |
| | | public CommonResult<Long> createEmployeeSocialSecurity(@Valid @RequestBody HrmEmployeeSocialSecuritySaveReqVO createReqVO) { |
| | | HrmEmployeeSocialSecurityDO socialSecurity = BeanUtils.toBean(createReqVO, HrmEmployeeSocialSecurityDO.class); |
| | | return success(employeeSocialSecurityService.createEmployeeSocialSecurity(socialSecurity)); |
| | |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°å工社ä¿å
¬ç§¯éæ¡£æ¡") |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security:update')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:employee-social-security:update')") |
| | | public CommonResult<Boolean> updateEmployeeSocialSecurity(@Valid @RequestBody HrmEmployeeSocialSecuritySaveReqVO updateReqVO) { |
| | | HrmEmployeeSocialSecurityDO socialSecurity = BeanUtils.toBean(updateReqVO, HrmEmployeeSocialSecurityDO.class); |
| | | employeeSocialSecurityService.updateEmployeeSocialSecurity(socialSecurity); |
| | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤å工社ä¿å
¬ç§¯éæ¡£æ¡") |
| | | @Parameter(name = "id", description = "æ¡£æ¡ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security:delete')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:employee-social-security:delete')") |
| | | public CommonResult<Boolean> deleteEmployeeSocialSecurity(@RequestParam("id") Long id) { |
| | | employeeSocialSecurityService.deleteEmployeeSocialSecurity(id); |
| | | return success(true); |
| | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·åå工社ä¿å
¬ç§¯éæ¡£æ¡") |
| | | @Parameter(name = "id", description = "æ¡£æ¡ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:employee-social-security:query')") |
| | | public CommonResult<HrmEmployeeSocialSecurityRespVO> getEmployeeSocialSecurity(@RequestParam("id") Long id) { |
| | | HrmEmployeeSocialSecurityDO socialSecurity = employeeSocialSecurityService.getEmployeeSocialSecurity(id); |
| | | if (socialSecurity == null) { |
| | |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·åå工社ä¿å
¬ç§¯éæ¡£æ¡å页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:employee-social-security:query')") |
| | | public CommonResult<PageResult<HrmEmployeeSocialSecurityRespVO>> getEmployeeSocialSecurityPage( |
| | | @Valid HrmEmployeeSocialSecurityPageReqVO pageReqVO) { |
| | | PageResult<HrmEmployeeSocialSecurityDO> pageResult = employeeSocialSecurityService.getEmployeeSocialSecurityPage(pageReqVO); |
| | |
| | | @GetMapping("/list-by-user") |
| | | @Operation(summary = "è·åå工社ä¿å
¬ç§¯éæ¡£æ¡åå²å表") |
| | | @Parameter(name = "userId", description = "ç³»ç»ç¨æ·ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:employee-social-security:query')") |
| | | public CommonResult<List<HrmEmployeeSocialSecurityRespVO>> getEmployeeSocialSecurityList( |
| | | @RequestParam("userId") Long userId) { |
| | | List<HrmEmployeeSocialSecurityDO> list = employeeSocialSecurityService.getEmployeeSocialSecurityList(userId); |
| | |
| | | @GetMapping("/get-latest") |
| | | @Operation(summary = "è·ååå·¥ææ°çæç社ä¿å
¬ç§¯éæ¡£æ¡") |
| | | @Parameter(name = "userId", description = "ç³»ç»ç¨æ·ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:employee-social-security:query')") |
| | | public CommonResult<HrmEmployeeSocialSecurityRespVO> getLatestEmployeeSocialSecurity( |
| | | @RequestParam("userId") Long userId) { |
| | | HrmEmployeeSocialSecurityDO socialSecurity = employeeSocialSecurityService.getLatestEmployeeSocialSecurity(userId); |
| | |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾èªé
¬æ ¸ç®å页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-calculation:query')") |
| | | public CommonResult<PageResult<HrmSalaryCalculationRespVO>> getSalaryCalculationPage(@Valid HrmSalaryCalculationPageReqVO pageReqVO) { |
| | | PageResult<HrmSalaryCalculationDO> pageResult = salaryCalculationService.getSalaryCalculationPage(pageReqVO); |
| | | // 转æ¢ä¸º VO |
| | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾èªé
¬æ ¸ç®") |
| | | @Parameter(name = "id", description = "æ ¸ç®ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-calculation:query')") |
| | | public CommonResult<HrmSalaryCalculationRespVO> getSalaryCalculation(@RequestParam("id") Long id) { |
| | | HrmSalaryCalculationDO salaryCalculation = salaryCalculationService.getSalaryCalculation(id); |
| | | if (salaryCalculation == null) { |
| | |
| | | @Operation(summary = "æ§è¡èªé
¬æ ¸ç®") |
| | | @Parameter(name = "period", description = "æ ¸ç®å¨æ", required = true, example = "2024-01") |
| | | @Parameter(name = "deptId", description = "é¨é¨IDï¼ä¸ºç©ºåæ ¸ç®ææé¨é¨", example = "1") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:calculate')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-calculation:calculate')") |
| | | public CommonResult<Boolean> calculateSalary(@RequestParam("period") String period, |
| | | @RequestParam(value = "deptId", required = false) Long deptId) { |
| | | salaryCalculationService.calculateSalary(period, deptId); |
| | |
| | | |
| | | @PostMapping("/confirm") |
| | | @Operation(summary = "æ¹é确认èªé
¬æ ¸ç®") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:confirm')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-calculation:confirm')") |
| | | public CommonResult<Boolean> confirmSalaryCalculation(@RequestBody Map<String, List<Long>> request) { |
| | | List<Long> ids = request.get("ids"); |
| | | salaryCalculationService.confirmSalaryCalculation(ids); |
| | |
| | | |
| | | @PostMapping("/revoke") |
| | | @Operation(summary = "æ¹éæ¤éèªé
¬æ ¸ç®ç¡®è®¤") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:confirm')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-calculation:confirm')") |
| | | public CommonResult<Boolean> revokeSalaryCalculation(@RequestBody Map<String, List<Long>> request) { |
| | | List<Long> ids = request.get("ids"); |
| | | salaryCalculationService.revokeSalaryCalculation(ids); |
| | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤èªé
¬æ ¸ç®è®°å½") |
| | | @Parameter(name = "id", description = "æ ¸ç®ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:delete')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-calculation:delete')") |
| | | public CommonResult<Boolean> deleteSalaryCalculation(@RequestParam("id") Long id) { |
| | | salaryCalculationService.deleteSalaryCalculation(id); |
| | | return success(true); |
| | |
| | | |
| | | @GetMapping("/export-excel") |
| | | @Operation(summary = "导åºèªé
¬æ ¸ç® Excel") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:export')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-calculation:export')") |
| | | @ApiAccessLog(operateType = EXPORT) |
| | | public void exportSalaryCalculationExcel(@Valid HrmSalaryCalculationPageReqVO pageReqVO, |
| | | HttpServletResponse response) throws IOException { |
| | |
| | | @Operation(summary = "é¢è§é¨é¨ä¸ææåå·¥çèªèµæ ¸ç®ä¿¡æ¯") |
| | | @Parameter(name = "period", description = "æ ¸ç®å¨æ", required = true, example = "2024-01") |
| | | @Parameter(name = "deptId", description = "é¨é¨IDï¼ä¸ºç©ºåæ¥è¯¢å
¨é¨", example = "1") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-calculation:query')") |
| | | public CommonResult<List<HrmSalaryCalculationRespVO>> previewSalaryCalculation( |
| | | @RequestParam("period") String period, |
| | | @RequestParam(value = "deptId", required = false) Long deptId) { |
| | |
| | | |
| | | @PostMapping("/save") |
| | | @Operation(summary = "æ¹éä¿åèªé
¬æ ¸ç®è®°å½") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:calculate')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-calculation:save')") |
| | | public CommonResult<Boolean> saveSalaryCalculation(@Valid @RequestBody HrmSalaryCalculationSaveReqVO saveReqVO) { |
| | | // 转æ¢ä¸º DO å表 |
| | | List<HrmSalaryCalculationDO> calculationList = saveReqVO.getList().stream() |
| | |
| | | |
| | | @GetMapping("/page") |
| | | @Operation(summary = "è·å¾èªèµåæ¾å页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-payment:query')") |
| | | public CommonResult<PageResult<HrmSalaryPaymentRespVO>> getSalaryPaymentPage(@Valid HrmSalaryPaymentPageReqVO pageReqVO) { |
| | | PageResult<HrmSalaryPaymentDO> pageResult = salaryPaymentService.getSalaryPaymentPage(pageReqVO); |
| | | return success(BeanUtils.toBean(pageResult, HrmSalaryPaymentRespVO.class)); |
| | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾èªèµåæ¾") |
| | | @Parameter(name = "id", description = "åæ¾ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-payment:query')") |
| | | public CommonResult<HrmSalaryPaymentRespVO> getSalaryPayment(@RequestParam("id") Long id) { |
| | | HrmSalaryPaymentDO salaryPayment = salaryPaymentService.getSalaryPayment(id); |
| | | HrmSalaryPaymentRespVO respVO = BeanUtils.toBean(salaryPayment, HrmSalaryPaymentRespVO.class); |
| | |
| | | @PostMapping("/generate") |
| | | @Operation(summary = "çæèªèµåæ¾å°è´¦") |
| | | @Parameter(name = "period", description = "æ ¸ç®å¨æ", required = true, example = "2024-01") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:generate')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-payment:generate')") |
| | | public CommonResult<Long> generatePayment(@RequestParam("period") String period) { |
| | | return success(salaryPaymentService.generatePayment(period)); |
| | | } |
| | |
| | | @PostMapping("/pay") |
| | | @Operation(summary = "åæ¾èªèµï¼æ´ä¸ªå°è´¦ï¼") |
| | | @Parameter(name = "id", description = "åæ¾å°è´¦ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:pay')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-payment:pay')") |
| | | public CommonResult<Boolean> paySalary(@RequestParam("id") Long id) { |
| | | salaryPaymentService.paySalary(id); |
| | | return success(true); |
| | |
| | | |
| | | @PostMapping("/pay-detail") |
| | | @Operation(summary = "æ¹éåæ¾èªèµæç»") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:pay')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-payment:pay')") |
| | | public CommonResult<Boolean> paySalaryDetail(@RequestBody Map<String, List<Long>> request) { |
| | | List<Long> detailIds = request.get("detailIds"); |
| | | salaryPaymentService.paySalaryDetail(detailIds); |
| | |
| | | |
| | | @PostMapping("/revoke-detail") |
| | | @Operation(summary = "æ¹éæ¤éèªèµåæ¾æç»") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:pay')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-payment:pay')") |
| | | public CommonResult<Boolean> revokeSalaryPaymentDetail(@RequestBody Map<String, List<Long>> request) { |
| | | List<Long> detailIds = request.get("detailIds"); |
| | | salaryPaymentService.revokeSalaryPaymentDetail(detailIds); |
| | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤èªèµåæ¾å°è´¦") |
| | | @Parameter(name = "id", description = "åæ¾å°è´¦ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:delete')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-payment:delete')") |
| | | public CommonResult<Boolean> deleteSalaryPayment(@RequestParam("id") Long id) { |
| | | salaryPaymentService.deleteSalaryPayment(id); |
| | | return success(true); |
| | |
| | | |
| | | @GetMapping("/detail/page") |
| | | @Operation(summary = "è·å¾èªèµåæ¾æç»å页") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-payment:query')") |
| | | public CommonResult<PageResult<HrmSalaryPaymentDetailRespVO>> getSalaryPaymentDetailPage(@Valid HrmSalaryPaymentDetailPageReqVO pageReqVO) { |
| | | PageResult<HrmSalaryPaymentDetailDO> pageResult = salaryPaymentService.getSalaryPaymentDetailPage(pageReqVO); |
| | | List<HrmSalaryPaymentDetailRespVO> list = BeanUtils.toBean(pageResult.getList(), HrmSalaryPaymentDetailRespVO.class); |
| | |
| | | @GetMapping("/detail/list") |
| | | @Operation(summary = "è·å¾èªèµåæ¾æç»å表") |
| | | @Parameter(name = "paymentId", description = "åæ¾å°è´¦ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:salary-payment:query')") |
| | | public CommonResult<List<HrmSalaryPaymentDetailRespVO>> getSalaryPaymentDetailList(@RequestParam("paymentId") Long paymentId) { |
| | | List<HrmSalaryPaymentDetailDO> detailList = salaryPaymentService.getSalaryPaymentDetailListByPaymentId(paymentId); |
| | | List<HrmSalaryPaymentDetailRespVO> list = BeanUtils.toBean(detailList, HrmSalaryPaymentDetailRespVO.class); |
| | |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建社ä¿å
¬ç§¯éæ¹æ¡") |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security:create')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security-scheme:create')") |
| | | public CommonResult<Long> createScheme(@Valid @RequestBody HrmSocialSecuritySchemeSaveReqVO createReqVO) { |
| | | HrmSocialSecuritySchemeDO scheme = BeanUtils.toBean(createReqVO, HrmSocialSecuritySchemeDO.class); |
| | | return success(schemeService.createScheme(scheme)); |
| | |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°ç¤¾ä¿å
¬ç§¯éæ¹æ¡") |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security:update')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security-scheme:update')") |
| | | public CommonResult<Boolean> updateScheme(@Valid @RequestBody HrmSocialSecuritySchemeSaveReqVO updateReqVO) { |
| | | HrmSocialSecuritySchemeDO scheme = BeanUtils.toBean(updateReqVO, HrmSocialSecuritySchemeDO.class); |
| | | schemeService.updateScheme(scheme); |
| | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤ç¤¾ä¿å
¬ç§¯éæ¹æ¡") |
| | | @Parameter(name = "id", description = "æ¹æ¡ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security:delete')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security-scheme:delete')") |
| | | public CommonResult<Boolean> deleteScheme(@RequestParam("id") Long id) { |
| | | schemeService.deleteScheme(id); |
| | | return success(true); |
| | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å社ä¿å
¬ç§¯éæ¹æ¡") |
| | | @Parameter(name = "id", description = "æ¹æ¡ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security-scheme:query')") |
| | | public CommonResult<HrmSocialSecuritySchemeRespVO> getScheme(@RequestParam("id") Long id) { |
| | | HrmSocialSecuritySchemeDO scheme = schemeService.getScheme(id); |
| | | return success(BeanUtils.toBean(scheme, HrmSocialSecuritySchemeRespVO.class)); |
| | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "è·å社ä¿å
¬ç§¯éæ¹æ¡å表") |
| | | @Parameter(name = "status", description = "ç¶æ") |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:social-security-scheme:query')") |
| | | public CommonResult<List<HrmSocialSecuritySchemeRespVO>> getSchemeList( |
| | | @RequestParam(value = "status", required = false) Integer status) { |
| | | List<HrmSocialSecuritySchemeDO> list = schemeService.getSchemeList(status); |
| | |
| | | |
| | | @PostMapping("/create-list") |
| | | @Operation(summary = "æ¹éå建个ç¨ç¨çé
ç½®ï¼ä¸ä¸ªç¨ç表å
å«7个档ä½ï¼") |
| | | @PreAuthorize("@ss.hasPermission('hrm:tax-rate:create')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:tax-rate-config:create')") |
| | | public CommonResult<Boolean> createTaxRateConfigList(@Valid @RequestBody List<HrmTaxRateConfigSaveReqVO> createReqVOList) { |
| | | List<HrmTaxRateConfigDO> configList = BeanUtils.toBean(createReqVOList, HrmTaxRateConfigDO.class); |
| | | taxRateConfigService.createTaxRateConfigList(configList); |
| | |
| | | |
| | | @PutMapping("/update") |
| | | @Operation(summary = "æ´æ°ä¸ªç¨ç¨çé
ç½®") |
| | | @PreAuthorize("@ss.hasPermission('hrm:tax-rate:update')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:tax-rate-config:update')") |
| | | public CommonResult<Boolean> updateTaxRateConfig(@Valid @RequestBody HrmTaxRateConfigSaveReqVO updateReqVO) { |
| | | HrmTaxRateConfigDO config = BeanUtils.toBean(updateReqVO, HrmTaxRateConfigDO.class); |
| | | taxRateConfigService.updateTaxRateConfig(config); |
| | |
| | | @DeleteMapping("/delete") |
| | | @Operation(summary = "å é¤ä¸ªç¨ç¨çé
ç½®") |
| | | @Parameter(name = "id", description = "é
ç½®ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:tax-rate:delete')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:tax-rate-config:delete')") |
| | | public CommonResult<Boolean> deleteTaxRateConfig(@RequestParam("id") Long id) { |
| | | taxRateConfigService.deleteTaxRateConfig(id); |
| | | return success(true); |
| | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å个ç¨ç¨çé
ç½®") |
| | | @Parameter(name = "id", description = "é
ç½®ID", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:tax-rate:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:tax-rate-config:query')") |
| | | public CommonResult<HrmTaxRateConfigRespVO> getTaxRateConfig(@RequestParam("id") Long id) { |
| | | HrmTaxRateConfigDO config = taxRateConfigService.getTaxRateConfig(id); |
| | | return success(BeanUtils.toBean(config, HrmTaxRateConfigRespVO.class)); |
| | |
| | | |
| | | @GetMapping("/list") |
| | | @Operation(summary = "è·å个ç¨ç¨çé
ç½®å表") |
| | | @PreAuthorize("@ss.hasPermission('hrm:tax-rate:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:tax-rate-config:query')") |
| | | public CommonResult<List<HrmTaxRateConfigRespVO>> getTaxRateConfigList() { |
| | | List<HrmTaxRateConfigDO> list = taxRateConfigService.getTaxRateConfigList(); |
| | | return success(BeanUtils.toBean(list, HrmTaxRateConfigRespVO.class)); |
| | |
| | | @GetMapping("/get-effective") |
| | | @Operation(summary = "è·åçæç个ç¨ç¨çé
ç½®åè¡¨ï¼æçº§æ°æåºï¼") |
| | | @Parameter(name = "effectiveDate", description = "çææ¥æ", required = true) |
| | | @PreAuthorize("@ss.hasPermission('hrm:tax-rate:query')") |
| | | @PreAuthorize("@ss.hasPermission('hrm:tax-rate-config:query')") |
| | | public CommonResult<List<HrmTaxRateConfigRespVO>> getEffectiveTaxRateConfigList( |
| | | @RequestParam("effectiveDate") LocalDate effectiveDate) { |
| | | List<HrmTaxRateConfigDO> list = taxRateConfigService.getEffectiveTaxRateConfigList(effectiveDate); |
| | |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<HrmAttendanceHolidayDO>() |
| | | .likeIfPresent(HrmAttendanceHolidayDO::getName, reqVO.getName()) |
| | | .eqIfPresent(HrmAttendanceHolidayDO::getType, reqVO.getType()) |
| | | .betweenIfPresent(HrmAttendanceHolidayDO::getDate, reqVO.getStartDate(), reqVO.getEndDate()) |
| | | .eqIfPresent(HrmAttendanceHolidayDO::getIsLegal, reqVO.getIsLegal()) |
| | | .betweenIfPresent(HrmAttendanceHolidayDO::getDate, reqVO.getDate()) |
| | | .orderByDesc(HrmAttendanceHolidayDO::getDate)); |
| | | } |
| | | |
| | |
| | | |
| | | private void validateAttendanceHolidayExists(Long id) { |
| | | if (attendanceHolidayMapper.selectById(id) == null) { |
| | | throw exception(ATTENDANCE_HOLIDAY_NOT_EXISTS); |
| | | throw exception(ATTENDANCE_HOLIDAY_NOT_EXISTS, id); |
| | | } |
| | | } |
| | | |
| | | private void validateAttendanceHolidayDateExists(LocalDate date) { |
| | | if (attendanceHolidayMapper.selectByDate(date) != null) { |
| | | throw exception(ATTENDANCE_HOLIDAY_DATE_EXISTS); |
| | | throw exception(ATTENDANCE_HOLIDAY_DATE_EXISTS, date); |
| | | } |
| | | } |
| | | |
| | |
| | | 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.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.md.item.MesMdItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; |
| | |
| | | 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("示ä¾-XXå·¥åè¿ç¨æ£éª").type("馿£").workOrderCode("MO20260101000001") |
| | | .workstationName("示ä¾å·¥ä½").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 |
| | | * |
| | | * 说æï¼ä¸è¡ = ä¸å¼ è¿ç¨æ£éªåã产åç©æç±ç产工åï¼æç产任å¡ï¼èªå¨æ¨å¯¼ï¼æ¨¡æ¿æ éå¡«åï¼ |
| | | * å·¥ä½ãè´¨æ£æ¹æ¡æåç§°å¹é
ç³»ç»å·²ææ°æ®ï¼æ£æµäººåç空åå½åç»å½ç¨æ·ï¼ç¶æåºå®ä¸ºãå¾
æ£éªãã |
| | | * |
| | | * @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 = "MO20260101000001") |
| | | private String workOrderCode; |
| | | |
| | | @ExcelProperty("å·¥ä½åç§°") |
| | | @Schema(description = "å·¥ä½åç§°ï¼éä¸å·¥ä½ç®¡çä¸çåç§°ä¸è´", requiredMode = Schema.RequiredMode.REQUIRED, example = "è£
é
å·¥ä½1") |
| | | private String workstationName; |
| | | |
| | | @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", example = "2") |
| | | private BigDecimal laborScrapQuantity; |
| | | |
| | | @ExcelProperty("æåºæ°é") |
| | | @Schema(description = "æåºæ°éï¼ç空é»è®¤ 0", example = "2") |
| | | private BigDecimal materialScrapQuantity; |
| | | |
| | | @ExcelProperty("å
¶ä»åºåæ°é") |
| | | @Schema(description = "å
¶ä»åºåæ°éï¼ç空é»è®¤ 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.srm.api.supplier.SrmSupplierApi; |
| | | import cn.iocoder.yudao.module.srm.api.supplier.dto.SrmSupplierRespDTO; |
| | |
| | | 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 客æ·ç®¡çä¸çåç§°ä¸è´", requiredMode = Schema.RequiredMode.REQUIRED, example = "示ä¾å®¢æ·æéå
¬å¸") |
| | | private String clientName; |
| | | |
| | | @ExcelProperty("æ¹æ¬¡å·") |
| | | @Schema(description = "æ¹æ¬¡å·", example = "BC20260101") |
| | | private String batchCode; |
| | | |
| | | @ExcelProperty("è´¨æ£æ¹æ¡") |
| | | @Schema(description = "è´¨æ£æ¹æ¡åç§°ï¼ç空åæç©æèªå¨å¹é
", example = "åºè´§æ£éªéç¨æ¹æ¡") |
| | | private String templateName; |
| | | |
| | | @ExcelProperty("æ¬æ¬¡åºè´§æ°é") |
| | | @Schema(description = "æ¬æ¬¡åºè´§æ°éï¼ä¸è½å°äº 0", requiredMode = Schema.RequiredMode.REQUIRED, 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", requiredMode = Schema.RequiredMode.REQUIRED, 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.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.string.StrUtils; |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.md.item.vo.MesMdItemPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemTypeDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | import org.apache.ibatis.annotations.Select; |
| | | import org.apache.ibatis.annotations.Update; |
| | |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| | | |
| | |
| | | public interface MesMdItemMapper extends BaseMapperX<MesMdItemDO> { |
| | | |
| | | default PageResult<MesMdItemDO> selectPage(MesMdItemPageReqVO reqVO, Collection<Long> itemTypeIds) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<MesMdItemDO>() |
| | | MPJLambdaWrapperX<MesMdItemDO> query = new MPJLambdaWrapperX<>(); |
| | | query.selectAll(MesMdItemDO.class); |
| | | // å
³èç©æåç±»ï¼ä»
ç¨äºæåºï¼ååç±»çç©æèå¨ä¸èµ·ï¼åç±»ä¹é´æåç±»çæ¾ç¤ºæåº |
| | | query.leftJoin(MesMdItemTypeDO.class, MesMdItemTypeDO::getId, MesMdItemDO::getItemTypeId) |
| | | .likeIfPresent(MesMdItemDO::getCode, reqVO.getCode()) |
| | | .likeIfPresent(MesMdItemDO::getName, reqVO.getName()) |
| | | .inIfPresent(MesMdItemDO::getItemTypeId, itemTypeIds) |
| | |
| | | StrUtil.isBlank(reqVO.getIds()) ? null : StrUtils.splitToLong(reqVO.getIds(), ",")) |
| | | .eqIfPresent(MesMdItemDO::getStatus, reqVO.getStatus()) |
| | | .betweenIfPresent(MesMdItemDO::getCreateTime, reqVO.getCreateTime()) |
| | | .orderByDesc(MesMdItemDO::getId)); |
| | | .orderByAsc(MesMdItemTypeDO::getSort) |
| | | .orderByAsc(MesMdItemTypeDO::getCode) |
| | | .orderByAsc(MesMdItemDO::getCode); |
| | | return selectPage(reqVO, query); |
| | | } |
| | | |
| | | default MesMdItemDO selectByCode(String code) { |
| | |
| | | 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 workOrderId, Integer type, Long workstationId, |
| | | LocalDateTime inspectDate) { |
| | | return selectList(new LambdaQueryWrapperX<MesQcIpqcDO>() |
| | | .eq(MesQcIpqcDO::getWorkOrderId, workOrderId) |
| | | .eq(MesQcIpqcDO::getType, type) |
| | | .eq(MesQcIpqcDO::getWorkstationId, workstationId) |
| | | .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); |
| | | } |
| | | |
| | | /** |
| | | * æå¯¼å
¥å»é鮿¥è¯¢ï¼åä¸ ç©æ + å®¢æ· + æ¹æ¬¡å· + åºè´§æ¥æ è§ä¸ºå䏿¹åºè´§æ£éªæ°æ® |
| | | */ |
| | | default List<MesQcOqcDO> selectListByImportKey(Long itemId, Long clientId, String batchCode, |
| | | LocalDateTime outDate) { |
| | | return selectList(new LambdaQueryWrapperX<MesQcOqcDO>() |
| | | .eq(MesQcOqcDO::getItemId, itemId) |
| | | .eq(MesQcOqcDO::getClientId, clientId) |
| | | .eq(batchCode != null, MesQcOqcDO::getBatchCode, batchCode) |
| | | .isNull(batchCode == null, MesQcOqcDO::getBatchCode) |
| | | .eq(MesQcOqcDO::getOutDate, outDate) |
| | | .orderByAsc(MesQcOqcDO::getId)); |
| | | } |
| | | |
| | | } |
| | |
| | | PageResult<MesMdWorkstationDO> getWorkstationPage(MesMdWorkstationPageReqVO pageReqVO); |
| | | |
| | | /** |
| | | * æåç§°è·å¾å·¥ä½ç«ï¼åç§°å
¨å±å¯ä¸ï¼ |
| | | * |
| | | * @param name å·¥ä½ç«åç§° |
| | | * @return å·¥ä½ç« |
| | | */ |
| | | MesMdWorkstationDO getWorkstationByName(String name); |
| | | |
| | | /** |
| | | * è·å¾æå®ç¶æçå·¥ä½ç«å表 |
| | | * |
| | | * @param status ç¶æ |
| | |
| | | } |
| | | |
| | | @Override |
| | | public MesMdWorkstationDO getWorkstationByName(String name) { |
| | | return workstationMapper.selectByName(name); |
| | | } |
| | | |
| | | @Override |
| | | public List<MesMdWorkstationDO> getWorkstationListByStatus(Integer status) { |
| | | return workstationMapper.selectListByStatus(status); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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.md.workstation.MesMdWorkstationDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.template.MesQcTemplateDO; |
| | | import cn.iocoder.yudao.module.mes.service.md.autocode.MesMdAutoCodeRecordService; |
| | | import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService; |
| | | import cn.iocoder.yudao.module.mes.service.pro.workorder.MesProWorkOrderService; |
| | | 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; |
| | | @Resource |
| | | private MesProWorkOrderService workOrderService; |
| | | @Resource |
| | | private MesMdWorkstationService workstationService; |
| | | |
| | | /** è´¨æ£æ¹æ¡åç§° -> ç¼å·ï¼å¯è½éåï¼å½ä¸å¤ä¸ªæ¶å第ä¸ä¸ªï¼ */ |
| | | 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; |
| | | } |
| | | |
| | | /** |
| | | * è§£æå®¢æ·ç¼å·ï¼åºäºå®¢æ·åç§° |
| | | */ |
| | | public Long resolveClientId(String clientName) { |
| | | if (StrUtil.isBlank(clientName)) { |
| | | throw new IllegalArgumentException("客æ·åç§°ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çã客æ·åç§°ãå"); |
| | | } |
| | | 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 客æ·ç®¡ç-æè´è´£çã䏿¥çï¼ï¼" |
| | | + "æè系管çå为æ¨å¼é该客æ·çæéå鿰坼å
¥"); |
| | | } |
| | | |
| | | /** |
| | | * è§£æç产工åç¼å·ï¼åºäºå·¥åå· |
| | | */ |
| | | public Long resolveWorkOrderId(String workOrderCode) { |
| | | if (StrUtil.isBlank(workOrderCode)) { |
| | | throw new IllegalArgumentException("ç产工åå·ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çãç产工åå·ãå"); |
| | | } |
| | | MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(workOrderCode.trim()); |
| | | if (workOrder == null) { |
| | | throw new IllegalArgumentException("ç产工åä¸åå¨ï¼" + workOrderCode.trim() |
| | | + "ã请å¨ãç产管ç-ç产工åã䏿 ¸å¯¹è¯¥å·¥åå·ï¼é䏿¨¡æ¿å®å
¨ä¸è´ï¼ï¼æä¿®æ¹æ¨¡æ¿å鿰坼å
¥"); |
| | | } |
| | | return workOrder.getId(); |
| | | } |
| | | |
| | | /** |
| | | * è§£æå·¥ä½ç¼å·ï¼åºäºå·¥ä½åç§° |
| | | */ |
| | | public Long resolveWorkstationId(String workstationName) { |
| | | if (StrUtil.isBlank(workstationName)) { |
| | | throw new IllegalArgumentException("å·¥ä½åç§°ä¸è½ä¸ºç©ºï¼è¯·å¡«å模æ¿ä¸è¯¥è¡çãå·¥ä½åç§°ãå"); |
| | | } |
| | | MesMdWorkstationDO workstation = workstationService.getWorkstationByName(workstationName.trim()); |
| | | if (workstation == null) { |
| | | throw new IllegalArgumentException("å·¥ä½ä¸åå¨ï¼" + workstationName.trim() |
| | | + "ã请å¨ãåºç¡æ°æ®-å·¥ä½ç®¡çã䏿 ¸å¯¹è¯¥å·¥ä½åç§°ï¼é䏿¨¡æ¿å®å
¨ä¸è´ï¼ï¼æä¿®æ¹æ¨¡æ¿å鿰坼å
¥"); |
| | | } |
| | | return workstation.getId(); |
| | | } |
| | | |
| | | /** |
| | | * è§£æåå
¸å¼ï¼æ¯æå¡«ååå
¸åç§°ï¼å¦ æ ¡éªéè¿ï¼æåå
¸å¼ï¼å¦ 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.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.exception.ServiceException; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | 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.enums.DictTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.qc.imports.MesQcImportHelper; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProductDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; |
| | |
| | | |
| | | import 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 AdminUserApi adminUserApi; |
| | | |
| | | @Resource |
| | | private MesQcImportHelper qcImportHelper; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | 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.getWorkOrderCode()) |
| | | && StrUtil.isBlank(row.getWorkstationName()) && 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.setWorkOrderId(qcImportHelper.resolveWorkOrderId(row.getWorkOrderCode())); |
| | | reqVO.setWorkstationId(qcImportHelper.resolveWorkstationId(row.getWorkstationName())); |
| | | 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.getWorkOrderId(), |
| | | reqVO.getType(), reqVO.getWorkstationId(), reqVO.getInspectDate())); |
| | | if (duplicate != null) { |
| | | throw MesQcImportHelper.duplicateExistingException(buildImportKeyDesc(row), "è¿ç¨æ£éªå", |
| | | duplicate.getCode(), "è´¨é管ç-è¿ç¨æ£éª"); |
| | | } |
| | | // 6. å¤ç¨å建é»è¾ï¼æ ¡éªå·¥å/å·¥ä½/人åãæç©æå¹é
è´¨æ£æ¹æ¡ãçææ£éªè¡ |
| | | try { |
| | | createIpqc(reqVO); |
| | | } catch (ServiceException ex) { |
| | | MesQcImportHelper.rethrowTemplateError(ex, row.getWorkOrderCode(), "è¿ç¨æ£éª(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.getWorkOrderCode()), StrUtil.trimToEmpty(row.getType()), |
| | | StrUtil.trimToEmpty(row.getWorkstationName()), StrUtil.trimToEmpty(row.getInspectDate())); |
| | | } |
| | | |
| | | private String buildImportKeyDesc(MesQcIpqcImportExcelVO row) { |
| | | return "ç产工å[" + MesQcImportHelper.describeImportValue(row.getWorkOrderCode()) |
| | | + "]ãæ£éªç±»å[" + MesQcImportHelper.describeImportValue(row.getType()) |
| | | + "]ãå·¥ä½[" + MesQcImportHelper.describeImportValue(row.getWorkstationName()) |
| | | + "]ãæ£æµæ¥æ[" + 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.exception.ServiceException; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | 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.enums.DictTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.qc.imports.MesQcImportHelper; |
| | | 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; |
| | |
| | | @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.dataobject.md.item.MesMdItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.qc.ledger.MesQcInspectionLedgerMapper; |
| | | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| | | import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; |
| | | import cn.iocoder.yudao.module.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 MesMdItemService itemService; |
| | | @Resource |
| | | private MesMdUnitMeasureService unitMeasureService; |
| | | @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()); |
| | | } |
| | | // æ¹éæ¥è¯¢ç©æã计éåä½ãæ£æµäººåï¼å¹¶æ¼è£
å¤å®ä¾æ® |
| | | Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(convertSet(list, MesQcInspectionLedgerRespVO::getItemId)); |
| | | Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap( |
| | | convertSet(itemMap.values(), MesMdItemDO::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.enums.DictTypeConstants; |
| | | import cn.iocoder.yudao.module.mes.enums.md.autocode.MesMdAutoCodeRuleCodeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.qc.imports.MesQcImportHelper; |
| | | 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 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 |
| | | @Lazy |
| | | private MesQcNcrService ncrService; |
| | | |
| | | @Resource |
| | | private MesQcImportHelper qcImportHelper; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | 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()); |
| | | 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(), "æ¬æ¬¡åºè´§æ°é", true)); |
| | | 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.parseRequiredDateTime(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, |
| | | NULL 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> |