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 @@ - + - + - + - + - +