|
|
|
@ -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;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 为节点设置子节点(优化的递归实现)
|
|
|
|
|