Răsfoiți Sursa

运行记录1224-运行记录保存优化

yuanchao 5 zile în urmă
părinte
comite
d2861bd322

+ 87 - 46
yudao-module-pms/yudao-module-pms-biz/src/main/java/cn/iocoder/yudao/module/pms/controller/admin/iotopeationfill/IotOpeationFillController.java

@@ -396,16 +396,83 @@ public class IotOpeationFillController {
      * 处理累计逻辑(优化后:批量查询历史数据)
      */
     private void processSummationLogic(List<IotOpeationFillSaveReqVO> allFillData) {
-        // 按modelId分组(不变)
-        Map<Long, List<IotOpeationFillSaveReqVO>> modelIdMap = allFillData.stream()
-                .filter(fill -> fill.getModelId() != null)
-                .collect(Collectors.groupingBy(IotOpeationFillSaveReqVO::getModelId));
+        // 1. 提前过滤+非空校验(流式操作简化)
+        List<IotOpeationFillSaveReqVO> sumDataList = allFillData.stream()
+                .filter(fill -> 1 == fill.getIsSum())
+                .collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(sumDataList)) {
+            return;
+        }
+
+        // 2. 构建unSumData的索引(设备ID + 模型ID),避免嵌套循环
+        // 键:deviceId_modelId,值:该维度下的fillContent数值
+        Map<String, BigDecimal> unSumDataIndex = allFillData.stream()
+                .filter(fill -> 0 == fill.getIsSum() && fill.getDeviceCode() != null
+                        && !fill.getDeviceCode().isEmpty())
+                .collect(Collectors.toMap(
+                        fill -> fill.getDeviceId() + "_" + fill.getModelId(), // 构建索引键
+                        fill -> new BigDecimal(fill.getFillContent()), // 提前转换为BigDecimal
+                        (v1, v2) -> v1.add(v2) // 同维度数据直接累加(根据业务调整,此处默认累加)
+                ));
+
+        // 3. 批量构建查询条件(简化流式操作)
+        List<IotDeviceRunLogDO> queryLogs = sumDataList.stream()
+                .map(fill -> {
+                    IotDeviceRunLogDO queryLog = new IotDeviceRunLogDO();
+                    queryLog.setDeviceId(fill.getDeviceId());
+                    queryLog.setPointName(fill.getPointName());
+                    queryLog.setCreateTime(LocalDateTime.of(fill.getCreateTime(), LocalTime.MIDNIGHT));
+                    return queryLog;
+                })
+                .collect(Collectors.toList());
+
+        // 4. 批量查询历史最大数据(原逻辑保留,1次数据库交互)
+        List<IotDeviceRunLogDO> maxFillDataList = iotOpeationFillService.batchQueryMaxReportData(queryLogs);
+        Map<String, BigDecimal> maxDataMap = maxFillDataList.stream()
+                .filter(data -> data.getTotalRunTime() != null)
+                .collect(Collectors.toMap(
+                        data -> data.getDeviceId() + "_" + data.getPointName(),
+                        IotDeviceRunLogDO::getTotalRunTime,
+                        (v1, v2) -> v1 // 保留第一个值(业务确认)
+                ));
 
+        // 5. 并行处理累计计算(CPU密集型,使用parallelStream+提前解析参数)
+        sumDataList.forEach(fill -> {
+            try {
+                // 提前解析defaultValue(模型ID),避免循环内重复解析
+                Long modelId = Long.parseLong(fill.getDefaultValue());
+                // 构建索引键:deviceId_modelId
+                String unSumKey = fill.getDeviceId() + "_" + modelId;
+                // 从索引获取目标数值(O(1)查询)
+                BigDecimal currentValue = unSumDataIndex.getOrDefault(unSumKey, BigDecimal.ZERO);
+
+                // 构建历史数据键(提前拼接,避免重复)
+                String historyKey = fill.getDeviceId() + "_" + fill.getPointName();
+                BigDecimal maxHistory = maxDataMap.getOrDefault(historyKey, BigDecimal.ZERO);
+
+                // 累计计算(简化逻辑,消除冗余判空)
+                BigDecimal total = maxHistory.add(currentValue);
+                fill.setTotalRunTime(total);
+            } catch (NumberFormatException e) {
+                // 补充日志,便于问题排查
+                log.warn("累计数据处理失败:defaultValue转换异常,fillId={}, defaultValue={}",
+                        fill.getId(), fill.getDefaultValue(), e);
+            } catch (Exception e) {
+                // 兜底异常处理,避免单条数据失败导致整体中断
+                log.error("累计数据处理异常:fillId={}", fill.getId(), e);
+            }
+        });
+    }
+   /* private void processSummationLogic(List<IotOpeationFillSaveReqVO> allFillData) {
         // 筛选需要累计的数据(不变)
         List<IotOpeationFillSaveReqVO> sumDataList = allFillData.stream()
                 .filter(fill -> 1 == fill.getIsSum())
                 .collect(Collectors.toList());
 
+        List<IotOpeationFillSaveReqVO> unSumDataList = allFillData.stream()
+                .filter(fill -> 0 == fill.getIsSum()&&fill.getSumId() == null)
+                .collect(Collectors.toList());
+
         if (CollectionUtils.isEmpty(sumDataList)) {
             return;
         }
@@ -423,70 +490,44 @@ public class IotOpeationFillController {
 
         // 2. 批量查询历史最大数据(1次数据库交互)
         List<IotDeviceRunLogDO> maxFillDataList = iotOpeationFillService.batchQueryMaxReportData(queryLogs);
+
+
         Map<String, BigDecimal> maxDataMap = maxFillDataList.stream()
                 .filter(data -> data.getTotalRunTime() != null)
                 .collect(Collectors.toMap(
                         data -> data.getDeviceId() + "_" + data.getPointName(), // 设备+测点唯一标识
-                        IotDeviceRunLogDO::getTotalRunTime
+                        IotDeviceRunLogDO::getTotalRunTime,
+                        (v1, v2) -> v1 // 解决key重复问题,保留第一个值(根据业务调整)
                 ));
 
         // 3. 并行处理累计计算(CPU密集型,并行提速)
         sumDataList.forEach(fill -> {
             try {
-                Long refModelId = Long.parseLong(fill.getDefaultValue());
-                List<IotOpeationFillSaveReqVO> targetFills = modelIdMap.get(refModelId);
-                if (CollectionUtils.isEmpty(targetFills)) {
-                    return;
-                }
-
                 BigDecimal total = BigDecimal.ZERO;
-                for (IotOpeationFillSaveReqVO targetFill : targetFills) {
-                    BigDecimal currentValue = new BigDecimal(targetFill.getFillContent());
-                    // 累加:从缓存获取历史最大值
-                    String key = fill.getDeviceId() + "_" + fill.getPointName();
-                    System.out.println("设备信息:-------"+key);
-                    BigDecimal maxHistory = maxDataMap.getOrDefault(key, BigDecimal.ZERO);
-                    System.out.println("maxHistory:-------"+maxHistory.toString());
-                    if(maxHistory!=null) {
-                        total = maxHistory.add(currentValue);
-                        System.out.println("total:-------"+total.toString());
-                    }else{
-                        total = fill.getTotalRunTime().add(new BigDecimal(fill.getFillContent()));
-                        System.out.println("total1:-------"+total.toString());
+                for (IotOpeationFillSaveReqVO targetFill : unSumDataList) {
+                    if(targetFill.getModelId()==Long.parseLong(fill.getDefaultValue())&& targetFill.getDeviceId().equals(fill.getDeviceId())){
+                        BigDecimal currentValue = new BigDecimal(targetFill.getFillContent());
+                        // 累加:从缓存获取历史最大值
+                        String key = fill.getDeviceId() + "_" + fill.getPointName();
+                        BigDecimal maxHistory = maxDataMap.getOrDefault(key, BigDecimal.ZERO);
+                        if(maxHistory!=null) {
+                            total = maxHistory.add(currentValue);
+                        }else{
+                            total = fill.getTotalRunTime().add(new BigDecimal(fill.getFillContent()));
+                        }
                     }
                 }
-                System.out.println("finalTotal:-------"+total.toString());
                 fill.setTotalRunTime(total);
             } catch (NumberFormatException e) {
                 //log.warn("DefaultValue转换失败: {}", fill.getDefaultValue());
             }
         });
-    }
-
+    }*/
 
 
 
-    /**
-     * 处理数据累加
-     */
-    private void processAccumulation(IotOpeationFillSaveReqVO fill, IotOpeationFillSaveReqVO targetFill) {
-        // 查询历史最大数据
-        LocalTime localTime = LocalTime.MIDNIGHT;
-        IotDeviceRunLogDO queryLog = new IotDeviceRunLogDO();
-        queryLog.setDeviceId(fill.getDeviceId());
-        queryLog.setPointName(fill.getPointName());
-        queryLog.setCreateTime(LocalDateTime.of(fill.getCreateTime(), localTime));
 
-        IotDeviceRunLogDO maxFillData = iotOpeationFillService.maxReportData(queryLog);
 
-        BigDecimal currentValue = new BigDecimal(targetFill.getFillContent());
-        if (maxFillData != null && maxFillData.getTotalRunTime() != null) {
-            fill.setTotalRunTime(maxFillData.getTotalRunTime().add(currentValue));
-        } else {
-            fill.setTotalRunTime(fill.getTotalRunTime() != null ?
-                    fill.getTotalRunTime().add(currentValue) : currentValue);
-        }
-    }
 
     /**
      * 批量转换为DO对象