package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.step;

import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesEquipmentLogExtService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionDispatchContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesProductionProcessContextStepService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.spot.IMesSpotCheckOrderService;
import cn.estsh.i3plus.ext.mes.pcn.pojo.constant.MesCommonConstant;
import cn.estsh.i3plus.ext.mes.pcn.pojo.context.*;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.api.iservice.busi.ISyncFuncService;
import cn.estsh.i3plus.mes.pcn.serviceimpl.fsm.BaseStepService;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.codemaker.SnowflakeIdMaker;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesPcnEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.i3plus.pojo.mes.model.StationRequestBean;
import cn.estsh.i3plus.pojo.mes.model.StationResultBean;
import cn.estsh.i3plus.pojo.mes.model.StepResult;
import cn.estsh.i3plus.pojo.mes.repository.MesSpotCheckOrderRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesSpotCheckOrderResultRepository;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description : 设备点检超差预警工步 【此工步绘制为一个独立的工步集 需要配置在读加工结果状态工步集与保存加工结果工步集之间】
 * @Author : wangjie
 **/
@Slf4j
@Service("mesEquipSpotCheckAlarmStepService")
public class MesEquipSpotCheckAlarmStepService extends BaseStepService {

    @Autowired
    private IMesProductionProcessContextStepService productionProcessContextStepService;

    @Autowired
    private IMesProductionDispatchContextStepService productionDispatchContextStepService;

    @Autowired
    private IMesEquipmentLogExtService equipmentLogExtService;

    @Autowired
    private IMesSpotCheckOrderService spotCheckOrderService;

    @Autowired
    private MesSpotCheckOrderRepository spotCheckOrderRepository;

    @Autowired
    private MesSpotCheckOrderResultRepository spotCheckOrderResultRepository;

    @Autowired
    private ISyncFuncService syncFuncService;

    @Autowired
    private SnowflakeIdMaker snowflakeIdMaker;

    @Override
    public void title(StationRequestBean reqBean) {
        this.sendMessage(reqBean, new StationResultBean().resultObj(MesPcnExtConstWords.STEP_DISABLE_SCAN), String.format("工步: %s", reqBean.getStepName()), MesPcnEnumUtil.STATION_BUSI_TYPE.STEP_TITLE, MesPcnEnumUtil.STATION_DATA_TYPE.TITLE);
    }

    @Override
    public StepResult execute(StationRequestBean reqBean) {

        StationResultBean resultBean = new StationResultBean();

        StepResult stepResult = StepResult.getSuccessComplete();

        //获取上下文信息
        MesProductionProcessContext productionProcessContext = productionProcessContextStepService.dispatchCurCellEquipment(reqBean);

        //配置错误 抛出异常
        if (!productionProcessContext.getSuccess()) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), productionProcessContext.getMessage());

        //当前工位使用的设备
        MesCellEquipContext cellEquipContext = productionProcessContext.getCurCellEquip();

        //获取上下文产出条码数据信息集合
        List<MesProductionPsOutContext> productionPsOutContextList = productionDispatchContextStepService.getProductionPsOutContext(reqBean);
        if (CollectionUtils.isEmpty(productionPsOutContextList)) stepExpSendMsgAndThrowEx(reqBean, resultBean.writeDbLog(), "当前不存在产出零件条码信息,请重置工序解决!");
        //搜集产成零件号[去重]
        List<String> partNoList = (productionPsOutContextList.stream().filter(o -> null != o).map(MesProductionPsOutContext::getPartNo).collect(Collectors.toList()))
                .stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());

        //获取设备点检上下文对象
        MesEquipSpotCheckContext equipSpotCheckContext = productionProcessContextStepService.dispatchEquipSpotCheckContext(reqBean, cellEquipContext.getEquipmentCode());
        if (null == equipSpotCheckContext || equipSpotCheckContext.getIsExistSpot().equals(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValueStr())) {
            return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true,
                    MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, String.format("设备代码[%s]未维护点检主数据,跳过设备点检超差预警!", cellEquipContext.getEquipmentCode()));
        }

        //点检主数据主表集合
        List<MesEquipmentSpotCheck> equipmentSpotCheckList = equipSpotCheckContext.getEquipmentSpotCheckList();
        //设备点检主数据明细表集合
        List<MesEquipmentSpotCheckDetail> equipmentSpotCheckDetailList = equipSpotCheckContext.getEquipmentSpotCheckDetailList();
        //设备点检主数据关联零件表集合
        List<MesEquipmentSpotCheckPart> equipmentSpotPartList = equipSpotCheckContext.getEquipmentSpotCheckPartList();

        //根据零件搜集需要执行的点检主数据
        equipmentSpotCheckList = filterEquipmentSpotCheckList(equipmentSpotCheckList, equipmentSpotPartList, partNoList);
        if (CollectionUtils.isEmpty(equipmentSpotCheckList)) {
            return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true,
                    MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT, String.format("设备代码[%s]产成零件号%s未维护点检主数据,跳过设备点检超差预警!", cellEquipContext.getEquipmentCode(), partNoList.toString()));
        }

        //根据点检方式搜集设备点检主数据[加工后]
        List<MesEquipmentSpotCheck> equipmentSpotCheckList2After = filterEquipmentSpotCheckList(equipmentSpotCheckList, MesExtEnumUtil.EQUIPMENT_CHECK_INSPECTION_METHOD.AFTER_PROCESSING.getValue());
        //根据点检方式搜集设备点检主数据[全部点检]
        List<MesEquipmentSpotCheck> equipmentSpotCheckList2All = filterEquipmentSpotCheckList(equipmentSpotCheckList, MesExtEnumUtil.EQUIPMENT_CHECK_INSPECTION_METHOD.ALL_INSPECTIONS.getValue());

        //搜集点检方式加工后的设备点检主数据的ID集合; 根据生产线代码,设备代码,点检项目ID集合查询 每个点检项目ID对应的最新的未完成的单据
        List<MesSpotCheckOrder> spotCheckOrderList2After = CollectionUtils.isEmpty(equipmentSpotCheckList2After) ? null :
                spotCheckOrderService.getSpotCheckOrderList(reqBean.getOrganizeCode(), reqBean.getWorkCenterCode(), cellEquipContext.getEquipmentCode(), filterSpotCheckIdList(equipmentSpotCheckList2After));

        //搜集点检方式加工后的设备点检单据的ID集合; 根据设备点检单据ID集合查询后搜集点检项类型为自动类型的明细信息
        List<MesSpotCheckOrderResult> spotCheckOrderResultList2After = CollectionUtils.isEmpty(spotCheckOrderList2After) ? null :
                spotCheckOrderService.getSpotCheckOrderResultAutoItemTypeList(reqBean.getOrganizeCode(), filterSpotCheckOrderIdList(spotCheckOrderList2After));

        //搜集点检方式全部点检的设备点检主数据的ID集合; 根据全部点检的设备点检主数据的ID集合搜集明细集合
        List<MesEquipmentSpotCheckDetail> equipmentSpotCheckDetailList2All = filterEquipmentSpotCheckDetailList(equipmentSpotCheckDetailList, filterSpotCheckIdList(equipmentSpotCheckList2All));
        //将明细主数据封装成单据明细数据
        List<MesSpotCheckOrderResult> spotCheckOrderResultList2All = packSpotCheckOrderResultList(reqBean, cellEquipContext, equipmentSpotCheckDetailList2All);

        if (CollectionUtils.isEmpty(spotCheckOrderResultList2After) || CollectionUtils.isEmpty(spotCheckOrderResultList2All)) {
            return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true,
                    MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT,
                    String.format("设备代码[%s]产成零件号%s未关联加工后类型的单据或全部点检类型的主数据,跳过设备点检超差预警!", cellEquipContext.getEquipmentCode(), partNoList.toString()));
        }

        //根据设备ID,是否常变值状态,变量类型查询设备ID分表采集数据, 再根据设备数据变量ID集合过滤数据; 采集后的数据进行分组
        Map<Long, String> equipVariableCollectMap = groupByEquipVariableCollectContext(equipmentLogExtService.getEquipmentLogCollectListThenFilter(
                reqBean.getOrganizeCode(), cellEquipContext.getEquipId(), MesExtEnumUtil.EQUIP_VARIABLE_NEED_NEW_VALUE.FALSE.getValue(), MesExtEnumUtil.EQUIP_VARIABLE_TYPE.PROCESS_FINISH.getValue(),
                filterEquipmentVariableIdList(spotCheckOrderResultList2All, spotCheckOrderResultList2After)));

        if (CollectionUtils.isEmpty(equipVariableCollectMap)) {
            return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true,
                    MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT,
                    String.format("根据设备代码[%s]产成零件号%s维护的设备点检明细清单未读取到有效的点位值,跳过设备点检超差预警!", cellEquipContext.getEquipmentCode(), partNoList.toString()));
        }

        //保存点检数据, 判断是否超差
        Boolean isTolerance2After = saveSpotCheckOrderResultListValue(reqBean, cellEquipContext, spotCheckOrderResultList2After, equipVariableCollectMap, spotCheckOrderList2After, null, null);
        Boolean isTolerance2All = saveSpotCheckOrderResultListValue(reqBean, cellEquipContext, spotCheckOrderResultList2All, equipVariableCollectMap, null, equipmentSpotCheckDetailList2All, equipmentSpotCheckList2All);

        //超差则标记可疑
        if (isTolerance2After || isTolerance2All) {
            //获取上下文加工结果
            String productResult = productionDispatchContextStepService.getProductResultContext(reqBean);
            if (StringUtils.isEmpty(productResult) || productResult.equals(MesExtEnumUtil.PRODUCE_QC_STATUS.QUALIFIED.getValue() + MesPcnExtConstWords.EMPTY)) {
                //保存上下文加工结果:零件可疑
                productionDispatchContextStepService.dispatchProductResultContext(reqBean, MesExtEnumUtil.PRODUCE_QC_STATUS.SUSPICIOUS.getValue() + MesPcnExtConstWords.EMPTY);
            }
        }

        //超差结果不发送给客户端显示
        return stepDynamicsCompleteAndSendMsgReturn(reqBean, resultBean.writeDbLog(), stepResult, true,
                MesPcnEnumUtil.STATION_BUSI_TYPE.RUNNING_INFO, MesPcnEnumUtil.STATION_DATA_TYPE.TEXT,
                String.format("设备代码[%s]产成零件号%s设备点检超差预警执行结果[是否超差: %s]!", cellEquipContext.getEquipmentCode(), partNoList.toString(), isTolerance2After || isTolerance2All));

    }

    //根据零件搜集需要执行的点检主数据
    private List<MesEquipmentSpotCheck> filterEquipmentSpotCheckList(List<MesEquipmentSpotCheck> equipmentSpotCheckList, List<MesEquipmentSpotCheckPart> equipmentSpotPartList, List<String> partNoList) {
        //搜集设备点检主数据关联零件表集合的PID
        List<Long> pidList2Part = CollectionUtils.isEmpty(equipmentSpotPartList) ? null : equipmentSpotPartList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getPid()))).map(MesEquipmentSpotCheckPart::getPid).collect(Collectors.toList());
        //搜集设备点检主数据关联零件表集合中与当前产成零件相关的PID
        List<Long> pidList2CurPart = CollectionUtils.isEmpty(equipmentSpotPartList) ? null : equipmentSpotPartList.stream().filter(o -> (null != o &&
                !StringUtils.isEmpty(o.getPid()) && !StringUtils.isEmpty(o.getPartNo()) && partNoList.contains(o.getPartNo()))).map(MesEquipmentSpotCheckPart::getPid).collect(Collectors.toList());

        if (!CollectionUtils.isEmpty(pidList2Part)) {
            //搜集未关联任何零件的设备点检主数据
            List<MesEquipmentSpotCheck> equipmentSpotCheckList2WithOutPart = equipmentSpotCheckList.stream().filter(o -> (null != o && !pidList2Part.contains(o.getId()))).collect(Collectors.toList());
            //搜集关联当前产成零件的设备点检主数据
            List<MesEquipmentSpotCheck> equipmentSpotCheckList2CurPart = CollectionUtils.isEmpty(pidList2CurPart) ? null : equipmentSpotCheckList.stream().filter(o -> (null != o && pidList2CurPart.contains(o.getId()))).collect(Collectors.toList());
            //合并过滤的设备点检主数据
            List<MesEquipmentSpotCheck> filterList = new ArrayList<>();
            if (!CollectionUtils.isEmpty(equipmentSpotCheckList2WithOutPart)) filterList.addAll(equipmentSpotCheckList2WithOutPart);
            if (!CollectionUtils.isEmpty(equipmentSpotCheckList2CurPart)) filterList.addAll(equipmentSpotCheckList2CurPart);
            return filterList;
        } else return equipmentSpotCheckList;

    }

    //根据点检方式搜集设备点检主数据
    private List<MesEquipmentSpotCheck> filterEquipmentSpotCheckList(List<MesEquipmentSpotCheck> equipmentSpotCheckList, Integer spotCheckType) {
        return equipmentSpotCheckList.stream().filter(o -> (null != o && o.getSpotCheckType().compareTo(spotCheckType) == 0)).collect(Collectors.toList());
    }

    //搜集设备点检主数据的ID集合
    private List<Long> filterSpotCheckIdList(List<MesEquipmentSpotCheck> equipmentSpotCheckList) {
        return CollectionUtils.isEmpty(equipmentSpotCheckList) ? null : equipmentSpotCheckList.stream().filter(o -> null != o).map(MesEquipmentSpotCheck::getId).collect(Collectors.toList());
    }

    //搜集设备点检单据的ID集合
    private List<Long> filterSpotCheckOrderIdList(List<MesSpotCheckOrder> spotCheckOrderList) {
        return CollectionUtils.isEmpty(spotCheckOrderList) ? null : spotCheckOrderList.stream().filter(o -> null != o).map(MesSpotCheckOrder::getId).collect(Collectors.toList());
    }

    //根据设备点检主数据的ID集合搜集明细集合
    private List<MesEquipmentSpotCheckDetail> filterEquipmentSpotCheckDetailList(List<MesEquipmentSpotCheckDetail> equipmentSpotCheckDetailList, List<Long> spotCheckIdList) {
        return (CollectionUtils.isEmpty(equipmentSpotCheckDetailList) || CollectionUtils.isEmpty(spotCheckIdList)) ? null :
                equipmentSpotCheckDetailList.stream().filter(o -> (null != o && spotCheckIdList.contains(o.getPid()))).collect(Collectors.toList());
    }

    //搜集设备数据变量ID集合
    private List<Long> filterEquipmentVariableIdList(List<MesSpotCheckOrderResult> spotCheckOrderResultList2After, List<MesSpotCheckOrderResult> spotCheckOrderResultList2All) {
        List<Long> equipmentVariableIdList = new ArrayList<>();
        addSetEquipVariableId(equipmentVariableIdList, spotCheckOrderResultList2After);
        addRealEquipVariableId(equipmentVariableIdList, spotCheckOrderResultList2After);
        addSetEquipVariableId(equipmentVariableIdList, spotCheckOrderResultList2All);
        addRealEquipVariableId(equipmentVariableIdList, spotCheckOrderResultList2All);
        if (!CollectionUtils.isEmpty(equipmentVariableIdList)) equipmentVariableIdList = equipmentVariableIdList.stream().filter(o -> !StringUtils.isEmpty(o)).distinct().collect(Collectors.toList());
        return equipmentVariableIdList;
    }

    //搜集设备数据变量ID集合[设定值]
    private void addSetEquipVariableId(List<Long> equipmentVariableIdList, List<MesSpotCheckOrderResult> spotCheckOrderResultList) {
        if (CollectionUtils.isEmpty(spotCheckOrderResultList)) return;
        List<Long> setIdList = spotCheckOrderResultList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getSetEquipVariableId()))).map(MesSpotCheckOrderResult::getSetEquipVariableId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(setIdList)) equipmentVariableIdList.addAll(setIdList);
    }

    //搜集设备数据变量ID集合[实际值]
    private void addRealEquipVariableId(List<Long> equipmentVariableIdList, List<MesSpotCheckOrderResult> spotCheckOrderResultList) {
        if (CollectionUtils.isEmpty(spotCheckOrderResultList)) return;
        List<Long> realIdList = spotCheckOrderResultList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getRealEquipVariableId()))).map(MesSpotCheckOrderResult::getRealEquipVariableId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(realIdList)) equipmentVariableIdList.addAll(realIdList);
    }

    //将明细主数据封装成单据明细数据
    private List<MesSpotCheckOrderResult> packSpotCheckOrderResultList(StationRequestBean reqBean, MesCellEquipContext cellEquipContext, List<MesEquipmentSpotCheckDetail> equipmentSpotCheckDetailList) {
        if (CollectionUtils.isEmpty(equipmentSpotCheckDetailList)) return null;

        List<MesSpotCheckOrderResult> spotCheckOrderResultList = new ArrayList<>();
        for (MesEquipmentSpotCheckDetail equipmentSpotCheckDetail : equipmentSpotCheckDetailList) {
            if (null == equipmentSpotCheckDetail) continue;

            MesSpotCheckOrderResult spotCheckOrderResult = new MesSpotCheckOrderResult();
            BeanUtils.copyProperties(equipmentSpotCheckDetail, spotCheckOrderResult, MesPcnExtConstWords.BASE_BEAN_FIELDS);
            spotCheckOrderResult.setOrganizeCode(reqBean.getOrganizeCode());
            spotCheckOrderResult.setWorkCenterCode(reqBean.getWorkCenterCode());
            spotCheckOrderResult.setWorkCellCode(reqBean.getWorkCellCode());
            spotCheckOrderResult.setSpotCheckItemId(equipmentSpotCheckDetail.getId());
            spotCheckOrderResult.setTaskItemName(equipmentSpotCheckDetail.getSpotCheckItemName());
            spotCheckOrderResult.setSpotCheckStandardValue(equipmentSpotCheckDetail.getStandardValue());

            spotCheckOrderResultList.add(spotCheckOrderResult);
        }
        return spotCheckOrderResultList;
    }

    //采集后的数据进行分组
    private Map<Long, String> groupByEquipVariableCollectContext(List<MesEquipVariableCollectContext> equipVariableCollectContextList) {
        equipVariableCollectContextList = equipVariableCollectContextList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getEquipVariableValue())))
                .distinct().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MesEquipVariableCollectContext::getEquipVariableId))), ArrayList::new));
        return CollectionUtils.isEmpty(equipVariableCollectContextList) ? null :
                equipVariableCollectContextList.stream().filter(o -> null != o).collect(Collectors.toMap(MesEquipVariableCollectContext::getEquipVariableId, MesEquipVariableCollectContext::getEquipVariableValue));
    }

    //保存点检数据, 判断是否超差
    private Boolean saveSpotCheckOrderResultListValue(StationRequestBean reqBean, MesCellEquipContext cellEquipContext, List<MesSpotCheckOrderResult> spotCheckOrderResultList, Map<Long, String> equipVariableCollectMap,
                                                      List<MesSpotCheckOrder> spotCheckOrderList, List<MesEquipmentSpotCheckDetail> equipmentSpotCheckDetailList, List<MesEquipmentSpotCheck> equipmentSpotCheckList) {
        if (CollectionUtils.isEmpty(spotCheckOrderResultList)) return false;

        //判断点检方式: true=全部点检  false=加工后
        Boolean isAllCheck = CollectionUtils.isEmpty(spotCheckOrderList) ? true : false;

        Map<Long, MesSpotCheckOrder> spotCheckOrderMap;
        Map<Long, MesEquipmentSpotCheckDetail> equipmentSpotCheckDetailMap = null;
        Map<Long, MesEquipmentSpotCheck> equipmentSpotCheckMap = null;
        if (isAllCheck) {
            //全部点检基于主数据
            spotCheckOrderMap = new HashMap<>();
            equipmentSpotCheckDetailMap = equipmentSpotCheckDetailList.stream().filter(o -> null != o).collect(Collectors.toMap(MesEquipmentSpotCheckDetail::getId, o -> o));
            equipmentSpotCheckMap = equipmentSpotCheckList.stream().filter(o -> null != o).collect(Collectors.toMap(MesEquipmentSpotCheck::getId, o -> o));
        } else {
            //加工后基于单据
            spotCheckOrderMap = spotCheckOrderList.stream().filter(o -> null != o).collect(Collectors.toMap(MesSpotCheckOrder::getId, o -> o));
        }

        String nowTime = TimeTool.getNowTime(true);

        //当前类型的超差结果
        Boolean isTolerance = false;
        //点检项结果
        Boolean spotCheckResult;
        for (MesSpotCheckOrderResult spotCheckOrderResult : spotCheckOrderResultList) {
            if (null == spotCheckOrderResult) continue;

            //判断是否超差
            if (checkIsTolerance(spotCheckOrderResult.getMaxValue(), spotCheckOrderResult.getMinValue(), spotCheckOrderResult.getSpotCheckSetValue()) ||
                    checkIsTolerance(spotCheckOrderResult.getMaxValue(), spotCheckOrderResult.getMinValue(), spotCheckOrderResult.getSpotCheckSetValue())) {
                isTolerance = true;
                spotCheckResult = false;
            } else {
                spotCheckResult = true;
            }

            if (!isAllCheck) {
                //加工后:修改点检项结果
                spotCheckOrderResultRepository.updateByPropertiesNoSync(
                        new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.ID},
                        new Object[]{reqBean.getOrganizeCode(), spotCheckOrderResult.getId()},
                        new String[]{MesPcnExtConstWords.SET_VALUE_RECORD_TYPE, MesPcnExtConstWords.REAL_VALUE_RECORD_TYPE, MesPcnExtConstWords.SPOT_CHECK_SET_VALUE,
                                MesPcnExtConstWords.SPOT_CHECK_REAL_VALUE, MesPcnExtConstWords.IS_TOLERANCE, MesPcnExtConstWords.SPOT_CHECK_RESULT,
                                MesPcnExtConstWords.MODIFY_USER, MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.SYSTEM_SYNC_STATUS, MesPcnExtConstWords.SYSTEM_SYNC_DATE_TIME},
                        new Object[]{MesExtEnumUtil.SPOT_VALUE_RECORD_TYPE.EQUIPMENT_INPUT.getValue(), MesExtEnumUtil.SPOT_VALUE_RECORD_TYPE.EQUIPMENT_INPUT.getValue(),
                                equipVariableCollectMap.get(spotCheckOrderResult.getSetEquipVariableId()), equipVariableCollectMap.get(spotCheckOrderResult.getRealEquipVariableId()),
                                !spotCheckResult ? CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue() : MesPcnExtConstWords.ZERO,
                                !spotCheckResult ? MesExtEnumUtil.SPOT_CHECK_ORDER_RESULT_TYPE.NOK.getDescription() : MesExtEnumUtil.SPOT_CHECK_ORDER_RESULT_TYPE.OK.getDescription(),
                                reqBean.getUserInfo(), nowTime, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesPcnExtConstWords.EMPTY});

                //加工后:如果NOK则修改点检单据结果,然后从spotCheckOrderMap集合中剔除该单据,key=单据ID; 剩下的均是OK的单据在最后再进行遍历修改OK结果
                if (!spotCheckResult && spotCheckOrderMap.containsKey(spotCheckOrderResult.getPid())) {
                    spotCheckOrderRepository.updateByPropertiesNoSync(
                            new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.ID},
                            new Object[]{reqBean.getOrganizeCode(), spotCheckOrderResult.getPid()},
                            new String[]{MesPcnExtConstWords.SPOT_CHECK_ORDER_RESULT, MesPcnExtConstWords.SPOT_CHECK_TIME, MesPcnExtConstWords.SPOT_CHECK_USER, MesPcnExtConstWords.STATUS,
                                    MesPcnExtConstWords.MODIFY_USER, MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.SYSTEM_SYNC_STATUS, MesPcnExtConstWords.SYSTEM_SYNC_DATE_TIME},
                            new Object[]{MesExtEnumUtil.SPOT_CHECK_ORDER_RESULT_TYPE.NOK.getValue(), nowTime, reqBean.getUserInfo(), MesExtEnumUtil.SPOT_CHECK_ORDER_STATUS.COMPLETE.getValue(),
                                    reqBean.getUserInfo(), nowTime, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesPcnExtConstWords.EMPTY});
                    spotCheckOrderMap.remove(spotCheckOrderResult.getPid());
                }

            } else {
                //全部点检:NOK需要创建一个单据记录,并保存NOK的明细记录; OK情况下无须保存记录
                spotCheckOrderResult.setSetValueRecordType(MesExtEnumUtil.SPOT_VALUE_RECORD_TYPE.EQUIPMENT_INPUT.getValue());
                spotCheckOrderResult.setRealValueRecordType(MesExtEnumUtil.SPOT_VALUE_RECORD_TYPE.EQUIPMENT_INPUT.getValue());
                spotCheckOrderResult.setSpotCheckSetValue(equipVariableCollectMap.get(spotCheckOrderResult.getSetEquipVariableId()));
                spotCheckOrderResult.setSpotCheckRealValue(equipVariableCollectMap.get(spotCheckOrderResult.getRealEquipVariableId()));
                if (!spotCheckResult) {
                    spotCheckOrderResult.setIsTolerance(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
                    spotCheckOrderResult.setSpotCheckResult(MesExtEnumUtil.SPOT_CHECK_ORDER_RESULT_TYPE.NOK.getDescription());

                    Long spotCheckId = equipmentSpotCheckDetailMap.get(spotCheckOrderResult.getSpotCheckItemId()).getPid();
                    MesSpotCheckOrder spotCheckOrder = spotCheckOrderMap.get(spotCheckId);
                    //判断是否已经保存过全部点检类型的NOK单据, 保存之后暂存到spotCheckOrderMap集合中, key=主数据ID
                    if (null == spotCheckOrder) {
                        spotCheckOrder = new MesSpotCheckOrder();

                        try {
                            List<String> resultList = syncFuncService.syncSerialNo(new GenSerialNoModel(MesCommonConstant.SPOT_CHECK_ORDER_NO_RULE), reqBean.getUserInfo(), reqBean.getOrganizeCode(), 1).getResultList();
                            spotCheckOrder.setSpotCheckOrderNo(resultList.get(0));
                        } catch (Exception e) {
                            spotCheckOrder.setSpotCheckOrderNo(snowflakeIdMaker.nextId() + MesPcnExtConstWords.EMPTY);
                        }

                        MesEquipmentSpotCheck equipmentSpotCheck = equipmentSpotCheckMap.get(spotCheckId);
                        spotCheckOrder.setSpotCheckCode(equipmentSpotCheck.getSpotCheckCode());
                        spotCheckOrder.setSpotCheckName(equipmentSpotCheck.getSpotCheckName());
                        spotCheckOrder.setSpotCheckOrderType(equipmentSpotCheck.getSpotCheckOrderType());
                        spotCheckOrder.setTriggerMode(equipmentSpotCheck.getTriggerMode());

                        spotCheckOrder.setOrganizeCode(reqBean.getOrganizeCode());
                        spotCheckOrder.setWorkCenterCode(reqBean.getWorkCenterCode());
                        spotCheckOrder.setWorkCellCode(reqBean.getWorkCellCode());
                        spotCheckOrder.setSpotCheckId(spotCheckId);
                        spotCheckOrder.setEquipCode(cellEquipContext.getEquipmentCode());
                        spotCheckOrder.setEquipName(cellEquipContext.getEquipmentName());
                        spotCheckOrder.setTaskResource(MesCommonConstant.SPOT_CHECK_ORDER_TASK_RESOURCE);

                        spotCheckOrder.setSpotCheckOrderResult(MesExtEnumUtil.SPOT_CHECK_ORDER_RESULT_TYPE.NOK.getValue());
                        spotCheckOrder.setSpotCheckTime(nowTime);
                        spotCheckOrder.setSpotCheckUser(reqBean.getUserInfo());
                        spotCheckOrder.setStatus(MesExtEnumUtil.SPOT_CHECK_ORDER_STATUS.COMPLETE.getValue());
                        ConvertBean.serviceModelInitialize(spotCheckOrder, reqBean.getUserInfo());
                        spotCheckOrderRepository.insert(spotCheckOrder);
                        spotCheckOrderMap.put(spotCheckId, spotCheckOrder);
                    }
                    spotCheckOrderResult.setPid(spotCheckOrder.getId());
                    spotCheckOrderResult.setSpotCheckOrderNo(spotCheckOrder.getSpotCheckOrderNo());
                    ConvertBean.serviceModelInitialize(spotCheckOrderResult, reqBean.getUserInfo());
                    spotCheckOrderResultRepository.insert(spotCheckOrderResult);
                }

            }

        }

        //加工后:spotCheckOrderMap集合中剩下的均是OK的单据, 遍历修改OK结果
        if (!isAllCheck && !CollectionUtils.isEmpty(spotCheckOrderMap)) {
            for (Long id : spotCheckOrderMap.keySet()) {
                if (StringUtils.isEmpty(id)) continue;
                spotCheckOrderRepository.updateByPropertiesNoSync(
                        new String[]{MesPcnExtConstWords.ORGANIZE_CODE, MesPcnExtConstWords.ID},
                        new Object[]{reqBean.getOrganizeCode(), id},
                        new String[]{MesPcnExtConstWords.SPOT_CHECK_ORDER_RESULT, MesPcnExtConstWords.SPOT_CHECK_TIME, MesPcnExtConstWords.SPOT_CHECK_USER, MesPcnExtConstWords.STATUS,
                                MesPcnExtConstWords.MODIFY_USER, MesPcnExtConstWords.MODIFY_DATE_TIME, MesPcnExtConstWords.SYSTEM_SYNC_STATUS, MesPcnExtConstWords.SYSTEM_SYNC_DATE_TIME},
                        new Object[]{MesExtEnumUtil.SPOT_CHECK_ORDER_RESULT_TYPE.OK.getValue(), nowTime, reqBean.getUserInfo(), MesExtEnumUtil.SPOT_CHECK_ORDER_STATUS.COMPLETE.getValue(),
                                reqBean.getUserInfo(), nowTime, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), MesPcnExtConstWords.EMPTY});
            }
        }

        return isTolerance;
    }

    //判断是否超差
    private Boolean checkIsTolerance(Double maxValue, Double minValue, String spotCheckSetValue) {
        if (StringUtils.isEmpty(spotCheckSetValue)) return false;
        Double value;
        try {
            value = Double.valueOf(spotCheckSetValue);
        } catch (NumberFormatException e) {
            return false;
        }
        if (!StringUtils.isEmpty(maxValue) && MathOperation.compareTo(maxValue, value) < 0) return true;
        if (!StringUtils.isEmpty(minValue) && MathOperation.compareTo(minValue, value) > 0) return true;
        return false;
    }

}
