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.dynamicStaticGeometricData.entity.RailInspectionEquipmentItem;
import org.jeecg.modules.checkData.dynamicStaticGeometricData.entity.RailInspectionEquipmentItemDetail;
import org.jeecg.modules.checkData.dynamicStaticGeometricData.service.IRailInspectionEquipmentItemDetailService;
import org.jeecg.modules.checkData.dynamicStaticGeometricData.service.IRailInspectionEquipmentItemService;
import org.jeecg.modules.checkData.equipmentCheckData.entity.*;
import org.jeecg.modules.checkData.equipmentCheckData.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 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 IMovementCheckDataUnitDeviceMapService movementCheckDataUnitDeviceMapService;
    @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 IConfigRailVehicleTqiService configRailVehicleTqlService;

    @Resource
    private IConfigRailVehicleCheckService configRailVehicleCheckService;

    @Resource
    private IConfigInstrumentCheckService configInstrumentCheckService;

    @Resource
    private IMovementTqiReportUnitDeviceMapService movementTqiReportUnitDeviceMapService;

    @Resource
    private IAnalysisBatchUnitDeviceTqiScoreService analysisBatchUnitDeviceTqiScoreService;

    @Resource
    private IMovementAdditiveInfoUnitDeviceMapService movementAdditiveInfoUnitDeviceMapService;


    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();


            // 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(new BigDecimal("-1"));
                } else {
                    analysisBatchUnitDevice.setLabourCheck(1);
                    analysisBatchUnitDevice.setLabourCheckScore(labourCheckScore);
                    unitScore = labourCheckScore;
                }

                // 轨检仪检查得分
                BigDecimal railDeviceCheckScore = (BigDecimal) unitDevice.get("railDeviceCheckScore");
                if (null == railDeviceCheckScore) {
                    analysisBatchUnitDevice.setRailDeviceCheck(0);
                    analysisBatchUnitDevice.setRailDeviceCheckScore(new BigDecimal("-1"));
                } 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(new BigDecimal("-1"));
                } 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(new BigDecimal("-1"));
                } 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 = new BigDecimal("-1");
                    unitScoreLevelStr = "无";
                    unitScoreLevel = 4;
                }
                // -1代表未评分
                analysisBatchUnitDevice.setUnitScore(unitScore);
                analysisBatchUnitDevice.setUnitScoreLevel(unitScoreLevel);
                analysisBatchUnitDevice.setUnitScoreLevelStr(unitScoreLevelStr);


                // 保存人工检查数据超限
                AnalysisBatchUnitDeviceTransfinite labourCheckTransfinite = (AnalysisBatchUnitDeviceTransfinite) unitDevice.get("labourCheckTransfinite");
                if (ObjectUtil.isNotEmpty(labourCheckTransfinite)) {
                    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);
                }


                // 保存轨检仪检查数据超限
                AnalysisBatchUnitDeviceTransfinite railDeviceTransfinite = (AnalysisBatchUnitDeviceTransfinite) unitDevice.get("railDeviceTransfinite");
                if (ObjectUtil.isNotEmpty(railDeviceTransfinite)) {
                    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);
                    }
                }


            }
            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;
            String reasonValue = String.valueOf(dispatching.get("reasonValue"));
            String reasonLabel = String.valueOf(dispatching.get("reasonLabel"));

            if ("add_instrument_1".equals(reasonValue)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWorkAddInstrumentOver1 = 1;
                    reasonLabelAddInstrumentOver1 = reasonLabel;
                } else {
                    isWorkAddInstrumentOver1 = 0;
                }
            }
            if ("add_instrument_2".equals(reasonValue)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWorkAddInstrumentOver2 = 2;
                    reasonLabelAddInstrumentOver2 = reasonLabel;
                } else {
                    isWorkAddInstrumentOver2 = 0;
                }
            }
            if ("add_instrument_3".equals(reasonValue)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWorkAddInstrumentOver3 = 3;
                    reasonLabelAddInstrumentOver3 = reasonLabel;
                } else {
                    isWorkAddInstrumentOver3 = 0;
                }
            }
            if ("add_instrument_4".equals(reasonValue)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWorkAddInstrumentOver4 = 4;
                    reasonLabelAddInstrumentOver4 = reasonLabel;
                } 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<>();

            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);


                    // 水平超限
                    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.setMeasurePointValue(additiveInfo.getVerticalSpeed().toString());
                        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.setMeasurePointValue(additiveInfo.getVerticalSpeed().toString());
                        addInstrumentTransfiniteList.add(verticalSpeedTransfinite);
                    }


                    currentUnitDeviceAdditiveList.add(additiveInfo);

                    // 在集合中删除这个对象
                    iterator.remove();
                }
            }
            unitDevice.put("addInstrumentTransfiniteList", addInstrumentTransfiniteList);

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

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

            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 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();

        Map<BigDecimal, List<MovementOverReport>> movementOverReportMap = new HashMap<>();
        for (MovementOverReport movementOverReport : movementOverReports) {
            List<MovementOverReport> list = movementOverReportMap.get(movementOverReport.getMileage());
            if (ObjectUtil.isEmpty(list)) {
                list = new ArrayList<>();
                movementOverReportMap.put(movementOverReport.getMileage(), list);
            }
            list.add(movementOverReport);
        }


        // 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 获取是否派工配置
        // 轨检车动态检查数据-1级超限
        Integer isWorkRailVehicleOver1 = 1;
        String reasonLabelRailVehicleOver1 = "";

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

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

        // 轨检车动态检查数据-4级超限
        Integer isWorkRailVehicleOver4 = 1;
        String reasonLabelRailVehicleOver4 = "";
        JSONArray dispatchingList = JSONArray.parseArray(analysisBatch.getDispatching());

        for (Object obj : dispatchingList) {
            JSONObject dispatching = (JSONObject) obj;
            String reasonValue = String.valueOf(dispatching.get("reasonValue"));
            String reasonLabel = String.valueOf(dispatching.get("reasonLabel"));

            if ("rail_vehicle_over_1".equals(reasonValue)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWorkRailVehicleOver1 = 1;
                    reasonLabelRailVehicleOver1 = reasonLabel;
                } else {
                    isWorkRailVehicleOver1 = 0;
                }
            }
            if ("rail_vehicle_over_2".equals(reasonValue)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWorkRailVehicleOver2 = 1;
                    reasonLabelRailVehicleOver2 = reasonLabel;
                } else {
                    isWorkRailVehicleOver2 = 0;
                }
            }
            if ("rail_vehicle_over_3".equals(reasonValue)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWorkRailVehicleOver3 = 1;
                    reasonLabelRailVehicleOver3 = reasonLabel;
                } else {
                    isWorkRailVehicleOver3 = 0;
                }
            }
            if ("rail_vehicle_over_4".equals(reasonValue)) {
                Boolean isWorkTemp = Boolean.valueOf(dispatching.get("isWork").toString());
                if (isWorkTemp) {
                    isWorkRailVehicleOver4 = 1;
                    reasonLabelRailVehicleOver4 = reasonLabel;
                } else {
                    isWorkRailVehicleOver4 = 0;
                }
            }
        }


        //  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());


        // 2. 根据分析批次的里程查询出映射单元
        List<MovementOverReportUnitDeviceMap> overReportUnitDeviceMaps = new ArrayList<>();
        List<MovementTqiReportUnitDeviceMap> movementTqiReportUnitDeviceMaps = new ArrayList<>();
        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 trackGaugeWeightValues = weightValuesjsonObject.getBigDecimal("trackGauge");
            BigDecimal directionWeightValues = weightValuesjsonObject.getBigDecimal("direction");
            BigDecimal triangularPitWeightValues = weightValuesjsonObject.getBigDecimal("triangularPit");
            BigDecimal heightWeightValues = weightValuesjsonObject.getBigDecimal("height");
            BigDecimal levelWeightValues = weightValuesjsonObject.getBigDecimal("level");


            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 trackGaugeTqi = tqiJsonObject.getBigDecimal("trackGauge");
            BigDecimal directionTqi = tqiJsonObject.getBigDecimal("direction");
            BigDecimal triangularPitTqi = tqiJsonObject.getBigDecimal("triangularPit");
            BigDecimal heightTqi = tqiJsonObject.getBigDecimal("height");
            BigDecimal levelTqi = tqiJsonObject.getBigDecimal("level");
            BigDecimal tqiComeUponTqi = tqiJsonObject.getBigDecimal("tqi");


            List<AnalysisBatchUnitDeviceTransfinite> railVehicleTransfiniteList = new ArrayList<>();
            BigDecimal startMileage = Convert.toBigDecimal(unitDevice.get("startMileage"));
            BigDecimal centerMileage = Convert.toBigDecimal(unitDevice.get("centerMileage"));
            BigDecimal endMileage = Convert.toBigDecimal(unitDevice.get("endMileage"));


            // 2.1 缺陷记录报告表里程落在单元设备【开始-结束】这个设备上面，视为这个区间的超限记录
            for (MovementOverReport movementOverReport : movementOverReports) {
                // 说明超限
                if (startMileage.compareTo(movementOverReport.getMileage()) <= 0 && endMileage.compareTo(movementOverReport.getMileage()) > 0) {

                    Integer transfiniteGrade = Convert.toInt(movementOverReport.getOverrunLevel());
                    // 超限
                    AnalysisBatchUnitDeviceTransfinite transfinite = new AnalysisBatchUnitDeviceTransfinite();
                    transfinite.setId(UUIDGenerator.generate());
                    transfinite.setTransfiniteGrade(transfiniteGrade);
                    transfinite.setTransfiniteType(movementOverReport.getOverrunType());
                    if (1 == transfiniteGrade) {
                        transfinite.setTransfiniteGradeName(reasonLabelRailVehicleOver1);
                        transfinite.setIsWork(isWorkRailVehicleOver1);
                    } else if (2 == transfiniteGrade) {
                        transfinite.setTransfiniteGradeName(reasonLabelRailVehicleOver2);
                        transfinite.setIsWork(isWorkRailVehicleOver2);
                    } else if (3 == transfiniteGrade) {
                        transfinite.setTransfiniteGradeName(reasonLabelRailVehicleOver3);
                        transfinite.setIsWork(isWorkRailVehicleOver3);
                    } else {
                        transfinite.setTransfiniteGradeName(reasonLabelRailVehicleOver4);
                        transfinite.setIsWork(isWorkRailVehicleOver4);
                    }
                    String allowValue = Convert.toBigDecimal(movementOverReport.getPeakValue()).subtract(Convert.toBigDecimal(movementOverReport.getDataDifference())).toString();
                    transfinite.setAllowValue(allowValue);
                    transfinite.setMeasurePointValue(movementOverReport.getPeakValue());
                    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.setPeakValue(movementOverReport.getPeakValue());
                    overReportUnitDeviceMap.setDataDifference(movementOverReport.getDataDifference());
                    overReportUnitDeviceMap.setXianxing(movementOverReport.getXianxing());
                    overReportUnitDeviceMap.setStandard(movementOverReport.getStandard());
                    overReportUnitDeviceMap.setSpend(movementOverReport.getSpend());
                    overReportUnitDeviceMaps.add(overReportUnitDeviceMap);
                }
            }
            unitDevice.put("railVehicleTransfiniteList", railVehicleTransfiniteList);


            // 2.2 单元设备中心里程落在tqi【开始-结束】这个区间视为这个区间的单元设备
            // 统计单元得分
            // 统计tqi得分
            BigDecimal sumUnitScore = BigDecimal.ZERO;
            List<AnalysisBatchUnitDevicePointScore> scoreList = new ArrayList<>();
            int analysisType = analysisBatch.getAnalysisType();
            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);


                    // 计算轨距得分
                    BigDecimal finalTrackGauge = Convert.toBigDecimal(tqiReport.getTrackGauge()).abs();
                    if (ObjectUtil.isNotEmpty(railVehicleTransfiniteList)) {
                        int trackGaugeSize = 1;
                        BigDecimal sumTrackGauge = finalTrackGauge;
                        for (AnalysisBatchUnitDeviceTransfinite record : railVehicleTransfiniteList) {
                            if ("轨距".equals(record.getTransfiniteType())) {
                                BigDecimal trackGauge = Convert.toBigDecimal(record.getMeasurePointValue()).abs();

                                if (1 == analysisType) { // 均值
                                    sumTrackGauge = sumTrackGauge.add(trackGauge);
                                    trackGaugeSize++;
                                    finalTrackGauge = sumTrackGauge.divide(new BigDecimal(trackGaugeSize), 3, BigDecimal.ROUND_HALF_UP);
                                } else {    // 峰值
                                    if (finalTrackGauge.compareTo(trackGauge) < 0) {
                                        finalTrackGauge = trackGauge;
                                    }
                                }
                            }
                        }
                    }
                    BigDecimal trackGaugeUnitScore = trackGaugeWeightValues.multiply(finalTrackGauge);
                    sumUnitScore = sumUnitScore.add(trackGaugeUnitScore);

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


                    // 计算水平得分
                    BigDecimal finalLevel = Convert.toBigDecimal(tqiReport.getLevel()).abs();
                    if (ObjectUtil.isNotEmpty(railVehicleTransfiniteList)) {
                        int levelSize = 1;
                        BigDecimal sumLevel = finalLevel;
                        for (AnalysisBatchUnitDeviceTransfinite record : railVehicleTransfiniteList) {
                            if (record.getTransfiniteType().contains("水平")) {
                                BigDecimal level = Convert.toBigDecimal(record.getMeasurePointValue()).abs();

                                if (1 == analysisType) { // 均值
                                    sumLevel = sumLevel.add(level);
                                    levelSize++;
                                    finalLevel = sumLevel.divide(new BigDecimal(levelSize), 3, BigDecimal.ROUND_HALF_UP);
                                } else {    // 峰值
                                    if (finalLevel.compareTo(level) < 0) {
                                        finalLevel = level;
                                    }
                                }
                            }
                        }

                    }
                    BigDecimal levelUnitScore = levelWeightValues.multiply(finalLevel);
                    sumUnitScore = sumUnitScore.add(levelUnitScore);


                    AnalysisBatchUnitDevicePointScore levelPointScore = new AnalysisBatchUnitDevicePointScore();
                    levelPointScore.setId(UUIDGenerator.generate());
                    levelPointScore.setAnalysisType(analysisType);
                    levelPointScore.setSpeedMax(analysisBatch.getSpeedMax());
                    levelPointScore.setSpeedMin(analysisBatch.getSpeedMin());
                    levelPointScore.setAnalysisBatchId(analysisBatch.getId());
                    levelPointScore.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
                    levelPointScore.setPointTypeName("水平");
                    levelPointScore.setCheckType(3);
                    levelPointScore.setPointValue(finalLevel);
                    levelPointScore.setWeightValues(levelWeightValues);
                    levelPointScore.setPointScore(levelUnitScore);
                    scoreList.add(levelPointScore);


                    // 计算三角坑得分
                    BigDecimal finalTriangularPit = Convert.toBigDecimal(tqiReport.getLevel()).abs();
                    if (ObjectUtil.isNotEmpty(railVehicleTransfiniteList)) {
                        int triangularPitSize = 1;
                        BigDecimal sumTriangularPit = finalTriangularPit;
                        for (AnalysisBatchUnitDeviceTransfinite record : railVehicleTransfiniteList) {
                            if (record.getTransfiniteType().contains("三角坑")) {
                                BigDecimal level = Convert.toBigDecimal(record.getMeasurePointValue()).abs();

                                if (1 == analysisBatch.getAnalysisType()) { // 均值
                                    sumTriangularPit = sumTriangularPit.add(level);
                                    triangularPitSize++;
                                    finalTriangularPit = sumTriangularPit.divide(new BigDecimal(triangularPitSize), 3, BigDecimal.ROUND_HALF_UP);
                                } else {    // 峰值
                                    if (finalTriangularPit.compareTo(level) < 0) {
                                        finalTriangularPit = level;
                                    }
                                }
                            }
                        }
                    }
                    BigDecimal triangularPitUnitScore = triangularPitWeightValues.multiply(finalTriangularPit);
                    sumUnitScore = sumUnitScore.add(triangularPitUnitScore);


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


                    // 计算高低得分
                    BigDecimal finalHeight = null;
                    BigDecimal finalHeightLowLeft = Convert.toBigDecimal(tqiReport.getHighLowLeft()).abs();
                    BigDecimal finalHeightLowRight = Convert.toBigDecimal(tqiReport.getHighLowRight()).abs();
                    if (1 == analysisBatch.getAnalysisType()) {
                        finalHeight = finalHeightLowLeft.add(finalHeightLowRight).divide(new BigDecimal("2"), 3, BigDecimal.ROUND_HALF_UP);
                    } else {
                        if (finalHeightLowLeft.compareTo(finalHeightLowRight) > 0) {
                            finalHeight = finalHeightLowLeft;
                        } else {
                            finalHeight = finalHeightLowRight;
                        }
                    }
                    if (ObjectUtil.isNotEmpty(railVehicleTransfiniteList)) {
                        int heightSize = 1;
                        BigDecimal sumHeight = finalHeight;
                        for (AnalysisBatchUnitDeviceTransfinite record : railVehicleTransfiniteList) {
                            if (record.getTransfiniteType().contains("高低")) {
                                BigDecimal level = Convert.toBigDecimal(record.getMeasurePointValue()).abs();

                                if (1 == analysisBatch.getAnalysisType()) { // 均值
                                    sumHeight = sumHeight.add(level);
                                    heightSize++;
                                    finalHeight = sumHeight.divide(new BigDecimal(heightSize), 3, BigDecimal.ROUND_HALF_UP);
                                } else {    // 峰值
                                    if (finalHeight.compareTo(level) < 0) {
                                        finalHeight = level;
                                    }
                                }
                            }
                        }

                    }
                    BigDecimal heightUnitScore = heightWeightValues.multiply(finalHeight);
                    sumUnitScore = sumUnitScore.add(heightUnitScore);


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


                    // 计算轨向得分
                    BigDecimal finalDirection = null;
                    BigDecimal finalDirectionLeft = Convert.toBigDecimal(tqiReport.getTrackLeft()).abs();
                    BigDecimal finalDirectionRight = Convert.toBigDecimal(tqiReport.getTrackRight()).abs();
                    if (1 == analysisType) {
                        finalDirection = finalDirectionLeft.add(finalDirectionRight).divide(new BigDecimal("2"), 3, BigDecimal.ROUND_HALF_UP);
                    } else {
                        if (finalDirectionLeft.compareTo(finalDirectionRight) > 0) {
                            finalDirection = finalDirectionLeft;
                        } else {
                            finalDirection = finalDirectionRight;
                        }
                    }
                    if (ObjectUtil.isNotEmpty(railVehicleTransfiniteList)) {
                        int heightSize = 1;
                        BigDecimal sumDirection = finalDirection;
                        for (AnalysisBatchUnitDeviceTransfinite record : railVehicleTransfiniteList) {
                            if (record.getTransfiniteType().contains("轨向")) {
                                BigDecimal level = Convert.toBigDecimal(record.getMeasurePointValue()).abs();

                                if (1 == analysisType) { // 均值
                                    sumDirection = sumDirection.add(level);
                                    heightSize++;
                                    finalDirection = sumDirection.divide(new BigDecimal(heightSize), 3, BigDecimal.ROUND_HALF_UP);
                                } else {    // 峰值
                                    if (finalDirection.compareTo(level) < 0) {
                                        finalDirection = level;
                                    }
                                }
                            }
                        }
                    }
                    BigDecimal directionUnitScore = directionWeightValues.multiply(finalDirection);
                    sumUnitScore = sumUnitScore.add(directionUnitScore);


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


                    // 计算tqi的分数
                    // 左高低
                    BigDecimal highLowLeft = Convert.toBigDecimal(tqiReport.getHighLowLeft());
                    BigDecimal highLowLeftScore = highLowLeft.multiply(heightTqi);

                    // 右高低
                    BigDecimal highLowRight = Convert.toBigDecimal(tqiReport.getHighLowRight());
                    BigDecimal highLowRightScore = highLowRight.multiply(heightTqi);

                    // 轨向左
                    BigDecimal trackLeft = Convert.toBigDecimal(tqiReport.getTrackLeft());
                    BigDecimal trackLeftScore = trackLeft.multiply(directionTqi);


                    // 轨向右
                    BigDecimal trackRight = Convert.toBigDecimal(tqiReport.getTrackRight());
                    BigDecimal trackRightScore = trackRight.multiply(directionTqi);

                    // 水平
                    BigDecimal level = Convert.toBigDecimal(tqiReport.getLevel());
                    BigDecimal levelScore = level.multiply(levelTqi);

                    // 轨距
                    BigDecimal trackGauge = Convert.toBigDecimal(tqiReport.getTrackGauge());
                    BigDecimal trackGaugeScore = trackGauge.multiply(trackGaugeTqi);

                    // 三角坑
                    BigDecimal triangularPit = Convert.toBigDecimal(tqiReport.getTriangularPit());
                    BigDecimal triangularPitScore = triangularPit.multiply(triangularPitTqi);


                    // tqi
                    BigDecimal tqiComeUpon = Convert.toBigDecimal(tqiReport.getTqiComeUpon());
                    BigDecimal tqiComeUponScore = tqiComeUpon.multiply(tqiComeUponTqi);

                    BigDecimal sumScore = highLowLeftScore.add(highLowRightScore).add(trackLeftScore).add(trackRightScore).add(levelScore).add(trackGaugeScore).add(triangularPitScore).add(tqiComeUponScore);

                    AnalysisBatchUnitDeviceTqiScore tqiScore = new AnalysisBatchUnitDeviceTqiScore();
                    tqiScore.setId(UUIDGenerator.generate());
                    tqiScore.setAnalysisType(analysisType);
                    tqiScore.setAnalysisBatchId(analysisBatch.getId());
                    tqiScore.setAnalysisBatchCode(analysisBatch.getAnalysisBatchCode());
                    tqiScore.setUnitId(Convert.toStr(unitDevice.get("id")));
                    tqiScore.setUnitCode(Convert.toStr(unitDevice.get("unitCode")));
                    tqiScore.setUnitType(Convert.toInt(unitDevice.get("type")));
                    tqiScore.setUnitTypeName(Convert.toStr(unitDevice.get("typeName")));

                    tqiScore.setHighLowLeft(highLowLeft);
                    tqiScore.setHighLowLeftWeightValues(heightTqi);
                    tqiScore.setHighLowLeftScore(highLowLeftScore);

                    tqiScore.setHighLowRight(highLowRight);
                    tqiScore.setHighLowRightWeightValues(heightTqi);
                    tqiScore.setHighLowRightScore(highLowRightScore);

                    tqiScore.setTrackLeft(trackLeft);
                    tqiScore.setTrackLeftWeightValues(directionTqi);
                    tqiScore.setTrackLeftScore(trackLeftScore);

                    tqiScore.setTrackRight(trackRight);
                    tqiScore.setTrackRightWeightValues(directionTqi);
                    tqiScore.setTrackRightScore(trackRightScore);

                    tqiScore.setLevel(level);
                    tqiScore.setLevelWeightValues(levelTqi);
                    tqiScore.setLevelScore(levelScore);

                    tqiScore.setTrackGauge(trackGauge);
                    tqiScore.setTrackGaugeWeightValues(trackGaugeTqi);
                    tqiScore.setTrackGaugeScore(trackGaugeScore);

                    tqiScore.setTriangularPit(triangularPit);
                    tqiScore.setTriangularPitWeightValues(triangularPitTqi);
                    tqiScore.setTriangularPitScore(triangularPitScore);

                    tqiScore.setTqiComeUpon(tqiComeUpon);
                    tqiScore.setTqiComeUponWeightValues(tqiComeUponTqi);
                    tqiScore.setTqiComeUponScore(tqiComeUponScore);

                    tqiScore.setSumScore(sumScore);

                    unitDevice.put("railVehicleTqiScore", tqiScore);


                    // 判断tqi指标是否派工

                    break;
                }

            }

            unitDevice.put("railVehicleCheckScore", sumUnitScore);
            unitDevice.put("railVehicleCheckScoreList", scoreList);

        }

        if (ObjectUtil.isNotEmpty(overReportUnitDeviceMaps)) {
            movementOverReportUnitDeviceMapService.lambdaUpdate().eq(MovementOverReportUnitDeviceMap::getCheckId, checkDataMap.getEkId()).remove();
            movementOverReportUnitDeviceMapService.saveBatch(overReportUnitDeviceMaps);
        }
        if (ObjectUtil.isNotEmpty(movementTqiReportUnitDeviceMaps)) {
            movementTqiReportUnitDeviceMapService.lambdaUpdate().eq(MovementTqiReportUnitDeviceMap::getCheckId, checkDataMap.getEkId()).remove();
            movementTqiReportUnitDeviceMapService.saveBatch(movementTqiReportUnitDeviceMaps);
        }


    }

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


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


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

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

            // 2.1  循环遍历检查项目比较【开始-结束】来映射关联关系
            for (RailInspectionEquipmentItem checkItem : checkItemList) {
                // 1.2 处理检查项目是公里的情况
                BigDecimal checkItemStartingMileage = checkItem.getCourseStartingMileage().multiply(new BigDecimal("1000"));
                checkItem.setCourseStartingMileage(checkItemStartingMileage);
                BigDecimal checkItemEndMileage = checkItem.getCourseEndMileage().multiply(new BigDecimal("1000"));
                checkItem.setCourseEndMileage(checkItemEndMileage);
                if (checkItemStartingMileage.compareTo(checkItemEndMileage) > 0) {
                    checkItemStartingMileage = checkItem.getCourseEndMileage();
                    checkItemEndMileage = checkItem.getCourseStartingMileage();
                }

                // 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);
                            unitDevice.put("railDeviceCheck", railDeviceCheckList);
                            AnalysisBatchUnitDeviceTransfinite transfinite = null;

                            // 循环处理测点数据
                            for (RailInspectionEquipmentItemDetail movementCourseInfo : railDeviceCheckList) {
                                // 保存检查数据-单元关联关系
                                MovementCheckDataUnitDeviceMap map = this.railDeviceCheckDeviceMapSave(movementCourseInfo, unitDevice, checkItem);
                                map.setCheckDetailStartingMileage(currentStartMileage);
                                map.setCheckDetailEndMileage(currentEndEndMileage);
                                movementCheckDataUnitDeviceMaps.add(map);

                                // 计算超限:如果为null则计算,否则和单元绑定
                                if (null == transfinite) {
                                    transfinite = this.railDeviceCheckTransfinite(analysisBatch, movementCourseInfo);
                                } else {
                                    unitDevice.put("railDeviceTransfinite", transfinite);
                                }
                            }

                            // 计算得分
                            this.railDeviceCheckScore(analysisBatch, railDeviceCheckList, unitDevice);
                        }
                        currentStartMileage = currentEndEndMileage;
                        currentEndEndMileage = currentEndEndMileage.add(averageDec);
                    }

                    break;
                }
            }
        }


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

    /**
     * 轨检仪检查数据分数
     */
    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 = maxLevel;
                }

            }

            // 水平
            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 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;
            String reasonValue = String.valueOf(dispatching.get("reasonValue"));
            reasonLabel = String.valueOf(dispatching.get("reasonLabel"));
            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 = "三角坑";
            }
        }


        // 超限
        if (isTransfinite) {
            AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
            record.setId(UUIDGenerator.generate());
            record.setTransfiniteGrade(1);
            record.setTransfiniteGradeName(reasonLabel);
            record.setTransfiniteType(transfiniteType);
            record.setAllowValue(allowValueSave);
            record.setMeasurePointValue(measurePointValue);
            record.setIsWork(isWork);
            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);
                            unitDevice.put("labourCheck", labourCheckList);
                            AnalysisBatchUnitDeviceTransfinite transfinite = null;

                            // 循环处理测点数据
                            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);

                                // 计算超限:如果为null则计算,否则和单元绑定
                                if (null == transfinite) {
                                    transfinite = this.labourCheckTransfinite(analysisBatch, movementCourseInfo);
                                } else {
                                    unitDevice.put("labourCheckTransfinite", transfinite);
                                }
                            }

                            // 计算得分
                            this.labourCheckScore(analysisBatch, labourCheckList, unitDevice);
                        }
                        currentStartMileage = currentEndEndMileage;
                        currentEndEndMileage = currentEndEndMileage.add(averageDec);
                    }
                    break;
                }

            }
        }

    }

    /**
     * 人工分数
     */
    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 = maxLevel;
                }

            }

            // 水平
            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;
            String reasonValue = String.valueOf(dispatching.get("reasonValue"));
            reasonLabel = String.valueOf(dispatching.get("reasonLabel"));
            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 = "轨向";
            }
        }

        // 超限
        if (isTransfinite) {
            AnalysisBatchUnitDeviceTransfinite record = new AnalysisBatchUnitDeviceTransfinite();
            record.setId(UUIDGenerator.generate());
            record.setTransfiniteGrade(1);
            record.setTransfiniteGradeName(reasonLabel);
            record.setTransfiniteType(transfiniteType);
            record.setAllowValue(allowValueSave);
            record.setMeasurePointValue(measurePointValue);
            record.setIsWork(isWork);
            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;
    }


}