liuaini před 3 dny
rodič
revize
94d469899a

+ 64 - 45
common/common-se/src/main/java/com/hdkj/lt/bf/scheduler/SeCapacityDailyScheduler.java

@@ -1,6 +1,7 @@
 package com.hdkj.lt.bf.scheduler;
 package com.hdkj.lt.bf.scheduler;
 
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.hdkj.lt.bf.entity.FhzgSeCapacityDaily;
 import com.hdkj.lt.bf.entity.FhzgSeCapacityDaily;
 import com.hdkj.lt.bf.entity.FhzgSeCurrentEvent;
 import com.hdkj.lt.bf.entity.FhzgSeCurrentEvent;
 import com.hdkj.lt.bf.entity.FhzgSeSnapshotDetail;
 import com.hdkj.lt.bf.entity.FhzgSeSnapshotDetail;
@@ -49,60 +50,78 @@ public class SeCapacityDailyScheduler {
         LocalDateTime startTime = date.atStartOfDay();
         LocalDateTime startTime = date.atStartOfDay();
         LocalDateTime endTime = date.atTime(23, 59, 59);
         LocalDateTime endTime = date.atTime(23, 59, 59);
 
 
-        // 查当天所有馈线断面(负载率)
-        LambdaQueryWrapper<FhzgSeSnapshotDetail> wrapper = new LambdaQueryWrapper<FhzgSeSnapshotDetail>()
-                .eq(FhzgSeSnapshotDetail::getDeviceType, "feeder")
-                .isNotNull(FhzgSeSnapshotDetail::getLoadRate)
-                .ge(FhzgSeSnapshotDetail::getSnapshotTime, startTime)
-                .le(FhzgSeSnapshotDetail::getSnapshotTime, endTime);
-
-        List<FhzgSeSnapshotDetail> snapshots = snapshotDetailMapper.selectList(wrapper);
-
-        // 查当天重过载事件(事件数,口径与 fhzg_se_current_event 一致)
-        LambdaQueryWrapper<FhzgSeCurrentEvent> eventWrapper = new LambdaQueryWrapper<FhzgSeCurrentEvent>()
-                .ge(FhzgSeCurrentEvent::getFirstOverTime, startTime)
-                .lt(FhzgSeCurrentEvent::getFirstOverTime, date.plusDays(1).atStartOfDay())
-                .in(FhzgSeCurrentEvent::getAlarmType, "current_heavy", "current_overload");
-        List<FhzgSeCurrentEvent> events = currentEventMapper.selectList(eventWrapper);
-
-        if (snapshots.isEmpty() && events.isEmpty()) {
+        // 断面按馈线 SQL 聚合
+        QueryWrapper<FhzgSeSnapshotDetail> wrapper = new QueryWrapper<FhzgSeSnapshotDetail>()
+                .select("feeder_id",
+                        "MAX(county_id) AS county_id",
+                        "MAX(subs_id) AS subs_id",
+                        "MAX(feeder_name) AS feeder_name",
+                        "MAX(load_rate) AS max_load_rate",
+                        "COALESCE(SUM(load_rate), 0) AS sum_load_rate",
+                        "COUNT(load_rate) AS cnt")
+                .eq("device_type", "feeder")
+                .isNotNull("load_rate")
+                .ge("snapshot_time", startTime)
+                .le("snapshot_time", endTime)
+                .isNotNull("feeder_id")
+                .groupBy("feeder_id");
+
+        List<Map<String, Object>> snapshotRows = snapshotDetailMapper.selectMaps(wrapper);
+
+        // 重过载事件按馈线 SQL 聚合(事件数,口径与 fhzg_se_current_event 一致)
+        QueryWrapper<FhzgSeCurrentEvent> eventWrapper = new QueryWrapper<FhzgSeCurrentEvent>()
+                .select("feeder_id",
+                        "MAX(county_id) AS county_id",
+                        "MAX(subs_id) AS subs_id",
+                        "MAX(feeder_name) AS feeder_name",
+                        "COALESCE(SUM(CASE WHEN alarm_type = 'current_heavy' THEN 1 ELSE 0 END), 0) AS heavy",
+                        "COALESCE(SUM(CASE WHEN alarm_type = 'current_overload' THEN 1 ELSE 0 END), 0) AS overload")
+                .ge("first_over_time", startTime)
+                .lt("first_over_time", date.plusDays(1).atStartOfDay())
+                .in("alarm_type", "current_heavy", "current_overload")
+                .isNotNull("feeder_id")
+                .groupBy("feeder_id");
+
+        List<Map<String, Object>> eventRows = currentEventMapper.selectMaps(eventWrapper);
+
+        if ((snapshotRows == null || snapshotRows.isEmpty()) && (eventRows == null || eventRows.isEmpty())) {
             log.info("[供电能力日汇总] {} 无断面/事件数据,跳过", date);
             log.info("[供电能力日汇总] {} 无断面/事件数据,跳过", date);
             return date + " 无断面/事件数据";
             return date + " 无断面/事件数据";
         }
         }
 
 
-        // 按馈线分组聚合
+        // 按馈线分组聚合(断面维度)
         Map<String, DailyAccumulator> accumulatorMap = new HashMap<>();
         Map<String, DailyAccumulator> accumulatorMap = new HashMap<>();
-        for (FhzgSeSnapshotDetail s : snapshots) {
-            String feederId = s.getFeederId();
-            if (feederId == null) continue;
-
-            DailyAccumulator acc = accumulatorMap.computeIfAbsent(feederId, k -> new DailyAccumulator());
-            acc.countyId = s.getCountyId();
-            acc.subsId = s.getSubsId();
-            if (acc.feederName == null) acc.feederName = s.getFeederName();
-
-            BigDecimal loadRate = s.getLoadRate();
-            if (loadRate != null) {
-                if (loadRate.compareTo(acc.maxLoadRate) > 0) {
-                    acc.maxLoadRate = loadRate;
-                }
-                acc.sumLoadRate = acc.sumLoadRate.add(loadRate);
-                acc.totalSnapshots++;
+        if (snapshotRows != null) {
+            for (Map<String, Object> row : snapshotRows) {
+                String feederId = (String) row.get("feeder_id");
+                if (feederId == null) continue;
+
+                DailyAccumulator acc = new DailyAccumulator();
+                acc.countyId = (String) row.get("county_id");
+                acc.subsId = (String) row.get("subs_id");
+                acc.feederName = (String) row.get("feeder_name");
+                BigDecimal maxLoadRate = (BigDecimal) row.get("max_load_rate");
+                if (maxLoadRate != null) acc.maxLoadRate = maxLoadRate;
+                acc.sumLoadRate = (BigDecimal) row.get("sum_load_rate");
+                acc.totalSnapshots = ((Number) row.get("cnt")).intValue();
+                accumulatorMap.put(feederId, acc);
             }
             }
         }
         }
 
 
         // 事件数按馈线累加(同一条馈线当日多个事件算多次)
         // 事件数按馈线累加(同一条馈线当日多个事件算多次)
-        for (FhzgSeCurrentEvent e : events) {
-            String feederId = e.getFeederId();
-            if (feederId == null) continue;
-
-            DailyAccumulator acc = accumulatorMap.computeIfAbsent(feederId, k -> new DailyAccumulator());
-            if (acc.countyId == null) acc.countyId = e.getCountyId();
-            if (acc.subsId == null) acc.subsId = e.getSubsId();
-            if (acc.feederName == null) acc.feederName = e.getFeederName();
-
-            if ("current_heavy".equals(e.getAlarmType())) acc.heavyCount++;
-            else if ("current_overload".equals(e.getAlarmType())) acc.overloadCount++;
+        if (eventRows != null) {
+            for (Map<String, Object> row : eventRows) {
+                String feederId = (String) row.get("feeder_id");
+                if (feederId == null) continue;
+
+                DailyAccumulator acc = accumulatorMap.computeIfAbsent(feederId, k -> new DailyAccumulator());
+                if (acc.countyId == null) acc.countyId = (String) row.get("county_id");
+                if (acc.subsId == null) acc.subsId = (String) row.get("subs_id");
+                if (acc.feederName == null) acc.feederName = (String) row.get("feeder_name");
+
+                acc.heavyCount += ((Number) row.get("heavy")).intValue();
+                acc.overloadCount += ((Number) row.get("overload")).intValue();
+            }
         }
         }
 
 
         // 先删当天已有数据(避免重复运行时叠加)
         // 先删当天已有数据(避免重复运行时叠加)

+ 40 - 58
common/common-se/src/main/java/com/hdkj/lt/bf/scheduler/SeLineLossDailyScheduler.java

@@ -1,6 +1,7 @@
 package com.hdkj.lt.bf.scheduler;
 package com.hdkj.lt.bf.scheduler;
 
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.hdkj.lt.bf.entity.FhzgSeLineLossDaily;
 import com.hdkj.lt.bf.entity.FhzgSeLineLossDaily;
 import com.hdkj.lt.bf.entity.FhzgSeLineLossDetail;
 import com.hdkj.lt.bf.entity.FhzgSeLineLossDetail;
 import com.hdkj.lt.bf.mapper.FhzgSeLineLossDailyMapper;
 import com.hdkj.lt.bf.mapper.FhzgSeLineLossDailyMapper;
@@ -15,7 +16,6 @@ import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 
 
@@ -44,71 +44,65 @@ public class SeLineLossDailyScheduler {
         LocalDateTime startTime = date.atStartOfDay();
         LocalDateTime startTime = date.atStartOfDay();
         LocalDateTime endTime = date.atTime(23, 59, 59);
         LocalDateTime endTime = date.atTime(23, 59, 59);
 
 
-        // 查当天所有线损明细
-        LambdaQueryWrapper<FhzgSeLineLossDetail> wrapper = new LambdaQueryWrapper<FhzgSeLineLossDetail>()
-                .ge(FhzgSeLineLossDetail::getSnapTime, startTime)
-                .le(FhzgSeLineLossDetail::getSnapTime, endTime);
-
-        List<FhzgSeLineLossDetail> details = lineLossDetailMapper.selectList(wrapper);
-
-        if (details.isEmpty()) {
+        // 按馈线 SQL 聚合
+        // lineLossKwh = SUM(line_loss_kw) × 0.25(15min 断面间隔换算 kWh)
+        QueryWrapper<FhzgSeLineLossDetail> wrapper = new QueryWrapper<FhzgSeLineLossDetail>()
+                .select("feeder_id",
+                        "MAX(county_id) AS county_id",
+                        "MAX(subs_id) AS subs_id",
+                        "COALESCE(SUM(line_loss_kw), 0) AS sum_kw",
+                        "COALESCE(MAX(line_loss_kw), 0) AS max_kw",
+                        "COUNT(line_loss_kw) AS cnt")
+                .ge("snap_time", startTime)
+                .le("snap_time", endTime)
+                .isNotNull("feeder_id")
+                .groupBy("feeder_id");
+
+        List<Map<String, Object>> rows = lineLossDetailMapper.selectMaps(wrapper);
+
+        if (rows == null || rows.isEmpty()) {
             log.info("[线路线损日汇总] {} 无线损明细数据,跳过", date);
             log.info("[线路线损日汇总] {} 无线损明细数据,跳过", date);
             return date + " 无线损明细数据";
             return date + " 无线损明细数据";
         }
         }
 
 
-        // 按馈线分组聚合
-        Map<String, DailyAccumulator> accumulatorMap = new HashMap<>();
-        for (FhzgSeLineLossDetail d : details) {
-            String feederId = d.getFeederId();
+        // 构建日汇总记录
+        List<FhzgSeLineLossDaily> dailyRecords = new ArrayList<>();
+        for (Map<String, Object> row : rows) {
+            String feederId = (String) row.get("feeder_id");
             if (feederId == null) continue;
             if (feederId == null) continue;
 
 
-            DailyAccumulator acc = accumulatorMap.computeIfAbsent(feederId, k -> new DailyAccumulator());
-            acc.countyId = d.getCountyId();
-            acc.subsId = d.getSubsId();
-
-            BigDecimal loss = d.getLineLossKw();
-            if (loss != null) {
-                // 线损电量 kWh = 线损功率 kW × 断面间隔(15min = 0.25h)
-                BigDecimal energy = loss.multiply(BigDecimal.valueOf(0.25));
-                acc.sumKwh = acc.sumKwh.add(energy);
-                if (loss.compareTo(acc.maxKw) > 0) {
-                    acc.maxKw = loss;
-                }
-                acc.sumKw = acc.sumKw.add(loss);
-                acc.count++;
-            }
-        }
+            BigDecimal sumKw = (BigDecimal) row.get("sum_kw");
+            BigDecimal maxKw = (BigDecimal) row.get("max_kw");
+            int cnt = ((Number) row.get("cnt")).intValue();
 
 
-        // 先删当天已有数据(避免重复运行时叠加)
-        LambdaQueryWrapper<FhzgSeLineLossDaily> deleteWrapper = new LambdaQueryWrapper<FhzgSeLineLossDaily>()
-                .eq(FhzgSeLineLossDaily::getStatDate, date);
-        lineLossDailyMapper.delete(deleteWrapper);
+            // 线损电量 kWh = 线损功率 kW × 断面间隔(15min = 0.25h)
+            BigDecimal sumKwh = sumKw.multiply(BigDecimal.valueOf(0.25));
 
 
-        // 构建日汇总记录
-        List<FhzgSeLineLossDaily> dailyRecords = new ArrayList<>();
-        for (Map.Entry<String, DailyAccumulator> entry : accumulatorMap.entrySet()) {
-            DailyAccumulator acc = entry.getValue();
-
-            BigDecimal avgKw = acc.count > 0
-                    ? acc.sumKw.divide(BigDecimal.valueOf(acc.count), 4, RoundingMode.HALF_UP)
+            BigDecimal avgKw = cnt > 0
+                    ? sumKw.divide(BigDecimal.valueOf(cnt), 4, RoundingMode.HALF_UP)
                     : BigDecimal.ZERO;
                     : BigDecimal.ZERO;
 
 
             FhzgSeLineLossDaily daily = FhzgSeLineLossDaily.builder()
             FhzgSeLineLossDaily daily = FhzgSeLineLossDaily.builder()
                     .statDate(date)
                     .statDate(date)
-                    .feederId(entry.getKey())
+                    .feederId(feederId)
                     .feederName(null)
                     .feederName(null)
-                    .countyId(acc.countyId)
-                    .subsId(acc.subsId)
-                    .lineLossKwh(acc.sumKwh.setScale(2, RoundingMode.HALF_UP))
-                    .maxLineLossKw(acc.maxKw.compareTo(BigDecimal.ZERO) > 0 ? acc.maxKw.setScale(4, RoundingMode.HALF_UP) : BigDecimal.ZERO)
+                    .countyId((String) row.get("county_id"))
+                    .subsId((String) row.get("subs_id"))
+                    .lineLossKwh(sumKwh.setScale(2, RoundingMode.HALF_UP))
+                    .maxLineLossKw(maxKw.compareTo(BigDecimal.ZERO) > 0 ? maxKw.setScale(4, RoundingMode.HALF_UP) : BigDecimal.ZERO)
                     .avgLineLossKw(avgKw.setScale(4, RoundingMode.HALF_UP))
                     .avgLineLossKw(avgKw.setScale(4, RoundingMode.HALF_UP))
-                    .totalSnapshots(acc.count)
+                    .totalSnapshots(cnt)
                     .createTime(LocalDateTime.now())
                     .createTime(LocalDateTime.now())
                     .updateTime(LocalDateTime.now())
                     .updateTime(LocalDateTime.now())
                     .build();
                     .build();
             dailyRecords.add(daily);
             dailyRecords.add(daily);
         }
         }
 
 
+        // 先删当天已有数据(避免重复运行时叠加)
+        LambdaQueryWrapper<FhzgSeLineLossDaily> deleteWrapper = new LambdaQueryWrapper<FhzgSeLineLossDaily>()
+                .eq(FhzgSeLineLossDaily::getStatDate, date);
+        lineLossDailyMapper.delete(deleteWrapper);
+
         for (FhzgSeLineLossDaily record : dailyRecords) {
         for (FhzgSeLineLossDaily record : dailyRecords) {
             lineLossDailyMapper.insert(record);
             lineLossDailyMapper.insert(record);
         }
         }
@@ -117,16 +111,4 @@ public class SeLineLossDailyScheduler {
         log.info("[线路线损日汇总] {}", result);
         log.info("[线路线损日汇总] {}", result);
         return result;
         return result;
     }
     }
-
-    /**
-     * 日聚合累加器
-     */
-    private static class DailyAccumulator {
-        String countyId;
-        String subsId;
-        BigDecimal sumKwh = BigDecimal.ZERO;
-        BigDecimal maxKw = BigDecimal.ZERO;
-        BigDecimal sumKw = BigDecimal.ZERO;
-        int count = 0;
-    }
 }
 }

+ 5 - 5
common/common-se/src/main/java/com/hdkj/lt/bf/scheduler/SePartitionRotateScheduler.java

@@ -1,6 +1,5 @@
 package com.hdkj.lt.bf.scheduler;
 package com.hdkj.lt.bf.scheduler;
 
 
-import com.google.common.collect.ImmutableMap;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -36,10 +35,11 @@ public class SePartitionRotateScheduler {
     private static final DateTimeFormatter PART_FMT = DateTimeFormatter.ofPattern("yyyyMM");
     private static final DateTimeFormatter PART_FMT = DateTimeFormatter.ofPattern("yyyyMM");
 
 
     /** 需要滚动的分区表:表名 → 保留月数(含当前月,即最多保留 N+1 个自然月) */
     /** 需要滚动的分区表:表名 → 保留月数(含当前月,即最多保留 N+1 个自然月) */
-    private static final ImmutableMap<String, Integer> PARTITION_TABLES = ImmutableMap.of(
-            "fhzg_se_snapshot_detail", 2,    // 30 天保留 → 当前月+上月
-            "fhzg_se_line_loss_detail", 2     // 7 天保留 → 当前月+上月
-    );
+    private static final Map<String, Integer> PARTITION_TABLES = Collections.unmodifiableMap(
+            new HashMap<String, Integer>() {{
+                put("fhzg_se_snapshot_detail", 2);    // 30 天保留 → 当前月+上月
+                put("fhzg_se_line_loss_detail", 2);    // 7 天保留 → 当前月+上月
+            }});
 
 
     private final JdbcTemplate jdbcTemplate;
     private final JdbcTemplate jdbcTemplate;
 
 

+ 0 - 9
common/pom.xml

@@ -45,15 +45,6 @@
             <groupId>com.baomidou</groupId>
             <groupId>com.baomidou</groupId>
             <artifactId>mybatis-plus-boot-starter</artifactId>
             <artifactId>mybatis-plus-boot-starter</artifactId>
         </dependency>
         </dependency>
-        <dependency>
-            <groupId>com.google.code.gson</groupId>
-            <artifactId>gson</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <version>31.1-jre</version>
-        </dependency>
     </dependencies>
     </dependencies>
 
 
 </project>
 </project>