代码调整
This commit is contained in:
@@ -29,6 +29,7 @@ import com.njcn.gather.device.pojo.enums.PatternEnum;
|
||||
import com.njcn.gather.device.pojo.vo.PreDetection;
|
||||
import com.njcn.gather.device.service.IPqDevService;
|
||||
import com.njcn.gather.device.service.IPqStandardDevService;
|
||||
import com.njcn.gather.monitor.service.IPqMonitorService;
|
||||
import com.njcn.gather.plan.pojo.enums.DataSourceEnum;
|
||||
import com.njcn.gather.plan.service.IAdPlanService;
|
||||
import com.njcn.gather.storage.pojo.po.ContrastHarmonicResult;
|
||||
@@ -65,6 +66,7 @@ public class SocketContrastResponseService {
|
||||
private final IAdPlanService adPlanService;
|
||||
private final IDictDataService dictDataService;
|
||||
private final IPqDevService pqDevService;
|
||||
private final IPqMonitorService pqMonitorService;
|
||||
private final IPqStandardDevService pqStandardDevService;
|
||||
private final IDictTreeService dictTreeService;
|
||||
private final DetectionDataDealService detectionDataDealService;
|
||||
@@ -242,7 +244,6 @@ public class SocketContrastResponseService {
|
||||
FormalTestManager.devIdMapComm.putAll(FormalTestManager.devList.stream().collect(Collectors.toMap(PreDetection::getDevIP, PreDetection::getDevId)));
|
||||
FormalTestManager.devIdMapComm.putAll(FormalTestManager.standardDevList.stream().collect(Collectors.toMap(PreDetection::getDevIP, PreDetection::getDevId)));
|
||||
|
||||
|
||||
FormalTestManager.currentStep = SourceOperateCodeEnum.YJC_SBTXJY;
|
||||
}
|
||||
|
||||
@@ -1206,11 +1207,14 @@ public class SocketContrastResponseService {
|
||||
WebServiceManager.sendMsg(userId, JSON.toJSONString(webSend));
|
||||
}
|
||||
|
||||
// 获取被检设备的额定电流
|
||||
Double ratedCurrent = pqMonitorService.getRatedCurrent(devMonitorId);
|
||||
|
||||
// 是否存在电流
|
||||
boolean notHasCurrent = iDev.stream().allMatch(
|
||||
p -> p.getList().getA() != null && DetectionUtil.isZero(p.getList().getA())
|
||||
&& p.getList().getB() != null && DetectionUtil.isZero(p.getList().getB())
|
||||
&& p.getList().getC() != null && DetectionUtil.isZero(p.getList().getC()));
|
||||
p -> p.getList().getA() != null && DetectionUtil.isZero(p.getList().getA(),ratedCurrent)
|
||||
&& p.getList().getB() != null && DetectionUtil.isZero(p.getList().getB(),ratedCurrent)
|
||||
&& p.getList().getC() != null && DetectionUtil.isZero(p.getList().getC(),ratedCurrent));
|
||||
if (!notHasCurrent) {
|
||||
// 相角校验
|
||||
List<DevData.SqlDataDTO> vaUnblanceDev = getSingleMonitorSqlData(devData, DetectionCodeEnum.VA.getCode());
|
||||
|
||||
@@ -3,59 +3,138 @@ package com.njcn.gather.detection.util;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.njcn.gather.detection.pojo.po.DevData;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 检测工具类
|
||||
* <p>
|
||||
* 提供电能质量检测相关的数据处理、时间转换、统计计算等工具方法。
|
||||
* 主要功能包括:
|
||||
* <ul>
|
||||
* <li>相角矫正和标准化</li>
|
||||
* <li>设备数据时间对齐判断</li>
|
||||
* <li>时间格式转换和毫秒数计算</li>
|
||||
* <li>数值零值判断</li>
|
||||
* <li>统计数据处理(CP95分位数、部分值、平均值等)</li>
|
||||
* <li>数据排序和索引计算</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author caozehui
|
||||
* @data 2025-07-28
|
||||
* @version 1.0
|
||||
* @since 2025-07-28
|
||||
*/
|
||||
@Slf4j
|
||||
public class DetectionUtil {
|
||||
// ISO 8601格式
|
||||
/**
|
||||
* ISO 8601日期时间格式化器
|
||||
* 用于解析和格式化符合ISO 8601标准的日期时间字符串
|
||||
*/
|
||||
public static final DateTimeFormatter FORMATTER = DateTimeFormatter.ISO_DATE_TIME;
|
||||
|
||||
|
||||
/**
|
||||
* 相角矫正到统一个区间
|
||||
* 毫秒转秒的转换因子
|
||||
*/
|
||||
private static final long MILLIS_TO_SECONDS = 1000L;
|
||||
|
||||
/**
|
||||
* 时间对齐判断的容差毫秒数
|
||||
* 当两个时间戳差值小于此值时,认为时间是对齐的
|
||||
*/
|
||||
private static final long TIME_ALIGNMENT_TOLERANCE_MS = 100L;
|
||||
|
||||
/**
|
||||
* 角度相关常量
|
||||
*/
|
||||
private static final double ANGLE_180 = 180.0;
|
||||
private static final double ANGLE_360 = 360.0;
|
||||
private static final double ANGLE_MINUS_180 = -180.0;
|
||||
|
||||
/**
|
||||
* CP95算法相关常量
|
||||
*/
|
||||
private static final int CP95_DATA_SIZE_THRESHOLD = 21;
|
||||
private static final double CP95_PERCENTILE = 0.05;
|
||||
private static final int CP95_SMALL_DATA_INDEX = 1;
|
||||
|
||||
/**
|
||||
* 数据处理相关常量
|
||||
*/
|
||||
private static final int MIN_DATA_SIZE_FOR_SECTION_VALUE = 2;
|
||||
|
||||
|
||||
/**
|
||||
* 相角矫正到统一区间[-180°, 180°]
|
||||
* <p>
|
||||
* 将任意角度值标准化到[-180°, 180°]范围内,便于相角比较和计算。
|
||||
* 使用模运算处理任意大小的角度值,能正确处理超出多个360°范围的情况。
|
||||
* <p>
|
||||
* 示例:
|
||||
* <ul>
|
||||
* <li>-1080° → 0°</li>
|
||||
* <li>-900° → 180°</li>
|
||||
* <li>720° → 0°</li>
|
||||
* <li>450° → 90°</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param phase
|
||||
* @return
|
||||
* @param phase 待矫正的相角值(单位:度)
|
||||
* @return 矫正后的相角值,范围在[-180°, 180°]内
|
||||
*/
|
||||
public static Double adjustPhase(Double phase) {
|
||||
if (phase < -180) {
|
||||
return phase + 360;
|
||||
if (phase == null) {
|
||||
return null;
|
||||
}
|
||||
if (phase > 180) {
|
||||
return phase - 360;
|
||||
// 使用模运算将角度标准化到[-180, 180]范围
|
||||
double normalizedPhase = phase % ANGLE_360;
|
||||
// 处理超出[-180, 180]范围的情况
|
||||
if (normalizedPhase > ANGLE_180) {
|
||||
normalizedPhase -= ANGLE_360;
|
||||
} else if (normalizedPhase < ANGLE_MINUS_180) {
|
||||
normalizedPhase += ANGLE_360;
|
||||
}
|
||||
return phase;
|
||||
|
||||
return normalizedPhase;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断数据是否对齐
|
||||
* 判断被检设备数据与标准设备数据的时间是否对齐
|
||||
* <p>
|
||||
* 数据对齐的判断标准(满足任一条件即可):
|
||||
* 1. 将时间戳四舍五入到秒级精度后完全相等(处理跨秒边界情况)
|
||||
* 2. 两个时间戳的毫秒差值小于容差值(处理同秒内的精确对齐)
|
||||
* <p>
|
||||
* 示例:499ms vs 509ms → 四舍五入后不同秒,但差值仅10ms < 100ms → 对齐
|
||||
*
|
||||
* @param devData 被检设备数据
|
||||
* @param standardDevData 标准设备数据
|
||||
* @return
|
||||
* @param devData 被检设备数据,包含时间戳信息
|
||||
* @param standardDevData 标准设备数据,包含时间戳信息
|
||||
* @return true表示数据时间对齐,false表示不对齐
|
||||
*/
|
||||
public static boolean isAlignData(DevData devData, DevData standardDevData) {
|
||||
if (ObjectUtil.isNotNull(devData) && ObjectUtil.isNotNull(standardDevData)) {
|
||||
|
||||
// 获取两个设备数据的时间戳(毫秒)
|
||||
long devMillis = getMillis(devData.getTime());
|
||||
long standardMillis = getMillis(standardDevData.getTime());
|
||||
if (BigDecimal.valueOf(devMillis).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_HALF_UP).compareTo(BigDecimal.valueOf(standardMillis).divide(BigDecimal.valueOf(1000), 0, BigDecimal.ROUND_HALF_UP)) == 0) {
|
||||
|
||||
// 方式1:将时间戳转换为秒级精度进行比较(处理跨秒边界情况)
|
||||
BigDecimal devSeconds = BigDecimal.valueOf(devMillis).divide(BigDecimal.valueOf(MILLIS_TO_SECONDS), 0, RoundingMode.HALF_UP);
|
||||
BigDecimal standardSeconds = BigDecimal.valueOf(standardMillis).divide(BigDecimal.valueOf(MILLIS_TO_SECONDS), 0, RoundingMode.HALF_UP);
|
||||
if (devSeconds.compareTo(standardSeconds) == 0) {
|
||||
return true;
|
||||
} else if (Math.abs(devMillis - standardMillis) < 100) {
|
||||
}
|
||||
|
||||
// 方式2:毫秒级时间差小于容差值也认为是对齐的(处理精确对齐)
|
||||
if (Math.abs(devMillis - standardMillis) < TIME_ALIGNMENT_TOLERANCE_MS) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -63,167 +142,244 @@ public class DetectionUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串日期时间转换为指定格式的LocalDateTime
|
||||
* 将字符串日期时间转换为LocalDateTime对象
|
||||
* <p>
|
||||
* 使用指定的格式解析时间字符串,支持带时区的ISO 8601格式。
|
||||
* 解析时会将时间统一转换为UTC时区的LocalDateTime。
|
||||
*
|
||||
* @param dateTimeStr
|
||||
* @param formatter
|
||||
* @return
|
||||
* @param dateTimeStr 日期时间字符串,应符合指定格式
|
||||
* @param formatter 时间格式化器,用于解析字符串
|
||||
* @return 解析成功返回LocalDateTime对象,解析失败返回null
|
||||
*/
|
||||
public static LocalDateTime timeFormat(String dateTimeStr, DateTimeFormatter formatter) {
|
||||
try {
|
||||
// 使用UTC时区解析时间字符串
|
||||
ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateTimeStr, formatter.withZone(ZoneId.of("UTC")));
|
||||
LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();
|
||||
return localDateTime;
|
||||
// 转换为LocalDateTime对象
|
||||
return zonedDateTime.toLocalDateTime();
|
||||
} catch (DateTimeParseException e) {
|
||||
System.err.println("日期时间字符串格式错误: " + e.getMessage());
|
||||
log.error("日期时间字符串格式错误: {}", e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字符串日期时间对应的毫秒数
|
||||
* 获取字符串日期时间对应的UTC毫秒时间戳
|
||||
* <p>
|
||||
* 使用默认的ISO_DATE_TIME格式解析时间字符串,
|
||||
* 并转换为UTC时区的毫秒时间戳。
|
||||
*
|
||||
* @param dateTimeStr
|
||||
* @return
|
||||
* @param dateTimeStr ISO 8601格式的日期时间字符串
|
||||
* @return UTC时区的毫秒时间戳
|
||||
*/
|
||||
public static long getMillis(String dateTimeStr) {
|
||||
if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("日期时间字符串不能为空");
|
||||
}
|
||||
LocalDateTime localDateTime = timeFormat(dateTimeStr, FORMATTER);
|
||||
if (localDateTime == null) {
|
||||
throw new IllegalArgumentException("无法解析日期时间字符串: " + dateTimeStr);
|
||||
}
|
||||
return getMillis(localDateTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取LocalDateTime的所对应的毫秒数
|
||||
* 获取LocalDateTime对应的UTC毫秒时间戳
|
||||
* <p>
|
||||
* 将LocalDateTime对象转换为UTC时区的毫秒时间戳。
|
||||
*
|
||||
* @param localDateTime
|
||||
* @return
|
||||
* @param localDateTime 本地日期时间对象
|
||||
* @return UTC时区的毫秒时间戳
|
||||
*/
|
||||
public static long getMillis(LocalDateTime localDateTime) {
|
||||
if (localDateTime == null) {
|
||||
throw new IllegalArgumentException("LocalDateTime参数不能为null");
|
||||
}
|
||||
return localDateTime.atZone(ZoneId.of("UTC")).toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断value是否为0
|
||||
* 判断数值是否为零(在容差范围内)
|
||||
* <p>
|
||||
* 使用BigDecimal进行精确计算,避免浮点数精度问题。
|
||||
* 当数值的绝对值小于预设阈值(0.01)时,认为该数值为零。
|
||||
* 主要用于电流等物理量的零值判断。
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
* @param value 待判断的数值,null值被认为是零
|
||||
* @param ratedCurrent 额定电流,用于计算阈值
|
||||
* @return true表示数值为零(在容差范围内),false表示非零
|
||||
*/
|
||||
public static boolean isZero(Double value) {
|
||||
// todo 电流为0判断
|
||||
|
||||
BigDecimal bd = BigDecimal.valueOf(value);
|
||||
if (bd.subtract(BigDecimal.ZERO).abs().compareTo(BigDecimal.valueOf(0.01)) < 0) {
|
||||
public static boolean isZero(Double value, Double ratedCurrent) {
|
||||
if (value == null) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
double threshold = 0.01 * ratedCurrent;
|
||||
BigDecimal bd = BigDecimal.valueOf(value);
|
||||
return bd.subtract(BigDecimal.ZERO).abs().compareTo(BigDecimal.valueOf(threshold)) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取CP95值
|
||||
* 获取CP95分位数值
|
||||
* <p>
|
||||
* CP95表示95%分位数,即有95%的数据小于等于此值。
|
||||
* 算法逻辑:
|
||||
* <ul>
|
||||
* <li>数据量=1时:返回该数据</li>
|
||||
* <li>数据量<21时:返回第2个数据(索引1)</li>
|
||||
* <li>数据量≥21时:计算5%位置的数据(适用于从大到小排序的数据)</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param t
|
||||
* @return
|
||||
* @param t 已排序的数据列表(从大到小排序)
|
||||
* @return CP95分位数值列表,包含单个元素
|
||||
*/
|
||||
public static List<Double> getCP95Doubles(List<Double> t) {
|
||||
if (CollUtil.isNotEmpty(t)) {
|
||||
if (t.size() < 21) {
|
||||
if (t.size() == 1) {
|
||||
return t;
|
||||
}
|
||||
if (t.size() > 1) {
|
||||
return t.subList(1, 2);
|
||||
}
|
||||
} else {
|
||||
int v = (int) (t.size() * 0.5);
|
||||
return t.subList(v, v + 1);
|
||||
}
|
||||
if (CollUtil.isEmpty(t)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return t;
|
||||
|
||||
// 单个数据直接返回
|
||||
if (t.size() == 1) {
|
||||
return new ArrayList<>(t);
|
||||
}
|
||||
|
||||
// 数据量较少时,取第2个数据作为CP95值
|
||||
if (t.size() < CP95_DATA_SIZE_THRESHOLD) {
|
||||
return t.subList(CP95_SMALL_DATA_INDEX, CP95_SMALL_DATA_INDEX + 1);
|
||||
}
|
||||
|
||||
// 数据量充足时,计算真正的95%分位数
|
||||
// 由于数据已从大到小排序,95%分位数位于5%位置
|
||||
int cp95Index = (int) Math.ceil(t.size() * CP95_PERCENTILE) - 1;
|
||||
return t.subList(cp95Index, cp95Index + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取CP95值所在索引
|
||||
* 获取CP95分位数值在列表中的索引位置
|
||||
* <p>
|
||||
* 计算CP95分位数在已排序列表中的索引位置。
|
||||
* 索引计算规则与getCP95Doubles方法保持一致。
|
||||
*
|
||||
* @param t
|
||||
* @return
|
||||
* @param t 已排序的数据列表(从大到小排序)
|
||||
* @return CP95分位数的索引位置,列表为空时返回-1
|
||||
*/
|
||||
public static int getCP95Idx(List<Double> t) {
|
||||
if (CollUtil.isNotEmpty(t)) {
|
||||
if (t.size() < 21) {
|
||||
if (t.size() == 1) {
|
||||
return 0;
|
||||
}
|
||||
if (t.size() > 1) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
int v = (int) (t.size() * 0.5);
|
||||
return v;
|
||||
}
|
||||
if (CollUtil.isEmpty(t)) {
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
|
||||
// 单个数据返回索引0
|
||||
if (t.size() == 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 数据量较少时,返回索引1
|
||||
if (t.size() < CP95_DATA_SIZE_THRESHOLD) {
|
||||
return CP95_SMALL_DATA_INDEX;
|
||||
}
|
||||
|
||||
// 数据量充足时,计算95%分位数的索引位置
|
||||
// 由于数据已从大到小排序,95%分位数索引为5%位置
|
||||
return (int) Math.ceil(t.size() * CP95_PERCENTILE) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取部分值
|
||||
* 获取部分值(去除最大最小值后的数据)
|
||||
* <p>
|
||||
* 用于数据预处理,去除可能的异常值。
|
||||
* 算法逻辑:
|
||||
* <ul>
|
||||
* <li>数据量≤2时:返回原数据副本</li>
|
||||
* <li>数据量>2时:移除一个最大值和一个最小值后返回剩余数据</li>
|
||||
* </ul>
|
||||
* 注意:该方法不会修改原始列表,而是返回新的列表。
|
||||
*
|
||||
* @param t
|
||||
* @return
|
||||
* @param t 原始数据列表
|
||||
* @return 去除最大最小值后的数据列表副本
|
||||
*/
|
||||
public static List<Double> getSectionValueDoubles(List<Double> t) {
|
||||
if (CollUtil.isNotEmpty(t)) {
|
||||
if (t.size() > 2) {
|
||||
Double max = Collections.max(t);
|
||||
Double min = Collections.min(t);
|
||||
t.remove(max);
|
||||
t.remove(min);
|
||||
}
|
||||
if (CollUtil.isEmpty(t) || t.size() <= MIN_DATA_SIZE_FOR_SECTION_VALUE) {
|
||||
return new ArrayList<>(t);
|
||||
}
|
||||
return t;
|
||||
|
||||
// 创建副本避免修改原始列表
|
||||
List<Double> result = new ArrayList<>(t);
|
||||
Double max = Collections.max(result);
|
||||
Double min = Collections.min(result);
|
||||
result.remove(max);
|
||||
result.remove(min);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取平均值
|
||||
* 计算数据列表的算术平均值
|
||||
* <p>
|
||||
* 对输入的数值列表计算算术平均值,并以单元素列表形式返回。
|
||||
* 空列表会返回空列表。
|
||||
*
|
||||
* @param t
|
||||
* @return
|
||||
* @param t 数值列表
|
||||
* @return 包含平均值的单元素列表,输入为空时返回空列表
|
||||
*/
|
||||
public static List<Double> getAvgDoubles(List<Double> t) {
|
||||
if (CollUtil.isNotEmpty(t)) {
|
||||
t = Arrays.asList(t.stream().mapToDouble(Double::doubleValue).average().orElse(0.0));
|
||||
if (CollUtil.isEmpty(t)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return t;
|
||||
|
||||
// 计算列表中所有数值的算术平均值
|
||||
double average = t.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
|
||||
// 将平均值包装为单元素列表返回
|
||||
return Collections.singletonList(average);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对list进行排序,并返回排序后的索引序列
|
||||
* 对数据列表进行排序并返回原始索引序列
|
||||
* <p>
|
||||
* 使用选择排序算法对列表进行排序,同时跟踪每个元素的原始索引位置。
|
||||
* 这样可以在数据排序后仍然知道每个数据在原始列表中的位置。
|
||||
*
|
||||
* @param list
|
||||
* @param isAsc 是否升序
|
||||
* @return
|
||||
* <b>注意:</b>该方法会直接修改输入的列表。
|
||||
*
|
||||
* @param list 待排序的数据列表(会被直接修改)
|
||||
* @param isAsc 排序方式,true为升序,false为降序
|
||||
* @return 排序后各元素在原始列表中的索引位置
|
||||
*/
|
||||
public static List<Integer> sort(List<Double> list, Boolean isAsc) {
|
||||
if (CollUtil.isEmpty(list)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
if (isAsc == null) {
|
||||
throw new IllegalArgumentException("排序方式参数不能为null");
|
||||
}
|
||||
// 创建索引列表,记录每个元素的原始位置
|
||||
List<Integer> indexList = Stream.iterate(0, i -> i + 1).limit(list.size()).collect(Collectors.toList());
|
||||
// 使用选择排序算法,同时维护索引映射
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
int maxIdx = i;
|
||||
// 当前轮次要放置的目标位置
|
||||
int targetIdx = i;
|
||||
// 在未排序部分寻找最值
|
||||
for (int j = i + 1; j < list.size(); j++) {
|
||||
if (isAsc) {
|
||||
if (list.get(j) < list.get(maxIdx)) {
|
||||
maxIdx = j;
|
||||
// 升序:寻找最小值
|
||||
if (list.get(j) < list.get(targetIdx)) {
|
||||
targetIdx = j;
|
||||
}
|
||||
} else {
|
||||
if (list.get(j) > list.get(maxIdx)) {
|
||||
maxIdx = j;
|
||||
// 降序:寻找最大值
|
||||
if (list.get(j) > list.get(targetIdx)) {
|
||||
targetIdx = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (maxIdx != i) {
|
||||
// 交换数据值和对应的索引
|
||||
if (targetIdx != i) {
|
||||
// 交换数据值
|
||||
double temp = list.get(i);
|
||||
list.set(i, list.get(maxIdx));
|
||||
list.set(maxIdx, temp);
|
||||
list.set(i, list.get(targetIdx));
|
||||
list.set(targetIdx, temp);
|
||||
|
||||
// 交换对应的原始索引
|
||||
int tempIdx = indexList.get(i);
|
||||
indexList.set(i, indexList.get(maxIdx));
|
||||
indexList.set(maxIdx, tempIdx);
|
||||
indexList.set(i, indexList.get(targetIdx));
|
||||
indexList.set(targetIdx, tempIdx);
|
||||
}
|
||||
}
|
||||
return indexList;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.njcn.gather.monitor.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.gather.monitor.pojo.param.PqMonitorParam;
|
||||
import com.njcn.gather.monitor.pojo.po.PqMonitor;
|
||||
@@ -62,4 +61,18 @@ public interface IPqMonitorService extends IService<PqMonitor> {
|
||||
* @param monitorList
|
||||
*/
|
||||
void reverseVisualizeMonitor(List<PqMonitor> monitorList);
|
||||
|
||||
/**
|
||||
* 根据被检设备id获取额定电流
|
||||
* @param devMonitorId 被检设备id
|
||||
* @return 额定电流
|
||||
*/
|
||||
Double getRatedCurrent(String devMonitorId);
|
||||
|
||||
/**
|
||||
* 根据被检设备id获取额定电压
|
||||
* @param devMonitorId 被检设备id
|
||||
* @return 额定电压
|
||||
*/
|
||||
Double getRatedVoltage(String devMonitorId);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.njcn.gather.monitor.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
@@ -84,4 +85,30 @@ public class PqMonitorServiceImpl extends ServiceImpl<PqMonitorMapper, PqMonitor
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRatedCurrent(String devMonitorId) {
|
||||
PqMonitor pqMonitor = this.baseMapper.selectById(devMonitorId);
|
||||
if (ObjectUtil.isNotNull(pqMonitor)) {
|
||||
String ct = pqMonitor.getCt();
|
||||
if(StrUtil.isNotBlank(ct) && ct.contains(StrUtil.COLON)){
|
||||
String[] ctArray = ct.split(StrUtil.COLON);
|
||||
return Double.parseDouble(ctArray[1]);
|
||||
}
|
||||
}
|
||||
throw new BusinessException(DetectionResponseEnum.RATED_CT_ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double getRatedVoltage(String devMonitorId) {
|
||||
PqMonitor pqMonitor = this.baseMapper.selectById(devMonitorId);
|
||||
if (ObjectUtil.isNotNull(pqMonitor)) {
|
||||
String pt = pqMonitor.getPt();
|
||||
if(StrUtil.isNotBlank(pt) && pt.contains(StrUtil.COLON)){
|
||||
String[] ptArray = pt.split(StrUtil.COLON);
|
||||
return Double.parseDouble(ptArray[1]);
|
||||
}
|
||||
}
|
||||
throw new BusinessException(DetectionResponseEnum.RATED_PT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ public enum DetectionResponseEnum {
|
||||
* A02000 ~ A02
|
||||
*/
|
||||
DEV_TYPE_NAME_REPEAT("A02000", "设备类型名称重复"),
|
||||
RATED_CT_ERROR("A02001", "解析监测点的额定电流失败"),
|
||||
RATED_PT_ERROR("A02001", "解析监测点的额定电压失败"),
|
||||
SOURCE_BOUND_NOT_DELETE("A02001", "源已被计划所绑定,无法删除!"),
|
||||
SCRIPT_BOUND_NOT_DELETE("A02003", "脚本已被计划所绑定,无法删除!"),
|
||||
RAW_DATA_NOT_EXIST("A02004", "原始数据不存在"),
|
||||
|
||||
Reference in New Issue
Block a user