package org.jeecg.modules.dynamicStaticAnalysis.algorithm;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.checkData.entity.*;
import org.jeecg.modules.checkData.service.*;
import org.jeecg.modules.dynamicStaticAnalysis.entity.*;
import org.jeecg.modules.dynamicStaticAnalysis.mapper.AnalysisAlgorithmMapper;
import org.jeecg.modules.dynamicStaticAnalysis.service.*;
import org.jeecg.modules.dynamicStaticAnalysis.util.StrUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 分析算法
 */
@Service
@Slf4j
public class AnalysisAlgorithm {
    @Resource
    private AnalysisAlgorithmMapper analysisAlgorithmMapper;
    @Resource
    private IAnalysisBatchService analysisBatchService;
    @Resource
    private IAnalysisBatchCheckDataMapService analysisBatchCheckDataMapService;
    @Resource
    private IMovementCourseInfoService movementCourseInfoService;
    @Resource
    private IMovementCourseService movementCourseService;
    @Resource
    private IRailInspectionEquipmentItemService railInspectionEquipmentItemService;
    @Resource
    private IRailInspectionEquipmentItemDetailService railInspectionEquipmentItemDetailService;
    @Resource
    private IAnalysisBatchUnitDeviceService analysisBatchUnitDeviceService;
    @Resource
    private IAnalysisBatchUnitDeviceTransfiniteService analysisBatchUnitDeviceTransfiniteService;
    @Resource
    private IAnalysisBatchUnitDevicePointScoreService analysisBatchUnitDevicePointScoreService;
    @Resource
    private IConfigLabourCheckService configLabourCheckService;
    @Resource
    private IConfigRailDeviceCheckService configRailDeviceCheckService;
    @Resource
    private IMovementOverReportService movementOverReportService;
    @Resource
    private IConfigGradeLimitService configGradeLimitService;
    @Resource
    private IMovementTqiReportService movementTqiReportService;
    @Resource
    private IMovementAdditiveInfoService movementAdditiveInfoService;
    @Resource
    private IMovementOverReportUnitDeviceMapService movementOverReportUnitDeviceMapService;

    @Resource
    private IMovementCheckDataUnitDeviceMapService movementCheckDataUnitDeviceMapService;

    @Resource
    private IConfigRailVehicleTqiService configRailVehicleTqlService;

    @Resource
    private IConfigRailVehicleCheckService configRailVehicleCheckService;

    @Resource
    private IConfigInstrumentCheckService configInstrumentCheckService;

    @Resource
    private IMovementTqiReportUnitDeviceMapService movementTqiReportUnitDeviceMapService;

    @Resource
    private IAnalysisBatchUnitDeviceTqiScoreService analysisBatchUnitDeviceTqiScoreService;

    @Resource
    private IMovementAdditiveInfoUnitDeviceMapService movementAdditiveInfoUnitDeviceMapService;

    @Resource
    private IAnalysisLabourCheckDataUnitDeviceMapService analysisLabourCheckDataUnitDeviceMapService;

    @Resource
    private IAnalysisRailDeviceCheckDataUnitDeviceMapService analysisRailDeviceCheckDataUnitDeviceMapService;

    @Resource
    private IAnalysisAdditiveCheckUnitDeviceMapService analysisAdditiveCheckUnitDeviceMapService;

    @Resource
    private IAnalysisOverReportCheckUnitDeviceMapService analysisOverReportCheckUnitDeviceMapService;

    @Resource
    private IAnalysisTqiReportCheckUnitDeviceMapService analysisTqiReportCheckUnitDeviceMapService;

    @Resource
    private IConfigTqiLimitService configTqiLimitService;

    @Transactional
    public void analysis(String analysisBatchId) {
        Map<String, Map<String, Object>> unitDeviceTable = new LinkedHashMap<>();

        // 1.1 获取分析基础数据
        AnalysisBatch analysisBatch = analysisBatchService.getById(analysisBatchId);
        List<AnalysisBatchCheckDataMap> analysisBatchCheckDataMapList = analysisBatchCheckDataMapService.lambdaQuery().eq(AnalysisBatchCheckDataMap::getAnalysisBatchId, analysisBatchId).list();


        // 1.2 按公里数正序排序所有1-钢轨,2-曲线,3-竖曲线,4-道岔
        List<Map<String, Object>> unitDeviceList = analysisAlgorithmMapper.getUnitDevice(analysisBatch.getLightRailId(), analysisBatch.getLineAliasId(), analysisBatch.getStartingMileage(), analysisBatch.getEndMileage());


        // 1.3 关联关系
        for (Map<String, Object> unitDevice : unitDeviceList) {
            unitDeviceTable.put(unitDevice.get("unitCode").toString(), unitDevice);
        }


        // 1.4 循环分析检查项目
        for (AnalysisBatchCheckDataMap checkDataMap : analysisBatchCheckDataMapList) {
            // 检查数据类型 1-人工静态检查 2-轨检仪静态检查 3-轨检车检查 4-添乘仪检查
            if (1 == checkDataMap.getEkType()) {

                labourCheckDataAnalysis(analysisBatch, checkDataMap, unitDeviceList);

            } else if (2 == checkDataMap.getEkType()) {

                railDeviceCheckDataAnalysis(analysisBatch, checkDataMap, unitDeviceList);

            } else if (3 == checkDataMap.getEkType()) {

                railVehicleCheckDataAnalysis(analysisBatch, checkDataMap, unitDeviceList);

            } else {

                addInstrumentAnalysis(analysisBatch, checkDataMap, unitDeviceList);
            }
        }

        // 3.保存算法结果
        if (ObjectUtil.isNotEmpty(unitDeviceTable)) {

            // 删除超限
            analysisBatchUnitDeviceTransfiniteService.lambdaUpdate().eq(AnalysisBatchUnitDeviceTransfinite::getAnalysisBatchId, analysisBatch.getId()).remove();
            // 删除得分
            analysisBatchUnitDevicePointScoreService.lambdaUpdate().eq(AnalysisBatchUnitDevicePointScore::getAnalysisBatchId, analysisBatch.getId()).remove();
            // 删除分析关联设备id
            analysisBatchUnitDeviceService.lambdaUpdate().eq(AnalysisBatchUnitDevice::getAnalysisBatchId, analysisBatchId).remove();
            // 删除轨检车tqi得分
            analysisBatchUnitDeviceTqiScoreService.lambdaUpdate().eq(AnalysisBatchUnitDeviceTqiScore::getAnalysisBatchId, analysisBatch.getId()).remove();

            // 删除关联关系
            analysisLabourCheckDataUnitDeviceMapService.lambdaUpdate()
                    .eq(AnalysisLabourCheckDataUnitDeviceMap::getAnalysisBatchId, analysisBatchId)
                    .remove();
            analysisRailDeviceCheckDataUnitDeviceMapService.lambdaUpdate()
                    .eq(AnalysisRailDeviceCheckDataUnitDeviceMap::getAnalysisBatchId, analysisBatchId)
                    .remove();
            analysisAdditiveCheckUnitDeviceMapService.lambdaUpdate()
                    .eq(AnalysisAdditiveCheckUnitDeviceMap::getAnalysisBatchId, analysisBatchId)
                    .remove();
            analysisOverReportCheckUnitDeviceMapService.lambdaUpdate()
                    .eq(AnalysisOverReportCheckUnitDeviceMap::getAnalysisBatchId, analysisBatchId)
                    .remove();
            analysisTqiReportCheckUnitDeviceMapService.lambdaUpdate()
                    .eq(AnalysisTqiReportCheckUnitDeviceMap::getAnalysisBatchId, analysisBatchId)
                    .remove();


            // 3.1 保存分析批次-单元设备
            List<ConfigGradeLimit> configGradeLimitList = configGradeLimitService.lambdaQuery().eq(ConfigGradeLimit::getSpeedMax, analysisBatch.getSpeedMax()).eq(ConfigGradeLimit::getSpeedMin, analysisBatch.getSpeedMin()).eq(ConfigGradeLimit::getDelFlag, '0').list();

            List<AnalysisBatchUnitDevice> analysisBatchUnitDevices = new ArrayList<>();
            List<AnalysisBatchUnitDeviceTransfinite> transfiniteList = new ArrayList<>();
            List<AnalysisBatchUnitDevicePointScore> scoreList = new ArrayList<>();
            List<AnalysisBatchUnitDeviceTqiScore> tqiScoreList = new ArrayList<>();
            for (Map.Entry<String, Map<String, Object>> entry : unitDeviceTable.entrySet()) {
                Map<String, Object> unitDevice = entry.getValue();
                AnalysisBatchUnitDevice analysisBatchUnitDevice = new AnalysisBatchUnitDevice();
                analysisBatchUnitDevice.setId(UUIDGenerator.generate());
                analysisBatchUnitDevice.setAnalysisBatchId(analysisBatch.getId());
                analysisBatchUnitDevice.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
                analysisBatchUnitDevice.setUnitId(Convert.toStr(unitDevice.get("id")));
                analysisBatchUnitDevice.setUnitCode(Convert.toStr(unitDevice.get("unitCode")));
                analysisBatchUnitDevice.setUnitDeviceCode(Convert.toStr(unitDevice.get("deviceCode")));
                analysisBatchUnitDevice.setUnitType(Convert.toInt(unitDevice.get("type")));
                analysisBatchUnitDevice.setUnitTypeName(Convert.toStr(unitDevice.get("typeName")));
                analysisBatchUnitDevice.setUnitStartMileage(Convert.toBigDecimal(unitDevice.get("startMileage")));
                analysisBatchUnitDevice.setUnitCenterMileage(Convert.toBigDecimal(unitDevice.get("centerMileage")));
                analysisBatchUnitDevice.setUnitEndMileage(Convert.toBigDecimal(unitDevice.get("endMileage")));
                analysisBatchUnitDevices.add(analysisBatchUnitDevice);

                // 计算总得分
                BigDecimal unitScore = null;
                // 人工检查得分
                BigDecimal labourCheckScore = (BigDecimal) unitDevice.get("labourCheckScore");
                if (labourCheckScore == null) {
                    analysisBatchUnitDevice.setLabourCheck(0);
                    analysisBatchUnitDevice.setLabourCheckScore(null); // 设置空值
                } else {
                    analysisBatchUnitDevice.setLabourCheck(1);
                    analysisBatchUnitDevice.setLabourCheckScore(labourCheckScore);
                    unitScore = labourCheckScore;
                }

                // 轨检仪检查得分
                BigDecimal railDeviceCheckScore = (BigDecimal) unitDevice.get("railDeviceCheckScore");
                if (null == railDeviceCheckScore) {
                    analysisBatchUnitDevice.setRailDeviceCheck(0);
                    analysisBatchUnitDevice.setRailDeviceCheckScore(null);
                } else {
                    analysisBatchUnitDevice.setRailDeviceCheck(1);
                    analysisBatchUnitDevice.setRailDeviceCheckScore(railDeviceCheckScore);
                    if (unitScore == null) {
                        unitScore = railDeviceCheckScore;
                    } else {
                        unitScore = unitScore.add(railDeviceCheckScore);
                    }
                }


                // 轨检车得分
                BigDecimal railVehicleCheckScore = (BigDecimal) unitDevice.get("railVehicleCheckScore");
                if (null == railVehicleCheckScore) {
                    analysisBatchUnitDevice.setRailVehicleCheck(0);
                    analysisBatchUnitDevice.setRailVehicleCheckScore(null);
                } else {
                    analysisBatchUnitDevice.setRailVehicleCheck(1);
                    analysisBatchUnitDevice.setRailVehicleCheckScore(railVehicleCheckScore);
                    if (unitScore == null) {
                        unitScore = railVehicleCheckScore;
                    } else {
                        unitScore = unitScore.add(railVehicleCheckScore);
                    }
                }

                // 添乘仪得分
                BigDecimal addInstrumentCheckScore = (BigDecimal) unitDevice.get("addInstrumentCheckScore");
                if (null == addInstrumentCheckScore) {
                    analysisBatchUnitDevice.setAddDeviceCheck(0);
                    analysisBatchUnitDevice.setAddDeviceCheckScore(null);
                } else {
                    analysisBatchUnitDevice.setAddDeviceCheck(1);
                    analysisBatchUnitDevice.setAddDeviceCheckScore(railVehicleCheckScore);
                    if (unitScore == null) {
                        unitScore = addInstrumentCheckScore;
                    } else {
                        unitScore = unitScore.add(addInstrumentCheckScore);
                    }
                }


                // 计算总分
                Integer unitScoreLevel = null;
                String unitScoreLevelStr = "结果为空";
                if (unitScore != null) {
                    for (ConfigGradeLimit configGradeLimit : configGradeLimitList) {
                        // 匹配单元设备类型
                        if (analysisBatchUnitDevice.getUnitType().equals(configGradeLimit.getDeviceType())) {
                            // 匹配等级
                            if (configGradeLimit.getGradeMin().compareTo(unitScore) <= 0 && configGradeLimit.getGradeMax().compareTo(unitScore) > 0) {
                                unitScoreLevel = configGradeLimit.getGradeLevel();
                                unitScoreLevelStr = configGradeLimit.getGradeLevelStr();
                                break;
                            }

                        }
                    }
                } else {
                    unitScore = null;
                    unitScoreLevelStr = "无";
                    unitScoreLevel = 4;
                }
                // -1代表未评分
                analysisBatchUnitDevice.setUnitScore(unitScore);
                analysisBatchUnitDevice.setUnitScoreLevel(unitScoreLevel);
                analysisBatchUnitDevice.setUnitScoreLevelStr(unitScoreLevelStr);


                // 保存人工检查数据超限
                List<AnalysisBatchUnitDeviceTransfinite> labourCheckTransfiniteList = (List<AnalysisBatchUnitDeviceTransfinite>) unitDevice.get("labourCheckTransfinite");
                if (ObjectUtil.isNotEmpty(labourCheckTransfiniteList)) {
                    for (AnalysisBatchUnitDeviceTransfinite labourCheckTransfinite : labourCheckTransfiniteList) {
                        labourCheckTransfinite.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        labourCheckTransfinite.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        labourCheckTransfinite.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                        labourCheckTransfinite.setUnitId(analysisBatchUnitDevice.getUnitId());
                        labourCheckTransfinite.setUnitCode(analysisBatchUnitDevice.getUnitCode());
                        labourCheckTransfinite.setUnitType(analysisBatchUnitDevice.getUnitType());
                        labourCheckTransfinite.setUnitTypeName(analysisBatchUnitDevice.getUnitTypeName());
                        transfiniteList.add(labourCheckTransfinite);
                    }
                }

                // 保存人工检查数据计算得分
                List<AnalysisBatchUnitDevicePointScore> labourCheckScoreList = (List<AnalysisBatchUnitDevicePointScore>) unitDevice.get("labourCheckScoreList");
                if (ObjectUtil.isNotEmpty(labourCheckScoreList)) {
                    for (AnalysisBatchUnitDevicePointScore score : labourCheckScoreList) {
                        score.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        score.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        score.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                        score.setUnitId(analysisBatchUnitDevice.getUnitId());
                        score.setUnitCode(analysisBatchUnitDevice.getUnitCode());
                        score.setUnitType(analysisBatchUnitDevice.getUnitType());
                        score.setUnitTypeName(analysisBatchUnitDevice.getUnitTypeName());
                    }
                    scoreList.addAll(labourCheckScoreList);
                }


                // 保存轨检仪检查数据超限
                List<AnalysisBatchUnitDeviceTransfinite> railDeviceTransfiniteList = (List<AnalysisBatchUnitDeviceTransfinite>) unitDevice.get("railDeviceTransfinite");
                if (ObjectUtil.isNotEmpty(railDeviceTransfiniteList)) {
                    for (AnalysisBatchUnitDeviceTransfinite railDeviceTransfinite : railDeviceTransfiniteList) {
                        railDeviceTransfinite.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        railDeviceTransfinite.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        railDeviceTransfinite.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                        railDeviceTransfinite.setUnitId(analysisBatchUnitDevice.getUnitId());
                        railDeviceTransfinite.setUnitCode(analysisBatchUnitDevice.getUnitCode());
                        railDeviceTransfinite.setUnitType(analysisBatchUnitDevice.getUnitType());
                        railDeviceTransfinite.setUnitTypeName(analysisBatchUnitDevice.getUnitTypeName());
                        transfiniteList.add(railDeviceTransfinite);
                    }
                }


                // 保存轨检仪检检查数据计算得分
                List<AnalysisBatchUnitDevicePointScore> railDeviceCheckScoreList = (List<AnalysisBatchUnitDevicePointScore>) unitDevice.get("railDeviceCheckScoreList");
                if (ObjectUtil.isNotEmpty(railDeviceCheckScoreList)) {
                    for (AnalysisBatchUnitDevicePointScore score : railDeviceCheckScoreList) {
                        score.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        score.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        score.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                        score.setUnitId(analysisBatchUnitDevice.getUnitId());
                        score.setUnitCode(analysisBatchUnitDevice.getUnitCode());
                        score.setUnitType(analysisBatchUnitDevice.getUnitType());
                        score.setUnitTypeName(analysisBatchUnitDevice.getUnitTypeName());
                    }
                    scoreList.addAll(railDeviceCheckScoreList);
                }


                // 保存轨检车检查数据超限
                List<AnalysisBatchUnitDeviceTransfinite> railVehicleTransfiniteList = (List<AnalysisBatchUnitDeviceTransfinite>) unitDevice.get("railVehicleTransfiniteList");
                if (ObjectUtil.isNotEmpty(railVehicleTransfiniteList)) {
                    for (AnalysisBatchUnitDeviceTransfinite railVehicleTransfinite : railVehicleTransfiniteList) {
                        railVehicleTransfinite.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        railVehicleTransfinite.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        railVehicleTransfinite.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                        railVehicleTransfinite.setUnitId(analysisBatchUnitDevice.getUnitId());
                        railVehicleTransfinite.setUnitCode(analysisBatchUnitDevice.getUnitCode());
                        railVehicleTransfinite.setUnitType(analysisBatchUnitDevice.getUnitType());
                        railVehicleTransfinite.setUnitTypeName(analysisBatchUnitDevice.getUnitTypeName());
                        transfiniteList.add(railVehicleTransfinite);
                    }
                }

                // 保存轨检车检查查数据计算得分
                List<AnalysisBatchUnitDevicePointScore> railVehicleCheckScoreList = (List<AnalysisBatchUnitDevicePointScore>) unitDevice.get("railVehicleCheckScoreList");
                if (ObjectUtil.isNotEmpty(railVehicleCheckScoreList)) {
                    for (AnalysisBatchUnitDevicePointScore score : railVehicleCheckScoreList) {
                        score.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        score.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        score.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                        score.setUnitId(analysisBatchUnitDevice.getUnitId());
                        score.setUnitCode(analysisBatchUnitDevice.getUnitCode());
                        score.setUnitType(analysisBatchUnitDevice.getUnitType());
                        score.setUnitTypeName(analysisBatchUnitDevice.getUnitTypeName());
                    }
                    scoreList.addAll(railVehicleCheckScoreList);
                }

                // 保存轨检车tqi得分
                AnalysisBatchUnitDeviceTqiScore railVehicleTqiScore = (AnalysisBatchUnitDeviceTqiScore) unitDevice.get("railVehicleTqiScore");
                if (ObjectUtil.isNotEmpty(railVehicleTqiScore)) {
                    railVehicleTqiScore.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                    tqiScoreList.add(railVehicleTqiScore);
                }


                // 保存添乘仪检查数据超限
                List<AnalysisBatchUnitDeviceTransfinite> addInstrumentTransfiniteList = (List<AnalysisBatchUnitDeviceTransfinite>) unitDevice.get("addInstrumentTransfiniteList");
                if (ObjectUtil.isNotEmpty(addInstrumentTransfiniteList)) {
                    for (AnalysisBatchUnitDeviceTransfinite addInstrumentTransfinite : addInstrumentTransfiniteList) {
                        addInstrumentTransfinite.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        addInstrumentTransfinite.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        addInstrumentTransfinite.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                        addInstrumentTransfinite.setUnitId(analysisBatchUnitDevice.getUnitId());
                        addInstrumentTransfinite.setUnitCode(analysisBatchUnitDevice.getUnitCode());
                        addInstrumentTransfinite.setUnitType(analysisBatchUnitDevice.getUnitType());
                        addInstrumentTransfinite.setUnitTypeName(analysisBatchUnitDevice.getUnitTypeName());
                        transfiniteList.add(addInstrumentTransfinite);
                    }
                }


                // 保存添乘仪检查查数据计算得分
                List<AnalysisBatchUnitDevicePointScore> addInstrumentCheckScoreList = (List<AnalysisBatchUnitDevicePointScore>) unitDevice.get("addInstrumentCheckScoreList");
                if (ObjectUtil.isNotEmpty(addInstrumentCheckScoreList)) {
                    for (AnalysisBatchUnitDevicePointScore score : addInstrumentCheckScoreList) {
                        score.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        score.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        score.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                        score.setUnitId(analysisBatchUnitDevice.getUnitId());
                        score.setUnitCode(analysisBatchUnitDevice.getUnitCode());
                        score.setUnitType(analysisBatchUnitDevice.getUnitType());
                        score.setUnitTypeName(analysisBatchUnitDevice.getUnitTypeName());
                        scoreList.add(score);
                    }
                }

                // 保存人工检查数据分析批次映射
                List<AnalysisLabourCheckDataUnitDeviceMap> labourCheckDataUnitDeviceMapList = (List<AnalysisLabourCheckDataUnitDeviceMap>) unitDevice.get("labourCheckDataUnitDeviceMapList");
                if (ObjectUtil.isNotEmpty(labourCheckDataUnitDeviceMapList)) {
                    for (AnalysisLabourCheckDataUnitDeviceMap labourCheckDataUnitDeviceMap : labourCheckDataUnitDeviceMapList) {
                        labourCheckDataUnitDeviceMap.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        labourCheckDataUnitDeviceMap.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        labourCheckDataUnitDeviceMap.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                    }
                    analysisLabourCheckDataUnitDeviceMapService.saveBatch(labourCheckDataUnitDeviceMapList);
                }


                // 保存添乘仪数据分析批次映射
                List<AnalysisRailDeviceCheckDataUnitDeviceMap> railDeviceCheckDataUnitDeviceMapList = (List<AnalysisRailDeviceCheckDataUnitDeviceMap>) unitDevice.get("railDeviceCheckDataUnitDeviceMapList");
                if (ObjectUtil.isNotEmpty(railDeviceCheckDataUnitDeviceMapList)) {
                    for (AnalysisRailDeviceCheckDataUnitDeviceMap railDeviceCheckDataUnitDeviceMap : railDeviceCheckDataUnitDeviceMapList) {
                        railDeviceCheckDataUnitDeviceMap.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        railDeviceCheckDataUnitDeviceMap.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        railDeviceCheckDataUnitDeviceMap.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                    }
                    analysisRailDeviceCheckDataUnitDeviceMapService.saveBatch(railDeviceCheckDataUnitDeviceMapList);
                }

                // 保存轨检车数据分析批次映射
                List<AnalysisAdditiveCheckUnitDeviceMap> additiveCheckUnitDeviceMapList = (List<AnalysisAdditiveCheckUnitDeviceMap>) unitDevice.get("additiveCheckUnitDeviceMapList");
                if (ObjectUtil.isNotEmpty(additiveCheckUnitDeviceMapList)) {
                    for (AnalysisAdditiveCheckUnitDeviceMap additiveCheckUnitDeviceMap : additiveCheckUnitDeviceMapList) {
                        additiveCheckUnitDeviceMap.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        additiveCheckUnitDeviceMap.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        additiveCheckUnitDeviceMap.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                    }
                    analysisAdditiveCheckUnitDeviceMapService.saveBatch(additiveCheckUnitDeviceMapList);
                }

                // 保存轨检车数据分析批次映射
                List<AnalysisOverReportCheckUnitDeviceMap> overReportCheckUnitDeviceMapList = (List<AnalysisOverReportCheckUnitDeviceMap>) unitDevice.get("overReportCheckUnitDeviceMapList");
                if (ObjectUtil.isNotEmpty(overReportCheckUnitDeviceMapList)) {
                    for (AnalysisOverReportCheckUnitDeviceMap reportCheckUnitDeviceMap : overReportCheckUnitDeviceMapList) {
                        reportCheckUnitDeviceMap.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        reportCheckUnitDeviceMap.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        reportCheckUnitDeviceMap.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                    }
                    analysisOverReportCheckUnitDeviceMapService.saveBatch(overReportCheckUnitDeviceMapList);
                }


                // 保存轨检车Tqi数据分析批次映射
                List<AnalysisTqiReportCheckUnitDeviceMap> tqiReportCheckUnitDeviceMapList = (List<AnalysisTqiReportCheckUnitDeviceMap>) unitDevice.get("tqiReportCheckUnitDeviceMapList");
                if (ObjectUtil.isNotEmpty(tqiReportCheckUnitDeviceMapList)) {
                    for (AnalysisTqiReportCheckUnitDeviceMap tqiReportCheckUnitDeviceMap : tqiReportCheckUnitDeviceMapList) {
                        tqiReportCheckUnitDeviceMap.setAnalysisBatchUnitDeviceId(analysisBatchUnitDevice.getId());
                        tqiReportCheckUnitDeviceMap.setAnalysisBatchId(analysisBatchUnitDevice.getAnalysisBatchId());
                        tqiReportCheckUnitDeviceMap.setAnalysisBatchCode(analysisBatchUnitDevice.getAnalysisBatchCode());
                    }
                    analysisTqiReportCheckUnitDeviceMapService.saveBatch(tqiReportCheckUnitDeviceMapList);
                }


            }
            analysisBatchUnitDeviceTqiScoreService.saveBatch(tqiScoreList);
            analysisBatchUnitDeviceService.saveBatch(analysisBatchUnitDevices);
            analysisBatchUnitDeviceTransfiniteService.saveBatch(transfiniteList);
            analysisBatchUnitDevicePointScoreService.saveBatch(scoreList);
        }
        // 分析完成
        analysisBatchService.lambdaUpdate().set(AnalysisBatch::getAnalysisStatus, 99).eq(AnalysisBatch::getId, analysisBatchId).update();
        log.info("[分析完成]|线程id:【" + Thread.currentThread().getId() + "】=============分析批次ID:【" + analysisBatchId + "】");
    }

    /**
     * 添乘仪查数据解析
     */
    private void addInstrumentAnalysis(AnalysisBatch analysisBatch, AnalysisBatchCheckDataMap checkDataMap, List<Map<String, Object>> unitDeviceList) {

        // 缩小1000倍
        BigDecimal analysisStartingMileage = analysisBatch.getStartingMileage()
                .divide(new BigDecimal("1000"), 3, BigDecimal.ROUND_HALF_UP);
        BigDecimal analysisEndMileage = analysisBatch.getEndMileage()
                .divide(new BigDecimal("1000"), 3, BigDecimal.ROUND_HALF_UP);


        // 1.1 添乘仪查数据相关数据
        List<MovementAdditiveInfo> additiveInfos = movementAdditiveInfoService.lambdaQuery()
                .eq(MovementAdditiveInfo::getMovementMasterId, checkDataMap.getEkId())
                .ge(MovementAdditiveInfo::getPointMileage, analysisStartingMileage)
                .le(MovementAdditiveInfo::getPointMileage, analysisEndMileage)
                .orderByAsc(MovementAdditiveInfo::getPointMileage)
                .list();


        // 1.2 获添乘仪检查超限权值
        ConfigInstrumentCheck configInstrumentCheck = configInstrumentCheckService.lambdaQuery()
                .eq(ConfigInstrumentCheck::getSpeedMax, analysisBatch.getSpeedMax())
                .eq(ConfigInstrumentCheck::getSpeedMin, analysisBatch.getSpeedMin())
                .eq(ConfigInstrumentCheck::getDelFlag, "0")
                .last("limit 1")
                .one();
        // 1-钢轨,2-曲线,3-竖曲线,4-道岔
        JSONObject railWeightValueJsonObject = JSONObject.parseObject(configInstrumentCheck.getRail());
        JSONObject curveWeightValueJsonObject = JSONObject.parseObject(configInstrumentCheck.getCurve());
        JSONObject verticalCurveWeightValueJsonObject = JSONObject.parseObject(configInstrumentCheck.getVerticalCurve());
        JSONObject switchWeightValueJsonObject = JSONObject.parseObject(configInstrumentCheck.getRailSwitch());


        // 1.3 获取是否派工配置
        // 轨检车动态检查数据-1级超限
        Integer isWorkAddInstrumentOver1 = 1;
        String reasonLabelAddInstrumentOver1 = "";

        // 轨检车动态检查数据-2级超限
        Integer isWorkAddInstrumentOver2 = 1;
        String reasonLabelAddInstrumentOver2 = "";

        // 轨检车动态检查数据-3级超限
        Integer isWorkAddInstrumentOver3 = 1;
        String reasonLabelAddInstrumentOver3 = "";

        // 轨检车动态检查数据-4级超限
        Integer isWorkAddInstrumentOver4 = 1;
        String reasonLabelAddInstrumentOver4 = "";
        JSONArray dispatchingList = JSONArray.parseArray(analysisBatch.getDispatching());
        for (Object obj : dispatchingList) {
            JSONObject dispatching = (JSONObject) obj;
            Integer type = Convert.toInt(dispatching.get("type"));
            if (type != 4) {
                continue;
            }

            String reasonValue = String.valueOf(dispatching.get("reasonValue"));
            String reasonLabel = String.valueOf(dispatching.get("reasonLabel"));

            if ("add_instrument_1".equals(reasonValue)) {
                reasonLabelAddInstrumentOver1 = reasonLabel;
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWorkAddInstrumentOver1 = 1;
                } else {
                    isWorkAddInstrumentOver1 = 0;
                }
            }
            if ("add_instrument_2".equals(reasonValue)) {
                reasonLabelAddInstrumentOver2 = reasonLabel;
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWorkAddInstrumentOver2 = 1;
                } else {
                    isWorkAddInstrumentOver2 = 0;
                }
            }
            if ("add_instrument_3".equals(reasonValue)) {
                reasonLabelAddInstrumentOver3 = reasonLabel;
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWorkAddInstrumentOver3 = 1;
                } else {
                    isWorkAddInstrumentOver3 = 0;
                }
            }
            if ("add_instrument_4".equals(reasonValue)) {
                reasonLabelAddInstrumentOver4 = reasonLabel;
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWorkAddInstrumentOver4 = 1;
                } else {
                    isWorkAddInstrumentOver4 = 0;
                }
            }
        }


        // 2.循环遍历单元设备测点里程落在单元【开始-结束】这个区间视为这个区间的单元设备检查数据
        List<MovementAdditiveInfoUnitDeviceMap> additiveInfoUnitMaps = new ArrayList<>();
        int analysisType = analysisBatch.getAnalysisType();
        for (Map<String, Object> unitDevice : unitDeviceList) {
            // 1-钢轨,2-曲线,3-竖曲线,4-道岔
            Integer type = Convert.toInt(unitDevice.get("type"));
            JSONObject weightValuesjsonObject = null;
            if (type == 1) {
                weightValuesjsonObject = railWeightValueJsonObject;
            } else if (type == 2) {
                weightValuesjsonObject = curveWeightValueJsonObject;
            } else if (type == 3) {
                weightValuesjsonObject = verticalCurveWeightValueJsonObject;
            } else if (type == 4) {
                weightValuesjsonObject = switchWeightValueJsonObject;
            }
            // 垂直加速度权值
            BigDecimal verticalSpendWeightValue = weightValuesjsonObject.getBigDecimal("verticalSpend");
            // 水平加速度权值
            BigDecimal transverseSpendWeightValue = weightValuesjsonObject.getBigDecimal("transverseSpend");


            BigDecimal startMileage = Convert.toBigDecimal(unitDevice.get("startMileage"));
            BigDecimal endMileage = Convert.toBigDecimal(unitDevice.get("endMileage"));


            List<MovementAdditiveInfo> currentUnitDeviceAdditiveList = new ArrayList<>();
            List<AnalysisBatchUnitDeviceTransfinite> addInstrumentTransfiniteList = new ArrayList<>();
            List<AnalysisAdditiveCheckUnitDeviceMap> additiveCheckUnitDeviceMapList = new ArrayList<>();

            Iterator<MovementAdditiveInfo> iterator = additiveInfos.iterator();
            while (iterator.hasNext()) {
                MovementAdditiveInfo additiveInfo = iterator.next();
                BigDecimal pointMileage = additiveInfo.getPointMileage().multiply(new BigDecimal("1000"));


                if (startMileage.compareTo(pointMileage) <= 0 && endMileage.compareTo(pointMileage) > 0) {
                    // 记录映射关系
                    MovementAdditiveInfoUnitDeviceMap additiveInfoUnitMap = new MovementAdditiveInfoUnitDeviceMap();
                    additiveInfoUnitMap.setId(UUIDGenerator.generate());
                    additiveInfoUnitMap.setMovementMasterId(checkDataMap.getEkId());
                    additiveInfoUnitMap.setUnitId(Convert.toStr(unitDevice.get("id")));
                    additiveInfoUnitMap.setUnitCode(Convert.toStr(unitDevice.get("unitCode")));
                    additiveInfoUnitMap.setUnitDeviceCode(Convert.toStr(unitDevice.get("deviceCode")));
                    additiveInfoUnitMap.setUnitType(Convert.toInt(unitDevice.get("type")));
                    additiveInfoUnitMap.setUnitTypeName(Convert.toStr(unitDevice.get("typeName")));
                    additiveInfoUnitMap.setUnitStartMileage(Convert.toBigDecimal(unitDevice.get("startMileage")));
                    additiveInfoUnitMap.setUnitCenterMileage(Convert.toBigDecimal(unitDevice.get("centerMileage")));
                    additiveInfoUnitMap.setUnitEndMileage(Convert.toBigDecimal(unitDevice.get("endMileage")));
                    additiveInfoUnitMap.setPointMileage(pointMileage);
                    additiveInfoUnitMap.setZontalSpeed(additiveInfo.getZontalSpeed());
                    additiveInfoUnitMap.setZontalSpeedLevel(additiveInfo.getZontalSpeedLevel());
                    additiveInfoUnitMap.setVerticalSpeed(additiveInfo.getVerticalSpeed());
                    additiveInfoUnitMap.setVerticalSpeedLevel(additiveInfo.getVerticalSpeedLevel());
                    additiveInfoUnitMap.setSpeed(additiveInfo.getSpeed());
                    additiveInfoUnitMap.setMark(additiveInfo.getMark());
                    additiveInfoUnitMaps.add(additiveInfoUnitMap);


                    AnalysisAdditiveCheckUnitDeviceMap additiveCheckUnitDeviceMap = this.additiveCheckUnitDeviceMapSave(checkDataMap, unitDevice, additiveInfo);
                    additiveCheckUnitDeviceMapList.add(additiveCheckUnitDeviceMap);

                    // 水平超限
                    if (additiveInfo.getZontalSpeedLevel() != null) {
                        AnalysisBatchUnitDeviceTransfinite zontalSpeedTransfinite = new AnalysisBatchUnitDeviceTransfinite();
                        zontalSpeedTransfinite.setId(UUIDGenerator.generate());
                        zontalSpeedTransfinite.setTransfiniteGrade(additiveInfo.getZontalSpeedLevel());
                        zontalSpeedTransfinite.setTransfiniteType("水平超限");
                        if (1 == additiveInfo.getZontalSpeedLevel()) {
                            zontalSpeedTransfinite.setTransfiniteGradeName(reasonLabelAddInstrumentOver1);
                            zontalSpeedTransfinite.setIsWork(isWorkAddInstrumentOver1);
                        } else if (2 == additiveInfo.getZontalSpeedLevel()) {
                            zontalSpeedTransfinite.setTransfiniteGradeName(reasonLabelAddInstrumentOver2);
                            zontalSpeedTransfinite.setIsWork(isWorkAddInstrumentOver2);
                        } else if (3 == additiveInfo.getZontalSpeedLevel()) {
                            zontalSpeedTransfinite.setTransfiniteGradeName(reasonLabelAddInstrumentOver3);
                            zontalSpeedTransfinite.setIsWork(isWorkAddInstrumentOver3);
                        } else {
                            zontalSpeedTransfinite.setTransfiniteGradeName(reasonLabelAddInstrumentOver4);
                            zontalSpeedTransfinite.setIsWork(isWorkAddInstrumentOver4);
                        }
//                        String allowValue = Convert.toBigDecimal(movementOverReport.getPeakValue()).subtract(Convert.toBigDecimal(movementOverReport.getDataDifference())).toString();
//                        zontalSpeedTransfinite.setAllowValue();
                        zontalSpeedTransfinite.setEkId(additiveInfo.getMovementMasterId());
                        zontalSpeedTransfinite.setEkType(4);
                        zontalSpeedTransfinite.setEkItemId(additiveInfo.getId());
                        zontalSpeedTransfinite.setMeasurePointValue(additiveInfo.getVerticalSpeed().toString());
                        zontalSpeedTransfinite.setDiseaseMileage(pointMileage);
                        addInstrumentTransfiniteList.add(zontalSpeedTransfinite);
                    }

                    // 垂直超限
                    if (additiveInfo.getVerticalSpeedLevel() != null) {
                        AnalysisBatchUnitDeviceTransfinite verticalSpeedTransfinite = new AnalysisBatchUnitDeviceTransfinite();
                        verticalSpeedTransfinite.setId(UUIDGenerator.generate());
                        verticalSpeedTransfinite.setTransfiniteGrade(additiveInfo.getVerticalSpeedLevel());
                        verticalSpeedTransfinite.setTransfiniteType("垂直超限");
                        if (1 == additiveInfo.getVerticalSpeedLevel()) {
                            verticalSpeedTransfinite.setTransfiniteGradeName(reasonLabelAddInstrumentOver1);
                            verticalSpeedTransfinite.setIsWork(isWorkAddInstrumentOver1);
                        } else if (2 == additiveInfo.getVerticalSpeedLevel()) {
                            verticalSpeedTransfinite.setTransfiniteGradeName(reasonLabelAddInstrumentOver2);
                            verticalSpeedTransfinite.setIsWork(isWorkAddInstrumentOver2);
                        } else if (3 == additiveInfo.getVerticalSpeedLevel()) {
                            verticalSpeedTransfinite.setTransfiniteGradeName(reasonLabelAddInstrumentOver3);
                            verticalSpeedTransfinite.setIsWork(isWorkAddInstrumentOver3);
                        } else {
                            verticalSpeedTransfinite.setTransfiniteGradeName(reasonLabelAddInstrumentOver4);
                            verticalSpeedTransfinite.setIsWork(isWorkAddInstrumentOver4);
                        }
//                        String allowValue = Convert.toBigDecimal(movementOverReport.getPeakValue()).subtract(Convert.toBigDecimal(movementOverReport.getDataDifference())).toString();
//                        zontalSpeedTransfinite.setAllowValue();
                        verticalSpeedTransfinite.setEkId(additiveInfo.getMovementMasterId());
                        verticalSpeedTransfinite.setEkType(4);
                        verticalSpeedTransfinite.setEkItemId(additiveInfo.getId());
                        verticalSpeedTransfinite.setMeasurePointValue(additiveInfo.getVerticalSpeed().toString());
                        verticalSpeedTransfinite.setDiseaseMileage(pointMileage);
                        addInstrumentTransfiniteList.add(verticalSpeedTransfinite);
                    }


                    currentUnitDeviceAdditiveList.add(additiveInfo);

                    // 在集合中删除这个对象
                    iterator.remove();
                }
            }

            unitDevice.put("addInstrumentTransfiniteList", addInstrumentTransfiniteList);
            unitDevice.put("additiveCheckUnitDeviceMapList", additiveCheckUnitDeviceMapList);


            // 计算得分
            BigDecimal sumUnitScore = null;
            BigDecimal finalZontalSpeed = null;
            BigDecimal sumZontalSpeed = BigDecimal.ZERO;
            int zontalSpeedSize = 0;

            BigDecimal finalVerticalSpeed = null;
            BigDecimal sumVerticalSpeed = BigDecimal.ZERO;
            int verticalSpeedSize = 0;

            List<AnalysisBatchUnitDevicePointScore> scoreList = new ArrayList<>();
            for (MovementAdditiveInfo movementAdditiveInfo : currentUnitDeviceAdditiveList) {
                // 计算水平得分
                BigDecimal zontalSpeed = movementAdditiveInfo.getZontalSpeed().abs();
                if (1 == analysisType) {// 均值
                    sumZontalSpeed = sumZontalSpeed.add(zontalSpeed);
                    zontalSpeedSize++;
                    finalZontalSpeed = sumZontalSpeed.divide(new BigDecimal(zontalSpeedSize), 3, BigDecimal.ROUND_HALF_UP);
                } else { // 峰值
                    if (null == finalZontalSpeed || finalZontalSpeed.compareTo(zontalSpeed) < 0) {
                        finalZontalSpeed = zontalSpeed;
                    }
                }


                // 计算垂直得分
                BigDecimal verticalSpeed = movementAdditiveInfo.getVerticalSpeed().abs();
                if (1 == analysisType) {// 均值
                    sumVerticalSpeed = sumVerticalSpeed.add(verticalSpeed);
                    verticalSpeedSize++;
                    finalVerticalSpeed = sumVerticalSpeed.divide(new BigDecimal(verticalSpeedSize), 3, BigDecimal.ROUND_HALF_UP);
                } else { // 峰值
                    if (null == finalVerticalSpeed || finalVerticalSpeed.compareTo(verticalSpeed) < 0) {
                        finalVerticalSpeed = verticalSpeed;
                    }
                }
            }
            if (null != finalZontalSpeed) {
                BigDecimal zontalSpeedScore = finalZontalSpeed.multiply(transverseSpendWeightValue);
                if (sumUnitScore == null) {
                    sumUnitScore = zontalSpeedScore;
                } else {
                    sumUnitScore = sumUnitScore.add(zontalSpeedScore);
                }

                AnalysisBatchUnitDevicePointScore zontalSpeedPointScore = new AnalysisBatchUnitDevicePointScore();
                zontalSpeedPointScore.setId(UUIDGenerator.generate());
                zontalSpeedPointScore.setAnalysisType(analysisType);
                zontalSpeedPointScore.setSpeedMax(analysisBatch.getSpeedMax());
                zontalSpeedPointScore.setSpeedMin(analysisBatch.getSpeedMin());
                zontalSpeedPointScore.setAnalysisBatchId(analysisBatch.getId());
                zontalSpeedPointScore.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
                zontalSpeedPointScore.setPointTypeName("水平");
                zontalSpeedPointScore.setCheckType(4);
                zontalSpeedPointScore.setPointValue(finalZontalSpeed);
                zontalSpeedPointScore.setWeightValues(transverseSpendWeightValue);
                zontalSpeedPointScore.setPointScore(zontalSpeedScore);
                scoreList.add(zontalSpeedPointScore);
            }

            if (null != finalVerticalSpeed) {
                BigDecimal verticalSpeedScore = finalVerticalSpeed.multiply(verticalSpendWeightValue);
                if (sumUnitScore == null) {
                    sumUnitScore = verticalSpeedScore;
                } else {
                    sumUnitScore = sumUnitScore.add(verticalSpeedScore);
                }
                AnalysisBatchUnitDevicePointScore verticalSpeedPointScore = new AnalysisBatchUnitDevicePointScore();
                verticalSpeedPointScore.setId(UUIDGenerator.generate());
                verticalSpeedPointScore.setAnalysisType(analysisType);
                verticalSpeedPointScore.setSpeedMax(analysisBatch.getSpeedMax());
                verticalSpeedPointScore.setSpeedMin(analysisBatch.getSpeedMin());
                verticalSpeedPointScore.setAnalysisBatchId(analysisBatch.getId());
                verticalSpeedPointScore.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
                verticalSpeedPointScore.setPointTypeName("垂直");
                verticalSpeedPointScore.setCheckType(4);
                verticalSpeedPointScore.setPointValue(finalVerticalSpeed);
                verticalSpeedPointScore.setWeightValues(transverseSpendWeightValue);
                verticalSpeedPointScore.setPointScore(verticalSpeedScore);
                scoreList.add(verticalSpeedPointScore);
            }

            unitDevice.put("addInstrumentCheckScore", sumUnitScore);
            unitDevice.put("addInstrumentCheckScoreList", scoreList);
        }


        if (ObjectUtil.isNotEmpty(additiveInfoUnitMaps)) {
            movementAdditiveInfoUnitDeviceMapService.lambdaUpdate()
                    .eq(MovementAdditiveInfoUnitDeviceMap::getMovementMasterId, checkDataMap.getEkId())
                    .remove();
            movementAdditiveInfoUnitDeviceMapService.saveBatch(additiveInfoUnitMaps);
        }
    }

    private AnalysisAdditiveCheckUnitDeviceMap additiveCheckUnitDeviceMapSave(AnalysisBatchCheckDataMap checkDataMap, Map<String, Object> unitDevice, MovementAdditiveInfo additiveInfo) {
        AnalysisAdditiveCheckUnitDeviceMap additiveInfoUnitMap = new AnalysisAdditiveCheckUnitDeviceMap();
        additiveInfoUnitMap.setId(UUIDGenerator.generate());
        additiveInfoUnitMap.setMovementMasterId(checkDataMap.getEkId());
        additiveInfoUnitMap.setUnitId(Convert.toStr(unitDevice.get("id")));
        additiveInfoUnitMap.setUnitCode(Convert.toStr(unitDevice.get("unitCode")));
        additiveInfoUnitMap.setUnitDeviceCode(Convert.toStr(unitDevice.get("deviceCode")));
        additiveInfoUnitMap.setUnitType(Convert.toInt(unitDevice.get("type")));
        additiveInfoUnitMap.setUnitTypeName(Convert.toStr(unitDevice.get("typeName")));
        additiveInfoUnitMap.setUnitStartMileage(Convert.toBigDecimal(unitDevice.get("startMileage")));
        additiveInfoUnitMap.setUnitCenterMileage(Convert.toBigDecimal(unitDevice.get("centerMileage")));
        additiveInfoUnitMap.setUnitEndMileage(Convert.toBigDecimal(unitDevice.get("endMileage")));
        additiveInfoUnitMap.setMovementAdditiveInfoId(additiveInfo.getId());
        additiveInfoUnitMap.setPointMileage(additiveInfo.getPointMileage().multiply(new BigDecimal("1000")));
        additiveInfoUnitMap.setZontalSpeed(additiveInfo.getZontalSpeed());
        additiveInfoUnitMap.setZontalSpeedLevel(additiveInfo.getZontalSpeedLevel());
        additiveInfoUnitMap.setVerticalSpeed(additiveInfo.getVerticalSpeed());
        additiveInfoUnitMap.setVerticalSpeedLevel(additiveInfo.getVerticalSpeedLevel());
        additiveInfoUnitMap.setSpeed(additiveInfo.getSpeed());
        additiveInfoUnitMap.setMark(additiveInfo.getMark());
        return additiveInfoUnitMap;
    }


    /**
     * 轨检车检查数据解析
     */
    private void railVehicleCheckDataAnalysis(AnalysisBatch analysisBatch, AnalysisBatchCheckDataMap checkDataMap, List<Map<String, Object>> unitDeviceList) {
        // 1.获取轨检车相关数据
        // 1.1 获取缺陷报告
        List<MovementOverReport> movementOverReports = movementOverReportService.lambdaQuery().eq(MovementOverReport::getMovementMasterId, checkDataMap.getEkId()).ge(MovementOverReport::getMileage, analysisBatch.getStartingMileage()).le(MovementOverReport::getMileage, analysisBatch.getEndMileage()).orderByAsc(MovementOverReport::getMileage).list();

        // 1.2 获取tqi数据
        List<MovementTqiReport> tqiReports = movementTqiReportService.lambdaQuery().eq(MovementTqiReport::getMovementMasterId, checkDataMap.getEkId()).ge(MovementTqiReport::getStartMileage, analysisBatch.getStartingMileage()).le(MovementTqiReport::getEndMileage, analysisBatch.getEndMileage()).orderByAsc(MovementTqiReport::getStartMileage).list();

        // 1.3 派工设置
        JSONArray dispatchingList = JSONArray.parseArray(analysisBatch.getDispatching());

        //  1.4 获取轨检车检查超限权值
        ConfigRailVehicleCheck configRailVehicle = configRailVehicleCheckService.lambdaQuery().eq(ConfigRailVehicleCheck::getSpeedMax, analysisBatch.getSpeedMax()).eq(ConfigRailVehicleCheck::getSpeedMin, analysisBatch.getSpeedMin()).eq(ConfigRailVehicleCheck::getDelFlag, "0").last("limit 1").one();
        // 1-钢轨,2-曲线,3-竖曲线,4-道岔
        JSONObject railWeightValueJsonObject = JSONObject.parseObject(configRailVehicle.getRail());
        JSONObject curveWeightValueJsonObject = JSONObject.parseObject(configRailVehicle.getCurve());
        JSONObject verticalCurveWeightValueJsonObject = JSONObject.parseObject(configRailVehicle.getVerticalCurve());
        JSONObject switchWeightValueJsonObject = JSONObject.parseObject(configRailVehicle.getRailSwitch());

        // 1.5 获取轨检车TQI权值
        ConfigRailVehicleTqi configRailVehicleTqi = configRailVehicleTqlService.lambdaQuery().eq(ConfigRailVehicleTqi::getSpeedMax, analysisBatch.getSpeedMax()).eq(ConfigRailVehicleTqi::getSpeedMin, analysisBatch.getSpeedMin()).eq(ConfigRailVehicleTqi::getDelFlag, "0").last("limit 1").one();
        // 1-钢轨,2-曲线,3-竖曲线,4-道岔
        JSONObject railTqiJsonObject = JSONObject.parseObject(configRailVehicleTqi.getRail());
        JSONObject curveTqiJsonObject = JSONObject.parseObject(configRailVehicleTqi.getCurve());
        JSONObject verticalCurveTqiJsonObject = JSONObject.parseObject(configRailVehicleTqi.getVerticalCurve());
        JSONObject switchTqiJsonObject = JSONObject.parseObject(configRailVehicleTqi.getRailSwitch());


        // 1.6 获取轨检车TQI阀值
        List<ConfigTqiLimit> configTqiLimits = configTqiLimitService.lambdaQuery()
                .eq(ConfigTqiLimit::getSpeedMax, analysisBatch.getSpeedMax())
                .eq(ConfigTqiLimit::getSpeedMin, analysisBatch.getSpeedMin())
                .orderByAsc(ConfigTqiLimit::getOverStandardType)
                .list();


        // 2.根据分析批次的里程查询出映射单元
        List<MovementOverReportUnitDeviceMap> overReportUnitDeviceMaps = new ArrayList<>();
        List<MovementTqiReportUnitDeviceMap> movementTqiReportUnitDeviceMaps = new ArrayList<>();

        List<String> unitDeviceIds = new ArrayList<>();
        for (Map<String, Object> unitDevice : unitDeviceList) {
            // 添加所有单元ID
            String unitDeviceId = Convert.toStr(unitDevice.get("id"));
            unitDeviceIds.add(unitDeviceId);

            BigDecimal startMileage = Convert.toBigDecimal(unitDevice.get("startMileage"));
            BigDecimal centerMileage = Convert.toBigDecimal(unitDevice.get("centerMileage"));
            BigDecimal endMileage = Convert.toBigDecimal(unitDevice.get("endMileage"));


            BigDecimal sumUnitScore = null;
            List<AnalysisBatchUnitDevicePointScore> scoreList = new ArrayList<>();


            List<MovementOverReport> currentUnitDeviceOverReportList = new ArrayList<>();
            List<AnalysisOverReportCheckUnitDeviceMap> overReportCheckUnitDeviceMapList = new ArrayList<>();

            // 2.1 缺陷记录报告表里程落在单元设备【开始-结束】这个设备上面，视为这个区间的超限记录
            List<AnalysisBatchUnitDeviceTransfinite> railVehicleTransfiniteList = new ArrayList<>();
            for (MovementOverReport movementOverReport : movementOverReports) {
                // 说明超限
                if (startMileage.compareTo(movementOverReport.getMileage()) <= 0 && endMileage.compareTo(movementOverReport.getMileage()) > 0) {
                    // 轨检车超限等级
                    AnalysisBatchUnitDeviceTransfinite transfinite = this.railVehicleCheckTransfinite(dispatchingList, movementOverReport);
                    if (ObjectUtil.isNotEmpty(transfinite)) {
                        railVehicleTransfiniteList.add(transfinite);
                    }


                    // 保存超限和设备关联关系
                    MovementOverReportUnitDeviceMap overReportUnitDeviceMap = new MovementOverReportUnitDeviceMap();
                    overReportUnitDeviceMap.setId(UUIDGenerator.generate());
                    overReportUnitDeviceMap.setUnitId(Convert.toStr(unitDevice.get("id")));
                    overReportUnitDeviceMap.setUnitCode(Convert.toStr(unitDevice.get("unitCode")));
                    overReportUnitDeviceMap.setUnitType(Convert.toInt(unitDevice.get("type")));
                    overReportUnitDeviceMap.setUnitTypeName(Convert.toStr(unitDevice.get("typeName")));
                    overReportUnitDeviceMap.setUnitStartingMileage(Convert.toBigDecimal(unitDevice.get("startMileage")));
                    overReportUnitDeviceMap.setUnitCenterMileage(Convert.toBigDecimal(unitDevice.get("centerMileage")));
                    overReportUnitDeviceMap.setUnitEndMileage(Convert.toBigDecimal(unitDevice.get("endMileage")));
                    overReportUnitDeviceMap.setCheckId(checkDataMap.getEkId());
                    overReportUnitDeviceMap.setCheckType(checkDataMap.getEkType());
                    overReportUnitDeviceMap.setOverReportId(movementOverReport.getId());
                    overReportUnitDeviceMap.setOverReportMileage(movementOverReport.getMileage());
                    overReportUnitDeviceMap.setOverLevel(Convert.toInt(movementOverReport.getOverrunLevel()));
                    overReportUnitDeviceMap.setOverType(movementOverReport.getOverrunType());
                    overReportUnitDeviceMap.setLongitude(movementOverReport.getLongitude());
                    overReportUnitDeviceMap.setPeakValue(movementOverReport.getPeakValue());
                    overReportUnitDeviceMap.setDataDifference(movementOverReport.getDataDifference());
                    overReportUnitDeviceMap.setXianxing(movementOverReport.getXianxing());
                    overReportUnitDeviceMap.setStandard(movementOverReport.getStandard());
                    overReportUnitDeviceMap.setSpend(movementOverReport.getSpend());
                    overReportUnitDeviceMaps.add(overReportUnitDeviceMap);
                    currentUnitDeviceOverReportList.add(movementOverReport);


                    AnalysisOverReportCheckUnitDeviceMap overReportCheckUnitDeviceMap = this.analysisOverReportCheckUnitDeviceMapSave(unitDevice, checkDataMap, movementOverReport);
                    overReportCheckUnitDeviceMapList.add(overReportCheckUnitDeviceMap);
                }
            }


            // 2.2 计算单元超限得分
            Integer type = Convert.toInt(unitDevice.get("type"));
            JSONObject weightValuejsonObject = null;
            if (type == 1) {
                weightValuejsonObject = railWeightValueJsonObject;
            } else if (type == 2) {
                weightValuejsonObject = curveWeightValueJsonObject;
            } else if (type == 3) {
                weightValuejsonObject = verticalCurveWeightValueJsonObject;
            } else if (type == 4) {
                weightValuejsonObject = switchWeightValueJsonObject;
            }
            BigDecimal heightWeightValue = weightValuejsonObject.getBigDecimal("height");
            BigDecimal directionWeightValue = weightValuejsonObject.getBigDecimal("direction");
            BigDecimal levelWeightValue = weightValuejsonObject.getBigDecimal("level");
            BigDecimal trackGaugeWeightValue = weightValuejsonObject.getBigDecimal("trackGauge");
            BigDecimal triangularPitWeightValue = weightValuejsonObject.getBigDecimal("triangularPit");
            BigDecimal gaugeChangeWeightValue = weightValuejsonObject.getBigDecimal("gaugeChange");

            // 高低得分
            AnalysisBatchUnitDevicePointScore heightPointScore = this.createRailVehicleCheckTransfinitePointScore(analysisBatch,
                    currentUnitDeviceOverReportList,
                    "高低",
                    heightWeightValue);
            if (ObjectUtil.isNotEmpty(heightPointScore)) {
                sumUnitScore = sumUnitScore != null ?
                        sumUnitScore.add(heightPointScore.getPointScore()) :
                        heightPointScore.getPointScore();
                scoreList.add(heightPointScore);
            }


            // 轨向得分
            AnalysisBatchUnitDevicePointScore directionPointScore = this.createRailVehicleCheckTransfinitePointScore(analysisBatch,
                    currentUnitDeviceOverReportList,
                    "轨向",
                    directionWeightValue);
            if (ObjectUtil.isNotEmpty(directionPointScore)) {
                sumUnitScore = sumUnitScore != null ?
                        sumUnitScore.add(directionPointScore.getPointScore()) :
                        directionPointScore.getPointScore();
                scoreList.add(directionPointScore);
            }


            // 水平得分
            AnalysisBatchUnitDevicePointScore levelPointScore = this.createRailVehicleCheckTransfinitePointScore(analysisBatch,
                    currentUnitDeviceOverReportList,
                    "水平",
                    levelWeightValue);
            if (ObjectUtil.isNotEmpty(levelPointScore)) {
                sumUnitScore = sumUnitScore != null ?
                        sumUnitScore.add(levelPointScore.getPointScore()) :
                        levelPointScore.getPointScore();
                scoreList.add(levelPointScore);
            }


            // 轨距得分
            AnalysisBatchUnitDevicePointScore trackGaugePointScore = this.createRailVehicleCheckTransfinitePointScore(analysisBatch,
                    currentUnitDeviceOverReportList,
                    "轨距",
                    trackGaugeWeightValue);
            if (ObjectUtil.isNotEmpty(trackGaugePointScore)) {
                sumUnitScore = sumUnitScore != null ?
                        sumUnitScore.add(trackGaugePointScore.getPointScore()) :
                        trackGaugePointScore.getPointScore();
                scoreList.add(trackGaugePointScore);
            }


            // 三角坑得分
            AnalysisBatchUnitDevicePointScore triangularPitPointScore = this.createRailVehicleCheckTransfinitePointScore(analysisBatch,
                    currentUnitDeviceOverReportList,
                    "三角坑",
                    triangularPitWeightValue);
            if (ObjectUtil.isNotEmpty(triangularPitPointScore)) {
                sumUnitScore = sumUnitScore != null ?
                        sumUnitScore.add(triangularPitPointScore.getPointScore()) :
                        triangularPitPointScore.getPointScore();
                scoreList.add(triangularPitPointScore);
            }

            // 轨距变化率得分
            AnalysisBatchUnitDevicePointScore gaugeChangePitPointScore = this.createRailVehicleCheckTransfinitePointScore(analysisBatch,
                    currentUnitDeviceOverReportList,
                    "轨距变化率",
                    gaugeChangeWeightValue);
            if (ObjectUtil.isNotEmpty(gaugeChangePitPointScore)) {
                sumUnitScore = sumUnitScore != null ?
                        sumUnitScore.add(gaugeChangePitPointScore.getPointScore()) :
                        gaugeChangePitPointScore.getPointScore();
                scoreList.add(gaugeChangePitPointScore);
            }


            // 2.3 处理tqi数
            // 2.3.1 tqi权值
            // 1-钢轨,2-曲线,3-竖曲线,4-道岔
            JSONObject tqiJsonObject = null;
            if (type == 1) {
                tqiJsonObject = railTqiJsonObject;
            } else if (type == 2) {
                tqiJsonObject = curveTqiJsonObject;
            } else if (type == 3) {
                tqiJsonObject = verticalCurveTqiJsonObject;
            } else if (type == 4) {
                tqiJsonObject = switchTqiJsonObject;
            }
            BigDecimal heightTqi = tqiJsonObject.getBigDecimal("height");
            BigDecimal directionTqi = tqiJsonObject.getBigDecimal("direction");
            BigDecimal trackGaugeTqi = tqiJsonObject.getBigDecimal("trackGauge");
            BigDecimal triangularPitTqi = tqiJsonObject.getBigDecimal("triangularPit");
            BigDecimal levelTqi = tqiJsonObject.getBigDecimal("level");
            BigDecimal tqiComeUponTqi = tqiJsonObject.getBigDecimal("tqi");

            // 2.3.2 单元设备中心里程落在tqi【开始-结束】这个区间视为这个区间的单元设备
            List<AnalysisTqiReportCheckUnitDeviceMap> tqiReportCheckUnitDeviceMapList = new ArrayList<>();
            for (MovementTqiReport tqiReport : tqiReports) {
                // 如果命中处理测点映射关系
                if (tqiReport.getStartMileage().compareTo(centerMileage) <= 0 && tqiReport.getEndMileage().compareTo(centerMileage) > 0) {
                    MovementTqiReportUnitDeviceMap movementTqiReportUnitDeviceMap = new MovementTqiReportUnitDeviceMap();
                    movementTqiReportUnitDeviceMap.setId(UUIDGenerator.generate());
                    movementTqiReportUnitDeviceMap.setCheckId(checkDataMap.getEkId());
                    movementTqiReportUnitDeviceMap.setCheckType(checkDataMap.getEkType());
                    movementTqiReportUnitDeviceMap.setUnitId(Convert.toStr(unitDevice.get("id")));
                    movementTqiReportUnitDeviceMap.setUnitCode(Convert.toStr(unitDevice.get("unitCode")));
                    movementTqiReportUnitDeviceMap.setUnitType(Convert.toInt(unitDevice.get("type")));
                    movementTqiReportUnitDeviceMap.setUnitTypeName(Convert.toStr(unitDevice.get("typeName")));
                    movementTqiReportUnitDeviceMap.setUnitStartingMileage(Convert.toBigDecimal(unitDevice.get("startMileage")));
                    movementTqiReportUnitDeviceMap.setUnitCenterMileage(Convert.toBigDecimal(unitDevice.get("centerMileage")));
                    movementTqiReportUnitDeviceMap.setUnitEndMileage(Convert.toBigDecimal(unitDevice.get("endMileage")));
                    movementTqiReportUnitDeviceMap.setTqiReportId(tqiReport.getId());
                    movementTqiReportUnitDeviceMap.setStartMileage(tqiReport.getStartMileage());
                    movementTqiReportUnitDeviceMap.setEndMileage(tqiReport.getEndMileage());
                    movementTqiReportUnitDeviceMap.setSectionName(tqiReport.getSectionName());
                    movementTqiReportUnitDeviceMap.setHighLowLeft(tqiReport.getHighLowLeft());
                    movementTqiReportUnitDeviceMap.setHighLowRight(tqiReport.getHighLowRight());
                    movementTqiReportUnitDeviceMap.setTrackLeft(tqiReport.getTrackLeft());
                    movementTqiReportUnitDeviceMap.setTrackRight(tqiReport.getTrackRight());
                    movementTqiReportUnitDeviceMap.setLevel(tqiReport.getLevel());
                    movementTqiReportUnitDeviceMap.setTrackGauge(tqiReport.getTrackGauge());
                    movementTqiReportUnitDeviceMap.setTriangularPit(tqiReport.getTriangularPit());
                    movementTqiReportUnitDeviceMap.setTqiComeUpon(tqiReport.getTqiComeUpon());
                    movementTqiReportUnitDeviceMap.setTqiAboveStandard(tqiReport.getTqiAboveStandard());
                    movementTqiReportUnitDeviceMap.setDeduct(tqiReport.getDeduct());
                    movementTqiReportUnitDeviceMap.setStandard(tqiReport.getStandard());
                    movementTqiReportUnitDeviceMap.setSpend(tqiReport.getSpend());
                    movementTqiReportUnitDeviceMaps.add(movementTqiReportUnitDeviceMap);

                    AnalysisTqiReportCheckUnitDeviceMap tqiReportCheckUnitDeviceMap = this.tqiReportCheckUnitDeviceMapSave(checkDataMap, unitDevice, tqiReport);
                    tqiReportCheckUnitDeviceMapList.add(tqiReportCheckUnitDeviceMap);

                    // 计算分数
                    // 计算高低得分
                    BigDecimal finalTqiHeight;
                    BigDecimal heightLowLeft = Convert.toBigDecimal(tqiReport.getHighLowLeft()).abs();
                    BigDecimal heightLowRight = Convert.toBigDecimal(tqiReport.getHighLowRight()).abs();
                    if (1 == analysisBatch.getAnalysisType()) {
                        // 均值
                        finalTqiHeight = heightLowLeft.add(heightLowRight).divide(new BigDecimal("2"), 3, BigDecimal.ROUND_HALF_UP);
                    } else {
                        // 峰值
                        if (heightLowLeft.compareTo(heightLowRight) > 0) {
                            finalTqiHeight = heightLowLeft;
                        } else {
                            finalTqiHeight = heightLowRight;
                        }
                    }
                    AnalysisBatchUnitDevicePointScore tqiHeightPointScore = this.createRailVehicleCheckTqiPointScore(analysisBatch, finalTqiHeight, "高低", heightTqi);
                    if (sumUnitScore == null) {
                        sumUnitScore = tqiHeightPointScore.getPointScore();
                    } else {
                        sumUnitScore = sumUnitScore.add(tqiHeightPointScore.getPointScore());
                    }
                    scoreList.add(tqiHeightPointScore);


                    // 计算轨向得分
                    BigDecimal finalTqiDirection;
                    BigDecimal directionLeft = Convert.toBigDecimal(tqiReport.getTrackLeft()).abs();
                    BigDecimal directionRight = Convert.toBigDecimal(tqiReport.getTrackRight()).abs();
                    if (1 == analysisBatch.getAnalysisType()) {
                        // 均值
                        finalTqiDirection = directionLeft.add(directionRight).divide(new BigDecimal("2"), 3, BigDecimal.ROUND_HALF_UP);
                    } else {
                        // 峰值
                        if (directionLeft.compareTo(directionRight) > 0) {
                            finalTqiDirection = directionLeft;
                        } else {
                            finalTqiDirection = directionRight;
                        }
                    }
                    AnalysisBatchUnitDevicePointScore tqiDirectionPointScore = this.createRailVehicleCheckTqiPointScore(analysisBatch, finalTqiDirection, "轨向", directionTqi);
                    if (sumUnitScore == null) {
                        sumUnitScore = tqiDirectionPointScore.getPointScore();
                    } else {
                        sumUnitScore = sumUnitScore.add(tqiDirectionPointScore.getPointScore());
                    }
                    scoreList.add(tqiDirectionPointScore);


                    // 计算水平得分
                    BigDecimal finalTqiLevel = Convert.toBigDecimal(tqiReport.getLevel()).abs();
                    AnalysisBatchUnitDevicePointScore tqiLevelPointScore = this.createRailVehicleCheckTqiPointScore(analysisBatch, finalTqiLevel, "水平", levelTqi);
                    if (sumUnitScore == null) {
                        sumUnitScore = tqiLevelPointScore.getPointScore();
                    } else {
                        sumUnitScore = sumUnitScore.add(tqiLevelPointScore.getPointScore());
                    }
                    scoreList.add(tqiLevelPointScore);


                    // 计算轨距得分
                    BigDecimal finalTqiTrackGauge = Convert.toBigDecimal(tqiReport.getTrackGauge()).abs();
                    AnalysisBatchUnitDevicePointScore tqiTrackGaugePointScore = this.createRailVehicleCheckTqiPointScore(analysisBatch, finalTqiTrackGauge, "轨距", trackGaugeTqi);
                    if (sumUnitScore == null) {
                        sumUnitScore = tqiTrackGaugePointScore.getPointScore();
                    } else {
                        sumUnitScore = sumUnitScore.add(tqiTrackGaugePointScore.getPointScore());
                    }
                    scoreList.add(tqiTrackGaugePointScore);


                    // 计算三角坑得分
                    BigDecimal finalTqiTriangularPit = Convert.toBigDecimal(tqiReport.getTriangularPit()).abs();
                    AnalysisBatchUnitDevicePointScore tqiTriangularPitScore = this.createRailVehicleCheckTqiPointScore(analysisBatch, finalTqiTriangularPit, "三角坑", triangularPitTqi);
                    if (sumUnitScore == null) {
                        sumUnitScore = tqiTriangularPitScore.getPointScore();
                    } else {
                        sumUnitScore = sumUnitScore.add(tqiTriangularPitScore.getPointScore());
                    }
                    scoreList.add(tqiTriangularPitScore);


                    // 计算tqi得分
                    BigDecimal finalTqi = Convert.toBigDecimal(tqiReport.getTqiComeUpon()).abs();
                    AnalysisBatchUnitDevicePointScore tqiScore = this.createRailVehicleCheckTqiPointScore(analysisBatch, finalTqi, "tqi", tqiComeUponTqi);
                    if (sumUnitScore == null) {
                        sumUnitScore = tqiScore.getPointScore();
                    } else {
                        sumUnitScore = sumUnitScore.add(tqiScore.getPointScore());
                    }
                    scoreList.add(tqiScore);


                    // tqi 超限等级
                    AnalysisBatchUnitDeviceTransfinite tqiTransfinite = this.createRailVehicleCheckTqiTransfinite(dispatchingList, tqiReport, configTqiLimits);
                    if (ObjectUtil.isNotEmpty(tqiTransfinite)) {
                        railVehicleTransfiniteList.add(tqiTransfinite);
                    }

                    // 只映射一个tqi区间，映射到了就直接结束区间循环
                    break;
                }
            }

            unitDevice.put("railVehicleTransfiniteList", railVehicleTransfiniteList);
            unitDevice.put("railVehicleCheckScore", sumUnitScore);
            unitDevice.put("railVehicleCheckScoreList", scoreList);
            unitDevice.put("overReportCheckUnitDeviceMapList", overReportCheckUnitDeviceMapList);
            unitDevice.put("tqiReportCheckUnitDeviceMapList", tqiReportCheckUnitDeviceMapList);
        }


        // 3.先删除旧的关联关系,在新增

        if (ObjectUtil.isNotEmpty(overReportUnitDeviceMaps)) {
            movementOverReportUnitDeviceMapService.lambdaUpdate()
                    .in(MovementOverReportUnitDeviceMap::getUnitId, unitDeviceIds)
                    .remove();
            movementOverReportUnitDeviceMapService.saveBatch(overReportUnitDeviceMaps);
        }

        if (ObjectUtil.isNotEmpty(movementTqiReportUnitDeviceMaps)) {
            movementTqiReportUnitDeviceMapService.lambdaUpdate()
                    .in(MovementTqiReportUnitDeviceMap::getUnitId, unitDeviceIds)
                    .remove();
            movementTqiReportUnitDeviceMapService.saveBatch(movementTqiReportUnitDeviceMaps);
        }
    }

    private AnalysisBatchUnitDeviceTransfinite createRailVehicleCheckTqiTransfinite(JSONArray dispatchingList, MovementTqiReport tqiReport, List<ConfigTqiLimit> configTqiLimits) {
        // 先判断是否超限
        Integer transfiniteGrade = null;
        ConfigTqiLimit currentTqiLimit = null;

        for (ConfigTqiLimit tqiLimit : configTqiLimits) {

            // 1.获取tqi数值
            BigDecimal tqiComeUpon = Convert.toBigDecimal(tqiReport.getTqiComeUpon());
            if (tqiLimit.getTqiMin().compareTo(tqiComeUpon) <= 0 && tqiLimit.getTqiMax().compareTo(tqiComeUpon) >= 0) {
                transfiniteGrade = tqiLimit.getOverStandardType();
                currentTqiLimit = tqiLimit;
                break;
            }
        }

        // 如果没有读取到相应得配置表示不
        if (transfiniteGrade == null) {
            return null;
        }

        int isWork = 1;
        String reasonLabel = "";
        String railVehicleTqiOverGrade = "rail_vehicle_tqi_" + transfiniteGrade;
        for (Object obj : dispatchingList) {
            JSONObject dispatching = (JSONObject) obj;
            Integer type = Convert.toInt(dispatching.get("type"));
            if (type != 3) {
                continue;
            }
            String reasonValue = String.valueOf(dispatching.get("reasonValue"));
            if (reasonValue.equals(railVehicleTqiOverGrade)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                reasonLabel = dispatching.get("reasonLabel").toString();
                if (isWorkTemp) {
                    isWork = 1;
                } else {
                    isWork = 0;
                }
                break;
            }
        }


        // 人工的病害里程:这个格子的(起点里程 + 终点里程)/2
        BigDecimal diseaseMileage = tqiReport.getStartMileage().add(tqiReport.getEndMileage()).divide(new BigDecimal("2"), 3, BigDecimal.ROUND_HALF_UP);


        AnalysisBatchUnitDeviceTransfinite transfinite = new AnalysisBatchUnitDeviceTransfinite();
        transfinite.setId(UUIDGenerator.generate());
        transfinite.setTransfiniteGrade(transfiniteGrade);
        transfinite.setTransfiniteType("Tqi超限");
        String allowValue = currentTqiLimit.getTqiMin() + "< tqi <" + currentTqiLimit.getTqiMax();
        transfinite.setAllowValue(allowValue);
        transfinite.setEkId(tqiReport.getMovementMasterId());
        transfinite.setEkType(3);
        transfinite.setEkItemId(tqiReport.getId());
        transfinite.setMeasurePointValue(tqiReport.getTqiComeUpon());
        transfinite.setIsWork(isWork);
        transfinite.setDiseaseMileage(diseaseMileage);
        transfinite.setTransfiniteGradeName(reasonLabel);


        return transfinite;
    }

    private AnalysisTqiReportCheckUnitDeviceMap tqiReportCheckUnitDeviceMapSave(AnalysisBatchCheckDataMap
                                                                                        checkDataMap, Map<String, Object> unitDevice, MovementTqiReport tqiReport) {
        AnalysisTqiReportCheckUnitDeviceMap record = new AnalysisTqiReportCheckUnitDeviceMap();
        record.setId(UUIDGenerator.generate());
        record.setCheckId(checkDataMap.getEkId());
        record.setCheckType(checkDataMap.getEkType());
        record.setUnitId(Convert.toStr(unitDevice.get("id")));
        record.setUnitCode(Convert.toStr(unitDevice.get("unitCode")));
        record.setUnitType(Convert.toInt(unitDevice.get("type")));
        record.setUnitTypeName(Convert.toStr(unitDevice.get("typeName")));
        record.setUnitStartingMileage(Convert.toBigDecimal(unitDevice.get("startMileage")));
        record.setUnitCenterMileage(Convert.toBigDecimal(unitDevice.get("centerMileage")));
        record.setUnitEndMileage(Convert.toBigDecimal(unitDevice.get("endMileage")));
        record.setTqiReportId(tqiReport.getId());
        record.setStartMileage(tqiReport.getStartMileage());
        record.setEndMileage(tqiReport.getEndMileage());
        record.setSectionName(tqiReport.getSectionName());
        record.setHighLowLeft(tqiReport.getHighLowLeft());
        record.setHighLowRight(tqiReport.getHighLowRight());
        record.setTrackLeft(tqiReport.getTrackLeft());
        record.setTrackRight(tqiReport.getTrackRight());
        record.setLevel(tqiReport.getLevel());
        record.setTrackGauge(tqiReport.getTrackGauge());
        record.setTriangularPit(tqiReport.getTriangularPit());
        record.setTqiComeUpon(tqiReport.getTqiComeUpon());
        record.setTqiAboveStandard(tqiReport.getTqiAboveStandard());
        record.setDeduct(tqiReport.getDeduct());
        record.setStandard(tqiReport.getStandard());
        record.setSpend(tqiReport.getSpend());
        return record;
    }

    private AnalysisOverReportCheckUnitDeviceMap analysisOverReportCheckUnitDeviceMapSave
            (Map<String, Object> unitDevice, AnalysisBatchCheckDataMap checkDataMap, MovementOverReport
                    movementOverReport) {
        AnalysisOverReportCheckUnitDeviceMap record = new AnalysisOverReportCheckUnitDeviceMap();
        record.setId(UUIDGenerator.generate());
        record.setUnitId(Convert.toStr(unitDevice.get("id")));
        record.setUnitCode(Convert.toStr(unitDevice.get("unitCode")));
        record.setUnitType(Convert.toInt(unitDevice.get("type")));
        record.setUnitTypeName(Convert.toStr(unitDevice.get("typeName")));
        record.setUnitStartingMileage(Convert.toBigDecimal(unitDevice.get("startMileage")));
        record.setUnitCenterMileage(Convert.toBigDecimal(unitDevice.get("centerMileage")));
        record.setUnitEndMileage(Convert.toBigDecimal(unitDevice.get("endMileage")));
        record.setCheckId(checkDataMap.getEkId());
        record.setCheckType(checkDataMap.getEkType());
        record.setOverReportId(movementOverReport.getId());
        record.setOverReportMileage(movementOverReport.getMileage());
        record.setOverLevel(Convert.toInt(movementOverReport.getOverrunLevel()));
        record.setOverType(movementOverReport.getOverrunType());
        record.setLongitude(movementOverReport.getLongitude());
        record.setPeakValue(movementOverReport.getPeakValue());
        record.setDataDifference(movementOverReport.getDataDifference());
        record.setXianxing(movementOverReport.getXianxing());
        record.setStandard(movementOverReport.getStandard());
        record.setSpend(movementOverReport.getSpend());
        return record;
    }

    /**
     * 创建轨检车检查数据tqi测点分数
     *
     * @param analysisBatch   分析批次
     * @param finalPointValue 测点值
     * @param pointType       测点类型
     * @param weightValue     测点权值
     * @return
     */
    private AnalysisBatchUnitDevicePointScore createRailVehicleCheckTqiPointScore(AnalysisBatch analysisBatch,
                                                                                  BigDecimal finalPointValue,
                                                                                  String pointType,
                                                                                  BigDecimal weightValue) {
        BigDecimal unitScore = finalPointValue.multiply(weightValue);
        AnalysisBatchUnitDevicePointScore pointScore = new AnalysisBatchUnitDevicePointScore();
        pointScore.setId(UUIDGenerator.generate());
        pointScore.setAnalysisType(analysisBatch.getAnalysisType());
        pointScore.setSpeedMax(analysisBatch.getSpeedMax());
        pointScore.setSpeedMin(analysisBatch.getSpeedMin());
        pointScore.setAnalysisBatchId(analysisBatch.getId());
        pointScore.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
        pointScore.setPointTypeName("轨检车TQI-" + pointType);
        pointScore.setCheckType(3);
        pointScore.setPointValue(finalPointValue);
        pointScore.setWeightValues(weightValue);
        pointScore.setPointScore(unitScore);
        return pointScore;
    }


    /**
     * 创建轨检车测点得分
     */
    private AnalysisBatchUnitDevicePointScore createRailVehicleCheckTransfinitePointScore(AnalysisBatch analysisBatch,
                                                                                          List<MovementOverReport> currentUnitDeviceOverReportList,
                                                                                          String overrunType,
                                                                                          BigDecimal weightValue) {
        if (ObjectUtil.isEmpty(currentUnitDeviceOverReportList)) {
            return null;
        }

        int currentPointSize = 0;
        BigDecimal finalPointValue = null;
        BigDecimal sumPointValue = BigDecimal.ZERO;

        Iterator<MovementOverReport> iterator = currentUnitDeviceOverReportList.iterator();
        while (iterator.hasNext()) {
            MovementOverReport currentUnitDeviceOverReport = iterator.next();
            if (currentUnitDeviceOverReport.getOverrunType().contains(overrunType)) {
                BigDecimal currentPointValue = Convert.toBigDecimal(currentUnitDeviceOverReport.getPeakValue()).abs();
                sumPointValue = sumPointValue.add(currentPointValue);
                currentPointSize++;

                if (1 == analysisBatch.getAnalysisType()) {
                    // 均值
                    finalPointValue = sumPointValue.divide(new BigDecimal(currentPointSize), 3, BigDecimal.ROUND_HALF_UP);
                } else {
                    // 峰值
                    if (finalPointValue == null) {
                        finalPointValue = currentPointValue;
                    } else if (finalPointValue.compareTo(currentPointValue) < 0) {
                        finalPointValue = currentPointValue;
                    }
                }

                // 处理过的直接移除
                iterator.remove();
            }
        }

        AnalysisBatchUnitDevicePointScore pointScore = null;
        if (ObjectUtil.isNotEmpty(finalPointValue)) {
            BigDecimal unitScore = finalPointValue.multiply(weightValue);

            pointScore = new AnalysisBatchUnitDevicePointScore();
            pointScore.setId(UUIDGenerator.generate());
            pointScore.setAnalysisType(analysisBatch.getAnalysisType());
            pointScore.setSpeedMax(analysisBatch.getSpeedMax());
            pointScore.setSpeedMin(analysisBatch.getSpeedMin());
            pointScore.setAnalysisBatchId(analysisBatch.getId());
            pointScore.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
            pointScore.setPointTypeName("轨检车超限-" + overrunType);
            pointScore.setCheckType(3);
            pointScore.setPointValue(finalPointValue);
            pointScore.setWeightValues(weightValue);
            pointScore.setPointScore(unitScore);
        }


        return pointScore;
    }

    /**
     * @param dispatchingList
     * @param movementOverReport
     * @return
     */
    private AnalysisBatchUnitDeviceTransfinite railVehicleCheckTransfinite(JSONArray dispatchingList, MovementOverReport movementOverReport) {

        boolean isDisplay = false;
        int isWork = 1;
        String reasonLabel = "";
        Integer transfiniteGrade = Convert.toInt(movementOverReport.getOverrunLevel());
        String railVehicleOverGrade = "rail_vehicle_over_" + transfiniteGrade;
        for (Object obj : dispatchingList) {
            JSONObject dispatching = (JSONObject) obj;
            Integer type = Convert.toInt(dispatching.get("type"));
            if (type != 3) {
                continue;
            }
            String reasonValue = String.valueOf(dispatching.get("reasonValue"));
            if (reasonValue.equals(railVehicleOverGrade)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                reasonLabel = dispatching.get("reasonLabel").toString();
                if (isWorkTemp) {
                    isWork = 1;
                } else {
                    isWork = 0;
                }
                isDisplay = true;
                break;
            }
        }

        // 如果没有读取到相应得配置表示不用
        if (!isDisplay) {
            return null;
        }

        AnalysisBatchUnitDeviceTransfinite transfinite = new AnalysisBatchUnitDeviceTransfinite();
        transfinite.setId(UUIDGenerator.generate());
        transfinite.setTransfiniteGrade(transfiniteGrade);
        transfinite.setTransfiniteType(movementOverReport.getOverrunType());
        String allowValue = Convert.toBigDecimal(movementOverReport.getPeakValue()).subtract(Convert.toBigDecimal(movementOverReport.getDataDifference())).toString();
        transfinite.setAllowValue(allowValue);
        transfinite.setEkId(movementOverReport.getMovementMasterId());
        transfinite.setEkType(3);
        transfinite.setEkItemId(movementOverReport.getId());
        transfinite.setMeasurePointValue(movementOverReport.getPeakValue());
        transfinite.setIsWork(isWork);
        transfinite.setDiseaseMileage(movementOverReport.getMileage().multiply(new BigDecimal("1000")));
        transfinite.setTransfiniteGradeName(reasonLabel);


        return transfinite;
    }

    /**
     * 轨检仪检查数据分析
     */
    private void railDeviceCheckDataAnalysis(AnalysisBatch analysisBatch, AnalysisBatchCheckDataMap
            checkDataMap, List<Map<String, Object>> unitDeviceList) {
        List<MovementCheckDataUnitDeviceMap> movementCheckDataUnitDeviceMaps = new ArrayList<>();


        // 1.1 获取轨检仪静态检查
        List<RailInspectionEquipmentItem> checkItemList = railInspectionEquipmentItemService.lambdaQuery()
                .eq(RailInspectionEquipmentItem::getRailInspectionEquipmentId, checkDataMap.getEkId())
                .orderByAsc(RailInspectionEquipmentItem::getCourseStartingMileage)
                .list();
        List<RailInspectionEquipmentItemDetail> checkItemItemDetailList = railInspectionEquipmentItemDetailService.lambdaQuery().eq(RailInspectionEquipmentItemDetail::getRailInspectionEquipmentId, checkDataMap.getEkId()).list();
        Map<String, List<RailInspectionEquipmentItemDetail>> checkItemItemDetailMap = checkItemItemDetailList.stream().collect(Collectors.groupingBy(RailInspectionEquipmentItemDetail::getRailInspectionEquipmentItemId));

        // 1.2 处理检查项目的开始-结束里程
        for (RailInspectionEquipmentItem checkItem : checkItemList) {
            // 1.2 处理检查项目是公里的情况
            BigDecimal checkItemStartingMileage = checkItem.getCourseStartingMileage().multiply(new BigDecimal("1000"));
            BigDecimal checkItemEndMileage = checkItem.getCourseEndMileage().multiply(new BigDecimal("1000"));
            // 如果 开始里程>结束里程 就两两交换位置
            if (checkItemStartingMileage.compareTo(checkItemEndMileage) > 0) {
                BigDecimal tempMileage = checkItemStartingMileage;
                checkItemStartingMileage = checkItemEndMileage;
                checkItemEndMileage = tempMileage;
            }

            checkItem.setCourseStartingMileage(checkItemStartingMileage);
            checkItem.setCourseEndMileage(checkItemEndMileage);
        }


        // 2.循环单元设备根据单元设备的中心里程落在检查项目【开始-结束】这个区间视为这个区间的单元设备第第一个就行了
        for (Map<String, Object> unitDevice : unitDeviceList) {

            BigDecimal centerMileage = Convert.toBigDecimal(unitDevice.get("centerMileage"));
            // 2.1  循环遍历检查项目比较【开始-结束】来映射关联关系
            for (RailInspectionEquipmentItem checkItem : checkItemList) {
                BigDecimal checkItemStartingMileage = checkItem.getCourseStartingMileage();
                BigDecimal checkItemEndMileage = checkItem.getCourseEndMileage();


                // 2.2.1 命中检查项目
                if (checkItemStartingMileage.compareTo(centerMileage) <= 0 && checkItemEndMileage.compareTo(centerMileage) > 0) {
                    List<RailInspectionEquipmentItemDetail> movementCourseInfos = checkItemItemDetailMap.get(checkItem.getId());
                    // 按照检查项目聚合
                    Map<String, List<RailInspectionEquipmentItemDetail>> trackCodeMap = movementCourseInfos.stream().collect(Collectors.groupingBy(
                            // 处理一下“标示里程：20.100” 中文字符
                            record -> StrUtil.extractTextToNumber(record.getCheckItem()).toString()));
                    int size = trackCodeMap.size();
                    BigDecimal averageDec = checkItemEndMileage.subtract(checkItemStartingMileage).divide(new BigDecimal(size), 3, RoundingMode.HALF_UP);
                    List<String> trackCodes = trackCodeMap.keySet().stream().map(BigDecimal::new).sorted().map(BigDecimal::toString).collect(Collectors.toList());
                    BigDecimal currentStartMileage = checkItemStartingMileage;
                    BigDecimal currentEndEndMileage = checkItemStartingMileage.add(averageDec);


                    // 2.循环来命中格子
                    for (String trackCode : trackCodes) {
                        if (currentStartMileage.compareTo(centerMileage) <= 0 && currentEndEndMileage.compareTo(centerMileage) > 0) {
                            // 轨检仪检查数据
                            List<RailInspectionEquipmentItemDetail> railDeviceCheckList = trackCodeMap.get(trackCode);
                            List<AnalysisBatchUnitDeviceTransfinite> transfiniteList = new ArrayList<>();
                            List<AnalysisRailDeviceCheckDataUnitDeviceMap> railDeviceCheckDataUnitDeviceMapList = new ArrayList<>();

                            // 循环处理测点数据
                            for (RailInspectionEquipmentItemDetail movementCourseInfo : railDeviceCheckList) {
                                // 计算超限:如果为null则计算,否则和单元绑定
                                movementCourseInfo.setCurrentStartMileage(currentStartMileage);
                                movementCourseInfo.setCurrentEndEndMileage(currentEndEndMileage);

                                // 保存检查数据-单元关联关系
                                MovementCheckDataUnitDeviceMap map = this.railDeviceCheckDeviceMapSave(movementCourseInfo, unitDevice, checkItem);
                                map.setCheckDetailStartingMileage(currentStartMileage);
                                map.setCheckDetailEndMileage(currentEndEndMileage);
                                movementCheckDataUnitDeviceMaps.add(map);

                                // 静态检查数据和分析批次关联
                                AnalysisRailDeviceCheckDataUnitDeviceMap railDeviceCheckDataUnitDeviceMap = this.railDeviceCheckDataUnitDeviceMapSave(movementCourseInfo, unitDevice, checkItem);
                                railDeviceCheckDataUnitDeviceMapList.add(railDeviceCheckDataUnitDeviceMap);


//                                AnalysisBatchUnitDeviceTransfinite transfinite = this.railDeviceCheckTransfinite(analysisBatch, movementCourseInfo);
//                                if (transfinite != null) {
//                                    transfiniteList.add(transfinite);
//                                }
                                List<AnalysisBatchUnitDeviceTransfinite> innerTransfiniteList = this.railDeviceCheckTransfiniteList(analysisBatch, movementCourseInfo);
                                if (ObjectUtil.isNotEmpty(innerTransfiniteList)) {
                                    transfiniteList.addAll(innerTransfiniteList);
                                }


                            }

                            // 计算得分
                            this.railDeviceCheckScore(analysisBatch, railDeviceCheckList, unitDevice);

                            // 超限数据
                            unitDevice.put("railDeviceTransfinite", transfiniteList);
                            // 检查list
                            unitDevice.put("railDeviceCheck", railDeviceCheckList);
                            // 检查list
                            unitDevice.put("railDeviceCheckDataUnitDeviceMapList", railDeviceCheckDataUnitDeviceMapList);
                        }
                        currentStartMileage = currentEndEndMileage;
                        currentEndEndMileage = currentEndEndMileage.add(averageDec);
                    }

                    break;
                }
            }
        }

        if (ObjectUtil.isNotEmpty(movementCheckDataUnitDeviceMaps)) {
            movementCheckDataUnitDeviceMapService.lambdaUpdate().eq(MovementCheckDataUnitDeviceMap::getCheckId, checkDataMap.getEkId()).remove();
            movementCheckDataUnitDeviceMapService.saveBatch(movementCheckDataUnitDeviceMaps);
        }
    }

    private List<AnalysisBatchUnitDeviceTransfinite> railDeviceCheckTransfiniteList(AnalysisBatch analysisBatch, RailInspectionEquipmentItemDetail movementCourseInfo) {
        // 超限配置
        JSONObject allowValue = JSONObject.parseObject(analysisBatch.getAllowValue());
        BigDecimal bigTrackGauge = Convert.toBigDecimal(allowValue.get("bigTrackGauge")); // 大轨距
        BigDecimal smallTrackGauge = Convert.toBigDecimal(allowValue.get("smallTrackGauge")); // 小轨距
        BigDecimal allowLevel = Convert.toBigDecimal(allowValue.get("level")); // 水平
        BigDecimal allowTriangularPit = Convert.toBigDecimal(allowValue.get("triangularPit")); // 三角坑

        // 是否派工配置
        Integer isWork = 1;
        String reasonLabel = "轨检仪检查数据-超限";
        JSONArray dispatchingList = JSONArray.parseArray(analysisBatch.getDispatching());
        for (Object obj : dispatchingList) {
            JSONObject dispatching = (JSONObject) obj;
            Integer type = Convert.toInt(dispatching.get("type"));
            if (type != 1) {
                continue;
            }
            String reasonValue = String.valueOf(dispatching.get("reasonValue"));
            if ("static_limit".equals(reasonValue)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWork = 1;
                } else {
                    isWork = 0;
                }
            }
        }

        // 轨仪器的病害里程:这个格子的(起点里程 + 终点里程)/2
        BigDecimal diseaseMileage = movementCourseInfo.getCurrentStartMileage().add(movementCourseInfo.getCurrentEndEndMileage()).divide(new BigDecimal("2"), 3, BigDecimal.ROUND_HALF_UP);


        String allowValueSave = "";
        String measurePointValue = "";
        String transfiniteType = "";

        List<AnalysisBatchUnitDeviceTransfinite> transfiniteList = new ArrayList<>();

        // 轨距
        BigDecimal trackGauge = Convert.toBigDecimal(movementCourseInfo.getTrackGauge());
        if (ObjectUtil.isNotEmpty(trackGauge)) {
            if (trackGauge.compareTo(bigTrackGauge) > 0) {
                allowValueSave = bigTrackGauge.toString();
                measurePointValue = trackGauge.toString();
                transfiniteType = "大轨距";


                AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
                record.setId(UUIDGenerator.generate());
                record.setTransfiniteGrade(1);
                record.setTransfiniteGradeName(reasonLabel);
                record.setTransfiniteType(transfiniteType);
                record.setAllowValue(allowValueSave);
                record.setEkId(movementCourseInfo.getRailInspectionEquipmentId());
                record.setEkType(2);
                record.setEkItemId(movementCourseInfo.getRailInspectionEquipmentItemId());
                record.setMeasurePointValue(measurePointValue);
                record.setIsWork(isWork);
                record.setDiseaseMileage(diseaseMileage);
                transfiniteList.add(record);

            } else if (trackGauge.compareTo(smallTrackGauge) < 0) {
                allowValueSave = smallTrackGauge.toString();
                measurePointValue = trackGauge.toString();
                transfiniteType = "小轨距";

                AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
                record.setId(UUIDGenerator.generate());
                record.setTransfiniteGrade(1);
                record.setTransfiniteGradeName(reasonLabel);
                record.setTransfiniteType(transfiniteType);
                record.setAllowValue(allowValueSave);
                record.setEkId(movementCourseInfo.getRailInspectionEquipmentId());
                record.setEkType(2);
                record.setEkItemId(movementCourseInfo.getRailInspectionEquipmentItemId());
                record.setMeasurePointValue(measurePointValue);
                record.setIsWork(isWork);
                record.setDiseaseMileage(diseaseMileage);
                transfiniteList.add(record);
            }
        }


        // 水平
        BigDecimal level = Convert.toBigDecimal(movementCourseInfo.getLevel());
        if (ObjectUtil.isNotEmpty(level)) {
            if (level.compareTo(allowLevel) > 0) {
                allowValueSave = allowLevel.toString();
                measurePointValue = level.toString();
                transfiniteType = "水平";

                AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
                record.setId(UUIDGenerator.generate());
                record.setTransfiniteGrade(1);
                record.setTransfiniteGradeName(reasonLabel);
                record.setTransfiniteType(transfiniteType);
                record.setAllowValue(allowValueSave);
                record.setEkId(movementCourseInfo.getRailInspectionEquipmentId());
                record.setEkType(2);
                record.setEkItemId(movementCourseInfo.getRailInspectionEquipmentItemId());
                record.setMeasurePointValue(measurePointValue);
                record.setIsWork(isWork);
                record.setDiseaseMileage(diseaseMileage);
                transfiniteList.add(record);
            }
        }

        //三角坑
        BigDecimal triangularPit = Convert.toBigDecimal(movementCourseInfo.getTriangularPit());
        if (ObjectUtil.isNotEmpty(triangularPit)) {
            if (triangularPit.compareTo(allowTriangularPit) > 0) {
                allowValueSave = allowTriangularPit.toString();
                measurePointValue = triangularPit.toString();
                transfiniteType = "三角坑";

                AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
                record.setId(UUIDGenerator.generate());
                record.setTransfiniteGrade(1);
                record.setTransfiniteGradeName(reasonLabel);
                record.setTransfiniteType(transfiniteType);
                record.setAllowValue(allowValueSave);
                record.setEkId(movementCourseInfo.getRailInspectionEquipmentId());
                record.setEkType(2);
                record.setEkItemId(movementCourseInfo.getRailInspectionEquipmentItemId());
                record.setMeasurePointValue(measurePointValue);
                record.setIsWork(isWork);
                record.setDiseaseMileage(diseaseMileage);
                transfiniteList.add(record);
            }
        }

        return transfiniteList;
    }

    private AnalysisRailDeviceCheckDataUnitDeviceMap railDeviceCheckDataUnitDeviceMapSave
            (RailInspectionEquipmentItemDetail
                     movementCourseInfo, Map<String, Object> unitDevice, RailInspectionEquipmentItem checkItem) {
        AnalysisRailDeviceCheckDataUnitDeviceMap record = new AnalysisRailDeviceCheckDataUnitDeviceMap();
        record.setId(UUIDGenerator.generate());
        record.setUnitId(Convert.toStr(unitDevice.get("id")));
        record.setUnitCode(Convert.toStr(unitDevice.get("unitCode")));
        record.setUnitType(Convert.toInt(unitDevice.get("type")));
        record.setUnitTypeName(Convert.toStr(unitDevice.get("typeName")));
        record.setUnitStartingMileage(Convert.toBigDecimal(unitDevice.get("startMileage")));
        record.setUnitCenterMileage(Convert.toBigDecimal(unitDevice.get("centerMileage")));
        record.setUnitEndMileage(Convert.toBigDecimal(unitDevice.get("endMileage")));
        record.setCheckId(checkItem.getRailInspectionEquipmentId());
        record.setCheckItemId(checkItem.getRailInspectionEquipmentId());
        record.setCheckItemStartingMileage(checkItem.getCourseStartingMileage());
        record.setCheckItemEndMileage(checkItem.getCourseEndMileage());
        record.setCheckItemText(movementCourseInfo.getCheckItem());
        record.setCheckDetailId(movementCourseInfo.getId());
        record.setCheckDetailStartingMileage(movementCourseInfo.getCurrentStartMileage());
        record.setCheckDetailEndMileage(movementCourseInfo.getCurrentEndEndMileage());
        record.setTrackGauge(movementCourseInfo.getTrackGauge());
        record.setLevel(movementCourseInfo.getLevel());
        record.setTriangularPit(movementCourseInfo.getTriangularPit());
        record.setMeasurePoint(movementCourseInfo.getMeasurePoint());
        record.setCheckDetailStartingMileage(movementCourseInfo.getCurrentStartMileage());
        record.setCheckDetailEndMileage(movementCourseInfo.getCurrentEndEndMileage());
        return record;
    }

    /**
     * 轨检仪检查数据分数
     */
    private void railDeviceCheckScore(AnalysisBatch
                                              analysisBatch, List<RailInspectionEquipmentItemDetail> railDeviceCheckList, Map<String, Object> unitDevice) {
        Integer analysisType = analysisBatch.getAnalysisType();

        BigDecimal finalTrackGauge = null;
        BigDecimal finalTriangularPit = null;
        BigDecimal finalLevel = null;

        BigDecimal sumTrackGauge = BigDecimal.ZERO;
        BigDecimal sumTriangularPit = BigDecimal.ZERO;
        BigDecimal sumLevel = BigDecimal.ZERO;

        BigDecimal maxTrackGauge = BigDecimal.ZERO;
        BigDecimal maxTriangularPit = BigDecimal.ZERO;
        BigDecimal maxLevel = BigDecimal.ZERO;

        BigDecimal avgTrackGauge;
        BigDecimal avgTriangularPit;
        BigDecimal avgLevel;


        int trackGaugeSize = 0;
        int triangularPitSize = 0;
        int levelSize = 0;

        int scale = 3; // 保留3位小数

        // 循环计算均值/峰值
        for (RailInspectionEquipmentItemDetail movementCourseInfo : railDeviceCheckList) {
            // 轨距
            BigDecimal trackGauge = Convert.toBigDecimal(movementCourseInfo.getTrackGauge());
            if (ObjectUtil.isNotEmpty(trackGauge)) {
                trackGauge = trackGauge.abs();
                // 均值
                sumTrackGauge = sumTrackGauge.add(trackGauge);
                trackGaugeSize++;
                avgTrackGauge = sumTrackGauge.divide(new BigDecimal(trackGaugeSize), scale, BigDecimal.ROUND_HALF_UP);
                // 峰值
                if (trackGauge.compareTo(maxTrackGauge) > 0) {
                    maxTrackGauge = trackGauge;
                }

                if (1 == analysisType) {
                    finalTrackGauge = avgTrackGauge;
                } else {
                    finalTrackGauge = maxTrackGauge;
                }

            }

            // 水平
            BigDecimal level = Convert.toBigDecimal(movementCourseInfo.getLevel());
            if (ObjectUtil.isNotEmpty(level)) {
                level = level.abs();
                // 均值
                sumLevel = sumLevel.add(level);
                levelSize++;
                avgLevel = sumLevel.divide(new BigDecimal(levelSize), scale, BigDecimal.ROUND_HALF_UP);
                // 峰值
                if (level.compareTo(maxLevel) > 0) {
                    maxLevel = level;
                }

                if (1 == analysisType) {
                    finalLevel = avgLevel;
                } else {
                    finalLevel = maxLevel;
                }
            }

            //三角坑
            BigDecimal triangularPit = Convert.toBigDecimal(movementCourseInfo.getTriangularPit());
            if (ObjectUtil.isNotEmpty(triangularPit)) {
                triangularPit = triangularPit.abs();
                // 均值
                sumTriangularPit = sumTriangularPit.add(triangularPit);
                triangularPitSize++;
                avgTriangularPit = sumTriangularPit.divide(new BigDecimal(triangularPitSize), scale, BigDecimal.ROUND_HALF_UP);
                // 峰值
                if (triangularPit.compareTo(maxTriangularPit) > 0) {
                    maxTriangularPit = triangularPit;
                }

                if (1 == analysisType) {
                    finalTriangularPit = avgTriangularPit;
                } else {
                    finalTriangularPit = maxTriangularPit;
                }
            }
        }


        ConfigRailDeviceCheck configRailDevice = configRailDeviceCheckService.lambdaQuery().eq(ConfigRailDeviceCheck::getSpeedMax, analysisBatch.getSpeedMax()).eq(ConfigRailDeviceCheck::getSpeedMin, analysisBatch.getSpeedMin()).eq(ConfigRailDeviceCheck::getDelFlag, "0").last("limit 1").one();

        // 1-钢轨,2-曲线,3-竖曲线,4-道岔
        Integer type = Convert.toInt(unitDevice.get("type"));
        JSONObject jsonObject = null;
        if (type == 1) {
            jsonObject = JSONObject.parseObject(configRailDevice.getRail());
        } else if (type == 2) {
            jsonObject = JSONObject.parseObject(configRailDevice.getCurve());
        } else if (type == 3) {
            jsonObject = JSONObject.parseObject(configRailDevice.getVerticalCurve());
        } else if (type == 4) {
            jsonObject = JSONObject.parseObject(configRailDevice.getRailSwitch());
        }


        BigDecimal trackGaugeWeightValues = jsonObject.getBigDecimal("trackGauge");
        BigDecimal levelWeightValues = jsonObject.getBigDecimal("level");
        BigDecimal triangularPitWeightValues = jsonObject.getBigDecimal("triangularPit");
        // 总单元得分
        BigDecimal sumUnitScore = null;

        // 轨距单元得分
        BigDecimal trackGaugeUnitScore = null;
        List<AnalysisBatchUnitDevicePointScore> scoreList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(finalTrackGauge)) {
            trackGaugeUnitScore = trackGaugeWeightValues.multiply(new BigDecimal(finalTrackGauge.toString()));
            if (sumUnitScore == null) {
                sumUnitScore = BigDecimal.ZERO;
            }
            sumUnitScore = sumUnitScore.add(trackGaugeUnitScore);

            AnalysisBatchUnitDevicePointScore score = new AnalysisBatchUnitDevicePointScore();
            score.setId(UUIDGenerator.generate());
            score.setAnalysisType(analysisType);
            score.setSpeedMax(analysisBatch.getSpeedMax());
            score.setSpeedMin(analysisBatch.getSpeedMin());
            score.setAnalysisBatchId(analysisBatch.getId());
            score.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
            score.setPointTypeName("轨距");
            score.setCheckType(2);
            score.setPointValue(finalTrackGauge);
            score.setWeightValues(trackGaugeWeightValues);
            score.setPointScore(trackGaugeUnitScore);
            scoreList.add(score);
        }

        // 水平单元得分
        BigDecimal levelUnitScore;
        if (ObjectUtil.isNotEmpty(finalLevel)) {
            levelUnitScore = levelWeightValues.multiply(new BigDecimal(finalLevel.toString()));
            if (sumUnitScore == null) {
                sumUnitScore = BigDecimal.ZERO;
            }
            sumUnitScore = sumUnitScore.add(levelUnitScore);

            AnalysisBatchUnitDevicePointScore score = new AnalysisBatchUnitDevicePointScore();
            score.setId(UUIDGenerator.generate());
            score.setAnalysisType(analysisType);
            score.setSpeedMax(analysisBatch.getSpeedMax());
            score.setSpeedMin(analysisBatch.getSpeedMin());
            score.setAnalysisBatchId(analysisBatch.getId());
            score.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
            score.setPointTypeName("高低");
            score.setCheckType(2);
            score.setPointValue(finalLevel);
            score.setWeightValues(levelWeightValues);
            score.setPointScore(levelUnitScore);
            scoreList.add(score);
        }

        // 三角坑单元得分
        BigDecimal triangularPitGaugeUnitScore;
        if (ObjectUtil.isNotEmpty(finalTriangularPit)) {
            triangularPitGaugeUnitScore = triangularPitWeightValues.multiply(new BigDecimal(finalTriangularPit.toString()));
            if (sumUnitScore == null) {
                sumUnitScore = BigDecimal.ZERO;
            }
            sumUnitScore = sumUnitScore.add(triangularPitGaugeUnitScore);

            AnalysisBatchUnitDevicePointScore score = new AnalysisBatchUnitDevicePointScore();
            score.setId(UUIDGenerator.generate());
            score.setAnalysisType(analysisType);
            score.setSpeedMax(analysisBatch.getSpeedMax());
            score.setSpeedMin(analysisBatch.getSpeedMin());
            score.setAnalysisBatchId(analysisBatch.getId());
            score.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
            score.setPointTypeName("三角坑");
            score.setCheckType(2);
            score.setPointValue(finalTriangularPit);
            score.setWeightValues(triangularPitWeightValues);
            score.setPointScore(triangularPitGaugeUnitScore);
            scoreList.add(score);
        }

        unitDevice.put("railDeviceCheckScore", sumUnitScore);
        unitDevice.put("railDeviceCheckScoreList", scoreList);
    }

    /**
     * 轨检仪检查数据超限
     */
    private AnalysisBatchUnitDeviceTransfinite railDeviceCheckTransfinite(AnalysisBatch
                                                                                  analysisBatch, RailInspectionEquipmentItemDetail movementCourseInfo) {
        // 超限配置
        JSONObject allowValue = JSONObject.parseObject(analysisBatch.getAllowValue());
        Integer bigTrackGauge = Convert.toInt(allowValue.get("bigTrackGauge")); // 大轨距
        Integer smallTrackGauge = Convert.toInt(allowValue.get("smallTrackGauge")); // 小轨距
        Integer allowLevel = Convert.toInt(allowValue.get("level")); // 水平
        Integer allowTriangularPit = Convert.toInt(allowValue.get("triangularPit")); // 三角坑

        // 是否派工配置
        Integer isWork = 1;
        String reasonLabel = "轨检仪检查数据-超限";
        JSONArray dispatchingList = JSONArray.parseArray(analysisBatch.getDispatching());
        for (Object obj : dispatchingList) {
            JSONObject dispatching = (JSONObject) obj;
            Integer type = Convert.toInt(dispatching.get("type"));
            if (type != 1) {
                continue;
            }
            String reasonValue = String.valueOf(dispatching.get("reasonValue"));
            if ("static_limit".equals(reasonValue)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWork = 1;
                } else {
                    isWork = 0;
                }
            }
        }


        boolean isTransfinite = false;
        String allowValueSave = "";
        String measurePointValue = "";
        String transfiniteType = "";

        // 轨距
        Integer trackGauge = Convert.toInt(movementCourseInfo.getTrackGauge());
        if (ObjectUtil.isNotEmpty(trackGauge)) {
            if (trackGauge > bigTrackGauge) {
                isTransfinite = true;
                allowValueSave = bigTrackGauge.toString();
                measurePointValue = trackGauge.toString();
                transfiniteType = "大轨距";
            } else if (trackGauge < smallTrackGauge) {
                isTransfinite = true;
                allowValueSave = smallTrackGauge.toString();
                measurePointValue = trackGauge.toString();
                transfiniteType = "小轨距";
            }
        }


        // 水平
        Integer level = Convert.toInt(movementCourseInfo.getLevel());
        if (ObjectUtil.isNotEmpty(level)) {
            if (level > allowLevel) {
                isTransfinite = true;
                allowValueSave = allowLevel.toString();
                measurePointValue = level.toString();
                transfiniteType = "水平";
            }
        }

        //三角坑
        Integer triangularPit = Convert.toInt(movementCourseInfo.getTriangularPit());
        if (ObjectUtil.isNotEmpty(triangularPit)) {
            if (triangularPit > allowTriangularPit) {
                isTransfinite = true;
                allowValueSave = allowTriangularPit.toString();
                measurePointValue = triangularPit.toString();
                transfiniteType = "三角坑";
            }
        }

        // 轨仪器的病害里程:这个格子的(起点里程 + 终点里程)/2
        BigDecimal diseaseMileage = movementCourseInfo.getCurrentStartMileage().add(movementCourseInfo.getCurrentEndEndMileage()).divide(new BigDecimal("2"), 3, BigDecimal.ROUND_HALF_UP);


        // 超限
        if (isTransfinite) {
            AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
            record.setId(UUIDGenerator.generate());
            record.setTransfiniteGrade(1);
            record.setTransfiniteGradeName(reasonLabel);
            record.setTransfiniteType(transfiniteType);
            record.setAllowValue(allowValueSave);
            record.setEkId(movementCourseInfo.getRailInspectionEquipmentId());
            record.setEkType(2);
            record.setEkItemId(movementCourseInfo.getRailInspectionEquipmentItemId());
            record.setMeasurePointValue(measurePointValue);
            record.setIsWork(isWork);
            record.setDiseaseMileage(diseaseMileage);
            return record;
        } else {
            return null;
        }
    }


    /**
     * 轨检仪检查
     */
    private MovementCheckDataUnitDeviceMap railDeviceCheckDeviceMapSave(RailInspectionEquipmentItemDetail
                                                                                movementCourseInfo, Map<String, Object> unitDevice, RailInspectionEquipmentItem checkItem) {
        MovementCheckDataUnitDeviceMap movementCheckDataUnitDeviceMap = new MovementCheckDataUnitDeviceMap();
        movementCheckDataUnitDeviceMap.setId(UUIDGenerator.generate());
        movementCheckDataUnitDeviceMap.setCheckType(2);// 2-轨检仪静态检查
        movementCheckDataUnitDeviceMap.setUnitId(Convert.toStr(unitDevice.get("id")));
        movementCheckDataUnitDeviceMap.setUnitCode(Convert.toStr(unitDevice.get("unitCode")));
        movementCheckDataUnitDeviceMap.setUnitType(Convert.toInt(unitDevice.get("type")));
        movementCheckDataUnitDeviceMap.setUnitTypeName(Convert.toStr(unitDevice.get("typeName")));
        movementCheckDataUnitDeviceMap.setUnitStartingMileage(Convert.toBigDecimal(unitDevice.get("startMileage")));
        movementCheckDataUnitDeviceMap.setUnitCenterMileage(Convert.toBigDecimal(unitDevice.get("centerMileage")));
        movementCheckDataUnitDeviceMap.setUnitEndMileage(Convert.toBigDecimal(unitDevice.get("endMileage")));
        movementCheckDataUnitDeviceMap.setCheckId(checkItem.getRailInspectionEquipmentId());
        movementCheckDataUnitDeviceMap.setCheckItemId(checkItem.getRailInspectionEquipmentId());
        movementCheckDataUnitDeviceMap.setCheckItemStartingMileage(checkItem.getCourseStartingMileage());
        movementCheckDataUnitDeviceMap.setCheckItemEndMileage(checkItem.getCourseEndMileage());
        movementCheckDataUnitDeviceMap.setCheckItemText(movementCourseInfo.getCheckItem());
        movementCheckDataUnitDeviceMap.setCheckDetailId(movementCourseInfo.getId());
        movementCheckDataUnitDeviceMap.setCheckDetailStartingMileage(movementCourseInfo.getCurrentStartMileage());
        movementCheckDataUnitDeviceMap.setCheckDetailEndMileage(movementCourseInfo.getCurrentEndEndMileage());
        movementCheckDataUnitDeviceMap.setTrackGauge(movementCourseInfo.getTrackGauge());
        movementCheckDataUnitDeviceMap.setLevel(movementCourseInfo.getLevel());
        movementCheckDataUnitDeviceMap.setTriangularPit(movementCourseInfo.getTriangularPit());
        movementCheckDataUnitDeviceMap.setMeasurePoint(movementCourseInfo.getMeasurePoint());
        return movementCheckDataUnitDeviceMap;

    }

    /**
     * 人工检查数据分析
     */
    public void labourCheckDataAnalysis(AnalysisBatch analysisBatch, AnalysisBatchCheckDataMap
            checkDataMap, List<Map<String, Object>> unitDeviceList) {
        List<MovementCheckDataUnitDeviceMap> movementCheckDataUnitDeviceMaps = new ArrayList<>();
        // 1 获取人工检查数据
        List<MovementCourse> checkItemList = movementCourseService.lambdaQuery().eq(MovementCourse::getMovementMasterId, checkDataMap.getEkId()).list();
        List<MovementCourseInfo> checkItemItemDetailList = movementCourseInfoService.lambdaQuery().eq(MovementCourseInfo::getMovementMasterId, checkDataMap.getEkId()).list();
        Map<String, List<MovementCourseInfo>> checkItemItemDetailMap = checkItemItemDetailList.stream().collect(Collectors.groupingBy(MovementCourseInfo::getMovementCourseId));


        // 2.循环遍历单元设备中心里程落在检查项目【开始-结束】这个区间视为这个区间的单元设备数
        for (Map<String, Object> unitDevice : unitDeviceList) {
            BigDecimal centerMileage = Convert.toBigDecimal(unitDevice.get("centerMileage"));

            // 循环遍历检查项目比较【开始-结束】来映射关联关系
            for (MovementCourse checkItem : checkItemList) {
                // 这里可能出现开始时间比结束时间大的情况
                BigDecimal checkItemStartingMileage = checkItem.getCourseStartingMileage();
                BigDecimal checkItemEndMileage = checkItem.getCourseEndMileage();
                if (checkItemStartingMileage.compareTo(checkItemEndMileage) > 0) {
                    checkItemStartingMileage = checkItem.getCourseEndMileage();
                    checkItemEndMileage = checkItem.getCourseStartingMileage();
                }

                // 2.2.1 命中检查项目
                if (checkItemStartingMileage.compareTo(centerMileage) <= 0 && checkItemEndMileage.compareTo(centerMileage) > 0) {
                    List<MovementCourseInfo> movementCourseInfos = checkItemItemDetailMap.get(checkItem.getId());
                    // 1 处理3个格子映射问题
                    Map<String, List<MovementCourseInfo>> trackCodeMap = movementCourseInfos.stream().collect(Collectors.groupingBy(MovementCourseInfo::getTrackCode));
                    int size = trackCodeMap.size();
                    BigDecimal averageDec = checkItemEndMileage.subtract(checkItemStartingMileage).divide(new BigDecimal(size), 3, RoundingMode.HALF_UP);
                    List<String> trackCodes = trackCodeMap.keySet().stream().mapToInt(Integer::valueOf).sorted().mapToObj(String::valueOf).collect(Collectors.toList());
                    BigDecimal currentStartMileage = checkItemStartingMileage;
                    BigDecimal currentEndEndMileage = checkItemStartingMileage.add(averageDec);

                    // 2.循环来命中格子
                    for (String trackCode : trackCodes) {
                        if (currentStartMileage.compareTo(centerMileage) <= 0 && currentEndEndMileage.compareTo(centerMileage) > 0) {
                            List<MovementCourseInfo> labourCheckList = trackCodeMap.get(trackCode);
                            List<AnalysisBatchUnitDeviceTransfinite> transfiniteList = new ArrayList<>();
                            List<AnalysisLabourCheckDataUnitDeviceMap> labourCheckDataUnitDeviceMapList = new ArrayList<>();

                            // 循环处理测点数据
                            for (MovementCourseInfo movementCourseInfo : labourCheckList) {
                                // 保存数据
                                movementCourseInfo.setCurrentStartMileage(currentStartMileage);
                                movementCourseInfo.setCurrentEndEndMileage(currentEndEndMileage);

                                MovementCheckDataUnitDeviceMap map = this.labourCheckDeviceMapSave(movementCourseInfo, unitDevice, checkItem);
                                map.setCheckDetailStartingMileage(currentStartMileage);
                                map.setCheckDetailEndMileage(currentEndEndMileage);
                                movementCheckDataUnitDeviceMaps.add(map);

                                AnalysisLabourCheckDataUnitDeviceMap labourCheckDataUnitDeviceMap = this.labourCheckDataUnitDeviceMapSave(movementCourseInfo, unitDevice, checkItem);
                                labourCheckDataUnitDeviceMapList.add(labourCheckDataUnitDeviceMap);


                                // 计算超限:如果为null则计算,否则和单元绑定
//                                AnalysisBatchUnitDeviceTransfinite transfinite = this.labourCheckTransfinite(analysisBatch, movementCourseInfo);
//                                // 如果超限不为空则添加进去
//                                if (null != transfinite) {
//                                    transfiniteList.add(transfinite);
//                                }

                                List<AnalysisBatchUnitDeviceTransfinite> innerTransfiniteList = this.labourCheckTransfiniteList(analysisBatch, movementCourseInfo);
                                if (ObjectUtil.isNotEmpty(innerTransfiniteList)) {
                                    transfiniteList.addAll(innerTransfiniteList);
                                }
                            }
                            // 计算得分
                            this.labourCheckScore(analysisBatch, labourCheckList, unitDevice);
                            // 添加超限
                            unitDevice.put("labourCheckTransfinite", transfiniteList);
                            // 添加人工检查分数
                            unitDevice.put("labourCheck", labourCheckList);
                            // 添加人工检查数据分析批次映射
                            unitDevice.put("labourCheckDataUnitDeviceMapList", labourCheckDataUnitDeviceMapList);
                        }
                        currentStartMileage = currentEndEndMileage;
                        currentEndEndMileage = currentEndEndMileage.add(averageDec);
                    }
                    break;
                }

            }
        }

        if (ObjectUtil.isNotEmpty(movementCheckDataUnitDeviceMaps)) {
            movementCheckDataUnitDeviceMapService.lambdaUpdate().eq(MovementCheckDataUnitDeviceMap::getCheckId, checkDataMap.getEkId()).remove();
            movementCheckDataUnitDeviceMapService.saveBatch(movementCheckDataUnitDeviceMaps);
        }
    }

    private List<AnalysisBatchUnitDeviceTransfinite> labourCheckTransfiniteList(AnalysisBatch analysisBatch, MovementCourseInfo movementCourseInfo) {
        // 超限配置
        JSONObject allowValue = JSONObject.parseObject(analysisBatch.getAllowValue());
        BigDecimal bigTrackGauge = Convert.toBigDecimal(allowValue.get("bigTrackGauge")); // 大轨距
        BigDecimal smallTrackGauge = Convert.toBigDecimal(allowValue.get("smallTrackGauge")); // 小轨距
        BigDecimal allowLevel = Convert.toBigDecimal(allowValue.get("level")); // 水平
        BigDecimal allowTriangularPit = Convert.toBigDecimal(allowValue.get("triangularPit")); // 三角坑
        BigDecimal allowHeight = Convert.toBigDecimal(allowValue.get("height")); // 高低
        BigDecimal allowDirection = Convert.toBigDecimal(allowValue.get("direction")); // 轨向


        // 是否派工配置
        Integer isWork = 1;
        String reasonLabel = "人工检查数据超限-超限";
        JSONArray dispatchingList = JSONArray.parseArray(analysisBatch.getDispatching());
        for (Object obj : dispatchingList) {
            JSONObject dispatching = (JSONObject) obj;
            Integer type = Convert.toInt(dispatching.get("type"));
            if (type != 1) {
                continue;
            }
            String reasonValue = String.valueOf(dispatching.get("reasonValue"));
            if ("static_limit".equals(reasonValue)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWork = 1;
                } else {
                    isWork = 0;
                }
                break;
            }
        }

        // 人工的病害里程:这个格子的(起点里程 + 终点里程)/2
        BigDecimal diseaseMileage = movementCourseInfo.getCurrentStartMileage().add(movementCourseInfo.getCurrentEndEndMileage()).divide(new BigDecimal("2"), 3, BigDecimal.ROUND_HALF_UP);

        List<AnalysisBatchUnitDeviceTransfinite> transfiniteList = new ArrayList<>();

        String allowValueSave = "";
        String measurePointValue = "";
        String transfiniteType = "";

        // 轨距
        BigDecimal trackGauge = Convert.toBigDecimal(movementCourseInfo.getTrackGauge());
        if (ObjectUtil.isNotEmpty(trackGauge)) {
            if (trackGauge.compareTo(bigTrackGauge) > 0) {

                allowValueSave = bigTrackGauge.toString();
                measurePointValue = trackGauge.toString();
                transfiniteType = "大轨距";

                AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
                record.setId(UUIDGenerator.generate());
                record.setTransfiniteGrade(1);
                record.setTransfiniteGradeName(reasonLabel);
                record.setTransfiniteType(transfiniteType);
                record.setAllowValue(allowValueSave);
                record.setEkId(movementCourseInfo.getMovementMasterId());
                record.setEkType(1);
                record.setEkItemId(movementCourseInfo.getMovementCourseId());
                record.setMeasurePointValue(measurePointValue);
                record.setIsWork(isWork);
                record.setDiseaseMileage(diseaseMileage);
                transfiniteList.add(record);

            } else if (trackGauge.compareTo(smallTrackGauge) < 0) {
                allowValueSave = smallTrackGauge.toString();
                measurePointValue = trackGauge.toString();
                transfiniteType = "小轨距";

                AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
                record.setId(UUIDGenerator.generate());
                record.setTransfiniteGrade(1);
                record.setTransfiniteGradeName(reasonLabel);
                record.setTransfiniteType(transfiniteType);
                record.setAllowValue(allowValueSave);
                record.setEkId(movementCourseInfo.getMovementMasterId());
                record.setEkType(1);
                record.setEkItemId(movementCourseInfo.getMovementCourseId());
                record.setMeasurePointValue(measurePointValue);
                record.setIsWork(isWork);
                record.setDiseaseMileage(diseaseMileage);
                transfiniteList.add(record);
            }
        }

        // 水平
        BigDecimal level = Convert.toBigDecimal(movementCourseInfo.getLevel());
        if (ObjectUtil.isNotEmpty(level)) {
            if (level.compareTo(allowLevel) > 0) {
                allowValueSave = allowLevel.toString();
                measurePointValue = level.toString();
                transfiniteType = "水平";

                AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
                record.setId(UUIDGenerator.generate());
                record.setTransfiniteGrade(1);
                record.setTransfiniteGradeName(reasonLabel);
                record.setTransfiniteType(transfiniteType);
                record.setAllowValue(allowValueSave);
                record.setEkId(movementCourseInfo.getMovementMasterId());
                record.setEkType(1);
                record.setEkItemId(movementCourseInfo.getMovementCourseId());
                record.setMeasurePointValue(measurePointValue);
                record.setIsWork(isWork);
                record.setDiseaseMileage(diseaseMileage);
                transfiniteList.add(record);
            }
        }

        //三角坑
        BigDecimal triangularPit = Convert.toBigDecimal(movementCourseInfo.getTriangularPit());
        if (ObjectUtil.isNotEmpty(triangularPit)) {
            if (triangularPit.compareTo(allowTriangularPit) > 0) {
                allowValueSave = allowTriangularPit.toString();
                measurePointValue = triangularPit.toString();
                transfiniteType = "三角坑";

                AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
                record.setId(UUIDGenerator.generate());
                record.setTransfiniteGrade(1);
                record.setTransfiniteGradeName(reasonLabel);
                record.setTransfiniteType(transfiniteType);
                record.setAllowValue(allowValueSave);
                record.setEkId(movementCourseInfo.getMovementMasterId());
                record.setEkType(1);
                record.setEkItemId(movementCourseInfo.getMovementCourseId());
                record.setMeasurePointValue(measurePointValue);
                record.setIsWork(isWork);
                record.setDiseaseMileage(diseaseMileage);
                transfiniteList.add(record);
            }
        }

        // 高低
        BigDecimal height = Convert.toBigDecimal(movementCourseInfo.getHeight());
        if (ObjectUtil.isNotEmpty(height)) {
            if (height.compareTo(allowHeight) > 0) {
                allowValueSave = allowHeight.toString();
                measurePointValue = height.toString();
                transfiniteType = "高低";

                AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
                record.setId(UUIDGenerator.generate());
                record.setTransfiniteGrade(1);
                record.setTransfiniteGradeName(reasonLabel);
                record.setTransfiniteType(transfiniteType);
                record.setAllowValue(allowValueSave);
                record.setEkId(movementCourseInfo.getMovementMasterId());
                record.setEkType(1);
                record.setEkItemId(movementCourseInfo.getMovementCourseId());
                record.setMeasurePointValue(measurePointValue);
                record.setIsWork(isWork);
                record.setDiseaseMileage(diseaseMileage);
                transfiniteList.add(record);
            }
        }

        // 轨向
        BigDecimal direction = Convert.toBigDecimal(movementCourseInfo.getDirection());
        if (ObjectUtil.isNotEmpty(direction)) {
            if (direction.compareTo(allowDirection) > 0) {
                allowValueSave = allowDirection.toString();
                measurePointValue = direction.toString();
                transfiniteType = "轨向";

                AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
                record.setId(UUIDGenerator.generate());
                record.setTransfiniteGrade(1);
                record.setTransfiniteGradeName(reasonLabel);
                record.setTransfiniteType(transfiniteType);
                record.setAllowValue(allowValueSave);
                record.setEkId(movementCourseInfo.getMovementMasterId());
                record.setEkType(1);
                record.setEkItemId(movementCourseInfo.getMovementCourseId());
                record.setMeasurePointValue(measurePointValue);
                record.setIsWork(isWork);
                record.setDiseaseMileage(diseaseMileage);
                transfiniteList.add(record);
            }
        }

        return transfiniteList;
    }

    private AnalysisLabourCheckDataUnitDeviceMap labourCheckDataUnitDeviceMapSave(MovementCourseInfo
                                                                                          movementCourseInfo, Map<String, Object> unitDevice, MovementCourse checkItem) {
        AnalysisLabourCheckDataUnitDeviceMap record = new AnalysisLabourCheckDataUnitDeviceMap();
        record.setId(UUIDGenerator.generate());
        record.setUnitId(Convert.toStr(unitDevice.get("id")));
        record.setUnitCode(Convert.toStr(unitDevice.get("unitCode")));
        record.setUnitType(Convert.toInt(unitDevice.get("type")));
        record.setUnitTypeName(Convert.toStr(unitDevice.get("typeName")));
        record.setUnitStartingMileage(Convert.toBigDecimal(unitDevice.get("startMileage")));
        record.setUnitCenterMileage(Convert.toBigDecimal(unitDevice.get("centerMileage")));
        record.setUnitEndMileage(Convert.toBigDecimal(unitDevice.get("endMileage")));
        record.setCheckId(checkItem.getMovementMasterId());
        record.setCheckItemId(checkItem.getId());
        record.setCheckItemStartingMileage(checkItem.getCourseStartingMileage());
        record.setCheckItemEndMileage(checkItem.getCourseEndMileage());
        record.setCheckItemText(movementCourseInfo.getTrackCode());
        record.setCheckDetailId(movementCourseInfo.getId());
        record.setCheckDetailStartingMileage(movementCourseInfo.getCurrentStartMileage());
        record.setCheckDetailEndMileage(movementCourseInfo.getCurrentEndEndMileage());
        record.setTrackGauge(movementCourseInfo.getTrackGauge());
        record.setLevel(movementCourseInfo.getLevel());
        record.setTriangularPit(movementCourseInfo.getTriangularPit());
        record.setMeasurePoint(movementCourseInfo.getMeasurePoint());
        record.setDirection(movementCourseInfo.getDirection());
        record.setHeight(movementCourseInfo.getHeight());
        record.setStructure(movementCourseInfo.getStructure());
        record.setRectification(movementCourseInfo.getRectification());
        record.setCheckDetailEndMileage(movementCourseInfo.getCurrentEndEndMileage());
        record.setCheckDetailEndMileage(movementCourseInfo.getCurrentEndEndMileage());
        return record;
    }

    /**
     * 人工分数
     */
    private void labourCheckScore(AnalysisBatch
                                          analysisBatch, List<MovementCourseInfo> labourCheckList, Map<String, Object> unitDevice) {
        Integer analysisType = analysisBatch.getAnalysisType();

        BigDecimal finalTrackGauge = null;
        BigDecimal finalLevel = null;
        BigDecimal finalTriangularPit = null;
        BigDecimal finalHeight = null;
        BigDecimal finalDirection = null;

        BigDecimal sumTrackGauge = BigDecimal.ZERO;
        BigDecimal sumLevel = BigDecimal.ZERO;
        BigDecimal sumTriangularPit = BigDecimal.ZERO;
        BigDecimal sumHeight = BigDecimal.ZERO;
        BigDecimal sumDirection = BigDecimal.ZERO;

        BigDecimal maxTrackGauge = BigDecimal.ZERO;
        BigDecimal maxLevel = BigDecimal.ZERO;
        BigDecimal maxTriangularPit = BigDecimal.ZERO;
        BigDecimal maxHeight = BigDecimal.ZERO;
        BigDecimal maxDirection = BigDecimal.ZERO;

        BigDecimal avgTrackGauge;
        BigDecimal avgLevel;
        BigDecimal avgTriangularPit;
        BigDecimal avgHeight;
        BigDecimal avgDirection;


        int trackGaugeSize = 0;
        int levelSize = 0;
        int triangularPitSize = 0;
        int heightSize = 0;
        int directionSize = 0;

        int scale = 3; // 保留3位小数

        // 循环计算均值/峰值
        for (MovementCourseInfo movementCourseInfo : labourCheckList) {
            // 轨距
            BigDecimal trackGauge = Convert.toBigDecimal(movementCourseInfo.getTrackGauge());
            if (ObjectUtil.isNotEmpty(trackGauge)) {
                trackGauge = trackGauge.abs();
                // 均值
                sumTrackGauge = sumTrackGauge.add(trackGauge);
                trackGaugeSize++;
                avgTrackGauge = sumTrackGauge.divide(new BigDecimal(trackGaugeSize), scale, BigDecimal.ROUND_HALF_UP);
                // 峰值
                if (trackGauge.compareTo(maxTrackGauge) > 0) {
                    maxTrackGauge = trackGauge;
                }

                if (1 == analysisType) {
                    finalTrackGauge = avgTrackGauge;
                } else {
                    finalTrackGauge = maxTrackGauge;
                }

            }

            // 水平
            BigDecimal level = Convert.toBigDecimal(movementCourseInfo.getLevel());
            if (ObjectUtil.isNotEmpty(level)) {
                level = level.abs();
                // 均值
                sumLevel = sumLevel.add(level);
                levelSize++;
                avgLevel = sumLevel.divide(new BigDecimal(levelSize), scale, BigDecimal.ROUND_HALF_UP);
                // 峰值
                if (level.compareTo(maxLevel) > 0) {
                    maxLevel = level;
                }

                if (1 == analysisType) {
                    finalLevel = avgLevel;
                } else {
                    finalLevel = maxLevel;
                }
            }

            //三角坑
            BigDecimal triangularPit = Convert.toBigDecimal(movementCourseInfo.getTriangularPit());
            if (ObjectUtil.isNotEmpty(triangularPit)) {
                triangularPit = triangularPit.abs();
                // 均值
                sumTriangularPit = sumTriangularPit.add(triangularPit);
                triangularPitSize++;
                avgTriangularPit = sumTriangularPit.divide(new BigDecimal(triangularPitSize), scale, BigDecimal.ROUND_HALF_UP);
                // 峰值
                if (triangularPit.compareTo(maxTriangularPit) > 0) {
                    maxTriangularPit = triangularPit;
                }

                if (1 == analysisType) {
                    finalTriangularPit = avgTriangularPit;
                } else {
                    finalTriangularPit = maxTriangularPit;
                }
            }

            // 高低
            BigDecimal height = Convert.toBigDecimal(movementCourseInfo.getHeight());
            if (ObjectUtil.isNotEmpty(height)) {
                height = height.abs();
                // 均值
                sumHeight = sumHeight.add(height);
                heightSize++;
                avgHeight = sumHeight.divide(new BigDecimal(heightSize), scale, BigDecimal.ROUND_HALF_UP);
                // 峰值
                if (height.compareTo(maxHeight) > 0) {
                    maxHeight = height;
                }

                if (1 == analysisType) {
                    finalHeight = avgHeight;
                } else {
                    finalHeight = maxHeight;
                }
            }


            // 轨向
            BigDecimal direction = Convert.toBigDecimal(movementCourseInfo.getDirection());
            if (ObjectUtil.isNotEmpty(direction)) {
                direction = direction.abs();
                // 均值
                sumDirection = sumDirection.add(direction);
                directionSize++;
                avgDirection = sumDirection.divide(new BigDecimal(directionSize), scale, BigDecimal.ROUND_HALF_UP);
                // 峰值
                if (direction.compareTo(maxDirection) > 0) {
                    maxDirection = direction;
                }

                if (1 == analysisType) {
                    finalDirection = avgDirection;
                } else {
                    finalDirection = maxDirection;
                }
            }
        }


        ConfigLabourCheck configLabour = configLabourCheckService.lambdaQuery().eq(ConfigLabourCheck::getSpeedMax, analysisBatch.getSpeedMax()).eq(ConfigLabourCheck::getSpeedMin, analysisBatch.getSpeedMin()).eq(ConfigLabourCheck::getDelFlag, "0").last("limit 1").one();


        // 1-钢轨,2-曲线,3-竖曲线,4-道岔
        Integer type = Convert.toInt(unitDevice.get("type"));
        JSONObject jsonObject = null;
        if (type == 1) {
            jsonObject = JSONObject.parseObject(configLabour.getRail());
        } else if (type == 2) {
            jsonObject = JSONObject.parseObject(configLabour.getCurve());
        } else if (type == 3) {
            jsonObject = JSONObject.parseObject(configLabour.getVerticalCurve());
        } else if (type == 4) {
            jsonObject = JSONObject.parseObject(configLabour.getRailSwitch());
        }

        BigDecimal trackGaugeWeightValues = jsonObject.getBigDecimal("trackGauge");
        BigDecimal directionWeightValues = jsonObject.getBigDecimal("direction");
        BigDecimal triangularPitWeightValues = jsonObject.getBigDecimal("triangularPit");
        BigDecimal heightWeightValues = jsonObject.getBigDecimal("height");
        BigDecimal levelWeightValues = jsonObject.getBigDecimal("level");
        // 总单元得分
        BigDecimal sumUnitScore = null;

        // 轨距单元得分
        BigDecimal trackGaugeUnitScore;
        List<AnalysisBatchUnitDevicePointScore> scoreList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(finalTrackGauge)) {
            trackGaugeUnitScore = trackGaugeWeightValues.multiply(new BigDecimal(finalTrackGauge.toString()));
            if (sumUnitScore == null) {
                sumUnitScore = BigDecimal.ZERO;
            }
            sumUnitScore = sumUnitScore.add(trackGaugeUnitScore);

            AnalysisBatchUnitDevicePointScore score = new AnalysisBatchUnitDevicePointScore();
            score.setId(UUIDGenerator.generate());
            score.setAnalysisType(analysisType);
            score.setSpeedMax(analysisBatch.getSpeedMax());
            score.setSpeedMin(analysisBatch.getSpeedMin());
            score.setAnalysisBatchId(analysisBatch.getId());
            score.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
            score.setCheckType(1);
            score.setPointTypeName("轨距");
            score.setPointValue(finalTrackGauge);
            score.setWeightValues(trackGaugeWeightValues);
            score.setPointScore(trackGaugeUnitScore);
            scoreList.add(score);
        }


        // 轨向单元得分
        BigDecimal directionGaugeUnitScore = null;
        if (ObjectUtil.isNotEmpty(finalDirection)) {
            directionGaugeUnitScore = directionWeightValues.multiply(new BigDecimal(finalDirection.toString()));

            if (sumUnitScore == null) {
                sumUnitScore = BigDecimal.ZERO;
            }
            sumUnitScore = sumUnitScore.add(directionGaugeUnitScore);

            AnalysisBatchUnitDevicePointScore score = new AnalysisBatchUnitDevicePointScore();
            score.setId(UUIDGenerator.generate());
            score.setAnalysisType(analysisType);
            score.setSpeedMax(analysisBatch.getSpeedMax());
            score.setSpeedMin(analysisBatch.getSpeedMin());
            score.setAnalysisBatchId(analysisBatch.getId());
            score.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
            score.setCheckType(1);
            score.setPointTypeName("轨向");
            score.setPointValue(finalDirection);
            score.setWeightValues(directionGaugeUnitScore);
            score.setPointScore(directionGaugeUnitScore);
            scoreList.add(score);
        }


        // 三角坑单元得分
        BigDecimal triangularPitGaugeUnitScore;
        if (ObjectUtil.isNotEmpty(finalTriangularPit)) {
            triangularPitGaugeUnitScore = triangularPitWeightValues.multiply(new BigDecimal(finalTriangularPit.toString()));
            if (sumUnitScore == null) {
                sumUnitScore = BigDecimal.ZERO;
            }
            sumUnitScore = sumUnitScore.add(triangularPitGaugeUnitScore);

            AnalysisBatchUnitDevicePointScore score = new AnalysisBatchUnitDevicePointScore();
            score.setId(UUIDGenerator.generate());
            score.setAnalysisType(analysisType);
            score.setSpeedMax(analysisBatch.getSpeedMax());
            score.setSpeedMin(analysisBatch.getSpeedMin());
            score.setAnalysisBatchId(analysisBatch.getId());
            score.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
            score.setCheckType(1);
            score.setPointTypeName("三角坑");
            score.setPointValue(finalTriangularPit);
            score.setWeightValues(triangularPitWeightValues);
            score.setPointScore(triangularPitGaugeUnitScore);
            scoreList.add(score);
        }


        // 高低单元得分
        BigDecimal heightGaugeUnitScore;
        if (ObjectUtil.isNotEmpty(finalHeight)) {
            heightGaugeUnitScore = heightWeightValues.multiply(new BigDecimal(finalHeight.toString()));
            if (sumUnitScore == null) {
                sumUnitScore = BigDecimal.ZERO;
            }
            sumUnitScore = sumUnitScore.add(heightGaugeUnitScore);

            AnalysisBatchUnitDevicePointScore score = new AnalysisBatchUnitDevicePointScore();
            score.setId(UUIDGenerator.generate());
            score.setAnalysisType(analysisType);
            score.setSpeedMax(analysisBatch.getSpeedMax());
            score.setSpeedMin(analysisBatch.getSpeedMin());
            score.setAnalysisBatchId(analysisBatch.getId());
            score.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
            score.setCheckType(1);
            score.setPointTypeName("高低");
            score.setPointValue(finalHeight);
            score.setWeightValues(heightWeightValues);
            score.setPointScore(heightGaugeUnitScore);
            scoreList.add(score);
        }

        // 水平单元得分
        BigDecimal levelUnitScore;
        if (ObjectUtil.isNotEmpty(finalLevel)) {
            levelUnitScore = levelWeightValues.multiply(new BigDecimal(finalLevel.toString()));
            if (sumUnitScore == null) {
                sumUnitScore = BigDecimal.ZERO;
            }
            sumUnitScore = sumUnitScore.add(levelUnitScore);

            AnalysisBatchUnitDevicePointScore score = new AnalysisBatchUnitDevicePointScore();
            score.setId(UUIDGenerator.generate());
            score.setAnalysisType(analysisType);
            score.setSpeedMax(analysisBatch.getSpeedMax());
            score.setSpeedMin(analysisBatch.getSpeedMin());
            score.setAnalysisBatchId(analysisBatch.getId());
            score.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
            score.setCheckType(1);
            score.setPointTypeName("水平");
            score.setPointValue(finalLevel);
            score.setWeightValues(levelWeightValues);
            score.setPointScore(levelUnitScore);
            scoreList.add(score);
        }
        unitDevice.put("labourCheckScore", sumUnitScore);
        unitDevice.put("labourCheckScoreList", scoreList);
    }

    /**
     * 如果超限了就返回 超限对象,没有就返回 null
     *
     * @param analysisBatch
     * @param movementCourseInfo
     * @return
     */
    private AnalysisBatchUnitDeviceTransfinite labourCheckTransfinite(AnalysisBatch analysisBatch, MovementCourseInfo movementCourseInfo) {
        // 超限配置
        JSONObject allowValue = JSONObject.parseObject(analysisBatch.getAllowValue());
        Integer bigTrackGauge = Convert.toInt(allowValue.get("bigTrackGauge")); // 大轨距
        Integer smallTrackGauge = Convert.toInt(allowValue.get("smallTrackGauge")); // 小轨距
        Integer allowLevel = Convert.toInt(allowValue.get("level")); // 水平
        Integer allowTriangularPit = Convert.toInt(allowValue.get("triangularPit")); // 三角坑
        Integer allowHeight = Convert.toInt(allowValue.get("height")); // 高低
        Integer allowDirection = Convert.toInt(allowValue.get("direction")); // 轨向


        // 是否派工配置
        Integer isWork = 1;
        String reasonLabel = "人工检查数据超限-超限";
        JSONArray dispatchingList = JSONArray.parseArray(analysisBatch.getDispatching());
        for (Object obj : dispatchingList) {
            JSONObject dispatching = (JSONObject) obj;
            Integer type = Convert.toInt(dispatching.get("type"));
            if (type != 1) {
                continue;
            }
            String reasonValue = String.valueOf(dispatching.get("reasonValue"));
            if ("static_limit".equals(reasonValue)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWork = 1;
                } else {
                    isWork = 0;
                }
            }
        }

        boolean isTransfinite = false;
        String allowValueSave = "";
        String measurePointValue = "";
        String transfiniteType = "";

        // 轨距
        Integer trackGauge = Convert.toInt(movementCourseInfo.getTrackGauge());
        if (ObjectUtil.isNotEmpty(trackGauge)) {
            if (trackGauge > bigTrackGauge) {
                isTransfinite = true;
                allowValueSave = bigTrackGauge.toString();
                measurePointValue = trackGauge.toString();
                transfiniteType = "大轨距";
            } else if (trackGauge < smallTrackGauge) {
                isTransfinite = true;
                allowValueSave = smallTrackGauge.toString();
                measurePointValue = trackGauge.toString();
                transfiniteType = "小轨距";
            }
        }

        // 水平
        Integer level = Convert.toInt(movementCourseInfo.getLevel());
        if (ObjectUtil.isNotEmpty(level)) {
            if (level > allowLevel) {
                isTransfinite = true;
                allowValueSave = allowLevel.toString();
                measurePointValue = level.toString();
                transfiniteType = "水平";
            }
        }

        //三角坑
        Integer triangularPit = Convert.toInt(movementCourseInfo.getTriangularPit());
        if (ObjectUtil.isNotEmpty(triangularPit)) {
            if (triangularPit > allowTriangularPit) {
                isTransfinite = true;
                allowValueSave = allowTriangularPit.toString();
                measurePointValue = triangularPit.toString();
                transfiniteType = "三角坑";
            }
        }

        // 高低
        Integer height = Convert.toInt(movementCourseInfo.getHeight());
        if (ObjectUtil.isNotEmpty(height)) {
            if (height > allowHeight) {
                isTransfinite = true;
                allowValueSave = allowHeight.toString();
                measurePointValue = height.toString();
                transfiniteType = "高低";
            }
        }

        // 轨向
        Integer direction = Convert.toInt(movementCourseInfo.getDirection());
        if (ObjectUtil.isNotEmpty(direction)) {
            if (direction > allowDirection) {
                isTransfinite = true;
                allowValueSave = allowDirection.toString();
                measurePointValue = direction.toString();
                transfiniteType = "轨向";
            }
        }

        // 人工的病害里程:这个格子的(起点里程 + 终点里程)/2
        BigDecimal diseaseMileage = movementCourseInfo.getCurrentStartMileage().add(movementCourseInfo.getCurrentEndEndMileage()).divide(new BigDecimal("2"), 3, BigDecimal.ROUND_HALF_UP);


        // 超限
        if (isTransfinite) {
            AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
            record.setId(UUIDGenerator.generate());
            record.setTransfiniteGrade(1);
            record.setTransfiniteGradeName(reasonLabel);
            record.setTransfiniteType(transfiniteType);
            record.setAllowValue(allowValueSave);
            record.setEkId(movementCourseInfo.getMovementMasterId());
            record.setEkType(1);
            record.setEkItemId(movementCourseInfo.getMovementCourseId());
            record.setMeasurePointValue(measurePointValue);
            record.setIsWork(isWork);
            record.setDiseaseMileage(diseaseMileage);
            return record;
        } else {
            return null;
        }
    }

    /**
     * 人工检查设备映射
     *
     * @param movementCourseInfo
     * @param unitDevice
     * @param checkItem
     * @return
     */
    private MovementCheckDataUnitDeviceMap labourCheckDeviceMapSave(MovementCourseInfo movementCourseInfo, Map<String, Object> unitDevice, MovementCourse checkItem) {
        MovementCheckDataUnitDeviceMap record = new MovementCheckDataUnitDeviceMap();
        record.setId(UUIDGenerator.generate());
        record.setCheckType(1);// 人工检查
        record.setUnitId(Convert.toStr(unitDevice.get("id")));
        record.setUnitCode(Convert.toStr(unitDevice.get("unitCode")));
        record.setUnitType(Convert.toInt(unitDevice.get("type")));
        record.setUnitTypeName(Convert.toStr(unitDevice.get("typeName")));
        record.setUnitStartingMileage(Convert.toBigDecimal(unitDevice.get("startMileage")));
        record.setUnitCenterMileage(Convert.toBigDecimal(unitDevice.get("centerMileage")));
        record.setUnitEndMileage(Convert.toBigDecimal(unitDevice.get("endMileage")));
        record.setCheckId(checkItem.getMovementMasterId());
        record.setCheckItemId(checkItem.getId());
        record.setCheckItemStartingMileage(checkItem.getCourseStartingMileage());
        record.setCheckItemEndMileage(checkItem.getCourseEndMileage());
        record.setCheckItemText(movementCourseInfo.getTrackCode());
        record.setCheckDetailId(movementCourseInfo.getId());
        record.setCheckDetailStartingMileage(movementCourseInfo.getCurrentStartMileage());
        record.setCheckDetailEndMileage(movementCourseInfo.getCurrentEndEndMileage());
        record.setTrackGauge(movementCourseInfo.getTrackGauge());
        record.setLevel(movementCourseInfo.getLevel());
        record.setTriangularPit(movementCourseInfo.getTriangularPit());
        record.setMeasurePoint(movementCourseInfo.getMeasurePoint());
        record.setDirection(movementCourseInfo.getDirection());
        record.setHeight(movementCourseInfo.getHeight());
        record.setStructure(movementCourseInfo.getStructure());
        record.setRectification(movementCourseInfo.getRectification());
        return record;
    }


}
