package com.njcn.gather.detection.handler;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.collect.HashBiMap;
import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.gather.detection.pojo.dto.DevXiNumData;
import com.njcn.gather.detection.pojo.dto.WaveCommandDTO;
import com.njcn.gather.detection.pojo.dto.WaveResultDTO;
import com.njcn.gather.detection.pojo.enums.*;
import com.njcn.gather.detection.pojo.param.ContrastDetectionParam;
import com.njcn.gather.detection.pojo.param.DevPhaseSequenceParam;
import com.njcn.gather.detection.pojo.param.PreDetectionParam;
import com.njcn.gather.detection.pojo.po.AdPair;
import com.njcn.gather.detection.pojo.po.DevData;
import com.njcn.gather.detection.pojo.vo.*;
import com.njcn.gather.detection.service.IAdPariService;
import com.njcn.gather.detection.service.impl.DetectionServiceImpl;
import com.njcn.gather.detection.util.DetectionUtil;
import com.njcn.gather.detection.util.socket.*;
import com.njcn.gather.detection.util.socket.websocket.WebServiceManager;
import com.njcn.gather.device.pojo.enums.PatternEnum;
import com.njcn.gather.device.pojo.po.PqStandardDevGain;
import com.njcn.gather.device.pojo.po.PqStandardDevGainRecord;
import com.njcn.gather.device.pojo.vo.PreDetection;
import com.njcn.gather.device.service.IPqDevService;
import com.njcn.gather.device.service.IPqStandardDevGainRecordService;
import com.njcn.gather.device.service.IPqStandardDevGainService;
import com.njcn.gather.device.service.IPqStandardDevService;
import com.njcn.gather.monitor.pojo.po.PqMonitor;
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.plan.service.IAdPlanTestConfigService;
import com.njcn.gather.report.pojo.enums.PowerIndexEnum;
import com.njcn.gather.storage.pojo.po.ContrastHarmonicResult;
import com.njcn.gather.storage.pojo.po.ContrastNonHarmonicResult;
import com.njcn.gather.storage.service.DetectionDataDealService;
import com.njcn.gather.system.cfg.pojo.po.SysTestConfig;
import com.njcn.gather.system.cfg.service.ISysTestConfigService;
import com.njcn.gather.system.config.PathConfig;
import com.njcn.gather.system.dictionary.pojo.enums.DictDataEnum;
import com.njcn.gather.system.dictionary.pojo.po.DictData;
import com.njcn.gather.system.dictionary.pojo.po.DictTree;
import com.njcn.gather.system.dictionary.service.IDictDataService;
import com.njcn.gather.system.dictionary.service.IDictTreeService;
import com.njcn.gather.tools.comtrade.comparewave.core.model.CompareWaveDTO;
import com.njcn.gather.tools.comtrade.comparewave.core.model.PqsDataStruct;
import com.njcn.gather.tools.comtrade.comparewave.service.ICompareWaveService;
import com.njcn.gather.util.StorageUtil;
import com.njcn.web.utils.ExcelUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;


/**
 * @author caozehui
 * @data 2025-07-24
 */
@Service
@RequiredArgsConstructor
public class SocketContrastResponseService {

    private final IAdPlanService adPlanService;
    private final IDictDataService dictDataService;
    private final IPqDevService pqDevService;
    private final IPqStandardDevService pqStandardDevService;
    private final IDictTreeService dictTreeService;
    private final DetectionDataDealService detectionDataDealService;
    private final IPqMonitorService pqMonitorService;
    private final DetectionServiceImpl detectionService;
    private final ISysTestConfigService sysTestConfigService;
    private final IAdPariService adPairService;
    private final ICompareWaveService compareWaveService;
    private final IAdPlanTestConfigService adPlanTestConfigService;
    private final IPqStandardDevGainService pqStandardDevGainService;
    private final IPqStandardDevGainRecordService pqStandardDevGainRecordService;


    /**
     * 存放结果
     */
    private boolean checkResult = false;

    /**
     * 成功的配对 key:被检设备ip_通道号，value:配对设备ip_通道号
     */
    private Map<String, String> successPair = HashBiMap.create();

    /**
     * 接收数据成功的测点(设备ip_通道号)
     */
    private Set<String> successComm = new HashSet<>();

    /**
     * 接收数据失败的测点(设备ip_通道号)
     */
    private Set<String> failComm = new HashSet<>();

    /**
     * 存放比对式注册信息（包含了实时数据有效组数、统计数据有效组数、录播数据有效组数、闪变数据有效组数）
     */
//    private SysRegRes contrastRegRes = null;


//    @Value("${report.reportDir}")
//    private String alignDataFilePath;
    private final PathConfig pathConfig;

    public static final Map<String, List<String>> testItemCodeMap = new HashMap() {{
        put(PowerIndexEnum.FREQ.getKey(), Arrays.asList(DetectionCodeEnum.FREQ.getCode()));
        put(PowerIndexEnum.V.getKey(), Arrays.asList(DetectionCodeEnum.VRMS.getCode(), DetectionCodeEnum.PVRMS.getCode()));
        put(PowerIndexEnum.HV.getKey(), Arrays.asList(DetectionCodeEnum.V2_50.getCode(), DetectionCodeEnum.PV2_50.getCode()));
        put(PowerIndexEnum.HI.getKey(), Arrays.asList(DetectionCodeEnum.I2_50.getCode()));
        put(PowerIndexEnum.HP.getKey(), Arrays.asList(DetectionCodeEnum.P2_50.getCode()));
        put(PowerIndexEnum.HSV.getKey(), Arrays.asList(DetectionCodeEnum.SV_1_49.getCode(), DetectionCodeEnum.PSV_1_49.getCode()));
        put(PowerIndexEnum.HSI.getKey(), Arrays.asList(DetectionCodeEnum.SI_1_49.getCode()));
        put(PowerIndexEnum.I.getKey(), Arrays.asList(DetectionCodeEnum.IRMS.getCode()));
        put(PowerIndexEnum.IMBV.getKey(), Arrays.asList(DetectionCodeEnum.V_UNBAN.getCode()));
        put(PowerIndexEnum.IMBA.getKey(), Arrays.asList(DetectionCodeEnum.I_UNBAN.getCode()));
        put(PowerIndexEnum.F.getKey(), Arrays.asList(DetectionCodeEnum.PST.getCode()));
    }};

    /**
     * 获取比对式检测次数
     *
     * @param devMonitorIds 被检设备监测点id列表
     * @return
     */
    private Map<String, Integer> getContrastTestNum(List<String> devMonitorIds) {
        Map<String, Integer> resultMap = new HashMap<>();
        for (String devMonitorId : devMonitorIds) {
            Integer maxNum = 1;
            List<AdPair> adPairList = adPairService.lambdaQuery().select(AdPair::getNum)
                    .eq(AdPair::getDevMonitorId, devMonitorId)
                    .orderByDesc(AdPair::getNum)
                    .last("LIMIT 1").list();
            if (CollUtil.isNotEmpty(adPairList)) {
                if (maxNum <= adPairList.get(0).getNum()) {
                    maxNum = adPairList.get(0).getNum() + 1;
                }
            }

            resultMap.put(devMonitorId, maxNum);
            resultMap.put(FormalTestManager.pairsIdMap.get(devMonitorId), maxNum);
        }
        return resultMap;
    }

    /**
     * 初始化操作
     *
     * @param param
     */
    public void init(ContrastDetectionParam param) {
        FormalTestManager.currentTestPlan = adPlanService.getById(param.getPlanId());
        FormalTestManager.curretntTestPlanConfig = adPlanTestConfigService.getByPlanId(param.getPlanId());
        FormalTestManager.waveNum = 0;
        FormalTestManager.preNumTestResultList.clear();

        checkResult = false;
        FormalTestManager.isTesting = true;
        FormalTestManager.realProtocol = false;
        FormalTestManager.statisticsProtocol = false;
        FormalTestManager.voltageProtocol = false;
        FormalTestManager.pstDataType = null;
        FormalTestManager.isPstData = false;
        FormalTestManager.isWaveCheck = false;
        FormalTestManager.isXu = param.getPhaseCheck() == 1 ? true : false;
//        FormalTestManager.isXu = true;
        FormalTestManager.nonWaveDataSourceEnum = null;
        DetectionServiceImpl.vAndIResultMap = new HashMap<>();

        String[] datasourceIds = FormalTestManager.currentTestPlan.getDatasourceId().split(",");
        for (String datasourceId : datasourceIds) {
            switch (DataSourceEnum.ofByValue(datasourceId)) {
                case REAL_DATA:
                    FormalTestManager.nonWaveDataSourceEnum = DataSourceEnum.REAL_DATA;
                    break;
                case WAVE_DATA:
                    FormalTestManager.isWaveCheck = true;
                    break;
                case MINUTE_STATISTICS_MIN:
                    FormalTestManager.nonWaveDataSourceEnum = DataSourceEnum.MINUTE_STATISTICS_MIN;
                    break;
                case MINUTE_STATISTICS_MAX:
                    FormalTestManager.nonWaveDataSourceEnum = DataSourceEnum.MINUTE_STATISTICS_MAX;
                    break;
                case MINUTE_STATISTICS_AVG:
                    FormalTestManager.nonWaveDataSourceEnum = DataSourceEnum.MINUTE_STATISTICS_AVG;
                    break;
                case MINUTE_STATISTICS_CP95:
                    FormalTestManager.nonWaveDataSourceEnum = DataSourceEnum.MINUTE_STATISTICS_CP95;
                    break;
            }
        }

        if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
            SocketManager.contrastClockMap.put(FormalTestManager.nonWaveDataSourceEnum, 0L);
        }

        SocketManager.contrastClockMap.clear();
        successComm.clear();
        failComm.clear();
        successPair.clear();
        FormalTestManager.isRemoveSocket = false;
        FormalTestManager.waveCheckFlag = false;
        FormalTestManager.scheduler = null;
        if (FormalTestManager.scheduledFuture != null) {
            FormalTestManager.scheduledFuture.cancel(true);
            if (FormalTestManager.scheduler != null) {
                FormalTestManager.scheduler.shutdown();
            }
            FormalTestManager.scheduledFuture = null;
        }

        HashBiMap<String, String> hashBiMap = HashBiMap.create(param.getPairs());
        FormalTestManager.pairsIdMap.clear();
        FormalTestManager.pairsIdMap.putAll(hashBiMap);
        FormalTestManager.waveResultDTOMap.clear();

        List<PreDetection> pqDevList = pqDevService.getDevInfo(param.getDevIds());
        // key为被检设备id_通道号，value为监测点DTO
        Map<String, PreDetection.MonitorListDTO> devMonitorMap = new HashMap<>();
        pqDevList.forEach(x -> {
            List<PreDetection.MonitorListDTO> monitorList = x.getMonitorList();
            //移除不做检测的监测点
            monitorList.removeIf(y -> !hashBiMap.containsKey(x.getDevId() + CnSocketUtil.SPLIT_TAG + y.getLine()));
            monitorList.forEach(y -> {
                devMonitorMap.put(x.getDevId() + CnSocketUtil.SPLIT_TAG + y.getLine(), y);
            });
        });
        FormalTestManager.devList.clear();
        FormalTestManager.devList.addAll(pqDevList);

        // key为标准设备id，value为标准设备下的监测点列表(Id_通道号)
        Map<String, List<String>> pairsMap = new HashMap<>();
        hashBiMap.forEach((key, value) -> {
            String[] split = value.split(CnSocketUtil.SPLIT_TAG);
            List<String> monitorIdList = pairsMap.getOrDefault(split[0], new ArrayList<>());
            monitorIdList.add(value);
            pairsMap.put(split[0], monitorIdList);
        });

        FormalTestManager.standardDevList.clear();
        List<String> standardDevIds = hashBiMap.values().stream().map(key -> key.split(CnSocketUtil.SPLIT_TAG)[0]).distinct().collect(Collectors.toList());
        FormalTestManager.standardDevList.addAll(pqStandardDevService.listStandardDevPreDetection(standardDevIds));

        FormalTestManager.pairsIpMap.clear();

        final Integer[] maxStatInterval = {0};
        // 标准设备根据配对关系设置监测点
        FormalTestManager.standardDevList.stream().forEach(x -> {
            List<PreDetection.MonitorListDTO> monitorList = new ArrayList<>();

            pairsMap.get(x.getDevId()).forEach(y -> {
                PreDetection.MonitorListDTO monitorListDTO = new PreDetection.MonitorListDTO();
                String[] split = y.split(CnSocketUtil.SPLIT_TAG);
                monitorListDTO.setLineId(x.getDevIP() + CnSocketUtil.SPLIT_TAG + split[1]);
                monitorListDTO.setLine(Integer.valueOf(split[1]));

                PreDetection.MonitorListDTO monitorListDTO1 = devMonitorMap.get(hashBiMap.inverse().get(y));

                monitorListDTO.setConnection(monitorListDTO1.getConnection());
                monitorListDTO.setPtStr(monitorListDTO1.getPtStr());
                monitorListDTO.setCtStr(monitorListDTO1.getCtStr());
                monitorListDTO.setStatInterval(monitorListDTO1.getStatInterval());
                FormalTestManager.pairsIpMap.put(monitorListDTO1.getLineId(), monitorListDTO.getLineId());

                maxStatInterval[0] = Math.max(maxStatInterval[0], monitorListDTO.getStatInterval());
                monitorList.add(monitorListDTO);
            });
            x.setMonitorList(monitorList);
        });

        FormalTestManager.maxTime = (long) (maxStatInterval[0] * 5 * 60);

        FormalTestManager.devIdMapComm.clear();
        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)));

        Map<String, Integer> numMap = getContrastTestNum(param.getPairs().keySet().stream().collect(Collectors.toList()));
        FormalTestManager.numMap.clear();
        FormalTestManager.numMap.putAll(numMap);
        SysTestConfig oneConfig = sysTestConfigService.getOneConfig();
        if (param.isFormalTestSelected()) {
            numMap.forEach((devMonitorId, num) -> {
                if (oneConfig.getMaxTime() < num) {
                    throw new BusinessException(DetectionResponseEnum.EXCEED_MAX_TIME);
                }
            });
        }

        DictData pattern = dictDataService.getById(FormalTestManager.currentTestPlan.getPattern());
        FormalTestManager.patternEnum = PatternEnum.getEnum(pattern.getCode());

        FormalTestManager.devNameMapComm.clear();
        FormalTestManager.devNameMapComm.putAll(FormalTestManager.devList.stream().collect(Collectors.toMap(PreDetection::getDevIP, PreDetection::getDevName)));
        FormalTestManager.devNameMapComm.putAll(FormalTestManager.standardDevList.stream().collect(Collectors.toMap(PreDetection::getDevIP, PreDetection::getDevName)));

        FormalTestManager.devDataMap.clear();
        FormalTestManager.devDataMap.putAll(FormalTestManager.devList.stream().flatMap(x -> x.getMonitorList().stream()).collect(Collectors.toMap(PreDetection.MonitorListDTO::getLineId, x -> new ArrayList<>())));
        FormalTestManager.standardDevDataMap.clear();
        FormalTestManager.standardDevDataMap.putAll(FormalTestManager.standardDevList.stream().flatMap(x -> x.getMonitorList().stream()).collect(Collectors.toMap(PreDetection.MonitorListDTO::getLineId, x -> new ArrayList<>())));

        FormalTestManager.monitorMap.clear();
        FormalTestManager.monitorMap.putAll(FormalTestManager.devList.stream().flatMap(x -> x.getMonitorList().stream()).collect(Collectors.toMap(PreDetection.MonitorListDTO::getLineId, obj -> obj)));
        FormalTestManager.monitorMap.putAll(FormalTestManager.standardDevList.stream().flatMap(x -> x.getMonitorList().stream()).collect(Collectors.toMap(PreDetection.MonitorListDTO::getLineId, obj -> obj)));

        FormalTestManager.devMapMonitorNum.clear();
        FormalTestManager.devMapMonitorNum.putAll(FormalTestManager.devList.stream().collect(Collectors.toMap(PreDetection::getDevIP, it -> it.getMonitorList().stream().map(PreDetection.MonitorListDTO::getLineId).collect(Collectors.toList()))));
        FormalTestManager.devMapMonitorNum.putAll(FormalTestManager.standardDevList.stream().collect(Collectors.toMap(PreDetection::getDevIP, it -> it.getMonitorList().stream().map(PreDetection.MonitorListDTO::getLineId).collect(Collectors.toList()))));

        FormalTestManager.testItemMap.clear();
        List<String> testItemIds = Arrays.asList(FormalTestManager.currentTestPlan.getTestItem().split(","));
        List<DictTree> dictTreeList = dictTreeService.getDictTreeById(testItemIds);

        List<String> fatherIdList = dictTreeList.stream().map(DictTree::getId).collect(Collectors.toList());
        List<DictTree> childDictTreeList = dictTreeService.listByFatherIds(fatherIdList);
        if (CollUtil.isNotEmpty(childDictTreeList)) {
            List<String> collect1 = testItemCodeMap.values().stream().flatMap(Collection::stream).collect(Collectors.toList());
            DetectionCodeEnum prefixEnum = this.getPrefixEnum();
            FormalTestManager.testItemMap.putAll(childDictTreeList.stream().filter(x -> collect1.contains(x.getCode())).collect(Collectors.toMap(obj -> prefixEnum.getCode() + obj.getCode(), obj -> obj.getId())));
        }

        DictData dictData = dictDataService.getDictDataById(FormalTestManager.currentTestPlan.getDataRule());
        if (ObjectUtil.isNotNull(dictData)) {
            FormalTestManager.dataRule = DictDataEnum.getDictDataEnumByCode(dictData.getCode());
        } else {
            FormalTestManager.dataRule = DictDataEnum.SECTION_VALUE;
        }


        FormalTestManager.currentStep = SourceOperateCodeEnum.YJC_SBTXJY;
        FormalTestManager.checkStartTime = LocalDateTime.now();
    }

    public void deal(PreDetectionParam param, String msg) throws Exception {
        SocketDataMsg socketDataMsg = MsgUtil.socketDataMsg(msg);

        switch (Objects.requireNonNull(FormalTestManager.currentStep)) {
            //设备通讯校验
            case YJC_SBTXJY:
                this.devComm(socketDataMsg, param);
                break;
            //模型一致性校验
            case YJC_MXYZXJY:
                this.modelDeal(socketDataMsg, param);
                break;
            // 实时数据对齐校验
            case YJC_ALIGN:
                this.alignDeal(socketDataMsg, param);
                break;
            //相序校验
            case YJC_XUJY:
                this.devXu(param, socketDataMsg);
                break;
            //正式检测
            case FORMAL_REAL:
                this.formalDeal(param, socketDataMsg);
                break;
            // 启动录波
            case RECORD_WAVE_STEP1:
                this.recordWave(param, socketDataMsg);
                break;
            //系数校验
            case Coefficient_Check:
                this.coefficient(param, socketDataMsg);
                break;
            //退出关闭
            case QUITE:
                quitDeal(socketDataMsg, param);
                break;
            default:
                break;
        }

    }

    /**
     * 装置通讯检测
     */
    private void devComm(SocketDataMsg socketDataMsg, PreDetectionParam param) {
        SourceResponseCodeEnum dictDataEnumByCode = SourceResponseCodeEnum.getDictDataEnumByCode(socketDataMsg.getCode());
        String s = param.getUserPageId() + CnSocketUtil.CONTRAST_DEV_TAG;
        SourceOperateCodeEnum quitOperateCode = this.getQuitOperateCode();

        boolean real = false;
        boolean statistics = false;
        boolean voltage = false;
        if (ObjectUtil.isNotNull(dictDataEnumByCode)) {
            SourceOperateCodeEnum requestOperateCode = this.getRequestOperateCode();

            switch (dictDataEnumByCode) {
                case SUCCESS:
                    if (SourceOperateCodeEnum.RECORD_WAVE_STEP1.getValue().equals(socketDataMsg.getRequestId())) {
                        WaveResultDTO waveResultDTO = JSON.parseObject(socketDataMsg.getData(), WaveResultDTO.class);
                        FormalTestManager.waveResultDTOMap.put(waveResultDTO.getId(), waveResultDTO);
                        successComm.add(waveResultDTO.getId());

                        if (successComm.size() == FormalTestManager.monitorMap.size()) {
                            FormalTestManager.scheduledFuture.cancel(true);
                            FormalTestManager.scheduler.shutdown();
                            FormalTestManager.scheduler = null;

                            SocketDataMsg webSend = new SocketDataMsg();
                            webSend.setRequestId(SourceOperateCodeEnum.YJC_SBTXJY.getValue());
                            webSend.setOperateCode(SourceOperateCodeEnum.DEV_INIT_GATHER_03.getValue());
                            webSend.setCode(SourceResponseCodeEnum.ALL_SUCCESS.getCode());
                            webSend.setData("设备通讯校验成功！");
                            WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));

                            successComm.clear();
                            failComm.clear();

                            //开始模型一致性校验
                            System.out.println("装置通信成功！》》》》》》》》》》》》》》》》》》》》》》》》》》》》》开始模型一致性校验》》》》》》》》》》》》》》》》");
                            List<String> allDataType = this.getAllDataType();
                            if (allDataType.contains(DetectionCodeEnum.AVG_PREFIX.getCode() + DetectionCodeEnum.PST.getCode())) {
                                allDataType.remove(DetectionCodeEnum.AVG_PREFIX.getCode() + DetectionCodeEnum.PST.getCode());
                            }
                            if (CollUtil.isNotEmpty(allDataType)) {
                                this.sendModelDeal(s, allDataType);
                            } else {
                                SocketDataMsg webSend1 = new SocketDataMsg();
                                webSend1.setRequestId(SourceOperateCodeEnum.YJC_MXYZXJY.getValue());
                                webSend1.setCode(SourceResponseCodeEnum.ALL_SUCCESS.getCode());//最终成功推送
                                WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend1));

                                System.out.println("模型一致性校验成功！》》》》》》》》》》》》》》》》》》》》》》》》》》》》》开始数据对齐校验》》》》》》》》》》》》》》》》");

                                this.sendAlignData(s, requestOperateCode);

                                FormalTestManager.currentStep = SourceOperateCodeEnum.YJC_ALIGN;

                                this.resetTimer();
                            }
                        }
                    } else {
                        String result = socketDataMsg.getData();
                        successComm.add(result);
                        //单个测点通讯成功
                        socketDataMsg.setRequestId(SourceOperateCodeEnum.YJC_SBTXJY.getValue());
                        String msg = "";
                        statistics = SourceOperateCodeEnum.DEV_INIT_GATHER_01.getValue().equals(socketDataMsg.getOperateCode());
                        real = SourceOperateCodeEnum.DEV_INIT_GATHER_02.getValue().equals(socketDataMsg.getOperateCode());
                        voltage = SourceOperateCodeEnum.DEV_INIT_GATHER_03.getValue().equals(socketDataMsg.getOperateCode());
                        if (real) {
                            msg = "实时协议校验成功！";
                            FormalTestManager.realProtocol = true;
                        }
                        if (voltage) {
                            msg = "暂态协议校验成功！";
                            FormalTestManager.voltageProtocol = true;
                        }
                        if (statistics) {
                            msg = "统计协议校验成功！";
                            FormalTestManager.statisticsProtocol = true;
                        }
                        MsgUtil.msgToWebData(socketDataMsg, FormalTestManager.devNameMapComm, 1);
                        socketDataMsg.setData(socketDataMsg.getData() + msg);
                        WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));

                        System.out.println(msg + successComm.size() + "=====" + FormalTestManager.monitorMap.size());
                        if (successComm.size() == FormalTestManager.monitorMap.size()) {
                            if (FormalTestManager.testItemMap.keySet().stream().anyMatch(key -> DetectionCodeEnum.PST.getCode().equals(key.split("\\$")[1]))) {
                                if (!FormalTestManager.statisticsProtocol) {
                                    successComm.clear();
                                    failComm.clear();

                                    SocketMsg<String> socketMsg = new SocketMsg<>();
                                    // 进行统计协议校验
                                    socketMsg.setRequestId(SourceOperateCodeEnum.YJC_XYJY.getValue());
                                    socketMsg.setOperateCode(SourceOperateCodeEnum.DEV_INIT_GATHER_01.getValue());
                                    Map<String, List<PreDetection>> map = new HashMap<>(1);
                                    List<PreDetection> preDetectionList = new ArrayList<>();
                                    preDetectionList.addAll(FormalTestManager.devList);
                                    preDetectionList.addAll(FormalTestManager.standardDevList);
                                    map.put("deviceList", preDetectionList);
                                    socketMsg.setData(JSON.toJSONString(map));
                                    SocketManager.sendMsg(s, JSON.toJSONString(socketMsg));
                                    return;
                                }
                            }
                            if (FormalTestManager.isWaveCheck) {
                                if (FormalTestManager.voltageProtocol) {
                                    successComm.clear();
                                    failComm.clear();

                                    // 下发录波指令
                                    this.sendRecordWave(s);
                                    return;
                                } else {
                                    successComm.clear();
                                    failComm.clear();

                                    SocketMsg<String> socketMsg = new SocketMsg<>();
                                    // 进行暂态协议校验
                                    socketMsg.setRequestId(SourceOperateCodeEnum.YJC_XYJY.getValue());
                                    socketMsg.setOperateCode(SourceOperateCodeEnum.DEV_INIT_GATHER_03.getValue());
                                    Map<String, List<PreDetection>> map = new HashMap<>(1);
                                    List<PreDetection> preDetectionList = new ArrayList<>();
                                    preDetectionList.addAll(FormalTestManager.devList);
                                    preDetectionList.addAll(FormalTestManager.standardDevList);
                                    map.put("deviceList", preDetectionList);
                                    socketMsg.setData(JSON.toJSONString(map));
                                    SocketManager.sendMsg(s, JSON.toJSONString(socketMsg));
                                }
                            } else {
                                socketDataMsg.setCode(SourceResponseCodeEnum.ALL_SUCCESS.getCode());
                                socketDataMsg.setData("设备通讯校验成功！");
                                WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));

                                //开始模型一致性校验
                                System.out.println("装置通信成功！》》》》》》》》》》》》》》》》》》》》》》》》》》》》》开始模型一致性校验》》》》》》》》》》》》》》》》");

                                List<String> allDataType = this.getAllDataType();
                                if (allDataType.contains(DetectionCodeEnum.AVG_PREFIX.getCode() + DetectionCodeEnum.PST.getCode())) {
                                    allDataType.remove(DetectionCodeEnum.AVG_PREFIX.getCode() + DetectionCodeEnum.PST.getCode());
                                }
                                if (CollUtil.isNotEmpty(allDataType)) {
                                    this.sendModelDeal(s, allDataType);
                                } else {
                                    SocketDataMsg webSend = new SocketDataMsg();
                                    webSend.setRequestId(SourceOperateCodeEnum.YJC_MXYZXJY.getValue());
                                    webSend.setCode(SourceResponseCodeEnum.ALL_SUCCESS.getCode());//最终成功推送
                                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));

                                    System.out.println("模型一致性校验成功！》》》》》》》》》》》》》》》》》》》》》》》》》》》》》开始数据对齐校验》》》》》》》》》》》》》》》》");

                                    this.sendAlignData(s, requestOperateCode);

                                    FormalTestManager.currentStep = SourceOperateCodeEnum.YJC_ALIGN;
//                                    if (FormalTestManager.isWaveCheck) {
//                                        System.out.println("（仅有闪变、录波）模型一致性校验成功！》》》》》》》》》》》》》》》》》》》》》》》》》》》》》开始相序校验》》》》》》》》》》》》》》》》");
//                                        this.sendXu(s);
//                                        FormalTestManager.currentStep = SourceOperateCodeEnum.YJC_XUJY;
//                                    } else {
//                                        System.out.println("（仅有闪变）模型一致性校验成功！》》》》》》》》》》》》》》》》》》》》》》》》》》》》》开始数据对齐校验》》》》》》》》》》》》》》》》");
//                                        this.sendAlignData(s, requestOperateCode);
//                                        FormalTestManager.currentStep = SourceOperateCodeEnum.YJC_ALIGN;
//                                    }
                                    this.resetTimer();
                                }
                            }
                        }
                        completeJudgment(param);
                    }
                    break;
                case UNPROCESSED_BUSINESS:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    if (SourceOperateCodeEnum.RECORD_WAVE_STEP1.getValue().equals(socketDataMsg.getRequestId())) {
                        String data = socketDataMsg.getData();
                        if (StrUtil.isNotBlank(data) && data.equals("waiting")) {
                            if (Objects.isNull(FormalTestManager.scheduler)) {
                                FormalTestManager.scheduler = Executors.newScheduledThreadPool(1);
                                FormalTestManager.scheduledFuture = FormalTestManager.scheduler.schedule(() -> {
                                    if (!FormalTestManager.isRemoveSocket) {
                                        SocketDataMsg webSend = new SocketDataMsg();
                                        webSend.setRequestId(SourceOperateCodeEnum.RECORD_WAVE_STEP1.getValue());
                                        webSend.setOperateCode(SourceOperateCodeEnum.DEV_DATA_REQUEST_03.getValue());
                                        System.out.println("无效的录波指令！");

                                        if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                                            CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                                        }
                                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                                        CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                                        FormalTestManager.isTesting = false;

                                        Collection<String> disjunction = CollectionUtil.disjunction(FormalTestManager.monitorMap.keySet(), successComm);
                                        // 向前端推送
                                        for (String key : disjunction) {
                                            webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                                            webSend.setData(MsgUtil.getMonitorInfo(key, FormalTestManager.devNameMapComm) + " 无效的录波指令！");
                                            WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                                        }
                                        // 推送最终失败结果
                                        webSend.setCode(SourceResponseCodeEnum.ALL_FAIL.getCode());//最终错误推送
                                        webSend.setData("无效的录波指令！");
                                        WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                                    }
                                    FormalTestManager.scheduler.shutdown();
                                    FormalTestManager.scheduler = null;
                                }, 30, TimeUnit.SECONDS);
                            }
                        }
                    }
                    break;
                case DEV_ERROR:
                    failComm.addAll(FormalTestManager.devMapMonitorNum.get(socketDataMsg.getData()));
                    WebServiceManager.sendMsg(param.getUserPageId(), MsgUtil.msgToWebData(socketDataMsg, FormalTestManager.devNameMapComm, 0));
                    completeJudgment(param);
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case DEV_TARGET:
                    failComm.add(socketDataMsg.getData());
                    WebServiceManager.sendMsg(param.getUserPageId(), MsgUtil.msgToWebData(socketDataMsg, FormalTestManager.devNameMapComm, 1));
                    completeJudgment(param);
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case RE_OPERATE:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case NO_INIT_DEV:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                default:
                    WebServiceManager.sendUnknownErrorMessage(param.getUserPageId());
                    break;
            }
        }
    }


    /**
     * 模型一致性校验
     */
    private void modelDeal(SocketDataMsg socketDataMsg, PreDetectionParam param) {
        SourceResponseCodeEnum dictDataEnumByCode = SourceResponseCodeEnum.getDictDataEnumByCode(socketDataMsg.getCode());
        String s = param.getUserPageId() + CnSocketUtil.CONTRAST_DEV_TAG;
        DevData devData = JSON.parseObject(socketDataMsg.getData(), DevData.class);
        if (SourceOperateCodeEnum.FORMAL_REAL.getValue().equals(socketDataMsg.getRequestId())) {
            socketDataMsg.setRequestId(SourceOperateCodeEnum.YJC_MXYZXJY.getValue());
        }

        if (ObjectUtil.isNotNull(dictDataEnumByCode)) {
            SourceOperateCodeEnum requestOperateCode = this.getRequestOperateCode();
            SourceOperateCodeEnum quitOperateCode = this.getQuitOperateCode();

            switch (dictDataEnumByCode) {
                case SUCCESS:
                    if (SourceOperateCodeEnum.YJC_MXYZXJY.getValue().equals(socketDataMsg.getRequestId())) {
                        //成功收到数据后重置超时统计时间
                        this.resetTimer();
                        String monitorId1 = devData.getId();
                        successComm.add(monitorId1);

                        if (FormalTestManager.standardDevDataMap.containsKey(monitorId1)) {
                            FormalTestManager.standardDevDataMap.get(monitorId1).add(devData);
                            Collections.sort(FormalTestManager.standardDevDataMap.get(monitorId1), Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
                        }
                        if (FormalTestManager.devDataMap.containsKey(monitorId1)) {
                            FormalTestManager.devDataMap.get(monitorId1).add(devData);
                            Collections.sort(FormalTestManager.devDataMap.get(monitorId1), Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
                        }

                        if (successComm.size() == FormalTestManager.monitorMap.size()) {
                            boolean modelCheckResult = this.modelCheck(param, FormalTestManager.devDataMap, FormalTestManager.monitorMap.get(monitorId1), true);
                            modelCheckResult = this.modelCheck(param, FormalTestManager.standardDevDataMap, FormalTestManager.monitorMap.get(monitorId1), false) && modelCheckResult;

                            this.clearData();
                            if (!modelCheckResult) {
                                SocketDataMsg webSend = new SocketDataMsg();
                                webSend.setRequestId(SourceOperateCodeEnum.YJC_MXYZXJY.getValue());
                                webSend.setCode(SourceResponseCodeEnum.ALL_FAIL.getCode()); //最终错误推送
                                WebServiceManager.sendMsg(param.getUserPageId(), MsgUtil.msgToWebData(webSend, FormalTestManager.devNameMapComm, 0));

                                System.out.println("模型一致性校验失败！》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》");
                                if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                                    CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                                }
                                if (FormalTestManager.voltageProtocol) {
                                    CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_02, false);
                                }
                                CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, false);
                                FormalTestManager.isTesting = false;
                            } else {
                                SocketDataMsg webSend = new SocketDataMsg();
                                webSend.setRequestId(SourceOperateCodeEnum.YJC_MXYZXJY.getValue());
                                webSend.setCode(SourceResponseCodeEnum.ALL_SUCCESS.getCode());//最终成功推送
                                WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));

                                if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
                                    System.out.println("模型一致性校验成功！》》》》》》》》》》》》》》》》》》》》》》》》》》》》》开始数据对齐校验》》》》》》》》》》》》》》》》");

                                    this.sendAlignData(s, requestOperateCode);


                                    FormalTestManager.currentStep = SourceOperateCodeEnum.YJC_ALIGN;

                                    this.resetTimer();
                                } else if (FormalTestManager.isWaveCheck) {
                                    System.out.println("(仅有录波)模型一致性校验成功！》》》》》》》》》》》》》》》》》》》》》》》》》》》开始相序校验》》》》》》》》》》》》》》》》》》》》》》》》》》》");

                                    if (FormalTestManager.isXu) {
                                        this.sendXu(s);
                                        this.resetTimer();
                                        FormalTestManager.currentStep = SourceOperateCodeEnum.YJC_XUJY;
                                    } else {
                                        System.out.println("跳过相序校验！");
                                        this.sendFormalTest(s, param, requestOperateCode, quitOperateCode);
                                    }
                                }
                            }
                        }
                    }
                    break;
                case UNPROCESSED_BUSINESS:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    break;
                case NORMAL_RESPONSE:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    break;
                case DEV_ERROR:
                    WebServiceManager.sendMsg(param.getUserPageId(), MsgUtil.msgToWebData(socketDataMsg, FormalTestManager.devNameMapComm, 0));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case DEV_TARGET:
                    WebServiceManager.sendMsg(param.getUserPageId(), MsgUtil.msgToWebData(socketDataMsg, FormalTestManager.devNameMapComm, 1));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case RE_OPERATE:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case NO_INIT_DEV:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                default:
                    WebServiceManager.sendUnknownErrorMessage(param.getUserPageId());
                    break;
            }
        }
    }

    /**
     * 实时数据对齐校验
     *
     * @param socketDataMsg
     * @param param
     */
    private void alignDeal(SocketDataMsg socketDataMsg, PreDetectionParam param) {
        SourceResponseCodeEnum dictDataEnumByCode = SourceResponseCodeEnum.getDictDataEnumByCode(socketDataMsg.getCode());
        String s = param.getUserPageId() + CnSocketUtil.CONTRAST_DEV_TAG;
        DevData devData = JSON.parseObject(socketDataMsg.getData(), DevData.class);
        socketDataMsg.setRequestId(SourceOperateCodeEnum.YJC_ALIGN.getValue());


        if (ObjectUtil.isNotNull(dictDataEnumByCode)) {
            SourceOperateCodeEnum requestOperateCode = this.getRequestOperateCode();
            SourceOperateCodeEnum quitOperateCode = this.getQuitOperateCode();

            switch (dictDataEnumByCode) {
                case SUCCESS:
                case NORMAL_RESPONSE:
                    String monitorId1 = devData.getId();
                    this.resetTimer();

                    int type = 1;
                    int targetCount = 5;
                    if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
                        if (FormalTestManager.nonWaveDataSourceEnum != DataSourceEnum.REAL_DATA) {
                            type = 2;
                            targetCount = 2;
                        }
                    }

                    if (Objects.isNull(FormalTestManager.scheduler)) {
                        FormalTestManager.scheduler = Executors.newScheduledThreadPool(1);
                        long delay = this.getDelay(targetCount);
                        FormalTestManager.scheduledFuture = FormalTestManager.scheduler.schedule(() -> {
                            if (!checkResult) {
                                System.out.println(delay + "s内数据对齐校验失败！");
                                if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                                    CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                                }
                                if (FormalTestManager.voltageProtocol) {
                                    CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                                }
                                CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, false);
                                FormalTestManager.isTesting = false;
                                Collection<String> disjunction = CollectionUtil.disjunction(FormalTestManager.pairsIpMap.keySet(), successPair.keySet());
                                // 向前端推送实时数据对齐失败的配对项
                                for (String key : disjunction) {
                                    SocketDataMsg webSend = new SocketDataMsg();
                                    webSend.setRequestId(SourceOperateCodeEnum.YJC_ALIGN.getValue());
                                    webSend.setOperateCode(requestOperateCode.getValue());
                                    webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                                    webSend.setData(MsgUtil.getPairStr(key, FormalTestManager.pairsIpMap.get(key), FormalTestManager.devNameMapComm));
                                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                                }
                                // 推送最终失败结果
                                SocketDataMsg webSend = new SocketDataMsg();
                                webSend.setRequestId(SourceOperateCodeEnum.YJC_ALIGN.getValue());
                                webSend.setOperateCode(requestOperateCode.getValue());
                                webSend.setCode(SourceResponseCodeEnum.ALL_FAIL.getCode());//最终错误推送
                                webSend.setData(this.getAlignDataToWeb());
                                WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                                this.saveAlignData();

                                this.clearData();
                            }
                            FormalTestManager.scheduler.shutdown();
                            FormalTestManager.scheduler = null;
                        }, delay, TimeUnit.SECONDS);
                    }

                    String devMonitorId = monitorId1;
                    String standardDevMonitorId = monitorId1;
                    if (FormalTestManager.devDataMap.containsKey(monitorId1)) {
                        standardDevMonitorId = FormalTestManager.pairsIpMap.get(monitorId1);
                        if (!successPair.containsKey(devMonitorId)) {
                            FormalTestManager.devDataMap.get(devMonitorId).add(devData);
                            Collections.sort(FormalTestManager.devDataMap.get(devMonitorId), Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
                        }
                    }
                    if (FormalTestManager.standardDevDataMap.containsKey(monitorId1)) {
                        devMonitorId = FormalTestManager.pairsIpMap.inverse().get(monitorId1);
                        if (!successPair.containsKey(devMonitorId)) {
                            FormalTestManager.standardDevDataMap.get(standardDevMonitorId).add(devData);
                            Collections.sort(FormalTestManager.standardDevDataMap.get(standardDevMonitorId), Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
                        }
                    }

                    // 进行单个监测点的对齐校验
                    if (!successPair.containsKey(devMonitorId)) {
                        if (FormalTestManager.devDataMap.get(devMonitorId).size() >= targetCount && FormalTestManager.standardDevDataMap.get(standardDevMonitorId).size() >= targetCount) {
                            List<List<DevData>> singleMonitorAlignData = this.getSingleMonitorAlignData(FormalTestManager.devDataMap.get(devMonitorId), FormalTestManager.standardDevDataMap.get(standardDevMonitorId), targetCount, type);

                            if (singleMonitorAlignData.get(0).size() >= targetCount && singleMonitorAlignData.get(1).size() >= targetCount) {
                                successPair.put(devMonitorId, standardDevMonitorId);
                                FormalTestManager.devDataMap.get(devMonitorId).clear();
                                FormalTestManager.devDataMap.get(devMonitorId).addAll(singleMonitorAlignData.get(0));

                                FormalTestManager.standardDevDataMap.get(standardDevMonitorId).clear();
                                FormalTestManager.standardDevDataMap.get(standardDevMonitorId).addAll(singleMonitorAlignData.get(1));

                                //向前端推送实时数据对齐成功的配对
                                SocketDataMsg webSend = new SocketDataMsg();
                                webSend.setRequestId(SourceOperateCodeEnum.YJC_ALIGN.getValue());
                                webSend.setOperateCode(requestOperateCode.getValue());
                                webSend.setCode(SourceResponseCodeEnum.SUCCESS.getCode());
                                webSend.setData(MsgUtil.getPairStr(standardDevMonitorId, devMonitorId, FormalTestManager.devNameMapComm));
                                WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));

                                // 若成功的配对项等于总的配对项，则判定为成功
                                if (successPair.keySet().containsAll(FormalTestManager.pairsIpMap.keySet())) {
                                    checkResult = true;
                                    FormalTestManager.scheduledFuture.cancel(true);
                                    FormalTestManager.scheduler.shutdown();
                                    FormalTestManager.scheduler = null;

                                    this.saveAlignData();

                                    SocketDataMsg webSend1 = new SocketDataMsg();
                                    webSend1.setRequestId(SourceOperateCodeEnum.YJC_ALIGN.getValue());
                                    webSend1.setOperateCode(requestOperateCode.getValue());
                                    webSend1.setCode(SourceResponseCodeEnum.ALL_SUCCESS.getCode());//最终成功推送
                                    webSend1.setData(this.getAlignDataToWeb());
                                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend1));

                                    this.clearData();

                                    if (FormalTestManager.isXu) {
                                        System.out.println("数据对齐校验成功！》》》》》》》》》》》》》》》》》》》》》》》》》》》》》开始相序校验》》》》》》》》》》》》》》》》");
                                        this.sendXu(s);
                                        FormalTestManager.currentStep = SourceOperateCodeEnum.YJC_XUJY;
                                    } else {
                                        System.out.println("跳过相序校验！");
                                        this.sendFormalTest(s, param, requestOperateCode, quitOperateCode);
                                    }
                                    this.resetTimer();
                                }
                            }
                        }
                    }
                    break;
                case UNPROCESSED_BUSINESS:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    break;
                case DEV_ERROR:
                    WebServiceManager.sendMsg(param.getUserPageId(), MsgUtil.msgToWebData(socketDataMsg, FormalTestManager.devNameMapComm, 0));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case DEV_TARGET:
                    WebServiceManager.sendMsg(param.getUserPageId(), MsgUtil.msgToWebData(socketDataMsg, FormalTestManager.devNameMapComm, 1));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case RE_OPERATE:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case NO_INIT_DEV:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                default:
                    WebServiceManager.sendUnknownErrorMessage(param.getUserPageId());
                    break;
            }
        }
    }

    /**
     * 相序校验
     */
    private void devXu(PreDetectionParam param, SocketDataMsg socketDataMsg) {
        String s = param.getUserPageId() + CnSocketUtil.CONTRAST_DEV_TAG;
        DevData devData = JSON.parseObject(socketDataMsg.getData(), DevData.class);
        socketDataMsg.setRequestId(SourceOperateCodeEnum.YJC_XUJY.getValue());

        SourceResponseCodeEnum dictDataEnumByCode = SourceResponseCodeEnum.getDictDataEnumByCode(socketDataMsg.getCode());
        if (ObjectUtil.isNotNull(dictDataEnumByCode)) {
            SourceOperateCodeEnum requestOperateCode = this.getRequestOperateCode();
            SourceOperateCodeEnum quitOperateCode = this.getQuitOperateCode();

            switch (dictDataEnumByCode) {
                case SUCCESS:
                case NORMAL_RESPONSE:
                    String monitorId1 = devData.getId();
                    this.resetTimer();

                    String devMonitorId = monitorId1;
                    String standardDevMonitorId = monitorId1;

                    int type = 1;
                    if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
                        if (FormalTestManager.nonWaveDataSourceEnum != DataSourceEnum.REAL_DATA) {
                            type = 2;
                        }
                    }

                    if (FormalTestManager.devDataMap.containsKey(monitorId1)) {
                        standardDevMonitorId = FormalTestManager.pairsIpMap.get(monitorId1);
                        if (!successPair.containsKey(devMonitorId)) {
                            FormalTestManager.devDataMap.get(monitorId1).add(devData);
                            Collections.sort(FormalTestManager.devDataMap.get(monitorId1), Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
                        }
                    }
                    if (FormalTestManager.standardDevDataMap.containsKey(monitorId1)) {
                        devMonitorId = FormalTestManager.pairsIpMap.inverse().get(monitorId1);
                        if (!successPair.containsKey(devMonitorId)) {
                            FormalTestManager.standardDevDataMap.get(monitorId1).add(devData);
                            Collections.sort(FormalTestManager.standardDevDataMap.get(monitorId1), Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
                        }
                    }

                    if (!successPair.containsKey(devMonitorId)) {
                        if (FormalTestManager.devDataMap.get(devMonitorId).size() >= 1 && FormalTestManager.standardDevDataMap.get(standardDevMonitorId).size() >= 1) {
                            successComm.add(standardDevMonitorId);
                            successComm.add(devMonitorId);
                            List<List<DevData>> singleMonitorAlignData = getSingleMonitorAlignData(FormalTestManager.devDataMap.get(devMonitorId), FormalTestManager.standardDevDataMap.get(standardDevMonitorId), 1, type);

                            if (CollUtil.isNotEmpty(singleMonitorAlignData.get(0)) && CollUtil.isNotEmpty(singleMonitorAlignData.get(1))) {
                                PreDetection.MonitorListDTO monitorListDTO = FormalTestManager.monitorMap.get(devMonitorId);
                                if (this.singleMonitorXuCheck(devMonitorId, standardDevMonitorId, monitorListDTO, singleMonitorAlignData.get(0), singleMonitorAlignData.get(1), FormalTestManager.devNameMapComm, param.getUserPageId())) {
                                    successPair.put(devMonitorId, standardDevMonitorId);
                                    // 若成功的配对项等于总的配对项，则判定为成功
                                    if (successPair.keySet().containsAll(FormalTestManager.pairsIpMap.keySet())) {
                                        this.clearData();
                                        WebSocketVO webSend = new WebSocketVO();
                                        webSend.setRequestId(SourceOperateCodeEnum.YJC_XUJY.getValue());
                                        webSend.setOperateCode(requestOperateCode.getValue());
                                        webSend.setCode(SourceResponseCodeEnum.ALL_SUCCESS.getCode());//最终成功推送
                                        WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));

                                        this.sendFormalTest(s, param, requestOperateCode, quitOperateCode);
                                    }
                                } else if (successComm.size() == FormalTestManager.monitorMap.size()) {
                                    this.clearData();

                                    // 相序校验失败，最终向前端发送失败消息
                                    WebSocketVO<String> webSend = new WebSocketVO<>();
                                    webSend.setRequestId(SourceOperateCodeEnum.YJC_XUJY.getValue());
                                    webSend.setOperateCode(requestOperateCode.getValue());
                                    webSend.setCode(SourceResponseCodeEnum.ALL_FAIL.getCode()); //最终错误推送
                                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                                    }
                                    if (FormalTestManager.voltageProtocol) {
                                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                                    }
                                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, false);
                                    FormalTestManager.isTesting = false;
                                }
                            } else {
                                Integer maxReadCount = this.getReadCount(1);
                                WebSocketVO webSend = new WebSocketVO();
                                webSend.setRequestId(SourceOperateCodeEnum.YJC_XUJY.getValue());
                                webSend.setOperateCode(requestOperateCode.getValue());
                                if (FormalTestManager.devDataMap.get(devMonitorId).size() >= maxReadCount && FormalTestManager.standardDevDataMap.get(standardDevMonitorId).size() >= maxReadCount) {
                                    webSend.setCode(SourceResponseCodeEnum.ALL_FAIL.getCode());
                                    webSend.setData(MsgUtil.getPairStr(devMonitorId, standardDevMonitorId, FormalTestManager.devNameMapComm) + " 数据对齐失败！");
                                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));

                                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                                    }
                                    if (FormalTestManager.voltageProtocol) {
                                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                                    }
                                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, false);
                                    FormalTestManager.isTesting = false;
                                }
                            }
                        }
                    }
                    break;
                case UNPROCESSED_BUSINESS:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    break;
                case DEV_ERROR:
                    WebServiceManager.sendMsg(param.getUserPageId(), MsgUtil.msgToWebData(socketDataMsg, FormalTestManager.devNameMapComm, 0));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case DEV_TARGET:
                    WebServiceManager.sendMsg(param.getUserPageId(), MsgUtil.msgToWebData(socketDataMsg, FormalTestManager.devNameMapComm, 1));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case RE_OPERATE:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                default:
                    WebServiceManager.sendUnknownErrorMessage(param.getUserPageId());
                    break;
            }
        }
    }

    private void sendFormalTest(String s, PreDetectionParam param, SourceOperateCodeEnum requestOperateCode, SourceOperateCodeEnum quitOperateCode) {
        // 后续做正式检测
        if (param.isFormalTestSelected()) {
            System.out.println("开始正式检测！");
            if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
                SocketMsg<String> socketMsg = new SocketMsg<>();
                socketMsg.setRequestId(SourceOperateCodeEnum.FORMAL_REAL.getValue());
                socketMsg.setOperateCode(requestOperateCode.getValue());
                DevPhaseSequenceParam phaseSequenceParam = new DevPhaseSequenceParam();
                phaseSequenceParam.setMoniterIdList(Arrays.asList(FormalTestManager.monitorMap.keySet().toArray(new String[FormalTestManager.monitorMap.size()])));
                List<String> allDataType = this.getAllDataType();
                FormalTestManager.pstDataType = new ArrayList<>();
                if (allDataType.contains(DetectionCodeEnum.AVG_PREFIX.getCode() + DetectionCodeEnum.PST.getCode())) {
                    FormalTestManager.pstDataType.add(DetectionCodeEnum.AVG_PREFIX.getCode() + DetectionCodeEnum.PST.getCode());
                    allDataType.remove(DetectionCodeEnum.AVG_PREFIX.getCode() + DetectionCodeEnum.PST.getCode());
                }
                if (CollUtil.isNotEmpty(allDataType)) {
                    phaseSequenceParam.setDataType(allDataType);
                } else {
                    if (CollUtil.isNotEmpty(FormalTestManager.pstDataType)) {
                        FormalTestManager.isPstData = true;
                        socketMsg.setOperateCode(SourceOperateCodeEnum.DEV_DATA_REQUEST_01.getValue());
                        phaseSequenceParam.setDataType(FormalTestManager.pstDataType);
                    }
                }
                phaseSequenceParam.setReadCount(this.getReadCount(this.getTargetCount()));
                phaseSequenceParam.setIgnoreCount(0);
                socketMsg.setData(JSON.toJSONString(phaseSequenceParam));

                FormalTestManager.currentStep = SourceOperateCodeEnum.FORMAL_REAL;
                SocketManager.sendMsg(s, JSON.toJSONString(socketMsg));
                this.resetTimer();
                checkResult = false;
            } else if (FormalTestManager.isWaveCheck) {
                if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                }
                // 录波数据
                CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, false);
                successComm.clear();
                failComm.clear();
                FormalTestManager.currentStep = SourceOperateCodeEnum.RECORD_WAVE_STEP1;
                // 发送录波指令
                this.sendRecordWave(s);
            }
        } else {
            if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
            }
            if (FormalTestManager.voltageProtocol) {
                CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
            }
            CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, false);
            FormalTestManager.isTesting = false;
        }
    }

    /**
     * 正式检测
     *
     * @param param
     * @param socketDataMsg
     */
    private void formalDeal(PreDetectionParam param, SocketDataMsg socketDataMsg) {
        String data = socketDataMsg.getData();
        String s = param.getUserPageId() + CnSocketUtil.CONTRAST_DEV_TAG;
        DevData devData = JSON.parseObject(data, DevData.class);

        SourceResponseCodeEnum dictDataEnumByCode = SourceResponseCodeEnum.getDictDataEnumByCode(socketDataMsg.getCode());
        if (SourceOperateCodeEnum.FORMAL_REAL.getValue().equals(socketDataMsg.getRequestId())) {
            SourceOperateCodeEnum requestOperateCode = this.getRequestOperateCode();
            SourceOperateCodeEnum quitOperateCode = this.getQuitOperateCode();

            switch (Objects.requireNonNull(dictDataEnumByCode)) {
                case SUCCESS:
                case NORMAL_RESPONSE:
                    this.resetTimer();

                    SocketDataMsg webSend = new SocketDataMsg();
                    webSend.setRequestId(SourceOperateCodeEnum.FORMAL_REAL.getValue());
                    webSend.setOperateCode(requestOperateCode.getValue());

                    int targetCount = this.getTargetCount();

                    int type = 1;
                    if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
                        if (FormalTestManager.nonWaveDataSourceEnum != DataSourceEnum.REAL_DATA) {
                            type = 2;
                        }
                    }
                    this.setScheduler(targetCount, param.getUserPageId(), requestOperateCode, quitOperateCode);

                    String monitorId1 = devData.getId();
                    String devMonitorId = monitorId1;
                    String standardDevMonitorId = monitorId1;

                    if (FormalTestManager.devDataMap.containsKey(monitorId1)) {
                        standardDevMonitorId = FormalTestManager.pairsIpMap.get(monitorId1);
                        if (!successPair.containsKey(devMonitorId)) {
                            if (FormalTestManager.isPstData) {
                                if (devData.getSqlData().stream().anyMatch(obj -> DetectionCodeEnum.PST.getCode().equals(obj.getDesc()))) {
                                    FormalTestManager.devDataMap.get(monitorId1).add(devData);
                                }
                            } else {
                                FormalTestManager.devDataMap.get(monitorId1).add(devData);
                            }
                            Collections.sort(FormalTestManager.devDataMap.get(monitorId1), Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
                        }
                    }
                    if (FormalTestManager.standardDevDataMap.containsKey(monitorId1)) {
                        devMonitorId = FormalTestManager.pairsIpMap.inverse().get(monitorId1);
                        if (!successPair.containsKey(devMonitorId)) {
                            if (FormalTestManager.isPstData) {
                                if (devData.getSqlData().stream().anyMatch(obj -> DetectionCodeEnum.PST.getCode().equals(obj.getDesc()))) {
                                    FormalTestManager.standardDevDataMap.get(monitorId1).add(devData);
                                }
                            } else {
                                FormalTestManager.standardDevDataMap.get(monitorId1).add(devData);
                            }
                            Collections.sort(FormalTestManager.standardDevDataMap.get(monitorId1), Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
                        }
                    }

                    if (!successPair.containsKey(devMonitorId)) {
                        if (FormalTestManager.devDataMap.get(devMonitorId).size() >= targetCount && FormalTestManager.standardDevDataMap.get(standardDevMonitorId).size() >= targetCount) {
                            List<List<DevData>> singleMonitorAlignData = getSingleMonitorAlignData(FormalTestManager.devDataMap.get(devMonitorId), FormalTestManager.standardDevDataMap.get(standardDevMonitorId), targetCount, type);
                            if (singleMonitorAlignData.get(0).size() >= targetCount && singleMonitorAlignData.get(1).size() >= targetCount) {
                                successPair.put(devMonitorId, standardDevMonitorId);
                                // 推送收集数据成功的配对项
                                webSend.setCode(SourceResponseCodeEnum.SUCCESS.getCode());
                                webSend.setData(MsgUtil.getPairStr(devMonitorId, standardDevMonitorId, FormalTestManager.devNameMapComm) + " 数据收集成功！");
                                WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));

                                FormalTestManager.devDataMap.get(devMonitorId).clear();
                                FormalTestManager.standardDevDataMap.get(standardDevMonitorId).clear();

                                FormalTestManager.devDataMap.get(devMonitorId).addAll(singleMonitorAlignData.get(0));
                                FormalTestManager.standardDevDataMap.get(standardDevMonitorId).addAll(singleMonitorAlignData.get(1));

                                if (successPair.keySet().containsAll(FormalTestManager.pairsIpMap.keySet())) {
                                    checkResult = true;
                                    FormalTestManager.scheduledFuture.cancel(true);
                                    FormalTestManager.scheduler.shutdown();
                                    FormalTestManager.scheduler = null;

                                    String errorSysId = FormalTestManager.currentTestPlan.getErrorSysId();
                                    String code = String.valueOf(FormalTestManager.currentTestPlan.getCode());

                                    // 原始数据入库
                                    List<DevData> devDataList = FormalTestManager.devDataMap.values().stream().flatMap(List::stream).collect(Collectors.toList());
                                    List<DevData> standardDevDataList = FormalTestManager.standardDevDataMap.values().stream().flatMap(List::stream).collect(Collectors.toList());
                                    DetectionCodeEnum prefixEnum = this.getPrefixEnum();
                                    baseDataInsert(false, null, FormalTestManager.nonWaveDataSourceEnum, devDataList, FormalTestManager.numMap, prefixEnum, code);
                                    baseDataInsert(true, null, FormalTestManager.nonWaveDataSourceEnum, standardDevDataList, FormalTestManager.numMap, prefixEnum, code);

                                    List<String> testItem = null;
                                    if (FormalTestManager.isPstData) {
                                        testItem = FormalTestManager.testItemMap.keySet().stream().filter(a -> DetectionCodeEnum.PST.getCode().equals(a.split("\\$")[1])).collect(Collectors.toList());
                                    } else {
                                        testItem = FormalTestManager.testItemMap.keySet().stream().filter(a -> !DetectionCodeEnum.PST.getCode().equals(a.split("\\$")[1])).collect(Collectors.toList());
                                    }
                                    // 进行误差计算
                                    List<DevLineTestResult> allResultList = detectionService.processing(
                                            devDataList,
                                            standardDevDataList,
                                            FormalTestManager.pairsIpMap,
                                            FormalTestManager.devIdMapComm,
                                            testItem,
                                            errorSysId, FormalTestManager.dataRule, FormalTestManager.numMap, code, null, FormalTestManager.nonWaveDataSourceEnum);

                                    this.clearData();
                                    webSend.setData(JSON.toJSONString(allResultList));

                                    if (CollUtil.isNotEmpty(FormalTestManager.pstDataType)) {
                                        if (!FormalTestManager.isPstData) {
                                            webSend.setCode(SourceResponseCodeEnum.FLICKER_DATA_START.getCode());
                                            WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                                            SocketMsg<String> socketMsg = new SocketMsg<>();
                                            socketMsg.setRequestId(SourceOperateCodeEnum.FORMAL_REAL.getValue());
                                            socketMsg.setOperateCode(SourceOperateCodeEnum.DEV_DATA_REQUEST_01.getValue());
                                            DevPhaseSequenceParam phaseSequenceParam = new DevPhaseSequenceParam();
                                            phaseSequenceParam.setMoniterIdList(Arrays.asList(FormalTestManager.monitorMap.keySet().toArray(new String[FormalTestManager.monitorMap.size()])));
                                            FormalTestManager.isPstData = true;
                                            phaseSequenceParam.setDataType(FormalTestManager.pstDataType);
                                            phaseSequenceParam.setReadCount(this.getReadCount(this.getTargetCount()));
                                            phaseSequenceParam.setIgnoreCount(0);
                                            socketMsg.setData(JSON.toJSONString(phaseSequenceParam));

                                            FormalTestManager.currentStep = SourceOperateCodeEnum.FORMAL_REAL;
                                            SocketManager.sendMsg(s, JSON.toJSONString(socketMsg));
                                            this.resetTimer();
                                            this.setScheduler(targetCount, param.getUserPageId(), requestOperateCode, quitOperateCode);
                                            checkResult = false;
                                            return;
                                        }
                                    }
                                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                                    }
                                    // 断开与设备的连接,但是不要将Socket移除
                                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, false);

                                    List<String> adTypes = FormalTestManager.testItemMap.values().stream().collect(Collectors.toList());

                                    Map<String, Integer> result = detectionDataDealService.devResult(true, FormalTestManager.pairsIdMap.keySet().stream().collect(Collectors.toList()), adTypes, code);
                                    // 若有不符合的
                                    if (result.values().stream().anyMatch(r -> r.equals(ResultEnum.NOT_QUALIFIED.getValue()))) {
                                        // 最终将检测结果推送到前端
                                        if (FormalTestManager.isWaveCheck) {
                                            if (FormalTestManager.nonWaveDataSourceEnum == DataSourceEnum.REAL_DATA) {
                                                webSend.setCode(SourceResponseCodeEnum.REAL_DATA_CHECK_FAIL.getCode());
                                            } else {
                                                webSend.setCode(SourceResponseCodeEnum.STATISTICS_DATA_CHECK_FAIL.getCode());
                                            }
                                            WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                                            System.out.println("实时/统计数据校验失败！》》》》》》》》》》》》》》》》》》》》》》》》》》》》》开始录波》》》》》》》》》》》》》》》》");

                                            Set<String> delSet = new HashSet<>();
                                            for (int i = 0; i < FormalTestManager.devList.size(); i++) {
                                                PreDetection preDetection = FormalTestManager.devList.get(i);
                                                List<PreDetection.MonitorListDTO> monitorList = preDetection.getMonitorList();
                                                for (int j = monitorList.size() - 1; j >= 0; j--) {
                                                    String lineId = monitorList.get(j).getLineId();
                                                    String[] split = lineId.split(CnSocketUtil.SPLIT_TAG);
                                                    Integer res = result.get(FormalTestManager.devIdMapComm.get(split[0]) + split[1]);
                                                    if (ObjectUtil.isNotNull(res) && res.equals(ResultEnum.NOT_QUALIFIED.getValue())) {
                                                        monitorList.remove(j);
                                                        delSet.add(lineId);
                                                        FormalTestManager.monitorMap.remove(lineId);
                                                    }
                                                }
                                            }
                                            for (int i = 0; i < FormalTestManager.standardDevList.size(); i++) {
                                                PreDetection preDetection = FormalTestManager.standardDevList.get(i);
                                                List<PreDetection.MonitorListDTO> monitorList = preDetection.getMonitorList();
                                                for (int j = monitorList.size() - 1; j >= 0; j--) {
                                                    String lineId = monitorList.get(j).getLineId();
                                                    String s1 = FormalTestManager.pairsIpMap.inverse().get(lineId);
                                                    if (delSet.contains(s1)) {
                                                        monitorList.remove(j);
                                                        FormalTestManager.monitorMap.remove(lineId);
                                                    }
                                                }
                                            }

                                            successComm.clear();
                                            failComm.clear();
                                            FormalTestManager.currentStep = SourceOperateCodeEnum.RECORD_WAVE_STEP1;
                                            // 发送录波指令
                                            this.sendRecordWave(s);
                                        } else {
                                            // 配对关系入库
                                            this.pairDataInsert();

                                            if (FormalTestManager.isPstData) {
                                                webSend.setRequestId(SourceOperateCodeEnum.FLICKER_DATA_CHECK.getValue());
                                            }
                                            // 最终将检测结果推送到前端
                                            webSend.setCode(SourceResponseCodeEnum.ALL_SUCCESS.getCode());//最终成功推送
                                            WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                                            // 修改检测点状态、设备状态
                                            FormalTestManager.pairsIdMap.forEach((id1, id2) -> {
                                                pqMonitorService.updateMonitorResult(id1, adTypes, FormalTestManager.nonWaveDataSourceEnum, FormalTestManager.numMap.get(id1), null, code);
                                                pqDevService.updateResult(id1.split(CnSocketUtil.SPLIT_TAG)[0], param.getUserId());
                                            });
                                            FormalTestManager.isTesting = false;

                                            if (CollUtil.isNotEmpty(DetectionServiceImpl.vAndIResultMap)) {
                                                // 是否进行系数校准
                                                //万一录波了这里就进不来了，但是在误差处理的时候DetectionServiceImpl.vAndIResultMap该集合会保留不符合的结果

                                                XiNumberManager.xiDevList.clear();
                                                XiNumberManager.devXiNumDataMap.clear();
                                                List<String> stdIpList = DetectionServiceImpl.vAndIResultMap.values().stream().map(DetectionServiceImpl.VAndIResult::getIp).collect(Collectors.toList());
                                                XiNumberManager.xiDevList = FormalTestManager.standardDevList.stream().filter(d -> stdIpList.contains(d.getDevIP())).collect(Collectors.toList());
                                                // 逐一设备向通讯模块要原始系数
                                                SocketMsg<String> socketMsg = new SocketMsg<>();
                                                socketMsg.setRequestId(SourceOperateCodeEnum.Coefficient_Check.getValue());
                                                socketMsg.setOperateCode(SourceOperateCodeEnum.DATA_CHNFACTOR$01.getValue());
                                                PreDetection preDetection = XiNumberManager.xiDevList.get(0);
                                                Map<String, Object> map = new HashMap<>();
                                                map.put("devIP", preDetection.getDevIP());
                                                map.put("chnNum", preDetection.getDevChns());
                                                socketMsg.setData(JSON.toJSONString(map));
                                                SocketManager.sendMsg(param.getUserPageId() + CnSocketUtil.CONTRAST_DEV_TAG, JSON.toJSONString(socketMsg));

                                                FormalTestManager.currentStep = SourceOperateCodeEnum.Coefficient_Check;
                                            }
                                        }
                                    } else {
                                        // 配对关系入库
                                        this.pairDataInsert();

                                        if (FormalTestManager.isPstData) {
                                            webSend.setRequestId(SourceOperateCodeEnum.FLICKER_DATA_CHECK.getValue());
                                        }
                                        // 最终将检测结果推送到前端
                                        webSend.setCode(SourceResponseCodeEnum.ALL_SUCCESS.getCode());//最终成功推送
                                        WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                                        // 修改检测点状态、设备状态
                                        FormalTestManager.pairsIdMap.forEach((id1, id2) -> {
                                            pqMonitorService.updateMonitorResult(id1, adTypes, FormalTestManager.nonWaveDataSourceEnum, FormalTestManager.numMap.get(id1), null, code);
                                            pqDevService.updateResult(id1.split(CnSocketUtil.SPLIT_TAG)[0], param.getUserId());
                                        });

                                        if (FormalTestManager.voltageProtocol) {
                                            CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                                        }
                                        FormalTestManager.isTesting = false;
                                    }
                                }
                            }
                        }
                    }
                    break;
                case UNPROCESSED_BUSINESS:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    break;
                case DEV_ERROR:
                    WebServiceManager.sendMsg(param.getUserPageId(), MsgUtil.msgToWebData(socketDataMsg, FormalTestManager.devNameMapComm, 0));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case DEV_TARGET:
                    WebServiceManager.sendMsg(param.getUserPageId(), MsgUtil.msgToWebData(socketDataMsg, FormalTestManager.devNameMapComm, 1));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                case RE_OPERATE:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), quitOperateCode, true);
                    FormalTestManager.isTesting = false;
                    break;
                default:
                    WebServiceManager.sendUnknownErrorMessage(param.getUserPageId());
                    break;
            }
        }
    }


    /**
     * 启动录波功能
     *
     * @param param
     * @param socketDataMsg
     */
    private void recordWave(PreDetectionParam param, SocketDataMsg socketDataMsg) {
        String s = param.getUserPageId() + CnSocketUtil.CONTRAST_DEV_TAG;
        SourceResponseCodeEnum dictDataEnumByCode = SourceResponseCodeEnum.getDictDataEnumByCode(socketDataMsg.getCode());
        if (SourceOperateCodeEnum.RECORD_WAVE_STEP1.getValue().equals(socketDataMsg.getRequestId())) {
            switch (Objects.requireNonNull(dictDataEnumByCode)) {
                case SUCCESS:
                    WaveResultDTO waveResultDTO = JSON.parseObject(socketDataMsg.getData(), WaveResultDTO.class);
                    FormalTestManager.waveResultDTOMap.put(waveResultDTO.getId(), waveResultDTO);
                    successComm.add(waveResultDTO.getId());
                    if (successComm.size() == FormalTestManager.monitorMap.size()) {
                        FormalTestManager.waveNum += 1;
                        FormalTestManager.scheduledFuture.cancel(true);
                        FormalTestManager.scheduler.shutdown();
                        FormalTestManager.scheduler = null;

                        SocketDataMsg webSend = new SocketDataMsg();
                        webSend.setRequestId(SourceOperateCodeEnum.RECORD_WAVE_STEP1.getValue());
                        webSend.setOperateCode(SourceOperateCodeEnum.DEV_DATA_REQUEST_03.getValue());
                        webSend.setCode(SourceResponseCodeEnum.SUCCESS.getCode());
                        webSend.setData("第" + FormalTestManager.waveNum + "次录波完成！");
                        WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));

                        String errorSysId = FormalTestManager.currentTestPlan.getErrorSysId();
                        String code = String.valueOf(FormalTestManager.currentTestPlan.getCode());

                        AtomicBoolean flag = new AtomicBoolean(false);
                        FormalTestManager.pairsIpMap.forEach((devMonitorId, stdDevMonitorId) -> {
                            if (FormalTestManager.waveResultDTOMap.containsKey(devMonitorId)) {
                                WaveResultDTO waveResultDTO1 = FormalTestManager.waveResultDTOMap.get(devMonitorId);
                                WaveResultDTO waveResultDTO2 = FormalTestManager.waveResultDTOMap.get(stdDevMonitorId);
                                PreDetection.MonitorListDTO monitorListDTO = FormalTestManager.monitorMap.get(devMonitorId);
                                List<List<DevData>> lists = this.analyzeWaveFile(waveResultDTO1, waveResultDTO2, monitorListDTO, devMonitorId, stdDevMonitorId, FormalTestManager.testItemMap.keySet().stream().collect(Collectors.toList()));

                                if (CollUtil.isNotEmpty(lists) && lists.stream().flatMap(List::stream).allMatch(devData -> CollUtil.isNotEmpty(devData.getSqlData()) && CollUtil.isNotEmpty(devData.getSqlDataHarm()))) {
//                                if (false) {
                                    FormalTestManager.devDataMap.put(devMonitorId, lists.get(0));
                                    FormalTestManager.standardDevDataMap.put(stdDevMonitorId, lists.get(1));
                                } else {
                                    flag.set(true);
                                    webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                                    webSend.setData(MsgUtil.getPairStr(devMonitorId, stdDevMonitorId, FormalTestManager.devNameMapComm) + " 录波数据异常！");
                                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                                }
                            }
                        });

                        if (!flag.get()) {
//                        if (false) {
                            List<DevData> devDataList = FormalTestManager.devDataMap.values().stream().flatMap(List::stream).collect(Collectors.toList());
                            List<DevData> standardDevDataList = FormalTestManager.standardDevDataMap.values().stream().flatMap(List::stream).collect(Collectors.toList());

                            // 原始数据入库
                            DetectionCodeEnum prefixEnum = this.getPrefixEnum();
                            baseDataInsert(false, FormalTestManager.waveNum, DataSourceEnum.WAVE_DATA, devDataList, FormalTestManager.numMap, prefixEnum, code);
                            baseDataInsert(true, FormalTestManager.waveNum, DataSourceEnum.WAVE_DATA, standardDevDataList, FormalTestManager.numMap, prefixEnum, code);

                            // 进行误差计算
                            List<DevLineTestResult> allResultList = detectionService.processing(
                                    devDataList,
                                    standardDevDataList,
                                    FormalTestManager.pairsIpMap,
                                    FormalTestManager.devIdMapComm,
                                    FormalTestManager.testItemMap.keySet().stream().collect(Collectors.toList()),
                                    errorSysId, FormalTestManager.dataRule, FormalTestManager.numMap, code, FormalTestManager.waveNum, DataSourceEnum.WAVE_DATA);

                            Map<String, List<DevLineTestResult>> deviceIdMap = allResultList.stream().collect(Collectors.groupingBy(DevLineTestResult::getDeviceId, Collectors.toList()));
                            deviceIdMap.forEach((deviceId, devLineTestResultList) -> {
                                Map<Integer, Set<Integer>> chnMap = new HashMap<>();
                                devLineTestResultList.forEach(devLineTestResult -> {
                                    Integer[] chnResult = devLineTestResult.getChnResult(); // key为通道号，value为结果
                                    for (int i = 0; i < chnResult.length; i++) {
                                        chnMap.putIfAbsent(i + 1, new HashSet<>());
                                        chnMap.get(i + 1).add(chnResult[i]);
                                    }
                                });

                                DevLineTestResult devLineTestResult = new DevLineTestResult();
                                devLineTestResult.setDeviceId(deviceId);
                                devLineTestResult.setDeviceName(FormalTestManager.devNameMapComm.get(deviceId));
                                devLineTestResult.setScriptName(DataSourceEnum.WAVE_DATA.getValue());
                                Integer[] chnResult = new Integer[chnMap.size()];
                                chnMap.forEach((chn, resultSet) -> {
                                    Integer result = StorageUtil.getInteger(resultSet.stream().collect(Collectors.toList()));
                                    chnResult[chn - 1] = result;
                                });

                                DevLineTestResult devLineTestResult1 = FormalTestManager.preNumTestResultList.stream().filter(preNumTestResult -> preNumTestResult.getDeviceId().equals(deviceId)).findFirst().orElse(null);
                                if (ObjectUtil.isNotNull(devLineTestResult1)) {
                                    Integer[] chnResult1 = devLineTestResult1.getChnResult();
                                    for (int i = 0; i < chnResult1.length; i++) {
                                        Integer result = StorageUtil.getInteger(Arrays.asList(chnResult1[i], chnResult[i]));
                                        chnResult1[i] = result;
                                    }
                                } else {
                                    devLineTestResult.setChnResult(chnResult);
                                    FormalTestManager.preNumTestResultList.add(devLineTestResult);
                                }
                            });

                            if (FormalTestManager.waveNum < FormalTestManager.curretntTestPlanConfig.getWaveRecord()) {
                                // 继续录波
                                successComm.clear();
                                failComm.clear();
                                FormalTestManager.waveResultDTOMap.clear();

                                if (Objects.isNull(FormalTestManager.scheduler)) {
                                    FormalTestManager.scheduler = Executors.newScheduledThreadPool(1);
                                    FormalTestManager.scheduledFuture = FormalTestManager.scheduler.schedule(() -> {

                                        if (!FormalTestManager.isRemoveSocket) {
                                            System.out.println("第" + (FormalTestManager.waveNum + 1) + "次录波开始");
                                            this.sendRecordWave(s);
                                        }

                                        FormalTestManager.scheduler.shutdown();
                                        FormalTestManager.scheduler = null;
                                    }, 40, TimeUnit.SECONDS);
                                }
                            } else {
                                // 断开与设备的连接,但是不要将Socket移除
                                CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                                FormalTestManager.isTesting = false;

                                // 配对关系入库
                                this.pairDataInsert();

                                List<String> adTypes = FormalTestManager.testItemMap.values().stream().collect(Collectors.toList());
                                // 修改检测点状态、设备状态
                                FormalTestManager.pairsIpMap.forEach((ip1, ip2) -> {
                                    if (FormalTestManager.monitorMap.containsKey(ip1)) {
                                        String[] split = ip1.split(CnSocketUtil.SPLIT_TAG);
                                        String id = FormalTestManager.devIdMapComm.get(split[0]);
                                        pqMonitorService.updateMonitorResult(id + CnSocketUtil.SPLIT_TAG + split[1], adTypes, DataSourceEnum.WAVE_DATA, FormalTestManager.numMap.get(id + CnSocketUtil.SPLIT_TAG + split[1]), FormalTestManager.curretntTestPlanConfig.getWaveRecord(), code);
                                        pqDevService.updateResult(id, param.getUserId());
                                    }
                                });
                                // 最终将检测结果推送到前端
                                webSend.setCode(SourceResponseCodeEnum.ALL_SUCCESS.getCode());
                                webSend.setData(JSON.toJSONString(FormalTestManager.preNumTestResultList));
                                WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                            }
                        } else {
                            webSend.setCode(SourceResponseCodeEnum.ALL_FAIL.getCode());
                            webSend.setData("录波数据异常！");
                            WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));

                            // 断开与设备的连接,但是不要将Socket移除
                            CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                            FormalTestManager.isTesting = false;
                        }

                        successComm.clear();
                        failComm.clear();
                    }

                case UNPROCESSED_BUSINESS:
                    if (FormalTestManager.currentStep == SourceOperateCodeEnum.RECORD_WAVE_STEP1) {
                        String data = socketDataMsg.getData();
                        if (StrUtil.isNotBlank(data) && data.equals("waiting")) {
                            if (Objects.isNull(FormalTestManager.scheduler)) {
                                FormalTestManager.scheduler = Executors.newScheduledThreadPool(1);
                                FormalTestManager.scheduledFuture = FormalTestManager.scheduler.schedule(() -> {
                                    if (!FormalTestManager.isRemoveSocket) {
                                        SocketDataMsg webSend = new SocketDataMsg();
                                        webSend.setRequestId(SourceOperateCodeEnum.RECORD_WAVE_STEP1.getValue());
                                        webSend.setOperateCode(SourceOperateCodeEnum.DEV_DATA_REQUEST_03.getValue());
                                        System.out.println("无效的录波指令！");

                                        CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, true);
                                        FormalTestManager.isTesting = false;

                                        Collection<String> disjunction = CollectionUtil.disjunction(FormalTestManager.monitorMap.keySet(), successComm);
                                        // 向前端推送
                                        for (String key : disjunction) {
                                            webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                                            webSend.setData(MsgUtil.getMonitorInfo(key, FormalTestManager.devNameMapComm) + " 无效的录波指令！");
                                            WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                                        }
                                        // 推送最终失败结果
                                        webSend.setCode(SourceResponseCodeEnum.ALL_FAIL.getCode());//最终错误推送
                                        webSend.setData("无效的录波指令！");
                                        WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                                    }

                                    FormalTestManager.scheduler.shutdown();
                                    FormalTestManager.scheduler = null;
                                }, 30, TimeUnit.SECONDS);
                            }
                        }
                    }
                    break;
                case RECORD_WAVE_FAILED:
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
                    CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, true);
                    FormalTestManager.isTesting = false;
                    break;
            }
        }
    }

    private void coefficient(PreDetectionParam param, SocketDataMsg socketDataMsg) {
        SourceOperateCodeEnum sourceOperateCodeEnum = SourceOperateCodeEnum.getDictDataEnumByCode(socketDataMsg.getOperateCode());
        SourceResponseCodeEnum dictDataEnumByCode = SourceResponseCodeEnum.getDictDataEnumByCode(socketDataMsg.getCode());
        SocketMsg<String> xiSocket = new SocketMsg<>();
        xiSocket.setRequestId(SourceOperateCodeEnum.Coefficient_Check.getValue());

        switch (Objects.requireNonNull(sourceOperateCodeEnum)) {
            case DATA_CHNFACTOR$01:
                //获取系数
                switch (Objects.requireNonNull(dictDataEnumByCode)) {
                    case SUCCESS:
                        if (CollUtil.isNotEmpty(XiNumberManager.xiDevList)) {
                            List<DevXiNumData.GF> gfList = JSON.parseArray(socketDataMsg.getData(), DevXiNumData.GF.class);
                            DevXiNumData devXiNumData = new DevXiNumData();
                            String ip = XiNumberManager.xiDevList.get(0).getDevIP();
                            devXiNumData.setDevIP(ip);
                            //String stdMonitorId = DetectionServiceImpl.vAndIResultMap.keySet().stream().filter(key -> key.contains(ip)).findFirst().get();

                            List<PqStandardDevGain> pqStandardDevGainList = new ArrayList<>();
                            List<PqStandardDevGainRecord> recordList = new ArrayList<>();
                            for (int i = 0; i < gfList.size(); i++) {
                                DevXiNumData.GF gf = gfList.get(i);
                                String stdDevMonitorId = FormalTestManager.devIdMapComm.get(ip) + CnSocketUtil.SPLIT_TAG + (gf.getUMonitorPoint() + 1);
                                String devMonitorId = FormalTestManager.pairsIdMap.inverse().get(stdDevMonitorId);
                                PqStandardDevGain pqStandardDevGain = new PqStandardDevGain();
                                pqStandardDevGain.setStdDevMonitorId(stdDevMonitorId);

                                DevXiNumData.F f = gf.getF();
                                pqStandardDevGain.setUaGain(f.getUa_gain());
                                pqStandardDevGain.setUbGain(f.getUb_gain());
                                pqStandardDevGain.setUcGain(f.getUc_gain());
                                pqStandardDevGain.setU0Gain(f.getU0_gain());
                                pqStandardDevGain.setIaGain(f.getIa_gain());
                                pqStandardDevGain.setIbGain(f.getIb_gain());
                                pqStandardDevGain.setIcGain(f.getIc_gain());
                                pqStandardDevGain.setI0Gain(f.getI0_gain());
                                pqStandardDevGain.setUabGain(f.getUab_gain());
                                pqStandardDevGain.setUbcGain(f.getUbc_gain());
                                pqStandardDevGain.setUcaGain(f.getUca_gain());
                                pqStandardDevGain.setState(DataStateEnum.ENABLE.getCode());
                                pqStandardDevGainList.add(pqStandardDevGain);
                                DetectionServiceImpl.VAndIResult vAndIResult = DetectionServiceImpl.vAndIResultMap.get(ip + CnSocketUtil.SPLIT_TAG + (gf.getUMonitorPoint() + 1));
                                if (ObjectUtil.isNotNull(vAndIResult)) {
                                    int maxNum = pqStandardDevGainRecordService.getMaxNum(stdDevMonitorId, devMonitorId);
                                    PqStandardDevGainRecord record = new PqStandardDevGainRecord();
                                    record.setStdDevMonitorId(stdDevMonitorId);
                                    record.setDevMonitorId(devMonitorId);
                                    record.setNum(maxNum + 1);
                                    recordList.add(record);
                                    updateGfList(f, vAndIResult, stdDevMonitorId, maxNum);
                                }
                            }

                            xiSocket.setOperateCode(SourceOperateCodeEnum.DATA_CHNFACTOR$02.getValue());
                            devXiNumData.setGf(gfList);
                            xiSocket.setData(JSON.toJSONString(devXiNumData));
                            SocketManager.sendMsg(param.getUserPageId() + CnSocketUtil.CONTRAST_DEV_TAG, JSON.toJSONString(xiSocket));

                            // 原始系数入库
                            pqStandardDevGainService.add(pqStandardDevGainList);
                            pqStandardDevGainRecordService.addOrUpdate(recordList);
                        }
                        break;
                    case UNPROCESSED_BUSINESS:
                        break;
                    case NORMAL_RESPONSE:
                        break;
                    case DATA_RESOLVE:
                        break;
                    case COMMUNICATION_ERR:
                        break;
                    default:
                        break;
                }

                break;
            case DATA_CHNFACTOR$02:
                //系数下发后的响应
                switch (Objects.requireNonNull(dictDataEnumByCode)) {
                    case SUCCESS:
                        //单台装置系数下发后，需要删除集合中存在的当前装置
                        XiNumberManager.xiDevList.remove(0);
                        //继续下发每台装置系数，只到集合为空
                        if (CollUtil.isNotEmpty(XiNumberManager.xiDevList)) {
                            xiSocket.setOperateCode(SourceOperateCodeEnum.DATA_CHNFACTOR$01.getValue());
                            xiSocket.setData(JSON.toJSONString(XiNumberManager.devXiNumDataMap.get(XiNumberManager.xiDevList.get(0))));
                            PreDetection preDetection = XiNumberManager.xiDevList.get(0);
                            Map<String, Object> map = new HashMap<>();
                            map.put("devIP", preDetection.getDevIP());
                            map.put("chnNum", preDetection.getDevChns());
                            xiSocket.setData(JSON.toJSONString(map));
                            SocketManager.sendMsg(param.getUserPageId() + CnSocketUtil.CONTRAST_DEV_TAG, JSON.toJSONString(xiSocket));
                        } else {
                            //{"requestId":"Coefficient_Check","operateCode":"DATA_CHNFACTOR$02","data":"end","code":10200}
                            // 通知前端全部下发系数完成
                        }
                        break;
                    case UNPROCESSED_BUSINESS:
                        break;
                    case NORMAL_RESPONSE:
                        break;
                    case DATA_RESOLVE:
                        //quitSend(param);
                        break;
                    case COMMUNICATION_ERR:
                        break;
                    default:
                        break;
                }
                break;
//            case DEV_DATA_REQUEST_02:
//                //实时采集申请
//                String data = socketDataMsg.getData();
//                DevData devData = JSON.parseObject(data, DevData.class);
//                if (ObjectUtil.isNotNull(dictDataEnumByCode)) {
//                    switch (dictDataEnumByCode) {
//                        case SUCCESS:
//                            if (devData.getResult()) {
//                                FormalTestManager.realDataXiList.add(devData);
//                                successComm.add(devData.getId());
//                                System.out.println(successComm.size() + " ==" + FormalTestManager.monitorIdListComm.size() + "FormalTestManager.realDataXiList:" + FormalTestManager.realDataXiList.size() + "当前步骤" + XiNumberManager.stepNumber);
//                                if (successComm.size() == FormalTestManager.monitorIdListComm.size()) {
//                                    processData(param, xiSocket);
//                                }
//                            } else {
//                                System.out.println("系数校准抛除数据" + devData);
//                            }
//                            break;
//                        case UNPROCESSED_BUSINESS:
//                            WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(socketDataMsg));
//                            break;
//                        case NORMAL_RESPONSE:
//                            if (devData.getResult()) {
//                                FormalTestManager.realDataXiList.add(devData);
//                            } else {
//                                System.out.println("系数校准抛除数据" + devData);
//                            }
//                            break;
//                        default:
//                            xiSocket.setRequestId(socketDataMsg.getRequestId());
//                            xiSocket.setOperateCode(socketDataMsg.getOperateCode());
//                            xiSocket.setData(dictDataEnumByCode.getMessage());
//                            WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(xiSocket));
//                            break;
//                    }
//                }
//                break;
            default:
                WebServiceManager.sendUnknownErrorMessage(param.getUserPageId());
                break;
        }

    }


    /**
     * 退出检测返回
     */
    private void quitDeal(SocketDataMsg socketDataMsg, PreDetectionParam param) {
        SourceResponseCodeEnum dictDataEnumByCode = SourceResponseCodeEnum.getDictDataEnumByCode(socketDataMsg.getCode());
        SourceOperateCodeEnum operateCodeEnum = SourceOperateCodeEnum.getDictDataEnumByCode(socketDataMsg.getOperateCode());
        String s = param.getUserPageId() + CnSocketUtil.CONTRAST_DEV_TAG;

        switch (Objects.requireNonNull(dictDataEnumByCode)) {
            case SUCCESS:
                switch (Objects.requireNonNull(operateCodeEnum)) {
                    case QUIT_INIT_01:
                    case QUIT_INIT_02:
                    case QUIT_INIT_03:
                        if (FormalTestManager.isRemoveSocket) {
                            SocketManager.removeUser(s);
                        }
                        break;
                    default:
                }
                break;
            case UNPROCESSED_BUSINESS:
                break;
            case NO_INIT_DEV:
                switch (operateCodeEnum) {
                    case QUIT_INIT_01:
                    case QUIT_INIT_02:
                    case QUIT_INIT_03:
                        if (FormalTestManager.isRemoveSocket) {
                            SocketManager.removeUser(s);
                        }
                        break;
                }
                break;
            default:
                break;
        }

    }

    private void completeJudgment(PreDetectionParam param) {
        System.out.println("成功失败测点数量" + successComm.size() + ":" + failComm.size() + "监测点总数" + FormalTestManager.monitorMap.size());

        if (successComm.size() + failComm.size() == FormalTestManager.monitorMap.size()) {
            //全部装置返回
            if (!failComm.isEmpty()) {
                CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_01, false);
                CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_02, false);
                CnSocketUtil.contrastSendquit(param.getUserPageId(), SourceOperateCodeEnum.QUIT_INIT_03, false);
                FormalTestManager.isTesting = false;
                WebSocketVO<String> webSocketVO = new WebSocketVO<>();
                webSocketVO.setRequestId(SourceOperateCodeEnum.ERROR_FLOW_END.getValue());
                WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSocketVO));
            }
            successComm.clear();
            failComm.clear();
        }
    }

    /**
     * 清空数据
     */
    private void clearData() {
        successPair.clear();
        successComm.clear();
        failComm.clear();
        FormalTestManager.devDataMap.forEach((k, v) -> {
            v.clear();
        });
        FormalTestManager.standardDevDataMap.forEach((k, v) -> {
            v.clear();
        });
    }


    /**
     * 获取正式检测所需要的检测项code
     *
     * @return
     */
    private List<String> getAllDataType() {
        DetectionCodeEnum prefixEnum = this.getPrefixEnum();
        Set<String> testCodes = FormalTestManager.testItemMap.keySet().stream().collect(Collectors.toSet());
        if (testCodes.contains(prefixEnum.getCode() + DetectionCodeEnum.V2_50.getCode())
                || testCodes.contains(prefixEnum.getCode() + DetectionCodeEnum.PV2_50.getCode())
                || testCodes.contains(prefixEnum.getCode() + DetectionCodeEnum.SV_1_49.getCode())
                || testCodes.contains(prefixEnum.getCode() + DetectionCodeEnum.PSV_1_49.getCode())) {
            testCodes.add(prefixEnum.getCode() + DetectionCodeEnum.U1.getCode());
            testCodes.add(prefixEnum.getCode() + DetectionCodeEnum.PU1.getCode());
        }
        if (testCodes.contains(prefixEnum.getCode() + DetectionCodeEnum.I2_50.getCode()) || testCodes.contains(prefixEnum.getCode() + DetectionCodeEnum.SI_1_49.getCode())) {
            testCodes.add(prefixEnum.getCode() + DetectionCodeEnum.I1.getCode());
        }
        if (testCodes.contains(prefixEnum.getCode() + DetectionCodeEnum.PST.getCode())) {
            testCodes.remove(prefixEnum.getCode() + DetectionCodeEnum.PST.getCode());
            testCodes.add(DetectionCodeEnum.AVG_PREFIX.getCode() + DetectionCodeEnum.PST.getCode());
        }
        return testCodes.stream().sorted().collect(Collectors.toList());
    }

    /**
     * 获取前缀
     *
     * @return
     */
    private DetectionCodeEnum getPrefixEnum() {
        DetectionCodeEnum prefixEnum = DetectionCodeEnum.REAL_PREFIX;
        if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
            switch (FormalTestManager.nonWaveDataSourceEnum) {
                case REAL_DATA:
                    break;
                case MINUTE_STATISTICS_AVG:
                    prefixEnum = DetectionCodeEnum.AVG_PREFIX;
                    break;
                case MINUTE_STATISTICS_CP95:
                    prefixEnum = DetectionCodeEnum.CP_95_PREFIX;
                    break;
                case MINUTE_STATISTICS_MIN:
                    prefixEnum = DetectionCodeEnum.MIN_PREFIX;
                    break;
                case MINUTE_STATISTICS_MAX:
                    prefixEnum = DetectionCodeEnum.MAX_PREFIX;
                    break;
            }
        }
        return prefixEnum;
    }

    /**
     * 获取最大读取数据的组数
     *
     * @param targetCount 目标数量
     * @return
     */
    private Integer getReadCount(int targetCount) {
        if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
            if (FormalTestManager.nonWaveDataSourceEnum == DataSourceEnum.REAL_DATA) {
                return (int) (Math.ceil(targetCount / 5.0) * 20);
            } else {
                return (int) (Math.ceil(targetCount / 2.0) * 5);
            }
        } else {
            return (int) (Math.ceil(targetCount / 5.0) * 20);
        }
    }

    /**
     * 获取延迟时间
     *
     * @param targetCount
     * @return
     */
    private long getDelay(int targetCount) {
        if (FormalTestManager.isPstData) {
            return 60 * 10;
        }
        if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
            if (FormalTestManager.nonWaveDataSourceEnum == DataSourceEnum.REAL_DATA) {
                return (int) (Math.ceil(targetCount / 5.0) * 60);
            } else {
                return (int) (Math.ceil(targetCount / 2.0) * FormalTestManager.maxTime);
            }
        }
        return targetCount;
    }

    /**
     * 获取目标数量
     *
     * @return
     */
    private Integer getTargetCount() {
        if (FormalTestManager.isPstData) {
            return FormalTestManager.curretntTestPlanConfig.getFlicker() * 2;
        }
        if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
            if (FormalTestManager.nonWaveDataSourceEnum == DataSourceEnum.REAL_DATA) {
                return FormalTestManager.curretntTestPlanConfig.getRealTime() * 2;
            } else {
                return FormalTestManager.curretntTestPlanConfig.getStatistics() * 2;
            }
        }
        return -1;
    }

    private void setScheduler(int targetCount, String userPageId, SourceOperateCodeEnum requestOperateCode, SourceOperateCodeEnum quitOperateCode) {
        if (Objects.isNull(FormalTestManager.scheduler)) {
            SocketDataMsg webSend = new SocketDataMsg();
            webSend.setRequestId(SourceOperateCodeEnum.FORMAL_REAL.getValue());
            webSend.setOperateCode(requestOperateCode.getValue());

            FormalTestManager.scheduler = Executors.newScheduledThreadPool(1);
            long delay = this.getDelay(targetCount);
            FormalTestManager.scheduledFuture = FormalTestManager.scheduler.schedule(() -> {
                if (!checkResult) {
                    System.out.println("正式检测-" + delay + "s内收集数据不完整！");
                    // 断开与设备的连接,但是不要将Socket移除
                    if (FormalTestManager.statisticsProtocol && quitOperateCode == SourceOperateCodeEnum.QUIT_INIT_02) {
                        CnSocketUtil.contrastSendquit(userPageId, SourceOperateCodeEnum.QUIT_INIT_01, false);
                    }
                    if (FormalTestManager.voltageProtocol) {
                        CnSocketUtil.contrastSendquit(userPageId, SourceOperateCodeEnum.QUIT_INIT_03, false);
                    }
                    CnSocketUtil.contrastSendquit(userPageId, quitOperateCode, false);
                    FormalTestManager.isTesting = false;

                    this.clearData();

                    Collection<String> disjunction = CollectionUtil.disjunction(FormalTestManager.pairsIpMap.keySet(), successPair.keySet());
                    // 向前端推送收集数据不完整的配对项
                    for (String key : disjunction) {
                        webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                        webSend.setData(MsgUtil.getPairStr(key, FormalTestManager.pairsIpMap.inverse().get(key), FormalTestManager.devNameMapComm) + " 数据收集不完整！");
                        WebServiceManager.sendMsg(userPageId, JSON.toJSONString(webSend));
                    }
                    // 推送最终失败结果
                    webSend.setCode(SourceResponseCodeEnum.ALL_FAIL.getCode());//最终错误推送
                    WebServiceManager.sendMsg(userPageId, JSON.toJSONString(webSend));
                }
                FormalTestManager.scheduler.shutdown();
                FormalTestManager.scheduler = null;
            }, delay, TimeUnit.SECONDS);
        }
    }

    /**
     * 实时数据对齐-将数据推送给前端
     */
    private String getAlignDataToWeb() {
        List<AlignDataVO> data = new ArrayList<>();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(DatePattern.ISO8601_PATTERN);

        // key为标准设备的ip, value为该ip下所有通道的设备数据
        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, stdDevDataList) -> {
            AlignDataVO alignDataVO = new AlignDataVO();
            alignDataVO.setStdDevName(FormalTestManager.devNameMapComm.get(ip));

            // 按照通道号分组。key为通道号，value为该通道号下所有设备数据
            Map<String, List<DevData>> channelDataMap = stdDevDataList.stream().collect(Collectors.groupingBy(obj -> obj.getId().split(CnSocketUtil.SPLIT_TAG)[1]));

            List<AlignDataVO.ChannelData> channelDataList = new ArrayList<>();
            channelDataMap.forEach((channel, channelDevDataList) -> {
                String standardDevMonitorId = ip + CnSocketUtil.SPLIT_TAG + channel;
                String devMonitorId = FormalTestManager.pairsIpMap.inverse().get(standardDevMonitorId);
                PreDetection.MonitorListDTO monitorListDTO = FormalTestManager.monitorMap.get(devMonitorId);
                List<DevData> devDataList = BeanUtil.copyToList(FormalTestManager.devDataMap.get(devMonitorId), DevData.class);
                devDataList.sort(Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
                channelDevDataList.sort(Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));

                AlignDataVO.ChannelData channelData = new AlignDataVO.ChannelData();
                channelData.setStdDevNum(channel);
                String[] split = devMonitorId.split(CnSocketUtil.SPLIT_TAG);
                channelData.setDevInfo(FormalTestManager.devNameMapComm.get(split[0]) + "通道" + split[1]);

                boolean isStar = DetectionCodeEnum.STAR.getCode().equals(monitorListDTO.getConnection());
                boolean isDelta = DetectionCodeEnum.DELTA.getCode().equals(monitorListDTO.getConnection());

                PreDetection preDetection = FormalTestManager.devList.stream().filter(obj -> obj.getDevIP().equals(split[0])).findFirst().orElse(null);
                if (ObjectUtil.isNotNull(preDetection)) {
                    if (preDetection.getUsePhaseIndex() == 1) {
                        isStar = true;
                        isDelta = false;
                    } else {
                        if (DetectionCodeEnum.STAR.getCode().equals(monitorListDTO.getConnection())) {
                            isStar = true;
                            isDelta = false;
                        } else {
                            isStar = false;
                            isDelta = true;
                        }
                    }
                }

                List<AlignDataVO.RawData> dataList = new ArrayList<>();
                for (int i = 0; i < channelDevDataList.size(); i++) {
                    DevData.SqlDataDTO.ListDTO list1 = null;
                    DevData.SqlDataDTO sqlDataDTO1 = null;
                    if (isStar) {
                        sqlDataDTO1 = channelDevDataList.get(i).getSqlData().stream().filter(x -> x.getDesc().equals(DetectionCodeEnum.VRMS.getCode())).findFirst().orElse(null);
                    }
                    if (isDelta) {
                        sqlDataDTO1 = channelDevDataList.get(i).getSqlData().stream().filter(x -> x.getDesc().equals(DetectionCodeEnum.PVRMS.getCode())).findFirst().orElse(null);
                    }
                    if (ObjectUtil.isNotNull(sqlDataDTO1)) {
                        list1 = sqlDataDTO1.getList();
                    }
                    AlignDataVO.RawData rawData = new AlignDataVO.RawData();
                    rawData.setUaStdDev(list1.getA());
                    rawData.setUbStdDev(list1.getB());
                    rawData.setUcStdDev(list1.getC());

                    LocalDateTime localDateTime = DetectionUtil.timeFormat(channelDevDataList.get(i).getTime(), DetectionUtil.FORMATTER);
                    rawData.setTimeStdDev(localDateTime.format(dtf));

                    DevData devData = devDataList.get(i);
                    if (ObjectUtil.isNotNull(devData)) {
                        DevData.SqlDataDTO.ListDTO list2 = null;
                        DevData.SqlDataDTO sqlDataDTO2 = null;
                        if (isStar) {
                            sqlDataDTO2 = devData.getSqlData().stream().filter(x -> x.getDesc().equals(DetectionCodeEnum.VRMS.getCode())).findFirst().orElse(null);
                        }
                        if (isDelta) {
                            sqlDataDTO2 = devData.getSqlData().stream().filter(x -> x.getDesc().equals(DetectionCodeEnum.PVRMS.getCode())).findFirst().orElse(null);
                        }
                        if (ObjectUtil.isNotNull(sqlDataDTO2)) {
                            list2 = sqlDataDTO2.getList();
                        }
                        rawData.setUaDev(list2.getA());
                        rawData.setUbDev(list2.getB());
                        rawData.setUcDev(list2.getC());
                        localDateTime = DetectionUtil.timeFormat(devData.getTime(), DetectionUtil.FORMATTER);
                        rawData.setTimeDev(localDateTime.format(dtf));
                    }
                    dataList.add(rawData);
                }
                for (int i = channelDevDataList.size(); i < devDataList.size(); i++) {
                    AlignDataVO.RawData rawData = new AlignDataVO.RawData();
                    DevData devData = devDataList.get(i);
                    DevData.SqlDataDTO.ListDTO list = devData.getSqlData().get(0).getList();
                    rawData.setUaDev(list.getA());
                    rawData.setUbDev(list.getB());
                    rawData.setUcDev(list.getC());
                    LocalDateTime localDateTime = DetectionUtil.timeFormat(devDataList.get(i).getTime(), DetectionUtil.FORMATTER);
                    rawData.setTimeDev(localDateTime.format(dtf));
                }
                channelData.setDataList(dataList);
                channelDataList.add(channelData);
            });
            alignDataVO.setChannelDataList(channelDataList);
            data.add(alignDataVO);
        });

        return JSON.toJSONString(data, SerializerFeature.WriteMapNullValue);
    }

    /**
     * 实时数据对齐-保存数据到excel文件
     */
    private void saveAlignData() {
        List<Map<String, Object>> sheetsList = new ArrayList<>();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(DatePattern.ISO8601_PATTERN);

        // key为被检设备的ip, value为该ip下所有通道的设备数据
        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, stdDevDataList) -> {
            // 按照通道号分组。key为通道号，value为该通道号下所有设备数据
            Map<String, List<DevData>> channelDataMap = stdDevDataList.stream().collect(Collectors.groupingBy(obj -> obj.getId().split(CnSocketUtil.SPLIT_TAG)[1]));

            channelDataMap.forEach((channel, channelDevDataList) -> {
                String standardDevMonitorId = ip + CnSocketUtil.SPLIT_TAG + channel;
                String devMonitorId = FormalTestManager.pairsIpMap.inverse().get(standardDevMonitorId);
                String[] split = devMonitorId.split(CnSocketUtil.SPLIT_TAG);
                PreDetection.MonitorListDTO monitorListDTO = FormalTestManager.monitorMap.get(devMonitorId);
                List<DevData> devDataList = BeanUtil.copyToList(FormalTestManager.devDataMap.get(devMonitorId), DevData.class);
                channelDevDataList.sort(Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
                devDataList.sort(Comparator.comparing(obj -> DetectionUtil.getMillis(obj.getTime())));
                HashMap sheet = new HashMap<>();
                ExportParams exportParams = new ExportParams();
                String standardDevName = FormalTestManager.devNameMapComm.get(ip);
                exportParams.setSheetName(standardDevName + "通道" + channel);
                sheet.put("title", exportParams);

                boolean isStar = DetectionCodeEnum.STAR.getCode().equals(monitorListDTO.getConnection());
                boolean isDelta = DetectionCodeEnum.DELTA.getCode().equals(monitorListDTO.getConnection());

                PreDetection preDetection = FormalTestManager.devList.stream().filter(obj -> obj.getDevIP().equals(split[0])).findFirst().orElse(null);
                if (ObjectUtil.isNotNull(preDetection)) {
                    if (preDetection.getUsePhaseIndex() == 1) {
                        isStar = true;
                        isDelta = false;
                    } else {
                        if (DetectionCodeEnum.STAR.getCode().equals(monitorListDTO.getConnection())) {
                            isStar = true;
                            isDelta = false;
                        } else {
                            isStar = false;
                            isDelta = true;
                        }
                    }
                }

                List<AlignDataExcel> dataList = new ArrayList<>();
                for (int i = 0; i < channelDevDataList.size(); i++) {
                    DevData.SqlDataDTO.ListDTO list1 = null;
                    DevData.SqlDataDTO sqlDataDTO1 = null;
                    if (isStar) {
                        sqlDataDTO1 = channelDevDataList.get(i).getSqlData().stream().filter(x -> x.getDesc().equals(DetectionCodeEnum.VRMS.getCode())).findFirst().orElse(null);
                    }
                    if (isDelta) {
                        sqlDataDTO1 = channelDevDataList.get(i).getSqlData().stream().filter(x -> x.getDesc().equals(DetectionCodeEnum.PVRMS.getCode())).findFirst().orElse(null);
                    }
                    if (ObjectUtil.isNotNull(sqlDataDTO1)) {
                        list1 = sqlDataDTO1.getList();
                    }
                    AlignDataExcel alignDataExcel = new AlignDataExcel();
                    LocalDateTime localDateTime = DetectionUtil.timeFormat(channelDevDataList.get(i).getTime(), DetectionUtil.FORMATTER);
                    alignDataExcel.setTimeStdDev(localDateTime.format(dtf));
                    alignDataExcel.setUaStdDev(list1.getA());
                    alignDataExcel.setUbStdDev(list1.getB());
                    alignDataExcel.setUcStdDev(list1.getC());

                    DevData devData = devDataList.get(i);
                    if (ObjectUtil.isNotNull(devData)) {
                        DevData.SqlDataDTO.ListDTO list2 = null;
                        DevData.SqlDataDTO sqlDataDTO2 = null;
                        if (isStar) {
                            sqlDataDTO2 = devData.getSqlData().stream().filter(x -> x.getDesc().equals(DetectionCodeEnum.VRMS.getCode())).findFirst().orElse(null);
                        }
                        if (isDelta) {
                            sqlDataDTO2 = devData.getSqlData().stream().filter(x -> x.getDesc().equals(DetectionCodeEnum.PVRMS.getCode())).findFirst().orElse(null);
                        }
                        if (ObjectUtil.isNotNull(sqlDataDTO2)) {
                            list2 = sqlDataDTO2.getList();
                        }
                        alignDataExcel.setUaDev(list2.getA());
                        alignDataExcel.setUbDev(list2.getB());
                        alignDataExcel.setUcDev(list2.getC());
                        localDateTime = DetectionUtil.timeFormat(devData.getTime(), DetectionUtil.FORMATTER);
                        alignDataExcel.setTimeDev(localDateTime.format(dtf));
                    }
                    dataList.add(alignDataExcel);
                }

                for (int i = channelDevDataList.size(); i < devDataList.size(); i++) {
                    AlignDataExcel alignDataExcel = new AlignDataExcel();
                    DevData.SqlDataDTO.ListDTO list2 = devDataList.get(i).getSqlData().get(0).getList();
                    alignDataExcel.setUaDev(list2.getA());
                    alignDataExcel.setUbDev(list2.getB());
                    alignDataExcel.setUcDev(list2.getC());
                    LocalDateTime localDateTime = DetectionUtil.timeFormat(devDataList.get(i).getTime(), DetectionUtil.FORMATTER);
                    alignDataExcel.setTimeDev(localDateTime.format(dtf));

                    dataList.add(alignDataExcel);
                }
                sheet.put("data", dataList);
                sheet.put("entity", AlignDataExcel.class);
                sheetsList.add(sheet);
            });
        });

        ExcelUtil.saveExcel(pathConfig.getDataPath(), "对齐数据.xlsx", sheetsList);
    }

    /**
     * 模型一致性校验
     *
     * @param param   预检测参数
     * @param dataMap 收到的数据
     * @param isDev   是否是被检设备
     */
    private boolean modelCheck(PreDetectionParam param, Map<String, List<DevData>> dataMap, PreDetection.MonitorListDTO monitorListDTO, boolean isDev) {
        AtomicBoolean flag = new AtomicBoolean(true);
        DetectionCodeEnum prefixEnum = this.getPrefixEnum();
        dataMap.forEach((k, v) -> {
            v.stream().forEach(devData1 -> {
                List<String> descList = devData1.getSqlData().stream().map(obj -> prefixEnum.getCode() + obj.getDesc()).collect(Collectors.toList());
                descList.addAll(devData1.getSqlDataHarm().stream().map(obj -> prefixEnum.getCode() + obj.getDesc()).collect(Collectors.toList()));
                SocketDataMsg webSend = new SocketDataMsg();
                webSend.setRequestId(SourceOperateCodeEnum.YJC_MXYZXJY.getValue());
                webSend.setData(k);
                List<String> allTestItem = this.getAllDataType();
                if (allTestItem.contains(DetectionCodeEnum.AVG_PREFIX.getCode() + DetectionCodeEnum.PST.getCode())) {
                    allTestItem.remove(DetectionCodeEnum.AVG_PREFIX.getCode() + DetectionCodeEnum.PST.getCode());
                }
                if (DetectionCodeEnum.STAR.getCode().equals(monitorListDTO.getConnection())) {
                    // 移除相关线电压测试项
                    allTestItem.remove(prefixEnum.getCode() + DetectionCodeEnum.PVRMS.getCode());
                    allTestItem.remove(prefixEnum.getCode() + DetectionCodeEnum.PU1.getCode());
                    allTestItem.remove(prefixEnum.getCode() + DetectionCodeEnum.PV2_50.getCode());
                    allTestItem.remove(prefixEnum.getCode() + DetectionCodeEnum.PSV_1_49.getCode());
                }
                if (DetectionCodeEnum.DELTA.getCode().equals(monitorListDTO.getConnection())) {
                    // 移除相关相电压测试项
                    allTestItem.remove(prefixEnum.getCode() + DetectionCodeEnum.VRMS.getCode());
                    allTestItem.remove(prefixEnum.getCode() + DetectionCodeEnum.U1.getCode());
                    allTestItem.remove(prefixEnum.getCode() + DetectionCodeEnum.V2_50.getCode());
                    allTestItem.remove(prefixEnum.getCode() + DetectionCodeEnum.SV_1_49.getCode());

                    // 如果是在是没有线电压谐波含有率、线电压间谐波含有率，勉强使其通过
                    String ip = k.split(CnSocketUtil.SPLIT_TAG)[0];
                    PreDetection preDetection = null;
                    if (isDev) {
                        preDetection = FormalTestManager.devList.stream().filter(obj -> obj.getDevIP().equals(ip)).findFirst().orElse(null);
                    } else {
                        preDetection = FormalTestManager.standardDevList.stream().filter(obj -> obj.getDevIP().equals(ip)).findFirst().orElse(null);
                    }
                    if (ObjectUtil.isNotNull(preDetection)) {
                        if (preDetection.getUsePhaseIndex() == 1) {
                            allTestItem.remove(prefixEnum.getCode() + DetectionCodeEnum.PVRMS.getCode());
                            allTestItem.remove(prefixEnum.getCode() + DetectionCodeEnum.PU1.getCode());
                            allTestItem.remove(prefixEnum.getCode() + DetectionCodeEnum.PV2_50.getCode());
                            allTestItem.remove(prefixEnum.getCode() + DetectionCodeEnum.PSV_1_49.getCode());
                        }
                    }
                }

                if (CollUtil.isNotEmpty(descList) && descList.containsAll(allTestItem)) {
                    // 成功信息
                    webSend.setCode(SourceResponseCodeEnum.SUCCESS.getCode());
                    WebServiceManager.sendMsg(param.getUserPageId(), MsgUtil.msgToWebData(webSend, FormalTestManager.devNameMapComm, 1));
                } else {
                    // 错误信息
                    allTestItem.removeAll(descList);
                    String appendMsg = allTestItem.stream().map(obj -> {
                        String s = obj.replace(prefixEnum.getCode(), "");
                        DetectionCodeEnum anEnum = DetectionCodeEnum.getDetectionCodeByCode(s);
                        return anEnum.getMessage();
                    }).reduce((a, b) -> a + "、" + b).get();

                    appendMsg += "测试项未通过！";
                    webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                    webSend.setData(MsgUtil.getMsg(k, FormalTestManager.devNameMapComm, appendMsg));
                    WebServiceManager.sendMsg(param.getUserPageId(), JSON.toJSONString(webSend));
                    flag.set(false);
                }
            });
        });

        return flag.get();
    }

    /**
     * 根据数据对齐算法，针对单个监测点进行数据对齐
     *
     * @param devDataList         被检设备数据（已经按照时间戳从小到大排过序）
     * @param standardDevDataList 标准设备数据（已经按照时间戳从小到大排过序）
     * @param num                 对齐的组数
     * @return 返回一个List集合，集合中仅有2个元素。下标为0的元素为被检设备数据，下标为1的元素为其一一对齐的标准设备数据
     */
    private List<List<DevData>> getSingleMonitorAlignData(List<DevData> devDataList, List<DevData> standardDevDataList, int num, int type) {
        List<List<DevData>> result = new ArrayList<>();

        List<DevData> alignDevData = new ArrayList<>();
        List<DevData> alignStdDevData = new ArrayList<>();
        int jStart = 0;
        for (int i = 0; i < standardDevDataList.size(); i++) {
            int j = jStart;
            if (j >= devDataList.size()) {
                break;
            }
            for (; j < devDataList.size(); j++) {
                if (DetectionUtil.isAlignData(devDataList.get(j), standardDevDataList.get(i), type)) {
                    alignDevData.add(devDataList.get(j));
                    alignStdDevData.add(standardDevDataList.get(i));
                    jStart = j + 1;

                    if (alignDevData.size() >= num && alignStdDevData.size() >= num) {
                        jStart = devDataList.size();
                    }
                    break;
                }
            }
        }

        result.add(alignDevData);
        result.add(alignStdDevData);
        return result;
    }

    /**
     * 单个检测点相序校验
     *
     * @param devMonitorId         单个检测点的被检设备监测id
     * @param standardDevMonitorId 单个检测点的标准设备监测id
     * @param devData              单个检测点的被检设备数据
     * @param stdData              单个检测点的标准设备数据
     * @param devNameMapComm       设备名称映射表 key为设备IP，value为设备名称
     * @param userId               用户id（用于找到channel）
     * @return
     */
    private boolean singleMonitorXuCheck(String devMonitorId, String standardDevMonitorId, PreDetection.MonitorListDTO monitorListDTO, List<DevData> devData, List<DevData> stdData, Map<String, String> devNameMapComm, String userId) {
        DecimalFormat df = new DecimalFormat("0.000000");
        Boolean flagU = true;
        Boolean flagI = true;
        Boolean flagIMBV = true;
        Boolean flagIMBA = true;
        Boolean flagPhase = true;

        // 获取被检设备的额定电流
        Double ratedCurrent = Double.valueOf(monitorListDTO.getCtStr().split("\\:")[1]);

        String pairStr = MsgUtil.getPairStr(devMonitorId, standardDevMonitorId, devNameMapComm);
        SocketDataMsg webSend = new SocketDataMsg();
        webSend.setRequestId(SourceOperateCodeEnum.YJC_XUJY.getValue());
        webSend.setOperateCode(SourceOperateCodeEnum.DEV_DATA_REQUEST_02.getValue());

        boolean isStar = DetectionCodeEnum.STAR.getCode().equals(monitorListDTO.getConnection());
        boolean isDelta = DetectionCodeEnum.DELTA.getCode().equals(monitorListDTO.getConnection());

        String[] split = devMonitorId.split(CnSocketUtil.SPLIT_TAG);
        PreDetection preDetection = FormalTestManager.devList.stream().filter(obj -> obj.getDevIP().equals(split[0])).findFirst().orElse(null);

        if (ObjectUtil.isNotNull(preDetection)) {
            if (preDetection.getUsePhaseIndex() == 1) {
                isStar = true;
                isDelta = false;
            } else {
                if (DetectionCodeEnum.STAR.getCode().equals(monitorListDTO.getConnection())) {
                    isStar = true;
                    isDelta = false;
                } else {
                    isStar = false;
                    isDelta = true;
                }
            }
        }

        // 电压校验
        List<DevData.SqlDataDTO> uDev = null;
        List<DevData.SqlDataDTO> uStd = null;
        if (isStar) {
            uDev = getSingleMonitorSqlData(devData, DetectionCodeEnum.VRMS.getCode());
            uStd = getSingleMonitorSqlData(stdData, DetectionCodeEnum.VRMS.getCode());
        }
        if (isDelta) {
            // 角型接线方式，则获取线电压
            uDev = getSingleMonitorSqlData(devData, DetectionCodeEnum.PVRMS.getCode());
            uStd = getSingleMonitorSqlData(stdData, DetectionCodeEnum.PVRMS.getCode());
        }

        String detail = "数据为空！";
        if (CollUtil.isNotEmpty(uDev) && CollUtil.isNotEmpty(uStd)) {
            DevData.SqlDataDTO.ListDTO uDevList = uDev.get(0).getList();
            DevData.SqlDataDTO.ListDTO uStdList = uStd.get(0).getList();
            detail = "被检设备：" + (isDelta ? "Uab" : "Ua") + "=" + df.format(uDevList.getA()) +
                    ", " + (isDelta ? "Ubc" : "Ub") + "=" + df.format(uDevList.getB()) +
                    ", " + (isDelta ? "Uca" : "Uc") + "=" + df.format(uDevList.getC()) +
                    "；标准设备：" + (isDelta ? "Uab" : "Ua") + "=" + df.format(uStdList.getA()) +
                    ", " + (isDelta ? "Ubc" : "Ub") + "=" + df.format(uStdList.getB()) +
                    ", " + (isDelta ? "Uca" : "Uc") + "=" + df.format(uStdList.getC());
            if (!voltageOrCurrentCheck(uDevList.getA(), uDevList.getB(), uDevList.getC(), uStdList.getA(), uStdList.getB(), uStdList.getC(), true)) {
                flagU = false;
                // 单个检测点电压校验失败，推送失败消息
                webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                webSend.setData(pairStr + "：电压校验失败!" + detail);
            } else {
                webSend.setCode(SourceResponseCodeEnum.SUCCESS.getCode());
                webSend.setData(pairStr + "：电压校验成功!" + detail);
            }
        } else {
            flagU = false;
            webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
            webSend.setData(pairStr + "：电压校验失败!" + (isDelta ? "线" : "相") + "电压" + detail);
        }
        WebServiceManager.sendMsg(userId, JSON.toJSONString(webSend));

        // 电流校验
        detail = "数据为空！";
        List<DevData.SqlDataDTO> iDev = getSingleMonitorSqlData(devData, DetectionCodeEnum.IRMS.getCode());
        List<DevData.SqlDataDTO> iStd = getSingleMonitorSqlData(stdData, DetectionCodeEnum.IRMS.getCode());

        if (CollUtil.isNotEmpty(iDev) && CollUtil.isNotEmpty(iStd)) {
            DevData.SqlDataDTO.ListDTO iDevList = iDev.get(0).getList();
            DevData.SqlDataDTO.ListDTO iStdList = iStd.get(0).getList();

            if (!DetectionUtil.isZero(iDevList.getA(), ratedCurrent) && !DetectionUtil.isZero(iDevList.getB(), ratedCurrent) && !DetectionUtil.isZero(iDevList.getC(), ratedCurrent) && !DetectionUtil.isZero(iStdList.getA(), ratedCurrent) && !DetectionUtil.isZero(iStdList.getB(), ratedCurrent) && !DetectionUtil.isZero(iStdList.getC(), ratedCurrent)) {
                detail = "被检设备：Ia=" + df.format(iDevList.getA()) + ",Ib=" + df.format(iDevList.getB()) + ",Ic=" + df.format(iDevList.getC()) + "；标准设备：Ia=" + df.format(iStdList.getA()) + ",Ib=" + df.format(iStdList.getB()) + ",Ic=" + df.format(iStdList.getC());
                if (!voltageOrCurrentCheck(iDevList.getA(), iDevList.getB(), iDevList.getC(), iStdList.getA(), iStdList.getB(), iStdList.getC(), false)) {
                    // 单个检测点电流校验失败，推送失败消息
                    flagI = false;
                    webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                    webSend.setData(pairStr + "：电流校验失败!" + detail);
                    WebServiceManager.sendMsg(userId, JSON.toJSONString(webSend));
                } else {
                    webSend.setCode(SourceResponseCodeEnum.SUCCESS.getCode());
                    webSend.setData(pairStr + "：电流校验成功!" + detail);
                    WebServiceManager.sendMsg(userId, JSON.toJSONString(webSend));
                }
            } else {
                // 什么都不做，不推送消息
            }
        } else {
            flagI = false;
            webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
            webSend.setData(pairStr + "：电流校验失败!" + detail);
            WebServiceManager.sendMsg(userId, JSON.toJSONString(webSend));
        }


        // 根据接线方式（星型、角型）来决定是否进行三项不平衡校验
        detail = "数据为空！";
        if (isStar) {
            //进行三项不平衡校验
            List<DevData.SqlDataDTO> uUnblanceDev = getSingleMonitorSqlData(devData, DetectionCodeEnum.V_UNBAN.getCode());
            List<DevData.SqlDataDTO> uUnblanceStd = getSingleMonitorSqlData(stdData, DetectionCodeEnum.V_UNBAN.getCode());

            if (CollUtil.isNotEmpty(uUnblanceDev) && CollUtil.isNotEmpty(uUnblanceStd)) {
                DevData.SqlDataDTO.ListDTO uUnblanceDevList = uUnblanceDev.get(0).getList();
                DevData.SqlDataDTO.ListDTO uUnblanceStdList = uUnblanceStd.get(0).getList();
                detail = "被检设备：IMBV=" + df.format(uUnblanceDevList.getB()) + "；标准设备：IMBV=" + df.format(uUnblanceStdList.getB());
                if (!unbalanceCheck(uUnblanceDevList.getB(), uUnblanceStdList.getB(), true)) {
                    // 单个检测点三项电压不平衡校验失败，推送失败消息
                    flagIMBV = false;
                    webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                    webSend.setData(pairStr + "：三项电压不平衡校验失败!" + detail);
                } else {
                    webSend.setCode(SourceResponseCodeEnum.SUCCESS.getCode());
                    webSend.setData(pairStr + "：三项电压不平衡校验成功!" + detail);
                }
            } else {
                flagIMBV = false;
                webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                webSend.setData(pairStr + "：三项电压不平衡校验失败!" + detail);
            }
            WebServiceManager.sendMsg(userId, JSON.toJSONString(webSend));

            List<DevData.SqlDataDTO> iUnblanceDev = getSingleMonitorSqlData(devData, DetectionCodeEnum.I_UNBAN.getCode());
            List<DevData.SqlDataDTO> iUnblanceStd = getSingleMonitorSqlData(stdData, DetectionCodeEnum.I_UNBAN.getCode());
            if (CollUtil.isNotEmpty(iUnblanceDev) && CollUtil.isNotEmpty(iUnblanceStd)) {
                DevData.SqlDataDTO.ListDTO iUnblanceDevList = iUnblanceDev.get(0).getList();
                DevData.SqlDataDTO.ListDTO iUnblanceStdList = iUnblanceStd.get(0).getList();
                detail = "被检设备：IMBA=" + df.format(iUnblanceDevList.getB()) + "；标准设备：IMBA=" + df.format(iUnblanceStdList.getB());
                if (!unbalanceCheck(iUnblanceDevList.getB(), iUnblanceStdList.getB(), false)) {
                    flagIMBA = false;
                    webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                    webSend.setData(pairStr + "：三项电流不平衡校验失败!" + detail);
                } else {
                    webSend.setCode(SourceResponseCodeEnum.SUCCESS.getCode());
                    webSend.setData(pairStr + "：三项电流不平衡校验成功!" + detail);
                }
            } else {
                flagIMBA = false;
                webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                webSend.setData(pairStr + "：三项电流不平衡校验失败!" + detail);
            }
            WebServiceManager.sendMsg(userId, JSON.toJSONString(webSend));
        }

        boolean isPhaseAngle = false;
        if (ObjectUtil.isNotNull(preDetection)) {
            isPhaseAngle = preDetection.getAngle() == 1 ? true : false;
        }

        // 动态调控是否支持相角差校验
        if (isPhaseAngle) {
            if (flagIMBV && flagIMBA) {
                // 是否存在电流
                boolean hasCurrent = iDev.stream().allMatch(
                        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));
                hasCurrent = hasCurrent && iStd.stream().allMatch(
                        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 (hasCurrent) {
                    detail = "数据为空！";
                    // 相角差校验
                    List<DevData.SqlDataDTO> vaDev = null;
                    List<DevData.SqlDataDTO> vaStd = null;
                    List<DevData.SqlDataDTO> iaDev = null;
                    List<DevData.SqlDataDTO> iaStd = null;
                    if (isStar) {
                        vaDev = getSingleMonitorSqlData(devData, DetectionCodeEnum.VA.getCode());
                        vaStd = getSingleMonitorSqlData(stdData, DetectionCodeEnum.VA.getCode());
                        iaDev = getSingleMonitorSqlData(devData, DetectionCodeEnum.IA.getCode());
                        iaStd = getSingleMonitorSqlData(stdData, DetectionCodeEnum.IA.getCode());
                        if (CollUtil.isEmpty(vaDev) && CollUtil.isEmpty(vaStd) && CollUtil.isEmpty(iaDev) && CollUtil.isEmpty(iaStd)) {
                            vaDev = getSingleMonitorSqlData(devData, DetectionCodeEnum.U1A.getCode());
                            vaStd = getSingleMonitorSqlData(stdData, DetectionCodeEnum.U1A.getCode());
                            iaDev = getSingleMonitorSqlData(devData, DetectionCodeEnum.I1A.getCode());
                            iaStd = getSingleMonitorSqlData(stdData, DetectionCodeEnum.I1A.getCode());
                        }
                    }
                    if (isDelta) {
                        vaDev = getSingleMonitorSqlData(devData, DetectionCodeEnum.PU1A.getCode());
                        vaStd = getSingleMonitorSqlData(stdData, DetectionCodeEnum.PU1A.getCode());
                        iaDev = getSingleMonitorSqlData(devData, DetectionCodeEnum.I1A.getCode());
                        iaStd = getSingleMonitorSqlData(stdData, DetectionCodeEnum.I1A.getCode());
                    }

                    if (CollUtil.isNotEmpty(vaDev) && CollUtil.isNotEmpty(vaStd) && CollUtil.isNotEmpty(iaDev) && CollUtil.isNotEmpty(iaStd)) {
                        DevData.SqlDataDTO.ListDTO vaDevList = vaDev.get(0).getList();
                        DevData.SqlDataDTO.ListDTO vaStdList = vaDev.get(0).getList();
                        DevData.SqlDataDTO.ListDTO iaDevList = vaDev.get(0).getList();
                        DevData.SqlDataDTO.ListDTO iaStdList = vaDev.get(0).getList();

                        detail = "被检设备：a=" + (vaDevList.getA() - iaDevList.getA()) + "°,b=" + (vaDevList.getB() - iaDevList.getB()) + "°,c=" + (vaDevList.getC() - iaDevList.getC()) + "；标准设备：a=" + (vaStdList.getA() - iaStdList.getA()) + "°,b=" + (vaStdList.getB() - iaStdList.getB()) + "°,c=" + (vaStdList.getC() - iaStdList.getC());

                        if (!phaseCheck(vaDevList, iaDevList, vaStdList, iaStdList)) {
                            // 单个检测点相角校验失败，推送失败消息
                            flagPhase = false;
                            webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                            webSend.setData(pairStr + "：相角差校验失败!" + detail);
                        } else {
                            webSend.setCode(SourceResponseCodeEnum.SUCCESS.getCode());
                            webSend.setData(pairStr + "：相角差校验成功!" + detail);
                        }
                    } else {
                        flagPhase = false;
                        webSend.setCode(SourceResponseCodeEnum.FAIL.getCode());
                        webSend.setData(pairStr + "：相角差校验失败!相角差" + detail);
                    }
                    WebServiceManager.sendMsg(userId, JSON.toJSONString(webSend));
                }
            }
        }
        return flagU && flagI && flagIMBV && flagIMBA && flagPhase;
    }

    /**
     * 从单个检测点中，根据检测项code获取SqlDataDTO数据
     *
     * @param devData 原始数据
     * @param type    检测项code
     * @return key为设备id_通道号，value为对应的SqlDataDTO数据集合
     */
    public static List<DevData.SqlDataDTO> getSingleMonitorSqlData(List<DevData> devData, String type) {
        return devData.stream().flatMap(x -> x.getSqlData().stream().filter(x1 -> type.equals(x1.getDesc().substring(x1.getType().indexOf("$") + 1)))).collect(Collectors.toList());
    }

    /**
     * 相序校验中的电压或电流校验
     *
     * @param a         被检设备a相电压\电流
     * @param b         被检设备b相电压\电流
     * @param c         被检设备c相电压\电流
     * @param aStd      标准设备a相电压\电流
     * @param bStd      标准设备b相电压\电流
     * @param cStd      标准设备c相电压\电流
     * @param isVoltage 是否为电压校验
     * @return
     */
    private boolean voltageOrCurrentCheck(Double a, Double b, Double c, Double aStd, Double bStd, Double cStd, boolean isVoltage) {
        if (isVoltage) {
            return NumberUtil.isIn(BigDecimal.valueOf(a), BigDecimal.valueOf(aStd * 0.99), BigDecimal.valueOf(aStd * 1.01))
                    && NumberUtil.isIn(BigDecimal.valueOf(b), BigDecimal.valueOf(bStd * 0.99), BigDecimal.valueOf(bStd * 1.01))
                    && NumberUtil.isIn(BigDecimal.valueOf(c), BigDecimal.valueOf(cStd * 0.99), BigDecimal.valueOf(cStd * 1.01));
//            return true;
        } else {
            return NumberUtil.isIn(BigDecimal.valueOf(a), BigDecimal.valueOf(aStd * 0.90), BigDecimal.valueOf(aStd * 1.10))
                    && NumberUtil.isIn(BigDecimal.valueOf(b), BigDecimal.valueOf(bStd * 0.90), BigDecimal.valueOf(bStd * 1.10))
                    && NumberUtil.isIn(BigDecimal.valueOf(c), BigDecimal.valueOf(cStd * 0.90), BigDecimal.valueOf(cStd * 1.10));
//            return true;
        }
    }

    /**
     * 相序校验中的电压（电流）不平衡度校验
     *
     * @param devData   被检设备的数据
     * @param stdData   标准设备的数据
     * @param isVoltage 是否为三项电压不平衡度校验
     * @return
     */
    private boolean unbalanceCheck(Double devData, Double stdData, boolean isVoltage) {
        if (isVoltage) {
//            return NumberUtil.isIn(BigDecimal.valueOf(devData), BigDecimal.valueOf(stdData * 0.95), BigDecimal.valueOf(stdData * 1.05));
            return true;
        } else {
//            return NumberUtil.isIn(BigDecimal.valueOf(devData), BigDecimal.valueOf(stdData * 0.90), BigDecimal.valueOf(stdData * 1.10));
            return true;
        }
    }


    /**
     * 相序校验中的相角校验
     *
     * @param uDevPhaseData         被检设备电压相角数据
     * @param iDevPhaseData         被检设备电流相角数据
     * @param uStandardDevPhaseData 标准设备电压相角数据
     * @param iStandardDevPhaseData 标准设备电流相角数据
     * @return
     */
    private boolean phaseCheck(DevData.SqlDataDTO.ListDTO uDevPhaseData, DevData.SqlDataDTO.ListDTO iDevPhaseData, DevData.SqlDataDTO.ListDTO
            uStandardDevPhaseData, DevData.SqlDataDTO.ListDTO iStandardDevPhaseData) {
        Double ua1 = DetectionUtil.adjustPhase(uDevPhaseData.getA());
        Double ub1 = DetectionUtil.adjustPhase(uDevPhaseData.getB());
        Double uc1 = DetectionUtil.adjustPhase(uDevPhaseData.getC());
        Double ia1 = DetectionUtil.adjustPhase(iDevPhaseData.getA());
        Double ib1 = DetectionUtil.adjustPhase(iDevPhaseData.getB());
        Double ic1 = DetectionUtil.adjustPhase(iDevPhaseData.getC());

        Double ua2 = DetectionUtil.adjustPhase(uStandardDevPhaseData.getA());
        Double ub2 = DetectionUtil.adjustPhase(uStandardDevPhaseData.getB());
        Double uc2 = DetectionUtil.adjustPhase(uStandardDevPhaseData.getC());
        Double ia2 = DetectionUtil.adjustPhase(iStandardDevPhaseData.getA());
        Double ib2 = DetectionUtil.adjustPhase(iStandardDevPhaseData.getB());
        Double ic2 = DetectionUtil.adjustPhase(iStandardDevPhaseData.getC());

        return NumberUtil.isIn(BigDecimal.valueOf(ua1 - ia1), BigDecimal.valueOf(ua2 - ia2 - 1), BigDecimal.valueOf(ua2 - ia2 + 1))
                && NumberUtil.isIn(BigDecimal.valueOf(ub1 - ib1), BigDecimal.valueOf(ub2 - ib2 - 1), BigDecimal.valueOf(ub2 - ib2 + 1))
                && NumberUtil.isIn(BigDecimal.valueOf(uc1 - ic1), BigDecimal.valueOf(uc2 - ic2 - 1), BigDecimal.valueOf(uc2 - ic2 + 1));
    }

    /**
     * 比对式原始数据入库
     *
     * @param isStdDev    是否为标准设备
     * @param waveNum     第几次录波
     * @param dataType    数据类型
     * @param devDataList 原始数据
     * @param numMap      第几次监测 key为被检设备监测点id,value为第几次监测
     * @param code        表后缀code
     */
    private void baseDataInsert(boolean isStdDev, Integer waveNum, DataSourceEnum dataType, List<DevData> devDataList, Map<String, Integer> numMap, DetectionCodeEnum prefixEnum, String code) {
        System.out.println("原始数据插入数据库开始执行=========================================");
        List<ContrastNonHarmonicResult> contrastNonHarmonicResults = new ArrayList<>();
        List<ContrastHarmonicResult> contrastHarmonicResults = new ArrayList<>();
        Map<String, String> harmonicRelationMap = new HashMap<>();
        harmonicRelationMap.put(DetectionCodeEnum.V2_50.getCode(), DetectionCodeEnum.U1.getCode());
        harmonicRelationMap.put(DetectionCodeEnum.PV2_50.getCode(), DetectionCodeEnum.PU1.getCode());
        harmonicRelationMap.put(DetectionCodeEnum.SV_1_49.getCode(), DetectionCodeEnum.U1.getCode());
        harmonicRelationMap.put(DetectionCodeEnum.PSV_1_49.getCode(), DetectionCodeEnum.PU1.getCode());
        harmonicRelationMap.put(DetectionCodeEnum.I2_50.getCode(), DetectionCodeEnum.I1.getCode());
        harmonicRelationMap.put(DetectionCodeEnum.SI_1_49.getCode(), DetectionCodeEnum.I1.getCode());
        for (DevData data : devDataList) {
            LocalDateTime localDateTime = DetectionUtil.timeFormat(data.getTime(), DetectionUtil.FORMATTER);
            if (Objects.nonNull(localDateTime)) {

                String[] splitArr = data.getId().split(CnSocketUtil.SPLIT_TAG);
                String devId = FormalTestManager.devIdMapComm.get(splitArr[0]);
                String temId = devId + CnSocketUtil.SPLIT_TAG + splitArr[1];
                List<PreDetection> devInfo = null;
                if (isStdDev) {
                    devInfo = pqStandardDevService.listStandardDevPreDetection(Collections.singletonList(devId));
                } else {
                    devInfo = pqDevService.getDevInfo(Collections.singletonList(devId));
                }
                Integer usePhaseIndex = devInfo.get(0).getUsePhaseIndex();
                List<String> allDesc = data.getSqlData().stream().map(x -> x.getDesc()).collect(Collectors.toList());
                allDesc.addAll(data.getSqlDataHarm().stream().map(x -> x.getDesc()).collect(Collectors.toList()));

                String bzDevId = devId;
                if (isStdDev) {
                    String s = FormalTestManager.pairsIdMap.inverse().get(devId + CnSocketUtil.SPLIT_TAG + splitArr[1]);
                    bzDevId = s.split(CnSocketUtil.SPLIT_TAG)[0];
                }
                PqMonitor monitor = pqMonitorService.getByDevIdAndNum(bzDevId, Integer.parseInt(splitArr[1]));
                DictData dictData = dictDataService.getById(monitor.getConnection());
                for (DevData.SqlDataDTO sqlDataDTO : data.getSqlData()) {
                    if (usePhaseIndex.equals(1)) {
                        if (DetectionCodeEnum.PVRMS.getCode().equals(sqlDataDTO.getDesc()) || DetectionCodeEnum.PU1.getCode().equals(sqlDataDTO.getDesc())) {
                            continue;
                        }
                    } else {
                        if (DetectionCodeEnum.STAR.getCode().equals(dictData.getCode())) {
                            if (DetectionCodeEnum.PVRMS.getCode().equals(sqlDataDTO.getDesc()) || DetectionCodeEnum.PU1.getCode().equals(sqlDataDTO.getDesc())) {
                                continue;
                            }
                        } else {
                            if ((DetectionCodeEnum.VRMS.getCode().equals(sqlDataDTO.getDesc()) || DetectionCodeEnum.U1.getCode().equals(sqlDataDTO.getDesc()))) {
                                continue;
                            }
                        }
                    }

                    if (!DetectionCodeEnum.U1.getCode().equals(sqlDataDTO.getDesc()) && !DetectionCodeEnum.PU1.getCode().equals(sqlDataDTO.getDesc()) && !DetectionCodeEnum.I1.getCode().equals(sqlDataDTO.getDesc())) {
                        DevData.SqlDataDTO.ListDTO listDTO = sqlDataDTO.getList();
                        ContrastNonHarmonicResult adNonHarmonicResult = new ContrastNonHarmonicResult();
                        adNonHarmonicResult.setTimeId(localDateTime);
                        adNonHarmonicResult.setNum(numMap.get(temId));
                        adNonHarmonicResult.setAdType(FormalTestManager.testItemMap.get(prefixEnum.getCode() + sqlDataDTO.getDesc()));
                        adNonHarmonicResult.setDataType(dataType.getValue());
                        if (isStdDev) {
                            adNonHarmonicResult.setDevMonitorId(FormalTestManager.pairsIdMap.inverse().get(temId));
                            adNonHarmonicResult.setStdDevMonitorId(temId);
                            adNonHarmonicResult.setFlag(1);
                        } else {
                            adNonHarmonicResult.setDevMonitorId(temId);
                            adNonHarmonicResult.setStdDevMonitorId(FormalTestManager.pairsIdMap.get(temId));
                            adNonHarmonicResult.setFlag(0);
                        }
                        adNonHarmonicResult.setWaveNum(waveNum);

                        Double a = listDTO.getA();
                        Double b = listDTO.getB();
                        Double c = listDTO.getC();
                        Double d = listDTO.getT();
                        if (Objects.nonNull(a)) {
                            adNonHarmonicResult.setAValue(String.format("%.7f", a));
                        }
                        if (Objects.nonNull(b)) {
                            adNonHarmonicResult.setBValue(String.format("%.7f", b));
                        }
                        if (Objects.nonNull(c)) {
                            adNonHarmonicResult.setCValue(String.format("%.7f", c));
                        }
                        if (Objects.nonNull(d)) {
                            adNonHarmonicResult.setTValue(String.format("%.7f", d));
                        }
                        contrastNonHarmonicResults.add(adNonHarmonicResult);
                    }
                }
                for (int j = 0; j < data.getSqlDataHarm().size(); j++) {
                    DevData.SqlDataHarmDTO sqlDataDTO = data.getSqlDataHarm().get(j);
                    if (usePhaseIndex.equals(1)) {
                        if (DetectionCodeEnum.PV2_50.getCode().equals(sqlDataDTO.getDesc()) || DetectionCodeEnum.PSV_1_49.getCode().equals(sqlDataDTO.getDesc())) {
                            continue;
                        }
                    } else {
                        if (DetectionCodeEnum.STAR.getCode().equals(dictData.getCode())) {
                            if (DetectionCodeEnum.PV2_50.getCode().equals(sqlDataDTO.getDesc()) || DetectionCodeEnum.PSV_1_49.getCode().equals(sqlDataDTO.getDesc())) {
                                continue;
                            }
                        } else {
                            if (DetectionCodeEnum.V2_50.getCode().equals(sqlDataDTO.getDesc()) || DetectionCodeEnum.SV_1_49.getCode().equals(sqlDataDTO.getDesc())) {
                                continue;
                            }
                        }
                    }

                    String dui = harmonicRelationMap.get(sqlDataDTO.getDesc());
                    ContrastHarmonicResult adHarmonicResult = new ContrastHarmonicResult();
                    adHarmonicResult.setTimeId(localDateTime);
                    adHarmonicResult.setNum(numMap.get(temId));
                    adHarmonicResult.setAdType(FormalTestManager.testItemMap.get(prefixEnum.getCode() + sqlDataDTO.getDesc()));
                    adHarmonicResult.setDataType(dataType.getValue());
                    if (isStdDev) {
                        adHarmonicResult.setDevMonitorId(FormalTestManager.pairsIdMap.inverse().get(temId));
                        adHarmonicResult.setStdDevMonitorId(temId);
                        adHarmonicResult.setFlag(1);
                    } else {
                        adHarmonicResult.setDevMonitorId(temId);
                        adHarmonicResult.setStdDevMonitorId(FormalTestManager.pairsIdMap.get(temId));
                        adHarmonicResult.setFlag(0);
                    }
                    adHarmonicResult.setWaveNum(waveNum);

                    if (ObjectUtil.isNotNull(dui)) {
                        DevData.SqlDataDTO.ListDTO vvv = data.getSqlData().stream().filter(it -> it.getDesc().equals(dui)).collect(Collectors.toList()).get(0).getList();
                        if (ObjectUtil.isNotNull(vvv)) {
                            Double aV = vvv.getA();
                            Double bV = vvv.getB();
                            Double cV = vvv.getC();
                            if (Objects.nonNull(aV)) {
//                                adHarmonicResult.setAValue1(String.format("%.7f", aV));
                                adHarmonicResult.setAValue0(String.format("%.7f", aV));
                            }
                            if (Objects.nonNull(bV)) {
//                                adHarmonicResult.setBValue1(String.format("%.7f", bV));
                                adHarmonicResult.setBValue0(String.format("%.7f", bV));
                            }
                            if (Objects.nonNull(cV)) {
//                                adHarmonicResult.setCValue1(String.format("%.7f", cV));
                                adHarmonicResult.setCValue0(String.format("%.7f", bV));
                            }
                        }
                    }

                    DevData.SqlDataHarmDTO.ListDTO tem = sqlDataDTO.getList();
                    List<String> a = tem.getA();
                    List<String> b = tem.getB();
                    List<String> c = tem.getC();

                    Class<ContrastHarmonicResult> example = (Class<ContrastHarmonicResult>) adHarmonicResult.getClass();

                    if (DetectionCodeEnum.SV_1_49.getCode().equals(sqlDataDTO.getDesc()) || DetectionCodeEnum.PSV_1_49.getCode().equals(sqlDataDTO.getDesc()) || DetectionCodeEnum.SI_1_49.getCode().equals(sqlDataDTO.getDesc())) {
                        for (int i = 1; i < a.size() + 1; i++) {
                            try {
                                Field aField = example.getDeclaredField("aValue" + i);
                                Field bField = example.getDeclaredField("bValue" + i);
                                Field cField = example.getDeclaredField("cValue" + i);

                                aField.setAccessible(true);
                                aField.set(adHarmonicResult, a.get(i - 1));
                                bField.setAccessible(true);
                                bField.set(adHarmonicResult, b.get(i - 1));
                                cField.setAccessible(true);
                                cField.set(adHarmonicResult, c.get(i - 1));
                            } catch (NoSuchFieldException | IllegalAccessException e) {
                                e.printStackTrace();
                            }
                        }
                    } else {
                        for (int i = 2; i <= a.size() + 1; i++) {
                            try {
                                Field aField = example.getDeclaredField("aValue" + i);
                                Field bField = example.getDeclaredField("bValue" + i);
                                Field cField = example.getDeclaredField("cValue" + i);

                                aField.setAccessible(true);
                                aField.set(adHarmonicResult, a.get(i - 2));
                                bField.setAccessible(true);
                                bField.set(adHarmonicResult, b.get(i - 2));
                                cField.setAccessible(true);
                                cField.set(adHarmonicResult, c.get(i - 2));
                            } catch (NoSuchFieldException | IllegalAccessException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    contrastHarmonicResults.add(adHarmonicResult);
                }
            }
        }

        detectionDataDealService.acceptNonHarmonic(contrastNonHarmonicResults, code);
        detectionDataDealService.acceptHarmonic(contrastHarmonicResults, code);
        System.out.println("原始数据插入数据库执行成功=========================================");
    }

    /**
     * 配对关系入库
     */
    private void pairDataInsert() {
        List<AdPair> adPairList = new ArrayList<>();
        for (String key : FormalTestManager.pairsIdMap.keySet()) {
            AdPair adPair = new AdPair();
            adPair.setPlanId(FormalTestManager.currentTestPlan.getId());
            adPair.setDevMonitorId(key);
            adPair.setStdDevMonitorId(FormalTestManager.pairsIdMap.get(key));
            adPair.setNum(FormalTestManager.numMap.get(key));
            adPairList.add(adPair);
        }
        adPairService.saveBatch(adPairList);
    }

    /**
     * 发送录波指令
     *
     * @param s
     */
    private void sendRecordWave(String s) {
        SocketMsg<String> socketMsg = new SocketMsg<>();
        socketMsg.setRequestId(SourceOperateCodeEnum.RECORD_WAVE_STEP1.getValue());
        socketMsg.setOperateCode(SourceOperateCodeEnum.RDRE$01.getValue());
        Map<String, List<WaveCommandDTO>> map = new HashMap<>(1);

        List<WaveCommandDTO> waveCommandDTOList = new ArrayList<>();
        FormalTestManager.devList.forEach(preDetection -> {
            preDetection.getMonitorList().forEach(monitorListDTO -> {
                WaveCommandDTO waveCommandDTO = new WaveCommandDTO();
                waveCommandDTO.setIp(preDetection.getDevIP());
                waveCommandDTO.setPort(preDetection.getPort());
                waveCommandDTO.setOper(preDetection.getWaveCmd());
//                waveCommandDTO.setOper("RDRE1$CO$RcdTrg$Oper");
                waveCommandDTO.setLine(monitorListDTO.getLine());
                waveCommandDTOList.add(waveCommandDTO);
            });
        });
        FormalTestManager.standardDevList.forEach(preDetection -> {
            preDetection.getMonitorList().forEach(monitorListDTO -> {
                WaveCommandDTO waveCommandDTO = new WaveCommandDTO();
                waveCommandDTO.setIp(preDetection.getDevIP());
                waveCommandDTO.setPort(preDetection.getPort());
                waveCommandDTO.setOper(preDetection.getWaveCmd());
//                waveCommandDTO.setOper("RDRE1$CO$RcdTrg$Oper");
                waveCommandDTO.setLine(monitorListDTO.getLine());
                waveCommandDTOList.add(waveCommandDTO);
            });
        });

        map.put("opercommands", waveCommandDTOList);
        socketMsg.setData(JSON.toJSONString(map));
        SocketManager.sendMsg(s, JSON.toJSONString(socketMsg));
    }

    private void sendModelDeal(String s, List<String> allDataType) {
        SocketMsg<String> socketMsg = new SocketMsg<>();
        socketMsg.setRequestId(SourceOperateCodeEnum.FORMAL_REAL.getValue());
        socketMsg.setOperateCode(this.getRequestOperateCode().getValue());
        DevPhaseSequenceParam phaseSequenceParam = new DevPhaseSequenceParam();
        phaseSequenceParam.setMoniterIdList(Arrays.asList(FormalTestManager.monitorMap.keySet().toArray(new String[FormalTestManager.monitorMap.size()])));
        phaseSequenceParam.setDataType(allDataType);
        phaseSequenceParam.setReadCount(1);
        phaseSequenceParam.setIgnoreCount(1); // 刚一开始实时数据申请后，第一组数据为空数据，忽略掉
        socketMsg.setData(JSON.toJSONString(phaseSequenceParam));

        FormalTestManager.currentStep = SourceOperateCodeEnum.YJC_MXYZXJY;
        SocketManager.sendMsg(s, JSON.toJSONString(socketMsg));

        // 开始计时
        this.resetTimer();
    }

    private void sendAlignData(String s, SourceOperateCodeEnum requestOperateCode) {
        SocketMsg<String> socketMsg = new SocketMsg<>();
        socketMsg.setRequestId(SourceOperateCodeEnum.FORMAL_REAL.getValue());
        socketMsg.setOperateCode(requestOperateCode.getValue());
        DetectionCodeEnum prefixEnum = this.getPrefixEnum();
        DevPhaseSequenceParam phaseSequenceParam = new DevPhaseSequenceParam();
        phaseSequenceParam.setMoniterIdList(Arrays.asList(FormalTestManager.monitorMap.keySet().toArray(new String[FormalTestManager.monitorMap.size()])));
        phaseSequenceParam.setDataType(Arrays.asList(prefixEnum.getCode() + DetectionCodeEnum.VRMS.getCode(), prefixEnum.getCode() + DetectionCodeEnum.PVRMS.getCode()));

        int targetCount = 5;
        if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
            if (FormalTestManager.nonWaveDataSourceEnum != DataSourceEnum.REAL_DATA) {
                targetCount = 2;
            }
        }
        phaseSequenceParam.setReadCount(this.getReadCount(targetCount));
        phaseSequenceParam.setIgnoreCount(0);
        socketMsg.setData(JSON.toJSONString(phaseSequenceParam));
        SocketManager.sendMsg(s, JSON.toJSONString(socketMsg));
    }

    /**
     * 获取初始化operateCode
     *
     * @return
     */
    private SourceOperateCodeEnum getInitOperateCode() {
        if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
            if (FormalTestManager.nonWaveDataSourceEnum == DataSourceEnum.REAL_DATA) {
                return SourceOperateCodeEnum.DEV_INIT_GATHER_02;
            } else {
                return SourceOperateCodeEnum.DEV_INIT_GATHER_01;
            }
        } else {
            if (FormalTestManager.isWaveCheck) {
                return SourceOperateCodeEnum.DEV_INIT_GATHER_03;
            }
        }
        return null;
    }

    /**
     * 获取申请operateCode
     *
     * @return
     */
    private SourceOperateCodeEnum getRequestOperateCode() {
        if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
            if (FormalTestManager.nonWaveDataSourceEnum == DataSourceEnum.REAL_DATA) {
                return SourceOperateCodeEnum.DEV_DATA_REQUEST_02;
            } else {
                return SourceOperateCodeEnum.DEV_DATA_REQUEST_01;
            }
        } else {
            if (FormalTestManager.isWaveCheck) {
                return SourceOperateCodeEnum.DEV_DATA_REQUEST_02;
            }
        }
        return null;
    }

    /**
     * 获取退出operateCode
     *
     * @return
     */
    private SourceOperateCodeEnum getQuitOperateCode() {
        if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
            if (FormalTestManager.nonWaveDataSourceEnum == DataSourceEnum.REAL_DATA) {
                return SourceOperateCodeEnum.QUIT_INIT_02;
            } else {
                return SourceOperateCodeEnum.QUIT_INIT_01;
            }
        } else {
            if (FormalTestManager.isWaveCheck) {
                return SourceOperateCodeEnum.QUIT_INIT_02;
            }
        }
        return null;
    }

    /**
     * 重置超时时间
     */
    private void resetTimer() {
        if (ObjectUtil.isNotNull(FormalTestManager.nonWaveDataSourceEnum)) {
            SocketManager.contrastClockMap.put(FormalTestManager.nonWaveDataSourceEnum, 0L);
        }
    }

    private void sendXu(String s) {
        SocketMsg<String> socketMsg = new SocketMsg<>();
        socketMsg.setRequestId(SourceOperateCodeEnum.FORMAL_REAL.getValue());
        socketMsg.setOperateCode(this.getRequestOperateCode().getValue());
        DevPhaseSequenceParam phaseSequenceParam = new DevPhaseSequenceParam();
        phaseSequenceParam.setMoniterIdList(Arrays.asList(FormalTestManager.monitorMap.keySet().toArray(new String[FormalTestManager.monitorMap.size()])));
        DetectionCodeEnum prefixEnum = this.getPrefixEnum();
        phaseSequenceParam.setDataType(Arrays.asList(
                prefixEnum.getCode() + DetectionCodeEnum.VRMS.getCode(),
                prefixEnum.getCode() + DetectionCodeEnum.PVRMS.getCode(),
                prefixEnum.getCode() + DetectionCodeEnum.VA.getCode(),
                prefixEnum.getCode() + DetectionCodeEnum.IA.getCode(),
                prefixEnum.getCode() + DetectionCodeEnum.U1A.getCode(),
                prefixEnum.getCode() + DetectionCodeEnum.PU1A.getCode(),
                prefixEnum.getCode() + DetectionCodeEnum.I1A.getCode(),
                prefixEnum.getCode() + DetectionCodeEnum.IRMS.getCode(),
                prefixEnum.getCode() + DetectionCodeEnum.V_UNBAN.getCode(),
                prefixEnum.getCode() + DetectionCodeEnum.I_UNBAN.getCode()));
        phaseSequenceParam.setReadCount(this.getReadCount(1));
        phaseSequenceParam.setIgnoreCount(0);
        socketMsg.setData(JSON.toJSONString(phaseSequenceParam));
        SocketManager.sendMsg(s, JSON.toJSONString(socketMsg));
    }

    private List<List<DevData>> analyzeWaveFile(WaveResultDTO devWaveResultDTO, WaveResultDTO stdDevWaveResultDTO, PreDetection.MonitorListDTO
            monitorListDTO, String devMonitorId, String stdDevMonitorId, List<String> adTypeCodeList) {
        String stdDevCfgPath = stdDevWaveResultDTO.getPath().replaceAll("\\\\", "/").replace(".CFG", ".cfg");
        String devCfgPath = devWaveResultDTO.getPath().replaceAll("\\\\", "/").replace(".CFG", ".cfg");

//        String stdDevCfgPath = "D:\\数据比对\\统计数据1\\B码\\216\\PQMonitor_PQM1_000001_20200430_113404_845.cfg";
        String stdDevDatPath = stdDevCfgPath.replaceAll(".cfg", ".dat");
//        String devCfgPath = "D:\\数据比对\\统计数据1\\B码\\217\\PQMonitor_PQM1_000001_20200430_113407_075.cfg";
        String devDatPath = devCfgPath.replaceAll(".cfg", ".dat");

        // 验证文件是否存在
        DetectionUtil.checkFileExists(stdDevCfgPath, "源CFG文件");
        DetectionUtil.checkFileExists(stdDevDatPath, "源DAT文件");
        DetectionUtil.checkFileExists(devCfgPath, "目标CFG文件");
        DetectionUtil.checkFileExists(devDatPath, "目标DAT文件");

        boolean isStar = DetectionCodeEnum.STAR.getCode().equals(monitorListDTO.getConnection());
        boolean isDelta = DetectionCodeEnum.DELTA.getCode().equals(monitorListDTO.getConnection());

        // 读取本地文件并创建输入流
        try (InputStream sourceCfgStream = new FileInputStream(stdDevCfgPath);
             InputStream sourceDatStream = new FileInputStream(stdDevDatPath);
             InputStream targetCfgStream = new FileInputStream(devCfgPath);
             InputStream targetDatStream = new FileInputStream(devDatPath)) {

            CompareWaveDTO compareWaveDTO = compareWaveService.analyzeWithSegmentPreservation(
                    sourceCfgStream,
                    sourceDatStream,
                    targetCfgStream,
                    targetDatStream,
                    isStar ? 0 : isDelta ? 1 : 2);
            if (ObjectUtil.isNotNull(compareWaveDTO) && ObjectUtil.isNotNull(compareWaveDTO.getSourceResults()) && ObjectUtil.isNotNull(compareWaveDTO.getTargetResults())) {
//                DetectionCodeEnum prefixEnum = this.getPrefixEnum();
//                adTypeCodeList = Arrays.asList(prefixEnum.getCode() + DetectionCodeEnum.VRMS.getCode(),
//                        prefixEnum.getCode() + DetectionCodeEnum.PVRMS.getCode(),
//                        prefixEnum.getCode() + DetectionCodeEnum.IRMS.getCode(),
//                        prefixEnum.getCode() + DetectionCodeEnum.V_UNBAN.getCode(),
//                        prefixEnum.getCode() + DetectionCodeEnum.I_UNBAN.getCode(),
//                        prefixEnum.getCode() + DetectionCodeEnum.V2_50.getCode(),
//                        prefixEnum.getCode() + DetectionCodeEnum.P2_50.getCode(),
//                        prefixEnum.getCode() + DetectionCodeEnum.PV2_50.getCode(),
//                        prefixEnum.getCode() + DetectionCodeEnum.SV_1_49.getCode(),
//                        prefixEnum.getCode() + DetectionCodeEnum.SI_1_49.getCode(),
//                        prefixEnum.getCode() + DetectionCodeEnum.I2_50.getCode());
                return this.getDevData(compareWaveDTO.getSourceResults(), compareWaveDTO.getTargetResults(), devMonitorId, stdDevMonitorId, adTypeCodeList);
            } else {
                return null;
            }
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 根据解析波形文件后的数据转换成可以进行入库、误差计算的DevData对象
     *
     * @param sourceDataList 被检设备数据
     * @param targetDataList 标准设备数据
     * @return 下标为0的是被检设备数据，下标为1的是标准设备数据
     */
    private List<List<DevData>> getDevData(List<PqsDataStruct> sourceDataList, List<PqsDataStruct> targetDataList, String devMonitorId, String
            stdDevMonitorId, List<String> adTypeCodeList) {
        List<List<DevData>> result = new ArrayList<>();
        List<DevData> devDataList = new ArrayList<>();
        List<DevData> stdDevDataList = new ArrayList<>();
        int dataPoints = Math.min(sourceDataList.size(), targetDataList.size());
        for (int i = 0; i < dataPoints; i++) {
            devDataList.add(getSinglePointDevData(targetDataList.get(i), devMonitorId, adTypeCodeList));
            stdDevDataList.add(getSinglePointDevData(sourceDataList.get(i), stdDevMonitorId, adTypeCodeList));
        }
        result.add(devDataList);
        result.add(stdDevDataList);
        return result;
    }

    /**
     * 获取单个窗口的原始数据
     *
     * @param pointDevData
     * @param monitorId
     * @param adTypeCodeList
     * @return
     */
    private DevData getSinglePointDevData(PqsDataStruct pointDevData, String monitorId, List<String> adTypeCodeList) {
        DevData devData = new DevData();
        devData.setId(monitorId);
        devData.setTime(pointDevData.getClocktime().format());
        List<DevData.SqlDataDTO> sqlDataDTOS = new ArrayList<>();
        List<DevData.SqlDataHarmDTO> sqlDataHarmDTOS = new ArrayList<>();

        DevData.SqlDataDTO sqlDataDTO = null;
        DevData.SqlDataDTO.ListDTO listDTO = null;

        DevData.SqlDataHarmDTO sqlDataHarmDTOV = null;
        DevData.SqlDataHarmDTO.ListDTO listDTOHarmV = null;

        Double u1A = null;
        Double u1B = null;
        Double u1C = null;

        List<String> aListV = null;
        List<String> bListV = null;
        List<String> cListV = null;
        List<String> aListI = null;
        List<String> bListI = null;
        List<String> cListI = null;

        for (String adTypeCode : adTypeCodeList) {
            String code = adTypeCode.replace(this.getPrefixEnum().getCode(), "");
            DetectionCodeEnum detectionCodeEnum = DetectionCodeEnum.getDetectionCodeByCode(code);
            switch (detectionCodeEnum) {
//                case FREQ:
//                    // 频率
//                    sqlDataDTO = new DevData.SqlDataDTO();
//                    sqlDataDTO.setDesc(DetectionCodeEnum.FREQ.getCode());
//                    sqlDataDTO.setType("real");
//                    listDTO = new DevData.SqlDataDTO.ListDTO();
//                    listDTO.setT((double) pointDevData.getFreq()[0]);
//                    sqlDataDTO.setList(listDTO);
//                    sqlDataDTOS.add(sqlDataDTO);
//                    break;
                case VRMS:
                    // 相电压有效值
                    sqlDataDTO = new DevData.SqlDataDTO();
                    sqlDataDTO.setDesc(DetectionCodeEnum.VRMS.getCode());
                    sqlDataDTO.setType("wave");
                    listDTO = new DevData.SqlDataDTO.ListDTO();
                    listDTO.setA((double) pointDevData.getRms()[0]);
                    listDTO.setB((double) pointDevData.getRms()[1]);
                    listDTO.setC((double) pointDevData.getRms()[2]);
                    sqlDataDTO.setList(listDTO);
                    sqlDataDTOS.add(sqlDataDTO);
                    break;
                case PVRMS:
                    // 线电压有效值
                    sqlDataDTO = new DevData.SqlDataDTO();
                    sqlDataDTO.setDesc(DetectionCodeEnum.PVRMS.getCode());
                    sqlDataDTO.setType("wave");
                    listDTO = new DevData.SqlDataDTO.ListDTO();
                    listDTO.setA((double) pointDevData.getRms()[6]);
                    listDTO.setB((double) pointDevData.getRms()[7]);
                    listDTO.setC((double) pointDevData.getRms()[8]);
                    sqlDataDTO.setList(listDTO);
                    sqlDataDTOS.add(sqlDataDTO);
                    break;
                case IRMS:
                    // 相电流有效值
                    sqlDataDTO = new DevData.SqlDataDTO();
                    sqlDataDTO.setDesc(DetectionCodeEnum.IRMS.getCode());
                    sqlDataDTO.setType("wave");
                    listDTO = new DevData.SqlDataDTO.ListDTO();
                    listDTO.setA((double) pointDevData.getRms()[3]);
                    listDTO.setB((double) pointDevData.getRms()[4]);
                    listDTO.setC((double) pointDevData.getRms()[5]);
                    sqlDataDTO.setList(listDTO);
                    sqlDataDTOS.add(sqlDataDTO);
                    break;
                case V_UNBAN:
                    // 三项电压不平衡度
                    sqlDataDTO = new DevData.SqlDataDTO();
                    sqlDataDTO.setDesc(DetectionCodeEnum.V_UNBAN.getCode());
                    sqlDataDTO.setType("wave");
                    listDTO = new DevData.SqlDataDTO.ListDTO();
                    listDTO.setB((double) pointDevData.getUiSeq()[0][4]);
                    sqlDataDTO.setList(listDTO);
                    sqlDataDTOS.add(sqlDataDTO);
                    break;
                case I_UNBAN:
                    // 三项电流不平衡度
                    sqlDataDTO = new DevData.SqlDataDTO();
                    sqlDataDTO.setDesc(DetectionCodeEnum.I_UNBAN.getCode());
                    sqlDataDTO.setType("wave");
                    listDTO = new DevData.SqlDataDTO.ListDTO();
                    listDTO.setB((double) pointDevData.getUiSeq()[1][4]);
                    sqlDataDTO.setList(listDTO);
                    sqlDataDTOS.add(sqlDataDTO);
                    break;
                case V2_50:
                    // 谐波电压含有率
                    sqlDataDTO = new DevData.SqlDataDTO();
                    sqlDataDTO.setDesc(DetectionCodeEnum.U1.getCode());
                    sqlDataDTO.setType("wave");
                    listDTO = new DevData.SqlDataDTO.ListDTO();
                    u1A = (double) pointDevData.getFuHarm()[0][0];
                    u1B = (double) pointDevData.getFuHarm()[1][0];
                    u1C = (double) pointDevData.getFuHarm()[2][0];
                    listDTO.setA(u1A);
                    listDTO.setB(u1B);
                    listDTO.setC(u1C);
                    sqlDataDTO.setList(listDTO);
                    sqlDataDTOS.add(sqlDataDTO);

                    sqlDataHarmDTOV = new DevData.SqlDataHarmDTO();
                    sqlDataHarmDTOV.setDesc(DetectionCodeEnum.V2_50.getCode());
                    sqlDataHarmDTOV.setType("wave");
                    listDTOHarmV = new DevData.SqlDataHarmDTO.ListDTO();

                    aListV = new ArrayList<>();
                    bListV = new ArrayList<>();
                    cListV = new ArrayList<>();
                    // 前50次谐波
                    for (int harm = 1; harm < 50; harm++) {
                        // 谐波电压
                        aListV.add(String.format("%.7f", pointDevData.getFuHarmCON()[0][harm]));
                        bListV.add(String.format("%.7f", pointDevData.getFuHarmCON()[1][harm]));
                        cListV.add(String.format("%.7f", pointDevData.getFuHarmCON()[2][harm]));
                    }
                    listDTOHarmV.setA(aListV);
                    listDTOHarmV.setB(bListV);
                    listDTOHarmV.setC(cListV);

                    sqlDataHarmDTOV.setList(listDTOHarmV);
                    sqlDataHarmDTOS.add(sqlDataHarmDTOV);
                case PV2_50:
                    break;
                case I2_50:
                    // 谐波电流幅值
                    sqlDataDTO = new DevData.SqlDataDTO();
                    sqlDataDTO.setDesc(DetectionCodeEnum.I1.getCode());
                    sqlDataDTO.setType("wave");
                    listDTO = new DevData.SqlDataDTO.ListDTO();
                    listDTO.setA((double) pointDevData.getInHarm()[3][0]);
                    listDTO.setB((double) pointDevData.getInHarm()[4][0]);
                    listDTO.setC((double) pointDevData.getInHarm()[5][0]);
                    sqlDataDTO.setList(listDTO);
                    sqlDataDTOS.add(sqlDataDTO);

                    DevData.SqlDataHarmDTO sqlDataHarmDTOI = new DevData.SqlDataHarmDTO();
                    sqlDataHarmDTOI.setDesc(DetectionCodeEnum.I2_50.getCode());
                    sqlDataHarmDTOI.setType("wave");
                    DevData.SqlDataHarmDTO.ListDTO listDTOHarmI = new DevData.SqlDataHarmDTO.ListDTO();

                    aListI = new ArrayList<>();
                    bListI = new ArrayList<>();
                    cListI = new ArrayList<>();

                    // 前50次谐波
                    for (int harm = 1; harm < 50; harm++) {
                        // 谐波电流
                        aListI.add(String.format("%.7f", pointDevData.getFuHarm()[3][harm]));
                        bListI.add(String.format("%.7f", pointDevData.getFuHarm()[4][harm]));
                        cListI.add(String.format("%.7f", pointDevData.getFuHarm()[5][harm]));
                    }
                    listDTOHarmI.setA(aListI);
                    listDTOHarmI.setB(bListI);
                    listDTOHarmI.setC(cListI);

                    sqlDataHarmDTOI.setList(listDTOHarmI);
                    sqlDataHarmDTOS.add(sqlDataHarmDTOI);
                    break;
                case P2_50:
                    // 谐波有功功率
//                    DevData.SqlDataHarmDTO sqlDataHarmDTOP2_50 = new DevData.SqlDataHarmDTO();
//                    sqlDataHarmDTOP2_50.setDesc(DetectionCodeEnum.P2_50.getCode());
//                    sqlDataHarmDTOP2_50.setType("real");
//                    listDTOHarmV = new DevData.SqlDataHarmDTO.ListDTO();
//
//                    List<String> aListP2_50 = new ArrayList<>();
//                    List<String> bListP2_50 = new ArrayList<>();
//                    List<String> cListP2_50 = new ArrayList<>();
//                    for (int harm = 0; harm < 50; harm++) {
//                        aListP2_50.add(String.format("%.7f", pointDevData.getHarmP()[0][harm]));
//                        bListP2_50.add(String.format("%.7f", pointDevData.getHarmP()[1][harm]));
//                        cListP2_50.add(String.format("%.7f", pointDevData.getHarmP()[2][harm]));
//                    }
//                    listDTOHarmV.setA(aListP2_50);
//                    listDTOHarmV.setB(bListP2_50);
//                    listDTOHarmV.setC(cListP2_50);
//                    sqlDataHarmDTOP2_50.setList(listDTOHarmV);
//                    sqlDataHarmDTOS.add(sqlDataHarmDTOP2_50);
                    break;
                case SV_1_49:
                    // 间谐波电压含有率
                    sqlDataDTO = new DevData.SqlDataDTO();
                    sqlDataDTO.setDesc(DetectionCodeEnum.U1.getCode());
                    sqlDataDTO.setType("wave");
                    listDTO = new DevData.SqlDataDTO.ListDTO();
                    u1A = (double) pointDevData.getFuHarm()[0][0];
                    u1B = (double) pointDevData.getFuHarm()[1][0];
                    u1C = (double) pointDevData.getFuHarm()[2][0];
                    listDTO.setA(u1A);
                    listDTO.setB(u1B);
                    listDTO.setC(u1C);
                    sqlDataDTO.setList(listDTO);
                    sqlDataDTOS.add(sqlDataDTO);

                    sqlDataHarmDTOV = new DevData.SqlDataHarmDTO();
                    sqlDataHarmDTOV.setDesc(DetectionCodeEnum.SV_1_49.getCode());
                    sqlDataHarmDTOV.setType("wave");
                    listDTOHarmV = new DevData.SqlDataHarmDTO.ListDTO();

                    aListV = new ArrayList<>();
                    bListV = new ArrayList<>();
                    cListV = new ArrayList<>();
                    // 前50次间谐波
                    for (int harm = 0; harm < 50; harm++) {
                        // 间谐波电压
                        aListV.add(String.format("%.7f", pointDevData.getInHarmCON()[0][harm]));
                        bListV.add(String.format("%.7f", pointDevData.getInHarmCON()[1][harm]));
                        cListV.add(String.format("%.7f", pointDevData.getInHarmCON()[2][harm]));
                    }
                    listDTOHarmV.setA(aListV);
                    listDTOHarmV.setB(bListV);
                    listDTOHarmV.setC(cListV);

                    sqlDataHarmDTOV.setList(listDTOHarmV);
                    sqlDataHarmDTOS.add(sqlDataHarmDTOV);
                case PSV_1_49:
                    break;
                case SI_1_49:
                    sqlDataDTO = new DevData.SqlDataDTO();
                    sqlDataDTO.setDesc(DetectionCodeEnum.I1.getCode());
                    sqlDataDTO.setType("wave");
                    listDTO = new DevData.SqlDataDTO.ListDTO();
                    listDTO.setA((double) pointDevData.getInHarm()[3][0]);
                    listDTO.setB((double) pointDevData.getInHarm()[4][0]);
                    listDTO.setC((double) pointDevData.getInHarm()[5][0]);
                    sqlDataDTO.setList(listDTO);
                    sqlDataDTOS.add(sqlDataDTO);

                    // 间谐波电流幅值
                    sqlDataHarmDTOI = new DevData.SqlDataHarmDTO();
                    sqlDataHarmDTOI.setDesc(DetectionCodeEnum.SI_1_49.getCode());
                    sqlDataHarmDTOI.setType("wave");
                    listDTOHarmI = new DevData.SqlDataHarmDTO.ListDTO();

                    aListI = new ArrayList<>();
                    bListI = new ArrayList<>();
                    cListI = new ArrayList<>();

                    // 前50次间谐波
                    for (int harm = 1; harm < 51; harm++) {
                        // 间谐波电流
                        aListI.add(String.format("%.7f", pointDevData.getInHarm()[3][harm]));
                        bListI.add(String.format("%.7f", pointDevData.getInHarm()[4][harm]));
                        cListI.add(String.format("%.7f", pointDevData.getInHarm()[5][harm]));
                    }
                    listDTOHarmI.setA(aListI);
                    listDTOHarmI.setB(bListI);
                    listDTOHarmI.setC(cListI);

                    sqlDataHarmDTOI.setList(listDTOHarmI);
                    sqlDataHarmDTOS.add(sqlDataHarmDTOI);
                    break;
                case UNKNOWN_ERROR:
                    break;
            }
        }

        devData.setSqlData(sqlDataDTOS);
        devData.setSqlDataHarm(sqlDataHarmDTOS);
        return devData;
    }

    /**
     * 修改通道系数
     *
     * @param f
     */
    private void updateGfList(DevXiNumData.F f, DetectionServiceImpl.VAndIResult vAndIResult, String stdDevMonitorId, int maxNum) {
        DevXiNumData.F originF = BeanUtil.copyProperties(f, DevXiNumData.F.class);
        if (maxNum != 0) {
            PqStandardDevGain pqStandardDevGain = pqStandardDevGainService.get(stdDevMonitorId);
            originF.setUa_gain(pqStandardDevGain.getUaGain());
            originF.setUb_gain(pqStandardDevGain.getUbGain());
            originF.setUc_gain(pqStandardDevGain.getUcGain());
            originF.setU0_gain(pqStandardDevGain.getU0Gain());
            originF.setIa_gain(pqStandardDevGain.getIaGain());
            originF.setIb_gain(pqStandardDevGain.getIbGain());
            originF.setIc_gain(pqStandardDevGain.getIcGain());
            originF.setI0_gain(pqStandardDevGain.getI0Gain());
            originF.setUab_gain(pqStandardDevGain.getUabGain());
            originF.setUbc_gain(pqStandardDevGain.getUbcGain());
            originF.setUca_gain(pqStandardDevGain.getUcaGain());
        }

        if (vAndIResult.getVa() && NumberUtil.isIn(BigDecimal.valueOf(vAndIResult.getVaXi() * 10000), BigDecimal.valueOf(originF.getUa_gain() * 0.95), BigDecimal.valueOf(originF.getUa_gain() * 1.05))) {
            f.setUa_gain(BigDecimal.valueOf(f.getUa_gain()).multiply(BigDecimal.valueOf(vAndIResult.getVaXi())).setScale(0, RoundingMode.HALF_UP).intValue());
        }
        if (vAndIResult.getVb() && NumberUtil.isIn(BigDecimal.valueOf(vAndIResult.getVbXi() * 10000), BigDecimal.valueOf(originF.getUb_gain() * 0.95), BigDecimal.valueOf(originF.getUb_gain() * 1.05))) {
            f.setUb_gain(BigDecimal.valueOf(f.getUb_gain()).multiply(BigDecimal.valueOf(vAndIResult.getVbXi())).setScale(0, RoundingMode.HALF_UP).intValue());
        }
        if (vAndIResult.getVc() && NumberUtil.isIn(BigDecimal.valueOf(vAndIResult.getVcXi() * 10000), BigDecimal.valueOf(originF.getUc_gain() * 0.95), BigDecimal.valueOf(originF.getUc_gain() * 1.05))) {
            f.setUc_gain(BigDecimal.valueOf(f.getUc_gain()).multiply(BigDecimal.valueOf(vAndIResult.getVcXi())).setScale(0, RoundingMode.HALF_UP).intValue());
        }
        if (vAndIResult.getIa() && NumberUtil.isIn(BigDecimal.valueOf(vAndIResult.getIaXi() * 10000), BigDecimal.valueOf(originF.getIa_gain() * 0.95), BigDecimal.valueOf(originF.getIa_gain() * 1.05))) {
            f.setIa_gain(BigDecimal.valueOf(f.getIa_gain()).multiply(BigDecimal.valueOf(vAndIResult.getIaXi())).setScale(0, RoundingMode.HALF_UP).intValue());
        }
        if (vAndIResult.getIb() && NumberUtil.isIn(BigDecimal.valueOf(vAndIResult.getIbXi() * 10000), BigDecimal.valueOf(originF.getIb_gain() * 0.95), BigDecimal.valueOf(originF.getIb_gain() * 1.05))) {
            f.setIb_gain(BigDecimal.valueOf(f.getIb_gain()).multiply(BigDecimal.valueOf(vAndIResult.getIbXi())).setScale(0, RoundingMode.HALF_UP).intValue());
        }
        if (vAndIResult.getIc() && NumberUtil.isIn(BigDecimal.valueOf(vAndIResult.getIcXi() * 10000), BigDecimal.valueOf(originF.getIc_gain() * 0.95), BigDecimal.valueOf(originF.getIc_gain() * 1.05))) {
            f.setIc_gain(BigDecimal.valueOf(f.getIc_gain()).multiply(BigDecimal.valueOf(vAndIResult.getIcXi())).setScale(0, RoundingMode.HALF_UP).intValue());
        }
    }
}
