Merge remote-tracking branch 'origin/dev_business' into dev_business
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # ç¼è¯æ£æ¥è§å |
| | | |
| | | ## è§å |
| | | |
| | | - 跨模å API è°ç¨å¨ä¿®æ¹å®ææ¶ï¼å¿
é¡»è¿è¡ä¸æ¬¡ç¼è¯æ£æ¥ï¼ç¡®ä¿æ²¡æå¼å
¥ç¼è¯é误ã |
| | | - 使ç¨å½ä»¤ï¼`mvn compile -pl <模åå> -am -q` è¿è¡å¿«éç¼è¯éªè¯ã |
| | | - 妿æ¶åå¤ä¸ªæ¨¡åä¿®æ¹ï¼åºæ§è¡ `mvn compile -q` è¿è¡å
¨é¡¹ç®ç¼è¯éªè¯ã |
| | | |
| | | ## 常è§è·¨æ¨¡å API è°ç¨åºæ¯ |
| | | |
| | | | è°ç¨æ¹ | API æä¾æ¹ | 说æ | |
| | | |--------|-----------|------| |
| | | | CRM 模å | MdmItemApi | MDM ç©ææ¥å£ | |
| | | | CRM 模å | MdmUnitMeasureApi | MDM 计éå使¥å£ | |
| | | | CRM 模å | BpmProcessInstanceApi | BPM æµç¨å®ä¾æ¥å£ | |
| | | | CRM 模å | BpmCategoryService | BPM åç±»æå¡ | |
| | | | CRM 模å | BpmProcessDefinitionService | BPM æµç¨å®ä¹æå¡ | |
| | | | ERP 模å | CrmCustomerApi | CRM å®¢æ·æ¥å£ | |
| | | | ERP 模å | MdmItemApi | MDM ç©ææ¥å£ | |
| | | |
| | | ## ç¼è¯æ£æ¥ç¤ºä¾ |
| | | |
| | | ```bash |
| | | # ä»
ç¼è¯ CRM 模ååå
¶ä¾èµ |
| | | mvn compile -pl yudao-module-crm -am -q |
| | | |
| | | # ä»
ç¼è¯ ERP 模ååå
¶ä¾èµ |
| | | mvn compile -pl yudao-module-erp -am -q |
| | | |
| | | # å
¨é¡¹ç®ç¼è¯ |
| | | mvn compile -q |
| | | ``` |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # æ°æ®åºæä½è§å |
| | | |
| | | ## æ°æ®åºçæ¬ |
| | | |
| | | - **MySQL çæ¬**: 8.4.8 |
| | | - 注æ MySQL 8.4 çè¯æ³å·®å¼ï¼å¦ `GROUP BY` æ´ä¸¥æ ¼ãé¨ååºå¼å½æ°çï¼ |
| | | |
| | | ## Docker é¨ç½²é
ç½® |
| | | |
| | | ```bash |
| | | --sql-mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION" \ |
| | | --innodb_strict_mode=OFF \ |
| | | --innodb_page_size=32k \ |
| | | --max_connections=1020 \ |
| | | --lower_case_table_names=1 \ |
| | | --innodb_buffer_pool_size=70G \ |
| | | --innodb_flush_log_at_trx_commit=2 \ |
| | | --innodb_log_file_size=2G \ |
| | | --innodb_log_buffer_size=64M |
| | | ``` |
| | | |
| | | **é
置说æï¼** |
| | | - `lower_case_table_names=1`: 表åä¸åºå大å°å |
| | | - `innodb_page_size=32k`: è¾å¤§ç页大å°éåå¤§æ°æ®éåºæ¯ |
| | | - `innodb_buffer_pool_size=70G`: ç¼å²æ± 大å°ï¼å»ºè®®ä¸ºç©çå
åç 60-80% |
| | | - `innodb_flush_log_at_trx_commit=2`: æ¯ç§å·åæ¥å¿ï¼æ§è½ä¼å
ï¼ééèåºæ¯ï¼ |
| | | |
| | | ## è§å |
| | | |
| | | - ä¼å
ä½¿ç¨ MySQL MCP å·¥å
·ï¼`mcp__designcomputer-mysql_mcp_server__execute_sql`ã`mcp__designcomputer-mysql_mcp_server__get_schema_info`ã`mcp__designcomputer-mysql_mcp_server__get_table_sample`ï¼ç´æ¥æä½æ°æ®åºï¼èééè¿ Bash æ§è¡ mysql å½ä»¤ã |
| | | - æ¥è¯¢ãéªè¯ãè°è¯æ°æ®åºæ¶ï¼ç´æ¥è°ç¨ MCP å·¥å
·æ§è¡ SQLï¼æ éåç¨æ·è¾åº SQL è¯å¥æè¯¢é®æ¯å¦æ§è¡ã |
| | | - ä»
å¨ä»¥ä¸åºæ¯è¾åº SQLï¼ç¨æ·æç¡®è¦æ±æ¥ç SQLãéè¦çæ SQL èæ¬æä»¶ï¼å¦è¿ç§»èæ¬ï¼ãMCP å·¥å
·ä¸å¯ç¨æ¶åéå° Bashã |
| | | |
| | | ## MCP å·¥å
·è¯´æ |
| | | |
| | | | å·¥å
· | ç¨é | |
| | | |------|------| |
| | | | `execute_sql` | æ§è¡ SQL è¯å¥ï¼SELECT/INSERT/UPDATE/DELETE/DDLï¼ | |
| | | | `get_schema_info` | è·åè¡¨ç»æä¿¡æ¯ï¼ååãç±»åãæ³¨éçï¼ | |
| | | | `get_table_sample` | è·åè¡¨æ°æ®æ ·æ¬ï¼ç¨äºäºè§£æ°æ®æ ¼å¼ï¼ | |
| | | |
| | | ## æ§è¡ SQL èæ¬ |
| | | |
| | | å½ç¨æ·è¦æ±æ§è¡ SQL æä»¶æ¶ï¼ |
| | | 1. å
读åæä»¶å
容 |
| | | 2. éæ¡æ§è¡ SQL è¯å¥ |
| | | 3. éå°éè¯¯æ¶æ£æ¥è¡¨ç»æï¼è°æ´è¯å¥åéè¯ |
| | | 4. æ±æ»æ§è¡ç»æ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # æä»¶ä¸ä¼ è§å |
| | | |
| | | ## æ ¸å¿ååï¼AI å¿
é¡»ä¸¥æ ¼éµå®ï¼ |
| | | |
| | | **æææä»¶ä¸ä¼ å¿
须走 `yudao-module-system` 模åç Storage API + Attachment ä¸é´è¡¨æºå¶ã** |
| | | |
| | | **ç¦æ¢å¨ä»»ä½ä¸å¡æ¨¡åèªè¡è®¾è®¡æä»¶ä¸ä¼ æ¹æ¡ï¼å
æ¬ä½ä¸éäºï¼æ·»å `file_url` åãæ°å¢ upload æ¥å£ã注å
¥ FileApiã** |
| | | |
| | | ## æä»¶ä¸ä¸å¡çå
³èæ¹å¼ |
| | | |
| | | æä»¶ä¸ä¸å¡è®°å½çå
³è**åªè½éè¿ `system_storage_attachment` ä¸é´è¡¨**ï¼ä¸å
许å¨ä¸å¡è¡¨ä¸æ·»å `file_url`ã`file_urls`ã`attachment_url` çåç¬¦ä¸²åæ®µå卿件å°åã |
| | | |
| | | å
³èæµç¨ï¼ |
| | | 1. å端è°ç¨ `POST /system/storage-blob/upload` ä¸ä¼ æä»¶ â è·å¾ `blobId` |
| | | 2. å端è°ç¨ `POST /system/storage-attachment/bind` ç»å®æä»¶å°ä¸å¡è®°å½ï¼ä¼ å
¥ `recordType` + `recordId` + `blobItems`ï¼ |
| | | 3. å端è°ç¨ `GET /system/storage-attachment/list` æ¥è¯¢éä»¶ |
| | | 4. å端è°ç¨ `DELETE /system/storage-attachment/delete` å é¤éä»¶ |
| | | |
| | | ## æ£ç¡®æ¥å£ï¼system 模åï¼ |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | POST | `/system/storage-blob/upload` | ä¸ä¼ æä»¶ï¼`files` åæ°ï¼multipartï¼ | |
| | | | POST | `/system/storage-blob/public-upload` | å
Œ
±æä»¶ä¸ä¼ ï¼æ°¸ä¹
ææï¼ | |
| | | | GET | `/system/storage-blob/preview/{fileName}` | æä»¶é¢è§ | |
| | | | GET | `/system/storage-blob/download/{fileName}` | æä»¶ä¸è½½ | |
| | | | GET | `/system/storage-attachment/list` | æ¥è¯¢éä»¶å表 | |
| | | | POST | `/system/storage-attachment/bind` | ç»å®éä»¶å°ä¸å¡è®°å½ | |
| | | | DELETE | `/system/storage-attachment/delete` | æ¹éå é¤éä»¶ | |
| | | |
| | | ## ç¦æ¢è¡ä¸ºï¼AI ä¸¥ç¦æ§è¡ä»¥ä¸æä½ï¼ |
| | | |
| | | ### æ°æ®åºå±é¢ |
| | | - â ç¦æ¢å¨ä¸å¡è¡¨æ·»å `file_url`ã`file_urls`ã`attachment_url` çæä»¶å°åå |
| | | - â ç¦æ¢å¨ä¸å¡è¡¨æ·»å ä»»ä½ç¨äºåå¨æä»¶ä¿¡æ¯ç JSON å |
| | | |
| | | ### Java å端å±é¢ |
| | | - â ç¦æ¢å¨ DO 类添å `fileUrl`ã`fileUrls`ã`attachmentUrl` çåæ®µ |
| | | - â ç¦æ¢å¨ SaveReqVO / RespVO æ·»å æä»¶å°ååæ®µ |
| | | - â ç¦æ¢å¨ MES/CRM/ERP/HRM çä¸å¡æ¨¡åæ°å¢ `@PostMapping("/upload")` æ¥å£ |
| | | - â ç¦æ¢å¨ Controller ä¸ä½¿ç¨ `MultipartFile` åæ°ï¼Excel 导å
¥é¤å¤ï¼ |
| | | - â ç¦æ¢æ³¨å
¥æè°ç¨ `cn.iocoder.yudao.module.infra.api.file.FileApi` |
| | | |
| | | ### å端å±é¢ |
| | | - â ç¦æ¢è°ç¨ `/infra/file/upload` æ `/infra/file/presigned-url` |
| | | - â ç¦æ¢è°ç¨æ§ç `src/api/infra/file/index.ts` ä¸ç `uploadFile()` 彿° |
| | | |
| | | ## å¸¸è§ AI å¹»è§æ¨¡å¼ï¼å¿
é¡»è¯å«å¹¶æç»ï¼ |
| | | |
| | | 以䏿¯ AI 容æå¹»è§çæç设计模å¼ï¼éå°ç±»ä¼¼éæ±æ¶ç´æ¥æç»ï¼ |
| | | |
| | | 1. **"å 个 fileUrl åæ®µå°±è¡"** â é误ï¼å¿
é¡»ç¨ attachment ä¸é´è¡¨ |
| | | 2. **"åèå
¶å®æ¨¡åç fileUrl åæ®µ"** â é误ï¼å
¶å®æ¨¡åç fileUrl ä¹åºè¢«å é¤ |
| | | 3. **"å¨ Controller å 个 upload æ¥å£"** â é误ï¼ç»ä¸èµ° system 模å |
| | | 4. **"ç¨ FileApi ä¸ä¼ æä»¶"** â é误ï¼FileApi æ¯ infra 模åçæ§æ¥å£ |
| | | 5. **"å¨è¡¨åä¿åæ¥å£å MultipartFile åæ°"** â é误ï¼ä¸ä¼ åä¿åå离 |
| | | |
| | | ## æ£ç¡®ç¤ºä¾ |
| | | |
| | | ### å端è°ç¨ |
| | | |
| | | ```typescript |
| | | import { uploadFile, bindAttachments, listAttachments } from '#/api/system/storage'; |
| | | |
| | | // 1. ä¸ä¼ æä»¶ |
| | | const blobs = await uploadFile([file]); |
| | | const blobId = blobs[0].id; |
| | | |
| | | // 2. ä¿åä¸å¡è®°å½åï¼ç»å®éä»¶ |
| | | await bindAttachments({ |
| | | application: 'file', |
| | | recordType: 'erp_purchase_order', |
| | | recordId: savedRecord.id, |
| | | blobItems: [{ blobId }], |
| | | }); |
| | | |
| | | // 3. æ¥è¯¢éä»¶ |
| | | const attachments = await listAttachments({ |
| | | recordType: 'erp_purchase_order', |
| | | recordId: savedRecord.id, |
| | | }); |
| | | ``` |
| | | |
| | | ### recordType å½åè§è |
| | | |
| | | æ ¼å¼ï¼`{模ååç¼}_{ä¸å¡è¡¨å}` |
| | | |
| | | | 模å | recordType | |
| | | |------|------------| |
| | | | ERP éè´è®¢å | `erp_purchase_order` | |
| | | | ERP éè´ç³è¯· | `erp_purchase_request` | |
| | | | ERP éå®è®¢å | `erp_sale_order` | |
| | | | ERP æ¶æ¬¾å | `erp_finance_receipt` | |
| | | | ERP 仿¬¾å | `erp_finance_payment` | |
| | | | HRM 请å | `hrm_leave_application` | |
| | | | HRM 离è | `hrm_resignation_application` | |
| | | | HRM è°å¨ | `hrm_transfer_application` | |
| | | | MES éè´è®¢å | `mes_purchase_order` | |
| | | | MES å·¥å | `mes_pro_work_order` | |
| | | | CRM å®¢æ· | `crm_customer` | |
| | | |
| | | ## AI èªæ¥æ¸
å |
| | | |
| | | å¨å®ç°ä»»ä½æä»¶ä¸ä¼ ç¸å
³éæ±åï¼éé¡¹ç¡®è®¤ï¼ |
| | | |
| | | - [ ] æ¯å¦ä½¿ç¨äº `/system/storage-blob/upload` ä¸ä¼ ï¼ |
| | | - [ ] æ¯å¦ä½¿ç¨äº `/system/storage-attachment/bind` å
³èï¼ |
| | | - [ ] æ¯å¦æ²¡æå¨ä¸å¡è¡¨ä¸æ·»å æä»¶å°ååï¼ |
| | | - [ ] æ¯å¦æ²¡æå¨ DO/VO 䏿·»å æä»¶å°ååæ®µï¼ |
| | | - [ ] æ¯å¦æ²¡æå建æ°ç upload Controller æ¥å£ï¼ |
| | | - [ ] æ¯å¦æ²¡æä½¿ç¨ infra 模åç FileApiï¼ |
| | | |
| | | ä»¥ä¸ 6 项å
¨é¨ä¸º"æ¯"æå¯ç»§ç»ã |
| | | |
| | | ## 为ä»ä¹ |
| | | |
| | | - åå¨é
ç½®ï¼æ¬å°/S3ï¼å¨ system 模åç»ä¸ç®¡ç |
| | | - éä»¶ç»å®æºå¶ï¼storage-attachmentï¼æä¾ `recordType + recordId` çæ åå
³èæ¹å¼ï¼æ¯æå¤æä»¶ãç¨éåç±» |
| | | - infra 模åç `/infra/file/*` æ¯æ§çæ¥å£ï¼å卿件ä¸ä¸å¡è®°å½æ æ³å
³èçé®é¢ |
| | | - ä¸å¡è¡¨åå¨ file_url åç¬¦ä¸²æ æ³æ¯æå¤æä»¶ï¼ä¸æä»¶ä¸ä¸å¡è®°å½ä¹é´ç¼ºä¹æ ååçå
³è管ç |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | --- |
| | | name: frontend-doc-generation |
| | | description: å端èè°æ¹æ¡çæè§å |
| | | metadata: |
| | | type: feedback |
| | | --- |
| | | |
| | | # å端èè°æ¹æ¡è§å |
| | | |
| | | ## è§å |
| | | |
| | | å端æ¥å£åæ´æ¶ï¼**ä¸çæå端代ç **ï¼åªçæå端èè°æ¹æ¡ææ¡£ï¼è¾åºå° `docs/` ç®å½ã |
| | | |
| | | ## ç¦æ¢å
容 |
| | | |
| | | - â ç¦æ¢å Vue 模æ¿ä»£ç ï¼`<el-table-column>`ã`<el-form-item>` çï¼ |
| | | - â ç¦æ¢å JavaScript/TypeScript 代ç ï¼æ¹æ³ã彿°ãé»è¾å¤æçï¼ |
| | | - â ç¦æ¢å CSS æ ·å¼ä»£ç |
| | | - â ç¦æ¢åå端ç»ä»¶ä½¿ç¨ç¤ºä¾ |
| | | |
| | | ## èè°æ¹æ¡å
å®¹è¦æ± |
| | | |
| | | ææ¡£åºåªå
å«ä»¥ä¸å
å®¹ï¼ |
| | | |
| | | - **API 说æ**ï¼è·¯å¾ãæ¹æ³ã请æ±åæ°ãååºæ ¼å¼ |
| | | - **æ¶åçå端页é¢**ï¼ååºéè¦ä¿®æ¹ç页é¢åç§° |
| | | - **æ°æ®å¸¦å
¥è¯´æ**ï¼éç¹å¼ºè°ä¿¡æ¯å¦ä½ä»ä¸ä¸æ¥å¸¦å
¥ï¼å¦éè´è®¢å -> å°è´§éç¥ -> éè´å
¥åºï¼ |
| | | - **æ¥å£è°ç¨æ¶åº**ï¼è¯´æä½æ¶è°ç¨åªä¸ªæ¥å£è·åå
³èæ°æ® |
| | | - **åæ®µå±ç¤ºè§å**ï¼ç¨è¡¨æ ¼è¯´æå段å±ç¤ºä½ç½®å说æï¼ä¸å代ç |
| | | - **ä¸å¡è§å说æ**ï¼ç¨æåæè¡¨æ ¼è¯´æä¸å¡é»è¾ |
| | | - **注æäºé¡¹**ï¼éè¦å端注æçè¾¹çæ
åµ |
| | | |
| | | ## ææ¡£æ¨¡æ¿ |
| | | |
| | | ```markdown |
| | | # åè½åç§° - å端èè°æ¹æ¡ |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - 页é¢1 |
| | | - 页é¢2 |
| | | |
| | | ## ä¸å¡æµç¨ä¸æ°æ®å¸¦å
¥ |
| | | |
| | | 1. æ¥éª¤1 -> æ¥éª¤2ï¼å段Aãåæ®µB 仿¥éª¤1èªå¨å¸¦å
¥ |
| | | 2. æ¥éª¤2 -> æ¥éª¤3ï¼å段C 仿¥éª¤2èªå¨å¸¦å
¥ |
| | | |
| | | ## API |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | POST | /xxx/xxx | 说æ | |
| | | |
| | | **请æ±åæ°ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | xxx | String | æ¯ | xxx | |
| | | |
| | | **ååºå段æ°å¢ï¼** |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | |------|------|------| |
| | | | xxx | String | xxx | |
| | | |
| | | **ååºç¤ºä¾ï¼** |
| | | |
| | | ```json |
| | | { |
| | | "code": 0, |
| | | "data": {} |
| | | } |
| | | ``` |
| | | |
| | | ## åæ®µå±ç¤ºè§å |
| | | |
| | | | åæ®µ | å±ç¤ºä½ç½® | 说æ | |
| | | |------|----------|------| |
| | | | åæ®µA | å表ã详æ
| 说æ | |
| | | | åæ®µB | 详æ
| 说æ | |
| | | |
| | | ## ä¸å¡è§å说æ |
| | | |
| | | | åºæ¯ | è§å | |
| | | |------|------| |
| | | | åºæ¯1 | è§å说æ | |
| | | | åºæ¯2 | è§å说æ | |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - 注æäºé¡¹1 |
| | | - 注æäºé¡¹2 |
| | | ``` |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # æ¥å£åæ´å端èè°æ¹æ¡è§å |
| | | |
| | | ## è§å |
| | | |
| | | - æ¯æ¬¡æ¶åæ¥å£åæ´ï¼æ°å¢æ¥å£ãä¿®æ¹è¯·æ±åæ°ãä¿®æ¹ååºç»æï¼æ¶ï¼å¿
é¡»è¾åºä¸ä»½**å端èè°æ¹æ¡**å° `docs/` ç®å½ã |
| | | - **ä¸çæå端代ç **ï¼åªçæèè°æ¹æ¡ææ¡£ï¼æå¯¼å端å¼å人åå¦ä½å¯¹æ¥ã |
| | | - ææ¡£ä»¥ Markdown æ ¼å¼ç¼åï¼æä»¶å使ç¨å°å忝åä¸å线ï¼å¦ `docs/purchase_receipt_integration.md`ã |
| | | - ææ¡£å
容éç¹å¼ºè°**ä¿¡æ¯å¸¦å
¥**é®é¢ï¼åªäºæ°æ®ä»ä¸ä¸æ¥èªå¨å¸¦å
¥ã使¶è·åå
³èæ°æ®ãåæ®µå¦ä½æ å°ã |
| | | |
| | | ## ææ¡£æ¨¡æ¿ |
| | | |
| | | ```markdown |
| | | # åè½åç§° |
| | | |
| | | ## æ¶åé¡µé¢ |
| | | |
| | | - 页é¢1 |
| | | - 页é¢2 |
| | | |
| | | ## API |
| | | |
| | | | æ¹æ³ | è·¯å¾ | 说æ | |
| | | |------|------|------| |
| | | | POST | /xxx/xxx | 说æ | |
| | | |
| | | **请æ±åæ°ï¼** |
| | | |
| | | | åæ° | ç±»å | å¿
å¡« | 说æ | |
| | | |------|------|------|------| |
| | | | xxx | String | æ¯ | xxx | |
| | | |
| | | **ååºï¼** `{ "code": 200, "msg": "æä½æå" }` |
| | | |
| | | ## å端修æ¹ç¹ |
| | | |
| | | ### 1. æé®/å¼¹çª/è¡¨æ ¼ç |
| | | |
| | | \`\`\`html |
| | | <el-button>xxx</el-button> |
| | | \`\`\` |
| | | |
| | | ### 2. data æ°æ® |
| | | |
| | | \`\`\`js |
| | | data() { |
| | | return { |
| | | xxx: '', |
| | | } |
| | | } |
| | | \`\`\` |
| | | |
| | | ### 3. æ¹æ³ |
| | | |
| | | \`\`\`js |
| | | handleXxx() { |
| | | // ... |
| | | } |
| | | \`\`\` |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - 注æäºé¡¹1 |
| | | - 注æäºé¡¹2 |
| | | ``` |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # å端项ç®è§å |
| | | |
| | | ## è§å |
| | | |
| | | - `mom-pro2-before` æ¯å端项ç®ï¼ä½äºåç«¯é¡¹ç®æ ¹ç®å½ä¸ï¼`D:\ç马\åé\å端\mom-pro2-after\mom-pro2-before`ï¼ã |
| | | - å¯ä»¥æ¥çå端代ç ä½ä¸ºåèï¼å¸®å©çè§£ä¸å¡é»è¾ã设计åç«¯æ¹æ¡ã |
| | | - **æªç»ç¨æ·æç¡®å
许ï¼ç¦æ¢ä¿®æ¹å端项ç®ä¸ç任使件ã** |
| | | |
| | | ## 使ç¨åºæ¯ |
| | | |
| | | | å
许 | ç¦æ¢ | |
| | | |------|------| |
| | | | 读åå端æä»¶äºè§£ç°æå®ç° | ä¿®æ¹å端代ç | |
| | | | åèå端 API è°ç¨æ¹å¼è®¾è®¡å端æ¥å£ | æ°å¢å端ç»ä»¶/é¡µé¢ | |
| | | | åèåç«¯æ°æ®ç»æçè§£ä¸å¡ | å é¤å端æä»¶ | |
| | | | å¨å端项ç®ä¸æç´¢/æ¥æ¾ä»£ç | éæå端代ç | |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # æ°æ®äº¤æ¥æ¥è¯¢è§å |
| | | |
| | | ## è§å |
| | | |
| | | æææ¨¡å卿¥è¯¢"æçæ°æ®"ï¼æç¨æ· ID è¿æ»¤çä¸å¡æ°æ®åè¡¨ï¼æ¶ï¼**å¿
é¡»è°ç¨ `HrmUserHandoverApi.expandUserIds()`** æ©å±ç¨æ· ID éåï¼ç¡®ä¿äº¤æ¥äººè½æ¥ç已离è交æ¥äººçä¸å¡æ°æ®ã |
| | | |
| | | ## èæ¯ |
| | | |
| | | å½åå·¥ç¦»èæ¶ï¼å
¶ä¸å¡æ°æ®ï¼å®¢æ·ãåæºãå·¥åãéè´ç³è¯·çï¼éè¦äº¤ç±äº¤æ¥äººç®¡çãç³»ç»éè¿ `hrm_user_handover` æ å°è¡¨è®°å½äºç¦»èç¨æ·ä¸äº¤æ¥ç®æ ç¨æ·çå
³èï¼èéç´æ¥ä¿®æ¹ä¸å¡æ°æ®çææè
åæ®µã |
| | | |
| | | æ¥è¯¢æ¶éè¿ `expandUserIds` å°äº¤æ¥æºç¨æ· ID 纳å
¥æ¥è¯¢èå´ï¼ä½¿äº¤æ¥äººè½åæ¶çå°èªå·±å离èäººçæ°æ®ã |
| | | |
| | | ## æ ¸å¿ API |
| | | |
| | | ```java |
| | | // æ¥å£ï¼HrmUserHandoverApi (yudao-module-hrm-api) |
| | | public interface HrmUserHandoverApi { |
| | | Set<Long> expandUserIds(Set<Long> userIds); |
| | | } |
| | | ``` |
| | | |
| | | ## 忍¡åéææ¹å¼ |
| | | |
| | | ### åºæ¬ç¨æ³ |
| | | |
| | | ```java |
| | | // 注å
¥ API |
| | | @Resource |
| | | private HrmUserHandoverApi handoverApi; |
| | | |
| | | // 卿¥è¯¢åæ©å± userId |
| | | public PageResult<XxxDO> getXxxPage(XxxPageReqVO reqVO) { |
| | | Long currentUserId = getCurrentUserId(); |
| | | Set<Long> expandedUserIds = handoverApi.expandUserIds(Set.of(currentUserId)); |
| | | // ç¨ expandedUserIds å IN æ¥è¯¢ |
| | | return mapper.selectPage(reqVO, new LambdaQueryWrapperX<XxxDO>() |
| | | .in(XxxDO::getOwnerUserId, expandedUserIds) |
| | | ...); |
| | | } |
| | | ``` |
| | | |
| | | ### Mapper å±åæ³ |
| | | |
| | | ```java |
| | | // 妿 userId æ¯å¨æä¼ å
¥çï¼å¦ç®¡çå坿¥çææäººçæ°æ®ï¼ï¼å
åå¤æï¼ |
| | | default PageResult<XxxDO> selectPage(XxxPageReqVO reqVO, Set<Long> userIds) { |
| | | return selectPage(reqVO, new LambdaQueryWrapperX<XxxDO>() |
| | | .inIfPresent(XxxDO::getOwnerUserId, CollUtil.isNotEmpty(userIds) ? userIds : null) |
| | | ...); |
| | | } |
| | | ``` |
| | | |
| | | ## 忍¡åæ¶åçæ¥è¯¢åºæ¯ |
| | | |
| | | | 模å | æ¥è¯¢åºæ¯ | æ¶å表 | ç¨æ·å段 | |
| | | |------|----------|--------|----------| |
| | | | CRM | æçå®¢æ· | `crm_customer` | `ownerUserId` | |
| | | | CRM | æç线索 | `crm_clue` | `ownerUserId` | |
| | | | CRM | æçè系人 | `crm_contact` | `ownerUserId` | |
| | | | CRM | æçåå | `crm_contract` | `ownerUserId` | |
| | | | CRM | æçåæº | `crm_business` | `ownerUserId` | |
| | | | CRM | æç忬¾ | `crm_receivable` | `ownerUserId` | |
| | | | CRM | æç忬¾è®¡å | `crm_receivable_plan` | `ownerUserId` | |
| | | | CRM | æçæ¥ä»· | `crm_sale_quotation` | `ownerUserId` | |
| | | | ERP | æçéè´ç³è¯· | `erp_purchase_request` | `requestUserId` | |
| | | | ERP | æçéå®è®¢å | `erp_sale_order` | `saleUserId` | |
| | | | ERP | æç仿¬¾å | `erp_finance_payment` | `financeUserId` | |
| | | | ERP | æçæ¶æ¬¾å | `erp_finance_receipt` | `financeUserId` | |
| | | | MES | æçå·¥å/æ¥å·¥/è´¨æ£ç | å MES 表 | `userId` / `inspectorUserId` / `chargeUserId` ç | |
| | | |
| | | ## expandUserIds åç |
| | | |
| | | ``` |
| | | hrm_user_handover 表记å½: |
| | | ââââââ¬âââââââââââââââ¬âââââââââââââ¬ââââââââââââââââ¬ââââââââââââââââââ |
| | | â id â from_user_id â to_user_id â resignation_idâ handover_status â |
| | | ââââââ¼âââââââââââââââ¼âââââââââââââ¼ââââââââââââââââ¼âââââââââââââââââ⤠|
| | | â 1 â 100(离è人) â 101(交æ¥äºº)â 1 â 20(已宿) â |
| | | ââââââ´âââââââââââââââ´âââââââââââââ´ââââââââââââââââ´ââââââââââââââââââ |
| | | |
| | | expandUserIds({101}) â {101, 100} |
| | | â 交æ¥äºº101æ¥è¯¢æ¶ï¼WHERE owner_user_id IN (101, 100) |
| | | â åæ¶çå°èªå·±çå离èäººçæ°æ® |
| | | ``` |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - `expandUserIds` åªæ©å±**已宿ç交æ¥è®°å½**ï¼`handoverStatus = 20`ï¼ |
| | | - ä¼ å
¥ç©ºéåè¿å空éå |
| | | - æ¥è¯¢æ§è½ï¼æ å°è¡¨æ°æ®éæå°ï¼ä»
为已离èäººåæ°ï¼ï¼å¯æ¾å¿å¨æ¯æ¬¡æ¥è¯¢åè°ç¨ |
| | | - 妿æ¥è¯¢è¦æ±ä¸¥æ ¼åªçæ¬äººæ°æ®ï¼å¦ä¸ªäººè®¾ç½®é¡µï¼ï¼åä¸åºè°ç¨ `expandUserIds` |
| | | |
| | | ## Maven ä¾èµ |
| | | |
| | | éè¦å¨æ¨¡åç `pom.xml` 䏿·»å 对 HRM API çä¾èµï¼ |
| | | |
| | | ```xml |
| | | <dependency> |
| | | <groupId>cn.iocoder.boot</groupId> |
| | | <artifactId>yudao-module-hrm-api</artifactId> |
| | | <version>${revision}</version> |
| | | </dependency> |
| | | ``` |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # PowerShell å½ä»¤è§å |
| | | |
| | | ## è§å |
| | | |
| | | ç±äºé¡¹ç®è¿è¡å¨ Windows ç¯å¢ä¸ï¼ç¨æ·ç»ç«¯é»è®¤ä½¿ç¨ PowerShell èé bashã卿ä¾å½ä»¤è¡æå¯¼æ¶ï¼å¿
é¡»ä½¿ç¨ PowerShell è¯æ³ã |
| | | |
| | | ## 常ç¨å½ä»¤å¯¹ç
§ |
| | | |
| | | | æä½ | Bash | PowerShell | |
| | | |------|------|-------------| |
| | | | å é¤ç®å½ | `rm -rf <path>` | `Remove-Item -Recurse -Force <path>` æç®å `ri -r -fo <path>` | |
| | | | å¤å¶æä»¶ | `cp <src> <dest>` | `Copy-Item <src> <dest>` æç®å `cp <src> <dest>` | |
| | | | ç§»å¨æä»¶ | `mv <src> <dest>` | `Move-Item <src> <dest>` æç®å `mv <src> <dest>` | |
| | | | å建ç®å½ | `mkdir -p <path>` | `New-Item -ItemType Directory -Path <path>` æç®å `md <path>` | |
| | | | æ¥çæä»¶ | `cat <file>` | `Get-Content <file>` æç®å `gc <file>` | |
| | | | ååºæä»¶ | `ls` | `Get-ChildItem` æç®å `ls`/`dir` | |
| | | | æ¥æ¾æä»¶ | `find . -name "*.java"` | `Get-ChildItem -Recurse -Filter "*.java"` æç®å `gci -r -fi "*.java"` | |
| | | | æ¥æ¾å
容 | `grep -r "pattern" .` | `Select-String -Path "*.java" -Pattern "pattern"` æç®å `sls "pattern" *.java -r` | |
| | | |
| | | ## å é¤ç®å½ç¤ºä¾ |
| | | |
| | | ```powershell |
| | | # æ¨èï¼ä½¿ç¨ Remove-Item 宿´å½ä»¤ |
| | | Remove-Item -Recurse -Force yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/client |
| | | |
| | | # ç®åå½¢å¼ |
| | | ri -r -fo yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/md/client |
| | | ``` |
| | | |
| | | ## 注æäºé¡¹ |
| | | |
| | | - PowerShell åæ°ä½¿ç¨ `-` åç¼ï¼å¦ `-Recurse`ã`-Force` |
| | | - åæ°å¯ä»¥ç®åé¦åæ¯ï¼å¦ `-r`ã`-fo` |
| | | - è·¯å¾åéç¬¦å¨ PowerShell ä¸å¯ä»¥ä½¿ç¨ `/` æ `\`ï¼æ¨èä½¿ç¨ `/` ä»¥ä¿æè·¨å¹³å°å
¼å®¹ |
| | | - é¿å
`-rf` è¿æ ·ç bash 飿 ¼åæ°ç»åï¼PowerShell 䏿¯æ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # å®å
¨æ¤æ |
| | | |
| | | ## SQL 注å
¥é²æ¤ |
| | | |
| | | - æ°¸è¿ä¸è¦å°ç¨æ·è¾å
¥ç´æ¥æ¼æ¥å° SQL æ¥è¯¢ä¸ã |
| | | - å§ç»ä½¿ç¨åæ°åæ¥è¯¢æ ORM æ¹æ³ã |
| | | - 卿°æ®åºæä½åéªè¯åæ¸
çææè¾å
¥ã |
| | | |
| | | ## XSS 鲿¤ |
| | | |
| | | - å¨ HTML 䏿¸²æåè½¬ä¹ææç¨æ·çæçå
容ã |
| | | - ä½¿ç¨æ¨¡æ¿èªå¨è½¬ä¹åè½ã |
| | | - å¨å®¢æ·ç«¯åæå¡å¨ç«¯é½è¿è¡è¾å
¥éªè¯åæ¸
çã |
| | | |
| | | ## å¯é¥ç®¡ç |
| | | |
| | | - æ°¸è¿ä¸è¦å¨æºä»£ç ä¸ç¡¬ç¼ç å¯é¥ãAPI å¯é¥æå¯ç ã |
| | | - 使ç¨ç¯å¢åéæå®å
¨ä¿é©åºåå¨æææ°æ®ã |
| | | - å®æè½®æ¢å¯é¥ï¼é¿å
卿¥å¿ä¸è®°å½å®ä»¬ã |
| | | |
| | | ## è¾å
¥éªè¯ |
| | | |
| | | - å¨ç³»ç»è¾¹çå¤éªè¯ææè¾å
¥ã |
| | | - 使ç¨ç½ååèéé»ååè¿è¡éªè¯ã |
| | | - å¨å¤çä¸ä¼ åæ£æ¥æä»¶ç±»åå大å°ã |
| | | |
| | | ## é误å¤ç |
| | | |
| | | - ä¸è¦å¨éè¯¯æ¶æ¯ä¸æ´é²ææä¿¡æ¯ã |
| | | - å¨å
é¨è®°å½è¯¦ç»é误ï¼åç¨æ·è¿åéç¨æ¶æ¯ã |
| | | - å¤çææå¼å¸¸ä»¥é²æ¢ä¿¡æ¯æ³é²ã |
| | | |
| | | ## ä¾èµç®¡ç |
| | | |
| | | - ä¿æä¾èµé¡¹æ´æ°ã |
| | | - 审计ä¾èµé¡¹ä¸çå·²ç¥æ¼æ´ã |
| | | - åºå®çæ¬ä»¥é¿å
æå¤çç ´åæ§åæ´ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | --- |
| | | description: Automatically sync new SQL files to docs/sql and update the index |
| | | --- |
| | | |
| | | # SQL Files Management Rule |
| | | |
| | | **CRITICAL RULE**: Whenever you create or add a new SQL file (e.g. database migrations, init scripts) in this project (such as in `sql/mysql/` or anywhere else), you MUST: |
| | | |
| | | 1. **Copy/Create a duplicate** of that SQL file in the `docs/sql/` directory. |
| | | 2. **Update the SQL Index**: Record the newly added SQL file in `docs/sql/README.md` (create the README file if it does not exist) with a brief description of what the SQL file does. |
| | | |
| | | Always remember this when you are generating new SQL scripts to maintain the project's documentation consistency. |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # SQL èæ¬è§è |
| | | |
| | | ## è§å |
| | | |
| | | - SQL èæ¬ä¸ä¸è¦å
å« tenant_id åæ®µï¼é¡¹ç®ä¸ä½¿ç¨å¤ç§æ·æ¨¡å¼ã |
| | | - INSERT è¯å¥åªå
å«å¿
è¦çä¸å¡å段ï¼ä¸éè¦ tenant_idã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # SQL è¯æ³è§è |
| | | |
| | | ## è§å |
| | | |
| | | - MySQL `ALTER TABLE ADD COLUMN` 䏿¯æ `IF NOT EXISTS` è¯æ³ï¼å³ä½¿ MySQL 8.0+ ä¹ä¸æ¯æã |
| | | - æ·»å åæ®µåéè¦å
æ£æ¥å段æ¯å¦åå¨ï¼æç´æ¥æ§è¡å¹¶å¿½ç¥"åæ®µå·²åå¨"é误ã |
| | | |
| | | ## æ£ç¡®ç¤ºä¾ |
| | | |
| | | ```sql |
| | | -- æ£ç¡®ï¼ç´æ¥æ·»å åæ®µ |
| | | ALTER TABLE mes_wm_sn ADD COLUMN uuid VARCHAR(64) COMMENT 'æ¹æ¬¡UUID' AFTER id; |
| | | |
| | | -- æ£ç¡®ï¼å
æ£æ¥åæ·»å ï¼å
¼å®¹èæ¬ï¼ |
| | | SET @exists = (SELECT COUNT(*) FROM information_schema.columns |
| | | WHERE table_schema = DATABASE() AND table_name = 'mes_wm_sn' AND column_name = 'uuid'); |
| | | SET @sql = IF(@exists = 0, |
| | | 'ALTER TABLE mes_wm_sn ADD COLUMN uuid VARCHAR(64) COMMENT ''æ¹æ¬¡UUID'' AFTER id', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @sql; |
| | | EXECUTE stmt; |
| | | DEALLOCATE PREPARE stmt; |
| | | ``` |
| | | |
| | | ## éè¯¯ç¤ºä¾ |
| | | |
| | | ```sql |
| | | -- é误ï¼ADD COLUMN 䏿¯æ IF NOT EXISTS |
| | | ALTER TABLE mes_wm_sn ADD COLUMN IF NOT EXISTS uuid VARCHAR(64) COMMENT 'æ¹æ¬¡UUID' AFTER id; |
| | | ``` |
| | | |
| | | ## IF NOT EXISTS æ¯æåºæ¯ |
| | | |
| | | | è¯å¥ | æ¯å¦æ¯æ | |
| | | |------|---------| |
| | | | CREATE TABLE IF NOT EXISTS | â
æ¯æ | |
| | | | CREATE INDEX IF NOT EXISTS | â
æ¯æï¼MySQL 8.0+ï¼ | |
| | | | ALTER TABLE ADD COLUMN IF NOT EXISTS | â 䏿¯æ | |
| | | | ALTER TABLE ADD INDEX IF NOT EXISTS | â
æ¯æï¼MySQL 8.0+ï¼ | |
| | | | ALTER TABLE ADD CONSTRAINT IF NOT EXISTS | â 䏿¯æ | |
| | |
| | | .claude/settings.local.json |
| | | .claude/worktrees/ |
| | | .claude/scheduled_tasks.json |
| | | |
| | | graphify-out/ |
| | | .agents/ |
| | |
| | | DROP TABLE IF EXISTS `mes_pro_feedback`; |
| | | CREATE TABLE `mes_pro_feedback` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'æ¥å·¥åç¼å·', |
| | | `type` int NULL DEFAULT NULL COMMENT 'æ¥å·¥ç±»å', |
| | | `channel` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'æ¥å·¥éå¾', |
| | | `feedback_time` datetime NULL DEFAULT NULL COMMENT 'æ¥å·¥æ¶é´', |
| | | `workstation_id` bigint NULL DEFAULT NULL COMMENT 'å·¥ä½ç«ç¼å·', |
| | | `route_id` bigint NULL DEFAULT NULL COMMENT 'å·¥èºè·¯çº¿ç¼å·', |
| | | `process_id` bigint NULL DEFAULT NULL COMMENT 'å·¥åºç¼å·', |
| | | `work_order_id` bigint NULL DEFAULT NULL COMMENT 'ç产工åç¼å·', |
| | | `task_id` bigint NULL DEFAULT NULL COMMENT 'ç产任å¡ç¼å·', |
| | | `item_id` bigint NULL DEFAULT NULL COMMENT '产åç©æç¼å·', |
| | | `expire_date` datetime NULL DEFAULT NULL COMMENT 'è¿ææ¥æ', |
| | | `lot_number` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'ç产æ¹å·', |
| | | `scheduled_quantity` decimal(24, 6) NULL DEFAULT NULL COMMENT 'æäº§æ°é', |
| | | `feedback_quantity` decimal(24, 6) NULL DEFAULT NULL COMMENT 'æ¬æ¬¡æ¥å·¥æ°é', |
| | | `qualified_quantity` decimal(24, 6) NULL DEFAULT NULL COMMENT 'åæ ¼åæ°é', |
| | | `unqualified_quantity` decimal(24, 6) NULL DEFAULT NULL COMMENT 'ä¸è¯åæ°é', |
| | | `uncheck_quantity` decimal(24, 6) NULL DEFAULT NULL COMMENT 'å¾
æ£æµæ°é', |
| | | `labor_scrap_quantity` decimal(24, 6) NULL DEFAULT NULL COMMENT 'å·¥åºæ°é', |
| | | `material_scrap_quantity` decimal(24, 6) NULL DEFAULT NULL COMMENT 'æåºæ°é', |
| | | `other_scrap_quantity` decimal(24, 6) NULL DEFAULT NULL COMMENT 'å
¶ä»åºåæ°é', |
| | | `feedback_user_id` bigint NULL DEFAULT NULL COMMENT 'æ¥å·¥ç¨æ·ç¼å·', |
| | | `approve_user_id` bigint NULL DEFAULT NULL COMMENT 'å®¡æ ¸ç¨æ·ç¼å·', |
| | | `status` int NULL DEFAULT NULL COMMENT 'ç¶æ', |
| | | `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT 'å建è
', |
| | | `code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'æ¥å·¥åç¼å·', |
| | | `type` int DEFAULT NULL COMMENT 'æ¥å·¥ç±»å', |
| | | `channel` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'æ¥å·¥éå¾', |
| | | `feedback_time` datetime DEFAULT NULL COMMENT 'æ¥å·¥æ¶é´', |
| | | `workstation_id` bigint DEFAULT NULL COMMENT 'å·¥ä½ç«ç¼å·', |
| | | `route_id` bigint DEFAULT NULL COMMENT 'å·¥èºè·¯çº¿ç¼å·', |
| | | `process_id` bigint DEFAULT NULL COMMENT 'å·¥åºç¼å·', |
| | | `work_order_id` bigint DEFAULT NULL COMMENT 'ç产工åç¼å·', |
| | | `task_id` bigint DEFAULT NULL COMMENT 'ç产任å¡ç¼å·', |
| | | `item_id` bigint DEFAULT NULL COMMENT '产åç©æç¼å·', |
| | | `expire_date` datetime DEFAULT NULL COMMENT 'è¿ææ¥æ', |
| | | `lot_number` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'ç产æ¹å·', |
| | | `scheduled_quantity` decimal(24,6) DEFAULT NULL COMMENT 'æäº§æ°é', |
| | | `feedback_quantity` decimal(24,6) DEFAULT NULL COMMENT 'æ¬æ¬¡æ¥å·¥æ°é', |
| | | `qualified_quantity` decimal(24,6) DEFAULT NULL COMMENT 'åæ ¼åæ°é', |
| | | `unqualified_quantity` decimal(24,6) DEFAULT NULL COMMENT 'ä¸è¯åæ°é', |
| | | `uncheck_quantity` decimal(24,6) DEFAULT NULL COMMENT 'å¾
æ£æµæ°é', |
| | | `labor_scrap_quantity` decimal(24,6) DEFAULT NULL COMMENT 'å·¥åºæ°é', |
| | | `material_scrap_quantity` decimal(24,6) DEFAULT NULL COMMENT 'æåºæ°é', |
| | | `other_scrap_quantity` decimal(24,6) DEFAULT NULL COMMENT 'å
¶ä»åºåæ°é', |
| | | `feedback_user_id` bigint DEFAULT NULL COMMENT 'æ¥å·¥ç¨æ·ç¼å·', |
| | | `approve_user_id` bigint DEFAULT NULL COMMENT 'å®¡æ ¸ç¨æ·ç¼å·', |
| | | `status` int DEFAULT NULL COMMENT 'ç¶æ', |
| | | `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | PRIMARY KEY (`id`) USING BTREE |
| | | ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MES ç产æ¥å·¥' ROW_FORMAT = Dynamic; |
| | | |
| | | `process_instance_id` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'BPM æµç¨å®ä¾ç¼å·', |
| | | `process_definition_key` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'BPM æµç¨å®ä¹ Key', |
| | | PRIMARY KEY (`id`) USING BTREE, |
| | | ) ENGINE=InnoDB AUTO_INCREMENT=79 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='MES ç产æ¥å·¥'; |
| | | -- ---------------------------- |
| | | -- Records of mes_pro_feedback |
| | | -- ---------------------------- |
| | |
| | | DROP TABLE IF EXISTS `mes_pro_work_order`; |
| | | CREATE TABLE `mes_pro_work_order` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'å·¥åç¼ç ', |
| | | `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'å·¥ååç§°', |
| | | `type` int NULL DEFAULT NULL COMMENT 'å·¥åç±»å', |
| | | `order_source_type` int NULL DEFAULT NULL COMMENT 'æ¥æºç±»å', |
| | | `order_source_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'æ¥æºåæ®ç¼å·', |
| | | `product_id` bigint NULL DEFAULT NULL COMMENT '产åç¼å·', |
| | | `quantity` decimal(24, 6) NULL DEFAULT NULL COMMENT 'ç产æ°é', |
| | | `quantity_produced` decimal(24, 6) NULL DEFAULT NULL COMMENT 'å·²ç产æ°é', |
| | | `quantity_changed` decimal(24, 6) NULL DEFAULT NULL COMMENT 'è°æ´æ°é', |
| | | `quantity_scheduled` decimal(24, 6) NULL DEFAULT NULL COMMENT 'å·²æäº§æ°é', |
| | | `client_id` bigint NULL DEFAULT NULL COMMENT '客æ·ç¼å·', |
| | | `vendor_id` bigint NULL DEFAULT NULL COMMENT 'ä¾åºåç¼å·', |
| | | `batch_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'æ¹æ¬¡å·', |
| | | `request_date` datetime NULL DEFAULT NULL COMMENT 'éæ±æ¥æ', |
| | | `parent_id` bigint NULL DEFAULT NULL COMMENT 'ç¶å·¥åç¼å·', |
| | | `finish_date` datetime NULL DEFAULT NULL COMMENT '宿æ¶é´', |
| | | `cancel_date` datetime NULL DEFAULT NULL COMMENT 'åæ¶æ¶é´', |
| | | `status` int NULL DEFAULT NULL COMMENT 'å·¥åç¶æ', |
| | | `process_instance_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT 'BPM æµç¨å®ä¾ç¼å·', |
| | | `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT 'å建è
', |
| | | `code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'å·¥åç¼ç ', |
| | | `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'å·¥ååç§°', |
| | | `type` int DEFAULT NULL COMMENT 'å·¥åç±»å', |
| | | `order_source_type` int DEFAULT NULL COMMENT 'æ¥æºç±»å', |
| | | `order_source_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'æ¥æºåæ®ç¼å·', |
| | | `product_id` bigint DEFAULT NULL COMMENT '产åç¼å·', |
| | | `quantity` decimal(24,6) DEFAULT NULL COMMENT 'ç产æ°é', |
| | | `quantity_produced` decimal(24,6) DEFAULT NULL COMMENT 'å·²ç产æ°é', |
| | | `quantity_changed` decimal(24,6) DEFAULT NULL COMMENT 'è°æ´æ°é', |
| | | `quantity_scheduled` decimal(24,6) DEFAULT NULL COMMENT 'å·²æäº§æ°é', |
| | | `client_id` bigint DEFAULT NULL COMMENT '客æ·ç¼å·', |
| | | `vendor_id` bigint DEFAULT NULL COMMENT 'ä¾åºåç¼å·', |
| | | `batch_code` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'æ¹æ¬¡å·', |
| | | `route_id` bigint DEFAULT NULL COMMENT 'å·¥èºè·¯çº¿ç¼å·', |
| | | `auto_finish_flag` tinyint(1) DEFAULT '1' COMMENT 'æ¯å¦èªå¨å®æ', |
| | | `request_date` datetime DEFAULT NULL COMMENT 'éæ±æ¥æ', |
| | | `parent_id` bigint DEFAULT NULL COMMENT 'ç¶å·¥åç¼å·', |
| | | `finish_date` datetime DEFAULT NULL COMMENT '宿æ¶é´', |
| | | `cancel_date` datetime DEFAULT NULL COMMENT 'åæ¶æ¶é´', |
| | | `status` int DEFAULT NULL COMMENT 'å·¥åç¶æ', |
| | | `process_instance_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'BPM æµç¨å®ä¾ç¼å·', |
| | | `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '夿³¨', |
| | | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | `is_feedback_approve` tinyint(1) DEFAULT NULL COMMENT 'æ¯å¦å¼å¯æ¥å·¥å®¡æ¹ (1: å¼å¯, 0/NULL: å
³é)', |
| | | `process_definition_key` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'BPM æµç¨å®ä¹ Key', |
| | | `feedback_role` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'æ¥å·¥è§è² (å¤ä¸ªè§è²ä»¥éå·åé)', |
| | | PRIMARY KEY (`id`) USING BTREE |
| | | ) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'MES ç产工å' ROW_FORMAT = Dynamic; |
| | | |
| | | ) ENGINE=InnoDB AUTO_INCREMENT=62 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=DYNAMIC COMMENT='MES ç产工å'; |
| | | -- ---------------------------- |
| | | -- Records of mes_pro_work_order |
| | | -- ---------------------------- |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # SQL èæ¬ç´¢å¼ |
| | | |
| | | æ¬é¡¹ç®å
å«ç SQL èæ¬æ±æ»å¦ä¸ï¼ |
| | | |
| | | - [mes_pro_task_assignee.sql](mes_pro_task_assignee.sql): å¢å çäº§ä»»å¡æ¥å·¥äººåå
³è表ï¼ç¨äºå¤äººåæ¥å·¥åé
ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | CREATE TABLE `mes_pro_task_assignee` ( |
| | | `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `task_id` bigint(20) NOT NULL COMMENT 'çäº§ä»»å¡ ID', |
| | | `user_id` bigint(20) NOT NULL COMMENT 'ç³»ç»ç¨æ· ID (æå®æ¥å·¥äººå)', |
| | | `creator` varchar(64) DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | `tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT 'ç§æ·ç¼å·', |
| | | PRIMARY KEY (`id`), |
| | | KEY `idx_task_id` (`task_id`), |
| | | KEY `idx_user_id` (`user_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='çäº§ä»»å¡æå®æ¥å·¥äººå表'; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | CREATE TABLE `mes_pro_task_assignee` ( |
| | | `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ç¼å·', |
| | | `task_id` bigint(20) NOT NULL COMMENT 'çäº§ä»»å¡ ID', |
| | | `user_id` bigint(20) NOT NULL COMMENT 'ç³»ç»ç¨æ· ID (æå®æ¥å·¥äººå)', |
| | | `creator` varchar(64) DEFAULT '' COMMENT 'å建è
', |
| | | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'å建æ¶é´', |
| | | `updater` varchar(64) DEFAULT '' COMMENT 'æ´æ°è
', |
| | | `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'æ´æ°æ¶é´', |
| | | `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT 'æ¯å¦å é¤', |
| | | `tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT 'ç§æ·ç¼å·', |
| | | PRIMARY KEY (`id`), |
| | | KEY `idx_task_id` (`task_id`), |
| | | KEY `idx_user_id` (`user_id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='çäº§ä»»å¡æå®æ¥å·¥äººå表'; |
| | |
| | | |
| | | public static final String INFO_KEY_NICKNAME = "nickname"; |
| | | public static final String INFO_KEY_DEPT_ID = "deptId"; |
| | | public static final String INFO_KEY_ROLE_CODES = "roleCodes"; |
| | | |
| | | /** |
| | | * ç¨æ·ç¼å· |
| | |
| | | } |
| | | |
| | | /** |
| | | * è·å¾å½åç¨æ·çè§è²ç¼ç å表ï¼ä»ä¸ä¸æä¸ |
| | | * |
| | | * @return è§è²ç¼ç å表 |
| | | */ |
| | | public static java.util.List<String> getLoginUserRoleCodeList() { |
| | | LoginUser loginUser = getLoginUser(); |
| | | if (loginUser == null || loginUser.getInfo() == null) { |
| | | return Collections.emptyList(); |
| | | } |
| | | String roleCodes = loginUser.getInfo().get(LoginUser.INFO_KEY_ROLE_CODES); |
| | | return StrUtil.isNotEmpty(roleCodes) ? StrUtil.split(roleCodes, ",") : Collections.emptyList(); |
| | | } |
| | | |
| | | /** |
| | | * 夿å½åç¨æ·æ¯å¦ä¸ºè¶
级管çå |
| | | * |
| | | * @return æ¯å¦ä¸ºè¶
级管çå |
| | | */ |
| | | public static boolean isSuperAdmin() { |
| | | return getLoginUserRoleCodeList().contains("super_admin"); |
| | | } |
| | | |
| | | /** |
| | | * 设置å½åç¨æ· |
| | | * |
| | | * @param loginUser ç»å½ç¨æ· |
| | |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackQuickCreateRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackRespVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.MesProFeedbackSubmitReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; |
| | |
| | | |
| | | @PutMapping("/submit") |
| | | @Operation(summary = "æäº¤æ¥å·¥") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true) |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-feedback:update')") |
| | | public CommonResult<Boolean> submitFeedback(@RequestParam("id") Long id) { |
| | | feedbackService.submitFeedback(id); |
| | | public CommonResult<Boolean> submitFeedback(@Valid @RequestBody MesProFeedbackSubmitReqVO reqVO) { |
| | | feedbackService.submitFeedback(reqVO); |
| | | return success(true); |
| | | } |
| | | |
| | |
| | | @ExcelProperty("å建æ¶é´") |
| | | private LocalDateTime createTime; |
| | | |
| | | @Schema(description = "BPM æµç¨å®ä¾ç¼å·") |
| | | @ExcelProperty("BPM æµç¨å®ä¾ç¼å·") |
| | | private String processInstanceId; |
| | | |
| | | @Schema(description = "BPM æµç¨å®ä¹ Key") |
| | | @ExcelProperty("BPM æµç¨å®ä¹ Key") |
| | | private String processDefinitionKey; |
| | | |
| | | } |
| | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "BPM æµç¨å®ä¾ç¼å·") |
| | | private String processInstanceId; |
| | | |
| | | @Schema(description = "BPM æµç¨å®ä¹ Key") |
| | | private String processDefinitionKey; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo; |
| | | |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import jakarta.validation.constraints.NotNull; |
| | | import lombok.Data; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | @Schema(description = "管çåå° - MES ç产æ¥å·¥æäº¤ Request VO") |
| | | @Data |
| | | public class MesProFeedbackSubmitReqVO { |
| | | |
| | | @Schema(description = "æ¥å·¥åç¼å·", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") |
| | | @NotNull(message = "æ¥å·¥åIDä¸è½ä¸ºç©º") |
| | | private Long id; |
| | | |
| | | @Schema(description = "çäº§æ¥æ") |
| | | private LocalDateTime produceDate; |
| | | |
| | | @Schema(description = "è¿ææ¥æ") |
| | | private LocalDateTime expireDate; |
| | | |
| | | @Schema(description = "å
¥åºæ¥æ") |
| | | private LocalDateTime receiptDate; |
| | | |
| | | @Schema(description = "ä¾åºåID") |
| | | private Long vendorId; |
| | | |
| | | @Schema(description = "客æ·ID") |
| | | private Long clientId; |
| | | |
| | | @Schema(description = "éè´è®¢åç¼å·") |
| | | private String purchaseOrderCode; |
| | | |
| | | @Schema(description = "éå®è®¢åç¼å·") |
| | | private String salesOrderCode; |
| | | |
| | | @Schema(description = "å·¥å
·ID") |
| | | private Long toolId; |
| | | |
| | | @Schema(description = "模å
·ID") |
| | | private Long moldId; |
| | | |
| | | @Schema(description = "ç产æ¹å·") |
| | | private String lotNumber; |
| | | |
| | | @Schema(description = "è´¨éç¶æ") |
| | | private Integer qualityStatus; |
| | | |
| | | } |
| | |
| | | private MesProTaskPauseRecordMapper pauseRecordMapper; |
| | | @Resource |
| | | private AdminUserApi adminUserApi; |
| | | @Resource |
| | | private cn.iocoder.yudao.module.system.api.permission.PermissionApi permissionApi; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "å建ç产任å¡") |
| | |
| | | @Operation(summary = "è·å¾å¾
æ¥å·¥å°è´¦å页", description = "å·²æäº§ä¸ä»æå¾
æ¥å·¥æ°éçä»»å¡ï¼ç¶æ=è¿è¡ä¸ï¼") |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-task:query')") |
| | | public CommonResult<PageResult<MesProTaskRespVO>> getPendingFeedbackPage(@Valid MesProTaskPageReqVO pageReqVO) { |
| | | Long loginUserId = cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId(); |
| | | // 妿å½åç»å½äººä¸æ¯è¶
级管çåï¼åä»
æ¥è¯¢åé
ç»èªå·±çç产工å |
| | | if (loginUserId != null && !permissionApi.hasAnyRoles(loginUserId, cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum.SUPER_ADMIN.getCode())) { |
| | | pageReqVO.setAssigneeUserId(loginUserId); |
| | | } |
| | | PageResult<MesProTaskDO> pageResult = taskService.getPendingFeedbackPage(pageReqVO); |
| | | List<MesProTaskRespVO> respVOList = buildTaskRespVOList(pageResult.getList()); |
| | | |
| | |
| | | inTransitMap.merge(fb.getTaskId(), fbQty, BigDecimal::add); |
| | | } |
| | | } |
| | | |
| | | // æ¥è¯¢ææ´¾æ¥å·¥äººå |
| | | Set<Long> taskIds = convertSet(list, MesProTaskDO::getId); |
| | | Map<Long, List<cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskAssigneeDO>> assigneeMap = taskService.getTaskAssigneeMap(taskIds); |
| | | Set<Long> allAssigneeUserIds = new HashSet<>(); |
| | | assigneeMap.values().forEach(assignees -> |
| | | assignees.forEach(assignee -> allAssigneeUserIds.add(assignee.getUserId()))); |
| | | Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(allAssigneeUserIds); |
| | | |
| | | // æ¼æ¥ VO |
| | | return convertList(list, task -> { |
| | | MesProTaskRespVO vo = BeanUtils.toBean(task, MesProTaskRespVO.class); |
| | |
| | | findAndThen(processCheckMap, task.getProcessId(), vo::setCheckFlag)); |
| | | findAndThen(routeProcessBackflushFlagMap, task.getRouteId(), processBackflushMap -> |
| | | findAndThen(processBackflushMap, task.getProcessId(), vo::setBackflushFlag)); |
| | | |
| | | // è®¾ç½®ææ´¾æ¥å·¥äººå |
| | | List<cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskAssigneeDO> assignees = assigneeMap.get(task.getId()); |
| | | if (CollUtil.isNotEmpty(assignees)) { |
| | | List<Long> assigneeUserIds = convertList(assignees, cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskAssigneeDO::getUserId); |
| | | vo.setAssigneeUserIds(assigneeUserIds); |
| | | List<String> assigneeUserNames = new ArrayList<>(); |
| | | for (Long userId : assigneeUserIds) { |
| | | AdminUserRespDTO user = userMap.get(userId); |
| | | if (user != null && user.getNickname() != null) { |
| | | assigneeUserNames.add(user.getNickname()); |
| | | } |
| | | } |
| | | vo.setAssigneeUserNames(assigneeUserNames); |
| | | } |
| | | |
| | | return vo; |
| | | }); |
| | | } |
| | |
| | | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| | | private LocalDateTime[] createTime; |
| | | |
| | | @Schema(description = "å¤çäººç¨æ·ç¼å·", example = "1024") |
| | | private Long assigneeUserId; |
| | | |
| | | } |
| | |
| | | @Schema(description = "åå·¥åå²è®°å½") |
| | | private List<MesProTaskPauseRecordRespVO> pauseRecords; |
| | | |
| | | @Schema(description = "æå®æ¥å·¥äººå ID éå") |
| | | private List<Long> assigneeUserIds; |
| | | |
| | | @Schema(description = "æå®æ¥å·¥äººåå§åéå") |
| | | private List<String> assigneeUserNames; |
| | | |
| | | @Schema(description = "æ¯å¦æ¥å·¥å®¡æ¹") |
| | | private Boolean feedbackApprove; |
| | | } |
| | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "æå®æ¥å·¥äººå ID éå") |
| | | private java.util.List<Long> assigneeUserIds; |
| | | |
| | | } |
| | |
| | | return success(new PageResult<>(buildWorkOrderRespVOList(pageResult.getList()), pageResult.getTotal())); |
| | | } |
| | | |
| | | @GetMapping("/approve-process-list") |
| | | @Operation(summary = "è·åå®¡æ¹æ¥å·¥çæµç¨å®ä¹å表") |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-work-order:query')") |
| | | public CommonResult<List<Map<String, Object>>> getWorkOrderApproveProcessDefinitionList() { |
| | | return success(workOrderService.getWorkOrderApproveProcessDefinitionList()); |
| | | } |
| | | |
| | | @GetMapping("/schedule-page") |
| | | @Operation(summary = "è·å¾ç产工åè°åº¦ç¶æå页") |
| | | @PreAuthorize("@ss.hasPermission('mes:pro-work-order:query')") |
| | |
| | | @ExcelProperty("çäº§ç¶æ") |
| | | private Integer productionStatus; |
| | | |
| | | @Schema(description = "æ¯å¦æ¥å·¥å®¡æ¹") |
| | | @ExcelProperty("æ¯å¦æ¥å·¥å®¡æ¹") |
| | | private Boolean feedbackApprove; |
| | | |
| | | @Schema(description = "BPM æµç¨å®ä¹ Key") |
| | | @ExcelProperty("BPM æµç¨å®ä¹ Key") |
| | | private String processDefinitionKey; |
| | | |
| | | @Schema(description = "æ¥å·¥è§è² (å¤ä¸ªè§è²éå·åé)") |
| | | @ExcelProperty("æ¥å·¥è§è²") |
| | | private String feedbackRole; |
| | | |
| | | } |
| | |
| | | @Schema(description = "夿³¨", example = "夿³¨") |
| | | private String remark; |
| | | |
| | | @Schema(description = "æ¯å¦æ¥å·¥å®¡æ¹") |
| | | private Boolean feedbackApprove; |
| | | |
| | | @Schema(description = "BPM æµç¨å®ä¹ Key") |
| | | private String processDefinitionKey; |
| | | |
| | | @Schema(description = "æ¥å·¥è§è² (å¤ä¸ªè§è²éå·åé)") |
| | | private String feedbackRole; |
| | | |
| | | } |
| | |
| | | */ |
| | | private String remark; |
| | | |
| | | /** |
| | | * BPM æµç¨å®ä¾ç¼å· |
| | | */ |
| | | private String processInstanceId; |
| | | |
| | | /** |
| | | * BPM æµç¨å®ä¹ Key |
| | | */ |
| | | private String processDefinitionKey; |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.dataobject.pro.task; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import lombok.*; |
| | | |
| | | /** |
| | | * çäº§ä»»å¡æå®æ¥å·¥äººå表 DO |
| | | * |
| | | * @author èªå¨çæ |
| | | */ |
| | | @TableName("mes_pro_task_assignee") |
| | | @KeySequence("mes_pro_task_assignee_seq") |
| | | @Data |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @ToString(callSuper = true) |
| | | @Builder |
| | | @NoArgsConstructor |
| | | @AllArgsConstructor |
| | | public class MesProTaskAssigneeDO extends BaseDO { |
| | | |
| | | /** |
| | | * ç¼å· |
| | | */ |
| | | @TableId |
| | | private Long id; |
| | | /** |
| | | * çäº§ä»»å¡ ID |
| | | * |
| | | * å
³è {@link MesProTaskDO#getId()} |
| | | */ |
| | | private Long taskId; |
| | | /** |
| | | * ç³»ç»ç¨æ· ID (æå®æ¥å·¥äººå) |
| | | */ |
| | | private Long userId; |
| | | |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.annotation.KeySequence; |
| | | import com.baomidou.mybatisplus.annotation.TableId; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.*; |
| | | |
| | | import java.math.BigDecimal; |
| | |
| | | */ |
| | | private String remark; |
| | | |
| | | /** |
| | | * æ¯å¦æ¥å·¥å®¡æ¹ |
| | | */ |
| | | @com.baomidou.mybatisplus.annotation.TableField("is_feedback_approve") |
| | | private Boolean feedbackApprove; |
| | | |
| | | /** |
| | | * BPM æµç¨å®ä¹ Key |
| | | */ |
| | | private String processDefinitionKey; |
| | | |
| | | /** |
| | | * æ¥å·¥è§è² (å¤ä¸ªè§è²éå·åé) |
| | | */ |
| | | private String feedbackRole; |
| | | |
| | | |
| | | } |
| | |
| | | .orderByDesc(MesProMpsDO::getId); |
| | | if (permittedClientIds != null) { |
| | | if (CollUtil.isEmpty(permittedClientIds)) { |
| | | return PageResult.empty(); |
| | | wrapper.isNull(MesProMpsDO::getClientId); |
| | | } else { |
| | | wrapper.and(w -> w.in(MesProMpsDO::getClientId, permittedClientIds) |
| | | .or().isNull(MesProMpsDO::getClientId)); |
| | | } |
| | | wrapper.in(MesProMpsDO::getClientId, permittedClientIds); |
| | | } |
| | | return selectPage(reqVO, wrapper); |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.dal.mysql.pro.task; |
| | | |
| | | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskAssigneeDO; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * çäº§ä»»å¡æå®æ¥å·¥äººå Mapper |
| | | * |
| | | * @author èªå¨çæ |
| | | */ |
| | | @Mapper |
| | | public interface MesProTaskAssigneeMapper extends BaseMapperX<MesProTaskAssigneeDO> { |
| | | |
| | | default List<MesProTaskAssigneeDO> selectListByTaskId(Long taskId) { |
| | | return selectList(MesProTaskAssigneeDO::getTaskId, taskId); |
| | | } |
| | | |
| | | default List<MesProTaskAssigneeDO> selectListByTaskIds(Collection<Long> taskIds) { |
| | | return selectList(new LambdaQueryWrapperX<MesProTaskAssigneeDO>() |
| | | .inIfPresent(MesProTaskAssigneeDO::getTaskId, taskIds)); |
| | | } |
| | | |
| | | default void deleteByTaskId(Long taskId) { |
| | | delete(MesProTaskAssigneeDO::getTaskId, taskId); |
| | | } |
| | | |
| | | default void deleteByTaskIdAndUserIds(Long taskId, Collection<Long> userIds) { |
| | | delete(new LambdaQueryWrapperX<MesProTaskAssigneeDO>() |
| | | .eq(MesProTaskAssigneeDO::getTaskId, taskId) |
| | | .in(MesProTaskAssigneeDO::getUserId, userIds)); |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.route.MesProRouteProcessDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskAssigneeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; |
| | | import cn.iocoder.yudao.module.mes.enums.pro.MesProTaskStatusEnum; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | |
| | | default PageResult<MesProTaskDO> selectPendingFeedbackPage(MesProTaskPageReqVO reqVO) { |
| | | MPJLambdaWrapperX<MesProTaskDO> query = new MPJLambdaWrapperX<>(); |
| | | query.selectAll(MesProTaskDO.class); |
| | | // å½éè¦æ assigneeUserId è¿æ»¤æ¶ï¼INNER JOIN mes_pro_task_assignee |
| | | if (reqVO.getAssigneeUserId() != null) { |
| | | query.innerJoin(MesProTaskAssigneeDO.class, on -> on |
| | | .eq(MesProTaskAssigneeDO::getTaskId, MesProTaskDO::getId)); |
| | | query.eq(MesProTaskAssigneeDO::getUserId, reqVO.getAssigneeUserId()); |
| | | } |
| | | // å¾
æ¥å·¥å°è´¦ï¼è¿è¡ä¸çä»»å¡ï¼æé¤å·²å®æ/已忶ï¼ï¼ä¸ä»æå¾
æ¥å·¥é |
| | | query.in(MesProTaskDO::getStatus, MesProTaskStatusEnum.PREPARE.getStatus(),MesProTaskStatusEnum.PAUSED.getStatus()); |
| | | query.apply("(quantity - IFNULL(produced_quantity, 0)) > 0"); |
| | |
| | | ErrorCode MD_ITEM_BATCH_CONFIG_NOT_EXISTS = new ErrorCode(1_040_102_100, "ç©ææ¹æ¬¡å±æ§é
ç½®ä¸åå¨"); |
| | | ErrorCode MD_ITEM_BATCH_CONFIG_AT_LEAST_ONE_FLAG = new ErrorCode(1_040_102_101, "æ¹æ¬¡ç®¡çå·²å¯ç¨ï¼è³å°éè¦é
ç½®ä¸ä¸ªæ¹æ¬¡å±æ§"); |
| | | ErrorCode MD_ITEM_PRODUCT_BOM_REQUIRED = new ErrorCode(1_040_102_102, "产åç±»ç©æå¯ç¨åï¼å¿
é¡»é
ç½®è³å°ä¸ä¸ª BOM ç»æ"); |
| | | ErrorCode MD_ITEM_BATCH_CONFIG_AT_LEAST_ONE_APPROVE_FLAG = new ErrorCode(1_040_102_103, "éè¦é
ç½®ä¸ä¸ªæ¹æ¬¡å±æ§,请å¨å®¡æ¹æè§ä¸å¡«å"); |
| | | |
| | | // ========== MES ä»åºç®¡ç-æ¹æ¬¡ç®¡çï¼1-040-717-000ï¼ ========== |
| | | ErrorCode WM_BATCH_PRODUCE_DATE_REQUIRED = new ErrorCode(1_040_717_000, "æ¹æ¬¡é
ç½®è¦æ±çäº§æ¥æä¸è½ä¸ºç©º"); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.common.bpm; |
| | | |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * MES 模åçéç¨ BPM æµç¨å¤ç Service æ¥å£ |
| | | */ |
| | | public interface MesBpmProcessService { |
| | | |
| | | /** |
| | | * è·åæå®åç±»ä¸çæ¿æ´»ç¶æãææ°çæ¬çæµç¨å®ä¹å表 |
| | | * |
| | | * @param categoryCode æµç¨åç±»ç¼ç |
| | | * @return æµç¨å®ä¹å表ï¼å
å« id, key, name |
| | | */ |
| | | List<Map<String, Object>> getApproveProcessDefinitionList(String categoryCode); |
| | | |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.common.bpm; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; |
| | | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; |
| | | import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService; |
| | | import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.flowable.engine.repository.ProcessDefinition; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.validation.annotation.Validated; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * MES 模åçéç¨ BPM æµç¨å¤ç Service å®ç°ç±» |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @Slf4j |
| | | public class MesBpmProcessServiceImpl implements MesBpmProcessService { |
| | | |
| | | @Resource |
| | | private BpmCategoryService bpmCategoryService; |
| | | @Resource |
| | | private BpmProcessDefinitionService bpmProcessDefinitionService; |
| | | |
| | | @Override |
| | | public List<Map<String, Object>> getApproveProcessDefinitionList(String categoryCode) { |
| | | // 1. æ ¡éªåç±»æ¯å¦åå¨ |
| | | List<BpmCategoryDO> categories = bpmCategoryService.getCategoryListByCode( |
| | | Collections.singletonList(categoryCode)); |
| | | if (CollUtil.isEmpty(categories)) { |
| | | log.warn("[getApproveProcessDefinitionList] BPM æµç¨åç±» {} ä¸åå¨", categoryCode); |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | // 2. è·ååç±»ä¸çæµç¨å®ä¹ä¿¡æ¯ |
| | | List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService |
| | | .getProcessDefinitionInfoListByCategory(categoryCode); |
| | | if (CollUtil.isEmpty(definitionInfoList)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | // 3. è¿æ»¤æ¿æ´»ç¶æï¼ä¿çææ°çæ¬ |
| | | Map<String, ProcessDefinition> latestVersionMap = new HashMap<>(); |
| | | for (BpmProcessDefinitionInfoDO info : definitionInfoList) { |
| | | ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId()); |
| | | if (pd == null || pd.isSuspended()) { |
| | | continue; |
| | | } |
| | | ProcessDefinition existing = latestVersionMap.get(pd.getKey()); |
| | | if (existing == null || pd.getVersion() > existing.getVersion()) { |
| | | latestVersionMap.put(pd.getKey(), pd); |
| | | } |
| | | } |
| | | |
| | | // 4. è¿åæµç¨å®ä¹å表 |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | for (ProcessDefinition pd : latestVersionMap.values()) { |
| | | Map<String, Object> item = new HashMap<>(); |
| | | item.put("id", pd.getId()); |
| | | item.put("key", pd.getKey()); |
| | | item.put("name", pd.getName()); |
| | | result.add(item); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; |
| | | import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; |
| | | import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum; |
| | | import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService; |
| | | import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService; |
| | | import cn.iocoder.yudao.module.mes.service.common.bpm.MesBpmProcessService; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectPageReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pd.project.vo.MesPdProjectSaveReqVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pd.document.MesPdDocumentDO; |
| | |
| | | private BpmProcessInstanceApi processInstanceApi; |
| | | |
| | | @Resource |
| | | private BpmCategoryService bpmCategoryService; |
| | | |
| | | @Resource |
| | | private BpmProcessDefinitionService bpmProcessDefinitionService; |
| | | private MesBpmProcessService mesBpmProcessService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | |
| | | @Override |
| | | public List<Map<String, Object>> getProjectApproveProcessDefinitionList() { |
| | | // 1. æ ¡éªåç±»æ¯å¦åå¨ |
| | | List<BpmCategoryDO> categories = bpmCategoryService.getCategoryListByCode( |
| | | Collections.singletonList(BPM_PROCESS_DEFINITION_CATEGORY_CODE)); |
| | | if (CollUtil.isEmpty(categories)) { |
| | | throw exception(PD_PROJECT_BPM_CATEGORY_NOT_EXISTS); |
| | | } |
| | | // 2. è·ååç±»ä¸çæµç¨å®ä¹ä¿¡æ¯ |
| | | List<BpmProcessDefinitionInfoDO> definitionInfoList = bpmProcessDefinitionService |
| | | .getProcessDefinitionInfoListByCategory(BPM_PROCESS_DEFINITION_CATEGORY_CODE); |
| | | if (CollUtil.isEmpty(definitionInfoList)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | // 3. è¿æ»¤æ¿æ´»ç¶æï¼ä¿çææ°çæ¬ |
| | | Map<String, ProcessDefinition> latestVersionMap = new HashMap<>(); |
| | | for (BpmProcessDefinitionInfoDO info : definitionInfoList) { |
| | | ProcessDefinition pd = bpmProcessDefinitionService.getProcessDefinition(info.getProcessDefinitionId()); |
| | | if (pd == null || pd.isSuspended()) { |
| | | continue; |
| | | } |
| | | ProcessDefinition existing = latestVersionMap.get(pd.getKey()); |
| | | if (existing == null || pd.getVersion() > existing.getVersion()) { |
| | | latestVersionMap.put(pd.getKey(), pd); |
| | | } |
| | | } |
| | | // 4. è¿åæµç¨å®ä¹å表 |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | for (ProcessDefinition pd : latestVersionMap.values()) { |
| | | Map<String, Object> item = new HashMap<>(); |
| | | item.put("id", pd.getId()); |
| | | item.put("key", pd.getKey()); |
| | | item.put("name", pd.getName()); |
| | | result.add(item); |
| | | } |
| | | return result; |
| | | return mesBpmProcessService.getApproveProcessDefinitionList(BPM_PROCESS_DEFINITION_CATEGORY_CODE); |
| | | } |
| | | |
| | | @Override |
| | |
| | | /** |
| | | * æäº¤æ¥å·¥ï¼è稿 â 审æ¹ä¸ï¼ |
| | | * |
| | | * @param id ç¼å· |
| | | * @param reqVO æäº¤è¯·æ± |
| | | */ |
| | | void submitFeedback(Long id); |
| | | void submitFeedback(@Valid MesProFeedbackSubmitReqVO reqVO); |
| | | |
| | | /** |
| | | * 驳忥工ï¼å®¡æ¹ä¸ â èç¨¿ï¼ |
| | |
| | | MesProFeedbackBatchCheckRespVO checkBatchRequirements(Long feedbackId); |
| | | |
| | | /** |
| | | * å¤ç BPM 审æ¹ç»æ |
| | | * |
| | | * @param id æ¥å·¥åID |
| | | * @param bpmResult 审æ¹ç»æç¶æ |
| | | */ |
| | | void handleBpmProcessResult(Long id, Integer bpmResult,String reason); |
| | | |
| | | /** |
| | | * IPQC 宿ååè°ï¼å®ææ¥å·¥åå¹¶æ´æ°ä»»å¡/å·¥åè¿åº¦ |
| | | * |
| | | * <p>ç± IPQC æ£éªå®ææ¶è°ç¨ï¼å°æ¥å·¥åç¶æä»å¾
æ£éªæ¹ä¸ºå·²å®æï¼ |
| | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.ObjUtil; |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| | | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.feedback.vo.*; |
| | |
| | | */ |
| | | @Service |
| | | @Validated |
| | | @lombok.extern.slf4j.Slf4j |
| | | public class MesProFeedbackServiceImpl implements MesProFeedbackService { |
| | | |
| | | @Resource |
| | |
| | | private MesMdmItemService mdmItemService; |
| | | @Resource |
| | | private MdmItemBatchConfigApi itemBatchConfigApi; |
| | | @Resource |
| | | private cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi processInstanceApi; |
| | | |
| | | @Override |
| | | public Long createFeedback(MesProFeedbackSaveReqVO createReqVO) { |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void submitFeedback(Long id) { |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void submitFeedback(MesProFeedbackSubmitReqVO reqVO) { |
| | | Long id = reqVO.getId(); |
| | | // 1. æ ¡éªåå¨ + èç¨¿ç¶æ |
| | | validateFeedbackStatusPrepare(id); |
| | | MesProFeedbackDO feedback = validateFeedbackStatusPrepare(id); |
| | | |
| | | // 2. æ´æ°ç¶æä¸ºå®¡æ¹ä¸ï¼æ¥å·¥äººåæ¥å·¥æ¶é´ç±è¡¨åä¿åæ¶ç¡®å®ï¼æäº¤ä¸è¦çï¼ |
| | | MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(feedback.getWorkOrderId()); |
| | | |
| | | if (workOrder != null && Boolean.TRUE.equals(workOrder.getFeedbackApprove()) && cn.hutool.core.util.StrUtil.isNotBlank(workOrder.getProcessDefinitionKey())) { |
| | | // 2. æ´æ°ç¶æä¸ºå®¡æ¹ä¸ï¼å¹¶å¯å¨æµç¨ |
| | | String processInstanceId = processInstanceApi.createProcessInstance(cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId(), |
| | | new cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO() |
| | | .setProcessDefinitionKey(workOrder.getProcessDefinitionKey()) |
| | | .setBusinessKey(String.valueOf(id))); |
| | | |
| | | feedbackMapper.updateById(new MesProFeedbackDO().setId(id) |
| | | .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus()) |
| | | .setProcessDefinitionKey(workOrder.getProcessDefinitionKey()) |
| | | .setProcessInstanceId(processInstanceId)); |
| | | } else { |
| | | // 2. 夿è¿ä¸ªæ¥å·¥éä¸éè¦æ¹æ¬¡å· |
| | | MesProFeedbackBatchCheckRespVO mesProFeedbackBatchCheckRespVO = checkBatchRequirements(id); |
| | | if (mesProFeedbackBatchCheckRespVO.getNeedBatchInput()) { |
| | | if (StrUtil.isBlank(reqVO.getLotNumber())) { |
| | | throw exception(MD_ITEM_BATCH_CONFIG_AT_LEAST_ONE_APPROVE_FLAG); |
| | | } |
| | | } |
| | | |
| | | // 3. æ´æ°ç¶æä¸ºå®¡æ¹ä¸ï¼ç¶åç´æ¥éè¿å®¡æ¹ |
| | | feedbackMapper.updateById(new MesProFeedbackDO().setId(id) |
| | | .setStatus(MesProFeedbackStatusEnum.APPROVING.getStatus())); |
| | | MesProFeedbackApproveReqVO approveReqVO = cn.iocoder.yudao.framework.common.util.object.BeanUtils.toBean(reqVO, MesProFeedbackApproveReqVO.class); |
| | | approveFeedback(approveReqVO); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void handleBpmProcessResult(Long id, Integer bpmResult,String reason) { |
| | | // 1. ææ§æ ¡éªï¼è·åæ¥å·¥åå¹¶å¤æç¶æ |
| | | MesProFeedbackDO feedback = feedbackMapper.selectById(id); |
| | | if (feedback == null) { |
| | | log.warn("[handleBpmProcessResult] ç产æ¥å·¥({}) ä¸åå¨", id); |
| | | return; |
| | | } |
| | | if (!MesProFeedbackStatusEnum.APPROVING.getStatus().equals(feedback.getStatus())) { |
| | | log.warn("[handleBpmProcessResult] ç产æ¥å·¥({}) ä¸å¤äºå®¡æ¹ä¸ç¶æï¼å½åç¶æï¼{}", id, feedback.getStatus()); |
| | | return; |
| | | } |
| | | |
| | | // 2. æ ¹æ®å®¡æ¹ç»æè¿è¡å¤ç |
| | | if (cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.APPROVE.getStatus().equals(bpmResult)) { |
| | | MesProFeedbackApproveReqVO reqVO = new MesProFeedbackApproveReqVO(); |
| | | reqVO.setId(id); |
| | | // 夿è¿ä¸ªæ¥å·¥éä¸éè¦æ¹æ¬¡å· |
| | | MesProFeedbackBatchCheckRespVO mesProFeedbackBatchCheckRespVO = checkBatchRequirements(id); |
| | | if (mesProFeedbackBatchCheckRespVO.getNeedBatchInput()){ |
| | | if (StrUtil.isBlank(reason)){ |
| | | // æ¥é 请å¨å®¡æ¹æè§éå¡«åæ¹æ¬¡å· |
| | | throw exception(MD_ITEM_BATCH_CONFIG_AT_LEAST_ONE_APPROVE_FLAG); |
| | | }else { |
| | | BeanUtils.copyProperties(mesProFeedbackBatchCheckRespVO,reqVO); |
| | | reqVO.setLotNumber(reason); |
| | | } |
| | | } |
| | | approveFeedback(reqVO); |
| | | } else if (cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.REJECT.getStatus().equals(bpmResult) || |
| | | cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.CANCEL.getStatus().equals(bpmResult)) { |
| | | rejectFeedback(id); |
| | | } |
| | | } |
| | | |
| | | @Override |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package cn.iocoder.yudao.module.mes.service.pro.feedback.listener; |
| | | |
| | | import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent; |
| | | import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEventListener; |
| | | import cn.iocoder.yudao.module.mes.service.pro.feedback.MesProFeedbackService; |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants; |
| | | import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService; |
| | | import org.flowable.task.api.history.HistoricTaskInstance; |
| | | import jakarta.annotation.Resource; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * ç产æ¥å·¥å®¡æ¹ç¶æçå¬å¨ |
| | | * |
| | | * çå¬ BPM æµç¨å®ä¾ç¶æåæ´äºä»¶ï¼æ´æ°ç产æ¥å·¥ç审æ¹ç¶æ |
| | | * |
| | | * @author è¶
级管çå |
| | | */ |
| | | @Component |
| | | @Slf4j |
| | | public class MesProFeedbackStatusListener extends BpmProcessInstanceStatusEventListener { |
| | | |
| | | /** |
| | | * BPM ç产æ¥å·¥å®¡æ¹æµç¨å®ä¹ key |
| | | */ |
| | | private static final String BPM_PROCESS_DEFINITION_KEY = "mes-pro-feedback-audit"; |
| | | |
| | | @Resource |
| | | private MesProFeedbackService feedbackService; |
| | | |
| | | @Resource |
| | | private BpmTaskService bpmTaskService; |
| | | |
| | | @Override |
| | | protected String getProcessDefinitionKey() { |
| | | return BPM_PROCESS_DEFINITION_KEY; |
| | | } |
| | | |
| | | @Override |
| | | protected void onEvent(BpmProcessInstanceStatusEvent event) { |
| | | Long feedbackId; |
| | | try { |
| | | feedbackId = Long.parseLong(event.getBusinessKey()); |
| | | } catch (NumberFormatException e) { |
| | | log.warn("[onEvent] businessKey({}) 䏿¯ææçç产æ¥å·¥ç¼å·", event.getBusinessKey()); |
| | | return; |
| | | } |
| | | String reason = event.getReason(); |
| | | if (StrUtil.isEmpty(reason) && event.getId() != null) { |
| | | // å½ event.getReason() 为空æ¶ï¼å°è¯ä»æåä¸ä¸ªå®æçä»»å¡ä¸è·åå®¡æ¹æè§ |
| | | List<HistoricTaskInstance> tasks = bpmTaskService.getTaskListByProcessInstanceId(event.getId(), false); |
| | | if (CollUtil.isNotEmpty(tasks)) { |
| | | HistoricTaskInstance lastTask = tasks.stream() |
| | | .filter(task -> task.getEndTime() != null) |
| | | .max(Comparator.comparing(HistoricTaskInstance::getEndTime)) |
| | | .orElse(null); |
| | | if (lastTask != null && lastTask.getTaskLocalVariables() != null) { |
| | | reason = (String) lastTask.getTaskLocalVariables().get(BpmnVariableConstants.TASK_VARIABLE_REASON); |
| | | } |
| | | } |
| | | } |
| | | |
| | | log.info("[onEvent] æ¶å°BPM审æ¹äºä»¶ï¼feedbackId={}, status={},Reason={}", feedbackId, event.getStatus(), reason); |
| | | |
| | | feedbackService.handleBpmProcessResult(feedbackId, event.getStatus(), reason); |
| | | } |
| | | |
| | | } |
| | |
| | | */ |
| | | void resumeTask(cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskResumeReqVO resumeReqVO); |
| | | |
| | | /** |
| | | * è·åç产任å¡çæå®æ¥å·¥äººååè¡¨ï¼æä»»å¡ç¼å·åç» |
| | | * |
| | | * @param taskIds ä»»å¡ç¼å·éå |
| | | * @return ä»»å¡å
³èç人åå表 Map |
| | | */ |
| | | default Map<Long, List<cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskAssigneeDO>> getTaskAssigneeMap(Collection<Long> taskIds) { |
| | | if (cn.hutool.core.collection.CollUtil.isEmpty(taskIds)) { |
| | | return java.util.Collections.emptyMap(); |
| | | } |
| | | return cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap( |
| | | getTaskAssigneeListByTaskIds(taskIds), cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskAssigneeDO::getTaskId); |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®ä»»å¡ç¼å·éåè·åå
³è人åå表 |
| | | */ |
| | | List<cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskAssigneeDO> getTaskAssigneeListByTaskIds(Collection<Long> taskIds); |
| | | |
| | | } |
| | |
| | | import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskPauseRecordDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.pro.task.MesProTaskPauseRecordMapper; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskAssigneeDO; |
| | | import cn.iocoder.yudao.module.mes.dal.mysql.pro.task.MesProTaskAssigneeMapper; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskPauseReqVO; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.task.vo.MesProTaskResumeReqVO; |
| | | |
| | |
| | | |
| | | @Resource |
| | | private MesProTaskPauseRecordMapper taskPauseRecordMapper; |
| | | |
| | | @Resource |
| | | private MesProTaskAssigneeMapper taskAssigneeMapper; |
| | | |
| | | @Resource |
| | | @Lazy |
| | |
| | | } |
| | | // 2.2 æå
¥ |
| | | taskMapper.insert(task); |
| | | |
| | | // 2.3 ä¿åæå®æ¥å·¥äººå |
| | | updateTaskAssignees(task.getId(), createReqVO.getAssigneeUserIds()); |
| | | |
| | | return task.getId(); |
| | | } |
| | | |
| | |
| | | MesProTaskDO updateObj = BeanUtils.toBean(updateReqVO, MesProTaskDO.class) |
| | | .setName(buildTaskName(item, quantity)); |
| | | taskMapper.updateById(updateObj); |
| | | |
| | | // 3. æ´æ°æå®æ¥å·¥äººåï¼æ¯å¯¹æ´æ°ï¼ |
| | | updateTaskAssignees(task.getId(), updateReqVO.getAssigneeUserIds()); |
| | | } |
| | | |
| | | private void updateTaskAssignees(Long taskId, List<Long> assigneeUserIds) { |
| | | if (assigneeUserIds == null) { |
| | | assigneeUserIds = Collections.emptyList(); |
| | | } |
| | | // 1. æ¥è¯¢æ°æ®åºä¸åæç |
| | | List<MesProTaskAssigneeDO> oldAssignees = taskAssigneeMapper.selectListByTaskId(taskId); |
| | | Set<Long> oldUserIds = convertSet(oldAssignees, MesProTaskAssigneeDO::getUserId); |
| | | Set<Long> newUserIds = new java.util.HashSet<>(assigneeUserIds); |
| | | |
| | | // 2. 计ç®éè¦æ°å¢çåéè¦å é¤ç |
| | | Set<Long> toAddUserIds = newUserIds.stream().filter(id -> !oldUserIds.contains(id)).collect(java.util.stream.Collectors.toSet()); |
| | | Set<Long> toRemoveUserIds = oldUserIds.stream().filter(id -> !newUserIds.contains(id)).collect(java.util.stream.Collectors.toSet()); |
| | | |
| | | // 3. æ°å¢ |
| | | if (CollUtil.isNotEmpty(toAddUserIds)) { |
| | | List<MesProTaskAssigneeDO> addList = convertList(toAddUserIds, userId -> new MesProTaskAssigneeDO().setTaskId(taskId).setUserId(userId)); |
| | | taskAssigneeMapper.insertBatch(addList); |
| | | } |
| | | |
| | | // 4. å é¤ |
| | | if (CollUtil.isNotEmpty(toRemoveUserIds)) { |
| | | taskAssigneeMapper.deleteByTaskIdAndUserIds(taskId, toRemoveUserIds); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | if (feedbackMapper.selectCountByTaskId(id) > 0) { |
| | | throw exception(PRO_TASK_HAS_FEEDBACK); |
| | | } |
| | | // 3. å é¤ |
| | | // 3. å é¤ä»»å¡ä¸»è¡¨ |
| | | taskMapper.deleteById(id); |
| | | // 4. å é¤å
³èç人å |
| | | taskAssigneeMapper.deleteByTaskId(id); |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<MesProTaskAssigneeDO> getTaskAssigneeListByTaskIds(Collection<Long> taskIds) { |
| | | if (CollUtil.isEmpty(taskIds)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return taskAssigneeMapper.selectListByTaskIds(taskIds); |
| | | } |
| | | |
| | | @Override |
| | | public MesProTaskDO validateTaskExists(Long id) { |
| | | MesProTaskDO task = taskMapper.selectById(id); |
| | | if (task == null) { |
| | |
| | | MesProWorkOrderDO getWorkOrder(String code); |
| | | |
| | | /** |
| | | * è·åå®¡æ¹æ¥å·¥çæµç¨å®ä¹å表 |
| | | * |
| | | * @return æµç¨å®ä¹å表ï¼å
å« id, key, name |
| | | */ |
| | | List<Map<String, Object>> getWorkOrderApproveProcessDefinitionList(); |
| | | |
| | | /** |
| | | * è·å¾ç产工åå页 |
| | | * |
| | | * @param pageReqVO å页æ¥è¯¢ |
| | |
| | | import cn.iocoder.yudao.module.mes.enums.wm.BarcodeBizTypeEnum; |
| | | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemBatchConfigService; |
| | | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| | | import cn.iocoder.yudao.module.mes.service.common.bpm.MesBpmProcessService; |
| | | import cn.iocoder.yudao.module.mes.controller.admin.pro.workorder.vo.MesProWorkOrderProgressRespVO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; |
| | | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO; |
| | |
| | | @Service |
| | | @Validated |
| | | public class MesProWorkOrderServiceImpl implements MesProWorkOrderService { |
| | | |
| | | @Resource |
| | | private MesBpmProcessService mesBpmProcessService; |
| | | |
| | | private static final String BPM_PROCESS_DEFINITION_CATEGORY_CODE = "mes_pro_feedback_audit"; |
| | | |
| | | @Resource |
| | | private MesProWorkOrderMapper workOrderMapper; |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<Map<String, Object>> getWorkOrderApproveProcessDefinitionList() { |
| | | return mesBpmProcessService.getApproveProcessDefinitionList(BPM_PROCESS_DEFINITION_CATEGORY_CODE); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public MesProWorkOrderDO getWorkOrder(Long id) { |
| | | return workOrderMapper.selectById(id); |
| | | } |
| | |
| | | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; |
| | | import cn.iocoder.yudao.module.system.enums.common.SexEnum; |
| | | import cn.iocoder.yudao.module.system.service.dept.DeptService; |
| | | import cn.iocoder.yudao.module.system.service.permission.PermissionService; |
| | | import cn.iocoder.yudao.module.system.service.permission.RoleService; |
| | | import cn.iocoder.yudao.module.system.service.user.AdminUserService; |
| | | import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.Parameter; |
| | | import io.swagger.v3.oas.annotations.Parameters; |
| | |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; |
| | | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| | |
| | | private AdminUserService userService; |
| | | @Resource |
| | | private DeptService deptService; |
| | | @Resource |
| | | private RoleService roleService; |
| | | @Resource |
| | | private PermissionService permissionService; |
| | | |
| | | @PostMapping("/create") |
| | | @Operation(summary = "æ°å¢ç¨æ·") |
| | |
| | | return success(UserConvert.INSTANCE.convertSimpleList(list, deptMap)); |
| | | } |
| | | |
| | | @GetMapping("/list-by-role-code") |
| | | @Operation(summary = "éè¿è§è²æ è¯è·åç¨æ·ç²¾ç®ä¿¡æ¯å表", description = "åªå
嫿¥æè¿äºè§è²çç¨æ·ï¼ä¸»è¦ç¨äºå端ç䏿éé¡¹ãæ¯æéå·åéçå¤ä¸ªè§è²æ è¯") |
| | | @Parameter(name = "code", description = "è§è²æ è¯ï¼æ¯æå¤ä¸ªï¼éå·åé", required = true, example = "admin,user") |
| | | public CommonResult<List<UserSimpleRespVO>> getSimpleUserListByRoleCode( |
| | | @RequestParam("code") String code) { |
| | | if (StrUtil.isBlank(code)) { |
| | | return success(Collections.emptyList()); |
| | | } |
| | | List<String> codes = StrUtil.split(code, ","); |
| | | List<RoleDO> roles = roleService.getRoleListByCodes(codes); |
| | | if (CollUtil.isEmpty(roles)) { |
| | | return success(Collections.emptyList()); |
| | | } |
| | | Set<Long> userIds = permissionService.getUserRoleIdListByRoleId(convertList(roles, RoleDO::getId)); |
| | | if (CollUtil.isEmpty(userIds)) { |
| | | return success(Collections.emptyList()); |
| | | } |
| | | List<AdminUserDO> list = userService.getUserList(userIds); |
| | | |
| | | // æ¼æ¥æ°æ® |
| | | Map<Long, DeptDO> deptMap = deptService.getDeptMap( |
| | | convertList(list, AdminUserDO::getDeptId)); |
| | | return success(UserConvert.INSTANCE.convertSimpleList(list, deptMap)); |
| | | } |
| | | |
| | | |
| | | @GetMapping("/get") |
| | | @Operation(summary = "è·å¾ç¨æ·è¯¦æ
") |
| | | @Parameter(name = "id", description = "ç¼å·", required = true, example = "1024") |
| | |
| | | return selectOne(RoleDO::getCode, code); |
| | | } |
| | | |
| | | default List<RoleDO> selectListByCodes(Collection<String> codes) { |
| | | return selectList(RoleDO::getCode, codes); |
| | | } |
| | | |
| | | default List<RoleDO> selectListByStatus(@Nullable Collection<Integer> statuses) { |
| | | return selectList(RoleDO::getStatus, statuses); |
| | | } |
| | |
| | | @Resource |
| | | @Lazy // æå è½½ï¼é¿å
循ç¯ä¾èµ |
| | | private AdminUserService adminUserService; |
| | | @Resource |
| | | @Lazy |
| | | private cn.iocoder.yudao.module.system.service.permission.PermissionService permissionService; |
| | | @Resource |
| | | @Lazy |
| | | private cn.iocoder.yudao.module.system.service.permission.RoleService roleService; |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | } |
| | | if (userType.equals(UserTypeEnum.ADMIN.getValue())) { |
| | | AdminUserDO user = adminUserService.getUser(userId); |
| | | return MapUtil.builder(LoginUser.INFO_KEY_NICKNAME, user.getNickname()) |
| | | .put(LoginUser.INFO_KEY_DEPT_ID, StrUtil.toStringOrNull(user.getDeptId())).build(); |
| | | java.util.Map<String, String> info = new java.util.HashMap<>(); |
| | | info.put(LoginUser.INFO_KEY_NICKNAME, user.getNickname()); |
| | | info.put(LoginUser.INFO_KEY_DEPT_ID, cn.hutool.core.util.StrUtil.toStringOrNull(user.getDeptId())); |
| | | // Fetch roles and put into info |
| | | java.util.Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(userId); |
| | | if (cn.hutool.core.collection.CollUtil.isNotEmpty(roleIds)) { |
| | | java.util.List<cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO> roles = roleService.getRoleList(roleIds); |
| | | if (cn.hutool.core.collection.CollUtil.isNotEmpty(roles)) { |
| | | info.put(LoginUser.INFO_KEY_ROLE_CODES, cn.hutool.core.collection.CollUtil.join(roles, ",", cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO::getCode)); |
| | | } |
| | | } |
| | | return info; |
| | | } else if (userType.equals(UserTypeEnum.MEMBER.getValue())) { |
| | | // 注æï¼ç®å Member ææ¶ä¸è¯»åï¼å¯ä»¥æéå®ç° |
| | | return Collections.emptyMap(); |
| | |
| | | RoleDO getRole(Long id); |
| | | |
| | | /** |
| | | * è·å¾è§è² |
| | | * |
| | | * @param code è§è²ç¼ç |
| | | * @return è§è² |
| | | */ |
| | | RoleDO getRoleByCode(String code); |
| | | |
| | | /** |
| | | * è·å¾è§è²å表 |
| | | * |
| | | * @param codes è§è²ç¼ç æ°ç» |
| | | * @return è§è²å表 |
| | | */ |
| | | List<RoleDO> getRoleListByCodes(Collection<String> codes); |
| | | |
| | | /** |
| | | * è·å¾è§è²ï¼ä»ç¼åä¸ |
| | | * |
| | | * @param id è§è²ç¼å· |
| | |
| | | } |
| | | |
| | | @Override |
| | | public RoleDO getRoleByCode(String code) { |
| | | return roleMapper.selectByCode(code); |
| | | } |
| | | |
| | | @Override |
| | | public List<RoleDO> getRoleListByCodes(Collection<String> codes) { |
| | | if (CollUtil.isEmpty(codes)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | return roleMapper.selectListByCodes(codes); |
| | | } |
| | | |
| | | @Override |
| | | @Cacheable(value = RedisKeyConstants.ROLE, key = "#id", |
| | | unless = "#result == null") |
| | | public RoleDO getRoleFromCache(Long id) { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | server: |
| | | port: 48080 |
| | | |
| | | --- #################### æ°æ®åºç¸å
³é
ç½® #################### |
| | | spring: |
| | | autoconfigure: |
| | | # noinspection SpringBootApplicationYaml |
| | | exclude: |
| | | - org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration # é»è®¤ local ç¯å¢ï¼ä¸å¼å¯ Quartz çèªå¨é
ç½® |
| | | - org.springframework.ai.vectorstore.qdrant.autoconfigure.QdrantVectorStoreAutoConfiguration # ç¦ç¨ AI 模åç Qdrantï¼æå¨å建 |
| | | - org.springframework.ai.vectorstore.redis.autoconfigure.RedisVectorStoreAutoConfiguration # ç¦ç¨ AI 模åç Redisï¼æå¨å建 |
| | | - org.springframework.ai.vectorstore.milvus.autoconfigure.MilvusVectorStoreAutoConfiguration # ç¦ç¨ AI 模åç Milvusï¼æå¨å建 |
| | | - org.dromara.trans.config.TransServiceConfig # TODO èè¿ï¼easy-trans å
¼å®¹ Spring Boot 4 åç§»é¤ï¼TransServiceConfig å¼ç¨äºå·²ç§»é¤ç RestTemplateBuilderï¼ |
| | | # ç¦ç¨æªé
ç½® API Key çæ¨¡åèªå¨é
ç½®ï¼åªä¿çéä¹åé® Embedding çæå¨é
ç½®ï¼ |
| | | - org.springframework.ai.model.openai.autoconfigure.OpenAiChatAutoConfiguration |
| | | - org.springframework.ai.model.openai.autoconfigure.OpenAiEmbeddingAutoConfiguration |
| | | - org.springframework.ai.model.openai.autoconfigure.OpenAiImageAutoConfiguration |
| | | - org.springframework.ai.model.openai.autoconfigure.OpenAiAudioSpeechAutoConfiguration |
| | | - org.springframework.ai.model.openai.autoconfigure.OpenAiAudioTranscriptionAutoConfiguration |
| | | - org.springframework.ai.model.openai.autoconfigure.OpenAiModerationAutoConfiguration |
| | | - org.springframework.ai.model.deepseek.autoconfigure.DeepSeekChatAutoConfiguration |
| | | - org.springframework.ai.model.anthropic.autoconfigure.AnthropicChatAutoConfiguration |
| | | - org.springframework.ai.model.google.genai.autoconfigure.chat.GoogleGenAiChatAutoConfiguration |
| | | - org.springframework.ai.model.google.genai.autoconfigure.embedding.GoogleGenAiEmbeddingConnectionAutoConfiguration |
| | | - org.springframework.ai.model.google.genai.autoconfigure.embedding.GoogleGenAiTextEmbeddingAutoConfiguration |
| | | - org.springframework.ai.model.ollama.autoconfigure.OllamaApiAutoConfiguration |
| | | - org.springframework.ai.model.ollama.autoconfigure.OllamaChatAutoConfiguration |
| | | - org.springframework.ai.model.ollama.autoconfigure.OllamaEmbeddingAutoConfiguration |
| | | - org.springframework.ai.model.stabilityai.autoconfigure.StabilityAiImageAutoConfiguration |
| | | # æ°æ®æºé
置项 |
| | | datasource: |
| | | druid: # Druid ãçæ§ãç¸å
³çå
¨å±é
ç½® |
| | | web-stat-filter: |
| | | enabled: true |
| | | stat-view-servlet: |
| | | enabled: true |
| | | allow: # 设置ç½ååï¼ä¸å¡«åå
许ææè®¿é® |
| | | url-pattern: /druid/* |
| | | login-username: # æ§å¶å°ç®¡çç¨æ·ååå¯ç |
| | | login-password: |
| | | filter: |
| | | stat: |
| | | enabled: true |
| | | log-slow-sql: true # æ
¢ SQL è®°å½ |
| | | slow-sql-millis: 100 |
| | | merge-sql: true |
| | | wall: |
| | | config: |
| | | multi-statement-allow: true |
| | | dynamic: # 夿°æ®æºé
ç½® |
| | | druid: # Druid ãè¿æ¥æ± ãç¸å
³çå
¨å±é
ç½® |
| | | initial-size: 1 # åå§è¿æ¥æ° |
| | | min-idle: 1 # æå°è¿æ¥æ± æ°é |
| | | max-active: 20 # æå¤§è¿æ¥æ± æ°é |
| | | max-wait: 60000 # é
ç½®è·åè¿æ¥çå¾
è¶
æ¶çæ¶é´ï¼åä½ï¼æ¯«ç§ï¼1 åéï¼ |
| | | time-between-eviction-runs-millis: 60000 # é
ç½®é´éå¤ä¹
æè¿è¡ä¸æ¬¡æ£æµï¼æ£æµéè¦å
³éç空é²è¿æ¥ï¼åä½ï¼æ¯«ç§ï¼1 åéï¼ |
| | | min-evictable-idle-time-millis: 600000 # é
ç½®ä¸ä¸ªè¿æ¥å¨æ± 䏿å°çåçæ¶é´ï¼åä½ï¼æ¯«ç§ï¼10 åéï¼ |
| | | max-evictable-idle-time-millis: 1800000 # é
ç½®ä¸ä¸ªè¿æ¥å¨æ± 䏿大çåçæ¶é´ï¼åä½ï¼æ¯«ç§ï¼30 åéï¼ |
| | | validation-query: SELECT 1 FROM DUAL # é
ç½®æ£æµè¿æ¥æ¯å¦ææ |
| | | test-while-idle: true |
| | | test-on-borrow: false |
| | | test-on-return: false |
| | | pool-prepared-statements: true # æ¯å¦å¼å¯ PreparedStatement ç¼å |
| | | max-pool-prepared-statement-per-connection-size: 20 # æ¯ä¸ªè¿æ¥ç¼åç PreparedStatement æ°é |
| | | primary: master |
| | | datasource: |
| | | master: |
| | | url: jdbc:mysql://172.17.0.1:9002/mom-wtxc?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X è¿æ¥çç¤ºä¾ |
| | | # url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true # MySQL Connector/J 5.X è¿æ¥çç¤ºä¾ |
| | | # url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL è¿æ¥çç¤ºä¾ |
| | | # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle è¿æ¥çç¤ºä¾ |
| | | # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer è¿æ¥çç¤ºä¾ |
| | | # url: jdbc:dm://127.0.0.1:5236?schema=RUOYI_VUE_PRO # DM è¿æ¥çç¤ºä¾ |
| | | # url: jdbc:kingbase8://127.0.0.1:54321/test # 人大éä» KingbaseES è¿æ¥çç¤ºä¾ |
| | | # url: jdbc:postgresql://127.0.0.1:5432/postgres # OpenGauss è¿æ¥çç¤ºä¾ |
| | | # url: jdbc:postgresql://127.0.0.1:5866/ruoyi-vue-pro # çé« HighGo è¿æ¥çç¤ºä¾ |
| | | username: root |
| | | password: wtxc@123456.. |
| | | # username: sa # SQL Server è¿æ¥çç¤ºä¾ |
| | | # password: Yudao@2024 # SQL Server è¿æ¥çç¤ºä¾ |
| | | # username: SYSDBA # DM è¿æ¥çç¤ºä¾ |
| | | # password: SYSDBA001 # DM è¿æ¥çç¤ºä¾ |
| | | # username: root # OpenGauss è¿æ¥çç¤ºä¾ |
| | | # password: Yudao@2024 # OpenGauss è¿æ¥çç¤ºä¾ |
| | | # username: root # çé« HighGo è¿æ¥çç¤ºä¾ |
| | | # password: 123456 # çé« HighGo è¿æ¥çç¤ºä¾ |
| | | # tdengine: # IoT æ°æ®åºï¼éè¦ IoT ç©èç½åå¼å¯å¢ï¼ï¼ |
| | | # lazy: true # å¼å¯æå è½½ï¼ä¿è¯å¯å¨é度 |
| | | # url: jdbc:TAOS-WS://127.0.0.1:6041/ruoyi_vue_pro?varcharAsString=true&enableAutoReconnect=true # åè§ï¼https://t.zsxq.com/qaX9cï¼å¼å¯ TDengine WebSocket èªå¨éè¿ |
| | | # driver-class-name: com.taosdata.jdbc.ws.WebSocketDriver |
| | | # username: root |
| | | # password: taosdata |
| | | # druid: |
| | | # validation-query: SELECT SERVER_STATUS() # TDengine æ°æ®æºçæææ§æ£æ¥ SQL |
| | | |
| | | # Redis é
ç½®ãRedisson é»è®¤çé
置足å¤ä½¿ç¨ï¼ä¸è¬ä¸éè¦è¿è¡è°ä¼ |
| | | data: |
| | | redis: |
| | | host: 172.17.0.1 # å°å |
| | | port: 6379 # ç«¯å£ |
| | | database: 1 # æ°æ®åºç´¢å¼ |
| | | # password: dev # å¯ç ï¼å»ºè®®ç产ç¯å¢å¼å¯ |
| | | |
| | | --- #################### 宿¶ä»»å¡ç¸å
³é
ç½® #################### |
| | | |
| | | # Quartz é
置项ï¼å¯¹åº QuartzProperties é
置类 |
| | | spring: |
| | | quartz: |
| | | auto-startup: true # æ¬å°å¼åç¯å¢ï¼å°½éä¸è¦å¼å¯ Job |
| | | scheduler-name: schedulerName # Scheduler ååãé»è®¤ä¸º schedulerName |
| | | job-store-type: jdbc # Job åå¨å¨ç±»åãé»è®¤ä¸º memory 表示å
åï¼å¯é jdbc ä½¿ç¨æ°æ®åºã |
| | | wait-for-jobs-to-complete-on-shutdown: true # åºç¨å
³éæ¶ï¼æ¯å¦çå¾
宿¶ä»»å¡æ§è¡å®æãé»è®¤ä¸º false ï¼å»ºè®®è®¾ç½®ä¸º true |
| | | properties: # æ·»å Quartz Scheduler éå 屿§ï¼æ´å¤å¯ä»¥ç http://www.quartz-scheduler.org/documentation/2.4.0-SNAPSHOT/configuration.html ææ¡£ |
| | | org: |
| | | quartz: |
| | | # Scheduler ç¸å
³é
ç½® |
| | | scheduler: |
| | | instanceName: schedulerName |
| | | instanceId: AUTO # èªå¨çæ instance ID |
| | | # JobStore ç¸å
³é
ç½® |
| | | jobStore: |
| | | # JobStore å®ç°ç±»ãå¯è§å客ï¼https://blog.csdn.net/weixin_42458219/article/details/122247162 |
| | | class: org.springframework.scheduling.quartz.LocalDataSourceJobStore |
| | | isClustered: true # æ¯éç¾¤æ¨¡å¼ |
| | | clusterCheckinInterval: 15000 # éç¾¤æ£æ¥é¢çï¼åä½ï¼æ¯«ç§ãé»è®¤ä¸º 15000ï¼å³ 15 ç§ |
| | | misfireThreshold: 60000 # misfire éå¼ï¼åä½ï¼æ¯«ç§ã |
| | | # çº¿ç¨æ± ç¸å
³é
ç½® |
| | | threadPool: |
| | | threadCount: 25 # çº¿ç¨æ± 大å°ãé»è®¤ä¸º 10 ã |
| | | threadPriority: 5 # 线ç¨ä¼å
级 |
| | | class: org.quartz.simpl.SimpleThreadPool # çº¿ç¨æ± ç±»å |
| | | jdbc: # ä½¿ç¨ JDBC ç JobStore çæ¶åï¼JDBC çé
ç½® |
| | | initialize-schema: NEVER # æ¯å¦èªå¨ä½¿ç¨ SQL åå§å Quartz è¡¨ç»æãè¿é设置æ never ï¼æä»¬æå¨åå»ºè¡¨ç»æã |
| | | |
| | | --- #################### æå¡ä¿éç¸å
³é
ç½® #################### |
| | | |
| | | # Lock4j é
置项 |
| | | lock4j: |
| | | acquire-timeout: 3000 # è·ååå¸å¼éè¶
æ¶æ¶é´ï¼é»è®¤ä¸º 3000 æ¯«ç§ |
| | | expire: 30000 # åå¸å¼éçè¶
æ¶æ¶é´ï¼é»è®¤ä¸º 30000 æ¯«ç§ |
| | | |
| | | --- #################### çæ§ç¸å
³é
ç½® #################### |
| | | |
| | | # Actuator çæ§ç«¯ç¹çé
置项 |
| | | management: |
| | | endpoints: |
| | | web: |
| | | base-path: /actuator # Actuator æä¾ç API æ¥å£çæ ¹ç®å½ãé»è®¤ä¸º /actuator |
| | | exposure: |
| | | include: '*' # éè¦å¼æ¾ç端ç¹ãé»è®¤å¼åªæå¼ health å info 两个端ç¹ãéè¿è®¾ç½® * ï¼å¯ä»¥å¼æ¾ææç«¯ç¹ã |
| | | |
| | | # Spring Boot Admin é
置项 |
| | | spring: |
| | | boot: |
| | | admin: |
| | | # Spring Boot Admin Client 客æ·ç«¯çç¸å
³é
ç½® |
| | | client: |
| | | url: http://127.0.0.1:${server.port}/${spring.boot.admin.context-path} # 设置 Spring Boot Admin Server å°å |
| | | instance: |
| | | service-host-type: IP # 注åå®ä¾æ¶ï¼ä¼å
ä½¿ç¨ IP [IP, HOST_NAME, CANONICAL_HOST_NAME] |
| | | username: admin |
| | | password: admin |
| | | # Spring Boot Admin Server æå¡ç«¯çç¸å
³é
ç½® |
| | | context-path: /admin # é
ç½® Spring |
| | | # å
许åµå
¥ iframe çååï¼æ¯æéé
符ï¼ï¼å®é
é¨ç½²æ¶ï¼å¯ä»¥æ¹ä¸º "'self' [ä½ çå
¬ç½åå]" |
| | | frame-ancestors: "'self' localhost localhost:48080 127.0.0.1 127.0.0.1:48080" |
| | | |
| | | # æ¥å¿æä»¶é
ç½® |
| | | logging: |
| | | file: |
| | | name: logs/${spring.application.name}.log # æ¥å¿æä»¶åï¼ç¸å¯¹äºé¡¹ç®æ ¹ç®å½ |
| | | level: |
| | | # é
ç½®èªå·±åç MyBatis Mapper æå°æ¥å¿ |
| | | cn.iocoder.yudao.module.bpm.dal.mysql: debug |
| | | cn.iocoder.yudao.module.infra.dal.mysql: debug |
| | | cn.iocoder.yudao.module.infra.dal.mysql.logger.ApiErrorLogMapper: INFO # é
ç½® ApiErrorLogMapper çæ¥å¿çº§å«ä¸º infoï¼é¿å
å GlobalExceptionHandler éå¤æå° |
| | | cn.iocoder.yudao.module.infra.dal.mysql.job.JobLogMapper: INFO # é
ç½® JobLogMapper çæ¥å¿çº§å«ä¸º info |
| | | cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper: INFO # é
ç½® FileConfigMapper çæ¥å¿çº§å«ä¸º info |
| | | cn.iocoder.yudao.module.system.dal.mysql: debug |
| | | cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper: INFO # é
ç½® SmsChannelMapper çæ¥å¿çº§å«ä¸º info |
| | | cn.iocoder.yudao.module.member.dal.mysql: debug |
| | | cn.iocoder.yudao.module.crm.dal.mysql: debug |
| | | cn.iocoder.yudao.module.erp.dal.mysql: debug |
| | | cn.iocoder.yudao.module.mes.dal.mysql: debug |
| | | cn.iocoder.yudao.module.ai.dal.mysql: debug |
| | | cn.iocoder.yudao.module.im.dal.mysql: debug |
| | | org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO èè¿ï¼å
ç¦ç¨ï¼Spring Boot 3.X åå¨é¨åé误ç WARN æç¤º |
| | | |
| | | debug: false |
| | | |
| | | yudao: |
| | | ai: |
| | | vector-store: |
| | | type: milvus # åéåºç±»åï¼milvus |
| | | milvus: |
| | | initialize-schema: true |
| | | database-name: test |
| | | collection-name: knowledge_segment_wtxc |
| | | host: 36.213.90.123 |
| | | port: 19530 |
| | | |
| | | --- #################### è¶
级管çåç¸å
³é
ç½® #################### |
| | | |
| | | # è¶
级管çåé
置项ï¼è®¾ç½®å½åé¡¹ç®ææèªå®ä¹çé
ç½® |
| | | yudao: |
| | | captcha: |
| | | enable: false # æ¬å°ç¯å¢ï¼ææ¶å
³éå¾çéªè¯ç ï¼æ¹ä¾¿ç»å½çæ¥å£çæµè¯ï¼ |
| | | security: |
| | | mock-enable: true |
| | | access-log: # è®¿é®æ¥å¿çé
置项 |
| | | enable: false |
| | | demo: false # å
³éæ¼ç¤ºæ¨¡å¼ |
| | | storage: # æä»¶ä¸ä¼ é
ç½® |
| | | path: /data/javaWork/mom/file # æä»¶å卿 ¹ç®å½ |
| | | url-prefix: /admin-api/system/storage-blob # URLè·¯å¾åç¼ |
| | | domain: http://42.63.71.140:9001 # åååç¼ï¼æå®é
ååé
ç½®ï¼ï¼å端é
置好åä¸å¤ªå¯¹ç°å¨æ¯ç´è¿åç«¯ï¼ææè¦åç«¯ç«¯å£ |
| | | expired: 120 # tokenè¿ææ¶é´ï¼åéï¼ |
| | | use-limit: 10 # tokenä½¿ç¨æ¬¡æ°ä¸é |
| | | jwt-secret: abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG # JWTå¯é¥ |
| | | compress: true # æ¯å¦å缩å¾ç |
| | | need-compress-size: 10MB # 触åå缩çæä»¶å¤§å°éå¼ |
| | | compress-quality: 0.5 # å缩质é(0.0-1.0) |