From d2ab6f7153e604bac7bc4ad58f27f368b65d8a1e Mon Sep 17 00:00:00 2001
From: yuan <123@>
Date: 星期二, 16 六月 2026 13:54:58 +0800
Subject: [PATCH] feat: 添加能耗数据综合分析功能,支持按天和周维度的趋势分析

---
 src/main/java/com/ruoyi/http/util/StatisticEleAggregateUtil.java |   86 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 83 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/ruoyi/http/util/StatisticEleAggregateUtil.java b/src/main/java/com/ruoyi/http/util/StatisticEleAggregateUtil.java
index 4759781..4ff014f 100644
--- a/src/main/java/com/ruoyi/http/util/StatisticEleAggregateUtil.java
+++ b/src/main/java/com/ruoyi/http/util/StatisticEleAggregateUtil.java
@@ -34,6 +34,7 @@
         String monthKey = HOUR_TO_MONTH.apply(tk);
         return monthKey != null ? toQuarterKey(monthKey) : null;
     };
+    public static final Function<String, String> HOUR_TO_WEEK = StatisticEleAnalyticsUtil.HOUR_TO_WEEK;
 
     /**
      * 鎸夋椂闂存《姹囨�伙紙澶氱數琛ㄥ悎骞讹紝鐢ㄤ簬鍥捐〃锛�
@@ -66,10 +67,84 @@
             mergeInto(map, key, bucket, record);
             StatisticEleRecordVo agg = map.get(key);
             agg.setMeterId(record.getMeterId());
-            agg.setAddress(record.getAddress());
-            agg.setCollectorNo(record.getCollectorNo());
+            mergeMeterInfo(agg, record);
         }
         return sorted(map);
+    }
+
+    private static void mergeMeterInfo(StatisticEleRecordVo agg, StatisticEleRecordVo record) {
+        if (hasText(record.getMeterName())) {
+            agg.setMeterName(record.getMeterName());
+        }
+        if (hasText(record.getAddress())) {
+            agg.setAddress(record.getAddress());
+        }
+        mergeTimeRange(agg, record);
+    }
+
+    private static void mergeTimeRange(StatisticEleRecordVo agg, StatisticEleRecordVo record) {
+        if (hasText(record.getStartTime())) {
+            if (!hasText(agg.getStartTime()) || record.getStartTime().compareTo(agg.getStartTime()) < 0) {
+                agg.setStartTime(record.getStartTime());
+            }
+        }
+        if (hasText(record.getEndTime())) {
+            if (!hasText(agg.getEndTime()) || record.getEndTime().compareTo(agg.getEndTime()) > 0) {
+                agg.setEndTime(record.getEndTime());
+            }
+        }
+    }
+
+    /** 姹囨�诲悗鑻ヨ捣姝㈡椂闂翠负绌猴紝鎸� timeKey 鎺ㄥ */
+    private static void fillTimeRangeIfEmpty(StatisticEleRecordVo vo) {
+        if (hasText(vo.getStartTime()) && hasText(vo.getEndTime())) {
+            return;
+        }
+        String timeKey = vo.getTimeKey();
+        if (!hasText(timeKey)) {
+            return;
+        }
+        if (timeKey.contains("Q")) {
+            String[] parts = timeKey.split("Q");
+            if (parts.length != 2) {
+                return;
+            }
+            int year = Integer.parseInt(parts[0]);
+            int quarter = Integer.parseInt(parts[1]);
+            int startMonth = (quarter - 1) * 3 + 1;
+            int endMonth = startMonth + 2;
+            YearMonth endYm = YearMonth.of(year, endMonth);
+            vo.setStartTime(String.format("%04d-%02d-01 00:00:00", year, startMonth));
+            vo.setEndTime(String.format("%04d-%02d-%02d 23:59:59", year, endMonth, endYm.lengthOfMonth()));
+            return;
+        }
+        if (timeKey.length() == 4) {
+            vo.setStartTime(timeKey + "-01-01 00:00:00");
+            vo.setEndTime(timeKey + "-12-31 23:59:59");
+            return;
+        }
+        if (timeKey.length() == 6) {
+            YearMonth ym = YearMonth.parse(timeKey, DateTimeFormatter.ofPattern("yyyyMM"));
+            vo.setStartTime(String.format("%04d-%02d-01 00:00:00", ym.getYear(), ym.getMonthValue()));
+            vo.setEndTime(String.format("%04d-%02d-%02d 23:59:59",
+                    ym.getYear(), ym.getMonthValue(), ym.lengthOfMonth()));
+            return;
+        }
+        if (timeKey.length() >= 8) {
+            String day = timeKey.substring(0, 8);
+            vo.setStartTime(toDateTime(day, "00:00:00"));
+            vo.setEndTime(toDateTime(day, "23:59:59"));
+        }
+    }
+
+    private static String toDateTime(String yyyyMMdd, String time) {
+        return yyyyMMdd.substring(0, 4) + "-"
+                + yyyyMMdd.substring(4, 6) + "-"
+                + yyyyMMdd.substring(6, 8) + " " + time;
+    }
+
+    private static boolean hasText(String value) {
+        return value != null && !value.isBlank();
     }
 
     /**
@@ -104,6 +179,7 @@
         return switch (dimension) {
             case "hour" -> new HourRange(startTime, endTime);
             case "day" -> new HourRange(startTime + "00", endTime + "23");
+            case "week" -> new HourRange(startTime + "00", endTime + "23");
             case "month" -> new HourRange(startTime + "0100", endTime + lastDayOfMonth(endTime) + "23");
             case "year" -> new HourRange(startTime + "010100", endTime + "123123");
             case "quarter" -> new HourRange(
@@ -160,6 +236,7 @@
         return switch (dimension) {
             case "hour" -> HOUR_TO_HOUR;
             case "day" -> HOUR_TO_DAY;
+            case "week" -> HOUR_TO_WEEK;
             case "month" -> HOUR_TO_MONTH;
             case "quarter" -> HOUR_TO_QUARTER;
             case "year" -> HOUR_TO_YEAR;
@@ -219,7 +296,10 @@
 
     private static List<StatisticEleRecordVo> sorted(Map<String, StatisticEleRecordVo> map) {
         return map.values().stream()
-                .peek(vo -> normalizeConsumptions(vo))
+                .peek(vo -> {
+                    normalizeConsumptions(vo);
+                    fillTimeRangeIfEmpty(vo);
+                })
                 .sorted(Comparator.comparing(StatisticEleRecordVo::getTimeKey))
                 .collect(Collectors.toList());
     }

--
Gitblit v1.9.3