初始提交:添加分时处理
This commit is contained in:
parent
600242462e
commit
186a3db27c
@ -3,7 +3,43 @@ package com.southern.power.grid.dao;
|
|||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import com.southern.power.grid.entity.RegionalWeatherData;
|
import com.southern.power.grid.entity.RegionalWeatherData;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface RegionalWeatherDataMapper extends BaseMapper<RegionalWeatherData> {
|
public interface RegionalWeatherDataMapper extends BaseMapper<RegionalWeatherData> {
|
||||||
|
/**
|
||||||
|
* 插入一条区域气象数据记录
|
||||||
|
* @param record 实体对象
|
||||||
|
* @return 影响行数
|
||||||
|
*/
|
||||||
|
int insert(RegionalWeatherData record);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据主键ID查询
|
||||||
|
* @param id 主键ID
|
||||||
|
* @return 实体对象
|
||||||
|
*/
|
||||||
|
RegionalWeatherData selectByPrimaryKey(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据地区编码和资料时次查询
|
||||||
|
* @param orgCode 地区编码
|
||||||
|
* @param dataTime 资料时次
|
||||||
|
* @return 实体列表
|
||||||
|
*/
|
||||||
|
List<RegionalWeatherData> selectByOrgCodeAndDataTime(@Param("orgCode") String orgCode, @Param("dataTime") String dataTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据条件动态查询
|
||||||
|
* @param params 查询参数Map,支持:
|
||||||
|
* orgCode(精确匹配)
|
||||||
|
* dataTime(精确匹配)
|
||||||
|
* startCreateTime(创建时间起始,格式 yyyy-MM-dd HH:mm:ss)
|
||||||
|
* endCreateTime(创建时间结束)
|
||||||
|
* @return 实体列表
|
||||||
|
*/
|
||||||
|
List<RegionalWeatherData> selectByCondition(Map<String, Object> params);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
package com.southern.power.grid.entity;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
public class ExcelHourlyOutageRowDTO {
|
|
||||||
/** 资料时次,对应分时表的 data_time */
|
|
||||||
private LocalDateTime dataTime;
|
|
||||||
|
|
||||||
/** Excel 中体现的南网省/地市局/区县局(用于映射) */
|
|
||||||
private String nwProvince;
|
|
||||||
private String nwCity;
|
|
||||||
private String nwDistrict;
|
|
||||||
|
|
||||||
/** 停电影响用户数等业务字段(示例) */
|
|
||||||
private Integer userCount;
|
|
||||||
private Integer outageState;
|
|
||||||
private Integer outageType;
|
|
||||||
|
|
||||||
// ... 根据你的 Excel 列补全
|
|
||||||
|
|
||||||
// getter/setter
|
|
||||||
}
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
package com.southern.power.grid.entity;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分时统计结果DTO
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class HourlyStatisticDTO {
|
|
||||||
private List<String> timePoints; // 时间点列表,格式:yyyy-MM-dd HH:00:00
|
|
||||||
private List<Long> userCounts; // 停电影响用户数
|
|
||||||
private List<Double> precipitations; // 小时降水量
|
|
||||||
private List<Double> avgTemperatures; // 平均气温
|
|
||||||
private List<Double> maxTemperatures; // 最高气温
|
|
||||||
private List<Double> minTemperatures; // 最低气温
|
|
||||||
private List<Double> maxWindSpeeds; // 极大风速
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
@ -1,15 +1,14 @@
|
|||||||
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.RegionalWeatherDataMapper;
|
||||||
import com.southern.power.grid.dao.WeatherSiteAreaConfigurationMapper;
|
import com.southern.power.grid.dao.WeatherSiteAreaConfigurationMapper;
|
||||||
import com.southern.power.grid.entity.DataExcelEntity;
|
import com.southern.power.grid.entity.DataExcelEntity;
|
||||||
import com.southern.power.grid.entity.DnerHourlyPowerOutageEvent;
|
import com.southern.power.grid.entity.DnerHourlyPowerOutageEvent;
|
||||||
import com.southern.power.grid.entity.NwSiteAreaConfiguration;
|
import com.southern.power.grid.entity.NwSiteAreaConfiguration;
|
||||||
import com.southern.power.grid.entity.WeatherDataDTO;
|
import com.southern.power.grid.entity.RegionalWeatherData;
|
||||||
import com.southern.power.grid.entity.WeatherSiteAreaConfiguration;
|
import com.southern.power.grid.entity.WeatherSiteAreaConfiguration;
|
||||||
import com.southern.power.grid.service.WeatherDataService;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -17,6 +16,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.DateTimeParseException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -32,11 +32,15 @@ public class HourlyOutageExcelProcessService {
|
|||||||
private WeatherSiteAreaConfigurationMapper weatherSiteAreaConfigurationMapper;
|
private WeatherSiteAreaConfigurationMapper weatherSiteAreaConfigurationMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private WeatherDataService weatherDataService;
|
private RegionalWeatherDataMapper regionalWeatherDataMapper;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private DnerHourlyPowerOutageEventMapper dnerHourlyPowerOutageEventMapper;
|
private DnerHourlyPowerOutageEventMapper dnerHourlyPowerOutageEventMapper;
|
||||||
|
|
||||||
|
private static final Float lengthOutage = 60F;
|
||||||
|
|
||||||
|
// 定义时间格式器(建议定义为静态常量,避免重复创建)
|
||||||
|
private static final DateTimeFormatter DATA_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
/**
|
/**
|
||||||
* 南网区域配置
|
* 南网区域配置
|
||||||
* key = nw_province + "|" + nw_city + "|" + nw_district ;value = district_code
|
* key = nw_province + "|" + nw_city + "|" + nw_district ;value = district_code
|
||||||
@ -61,10 +65,16 @@ public class HourlyOutageExcelProcessService {
|
|||||||
// 2. 加载气象区划配置表
|
// 2. 加载气象区划配置表
|
||||||
loadWeatherAreaConfig();
|
loadWeatherAreaConfig();
|
||||||
|
|
||||||
List<DnerHourlyPowerOutageEvent> toInsert = new ArrayList<>();
|
// 使用 Map 存储待插入实体,Key 为 districtCode + "|" + dataTime
|
||||||
|
Map<String, DnerHourlyPowerOutageEvent> toInsertMap = new HashMap<>();
|
||||||
|
|
||||||
// 3 & 4. 循环处理 Excel 行
|
// 3 & 4. 循环处理 Excel 行
|
||||||
for (DataExcelEntity row : excelRows) {
|
for (DataExcelEntity row : excelRows) {
|
||||||
|
if(row.getLengthOutage()<lengthOutage) {
|
||||||
|
log.info("lengthOutage is less than 60! {}, {}, {}", row.getProvince(), row.getCity(), row.getDistrict());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// 3.1 根据南网省/市/区县 → district_code
|
// 3.1 根据南网省/市/区县 → district_code
|
||||||
String districtCode = findDistrictCode(row.getProvince(), row.getCity(), row.getDistrict());
|
String districtCode = findDistrictCode(row.getProvince(), row.getCity(), row.getDistrict());
|
||||||
if (districtCode == null) {
|
if (districtCode == null) {
|
||||||
@ -72,39 +82,51 @@ public class HourlyOutageExcelProcessService {
|
|||||||
log.info("districtCode is null! {}, {}, {}", row.getProvince(), row.getCity(), row.getDistrict());
|
log.info("districtCode is null! {}, {}, {}", row.getProvince(), row.getCity(), row.getDistrict());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// 3.2 获取区域时段内气象数据
|
||||||
// 3.2 district_code → station_id
|
List<RegionalWeatherData> regionalWeatherDataList =
|
||||||
List<WeatherSiteAreaConfiguration> weatherAreas = weatherAreaMap.get(districtCode);
|
regionalWeatherDataMapper.selectByOrgCodeAndDataTime(districtCode, DB_DATETIME_STR.format(row.getStartTime()));
|
||||||
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 + 时间,统一取8天气象数据(内部做缓存)
|
|
||||||
LocalDateTime dataTime = row.getStartTime();
|
|
||||||
List<WeatherDataDTO> weatherData = weatherDataService.getWeatherData(stationIds, dataTime);
|
|
||||||
|
|
||||||
// 3.4 组装分时停电事件实体
|
// 3.4 组装分时停电事件实体
|
||||||
for (WeatherDataDTO weatherDataDTO : weatherData) {
|
for (RegionalWeatherData regionalWeatherData : regionalWeatherDataList) {
|
||||||
DnerHourlyPowerOutageEvent entity = buildHourlyEvent(row, districtCode, weatherDataDTO);
|
LocalDateTime dataDateTime;
|
||||||
toInsert.add(entity);
|
try {
|
||||||
|
dataDateTime = LocalDateTime.parse(regionalWeatherData.getDataTime(), DATA_TIME_FORMATTER);
|
||||||
|
} catch (DateTimeParseException e) {
|
||||||
|
log.warn("解析 dataTime 失败: {}", regionalWeatherData.getDataTime());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (row.getStartTime().isBefore(dataDateTime) && dataDateTime.isBefore(row.getEndTime())) {
|
||||||
|
String key = districtCode + "|" + regionalWeatherData.getDataTime();
|
||||||
|
// 检查 Map 中是否已存在相同组合键
|
||||||
|
DnerHourlyPowerOutageEvent existing = toInsertMap.get(key);
|
||||||
|
if (existing == null) {
|
||||||
|
// 不存在,创建新实体并放入 Map
|
||||||
|
DnerHourlyPowerOutageEvent entity = buildHourlyEvent(row, districtCode, regionalWeatherData);
|
||||||
|
toInsertMap.put(key, entity);
|
||||||
|
} else {
|
||||||
|
// 已存在,执行累加逻辑
|
||||||
|
accumulateEvent(existing, row);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!toInsert.isEmpty()) {
|
if (!toInsertMap.isEmpty()) {
|
||||||
// 4. 批量入库
|
// 将 Map 中的 values 转为 List 进行批量插入
|
||||||
|
List<DnerHourlyPowerOutageEvent> toInsert = new ArrayList<>(toInsertMap.values());
|
||||||
dnerHourlyPowerOutageEventMapper.batchInsert(toInsert);
|
dnerHourlyPowerOutageEventMapper.batchInsert(toInsert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 累加已存在实体的字段
|
||||||
|
* @param existing 已存在的实体
|
||||||
|
* @param row 当前 Excel 行数据
|
||||||
|
*/
|
||||||
|
private void accumulateEvent(DnerHourlyPowerOutageEvent existing, DataExcelEntity row) {
|
||||||
|
existing.setUserCount(row.getUserCount() + existing.getUserCount());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载南网区划配置
|
* 加载南网区划配置
|
||||||
* **/
|
* **/
|
||||||
@ -155,31 +177,31 @@ public class HourlyOutageExcelProcessService {
|
|||||||
|
|
||||||
private DnerHourlyPowerOutageEvent buildHourlyEvent(DataExcelEntity row,
|
private DnerHourlyPowerOutageEvent buildHourlyEvent(DataExcelEntity row,
|
||||||
String districtCode,
|
String districtCode,
|
||||||
WeatherDataDTO weatherData) {
|
RegionalWeatherData regionalWeatherData) {
|
||||||
DnerHourlyPowerOutageEvent e = new DnerHourlyPowerOutageEvent();
|
DnerHourlyPowerOutageEvent event = new DnerHourlyPowerOutageEvent();
|
||||||
e.setOrgCode(districtCode);
|
event.setOrgCode(districtCode);
|
||||||
|
|
||||||
// 时间转成字符串,入库到 data_time
|
// 时间转成字符串,入库到 data_time
|
||||||
if (row.getStartTime() != null) {
|
if (row.getStartTime() != null) {
|
||||||
e.setDataTime(row.getStartTime().format(DB_DATETIME_STR));
|
event.setDataTime(regionalWeatherData.getDataTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Excel 本身的业务字段
|
// Excel 本身的业务字段
|
||||||
e.setUserCount(row.getUserCount());
|
event.setUserCount(row.getUserCount());
|
||||||
e.setOutageState(row.getOutageState());
|
event.setOutageState(row.getOutageState());
|
||||||
e.setOutageType(row.getOutageType());
|
event.setOutageType(row.getOutageType());
|
||||||
|
|
||||||
// 气象字段(如不存在数据可以为 null)
|
// 气象字段(如不存在数据可以为 null)
|
||||||
if (weatherData != null) {
|
if (regionalWeatherData != null) {
|
||||||
e.setTemperature(weatherData.getTemperature());
|
event.setTemperature(regionalWeatherData.getTemperature());
|
||||||
e.setHourlyMaxTemperature(weatherData.getHourlyMaxTemperature());
|
event.setHourlyMaxTemperature(regionalWeatherData.getHourlyMaxTemperature());
|
||||||
e.setHourlyMinTemperature(weatherData.getHourlyMinTemperature());
|
event.setHourlyMinTemperature(regionalWeatherData.getHourlyMinTemperature());
|
||||||
// e.setHourlyPrecipitation(weatherData.getHourlyPrecipitation());
|
event.setHourlyPrecipitation(regionalWeatherData.getHourlyPrecipitation());
|
||||||
e.setDailyPrecipitation(weatherData.getDailyPrecipitation());
|
event.setDailyPrecipitation(regionalWeatherData.getDailyPrecipitation());
|
||||||
e.setExtremeWindSpeedHourly(weatherData.getExtremeWindSpeedHourly());
|
event.setExtremeWindSpeedHourly(regionalWeatherData.getExtremeWindSpeedHourly());
|
||||||
}
|
}
|
||||||
|
|
||||||
// create_by/update_by 可根据当前登录用户等进行填充
|
// create_by/update_by 可根据当前登录用户等进行填充
|
||||||
return e;
|
return event;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,411 +0,0 @@
|
|||||||
package com.southern.power.grid.service.impl;
|
|
||||||
|
|
||||||
import com.southern.power.grid.dao.DnerHourlyPowerOutageEventMapper;
|
|
||||||
import com.southern.power.grid.dao.NwSiteAreaConfigurationMapper;
|
|
||||||
import com.southern.power.grid.dao.WeatherSiteAreaConfigurationMapper;
|
|
||||||
import com.southern.power.grid.entity.DnerHourlyPowerOutageEvent;
|
|
||||||
import com.southern.power.grid.entity.HourlyStatisticDTO;
|
|
||||||
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 com.southern.power.grid.utils.TimeUtil;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class HourlyStatisticService {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private NwSiteAreaConfigurationMapper nwSiteAreaConfigurationMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private WeatherSiteAreaConfigurationMapper weatherSiteAreaConfigurationMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private WeatherDataService weatherDataService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private DnerHourlyPowerOutageEventMapper dnerHourlyPowerOutageEventMapper;
|
|
||||||
|
|
||||||
private static final DateTimeFormatter TIME_POINT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00:00");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取分时统计全量数据(包含所有指标)
|
|
||||||
* @param areaType 区域类型:province-省,city-市,county-县
|
|
||||||
* @param areaCode 区域编码(省/市/县编码,县为org_code)
|
|
||||||
* @param startTime 开始时间(包含)
|
|
||||||
* @param endTime 结束时间(包含)
|
|
||||||
* @return 分时统计结果
|
|
||||||
*/
|
|
||||||
public HourlyStatisticDTO getHourlyStatistics(String areaType, String areaCode,
|
|
||||||
LocalDateTime startTime, LocalDateTime endTime) {
|
|
||||||
// 1. 生成时间点列表(整点)
|
|
||||||
List<LocalDateTime> timePoints = generateTimePoints(startTime, endTime);
|
|
||||||
if (timePoints.isEmpty()) {
|
|
||||||
return new HourlyStatisticDTO();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 根据区域类型获取需要统计的区县编码列表
|
|
||||||
List<String> districtCodes = getDistrictCodesByArea(areaType, areaCode);
|
|
||||||
if (districtCodes.isEmpty()) {
|
|
||||||
return new HourlyStatisticDTO();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 分别计算各指标
|
|
||||||
HourlyStatisticDTO result = new HourlyStatisticDTO();
|
|
||||||
result.setTimePoints(timePoints.stream().map(t -> t.format(TIME_POINT_FORMATTER)).collect(Collectors.toList()));
|
|
||||||
|
|
||||||
// 3.1 停电用户数(直接查分时停电事件表)
|
|
||||||
Map<LocalDateTime, Long> userCountMap = calculateUserCount(districtCodes, timePoints);
|
|
||||||
result.setUserCounts(fillList(timePoints, userCountMap, 0L));
|
|
||||||
|
|
||||||
// 3.2 降水量(需要多站点平均)
|
|
||||||
Map<LocalDateTime, Double> precipMap = calculatePrecipitation(districtCodes, timePoints);
|
|
||||||
result.setPrecipitations(fillList(timePoints, precipMap, 0.0));
|
|
||||||
|
|
||||||
// 3.3 气温(平均/最高/最低)
|
|
||||||
TemperatureResult tempResult = calculateTemperature(districtCodes, timePoints);
|
|
||||||
result.setAvgTemperatures(fillList(timePoints, tempResult.getAvgMap(), 0.0));
|
|
||||||
result.setMaxTemperatures(fillList(timePoints, tempResult.getMaxMap(), 0.0));
|
|
||||||
result.setMinTemperatures(fillList(timePoints, tempResult.getMinMap(), 0.0));
|
|
||||||
|
|
||||||
// 3.4 风速(极大值)
|
|
||||||
Map<LocalDateTime, Double> windMap = calculateWindSpeed(districtCodes, timePoints);
|
|
||||||
result.setMaxWindSpeeds(fillList(timePoints, windMap, 0.0));
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成整点时间序列(从startTime的整点开始,到endTime的整点结束,包含首尾)
|
|
||||||
*/
|
|
||||||
private List<LocalDateTime> generateTimePoints(LocalDateTime start, LocalDateTime end) {
|
|
||||||
List<LocalDateTime> points = new ArrayList<>();
|
|
||||||
LocalDateTime current = start.withMinute(0).withSecond(0).withNano(0);
|
|
||||||
LocalDateTime endPoint = end.withMinute(0).withSecond(0).withNano(0);
|
|
||||||
while (!current.isAfter(endPoint)) {
|
|
||||||
points.add(current);
|
|
||||||
current = current.plusHours(1);
|
|
||||||
}
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据区域类型获取所有需要统计的区县编码列表
|
|
||||||
*/
|
|
||||||
private List<String> getDistrictCodesByArea(String areaType, String areaCode) {
|
|
||||||
if ("county".equalsIgnoreCase(areaType)) {
|
|
||||||
return Collections.singletonList(areaCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询南网配置表,根据省/市编码获取所有区县编码
|
|
||||||
List<NwSiteAreaConfiguration> list;
|
|
||||||
if ("province".equalsIgnoreCase(areaType)) {
|
|
||||||
list = new ArrayList<>();// nwSiteAreaConfigurationMapper.selectByProvince(areaCode);
|
|
||||||
} else if ("city".equalsIgnoreCase(areaType)) {
|
|
||||||
list = new ArrayList<>(); // nwSiteAreaConfigurationMapper.selectByCity(areaCode);
|
|
||||||
} else {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(list)) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return list.stream()
|
|
||||||
.map(NwSiteAreaConfiguration::getDistrictCode)
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.distinct()
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===================== 停电用户数统计 =====================
|
|
||||||
private Map<LocalDateTime, Long> calculateUserCount(List<String> districtCodes, List<LocalDateTime> timePoints) {
|
|
||||||
// 查询所有区县在时间范围内的停电事件记录
|
|
||||||
List<DnerHourlyPowerOutageEvent> events = dnerHourlyPowerOutageEventMapper.selectByDistrictsAndTime(
|
|
||||||
districtCodes, timePoints.get(0), timePoints.get(timePoints.size() - 1).plusHours(1));
|
|
||||||
|
|
||||||
// 按区县和整点时刻聚合user_count
|
|
||||||
Map<LocalDateTime, Long> result = new HashMap<>();
|
|
||||||
for (LocalDateTime tp : timePoints) {
|
|
||||||
result.put(tp, 0L);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CollectionUtils.isEmpty(events)) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注意:data_time是停电开始时间,需按照“停电开始时间 > 整点时刻”的规则计入该整点
|
|
||||||
// 但我们表中没有结束时间,无法精确统计“正在停电中”,此处采用简化规则:按开始时间所在小时计入
|
|
||||||
// 若未来表添加end_time字段,可修改为更精确的逻辑
|
|
||||||
for (DnerHourlyPowerOutageEvent event : events) {
|
|
||||||
if (event.getDataTime() == null) continue;
|
|
||||||
LocalDateTime start = TimeUtil.parseToLocalDateTime(event.getDataTime()); // 需要工具类解析字符串
|
|
||||||
if (start == null) continue;
|
|
||||||
|
|
||||||
// 找到大于start的最小整点(即start所在的下一个整点)
|
|
||||||
LocalDateTime targetHour = start.withMinute(0).withSecond(0).withNano(0).plusHours(1);
|
|
||||||
if (result.containsKey(targetHour)) {
|
|
||||||
result.merge(targetHour, event.getUserCount() == null ? 0L : event.getUserCount().longValue(), Long::sum);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===================== 降水量统计(多站平均) =====================
|
|
||||||
private Map<LocalDateTime, Double> calculatePrecipitation(List<String> districtCodes, List<LocalDateTime> timePoints) {
|
|
||||||
// 1. 获取所有区县关联的气象站ID
|
|
||||||
List<String> stationIds = getStationIdsByDistricts(districtCodes);
|
|
||||||
if (stationIds.isEmpty()) {
|
|
||||||
return emptyMap(timePoints);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 批量获取所有站点的气象数据(按小时)
|
|
||||||
Map<String, Map<LocalDateTime, WeatherDataDTO>> stationDataMap = batchFetchWeatherData(stationIds, timePoints);
|
|
||||||
|
|
||||||
// 3. 按小时计算各县平均降水量
|
|
||||||
// 由于降水量县级规则是“国家站+区域站平均”,但我们有所有站的数据,需要先计算各县的平均值,再汇总
|
|
||||||
// 简化:直接对所有站的数据按小时取平均(因为最终市级还需要再平均,最终结果等价于所有站的平均)
|
|
||||||
// 但需求要求县级统计时是县级内平均,市级统计时是各县平均再平均,因此必须按县分组先计算平均值
|
|
||||||
// 此处我们实现为:先按县分组,每个小时取该县所有站的降水量平均值,得到各县小时降水量;然后所有县的小时降水量再平均(市级)或直接使用(县级)
|
|
||||||
// 但本方法返回值是总体结果,需要在调用前已经确定是县级还是市级,但调用时districtCodes已经是一个集合,方法需要返回这个集合整体的平均降水量。
|
|
||||||
// 因此:对每个小时,计算所有区县在该小时的平均降水量(即先计算每个县内所有站的平均,再对这些县的平均取平均)
|
|
||||||
return calculateAverageByDistrict(stationDataMap, districtCodes, timePoints,
|
|
||||||
WeatherDataDTO::getHourlyPrecipitation);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===================== 气温统计 =====================
|
|
||||||
private TemperatureResult calculateTemperature(List<String> districtCodes, List<LocalDateTime> timePoints) {
|
|
||||||
// 1. 获取所有区县关联的气象站ID
|
|
||||||
List<String> stationIds = getStationIdsByDistricts(districtCodes);
|
|
||||||
if (stationIds.isEmpty()) {
|
|
||||||
return new TemperatureResult(emptyMap(timePoints), emptyMap(timePoints), emptyMap(timePoints));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 获取所有站点的气象数据
|
|
||||||
Map<String, Map<LocalDateTime, WeatherDataDTO>> stationDataMap = batchFetchWeatherData(stationIds, timePoints);
|
|
||||||
|
|
||||||
// 3. 分别计算平均、最高、最低
|
|
||||||
Map<LocalDateTime, Double> avgMap = calculateAverageByDistrict(stationDataMap, districtCodes, timePoints,
|
|
||||||
d -> parseDouble(d.getTemperature()));
|
|
||||||
Map<LocalDateTime, Double> maxMap = calculateExtremeByDistrict(stationDataMap, districtCodes, timePoints,
|
|
||||||
d -> parseDouble(d.getHourlyMaxTemperature()), true);
|
|
||||||
Map<LocalDateTime, Double> minMap = calculateExtremeByDistrict(stationDataMap, districtCodes, timePoints,
|
|
||||||
d -> parseDouble(d.getHourlyMinTemperature()), false);
|
|
||||||
|
|
||||||
return new TemperatureResult(avgMap, maxMap, minMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===================== 风速统计(极大值) =====================
|
|
||||||
private Map<LocalDateTime, Double> calculateWindSpeed(List<String> districtCodes, List<LocalDateTime> timePoints) {
|
|
||||||
List<String> stationIds = getStationIdsByDistricts(districtCodes);
|
|
||||||
if (stationIds.isEmpty()) {
|
|
||||||
return emptyMap(timePoints);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, Map<LocalDateTime, WeatherDataDTO>> stationDataMap = batchFetchWeatherData(stationIds, timePoints);
|
|
||||||
|
|
||||||
// 风速规则:先取各县内所有站的最大值,再取所有县的最大值(市级)
|
|
||||||
return calculateExtremeByDistrict(stationDataMap, districtCodes, timePoints,
|
|
||||||
d -> parseDouble(d.getExtremeWindSpeedHourly()), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===================== 通用辅助方法 =====================
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据区县编码列表获取所有气象站ID(去重)
|
|
||||||
*/
|
|
||||||
private List<String> getStationIdsByDistricts(List<String> districtCodes) {
|
|
||||||
if (CollectionUtils.isEmpty(districtCodes)) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
List<WeatherSiteAreaConfiguration> configs = new ArrayList<>(); // new weatherSiteAreaConfigurationMapper.selectByDistrictCodes(districtCodes);
|
|
||||||
if (CollectionUtils.isEmpty(configs)) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return configs.stream()
|
|
||||||
.map(WeatherSiteAreaConfiguration::getStationId)
|
|
||||||
.filter(Objects::nonNull)
|
|
||||||
.distinct()
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量获取多个站点在多个时间点的气象数据
|
|
||||||
* @return Map<stationId, Map<小时, WeatherDataDTO>>
|
|
||||||
*/
|
|
||||||
private Map<String, Map<LocalDateTime, WeatherDataDTO>> batchFetchWeatherData(List<String> stationIds,
|
|
||||||
List<LocalDateTime> timePoints) {
|
|
||||||
Map<String, Map<LocalDateTime, WeatherDataDTO>> result = new HashMap<>();
|
|
||||||
for (String stationId : stationIds) {
|
|
||||||
Map<LocalDateTime, WeatherDataDTO> stationHourly = new HashMap<>();
|
|
||||||
for (LocalDateTime hour : timePoints) {
|
|
||||||
// WeatherDataDTO data = weatherDataService.getWeatherData(stationIds, hour);
|
|
||||||
// if (data != null) {
|
|
||||||
// stationHourly.put(hour, data);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
result.put(stationId, stationHourly);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算按县平均后的指标(先求每个县内所有站的平均,再对各县平均取平均)
|
|
||||||
* @param stationDataMap 站点原始数据
|
|
||||||
* @param districtCodes 区县列表
|
|
||||||
* @param timePoints 时间点
|
|
||||||
* @param valueExtractor 从WeatherDataDTO提取数值的函数
|
|
||||||
* @return 每个小时的平均值
|
|
||||||
*/
|
|
||||||
private Map<LocalDateTime, Double> calculateAverageByDistrict(Map<String, Map<LocalDateTime, WeatherDataDTO>> stationDataMap,
|
|
||||||
List<String> districtCodes,
|
|
||||||
List<LocalDateTime> timePoints,
|
|
||||||
Function<WeatherDataDTO, Double> valueExtractor) {
|
|
||||||
// 1. 建立区县 -> 站点ID列表的映射
|
|
||||||
Map<String, List<String>> districtStationMap = getDistrictStationMap(districtCodes);
|
|
||||||
|
|
||||||
Map<LocalDateTime, Double> result = new HashMap<>();
|
|
||||||
for (LocalDateTime hour : timePoints) {
|
|
||||||
List<Double> districtAverages = new ArrayList<>();
|
|
||||||
for (String districtCode : districtCodes) {
|
|
||||||
List<String> stations = districtStationMap.getOrDefault(districtCode, Collections.emptyList());
|
|
||||||
List<Double> values = new ArrayList<>();
|
|
||||||
for (String stationId : stations) {
|
|
||||||
WeatherDataDTO data = stationDataMap.getOrDefault(stationId, Collections.emptyMap()).get(hour);
|
|
||||||
Double val = valueExtractor.apply(data);
|
|
||||||
if (val != null) {
|
|
||||||
values.add(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!values.isEmpty()) {
|
|
||||||
double avg = values.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
|
|
||||||
districtAverages.add(avg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 所有县的平均再平均
|
|
||||||
if (!districtAverages.isEmpty()) {
|
|
||||||
double overallAvg = districtAverages.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
|
|
||||||
result.put(hour, overallAvg);
|
|
||||||
} else {
|
|
||||||
result.put(hour, 0.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算按县极值后的总体极值(先求每个县内所有站的极值,再取所有县的极值)
|
|
||||||
* @param isMax true-最大值,false-最小值
|
|
||||||
*/
|
|
||||||
private Map<LocalDateTime, Double> calculateExtremeByDistrict(Map<String, Map<LocalDateTime, WeatherDataDTO>> stationDataMap,
|
|
||||||
List<String> districtCodes,
|
|
||||||
List<LocalDateTime> timePoints,
|
|
||||||
Function<WeatherDataDTO, Double> valueExtractor,
|
|
||||||
boolean isMax) {
|
|
||||||
Map<String, List<String>> districtStationMap = getDistrictStationMap(districtCodes);
|
|
||||||
|
|
||||||
Map<LocalDateTime, Double> result = new HashMap<>();
|
|
||||||
for (LocalDateTime hour : timePoints) {
|
|
||||||
List<Double> districtExtremes = new ArrayList<>();
|
|
||||||
for (String districtCode : districtCodes) {
|
|
||||||
List<String> stations = districtStationMap.getOrDefault(districtCode, Collections.emptyList());
|
|
||||||
Double extreme = null;
|
|
||||||
for (String stationId : stations) {
|
|
||||||
WeatherDataDTO data = stationDataMap.getOrDefault(stationId, Collections.emptyMap()).get(hour);
|
|
||||||
Double val = valueExtractor.apply(data);
|
|
||||||
if (val != null) {
|
|
||||||
if (extreme == null) {
|
|
||||||
extreme = val;
|
|
||||||
} else if (isMax) {
|
|
||||||
extreme = Math.max(extreme, val);
|
|
||||||
} else {
|
|
||||||
extreme = Math.min(extreme, val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (extreme != null) {
|
|
||||||
districtExtremes.add(extreme);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 取所有县极值的极值
|
|
||||||
if (!districtExtremes.isEmpty()) {
|
|
||||||
double overall = isMax ?
|
|
||||||
districtExtremes.stream().mapToDouble(Double::doubleValue).max().orElse(0.0) :
|
|
||||||
districtExtremes.stream().mapToDouble(Double::doubleValue).min().orElse(0.0);
|
|
||||||
result.put(hour, overall);
|
|
||||||
} else {
|
|
||||||
result.put(hour, 0.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取区县到站点ID列表的映射
|
|
||||||
*/
|
|
||||||
private Map<String, List<String>> getDistrictStationMap(List<String> districtCodes) {
|
|
||||||
List<WeatherSiteAreaConfiguration> configs = new ArrayList<>(); // weatherSiteAreaConfigurationMapper.selectByDistrictCodes(districtCodes);
|
|
||||||
if (CollectionUtils.isEmpty(configs)) {
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
return configs.stream()
|
|
||||||
.filter(c -> c.getStationId() != null)
|
|
||||||
.collect(Collectors.groupingBy(WeatherSiteAreaConfiguration::getDistrictCode,
|
|
||||||
Collectors.mapping(WeatherSiteAreaConfiguration::getStationId, Collectors.toList())));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 填充列表,确保每个时间点都有值
|
|
||||||
*/
|
|
||||||
private <T> List<T> fillList(List<LocalDateTime> timePoints, Map<LocalDateTime, T> map, T defaultValue) {
|
|
||||||
List<T> list = new ArrayList<>();
|
|
||||||
for (LocalDateTime tp : timePoints) {
|
|
||||||
list.add(map.getOrDefault(tp, defaultValue));
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<LocalDateTime, Double> emptyMap(List<LocalDateTime> timePoints) {
|
|
||||||
Map<LocalDateTime, Double> map = new HashMap<>();
|
|
||||||
for (LocalDateTime tp : timePoints) {
|
|
||||||
map.put(tp, 0.0);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Double parseDouble(String str) {
|
|
||||||
try {
|
|
||||||
return str == null ? null : Double.parseDouble(str);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 内部类,用于返回气温的三个Map
|
|
||||||
private static class TemperatureResult {
|
|
||||||
private final Map<LocalDateTime, Double> avgMap;
|
|
||||||
private final Map<LocalDateTime, Double> maxMap;
|
|
||||||
private final Map<LocalDateTime, Double> minMap;
|
|
||||||
|
|
||||||
public TemperatureResult(Map<LocalDateTime, Double> avgMap,
|
|
||||||
Map<LocalDateTime, Double> maxMap,
|
|
||||||
Map<LocalDateTime, Double> minMap) {
|
|
||||||
this.avgMap = avgMap;
|
|
||||||
this.maxMap = maxMap;
|
|
||||||
this.minMap = minMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<LocalDateTime, Double> getAvgMap() { return avgMap; }
|
|
||||||
public Map<LocalDateTime, Double> getMaxMap() { return maxMap; }
|
|
||||||
public Map<LocalDateTime, Double> getMinMap() { return minMap; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -4,5 +4,82 @@
|
|||||||
|
|
||||||
<!-- namespace 必须 = Mapper 接口全类名 -->
|
<!-- namespace 必须 = Mapper 接口全类名 -->
|
||||||
<mapper namespace="com.southern.power.grid.dao.RegionalWeatherDataMapper">
|
<mapper namespace="com.southern.power.grid.dao.RegionalWeatherDataMapper">
|
||||||
|
<resultMap id="BaseResultMap" type="com.southern.power.grid.entity.RegionalWeatherData">
|
||||||
|
<id column="id" property="id" jdbcType="BIGINT"/>
|
||||||
|
<result column="org_code" property="orgCode" jdbcType="VARCHAR"/>
|
||||||
|
<result column="data_time" property="dataTime" jdbcType="VARCHAR"/>
|
||||||
|
<result column="hourly_precipitation" property="hourlyPrecipitation" jdbcType="VARCHAR"/>
|
||||||
|
<result column="daily_precipitation" property="dailyPrecipitation" jdbcType="VARCHAR"/>
|
||||||
|
<result column="temperature" property="temperature" jdbcType="VARCHAR"/>
|
||||||
|
<result column="hourly_max_temperature" property="hourlyMaxTemperature" jdbcType="VARCHAR"/>
|
||||||
|
<result column="hourly_min_temperature" property="hourlyMinTemperature" jdbcType="VARCHAR"/>
|
||||||
|
<result column="extreme_wind_speed_hourly" property="extremeWindSpeedHourly" jdbcType="VARCHAR"/>
|
||||||
|
<result column="create_by" property="createBy" jdbcType="VARCHAR"/>
|
||||||
|
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
|
||||||
|
<result column="update_by" property="updateBy" jdbcType="VARCHAR"/>
|
||||||
|
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
id, org_code, data_time, hourly_precipitation, daily_precipitation, temperature,
|
||||||
|
hourly_max_temperature, hourly_min_temperature, extreme_wind_speed_hourly,
|
||||||
|
create_by, create_time, update_by, update_time
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<!-- 插入语句:忽略主键id(自增),create_time/update_time由数据库默认生成 -->
|
||||||
|
<insert id="insert" parameterType="com.southern.power.grid.entity.RegionalWeatherData" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
INSERT INTO regional_weather_data (
|
||||||
|
org_code, data_time, hourly_precipitation, daily_precipitation,
|
||||||
|
temperature, hourly_max_temperature, hourly_min_temperature,
|
||||||
|
extreme_wind_speed_hourly, create_by, update_by
|
||||||
|
) VALUES (
|
||||||
|
#{orgCode, jdbcType=VARCHAR},
|
||||||
|
#{dataTime, jdbcType=VARCHAR},
|
||||||
|
#{hourlyPrecipitation, jdbcType=VARCHAR},
|
||||||
|
#{dailyPrecipitation, jdbcType=VARCHAR},
|
||||||
|
#{temperature, jdbcType=VARCHAR},
|
||||||
|
#{hourlyMaxTemperature, jdbcType=VARCHAR},
|
||||||
|
#{hourlyMinTemperature, jdbcType=VARCHAR},
|
||||||
|
#{extremeWindSpeedHourly, jdbcType=VARCHAR},
|
||||||
|
#{createBy, jdbcType=VARCHAR},
|
||||||
|
#{updateBy, jdbcType=VARCHAR}
|
||||||
|
)
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<!-- 根据主键查询 -->
|
||||||
|
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM regional_weather_data
|
||||||
|
WHERE id = #{id, jdbcType=BIGINT}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 根据地区编码和资料时次查询 -->
|
||||||
|
<select id="selectByOrgCodeAndDataTime" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM regional_weather_data
|
||||||
|
WHERE org_code = #{orgCode, jdbcType=VARCHAR}
|
||||||
|
AND data_time >= #{dataTime, jdbcType=VARCHAR}
|
||||||
|
ORDER BY data_time ASC
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 动态条件查询 -->
|
||||||
|
<select id="selectByCondition" parameterType="java.util.Map" resultMap="BaseResultMap">
|
||||||
|
SELECT <include refid="Base_Column_List"/>
|
||||||
|
FROM regional_weather_data
|
||||||
|
<where>
|
||||||
|
<if test="orgCode != null and orgCode != ''">
|
||||||
|
AND org_code = #{orgCode, jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="dataTime != null and dataTime != ''">
|
||||||
|
AND data_time = #{dataTime, jdbcType=VARCHAR}
|
||||||
|
</if>
|
||||||
|
<if test="startCreateTime != null and startCreateTime != ''">
|
||||||
|
AND create_time >= #{startCreateTime, jdbcType=TIMESTAMP}
|
||||||
|
</if>
|
||||||
|
<if test="endCreateTime != null and endCreateTime != ''">
|
||||||
|
AND create_time <= #{endCreateTime, jdbcType=TIMESTAMP}
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
ORDER BY create_time DESC
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
Loading…
x
Reference in New Issue
Block a user