正式检测-收取数据、原始数据组装和入库、配对关系入库、误差计算逻辑

This commit is contained in:
caozehui
2025-08-18 16:15:35 +08:00
parent 257d0b3af8
commit c9bf604a33
48 changed files with 1429 additions and 964 deletions

View File

@@ -9,7 +9,6 @@ import com.njcn.gather.detection.pojo.param.SimulateDetectionParam;
import com.njcn.gather.detection.service.PreDetectionService; import com.njcn.gather.detection.service.PreDetectionService;
import com.njcn.web.controller.BaseController; import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.HttpResultUtil; import com.njcn.web.utils.HttpResultUtil;
import com.njcn.web.utils.RequestUtil;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
@@ -18,6 +17,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.Map;
/** /**
* @author chendaofei * @author chendaofei
@@ -143,4 +144,20 @@ public class PreDetectionController extends BaseController {
preDetectionService.startContrastTest(param); preDetectionService.startContrastTest(param);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
} }
/**
* 获取比对检测的监测次数信息
*
* @param planId
* @return
*/
@GetMapping("/getContrastTestNumInfo")
@OperateInfo
@ApiOperation("获取比对检测的检测次数信息")
@ApiImplicitParam(name = "planId", value = "计划ID", required = true)
public HttpResult<Map<Integer, Integer>> getContrastTestNumInfo(@RequestParam("planId") String planId) {
String methodDescribe = getMethodDescribe("getContrastTestNumInfo");
Map<Integer, Integer> result = preDetectionService.getContrastTestNumInfo(planId);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
} }

View File

@@ -57,8 +57,6 @@ import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import static com.njcn.gather.detection.util.socket.FormalTestManager.harmonicRelationMap;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -1715,9 +1713,6 @@ public class SocketDevResponseService {
if (param.getTestItemList().get(1)) { if (param.getTestItemList().get(1)) {
initXiManager(param); initXiManager(param);
} }
harmonicRelationMap.put(DetectionCodeEnum.V2_50.getCode(), DetectionCodeEnum.U1.getCode());
harmonicRelationMap.put(DetectionCodeEnum.I2_50.getCode(), DetectionCodeEnum.I1.getCode());
} }
//初始化系数校验参数 //初始化系数校验参数
@@ -1782,6 +1777,9 @@ public class SocketDevResponseService {
System.out.println("原始数据插入数据库开始执行========================================="); System.out.println("原始数据插入数据库开始执行=========================================");
List<SimAndDigNonHarmonicResult> simAndDigNonHarmonicResultList = new ArrayList<>(); List<SimAndDigNonHarmonicResult> simAndDigNonHarmonicResultList = new ArrayList<>();
List<SimAndDigHarmonicResult> adHarmonicResultList = new ArrayList<>(); List<SimAndDigHarmonicResult> adHarmonicResultList = new ArrayList<>();
Map<String, String> harmonicRelationMap = new HashMap<>();
harmonicRelationMap.put(DetectionCodeEnum.V2_50.getCode(), DetectionCodeEnum.U1.getCode());
harmonicRelationMap.put(DetectionCodeEnum.I2_50.getCode(), DetectionCodeEnum.I1.getCode());
for (DevData data : devDataList) { for (DevData data : devDataList) {
LocalDateTime localDateTime = DetectionUtil.timeFormat(data.getTime(), DetectionUtil.FORMATTER); LocalDateTime localDateTime = DetectionUtil.timeFormat(data.getTime(), DetectionUtil.FORMATTER);
if (Objects.nonNull(localDateTime)) { if (Objects.nonNull(localDateTime)) {

View File

@@ -0,0 +1,11 @@
package com.njcn.gather.detection.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import com.njcn.gather.detection.pojo.po.AdPair;
/**
* @author caozehui
* @data 2025-08-18
*/
public interface AdPairMapper extends MPJBaseMapper<AdPair> {
}

View File

@@ -0,0 +1,29 @@
package com.njcn.gather.detection.pojo.dto;
import com.njcn.gather.err.pojo.po.PqErrSysDtls;
import lombok.Data;
/**
* @author caozehui
* @data 2025-08-12
*/
@Data
public class ConditionDataDTO {
/**
* 某一相别且某一个误差条件范围内的被检色设备数据
*/
private Double devData;
/**
* 某一相别且某一个误差条件范围内的标准设备数据
*/
private Double stdDevData;
/**
* 与上面数据所对应的误差体系详情
*/
private PqErrSysDtls pqErrSysDtls;
}

View File

@@ -0,0 +1,16 @@
package com.njcn.gather.detection.pojo.dto;
import lombok.Data;
/**
* @author caozehui
* @data 2025-08-12
*/
@Data
public class HarmonicConditionDataDTO extends ConditionDataDTO {
/**
* (间谐波)谐波次数
*/
private Double harmonicNum;
}

View File

@@ -13,6 +13,7 @@ public enum DetectionCodeEnum {
FREQ("FREQ", "频率"), FREQ("FREQ", "频率"),
VRMS("VRMS", "相电压有效值"), VRMS("VRMS", "相电压有效值"),
LINE_VRMS("LINE_VRMS", "线电压有效值"),
DELTA_V("DELTA_V", "电压偏差"), DELTA_V("DELTA_V", "电压偏差"),
VA("VA", "电压相角"), VA("VA", "电压相角"),
U1("U1", "基波电压"), U1("U1", "基波电压"),
@@ -34,7 +35,9 @@ public enum DetectionCodeEnum {
STAR("Star","星型接线"), STAR("Star","星型接线"),
DELTA("Delta","角型接线"); DELTA("Delta","角型接线"),
REAL_PREFIX("real$", "实时数据前缀");
private final String code; private final String code;
private final String message; private final String message;

View File

@@ -0,0 +1,24 @@
package com.njcn.gather.detection.pojo.enums;
import lombok.Getter;
/**
* @author caozehui
* @data 2025-08-13
*/
@Getter
public enum ResultEnum {
QUALIFIED(1, "符合"),
NOT_QUALIFIED(2, "不符合"),
NETWORK_TIMEOUT(3, "网络超时"),
NO_ERROR_SYS(4, "不在误差条件范围内"),
NO_COMPARE_ERROR_SYS(5, "不参与误差比较");
private int value;
private String msg;
ResultEnum(int value, String msg) {
this.value = value;
this.msg = msg;
}
}

View File

@@ -41,4 +41,9 @@ public class ContrastDetectionParam {
* 检测项列表。第一个元素为预检测、第二个元素为系数校准、第三个元素为正式检测 * 检测项列表。第一个元素为预检测、第二个元素为系数校准、第三个元素为正式检测
*/ */
private List<Boolean> testItemList; private List<Boolean> testItemList;
/**
* 当前检测次数
*/
private Integer num;
} }

View File

@@ -73,4 +73,9 @@ public class PreDetectionParam {
* 检测项列表。第一个元素为预检测、第二个元素为系数校准、第三个元素为正式检测 * 检测项列表。第一个元素为预检测、第二个元素为系数校准、第三个元素为正式检测
*/ */
private List<Boolean> testItemList; private List<Boolean> testItemList;
/**
* 第几次监测
*/
private Integer num;
} }

View File

@@ -0,0 +1,24 @@
package com.njcn.gather.detection.pojo.po;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
/**
* @author caozehui
* @data 2025-08-18
*/
@Data
@TableName("ad_pair")
public class AdPair implements Serializable {
private String id;
private String planId;
private Integer num;
private String devMonitorId;
private String stdDevMonitorId;
}

View File

@@ -13,7 +13,7 @@ import java.util.List;
@Data @Data
public class AlignDataVO { public class AlignDataVO {
private String devName; private String stdDevName;
private List<ChannelData> channelDataList; private List<ChannelData> channelDataList;
@@ -24,11 +24,11 @@ public class AlignDataVO {
@NoArgsConstructor @NoArgsConstructor
public static class ChannelData { public static class ChannelData {
// 被检设备通道号 // 标准设备通道号
private String devNum; private String stdDevNum;
// 与之对应的标准设备名称_通道号 // 与之对应的被检设备名称_通道号
private String standardDevInfo; private String devInfo;
// 数据 // 数据
private List<RawData> dataList; private List<RawData> dataList;

View File

@@ -48,4 +48,9 @@ public class DetectionData {
* 单位 * 单位
*/ */
private String unit; private String unit;
/**
* 误差体系详情ID(比对式使用)
*/
private String errorDtlId;
} }

View File

@@ -1,10 +1,7 @@
package com.njcn.gather.detection.pojo.vo; package com.njcn.gather.detection.pojo.vo;
import io.swagger.models.auth.In;
import lombok.Data; import lombok.Data;
import java.util.List;
/** /**
* @Author: cdf * @Author: cdf
* @CreateTime: 2024-12-26 * @CreateTime: 2024-12-26
@@ -13,6 +10,11 @@ import java.util.List;
@Data @Data
public class DevLineTestResult { public class DevLineTestResult {
/**
* 检测项code
*/
private String scriptName;
private String deviceId; private String deviceId;
private String deviceName; private String deviceName;

View File

@@ -0,0 +1,11 @@
package com.njcn.gather.detection.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.njcn.gather.detection.pojo.po.AdPair;
/**
* @author caozehui
* @data 2025-08-18
*/
public interface IAdPariService extends IService<AdPair> {
}

View File

@@ -4,6 +4,8 @@ import com.njcn.gather.detection.pojo.param.ContrastDetectionParam;
import com.njcn.gather.detection.pojo.param.PreDetectionParam; import com.njcn.gather.detection.pojo.param.PreDetectionParam;
import com.njcn.gather.detection.pojo.param.SimulateDetectionParam; import com.njcn.gather.detection.pojo.param.SimulateDetectionParam;
import java.util.Map;
/** /**
* @author wr * @author wr
@@ -56,4 +58,12 @@ public interface PreDetectionService {
* @param param * @param param
*/ */
void startContrastTest(ContrastDetectionParam param); void startContrastTest(ContrastDetectionParam param);
/**
* 获取比对式检测次数信息
*
* @param planId
* @return
*/
Map<Integer, Integer> getContrastTestNumInfo(String planId);
} }

View File

@@ -0,0 +1,17 @@
package com.njcn.gather.detection.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.gather.detection.mapper.AdPairMapper;
import com.njcn.gather.detection.pojo.po.AdPair;
import com.njcn.gather.detection.service.IAdPariService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
* @author caozehui
* @data 2025-08-18
*/
@Service
@RequiredArgsConstructor
public class AdPairServiceImpl extends ServiceImpl<AdPairMapper, AdPair> implements IAdPariService {
}

View File

@@ -6,6 +6,7 @@ import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.db.mybatisplus.handler.DynamicTableNameHandler;
import com.njcn.gather.detection.handler.SocketContrastResponseService; import com.njcn.gather.detection.handler.SocketContrastResponseService;
import com.njcn.gather.detection.handler.SocketDevResponseService; import com.njcn.gather.detection.handler.SocketDevResponseService;
import com.njcn.gather.detection.handler.SocketSourceResponseService; import com.njcn.gather.detection.handler.SocketSourceResponseService;
@@ -22,7 +23,6 @@ import com.njcn.gather.detection.util.socket.CnSocketUtil;
import com.njcn.gather.detection.util.socket.FormalTestManager; import com.njcn.gather.detection.util.socket.FormalTestManager;
import com.njcn.gather.detection.util.socket.SocketManager; import com.njcn.gather.detection.util.socket.SocketManager;
import com.njcn.gather.detection.util.socket.websocket.WebServiceManager; import com.njcn.gather.detection.util.socket.websocket.WebServiceManager;
import com.njcn.web.utils.RequestUtil;
import com.njcn.gather.device.pojo.po.PqDev; import com.njcn.gather.device.pojo.po.PqDev;
import com.njcn.gather.device.pojo.vo.PreDetection; import com.njcn.gather.device.pojo.vo.PreDetection;
import com.njcn.gather.device.service.IPqDevService; import com.njcn.gather.device.service.IPqDevService;
@@ -37,8 +37,15 @@ import com.njcn.gather.script.service.IPqScriptCheckDataService;
import com.njcn.gather.script.service.IPqScriptDtlsService; import com.njcn.gather.script.service.IPqScriptDtlsService;
import com.njcn.gather.source.pojo.po.SourceInitialize; import com.njcn.gather.source.pojo.po.SourceInitialize;
import com.njcn.gather.source.service.IPqSourceService; import com.njcn.gather.source.service.IPqSourceService;
import com.njcn.gather.storage.pojo.po.ContrastHarmonicResult;
import com.njcn.gather.storage.pojo.po.ContrastNonHarmonicResult;
import com.njcn.gather.storage.service.ContrastHarmonicService;
import com.njcn.gather.storage.service.ContrastNonHarmonicService;
import com.njcn.gather.system.cfg.pojo.po.SysTestConfig;
import com.njcn.gather.system.cfg.service.ISysTestConfigService;
import com.njcn.gather.system.dictionary.pojo.enums.DictDataEnum; import com.njcn.gather.system.dictionary.pojo.enums.DictDataEnum;
import com.njcn.gather.system.dictionary.service.IDictDataService; import com.njcn.gather.system.dictionary.service.IDictDataService;
import com.njcn.web.utils.RequestUtil;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -55,7 +62,6 @@ import java.util.stream.Collectors;
public class PreDetectionServiceImpl implements PreDetectionService { public class PreDetectionServiceImpl implements PreDetectionService {
private final String stepTag = "&&"; private final String stepTag = "&&";
private final String handlerSourceStr = "_Source";
private final IPqDevService iPqDevService; private final IPqDevService iPqDevService;
private final IDictDataService dictDataService; private final IDictDataService dictDataService;
@@ -63,11 +69,14 @@ public class PreDetectionServiceImpl implements PreDetectionService {
private final IAdPlanSourceService adPlanSourceService; private final IAdPlanSourceService adPlanSourceService;
private final IPqSourceService pqSourceService; private final IPqSourceService pqSourceService;
private final IPqScriptDtlsService pqScriptDtlsService; private final IPqScriptDtlsService pqScriptDtlsService;
private final ISysTestConfigService testConfigService;
private final SocketDevResponseService socketDevResponseService; private final SocketDevResponseService socketDevResponseService;
private final SocketSourceResponseService socketSourceResponseService; private final SocketSourceResponseService socketSourceResponseService;
private final SocketContrastResponseService socketContrastResponseService; private final SocketContrastResponseService socketContrastResponseService;
private final IPqScriptCheckDataService iPqScriptCheckDataService; private final IPqScriptCheckDataService iPqScriptCheckDataService;
private final ContrastNonHarmonicService contrastNonHarmonicService;
private final ContrastHarmonicService contrastHarmonicService;
private final SocketManager socketManager; private final SocketManager socketManager;
@@ -293,7 +302,7 @@ public class PreDetectionServiceImpl implements PreDetectionService {
socketMsg.setOperateCode(SourceOperateCodeEnum.OPER_GATHER.getValue()); socketMsg.setOperateCode(SourceOperateCodeEnum.OPER_GATHER.getValue());
socketMsg.setRequestId(SourceOperateCodeEnum.FORMAL_REAL.getValue() + stepTag + sourceIssue.getType()); socketMsg.setRequestId(SourceOperateCodeEnum.FORMAL_REAL.getValue() + stepTag + sourceIssue.getType());
socketMsg.setData(JSON.toJSONString(sourceIssues.get(0))); socketMsg.setData(JSON.toJSONString(sourceIssues.get(0)));
SocketManager.sendMsg(param.getUserPageId() + handlerSourceStr, JSON.toJSONString(socketMsg)); SocketManager.sendMsg(param.getUserPageId() + CnSocketUtil.SOURCE_TAG, JSON.toJSONString(socketMsg));
} }
@Override @Override
@@ -315,13 +324,44 @@ public class PreDetectionServiceImpl implements PreDetectionService {
// 参数校验目前仅检查IP是否重复后续可在里面扩展 // 参数校验目前仅检查IP是否重复后续可在里面扩展
checkDevIp(param.getDevIds()); checkDevIp(param.getDevIds());
socketContrastResponseService.init(param); socketContrastResponseService.init(param);
//用于处理异常导致的socket通道未关闭socket交互异常
//DetectionCommunicateUtil.checkContrastCommunicateChannel(param.getLoginName());
// 和通信模块进行连接 // 和通信模块进行连接
this.sendContrastSocket(param); this.sendContrastSocket(param);
} }
@Override
public Map<Integer, Integer> getContrastTestNumInfo(String planId) {
AdPlan plan = iAdPlanService.getById(planId);
SysTestConfig oneConfig = testConfigService.getOneConfig();
Integer maxNum = 1;
String code = String.valueOf(plan.getCode());
String adNonTable = "ad_non_harmonic_";
String adTable = "ad_harmonic_";
DynamicTableNameHandler.setTableName(adNonTable + code);
ContrastNonHarmonicResult result1 = contrastNonHarmonicService.lambdaQuery().select(ContrastNonHarmonicResult::getNum).orderByDesc().last("LIMIT 1").one();
if (ObjectUtil.isNotNull(result1)) {
if (result1.getNum().compareTo(maxNum) > 0) {
maxNum = result1.getNum() + 1;
}
}
DynamicTableNameHandler.remove();
DynamicTableNameHandler.setTableName(adTable + code);
ContrastHarmonicResult result2 = contrastHarmonicService.lambdaQuery().select(ContrastHarmonicResult::getNum).orderByDesc().last("LIMIT 1").one();
if (ObjectUtil.isNotNull(result2)) {
if (result2.getNum().compareTo(maxNum) > 0) {
maxNum = result2.getNum() + 1;
}
}
DynamicTableNameHandler.remove();
Map<Integer, Integer> map = new HashMap<>();
map.put(oneConfig.getMaxTime(), maxNum);
return map;
}
/** /**
* 比对式-与通信模块进行连接 * 比对式-与通信模块进行连接
* *

View File

@@ -12,7 +12,9 @@ import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.util.*; import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -385,4 +387,24 @@ public class DetectionUtil {
return indexList; return indexList;
} }
/**
* 根据idxList索引列表从oldList中获取新数组
*
* @param oldList
* @param idxList
* @return
*/
public static List<Double> getNewArray(List<Double> oldList, List<Integer> idxList) {
if (CollUtil.isNotEmpty(oldList) && CollUtil.isNotEmpty(idxList)) {
if (CollUtil.max(idxList) > oldList.size() - 1 || CollUtil.min(idxList) < 0) {
return null;
}
List<Double> newList = new ArrayList<>();
for (int i = 0; i < idxList.size(); i++) {
newList.add(oldList.get(idxList.get(i)));
}
return newList;
}
return null;
}
} }

View File

@@ -79,11 +79,6 @@ public class FormalTestManager {
*/ */
public static Integer stopTime = 0; public static Integer stopTime = 0;
/**
* 强行赋值关系
*/
public static Map<String, String> harmonicRelationMap = new HashMap<>();
/** /**
* 当前正在检测的计划 * 当前正在检测的计划
*/ */
@@ -95,9 +90,9 @@ public class FormalTestManager {
public static PatternEnum patternEnum; public static PatternEnum patternEnum;
/** /**
* 比对式检测-检测项。 * 比对式检测-检测项。key为检测项id,value为检测项code
*/ */
public static List<String> testItemCodeList = new ArrayList<>(); public static Map<String,String> testItemMap = new HashMap<>();
/** /**
* 数据处理原则 * 数据处理原则

View File

@@ -10,15 +10,10 @@ import com.njcn.gather.detection.util.socket.MsgUtil;
import com.njcn.gather.detection.util.socket.SocketManager; import com.njcn.gather.detection.util.socket.SocketManager;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
/** /**
* Netty心跳处理器 * Netty心跳处理器
@@ -26,7 +21,7 @@ import java.util.concurrent.TimeUnit;
* 负责维护Socket长连接的心跳检测机制通过定期发送心跳包来检测连接状态 * 负责维护Socket长连接的心跳检测机制通过定期发送心跳包来检测连接状态
* 当连续多次未收到心跳响应时自动断开连接并清理相关资源。 * 当连续多次未收到心跳响应时自动断开连接并清理相关资源。
* </p> * </p>
* *
* <h3>核心功能:</h3> * <h3>核心功能:</h3>
* <ul> * <ul>
* <li>定时发送心跳包 (默认10秒间隔3秒后开始)</li> * <li>定时发送心跳包 (默认10秒间隔3秒后开始)</li>
@@ -35,7 +30,7 @@ import java.util.concurrent.TimeUnit;
* <li>异步处理断开操作,避免阻塞心跳线程</li> * <li>异步处理断开操作,避免阻塞心跳线程</li>
* <li>优雅关闭资源,防止内存泄漏</li> * <li>优雅关闭资源,防止内存泄漏</li>
* </ul> * </ul>
* *
* <h3>心跳机制流程:</h3> * <h3>心跳机制流程:</h3>
* <pre> * <pre>
* 连接建立 → 启动心跳定时任务(3秒后开始每10秒执行) * 连接建立 → 启动心跳定时任务(3秒后开始每10秒执行)
@@ -46,60 +41,72 @@ import java.util.concurrent.TimeUnit;
* ↓ * ↓
* 连接断开 → 优雅关闭定时任务和线程池 * 连接断开 → 优雅关闭定时任务和线程池
* </pre> * </pre>
* *
* <h3>线程安全设计:</h3> * <h3>线程安全设计:</h3>
* <p> * <p>
* 使用单线程的ScheduledExecutorService处理心跳发送避免并发问题。 * 使用单线程的ScheduledExecutorService处理心跳发送避免并发问题。
* 超时处理使用CompletableFuture异步执行不阻塞心跳发送线程。 * 超时处理使用CompletableFuture异步执行不阻塞心跳发送线程。
* Future引用使用volatile修饰确保多线程环境下的可见性。 * Future引用使用volatile修饰确保多线程环境下的可见性。
* </p> * </p>
* *
* <h3>设备类型支持:</h3> * <h3>设备类型支持:</h3>
* <ul> * <ul>
* <li>程控源设备 (CnSocketUtil.SOURCE_TAG): "_Source"</li> * <li>程控源设备 (CnSocketUtil.SOURCE_TAG): "_Source"</li>
* <li>被检设备 (CnSocketUtil.DEV_TAG): "_Dev"</li> * <li>被检设备 (CnSocketUtil.DEV_TAG): "_Dev"</li>
* </ul> * </ul>
* *
* <h3>使用示例:</h3> * <h3>使用示例:</h3>
* <pre>{@code * <pre>{@code
* // 创建心跳处理器 * // 创建心跳处理器
* HeartbeatHandler handler = new HeartbeatHandler(param, CnSocketUtil.SOURCE_TAG); * HeartbeatHandler handler = new HeartbeatHandler(param, CnSocketUtil.SOURCE_TAG);
* *
* // 添加到Netty管道中 * // 添加到Netty管道中
* pipeline.addLast(handler); * pipeline.addLast(handler);
* }</pre> * }</pre>
* *
* @author cdf * @author cdf
* @since 2025-02-11
* @version 1.2 * @version 1.2
* @since 2025-02-11
*/ */
@Slf4j @Slf4j
public class HeartbeatHandler extends SimpleChannelInboundHandler<String> { public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
/** 心跳定时任务执行器,使用单线程池避免并发问题 */ /**
* 心跳定时任务执行器,使用单线程池避免并发问题
*/
private final ScheduledExecutorService heartbeatExecutor = Executors.newScheduledThreadPool(1); private final ScheduledExecutorService heartbeatExecutor = Executors.newScheduledThreadPool(1);
/** 检测参数包含用户页面ID等信息 */ /**
* 检测参数包含用户页面ID等信息
*/
private final PreDetectionParam param; private final PreDetectionParam param;
/** 处理器类型标识("_Source" 或 "_Dev" */ /**
* 处理器类型标识("_Source" 或 "_Dev"
*/
private final String handlerType; private final String handlerType;
/** 保存定时任务的Future引用便于取消和管理 */ /**
* 保存定时任务的Future引用便于取消和管理
*/
private ScheduledFuture<?> heartbeatFuture; private ScheduledFuture<?> heartbeatFuture;
/** 允许连续未收到心跳响应的最大次数 */ /**
* 允许连续未收到心跳响应的最大次数
*/
private static final int MAX_HEARTBEAT_MISSES = 3; private static final int MAX_HEARTBEAT_MISSES = 3;
/** 连续未收到心跳响应的次数 */ /**
* 连续未收到心跳响应的次数
*/
private int consecutiveHeartbeatMisses = 0; private int consecutiveHeartbeatMisses = 0;
/** /**
* 构造函数 * 构造函数
* *
* @param param 检测参数包含用户页面ID等信息 * @param param 检测参数包含用户页面ID等信息
* @param type 处理器类型CnSocketUtil.SOURCE_TAG 或 CnSocketUtil.DEV_TAG * @param type 处理器类型CnSocketUtil.SOURCE_TAG 或 CnSocketUtil.DEV_TAG
*/ */
public HeartbeatHandler(PreDetectionParam param, String type) { public HeartbeatHandler(PreDetectionParam param, String type) {
this.param = param; this.param = param;
@@ -110,7 +117,7 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
/** /**
* 通道激活时的回调方法 * 通道激活时的回调方法
* 在Socket连接建立成功后被调用启动心跳机制 * 在Socket连接建立成功后被调用启动心跳机制
* *
* @param ctx Netty的通道上下文对象 * @param ctx Netty的通道上下文对象
*/ */
@Override @Override
@@ -125,7 +132,7 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
/** /**
* 通道断开时的回调方法 * 通道断开时的回调方法
* 在Socket连接断开时被调用负责清理相关资源 * 在Socket连接断开时被调用负责清理相关资源
* *
* @param ctx Netty的通道上下文对象 * @param ctx Netty的通道上下文对象
* @throws Exception 异常情况 * @throws Exception 异常情况
*/ */
@@ -139,7 +146,7 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
/** /**
* 启动心跳定时任务 * 启动心跳定时任务
* 每10秒发送一次心跳包3秒后开始执行 * 每10秒发送一次心跳包3秒后开始执行
* *
* @param ctx Netty的通道上下文对象 * @param ctx Netty的通道上下文对象
*/ */
private void scheduleHeartbeat(ChannelHandlerContext ctx) { private void scheduleHeartbeat(ChannelHandlerContext ctx) {
@@ -156,8 +163,8 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
consecutiveHeartbeatMisses++; consecutiveHeartbeatMisses++;
if (consecutiveHeartbeatMisses >= MAX_HEARTBEAT_MISSES) { if (consecutiveHeartbeatMisses >= MAX_HEARTBEAT_MISSES) {
// 连续三次未收到心跳响应,异步处理断开逻辑,避免阻塞心跳线程 // 连续三次未收到心跳响应,异步处理断开逻辑,避免阻塞心跳线程
log.warn("心跳响应超时 - 设备类型: {}, 连续失败次数: {}/{}, 执行断开连接", log.warn("心跳响应超时 - 设备类型: {}, 连续失败次数: {}/{}, 执行断开连接",
handlerType, consecutiveHeartbeatMisses, MAX_HEARTBEAT_MISSES); handlerType, consecutiveHeartbeatMisses, MAX_HEARTBEAT_MISSES);
handleHeartbeatTimeoutAsync(); handleHeartbeatTimeoutAsync();
consecutiveHeartbeatMisses = 0; // 重置连续心跳丢失次数 consecutiveHeartbeatMisses = 0; // 重置连续心跳丢失次数
} }
@@ -182,8 +189,10 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
// 根据设备类型发送对应的退出指令 // 根据设备类型发送对应的退出指令
if (CnSocketUtil.DEV_TAG.equals(handlerType)) { if (CnSocketUtil.DEV_TAG.equals(handlerType)) {
CnSocketUtil.quitSend(param); CnSocketUtil.quitSend(param);
} else { } else if (CnSocketUtil.SOURCE_TAG.equals(handlerType)) {
CnSocketUtil.quitSendSource(param); CnSocketUtil.quitSendSource(param);
} else {
CnSocketUtil.contrastSendquit(param.getUserPageId(), true);
} }
log.debug("退出指令已发送等待3秒后清理连接 - 设备类型: {}", handlerType); log.debug("退出指令已发送等待3秒后清理连接 - 设备类型: {}", handlerType);
} catch (Exception e) { } catch (Exception e) {
@@ -194,9 +203,9 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
// 延迟3秒后清理连接给退出指令留出处理时间 // 延迟3秒后清理连接给退出指令留出处理时间
Thread.sleep(3000); Thread.sleep(3000);
// 构建连接Key并从SocketManager中移除 // 构建连接Key并从SocketManager中移除
String key = CnSocketUtil.DEV_TAG.equals(handlerType) ? String key = CnSocketUtil.DEV_TAG.equals(handlerType) ?
param.getUserPageId() + CnSocketUtil.DEV_TAG : param.getUserPageId() + CnSocketUtil.DEV_TAG :
param.getUserPageId() + CnSocketUtil.SOURCE_TAG; param.getUserPageId() + CnSocketUtil.SOURCE_TAG;
SocketManager.removeUser(key); SocketManager.removeUser(key);
log.info("心跳超时断开处理完成 - 设备类型: {}, 连接已清理", handlerType); log.info("心跳超时断开处理完成 - 设备类型: {}, 连接已清理", handlerType);
} catch (InterruptedException e) { } catch (InterruptedException e) {
@@ -254,7 +263,7 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
* 1. 过滤心跳响应包,重置失败计数器 * 1. 过滤心跳响应包,重置失败计数器
* 2. 业务消息传递给后续处理器 * 2. 业务消息传递给后续处理器
* </p> * </p>
* *
* @param ctx Netty的通道上下文对象 * @param ctx Netty的通道上下文对象
* @param msg 接收到的消息内容 * @param msg 接收到的消息内容
* @throws Exception 异常情况 * @throws Exception 异常情况
@@ -278,7 +287,7 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
* 通过解析消息的operateCode字段来判断是否为心跳响应。 * 通过解析消息的operateCode字段来判断是否为心跳响应。
* 心跳包的操作码为SourceOperateCodeEnum.HEARTBEAT。 * 心跳包的操作码为SourceOperateCodeEnum.HEARTBEAT。
* </p> * </p>
* *
* @param msg 需要判断的消息内容 * @param msg 需要判断的消息内容
* @return true:心跳包, false:业务消息 * @return true:心跳包, false:业务消息
*/ */
@@ -287,9 +296,9 @@ public class HeartbeatHandler extends SimpleChannelInboundHandler<String> {
// 解析消息为SocketDataMsg对象 // 解析消息为SocketDataMsg对象
SocketDataMsg socketDataMsg = MsgUtil.socketDataMsg(msg); SocketDataMsg socketDataMsg = MsgUtil.socketDataMsg(msg);
// 检查操作码是否为心跳类型 // 检查操作码是否为心跳类型
return socketDataMsg != null && return socketDataMsg != null &&
socketDataMsg.getOperateCode() != null && socketDataMsg.getOperateCode() != null &&
socketDataMsg.getOperateCode().equals(SourceOperateCodeEnum.HEARTBEAT.getValue()); socketDataMsg.getOperateCode().equals(SourceOperateCodeEnum.HEARTBEAT.getValue());
} catch (Exception e) { } catch (Exception e) {
// 消息解析失败,可能不是标准格式的心跳包 // 消息解析失败,可能不是标准格式的心跳包
log.debug("消息解析失败,可能不是心跳包: {}", msg, e); log.debug("消息解析失败,可能不是心跳包: {}", msg, e);

View File

@@ -127,6 +127,7 @@ public class NettyClient {
PreDetectionParam preDetectionParam = new PreDetectionParam(); PreDetectionParam preDetectionParam = new PreDetectionParam();
preDetectionParam.setUserPageId(param.getLoginName()); preDetectionParam.setUserPageId(param.getLoginName());
preDetectionParam.setTestItemList(param.getTestItemList()); preDetectionParam.setTestItemList(param.getTestItemList());
preDetectionParam.setNum(param.getNum());
NettyContrastClientHandler handler = new NettyContrastClientHandler(preDetectionParam, socketContrastResponseService); NettyContrastClientHandler handler = new NettyContrastClientHandler(preDetectionParam, socketContrastResponseService);
executeSocketConnection(ip, port, preDetectionParam, msg, handler); executeSocketConnection(ip, port, preDetectionParam, msg, handler);
} }

View File

@@ -3,6 +3,7 @@ package com.njcn.gather.detection.util.socket.cilent;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.njcn.gather.detection.handler.SocketDevResponseService; import com.njcn.gather.detection.handler.SocketDevResponseService;
import com.njcn.gather.detection.pojo.enums.ResultEnum;
import com.njcn.gather.detection.pojo.enums.SourceOperateCodeEnum; import com.njcn.gather.detection.pojo.enums.SourceOperateCodeEnum;
import com.njcn.gather.detection.pojo.param.PreDetectionParam; import com.njcn.gather.detection.pojo.param.PreDetectionParam;
import com.njcn.gather.detection.pojo.vo.DevLineTestResult; import com.njcn.gather.detection.pojo.vo.DevLineTestResult;
@@ -71,11 +72,6 @@ public class NettyDevClientHandler extends SimpleChannelInboundHandler<String> {
*/ */
private static final long STOP_TIMEOUT = 600L; private static final long STOP_TIMEOUT = 600L;
/**
* 超时时默认结果标志3表示超时失败
*/
private static final int DEFAULT_RESULT_FLAG = 3;
private final PreDetectionParam param; private final PreDetectionParam param;
private final SocketDevResponseService socketResponseService; private final SocketDevResponseService socketResponseService;
@@ -247,7 +243,7 @@ public class NettyDevClientHandler extends SimpleChannelInboundHandler<String> {
log.warn("当前进入暂停操作超时函数,停止时间: {}", FormalTestManager.stopTime); log.warn("当前进入暂停操作超时函数,停止时间: {}", FormalTestManager.stopTime);
if (FormalTestManager.stopTime > STOP_TIMEOUT) { if (FormalTestManager.stopTime > STOP_TIMEOUT) {
CnSocketUtil.quitSend(param); CnSocketUtil.quitSend(param);
WebServiceManager.sendDetectionErrorMessage(param.getUserPageId(),SourceOperateCodeEnum.FORMAL_REAL.getValue(), SourceOperateCodeEnum.STOP_TIMEOUT); WebServiceManager.sendDetectionErrorMessage(param.getUserPageId(), SourceOperateCodeEnum.FORMAL_REAL.getValue(), SourceOperateCodeEnum.STOP_TIMEOUT);
} }
} }
@@ -285,13 +281,13 @@ public class NettyDevClientHandler extends SimpleChannelInboundHandler<String> {
// 根据不同检测类型使用不同的超时阈值 // 根据不同检测类型使用不同的超时阈值
if (DicDataEnum.F.getCode().equals(type)) { if (DicDataEnum.F.getCode().equals(type)) {
// 闪变检测需要更长时间20分钟超时 // 闪变检测需要更长时间20分钟超时
return currentTime > FLICKER_TIMEOUT; return currentTime >= FLICKER_TIMEOUT;
} else if (DicDataEnum.VOLTAGE.getCode().equals(type) || DicDataEnum.HP.getCode().equals(type)) { } else if (DicDataEnum.VOLTAGE.getCode().equals(type) || DicDataEnum.HP.getCode().equals(type)) {
// 统计数据类型电压、谐波中等时间3分钟超时 // 统计数据类型电压、谐波中等时间3分钟超时
return currentTime > STATISTICS_TIMEOUT; return currentTime >= STATISTICS_TIMEOUT;
} else { } else {
// 实时数据类型短时间1分钟超时 // 实时数据类型短时间1分钟超时
return currentTime > REALTIME_TIMEOUT; return currentTime >= REALTIME_TIMEOUT;
} }
} }
@@ -340,7 +336,7 @@ public class NettyDevClientHandler extends SimpleChannelInboundHandler<String> {
devLineTestResult.setDeviceName(dev.getDevName()); devLineTestResult.setDeviceName(dev.getDevName());
Integer[] resultFlags = dev.getMonitorList().stream() Integer[] resultFlags = dev.getMonitorList().stream()
.map(monitor -> DEFAULT_RESULT_FLAG) .map(monitor -> ResultEnum.NETWORK_TIMEOUT)
.toArray(Integer[]::new); .toArray(Integer[]::new);
devLineTestResult.setChnResult(resultFlags); devLineTestResult.setChnResult(resultFlags);

View File

@@ -1,6 +1,5 @@
package com.njcn.gather.device.controller; package com.njcn.gather.device.controller;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njcn.common.pojo.annotation.OperateInfo; import com.njcn.common.pojo.annotation.OperateInfo;
@@ -10,12 +9,10 @@ import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.pojo.response.HttpResult; import com.njcn.common.pojo.response.HttpResult;
import com.njcn.common.utils.LogUtil; import com.njcn.common.utils.LogUtil;
import com.njcn.gather.device.pojo.enums.CommonEnum;
import com.njcn.gather.device.pojo.param.PqDevParam; import com.njcn.gather.device.pojo.param.PqDevParam;
import com.njcn.gather.device.pojo.vo.PqDevVO; import com.njcn.gather.device.pojo.vo.PqDevVO;
import com.njcn.gather.device.service.IPqDevService; import com.njcn.gather.device.service.IPqDevService;
import com.njcn.gather.plan.pojo.po.AdPlan; import com.njcn.gather.monitor.pojo.po.PqMonitor;
import com.njcn.gather.type.pojo.po.DevType;
import com.njcn.gather.type.service.IDevTypeService; import com.njcn.gather.type.service.IDevTypeService;
import com.njcn.web.controller.BaseController; import com.njcn.web.controller.BaseController;
import com.njcn.web.utils.FileUtil; import com.njcn.web.utils.FileUtil;
@@ -147,7 +144,7 @@ public class PqDevController extends BaseController {
if (!fileType) { if (!fileType) {
throw new BusinessException(CommonResponseEnum.FILE_XLSX_ERROR); throw new BusinessException(CommonResponseEnum.FILE_XLSX_ERROR);
} }
if("null".equals(planId)){ if ("null".equals(planId)) {
planId = null; planId = null;
} }
Boolean result = pqDevService.importDev(file, patternId, planId, response); Boolean result = pqDevService.importDev(file, patternId, planId, response);

View File

@@ -7,6 +7,7 @@ import com.njcn.gather.device.pojo.enums.TimeCheckResultEnum;
import com.njcn.gather.device.pojo.param.PqDevParam; import com.njcn.gather.device.pojo.param.PqDevParam;
import com.njcn.gather.device.pojo.po.PqDev; import com.njcn.gather.device.pojo.po.PqDev;
import com.njcn.gather.device.pojo.vo.*; import com.njcn.gather.device.pojo.vo.*;
import com.njcn.gather.monitor.pojo.po.PqMonitor;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;

View File

@@ -209,7 +209,7 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
public boolean deletePqDev(PqDevParam.DeleteParam param) { public boolean deletePqDev(PqDevParam.DeleteParam param) {
if (PatternEnum.CONTRAST.getValue().equals(dictDataService.getDictDataById(param.getPattern()).getCode())) { if (PatternEnum.CONTRAST.getValue().equals(dictDataService.getDictDataById(param.getPattern()).getCode())) {
for (String id : param.getIds()) { for (String id : param.getIds()) {
if (ObjectUtils.isNotEmpty(pqMonitorService.listPqMonitorByDevId(id))) { if (ObjectUtils.isNotEmpty(pqMonitorService.listPqMonitorByDevIds(Collections.singletonList(id)))) {
throw new BusinessException(DetectionResponseEnum.PQ_DEV_HAS_MONITOR); throw new BusinessException(DetectionResponseEnum.PQ_DEV_HAS_MONITOR);
} }
} }
@@ -363,7 +363,7 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
pqDevVO.setDevVolt(devType.getDevVolt()); pqDevVO.setDevVolt(devType.getDevVolt());
} }
List<PqMonitor> monitorList = pqMonitorService.listPqMonitorByDevId(id); List<PqMonitor> monitorList = pqMonitorService.listPqMonitorByDevIds(Collections.singletonList(id));
if (ObjectUtil.isNotEmpty(monitorList)) { if (ObjectUtil.isNotEmpty(monitorList)) {
pqDevVO.setMonitorList(monitorList); pqDevVO.setMonitorList(monitorList);
} }
@@ -1384,7 +1384,7 @@ public class PqDevServiceImpl extends ServiceImpl<PqDevMapper, PqDev> implements
this.visualizeProvinceDev(pqDevVOList); this.visualizeProvinceDev(pqDevVOList);
contrastDevExcels.addAll(BeanUtil.copyToList(pqDevVOList, ContrastDevExcel.class)); contrastDevExcels.addAll(BeanUtil.copyToList(pqDevVOList, ContrastDevExcel.class));
contrastDevExcels.forEach(contrastDevExcel -> { contrastDevExcels.forEach(contrastDevExcel -> {
List<PqMonitor> monitorList = pqMonitorService.listPqMonitorByDevId(contrastDevExcel.getId()); List<PqMonitor> monitorList = pqMonitorService.listPqMonitorByDevIds(Collections.singletonList(contrastDevExcel.getId()));
pqMonitorService.visualizeMonitor(monitorList); pqMonitorService.visualizeMonitor(monitorList);
List<PqMonitorExcel> pqMonitorExcelList = BeanUtil.copyToList(monitorList, PqMonitorExcel.class); List<PqMonitorExcel> pqMonitorExcelList = BeanUtil.copyToList(monitorList, PqMonitorExcel.class);
contrastDevExcel.setPqMonitorExcelList(pqMonitorExcelList); contrastDevExcel.setPqMonitorExcelList(pqMonitorExcelList);

View File

@@ -162,7 +162,7 @@ public class PqErrSysDtlsServiceImpl extends ServiceImpl<PqErrSysDtlsMapper, PqE
wrapper.selectAll(PqErrSysDtls.class) wrapper.selectAll(PqErrSysDtls.class)
.leftJoin(DictTree.class, DictTree::getId, PqErrSysDtls::getScriptType) .leftJoin(DictTree.class, DictTree::getId, PqErrSysDtls::getScriptType)
.eq(PqErrSysDtls::getErrorSysId, errSysId) .eq(PqErrSysDtls::getErrorSysId, errSysId)
.eq(DictTree::getId, scriptType); .eq(DictTree::getCode, scriptType);
return this.list(wrapper); return this.list(wrapper);
} }
} }

View File

@@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.Collections;
import java.util.List; import java.util.List;
@@ -41,7 +42,7 @@ public class PqMonitorController extends BaseController {
public HttpResult<List<PqMonitor>> list(@RequestBody PqMonitorParam.QueryParam queryParam) { public HttpResult<List<PqMonitor>> list(@RequestBody PqMonitorParam.QueryParam queryParam) {
String methodDescribe = getMethodDescribe("list"); String methodDescribe = getMethodDescribe("list");
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, queryParam); LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, queryParam);
List<PqMonitor> result = pqMonitorService.listPqMonitorByDevId(queryParam.getDevId()); List<PqMonitor> result = pqMonitorService.listPqMonitorByDevIds(queryParam.getDevIds());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
} }
} }

View File

@@ -15,11 +15,23 @@ public interface PqMonitorMapper extends MPJBaseMapper<PqMonitor> {
/** /**
* 根据终端id获取监测点集合 * 根据终端id获取监测点集合
*
* @param devId * @param devId
* @return: java.util.List<com.njcn.gather.device.pojo.vo.PreDetection.MonitorListDTO> * @return: java.util.List<com.njcn.gather.device.pojo.vo.PreDetection.MonitorListDTO>
* @Author: wr * @Author: wr
* @Date: 2024/12/12 13:15 * @Date: 2024/12/12 13:15
*/ */
List<PreDetection.MonitorListDTO> selectMonitorInfo(@Param("devId") String devId); List<PreDetection.MonitorListDTO> selectMonitorInfo(@Param("devId") String devId);
/**
* 根据被检设备id和线路号获取监测点信息
*
* @param devId 被检设备id
* @param num 线路号
* @return
*/
PqMonitor getByDevIdAndNum(@Param("devId") String devId, @Param("num") Integer num);
List<PqMonitor> listByDevIds(@Param("devIds") List<String> devIds);
} }

View File

@@ -16,5 +16,39 @@
WHERE Dev_Id = #{devId} WHERE Dev_Id = #{devId}
</select> </select>
<select id="getByDevIdAndNum" resultType="com.njcn.gather.monitor.pojo.po.PqMonitor">
select pq_monitor.Id,
pq_monitor.Dev_Id,
pq_monitor.Name,
pq_monitor.Busbar,
pq_monitor.Num,
pq_monitor.Pt,
pq_monitor.Ct,
pq_monitor.Stat_Interval,
pq_monitor.Harm_Sys_Id,
sys_dict_data.Code as `Connection`
from pq_monitor
inner join sys_dict_data on pq_monitor.Connection = sys_dict_data.id
where Dev_Id = #{devId}
and Num = #{num}
</select>
<select id="listByDevIds" resultType="com.njcn.gather.monitor.pojo.po.PqMonitor">
select pq_monitor.Id,
pq_monitor.Dev_Id,
pq_monitor.Name,
pq_monitor.Busbar,
pq_monitor.Num,
pq_monitor.Pt,
pq_monitor.Ct,
pq_monitor.Stat_Interval,
pq_monitor.Harm_Sys_Id,
sys_dict_data.Code as `Connection`
from pq_monitor
inner join sys_dict_data on pq_monitor.Connection = sys_dict_data.id
where Dev_Id in
<foreach collection="devIds" item="devId" open="(" separator="," close=")">
#{devId}
</foreach>
</select>
</mapper> </mapper>

View File

@@ -9,6 +9,7 @@ import lombok.EqualsAndHashCode;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern; import javax.validation.constraints.Pattern;
import java.util.List;
/** /**
* @author caozehui * @author caozehui
@@ -62,18 +63,6 @@ public class PqMonitorParam {
public static class QueryParam { public static class QueryParam {
@ApiModelProperty(value = "所属设备id") @ApiModelProperty(value = "所属设备id")
@NotBlank(message = DetectionValidMessage.DEVICE_ID_NOT_BLANK) @NotBlank(message = DetectionValidMessage.DEVICE_ID_NOT_BLANK)
private String devId; private List<String> devIds;
} }
/**
* 修改实体
*/
// @Data
// @EqualsAndHashCode(callSuper = true)
// public static class UpdateParam extends PqMonitorParam {
// @ApiModelProperty(value = "监测点id", required = true)
// @NotBlank(message = DetectionValidMessage.ID_NOT_BLANK)
// @Pattern(regexp = PatternRegex.SYSTEM_ID, message = DetectionValidMessage.ID_FORMAT_ERROR)
// private String id;
// }
} }

View File

@@ -17,10 +17,10 @@ public interface IPqMonitorService extends IService<PqMonitor> {
/** /**
* 根据设备id获取所有监测点信息 * 根据设备id获取所有监测点信息
* *
* @param devId 被检设备id * @param devIds 被检设备id列表
* @return 监测点信息列表 * @return 监测点信息列表
*/ */
List<PqMonitor> listPqMonitorByDevId(String devId); List<PqMonitor> listPqMonitorByDevIds(List<String> devId);
/** /**
* 根据设备id批量新增监测点信息 * 根据设备id批量新增监测点信息
@@ -62,6 +62,14 @@ public interface IPqMonitorService extends IService<PqMonitor> {
*/ */
void reverseVisualizeMonitor(List<PqMonitor> monitorList); void reverseVisualizeMonitor(List<PqMonitor> monitorList);
/**
* 根据被检设备监测点id获取监测点信息
*
* @param devMonitorId 被检设备监测点id
* @return
*/
PqMonitor getByDevMonitorId(String devMonitorId);
/** /**
* 根据被检设备id获取额定电流 * 根据被检设备id获取额定电流
* @param devMonitorId 被检设备监测点id * @param devMonitorId 被检设备监测点id

View File

@@ -1,6 +1,7 @@
package com.njcn.gather.monitor.service.impl; package com.njcn.gather.monitor.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -32,8 +33,11 @@ public class PqMonitorServiceImpl extends ServiceImpl<PqMonitorMapper, PqMonitor
private final IDictDataService dictDataService; private final IDictDataService dictDataService;
@Override @Override
public List<PqMonitor> listPqMonitorByDevId(String devId) { public List<PqMonitor> listPqMonitorByDevIds(List<String> devIds) {
return this.lambdaQuery().eq(PqMonitor::getDevId, devId).list(); if (CollUtil.isNotEmpty(devIds)) {
return this.baseMapper.listByDevIds(devIds);
}
return CollUtil.empty(PqMonitor.class);
} }
@Override @Override
@@ -86,12 +90,18 @@ public class PqMonitorServiceImpl extends ServiceImpl<PqMonitorMapper, PqMonitor
}); });
} }
@Override
public PqMonitor getByDevMonitorId(String devMonitorId) {
String[] split = devMonitorId.split("_");
return this.baseMapper.getByDevIdAndNum(split[0], Integer.valueOf(split[1]));
}
@Override @Override
public Double getRatedCurrent(String devMonitorId) { public Double getRatedCurrent(String devMonitorId) {
PqMonitor pqMonitor = this.baseMapper.selectById(devMonitorId); PqMonitor pqMonitor = this.getByDevMonitorId(devMonitorId);
if (ObjectUtil.isNotNull(pqMonitor)) { if (ObjectUtil.isNotNull(pqMonitor)) {
String ct = pqMonitor.getCt(); String ct = pqMonitor.getCt();
if(StrUtil.isNotBlank(ct) && ct.contains(StrUtil.COLON)){ if (StrUtil.isNotBlank(ct) && ct.contains(StrUtil.COLON)) {
String[] ctArray = ct.split(StrUtil.COLON); String[] ctArray = ct.split(StrUtil.COLON);
return Double.parseDouble(ctArray[1]); return Double.parseDouble(ctArray[1]);
} }
@@ -101,10 +111,10 @@ public class PqMonitorServiceImpl extends ServiceImpl<PqMonitorMapper, PqMonitor
@Override @Override
public Double getRatedVoltage(String devMonitorId) { public Double getRatedVoltage(String devMonitorId) {
PqMonitor pqMonitor = this.baseMapper.selectById(devMonitorId); PqMonitor pqMonitor = this.getByDevMonitorId(devMonitorId);
if (ObjectUtil.isNotNull(pqMonitor)) { if (ObjectUtil.isNotNull(pqMonitor)) {
String pt = pqMonitor.getPt(); String pt = pqMonitor.getPt();
if(StrUtil.isNotBlank(pt) && pt.contains(StrUtil.COLON)){ if (StrUtil.isNotBlank(pt) && pt.contains(StrUtil.COLON)) {
String[] ptArray = pt.split(StrUtil.COLON); String[] ptArray = pt.split(StrUtil.COLON);
return Double.parseDouble(ptArray[1]); return Double.parseDouble(ptArray[1]);
} }

View File

@@ -171,7 +171,7 @@ public class AdPlanController extends BaseController {
public HttpResult<List<Map<String, String>>> getBigTestItem(@RequestBody AdPlanParam.CheckParam checkParam) { public HttpResult<List<Map<String, String>>> getBigTestItem(@RequestBody AdPlanParam.CheckParam checkParam) {
String methodDescribe = getMethodDescribe("getBigTestItem"); String methodDescribe = getMethodDescribe("getBigTestItem");
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, checkParam); LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, checkParam);
List<Map<String, String>> result = adPlanService.getBigTestItem(checkParam.getReCheckType(), checkParam.getPlanId(), checkParam.getDevIds()); List<Map<String, String>> result = adPlanService.getBigTestItem(checkParam.getReCheckType(), checkParam.getPlanId(), checkParam.getDevIds(), checkParam.getPatternId());
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
} }

View File

@@ -118,5 +118,6 @@ public class AdPlanParam {
private Integer reCheckType; private Integer reCheckType;
private String planId; private String planId;
private List<String> devIds; private List<String> devIds;
private String patternId;
} }
} }

View File

@@ -45,12 +45,11 @@ public interface IAdPlanService extends IService<AdPlan> {
/** /**
* 删除检测计划 * 删除检测计划
* *
* @param ids 检测计划id列表 * @param ids 检测计划id列表
* @param pattern 模式Id * @param pattern 模式Id
*
* @return 删除成功则返回true否则返回false * @return 删除成功则返回true否则返回false
*/ */
boolean deleteAdPlan(List<String> ids,String pattern); boolean deleteAdPlan(List<String> ids, String pattern);
/** /**
* 根据模式查询检测计划 * 根据模式查询检测计划
@@ -70,12 +69,13 @@ public interface IAdPlanService extends IService<AdPlan> {
/** /**
* 获取检测大项 * 获取检测大项
* *
* @param reCheckType 0:不合格项复检 1:全部复检 * @param reCheckType 0:不合格项复检 1:全部复检
* @param planId 检测计划Id * @param planId 检测计划Id
* @param devIds 设备Id列表 * @param devIds 设备Id列表
* @param patternId 模式Id
* @return * @return
*/ */
List<Map<String, String>> getBigTestItem(Integer reCheckType, String planId, List<String> devIds); List<Map<String, String>> getBigTestItem(Integer reCheckType, String planId, List<String> devIds, String patternId);
/** /**
* 修改计划状态 * 修改计划状态
@@ -150,7 +150,6 @@ public interface IAdPlanService extends IService<AdPlan> {
* *
* @param planId * @param planId
* @param name * @param name
*
* @return * @return
*/ */
boolean updateSubPlanName(String planId, String name); boolean updateSubPlanName(String planId, String name);

View File

@@ -510,18 +510,30 @@ public class AdPlanServiceImpl extends ServiceImpl<AdPlanMapper, AdPlan> impleme
} }
@Override @Override
public List<Map<String, String>> getBigTestItem(Integer reCheckType, String planId, List<String> devIds) { public List<Map<String, String>> getBigTestItem(Integer reCheckType, String planId, List<String> devIds, String patternId) {
List<Map<String, String>> result = new ArrayList<>(); List<Map<String, String>> result = new ArrayList<>();
AdPlan adPlan = this.getById(planId); AdPlan adPlan = this.getById(planId);
if (ObjectUtil.isNull(adPlan)) { if (ObjectUtil.isNull(adPlan)) {
throw new BusinessException(DetectionResponseEnum.PLAN_NOT_EXIST); throw new BusinessException(DetectionResponseEnum.PLAN_NOT_EXIST);
} }
String scriptId = adPlan.getScriptId(); DictData dictData = dictDataService.getById(patternId);
if (PatternEnum.CONTRAST.getValue().equals(dictData.getCode())) {
String[] split = adPlan.getTestItem().split(StrUtil.COMMA);
List<DictTree> dictTreeList = dictTreeService.list(new QueryWrapper<DictTree>().in("id", split).eq("state", DataStateEnum.DELETED.getCode()));
List<PqScriptDtls> scriptDtlsList = pqScriptDtlsService.listPqScriptDtlByScriptId(scriptId); for (DictTree dictTree : dictTreeList) {
Map<String, String> map = new HashMap<>();
map.put("id", dictTree.getId());
map.put("code", dictTree.getCode());
map.put("scriptName", dictTree.getName());
result.add(map);
}
} else {
String scriptId = adPlan.getScriptId();
List<PqScriptDtls> scriptDtlsList = pqScriptDtlsService.listPqScriptDtlByScriptId(scriptId);
// 不合格项复检 // 不合格项复检
if (reCheckType == 0) { if (reCheckType == 0) {
// List<SimAndDigBaseResult> allResultList = new ArrayList<>(); // List<SimAndDigBaseResult> allResultList = new ArrayList<>();
// allResultList.addAll(adHarmonicService.get(scriptId, null, devId, "-1", adPlan.getCode())); // allResultList.addAll(adHarmonicService.get(scriptId, null, devId, "-1", adPlan.getCode()));
// allResultList.addAll(adNonHarmonicService.get(scriptId, null, devId, "-1", adPlan.getCode())); // allResultList.addAll(adNonHarmonicService.get(scriptId, null, devId, "-1", adPlan.getCode()));
@@ -532,33 +544,35 @@ public class AdPlanServiceImpl extends ServiceImpl<AdPlanMapper, AdPlan> impleme
// //
// scriptDtlsList = scriptDtlsList.stream().filter(obj -> !sortSet.contains(obj.getScriptIndex())).collect(Collectors.toList()); // scriptDtlsList = scriptDtlsList.stream().filter(obj -> !sortSet.contains(obj.getScriptIndex())).collect(Collectors.toList());
// } // }
Set<Integer> indexes = new HashSet<>(); Set<Integer> indexes = new HashSet<>();
StorageParam storageParam = new StorageParam(); StorageParam storageParam = new StorageParam();
storageParam.setCode(adPlan.getCode() + ""); storageParam.setCode(adPlan.getCode() + "");
storageParam.setScriptId(adPlan.getScriptId()); storageParam.setScriptId(adPlan.getScriptId());
devIds.forEach(devId -> { devIds.forEach(devId -> {
storageParam.setDevId(devId); storageParam.setDevId(devId);
indexes.addAll(adHarmonicService.getIndex(storageParam)); indexes.addAll(adHarmonicService.getIndex(storageParam));
});
scriptDtlsList = scriptDtlsList.stream().filter(obj -> indexes.contains(obj.getScriptIndex())).collect(Collectors.toList());
}
Map<String, List<PqScriptDtls>> collect = scriptDtlsList.stream()
.sorted(Comparator.comparing(PqScriptDtls::getScriptIndex))
.collect(Collectors.groupingBy(PqScriptDtls::getScriptType, LinkedHashMap::new, Collectors.toList()));
collect.forEach((key, value) -> {
Map<String, String> map = new HashMap<>();
map.put("id", key);
DictTree dictTree = dictTreeService.getById(key);
if (ObjectUtil.isNotNull(dictTree)) {
map.put("code", dictTree.getCode());
map.put("scriptName", dictTree.getName());
} else {
throw new BusinessException(DetectionResponseEnum.SCRIPT_RELATE_DICT_NOT_EXIST);
}
result.add(map);
}); });
scriptDtlsList = scriptDtlsList.stream().filter(obj -> indexes.contains(obj.getScriptIndex())).collect(Collectors.toList());
} }
Map<String, List<PqScriptDtls>> collect = scriptDtlsList.stream()
.sorted(Comparator.comparing(PqScriptDtls::getScriptIndex))
.collect(Collectors.groupingBy(PqScriptDtls::getScriptType, LinkedHashMap::new, Collectors.toList()));
collect.forEach((key, value) -> {
Map<String, String> map = new HashMap<>();
map.put("id", key);
DictTree dictTree = dictTreeService.getById(key);
if (ObjectUtil.isNotNull(dictTree)) {
map.put("code", dictTree.getCode());
map.put("scriptName", dictTree.getName());
} else {
throw new BusinessException(DetectionResponseEnum.SCRIPT_RELATE_DICT_NOT_EXIST);
}
result.add(map);
});
return result; return result;
} }

View File

@@ -16,6 +16,7 @@ public enum PowerIndexEnum {
FREQ("FREQ", "频率"), FREQ("FREQ", "频率"),
V("V", "电压"), V("V", "电压"),
I("I", "电流"), I("I", "电流"),
P("P", "功率"),
IMBV("IMBV", "负序电压不平衡度"), IMBV("IMBV", "负序电压不平衡度"),
IMBA("IMBA", "负序电流不平衡度"), IMBA("IMBA", "负序电流不平衡度"),
F("F", "短时电压闪变"), F("F", "短时电压闪变"),

View File

@@ -1500,57 +1500,58 @@ public class ResultServiceImpl implements IResultService {
List<Map<String, Object>> sheetsList = new ArrayList<>(); List<Map<String, Object>> sheetsList = new ArrayList<>();
// key为被检设备的ip, value为该ip下所有通道的设备数据 // key为被检设备的ip, value为该ip下所有通道的设备数据
Map<String, List<DevData>> ipDevDataMap = FormalTestManager.devDataMap.values().stream().flatMap(List::stream).collect(Collectors.groupingBy(obj -> obj.getId().split(CnSocketUtil.SPLIT_TAG)[0])); Map<String, List<DevData>> ipDevDataMap = FormalTestManager.standardDevDataMap.values().stream().flatMap(List::stream).collect(Collectors.groupingBy(obj -> obj.getId().split(CnSocketUtil.SPLIT_TAG)[0]));
ipDevDataMap.forEach((ip, devDataList) -> { ipDevDataMap.forEach((ip, stdDevDataList) -> {
// 按照通道号分组。key为通道号value为该通道号下所有设备数据 // 按照通道号分组。key为通道号value为该通道号下所有设备数据
Map<String, List<DevData>> channelDataMap = devDataList.stream().collect(Collectors.groupingBy(obj -> obj.getId().split(CnSocketUtil.SPLIT_TAG)[1])); Map<String, List<DevData>> channelDataMap = stdDevDataList.stream().collect(Collectors.groupingBy(obj -> obj.getId().split(CnSocketUtil.SPLIT_TAG)[1]));
channelDataMap.forEach((channel, channelDevDataList) -> { channelDataMap.forEach((channel, channelDevDataList) -> {
String standardDevMonitorId = FormalTestManager.pairsMap.get(ip + channel); String standardDevMonitorId = ip + CnSocketUtil.SPLIT_TAG + channel;
List<DevData> standarDevDataList = BeanUtil.copyToList(FormalTestManager.standardDevDataMap.get(standardDevMonitorId), DevData.class); String devMonitorId = FormalTestManager.pairsMap.inverse().get(standardDevMonitorId);
List<DevData> devDataList = BeanUtil.copyToList(FormalTestManager.devDataMap.get(standardDevMonitorId), DevData.class);
channelDevDataList.sort(Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime()))); channelDevDataList.sort(Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
HashMap sheet = new HashMap<>(); HashMap sheet = new HashMap<>();
ExportParams exportParams = new ExportParams(); ExportParams exportParams = new ExportParams();
String devName = FormalTestManager.devNameMapComm.get(ip); String standardDevName = FormalTestManager.devNameMapComm.get(ip);
String[] split = standardDevMonitorId.split(CnSocketUtil.SPLIT_TAG); String[] split = devMonitorId.split(CnSocketUtil.SPLIT_TAG);
String standardDevName = FormalTestManager.devNameMapComm.get(split[0]); String devName = FormalTestManager.devNameMapComm.get(split[0]);
exportParams.setSheetName(devName + "通道" + channel); exportParams.setSheetName(devName + "通道" + channel);
sheet.put("title", exportParams); sheet.put("title", exportParams);
List<AlignDataExcel> dataList = new ArrayList<>(); List<AlignDataExcel> dataList = new ArrayList<>();
channelDevDataList.stream().forEach(obj -> { channelDevDataList.stream().forEach(obj -> {
AlignDataExcel alignDataExcel = new AlignDataExcel(); AlignDataExcel alignDataExcel = new AlignDataExcel();
alignDataExcel.getDevDataConfig().setName(devName + "通道" + channel); alignDataExcel.getDevDataConfig().setName(devName + "通道" + split[1]);
alignDataExcel.getStandardDevDataConfig().setName(standardDevName + "通道" + split[1]); alignDataExcel.getStandardDevDataConfig().setName(standardDevName + "通道" + channel);
DevData.SqlDataDTO.ListDTO list1 = obj.getSqlData().get(0).getList(); DevData.SqlDataDTO.ListDTO list1 = obj.getSqlData().get(0).getList();
alignDataExcel.setTimeDev(obj.getTime()); alignDataExcel.setTimeStdDev(obj.getTime());
alignDataExcel.setUaDev(list1.getA()); alignDataExcel.setUaStdDev(list1.getA());
alignDataExcel.setUbDev(list1.getB()); alignDataExcel.setUbStdDev(list1.getB());
alignDataExcel.setUcDev(list1.getC()); alignDataExcel.setUcStdDev(list1.getC());
DevData devData = standarDevDataList.stream().filter(obj1 -> DetectionUtil.isAlignData(obj1, obj)).findFirst().get(); DevData devData = devDataList.stream().filter(obj1 -> DetectionUtil.isAlignData(obj1, obj)).findFirst().get();
if (ObjectUtil.isNotNull(devData)) { if (ObjectUtil.isNotNull(devData)) {
DevData.SqlDataDTO.ListDTO list2 = devData.getSqlData().get(0).getList(); DevData.SqlDataDTO.ListDTO list2 = devData.getSqlData().get(0).getList();
alignDataExcel.setTimeStdDev(devData.getTime()); alignDataExcel.setTimeDev(devData.getTime());
alignDataExcel.setUaStdDev(list2.getA()); alignDataExcel.setUaDev(list2.getA());
alignDataExcel.setUbStdDev(list2.getB()); alignDataExcel.setUbDev(list2.getB());
alignDataExcel.setUcStdDev(list2.getC()); alignDataExcel.setUcDev(list2.getC());
standarDevDataList.remove(devData); devDataList.remove(devData);
} }
dataList.add(alignDataExcel); dataList.add(alignDataExcel);
}); });
standarDevDataList.sort(Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime()))); devDataList.sort(Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
standarDevDataList.stream().forEach(obj -> { devDataList.stream().forEach(obj -> {
AlignDataExcel alignDataExcel = new AlignDataExcel(); AlignDataExcel alignDataExcel = new AlignDataExcel();
alignDataExcel.getDevDataConfig().setName(devName + "通道" + channel); alignDataExcel.getDevDataConfig().setName(devName + "通道" + split[1]);
alignDataExcel.getStandardDevDataConfig().setName(standardDevName + "通道" + split[1]); alignDataExcel.getStandardDevDataConfig().setName(standardDevName + "通道" + channel);
DevData.SqlDataDTO.ListDTO list2 = obj.getSqlData().get(0).getList(); DevData.SqlDataDTO.ListDTO list2 = obj.getSqlData().get(0).getList();
alignDataExcel.setTimeStdDev(obj.getTime()); alignDataExcel.setTimeDev(obj.getTime());
alignDataExcel.setUaStdDev(list2.getA()); alignDataExcel.setUaDev(list2.getA());
alignDataExcel.setUbStdDev(list2.getB()); alignDataExcel.setUbDev(list2.getB());
alignDataExcel.setUcStdDev(list2.getC()); alignDataExcel.setUcDev(list2.getC());
dataList.add(alignDataExcel); dataList.add(alignDataExcel);
}); });

View File

@@ -12,12 +12,11 @@
B_Value float DEFAULT NULL COMMENT 'B相值', B_Value float DEFAULT NULL COMMENT 'B相值',
C_Value float DEFAULT NULL COMMENT 'C相值', C_Value float DEFAULT NULL COMMENT 'C相值',
T_Value float DEFAULT NULL COMMENT 'T相值(没有相别的则存这里)', T_Value float DEFAULT NULL COMMENT 'T相值(没有相别的则存这里)',
Result_Flag int(1) NULL COMMENT '1合格 2不合格 4无法处理', Result_Flag int(1) NULL COMMENT '1合格 2不合格 4无法处理',
<choose> <choose>
<when test="isContrast"> <when test="isContrast">
Error_Id CHAR(32) NOT NULL COMMENT '误差体系表ID',
Num tinyint(1) unsigned DEFAULT 0 COMMENT '第几次检测', Num tinyint(1) unsigned DEFAULT 0 COMMENT '第几次检测',
PRIMARY KEY (Monitor_Id, Time_Id, Error_Id, AD_Type) PRIMARY KEY (Monitor_Id, Time_Id, AD_Type, Num)
</when> </when>
<otherwise> <otherwise>
Script_Id CHAR(32) NOT NULL COMMENT '检测脚本表Id', Script_Id CHAR(32) NOT NULL COMMENT '检测脚本表Id',
@@ -47,9 +46,8 @@
Result_Flag int(1) NOT NULL COMMENT '1合格 2不合格 4无法处理', Result_Flag int(1) NOT NULL COMMENT '1合格 2不合格 4无法处理',
<choose> <choose>
<when test="isContrast"> <when test="isContrast">
Error_Id CHAR(32) NOT NULL COMMENT '误差体系表ID',
Num tinyint(1) unsigned DEFAULT 0 COMMENT '第几次检测', Num tinyint(1) unsigned DEFAULT 0 COMMENT '第几次检测',
PRIMARY KEY (Monitor_Id, Error_Id, Num, AD_Type) PRIMARY KEY (Monitor_Id, AD_Type, Num)
</when> </when>
<otherwise> <otherwise>
Script_Id CHAR(32) NOT NULL COMMENT '检测脚本表Id', Script_Id CHAR(32) NOT NULL COMMENT '检测脚本表Id',

View File

@@ -10,11 +10,6 @@ import lombok.EqualsAndHashCode;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
public class ContrastBaseResult extends BaseResult { public class ContrastBaseResult extends BaseResult {
/**
* 误差体系Id
*/
private String errorId;
/** /**
* 第几次检测 * 第几次检测
*/ */

View File

@@ -57,7 +57,6 @@ public class DetectionDataServiceImpl extends ReplenishMybatisServiceImpl<Detect
List<String> monitorIds = contrastNonHarmonicResults.stream().map(ContrastNonHarmonicResult::getMonitorId).distinct().collect(Collectors.toList()); List<String> monitorIds = contrastNonHarmonicResults.stream().map(ContrastNonHarmonicResult::getMonitorId).distinct().collect(Collectors.toList());
if (CollUtil.isNotEmpty(monitorIds)) { if (CollUtil.isNotEmpty(monitorIds)) {
contrastNonHarmonicService.remove(new LambdaQueryWrapper<ContrastNonHarmonicResult>().in(ContrastNonHarmonicResult::getMonitorId, monitorIds) contrastNonHarmonicService.remove(new LambdaQueryWrapper<ContrastNonHarmonicResult>().in(ContrastNonHarmonicResult::getMonitorId, monitorIds)
.eq(ContrastNonHarmonicResult::getErrorId, contrastNonHarmonicResults.get(0).getErrorId())
.eq(ContrastNonHarmonicResult::getNum, contrastNonHarmonicResults.get(0).getNum())); .eq(ContrastNonHarmonicResult::getNum, contrastNonHarmonicResults.get(0).getNum()));
contrastNonHarmonicService.saveBatch(contrastNonHarmonicResults, 100); contrastNonHarmonicService.saveBatch(contrastNonHarmonicResults, 100);
} }
@@ -72,7 +71,7 @@ public class DetectionDataServiceImpl extends ReplenishMybatisServiceImpl<Detect
@Override @Override
@Transactional @Transactional
public Boolean acceptAd(List<? extends BaseResult> harmonicResultList, String code) { public Boolean acceptAd(List<? extends BaseResult> harmonicResultList, String code) {
if (CollUtil.isEmpty(harmonicResultList)) { if (CollUtil.isNotEmpty(harmonicResultList)) {
String adTable = "ad_harmonic_"; String adTable = "ad_harmonic_";
DynamicTableNameHandler.setTableName(adTable + code); DynamicTableNameHandler.setTableName(adTable + code);
@@ -92,7 +91,6 @@ public class DetectionDataServiceImpl extends ReplenishMybatisServiceImpl<Detect
List<String> monitorIds = contrastHarmonicResultList.stream().map(ContrastHarmonicResult::getMonitorId).distinct().collect(Collectors.toList()); List<String> monitorIds = contrastHarmonicResultList.stream().map(ContrastHarmonicResult::getMonitorId).distinct().collect(Collectors.toList());
if (CollUtil.isNotEmpty(monitorIds)) { if (CollUtil.isNotEmpty(monitorIds)) {
contrastHarmonicService.remove(new LambdaQueryWrapper<ContrastHarmonicResult>().in(ContrastHarmonicResult::getMonitorId, monitorIds) contrastHarmonicService.remove(new LambdaQueryWrapper<ContrastHarmonicResult>().in(ContrastHarmonicResult::getMonitorId, monitorIds)
.eq(ContrastHarmonicResult::getErrorId, contrastHarmonicResultList.get(0).getErrorId())
.eq(ContrastHarmonicResult::getNum, contrastHarmonicResultList.get(0).getNum())); .eq(ContrastHarmonicResult::getNum, contrastHarmonicResultList.get(0).getNum()));
contrastHarmonicService.saveBatch(contrastHarmonicResultList, 100); contrastHarmonicService.saveBatch(contrastHarmonicResultList, 100);
} }
@@ -125,7 +123,7 @@ public class DetectionDataServiceImpl extends ReplenishMybatisServiceImpl<Detect
List<String> monitorIds = contrastNonHarmonicResultList.stream().map(ContrastNonHarmonicResult::getMonitorId).distinct().collect(Collectors.toList()); List<String> monitorIds = contrastNonHarmonicResultList.stream().map(ContrastNonHarmonicResult::getMonitorId).distinct().collect(Collectors.toList());
if (CollUtil.isNotEmpty(monitorIds)) { if (CollUtil.isNotEmpty(monitorIds)) {
contrastNonHarmonicService.remove(new LambdaQueryWrapper<ContrastNonHarmonicResult>().in(ContrastNonHarmonicResult::getMonitorId, monitorIds) contrastNonHarmonicService.remove(new LambdaQueryWrapper<ContrastNonHarmonicResult>().in(ContrastNonHarmonicResult::getMonitorId, monitorIds)
.eq(ContrastNonHarmonicResult::getErrorId, contrastNonHarmonicResultList.get(0).getErrorId()) .eq(ContrastNonHarmonicResult::getAdType, contrastNonHarmonicResultList.get(0).getAdType())
.eq(ContrastNonHarmonicResult::getNum, contrastNonHarmonicResultList.get(0).getNum())); .eq(ContrastNonHarmonicResult::getNum, contrastNonHarmonicResultList.get(0).getNum()));
contrastNonHarmonicService.saveBatch(contrastNonHarmonicResultList, 100); contrastNonHarmonicService.saveBatch(contrastNonHarmonicResultList, 100);
} }
@@ -157,7 +155,7 @@ public class DetectionDataServiceImpl extends ReplenishMybatisServiceImpl<Detect
List<String> monitorIds = contrastHarmonicResultList.stream().map(ContrastHarmonicResult::getMonitorId).distinct().collect(Collectors.toList()); List<String> monitorIds = contrastHarmonicResultList.stream().map(ContrastHarmonicResult::getMonitorId).distinct().collect(Collectors.toList());
if (CollUtil.isNotEmpty(monitorIds)) { if (CollUtil.isNotEmpty(monitorIds)) {
contrastHarmonicService.remove(new LambdaQueryWrapper<ContrastHarmonicResult>().in(ContrastHarmonicResult::getMonitorId, monitorIds) contrastHarmonicService.remove(new LambdaQueryWrapper<ContrastHarmonicResult>().in(ContrastHarmonicResult::getMonitorId, monitorIds)
.eq(ContrastHarmonicResult::getErrorId, contrastHarmonicResultList.get(0).getErrorId()) .eq(ContrastHarmonicResult::getAdType, contrastHarmonicResultList.get(0).getAdType())
.eq(ContrastHarmonicResult::getNum, contrastHarmonicResultList.get(0).getNum())); .eq(ContrastHarmonicResult::getNum, contrastHarmonicResultList.get(0).getNum()));
contrastHarmonicService.saveBatch(contrastHarmonicResultList, 100); contrastHarmonicService.saveBatch(contrastHarmonicResultList, 100);
} }

View File

@@ -39,16 +39,15 @@ public class TableGenServiceImpl implements TableGenService {
" Time_Id DATETIME(3) NOT NULL COMMENT '时间',\n" + " Time_Id DATETIME(3) NOT NULL COMMENT '时间',\n" +
" AD_Type CHAR(32) NOT NULL COMMENT '检测指标,字典表',\n" + " AD_Type CHAR(32) NOT NULL COMMENT '检测指标,字典表',\n" +
" Data_Type CHAR(32) NOT NULL COMMENT '数据指标只有数据源为分钟统计时候才会使用最大、最小、平均、CP95默认平均值字典表',\n" + " Data_Type CHAR(32) NOT NULL COMMENT '数据指标只有数据源为分钟统计时候才会使用最大、最小、平均、CP95默认平均值字典表',\n" +
A + B + C +
" Result_Flag int(1) NULL COMMENT '0不合格 1合格 4无法处理',\n" + " Result_Flag int(1) NULL COMMENT '0不合格 1合格 4无法处理',\n" +
A + B + C +
(isContrast ? (isContrast ?
" Error_Id CHAR(32) NOT NULL COMMENT '误差体系表Id',\n" +
" Num tinyint(1) unsigned DEFAULT 0 COMMENT '第几次检测',\n" + " Num tinyint(1) unsigned DEFAULT 0 COMMENT '第几次检测',\n" +
" PRIMARY KEY (Monitor_Id,Time_Id,Error_Id, AD_Type)\n" " PRIMARY KEY (Monitor_Id,Time_Id, AD_Type, Num)\n"
: :
" Script_Id CHAR(32) NOT NULL COMMENT '检测脚本表Id',\n" + " Script_Id CHAR(32) NOT NULL COMMENT '检测脚本表Id',\n" +
" Sort int(4) NOT NULL COMMENT '总检测脚本中的测试项序号',\n"+ " Sort int(4) NOT NULL COMMENT '总检测脚本中的测试项序号',\n" +
" PRIMARY KEY (Monitor_Id, Time_Id, Script_Id, Sort, AD_Type)\n" " PRIMARY KEY (Monitor_Id, Time_Id, Script_Id, Sort, AD_Type)\n"
) + ") COMMENT='谐波类原始数据表';"; ) + ") COMMENT='谐波类原始数据表';";
tableGenMapper.genAdHarmonicTable(sql); tableGenMapper.genAdHarmonicTable(sql);
@@ -60,15 +59,14 @@ public class TableGenServiceImpl implements TableGenService {
" Time_Id DATETIME(3) NULL COMMENT '时间',\n" + " Time_Id DATETIME(3) NULL COMMENT '时间',\n" +
" AD_Type CHAR(32) NOT NULL COMMENT '检测指标,字典表',\n" + " AD_Type CHAR(32) NOT NULL COMMENT '检测指标,字典表',\n" +
" Data_Type CHAR(32) NOT NULL COMMENT '数据指标只有数据源为分钟统计时候才会使用最大、最小、平均、CP95默认平均值字典表',\n" + " Data_Type CHAR(32) NOT NULL COMMENT '数据指标只有数据源为分钟统计时候才会使用最大、最小、平均、CP95默认平均值字典表',\n" +
a + b + c +
" Result_Flag int(1) NOT NULL COMMENT '1合格 2不合格 4无法处理',\n" + " Result_Flag int(1) NOT NULL COMMENT '1合格 2不合格 4无法处理',\n" +
a + b + c +
(isContrast ? (isContrast ?
" Error_Id CHAR(32) NOT NULL COMMENT '误差体系表Id',\n" + " Num tinyint(1) unsigned DEFAULT 0 COMMENT '第几次检测',\n" +
" Num tinyint(1) unsigned DEFAULT 0 COMMENT '第几次检测',\n" + " PRIMARY KEY (Monitor_Id, AD_Type, Num)\n"
" PRIMARY KEY (Monitor_Id, Error_Id, Num, AD_Type)\n"
: :
" Script_Id CHAR(32) NOT NULL COMMENT '检测脚本表Id',\n" + " Script_Id CHAR(32) NOT NULL COMMENT '检测脚本表Id',\n" +
" Sort int(4) NOT NULL COMMENT '总检测脚本中的测试项序号',\n"+ " Sort int(4) NOT NULL COMMENT '总检测脚本中的测试项序号',\n" +
" PRIMARY KEY (Monitor_Id,Script_Id, Sort, AD_Type)\n" " PRIMARY KEY (Monitor_Id,Script_Id, Sort, AD_Type)\n"
) + ") COMMENT='谐波类检测结果表';"; ) + ") COMMENT='谐波类检测结果表';";
tableGenMapper.genAdHarmonicTable(sql2); tableGenMapper.genAdHarmonicTable(sql2);

View File

@@ -60,4 +60,6 @@ public interface IDictTreeService extends IService<DictTree> {
List<DictTree> getDictTreeById(List<String> ids); List<DictTree> getDictTreeById(List<String> ids);
DictTree getDictTreeByCode(String code); DictTree getDictTreeByCode(String code);
List<DictTree> listByFatherIds(List<String> fatherIdList);
} }

View File

@@ -7,7 +7,6 @@ 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.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.gather.system.dictionary.mapper.DictTreeMapper; import com.njcn.gather.system.dictionary.mapper.DictTreeMapper;
import com.njcn.gather.system.dictionary.pojo.param.DictTreeParam; import com.njcn.gather.system.dictionary.pojo.param.DictTreeParam;
@@ -82,7 +81,7 @@ public class DictTreeServiceImpl extends ServiceImpl<DictTreeMapper, DictTree> i
public boolean updateDictTree(DictTreeParam.UpdateParam param) { public boolean updateDictTree(DictTreeParam.UpdateParam param) {
param.setName(param.getName().trim()); param.setName(param.getName().trim());
DictTree dictTree = this.getById(param.getId()); DictTree dictTree = this.getById(param.getId());
if("975f63baeb6f653c54fca226a9ae36ca".equals(param.getId()) || dictTree.getPids().contains("975f63baeb6f653c54fca226a9ae36ca")){ if ("975f63baeb6f653c54fca226a9ae36ca".equals(param.getId()) || dictTree.getPids().contains("975f63baeb6f653c54fca226a9ae36ca")) {
throw new BusinessException(SystemResponseEnum.CAN_NOT_UPDATE_USED_DICT); throw new BusinessException(SystemResponseEnum.CAN_NOT_UPDATE_USED_DICT);
} }
checkRepeat(param, true); checkRepeat(param, true);
@@ -96,7 +95,7 @@ public class DictTreeServiceImpl extends ServiceImpl<DictTreeMapper, DictTree> i
public boolean deleteDictTree(String id) { public boolean deleteDictTree(String id) {
boolean result = false; boolean result = false;
DictTree dictTree = this.getById(id); DictTree dictTree = this.getById(id);
if("975f63baeb6f653c54fca226a9ae36ca".equals(id) || dictTree.getPids().contains("975f63baeb6f653c54fca226a9ae36ca")){ if ("975f63baeb6f653c54fca226a9ae36ca".equals(id) || dictTree.getPids().contains("975f63baeb6f653c54fca226a9ae36ca")) {
throw new BusinessException(SystemResponseEnum.CAN_NOT_DELETE_USED_DICT); throw new BusinessException(SystemResponseEnum.CAN_NOT_DELETE_USED_DICT);
} }
@@ -139,6 +138,14 @@ public class DictTreeServiceImpl extends ServiceImpl<DictTreeMapper, DictTree> i
); );
} }
@Override
public List<DictTree> listByFatherIds(List<String> fatherIdList) {
if (CollUtil.isNotEmpty(fatherIdList)) {
return this.lambdaQuery().in(DictTree::getPid, fatherIdList).eq(DictTree::getState, DictConst.ENABLE).list();
}
return null;
}
private void checkRepeat(DictTreeParam dictTreeParam, boolean isExcludeSelf) { private void checkRepeat(DictTreeParam dictTreeParam, boolean isExcludeSelf) {
LambdaQueryWrapper<DictTree> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<DictTree> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(DictTree::getPid, dictTreeParam.getPid()) // 同一父节点下不能有相同的code wrapper.eq(DictTree::getPid, dictTreeParam.getPid()) // 同一父节点下不能有相同的code

View File

@@ -14,7 +14,7 @@ import java.util.Map;
*/ */
public interface ISysRegResService extends IService<SysRegRes> { public interface ISysRegResService extends IService<SysRegRes> {
/** /**
* 查询版本注册 * 查询版本注册信息
* @return * @return
*/ */
SysRegRes getRegResByType(String type); SysRegRes getRegResByType(String type);
@@ -38,4 +38,10 @@ public interface ISysRegResService extends IService<SysRegRes> {
* @return 版本注册信息 * @return 版本注册信息
*/ */
SysRegResVO listRegRes(); SysRegResVO listRegRes();
/**
* 获取比对式的注册信息
* @return
*/
SysRegRes getContrastRegRes();
} }

View File

@@ -212,6 +212,11 @@ public class SysRegResServiceImpl extends ServiceImpl<SysRegResMapper, SysRegRes
return sysRegResVO; return sysRegResVO;
} }
@Override
public SysRegRes getContrastRegRes() {
return this.getRegResByType("7cd65363a6bf675ae408f28a281b77d4");
}
/** /**
* 格式化日期 (将日期格式化为yyyy-MM-dd) * 格式化日期 (将日期格式化为yyyy-MM-dd)
* *