feat(event): 新增压降落点区域判定功能
- 在EventAnalysisService中添加determineDropZone方法用于判定压降落点区域 - 实现压降落点区域判定逻辑,支持A/B/C/D四个区域的分类判断 - 添加精确的数值范围匹配算法,使用BigDecimal确保计算精度 - 集成日志记录功能,便于问题排查和监控 - 在RedisUtil中新增scanKeysByPattern方法支持模糊查询key功能 - 优化代码结构,移除冗余的导入包和空行 - 更新类级别的注解配置,添加@Slf4j注解支持日志功能
This commit is contained in:
@@ -347,6 +347,30 @@ public class RedisUtil {
|
|||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据key模糊查询,并取出所有符合条件的key集合
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
|
||||||
|
public Set<String> scanKeysByPattern(String pattern, int count) {
|
||||||
|
Set<String> keys = new HashSet<>();
|
||||||
|
ScanOptions options = ScanOptions.scanOptions()
|
||||||
|
.match(pattern)
|
||||||
|
.count(count)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Cursor<byte[]> cursor = redisTemplate.getConnectionFactory()
|
||||||
|
.getConnection()
|
||||||
|
.scan(options)) {
|
||||||
|
while (cursor.hasNext()) {
|
||||||
|
keys.add(new String(cursor.next()));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("扫描Redis keys失败", e);
|
||||||
|
}
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据切库
|
* 数据切库
|
||||||
* @param dbIndex
|
* @param dbIndex
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.njcn.event.common.service;
|
package com.njcn.event.common.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.njcn.event.pojo.param.*;
|
import com.njcn.event.pojo.param.EventBaseParam;
|
||||||
|
import com.njcn.event.pojo.param.StatisticsParam;
|
||||||
import com.njcn.event.pojo.vo.*;
|
import com.njcn.event.pojo.vo.*;
|
||||||
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,8 +79,6 @@ public interface EventAnalysisService {
|
|||||||
*/
|
*/
|
||||||
Page<WaveTypeVO> getMonitorEventAnalyseQuery(EventBaseParam eventBaseParam);
|
Page<WaveTypeVO> getMonitorEventAnalyseQuery(EventBaseParam eventBaseParam);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*监测点事件波形下载
|
*监测点事件波形下载
|
||||||
* @author zbj
|
* @author zbj
|
||||||
@@ -88,6 +86,20 @@ public interface EventAnalysisService {
|
|||||||
*/
|
*/
|
||||||
//HttpServletResponse downloadMonitorEventWaveFile(WaveFileParam waveFileParam, HttpServletResponse response) throws Exception;
|
//HttpServletResponse downloadMonitorEventWaveFile(WaveFileParam waveFileParam, HttpServletResponse response) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判定压降落点区域
|
||||||
|
* <p>
|
||||||
|
* 入参:
|
||||||
|
* eventValue 特征幅值(百分比形式,如 "80.5" 表示 80.5%),内部 /100 得到 VVm(0~1)
|
||||||
|
* persistTime 持续时间(秒)
|
||||||
|
* <p>
|
||||||
|
* 优先规则:
|
||||||
|
* 1) 持续时间 < 0.001 秒 或 VVm = 0 → A区
|
||||||
|
* 2) 按区间表逐行匹配(左闭右开 [下限, 上限))
|
||||||
|
* 3) 都不匹配返回 null,由调用方走兜底
|
||||||
|
*
|
||||||
|
* @return 区域名(A区/B区/C区/D区);解析失败或未匹配返回 null
|
||||||
|
*/
|
||||||
|
String determineDropZone(String eventValue, String persistTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import cn.hutool.core.bean.BeanUtil;
|
|||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.njcn.common.config.GeneralInfo;
|
import com.njcn.common.config.GeneralInfo;
|
||||||
@@ -13,6 +12,7 @@ import com.njcn.common.pojo.response.HttpResult;
|
|||||||
import com.njcn.device.pq.api.LineFeignClient;
|
import com.njcn.device.pq.api.LineFeignClient;
|
||||||
import com.njcn.device.pq.pojo.vo.AreaLineInfoVO;
|
import com.njcn.device.pq.pojo.vo.AreaLineInfoVO;
|
||||||
import com.njcn.device.pq.pojo.vo.LineDetailDataVO;
|
import com.njcn.device.pq.pojo.vo.LineDetailDataVO;
|
||||||
|
import com.njcn.event.common.service.EventAnalysisService;
|
||||||
import com.njcn.event.common.service.EventDetailService;
|
import com.njcn.event.common.service.EventDetailService;
|
||||||
import com.njcn.event.enums.EventResponseEnum;
|
import com.njcn.event.enums.EventResponseEnum;
|
||||||
import com.njcn.event.file.pojo.enums.WaveFileResponseEnum;
|
import com.njcn.event.file.pojo.enums.WaveFileResponseEnum;
|
||||||
@@ -21,19 +21,20 @@ import com.njcn.event.pojo.param.StatisticsParam;
|
|||||||
import com.njcn.event.pojo.po.EventDetail;
|
import com.njcn.event.pojo.po.EventDetail;
|
||||||
import com.njcn.event.pojo.po.RmpEventDetailPO;
|
import com.njcn.event.pojo.po.RmpEventDetailPO;
|
||||||
import com.njcn.event.pojo.vo.*;
|
import com.njcn.event.pojo.vo.*;
|
||||||
import com.njcn.event.common.service.EventAnalysisService;
|
|
||||||
import com.njcn.influx.utils.InfluxDbUtils;
|
import com.njcn.influx.utils.InfluxDbUtils;
|
||||||
import com.njcn.system.api.DicDataFeignClient;
|
import com.njcn.system.api.DicDataFeignClient;
|
||||||
import com.njcn.system.enums.DicDataEnum;
|
import com.njcn.system.enums.DicDataEnum;
|
||||||
import com.njcn.system.enums.DicDataTypeEnum;
|
import com.njcn.system.enums.DicDataTypeEnum;
|
||||||
import com.njcn.system.pojo.po.DictData;
|
import com.njcn.system.pojo.po.DictData;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.influxdb.dto.QueryResult;
|
import org.influxdb.dto.QueryResult;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.text.ParseException;
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
@@ -51,6 +52,7 @@ import java.util.zip.ZipOutputStream;
|
|||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@Slf4j
|
||||||
public class EventAnalysisServiceImpl implements EventAnalysisService {
|
public class EventAnalysisServiceImpl implements EventAnalysisService {
|
||||||
|
|
||||||
// 定义阈值常量(单位:百分比)
|
// 定义阈值常量(单位:百分比)
|
||||||
@@ -1727,6 +1729,75 @@ public class EventAnalysisServiceImpl implements EventAnalysisService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String determineDropZone(String eventValue, String persistTime) {
|
||||||
|
if (eventValue == null || eventValue.trim().isEmpty()
|
||||||
|
|| persistTime == null || persistTime.trim().isEmpty()) {
|
||||||
|
log.warn("判定压降落点区域入参为空,eventValue={}, persistTime={}", eventValue, persistTime);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
BigDecimal vvm;
|
||||||
|
BigDecimal vvtm;
|
||||||
|
try {
|
||||||
|
// params[3] 是百分比(如 "80.5"),/100 得到 0~1 的 VVm
|
||||||
|
vvm = new BigDecimal(eventValue.trim()).divide(new BigDecimal("100"), 6, RoundingMode.HALF_UP);
|
||||||
|
vvtm = new BigDecimal(persistTime.trim());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("判定压降落点区域入参解析失败,eventValue={}, persistTime={}", eventValue, persistTime, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1) 超短脉冲 或 完全失压 默认 A 区
|
||||||
|
if (vvtm.compareTo(new BigDecimal("0.001")) < 0
|
||||||
|
|| vvm.compareTo(BigDecimal.ZERO) == 0) {
|
||||||
|
return "A区";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) 区间表(左闭右开)
|
||||||
|
// A区
|
||||||
|
if (inRange(vvm, "0.9", "1") && inRange(vvtm, "0.001", "60")) {
|
||||||
|
return "A区";
|
||||||
|
}
|
||||||
|
if (inRange(vvm, "0", "0.9") && inRange(vvtm, "0.001", "0.05")) {
|
||||||
|
return "A区";
|
||||||
|
}
|
||||||
|
// B区
|
||||||
|
if (inRange(vvm, "0.5", "0.7") && inRange(vvtm, "0.05", "0.2")) {
|
||||||
|
return "B区";
|
||||||
|
}
|
||||||
|
if (inRange(vvm, "0.7", "0.8") && inRange(vvtm, "0.05", "0.5")) {
|
||||||
|
return "B区";
|
||||||
|
}
|
||||||
|
if (inRange(vvm, "0.8", "0.9") && inRange(vvtm, "0.05", "60")) {
|
||||||
|
return "B区";
|
||||||
|
}
|
||||||
|
// C区
|
||||||
|
if (inRange(vvm, "0", "0.5") && inRange(vvtm, "0.05", "1")) {
|
||||||
|
return "C区";
|
||||||
|
}
|
||||||
|
if (inRange(vvm, "0.5", "0.7") && inRange(vvtm, "0.2", "1")) {
|
||||||
|
return "C区";
|
||||||
|
}
|
||||||
|
if (inRange(vvm, "0.7", "0.8") && inRange(vvtm, "0.5", "1")) {
|
||||||
|
return "C区";
|
||||||
|
}
|
||||||
|
// D区
|
||||||
|
if (inRange(vvm, "0", "0.8") && inRange(vvtm, "1", "60")) {
|
||||||
|
return "D区";
|
||||||
|
}
|
||||||
|
|
||||||
|
log.warn("压降落点区域未匹配任何规则,eventValue={}, persistTime={}", eventValue, persistTime);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 左闭右开区间判断:lowerInclusive ≤ value < upperExclusive
|
||||||
|
*/
|
||||||
|
private boolean inRange(BigDecimal value, String lowerInclusive, String upperExclusive) {
|
||||||
|
return value.compareTo(new BigDecimal(lowerInclusive)) >= 0
|
||||||
|
&& value.compareTo(new BigDecimal(upperExclusive)) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监测点事件波形下载
|
* 监测点事件波形下载
|
||||||
|
|||||||
Reference in New Issue
Block a user