From edfafe9cc4129fd1ddda77e64564e087f43d26e2 Mon Sep 17 00:00:00 2001 From: "zangch@mesnac.com" Date: Thu, 2 Apr 2026 11:11:12 +0800 Subject: [PATCH] =?UTF-8?q?feat(TempBoard=E6=B8=A9=E5=BA=A6=E6=8A=A5?= =?UTF-8?q?=E8=A1=A8/=E9=AB=98=E7=BA=A7=E5=88=86=E6=9E=90):=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E4=B8=BB=E9=A2=98=E6=B2=B3=E6=B5=81=E5=9B=BE=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=80=A7=E8=83=BD=E5=B9=B6=E6=94=AF=E6=8C=81=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E7=B2=92=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加动态粒度参数支持,根据查询时间跨度自动选择分钟/15分钟/小时级聚合 - 重构SQL查询逻辑,使用DATEADD替代FORMAT提升性能 - 添加90天查询时间范围硬限制 - 使用线程安全的DateTimeFormatter替代SimpleDateFormat --- .../ems/report/mapper/TempBoardMapper.java | 5 +- .../service/impl/TempBoardServiceImpl.java | 45 ++++++- .../mapper/ems/report/TempBoardMapper.xml | 126 +++++++++++------- 3 files changed, 121 insertions(+), 55 deletions(-) diff --git a/ruoyi-ems/src/main/java/org/dromara/ems/report/mapper/TempBoardMapper.java b/ruoyi-ems/src/main/java/org/dromara/ems/report/mapper/TempBoardMapper.java index 6d83842..696e71b 100644 --- a/ruoyi-ems/src/main/java/org/dromara/ems/report/mapper/TempBoardMapper.java +++ b/ruoyi-ems/src/main/java/org/dromara/ems/report/mapper/TempBoardMapper.java @@ -240,10 +240,11 @@ public interface TempBoardMapper { @Param("startTime") String startTime, @Param("endTime") String endTime); - /** 主题河流图数据 */ + /** 主题河流图数据(支持动态粒度) */ List selectThemeRiverData(@Param("tableNames") List tableNames, @Param("startTime") String startTime, - @Param("endTime") String endTime); + @Param("endTime") String endTime, + @Param("granularity") String granularity); /** 矩形树图数据 */ List selectTreemapData(@Param("tableNames") List tableNames, diff --git a/ruoyi-ems/src/main/java/org/dromara/ems/report/service/impl/TempBoardServiceImpl.java b/ruoyi-ems/src/main/java/org/dromara/ems/report/service/impl/TempBoardServiceImpl.java index 01c33c4..153ec02 100644 --- a/ruoyi-ems/src/main/java/org/dromara/ems/report/service/impl/TempBoardServiceImpl.java +++ b/ruoyi-ems/src/main/java/org/dromara/ems/report/service/impl/TempBoardServiceImpl.java @@ -10,6 +10,10 @@ import org.dromara.ems.report.service.ITempBoardService; import org.springframework.stereotype.Service; import java.text.SimpleDateFormat; +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.List; @@ -33,15 +37,28 @@ public class TempBoardServiceImpl implements ITempBoardService { private static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; + /** 线程安全的静态格式化器,替代每次 new SimpleDateFormat */ + private static final DateTimeFormatter FMT = DateTimeFormatter.ofPattern(DATETIME_FORMAT); + + /** 最大查询天数(硬限制,防止灾难性查询) */ + private static final int MAX_QUERY_DAYS = 90; + // ==================== 工具方法 ==================== /** * 解析查询时间范围并获取分表列表 + * 包含时间范围硬限制校验 */ private List resolveTables(TempBoardQueryBo query) { if (query.getStartTime() == null || query.getEndTime() == null) { throw new ServiceException("请选择时间范围"); } + // 时间范围硬限制校验 + long diffMs = query.getEndTime().getTime() - query.getStartTime().getTime(); + long diffDays = diffMs / (24 * 3600 * 1000); + if (diffDays > MAX_QUERY_DAYS) { + throw new ServiceException("查询跨度不能超过" + MAX_QUERY_DAYS + "天,请缩小范围"); + } List tables = partitionService.resolveTables(query.getStartTime(), query.getEndTime()); if (tables.isEmpty()) { throw new ServiceException("所选时间范围内无数据表"); @@ -49,8 +66,27 @@ public class TempBoardServiceImpl implements ITempBoardService { return tables; } + /** Date → 格式化字符串(兼容旧接口) */ private String fmt(Date date) { - return new SimpleDateFormat(DATETIME_FORMAT).format(date); + return FMT.format(date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()); + } + + /** + * 根据查询时间跨度自动决定高级分析的聚合粒度 + * 跨度 <= 1 天:分钟级 + * 跨度 > 1 天 且 <= 7 天:15分钟级 + * 跨度 > 7 天:小时级 + */ + private String resolveGranularity(TempBoardQueryBo query) { + long diffMs = query.getEndTime().getTime() - query.getStartTime().getTime(); + long diffHours = diffMs / (3600 * 1000); + if (diffHours <= 24) { + return "MINUTE"; + } else if (diffHours <= 168) { // 7 天 + return "FIFTEEN_MINUTE"; + } else { + return "HOUR"; + } } // ==================== A. 温度总览 ==================== @@ -343,7 +379,7 @@ public class TempBoardServiceImpl implements ITempBoardService { return tempBoardMapper.selectMonitorActivity(tables, fmt(query.getStartTime()), fmt(query.getEndTime())); } - // ==================== H. 高级分析 ==================== + // ==================== H. 高级分析(已优化) ==================== @Override public List getSankeyData(TempBoardQueryBo query) { @@ -354,7 +390,10 @@ public class TempBoardServiceImpl implements ITempBoardService { @Override public List getThemeRiverData(TempBoardQueryBo query) { List tables = resolveTables(query); - return tempBoardMapper.selectThemeRiverData(tables, fmt(query.getStartTime()), fmt(query.getEndTime())); + // 根据时间跨度自动选择聚合粒度 + String granularity = resolveGranularity(query); + return tempBoardMapper.selectThemeRiverData( + tables, fmt(query.getStartTime()), fmt(query.getEndTime()), granularity); } @Override diff --git a/ruoyi-ems/src/main/resources/mapper/ems/report/TempBoardMapper.xml b/ruoyi-ems/src/main/resources/mapper/ems/report/TempBoardMapper.xml index 12240e5..cb178d9 100644 --- a/ruoyi-ems/src/main/resources/mapper/ems/report/TempBoardMapper.xml +++ b/ruoyi-ems/src/main/resources/mapper/ems/report/TempBoardMapper.xml @@ -918,38 +918,33 @@ - + - + - + - + - +