|
@@ -1,178 +0,0 @@
|
|
|
-package com.hdkj.lt.bf.scheduler;
|
|
|
|
|
-
|
|
|
|
|
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
-import com.hdkj.lt.bf.entity.FhzgSeCapacityDaily;
|
|
|
|
|
-import com.hdkj.lt.bf.entity.FhzgSeCurrentEvent;
|
|
|
|
|
-import com.hdkj.lt.bf.entity.FhzgSeSnapshotDetail;
|
|
|
|
|
-import com.hdkj.lt.bf.mapper.FhzgSeCapacityDailyMapper;
|
|
|
|
|
-import com.hdkj.lt.bf.mapper.FhzgSeCurrentEventMapper;
|
|
|
|
|
-import com.hdkj.lt.bf.mapper.FhzgSeSnapshotDetailMapper;
|
|
|
|
|
-import lombok.RequiredArgsConstructor;
|
|
|
|
|
-import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
-import org.springframework.scheduling.annotation.Scheduled;
|
|
|
|
|
-import org.springframework.stereotype.Component;
|
|
|
|
|
-
|
|
|
|
|
-import java.math.BigDecimal;
|
|
|
|
|
-import java.math.RoundingMode;
|
|
|
|
|
-import java.time.LocalDate;
|
|
|
|
|
-import java.time.LocalDateTime;
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
|
-import java.util.HashMap;
|
|
|
|
|
-import java.util.List;
|
|
|
|
|
-import java.util.Map;
|
|
|
|
|
-
|
|
|
|
|
-/**
|
|
|
|
|
- * 供电能力日汇总定时任务
|
|
|
|
|
- * 每天凌晨1点,将昨天的断面明细聚合写入 fhzg_se_capacity_daily
|
|
|
|
|
- *
|
|
|
|
|
- * @author lsl
|
|
|
|
|
- * @since 2026-07-25
|
|
|
|
|
- */
|
|
|
|
|
-@Slf4j
|
|
|
|
|
-@Component
|
|
|
|
|
-@RequiredArgsConstructor
|
|
|
|
|
-public class SeCapacityDailyScheduler {
|
|
|
|
|
-
|
|
|
|
|
- private final FhzgSeSnapshotDetailMapper snapshotDetailMapper;
|
|
|
|
|
- private final FhzgSeCurrentEventMapper currentEventMapper;
|
|
|
|
|
- private final FhzgSeCapacityDailyMapper capacityDailyMapper;
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 每天凌晨1点执行
|
|
|
|
|
- */
|
|
|
|
|
- @Scheduled(cron = "0 0 1 * * ?")
|
|
|
|
|
- public void aggregateYesterdayCapacity() {
|
|
|
|
|
- LocalDate yesterday = LocalDate.now().minusDays(1);
|
|
|
|
|
- log.info("[供电能力日汇总] 开始处理 {} 数据", yesterday);
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- String result = aggregateForDate(yesterday);
|
|
|
|
|
- log.info("[供电能力日汇总] {} {}", yesterday, result);
|
|
|
|
|
- } catch (Exception e) {
|
|
|
|
|
- log.error("[供电能力日汇总] {} 处理失败", yesterday, e);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 聚合指定日期的断面/事件数据到日汇总表(手动触发时调用)
|
|
|
|
|
- * <p>
|
|
|
|
|
- * 负载率从断面明细聚合,重过载事件数从事件表统计(与事件表口径一致)
|
|
|
|
|
- */
|
|
|
|
|
- public String aggregateForDate(LocalDate date) {
|
|
|
|
|
- LocalDateTime startTime = date.atStartOfDay();
|
|
|
|
|
- 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()) {
|
|
|
|
|
- log.info("[供电能力日汇总] {} 无断面/事件数据,跳过", date);
|
|
|
|
|
- return date + " 无断面/事件数据";
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 按馈线分组聚合
|
|
|
|
|
- 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++;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 事件数按馈线累加(同一条馈线当日多个事件算多次)
|
|
|
|
|
- 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++;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 先删当天已有数据(避免重复运行时叠加)
|
|
|
|
|
- LambdaQueryWrapper<FhzgSeCapacityDaily> deleteWrapper = new LambdaQueryWrapper<FhzgSeCapacityDaily>()
|
|
|
|
|
- .eq(FhzgSeCapacityDaily::getStatDate, date);
|
|
|
|
|
- capacityDailyMapper.delete(deleteWrapper);
|
|
|
|
|
-
|
|
|
|
|
- // 批量插入
|
|
|
|
|
- List<FhzgSeCapacityDaily> dailyRecords = new ArrayList<>();
|
|
|
|
|
- for (Map.Entry<String, DailyAccumulator> entry : accumulatorMap.entrySet()) {
|
|
|
|
|
- String feederId = entry.getKey();
|
|
|
|
|
- DailyAccumulator acc = entry.getValue();
|
|
|
|
|
-
|
|
|
|
|
- BigDecimal avgLoadRate = acc.totalSnapshots > 0
|
|
|
|
|
- ? acc.sumLoadRate.divide(BigDecimal.valueOf(acc.totalSnapshots), 2, RoundingMode.HALF_UP)
|
|
|
|
|
- : BigDecimal.ZERO;
|
|
|
|
|
-
|
|
|
|
|
- FhzgSeCapacityDaily daily = FhzgSeCapacityDaily.builder()
|
|
|
|
|
- .statDate(date)
|
|
|
|
|
- .feederId(feederId)
|
|
|
|
|
- .feederName(acc.feederName)
|
|
|
|
|
- .countyId(acc.countyId)
|
|
|
|
|
- .subsId(acc.subsId)
|
|
|
|
|
- .maxLoadRate(acc.maxLoadRate)
|
|
|
|
|
- .avgLoadRate(avgLoadRate)
|
|
|
|
|
- .heavyCount(acc.heavyCount)
|
|
|
|
|
- .overloadCount(acc.overloadCount)
|
|
|
|
|
- .totalSnapshots(acc.totalSnapshots)
|
|
|
|
|
- .createTime(LocalDateTime.now())
|
|
|
|
|
- .updateTime(LocalDateTime.now())
|
|
|
|
|
- .build();
|
|
|
|
|
- dailyRecords.add(daily);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- // 批量插入
|
|
|
|
|
- for (FhzgSeCapacityDaily record : dailyRecords) {
|
|
|
|
|
- capacityDailyMapper.insert(record);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- String result = date + " 处理完成: " + dailyRecords.size() + " 条馈线日汇总";
|
|
|
|
|
- log.info("[供电能力日汇总] {}", result);
|
|
|
|
|
- return result;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /**
|
|
|
|
|
- * 日聚合累加器
|
|
|
|
|
- */
|
|
|
|
|
- private static class DailyAccumulator {
|
|
|
|
|
- String countyId;
|
|
|
|
|
- String subsId;
|
|
|
|
|
- String feederName;
|
|
|
|
|
- BigDecimal maxLoadRate = BigDecimal.ZERO;
|
|
|
|
|
- BigDecimal sumLoadRate = BigDecimal.ZERO;
|
|
|
|
|
- /** 当日重载事件数(从事件表统计) */
|
|
|
|
|
- int heavyCount = 0;
|
|
|
|
|
- /** 当日过载事件数(从事件表统计) */
|
|
|
|
|
- int overloadCount = 0;
|
|
|
|
|
- int totalSnapshots = 0;
|
|
|
|
|
- }
|
|
|
|
|
-}
|
|
|