From 2fc382585ca4420ec5af2bc254954602d56cf671 Mon Sep 17 00:00:00 2001 From: zch <zangch@mesnac.com> Date: Fri, 21 Mar 2025 13:04:31 +0800 Subject: [PATCH] =?UTF-8?q?refactor(ems):=20=E4=BC=98=E5=8C=96=E7=9B=91?= =?UTF-8?q?=E6=8E=A7=E4=BF=A1=E6=81=AF=E6=A0=91=E6=9E=84=E5=BB=BA=E6=96=B9?= =?UTF-8?q?=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了基于数据量的并行处理逻辑,提高大数据量处理效率 - 引入异步处理机制,优化数据库查询性能 - 保留了原有的方法逻辑,确保功能一致性 - 新增方法实现了更高效的温度数据加载和父子关系构建 --- .../impl/EmsBaseMonitorInfoServiceImpl.java | 85 ++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) 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<EmsBaseMonitorInfo> buildMonitorInfoTree(List<EmsBaseMonitorInfo> baseMonitorInfos) { + // 数据量阈值,低于此值使用单线程,高于此值使用多线程 + final int THRESHOLD = 100; + + // 1. 提取监控类型为1L的设备编号 - 根据数据量选择是否并行 + List<String> 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<String, BigDecimal> tempDataMap = new HashMap<>(); + + // 数据库查询通常是IO密集型,使用异步可以提高效率 + if (CollectionUtils.isNotEmpty(monitorCodes)) { + // 使用CompletableFuture异步获取温度数据 + List<TWTempertureData> 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<Long> allIds = baseMonitorInfos.stream() + .map(EmsBaseMonitorInfo::getObjId) + .collect(Collectors.toSet()); + + Map<Long, List<EmsBaseMonitorInfo>> 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<EmsBaseMonitorInfo> 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<EmsBaseMonitorInfo> buildMonitorInfoTree(List<EmsBaseMonitorInfo> baseMonitorInfos) { // 创建一个List来存储设备编号,只获取监控类型为1L的设备编号 List<String> monitorCodes = baseMonitorInfos.stream() @@ -206,6 +288,7 @@ public class EmsBaseMonitorInfoServiceImpl implements IEmsBaseMonitorInfoService return rootNodes.isEmpty() ? baseMonitorInfos : rootNodes; } +*/ /** * 为节点设置子节点(优化的递归实现)