初始提交:添加分时处理

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;
/**
* TODO
* 日停电记录VO
*
* @author: junzhangfm
* @date: 2026/3/14

View File

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

View File

@ -63,6 +63,11 @@ public class DnerHourlyPowerOutageEvent {
*/
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;
/**
* 站点气象数据
*
* @author: LIUZHIMING
* @date: 2026/3/13
**/
@Data
public class WeatherDataDTO {
private String stationId;
private String stationName;
private LocalDateTime dataTime;
// 平均气温
private String temperature;
// 小时最高气温
private String hourlyMaxTemperature;
// 小时最低气温
private String hourlyMinTemperature;
// 小时降雨量
private Double hourlyPrecipitation;
// 日累计降雨量
private String dailyPrecipitation;
// 小时内极大风速
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;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.southern.power.grid.dao.DnerHourlyPowerOutageEventMapper;
import com.southern.power.grid.dao.NwSiteAreaConfigurationMapper;
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.WeatherSiteAreaConfiguration;
import com.southern.power.grid.service.WeatherDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@ -20,6 +23,7 @@ import java.util.List;
import java.util.Map;
@Service
@Slf4j
public class HourlyOutageExcelProcessService {
@Resource
private NwSiteAreaConfigurationMapper nwSiteAreaConfigurationMapper;
@ -34,14 +38,16 @@ public class HourlyOutageExcelProcessService {
private DnerHourlyPowerOutageEventMapper dnerHourlyPowerOutageEventMapper;
/**
* 南网区域配置
* key = nw_province + "|" + nw_city + "|" + nw_district value = district_code
*/
private final Map<String, String> nwAreaMap = new HashMap<>();
/**
* 气象区域配置
* 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 =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@ -63,25 +69,35 @@ public class HourlyOutageExcelProcessService {
String districtCode = findDistrictCode(row.getProvince(), row.getCity(), row.getDistrict());
if (districtCode == null) {
// 找不到映射可记录日志或统计
log.info("districtCode is null! {}, {}, {}", row.getProvince(), row.getCity(), row.getDistrict());
continue;
}
// 3.2 district_code station_id
WeatherSiteAreaConfiguration weatherArea = weatherAreaMap.get(districtCode);
if (weatherArea == null || weatherArea.getStationId() == null) {
List<WeatherSiteAreaConfiguration> weatherAreas = weatherAreaMap.get(districtCode);
if (weatherAreas == null) {
// 找不到对应气象站
log.info("weatherAreas is null! {}", districtCode);
continue;
}
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();
WeatherDataDTO weatherData = weatherDataService.getWeatherData(stationId, dataTime);
List<WeatherDataDTO> weatherData = weatherDataService.getWeatherData(stationIds, dataTime);
// 3.4 组装分时停电事件实体
DnerHourlyPowerOutageEvent entity = buildHourlyEvent(row, districtCode, weatherData);
for (WeatherDataDTO weatherDataDTO : weatherData) {
DnerHourlyPowerOutageEvent entity = buildHourlyEvent(row, districtCode, weatherDataDTO);
toInsert.add(entity);
}
}
if (!toInsert.isEmpty()) {
// 4. 批量入库
@ -114,7 +130,14 @@ public class HourlyOutageExcelProcessService {
if (list == null) return;
for (WeatherSiteAreaConfiguration cfg : list) {
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) {
Map<LocalDateTime, WeatherDataDTO> stationHourly = new HashMap<>();
for (LocalDateTime hour : timePoints) {
WeatherDataDTO data = weatherDataService.getWeatherData(stationId, hour);
if (data != null) {
stationHourly.put(hour, data);
}
// WeatherDataDTO data = weatherDataService.getWeatherData(stationIds, hour);
// if (data != null) {
// stationHourly.put(hour, data);
// }
}
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 org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.time.LocalDate;
@ -26,7 +27,7 @@ public class WeatherDataServiceImpl implements WeatherDataService {
/**
* 缓存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");
@ -58,31 +59,24 @@ public class WeatherDataServiceImpl implements WeatherDataService {
}
@Override
public WeatherDataDTO getWeatherData(String stationId, LocalDateTime dateTime) {
if (stationId == null || dateTime == null) {
public List<WeatherDataDTO> getWeatherData(List<String> stationIds, LocalDateTime dateTime) {
if (CollectionUtils.isEmpty(stationIds) || dateTime == null) {
return null;
}
LocalDate startDate = dateTime.toLocalDate();
String windowKey = buildWindowKey(stationId, startDate);
Map<LocalDateTime, WeatherDataDTO> stationMap = cache.get(windowKey);
if (stationMap == null) {
stationMap = new HashMap<>();
List<WeatherDataDTO> list = query7DaysWeather(stationId, startDate);
if (list != null) {
for (WeatherDataDTO dto : list) {
if (dto.getDataTime() != null) {
stationMap.put(dto.getDataTime(), dto);
List<WeatherDataDTO> result = new ArrayList<>();
for (String stationId : stationIds) {
List<WeatherDataDTO> stationList = cache.get(stationId);
if (stationList == null) {
stationList = query7DaysWeather(stationId, startDate);
if (stationList != null) {
result.addAll(stationList);
cache.put(stationId, stationList);
}
}
}
cache.put(windowKey, stationMap);
}
return stationMap.get(dateTime);
}
private String buildWindowKey(String stationId, LocalDate startDate) {
return stationId + "|" + startDate.toString();
return result;
}
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_min_temperature` 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 '停电影响用户总数',
`star_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_min_temperature` 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 '停电影响用户总数',
`outage_state` tinyint(4) DEFAULT NULL COMMENT '停电状态1-待停电2-停电中3-已复电)',
`outage_type` tinyint(4) DEFAULT NULL COMMENT '停电类型1-故障类2-计划类)',