2026-03-18提交:部分高级筛选代码

This commit is contained in:
junzhangfm 2026-03-18 10:59:02 +08:00
parent f8454295e9
commit 4efced3ec7
11 changed files with 308 additions and 21 deletions

View File

@ -79,6 +79,12 @@
<version>5.8.25</version> <version>5.8.25</version>
</dependency> </dependency>
<!-- 校验依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Spring Boot Test --> <!-- Spring Boot Test -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>

View File

@ -11,6 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid;
import java.util.List; import java.util.List;
/** /**
@ -36,9 +37,8 @@ public class DnerController {
private IDnerSiteAreaConfigurationService dnerSiteAreaConfigurationService; private IDnerSiteAreaConfigurationService dnerSiteAreaConfigurationService;
@PostMapping("/area-tree/query") @PostMapping("/area-tree/query")
public Result<List<AreaTreeVO>> queryAreaTree(@RequestBody AreaTreeReq req) { public Result<List<AreaTreeVO>> queryAreaTree(@RequestBody @Valid AreaTreeReq req) {
// TODO 使用POST请求后续新增高级筛选时加入请求入参 return Result.success(dnerSiteAreaConfigurationService.queryAreaTree(req));
return Result.success(dnerSiteAreaConfigurationService.queryAreaTree());
} }
/** /**

View File

@ -1,8 +1,10 @@
package com.southern.power.grid.dao; 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.AreaTreeReq;
import com.southern.power.grid.entity.DnerSiteAreaConfiguration; import com.southern.power.grid.entity.DnerSiteAreaConfiguration;
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.List;
@ -15,4 +17,8 @@ import java.util.List;
@Mapper @Mapper
public interface DnerSiteAreaConfigurationMapper extends BaseMapper<DnerSiteAreaConfiguration> { public interface DnerSiteAreaConfigurationMapper extends BaseMapper<DnerSiteAreaConfiguration> {
List<DnerSiteAreaConfiguration> selectAll(); List<DnerSiteAreaConfiguration> selectAll();
List<DnerSiteAreaConfiguration> selectHourlyChartAreaTree(@Param("param") AreaTreeReq req);
List<DnerSiteAreaConfiguration> selectDailyChartAreaTree(@Param("param") AreaTreeReq req);
} }

View File

@ -2,6 +2,8 @@ package com.southern.power.grid.entity;
import lombok.Data; import lombok.Data;
import javax.validation.constraints.NotBlank;
/** /**
* 区域树请求入参 * 区域树请求入参
* *
@ -10,5 +12,112 @@ import lombok.Data;
**/ **/
@Data @Data
public class AreaTreeReq { 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;
} }

View File

@ -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;
}
}

View File

@ -1,11 +1,14 @@
package com.southern.power.grid.enums; package com.southern.power.grid.enums;
import lombok.Getter;
/** /**
* 导入任务状态枚举 * 导入任务状态枚举
* *
* @author: junzhangfm * @author: junzhangfm
* @date: 2026/3/16 * @date: 2026/3/16
**/ **/
@Getter
public enum ImportTaskStatusEnum { public enum ImportTaskStatusEnum {
// 定义 5 个状态编码 + 描述 // 定义 5 个状态编码 + 描述
WAITING("WAITING", "等待执行"), WAITING("WAITING", "等待执行"),
@ -16,6 +19,7 @@ public enum ImportTaskStatusEnum {
// 状态值存入数据库的值 // 状态值存入数据库的值
private final String code; private final String code;
// 状态描述 // 状态描述
private final String desc; private final String desc;
@ -24,13 +28,4 @@ public enum ImportTaskStatusEnum {
this.desc = desc; this.desc = desc;
} }
// 获取状态值你要的就是这个
public String getCode() {
return code;
}
// 获取描述
public String getDesc() {
return desc;
}
} }

View File

@ -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<String, Object> handleValidException(BindException e) {
FieldError fieldError = e.getBindingResult().getFieldError();
String msg = "参数校验失败,请核对入参";
if (!Objects.isNull(fieldError)) {
msg = fieldError.getField() + ":" + fieldError.getDefaultMessage();
}
Map<String, Object> map = new HashMap<>();
map.put("code", 400);
map.put("msg", msg);
return map;
}
}

View File

@ -1,7 +1,7 @@
package com.southern.power.grid.service; package com.southern.power.grid.service;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.extension.service.IService; 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.AreaTreeVO;
import com.southern.power.grid.entity.DnerSiteAreaConfiguration; import com.southern.power.grid.entity.DnerSiteAreaConfiguration;
@ -19,5 +19,5 @@ public interface IDnerSiteAreaConfigurationService extends IService<DnerSiteArea
* *
* @return 结果 * @return 结果
*/ */
List<AreaTreeVO> queryAreaTree(); List<AreaTreeVO> queryAreaTree(AreaTreeReq req);
} }

View File

@ -2,12 +2,18 @@ package com.southern.power.grid.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.southern.power.grid.dao.DnerSiteAreaConfigurationMapper; 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.AreaTreeVO;
import com.southern.power.grid.entity.DnerSiteAreaConfiguration; 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.service.IDnerSiteAreaConfigurationService;
import com.southern.power.grid.utils.TimeUtil;
import lombok.NonNull; import lombok.NonNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
/** /**
@ -20,10 +26,44 @@ import java.util.*;
public class DnerSiteAreaConfigurationServiceImpl public class DnerSiteAreaConfigurationServiceImpl
extends ServiceImpl<DnerSiteAreaConfigurationMapper, DnerSiteAreaConfiguration> extends ServiceImpl<DnerSiteAreaConfigurationMapper, DnerSiteAreaConfiguration>
implements IDnerSiteAreaConfigurationService { implements IDnerSiteAreaConfigurationService {
@Autowired
private DnerSiteAreaConfigurationMapper dnerSiteAreaConfigurationMapper;
@Override @Override
public List<AreaTreeVO> queryAreaTree() { public List<AreaTreeVO> 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<DnerSiteAreaConfiguration> dataList = list(); List<DnerSiteAreaConfiguration> 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<AreaTreeVO> result = new ArrayList<>(); List<AreaTreeVO> result = new ArrayList<>();
// 1. 构建所有省份节点 // 1. 构建所有省份节点

View File

@ -22,10 +22,11 @@ public class TimeUtil {
/** /**
* 获取开始时间到结束时间的小时数组仅当天的第一条数据会展示年月日 * 获取开始时间到结束时间的小时数组仅当天的第一条数据会展示年月日
* 比如[2026-03-13 22:00, 23:00, 2026-03-14 00:00, 01:00]
* *
* @param startTime 开始时间 * @param startTime 开始时间
* @param endTime 结束时间 * @param endTime 结束时间
* @return * @return 结果
*/ */
public static List<String> generateHourList(String startTime, String endTime) { public static List<String> generateHourList(String startTime, String endTime) {
LocalDateTime start = LocalDateTime.parse(startTime, FULL); 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 startTime 开始时间
* @param endTime 结束时间 * @param endTime 结束时间
* @return * @return 结果
*/ */
public static List<String> generateHourListAll(String startTime, String endTime) { public static List<String> generateHourListAll(String startTime, String endTime) {
LocalDateTime start = LocalDateTime.parse(startTime, FULL); LocalDateTime start = LocalDateTime.parse(startTime, FULL);
@ -117,11 +118,46 @@ public class TimeUtil {
return beforeDay.format(formatter); 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) { public static void main(String[] args) {
// List<String> strings = generateHourListAll("2026-03-13 22:00", "2026-03-14 02:00"); // List<String> strings = generateHourList("2026-03-13 22:00", "2026-03-14 01:00");
// List<String> strings = getBetweenDates("2026-03-10", "2026-03-14"); // List<String> strings = getBetweenDates("2026-03-10", "2026-03-14");
// String strings = getBeforeNumDays("2026-03-15", 5); // 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"); private static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

View File

@ -25,4 +25,37 @@
create_by, create_time, update_by, update_time create_by, create_time, update_by, update_time
FROM dner_site_area_configuration FROM dner_site_area_configuration
</select> </select>
<select id="selectHourlyChartAreaTree" resultMap="BaseResultMap">
SELECT
t1.id, t1.province, t1.province_code, t1.city, t1.city_code, t1.district, t1.district_code,
t1.create_by, t1.create_time, t1.update_by, t1.update_time
FROM dner_site_area_configuration t1
<where>
<choose>
<when test="param.advancedFilterFlag == '1'">
<if test="param.rainPastTime != null and param.rainPastTime != 0">
# 过去 X 小时累计降雨量超过 Y mm
EXISTS (
select 1
from dner_hourly_power_outage_event t2
where t1.district_code = t2.org_code and )
</if>
</when>
<otherwise>
# 过滤得到已存在数据的分时图
EXISTS (select 1 from dner_hourly_power_outage_event t2 where t1.district_code = t2.org_code)
</otherwise>
</choose>
</where>
</select>
<select id="selectDailyChartAreaTree" resultMap="BaseResultMap">
SELECT
t1.id, t1.province, t1.province_code, t1.city, t1.city_code, t1.district, t1.district_code,
t1.create_by, t1.create_time, t1.update_by, t1.update_time
FROM dner_site_area_configuration t1
WHERE EXISTS (select 1 from dner_daily_power_outage_event t2 where t1.district_code = t2.org_code);
</select>
</mapper> </mapper>