diff --git a/pom.xml b/pom.xml
index 4244e94..1cfa029 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,6 +58,20 @@
true
+
+
+ com.alibaba.fastjson2
+ fastjson2
+ 2.0.48
+
+
+
+
+ com.alibaba
+ easyexcel
+ 3.3.2
+
+
org.springframework.boot
diff --git a/src/main/java/com/southern/power/grid/SouthernPowerGridApplication.java b/src/main/java/com/southern/power/grid/SouthernPowerGridApplication.java
index a4d72c7..a672c7b 100644
--- a/src/main/java/com/southern/power/grid/SouthernPowerGridApplication.java
+++ b/src/main/java/com/southern/power/grid/SouthernPowerGridApplication.java
@@ -2,6 +2,7 @@ package com.southern.power.grid;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
/**
* MyBatis-Plus测试应用启动类
@@ -9,6 +10,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* @author jinshan
*/
@SpringBootApplication
+@EnableAsync
public class SouthernPowerGridApplication {
public static void main(String[] args) {
diff --git a/src/main/java/com/southern/power/grid/controller/AiMessageController.java b/src/main/java/com/southern/power/grid/controller/AiMessageController.java
index 4c66ae6..5e3b0e9 100644
--- a/src/main/java/com/southern/power/grid/controller/AiMessageController.java
+++ b/src/main/java/com/southern/power/grid/controller/AiMessageController.java
@@ -1,16 +1,16 @@
package com.southern.power.grid.controller;
+import com.alibaba.fastjson2.JSONObject;
+
import com.southern.power.grid.common.Result;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ContentDisposition;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
-import javax.servlet.http.HttpServletResponse;
-import java.io.InputStream;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
@@ -32,5 +32,27 @@ public class AiMessageController {
log.info("download report");
return Result.success(Boolean.TRUE);
}
+
+ /**
+ * K线图Demo数据返回
+ *
+ * @return K线图数据
+ */
+ @GetMapping("/query")
+ public Result queryData() {
+ JSONObject jsonObject = null;
+ try {
+ // 1. 定位文件(resources/testData/data.json)
+ ClassPathResource resource = new ClassPathResource("testData\\data.json");
+
+ // 2. 读取文件内容为字符串(Spring工具类,无需手动流关闭)
+ byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream());
+ String jsonStr = new String(bytes, StandardCharsets.UTF_8);
+ jsonObject = JSONObject.parseObject(jsonStr);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return Result.success(jsonObject);
+ }
}
diff --git a/src/main/java/com/southern/power/grid/controller/DnerController.java b/src/main/java/com/southern/power/grid/controller/DnerController.java
new file mode 100644
index 0000000..1a8bed2
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/controller/DnerController.java
@@ -0,0 +1,92 @@
+package com.southern.power.grid.controller;
+
+import com.alibaba.excel.EasyExcel;
+import com.southern.power.grid.common.Result;
+import com.southern.power.grid.entity.*;
+import com.southern.power.grid.listener.DataExcelListener;
+import com.southern.power.grid.service.IDnerDailyPowerOutageEventService;
+import com.southern.power.grid.service.IDnerHourlyPowerOutageEventService;
+import com.southern.power.grid.service.IDnerSiteAreaConfigurationService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.InputStream;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * 配网抢修-Controller
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@RestController
+@RequestMapping("/api/v1/dner")
+@Slf4j
+public class DnerController {
+ @Autowired
+ private DataExcelListener dataExcelListener;
+
+ @Autowired
+ private IDnerHourlyPowerOutageEventService dnerHourlyPowerOutageEventService;
+
+ @Autowired
+ private IDnerDailyPowerOutageEventService dnerDailyPowerOutageEventService;
+
+ @Autowired
+ private IDnerSiteAreaConfigurationService dnerSiteAreaConfigurationService;
+
+ @PostMapping("/area-tree/query")
+ public Result> queryAreaTree(@RequestBody AreaTreeReq req) {
+ // TODO 使用POST请求,后续新增高级筛选时,加入请求入参
+ return Result.success(dnerSiteAreaConfigurationService.queryAreaTree());
+ }
+
+ /**
+ * 分时图数据查询
+ *
+ * @param orgCode 地区编码
+ * @param startDate 开始时间
+ * @param endDate 结束时间
+ * @return 返回结果
+ */
+ @GetMapping("/intraday/query")
+ public Result queryIntradayData(@RequestParam String orgCode,
+ @RequestParam String startDate,
+ @RequestParam String endDate) {
+ return Result.success(dnerHourlyPowerOutageEventService.queryIntradayData(orgCode, startDate, endDate));
+ }
+
+
+ /**
+ * K线数据查询
+ *
+ * @param orgCode 地区编码
+ * @param startDate 开始时间
+ * @param endDate 结束时间
+ * @return 返回结果
+ */
+ @GetMapping("/kline/query")
+ public Result queryKlineData(@RequestParam String orgCode,
+ @RequestParam String startDate,
+ @RequestParam String endDate) {
+ return Result.success(dnerDailyPowerOutageEventService.queryKlineData(orgCode, startDate, endDate));
+ }
+
+ /**
+ * 通过easyexcel流式读取导入数据
+ *
+ * @param inputStream 文件流
+ * @return 返回结果
+ */
+ @PostMapping("/excel/import")
+ public Result importExcel(@RequestParam("file") InputStream inputStream) {
+ // 采用easyExcel流式读取,一行一行读,不加载整个excel文件,防止OOM
+ EasyExcel.read(inputStream, DataExcelEntity.class, dataExcelListener)
+ .sheet()
+ .doRead();
+ return Result.success(Boolean.TRUE);
+ }
+}
diff --git a/src/main/java/com/southern/power/grid/dao/DataExcelMapper.java b/src/main/java/com/southern/power/grid/dao/DataExcelMapper.java
new file mode 100644
index 0000000..fb90719
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/dao/DataExcelMapper.java
@@ -0,0 +1,18 @@
+package com.southern.power.grid.dao;
+
+import com.southern.power.grid.entity.DataExcelEntity;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * excel数据-mapper类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Mapper
+public interface DataExcelMapper {
+ void batchInsert(@Param("list") List list);
+}
diff --git a/src/main/java/com/southern/power/grid/dao/DnerDailyPowerOutageEventMapper.java b/src/main/java/com/southern/power/grid/dao/DnerDailyPowerOutageEventMapper.java
new file mode 100644
index 0000000..ef482ff
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/dao/DnerDailyPowerOutageEventMapper.java
@@ -0,0 +1,21 @@
+package com.southern.power.grid.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.southern.power.grid.entity.DnerDailyPowerOutageEvent;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 日K线停电事件 -- mapper类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Mapper
+public interface DnerDailyPowerOutageEventMapper extends BaseMapper {
+ List selectListByConditions(@Param("orgCode") String orgCode,
+ @Param("startDate") String startDate,
+ @Param("endDate") String endDate);
+}
diff --git a/src/main/java/com/southern/power/grid/dao/DnerHourlyPowerOutageEventMapper.java b/src/main/java/com/southern/power/grid/dao/DnerHourlyPowerOutageEventMapper.java
new file mode 100644
index 0000000..bd2bed1
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/dao/DnerHourlyPowerOutageEventMapper.java
@@ -0,0 +1,21 @@
+package com.southern.power.grid.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.southern.power.grid.entity.DnerHourlyPowerOutageEvent;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 分时停电事件 -- mapper类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Mapper
+public interface DnerHourlyPowerOutageEventMapper extends BaseMapper {
+ List selectListByConditions(@Param("orgCode") String orgCode,
+ @Param("startDate") String startDate,
+ @Param("endDate") String endDate);
+}
diff --git a/src/main/java/com/southern/power/grid/dao/DnerSiteAreaConfigurationMapper.java b/src/main/java/com/southern/power/grid/dao/DnerSiteAreaConfigurationMapper.java
new file mode 100644
index 0000000..8f7c855
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/dao/DnerSiteAreaConfigurationMapper.java
@@ -0,0 +1,16 @@
+package com.southern.power.grid.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.southern.power.grid.entity.DnerSiteAreaConfiguration;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 行政区划配置表 -- mapper类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Mapper
+public interface DnerSiteAreaConfigurationMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/southern/power/grid/dao/NationalWeatherStationMapper.java b/src/main/java/com/southern/power/grid/dao/NationalWeatherStationMapper.java
new file mode 100644
index 0000000..7b6ef42
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/dao/NationalWeatherStationMapper.java
@@ -0,0 +1,15 @@
+package com.southern.power.grid.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.southern.power.grid.entity.NationalWeatherStation;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 国家气象站 -- mapper类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Mapper
+public interface NationalWeatherStationMapper extends BaseMapper {
+}
diff --git a/src/main/java/com/southern/power/grid/dao/NwSiteAreaConfigurationMapper.java b/src/main/java/com/southern/power/grid/dao/NwSiteAreaConfigurationMapper.java
new file mode 100644
index 0000000..556c6af
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/dao/NwSiteAreaConfigurationMapper.java
@@ -0,0 +1,16 @@
+package com.southern.power.grid.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.southern.power.grid.entity.NwSiteAreaConfiguration;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 南网区划配置表 Mapper接口
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/14
+ **/
+@Mapper
+public interface NwSiteAreaConfigurationMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/southern/power/grid/dao/RegionalWeatherStationMapper.java b/src/main/java/com/southern/power/grid/dao/RegionalWeatherStationMapper.java
new file mode 100644
index 0000000..d8c4be7
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/dao/RegionalWeatherStationMapper.java
@@ -0,0 +1,15 @@
+package com.southern.power.grid.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.southern.power.grid.entity.RegionalWeatherStation;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 区域气象站 -- mapper类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Mapper
+public interface RegionalWeatherStationMapper extends BaseMapper {
+}
diff --git a/src/main/java/com/southern/power/grid/dao/WeatherSiteAreaConfigurationMapper.java b/src/main/java/com/southern/power/grid/dao/WeatherSiteAreaConfigurationMapper.java
new file mode 100644
index 0000000..12348fd
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/dao/WeatherSiteAreaConfigurationMapper.java
@@ -0,0 +1,16 @@
+package com.southern.power.grid.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.southern.power.grid.entity.WeatherSiteAreaConfiguration;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 气象区划配置表 Mapper 接口
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/14
+ **/
+@Mapper
+public interface WeatherSiteAreaConfigurationMapper extends BaseMapper {
+
+}
diff --git a/src/main/java/com/southern/power/grid/entity/AreaTreeReq.java b/src/main/java/com/southern/power/grid/entity/AreaTreeReq.java
new file mode 100644
index 0000000..4de8824
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/entity/AreaTreeReq.java
@@ -0,0 +1,14 @@
+package com.southern.power.grid.entity;
+
+import lombok.Data;
+
+/**
+ * 区域树请求入参
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/16
+ **/
+@Data
+public class AreaTreeReq {
+
+}
diff --git a/src/main/java/com/southern/power/grid/entity/AreaTreeVO.java b/src/main/java/com/southern/power/grid/entity/AreaTreeVO.java
new file mode 100644
index 0000000..308a6db
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/entity/AreaTreeVO.java
@@ -0,0 +1,18 @@
+package com.southern.power.grid.entity;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 地区树
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/14
+ **/
+@Data
+public class AreaTreeVO {
+ String label;
+ String value;
+ List children;
+}
diff --git a/src/main/java/com/southern/power/grid/entity/DailyPowerOutageEventVO.java b/src/main/java/com/southern/power/grid/entity/DailyPowerOutageEventVO.java
new file mode 100644
index 0000000..3dc5457
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/entity/DailyPowerOutageEventVO.java
@@ -0,0 +1,59 @@
+package com.southern.power.grid.entity;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * TODO
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/14
+ **/
+@Data
+public class DailyPowerOutageEventVO {
+ /**
+ * 日期列表
+ */
+ private List fullDates;
+
+ /**
+ * K线数组,每一项包含起始值、结束值、最低、最高
+ */
+ private List> kline;
+
+ /**
+ * 近5/10/20/30日其下各县区23时停电用户数累加/县数量
+ */
+ private List ma5;
+ private List ma10;
+ private List ma20;
+ private List ma30;
+
+ /**
+ * 日累计降雨量
+ */
+ private List cumulativeRain;
+
+ /**
+ * 平均降雨量
+ */
+ private List avgRain;
+
+ /**
+ * 平均气温
+ */
+ private List avgTemp;
+
+ /**
+ * 最大气温
+ */
+ private List maxTemp;
+
+ /**
+ * 最低气温
+ */
+ private List minTemp;
+
+
+}
diff --git a/src/main/java/com/southern/power/grid/entity/DataExcelEntity.java b/src/main/java/com/southern/power/grid/entity/DataExcelEntity.java
new file mode 100644
index 0000000..777024f
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/entity/DataExcelEntity.java
@@ -0,0 +1,16 @@
+package com.southern.power.grid.entity;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * TODO excel导入待完善
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Data
+public class DataExcelEntity {
+ @ExcelProperty(index = 0, value = "省份")
+ private String province;
+}
diff --git a/src/main/java/com/southern/power/grid/entity/DnerDailyPowerOutageEvent.java b/src/main/java/com/southern/power/grid/entity/DnerDailyPowerOutageEvent.java
new file mode 100644
index 0000000..af0ac8d
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/entity/DnerDailyPowerOutageEvent.java
@@ -0,0 +1,120 @@
+package com.southern.power.grid.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 日K线停电事件 -- 实体
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Data
+@TableName("dner_daily_power_outage_event")
+public class DnerDailyPowerOutageEvent {
+
+ /**
+ * 主键ID
+ */
+ @TableId(type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 地区编码
+ */
+ private String orgCode;
+
+ /**
+ * 资料日期
+ */
+ private String dataTime;
+
+ /**
+ * 小时降水量
+ */
+ private String hourlyPrecipitation;
+
+ /**
+ * 日累计降水量
+ */
+ private String dailyPrecipitation;
+
+ /**
+ * 气温
+ */
+ private String temperature;
+
+ /**
+ * 日内最高气温
+ */
+ private String hourlyMaxTemperature;
+
+ /**
+ * 日内最低气温
+ */
+ private String hourlyMinTemperature;
+
+ /**
+ * 日内极大风速
+ */
+ private String extremeWindSpeedHourly;
+
+ /**
+ * 停电影响用户总数
+ */
+ private Integer userCount;
+
+ /**
+ * 起始影响用户总数
+ */
+ private Integer starUserCount;
+
+ /**
+ * 结束影响用户总数
+ */
+ private Integer endUserCount;
+
+ /**
+ * 最低停电影响用户总数
+ */
+ private Integer minUserCount;
+
+ /**
+ * 最高停电影响用户总数
+ */
+ private Integer maxUserCount;
+
+ /**
+ * 停电状态(1-待停电;2-停电中;3-已复电)
+ */
+ private Integer outageState;
+
+ /**
+ * 停电类型(1-故障类;2-计划类)
+ */
+ private Integer outageType;
+
+ /**
+ * 创建人
+ */
+ private String createBy;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+
+ /**
+ * 修改人
+ */
+ private String updateBy;
+
+ /**
+ * 修改时间
+ */
+ private LocalDateTime updateTime;
+}
diff --git a/src/main/java/com/southern/power/grid/entity/DnerHourlyPowerOutageEvent.java b/src/main/java/com/southern/power/grid/entity/DnerHourlyPowerOutageEvent.java
new file mode 100644
index 0000000..159bd75
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/entity/DnerHourlyPowerOutageEvent.java
@@ -0,0 +1,100 @@
+package com.southern.power.grid.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 分时停电事件 -- 实体类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Data
+@TableName("dner_hourly_power_outage_event")
+public class DnerHourlyPowerOutageEvent {
+
+ /**
+ * 主键ID
+ */
+ @TableId(type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 地区编码
+ */
+ private String orgCode;
+
+ /**
+ * 资料时次
+ */
+ private String dataTime;
+
+ /**
+ * 小时降水量
+ */
+ private String hourlyPrecipitation;
+
+ /**
+ * 日累计降水量
+ */
+ private String dailyPrecipitation;
+
+ /**
+ * 气温
+ */
+ private String temperature;
+
+ /**
+ * 小时内最高气温
+ */
+ private String hourlyMaxTemperature;
+
+ /**
+ * 小时内最低气温
+ */
+ private String hourlyMinTemperature;
+
+ /**
+ * 小时内极大风速
+ */
+ private String extremeWindSpeedHourly;
+
+ /**
+ * 停电影响用户总数
+ */
+ private Integer userCount;
+
+ /**
+ * 停电状态(1-待停电;2-停电中;3-已复电)
+ */
+ private Integer outageState;
+
+ /**
+ * 停电类型(1-故障类;2-计划类)
+ */
+ private Integer outageType;
+
+ /**
+ * 创建人
+ */
+ private String createBy;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+
+ /**
+ * 修改人
+ */
+ private String updateBy;
+
+ /**
+ * 修改时间
+ */
+ private LocalDateTime updateTime;
+}
diff --git a/src/main/java/com/southern/power/grid/entity/DnerSiteAreaConfiguration.java b/src/main/java/com/southern/power/grid/entity/DnerSiteAreaConfiguration.java
new file mode 100644
index 0000000..3f7780c
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/entity/DnerSiteAreaConfiguration.java
@@ -0,0 +1,75 @@
+package com.southern.power.grid.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 行政区划配置表
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Data
+@TableName("dner_site_area_configuration")
+public class DnerSiteAreaConfiguration {
+
+ /**
+ * 主键ID
+ */
+ @TableId(type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 省份
+ */
+ private String province;
+
+ /**
+ * 省份编码
+ */
+ private String provinceCode;
+
+ /**
+ * 地市
+ */
+ private String city;
+
+ /**
+ * 地市编码
+ */
+ private String cityCode;
+
+ /**
+ * 区县
+ */
+ private String district;
+
+ /**
+ * 地区编码
+ */
+ private String districtCode;
+
+ /**
+ * 创建人
+ */
+ private String createBy;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+
+ /**
+ * 修改人
+ */
+ private String updateBy;
+
+ /**
+ * 修改时间
+ */
+ private LocalDateTime updateTime;
+}
diff --git a/src/main/java/com/southern/power/grid/entity/HourlyPowerOutageEventChartVO.java b/src/main/java/com/southern/power/grid/entity/HourlyPowerOutageEventChartVO.java
new file mode 100644
index 0000000..b358011
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/entity/HourlyPowerOutageEventChartVO.java
@@ -0,0 +1,49 @@
+package com.southern.power.grid.entity;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 分时图数据
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/14
+ **/
+@Data
+public class HourlyPowerOutageEventChartVO {
+ /**
+ * 日期列表
+ */
+ private List dateList;
+
+ /**
+ * 停电影响用户总数
+ */
+ private List powerOutageUserCountList;
+
+ /**
+ * 平均气温
+ */
+ private List avgTemList;
+
+ /**
+ * 小时最大气温
+ */
+ private List maxTemList;
+
+ /**
+ * 小时最低气温
+ */
+ private List minTemList;
+
+ /**
+ * 小时降雨量
+ */
+ private List precList;
+
+ /**
+ * 小时极大风速
+ */
+ private List windList;
+}
diff --git a/src/main/java/com/southern/power/grid/entity/NationalWeatherStation.java b/src/main/java/com/southern/power/grid/entity/NationalWeatherStation.java
new file mode 100644
index 0000000..d74c2a0
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/entity/NationalWeatherStation.java
@@ -0,0 +1,57 @@
+package com.southern.power.grid.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 国家气象站 -- 实体
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Data
+@TableName("national_weather_station")
+public class NationalWeatherStation {
+
+ @TableId(type = IdType.AUTO)
+ private Integer id;
+
+ private String dataTime; // 资料时次
+ private String stationId; // 自动站站号
+ private String stationName; // 站名
+ private String stationPressure; // 本站气压
+ private String hourlyMaxPressure; // 小时内最高本站气压
+ private String hourlyMinPressure; // 小时内最低本站气压
+ private String temperature; // 气温
+ private String hourlyMaxTemperature; // 小时内最高气温
+ private String hourlyMinTemperature; // 小时内最低气温
+ private String dewPointTemperature; // 露点温度
+ private String relativeHumidity; // 相对湿度
+ private String waterVaporPressure; // 水汽压
+ private String hourlyPrecipitation; // 小时降水量
+ private String dailyPrecipitation; // 日累计降水量
+ private String windDirection2min; // 2分钟风向
+ private String windSpeed2min; // 2分钟平均风速
+ private String windDirection10min; // 10分钟风向
+ private String windSpeed10min; // 10分钟平均风速
+ private String maxWindDirectionHourly; // 小时内最大风速的风向
+ private String maxWindSpeedHourly; // 小时内最大风速
+ private String instantaneousWindDirection;// 瞬时风向
+ private String instantaneousWindSpeed; // 瞬时风速
+ private String extremeWindDirectionHourly;// 小时内极大风速的风向
+ private String extremeWindSpeedHourly; // 小时内极大风速
+ private String extremeWindTimeHourly; // 小时内极大风速出现时间
+ private String minVisibilityHourly; // 小时内最小能见度
+ private String province; // 所属省份
+ private String city; // 所属地市
+ private String district; // 所属区县
+ private String latitude; // 纬度
+ private String longitude; // 经度
+ private String altitude; // 海拔高度
+ private String createTime; // 创建时间
+ private LocalDateTime importTime; // 导入时间
+}
diff --git a/src/main/java/com/southern/power/grid/entity/NwSiteAreaConfiguration.java b/src/main/java/com/southern/power/grid/entity/NwSiteAreaConfiguration.java
new file mode 100644
index 0000000..66da0ac
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/entity/NwSiteAreaConfiguration.java
@@ -0,0 +1,65 @@
+package com.southern.power.grid.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 南网区划配置表
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/14
+ **/
+@Data
+@TableName("nw_site_area_configuration")
+public class NwSiteAreaConfiguration {
+
+ /**
+ * 主键ID
+ */
+ @TableId(type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 地区编码
+ */
+ private String districtCode;
+
+ /**
+ * 南网省
+ */
+ private String nwProvince;
+
+ /**
+ * 南网地市局
+ */
+ private String nwCity;
+
+ /**
+ * 南网区县局
+ */
+ private String nwDistrict;
+
+ /**
+ * 创建人
+ */
+ private String createBy;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+
+ /**
+ * 修改人
+ */
+ private String updateBy;
+
+ /**
+ * 修改时间
+ */
+ private LocalDateTime updateTime;
+}
diff --git a/src/main/java/com/southern/power/grid/entity/RegionalWeatherStation.java b/src/main/java/com/southern/power/grid/entity/RegionalWeatherStation.java
new file mode 100644
index 0000000..4782d8a
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/entity/RegionalWeatherStation.java
@@ -0,0 +1,56 @@
+package com.southern.power.grid.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 区域气象站
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Data
+@TableName("regional_weather_station")
+public class RegionalWeatherStation {
+
+ @TableId(type = IdType.AUTO)
+ private Integer id;
+
+ private String dataTime; // 资料时次
+ private String stationId; // 自动站站号
+ private String stationName; // 站名
+ private String stationPressure; // 本站气压
+ private String hourlyMaxPressure; // 小时内最高本站气压
+ private String hourlyMinPressure; // 小时内最低本站气压
+ private String temperature; // 气温
+ private String hourlyMaxTemperature; // 小时内最高气温
+ private String hourlyMinTemperature; // 小时内最低气温
+ private String dewPointTemperature; // 露点温度
+ private String relativeHumidity; // 相对湿度
+ private String hourlyPrecipitation; // 小时降水量
+ private String dailyPrecipitation; // 日累计降水量
+ private String windDirection2min; // 2分钟风向
+ private String windSpeed2min; // 2分钟平均风速
+ private String windDirection10min; // 10分钟风向
+ private String windSpeed10min; // 10分钟平均风速
+ private String maxWindDirectionHourly; // 小时内最大风速的风向
+ private String maxWindSpeedHourly; // 小时内最大风速
+ private String instantaneousWindDirection;// 瞬时风向
+ private String instantaneousWindSpeed; // 瞬时风速
+ private String extremeWindDirectionHourly;// 小时内极大风速的风向
+ private String extremeWindSpeedHourly; // 小时内极大风速
+ private String extremeWindTimeHourly; // 小时内极大风速出现时间
+ private String minVisibilityHourly; // 小时内最小能见度
+ private String province; // 所属省份
+ private String city; // 所属地市
+ private String district; // 所属区县
+ private String latitude; // 纬度
+ private String longitude; // 经度
+ private String altitude; // 海拔高度
+ private String createTime; // 创建时间
+ private LocalDateTime importTime; // 导入时间
+}
diff --git a/src/main/java/com/southern/power/grid/entity/WeatherSiteAreaConfiguration.java b/src/main/java/com/southern/power/grid/entity/WeatherSiteAreaConfiguration.java
new file mode 100644
index 0000000..b96f361
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/entity/WeatherSiteAreaConfiguration.java
@@ -0,0 +1,75 @@
+package com.southern.power.grid.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 气象区划配置表 实体类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/14
+ **/
+@Data
+@TableName("weather_site_area_configuration")
+public class WeatherSiteAreaConfiguration {
+
+ /**
+ * 主键ID
+ */
+ @TableId(type = IdType.AUTO)
+ private Long id;
+
+ /**
+ * 地区编码
+ */
+ private String districtCode;
+
+ /**
+ * 气象所属省份
+ */
+ private String weatherProvince;
+
+ /**
+ * 气象所属地市
+ */
+ private String weatherCity;
+
+ /**
+ * 气象所属区县
+ */
+ private String weatherDistrict;
+
+ /**
+ * 自动站站号
+ */
+ private String stationId;
+
+ /**
+ * 气象站名
+ */
+ private String stationName;
+
+ /**
+ * 创建人
+ */
+ private String createBy;
+
+ /**
+ * 创建时间
+ */
+ private LocalDateTime createTime;
+
+ /**
+ * 修改人
+ */
+ private String updateBy;
+
+ /**
+ * 修改时间
+ */
+ private LocalDateTime updateTime;
+}
diff --git a/src/main/java/com/southern/power/grid/listener/DataExcelListener.java b/src/main/java/com/southern/power/grid/listener/DataExcelListener.java
new file mode 100644
index 0000000..e75f100
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/listener/DataExcelListener.java
@@ -0,0 +1,86 @@
+package com.southern.power.grid.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.southern.power.grid.dao.DataExcelMapper;
+import com.southern.power.grid.entity.DataExcelEntity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.support.DefaultTransactionDefinition;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 数据导入逻辑 -- easyexcel事件监听器
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Component
+public class DataExcelListener extends AnalysisEventListener {
+
+ // 每批次大小
+ private static final int BATCH_SIZE = 500;
+
+ // 缓存数据
+ private List cacheList = new ArrayList<>(BATCH_SIZE);
+
+ @Autowired
+ // 注入 Mapper
+ private final DataExcelMapper dataExcelMapper;
+
+ @Autowired
+ // 手动事务管理器
+ private final PlatformTransactionManager transactionManager;
+
+ // 构造方法 -- 交给spring容器创建
+ public DataExcelListener(DataExcelMapper dataExcelMapper, PlatformTransactionManager transactionManager) {
+ this.dataExcelMapper = dataExcelMapper;
+ this.transactionManager = transactionManager;
+ }
+
+ // 逐行读取(不会OOM)
+ @Override
+ public void invoke(DataExcelEntity data, AnalysisContext context) {
+ //TODO 待完善 等志明拿到具体数据再导入到数据库中
+ cacheList.add(data);
+ // 达到批次数量 → 插入数据库
+ if (cacheList.size() >= BATCH_SIZE) {
+ batchInsert();
+ }
+ }
+
+ // 读取完毕 → 插入剩余数据
+ @Override
+ public void doAfterAllAnalysed(AnalysisContext context) {
+ if (!cacheList.isEmpty()) {
+ batchInsert();
+ }
+ }
+
+ // ==================== 核心:分批插入 + 手动事务 ====================
+ private void batchInsert() {
+ // 开启事务
+ DefaultTransactionDefinition def = new DefaultTransactionDefinition();
+ TransactionStatus status = transactionManager.getTransaction(def);
+
+ try {
+ // 批量插入(500条)
+ dataExcelMapper.batchInsert(cacheList);
+
+ // 提交事务
+ transactionManager.commit(status);
+
+ // 清空缓存(极其重要!防OOM)
+ cacheList.clear();
+
+ } catch (Exception e) {
+ // 回滚
+ transactionManager.rollback(status);
+ throw new RuntimeException("导入失败,已回滚:" + e.getMessage());
+ }
+ }
+}
diff --git a/src/main/java/com/southern/power/grid/service/IDnerDailyPowerOutageEventService.java b/src/main/java/com/southern/power/grid/service/IDnerDailyPowerOutageEventService.java
new file mode 100644
index 0000000..b1c6f89
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/IDnerDailyPowerOutageEventService.java
@@ -0,0 +1,24 @@
+package com.southern.power.grid.service;
+
+import com.alibaba.fastjson2.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.southern.power.grid.entity.DailyPowerOutageEventVO;
+import com.southern.power.grid.entity.DnerDailyPowerOutageEvent;
+
+/**
+ * 日K线停电事件 -- service接口
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+public interface IDnerDailyPowerOutageEventService extends IService {
+ /**
+ * 查询K线图数据
+ *
+ * @param orgCode 地区编码
+ * @param startDate 开始时间
+ * @param endDate 结束时间
+ * @return 返回结果
+ */
+ DailyPowerOutageEventVO queryKlineData(String orgCode, String startDate, String endDate);
+}
diff --git a/src/main/java/com/southern/power/grid/service/IDnerHourlyPowerOutageEventService.java b/src/main/java/com/southern/power/grid/service/IDnerHourlyPowerOutageEventService.java
new file mode 100644
index 0000000..425134e
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/IDnerHourlyPowerOutageEventService.java
@@ -0,0 +1,23 @@
+package com.southern.power.grid.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.southern.power.grid.entity.DnerHourlyPowerOutageEvent;
+import com.southern.power.grid.entity.HourlyPowerOutageEventChartVO;
+
+/**
+ * 分时停电事件 -- service接口
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+public interface IDnerHourlyPowerOutageEventService extends IService {
+ /**
+ * 查询分时图数据
+ *
+ * @param orgCode 地区编码
+ * @param startDate 开始时间
+ * @param endDate 结束时间
+ * @return 返回结果
+ */
+ HourlyPowerOutageEventChartVO queryIntradayData(String orgCode, String startDate, String endDate);
+}
diff --git a/src/main/java/com/southern/power/grid/service/IDnerSiteAreaConfigurationService.java b/src/main/java/com/southern/power/grid/service/IDnerSiteAreaConfigurationService.java
new file mode 100644
index 0000000..36006e1
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/IDnerSiteAreaConfigurationService.java
@@ -0,0 +1,23 @@
+package com.southern.power.grid.service;
+
+import com.alibaba.fastjson2.JSONArray;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.southern.power.grid.entity.AreaTreeVO;
+import com.southern.power.grid.entity.DnerSiteAreaConfiguration;
+
+import java.util.List;
+
+/**
+ * 行政区划配置表 -- service接口
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+public interface IDnerSiteAreaConfigurationService extends IService {
+ /**
+ * 查询地区树
+ *
+ * @return 结果
+ */
+ List queryAreaTree();
+}
diff --git a/src/main/java/com/southern/power/grid/service/INationalWeatherStationService.java b/src/main/java/com/southern/power/grid/service/INationalWeatherStationService.java
new file mode 100644
index 0000000..a57e822
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/INationalWeatherStationService.java
@@ -0,0 +1,13 @@
+package com.southern.power.grid.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.southern.power.grid.entity.NationalWeatherStation;
+
+/**
+ * 国家气象站 -- service接口
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+public interface INationalWeatherStationService extends IService {
+}
diff --git a/src/main/java/com/southern/power/grid/service/INwSiteAreaConfigurationService.java b/src/main/java/com/southern/power/grid/service/INwSiteAreaConfigurationService.java
new file mode 100644
index 0000000..e9450b5
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/INwSiteAreaConfigurationService.java
@@ -0,0 +1,14 @@
+package com.southern.power.grid.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.southern.power.grid.entity.NwSiteAreaConfiguration;
+
+/**
+ * 南网区划配置表 -- service接口
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/14
+ **/
+public interface INwSiteAreaConfigurationService extends IService {
+
+}
diff --git a/src/main/java/com/southern/power/grid/service/IRegionalWeatherStationService.java b/src/main/java/com/southern/power/grid/service/IRegionalWeatherStationService.java
new file mode 100644
index 0000000..de4b071
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/IRegionalWeatherStationService.java
@@ -0,0 +1,13 @@
+package com.southern.power.grid.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.southern.power.grid.entity.RegionalWeatherStation;
+
+/**
+ * 区域气象站 -- service接口
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+public interface IRegionalWeatherStationService extends IService {
+}
diff --git a/src/main/java/com/southern/power/grid/service/IWeatherSiteAreaConfigurationService.java b/src/main/java/com/southern/power/grid/service/IWeatherSiteAreaConfigurationService.java
new file mode 100644
index 0000000..0021f9c
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/IWeatherSiteAreaConfigurationService.java
@@ -0,0 +1,14 @@
+package com.southern.power.grid.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.southern.power.grid.entity.WeatherSiteAreaConfiguration;
+
+/**
+ * 气象区划配置表 service接口
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/14
+ **/
+public interface IWeatherSiteAreaConfigurationService extends IService {
+
+}
diff --git a/src/main/java/com/southern/power/grid/service/impl/DnerDailyPowerOutageEventServiceImpl.java b/src/main/java/com/southern/power/grid/service/impl/DnerDailyPowerOutageEventServiceImpl.java
new file mode 100644
index 0000000..8104746
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/impl/DnerDailyPowerOutageEventServiceImpl.java
@@ -0,0 +1,106 @@
+package com.southern.power.grid.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.southern.power.grid.dao.DnerDailyPowerOutageEventMapper;
+import com.southern.power.grid.entity.DailyPowerOutageEventVO;
+import com.southern.power.grid.entity.DnerDailyPowerOutageEvent;
+import com.southern.power.grid.service.IDnerDailyPowerOutageEventService;
+import com.southern.power.grid.utils.TimeUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 日K线停电事件 -- service实现类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Service
+public class DnerDailyPowerOutageEventServiceImpl
+ extends ServiceImpl
+ implements IDnerDailyPowerOutageEventService {
+ @Autowired
+ private DnerDailyPowerOutageEventMapper dnerDailyPowerOutageEventMapper;
+
+ @Override
+ public DailyPowerOutageEventVO queryKlineData(String orgCode, String startDate, String endDate) {
+ // 为了计算ma5/10/20/30,查询起始日期往前推29天的记录
+ String beforeNumDays = TimeUtil.getBeforeNumDays(startDate, 29); // 获取前29天的日期
+ List dataList = dnerDailyPowerOutageEventMapper.selectListByConditions(
+ orgCode, beforeNumDays, endDate);
+ Map dateTimeAndEntityMap = dataList.stream().collect(Collectors.toMap(
+ DnerDailyPowerOutageEvent::getDataTime, Function.identity(), (k1, k2) -> k1));
+ List> kline = new ArrayList<>();
+ List cumulativeRain = new ArrayList<>();
+ List avgRain = new ArrayList<>();
+ List avgTemp = new ArrayList<>();
+ List maxTemp = new ArrayList<>();
+ List minTemp = new ArrayList<>();
+ List ma5List = new ArrayList<>();
+ List ma10List = new ArrayList<>();
+ List ma20List = new ArrayList<>();
+ List ma30List = new ArrayList<>();
+ List dateTimeList = TimeUtil.getBetweenDates(startDate, endDate); // 获取开始时间到结束时间每一天的数组
+ dateTimeList.forEach(e -> { // 遍历开始时间和结束时间的日期
+ DnerDailyPowerOutageEvent event = dateTimeAndEntityMap.get(e);
+ if (Objects.isNull(event)) { // 数据为空,全部默认为0值
+ List klineE = Arrays.asList(0, 0, 0, 0);
+ kline.add(klineE);
+ cumulativeRain.add(0.0);
+ avgRain.add(0.0);
+ avgTemp.add(0.0);
+ maxTemp.add(0.0);
+ minTemp.add(0.0);
+ ma5List.add(0);
+ ma10List.add(0);
+ ma20List.add(0);
+ ma30List.add(0);
+ } else {
+ List klineE = Arrays.asList(event.getStarUserCount(), event.getEndUserCount(),
+ event.getMinUserCount(), event.getMaxUserCount());
+ kline.add(klineE);
+ cumulativeRain.add(Double.valueOf(event.getDailyPrecipitation()));
+ avgRain.add(Double.valueOf(event.getHourlyPrecipitation()));
+ avgTemp.add(Double.valueOf(event.getTemperature()));
+ maxTemp.add(Double.valueOf(event.getHourlyMaxTemperature()));
+ minTemp.add(Double.valueOf(event.getHourlyMinTemperature()));
+ ma5List.add(getMa(event, dateTimeAndEntityMap, 5));
+ ma10List.add(getMa(event, dateTimeAndEntityMap, 10));
+ ma20List.add(getMa(event, dateTimeAndEntityMap, 20));
+ ma30List.add(getMa(event, dateTimeAndEntityMap, 30));
+ }
+ });
+ DailyPowerOutageEventVO result = new DailyPowerOutageEventVO();
+ result.setFullDates(dateTimeList); // 日期列表
+ result.setKline(kline); // K线数组,每一项包含起始值、结束值、最低、最高
+ result.setCumulativeRain(cumulativeRain); // 日累计降雨量
+ result.setAvgRain(avgRain); // 平均降雨量
+ result.setAvgTemp(avgTemp); // 平均气温
+ result.setMaxTemp(maxTemp); // 最大气温
+ result.setMinTemp(minTemp); // 最低气温
+ result.setMa5(ma5List); // ma5
+ result.setMa10(ma10List);
+ result.setMa20(ma20List);
+ result.setMa30(ma30List);
+ return result;
+ }
+
+ private static int getMa(DnerDailyPowerOutageEvent event,
+ Map dateTimeAndEntityMap,
+ int maNum) {
+ int userCount = 0;
+ List maDateList = TimeUtil.getBetweenDates(
+ TimeUtil.getBeforeNumDays(event.getDataTime(), maNum - 1), event.getDataTime());
+ for (String date : maDateList) {
+ DnerDailyPowerOutageEvent outageEvent = dateTimeAndEntityMap.get(date);
+ if (!Objects.isNull(outageEvent)) {
+ userCount += outageEvent.getUserCount();
+ }
+ }
+ return userCount/maNum;
+ }
+}
diff --git a/src/main/java/com/southern/power/grid/service/impl/DnerHourlyPowerOutageEventServiceImpl.java b/src/main/java/com/southern/power/grid/service/impl/DnerHourlyPowerOutageEventServiceImpl.java
new file mode 100644
index 0000000..450cdc6
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/impl/DnerHourlyPowerOutageEventServiceImpl.java
@@ -0,0 +1,73 @@
+package com.southern.power.grid.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.southern.power.grid.dao.DnerHourlyPowerOutageEventMapper;
+import com.southern.power.grid.entity.DnerHourlyPowerOutageEvent;
+import com.southern.power.grid.entity.HourlyPowerOutageEventChartVO;
+import com.southern.power.grid.service.IDnerHourlyPowerOutageEventService;
+import com.southern.power.grid.utils.TimeUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 分时停电事件 -- service实现类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Service
+public class DnerHourlyPowerOutageEventServiceImpl
+ extends ServiceImpl
+ implements IDnerHourlyPowerOutageEventService {
+ @Autowired
+ private DnerHourlyPowerOutageEventMapper dnerHourlyPowerOutageEventMapper;
+
+ @Override
+ public HourlyPowerOutageEventChartVO queryIntradayData(String orgCode, String startDate, String endDate) {
+ List dataList = dnerHourlyPowerOutageEventMapper.selectListByConditions(
+ orgCode, startDate, endDate);
+ Map dateTimeAndEntityMap = dataList.stream().collect(Collectors.toMap(
+ DnerHourlyPowerOutageEvent::getDataTime, Function.identity(), (k1, k2) -> k1));
+ List powerOutageUserCountList = new ArrayList<>();
+ List avgTemList = new ArrayList<>();
+ List maxTemList = new ArrayList<>();
+ List minTemList = new ArrayList<>();
+ List precList = new ArrayList<>();
+ List windList = new ArrayList<>();
+ List dateTimeList = TimeUtil.generateHourListAll(startDate, endDate); // 获取开始时间到结束时间的小时数组
+ dateTimeList.forEach(e -> {
+ DnerHourlyPowerOutageEvent event = dateTimeAndEntityMap.get(e);
+ if (Objects.isNull(event)) { // 数据为空,全部默认为0值
+ powerOutageUserCountList.add(0); // 停电影响用户总数
+ avgTemList.add(0.0); // 平均气温
+ maxTemList.add(0.0); // 小时最大气温
+ minTemList.add(0.0); // 小时最低气温
+ precList.add(0.0); // 小时降雨量
+ windList.add(0.0); // 小时极大风速
+ } else {
+ powerOutageUserCountList.add(event.getUserCount()); // 停电影响用户总数
+ avgTemList.add(Double.valueOf(event.getTemperature())); // 平均气温
+ maxTemList.add(Double.valueOf(event.getHourlyMaxTemperature())); // 小时最大气温
+ minTemList.add(Double.valueOf(event.getHourlyMinTemperature())); // 小时最低气温
+ precList.add(Double.valueOf(event.getHourlyPrecipitation())); // 小时降雨量
+ windList.add(Double.valueOf(event.getExtremeWindSpeedHourly())); // 小时极大风速
+ }
+ });
+ HourlyPowerOutageEventChartVO result = new HourlyPowerOutageEventChartVO();
+ result.setDateList(TimeUtil.generateHourList(startDate, endDate)); // 日期列表
+ result.setPowerOutageUserCountList(powerOutageUserCountList);
+ result.setAvgTemList(avgTemList);
+ result.setMaxTemList(maxTemList);
+ result.setMinTemList(minTemList);
+ result.setPrecList(precList);
+ result.setWindList(windList);
+ return result;
+ }
+}
diff --git a/src/main/java/com/southern/power/grid/service/impl/DnerSiteAreaConfigurationServiceImpl.java b/src/main/java/com/southern/power/grid/service/impl/DnerSiteAreaConfigurationServiceImpl.java
new file mode 100644
index 0000000..11bda1f
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/impl/DnerSiteAreaConfigurationServiceImpl.java
@@ -0,0 +1,100 @@
+package com.southern.power.grid.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.southern.power.grid.dao.DnerSiteAreaConfigurationMapper;
+import com.southern.power.grid.entity.AreaTreeVO;
+import com.southern.power.grid.entity.DnerSiteAreaConfiguration;
+import com.southern.power.grid.service.IDnerSiteAreaConfigurationService;
+import lombok.NonNull;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+/**
+ * 行政区划配置表 -- service实现类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Service
+public class DnerSiteAreaConfigurationServiceImpl
+ extends ServiceImpl
+ implements IDnerSiteAreaConfigurationService {
+ @Override
+ public List queryAreaTree() {
+ // 查询出所有的省市区
+ List dataList = list();
+ // 最终树
+ List result = new ArrayList<>();
+ // 1. 构建所有省份节点
+ Map provinceCodeAndProvinceMap = buildProvince(dataList, result);
+ // 2. 给每个省份挂上市
+ Map> cityMap = city2Province(dataList, provinceCodeAndProvinceMap);
+ // 3. 给每个市挂上区
+ district2City(dataList, cityMap);
+ return result;
+ }
+
+ private static @NonNull Map buildProvince(
+ List dataList, List result) {
+ Map provinceCodeAndProvinceMap = new LinkedHashMap<>();
+ for (DnerSiteAreaConfiguration item : dataList) {
+ String pCode = item.getProvinceCode();
+ String pName = item.getProvince();
+
+ if (!provinceCodeAndProvinceMap.containsKey(pCode)) { // 判断是否创建省节点
+ AreaTreeVO province = new AreaTreeVO();
+ province.setValue(pCode);
+ province.setLabel(pName);
+ province.setChildren(new ArrayList<>());
+ provinceCodeAndProvinceMap.put(pCode, province);
+ result.add(province);
+ }
+ }
+ return provinceCodeAndProvinceMap;
+ }
+
+ private static @NonNull Map> city2Province(
+ List dataList, Map provinceCodeAndProvinceMap) {
+ Map> cityMap = new HashMap<>();
+ for (DnerSiteAreaConfiguration item : dataList) {
+ String pCode = item.getProvinceCode();
+ String cCode = item.getCityCode();
+ String cName = item.getCity();
+
+ if (!cityMap.containsKey(pCode)) { // 若省份下没有市map,则创建一个
+ cityMap.put(pCode, new LinkedHashMap<>());
+ }
+ Map cityCodeAndCityMap = cityMap.get(pCode);
+
+ if (!cityCodeAndCityMap.containsKey(cCode)) { // 判断是否创建市节点
+ AreaTreeVO city = new AreaTreeVO();
+ city.setValue(cCode);
+ city.setLabel(cName);
+ city.setChildren(new ArrayList<>());
+ cityCodeAndCityMap.put(cCode, city);
+ // 挂到省份下
+ provinceCodeAndProvinceMap.get(pCode).getChildren().add(city);
+ }
+ }
+ return cityMap;
+ }
+
+ private static void district2City(
+ List dataList, Map> cityMap) {
+ for (DnerSiteAreaConfiguration item : dataList) {
+ String pCode = item.getProvinceCode();
+ String cCode = item.getCityCode();
+ String dCode = item.getDistrictCode();
+ String dName = item.getDistrict();
+
+ AreaTreeVO district = new AreaTreeVO();
+ district.setValue(dCode);
+ district.setLabel(dName);
+
+ // 挂到对应市下面
+ AreaTreeVO city = cityMap.get(pCode).get(cCode);
+ city.getChildren().add(district);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/southern/power/grid/service/impl/NationalWeatherStationServiceImpl.java b/src/main/java/com/southern/power/grid/service/impl/NationalWeatherStationServiceImpl.java
new file mode 100644
index 0000000..41a5aa6
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/impl/NationalWeatherStationServiceImpl.java
@@ -0,0 +1,19 @@
+package com.southern.power.grid.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.southern.power.grid.dao.NationalWeatherStationMapper;
+import com.southern.power.grid.entity.NationalWeatherStation;
+import com.southern.power.grid.service.INationalWeatherStationService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 国家气象站 -- service实现类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Service
+public class NationalWeatherStationServiceImpl
+ extends ServiceImpl
+ implements INationalWeatherStationService {
+}
diff --git a/src/main/java/com/southern/power/grid/service/impl/NwSiteAreaConfigurationServiceImpl.java b/src/main/java/com/southern/power/grid/service/impl/NwSiteAreaConfigurationServiceImpl.java
new file mode 100644
index 0000000..92f54d0
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/impl/NwSiteAreaConfigurationServiceImpl.java
@@ -0,0 +1,19 @@
+package com.southern.power.grid.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.southern.power.grid.dao.NwSiteAreaConfigurationMapper;
+import com.southern.power.grid.entity.NwSiteAreaConfiguration;
+import com.southern.power.grid.service.INwSiteAreaConfigurationService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 南网区划配置表 -- service实现类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/14
+ **/
+@Service
+public class NwSiteAreaConfigurationServiceImpl extends ServiceImpl
+ implements INwSiteAreaConfigurationService {
+
+}
diff --git a/src/main/java/com/southern/power/grid/service/impl/RegionalWeatherStationServiceImpl.java b/src/main/java/com/southern/power/grid/service/impl/RegionalWeatherStationServiceImpl.java
new file mode 100644
index 0000000..2fc31fe
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/impl/RegionalWeatherStationServiceImpl.java
@@ -0,0 +1,19 @@
+package com.southern.power.grid.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.southern.power.grid.dao.RegionalWeatherStationMapper;
+import com.southern.power.grid.entity.RegionalWeatherStation;
+import com.southern.power.grid.service.IRegionalWeatherStationService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 区域气象站 -- service实现类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/13
+ **/
+@Service
+public class RegionalWeatherStationServiceImpl
+ extends ServiceImpl
+ implements IRegionalWeatherStationService {
+}
diff --git a/src/main/java/com/southern/power/grid/service/impl/WeatherSiteAreaConfigurationServiceImpl.java b/src/main/java/com/southern/power/grid/service/impl/WeatherSiteAreaConfigurationServiceImpl.java
new file mode 100644
index 0000000..5a4c30a
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/service/impl/WeatherSiteAreaConfigurationServiceImpl.java
@@ -0,0 +1,20 @@
+package com.southern.power.grid.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.southern.power.grid.dao.WeatherSiteAreaConfigurationMapper;
+import com.southern.power.grid.entity.WeatherSiteAreaConfiguration;
+import com.southern.power.grid.service.IWeatherSiteAreaConfigurationService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 气象区划配置表 -- service实现类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/14
+ **/
+@Service
+public class WeatherSiteAreaConfigurationServiceImpl
+ extends ServiceImpl
+ implements IWeatherSiteAreaConfigurationService {
+
+}
diff --git a/src/main/java/com/southern/power/grid/utils/TimeUtil.java b/src/main/java/com/southern/power/grid/utils/TimeUtil.java
new file mode 100644
index 0000000..fc39f02
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/utils/TimeUtil.java
@@ -0,0 +1,125 @@
+package com.southern.power.grid.utils;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 时间工具类
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/14
+ **/
+public class TimeUtil {
+ // 完整格式:年月日 时分
+ private static final DateTimeFormatter FULL = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+
+ // 仅小时格式
+ private static final DateTimeFormatter HOUR = DateTimeFormatter.ofPattern("HH:mm");
+
+ /**
+ * 获取开始时间到结束时间的小时数组,仅当天的第一条数据会展示年月日
+ *
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @return
+ */
+ public static List generateHourList(String startTime, String endTime) {
+ LocalDateTime start = LocalDateTime.parse(startTime, FULL);
+ LocalDateTime end = LocalDateTime.parse(endTime, FULL);
+ if (start.isAfter(end)) {
+ throw new RuntimeException("generateHourList error! The endTime comes before the startTime.");
+ }
+
+ List result = new ArrayList<>();
+ LocalDateTime current = start;
+ LocalDateTime preDate = null;
+
+ while (!current.isAfter(end)) {
+ // 第一次 或 日期发生变化(跨天0点)→ 显示完整年月日
+ if (preDate == null || !current.toLocalDate().equals(preDate.toLocalDate())) {
+ result.add(current.format(FULL));
+ } else {
+ // 同一天 → 只显示小时
+ result.add(current.format(HOUR));
+ }
+ preDate = current;
+ current = current.plusHours(1);
+ }
+
+ return result;
+ }
+
+ /**
+ * 获取开始时间到结束时间的小时数组
+ *
+ * @param startTime 开始时间
+ * @param endTime 结束时间
+ * @return
+ */
+ public static List generateHourListAll(String startTime, String endTime) {
+ LocalDateTime start = LocalDateTime.parse(startTime, FULL);
+ LocalDateTime end = LocalDateTime.parse(endTime, FULL);
+ if (start.isAfter(end)) {
+ throw new RuntimeException("generateHourList error! The endTime comes before the startTime.");
+ }
+
+ List result = new ArrayList<>();
+ LocalDateTime current = start;
+
+ while (!current.isAfter(end)) {
+ // 第一次 或 日期发生变化(跨天0点)→ 显示完整年月日
+ result.add(current.format(FULL));
+ current = current.plusHours(1);
+ }
+
+ return result;
+ }
+
+ /**
+ * 获取开始日期到结束日期之间的所有日期(包含首尾)
+ */
+ public static List getBetweenDates(String startDate, String endDate) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+ List dateList = new ArrayList<>();
+
+ // 字符串转日期
+ LocalDate start = LocalDate.parse(startDate, formatter);
+ LocalDate end = LocalDate.parse(endDate, formatter);
+
+ // 循环遍历每一天
+ LocalDate current = start;
+ while (!current.isAfter(end)) {
+ dateList.add(current.format(formatter));
+ current = current.plusDays(1);
+ }
+
+ return dateList;
+ }
+
+ /**
+ * 获取指定日期 往前推n天 的日期
+ *
+ * @param dateStr 传入日期字符串 yyyy-MM-dd
+ * @param num 前n天
+ * @return 前n天日期字符串
+ */
+ public static String getBeforeNumDays(String dateStr, int num) {
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+ // 字符串转日期
+ LocalDate date = LocalDate.parse(dateStr, formatter);
+ // 减去n天
+ LocalDate beforeDay = date.minusDays(num);
+ // 转回字符串
+ return beforeDay.format(formatter);
+ }
+
+ public static void main(String[] args) {
+// List strings = generateHourListAll("2026-03-13 22:00", "2026-03-14 02:00");
+// List strings = getBetweenDates("2026-03-10", "2026-03-14");
+// String strings = getBeforeNumDays("2026-03-15", 5);
+ System.out.println(14/5);
+ }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 665dd8d..f48c746 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -1,5 +1,5 @@
server:
- port: 8080
+ port: 18090
spring:
application:
@@ -7,9 +7,9 @@ spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://127.0.0.1:13360/jinshan?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
- username: jinshan
- password: jinshan@1234A.
+ url: jdbc:mysql://127.0.0.1:3306/south_power_grid?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
+ username: root
+ password: Root@123456
hikari:
connection-timeout: 30000
validation-timeout: 5000
diff --git a/src/main/resources/mapper/DataExcelMapper.xml b/src/main/resources/mapper/DataExcelMapper.xml
new file mode 100644
index 0000000..e33125a
--- /dev/null
+++ b/src/main/resources/mapper/DataExcelMapper.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/mapper/DnerDailyPowerOutageEventMapper.xml b/src/main/resources/mapper/DnerDailyPowerOutageEventMapper.xml
new file mode 100644
index 0000000..9699533
--- /dev/null
+++ b/src/main/resources/mapper/DnerDailyPowerOutageEventMapper.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/mapper/DnerHourlyPowerOutageEventMapper.xml b/src/main/resources/mapper/DnerHourlyPowerOutageEventMapper.xml
new file mode 100644
index 0000000..1d72981
--- /dev/null
+++ b/src/main/resources/mapper/DnerHourlyPowerOutageEventMapper.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/sql/20260313-001.sql b/src/main/resources/sql/20260313-001.sql
new file mode 100644
index 0000000..beda655
--- /dev/null
+++ b/src/main/resources/sql/20260313-001.sql
@@ -0,0 +1,195 @@
+-- 行政区划配置表
+CREATE TABLE `dner_site_area_configuration`
+(
+ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+ `province` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '省份',
+ `province_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '省份编码',
+ `city` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地市',
+ `city_code` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地市编码',
+ `district` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '区县',
+ `district_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地区编码',
+ `create_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建人',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '修改人',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+ PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT ='行政区划配置表';
+
+-- 南网区划配置表
+CREATE TABLE `nw_site_area_configuration`
+(
+ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+ `district_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地区编码',
+ `nw_province` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '南网省',
+ `nw_city` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '南网地市局',
+ `nw_district` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '南网区县局',
+ `create_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建人',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '修改人',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+ PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT ='南网区划配置表';
+
+-- 气象区划配置表
+CREATE TABLE `weather_site_area_configuration`
+(
+ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+ `district_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地区编码',
+ `weather_province` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '气象所属省份',
+ `weather_city` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '气象所属地市',
+ `weather_district` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '气象所属区县',
+ `station_id` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '自动站站号',
+ `station_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '气象站名',
+ `create_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建人',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '修改人',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+ PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT ='气象区划配置表';
+
+-- 日K线停电事件表
+CREATE TABLE `dner_daily_power_outage_event`
+(
+ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+ `org_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地区编码',
+ `data_time` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '资料日期',
+ `hourly_precipitation` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时降水量',
+ `daily_precipitation` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '日累计降水量',
+ `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 '日内最低气温',
+ `extreme_wind_speed_hourly` 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 '结束影响用户总数',
+ `min_user_count` int(11) DEFAULT NULL COMMENT '最低停电影响用户总数',
+ `max_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-计划类)',
+ `create_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建人',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '修改人',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+ PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT ='日K线停电事件表';
+
+-- 分时停电事件表
+CREATE TABLE `dner_hourly_power_outage_event`
+(
+ `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
+ `org_code` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地区编码',
+ `data_time` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '资料时次',
+ `hourly_precipitation` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时降水量',
+ `daily_precipitation` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '日累计降水量',
+ `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 '小时内最低气温',
+ `extreme_wind_speed_hourly` 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-计划类)',
+ `create_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建人',
+ `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_by` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '修改人',
+ `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
+ PRIMARY KEY (`id`)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT ='分时停电事件表';
+
+-- 国家气象站
+CREATE TABLE `national_weather_station`
+(
+ `id` int NOT NULL AUTO_INCREMENT,
+ `data_time` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '资料时次',
+ `station_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '自动站站号',
+ `station_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '站名',
+ `station_pressure` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '本站气压',
+ `hourly_max_pressure` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最高本站气压',
+ `hourly_min_pressure` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最低本站气压',
+ `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 '小时内最低气温',
+ `dew_point_temperature` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '露点温度',
+ `relative_humidity` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '相对湿度',
+ `water_vapor_pressure` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '水汽压',
+ `hourly_precipitation` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时降水量',
+ `daily_precipitation` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '日累计降水量',
+ `wind_direction_2min` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '2分钟风向',
+ `wind_speed_2min` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '2分钟平均风速',
+ `wind_direction_10min` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '10分钟风向',
+ `wind_speed_10min` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '10分钟平均风速',
+ `max_wind_direction_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最大风速的风向',
+ `max_wind_speed_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最大风速',
+ `instantaneous_wind_direction` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '瞬时风向',
+ `instantaneous_wind_speed` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '瞬时风速',
+ `extreme_wind_direction_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内极大风速的风向',
+ `extreme_wind_speed_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内极大风速',
+ `extreme_wind_time_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内极大风速出现时间',
+ `min_visibility_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最小能见度',
+ `province` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '所属省份',
+ `city` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '所属地市',
+ `district` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '所属区县',
+ `latitude` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '纬度',
+ `longitude` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '经度',
+ `altitude` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '海拔高度',
+ `create_time` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建时间',
+ `import_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`),
+ KEY `index_1` (`data_time`)
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 1875958
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT ='国家气象站';
+
+-- 区域气象站
+CREATE TABLE `regional_weather_station`
+(
+ `id` int NOT NULL AUTO_INCREMENT,
+ `data_time` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '资料时次',
+ `station_id` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '自动站站号',
+ `station_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '站名',
+ `station_pressure` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '本站气压',
+ `hourly_max_pressure` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最高本站气压',
+ `hourly_min_pressure` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最低本站气压',
+ `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 '小时内最低气温',
+ `dew_point_temperature` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '露点温度',
+ `relative_humidity` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '相对湿度',
+ `hourly_precipitation` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时降水量',
+ `daily_precipitation` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '日累计降水量',
+ `wind_direction_2min` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '2分钟风向',
+ `wind_speed_2min` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '2分钟平均风速',
+ `wind_direction_10min` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '10分钟风向',
+ `wind_speed_10min` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '10分钟平均风速',
+ `max_wind_direction_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最大风速的风向',
+ `max_wind_speed_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最大风速',
+ `instantaneous_wind_direction` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '瞬时风向',
+ `instantaneous_wind_speed` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '瞬时风速',
+ `extreme_wind_direction_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内极大风速的风向',
+ `extreme_wind_speed_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内极大风速',
+ `extreme_wind_time_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内极大风速出现时间',
+ `min_visibility_hourly` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '小时内最小能见度',
+ `province` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '所属省份',
+ `city` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '所属地市',
+ `district` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '所属区县',
+ `latitude` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '纬度',
+ `longitude` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '经度',
+ `altitude` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '海拔高度',
+ `create_time` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '创建时间',
+ `import_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`),
+ KEY `index_1` (`data_time`)
+) ENGINE = InnoDB
+ AUTO_INCREMENT = 33601113
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT ='区域气象站'
diff --git a/src/main/resources/testdata/data.json b/src/main/resources/testdata/data.json
new file mode 100644
index 0000000..f6d06bf
--- /dev/null
+++ b/src/main/resources/testdata/data.json
@@ -0,0 +1,120 @@
+{
+ "fullDates": [
+ "2025-08-14",
+ "2025-08-15",
+ "2025-08-16",
+ "2025-08-17",
+ "2025-08-18",
+ "2025-08-19",
+ "2025-08-20",
+ "2025-08-21",
+ "2025-08-22",
+ "2025-08-23",
+ "2025-08-24",
+ "2025-08-25",
+ "2025-08-26",
+ "2025-08-27",
+ "2025-08-28",
+ "2025-08-29",
+ "2025-08-30",
+ "2025-08-31",
+ "2025-09-01",
+ "2025-09-02",
+ "2025-09-03",
+ "2025-09-04",
+ "2025-09-05",
+ "2025-09-06",
+ "2025-09-07",
+ "2025-09-08",
+ "2025-09-09",
+ "2025-09-10",
+ "2025-09-11",
+ "2025-09-12",
+ "2025-09-13",
+ "2025-09-14",
+ "2025-09-15",
+ "2025-09-16",
+ "2025-09-17",
+ "2025-09-18",
+ "2025-09-19"
+ ],
+ "kline": [
+ [100, 200, 100, 5000],
+ [150, 250, 150, 5100],
+ [200, 300, 200, 5200],
+ [250, 350, 250, 5300],
+ [300, 400, 300, 5400],
+ [350, 450, 450, 5500],
+ [500, 800, 500, 6000],
+ [550, 850, 550, 6100],
+ [600, 900, 600, 6200],
+ [650, 950, 650, 6300],
+ [700, 1000, 700, 6400],
+ [750, 1050, 750, 6500],
+ [800, 5000, 800, 8000],
+ [850, 5050, 850, 5600],
+ [900, 5100, 900, 5700],
+ [950, 5150, 950, 5800],
+ [1000, 5200, 1000, 5900],
+ [1050, 5250, 1050, 6000],
+ [5000, 4000, 3800, 5500],
+ [4950, 3950, 3750, 5400],
+ [4900, 3900, 3700, 5300],
+ [4850, 3850, 3650, 5200],
+ [4800, 3800, 3600, 5100],
+ [4750, 3750, 3550, 5000],
+ [4000, 3000, 2800, 4500],
+ [3950, 2950, 2750, 4400],
+ [3900, 2900, 2700, 4300],
+ [3850, 2850, 2650, 4200],
+ [3800, 2800, 2600, 4100],
+ [3750, 2750, 2550, 4000],
+ [3000, 2500, 2000, 3500],
+ [2950, 2450, 1950, 3400],
+ [2900, 2400, 1900, 3300],
+ [2850, 2350, 1850, 3200],
+ [2800, 2300, 1800, 3100],
+ [2750, 2250, 1750, 3000],
+ [2500, 1800, 1500, 3000]
+ ],
+ "ma5": [
+ 100, 150, 200, 250, 300, 350, 1500, 1550, 1600, 1650, 1700, 1750, 3000, 3050, 3100, 3150,
+ 3200, 3250, 4000, 3950, 3900, 3850, 3800, 3750, 3800, 3750, 3700, 3650, 3600, 3550, 3200,
+ 3150, 3100, 3050, 3000, 2800, 2800
+ ],
+ "ma10": [
+ 800, 850, 900, 950, 1000, 1050, 1200, 1250, 1300, 1350, 1400, 1450, 2500, 2550, 2600, 2650,
+ 2700, 2750, 3800, 3750, 3700, 3650, 3600, 3550, 3600, 3550, 3500, 3450, 3400, 3350, 3000,
+ 2950, 2900, 2850, 2800, 2600, 2800
+ ],
+ "ma20": [
+ 900, 950, 1000, 1050, 1100, 1150, 1300, 1350, 1400, 1450, 1500, 1550, 2800, 2850, 2900, 2950,
+ 3000, 3050, 3900, 3850, 3800, 3750, 3700, 3650, 3700, 3650, 3600, 3550, 3500, 3450, 3100,
+ 3050, 3000, 2950, 2900, 2700, 2800
+ ],
+ "ma30": [
+ 1100, 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500, 1550, 1600, 1650, 2900, 2950, 3000,
+ 3050, 3100, 3150, 4100, 4050, 4000, 3950, 3900, 3850, 3900, 3850, 3800, 3750, 3700, 3650,
+ 3300, 3250, 3200, 3150, 3100, 2900, 2800
+ ],
+ "cumulativeRain": [
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 10, 5, 0, 0, 0, 0,
+ 0, 0, 0, 30, 50, 55
+ ],
+ "avgRain": [
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 2, 1, 0, 0, 0, 0,
+ 0, 0, 0, 3, 5, 6
+ ],
+ "avgTemp": [
+ 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 31, 31, 31,
+ 31, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 32, 32
+ ],
+ "maxTemp": [
+ 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 36, 36, 36,
+ 36, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 37, 32
+ ],
+ "minTemp": [
+ 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 26, 26, 26,
+ 26, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 27, 32
+ ]
+}
\ No newline at end of file