diff --git a/pom.xml b/pom.xml
index 0cbb550..4bfa9e8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -79,6 +79,12 @@
5.8.25
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
org.springframework.boot
diff --git a/src/main/java/com/southern/power/grid/controller/DnerController.java b/src/main/java/com/southern/power/grid/controller/DnerController.java
index 8b8f016..83b88b2 100644
--- a/src/main/java/com/southern/power/grid/controller/DnerController.java
+++ b/src/main/java/com/southern/power/grid/controller/DnerController.java
@@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
+import javax.validation.Valid;
import java.util.List;
/**
@@ -36,9 +37,8 @@ public class DnerController {
private IDnerSiteAreaConfigurationService dnerSiteAreaConfigurationService;
@PostMapping("/area-tree/query")
- public Result> queryAreaTree(@RequestBody AreaTreeReq req) {
- // TODO 使用POST请求,后续新增高级筛选时,加入请求入参
- return Result.success(dnerSiteAreaConfigurationService.queryAreaTree());
+ public Result> queryAreaTree(@RequestBody @Valid AreaTreeReq req) {
+ return Result.success(dnerSiteAreaConfigurationService.queryAreaTree(req));
}
/**
diff --git a/src/main/java/com/southern/power/grid/dao/DnerSiteAreaConfigurationMapper.java b/src/main/java/com/southern/power/grid/dao/DnerSiteAreaConfigurationMapper.java
index e2c609d..0f89b64 100644
--- a/src/main/java/com/southern/power/grid/dao/DnerSiteAreaConfigurationMapper.java
+++ b/src/main/java/com/southern/power/grid/dao/DnerSiteAreaConfigurationMapper.java
@@ -1,8 +1,10 @@
package com.southern.power.grid.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.southern.power.grid.entity.AreaTreeReq;
import com.southern.power.grid.entity.DnerSiteAreaConfiguration;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
import java.util.List;
@@ -15,4 +17,8 @@ import java.util.List;
@Mapper
public interface DnerSiteAreaConfigurationMapper extends BaseMapper {
List selectAll();
+
+ List selectHourlyChartAreaTree(@Param("param") AreaTreeReq req);
+
+ List selectDailyChartAreaTree(@Param("param") AreaTreeReq req);
}
diff --git a/src/main/java/com/southern/power/grid/entity/AreaTreeReq.java b/src/main/java/com/southern/power/grid/entity/AreaTreeReq.java
index 4de8824..4a3764e 100644
--- a/src/main/java/com/southern/power/grid/entity/AreaTreeReq.java
+++ b/src/main/java/com/southern/power/grid/entity/AreaTreeReq.java
@@ -2,6 +2,8 @@ package com.southern.power.grid.entity;
import lombok.Data;
+import javax.validation.constraints.NotBlank;
+
/**
* 区域树请求入参
*
@@ -10,5 +12,112 @@ import lombok.Data;
**/
@Data
public class AreaTreeReq {
+ /**
+ * daily-日K图
+ * hourly-分时图
+ */
+ @NotBlank(message = "查询类型不能为空")
+ String queryType;
+ /**
+ * 是否开启高级筛选 0-未开启 1-开启
+ */
+ String advancedFilterFlag;
+
+ // ================= 用于高级筛选的属性 ====================
+ /**
+ * 过去XX小时/天
+ */
+ Integer rainPastTime;
+
+ /**
+ * 过去XX小时/天的累计降雨量超过的mm
+ */
+ Double pastTimeRainCount;
+
+ /**
+ * 过去XX小时/天
+ */
+ Integer avgTempPastTime;
+
+ /**
+ * 过去XX小时/天的平均气温超过的℃
+ */
+ Double pastTimeAvgTempCount;
+
+ /**
+ * 过去XX小时/天
+ */
+ Integer maxWindPastTime;
+
+ /**
+ * 过去XX小时/天的极大风速超过的m/s
+ */
+ Double pastTimeMaxWindCount;
+
+ /**
+ * 过去XX小时/天
+ */
+ Integer powerOutageTimePastTime;
+
+ /**
+ * 过去XX小时/天的停电时长超过的小时数
+ */
+ Double pastTimePowerOutageHourCount;
+
+ /**
+ * 过去XX小时/天
+ */
+ Integer powerOutageUserPastTime;
+
+ /**
+ * 过去XX小时/天的停电用户数超过的户数
+ */
+ Integer pastTimePowerOutageUserCount;
+
+ /**
+ * 过去XX小时/天
+ */
+ Integer powerOutageRatioPastTime;
+
+ /**
+ * 未复电用户数/总停电用户数大于等于的百分比
+ */
+ Double pastTimePowerOutageRatioCount;
+
+ // ============== 其他属性 ============
+ /**
+ * 当前时间
+ */
+ String currentDateTime;
+
+ /**
+ * 累计降雨量开始查询时间
+ */
+ String rainStartDateTime;
+
+ /**
+ * 平均气温开始查询时间
+ */
+ String avgTempStartDateTime;
+
+ /**
+ * 极大风速开始查询时间
+ */
+ String maxWindStartDateTime;
+
+ /**
+ * 停电时长开始查询时间
+ */
+ String powerOutageTimeStartDateTime;
+
+ /**
+ * 停电用户数开始查询时间
+ */
+ String powerOutageUserStartDateTime;
+
+ /**
+ * 未复电用户数/总停电用户数百分比
+ */
+ String powerOutageRatioStartDateTime;
}
diff --git a/src/main/java/com/southern/power/grid/enums/ChartQueryTypeEnum.java b/src/main/java/com/southern/power/grid/enums/ChartQueryTypeEnum.java
new file mode 100644
index 0000000..a69dca9
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/enums/ChartQueryTypeEnum.java
@@ -0,0 +1,28 @@
+package com.southern.power.grid.enums;
+
+import lombok.Getter;
+
+/**
+ * 图查询类型
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/17
+ **/
+@Getter
+public enum ChartQueryTypeEnum {
+ DAILY_CHART("DAILY", "日K图查询"),
+
+ HOURLY_CHART("HOURLY", "分时图查询")
+ ;
+
+ // 状态值
+ private final String code;
+ // 状态描述
+ private final String desc;
+
+ ChartQueryTypeEnum(String code, String desc) {
+ this.code = code;
+ this.desc = desc;
+ }
+
+}
diff --git a/src/main/java/com/southern/power/grid/enums/ImportTaskStatusEnum.java b/src/main/java/com/southern/power/grid/enums/ImportTaskStatusEnum.java
index f9a419f..ee0d476 100644
--- a/src/main/java/com/southern/power/grid/enums/ImportTaskStatusEnum.java
+++ b/src/main/java/com/southern/power/grid/enums/ImportTaskStatusEnum.java
@@ -1,11 +1,14 @@
package com.southern.power.grid.enums;
+import lombok.Getter;
+
/**
* 导入任务状态枚举
*
* @author: junzhangfm
* @date: 2026/3/16
**/
+@Getter
public enum ImportTaskStatusEnum {
// 定义 5 个状态:编码 + 描述
WAITING("WAITING", "等待执行"),
@@ -16,6 +19,7 @@ public enum ImportTaskStatusEnum {
// 状态值(存入数据库的值)
private final String code;
+
// 状态描述
private final String desc;
@@ -24,13 +28,4 @@ public enum ImportTaskStatusEnum {
this.desc = desc;
}
- // 获取状态值(你要的就是这个)
- public String getCode() {
- return code;
- }
-
- // 获取描述
- public String getDesc() {
- return desc;
- }
}
diff --git a/src/main/java/com/southern/power/grid/exception/GlobalExceptionHandler.java b/src/main/java/com/southern/power/grid/exception/GlobalExceptionHandler.java
new file mode 100644
index 0000000..e78f4d2
--- /dev/null
+++ b/src/main/java/com/southern/power/grid/exception/GlobalExceptionHandler.java
@@ -0,0 +1,34 @@
+package com.southern.power.grid.exception;
+
+import org.springframework.validation.BindException;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * TODO
+ *
+ * @author: junzhangfm
+ * @date: 2026/3/17
+ **/
+@RestControllerAdvice
+public class GlobalExceptionHandler {
+
+ // 捕获参数校验异常
+ @ExceptionHandler(BindException.class)
+ public Map handleValidException(BindException e) {
+ FieldError fieldError = e.getBindingResult().getFieldError();
+ String msg = "参数校验失败,请核对入参";
+ if (!Objects.isNull(fieldError)) {
+ msg = fieldError.getField() + ":" + fieldError.getDefaultMessage();
+ }
+ Map map = new HashMap<>();
+ map.put("code", 400);
+ map.put("msg", msg);
+ return map;
+ }
+}
diff --git a/src/main/java/com/southern/power/grid/service/IDnerSiteAreaConfigurationService.java b/src/main/java/com/southern/power/grid/service/IDnerSiteAreaConfigurationService.java
index 36006e1..99ebdbd 100644
--- a/src/main/java/com/southern/power/grid/service/IDnerSiteAreaConfigurationService.java
+++ b/src/main/java/com/southern/power/grid/service/IDnerSiteAreaConfigurationService.java
@@ -1,7 +1,7 @@
package com.southern.power.grid.service;
-import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.extension.service.IService;
+import com.southern.power.grid.entity.AreaTreeReq;
import com.southern.power.grid.entity.AreaTreeVO;
import com.southern.power.grid.entity.DnerSiteAreaConfiguration;
@@ -19,5 +19,5 @@ public interface IDnerSiteAreaConfigurationService extends IService queryAreaTree();
+ List queryAreaTree(AreaTreeReq req);
}
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
index 11bda1f..8307b90 100644
--- a/src/main/java/com/southern/power/grid/service/impl/DnerSiteAreaConfigurationServiceImpl.java
+++ b/src/main/java/com/southern/power/grid/service/impl/DnerSiteAreaConfigurationServiceImpl.java
@@ -2,12 +2,18 @@ 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.AreaTreeReq;
import com.southern.power.grid.entity.AreaTreeVO;
import com.southern.power.grid.entity.DnerSiteAreaConfiguration;
+import com.southern.power.grid.enums.ChartQueryTypeEnum;
import com.southern.power.grid.service.IDnerSiteAreaConfigurationService;
+import com.southern.power.grid.utils.TimeUtil;
import lombok.NonNull;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.*;
/**
@@ -20,10 +26,44 @@ import java.util.*;
public class DnerSiteAreaConfigurationServiceImpl
extends ServiceImpl
implements IDnerSiteAreaConfigurationService {
+ @Autowired
+ private DnerSiteAreaConfigurationMapper dnerSiteAreaConfigurationMapper;
+
@Override
- public List queryAreaTree() {
+ public List queryAreaTree(AreaTreeReq req) {
+ // 判断是否开启高级筛选
+ String advancedFilterFlag ="0";
+ if ((!Objects.isNull(req.getRainPastTime()) && req.getRainPastTime() != 0)
+ || (!Objects.isNull(req.getAvgTempPastTime()) && req.getAvgTempPastTime() != 0)
+ || (!Objects.isNull(req.getMaxWindPastTime()) && req.getMaxWindPastTime() != 0)
+ || (!Objects.isNull(req.getPowerOutageTimePastTime()) && req.getPowerOutageTimePastTime() != 0)
+ || (!Objects.isNull(req.getPowerOutageUserPastTime()) && req.getPowerOutageUserPastTime() != 0)
+ || (!Objects.isNull(req.getPowerOutageRatioPastTime()) && req.getPowerOutageRatioPastTime() != 0)) {
+ advancedFilterFlag = "1"; // 开启高级筛选
+ }
+ req.setAdvancedFilterFlag(advancedFilterFlag);
// 查询出所有的省市区
- List dataList = list();
+ List dataList;
+ if (ChartQueryTypeEnum.HOURLY_CHART.getCode().equals(req.getQueryType())) {
+ // 分时图
+ if ("1".equals(advancedFilterFlag)) {
+ String currentDateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00"));
+ req.setCurrentDateTime(currentDateTime);
+ if (!Objects.isNull(req.getRainPastTime()) && req.getRainPastTime() != 0) {
+ req.setRainStartDateTime(TimeUtil.getBeforeHourTime(currentDateTime, req.getRainPastTime()));
+ }
+ if (!Objects.isNull(req.getAvgTempPastTime()) && req.getAvgTempPastTime() != 0) {
+ req.setAvgTempStartDateTime(TimeUtil.getBeforeHourTime(currentDateTime, req.getAvgTempPastTime()));
+ }
+ }
+ dataList = dnerSiteAreaConfigurationMapper.selectHourlyChartAreaTree(req);
+ } else {
+ // 日K图
+ if ("1".equals(advancedFilterFlag)) {
+ req.setCurrentDateTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+ }
+ dataList = dnerSiteAreaConfigurationMapper.selectDailyChartAreaTree(req);
+ }
// 最终树
List result = new ArrayList<>();
// 1. 构建所有省份节点
diff --git a/src/main/java/com/southern/power/grid/utils/TimeUtil.java b/src/main/java/com/southern/power/grid/utils/TimeUtil.java
index d3a81ab..d5cc15d 100644
--- a/src/main/java/com/southern/power/grid/utils/TimeUtil.java
+++ b/src/main/java/com/southern/power/grid/utils/TimeUtil.java
@@ -22,10 +22,11 @@ public class TimeUtil {
/**
* 获取开始时间到结束时间的小时数组,仅当天的第一条数据会展示年月日
+ * 比如[2026-03-13 22:00, 23:00, 2026-03-14 00:00, 01:00]
*
* @param startTime 开始时间
* @param endTime 结束时间
- * @return
+ * @return 结果
*/
public static List generateHourList(String startTime, String endTime) {
LocalDateTime start = LocalDateTime.parse(startTime, FULL);
@@ -54,11 +55,11 @@ public class TimeUtil {
}
/**
- * 获取开始时间到结束时间的小时数组
+ * 获取开始时间到结束时间的小时数组,比如[2026-03-13 23:00, 2026-03-14 00:00, 2026-03-14 01:00]
*
* @param startTime 开始时间
* @param endTime 结束时间
- * @return
+ * @return 结果
*/
public static List generateHourListAll(String startTime, String endTime) {
LocalDateTime start = LocalDateTime.parse(startTime, FULL);
@@ -117,11 +118,46 @@ public class TimeUtil {
return beforeDay.format(formatter);
}
+ /**
+ * 获取当前时间,精确到小时,比如2026-03-17 11:00
+ *
+ * @return 字符串结果
+ */
+ public static String getCurrentHourTime() {
+ return LocalDateTime.now() // 获取当前时间
+ .withMinute(0) // 分钟设置为0
+ .withSecond(0) // 秒设置为0
+ .withNano(0) // 毫秒设置为0
+ .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00")); // 转换为字符串
+ }
+
+ /**
+ * 获取前n个小时的时间
+ *
+ * @param hourTime 指定时间,比如2026-03-17 11:00
+ * @param beforeHourNum 前n小时,比如2
+ * @return 前n小时的时间,比如2026-03-17 09:00
+ */
+ public static String getBeforeHourTime(String hourTime, int beforeHourNum) {
+ // 定义格式
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00");
+
+ // 1. 把字符串转成 LocalDateTime
+ LocalDateTime dateTime = LocalDateTime.parse(hourTime, formatter);
+
+ // 2. 减去 n 小时(核心方法)
+ LocalDateTime beforeHour = dateTime.minusHours(beforeHourNum);
+
+ // 3. 格式化返回(精确到小时,分钟固定 00)
+ return beforeHour.format(formatter);
+ }
+
public static void main(String[] args) {
-// List strings = generateHourListAll("2026-03-13 22:00", "2026-03-14 02:00");
+// List strings = generateHourList("2026-03-13 22:00", "2026-03-14 01:00");
// List strings = getBetweenDates("2026-03-10", "2026-03-14");
// String strings = getBeforeNumDays("2026-03-15", 5);
- System.out.println(14/5);
+ String beforeHourTime = getBeforeHourTime("2026-03-17 11:00", 2);
+ System.out.println(beforeHourTime);
}
private static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
diff --git a/src/main/resources/mapper/DnerSiteAreaConfigurationMapper.xml b/src/main/resources/mapper/DnerSiteAreaConfigurationMapper.xml
index a40b601..205a732 100644
--- a/src/main/resources/mapper/DnerSiteAreaConfigurationMapper.xml
+++ b/src/main/resources/mapper/DnerSiteAreaConfigurationMapper.xml
@@ -25,4 +25,37 @@
create_by, create_time, update_by, update_time
FROM dner_site_area_configuration
+
+
+
+
\ No newline at end of file