diff --git a/ruoyi-ems/src/main/java/com/ruoyi/ems/base/service/impl/EmsBaseMonitorInfoServiceImpl.java b/ruoyi-ems/src/main/java/com/ruoyi/ems/base/service/impl/EmsBaseMonitorInfoServiceImpl.java index 50b4bf2..2b228f5 100644 --- a/ruoyi-ems/src/main/java/com/ruoyi/ems/base/service/impl/EmsBaseMonitorInfoServiceImpl.java +++ b/ruoyi-ems/src/main/java/com/ruoyi/ems/base/service/impl/EmsBaseMonitorInfoServiceImpl.java @@ -2,7 +2,7 @@ package com.ruoyi.ems.base.service.impl; import java.math.BigDecimal; import java.util.*; - +import java.util.concurrent.CompletableFuture; import java.util.function.Function; import java.util.stream.Collectors; @@ -148,6 +148,88 @@ public class EmsBaseMonitorInfoServiceImpl implements IEmsBaseMonitorInfoService * @return 树结构列表 */ @Override + public List buildMonitorInfoTree(List baseMonitorInfos) { + // 数据量阈值,低于此值使用单线程,高于此值使用多线程 + final int THRESHOLD = 100; + + // 1. 提取监控类型为1L的设备编号 - 根据数据量选择是否并行 + List monitorCodes; + if(baseMonitorInfos.size() > THRESHOLD) { + monitorCodes = baseMonitorInfos.parallelStream() + .filter(item -> !ObjectUtils.isEmpty(item) && item.getMonitorType() == 1L) + .map(EmsBaseMonitorInfo::getMonitorCode) + .collect(Collectors.toList()); + } else { + monitorCodes = baseMonitorInfos.stream() + .filter(item -> !ObjectUtils.isEmpty(item) && item.getMonitorType() == 1L) + .map(EmsBaseMonitorInfo::getMonitorCode) + .collect(Collectors.toList()); + } + + // 2. 创建温度数据Map - 异步执行耗时的数据库查询 + Map tempDataMap = new HashMap<>(); + + // 数据库查询通常是IO密集型,使用异步可以提高效率 + if (CollectionUtils.isNotEmpty(monitorCodes)) { + // 使用CompletableFuture异步获取温度数据 + List tempDatas = + CompletableFuture.supplyAsync(() -> + tWTempertureDataMapper.selectLastTWTempertureDataByMonitorCodes(monitorCodes) + ).join(); // 等待数据库查询完成 + + tempDataMap = tempDatas.stream() + .filter(data -> !ObjectUtils.isEmpty(data) && data.getTempreture() != null) + .collect(Collectors.toMap( + TWTempertureData::getMonitorId, + TWTempertureData::getTempreture, + (v1, v2) -> v1)); + } + + // 3. 收集所有设备ID和构建父子关系映射 - 单线程处理简单逻辑 + Set allIds = baseMonitorInfos.stream() + .map(EmsBaseMonitorInfo::getObjId) + .collect(Collectors.toSet()); + + Map> parentChildMap = new HashMap<>(); + + // 4. 设置温度值并构建父子关系 - 简单循环,数据量不大时开销小 + for (EmsBaseMonitorInfo info : baseMonitorInfos) { + // 设置温度值 + if (info.getMonitorType() == 1L) { + BigDecimal temperature = tempDataMap.get(info.getMonitorCode()); + if (temperature != null) { + info.setTemperature(temperature); + } + } + + // 构建父子关系映射 + Long parentId = info.getParentId(); + if (parentId != null) { + parentChildMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(info); + } + } + + // 5. 找出所有顶级节点 + List rootNodes = baseMonitorInfos.stream() + .filter(info -> info.getParentId() == null || !allIds.contains(info.getParentId())) + .collect(Collectors.toList()); + + // 6. 为顶级节点设置子节点 + for (EmsBaseMonitorInfo root : rootNodes) { + setChildren(root, parentChildMap); + } + + return rootNodes.isEmpty() ? baseMonitorInfos : rootNodes; + } + + /** + * 构建前端所需要树结构 + * + * @param + * @return 树结构列表 + */ +/* + @Override public List buildMonitorInfoTree(List baseMonitorInfos) { // 创建一个List来存储设备编号,只获取监控类型为1L的设备编号 List monitorCodes = baseMonitorInfos.stream() @@ -206,6 +288,7 @@ public class EmsBaseMonitorInfoServiceImpl implements IEmsBaseMonitorInfoService return rootNodes.isEmpty() ? baseMonitorInfos : rootNodes; } +*/ /** * 为节点设置子节点(优化的递归实现)