初始提交:添加分时处理

This commit is contained in:
liuzhiming 2026-03-17 14:46:01 +08:00
parent 71821493ee
commit ce01389d7a
10 changed files with 105 additions and 34 deletions

View File

@ -5,7 +5,7 @@ import lombok.Data;
import java.util.List; import java.util.List;
/** /**
* TODO * 日停电记录VO
* *
* @author: junzhangfm * @author: junzhangfm
* @date: 2026/3/14 * @date: 2026/3/14

View File

@ -63,6 +63,11 @@ public class DnerDailyPowerOutageEvent {
*/ */
private String extremeWindSpeedHourly; private String extremeWindSpeedHourly;
/**
* 停电时长
*/
private String powerOutageDuration;
/** /**
* 停电影响用户总数 * 停电影响用户总数
*/ */

View File

@ -63,6 +63,11 @@ public class DnerHourlyPowerOutageEvent {
*/ */
private String extremeWindSpeedHourly; private String extremeWindSpeedHourly;
/**
* 停电时长
*/
private String powerOutageDuration;
/** /**
* 停电影响用户总数 * 停电影响用户总数
*/ */

View File

@ -0,0 +1,30 @@
package com.southern.power.grid.entity;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 站点气象数据
*
* @author: LIUZHIMING
* @date: 2026/3/17
**/
@Data
public class WeatherAreaDataDTO {
String districtCode;
private LocalDateTime dataTime;
// 平均气温
private String temperature;
// 小时最高气温
private String hourlyMaxTemperature;
// 小时最低气温
private String hourlyMinTemperature;
// 小时降雨量
private Double hourlyPrecipitation;
// 日累计降雨量
private String dailyPrecipitation;
// 小时内极大风速
private String extremeWindSpeedHourly;
}

View File

@ -4,16 +4,28 @@ import lombok.Data;
import java.time.LocalDateTime; import java.time.LocalDateTime;
/**
* 站点气象数据
*
* @author: LIUZHIMING
* @date: 2026/3/13
**/
@Data @Data
public class WeatherDataDTO { public class WeatherDataDTO {
private String stationId; private String stationId;
private String stationName; private String stationName;
private LocalDateTime dataTime; private LocalDateTime dataTime;
// 平均气温
private String temperature; private String temperature;
// 小时最高气温
private String hourlyMaxTemperature; private String hourlyMaxTemperature;
// 小时最低气温
private String hourlyMinTemperature; private String hourlyMinTemperature;
// 小时降雨量
private Double hourlyPrecipitation; private Double hourlyPrecipitation;
// 日累计降雨量
private String dailyPrecipitation; private String dailyPrecipitation;
// 小时内极大风速
private String extremeWindSpeedHourly; private String extremeWindSpeedHourly;
} }

View File

@ -15,5 +15,5 @@ public interface WeatherDataService {
/** /**
* 从缓存若无则查库中获取指定 站点 + 时间点 对应的气象数据 * 从缓存若无则查库中获取指定 站点 + 时间点 对应的气象数据
*/ */
WeatherDataDTO getWeatherData(String stationId, LocalDateTime dateTime); List<WeatherDataDTO> getWeatherData(List<String> stationIds, LocalDateTime dateTime);
} }

View File

@ -1,5 +1,6 @@
package com.southern.power.grid.service.impl; package com.southern.power.grid.service.impl;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.southern.power.grid.dao.DnerHourlyPowerOutageEventMapper; import com.southern.power.grid.dao.DnerHourlyPowerOutageEventMapper;
import com.southern.power.grid.dao.NwSiteAreaConfigurationMapper; import com.southern.power.grid.dao.NwSiteAreaConfigurationMapper;
import com.southern.power.grid.dao.WeatherSiteAreaConfigurationMapper; import com.southern.power.grid.dao.WeatherSiteAreaConfigurationMapper;
@ -9,6 +10,8 @@ import com.southern.power.grid.entity.NwSiteAreaConfiguration;
import com.southern.power.grid.entity.WeatherDataDTO; import com.southern.power.grid.entity.WeatherDataDTO;
import com.southern.power.grid.entity.WeatherSiteAreaConfiguration; import com.southern.power.grid.entity.WeatherSiteAreaConfiguration;
import com.southern.power.grid.service.WeatherDataService; import com.southern.power.grid.service.WeatherDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -20,6 +23,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
@Service @Service
@Slf4j
public class HourlyOutageExcelProcessService { public class HourlyOutageExcelProcessService {
@Resource @Resource
private NwSiteAreaConfigurationMapper nwSiteAreaConfigurationMapper; private NwSiteAreaConfigurationMapper nwSiteAreaConfigurationMapper;
@ -34,14 +38,16 @@ public class HourlyOutageExcelProcessService {
private DnerHourlyPowerOutageEventMapper dnerHourlyPowerOutageEventMapper; private DnerHourlyPowerOutageEventMapper dnerHourlyPowerOutageEventMapper;
/** /**
* 南网区域配置
* key = nw_province + "|" + nw_city + "|" + nw_district value = district_code * key = nw_province + "|" + nw_city + "|" + nw_district value = district_code
*/ */
private final Map<String, String> nwAreaMap = new HashMap<>(); private final Map<String, String> nwAreaMap = new HashMap<>();
/** /**
* 气象区域配置
* key = district_code value = WeatherSiteAreaConfiguration包含 station_id/station_name * key = district_code value = WeatherSiteAreaConfiguration包含 station_id/station_name
*/ */
private final Map<String, WeatherSiteAreaConfiguration> weatherAreaMap = new HashMap<>(); private final Map<String, List<WeatherSiteAreaConfiguration>> weatherAreaMap = new HashMap<>();
private static final DateTimeFormatter DB_DATETIME_STR = private static final DateTimeFormatter DB_DATETIME_STR =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@ -63,24 +69,34 @@ public class HourlyOutageExcelProcessService {
String districtCode = findDistrictCode(row.getProvince(), row.getCity(), row.getDistrict()); String districtCode = findDistrictCode(row.getProvince(), row.getCity(), row.getDistrict());
if (districtCode == null) { if (districtCode == null) {
// 找不到映射可记录日志或统计 // 找不到映射可记录日志或统计
log.info("districtCode is null! {}, {}, {}", row.getProvince(), row.getCity(), row.getDistrict());
continue; continue;
} }
// 3.2 district_code station_id // 3.2 district_code station_id
WeatherSiteAreaConfiguration weatherArea = weatherAreaMap.get(districtCode); List<WeatherSiteAreaConfiguration> weatherAreas = weatherAreaMap.get(districtCode);
if (weatherArea == null || weatherArea.getStationId() == null) { if (weatherAreas == null) {
// 找不到对应气象站 // 找不到对应气象站
log.info("weatherAreas is null! {}", districtCode);
continue; continue;
} }
String stationId = weatherArea.getStationId(); List<String> stationIds = new ArrayList<>();
for (WeatherSiteAreaConfiguration weatherArea : weatherAreas) {
String stationId = weatherArea.getStationId();
if (StringUtils.isNotEmpty(stationId) && !stationIds.contains(stationId)) {
stationIds.add(stationId);
}
}
// 3.3 通过 stationId + 时间统一取7天气象数据内部做缓存 // 3.3 通过 stationId + 时间统一取8天气象数据内部做缓存
LocalDateTime dataTime = row.getStartTime(); LocalDateTime dataTime = row.getStartTime();
WeatherDataDTO weatherData = weatherDataService.getWeatherData(stationId, dataTime); List<WeatherDataDTO> weatherData = weatherDataService.getWeatherData(stationIds, dataTime);
// 3.4 组装分时停电事件实体 // 3.4 组装分时停电事件实体
DnerHourlyPowerOutageEvent entity = buildHourlyEvent(row, districtCode, weatherData); for (WeatherDataDTO weatherDataDTO : weatherData) {
toInsert.add(entity); DnerHourlyPowerOutageEvent entity = buildHourlyEvent(row, districtCode, weatherDataDTO);
toInsert.add(entity);
}
} }
if (!toInsert.isEmpty()) { if (!toInsert.isEmpty()) {
@ -114,7 +130,14 @@ public class HourlyOutageExcelProcessService {
if (list == null) return; if (list == null) return;
for (WeatherSiteAreaConfiguration cfg : list) { for (WeatherSiteAreaConfiguration cfg : list) {
if (cfg.getDistrictCode() != null && !cfg.getDistrictCode().isEmpty()) { if (cfg.getDistrictCode() != null && !cfg.getDistrictCode().isEmpty()) {
weatherAreaMap.put(cfg.getDistrictCode(), cfg); List<WeatherSiteAreaConfiguration> weatherSiteAreaConfigurations = weatherAreaMap.get(cfg.getDistrictCode());
if (weatherSiteAreaConfigurations == null) {
weatherSiteAreaConfigurations = new ArrayList<>();
weatherSiteAreaConfigurations.add(cfg);
weatherAreaMap.put(cfg.getDistrictCode(), weatherSiteAreaConfigurations);
} else {
weatherSiteAreaConfigurations.add(cfg);
}
} }
} }
} }

View File

@ -248,10 +248,10 @@ public class HourlyStatisticService {
for (String stationId : stationIds) { for (String stationId : stationIds) {
Map<LocalDateTime, WeatherDataDTO> stationHourly = new HashMap<>(); Map<LocalDateTime, WeatherDataDTO> stationHourly = new HashMap<>();
for (LocalDateTime hour : timePoints) { for (LocalDateTime hour : timePoints) {
WeatherDataDTO data = weatherDataService.getWeatherData(stationId, hour); // WeatherDataDTO data = weatherDataService.getWeatherData(stationIds, hour);
if (data != null) { // if (data != null) {
stationHourly.put(hour, data); // stationHourly.put(hour, data);
} // }
} }
result.put(stationId, stationHourly); result.put(stationId, stationHourly);
} }

View File

@ -8,6 +8,7 @@ import com.southern.power.grid.entity.WeatherDataDTO;
import com.southern.power.grid.service.WeatherDataService; import com.southern.power.grid.service.WeatherDataService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDate; import java.time.LocalDate;
@ -26,7 +27,7 @@ public class WeatherDataServiceImpl implements WeatherDataService {
/** /**
* 缓存key = stationId + "|" + startDate(yyyy-MM-dd)value = Map<dataTime, WeatherDataDTO> * 缓存key = stationId + "|" + startDate(yyyy-MM-dd)value = Map<dataTime, WeatherDataDTO>
*/ */
private final Map<String, Map<LocalDateTime, WeatherDataDTO>> cache = new HashMap<>(); private final Map<String, List<WeatherDataDTO>> cache = new HashMap<>();
private static final DateTimeFormatter DB_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH"); private static final DateTimeFormatter DB_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");
@ -58,31 +59,24 @@ public class WeatherDataServiceImpl implements WeatherDataService {
} }
@Override @Override
public WeatherDataDTO getWeatherData(String stationId, LocalDateTime dateTime) { public List<WeatherDataDTO> getWeatherData(List<String> stationIds, LocalDateTime dateTime) {
if (stationId == null || dateTime == null) { if (CollectionUtils.isEmpty(stationIds) || dateTime == null) {
return null; return null;
} }
LocalDate startDate = dateTime.toLocalDate(); LocalDate startDate = dateTime.toLocalDate();
String windowKey = buildWindowKey(stationId, startDate); List<WeatherDataDTO> result = new ArrayList<>();
for (String stationId : stationIds) {
Map<LocalDateTime, WeatherDataDTO> stationMap = cache.get(windowKey); List<WeatherDataDTO> stationList = cache.get(stationId);
if (stationMap == null) { if (stationList == null) {
stationMap = new HashMap<>(); stationList = query7DaysWeather(stationId, startDate);
List<WeatherDataDTO> list = query7DaysWeather(stationId, startDate); if (stationList != null) {
if (list != null) { result.addAll(stationList);
for (WeatherDataDTO dto : list) { cache.put(stationId, stationList);
if (dto.getDataTime() != null) {
stationMap.put(dto.getDataTime(), dto);
}
} }
} }
cache.put(windowKey, stationMap);
} }
return stationMap.get(dateTime);
}
private String buildWindowKey(String stationId, LocalDate startDate) { return result;
return stationId + "|" + startDate.toString();
} }
private WeatherDataDTO convertFromNational(NationalWeatherStation n) { private WeatherDataDTO convertFromNational(NationalWeatherStation n) {

View File

@ -80,6 +80,7 @@ CREATE TABLE `dner_daily_power_outage_event`
`hourly_max_temperature` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '日内最高气温', `hourly_max_temperature` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '日内最高气温',
`hourly_min_temperature` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '日内最低气温', `hourly_min_temperature` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '日内最低气温',
`extreme_wind_speed_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '日内极大风速', `extreme_wind_speed_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '日内极大风速',
`power_outage_duration` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '停电时长',
`user_count` int(11) DEFAULT NULL COMMENT '停电影响用户总数', `user_count` int(11) DEFAULT NULL COMMENT '停电影响用户总数',
`star_user_count` int(11) DEFAULT NULL COMMENT '起始影响用户总数', `star_user_count` int(11) DEFAULT NULL COMMENT '起始影响用户总数',
`end_user_count` int(11) DEFAULT NULL COMMENT '结束影响用户总数', `end_user_count` int(11) DEFAULT NULL COMMENT '结束影响用户总数',
@ -108,6 +109,7 @@ CREATE TABLE `dner_hourly_power_outage_event`
`hourly_max_temperature` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最高气温', `hourly_max_temperature` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最高气温',
`hourly_min_temperature` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最低气温', `hourly_min_temperature` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最低气温',
`extreme_wind_speed_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内极大风速', `extreme_wind_speed_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内极大风速',
`power_outage_duration` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '停电时长',
`user_count` int(11) DEFAULT NULL COMMENT '停电影响用户总数', `user_count` int(11) DEFAULT NULL COMMENT '停电影响用户总数',
`outage_state` tinyint(4) DEFAULT NULL COMMENT '停电状态1-待停电2-停电中3-已复电)', `outage_state` tinyint(4) DEFAULT NULL COMMENT '停电状态1-待停电2-停电中3-已复电)',
`outage_type` tinyint(4) DEFAULT NULL COMMENT '停电类型1-故障类2-计划类)', `outage_type` tinyint(4) DEFAULT NULL COMMENT '停电类型1-故障类2-计划类)',