feat(sales): 添加框架合同订单功能并优化销售台账管理
- 新增合同类型字段(普通销售合同、框架合同、框架订单)
- 实现框架订单创建和查询接口
- 添加框架合同累计发货数量统计功能
- 重构生产计划关联逻辑,支持框架订单独立交货日期
- 优化销售台账金额更新方式,避免字段覆盖问题
- 增加框架合同删除时子订单校验机制
fix(customer): 修复客户回收功能中的安全检查和数据更新问题
- 添加客户ID和存在性校验
- 重构客户回收权限验证逻辑
- 使用UpdateWrapper进行精确字段更新
- 添加共享关系清理机制
feat(device): 添加设备区域管理和年度维护计划功能
- 在设备台账中增加区域ID和名称字段
- 实现按区域递归筛选设备功能
- 新增年度维护任务调度支持
- 优化巡检任务设备存在性验证
feat(measuring): 添加计量器具台账批量导入导出功能
- 实现Excel模板下载和批量导入功能
- 添加数据校验和去重机制
- 优化台账导入时的错误处理
- 新增码重复性检查功能
feat(production): 优化生产计划与销售台账关联验证
- 添加销售来源关联性校验
- 实现销售产品与台账匹配验证
- 支持框架订单产品关联机制
- 优化生产计划创建和编辑流程
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # æ¡æ¶åå䏿¡æ¶è®¢åå端èè°ææ¡£ |
| | | |
| | | ## ä¸ãä¸å¡è¯´æ |
| | | |
| | | éå®å°è´¦ä¸çéå®ååææ¡æ¶ååå¤çï¼ |
| | | |
| | | - æ¡æ¶åååªç»è®°åååºç¡ä¿¡æ¯å产åèå´ã |
| | | - æ¡æ¶ååä¸å¡«åæ°éåäº¤è´§æ¥æã |
| | | - ä¸ä¸ªæ¡æ¶ååä¸å¯ä»¥å建å¤ä¸ªæ¡æ¶è®¢åã |
| | | - æ¡æ¶è®¢ååªç»è®°äº§ååäº¤è´§æ¥æï¼ä¸å¡«åæ°éã |
| | | - å®é
æ°éåªå¨æ¯æ¬¡åè´§æ¶å¡«åï¼ä¿åäºåè´§æç»ã |
| | | - ä¸ä¸ªæ¡æ¶è®¢å产åå¯ä»¥å¤æ¬¡åæ¹åè´§ã |
| | | - æ¡æ¶åå产åä¸è½ç´æ¥åè´§ï¼å¿
é¡»éæ©æ¡æ¶è®¢å产åã |
| | | - æ¡æ¶ååå建æ¶ä¸çæç产计åï¼æ¡æ¶è®¢åå建æ¶èªå¨çæç产计åï¼éæ±æ°éç空ï¼ã |
| | | - ç产æ°éå¨ç产计åä¸åæ¶å¡«åï¼ç产计åä¸åæ¶ä¸åéå®å°è´¦æ°ééå¶ã |
| | | |
| | | ## äºãååç±»å |
| | | |
| | | | contractType | å«ä¹ | æ°é | äº¤è´§æ¥æ | æ¯å¦èªå¨çæç产计å | |
| | | | --- | --- | --- | --- | --- | |
| | | | 1 | æ®ééå®åå | æåæä¸å¡ | æåæä¸å¡ | æåæä¸å¡ | |
| | | | 2 | æ¡æ¶åå | ä¸å¡«å | ä¸å¡«å | å¦ | |
| | | | 3 | æ¡æ¶è®¢å | ä¸å¡«å | 产åæç»å¡«å | æ¯ï¼éæ±æ°éç空ï¼ä¸åæ¶å¡«åï¼ | |
| | | |
| | | ## ä¸ãå建æä¿åæ¡æ¶åå |
| | | |
| | | æ¥å£ï¼ |
| | | |
| | | ```text |
| | | POST /sales/ledger/addOrUpdateSalesLedger |
| | | ``` |
| | | |
| | | 请æ±ç¤ºä¾ï¼ |
| | | |
| | | ```json |
| | | { |
| | | "contractType": 2, |
| | | "customerId": 1001, |
| | | "customerContractNo": "客æ·ååå·", |
| | | "projectName": "项ç®åç§°", |
| | | "salesman": "ä¸å¡å", |
| | | "entryDate": "2026-08-27", |
| | | "executionDate": "2026-08-27", |
| | | "paymentMethod": "æåå约å®", |
| | | "remarks": "æ¡æ¶åå", |
| | | "productData": [ |
| | | { |
| | | "productId": 10, |
| | | "productModelId": 101, |
| | | "productCategory": "产ååç§°", |
| | | "specificationModel": "è§æ ¼åå·", |
| | | "unit": "ä»¶", |
| | | "quantity": null, |
| | | "deliveryDate": null, |
| | | "isProduction": false, |
| | | "type": 1 |
| | | } |
| | | ] |
| | | } |
| | | ``` |
| | | |
| | | åç«¯è¦æ±ï¼ |
| | | |
| | | - `contractType` ä¼ `2`ã |
| | | - äº§åæ°éä¼ `null` æä¸ä¼ ï¼ä¸ä¼ 空å符串ã |
| | | - 产åäº¤è´§æ¥æä¼ `null` æä¸ä¼ ã |
| | | - ä¸è¦æ ¹æ®æ¡æ¶ååäº§åæ°éæ§å¶åè´§æ°éã |
| | | - ä¸è¦å¨ä¿åæååèªå¨è·³è½¬ç产计åå建ã |
| | | |
| | | ## åãåå»ºæ¡æ¶è®¢å |
| | | |
| | | æ¥å£ï¼ |
| | | |
| | | ```text |
| | | POST /sales/ledger/createFrameworkOrder |
| | | ``` |
| | | |
| | | 请æ±ç¤ºä¾ï¼ |
| | | |
| | | ```json |
| | | { |
| | | "id": 10001, |
| | | "remarks": "ç¬¬ä¸æ¹æ¡æ¶è®¢å", |
| | | "productData": [ |
| | | { |
| | | "parentProductId": 20001, |
| | | "deliveryDate": "2026-09-15" |
| | | }, |
| | | { |
| | | "parentProductId": 20002, |
| | | "deliveryDate": "2026-09-20" |
| | | } |
| | | ] |
| | | } |
| | | ``` |
| | | |
| | | åæ®µè¯´æï¼ |
| | | |
| | | - `id`ï¼ç¶æ¡æ¶åå IDã |
| | | - `remarks`ï¼æ¡æ¶è®¢å夿³¨ã |
| | | - `productData[].parentProductId`ï¼ç¶æ¡æ¶åå产å IDã |
| | | - `productData[].deliveryDate`ï¼å½åæ¡æ¶è®¢å产åäº¤è´§æ¥æï¼å¿
å¡«ã |
| | | - ä¸è¦ä¼ æ°éï¼æ¡æ¶è®¢åäº§åæ°éåºå®ä¸ºç©ºã |
| | | - å䏿¡æ¶è®¢åä¸ä¸è½éå¤éæ©åä¸ä¸ªç¶åå产åã |
| | | |
| | | æåè¿åï¼æ²¿ç¨ç³»ç» `toAjax` è¿åæ ¼å¼ï¼æåæ¶è¡¨ç¤ºæ¡æ¶è®¢åå·²å建ã |
| | | |
| | | å¤±è´¥åºæ¯ï¼ |
| | | |
| | | - æªä¼ ç¶åå IDï¼è¯·éæ©æ¡æ¶ååã |
| | | - ç¶å䏿¯æ¡æ¶ååï¼ç¶å°è´¦ä¸æ¯æ¡æ¶ååã |
| | | - æªéæ©äº§åï¼è¯·å¡«åæ¡æ¶è®¢å产åã |
| | | - æªå¡«åç¶äº§åæäº¤è´§æ¥æï¼æ¡æ¶è®¢å产åå¿
é¡»å
³èç¶äº§åå¹¶å¡«åäº¤è´§æ¥æã |
| | | - ç¶äº§åä¸å±äºè¯¥æ¡æ¶ååï¼æ¡æ¶è®¢å产åä¸å±äºè¯¥æ¡æ¶ååã |
| | | |
| | | ## äºãæ¥è¯¢æ¡æ¶è®¢åå表 |
| | | |
| | | æ¥å£ï¼ |
| | | |
| | | ```text |
| | | GET /sales/ledger/listFrameworkOrders?parentContractId=10001 |
| | | ``` |
| | | |
| | | è¿å示ä¾ï¼ |
| | | |
| | | ```json |
| | | { |
| | | "code": 200, |
| | | "data": [ |
| | | { |
| | | "id": 30001, |
| | | "salesContractNo": "éå®ååå·", |
| | | "contractType": 3, |
| | | "parentContractId": 10001, |
| | | "customerId": 1001, |
| | | "customerName": "客æ·åç§°", |
| | | "projectName": "项ç®åç§°", |
| | | "remarks": "ç¬¬ä¸æ¹æ¡æ¶è®¢å", |
| | | "shippedQuantity": 120 |
| | | } |
| | | ] |
| | | } |
| | | ``` |
| | | |
| | | 说æï¼ |
| | | |
| | | - `contractType` åºå®ä¸º `3`ã |
| | | - `orderedQuantity` ä¸ä½ä¸ºæ°éæ¥æºï¼æ¡æ¶è®¢åä¸è®°å½ååæ°éã |
| | | - `shippedQuantity` æ¯è¯¥æ¡æ¶è®¢å䏿æå·²åè´§åè´§æç»æ°éä¹åã |
| | | - `shippedQuantity` ä»
ç»è®¡ç¶æä¸ºâå·²åè´§âçåè´§åã |
| | | - æ åè´§è®°å½æ¶ `shippedQuantity` è¿å `0`ã |
| | | |
| | | ## å
ãæ¥è¯¢æ¡æ¶åå累计åè´§æ°é |
| | | |
| | | æ¥å£ï¼ |
| | | |
| | | ```text |
| | | GET /sales/ledger/frameworkContractShippedQuantity?parentContractId=10001 |
| | | ``` |
| | | |
| | | è¿å示ä¾ï¼ |
| | | |
| | | ```json |
| | | { |
| | | "code": 200, |
| | | "data": 320 |
| | | } |
| | | ``` |
| | | |
| | | 该æ°éä¸ºç¶æ¡æ¶ååä¸æææ¡æ¶è®¢åãææå·²åè´§åè´§åæç»çæ°éå计ã该æ¥å£åªç¨äºå±ç¤ºç»è®¡ï¼ä¸ç¨äºéå¶åç»åè´§æ°éã |
| | | |
| | | ## ä¸ãå建åè´§ç³è¯· |
| | | |
| | | æ¥å£ï¼ |
| | | |
| | | ```text |
| | | POST /shippingInfo/addReq |
| | | ``` |
| | | |
| | | ç°æå货请æ±ä¸ç»§ç»ä½¿ç¨ï¼ |
| | | |
| | | ```json |
| | | { |
| | | "salesLedgerId": 30001, |
| | | "salesLedgerProductId": 30101, |
| | | "batchNoDetailList": [ |
| | | { |
| | | "stockInventoryId": 5001, |
| | | "batchNo": "RK20260827001", |
| | | "productModelId": 101, |
| | | "quantity": 80 |
| | | } |
| | | ], |
| | | "shippingAddress": "æ¶è´§å°å", |
| | | "type": "ç©æµ" |
| | | } |
| | | ``` |
| | | |
| | | èè°è§åï¼ |
| | | |
| | | - `salesLedgerId` å¿
é¡»ä¸ `salesLedgerProductId` æå±å°è´¦ä¸è´ã |
| | | - `salesLedgerProductId` å¿
é¡»å
³èæ®ééå®ååäº§åææ¡æ¶è®¢å产åã |
| | | - ä¸å
è®¸ä½¿ç¨æ¡æ¶åå产å ID åè´§ã |
| | | - `batchNoDetailList` ä¸çæ°éæ¯æ¬æ¬¡å®é
åè´§æ°éï¼å¿
å¡«ä¸å¤§äºé¶ã |
| | | - åä¸ä¸ªæ¡æ¶è®¢å产åå¯ä»¥å¤æ¬¡æäº¤åè´§ç³è¯·ã |
| | | - ä¸è½åæ¶åå¨å¤ä¸ªâå¾
å®¡æ ¸âæâå®¡æ ¸ä¸âçå产ååè´§ç³è¯·ã |
| | | - å·²åè´§åå²ä¸ä¼é»æ¢ä¸ä¸æ¬¡åæ¹åè´§ã |
| | | - åè´§æ°éä¸ä¸éå®å°è´¦æ°éæ¯è¾ï¼æç»ä»¥åºåæ¹æ¬¡å¯ç¨éååºåæ£åç»æä¸ºåã |
| | | |
| | | ## å
«ãç产计åèè° |
| | | |
| | | åå»ºæ¡æ¶è®¢åæ¶ï¼å端ä¼ä¸ºæ¯ä¸ªæ¡æ¶è®¢å产å**èªå¨çæä¸æ¡ç产计å**ï¼ |
| | | |
| | | - `salesLedgerId`ã`salesLedgerProductId` èªå¨ç»å®å½åæ¡æ¶è®¢åã |
| | | - `productModelId` åæ¡æ¶è®¢å产ååå·ã |
| | | - `qtyRequired`ï¼éæ±æ°éï¼**ç空**ï¼ç产æ°éå¨ç产计åä¸åæ¶å¡«åã |
| | | - `requiredDate`ã`promisedDeliveryDate` åæ¡æ¶è®¢å产åäº¤è´§æ¥æã |
| | | - `source = éå®`ï¼ç¶æä¸ºå¾
ä¸åã |
| | | - æ¡æ¶ååå建æ¶ä¸çæç产计åã |
| | | |
| | | ä¸åçäº§è®¢åæ¶ä½¿ç¨ä¸å请æ±ä¸çæ°éï¼ä¸ä¾èµéå®å°è´¦äº§å `quantity`ï¼ä¹ä¸æ ¡éªè®¡åéæ±æ°éï¼å¯ç»§ç»åæ¹ä¸åã |
| | | |
| | | `validateSalesSource` æ ¡éªè§åä¸åï¼ |
| | | |
| | | - `salesLedgerId` å `salesLedgerProductId` å¿
须忶填åï¼æåæ¶ä¸å¡«åã |
| | | - å
³èé宿¥æºæ¶ï¼éå®äº§åå¿
é¡»å±äºè¯¥éå®å°è´¦ã |
| | | - éå®å°è´¦ç±»ååªè½æ¯æ®ééå®åå `1` ææ¡æ¶è®¢å `3`ã |
| | | - ä¸è½ç´æ¥å
³èæ¡æ¶åå `2`ã |
| | | - `productModelId` å¿
é¡»ä¸éå®äº§ååå·ä¸è´ã |
| | | |
| | | ## ä¹ã页é¢äº¤äºå»ºè®® |
| | | |
| | | ### æ¡æ¶ååé¡µé¢ |
| | | |
| | | - ååç±»åéæ©âæ¡æ¶ååâåéèæç¦ç¨ååæ°éè¾å
¥ã |
| | | - éèæç¦ç¨ååçº§äº¤è´§æ¥æã |
| | | - 产åæç»éèæ°éåäº¤è´§æ¥æè¾å
¥ã |
| | | - ä¿ååæä¾âåå»ºæ¡æ¶è®¢åâå
¥å£ã |
| | | |
| | | ### æ¡æ¶è®¢åé¡µé¢ |
| | | |
| | | - å±ç¤ºç¶æ¡æ¶ååä¿¡æ¯ï¼åªè¯»ã |
| | | - 产åéæ©èå´ä¸ºç¶æ¡æ¶åå产åã |
| | | - æ¯ä¸ªäº§ååªå¡«åäº¤è´§æ¥æã |
| | | - éèæ°éè¾å
¥ã |
| | | - ä¿åæååå±ç¤ºè®¢åç¼å·å订å产åå表ã |
| | | |
| | | ### åè´§é¡µé¢ |
| | | |
| | | - éæ©éå®ååæ¶ï¼æ¡æ¶ååä¸è½ä½ä¸ºç´æ¥åè´§å°è´¦ã |
| | | - æ¡æ¶åååºå±å¼éæ©å
¶ä¸æ¡æ¶è®¢åï¼åéæ©æ¡æ¶è®¢å产åã |
| | | - æ¯æ¬¡åè´§å¡«åå®é
åè´§æ°éååºåæ¹æ¬¡ã |
| | | - å·²åè´§åä»å
è®¸åæ¬¡å建æ°çåè´§æ¹æ¬¡ã |
| | | |
| | | ### ç产计åé¡µé¢ |
| | | |
| | | - æ¡æ¶è®¢åå建åèªå¨çæç产计åè®°å½ï¼éæ±æ°é为空ï¼ã |
| | | - çäº§è®¡åæ°éå¨ç产计åä¸åæ¶åç¬å¡«åã |
| | | - ä¸ä»éå®å°è´¦äº§åæ°éåå¡«çäº§è®¡åæ°éã |
| | | |
| | | ## åãèè°éªæ¶æµç¨ |
| | | |
| | | 1. åå»ºä¸æ¡æ¡æ¶ååï¼äº§åä¸å¡«åæ°éåäº¤è´§æ¥æã |
| | | 2. æ¥è¯¢æ¡æ¶åå详æ
ï¼ç¡®è®¤ååç±»å为 `2`ã |
| | | 3. åºäºå䏿¡æ¶åååå»ºä¸¤ä¸ªæ¡æ¶è®¢åã |
| | | 4. ç¡®è®¤ä¸¤ä¸ªæ¡æ¶è®¢åå为 `contractType = 3`ï¼äº§åæ°é为空ã |
| | | 5. åå»ºæ¡æ¶è®¢ååï¼ç产计åå表åºåºç°å¯¹åºè®¡åï¼`qtyRequired` 为空ï¼`source = éå®`ï¼éæ±æ¥æä¸ºäº§åäº¤è´§æ¥æã |
| | | 6. 为第ä¸ä¸ªæ¡æ¶è®¢å产åå建第ä¸ç¬åè´§ç³è¯·ã |
| | | 7. å®¡æ ¸å¹¶å®æåè´§ã |
| | | 8. 为åä¸ä¸ªæ¡æ¶è®¢å产åå建第äºç¬åè´§ç³è¯·ã |
| | | 9. æ¥è¯¢æ¡æ¶è®¢åå表ï¼ç¡®è®¤ `shippedQuantity` 为两次åè´§æ°éä¹åã |
| | | 10. æ¥è¯¢æ¡æ¶åå累计åè´§æ°éï¼ç¡®è®¤å
å«æææ¡æ¶è®¢åçå·²åè´§æ°éã |
| | | 11. 对èªå¨çæçç产计åå¡«åä¸åæ°éå¹¶ä¸åï¼ç¡®è®¤ä¸ä¾èµéå®äº§åæ°éã |
| | | 12. å°è¯ç´æ¥ä½¿ç¨æ¡æ¶åå产ååè´§ï¼æ¥å£åºè¿åé误ã |
| | | 13. å°è¯ä¸ºåä¸äº§ååæ¶æäº¤ä¸¤ç¬å¾
å®¡æ ¸åè´§ç³è¯·ï¼ç¬¬äºç¬åºè¢«æç»ã |
| | | |
| | | ## åä¸ãå½åå端éªè¯ç¶æ |
| | | |
| | | å·²å®æï¼ |
| | | |
| | | - æ¡æ¶ååãæ¡æ¶è®¢åæ°æ®å段ã |
| | | - æ¡æ¶è®¢åå建æ¥å£ã |
| | | - æ¡æ¶è®¢åå建æ¶èªå¨çæç产计åï¼éæ±æ°éç空ï¼ã |
| | | - æ¡æ¶è®¢åå表æ¥å£ã |
| | | - æ¡æ¶åå累计已åè´§æ°éæ¥å£ã |
| | | - æ¡æ¶åå产åç´æ¥åè´§æ¦æªã |
| | | - ç产计åé宿¥æºå½å±æ ¡éªã |
| | | - æ°æ®åºè¿ç§»åç®æ æ°æ®åºå段éªè¯ã |
| | | |
| | | 说æï¼å端已éè¿ `mvn compile` ç¼è¯éªè¯ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 设å¤åºåï¼è½¦é´/ä½ç½®ï¼å端èè°ææ¡£ |
| | | |
| | | ## ä¸ãä¸å¡è¯´æ |
| | | |
| | | 设å¤å°è´¦éæè½¦é´/åºåæ±æ»è®¾å¤ï¼è½¦é´/ä½ç½®å¯èªè¡æ°å¢ï¼ä¸æ¯æåç¶çº§éå½ï¼ |
| | | |
| | | - æ°å¢ç¬ç«â设å¤åºåâæ¦å¿µï¼è½¦é´ãåºåãä½ç½®ç»ä¸ä½ä¸ºåºåèç¹ã |
| | | - åºåæ¯æä»»æå±çº§ç¶åéå½ã |
| | | - 设å¤å°è´¦å
³èä¸ä¸ªåºåï¼`area_id`ï¼ã |
| | | - æåºåæ±æ»è®¾å¤æ¶ï¼æ±æ»è¯¥åºååå
¶ææå级åºåç设å¤ã |
| | | - 设å¤å°è´¦é¡µé¢å»ºè®®éç¨â左侧åºåæ + å³ä¾§è®¾å¤å表âå½¢å¼ã |
| | | |
| | | ## äºãæ°æ®åºè¿ç§» |
| | | |
| | | æ§è¡ `sql/migration_device_area.sql`ï¼å·²åå¹çå¤çï¼`device_area` 表已å卿¶è·³è¿å»ºè¡¨ã`area_id` åå·²å卿¶è·³è¿å åï¼å¯å®å
¨é夿§è¡ï¼ï¼å
å®¹ï¼ |
| | | |
| | | 1. æ°å¢è¡¨ `device_area`ï¼ä¸»é®æ å
¶å®çº¦æï¼ï¼ |
| | | |
| | | | åæ®µ | ç±»å | 说æ | |
| | | | --- | --- | --- | |
| | | | `id` | bigint | 主é®èªå¢ | |
| | | | `name` | varchar(255) | åºå/车é´/ä½ç½®åç§° | |
| | | | `parent_id` | bigint | ç¶çº§åºåIDï¼æ ¹èç¹ä¸º NULL | |
| | | | `ancestors` | varchar(1000) | ç¥çº§è·¯å¾ï¼å¦ `1,2,3` | |
| | | | `sort` | int | æåº | |
| | | | `dept_id` | bigint | é¨é¨IDï¼å¯éï¼ | |
| | | | `tenant_id` | bigint | ç§æ·ID | |
| | | | `create_user` | int | å建人 | |
| | | | `create_time` | datetime | å建æ¶é´ | |
| | | | `update_user` | int | æ´æ°äºº | |
| | | | `update_time` | datetime | æ´æ°æ¶é´ | |
| | | |
| | | 2. `device_ledger` å¢å `area_id bigint NULL`ï¼è®¾å¤åºåIDï¼ã |
| | | |
| | | ## ä¸ãæ¥å£å表 |
| | | |
| | | | æ¥å£ | æ¹æ³ | è·¯å¾ | 说æ | |
| | | | --- | --- | --- | --- | |
| | | | æ¥è¯¢åºåæ | GET | `/device/area/tree` | è¿åæ å½¢åºååéå½è®¾å¤æ°é | |
| | | | æ°å¢åºå | POST | `/device/area` | æ°å¢åºå/车é´/ä½ç½® | |
| | | | ä¿®æ¹åºå | PUT | `/device/area` | ä¿®æ¹åºååç§°/ç¶çº§/æåº | |
| | | | å é¤åºå | DELETE | `/device/area/{ids}` | å é¤åºå | |
| | | | 设å¤å表 | GET | `/device/ledger/page` | æ¯ææåºåéå½çéï¼æ°å¢ `areaId` åæ°ï¼ | |
| | | | 设å¤éæ©å表 | GET | `/device/ledger/getDeviceLedger` | å·¡æ£é设å¤ç¨ï¼æ¯æ `areaId` éå½çéï¼è¿å `areaName` | |
| | | |
| | | ## åãåºåæ æ¥å£ |
| | | |
| | | ### æ¥è¯¢åºåæ |
| | | |
| | | ```text |
| | | GET /device/area/tree |
| | | ``` |
| | | |
| | | è¿å示ä¾ï¼ |
| | | |
| | | ```json |
| | | { |
| | | "code": 200, |
| | | "msg": "æä½æå", |
| | | "data": [ |
| | | { |
| | | "id": 1, |
| | | "parentId": null, |
| | | "label": "ä¸å·è½¦é´", |
| | | "deviceCount": 8, |
| | | "children": [ |
| | | { |
| | | "id": 2, |
| | | "parentId": 1, |
| | | "label": "å²ååº", |
| | | "deviceCount": 5, |
| | | "children": [] |
| | | }, |
| | | { |
| | | "id": 3, |
| | | "parentId": 1, |
| | | "label": "è£
é
åº", |
| | | "deviceCount": 3, |
| | | "children": [] |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | } |
| | | ``` |
| | | |
| | | åæ®µè¯´æï¼ |
| | | |
| | | - `id`ï¼åºåIDã |
| | | - `parentId`ï¼ç¶çº§åºåIDï¼æ ¹èç¹ä¸º `null`ã |
| | | - `label`ï¼åºåæ¾ç¤ºåç§°ï¼å端 el-tree ç´æ¥ç¨ `label` 渲æã |
| | | - `deviceCount`ï¼**该åºååææå级åºå**çè®¾å¤æ°éï¼é彿±æ»ï¼ã |
| | | |
| | | åç«¯å»ºè®®ç´æ¥ç¨äº `el-tree`ï¼ |
| | | |
| | | ```html |
| | | <el-tree |
| | | :data="areaTree" |
| | | node-key="id" |
| | | :props="{ label: 'label', children: 'children' }" |
| | | @node-click="onAreaClick" |
| | | /> |
| | | ``` |
| | | |
| | | ç¹å»èç¹æ¶ï¼æ `id` ä½ä¸º `areaId` ä¼ ç»è®¾å¤å表æ¥è¯¢ã |
| | | |
| | | ## äºãæ°å¢åºå |
| | | |
| | | ```text |
| | | POST /device/area |
| | | Content-Type: application/json |
| | | ``` |
| | | |
| | | 请æ±ä½ï¼ |
| | | |
| | | ```json |
| | | { |
| | | "name": "äºå·è½¦é´", |
| | | "parentId": null, |
| | | "sort": 1 |
| | | } |
| | | ``` |
| | | |
| | | - `name`ï¼å¿
å¡«ï¼åºååç§°ã |
| | | - `parentId`ï¼ç¶çº§åºåIDï¼åå»ºæ ¹èç¹æ¶ä¼ `null` æä¸ä¼ ã |
| | | - `sort`ï¼æåºï¼å¯ç©ºã |
| | | |
| | | æåè¿å `AjaxResult.success()`ã |
| | | |
| | | å¤±è´¥åºæ¯ï¼ |
| | | |
| | | - å称为空ï¼`åºååç§°ä¸è½ä¸ºç©º`ã |
| | | - ç¶çº§åºåä¸åå¨ï¼`ç¶çº§åºåä¸åå¨`ã |
| | | |
| | | ## å
ãä¿®æ¹åºå |
| | | |
| | | ```text |
| | | PUT /device/area |
| | | Content-Type: application/json |
| | | ``` |
| | | |
| | | 请æ±ä½ï¼ |
| | | |
| | | ```json |
| | | { |
| | | "id": 2, |
| | | "name": "å²å车é´", |
| | | "parentId": 1, |
| | | "sort": 1 |
| | | } |
| | | ``` |
| | | |
| | | æ¯æä¿®æ¹åç§°ãç¶çº§ï¼æå¨è°æ´å±çº§ï¼ãæåºãå端èªå¨ç»´æ¤ `ancestors` ç¥çº§è·¯å¾ï¼ä¿®æ¹ç¶çº§æ¶å端æ éä¼ `ancestors`ã |
| | | |
| | | å¤±è´¥åºæ¯ï¼ |
| | | |
| | | - æªä¼ IDï¼`åºåIDä¸è½ä¸ºç©º`ã |
| | | - åºåä¸åå¨ï¼`åºåä¸åå¨`ã |
| | | - æè½½å°èªèº«ï¼`ä¸è½å°åºåæè½½å°èªèº«`ã |
| | | - æè½½å°èªå·±çå级ï¼`ä¸è½å°åºåæè½½å°èªå·±çå级ä¸`ï¼é²æ¢å¾ªç¯ï¼ã |
| | | |
| | | ## ä¸ãå é¤åºå |
| | | |
| | | ```text |
| | | DELETE /device/area/{ids} |
| | | ``` |
| | | |
| | | 示ä¾ï¼ |
| | | |
| | | ```text |
| | | DELETE /device/area/2,3 |
| | | ``` |
| | | |
| | | æåè¿å `AjaxResult.success()`ã |
| | | |
| | | å¤±è´¥åºæ¯ï¼ |
| | | |
| | | - 该åºååå¨å级åºåï¼è¯·å
å é¤å级ã |
| | | - 该åºåä¸åå¨è®¾å¤ï¼è¯·å
ç§»é¤è®¾å¤å
³èã |
| | | |
| | | å端建议ï¼å é¤åå¼¹çªç¡®è®¤ï¼è¥å端è¿åä¸è¿°é误æç¤ºï¼ç´æ¥å±ç¤ºç»ç¨æ·ã |
| | | |
| | | ## å
«ã设å¤å表æåºåçé |
| | | |
| | | å¨åæè®¾å¤å°è´¦å页æ¥å£å¢å `areaId` åæ°ï¼ |
| | | |
| | | ```text |
| | | GET /device/ledger/page?areaId=1&pageNum=1&pageSize=10 |
| | | ``` |
| | | |
| | | æ°å¢è¡ä¸ºï¼ |
| | | |
| | | - è¿ååæ®µæ°å¢ `areaId`ã`areaName`ï¼åºååç§°ï¼ï¼ä¾å表å±ç¤ºã |
| | | - å½ `areaId` æå¼æ¶ï¼æ¥è¯¢è¯¥åºå**åå
¶ææå级åºå**ä¸ç设å¤ï¼éè¿ `ancestors` ç¥çº§å¹é
ï¼å端æ éå
³å¿ï¼ã |
| | | |
| | | 示ä¾è¿åè®°å½ï¼ |
| | | |
| | | ```json |
| | | { |
| | | "records": [ |
| | | { |
| | | "id": 100, |
| | | "deviceName": "æ¶²åæº", |
| | | "deviceModel": "YQ-100", |
| | | "areaId": 2, |
| | | "areaName": "å²ååº", |
| | | "...": "..." |
| | | } |
| | | ] |
| | | } |
| | | ``` |
| | | |
| | | ## ä¹ã页é¢äº¤äºå»ºè®® |
| | | |
| | | ### 设å¤å°è´¦å表页 |
| | | |
| | | - 左侧å±ç¤ºåºåæ ï¼`/device/area/tree`ï¼ã |
| | | - æ é¡¶åºå®ä¸ä¸ªâå
¨é¨è®¾å¤âå
¥å£ï¼ç¹å»æ¶ `areaId` ä¼ ç©ºï¼æ¥è¯¢ææè®¾å¤ã |
| | | - ç¹å»ä»»æåºåèç¹ï¼å³ä¾§è®¾å¤å表æè¯¥åºååå
¶å级éå½çéã |
| | | - å表å¢å âæå±åºåâåï¼æ¾ç¤º `areaName`ã |
| | | - æ°å¢/ç¼è¾è®¾å¤æ¶ï¼ç¨åºåæ éæ©å¨ï¼å¯çº§èå±å¼ï¼éæ©æå±åºåï¼æäº¤æ¶ä¼ `areaId`ã |
| | | |
| | | ### åºå管ç |
| | | |
| | | - å¯å¨åºåæ ä¸ç´æ¥âæ°å¢å级/æ°å¢å级âèç¹ã |
| | | - æ¯æææ½è°æ´ç¶åå
³ç³»ï¼è°ç¨ PUT ä¼ æ° `parentId`ï¼ã |
| | | - å 餿é®å¨æ åçº§ä¸æ 设å¤å
³èæ¶æå¯ç¨ã |
| | | |
| | | ### å·¡æ£éæ©è®¾å¤ |
| | | |
| | | å·¡æ£ä»»å¡ï¼`/inspectionTask/addOrEditInspectionTask`ï¼ä¸å®æ¶å·¡æ£ï¼`/timingTask/addOrEditTimingTask`ï¼å建/ç¼è¾æ¶éæ©å·¡æ£è®¾å¤ï¼å»ºè®®æ¹ä¸ºæè½¦é´/ä½ç½®çéï¼ |
| | | |
| | | - å¼¹çªå·¦ä¾§å±ç¤ºåºåæ ï¼`GET /device/area/tree`ï¼ï¼é¡¶é¨åºå®âå
¨é¨è®¾å¤âã |
| | | - ç¹å»åºåèç¹åï¼å³ä¾§è° `GET /device/ledger/getDeviceLedger?areaId=x` å 载该åºåï¼å«å级ï¼è®¾å¤å表ã |
| | | - éä¸è®¾å¤ååå¡« `taskId`ï¼è®¾å¤IDï¼ä¸ `taskName`ï¼è®¾å¤åç§°ï¼ï¼éå·¡æ£ä»»å¡ä¸èµ·æäº¤ã |
| | | - `getDeviceLedger` è¿å示ä¾ï¼ |
| | | |
| | | ```json |
| | | [ |
| | | { |
| | | "id": 100, |
| | | "deviceName": "æ¶²åæº", |
| | | "deviceModel": "YQ-100", |
| | | "deviceBrand": "XX", |
| | | "type": "ååæº", |
| | | "areaId": 2, |
| | | "areaName": "å²ååº" |
| | | } |
| | | ] |
| | | ``` |
| | | |
| | | - `areaId` ä¸ä¼ æ¶è¿åå
¨é¨è®¾å¤ï¼å
¼å®¹æ§è°ç¨ï¼ã |
| | | |
| | | å端æ°å¢æ ¡éªï¼å·¡æ£ä»»å¡/宿¶å·¡æ£ä¿åæ¶ï¼è¥ `taskId` 对åºè®¾å¤ä¸åå¨ï¼è¿å `æé设å¤ä¸åå¨ï¼è¯·éæ°éæ©`ã |
| | | |
| | | ## åãèè°éªæ¶æµç¨ |
| | | |
| | | 1. å建ä¸ä¸ªæ ¹åºåâä¸å·è½¦é´âã |
| | | 2. å¨âä¸å·è½¦é´âä¸å建âå²ååºââè£
é
åºâã |
| | | 3. æ¥è¯¢åºåæ ï¼ç¡®è®¤å±çº§æ£ç¡®ï¼`deviceCount` å
¨é¨ä¸º 0ã |
| | | 4. æ°å¢ 2 å°è®¾å¤æå°âå²ååºâï¼1 å°æå°âè£
é
åºâã |
| | | 5. æ¥è¯¢åºåæ ï¼ç¡®è®¤âå²ååºâ`deviceCount` 为 2ï¼âè£
é
åºâ为 1ï¼âä¸å·è½¦é´â为 3ï¼é彿±æ»ï¼ã |
| | | 6. 设å¤åè¡¨ä¼ `areaId=ä¸å·è½¦é´`ï¼ç¡®è®¤è¿å 3 å°è®¾å¤ï¼å«å级ï¼ã |
| | | 7. 设å¤åè¡¨ä¼ `areaId=å²ååº`ï¼ç¡®è®¤åªè¿å 2 å°ã |
| | | 8. å°è¯å é¤âä¸å·è½¦é´âï¼åºæ¥âåå¨å级åºåâã |
| | | 9. å°è¯å é¤âå²ååºâï¼åºæ¥âåºåä¸åå¨è®¾å¤âã |
| | | 10. å°âè£
é
åºâç¶çº§æ¹ä¸ºâå²ååºâï¼åæ¥åºåæ ï¼ç¡®è®¤å±çº§ååå½ä¸å¾ªç¯æ ¡éªä¸å¤±è´¥ã |
| | | 11. æ°å¢/ç¼è¾è®¾å¤æ¶éæ©åºåï¼ç¡®è®¤ `areaId` æ£ç¡®ä¿åä¸å表æ¾ç¤º `areaName`ã |
| | | |
| | | ### å·¡æ£é设å¤èè° |
| | | |
| | | 1. å·¡æ£ä»»å¡æ°å»ºï¼ç¹é设å¤å¼¹çªï¼ç¡®è®¤å·¦ä¾§åºç°åºåæ ã |
| | | 2. ç¹å»âä¸å·è½¦é´âï¼å³ä¾§åºæ¾ç¤ºè¯¥è½¦é´ï¼å«å级ï¼å
¨é¨è®¾å¤ã |
| | | 3. ç¹å»âå²ååºâï¼å³ä¾§åªæ¾ç¤ºå²ååºè®¾å¤ã |
| | | 4. éä¸è®¾å¤åæäº¤ï¼å·¡æ£ä»»å¡ä¿åæåï¼`taskId`/`taskName` æ£ç¡®åæ¾ã |
| | | 5. æå·¥æé ä¸ä¸ªä¸åå¨ç设å¤IDæäº¤ï¼åºè¿å `æé设å¤ä¸åå¨ï¼è¯·éæ°éæ©`ã |
| | | 6. 宿¶å·¡æ£é¡µé¢æ§è¡åæ ·æä½ï¼è¡ä¸ºä¸è´ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 计éå¨å
·å°è´¦æ¹é导å
¥åç«¯å¯¹æ¥ææ¡£ |
| | | |
| | | ## ä¸ãåè½è¯´æ |
| | | |
| | | 计éå¨å
·å°è´¦æ¯æéè¿ Excel æä»¶æ¹éæ°å¢æ°æ®ã |
| | | |
| | | æ¬åè½å
å«ï¼ |
| | | |
| | | - ä¸è½½ Excel 导å
¥æ¨¡æ¿ |
| | | - ä¸ä¼ Excel æä»¶æ¹é导å
¥ |
| | | - 导å
¥åè¿è¡æ°æ®æ ¡éª |
| | | - æ ¡éªå¤±è´¥æ¶æ´æ¹æ°æ®ä¸åå
¥æ°æ®åº |
| | | - èªå¨ä½¿ç¨å½åç»å½ç¨æ·åå½åç§æ·ä¿¡æ¯ |
| | | - èªå¨è®¡ç®é¢è®¡ä¸æ¬¡æ£å®æ¥æ |
| | | |
| | | æ¥å£åºç¡è·¯å¾ï¼ |
| | | |
| | | ```text |
| | | /measuringInstrumentLedger |
| | | ``` |
| | | |
| | | æ¥å£è¯·æ±éè¦æºå¸¦é¡¹ç®ç°æç»å½è®¤è¯ä¿¡æ¯ã |
| | | |
| | | ## äºãä¸è½½å¯¼å
¥æ¨¡æ¿ |
| | | |
| | | ### 请æ±ä¿¡æ¯ |
| | | |
| | | ```text |
| | | POST /measuringInstrumentLedger/downloadTemplate |
| | | ``` |
| | | |
| | | ### 请æ±åæ° |
| | | |
| | | æ ã |
| | | |
| | | ### åç«¯ç¤ºä¾ |
| | | |
| | | ```javascript |
| | | const response = await request({ |
| | | url: '/measuringInstrumentLedger/downloadTemplate', |
| | | method: 'post', |
| | | responseType: 'blob' |
| | | }) |
| | | |
| | | const blob = new Blob([response], { |
| | | type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' |
| | | }) |
| | | const link = document.createElement('a') |
| | | link.href = URL.createObjectURL(blob) |
| | | link.download = '计éå¨å
·å°è´¦å¯¼å
¥æ¨¡æ¿.xlsx' |
| | | link.click() |
| | | URL.revokeObjectURL(link.href) |
| | | ``` |
| | | |
| | | 项ç®å·²æè¯·æ±å°è£
çï¼æé¡¹ç®è¯·æ±å°è£
æ¹å¼è®¾ç½® `responseType: 'blob'` å³å¯ã |
| | | |
| | | ## ä¸ãæ¹é导å
¥ |
| | | |
| | | ### 请æ±ä¿¡æ¯ |
| | | |
| | | ```text |
| | | POST /measuringInstrumentLedger/import |
| | | ``` |
| | | |
| | | ### 请æ±ç±»å |
| | | |
| | | ```text |
| | | multipart/form-data |
| | | ``` |
| | | |
| | | ### 请æ±åæ° |
| | | |
| | | | åæ°å | ç±»å | å¿
å¡« | 说æ | |
| | | |---|---|---|---| |
| | | | file | File | æ¯ | Excel æä»¶ï¼ä»
æ¯æ `.xls` å `.xlsx` | |
| | | |
| | | ### åç«¯ç¤ºä¾ |
| | | |
| | | ```javascript |
| | | const formData = new FormData() |
| | | formData.append('file', file) |
| | | |
| | | const result = await request({ |
| | | url: '/measuringInstrumentLedger/import', |
| | | method: 'post', |
| | | data: formData, |
| | | headers: { |
| | | 'Content-Type': 'multipart/form-data' |
| | | } |
| | | }) |
| | | ``` |
| | | |
| | | 注æï¼ä¸è¦å°æä»¶è½¬æ JSONï¼ä¹ä¸è¦ä½¿ç¨ `@RequestBody` æ¹å¼æäº¤ã |
| | | |
| | | ## åãExcel 模æ¿å |
| | | |
| | | 模æ¿ç¬¬ä¸è¡ä¸ºè¡¨å¤´ï¼æ°æ®ä»ç¬¬äºè¡å¼å§ã |
| | | |
| | | | Excel 表头 | ç±»å | å¿
å¡« | 说æ | |
| | | |---|---|---|---| |
| | | | 计éå¨å
·ç¼å· | ææ¬ | æ¯ | å½åç§æ·å
ä¸è½éå¤ | |
| | | | 计éå¨å
·åç§° | ææ¬ | æ¯ | ä¸è½å¡«åç©ºå¼ | |
| | | | è§æ ¼åå· | ææ¬ | å¦ | 计éå¨å
·è§æ ¼æåå· | |
| | | | æè¿ä¸æ¬¡æ£å®æ¥æ | æ¥æ | å¦ | å»ºè®®æ ¼å¼ï¼`yyyy-MM-dd` | |
| | | | æ£å®æææ | æ´æ° | å¦ | åä½ï¼å¤©ï¼å¡«åæ¶å¿
é¡»å¤§äº 0 | |
| | | | å½å
¥æ¥æ | æ¥æ | å¦ | å»ºè®®æ ¼å¼ï¼`yyyy-MM-dd`ï¼ä¸å¡«åæ¶ä½¿ç¨å½åæ¥æ | |
| | | | åä½ | ææ¬ | å¦ | 使ç¨åä½ | |
| | | | é¨é¨ID | æ´æ° | å¦ | é¨é¨ ID | |
| | | | å®è£
ä½ç½® | ææ¬ | å¦ | 计éå¨å
·å®è£
ä½ç½® | |
| | | | æ£å®å¨æ | ææ¬ | å¦ | æ£å®å¨æ | |
| | | |
| | | ### æ¥æåæææè§å |
| | | |
| | | å½åæ¶å¡«å以ä¸ä¸¤åæ¶ï¼å端èªå¨è®¡ç®é¢è®¡ä¸æ¬¡æ£å®æ¥æï¼ |
| | | |
| | | ```text |
| | | é¢è®¡ä¸æ¬¡æ£å®æ¥æ = æè¿ä¸æ¬¡æ£å®æ¥æ + æ£å®æææï¼å¤©ï¼ |
| | | ``` |
| | | |
| | | Excel ä¸éè¦å¡«åâé¢è®¡ä¸æ¬¡æ£å®æ¥æâã |
| | | |
| | | 以ä¸å段ä¸éè¦ãä¹ä¸å
许éè¿ Excel ç»´æ¤ï¼ |
| | | |
| | | - ID |
| | | - å½å
¥äºº ID |
| | | - å½å
¥äººåç§° |
| | | - ç§æ· ID |
| | | - ç¶æ |
| | | - å建人ãå建æ¶é´ |
| | | - ä¿®æ¹äººãä¿®æ¹æ¶é´ |
| | | |
| | | è¿äºå段ç±åç«¯æ ¹æ®å½åç»å½ä¿¡æ¯æç³»ç»è§åèªå¨å¤çã |
| | | |
| | | ## äºãæåè¿å |
| | | |
| | | æåæ¶è¿å项ç®ç»ä¸æåç»æï¼æç¤ºä¿¡æ¯ç±»ä¼¼ï¼ |
| | | |
| | | ```json |
| | | { |
| | | "code": 200, |
| | | "msg": "æå导å
¥ 10 æ¡æ°æ®" |
| | | } |
| | | ``` |
| | | |
| | | åç«¯å»ºè®®ï¼ |
| | | |
| | | 1. å
³éä¸ä¼ å¼¹çªã |
| | | 2. æç¤º `msg` å
容ã |
| | | 3. å·æ°å°è´¦å页å表ã |
| | | |
| | | ## å
ã失败è¿å |
| | | |
| | | ### 1. æªéæ©æä»¶ |
| | | |
| | | ```json |
| | | { |
| | | "code": 500, |
| | | "msg": "请ä¸ä¼ Excel æä»¶" |
| | | } |
| | | ``` |
| | | |
| | | ### 2. æä»¶æ ¼å¼ä¸æ£ç¡® |
| | | |
| | | ```json |
| | | { |
| | | "code": 500, |
| | | "msg": "åªæ¯æå¯¼å
¥ xls æ xlsx æä»¶" |
| | | } |
| | | ``` |
| | | |
| | | ### 3. æä»¶æ²¡ææ°æ® |
| | | |
| | | ```json |
| | | { |
| | | "code": 500, |
| | | "msg": "Excel 䏿²¡æå¯å¯¼å
¥çæ°æ®" |
| | | } |
| | | ``` |
| | | |
| | | ### 4. æ°æ®æ ¡éªå¤±è´¥ |
| | | |
| | | ```json |
| | | { |
| | | "code": 500, |
| | | "msg": "导å
¥æ ¡éªå¤±è´¥ï¼è®¡éå¨å
·ç¼å·ä¸è½ä¸ºç©ºï¼è®¡éå¨å
·ç¼å·å¨ Excel ä¸éå¤ï¼æ£å®æææå¿
é¡»å¤§äº 0" |
| | | } |
| | | ``` |
| | | |
| | | å¸¸è§æ ¡éªæç¤ºï¼ |
| | | |
| | | | æç¤º | å¤ç建议 | |
| | | |---|---| |
| | | | 计éå¨å
·ç¼å·ä¸è½ä¸ºç©º | è¡¥å
â计éå¨å
·ç¼å·â | |
| | | | 计éå¨å
·åç§°ä¸è½ä¸ºç©º | è¡¥å
â计éå¨å
·åç§°â | |
| | | | 计éå¨å
·ç¼å·å¨ Excel ä¸éå¤ | å é¤æä¿®æ¹éå¤ç¼å· | |
| | | | 计éå¨å
·ç¼å·å·²åå¨ï¼xxx | ä¿®æ¹è¯¥ç¼å·ï¼é¿å
ä¸å½åç§æ·å·²æå°è´¦éå¤ | |
| | | | æ£å®æææå¿
é¡»å¤§äº 0 | å¡«åå¤§äº 0 çæ´æ° | |
| | | | 导å
¥å¤±è´¥ï¼è¯·æ£æ¥ Excel å
容 | æ£æ¥æä»¶æ ¼å¼ã表头ååå
æ ¼ç±»å | |
| | | |
| | | ## ä¸ã页é¢äº¤äºå»ºè®® |
| | | |
| | | 建议å¨å°è´¦å表页é¢å¢å 两个æé®ï¼ |
| | | |
| | | - ä¸è½½æ¨¡æ¿ |
| | | - æ¹é导å
¥ |
| | | |
| | | æ¨èäº¤äºæµç¨ï¼ |
| | | |
| | | 1. ç¨æ·ç¹å»âä¸è½½æ¨¡æ¿âã |
| | | 2. å端ä¸è½½å¹¶ä¿å Excel 模æ¿ã |
| | | 3. ç¨æ·æç
§æ¨¡æ¿å¡«åæ°æ®ã |
| | | 4. ç¨æ·ç¹å»âæ¹é导å
¥âã |
| | | 5. å¼¹åºæä»¶éæ©æ¡ï¼ä»
å
è®¸éæ© `.xls`ã`.xlsx` æä»¶ã |
| | | 6. éæ©æä»¶åä¸ä¼ ã |
| | | 7. ä¸ä¼ æé´æé®æ¾ç¤ºå è½½ç¶æï¼å¹¶ç¦æ¢éå¤æäº¤ã |
| | | 8. æ ¹æ®æ¥å£è¿åç `code` å `msg` æ¾ç¤ºç»æã |
| | | 9. 导å
¥æååå·æ°å表ã |
| | | 10. 导å
¥å¤±è´¥æ¶ä¿çå¼¹çªï¼æ¹ä¾¿ç¨æ·éæ°éæ©æä»¶ã |
| | | |
| | | ## å
«ãå端æä»¶éæ©éå¶ |
| | | |
| | | ```javascript |
| | | const accept = '.xls,.xlsx' |
| | | ``` |
| | | |
| | | å端å¯ä»¥å
æ ¡éªæä»¶æ©å±åï¼ä½åç«¯æ ¡éªä»ç¶å¿
é¡»ä¿çã |
| | | |
| | | å»ºè®®åæ¶æ ¡éªï¼ |
| | | |
| | | - æä»¶ä¸è½ä¸ºç©º |
| | | - æä»¶æ©å±å为 `.xls` æ `.xlsx` |
| | | - æä»¶å¤§å°ä¸è¶
è¿é¡¹ç®ç»ä¸ä¸ä¼ éå¶ |
| | | |
| | | ## ä¹ãéè¦æ³¨æäºé¡¹ |
| | | |
| | | 1. 䏿¬¡å¯¼å
¥ä¸åªè¦æä¸æ¡æ°æ®æ ¡éªå¤±è´¥ï¼æ´æ¹æ°æ®é½ä¸ä¼åå
¥ã |
| | | 2. 计éå¨å
·ç¼å·æå½åç§æ·æ ¡éªï¼ä¸åç§æ·ä¹é´å¯ä»¥ä½¿ç¨ç¸åç¼å·ã |
| | | 3. Excel ä¸çå½å
¥äººãç§æ·ãç¶æçåæ®µä¸ä¼ä½ä¸ºææå¯¼å
¥æ°æ®ä½¿ç¨ã |
| | | 4. âæè¿ä¸æ¬¡æ£å®æ¥æâåâæ£å®æææâå¯ä»¥ä¸å¡«åï¼å¦æé½å¡«åï¼å端èªå¨è®¡ç®é¢è®¡ä¸æ¬¡æ£å®æ¥æã |
| | | 5. Excel 表头å¿
é¡»ä½¿ç¨æ¨¡æ¿ä¸çåç§°ï¼ä¸è¦èªè¡ä¿®æ¹è¡¨å¤´æåã |
| | | 6. 导å
¥æ¥å£ä¸æ¯ JSON æ¥å£ï¼å¿
é¡»ä½¿ç¨ `FormData` ä¸ä¼ æä»¶ã |
| | | 7. å½åä»åºä¸å
å«å端代ç ï¼ä»¥ä¸ä»£ç 为å端对æ¥ç¤ºä¾ï¼å
·ä½è¯·æ±å½æ°åç§°æå端项ç®å®é
å°è£
è°æ´ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | # 设å¤ä¿å
»å¹´åº¦ä¿å
»å端èè°è¯´æ |
| | | |
| | | ## 1. åæ´è¯´æ |
| | | |
| | | 设å¤ä¿å
»å®æ¶ä»»å¡æ°å¢â年度ä¿å
»âä»»å¡é¢çã |
| | | |
| | | - é¢çç¼ç ï¼`YEARLY` |
| | | - å端æ¾ç¤ºåç§°ï¼`年度ä¿å
»` |
| | | - åºç¡è·¯å¾ï¼`/deviceMaintenanceTask` |
| | | - éç¨æ¥å£ï¼æ°å¢ãä¿®æ¹ãæ¥è¯¢è®¾å¤ä¿å
»å®æ¶ä»»å¡ |
| | | |
| | | ## 2. æ¥å£æ¸
å |
| | | |
| | | | è¯·æ±æ¹å¼ | æ¥å£ | 说æ | |
| | | |---|---|---| |
| | | | `GET` | `/deviceMaintenanceTask/listPage` | æ¥è¯¢è®¾å¤ä¿å
»å®æ¶ä»»å¡ | |
| | | | `POST` | `/deviceMaintenanceTask/add` | æ°å¢è®¾å¤ä¿å
»å®æ¶ä»»å¡ | |
| | | | `POST` | `/deviceMaintenanceTask/update` | ä¿®æ¹è®¾å¤ä¿å
»å®æ¶ä»»å¡ | |
| | | | `DELETE` | `/deviceMaintenanceTask/delete` | å é¤è®¾å¤ä¿å
»å®æ¶ä»»å¡ | |
| | | |
| | | ## 3. é¢çé项 |
| | | |
| | | å端任å¡é¢ç䏿æ¡å¢å 以ä¸éé¡¹ï¼ |
| | | |
| | | | æ¾ç¤ºåç§° | æäº¤å¼ | |
| | | |---|---| |
| | | | æ¯æ¥ä¿å
» | `DAILY` | |
| | | | æ¯å¨ä¿å
» | `WEEKLY` | |
| | | | æ¯æä¿å
» | `MONTHLY` | |
| | | | æ¯å£åº¦ä¿å
» | `QUARTERLY` | |
| | | | 年度ä¿å
» | `YEARLY` | |
| | | |
| | | `frequencyType` å¿
é¡»æäº¤ç¼ç å¼ï¼ä¸è¦æäº¤ä¸æåç§°ã |
| | | |
| | | ## 4. 年度ä¿å
»åæ°æ ¼å¼ |
| | | |
| | | 年度ä¿å
»ç `frequencyDetail` æ ¼å¼ä¸ºï¼ |
| | | |
| | | ```text |
| | | æä»½,æ¥æ,æ¶é´ |
| | | ``` |
| | | |
| | | 示ä¾ï¼ |
| | | |
| | | ```text |
| | | 12,31,09:00 |
| | | ``` |
| | | |
| | | åæ°è¯´æï¼ |
| | | |
| | | | ä½ç½® | å
容 | æ ¼å¼ | ç¤ºä¾ | |
| | | |---|---|---|---| |
| | | | 第 1 段 | æä»½ | `1-12` | `12` | |
| | | | 第 2 段 | æ¥æ | `1-31` | `31` | |
| | | | 第 3 段 | æ§è¡æ¶é´ | `HH:mm` | `09:00` | |
| | | |
| | | å端建议使ç¨âæä»½éæ©å¨ + æ¥æéæ©å¨ + æ¶é´éæ©å¨âçæè¯¥å符串ï¼ä¸è¦è®©ç¨æ·æå·¥è¾å
¥éå·åéæ ¼å¼ã |
| | | |
| | | ## 5. æ°å¢è¯·æ±ç¤ºä¾ |
| | | |
| | | æ¥å£ï¼`POST /deviceMaintenanceTask/add` |
| | | |
| | | ```json |
| | | { |
| | | "taskName": "ç©ºåæºå¹´åº¦ä¿å
»ä»»å¡", |
| | | "taskId": 1001, |
| | | "deviceModel": "C-01", |
| | | "machineryCategory": "ç产设å¤", |
| | | "maintenancePerson": "å¼ ä¸", |
| | | "frequencyType": "YEARLY", |
| | | "frequencyDetail": "12,31,09:00", |
| | | "remarks": "æ¯å¹´å¹´æ«ä¿å
»" |
| | | } |
| | | ``` |
| | | |
| | | æ°å¢æååï¼åç«¯ä¼æ ¹æ®é¢ç详æ
è®¡ç® `nextExecutionTime`ï¼å¹¶å建年度 Quartz 宿¶ä»»å¡ã |
| | | |
| | | ## 6. ä¿®æ¹è¯·æ±ç¤ºä¾ |
| | | |
| | | æ¥å£ï¼`POST /deviceMaintenanceTask/update` |
| | | |
| | | ```json |
| | | { |
| | | "id": 1, |
| | | "taskName": "ç©ºåæºå¹´åº¦ä¿å
»ä»»å¡", |
| | | "taskId": 1001, |
| | | "maintenancePerson": "å¼ ä¸", |
| | | "frequencyType": "YEARLY", |
| | | "frequencyDetail": "6,15,14:30", |
| | | "remarks": "æ¯å¹´å
æä¿å
»" |
| | | } |
| | | ``` |
| | | |
| | | ä¿®æ¹é¢çæé¢ç详æ
åï¼å端ä¼éæ°çæå®æ¶ä»»å¡è§¦åå¨ã |
| | | |
| | | ## 7. æ¥è¯¢è¿åç¤ºä¾ |
| | | |
| | | æ¥å£ï¼`GET /deviceMaintenanceTask/listPage` |
| | | |
| | | 年度任å¡è¿å示ä¾ï¼ |
| | | |
| | | ```json |
| | | { |
| | | "code": 200, |
| | | "msg": "æä½æå", |
| | | "data": { |
| | | "records": [ |
| | | { |
| | | "id": 1, |
| | | "taskName": "ç©ºåæºå¹´åº¦ä¿å
»ä»»å¡", |
| | | "taskId": 1001, |
| | | "maintenancePerson": "å¼ ä¸", |
| | | "frequencyType": "YEARLY", |
| | | "frequencyDetail": "12,31,09:00", |
| | | "nextExecutionTime": "2026-12-31 09:00:00", |
| | | "lastExecutionTime": null, |
| | | "isActive": true, |
| | | "remarks": "æ¯å¹´å¹´æ«ä¿å
»" |
| | | } |
| | | ], |
| | | "total": 1 |
| | | } |
| | | } |
| | | ``` |
| | | |
| | | å表å±ç¤ºæ¶å»ºè®®å°ï¼ |
| | | |
| | | - `YEARLY` æ¾ç¤ºä¸ºâ年度ä¿å
ȉ |
| | | - `12,31,09:00` æ¾ç¤ºä¸ºâæ¯å¹´12æ31æ¥ 09:00â |
| | | |
| | | ## 8. 宿¶æ§è¡è§å |
| | | |
| | | 1. 年度任å¡é¦æ¬¡æ§è¡æ¶é´åå½å年份ä¸é
ç½®çæä»½ãæ¥æåæ¶é´ã |
| | | 2. 妿å½åå¹´ä»½çæ§è¡æ¶é´å·²ç»è¿å»ï¼å馿¬¡æ§è¡å®æå°ä¸ä¸å¹´åº¦ã |
| | | 3. 任塿§è¡åï¼å端èªå¨è®¡ç®ä¸ä¸å¹´åº¦æ§è¡æ¶é´ã |
| | | 4. é
ç½®æ¥æè¶
è¿ç®æ æä»½å®é
å¤©æ°æ¶ï¼æç®æ æä»½æåä¸å¤©æ§è¡ãä¾å¦ï¼ |
| | | - `2,31,09:00` æ 2 ææåä¸å¤©æ§è¡ã |
| | | 5. ä¿å
»ä»»å¡æ§è¡åä¼èªå¨çæè®¾å¤ä¿å
»è®°å½ï¼å¹¶åæ¥ä»¥ä¸åæ®µï¼ |
| | | - `frequencyType = YEARLY` |
| | | - `frequencyDetail = 年度任å¡é
ç½®å¼` |
| | | - `maintenanceActuallyName = maintenancePerson` |
| | | |
| | | ## 9. åç«¯æ ¡éªè¦æ± |
| | | |
| | | æäº¤å¹´åº¦ä¿å
»ä»»å¡ååºæ ¡éªï¼ |
| | | |
| | | - æä»½èå´ä¸º `1-12` |
| | | - æ¥æèå´ä¸º `1-31` |
| | | - æ¶é´æ ¼å¼ä¸º `HH:mm` |
| | | - `frequencyDetail` å¿
é¡»ä¸ºä¸æ®µéå·åéå¼ |
| | | - `frequencyType` æäº¤ `YEARLY` |
| | | |
| | | æ¨èé误æç¤ºï¼ |
| | | |
| | | - â年度ä¿å
»æ ¼å¼åºä¸ºï¼æä»½,æ¥æ,æ¶é´ï¼ä¾å¦ 12,31,09:00â |
| | | - âæä»½å¿
é¡»å¨1-12ä¹é´â |
| | | - âæ¥æå¿
é¡»å¨1-31ä¹é´â |
| | | - âæ¶é´æ ¼å¼å¿
须为 HH:mmâ |
| | | |
| | | ## 10. èè°æµè¯æ¸
å |
| | | |
| | | - [ ] æ°å¢é¢çä¸ææ¡æ¾ç¤ºâ年度ä¿å
»âã |
| | | - [ ] æ°å¢ä»»å¡æäº¤ `frequencyType=YEARLY`ã |
| | | - [ ] æ°å¢ä»»å¡æäº¤ `frequencyDetail=12,31,09:00` æåã |
| | | - [ ] åè¡¨ä¸æ£ç¡®æ¾ç¤ºâ年度ä¿å
»âã |
| | | - [ ] ç¼è¾å¹´åº¦ä»»å¡å¹¶ä¿®æ¹æä»½ãæ¥æãæ¶é´æåã |
| | | - [ ] ç¼è¾å `nextExecutionTime` ææ°é
ç½®éæ°è®¡ç®ã |
| | | - [ ] æ ¡éªæä»½ä¸º 0 æ 13 æ¶ä¸è½æäº¤ã |
| | | - [ ] æ ¡éªæ¥æä¸º 0 æ 32 æ¶ä¸è½æäº¤ã |
| | | - [ ] æ ¡éªæ¶é´æ ¼å¼é误æ¶ä¸è½æäº¤ã |
| | | - [ ] ä½¿ç¨ `2,31,09:00` éªè¯ææ«æ¥æå¤ç符å产å颿ã |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- 设å¤åºåï¼è½¦é´/ä½ç½®ï¼ç¶åéå½ç»æ |
| | | CREATE TABLE IF NOT EXISTS `device_area` ( |
| | | `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主é®ID', |
| | | `name` varchar(255) NOT NULL COMMENT 'åºå/车é´/ä½ç½®åç§°', |
| | | `parent_id` bigint NULL COMMENT 'ç¶çº§åºåIDï¼æ ¹èç¹ä¸ºNULL', |
| | | `ancestors` varchar(1000) NULL COMMENT 'ç¥çº§è·¯å¾ï¼å¦ 1,2,3', |
| | | `sort` int NULL COMMENT 'æåº', |
| | | `dept_id` bigint NULL COMMENT 'é¨é¨ID', |
| | | `tenant_id` bigint NULL COMMENT 'ç§æ·ID', |
| | | `create_user` int NULL COMMENT 'å建人', |
| | | `create_time` datetime NULL COMMENT 'å建æ¶é´', |
| | | `update_user` int NULL COMMENT 'æ´æ°äºº', |
| | | `update_time` datetime NULL COMMENT 'æ´æ°æ¶é´', |
| | | PRIMARY KEY (`id`) |
| | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='设å¤åºå表ï¼è½¦é´/ä½ç½®ï¼'; |
| | | |
| | | -- 设å¤å°è´¦å
³èåºåï¼å¹çï¼å·²åå¨åæ¶è·³è¿ï¼ |
| | | SET @col_exists = (SELECT COUNT(*) FROM information_schema.COLUMNS |
| | | WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'device_ledger' AND COLUMN_NAME = 'area_id'); |
| | | SET @ddl = IF(@col_exists = 0, |
| | | 'ALTER TABLE `device_ledger` ADD COLUMN `area_id` bigint NULL COMMENT ''设å¤åºåID'' AFTER `dept_id`', |
| | | 'SELECT 1'); |
| | | PREPARE stmt FROM @ddl; |
| | | EXECUTE stmt; |
| | | DEALLOCATE PREPARE stmt; |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | -- æ¡æ¶åå䏿¡æ¶è®¢åå
³ç³»ï¼å¹çï¼å·²åå¨çå/åæ®µè·³è¿ï¼å¯å®å
¨é夿§è¡ï¼ |
| | | |
| | | -- sales_ledger.contract_type / parent_contract_id |
| | | SET @c1 = (SELECT COUNT(*) FROM information_schema.COLUMNS |
| | | WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sales_ledger' AND COLUMN_NAME = 'contract_type'); |
| | | SET @ddl1 = IF(@c1 = 0, |
| | | 'ALTER TABLE `sales_ledger` ADD COLUMN `contract_type` tinyint NOT NULL DEFAULT 1 COMMENT ''ååç±»åï¼1æ®ééå®ååï¼2æ¡æ¶ååï¼3æ¡æ¶è®¢å'' AFTER `sales_contract_no`', |
| | | 'SELECT 1'); |
| | | PREPARE stmt1 FROM @ddl1; |
| | | EXECUTE stmt1; |
| | | DEALLOCATE PREPARE stmt1; |
| | | |
| | | SET @c2 = (SELECT COUNT(*) FROM information_schema.COLUMNS |
| | | WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sales_ledger' AND COLUMN_NAME = 'parent_contract_id'); |
| | | SET @ddl2 = IF(@c2 = 0, |
| | | 'ALTER TABLE `sales_ledger` ADD COLUMN `parent_contract_id` bigint NULL COMMENT ''ç¶æ¡æ¶ååID'' AFTER `contract_type`', |
| | | 'SELECT 1'); |
| | | PREPARE stmt2 FROM @ddl2; |
| | | EXECUTE stmt2; |
| | | DEALLOCATE PREPARE stmt2; |
| | | |
| | | -- sales_ledger_product.quantity å
许为空 |
| | | SET @c3 = (SELECT COUNT(*) FROM information_schema.COLUMNS |
| | | WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sales_ledger_product' AND COLUMN_NAME = 'quantity' |
| | | AND IS_NULLABLE = 'NO'); |
| | | SET @ddl3 = IF(@c3 = 1, |
| | | 'ALTER TABLE `sales_ledger_product` MODIFY COLUMN `quantity` decimal(18, 2) NULL COMMENT ''æ°éï¼æ¡æ¶åååæ¡æ¶è®¢åä¸è®°å½æ°éï¼å®é
åè´§æ°éè®°å½å¨åè´§æç»''', |
| | | 'SELECT 1'); |
| | | PREPARE stmt3 FROM @ddl3; |
| | | EXECUTE stmt3; |
| | | DEALLOCATE PREPARE stmt3; |
| | | |
| | | -- sales_ledger_product.parent_product_id |
| | | SET @c4 = (SELECT COUNT(*) FROM information_schema.COLUMNS |
| | | WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sales_ledger_product' AND COLUMN_NAME = 'parent_product_id'); |
| | | SET @ddl4 = IF(@c4 = 0, |
| | | 'ALTER TABLE `sales_ledger_product` ADD COLUMN `parent_product_id` bigint NULL COMMENT ''ç¶æ¡æ¶åå产åID'' AFTER `sales_ledger_id`', |
| | | 'SELECT 1'); |
| | | PREPARE stmt4 FROM @ddl4; |
| | | EXECUTE stmt4; |
| | | DEALLOCATE PREPARE stmt4; |
| | | |
| | | -- sales_ledger_product.delivery_date |
| | | SET @c5 = (SELECT COUNT(*) FROM information_schema.COLUMNS |
| | | WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'sales_ledger_product' AND COLUMN_NAME = 'delivery_date'); |
| | | SET @ddl5 = IF(@c5 = 0, |
| | | 'ALTER TABLE `sales_ledger_product` ADD COLUMN `delivery_date` date NULL COMMENT ''æ¡æ¶è®¢åäº¤è´§æ¥æ'' AFTER `parent_product_id`', |
| | | 'SELECT 1'); |
| | | PREPARE stmt5 FROM @ddl5; |
| | | EXECUTE stmt5; |
| | | DEALLOCATE PREPARE stmt5; |
| | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void recycleCustomer(CustomerDto customerDto) { |
| | | Customer customer = customerMapper.selectById(customerDto.getId()); |
| | | if (customer.getType() == 1 && customer.getIsAssigned() == 1) { // å
¬æµ·ä¸å·²åé
|
| | | validatePublicSeaRecyclePermission(customer.getId()); |
| | | customer.setIsAssigned(0); |
| | | customer.setUsageStatus(0L); |
| | | customer.setUsageUser(0L); |
| | | customerMapper.updateById(customer); |
| | | |
| | | // å é¤è¯¥å®¢æ·çææå
±äº«å
³ç³» |
| | | customerUserService.remove( |
| | | new QueryWrapper<CustomerUser>().lambda() |
| | | .eq(CustomerUser::getCustomerId, customerDto.getId()) |
| | | ); |
| | | if (customerDto == null || customerDto.getId() == null) { |
| | | throw new RuntimeException("客æ·IDä¸è½ä¸ºç©º"); |
| | | } |
| | | Customer customer = customerMapper.selectById(customerDto.getId()); |
| | | if (customer == null) { |
| | | throw new RuntimeException("å®¢æ·æ¡£æ¡ä¸åå¨"); |
| | | } |
| | | boolean assigned = Objects.equals(customer.getIsAssigned(), 1) |
| | | || Objects.equals(customer.getUsageStatus(), 1L) |
| | | || (customer.getUsageUser() != null && customer.getUsageUser() > 0); |
| | | if (!assigned) { |
| | | throw new RuntimeException("该客æ·å½åæªå¤äºé¢ç¨ç¶æï¼æ æ³åæ¶"); |
| | | } |
| | | validatePublicSeaRecyclePermission(customer.getId()); |
| | | int updated = customerMapper.update(null, new UpdateWrapper<Customer>() |
| | | .eq("id", customer.getId()) |
| | | .set("is_assigned", 0) |
| | | .set("usage_status", 0) |
| | | .set("usage_user", null)); |
| | | if (updated == 0) { |
| | | throw new RuntimeException("客æ·åæ¶å¤±è´¥ï¼è¯·å·æ°åéè¯"); |
| | | } |
| | | |
| | | // å é¤è¯¥å®¢æ·çææå
±äº«å
³ç³» |
| | | customerUserService.remove( |
| | | new QueryWrapper<CustomerUser>().lambda() |
| | | .eq(CustomerUser::getCustomerId, customerDto.getId()) |
| | | ); |
| | | } |
| | | |
| | | // 客æ·å
񄧮 |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.controller; |
| | | |
| | | import com.ruoyi.device.dto.DeviceAreaDto; |
| | | import com.ruoyi.device.service.IDeviceAreaService; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import io.swagger.v3.oas.annotations.Operation; |
| | | import io.swagger.v3.oas.annotations.tags.Tag; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import java.util.List; |
| | | |
| | | @Tag(name = "设å¤åºå管ç") |
| | | @RequestMapping("/device/area") |
| | | @RestController |
| | | @AllArgsConstructor |
| | | public class DeviceAreaController { |
| | | |
| | | private final IDeviceAreaService deviceAreaService; |
| | | |
| | | @Operation(summary = "æ¥è¯¢è®¾å¤åºåæ ï¼å«éå½è®¾å¤æ°éï¼") |
| | | @GetMapping("/tree") |
| | | public AjaxResult tree() { |
| | | return AjaxResult.success(deviceAreaService.selectAreaTree()); |
| | | } |
| | | |
| | | @Operation(summary = "æ°å¢è®¾å¤åºå") |
| | | @PostMapping() |
| | | public AjaxResult add(@RequestBody DeviceAreaDto dto) { |
| | | return deviceAreaService.addArea(dto); |
| | | } |
| | | |
| | | @Operation(summary = "ä¿®æ¹è®¾å¤åºå") |
| | | @PutMapping() |
| | | public AjaxResult update(@RequestBody DeviceAreaDto dto) { |
| | | return deviceAreaService.updateArea(dto); |
| | | } |
| | | |
| | | @Operation(summary = "å é¤è®¾å¤åºå") |
| | | @DeleteMapping("/{ids}") |
| | | public AjaxResult delete(@PathVariable("ids") List<Long> ids) { |
| | | return deviceAreaService.deleteArea(ids); |
| | | } |
| | | } |
| | |
| | | package com.ruoyi.device.controller; |
| | | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.device.dto.DeviceLedgerDto; |
| | |
| | | |
| | | |
| | | @GetMapping("getDeviceLedger") |
| | | @Operation(summary = "è·å设å¤å°è´¦") |
| | | public AjaxResult getDeviceLedger() { |
| | | return AjaxResult.success(deviceLedgerService.list(new QueryWrapper<DeviceLedger>().lambda() |
| | | .select(DeviceLedger::getId, DeviceLedger::getDeviceName, DeviceLedger::getDeviceModel))); |
| | | @Operation(summary = "è·å设å¤å°è´¦ï¼å·¡æ£éæ©è®¾å¤ï¼æ¯ææåºåçéï¼") |
| | | public AjaxResult getDeviceLedger(Long areaId) { |
| | | return AjaxResult.success(deviceLedgerService.selectDeviceOptions(areaId)); |
| | | } |
| | | |
| | | @GetMapping("scanDevice") |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * 设å¤åºå DTO |
| | | */ |
| | | @Data |
| | | public class DeviceAreaDto { |
| | | |
| | | /** |
| | | * 主é®ID |
| | | */ |
| | | private Long id; |
| | | |
| | | /** |
| | | * åºå/车é´/ä½ç½®åç§° |
| | | */ |
| | | private String name; |
| | | |
| | | /** |
| | | * ç¶çº§åºåID |
| | | */ |
| | | private Long parentId; |
| | | |
| | | /** |
| | | * æåº |
| | | */ |
| | | private Integer sort; |
| | | |
| | | /** |
| | | * é¨é¨ID |
| | | */ |
| | | private Long deptId; |
| | | } |
| | |
| | | |
| | | @Schema(description = "设å¤ç±»å") |
| | | private String type; |
| | | |
| | | /** |
| | | * 设å¤åºåID |
| | | */ |
| | | private Long areaId; |
| | | |
| | | /** |
| | | * 设å¤åºååç§°ï¼éæ°æ®åºå段ï¼å表å±ç¤ºï¼ |
| | | */ |
| | | @TableField(exist = false) |
| | | private String areaName; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.mapper; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.ruoyi.device.pojo.DeviceArea; |
| | | import org.apache.ibatis.annotations.Mapper; |
| | | |
| | | /** |
| | | * 设å¤åºå Mapper |
| | | */ |
| | | @Mapper |
| | | public interface DeviceAreaMapper extends BaseMapper<DeviceArea> { |
| | | } |
| | |
| | | |
| | | IPage<DeviceLedgerDto> queryPage(Page page, @Param("deviceLedger") DeviceLedgerDto deviceLedgerDto); |
| | | |
| | | /** |
| | | * 设å¤éæ©å表ï¼å·¡æ£ç模åé设å¤ç¨ï¼ï¼æ¯ææåºåéå½çé |
| | | * @param areaId åºåIDï¼å¯ä¸ºç©ºè¡¨ç¤ºå
¨é¨ |
| | | */ |
| | | List<DeviceLedgerDto> selectDeviceOptions(@Param("areaId") Long areaId); |
| | | |
| | | List<DeviceLedgerExeclDto> deviceLedgerExportList(DeviceLedger deviceLedger); |
| | | |
| | | @InterceptorIgnore(tenantLine = "true") |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.pojo; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.FieldFill; |
| | | import com.baomidou.mybatisplus.annotation.TableField; |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import io.swagger.v3.oas.annotations.media.Schema; |
| | | import lombok.Data; |
| | | import org.springframework.format.annotation.DateTimeFormat; |
| | | |
| | | import java.time.LocalDateTime; |
| | | |
| | | /** |
| | | * 设å¤åºåå®ä½ç±»ï¼è½¦é´/ä½ç½®ï¼ç¶åéå½ï¼ |
| | | */ |
| | | @Data |
| | | @TableName("device_area") |
| | | @Schema |
| | | public class DeviceArea { |
| | | |
| | | /** |
| | | * 主é®IDï¼èªå¢ |
| | | */ |
| | | private Long id; |
| | | |
| | | /** |
| | | * åºå/车é´/ä½ç½®åç§° |
| | | */ |
| | | @Schema(description = "åºå/车é´/ä½ç½®åç§°") |
| | | private String name; |
| | | |
| | | /** |
| | | * ç¶çº§åºåIDï¼æ ¹èç¹ä¸ºNULL |
| | | */ |
| | | @Schema(description = "ç¶çº§åºåID") |
| | | private Long parentId; |
| | | |
| | | /** |
| | | * ç¥çº§è·¯å¾ï¼å¦ 1,2,3 |
| | | */ |
| | | @Schema(description = "ç¥çº§è·¯å¾") |
| | | private String ancestors; |
| | | |
| | | /** |
| | | * æåº |
| | | */ |
| | | @Schema(description = "æåº") |
| | | private Integer sort; |
| | | |
| | | /** |
| | | * é¨é¨ID |
| | | */ |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * ç§æ·ID |
| | | */ |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long tenantId; |
| | | |
| | | /** |
| | | * å建人 |
| | | */ |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Integer createUser; |
| | | |
| | | /** |
| | | * å建æ¶é´ |
| | | */ |
| | | @TableField(fill = FieldFill.INSERT) |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime createTime; |
| | | |
| | | /** |
| | | * æ´æ°äºº |
| | | */ |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | private Integer updateUser; |
| | | |
| | | /** |
| | | * æ´æ°æ¶é´ |
| | | */ |
| | | @TableField(fill = FieldFill.INSERT_UPDATE) |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") |
| | | private LocalDateTime updateTime; |
| | | } |
| | |
| | | |
| | | @TableField(fill = FieldFill.INSERT) |
| | | private Long deptId; |
| | | |
| | | /** |
| | | * 设å¤åºåID |
| | | */ |
| | | private Long areaId; |
| | | |
| | | /** |
| | | * 设å¤åºååç§°ï¼éæ°æ®åºå段ï¼å表å±ç¤ºï¼ |
| | | */ |
| | | @TableField(exist = false) |
| | | private String areaName; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ruoyi.device.dto.DeviceAreaDto; |
| | | import com.ruoyi.device.pojo.DeviceArea; |
| | | import com.ruoyi.device.vo.DeviceAreaTreeDto; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 设å¤åºå Service |
| | | */ |
| | | public interface IDeviceAreaService extends IService<DeviceArea> { |
| | | |
| | | /** |
| | | * æ¥è¯¢åºåæ ï¼å«åèç¹éå½è®¾å¤æ°éï¼ |
| | | */ |
| | | List<DeviceAreaTreeDto> selectAreaTree(); |
| | | |
| | | /** |
| | | * æ°å¢åºå |
| | | */ |
| | | AjaxResult addArea(DeviceAreaDto dto); |
| | | |
| | | /** |
| | | * ä¿®æ¹åºå |
| | | */ |
| | | AjaxResult updateArea(DeviceAreaDto dto); |
| | | |
| | | /** |
| | | * å é¤åºåï¼æå级æå
³èè®¾å¤æ¶ç¦æ¢å é¤ï¼ |
| | | */ |
| | | AjaxResult deleteArea(List<Long> ids); |
| | | } |
| | |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | import java.util.List; |
| | | |
| | | public interface IDeviceLedgerService extends IService<DeviceLedger> { |
| | | IPage<DeviceLedgerDto> queryPage(Page page, DeviceLedgerDto deviceLedger); |
| | | |
| | | /** |
| | | * 设å¤éæ©å表ï¼å·¡æ£ç模åé设å¤ç¨ï¼ï¼æ¯ææåºåéå½çé |
| | | */ |
| | | List<DeviceLedgerDto> selectDeviceOptions(Long areaId); |
| | | |
| | | AjaxResult saveDeviceLedger(DeviceLedgerDto deviceLedgerDto); |
| | | |
| | | AjaxResult updateDeviceLedger(DeviceLedgerDto deviceLedgerDto); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.device.dto.DeviceAreaDto; |
| | | import com.ruoyi.device.mapper.DeviceAreaMapper; |
| | | import com.ruoyi.device.mapper.DeviceLedgerMapper; |
| | | import com.ruoyi.device.pojo.DeviceArea; |
| | | import com.ruoyi.device.pojo.DeviceLedger; |
| | | import com.ruoyi.device.service.IDeviceAreaService; |
| | | import com.ruoyi.device.vo.DeviceAreaTreeDto; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 设å¤åºå Service å®ç° |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class DeviceAreaServiceImpl extends ServiceImpl<DeviceAreaMapper, DeviceArea> implements IDeviceAreaService { |
| | | |
| | | private final DeviceAreaMapper deviceAreaMapper; |
| | | private final DeviceLedgerMapper deviceLedgerMapper; |
| | | |
| | | @Override |
| | | public List<DeviceAreaTreeDto> selectAreaTree() { |
| | | List<DeviceArea> all = this.list(new LambdaQueryWrapper<DeviceArea>().orderByAsc(DeviceArea::getSort)); |
| | | if (all == null || all.isEmpty()) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | // ç»è®¡æ¯ä¸ªåºåç´æ¥æè½½çè®¾å¤æ°é |
| | | Map<Long, Long> directCountMap = deviceLedgerMapper.selectList( |
| | | new LambdaQueryWrapper<DeviceLedger>() |
| | | .select(DeviceLedger::getAreaId) |
| | | .isNotNull(DeviceLedger::getAreaId)) |
| | | .stream() |
| | | .filter(d -> d.getAreaId() != null) |
| | | .collect(Collectors.groupingBy(DeviceLedger::getAreaId, Collectors.counting())); |
| | | |
| | | Map<Long, DeviceArea> areaMap = all.stream() |
| | | .collect(Collectors.toMap(DeviceArea::getId, a -> a)); |
| | | |
| | | // é彿±æ»æ¯ä¸ªèç¹çè®¾å¤æ°éï¼å«ææåçº§ï¼ |
| | | Map<Long, Long> countMap = directCountMap.entrySet().stream() |
| | | .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); |
| | | for (DeviceArea area : all) { |
| | | accumulate(area.getId(), directCountMap.getOrDefault(area.getId(), 0L), countMap, areaMap); |
| | | } |
| | | |
| | | List<Long> rootIds = all.stream() |
| | | .filter(a -> a.getParentId() == null || !areaMap.containsKey(a.getParentId())) |
| | | .map(DeviceArea::getId) |
| | | .collect(Collectors.toList()); |
| | | |
| | | List<DeviceAreaTreeDto> tree = new ArrayList<>(); |
| | | for (Long rootId : rootIds) { |
| | | DeviceArea root = areaMap.get(rootId); |
| | | tree.add(buildNode(root, all, countMap)); |
| | | } |
| | | return tree; |
| | | } |
| | | |
| | | // å°å½åèç¹æ°éç´¯å å°ææç¥çº§èç¹ |
| | | private void accumulate(Long areaId, Long count, Map<Long, Long> countMap, Map<Long, DeviceArea> areaMap) { |
| | | DeviceArea area = areaMap.get(areaId); |
| | | if (area == null) { |
| | | return; |
| | | } |
| | | countMap.merge(areaId, count, Long::sum); |
| | | // 沿ç¥å
é¾ç»§ç»ç´¯å ï¼é¿å
ç¥å
é¾å¾ªç¯ä¾èµï¼ |
| | | if (area.getParentId() != null && areaMap.containsKey(area.getParentId())) { |
| | | accumulate(area.getParentId(), count, countMap, areaMap); |
| | | } |
| | | } |
| | | |
| | | private DeviceAreaTreeDto buildNode(DeviceArea area, List<DeviceArea> all, Map<Long, Long> countMap) { |
| | | DeviceAreaTreeDto node = new DeviceAreaTreeDto(); |
| | | node.setId(area.getId()); |
| | | node.setParentId(area.getParentId()); |
| | | node.setLabel(area.getName()); |
| | | node.setDeviceCount(countMap.getOrDefault(area.getId(), 0L)); |
| | | for (DeviceArea child : all) { |
| | | if (area.getId().equals(child.getParentId())) { |
| | | node.getChildren().add(buildNode(child, all, countMap)); |
| | | } |
| | | } |
| | | return node; |
| | | } |
| | | |
| | | @Override |
| | | public AjaxResult addArea(DeviceAreaDto dto) { |
| | | if (StringUtils.isEmpty(dto.getName())) { |
| | | return AjaxResult.error("åºååç§°ä¸è½ä¸ºç©º"); |
| | | } |
| | | DeviceArea area = new DeviceArea(); |
| | | area.setName(dto.getName()); |
| | | area.setParentId(dto.getParentId()); |
| | | area.setSort(dto.getSort()); |
| | | area.setDeptId(dto.getDeptId()); |
| | | area.setTenantId(SecurityUtils.getLoginUser().getTenantId()); |
| | | |
| | | if (dto.getParentId() != null) { |
| | | DeviceArea parent = this.getById(dto.getParentId()); |
| | | if (parent == null) { |
| | | return AjaxResult.error("ç¶çº§åºåä¸åå¨"); |
| | | } |
| | | area.setAncestors(StringUtils.isEmpty(parent.getAncestors()) |
| | | ? String.valueOf(parent.getId()) |
| | | : parent.getAncestors() + "," + parent.getId()); |
| | | } |
| | | this.save(area); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | @Override |
| | | public AjaxResult updateArea(DeviceAreaDto dto) { |
| | | if (dto.getId() == null) { |
| | | return AjaxResult.error("åºåIDä¸è½ä¸ºç©º"); |
| | | } |
| | | DeviceArea area = this.getById(dto.getId()); |
| | | if (area == null) { |
| | | return AjaxResult.error("åºåä¸åå¨"); |
| | | } |
| | | // ä¸å
许æåºåæå°èªå·±çå级ä¸ï¼é¿å
å¾ªç¯ |
| | | if (dto.getParentId() != null && dto.getParentId().equals(dto.getId())) { |
| | | return AjaxResult.error("ä¸è½å°åºåæè½½å°èªèº«"); |
| | | } |
| | | if (dto.getParentId() != null && isDescendant(dto.getId(), dto.getParentId())) { |
| | | return AjaxResult.error("ä¸è½å°åºåæè½½å°èªå·±çå级ä¸"); |
| | | } |
| | | area.setName(dto.getName()); |
| | | area.setSort(dto.getSort()); |
| | | area.setDeptId(dto.getDeptId()); |
| | | if (!java.util.Objects.equals(dto.getParentId(), area.getParentId())) { |
| | | area.setParentId(dto.getParentId()); |
| | | if (dto.getParentId() == null) { |
| | | area.setAncestors(null); |
| | | } else { |
| | | DeviceArea parent = this.getById(dto.getParentId()); |
| | | if (parent == null) { |
| | | return AjaxResult.error("ç¶çº§åºåä¸åå¨"); |
| | | } |
| | | area.setAncestors(StringUtils.isEmpty(parent.getAncestors()) |
| | | ? String.valueOf(parent.getId()) |
| | | : parent.getAncestors() + "," + parent.getId()); |
| | | } |
| | | } |
| | | this.updateById(area); |
| | | return AjaxResult.success(); |
| | | } |
| | | |
| | | private boolean isDescendant(Long targetId, Long candidateParentId) { |
| | | DeviceArea cur = this.getById(candidateParentId); |
| | | while (cur != null && cur.getParentId() != null) { |
| | | if (cur.getParentId().equals(targetId)) { |
| | | return true; |
| | | } |
| | | cur = this.getById(cur.getParentId()); |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult deleteArea(List<Long> ids) { |
| | | for (Long id : ids) { |
| | | DeviceArea area = this.getById(id); |
| | | if (area == null) { |
| | | return AjaxResult.error("åºåä¸åå¨"); |
| | | } |
| | | long childCount = this.count(new LambdaQueryWrapper<DeviceArea>().eq(DeviceArea::getParentId, id)); |
| | | if (childCount > 0) { |
| | | return AjaxResult.error("该åºååå¨å级åºåï¼è¯·å
å é¤å级"); |
| | | } |
| | | long deviceCount = deviceLedgerMapper.selectCount( |
| | | new LambdaQueryWrapper<DeviceLedger>().eq(DeviceLedger::getAreaId, id)); |
| | | if (deviceCount > 0) { |
| | | return AjaxResult.error("该åºåä¸åå¨è®¾å¤ï¼è¯·å
ç§»é¤è®¾å¤å
³è"); |
| | | } |
| | | } |
| | | this.removeByIds(ids); |
| | | return AjaxResult.success(); |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | @Override |
| | | public List<DeviceLedgerDto> selectDeviceOptions(Long areaId) { |
| | | return deviceLedgerMapper.selectDeviceOptions(areaId); |
| | | } |
| | | |
| | | @Override |
| | | public AjaxResult saveDeviceLedger(DeviceLedgerDto deviceLedgerDto) { |
| | | LambdaQueryWrapper<DeviceLedger> deviceLedgerLambdaQueryWrapper = new LambdaQueryWrapper<>(); |
| | | deviceLedgerLambdaQueryWrapper.eq(DeviceLedger::getDeviceName,deviceLedgerDto.getDeviceName()); |
| | |
| | | return calculateMonthlyNextTime(frequencyDetail, currentTime); |
| | | case "QUARTERLY": |
| | | return calculateQuarterlyNextTime(frequencyDetail, currentTime); |
| | | case "YEARLY": |
| | | return calculateYearlyNextTime(frequencyDetail, currentTime); |
| | | default: |
| | | throw new IllegalArgumentException("䏿¯æçé¢çç±»å: " + frequencyType); |
| | | } |
| | |
| | | ); |
| | | } |
| | | |
| | | private LocalDateTime calculateYearlyNextTime(String detail, LocalDateTime current) { |
| | | String[] parts = detail.split(","); |
| | | int month = Integer.parseInt(parts[0]); |
| | | int day = Integer.parseInt(parts[1]); |
| | | LocalTime time = LocalTime.parse(parts[2]); |
| | | |
| | | int year = current.getYear(); |
| | | LocalDateTime nextTime = LocalDateTime.of(java.time.LocalDate.of(year, month, |
| | | Math.min(day, YearMonth.of(year, month).lengthOfMonth())), time); |
| | | if (!nextTime.isAfter(current)) { |
| | | year++; |
| | | nextTime = LocalDateTime.of(java.time.LocalDate.of(year, month, |
| | | Math.min(day, YearMonth.of(year, month).lengthOfMonth())), time); |
| | | } |
| | | return nextTime; |
| | | } |
| | | |
| | | /** |
| | | * è§£æææå å符串 |
| | | */ |
| | |
| | | return convertMonthlyToCron(task.getFrequencyDetail()); |
| | | case "QUARTERLY": |
| | | return convertQuarterlyToCron(task.getFrequencyDetail()); |
| | | case "YEARLY": |
| | | return convertYearlyToCron(task.getFrequencyDetail()); |
| | | default: |
| | | throw new IllegalArgumentException("䏿¯æçé¢çç±»å: " + task.getFrequencyType()); |
| | | } |
| | |
| | | quarterStartMonth); |
| | | } |
| | | |
| | | private String convertYearlyToCron(String frequencyDetail) { |
| | | String[] parts = validateAndSplit(frequencyDetail, ",", 3); |
| | | int month = validateMonth(parts[0]); |
| | | int day = validateDayOfMonth(parts[1]); |
| | | LocalTime time = parseTime(parts[2]); |
| | | return String.format("0 %d %d %d %d ?", time.getMinute(), time.getHour(), day, month); |
| | | } |
| | | |
| | | // æ°å¢éªè¯æä»½çæ¹æ³(1-12) |
| | | private int validateMonth(String monthStr) { |
| | | try { |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.device.vo; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * 设å¤åºåæ VOï¼å端 el-tree ç»æï¼ |
| | | */ |
| | | @Data |
| | | public class DeviceAreaTreeDto { |
| | | |
| | | private Long id; |
| | | |
| | | private Long parentId; |
| | | |
| | | /** |
| | | * èç¹åç§° |
| | | */ |
| | | private String label; |
| | | |
| | | /** |
| | | * å½åèç¹åææå级åºåä¸çè®¾å¤æ°é |
| | | */ |
| | | private Long deviceCount; |
| | | |
| | | private List<DeviceAreaTreeDto> children = new ArrayList<>(); |
| | | } |
| | |
| | | } |
| | | } |
| | | validateInspectionInput(inspectionTaskDto, oldInspectionTask); |
| | | validateDeviceExists(inspectionTaskDto, oldInspectionTask); |
| | | |
| | | InspectionTask inspectionTask = new InspectionTask(); |
| | | BeanUtils.copyProperties(inspectionTaskDto, inspectionTask); |
| | |
| | | return i; |
| | | } |
| | | |
| | | private void validateDeviceExists(InspectionTaskDto inspectionTaskDto, InspectionTask oldInspectionTask) { |
| | | Integer taskId = inspectionTaskDto.getTaskId(); |
| | | if (taskId == null && oldInspectionTask != null) { |
| | | taskId = oldInspectionTask.getTaskId(); |
| | | } |
| | | if (taskId == null || taskId <= 0) { |
| | | return; |
| | | } |
| | | DeviceLedger deviceLedger = deviceLedgerMapper.selectById(taskId.longValue()); |
| | | if (deviceLedger == null) { |
| | | throw new IllegalArgumentException("æé设å¤ä¸åå¨ï¼è¯·éæ°éæ©"); |
| | | } |
| | | } |
| | | |
| | | private void validateInspectionInput(InspectionTaskDto inspectionTaskDto, InspectionTask oldInspectionTask) { |
| | | String inspectionResult = inspectionTaskDto.getInspectionResult(); |
| | | if (StringUtils.isBlank(inspectionResult) && oldInspectionTask != null) { |
| | |
| | | private final TimingTaskMapper timingTaskMapper; |
| | | private final TimingTaskScheduler timingTaskScheduler; |
| | | private final SysUserMapper sysUserMapper; |
| | | private final com.ruoyi.device.mapper.DeviceLedgerMapper deviceLedgerMapper; |
| | | private static final int ENABLED = 1; |
| | | private static final int DISABLED = 0; |
| | | |
| | |
| | | throw new IllegalArgumentException("宿¶ä»»å¡ä¸åå¨"); |
| | | } |
| | | } |
| | | validateDeviceExists(timingTaskDto, oldTimingTask); |
| | | TimingTask timingTask = new TimingTask(); |
| | | BeanUtils.copyProperties(timingTaskDto, timingTask); |
| | | timingTask.setIsEnabled(resolveEnabledValue(timingTask.getIsEnabled(), oldTimingTask)); |
| | |
| | | } |
| | | } |
| | | |
| | | private void validateDeviceExists(TimingTaskDto timingTaskDto, TimingTask oldTimingTask) { |
| | | Integer taskId = timingTaskDto.getTaskId(); |
| | | if (taskId == null && oldTimingTask != null) { |
| | | taskId = oldTimingTask.getTaskId(); |
| | | } |
| | | if (taskId == null || taskId <= 0) { |
| | | return; |
| | | } |
| | | if (deviceLedgerMapper.selectById(taskId.longValue()) == null) { |
| | | throw new IllegalArgumentException("æé设å¤ä¸åå¨ï¼è¯·éæ°éæ©"); |
| | | } |
| | | } |
| | | |
| | | public LocalDateTime calculateFirstExecutionTime(TimingTask task) { |
| | | // æ ¹æ®é¢çç±»åå详æ
计ç®é¦æ¬¡æ§è¡æ¶é´ |
| | | String frequencyType = task.getFrequencyType(); |
| | |
| | | // å¦ææ¯æ¯ææ§è¡ï¼è®¡ç®ä¸ä¸ªæçå
·ä½æ¥æ |
| | | return calculateMonthlyFirstExecution(task.getFrequencyDetail()); |
| | | } else if ("QUARTERLY".equals(frequencyType)) { |
| | | // èªå®ä¹é¢çï¼å¦æ¯å°æ¶ãæ¯30åéç |
| | | return calculateCustomFirstExecution(task.getFrequencyDetail()); |
| | | } else if ("YEARLY".equals(frequencyType)) { |
| | | return calculateAnnualFirstExecution(task.getFrequencyDetail()); |
| | | } else { |
| | | throw new IllegalArgumentException("䏿¯æçé¢çç±»å: " + task.getFrequencyType()); |
| | | } |
| | |
| | | return targetDateTime; |
| | | } |
| | | |
| | | private LocalDateTime calculateAnnualFirstExecution(String frequencyDetail) { |
| | | String[] parts = frequencyDetail.split(","); |
| | | if (parts.length != 3) { |
| | | throw new IllegalArgumentException("åæ°æ ¼å¼é误ï¼åºä¸º'12,31,09:00'æ ¼å¼"); |
| | | } |
| | | |
| | | int month; |
| | | int day; |
| | | try { |
| | | month = Integer.parseInt(parts[0].trim()); |
| | | day = Integer.parseInt(parts[1].trim()); |
| | | } catch (NumberFormatException e) { |
| | | throw new IllegalArgumentException("æä»½ææ¥ææ ¼å¼é误", e); |
| | | } |
| | | if (month < 1 || month > 12 || day < 1 || day > 31) { |
| | | throw new IllegalArgumentException("æä»½å¿
é¡»å¨1-12ä¹é´ï¼æ¥æå¿
é¡»å¨1-31ä¹é´"); |
| | | } |
| | | |
| | | LocalTime time = LocalTime.parse(parts[2].trim(), DateTimeFormatter.ofPattern("HH:mm")); |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | int year = now.getYear(); |
| | | LocalDateTime target = LocalDateTime.of(LocalDate.of(year, month, Math.min(day, YearMonth.of(year, month).lengthOfMonth())), time); |
| | | return target.isAfter(now) ? target : LocalDateTime.of(LocalDate.of(year + 1, month, |
| | | Math.min(day, YearMonth.of(year + 1, month).lengthOfMonth())), time); |
| | | } |
| | | |
| | | private LocalDateTime calculateCustomFirstExecution(String frequencyDetail) { |
| | | return null; |
| | | } |
| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.web.bind.annotation.*; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import java.io.IOException; |
| | | import java.util.List; |
| | |
| | | return update ? AjaxResult.success("æ£å®æå") : AjaxResult.error("æ£å®å¤±è´¥"); |
| | | } |
| | | |
| | | @PostMapping("/downloadTemplate") |
| | | @Operation(summary = "ä¸è½½è®¡éå¨å
·å°è´¦å¯¼å
¥æ¨¡æ¿") |
| | | public void downloadTemplate(HttpServletResponse response) { |
| | | measuringInstrumentLedgerService.downloadTemplate(response); |
| | | } |
| | | |
| | | @PostMapping("/import") |
| | | @Operation(summary = "æ¹é导å
¥è®¡éå¨å
·å°è´¦") |
| | | @Log(title = "æ¹é导å
¥è®¡éå¨å
·å°è´¦", businessType = BusinessType.IMPORT) |
| | | public AjaxResult importData(@RequestParam("file") MultipartFile file) { |
| | | return measuringInstrumentLedgerService.importData(file); |
| | | } |
| | | |
| | | /** |
| | | * 导åºè®¡éå¨å
·å°è´¦ |
| | | */ |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.measuringinstrumentledger.dto; |
| | | |
| | | import com.ruoyi.framework.aspectj.lang.annotation.Excel; |
| | | import lombok.Data; |
| | | |
| | | import java.util.Date; |
| | | |
| | | @Data |
| | | public class MeasuringInstrumentLedgerImportDto { |
| | | |
| | | @Excel(name = "计éå¨å
·ç¼å·") |
| | | private String code; |
| | | |
| | | @Excel(name = "计éå¨å
·åç§°") |
| | | private String name; |
| | | |
| | | @Excel(name = "è§æ ¼åå·") |
| | | private String model; |
| | | |
| | | @Excel(name = "æè¿ä¸æ¬¡æ£å®æ¥æ", dateFormat = "yyyy-MM-dd") |
| | | private Date mostDate; |
| | | |
| | | @Excel(name = "æ£å®æææ") |
| | | private Integer valid; |
| | | |
| | | @Excel(name = "å½å
¥æ¥æ", dateFormat = "yyyy-MM-dd") |
| | | private Date recordDate; |
| | | |
| | | @Excel(name = "åä½") |
| | | private String unit; |
| | | |
| | | @Excel(name = "é¨é¨ID") |
| | | private Long deptId; |
| | | |
| | | @Excel(name = "å®è£
ä½ç½®") |
| | | private String instationLocation; |
| | | |
| | | @Excel(name = "æ£å®å¨æ") |
| | | private String cycle; |
| | | } |
| | |
| | | import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedger; |
| | | import org.apache.ibatis.annotations.Param; |
| | | |
| | | import java.util.Collection; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | IPage<MeasuringInstrumentLedger> listPage(Page page,@Param("req") MeasuringInstrumentLedger measuringInstrumentLedger); |
| | | |
| | | List<MeasuringInstrumentLedger> listPage(@Param("req") MeasuringInstrumentLedger measuringInstrumentLedger); |
| | | |
| | | List<String> selectExistingCodes(@Param("tenantId") Long tenantId, @Param("codes") Collection<String> codes); |
| | | } |
| | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.measuringinstrumentledger.dto.MeasuringInstrumentLedgerDto; |
| | | import com.ruoyi.measuringinstrumentledger.pojo.MeasuringInstrumentLedger; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | |
| | | |
| | | void export(HttpServletResponse response); |
| | | |
| | | AjaxResult importData(MultipartFile file); |
| | | |
| | | void downloadTemplate(HttpServletResponse response); |
| | | |
| | | /** |
| | | * æ°å¢ |
| | | * |
| | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.common.enums.FileNameType; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.measuringinstrumentledger.dto.MeasuringInstrumentLedgerImportDto; |
| | | import com.ruoyi.measuringinstrumentledger.dto.MeasuringInstrumentLedgerDto; |
| | | import com.ruoyi.measuringinstrumentledger.mapper.MeasuringInstrumentLedgerMapper; |
| | | import com.ruoyi.measuringinstrumentledger.mapper.MeasuringInstrumentLedgerRecordMapper; |
| | |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.HashSet; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.Map; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public AjaxResult importData(MultipartFile file) { |
| | | if (file == null || file.isEmpty()) { |
| | | return AjaxResult.error("请ä¸ä¼ Excel æä»¶"); |
| | | } |
| | | String filename = file.getOriginalFilename(); |
| | | if (filename == null || !(filename.endsWith(".xls") || filename.endsWith(".xlsx"))) { |
| | | return AjaxResult.error("åªæ¯æå¯¼å
¥ xls æ xlsx æä»¶"); |
| | | } |
| | | try { |
| | | ExcelUtil<MeasuringInstrumentLedgerImportDto> util = new ExcelUtil<>(MeasuringInstrumentLedgerImportDto.class); |
| | | List<MeasuringInstrumentLedgerImportDto> rows = util.importExcel(file.getInputStream()); |
| | | if (CollectionUtils.isEmpty(rows)) { |
| | | return AjaxResult.error("Excel 䏿²¡æå¯å¯¼å
¥çæ°æ®"); |
| | | } |
| | | Set<String> codes = new HashSet<>(); |
| | | Map<Integer, String> errors = new LinkedHashMap<>(); |
| | | List<MeasuringInstrumentLedger> ledgers = new ArrayList<>(); |
| | | Long tenantId = SecurityUtils.getLoginUser().getTenantId(); |
| | | Long userId = SecurityUtils.getUserId(); |
| | | String userName = SecurityUtils.getLoginUser().getNickName(); |
| | | for (int i = 0; i < rows.size(); i++) { |
| | | MeasuringInstrumentLedgerImportDto row = rows.get(i); |
| | | int excelRow = i + 2; |
| | | String code = StringUtils.trim(row.getCode()); |
| | | String name = StringUtils.trim(row.getName()); |
| | | if (!StringUtils.hasText(code)) { |
| | | errors.put(excelRow, "计éå¨å
·ç¼å·ä¸è½ä¸ºç©º"); |
| | | continue; |
| | | } |
| | | if (!StringUtils.hasText(name)) { |
| | | errors.put(excelRow, "计éå¨å
·åç§°ä¸è½ä¸ºç©º"); |
| | | continue; |
| | | } |
| | | if (!codes.add(code)) { |
| | | errors.put(excelRow, "计éå¨å
·ç¼å·å¨ Excel ä¸éå¤"); |
| | | continue; |
| | | } |
| | | if (row.getValid() != null && row.getValid() <= 0) { |
| | | errors.put(excelRow, "æ£å®æææå¿
é¡»å¤§äº 0"); |
| | | continue; |
| | | } |
| | | MeasuringInstrumentLedger ledger = new MeasuringInstrumentLedger(); |
| | | ledger.setCode(code); |
| | | ledger.setName(name); |
| | | ledger.setModel(StringUtils.trim(row.getModel())); |
| | | ledger.setMostDate(row.getMostDate()); |
| | | ledger.setValid(row.getValid()); |
| | | ledger.setRecordDate(row.getRecordDate() == null ? new Date() : row.getRecordDate()); |
| | | ledger.setUnit(StringUtils.trim(row.getUnit())); |
| | | ledger.setDeptId(row.getDeptId()); |
| | | ledger.setInstationLocation(StringUtils.trim(row.getInstationLocation())); |
| | | ledger.setCycle(StringUtils.trim(row.getCycle())); |
| | | ledger.setUserId(userId); |
| | | ledger.setUserName(userName); |
| | | ledger.setTenantId(tenantId); |
| | | if (row.getMostDate() != null && row.getValid() != null) { |
| | | ledger.setNextDate(new Date(row.getMostDate().getTime() + 86400000L * row.getValid())); |
| | | } |
| | | ledgers.add(ledger); |
| | | } |
| | | if (!codes.isEmpty()) { |
| | | for (String code : measuringInstrumentLedgerMapper.selectExistingCodes(tenantId, codes)) { |
| | | errors.put(-1, "计éå¨å
·ç¼å·å·²åå¨ï¼" + code); |
| | | } |
| | | } |
| | | if (!errors.isEmpty()) { |
| | | return AjaxResult.error("导å
¥æ ¡éªå¤±è´¥ï¼" + errors.values().stream().limit(100).collect(Collectors.joining("ï¼"))); |
| | | } |
| | | saveBatch(ledgers); |
| | | return AjaxResult.success("æå导å
¥ " + ledgers.size() + " æ¡æ°æ®"); |
| | | } catch (Exception e) { |
| | | log.error("计éå¨å
·å°è´¦å¯¼å
¥å¤±è´¥", e); |
| | | return AjaxResult.error("导å
¥å¤±è´¥ï¼è¯·æ£æ¥ Excel å
容"); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void downloadTemplate(HttpServletResponse response) { |
| | | ExcelUtil<MeasuringInstrumentLedgerImportDto> util = new ExcelUtil<>(MeasuringInstrumentLedgerImportDto.class); |
| | | util.importTemplateExcel(response, "计éå¨å
·å°è´¦å¯¼å
¥æ¨¡æ¿"); |
| | | } |
| | | |
| | | @Override |
| | | public void export(HttpServletResponse response) { |
| | | List<MeasuringInstrumentLedger> list = measuringInstrumentLedgerMapper.listPage(new MeasuringInstrumentLedger()); |
| | | ExcelUtil<MeasuringInstrumentLedger> util = new ExcelUtil<MeasuringInstrumentLedger>(MeasuringInstrumentLedger.class); |
| | |
| | | import com.ruoyi.production.pojo.ProductionPlan; |
| | | import com.ruoyi.production.service.ProductionOrderService; |
| | | import com.ruoyi.production.service.ProductionPlanService; |
| | | import com.ruoyi.sales.mapper.SalesLedgerMapper; |
| | | import com.ruoyi.sales.mapper.SalesLedgerProductMapper; |
| | | import com.ruoyi.sales.pojo.SalesLedger; |
| | | import com.ruoyi.sales.pojo.SalesLedgerProduct; |
| | | import jakarta.servlet.http.HttpServletResponse; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | private final ProductionOrderService productionOrderService; |
| | | private final ProductModelMapper productModelMapper; |
| | | private final ProductMapper productMapper; |
| | | private final SalesLedgerMapper salesLedgerMapper; |
| | | private final SalesLedgerProductMapper salesLedgerProductMapper; |
| | | |
| | | @Override |
| | | public IPage<ProductionPlanVo> listPage(Page<ProductionPlanDto> page, ProductionPlanDto productionPlanDto) { |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean add(ProductionPlanDto dto) { |
| | | validateSalesSource(dto); |
| | | // æ°å¢ä¸»ç产计å |
| | | if (StringUtils.isBlank(dto.getMpsNo())) { |
| | | String datePrefix = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")); |
| | |
| | | throw new ServiceException("ç¼è¾å¤±è´¥ï¼æ°æ®ä¸è½ä¸ºç©º"); |
| | | } |
| | | |
| | | validateSalesSource(dto); |
| | | ProductionPlan old = getById(dto.getId()); |
| | | if (old == null) { |
| | | throw new ServiceException("ç¼è¾å¤±è´¥ï¼ç产计åä¸åå¨"); |
| | |
| | | util.exportExcel(response, exportList, "主ç产计å"); |
| | | } |
| | | |
| | | private void validateSalesSource(ProductionPlanDto dto) { |
| | | if (dto == null) { |
| | | throw new ServiceException("ç产计åä¸è½ä¸ºç©º"); |
| | | } |
| | | if (dto.getSalesLedgerId() == null && dto.getSalesLedgerProductId() == null) { |
| | | return; |
| | | } |
| | | if (dto.getSalesLedgerId() == null || dto.getSalesLedgerProductId() == null) { |
| | | throw new ServiceException("éå®å°è´¦åéå®äº§åå¿
须忶填å"); |
| | | } |
| | | SalesLedgerProduct product = salesLedgerProductMapper.selectById(dto.getSalesLedgerProductId()); |
| | | if (product == null || !Objects.equals(product.getSalesLedgerId(), dto.getSalesLedgerId())) { |
| | | throw new ServiceException("éå®äº§åä¸éå®å°è´¦ä¸å¹é
"); |
| | | } |
| | | SalesLedger ledger = salesLedgerMapper.selectById(dto.getSalesLedgerId()); |
| | | if (ledger == null || (!Objects.equals(ledger.getContractType(), 1) |
| | | && !Objects.equals(ledger.getContractType(), 3))) { |
| | | throw new ServiceException("ç产计ååªè½å
³èæ®ééå®äº§åææ¡æ¶è®¢å产å"); |
| | | } |
| | | if (dto.getProductModelId() == null) { |
| | | dto.setProductModelId(product.getProductModelId()); |
| | | } else if (!Objects.equals(dto.getProductModelId(), product.getProductModelId())) { |
| | | throw new ServiceException("ç产计å产ååå·ä¸éå®äº§åä¸ä¸è´"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ ¡éªä¸»ç产计åå·å¯ä¸æ§ï¼å¯éè¿ excludeId æé¤å½åè®°å½ã |
| | | */ |
| | |
| | | return toAjax(salesLedgerService.addOrUpdateSalesLedger(salesLedgerDto)); |
| | | } |
| | | |
| | | @PostMapping("/createFrameworkOrder") |
| | | @Operation(summary = "åå»ºæ¡æ¶è®¢å") |
| | | public AjaxResult createFrameworkOrder(@RequestBody SalesLedgerDto salesLedgerDto) { |
| | | return toAjax(salesLedgerService.createFrameworkOrder(salesLedgerDto)); |
| | | } |
| | | |
| | | @GetMapping("/listFrameworkOrders") |
| | | @Operation(summary = "æ¥è¯¢æ¡æ¶ååä¸çæ¡æ¶è®¢å") |
| | | public AjaxResult listFrameworkOrders(@RequestParam("parentContractId") Long parentContractId) { |
| | | return AjaxResult.success(salesLedgerService.listFrameworkOrders(parentContractId)); |
| | | } |
| | | |
| | | @GetMapping("/frameworkContractShippedQuantity") |
| | | @Operation(summary = "æ¥è¯¢æ¡æ¶åå累计已åè´§æ°é") |
| | | public AjaxResult frameworkContractShippedQuantity(@RequestParam("parentContractId") Long parentContractId) { |
| | | return AjaxResult.success(salesLedgerService.getFrameworkContractShippedQuantity(parentContractId)); |
| | | } |
| | | |
| | | /** |
| | | * å é¤éå®å°è´¦ |
| | | */ |
| | |
| | | public class SalesLedgerDto { |
| | | private Long id; |
| | | private String salesContractNo; |
| | | private Integer contractType = 1; |
| | | private Long parentContractId; |
| | | private String customerContractNo; |
| | | private String projectName; |
| | | @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
| | |
| | | |
| | | IPage<PurchaseReportVo> selectPurchaseReportVoPage(Page page, @Param("customerName") String customerName); |
| | | |
| | | /** |
| | | * æ¥è¯¢æ¡æ¶ååä¸çæ¡æ¶è®¢åå表ï¼å¹¶å
³èæ±æ»å·²åè´§æ°é |
| | | */ |
| | | List<com.ruoyi.sales.vo.FrameworkOrderVo> listFrameworkOrders(@Param("parentContractId") Long parentContractId); |
| | | |
| | | /** |
| | | * ææ¡æ¶ååç»è®¡ç´¯è®¡åè´§æ°é |
| | | */ |
| | | BigDecimal sumShippedByParentContract(@Param("parentContractId") Long parentContractId); |
| | | |
| | | } |
| | |
| | | private String salesContractNo; |
| | | |
| | | /** |
| | | * ååç±»åï¼1æ®ééå®ååï¼2æ¡æ¶ååï¼3æ¡æ¶è®¢å |
| | | */ |
| | | private Integer contractType = 1; |
| | | |
| | | /** |
| | | * ç¶æ¡æ¶ååID |
| | | */ |
| | | private Long parentContractId; |
| | | |
| | | /** |
| | | * 客æ·ååå· |
| | | */ |
| | | @Excel(name = "客æ·ååå·", type = Excel.Type.IMPORT) |
| | |
| | | private Long salesLedgerId; |
| | | |
| | | /** |
| | | * ç¶æ¡æ¶åå产åID |
| | | */ |
| | | private Long parentProductId; |
| | | |
| | | /** |
| | | * æ¡æ¶è®¢åäº¤è´§æ¥æ |
| | | */ |
| | | @JsonFormat(pattern = "yyyy-MM-dd") |
| | | private java.time.LocalDate deliveryDate; |
| | | |
| | | /** |
| | | * é¢è¦æ°é |
| | | */ |
| | | private BigDecimal warnNum; |
| | |
| | | import com.ruoyi.sales.dto.SalesLedgerDto; |
| | | import com.ruoyi.sales.pojo.SalesLedger; |
| | | import com.ruoyi.sales.pojo.SalesLedgerProduct; |
| | | import com.ruoyi.sales.vo.FrameworkOrderVo; |
| | | import com.ruoyi.sales.vo.SalesLedgerVo; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | |
| | | |
| | | int addOrUpdateSalesLedger(SalesLedgerDto salesLedgerDto); |
| | | |
| | | int createFrameworkOrder(SalesLedgerDto salesLedgerDto); |
| | | |
| | | List<FrameworkOrderVo> listFrameworkOrders(Long parentContractId); |
| | | |
| | | BigDecimal getFrameworkContractShippedQuantity(Long parentContractId); |
| | | |
| | | List<SalesLedgerProduct> getSalesLedgerProductListByRelateId(@NotNull Long relateId,@NotNull SaleEnum type); |
| | | List<SalesLedgerProduct> getSalesLedgerProductListByIds(@Nullable List<Long> relateIds, @NotNull SaleEnum type); |
| | | |
| | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.framework.web.domain.R; |
| | | import com.ruoyi.procurementrecord.utils.StockUtils; |
| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.lang.reflect.Field; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.time.LocalDate; |
| | | import java.time.LocalDateTime; |
| | | import java.time.format.DateTimeFormatter; |
| | | import java.util.Arrays; |
| | |
| | | * æ°å¢çäº§æ°æ® |
| | | */ |
| | | public void addProductionData(SalesLedgerProduct salesLedgerProduct) { |
| | | //å
å¤æè¯¥äº§åæ¯å¦éè¦ç产 |
| | | if (!BooleanUtils.isTrue(salesLedgerProduct.getIsProduction())) { |
| | | SalesLedger salesLedger = salesLedgerMapper.selectById(salesLedgerProduct.getSalesLedgerId()); |
| | | if (salesLedger == null) { |
| | | return; |
| | | } |
| | | SalesLedger salesLedger = salesLedgerMapper.selectById(salesLedgerProduct.getSalesLedgerId()); |
| | | boolean isFrameworkOrder = Objects.equals(salesLedger.getContractType(), 3); |
| | | // æ¡æ¶ååä¸çæç产计åï¼æ¡æ¶è®¢ååºå®çæï¼æ°éç空ï¼ä¸åæ¶å¡«åï¼ |
| | | if (Objects.equals(salesLedger.getContractType(), 2)) { |
| | | return; |
| | | } |
| | | if (!isFrameworkOrder && !BooleanUtils.isTrue(salesLedgerProduct.getIsProduction())) { |
| | | return; |
| | | } |
| | | ProductionPlan productionPlan = new ProductionPlan(); |
| | | productionPlan.setSalesLedgerId(salesLedgerProduct.getSalesLedgerId()); |
| | | productionPlan.setSalesLedgerProductId(salesLedgerProduct.getId()); |
| | | productionPlan.setMpsNo(generateNextPlanNo(com.ruoyi.common.utils.DateUtils.toLocalDate(salesLedger.getEntryDate()) |
| | | .format(DateTimeFormatter.ofPattern("yyyyMMdd")))); |
| | | // 计ååå·æ¥æåç¼ï¼ç»è®°æ¥æä¸ºç©ºæ¶åå½åæ¥æ |
| | | java.time.LocalDate planDate = salesLedger.getEntryDate() != null |
| | | ? com.ruoyi.common.utils.DateUtils.toLocalDate(salesLedger.getEntryDate()) |
| | | : java.time.LocalDate.now(); |
| | | productionPlan.setMpsNo(generateNextPlanNo(planDate.format(DateTimeFormatter.ofPattern("yyyyMMdd")))); |
| | | productionPlan.setProductModelId(salesLedgerProduct.getProductModelId()); |
| | | productionPlan.setQtyRequired(salesLedgerProduct.getQuantity()); |
| | | productionPlan.setSource("éå®"); |
| | | productionPlan.setStatus(0); |
| | | productionPlan.setRequiredDate(salesLedger.getDeliveryDate());//éæ±æ¥æ=äº¤è´§æ¥æ |
| | | productionPlan.setPromisedDeliveryDate(salesLedger.getDeliveryDate());//æ¿è¯ºæ¥æ=äº¤è´§æ¥æ |
| | | // éæ±æ¥æ=äº¤è´§æ¥æï¼æ¡æ¶è®¢åå产åäº¤è´§æ¥æï¼å
¶ä½åä¸»è¡¨äº¤è´§æ¥æ |
| | | LocalDate deliveryDate = isFrameworkOrder ? salesLedgerProduct.getDeliveryDate() : salesLedger.getDeliveryDate(); |
| | | productionPlan.setRequiredDate(deliveryDate);//éæ±æ¥æ=äº¤è´§æ¥æ |
| | | productionPlan.setPromisedDeliveryDate(deliveryDate);//æ¿è¯ºæ¥æ=äº¤è´§æ¥æ |
| | | productionPlanMapper.insert(productionPlan); |
| | | |
| | | } |
| | |
| | | .filter(Objects::nonNull) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | |
| | | try { |
| | | S entity = mainEntityClass.getDeclaredConstructor().newInstance(); |
| | | Field idField = mainEntityClass.getDeclaredField("id"); |
| | | idField.setAccessible(true); |
| | | idField.set(entity, mainId); |
| | | |
| | | Field amountField = mainEntityClass.getDeclaredField("contractAmount"); |
| | | amountField.setAccessible(true); |
| | | amountField.set(entity, totalAmount); |
| | | |
| | | mainMapper.updateById(entity); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("å¨ææ´æ°ä¸»è¡¨éé¢å¤±è´¥", e); |
| | | } |
| | | // ä»
æ´æ°éé¢åï¼é¿å
æ´å®ä½ updateById æå
¶å®éç©ºåæ®µï¼å¦ contract_type é»è®¤å¼ 1ï¼ä¸å¹¶è¦ç |
| | | UpdateWrapper<S> wrapper = Wrappers.update(); |
| | | wrapper.eq("id", mainId) |
| | | .set("contract_amount", totalAmount); |
| | | mainMapper.update(null, wrapper); |
| | | } |
| | | @Override |
| | | public R judgmentInventory(SalesLedgerProduct salesLedgerProduct) { |
| | |
| | | package com.ruoyi.sales.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; |
| | |
| | | import com.ruoyi.sales.pojo.SalesLedgerProduct; |
| | | import com.ruoyi.sales.pojo.ShippingInfo; |
| | | import com.ruoyi.sales.service.ISalesLedgerService; |
| | | import com.ruoyi.sales.vo.FrameworkOrderVo; |
| | | import com.ruoyi.sales.vo.SalesLedgerVo; |
| | | import lombok.RequiredArgsConstructor; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | |
| | | import java.io.InputStream; |
| | | import java.lang.reflect.Field; |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.time.LocalDate; |
| | |
| | | salesLedgerProduct.setApproveStatus(0); |
| | | salesLedgerProduct.setIsProduction(salesLedgerProductImportDto.getIsProduction() == 1); |
| | | salesLedgerProductMapper.insert(salesLedgerProduct); |
| | | // æ·»å çäº§æ°æ® |
| | | salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct); |
| | | addProductionDataIfNeeded(salesLedgerProduct); |
| | | } |
| | | } |
| | | |
| | |
| | | if (CollectionUtils.isEmpty(idList)) { |
| | | return 0; |
| | | } |
| | | long childCount = salesLedgerMapper.selectCount(new LambdaQueryWrapper<SalesLedger>() |
| | | .in(SalesLedger::getParentContractId, idList)); |
| | | if (childCount > 0) { |
| | | throw new BaseException("æ¡æ¶ååå卿¡æ¶è®¢åï¼ä¸è½å é¤"); |
| | | } |
| | | // å é¤éå®ç®¡çæ°æ® |
| | | LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.in(SalesLedgerProduct::getSalesLedgerId, idList) |
| | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int addOrUpdateSalesLedger(SalesLedgerDto salesLedgerDto) { |
| | | log.info("addOrUpdateSalesLedger æ¶å° contractType={}, parentContractId={}, id={}", |
| | | salesLedgerDto == null ? null : salesLedgerDto.getContractType(), |
| | | salesLedgerDto == null ? null : salesLedgerDto.getParentContractId(), |
| | | salesLedgerDto == null ? null : salesLedgerDto.getId()); |
| | | // 1. æ ¡éªå®¢æ·ä¿¡æ¯ |
| | | Customer customer = customerMapper.selectById(salesLedgerDto.getCustomerId()); |
| | | if (customer == null) { |
| | |
| | | |
| | | // 2. DTO转Entity |
| | | SalesLedger salesLedger = convertToEntity(salesLedgerDto); |
| | | log.info("convertToEntity å contractType={}", salesLedger.getContractType()); |
| | | salesLedger.setCustomerName(customer.getCustomerName()); |
| | | salesLedger.setTenantId(customer.getTenantId()); |
| | | // å½å
¥äººï¼å¦ææªä¼ å使ç¨å½åç»å½ç¨æ· |
| | |
| | | } else { |
| | | salesLedgerMapper.updateById(salesLedger); |
| | | } |
| | | // è¯æï¼insert/update ååæ¥æ°æ®åºå®é
åå
¥ç contract_type |
| | | SalesLedger dbCheckLedger = salesLedgerMapper.selectById(salesLedger.getId()); |
| | | log.info("DB å®é
contract_type={}, id={}", dbCheckLedger == null ? null : dbCheckLedger.getContractType(), salesLedger.getId()); |
| | | |
| | | |
| | | // 4. å¤çåè¡¨æ°æ® |
| | |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int createFrameworkOrder(SalesLedgerDto dto) { |
| | | if (dto == null || dto.getId() == null) { |
| | | throw new BaseException("è¯·éæ©æ¡æ¶åå"); |
| | | } |
| | | SalesLedger parent = salesLedgerMapper.selectById(dto.getId()); |
| | | if (parent == null || !Objects.equals(parent.getContractType(), 2)) { |
| | | throw new BaseException("ç¶å°è´¦ä¸æ¯æ¡æ¶åå"); |
| | | } |
| | | if (CollectionUtils.isEmpty(dto.getProductData())) { |
| | | throw new BaseException("è¯·å¡«åæ¡æ¶è®¢å产å"); |
| | | } |
| | | SalesLedger order = new SalesLedger(); |
| | | order.setCustomerContractNo(parent.getCustomerContractNo()); |
| | | order.setProjectName(parent.getProjectName()); |
| | | order.setSalesman(parent.getSalesman()); |
| | | order.setCustomerId(parent.getCustomerId()); |
| | | order.setCustomerName(parent.getCustomerName()); |
| | | order.setEntryPerson(String.valueOf(SecurityUtils.getUserId())); |
| | | order.setRemarks(dto.getRemarks()); |
| | | order.setTenantId(parent.getTenantId()); |
| | | order.setExecutionDate(parent.getExecutionDate()); |
| | | order.setPaymentMethod(parent.getPaymentMethod()); |
| | | order.setEntryDate(parent.getEntryDate()); |
| | | order.setId(null); |
| | | order.setContractType(3); |
| | | order.setParentContractId(parent.getId()); |
| | | order.setSalesContractNo(generateSalesContractNo(new Date())); |
| | | order.setDeliveryDate(null); |
| | | order.setContractAmount(BigDecimal.ZERO); |
| | | order.setNetContractAmount(BigDecimal.ZERO); |
| | | salesLedgerMapper.insert(order); |
| | | |
| | | Set<Long> parentProductIds = dto.getProductData().stream() |
| | | .map(SalesLedgerProduct::getParentProductId) |
| | | .collect(Collectors.toSet()); |
| | | if (parentProductIds.contains(null) || parentProductIds.size() != dto.getProductData().size()) { |
| | | throw new BaseException("æ¡æ¶è®¢å产åå¿
é¡»å
³èä¸åçç¶äº§å"); |
| | | } |
| | | Map<Long, SalesLedgerProduct> parentProducts = salesLedgerProductMapper.selectBatchIds(parentProductIds).stream() |
| | | .collect(Collectors.toMap(SalesLedgerProduct::getId, Function.identity())); |
| | | for (SalesLedgerProduct requestProduct : dto.getProductData()) { |
| | | if (requestProduct.getDeliveryDate() == null) { |
| | | throw new BaseException("æ¡æ¶è®¢å产åå¿
é¡»å
³èç¶äº§åå¹¶å¡«åäº¤è´§æ¥æ"); |
| | | } |
| | | SalesLedgerProduct parentProduct = parentProducts.get(requestProduct.getParentProductId()); |
| | | if (parentProduct == null || !Objects.equals(parentProduct.getSalesLedgerId(), parent.getId()) |
| | | || !Objects.equals(parentProduct.getType(), SaleEnum.SALE.getCode())) { |
| | | throw new BaseException("æ¡æ¶è®¢å产åä¸å±äºè¯¥æ¡æ¶åå"); |
| | | } |
| | | SalesLedgerProduct product = new SalesLedgerProduct(); |
| | | BeanUtils.copyProperties(parentProduct, product); |
| | | product.setId(null); |
| | | product.setSalesLedgerId(order.getId()); |
| | | product.setParentProductId(parentProduct.getId()); |
| | | product.setQuantity(null); |
| | | product.setDeliveryDate(requestProduct.getDeliveryDate()); |
| | | product.setIsProduction(false); |
| | | product.setType(SaleEnum.SALE.getCode()); |
| | | if (product.getTaxRate() == null) { |
| | | product.setTaxRate(BigDecimal.ZERO); |
| | | } |
| | | salesLedgerProductMapper.insert(product); |
| | | // æ¡æ¶è®¢åå建æ¶çæç产计åï¼æ°éç空ï¼ä¸åæ¶å¡«åï¼ |
| | | salesLedgerProductServiceImpl.addProductionData(product); |
| | | } |
| | | return 1; |
| | | } |
| | | |
| | | @Override |
| | | public List<FrameworkOrderVo> listFrameworkOrders(Long parentContractId) { |
| | | return salesLedgerMapper.listFrameworkOrders(parentContractId); |
| | | } |
| | | |
| | | @Override |
| | | public BigDecimal getFrameworkContractShippedQuantity(Long parentContractId) { |
| | | return salesLedgerMapper.sumShippedByParentContract(parentContractId); |
| | | } |
| | | |
| | | @Override |
| | | public void handleSalesLedgerProducts(Long salesLedgerId, List<SalesLedgerProduct> products, SaleEnum type) { |
| | | // æIDåç»ï¼åºåæ°å¢åæ´æ°çè®°å½ |
| | | Map<Boolean, List<SalesLedgerProduct>> partitionedProducts = products.stream() |
| | |
| | | if (!insertList.isEmpty()) { |
| | | for (SalesLedgerProduct salesLedgerProduct : insertList) { |
| | | salesLedgerProduct.setType(type.getCode()); |
| | | if (salesLedgerProduct.getTaxRate() == null) { |
| | | salesLedgerProduct.setTaxRate(BigDecimal.ZERO); |
| | | } |
| | | salesLedgerProductMapper.insert(salesLedgerProduct); |
| | | // æ·»å çäº§æ°æ® |
| | | salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct); |
| | | addProductionDataIfNeeded(salesLedgerProduct); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void addProductionDataIfNeeded(SalesLedgerProduct product) { |
| | | SalesLedger ledger = salesLedgerMapper.selectById(product.getSalesLedgerId()); |
| | | if (ledger != null && !Objects.equals(ledger.getContractType(), 2) |
| | | && !Objects.equals(ledger.getContractType(), 3)) { |
| | | salesLedgerProductServiceImpl.addProductionData(product); |
| | | } |
| | | } |
| | | |
| | |
| | | .filter(Objects::nonNull) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | |
| | | // æé ä¸»è¡¨æ´æ°å¯¹è±¡ |
| | | // ä»
æ´æ°éé¢åï¼é¿å
æ´å®ä½ updateById æå
¶å®éç©ºåæ®µï¼å¦ contract_type é»è®¤å¼ 1ï¼ä¸å¹¶è¦ç |
| | | UpdateWrapper<S> wrapper = Wrappers.update(); |
| | | wrapper.eq("id", mainId) |
| | | .set("contract_amount", totalAmount); |
| | | // å®é
ååéé¢åå§å¼çäºååéé¢ |
| | | boolean hasNetAmount; |
| | | try { |
| | | S entity = mainEntityClass.getDeclaredConstructor().newInstance(); |
| | | Field idField = mainEntityClass.getDeclaredField("id"); |
| | | idField.setAccessible(true); |
| | | idField.set(entity, mainId); |
| | | |
| | | Field amountField = mainEntityClass.getDeclaredField("contractAmount"); |
| | | amountField.setAccessible(true); |
| | | amountField.set(entity, totalAmount); |
| | | |
| | | // å®é
ååéé¢åå§å¼çäºååéé¢ |
| | | try { |
| | | Field netAmountField = mainEntityClass.getDeclaredField("netContractAmount"); |
| | | netAmountField.setAccessible(true); |
| | | netAmountField.set(entity, totalAmount); |
| | | } catch (NoSuchFieldException ignored) { |
| | | // åç±»å¯è½æ²¡æè¯¥å段ï¼å¿½ç¥ |
| | | } |
| | | |
| | | mainMapper.updateById(entity); |
| | | } catch (Exception e) { |
| | | throw new RuntimeException("å¨ææ´æ°ä¸»è¡¨éé¢å¤±è´¥", e); |
| | | mainEntityClass.getDeclaredField("netContractAmount"); |
| | | hasNetAmount = true; |
| | | } catch (NoSuchFieldException e) { |
| | | hasNetAmount = false; |
| | | } |
| | | if (hasNetAmount) { |
| | | wrapper.set("net_contract_amount", totalAmount); |
| | | } |
| | | mainMapper.update(null, wrapper); |
| | | } |
| | | |
| | | // å
é¨ç±»ç¨äºåå¨èåç»æ |
| | |
| | | import com.ruoyi.sales.dto.ShippingApproveDto; |
| | | import com.ruoyi.sales.dto.ShippingInfoDto; |
| | | import com.ruoyi.sales.dto.ShippingProductDetailDto; |
| | | import com.ruoyi.sales.mapper.SalesLedgerMapper; |
| | | import com.ruoyi.sales.mapper.SalesLedgerProductMapper; |
| | | import com.ruoyi.sales.mapper.ShippingInfoMapper; |
| | | import com.ruoyi.sales.mapper.ShippingProductDetailMapper; |
| | | import com.ruoyi.sales.pojo.SalesLedger; |
| | | import com.ruoyi.sales.pojo.SalesLedgerProduct; |
| | | import com.ruoyi.sales.pojo.ShippingInfo; |
| | | import com.ruoyi.sales.pojo.ShippingProductDetail; |
| | | import com.ruoyi.sales.service.ShippingInfoService; |
| | |
| | | |
| | | |
| | | private final SalesLedgerProductMapper salesLedgerProductMapper; |
| | | |
| | | private final SalesLedgerMapper salesLedgerMapper; |
| | | |
| | | private final StockUtils stockUtils; |
| | | |
| | |
| | | @Override |
| | | public boolean addReq(ShippingInfoDto req) { |
| | | |
| | | // æ ¡éªè¯¥äº§åæ¯å¦å·²æå¾
å®¡æ ¸/å®¡æ ¸ä¸çåè´§è®°å½ï¼é²æ¢éå¤æäº¤ |
| | | // æ¡æ¶åååªç¨äºç»è®°äº§åèå´ï¼å®é
åè´§å¿
é¡»å
³èæ¡æ¶è®¢å产åã |
| | | Long salesLedgerProductId = req.getSalesLedgerProductId(); |
| | | if (salesLedgerProductId != null) { |
| | | SalesLedgerProduct product = salesLedgerProductMapper.selectById(salesLedgerProductId); |
| | | if (product == null) { |
| | | throw new RuntimeException("éå®äº§åä¸åå¨"); |
| | | } |
| | | if (req.getSalesLedgerId() != null |
| | | && !java.util.Objects.equals(req.getSalesLedgerId(), product.getSalesLedgerId())) { |
| | | throw new RuntimeException("åè´§å°è´¦ä¸éå®äº§åä¸å¹é
"); |
| | | } |
| | | SalesLedger ledger = salesLedgerMapper.selectById(product.getSalesLedgerId()); |
| | | if (ledger == null || (!java.util.Objects.equals(ledger.getContractType(), 1) |
| | | && !java.util.Objects.equals(ledger.getContractType(), 3))) { |
| | | throw new RuntimeException("该éå®äº§åä¸å
许åè´§"); |
| | | } |
| | | } |
| | | // æ ¡éªè¯¥äº§åæ¯å¦å·²æå¾
å®¡æ ¸/å®¡æ ¸ä¸çåè´§è®°å½ï¼é²æ¢éå¤æäº¤ |
| | | if (salesLedgerProductId != null) { |
| | | long pendingCount = this.count(new LambdaQueryWrapper<ShippingInfo>() |
| | | .eq(ShippingInfo::getSalesLedgerProductId, salesLedgerProductId) |
| | | .in(ShippingInfo::getStatus, "å¾
å®¡æ ¸", "å®¡æ ¸ä¸")); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | package com.ruoyi.sales.vo; |
| | | |
| | | import com.ruoyi.sales.pojo.SalesLedger; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * æ¡æ¶ååä¸çæ¡æ¶è®¢ååè¡¨åæ±æ» |
| | | */ |
| | | @Data |
| | | public class FrameworkOrderVo extends SalesLedger { |
| | | |
| | | private BigDecimal shippedQuantity; |
| | | |
| | | private BigDecimal orderedQuantity; |
| | | } |
| | |
| | | import com.ruoyi.sales.pojo.SalesLedger; |
| | | import lombok.Data; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.List; |
| | | |
| | | @Data |
| | | public class SalesLedgerVo extends SalesLedger { |
| | | |
| | | private List<StorageBlobVO> storageBlobVOs; |
| | | |
| | | private BigDecimal shippedQuantity; |
| | | |
| | | private Integer frameworkOrderCount; |
| | | } |
| | |
| | | dl.tenant_id, |
| | | dl.is_depr, |
| | | dl.annual_depreciation_amount, |
| | | dl.type |
| | | dl.type, |
| | | dl.area_id, |
| | | da.name AS area_name |
| | | FROM device_ledger dl |
| | | left join sys_user su on dl.create_user = su.user_id |
| | | left join device_area da on dl.area_id = da.id |
| | | <where> |
| | | <!-- 设å¤åç§° --> |
| | | <if test="deviceLedger.deviceName != null and deviceLedger.deviceName != ''"> |
| | |
| | | <if test="deviceLedger.tenantId != null"> |
| | | AND tenant_id = #{deviceLedger.tenantId} |
| | | </if> |
| | | |
| | | <!-- åºåIDï¼å«è¯¥åºååå
¶ææå级ï¼éè¿ç¥çº§è·¯å¾å¹é
ï¼ --> |
| | | <if test="deviceLedger.areaId != null"> |
| | | AND ( |
| | | dl.area_id = #{deviceLedger.areaId} |
| | | OR EXISTS ( |
| | | SELECT 1 FROM device_area da2 |
| | | WHERE da2.id = dl.area_id |
| | | AND (da2.ancestors = #{deviceLedger.areaId} |
| | | OR da2.ancestors LIKE CONCAT(#{deviceLedger.areaId}, ',%') |
| | | OR da2.ancestors LIKE CONCAT('%,', #{deviceLedger.areaId}, ',%') |
| | | OR da2.ancestors LIKE CONCAT('%,', #{deviceLedger.areaId})) |
| | | ) |
| | | ) |
| | | </if> |
| | | </where> |
| | | ORDER BY create_time DESC |
| | | </select> |
| | | <select id="selectDeviceOptions" resultType="com.ruoyi.device.dto.DeviceLedgerDto"> |
| | | SELECT |
| | | dl.id, |
| | | dl.device_name, |
| | | dl.device_model, |
| | | dl.device_brand, |
| | | dl.type, |
| | | dl.area_id, |
| | | da.name AS area_name |
| | | FROM device_ledger dl |
| | | left join device_area da on dl.area_id = da.id |
| | | <where> |
| | | <if test="areaId != null"> |
| | | AND ( |
| | | dl.area_id = #{areaId} |
| | | OR EXISTS ( |
| | | SELECT 1 FROM device_area da2 |
| | | WHERE da2.id = dl.area_id |
| | | AND (da2.ancestors = #{areaId} |
| | | OR da2.ancestors LIKE CONCAT(#{areaId}, ',%') |
| | | OR da2.ancestors LIKE CONCAT('%,', #{areaId}, ',%') |
| | | OR da2.ancestors LIKE CONCAT('%,', #{areaId})) |
| | | ) |
| | | ) |
| | | </if> |
| | | </where> |
| | | ORDER BY dl.create_time DESC |
| | | </select> |
| | | |
| | | <select id="deviceLedgerExportList" resultType="com.ruoyi.device.execl.DeviceLedgerExeclDto"> |
| | | |
| | | </select> |
| | |
| | | </where> |
| | | ORDER BY create_time DESC |
| | | </select> |
| | | |
| | | <select id="selectExistingCodes" resultType="java.lang.String"> |
| | | SELECT code |
| | | FROM measuring_instrument_ledger |
| | | WHERE tenant_id = #{tenantId} |
| | | AND code IN |
| | | <foreach collection="codes" item="code" open="(" separator="," close=")"> |
| | | #{code} |
| | | </foreach> |
| | | </select> |
| | | </mapper> |
| | |
| | | order by sl.entry_date desc |
| | | </select> |
| | | |
| | | <select id="listFrameworkOrders" resultType="com.ruoyi.sales.vo.FrameworkOrderVo"> |
| | | select sl.*, IFNULL(shipped.shipped_quantity, 0) AS shippedQuantity |
| | | from sales_ledger sl |
| | | left join ( |
| | | select slp.sales_ledger_id, SUM(spd.quantity) AS shipped_quantity |
| | | from sales_ledger_product slp |
| | | inner join shipping_info si on slp.id = si.sales_ledger_product_id and si.status = 'å·²åè´§' |
| | | inner join shipping_product_detail spd on si.id = spd.shipping_info_id |
| | | group by slp.sales_ledger_id |
| | | ) shipped on sl.id = shipped.sales_ledger_id |
| | | where sl.parent_contract_id = #{parentContractId} |
| | | and sl.contract_type = 3 |
| | | order by sl.execution_date desc |
| | | </select> |
| | | |
| | | <select id="sumShippedByParentContract" resultType="java.math.BigDecimal"> |
| | | select IFNULL(SUM(spd.quantity), 0) |
| | | from sales_ledger slo |
| | | inner join sales_ledger_product slp on slo.id = slp.sales_ledger_id |
| | | inner join shipping_info si on slp.id = si.sales_ledger_product_id and si.status = 'å·²åè´§' |
| | | inner join shipping_product_detail spd on si.id = spd.shipping_info_id |
| | | where slo.parent_contract_id = #{parentContractId} |
| | | </select> |
| | | |
| | | </mapper> |