| doc/20260601_出库领用批次_前端联调文档.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| doc/20260601_库存物联设备绑定_前端联调文档.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/quality/dto/BatchQuickInspectRequest.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/stock/controller/StockInventoryController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/stock/dto/StockIotRealtimeDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/resources/mapper/stock/StockInventoryMapper.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
doc/20260601_³ö¿âÁìÓÃÅú´Î_ǰ¶ËÁªµ÷Îĵµ.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,107 @@ # åºåºé¢ç¨ â å è®¸ç¨æ·å¡«ååºåºæ¹æ¬¡ â å端èè°ææ¡£ ## åæ´æ¦è¿° åºåºé¢ç¨æ¶æ°å¢**åºåºæ¹æ¬¡**ï¼`outboundBatches`ï¼å段ï¼å è®¸ç¨æ·å¨åºåºè¡¨å䏿å¨å¡«åãè¥ç空åç³»ç»èªå¨çæï¼æ ¼å¼ï¼`CK20260601-001`ï¼ã --- ## æ¶åçæ¥å£ ä¸¤ä¸ªåºåºæ¥å£åå·²æ¯æ `outboundBatches` åæ®µï¼ | æ¥å£ | 说æ | |------|------| | `POST /stockInventory/subtractStockInventory` | ç´æ¥æ£ååºåï¼å«åºåºæ¹æ¬¡ï¼ | | `POST /stockInventory/addStockOutRecordOnly` | ä» å建åºåºè®°å½ä¸æ£åºåï¼å®¡æ¹æµï¼ | --- ## 请æ±åæ°æ°å¢å段 `StockInventoryDto` ä¸å·²æçå¯éåæ®µï¼ | åæ°å | ç±»å | å¿ å¡« | 说æ | |--------|------|------|------| | `outboundBatches` | `String` | **å¦** | åºåºæ¹æ¬¡å·ï¼ç¨æ·å¯æå¨å¡«å | ### æäº¤ç¤ºä¾ ```json { "productModelId": 123, "batchNo": "BN20250501", "qualitity": 50, "outboundBatches": "2025-颿-第3æ¹", "recordType": "1", "recordId": 0 } ``` ### åæ®µè¡ä¸º | åºæ¯ | `outboundBatches` ä¼ å¼ | ç»æ | |------|----------------------|------| | ç¨æ·æå¨å¡«å | `"2025-颿-第3æ¹"` | 使ç¨ç¨æ·å¡«åçå¼ | | ç¨æ·ç空 | `null` æä¸ä¼ | ç³»ç»èªå¨çæ `CK20260601-001` | | ç¨æ·ä¼ 空串 | `""` | ç³»ç»èªå¨çæ | --- ## åç«¯äº¤äº ### åºåºè¡¨å å¨åºåº/é¢ç¨å¼¹çªä¸æ°å¢ä¸ä¸ªè¾å ¥æ¡ï¼ ``` âââââââââââââââââââââââââââââââââââââââ â åºåºé¢ç¨ â ââââââââââââââââââââââââââââââââââââââ⤠â 产åè§æ ¼ï¼ 马éè¯-å¤§å· â â æ¹å·ï¼ BN20250501 â â åºåºæ°éï¼ [____50____] â â åºåºæ¹æ¬¡ï¼ [2025-颿-第3æ¹] (éå¡«) â â â â æç¤ºï¼ç空å°èªå¨çæ CK20260601-001 â â â â [åæ¶] [确认åºåº] â âââââââââââââââââââââââââââââââââââââââ ``` ### UI 建议 - **è¾å ¥æ¡æ ç¾ï¼** "åºåºæ¹æ¬¡" - **Placeholderï¼** "ç空èªå¨çæ" - **æç¤ºæåï¼ç°è²å°åï¼ï¼** "ä¸å¡«åèªå¨çæï¼æ ¼å¼ï¼CKå¹´ææ¥-åºå·" - **é¿åº¦éå¶ï¼** 建议 100 å符以å --- ## åºåºè®°å½å表å±ç¤º `GET /stockOutRecord/listPage` è¿åçåºåºè®°å½ä¸å·²æ `outboundBatches` åæ®µï¼å端å¯ç´æ¥å±ç¤ºï¼ ```json { "id": 5001, "outboundBatches": "CK20260601-001", "batchNo": "BN20250501", "stockOutNum": 50, "productName": "马éè¯", "model": "大å·", "recordType": "1", "approvalStatus": 0 } ``` åè¡¨ä¸ `outboundBatches` å建议设置å¯ç¹å»æåºåæç´¢ã --- ## 注æäºé¡¹ 1. **ä» æ°å¢å段ï¼ååå ¼å®¹ï¼** ä¸ä¼ `outboundBatches` ä¿æåæè¡ä¸ºï¼èªå¨çæï¼ï¼å·²æè°ç¨ä¸åå½±å 2. **䏿 ¡éªå¯ä¸æ§ï¼** æ¹æ¬¡å·ä¸å¼ºå¶å¯ä¸ï¼ç¨æ·å¯å¡«åèªå®ä¹æ ¼å¼ 3. **åéæ°æ®ï¼** åå²åºåºè®°å½çæ¹æ¬¡å·ä¸ºèªå¨çæçæ ¼å¼ï¼`CK` åç¼ï¼ï¼ä¸ç¨æ·èªå®ä¹æ¹æ¬¡å ±å 4. **å®¡æ¹æµåæ ·æ¯æï¼** `/addStockOutRecordOnly` åå»ºå¾ å®¡æ¹åºåºè®°å½æ¶ä¹æ¯æä¼ å ¥æ¹æ¬¡å· doc/20260601_¿â´æÎïÁªÉ豸°ó¶¨_ǰ¶ËÁªµ÷Îĵµ.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,213 @@ # åºå管ç â ç©è设å¤ç»å® & 宿¶æ°é â å端èè°ææ¡£ ## åæ´æ¦è¿° åºå表 `stock_inventory` ç `warehouse` åæ®µæ¹ä¸ºåå¨**ç©è设å¤ID**ï¼å¤éï¼éå·åéï¼ãæ¶å两个æ¥å£ï¼ - **æ¥å£ä¸ï¼è®¾å¤ç»å®ï¼ï¼** å¤ç¨ç°æåºå墿¹æ¥å£ï¼`warehouse` åæ®µä¼ éå·åéç设å¤ID - **æ¥å£äºï¼å®æ¶æ°éï¼ï¼** æ°å¢ `GET /stockInventory/iotRealtime/{id}`ï¼æ¥è¯¢ç»å®è®¾å¤ç宿¶æ¸©æ¹¿åº¦/CO2çæ°æ® --- ## æ¥å£ä¸ï¼è®¾å¤ç»å® ### 1.1 æ¥å£ä¿¡æ¯ | é¡¹ç® | å 容 | |------|------| | æ¥å£å°å | `POST /stockInventory/addstockInventory` | | è¯·æ±æ¹å¼ | `POST` | | æ¥å£è¯´æ | æ°å¢åºåï¼`warehouse` åæ®µä¼ ç©è设å¤IDï¼å¤ééå·åéï¼ | > ç¼è¾åºååçï¼å¨åæç¼è¾æ¥å£ä¸å° `warehouse` æ¹ä¸ºè®¾å¤IDå³å¯ã ### 1.2 è·åå¯é设å¤å表 **å¤ç¨å·²ææ¥å£ï¼** `GET /device/ledger/page` | åæ° | å¼ | 说æ | |------|-----|------| | `isIotDevice` | `1` | åªæ¥è¯¢ç©èè®¾å¤ | | `size` | `999` | 䏿¬¡æåå ¨é¨ | ååºå ³é®åæ®µï¼ | åæ®µ | ç±»å | 说æ | |------|------|------| | `id` | `Long` | 设å¤IDï¼æäº¤æ¶å¡«å ¥ warehouseï¼ | | `deviceName` | `String` | 设å¤åç§° | | `deviceModel` | `String` | 设å¤åå· | | `externalCode` | `String` | ç©èå¹³å°GUID | ### 1.3 请æ±åæ° `StockInventoryDto` ä¸ `warehouse` åæ®µä¼ **éå·åéç设å¤IDå符串**ï¼ ```json { "productModelId": 123, "batchNo": "BN20250501", "warehouse": "1,3,5", "qualitity": 100 } ``` | åæ°å | ç±»å | å¿ å¡« | 说æ | |--------|------|------|------| | `warehouse` | `String` | å¦ | ç»å®çç©è设å¤IDï¼éå·åéï¼å¦ `"1,3,5"` | | å ¶ä»å段 | â | â | ä¸åæåºåæ°å¢/ç¼è¾æ¥å£ä¸è´ | --- ## æ¥å£äºï¼å®æ¶æ°éæ¥ç ### 2.1 æ¥å£ä¿¡æ¯ | é¡¹ç® | å 容 | |------|------| | æ¥å£å°å | `GET /stockInventory/iotRealtime/{id}` | | è¯·æ±æ¹å¼ | `GET` | | æ¥å£è¯´æ | è·åæå®åºåè®°å½ç»å®çç©è设å¤å®æ¶æ°éæ°æ® | ### 2.2 请æ±åæ° | åæ°å | ç±»å | å¿ å¡« | 说æ | |--------|------|------|------| | `id` | `Long` | æ¯ | åºåè®°å½IDï¼è·¯å¾åæ°ï¼ | ### 2.3 ååºç¤ºä¾ ```json { "code": 200, "msg": "æä½æå", "data": { "inventoryId": 1001, "iotDeviceIds": "1,3", "devices": [ { "deviceId": "1", "deviceName": "æ¸©æ¹¿åº¦ä¼ æå¨A", "deviceModel": "TH-100", "externalCode": "abc123-guid", "guid": "abc123-guid", "status": "å¨çº¿", "temperature": "25.6â", "humidity": "65.2%", "co2": "420ppm", "light": "800lux", "battery": "85%" }, { "deviceId": "3", "deviceName": "æ¸©æ¹¿åº¦ä¼ æå¨B", "deviceModel": "TH-200", "externalCode": "def456-guid", "guid": "def456-guid", "status": "offline", "statusMessage": "device not returned by remote API" } ] } } ``` ### 2.4 devices åæ®µè¯´æ | åæ®µ | ç±»å | 说æ | |------|------|------| | `deviceId` | `String` | 设å¤ID | | `deviceName` | `String` | 设å¤åç§° | | `deviceModel` | `String` | 设å¤åå· | | `externalCode` | `String` | ç©èå¹³å°GUID | | `guid` | `String` | ç©èå¹³å°GUIDï¼å externalCodeï¼ | | `status` | `String` | `å¨çº¿` / `offline` / `error` | | `statusMessage` | `String` | ç¶ææè¿°ï¼å¼å¸¸æ¶æå¼ï¼ | | `temperature` | `String` | 温度å¼ï¼å«åä½ï¼å¦ `25.6â`ï¼ | | `humidity` | `String` | 湿度å¼ï¼å«åä½ï¼å¦ `65.2%`ï¼ | | `co2` | `String` | CO2å¼ï¼å«åä½ï¼å¦ `420ppm`ï¼ | | `light` | `String` | å ç §å¼ï¼å«åä½ï¼å¦ `800lux`ï¼ | | `battery` | `String` | çµéï¼å«åä½ï¼å¦ `85%`ï¼ | ### 2.5 æ ç»å®è®¾å¤æ¶ ```json { "code": 200, "data": { "inventoryId": 1002, "iotDeviceIds": "", "devices": [] } } ``` --- ## 3. åç«¯äº¤äºæµç¨ ``` åºåå表页 ââ warehouse åï¼æ¾ç¤ºå·²ç»å®ç设å¤åç§°ï¼æ ¹æ®è®¾å¤IDæ¥ device_ledger æ å°ï¼ ââ æä½åï¼[æ¥çæ°é] æé® â ââ ç¹å» â è°ç¨æ¥å£äº GET /stockInventory/iotRealtime/{id} â ââ å¼¹åºå¼¹çª/æ½å± ââ 设å¤åç§° + åå· ââ ç¶ææç¤ºç¯ï¼å¨çº¿=绿 / 离线=ç° / å¼å¸¸=çº¢ï¼ ââ æ¸©åº¦ã湿度ãCO2ãå ç §ãçµé æ°å¼å¡ç ââ 30ç§èªå¨å·æ°ï¼å¯éï¼ æ°å¢/ç¼è¾åºåå¼¹çª ââ warehouse åæ®µ â ç©è设å¤å¤éä¸ææ¡ â ââ æ°æ®æºï¼æ¥å£ GET /device/ledger/page?isIotDevice=1 ââ æäº¤ï¼è°ç¨æ¥å£ä¸ï¼warehouse = "1,3,5" ``` ### å¼¹çª UI 建议 - **设å¤ç¶æï¼** 顶鍿¾ç¤ºç¶ææ ç¾ï¼å¨çº¿/离线/å¼å¸¸ï¼ï¼é å绿/ç°/红è²åç¹ - **æ°æ®å¡çï¼** æ¯é¡¹æ°æ®ç¨å¡çå±ç¤ºï¼å¾æ + æ°å¼ + åä½ - **èªå¨å·æ°ï¼** å¯å ä¸ä¸ªå¼å ³ï¼å¼å¯åæ¯30ç§éæ°è¯·æ±æ¥å£äº - **ç©ºç¶æï¼** æªç»å®è®¾å¤æ¶æ¾ç¤º"ææ ç»å®çç©è设å¤"å¼å¯¼å»ç»å® --- ## 4. æ°æ®æ¥æºè¯´æ 宿¶æ°éæ°æ®æ¥èª **ç²¾åç©èå¹³å° (Elitech IoT)**ï¼ - API å°åï¼`https://new.e-elitech.cn/api/data-api` - æ°æ®ç¼åï¼Redis ç¼å 30 ç§ - æ°æ®é¡¹ç¼ç å¯¹ç §ï¼ | paramCode | å«ä¹ | åä½ | |-----------|------|------| | `0110` | 温度 | â | | `0120` | 湿度 | % | | `0130` | CO2 | ppm | | `0100` | å ç § | lux | | `0042` | çµé | % | --- ## 5. æ¥å£æ±æ» | åºå· | æ¥å£ | æ¹æ³ | 说æ | ç¶æ | |------|------|------|------|------| | æ¥å£ä¸ | `/stockInventory/addstockInventory` | POST | æ°å¢åºåï¼warehouse ä¼ è®¾å¤ID | å·²æ | | â | åºåç¼è¾æ¥å£ | PUT | ç¼è¾åºåï¼warehouse ä¼ è®¾å¤ID | å·²æ | | æ¥å£äº | `/stockInventory/iotRealtime/{id}` | GET | æ¥è¯¢ç»å®è®¾å¤å®æ¶æ°éæ°æ® | æ°å¢ | | è¾ å© | `/device/ledger/page?isIotDevice=1` | GET | è·åå¯éç©è设å¤å表 | å·²æ | --- ## 6. 注æäºé¡¹ 1. **warehouse åæ®µè¯ä¹åæ´ï¼** è¯¥åæ®µåæ¥åå¨ä»åºåå ¸å¼ï¼ç°æ¹ä¸ºåå¨ç©è设å¤IDï¼éå·åéï¼ï¼è¯·ç¡®ä¿å岿°æ®å ¼å®¹ 2. **设å¤å¿ é¡»ç»å®ç©èå¹³å°ï¼** åªæ `isIotDevice=1` ä¸ `externalCode` é空çè®¾å¤æè½è·å宿¶æ°æ® 3. **宿¶æ°æ®æç¼åï¼** æ¥å£äºæ 30 ç§ Redis ç¼åï¼å䏿¹è®¾å¤ 30 ç§å éå¤è¯·æ±ä¸ä¼éå¤è°ç¨å¤é¨ API 4. **é¨å设å¤ç¦»çº¿ï¼** å½ç©è平尿ªè¿åæè®¾å¤æ°æ®æ¶ï¼`status` 为 `offline`ï¼å端åºå±ç¤ºç¦»çº¿ç¶æè鿥é 5. **æ¹é请æ±ï¼** æ¥å£äºä¸æ¬¡è¯·æ±å¯è·åå¤ä¸ªè®¾å¤æ°æ®ï¼å端æ éé个设å¤è½®è¯¢ src/main/java/com/ruoyi/quality/dto/BatchQuickInspectRequest.java
@@ -4,7 +4,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.math.BigDecimal; import java.util.List; @Data @@ -18,15 +17,6 @@ @Schema(description = "ææ æ åID") private Long testStandardId; @Schema(description = "æ»æ°é") private BigDecimal quantity; @Schema(description = "åæ ¼æ°é") private BigDecimal qualifiedQuantity; @Schema(description = "ä¸åæ ¼æ°é") private BigDecimal unqualifiedQuantity; @Schema(description = "æ£æµåä½") private String checkCompany; src/main/java/com/ruoyi/quality/service/impl/QualityInspectServiceImpl.java
@@ -200,33 +200,11 @@ if (!validResults.contains(request.getCheckResult())) { return R.fail("æ£æµç»æå¿ 须为ï¼åæ ¼ãä¸åæ ¼ãé¨ååæ ¼"); } if (request.getQuantity() == null || request.getQuantity().compareTo(BigDecimal.ZERO) <= 0) { return R.fail("æ»æ°éå¿ é¡»å¤§äº0"); } if (request.getTestStandardId() == null) { return R.fail("ææ æ åIDä¸è½ä¸ºç©º"); } // quantity = qualifiedQuantity + unqualifiedQuantity BigDecimal qty = request.getQuantity(); BigDecimal qualified = request.getQualifiedQuantity() != null ? request.getQualifiedQuantity() : BigDecimal.ZERO; BigDecimal unqualified = request.getUnqualifiedQuantity() != null ? request.getUnqualifiedQuantity() : BigDecimal.ZERO; if (qty.compareTo(qualified.add(unqualified)) != 0) { return R.fail("æ»æ°éå¿ é¡»çäºåæ ¼æ°éå ä¸åæ ¼æ°é"); } String checkResult = request.getCheckResult(); if ("åæ ¼".equals(checkResult)) { if (qualified.compareTo(qty) != 0 || unqualified.compareTo(BigDecimal.ZERO) != 0) { return R.fail("æ£éªç»æä¸ºåæ ¼æ¶ï¼åæ ¼æ°éåºçäºæ»æ°éï¼ä¸åæ ¼æ°éåºä¸º0"); } } else if ("ä¸åæ ¼".equals(checkResult)) { if (qualified.compareTo(BigDecimal.ZERO) != 0 || unqualified.compareTo(qty) != 0) { return R.fail("æ£éªç»æä¸ºä¸åæ ¼æ¶ï¼åæ ¼æ°éåºä¸º0ï¼ä¸åæ ¼æ°éåºçäºæ»æ°é"); } } else { if (qualified.compareTo(BigDecimal.ZERO) <= 0 || unqualified.compareTo(BigDecimal.ZERO) <= 0) { return R.fail("æ£éªç»æä¸ºé¨ååæ ¼æ¶ï¼åæ ¼æ°éåä¸åæ ¼æ°éé½å¿ 须大äº0"); } } // è§£ææ£æµæ¥æ Date checkTimeDate = null; @@ -239,8 +217,7 @@ for (Long id : request.getIds()) { try { // 使ç¨ç¬ç«äºå¡å¤çæ¯ä¸ªæ£éªåï¼é¿å åä¸ªå¤±è´¥å½±åæ´ä½äºå¡ processSingleInspect(id, request, checkResult, qty, qualified, unqualified, checkTimeDate); processSingleInspect(id, request, checkResult, checkTimeDate); success++; } catch (Exception e) { errors.add("æ£éªå " + id + " å¤ç失败ï¼" + e.getMessage()); @@ -256,12 +233,11 @@ /** * å¨ç¬ç«äºå¡ä¸å¤çå个æ£éªå * æ°éãåæ ¼æ°éé»è®¤ä½¿ç¨æ£éªåèªèº«çæ°éï¼ä¸åæ ¼æ°é为0 */ @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) public void processSingleInspect(Long id, BatchQuickInspectRequest request, String checkResult, BigDecimal qty, BigDecimal qualified, BigDecimal unqualified, Date checkTimeDate) { String checkResult, Date checkTimeDate) { QualityInspect qualityInspect = qualityInspectMapper.selectById(id); if (qualityInspect == null) { throw new RuntimeException("æ£éªåä¸åå¨"); @@ -270,6 +246,11 @@ throw new RuntimeException("æ£éªåå·²æäº¤"); } // æ°éé»è®¤åæ£éªåèªèº«çæ°éï¼ä¸åæ ¼æ°é为0 BigDecimal qty = qualityInspect.getQuantity() != null ? qualityInspect.getQuantity() : BigDecimal.ZERO; BigDecimal qualified = qty; BigDecimal unqualified = BigDecimal.ZERO; // 2. æ´æ°æ£éªååæ®µ qualityInspect.setCheckResult(checkResult); qualityInspect.setTestStandardId(request.getTestStandardId()); src/main/java/com/ruoyi/stock/controller/StockInventoryController.java
@@ -1,15 +1,22 @@ package com.ruoyi.stock.controller; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockOutQualifiedRecordTypeEnum; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.device.pojo.DeviceLedger; import com.ruoyi.device.service.IDeviceLedgerService; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.domain.R; import com.ruoyi.http.service.impl.RealTimeEnergyConsumptionServiceImpl; import com.ruoyi.stock.dto.StockInventoryDto; import com.ruoyi.stock.dto.StockIotRealtimeDto; import com.ruoyi.stock.execl.StockInventoryExportData; import com.ruoyi.stock.pojo.StockInventory; import com.ruoyi.stock.service.StockInventoryService; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; @@ -18,8 +25,8 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.util.ArrayList; import java.util.List; import java.util.*; import java.util.stream.Collectors; /** * <p> @@ -36,6 +43,8 @@ public class StockInventoryController { private StockInventoryService stockInventoryService; private IDeviceLedgerService deviceLedgerService; private RealTimeEnergyConsumptionServiceImpl realTimeEnergyConsumptionService; @GetMapping("/pagestockInventory") @Operation(summary = "å页æ¥è¯¢åºå") @@ -147,4 +156,50 @@ public R getByModelId(Long productModelId) { return R.ok(stockInventoryService.getByModelId(productModelId)); } @PostMapping("/iotRealtime") @Operation(summary = "è·ååºåç»å®çç©è设å¤å®æ¶æ°éæ°æ®") @Log(title = "åºåç©è设å¤å®æ¶æ°é", businessType = BusinessType.OTHER) public R iotRealtime(@RequestBody List<Long> ids) { StockIotRealtimeDto result = new StockIotRealtimeDto(); if (ids.isEmpty()) { result.setDevices(Collections.emptyList()); return R.ok(result); } List<DeviceLedger> devices = deviceLedgerService.listByIds(ids); List<String> guidList = devices.stream() .map(DeviceLedger::getExternalCode) .filter(StringUtils::isNotEmpty) .collect(Collectors.toList()); Map<String, Map<String, String>> realTimeDataMap = new HashMap<>(); if (!guidList.isEmpty()) { List<Map<String, String>> realTimeList = realTimeEnergyConsumptionService.getRealData(guidList); for (Map<String, String> item : realTimeList) { String guid = item.get("guid"); if (StringUtils.isNotEmpty(guid)) { realTimeDataMap.put(guid.trim(), item); } } } List<Map<String, String>> deviceDataList = devices.stream().map(device -> { Map<String, String> data = new LinkedHashMap<>(); data.put("deviceId", String.valueOf(device.getId())); data.put("deviceName", device.getDeviceName() != null ? device.getDeviceName() : ""); data.put("deviceModel", device.getDeviceModel() != null ? device.getDeviceModel() : ""); data.put("externalCode", device.getExternalCode() != null ? device.getExternalCode() : ""); Map<String, String> rt = realTimeDataMap.getOrDefault( device.getExternalCode() != null ? device.getExternalCode().trim() : "", Collections.emptyMap()); data.putAll(rt); return data; }).collect(Collectors.toList()); result.setDevices(deviceDataList); return R.ok(result); } } src/main/java/com/ruoyi/stock/dto/StockIotRealtimeDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,21 @@ package com.ruoyi.stock.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.util.List; import java.util.Map; @Data @Schema(description = "åºåç»å®çç©è设å¤å®æ¶æ°éæ°æ®") public class StockIotRealtimeDto { @Schema(description = "åºåè®°å½ID") private Long inventoryId; @Schema(description = "ç»å®çç©è设å¤IDå表ï¼éå·åéï¼") private String iotDeviceIds; @Schema(description = "设å¤å®æ¶æ°éæ°æ®å表") private List<Map<String, String>> devices; } src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -134,6 +134,7 @@ stockOutRecordDto.setStockOutNum(stockInventoryDto.getQualitity()); stockOutRecordDto.setBatchNo(stockInventoryDto.getBatchNo()); stockOutRecordDto.setProductModelId(stockInventoryDto.getProductModelId()); stockOutRecordDto.setOutboundBatches(stockInventoryDto.getOutboundBatches()); stockOutRecordDto.setType("0"); stockOutRecordService.add(stockOutRecordDto); src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -228,8 +228,7 @@ model, unit, product_name, product_id, warehouse product_id order by create_time desc </select>