package cn.estsh.i3plus.ext.mes.apiservice.serviceimpl.base;

import cn.estsh.i3plus.ext.mes.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pojo.model.MesHistogramModel;
import cn.estsh.i3plus.ext.mes.pojo.model.WorkCenterBorderModule;
import cn.estsh.i3plus.ext.mes.pojo.repository.*;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
import cn.estsh.i3plus.mes.api.iservice.base.IConfigService;
import cn.estsh.i3plus.mes.apiservice.util.DateUtil;
import cn.estsh.i3plus.platform.common.tool.MathOperation;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.bean.ListPager;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.common.PagerHelper;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.repository.MesAreaRepository;
import cn.estsh.i3plus.pojo.mes.repository.MesBoardRepository;
import cn.estsh.i3plus.pojo.mes.sqlpack.MesHqlPack;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author yumingxing
 * @version 1.0
 * @date 2021/6/8 15:21
 **/
@Service
@Slf4j
public class WorkCenterRunningStatusService {

    public final static String CONFIG_NAME = "PRODUCTION-OPERATION";

    @Autowired
    private MesWorkCenterExtRepository workCenterExtRepository;
    @Autowired
    private MesShiftExtRepository shiftExtRepository;
    @Autowired
    private MesOrderJobRepository orderJobRepository;
    @Autowired
    private MesWorkOrderExtRepository workOrderExtRepository;
    @Autowired
    private MesFourMDetailRepository fourMDetailRepository;
    @Autowired
    private MesBoardRepository boardRepository;
    @Autowired
    private MesRepairTaskRepository repairTaskRDao;
    @Autowired
    private MesPartExtRepository partExtRDao;
    @Autowired
    private MesShiftProdCenterRecordRepository shiftProdCenterRecordRepository;
    @Autowired
    private MesWorkCenterNotificationBarRepository workCenterNotificationBarRDao;
    @Autowired
    private MesAreaRepository areaRepository;
    @Autowired
    private MesOutPutStatisticsRepository outPutStatisticsRDao;
    @Autowired
    private IConfigService configService;


    public WorkCenterBorderModule getData(String workCenterCode, String areaCode, String organizeCode) throws ParseException {

        WorkCenterBorderModule workCenterBorderModule = new WorkCenterBorderModule();

        //日期时间
        workCenterBorderModule.setCurrentTime(DateUtil.formatDate());
        //获取产线信息
        MesWorkCenterExt workCenterExt = getWorkCenterExt(workCenterCode, areaCode, organizeCode);

        if(organizeCode.contains(MesExtConstWords.CJ)){
            //看板名称
            workCenterBorderModule.setBorderName(workCenterExt.getWorkCenterDesc() + "产线运行状态看板");
        }else{
            //看板名称
            workCenterBorderModule.setBorderName(workCenterCode + "产线运行状态看板");
        }


        if (null == workCenterExt) {
            return workCenterBorderModule;
        }
        String shiftCode = workCenterExt.getShiftCode();
        MesShiftExt shiftExt = getShiftExt(shiftCode, workCenterCode, organizeCode);
        if(shiftExt == null){
            log.info("根据班次代码{}产线代码{}未找到班次信息",shiftExt, workCenterExt);
        }else{
            String shiftName = shiftExt.getShiftName();
            //当前班次
            workCenterBorderModule.setShiftName(shiftName);
        }


        //产线公告
        List<MesWorkCenterNotificationBar> centerNotificationBars = getCenterNotificationBars(workCenterCode, areaCode, organizeCode);
        //公告内容
        if (CollectionUtils.isEmpty(centerNotificationBars)) {
            workCenterBorderModule.setNotificationBar("暂无公告");
        } else {
            MesWorkCenterNotificationBar notificationBar = centerNotificationBars.iterator().next();
            workCenterBorderModule.setNotificationBar(notificationBar.getContent());
        }
        //工单作业时间
        String workTime = workCenterExt.getWorkTime();
        if (StringUtils.isEmpty(workTime)) {
            workTime = TimeTool.getToday();
        }

        //单据作业,查询当天的作业单据总数
        List<MesOrderJob> totalOrderJobs = getTotalOrderJobs(workTime, workCenterCode, organizeCode);

        workCenterBorderModule.setTotalOrderJobCount(CollectionUtils.isEmpty(totalOrderJobs) ? 0 : totalOrderJobs.size());
        //查询当天作业单据的完成总数量
        List<MesOrderJob> finishOrderJobs = getFinishOrderJobs(workTime, workCenterCode, organizeCode);
        workCenterBorderModule.setFinishOrderJobCount(CollectionUtils.isEmpty(finishOrderJobs) ? 0 : finishOrderJobs.size());

        //标准工时
        //标准作业时间 ：各产品当日实绩数量*产品标准工时然后进行汇总。
        double standardWorkTime = 0.0;

        //查询当前班次启动日期下线条码
        //List<MesProduceSnExt> snExtList = getMesProduceSnExts(workCenterCode, workTime, organizeCode, null);
        List<MesOutPutStatistics> outPutStatisticsList = getOutPutStatistics(workCenterCode, workTime, null, null, organizeCode);
        //查询当前班次下线条码
        //List<MesProduceSnExt> snExtListByCode = getMesProduceSnExts(workCenterCode, workTime, organizeCode, shiftCode);
        List<MesOutPutStatistics> outPutStatisticsListByShiftCode = getOutPutStatistics(workCenterCode, workTime, shiftCode, null, organizeCode);

        Map<String, List<MesOutPutStatistics>> snMapGroupByPartNo = outPutStatisticsListByShiftCode.stream().collect(Collectors.groupingBy(MesOutPutStatistics::getPartNo));

        for (Map.Entry<String, List<MesOutPutStatistics>> snListEntry : snMapGroupByPartNo.entrySet()) {
            //物料编码
            String partNo = snListEntry.getKey();
            //物料信息
            MesPartExt mesPartExt = getMesPartExt(partNo, organizeCode);
            //物料标准工数
            Double standardWork = mesPartExt.getStandardWork();
            if (BigDecimal.valueOf(standardWork).compareTo(BigDecimal.ZERO) == 0 || BigDecimal.valueOf(standardWork).compareTo(BigDecimal.ZERO) == -1) {
                standardWork = 1.0;
            }

            //物料的完成数量（各产品当日实绩数量）
            Double sumCompleteQtyByPartNo = snListEntry.getValue().stream().map(MesOutPutStatistics::getQty).reduce(0.00, Double::sum);

            //产品标准工时
            double standardWorkTimeByPartNo = MathOperation.mul(sumCompleteQtyByPartNo, standardWork);

            //各产品当日产品标准工时进行累加。
            standardWorkTime = MathOperation.add(standardWorkTime, standardWorkTimeByPartNo);
        }

        //今日工单
        List<MesWorkOrderExt> workOrderExts = getWorkOrderExts(workCenterCode, TimeTool.getToday(), organizeCode);
        //当日计划
        Double sumQty = workOrderExts.stream().map(MesWorkOrderExt::getQty).reduce(0.00, Double::sum);
        workCenterBorderModule.setTotalQty(sumQty);
        //当日实际生产
        Double sumCompleteQty = outPutStatisticsList.stream().map(MesOutPutStatistics::getQty).reduce(0.00, Double::sum);
        workCenterBorderModule.setTotalCompleteQty(sumCompleteQty);

        //当前产线停开机记录
        List<MesShiftProdCenterRecord> shiftProdCenterRecordList = getShiftProdCenterRecord(workCenterCode, shiftCode, workTime, organizeCode);

        //过滤停开机作业记录中 常规生产的数据（正常上班）
        List<MesShiftProdCenterRecord> conventionList = shiftProdCenterRecordList.stream().filter(
                o -> (null != o && (o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.NORMAL_PROD.getValue()))).collect(Collectors.toList());
        //当前常规作业时长（正常上班）
        Double conventionWorkTime = getServiceWorkTime(conventionList);

        //过滤停开机作业记录中 非常规生产的数据（加班上班）
        List<MesShiftProdCenterRecord> unConventionList = shiftProdCenterRecordList.stream().filter(
                o -> (null != o && (o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.UNNORMAL_PROD.getValue()))).collect(Collectors.toList());
        //当前非常规作业时长（加班上班）
        Double unConventionWorkTime = getServiceWorkTime(unConventionList);


        //过滤停开机作业记录中 非常规停机的数据（异常停机）
        List<MesShiftProdCenterRecord> unnormalStopCenterList = shiftProdCenterRecordList.stream().filter(
                o -> (null != o && (o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.UNNORMAL_STOP_CENTER.getValue()))).collect(Collectors.toList());
        //当前非常规停机时长（非作业时长）
        Double unormalStopCenterTime = getServiceWorkTime(unnormalStopCenterList);

        //过滤停开机作业记录中 常规停机的数据（常规停机）
        List<MesShiftProdCenterRecord> stopCenterList = shiftProdCenterRecordList.stream().filter(
                o -> (null != o && (o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.NORMAL_STOP_CENTER.getValue()))).collect(Collectors.toList());
        //当前常规停机的数据（非作业时长）
        Double stopCenterTime = getServiceWorkTime(stopCenterList);


        //总作业时间：(当前常规作业时长+当前非常规作业时长)-当前非常规停机时长
        Double totalWorkTime = MathOperation.sub(MathOperation.add(conventionWorkTime, unConventionWorkTime), MathOperation.add(unormalStopCenterTime, stopCenterTime));

        //作业能率 = 标准作业时间/（勤务时间-非作业时间) * 100%,保留一位小数
        //作业能率 =标准作业时间/总作业时间*100%，保留一位小数
        BigDecimal workRateBigDecimal = BigDecimal.valueOf(totalWorkTime);
        BigDecimal workRate = workRateBigDecimal.compareTo(BigDecimal.ZERO) > 0 ? BigDecimal.valueOf(standardWorkTime).divide(workRateBigDecimal, 3, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO;
        workCenterBorderModule.setWorkRate(workRate.doubleValue());

        //总勤务时间
        //Double serviceWorkTime = getServiceWorkTime(shiftProdCenterRecordList);
        Double serviceWorkTime = MathOperation.add(conventionWorkTime, unConventionWorkTime);
        //综合能率：标准作业时间/勤务时间*100%，保留1位小数。
        BigDecimal serviceWorkTimeBigDecimal = BigDecimal.valueOf(serviceWorkTime);
        BigDecimal totalRate = serviceWorkTimeBigDecimal.compareTo(BigDecimal.ZERO) > 0 ? BigDecimal.valueOf(standardWorkTime).divide(serviceWorkTimeBigDecimal, 3, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO;
        workCenterBorderModule.setTotalRate(totalRate.doubleValue());

        //达成率 = 当日实绩/当日计划*100%,保留1位小数
        BigDecimal yieldRate = BigDecimal.valueOf(sumQty).compareTo(BigDecimal.ZERO) > 0 ? BigDecimal.valueOf(sumCompleteQty).divide(BigDecimal.valueOf(sumQty), 3, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO;
        workCenterBorderModule.setYieldRate(yieldRate.doubleValue());

        //过滤当日下线中的所有工单
        List<String> outPutWoNoList = outPutStatisticsList.stream().map(MesOutPutStatistics::getWorkOrderNo).collect(Collectors.toList());
        List<MesRepairTask> repairTasks = getMesRepairTasksByTodayAndWoNo(outPutWoNoList, organizeCode);
        Double repairQty = repairTasks.stream().map(MesRepairTask::getRepairQty).reduce(0.00, Double::sum);
        //不良率 = 当日不良数量汇总/当日实绩汇总*100%，保留1位小数。
        if (BigDecimal.valueOf(sumCompleteQty).compareTo(BigDecimal.ZERO) > 0) {
            BigDecimal defectiveRate = BigDecimal.valueOf(repairQty).compareTo(BigDecimal.ZERO) > 0 ? BigDecimal.valueOf(repairQty).divide(BigDecimal.valueOf(sumCompleteQty), 3, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO;
            workCenterBorderModule.setDefectiveRate(defectiveRate.doubleValue());
        } else {
            workCenterBorderModule.setDefectiveRate(0.0);
        }

        //当前系统时间去查询是存在停开机记录当中的数据
        List<MesShiftProdCenterRecord> shiftProdCenterRecordByNowList = getShiftProdCenterRecordByNow(workCenterCode, shiftCode, organizeCode);

        if (CollectionUtils.isEmpty(shiftProdCenterRecordByNowList)) {
            workCenterBorderModule.setWorkCenterStatus("gray");
            workCenterBorderModule.setWorkCenterStatusName("无生产");
            //无生产，当前作业人数为零
            workCenterBorderModule.setWorkerQty(0.0);
        }

        //通知栏：
        for (MesShiftProdCenterRecord shiftProdCenterRecord : shiftProdCenterRecordByNowList) {
            //停机类型
            Integer prodType = shiftProdCenterRecord.getProdType();
            workCenterBorderModule.setWorkerQty(shiftProdCenterRecord.getWorkerQty());

            //判断存在于哪个停开机类型
            switch (MesExtEnumUtil.SHIFT_PROD_TYPE.getByValue(prodType)) {
                //红色 异常停机项目描述：停机作业记录中非常规停机项目描述。
                case UNNORMAL_STOP_CENTER:
                    workCenterBorderModule.setWorkCenterStatus("red");
                    workCenterBorderModule.setWorkCenterStatusName("异常停机");
                    break;
                case NORMAL_STOP_CENTER:
                    workCenterBorderModule.setWorkCenterStatus("gray");
                    workCenterBorderModule.setWorkCenterStatusName("常规停机");
                    break;
                case UNNORMAL_PROD:
                    workCenterBorderModule.setWorkCenterStatus("green");
                    workCenterBorderModule.setWorkCenterStatusName("加班生产");
                    break;
                case NORMAL_PROD:
                    workCenterBorderModule.setWorkCenterStatus("green");
                    workCenterBorderModule.setWorkCenterStatusName("正常生产");
                    break;
                default:
                    workCenterBorderModule.setWorkCenterStatus("gray");
                    workCenterBorderModule.setWorkCenterStatusName("无生产");
                    break;
            }
        }

        return workCenterBorderModule;
    }


    public WorkCenterBorderModule getEpData(String workCenterCode, String areaCode, String organizeCode) throws ParseException {

        WorkCenterBorderModule workCenterBorderModule = new WorkCenterBorderModule();

        //日期时间
        workCenterBorderModule.setCurrentTime(DateUtil.formatDate());
        //获取产线信息
        MesWorkCenterExt workCenterExt = getWorkCenterExt(workCenterCode, areaCode, organizeCode);

        //看板名称
        workCenterBorderModule.setBorderName(workCenterExt.getWorkCenterDesc() + "线运行看板");

        if (null == workCenterExt) {
            return workCenterBorderModule;
        }
        String shiftCode = workCenterExt.getShiftCode();
        MesShiftExt shiftExt = getShiftExt(shiftCode, workCenterCode, organizeCode);
        if(shiftExt == null){
            log.info("根据班次代码{}产线代码{}未找到班次信息",shiftExt, workCenterExt);
        }else{
            String shiftName = shiftExt.getShiftName();
            //当前班次
            workCenterBorderModule.setShiftName(shiftName);
        }

        //产线公告
        List<MesWorkCenterNotificationBar> centerNotificationBars = getCenterNotificationBars(workCenterCode, areaCode, organizeCode);
        //公告内容
        if (CollectionUtils.isEmpty(centerNotificationBars)) {
            workCenterBorderModule.setNotificationBar("暂无公告");
        } else {
            MesWorkCenterNotificationBar notificationBar = centerNotificationBars.iterator().next();
            workCenterBorderModule.setNotificationBar(notificationBar.getContent());
        }
        //工单作业时间
        String workTime = workCenterExt.getWorkTime();
        if (StringUtils.isEmpty(workTime)) {
            workTime = TimeTool.getToday();
        }

        //单据作业,查询当天的作业单据总数
        List<MesOrderJob> totalOrderJobs = getTotalOrderJobs(workTime, workCenterCode, organizeCode);
        //过滤不包含关闭状态的单据作业
        totalOrderJobs = CollectionUtils.isEmpty(totalOrderJobs) ? null : totalOrderJobs.stream().filter(orderJob -> orderJob.getOrderStatus() != MesExtEnumUtil.MES_ORJ_ORDER_STATUS.CLOSE.getValue()).collect(Collectors.toList());
        workCenterBorderModule.setTotalOrderJobCount(CollectionUtils.isEmpty(totalOrderJobs) ? 0 : totalOrderJobs.size());
        //查询当天作业单据的完成总数量
        List<MesOrderJob> finishOrderJobs = getFinishOrderJobs(workTime, workCenterCode, organizeCode);
        workCenterBorderModule.setFinishOrderJobCount(CollectionUtils.isEmpty(finishOrderJobs) ? 0 : finishOrderJobs.size());

        //标准工时
        //标准作业时间 ：各产品当日实绩数量*产品标准工时然后进行汇总。
        double standardWorkTime = 0.0;

        //查询当前班次启动日期下线条码
        //List<MesProduceSnExt> snExtList = getMesProduceSnExts(workCenterCode, workTime, organizeCode, null);
        List<MesOutPutStatistics> outPutStatisticsList = getOutPutStatistics(workCenterCode, workTime, null, null, organizeCode);
        //查询当前班次下线条码
        //List<MesProduceSnExt> snExtListByCode = getMesProduceSnExts(workCenterCode, workTime, organizeCode, shiftCode);
        List<MesOutPutStatistics> outPutStatisticsListByShiftCode = getOutPutStatistics(workCenterCode, workTime, shiftCode, null, organizeCode);

        Map<String, List<MesOutPutStatistics>> snMapGroupByPartNo = outPutStatisticsListByShiftCode.stream().collect(Collectors.groupingBy(MesOutPutStatistics::getPartNo));

        for (Map.Entry<String, List<MesOutPutStatistics>> snListEntry : snMapGroupByPartNo.entrySet()) {
            //物料编码
            String partNo = snListEntry.getKey();
            //物料信息
            MesPartExt mesPartExt = getMesPartExt(partNo, organizeCode);
            //物料标准工数
            Double standardWork = mesPartExt.getStandardWork();
            if (BigDecimal.valueOf(standardWork).compareTo(BigDecimal.ZERO) == 0 || BigDecimal.valueOf(standardWork).compareTo(BigDecimal.ZERO) == -1) {
                standardWork = 1.0;
            }

            //物料的完成数量（各产品当日实绩数量）
            Double sumCompleteQtyByPartNo = snListEntry.getValue().stream().map(MesOutPutStatistics::getQty).reduce(0.00, Double::sum);

            //产品标准工时
            double standardWorkTimeByPartNo = MathOperation.mul(sumCompleteQtyByPartNo, standardWork);

            //各产品当日产品标准工时进行累加。
            standardWorkTime = MathOperation.add(standardWorkTime, standardWorkTimeByPartNo);
        }

        //今日工单
        List<MesWorkOrderExt> workOrderExts = getWorkOrderExtsContainReusePlanDatetime(workCenterCode, TimeTool.getToday(), organizeCode);
        //当日计划
        Double sumQty = workOrderExts.stream().filter(mesWorkOrderExt -> StringUtils.isEmpty(mesWorkOrderExt.getReusePlanDatetime())).map(MesWorkOrderExt::getQty).reduce(0.00, Double::sum);
        Double reusePlanCompleteQty = workOrderExts.stream().filter(mesWorkOrderExt -> !StringUtils.isEmpty(mesWorkOrderExt.getReusePlanDatetime())).map(MesWorkOrderExt::getReusePlanCompleteQty).reduce(0.00, Double::sum);
        sumQty += reusePlanCompleteQty;
        workCenterBorderModule.setTotalQty(sumQty);
        //当日实际生产
        Double sumCompleteQty = outPutStatisticsList.stream().map(MesOutPutStatistics::getQty).reduce(0.00, Double::sum);
        workCenterBorderModule.setTotalCompleteQty(sumCompleteQty);

        //当前产线停开机记录
        List<MesShiftProdCenterRecord> shiftProdCenterRecordList = getShiftProdCenterRecord(workCenterCode, shiftCode, workTime, organizeCode);

        //过滤停开机作业记录中 常规生产的数据（正常上班）
        List<MesShiftProdCenterRecord> conventionList = shiftProdCenterRecordList.stream().filter(
                o -> (null != o && (o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.NORMAL_PROD.getValue()))).collect(Collectors.toList());
        //当前常规作业时长（正常上班）
        Double conventionWorkTime = getServiceWorkTime(conventionList);

        //过滤停开机作业记录中 非常规生产的数据（加班上班）
        List<MesShiftProdCenterRecord> unConventionList = shiftProdCenterRecordList.stream().filter(
                o -> (null != o && (o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.UNNORMAL_PROD.getValue()))).collect(Collectors.toList());
        //当前非常规作业时长（加班上班）
        Double unConventionWorkTime = getServiceWorkTime(unConventionList);


        //过滤停开机作业记录中 非常规停机的数据（异常停机）
        List<MesShiftProdCenterRecord> unnormalStopCenterList = shiftProdCenterRecordList.stream().filter(
                o -> (null != o && (o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.UNNORMAL_STOP_CENTER.getValue()))).collect(Collectors.toList());
        //当前非常规停机时长（非作业时长）
        Double unormalStopCenterTime = getServiceWorkTime(unnormalStopCenterList);

        //过滤停开机作业记录中 常规停机的数据（常规停机）
        List<MesShiftProdCenterRecord> stopCenterList = shiftProdCenterRecordList.stream().filter(
                o -> (null != o && (o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.NORMAL_STOP_CENTER.getValue()))).collect(Collectors.toList());
        //当前常规停机的数据（非作业时长）
        Double stopCenterTime = getServiceWorkTime(stopCenterList);


        //总作业时间：(当前常规作业时长+当前非常规作业时长)-当前非常规停机时长
        Double totalWorkTime = MathOperation.sub(MathOperation.add(conventionWorkTime, unConventionWorkTime), MathOperation.add(unormalStopCenterTime, stopCenterTime));

        //作业能率 = 标准作业时间/（勤务时间-非作业时间) * 100%,保留一位小数
        //作业能率 =标准作业时间/总作业时间*100%，保留一位小数
        BigDecimal workRateBigDecimal = BigDecimal.valueOf(totalWorkTime);
        BigDecimal workRate = workRateBigDecimal.compareTo(BigDecimal.ZERO) > 0 ? BigDecimal.valueOf(standardWorkTime).divide(workRateBigDecimal, 3, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO;
        workCenterBorderModule.setWorkRate(workRate.doubleValue());

        //总勤务时间
        //Double serviceWorkTime = getServiceWorkTime(shiftProdCenterRecordList);
        Double serviceWorkTime = MathOperation.add(conventionWorkTime, unConventionWorkTime);
        //综合能率：标准作业时间/勤务时间*100%，保留1位小数。
        BigDecimal serviceWorkTimeBigDecimal = BigDecimal.valueOf(serviceWorkTime);
        BigDecimal totalRate = serviceWorkTimeBigDecimal.compareTo(BigDecimal.ZERO) > 0 ? BigDecimal.valueOf(standardWorkTime).divide(serviceWorkTimeBigDecimal, 3, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO;
        workCenterBorderModule.setTotalRate(totalRate.doubleValue());

        //达成率 = 当日实绩/当日计划*100%,保留1位小数
        BigDecimal yieldRate = BigDecimal.valueOf(sumQty).compareTo(BigDecimal.ZERO) > 0 ? BigDecimal.valueOf(sumCompleteQty).divide(BigDecimal.valueOf(sumQty), 3, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO;
        workCenterBorderModule.setYieldRate(yieldRate.doubleValue());

        //过滤当日下线中的所有工单
        List<String> outPutWoNoList = outPutStatisticsList.stream().map(MesOutPutStatistics::getWorkOrderNo).collect(Collectors.toList());
        List<MesRepairTask> repairTasks = getMesRepairTasksByTodayAndWoNo(outPutWoNoList, organizeCode);
        Double repairQty = repairTasks.stream().map(MesRepairTask::getRepairQty).reduce(0.00, Double::sum);
        //不良率 = 当日不良数量汇总/当日实绩汇总*100%，保留1位小数。
        if (BigDecimal.valueOf(sumCompleteQty).compareTo(BigDecimal.ZERO) > 0) {
            BigDecimal defectiveRate = BigDecimal.valueOf(repairQty).compareTo(BigDecimal.ZERO) > 0 ? BigDecimal.valueOf(repairQty).divide(BigDecimal.valueOf(sumCompleteQty), 3, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)) : BigDecimal.ZERO;
            workCenterBorderModule.setDefectiveRate(defectiveRate.doubleValue());
        } else {
            workCenterBorderModule.setDefectiveRate(0.0);
        }

        //当前系统时间去查询是存在停开机记录当中的数据
        List<MesShiftProdCenterRecord> shiftProdCenterRecordByNowList = getShiftProdCenterRecordByNow(workCenterCode, shiftCode, organizeCode);

        if (CollectionUtils.isEmpty(shiftProdCenterRecordByNowList)) {
            workCenterBorderModule.setWorkCenterStatus("gray");
            workCenterBorderModule.setWorkCenterStatusName("无生产");
            //无生产，当前作业人数为零
            workCenterBorderModule.setWorkerQty(0.0);
        }

        //通知栏：
        for (MesShiftProdCenterRecord shiftProdCenterRecord : shiftProdCenterRecordByNowList) {
            //停机类型
            Integer prodType = shiftProdCenterRecord.getProdType();
            workCenterBorderModule.setWorkerQty(shiftProdCenterRecord.getWorkerQty());

            //判断存在于哪个停开机类型
            switch (MesExtEnumUtil.SHIFT_PROD_TYPE.getByValue(prodType)) {
                //红色 异常停机项目描述：停机作业记录中非常规停机项目描述。
                case UNNORMAL_STOP_CENTER:
                    workCenterBorderModule.setWorkCenterStatus("red");
                    workCenterBorderModule.setWorkCenterStatusName("异常停机");
                    break;
                case NORMAL_STOP_CENTER:
                    workCenterBorderModule.setWorkCenterStatus("gray");
                    workCenterBorderModule.setWorkCenterStatusName("常规停机");
                    break;
                case UNNORMAL_PROD:
                    workCenterBorderModule.setWorkCenterStatus("green");
                    workCenterBorderModule.setWorkCenterStatusName("加班生产");
                    break;
                case NORMAL_PROD:
                    workCenterBorderModule.setWorkCenterStatus("green");
                    workCenterBorderModule.setWorkCenterStatusName("正常生产");
                    break;
                default:
                    workCenterBorderModule.setWorkCenterStatus("gray");
                    workCenterBorderModule.setWorkCenterStatusName("无生产");
                    break;
            }
        }

        return workCenterBorderModule;
    }

    /**
     * @return java.util.List<cn.estsh.i3plus.ext.mes.pojo.bean.MesWorkCenterNotificationBar>
     * @Description: 获取产线公告
     * @Param [workCenterCode, areaCode]
     * @Date 2021/8/24 11:05
     **/
    private List<MesWorkCenterNotificationBar> getCenterNotificationBars(String workCenterCode, String areaCode, String organizeCode) {
        DdlPackBean notificationPackBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, notificationPackBean);
        DdlPreparedPack.getStringEqualPack(areaCode, MesExtConstWords.AREA_CODE, notificationPackBean);
        notificationPackBean.setOrderByStr(" order by createDatetime desc ");
        List<MesWorkCenterNotificationBar> centerNotificationBars = workCenterNotificationBarRDao.findByHqlWhere(notificationPackBean);
        return centerNotificationBars;
    }

    private MesPartExt getMesPartExt(String partNo, String organizeCode) {
        DdlPackBean partNoPackBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(partNo, MesExtConstWords.PART_NO, partNoPackBean);
        //物料信息
        MesPartExt mesPartExt = partExtRDao.getByProperty(partNoPackBean);
        return mesPartExt;
    }

    private List<MesRepairTask> getMesRepairTasksByTodayAndWoNo(List<String> outPutWoNoList, String organizeCode) {
        DdlPackBean repairTaskBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringRightLikerPack(TimeTool.getToday(), "repairDate", repairTaskBean);
        DdlPreparedPack.getInPackList(outPutWoNoList, MesExtConstWords.WORK_ORDER_NO, repairTaskBean);
        List<MesRepairTask> repairTasks = repairTaskRDao.findByHqlWhere(repairTaskBean);
        return repairTasks;
    }

    /**
     * 获取产线信息
     *
     * @param workCenterCode 工作中心代码
     * @param areaCode       区号
     * @return {@link MesWorkCenterExt}
     */
    public MesWorkCenterExt getWorkCenterExt(String workCenterCode, String areaCode, String organizeCode) {
        DdlPackBean workCenterCondition = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, workCenterCondition);
        DdlPreparedPack.getStringEqualPack(areaCode, MesExtConstWords.AREA_CODE, workCenterCondition);
        return workCenterExtRepository.getByProperty(workCenterCondition);
    }

    public MesShiftExt getShiftExt(String shiftCode, String workCenterCode, String organizeCode) {
        DdlPackBean shiftCondition = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, shiftCondition);
        DdlPreparedPack.getStringEqualPack(shiftCode, MesExtConstWords.SHIFT_CODE, shiftCondition);
        //DdlPreparedPack.getStringLikeEqualPack(TimeTool.getToday(),"");
        return shiftExtRepository.getByProperty(shiftCondition);
    }

    public List<MesOrderJob> getTotalOrderJobs(String workTime, String workCenterCode, String organizeCode) {
        //String today = DateUtil.formatDate(MesExtConstWords.DATE_FORMAT, new Date());
        //List<Integer> statusList = Arrays.asList(MesExtEnumUtil.MES_ORJ_ORDER_STATUS.CREATE.getValue(), MesExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECKING.getValue());
        DdlPackBean orderRuleCondition = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, orderRuleCondition);
        //DdlPreparedPack.getNotInPack(MesExtEnumUtil.MES_ORJ_ORDER_STATUS.CLOSE.getValue(), MesExtConstWords.ORDER_STATUS, orderRuleCondition);
        //DdlPreparedPack.getInPackList(statusList, "orderStatus", orderRuleCondition);
        DdlPreparedPack.getStringLikerPack(workTime.substring(0, 10), MesExtConstWords.CREATE_DATE_TIME, orderRuleCondition);
        log.info("workTime.substring(0, 10):{}", workTime.substring(0, 10));
        return orderJobRepository.findByHqlWhere(orderRuleCondition);
    }

    public List<MesOrderJob> getFinishOrderJobs(String workTime, String workCenterCode, String organizeCode) {
        //String today = DateUtil.formatDate(MesExtConstWords.DATE_FORMAT, new Date());
        //List<Integer> statusList = Arrays.asList(MesExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECK_COMPLETE.getValue());
        DdlPackBean orderRuleCondition = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, orderRuleCondition);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.MES_ORJ_ORDER_STATUS.CHECK_COMPLETE.getValue(), MesExtConstWords.ORDER_STATUS, orderRuleCondition);
        //DdlPreparedPack.getInPackList(statusList, MesExtConstWords.ORDER_STATUS, orderRuleCondition);
        DdlPreparedPack.getStringLikerPack(workTime.substring(0, 10), MesExtConstWords.CREATE_DATE_TIME, orderRuleCondition);
        return orderJobRepository.findByHqlWhere(orderRuleCondition);
    }

    public List<MesWorkOrderExt> getWorkOrderExts(String workCenterCode, String currentTime, String organizeCode) {
        DdlPackBean workOrderCondition = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, workOrderCondition);
        //DdlPreparedPack.getNotInPack(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue(), MesExtConstWords.WORK_ORDER_STATUS, workOrderCondition);
        //工单状态
        List<Integer> workOrderStatusList = new ArrayList<>();
        workOrderStatusList.add(MesExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue());
        workOrderStatusList.add(MesExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue());
        workOrderStatusList.add(MesExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue());
        workOrderStatusList.add(MesExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue());

        DdlPreparedPack.getInPackList(workOrderStatusList, MesExtConstWords.WORK_ORDER_STATUS, workOrderCondition);
        DdlPreparedPack.getStringRightLikerPack(currentTime, MesExtConstWords.START_TIME, workOrderCondition);
        return workOrderExtRepository.findByHqlWhere(workOrderCondition);
    }

    public List<MesWorkOrderExt> getWorkOrderExtsContainReusePlanDatetime(String workCenterCode, String currentTime, String organizeCode) {
        DdlPackBean workOrderCondition = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, workOrderCondition);
        //DdlPreparedPack.getNotInPack(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue(), MesExtConstWords.WORK_ORDER_STATUS, workOrderCondition);
        //工单状态
        List<Integer> workOrderStatusList = new ArrayList<>();
        workOrderStatusList.add(MesExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue());
        workOrderStatusList.add(MesExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue());
        workOrderStatusList.add(MesExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue());
        workOrderStatusList.add(MesExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue());

        DdlPreparedPack.getInPackList(workOrderStatusList, MesExtConstWords.WORK_ORDER_STATUS, workOrderCondition);
        //DdlPreparedPack.getStringRightLikerPack(currentTime, MesExtConstWords.START_TIME, workOrderCondition);
        workOrderCondition.addColumnQuery(MesExtConstWords.START_TIME, " and ( model." + MesExtConstWords.START_TIME + " like :m_" + MesExtConstWords.START_TIME, currentTime + "%");
        workOrderCondition.addColumnQuery(MesExtConstWords.REUSE_PLAN_DATE_TIME, " or model." + MesExtConstWords.REUSE_PLAN_DATE_TIME + " like :m_" + MesExtConstWords.REUSE_PLAN_DATE_TIME + " )", currentTime + "%");
        //DdlPreparedPack.getStringRightLikerPack(currentTime, MesExtConstWords.REUSE_PLAN_DATE_TIME, workOrderCondition);
        return workOrderExtRepository.findByHqlWhere(workOrderCondition);
    }

    public List<MesShiftProdCenterRecord> getShiftProdCenterRecord(String workCenterCode, String shiftCode, String workTime, String organizeCode) {
        DdlPackBean condition = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, condition);
        DdlPreparedPack.getStringEqualPack(shiftCode, MesExtConstWords.SHIFT_CODE, condition);
        DdlPreparedPack.getStringEqualPack(workTime, MesExtConstWords.WORK_TIME, condition);
        return shiftProdCenterRecordRepository.findByHqlWhere(condition);
    }

    public List<MesShiftProdCenterRecord> getShiftProdCenterRecordByNow(String workCenterCode, String shiftCode, String organizeCode) {
        DdlPackBean condition = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, condition);
        DdlPreparedPack.getStringEqualPack(shiftCode, MesExtConstWords.SHIFT_CODE, condition);
        DdlPreparedPack.getTimeBetweenCol(TimeTool.getNowTime(true), MesExtConstWords.START_TIME, MesExtConstWords.END_TIME, condition, true);
        return shiftProdCenterRecordRepository.findByHqlWhere(condition);
    }

    private Double getServiceWorkTime(List<MesShiftProdCenterRecord> modelList) throws ParseException {
        Iterator<MesShiftProdCenterRecord> iterator = modelList.iterator();

        Double workTimeByNow = 0.0;
        while (iterator.hasNext()) {
            MesShiftProdCenterRecord shiftProdCenterRecord = iterator.next();
            Date startTime = DateUtil.parse(shiftProdCenterRecord.getStartTime(), DateUtil.BASE_FORMAT);
            Date endTime = DateUtil.parse(shiftProdCenterRecord.getEndTime(), DateUtil.BASE_FORMAT);
            Date now = DateUtil.parse(TimeTool.getNowTime(true), DateUtil.BASE_FORMAT);

            //是否大于结束时间
            int isAfterEndTime = now.compareTo(DateUtil.parse(shiftProdCenterRecord.getEndTime(), DateUtil.BASE_FORMAT));

            //当前时间所在的作业区间
            if (TimeTool.isEffectiveDate(now, startTime, endTime)) {
                int secoundsBetweenTime = Math.abs(TimeTool.getSecoundsBetweenTime(2, shiftProdCenterRecord.getStartTime(), TimeTool.getNowTime(true)));
                double add = MathOperation.add(MathOperation.mul(secoundsBetweenTime, shiftProdCenterRecord.getWorkerQty()), workTimeByNow);
                workTimeByNow = add;
            } else {
                if (isAfterEndTime == 0 || isAfterEndTime == 1) {
                    int secoundsBetweenTime = Math.abs(TimeTool.getSecoundsBetweenTime(2, shiftProdCenterRecord.getStartTime(), shiftProdCenterRecord.getEndTime()));
                    double add = MathOperation.add(MathOperation.mul(secoundsBetweenTime, shiftProdCenterRecord.getWorkerQty()), workTimeByNow);
                    workTimeByNow = add;
                }
            }
        }

        return workTimeByNow;
    }


    public ListPager<MesHistogramModel> workOrderOHistogram(String organizeCode, String workCenterCode, Pager pager) {
        List<MesWorkOrderExt> orderExts = getWorkOrderExts(workCenterCode, TimeTool.getToday(), organizeCode);
        return getMesHistogramModelListPager(organizeCode, workCenterCode, pager, orderExts);
    }

    public ListPager<MesHistogramModel> epWorkOrderOHistogram(String organizeCode, String workCenterCode, Pager pager) {
        List<MesWorkOrderExt> orderExts = getWorkOrderExtsContainReusePlanDatetime(workCenterCode, TimeTool.getToday(), organizeCode);
        Map<String, List<MesWorkOrderExt>> partNoMap = orderExts.stream().collect(Collectors.groupingBy(MesWorkOrderExt::getPartNo));

        List<MesHistogramModel> resultList = new ArrayList<>();

        for (Map.Entry<String, List<MesWorkOrderExt>> stringListEntry : partNoMap.entrySet()) {
            MesHistogramModel histogramModel = new MesHistogramModel();
            //物料号
            String partNo = stringListEntry.getKey();
            histogramModel.setPartNo(partNo);

            //同物料号工单集合
            List<MesWorkOrderExt> workOrderExts = stringListEntry.getValue();
            //取当前最排序最先的seq值
            Double seq = workOrderExts.stream().min(Comparator.comparing(MesWorkOrder::getSeq)).get().getSeq();
            histogramModel.setSeq(seq);

            //当日计划
            Double sumQty = workOrderExts.stream().filter(mesWorkOrderExt -> StringUtils.isEmpty(mesWorkOrderExt.getReusePlanDatetime())).map(MesWorkOrderExt::getQty).reduce(0.00, Double::sum);
            //复用计划数量
            Double reuseSumQty = workOrderExts.stream().filter(mesWorkOrderExt -> !StringUtils.isEmpty(mesWorkOrderExt.getReusePlanDatetime())).map(MesWorkOrderExt::getReusePlanCompleteQty).reduce(0.00, Double::sum);
            histogramModel.setQty(sumQty + reuseSumQty);

            //获取产线信息
            MesWorkCenterExt workCenterExt = getWorkCenterExt(workCenterCode, null, organizeCode);
            String workTime = workCenterExt.getWorkTime();

            if (!StringUtils.isEmpty(workTime)) {
                //查询下线条码
                //List<MesProduceSnExt> snExtList = getMesProduceSnExtsByPartNo(workCenterCode, workTime, partNo, organizeCode);
                List<MesOutPutStatistics> outPutStatisticsList = getOutPutStatistics(workCenterCode, workTime, null, partNo, organizeCode);
                //当日实际
                Double sumCompleteQty = outPutStatisticsList.stream().map(MesOutPutStatistics::getQty).reduce(0.00, Double::sum);
                histogramModel.setCompleteQty(sumCompleteQty);
            } else {
                histogramModel.setCompleteQty(0.0);
            }
            resultList.add(histogramModel);
        }
        List<MesHistogramModel> histogramModelsBySort = resultList.stream().sorted(Comparator.comparing(MesHistogramModel::getSeq)).collect(Collectors.toList());

        pager = PagerHelper.getPager(pager, histogramModelsBySort.size());

        List<MesHistogramModel> requestListByPage = histogramModelsBySort.stream().skip((pager.getCurrentPage() - 1) * pager.getPageSize()).limit(pager.getPageSize()).collect(Collectors.toList());
        return new ListPager(requestListByPage, pager);
    }

    private ListPager<MesHistogramModel> getMesHistogramModelListPager(String organizeCode, String workCenterCode, Pager pager, List<MesWorkOrderExt> orderExts) {
        //DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, workOrderCondition);
        ////DdlPreparedPack.getNotInPack(MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue(), MesExtConstWords.WORK_ORDER_STATUS, workOrderCondition);
        //
        ////工单状态
        //List<Integer> workOrderStatusList = new ArrayList<>();
        //workOrderStatusList.add(MesExtEnumUtil.WORK_ORDER_STATUS.LANDED.getValue());
        //workOrderStatusList.add(MesExtEnumUtil.WORK_ORDER_STATUS.OPEN.getValue());
        //workOrderStatusList.add(MesExtEnumUtil.WORK_ORDER_STATUS.PAUSE.getValue());
        //workOrderStatusList.add(MesExtEnumUtil.WORK_ORDER_STATUS.CLOSE.getValue());
        //
        //DdlPreparedPack.getInPackList(workOrderStatusList, MesExtConstWords.WORK_ORDER_STATUS, workOrderCondition);
        //
        //
        //DdlPreparedPack.getStringRightLikerPack(TimeTool.getToday(), MesExtConstWords.START_TIME, workOrderCondition);
        //List<MesWorkOrderExt> orderExts = workOrderExtRepository.findByHqlWhere(workOrderCondition);

        //根据
        Map<String, List<MesWorkOrderExt>> partNoMap = orderExts.stream().collect(Collectors.groupingBy(MesWorkOrderExt::getPartNo));

        List<MesHistogramModel> resultList = new ArrayList<>();

        for (Map.Entry<String, List<MesWorkOrderExt>> stringListEntry : partNoMap.entrySet()) {
            MesHistogramModel histogramModel = new MesHistogramModel();
            //物料号
            String partNo = stringListEntry.getKey();
            histogramModel.setPartNo(partNo);

            //同物料号工单集合
            List<MesWorkOrderExt> workOrderExts = stringListEntry.getValue();
            //取当前最排序最先的seq值
            Double seq = workOrderExts.stream().min(Comparator.comparing(MesWorkOrder::getSeq)).get().getSeq();
            histogramModel.setSeq(seq);

            //当日计划
            Double sumQty = workOrderExts.stream().map(MesWorkOrderExt::getQty).reduce(0.00, Double::sum);
            histogramModel.setQty(sumQty);

            //获取产线信息
            MesWorkCenterExt workCenterExt = getWorkCenterExt(workCenterCode, null, organizeCode);
            String workTime = workCenterExt.getWorkTime();

            if (!StringUtils.isEmpty(workTime)) {
                //查询下线条码
                //List<MesProduceSnExt> snExtList = getMesProduceSnExtsByPartNo(workCenterCode, workTime, partNo, organizeCode);
                List<MesOutPutStatistics> outPutStatisticsList = getOutPutStatistics(workCenterCode, workTime, null, partNo, organizeCode);
                //当日实际
                Double sumCompleteQty = outPutStatisticsList.stream().map(MesOutPutStatistics::getQty).reduce(0.00, Double::sum);
                histogramModel.setCompleteQty(sumCompleteQty);
            } else {
                histogramModel.setCompleteQty(0.0);
            }


            resultList.add(histogramModel);
        }
        List<MesHistogramModel> histogramModelsBySort = resultList.stream().sorted(Comparator.comparing(MesHistogramModel::getSeq)).collect(Collectors.toList());

        pager = PagerHelper.getPager(pager, histogramModelsBySort.size());

        List<MesHistogramModel> requestListByPage = histogramModelsBySort.stream().skip((pager.getCurrentPage() - 1) * pager.getPageSize()).limit(pager.getPageSize()).collect(Collectors.toList());
        return new ListPager(requestListByPage, pager);
    }

    public List<MesFourMDetail> getFourMDetail(String workCenterCode, String organizeCode) {
        String currentTime = DateUtil.formatDate().substring(0, 10);
        DdlPackBean workOrderCondition = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, workOrderCondition);
        DdlPreparedPack.getStringRightLikerPack(currentTime, MesExtConstWords.CREATE_DATE_TIME, workOrderCondition);
        workOrderCondition.setOrderByStr(" order by createDatetime desc ");
        workOrderCondition.setHqlAppend(" limit 3");
        List<MesFourMDetail> details = fourMDetailRepository.findByHqlWhere(workOrderCondition);
        details.forEach(a -> {
            a.setManageTypeName(MesExtEnumUtil.MANAGE_TYPE.valueOfDescription(a.getManageType()));
        });
        return details;
    }

    public ListPager<MesFourMDetail> getFourMDetailByPager(String workCenterCode, String organizeCode, Pager pager) {
        DdlPackBean workOrderCondition = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, workOrderCondition);
        DdlPreparedPack.getStringRightLikerPack(TimeTool.getToday(), MesExtConstWords.CREATE_DATE_TIME, workOrderCondition);
        workOrderCondition.setOrderByStr(" order by createDatetime desc ");
        pager = PagerHelper.getPager(pager, fourMDetailRepository.findByHqlWhereCount(workOrderCondition));
        List<MesFourMDetail> mesFourMDetails = fourMDetailRepository.findByHqlWherePage(workOrderCondition, pager);

        mesFourMDetails.forEach(a -> {
            a.setManageTypeName(MesExtEnumUtil.MANAGE_TYPE.valueOfDescription(a.getManageType()));
        });
        return new ListPager(mesFourMDetails, pager);
    }

    public List<MesShiftProdCenterRecord> abnormalDowntime(String workCenterCode, String organizeCode) {
        String currentTime = DateUtil.formatDate().substring(0, 10);
        DdlPackBean workOrderCondition = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, workOrderCondition);
        DdlPreparedPack.getStringRightLikerPack(currentTime, MesExtConstWords.START_TIME, workOrderCondition);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.SHIFT_PROD_TYPE.UNNORMAL_STOP_CENTER.getValue(), "prodType", workOrderCondition);
        workOrderCondition.setOrderByStr(" order by createDatetime desc ");
        workOrderCondition.setHqlAppend(" limit 3");
        return shiftProdCenterRecordRepository.findByHqlWhere(workOrderCondition);
    }

    public ListPager<MesShiftProdCenterRecord> abnormalDowntimeByPager(String workCenterCode, String organizeCode, Pager pager) {
        DdlPackBean workOrderCondition = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, MesExtConstWords.WORK_CENTER_CODE, workOrderCondition);
        DdlPreparedPack.getStringRightLikerPack(TimeTool.getToday(), MesExtConstWords.START_TIME, workOrderCondition);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.SHIFT_PROD_TYPE.UNNORMAL_STOP_CENTER.getValue(), "prodType", workOrderCondition);
        workOrderCondition.setOrderByStr(" order by createDatetime desc ");

        pager = PagerHelper.getPager(pager, shiftProdCenterRecordRepository.findByHqlWhereCount(workOrderCondition));
        List<MesShiftProdCenterRecord> shiftProdCenterRecords = shiftProdCenterRecordRepository.findByHqlWherePage(workOrderCondition, pager);

        return new ListPager(shiftProdCenterRecords, pager);
    }

    public MesBoard getBoard(String configName, String organizeCode) {
        DdlPackBean forBoard = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(configName, "boardCode", forBoard);
        return boardRepository.getByProperty(forBoard);
    }

    /**
     * @return java.util.List<cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter>
     * @Description: 查询所有本体线
     * @Param [mesWorkCenter]
     * @Date 2021/10/20 16:59
     **/
    public List<MesWorkCenterExt> queryWorkCenter(MesWorkCenter mesWorkCenter) {
        DdlPackBean hqlPack = MesHqlPack.getMesWorkCenter(mesWorkCenter, mesWorkCenter.getOrganizeCode());
        //查询MES系统配置中只需要查询本体线的工厂
        MesConfig config = configService.getConfigByCfgCode(MesExtConstWords.ONTOLOGY_LINE_ORGANIZECODE_CONFIG_CODE, mesWorkCenter.getOrganizeCode());
        if(null == config || !mesWorkCenter.getOrganizeCode().equals(config.getCfgValue())){
            DdlPreparedPack.getInPackList(Arrays.asList(
                    String.valueOf(MesExtEnumUtil.LINE_TYPE.ONTOLOGY_LINE.getValue()),
                    String.valueOf(MesExtEnumUtil.LINE_TYPE.COMPONENT_LINE.getValue())
            ),"lineType", hqlPack);
        }else {
            DdlPreparedPack.getStringEqualPack(String.valueOf(MesExtEnumUtil.LINE_TYPE.ONTOLOGY_LINE.getValue()), "lineType", hqlPack);
        }
        hqlPack.setOrderByStr(" order by workCenterCode asc ");
        return workCenterExtRepository.findByHqlWhere(hqlPack);
    }

    public List<MesArea> queryMesArea(MesArea mesArea) {
        DdlPackBean hqlPack = MesHqlPack.getMesArea(mesArea, mesArea.getOrganizeCode());
        hqlPack.setOrderByStr(" order by areaCode asc ");
        return areaRepository.findByHqlWhere(hqlPack);
    }

    private List<MesOutPutStatistics> getOutPutStatistics(String workCenterCode, String workTime, String shiftCode, String partNo, String organizeCode) {
        DdlPackBean outPutStatisticsPackBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(workCenterCode, "workCenterCode", outPutStatisticsPackBean);
        DdlPreparedPack.getStringEqualPack(workTime, "workTime", outPutStatisticsPackBean);
        if (!StringUtils.isEmpty(shiftCode)) {
            DdlPreparedPack.getStringEqualPack(shiftCode, "shiftCode", outPutStatisticsPackBean);
        }
        if (!StringUtils.isEmpty(partNo)) {
            DdlPreparedPack.getStringEqualPack(partNo, "partNo", outPutStatisticsPackBean);
        }
        List<MesOutPutStatistics> outPutStatisticsList = outPutStatisticsRDao.findByHqlWhere(outPutStatisticsPackBean);
        return outPutStatisticsList;
    }
}
