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

import cn.estsh.i3plus.ext.mes.api.base.IProdOrgExtService;
import cn.estsh.i3plus.ext.mes.api.base.IShiftExtService;
import cn.estsh.i3plus.ext.mes.api.busi.ISxReportFormService;
import cn.estsh.i3plus.ext.mes.apiservice.dao.*;
import cn.estsh.i3plus.ext.mes.pojo.bean.*;
import cn.estsh.i3plus.ext.mes.pojo.model.*;
import cn.estsh.i3plus.ext.mes.pojo.repository.*;
import cn.estsh.i3plus.ext.mes.pojo.sqlpack.MesExtHqlPack;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtEnumUtil;
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.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.MesEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.MesPartCategory;
import cn.estsh.i3plus.pojo.mes.bean.MesShift;
import cn.estsh.i3plus.pojo.mes.bean.MesWorkCenter;
import cn.estsh.i3plus.pojo.mes.repository.MesPartCategoryRepository;
import cn.estsh.i3plus.pojo.mes.sqlpack.MesHqlPack;
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.function.Function;
import java.util.stream.Collectors;

/**
 * @author wangjie
 * @version 1.0
 * @date 2021/1/13 9:28
 **/
@Slf4j
@Service
public class SxReportFormService implements ISxReportFormService {

    @Autowired
    private MesProduceSnTravelExtRepository produceSnTravelExtRepository;

    @Autowired
    private IProduceSnRepairDao produceSnRepairDao;

    @Autowired
    private IPackageExtDao packageExtDao;

    @Autowired
    private MesShiftProdCenterRecordRepository shiftProdCenterRecordRepository;

    @Autowired
    private IUnWorkTimeStatisticsDao unWorkTimeStatisticsDao;

    @Autowired
    private IOutPutStatisticsDao outPutStatisticsDao;

    @Autowired
    private MesPartCategoryRepository partCategoryRepository;

    @Autowired
    private IProdOrgExtService prodOrgExtService;

    @Autowired
    private MesProduceSnExtRepository produceSnExtRepository;

    @Autowired
    private MesReplacementTravelRepository replacementTravelRepository;

    @Autowired
    private MesRepairTaskRepository repairTaskRepository;

    @Autowired
    private MesContainerJobBookingRepository jobBookingRepository;

    @Autowired
    private IShiftExtService shiftExtService;

    @Autowired
    private IWorkOrderExtDao workOrderExtDao;

    @Override
    public ListPager<MesProduceSnTravelExt> queryProduceSnTravelExtByPager(MesProduceSnTravelExt produceSnTravelExt, Pager pager) {
        DdlPackBean hqlPack = MesHqlPack.getMesProduceSnTravel(produceSnTravelExt, produceSnTravelExt.getOrganizeCode());
        pager = PagerHelper.getPager(pager, produceSnTravelExtRepository.findByHqlWhereCount(hqlPack));
        hqlPack.setOrderByStr(produceSnTravelExt.orderBy());
        List<MesProduceSnTravelExt> produceSnTravelExtList = produceSnTravelExtRepository.findByHqlWherePage(hqlPack, pager);
        if (!CollectionUtils.isEmpty(produceSnTravelExtList)) {
            for (MesProduceSnTravelExt item : produceSnTravelExtList) {
                item.setSnStatusName(StringUtils.isEmpty(item.getSnStatus()) ?
                        null : MesExtEnumUtil.PRODUCE_SN_STATUS.valueOfDescription(item.getSnStatus()));
                item.setQcStatusName(StringUtils.isEmpty(item.getQcStatus()) ?
                        null : MesExtEnumUtil.PRODUCE_SN_QC_STATUS.valueOfDescription(item.getQcStatus()));
                item.setSnTypeName(StringUtils.isEmpty(item.getSnType()) ?
                        null : MesExtEnumUtil.PRODUCE_SN_TYPE.valueOfDescription(item.getSnType()));
            }
        }
        return new ListPager(produceSnTravelExtList, pager);
    }

    @Override
    public ListPager<SxPackSnReportModel> queryStandardWorkOrderPackSnPager(SxPackSnReportModel model, Pager pager) {
        pager = PagerHelper.getPager(pager, packageExtDao.queryStandardWorkOrderPackSnPagerCount(model));
        List<SxPackSnReportModel> packSnReportModelList = packageExtDao.queryStandardWorkOrderPackSnPager(model, pager);
        if (!CollectionUtils.isEmpty(packSnReportModelList)) {
            for (SxPackSnReportModel item : packSnReportModelList) {
                if (null != item) {
                    item.setIsSealedName(!StringUtils.isEmpty(item.getIsSealed()) ? MesEnumUtil.PACKAGE_IS_SEALED.valueOfDescription(item.getIsSealed()) : null);
                    item.setPrintStatusName(!StringUtils.isEmpty(item.getPrintStatus()) ? MesExtEnumUtil.PRODUCE_SN_PRINT_STATUS.valueOfDescription(item.getPrintStatus()) : null);
                }
            }
        }
        return new ListPager(packSnReportModelList, pager);
    }

    @Override
    public ListPager<SxPackSnReportModel> queryRepairWorkOrderPackSnPager(SxPackSnReportModel model, Pager pager) {
        pager = PagerHelper.getPager(pager, packageExtDao.queryRepairWorkOrderPackSnPagerCount(model));
        List<SxPackSnReportModel> packSnReportModelList = packageExtDao.queryRepairWorkOrderPackSnPager(model, pager);
        if (!CollectionUtils.isEmpty(packSnReportModelList)) {
            for (SxPackSnReportModel item : packSnReportModelList) {
                if (null != item) {
                    item.setIsSealedName(!StringUtils.isEmpty(item.getIsSealed()) ? MesEnumUtil.PACKAGE_IS_SEALED.valueOfDescription(item.getIsSealed()) : null);
                    item.setPrintStatusName(!StringUtils.isEmpty(item.getPrintStatus()) ? MesExtEnumUtil.PRODUCE_SN_PRINT_STATUS.valueOfDescription(item.getPrintStatus()) : null);
                }
            }
        }
        return new ListPager(packSnReportModelList, pager);
    }

    @Override
    public ListPager<ProduceSnExtModel> queryStandardWorkOrderSnPager(ProduceSnExtModel model, Pager pager) {
        List<ProduceSnExtModel> resultList = new ArrayList<>();
        DdlPackBean hqlPack = MesExtHqlPack.getProduceSnExt(model);
        pager = PagerHelper.getPager(pager, this.produceSnExtRepository.findByHqlWhereCount(hqlPack));
        hqlPack.setOrderByStr(" order by serialNumber asc ");
        List<MesProduceSnExt> produceSnExtList = this.produceSnExtRepository.findByHqlWherePage(hqlPack, pager);
        if (!CollectionUtils.isEmpty(produceSnExtList)) {
            Map<String, List<MesShift>> shiftCodeMapByCenter = getShiftCodeMapByCenter(model.getOrganizeCode());
            for (MesProduceSnExt produceSnExt : produceSnExtList) {
                if (null == produceSnExt) {
                    continue;
                }
                ProduceSnExtModel result = new ProduceSnExtModel();
                BeanUtils.copyProperties(produceSnExt, result);
                result.setQcStatusName(!StringUtils.isEmpty(result.getQcStatus()) ? MesExtEnumUtil.PRODUCE_SN_QC_STATUS.valueOfDescription(result.getQcStatus()) : null);
                result.setSnStatusName(!StringUtils.isEmpty(result.getSnStatus()) ? MesExtEnumUtil.PRODUCE_SN_STATUS.valueOfDescription(result.getSnStatus()) : null);
                result.setSnTypeName(!StringUtils.isEmpty(result.getSnType()) ? MesExtEnumUtil.PRODUCE_SN_TYPE.valueOfDescription(result.getSnType()) : null);
                result.setShiftName(getShiftName(shiftCodeMapByCenter, result.getWorkCenterCode(), result.getShiftCode()));
                resultList.add(result);
            }
        }
        return new ListPager(resultList, pager);
    }

    @Override
    public ListPager<ProduceSnRepairModel> queryRepairWorkOrderSnPager(ProduceSnRepairModel model, Pager pager) {
        pager = PagerHelper.getPager(pager, produceSnRepairDao.queryProduceSnRepairByPagerCount(model));
        List<ProduceSnRepairModel> produceSnRepairModelList = produceSnRepairDao.queryProduceSnRepairByPager(model, pager);
        if (!CollectionUtils.isEmpty(produceSnRepairModelList)) {
            Map<String, List<MesShift>> shiftCodeMapByCenter = getShiftCodeMapByCenter(model.getOrganizeCode());
            for (ProduceSnRepairModel item : produceSnRepairModelList) {
                if (null != item) {
                    item.setQcStatusName(!StringUtils.isEmpty(item.getQcStatus()) ? MesExtEnumUtil.PRODUCE_SN_QC_STATUS.valueOfDescription(item.getQcStatus()) : null);
                    item.setSnStatusName(!StringUtils.isEmpty(item.getSnStatus()) ? MesExtEnumUtil.PRODUCE_SN_STATUS.valueOfDescription(item.getSnStatus()) : null);
                    item.setSnTypeName(!StringUtils.isEmpty(item.getSnType()) ? MesExtEnumUtil.PRODUCE_SN_TYPE.valueOfDescription(item.getSnType()) : null);
                    item.setShiftName(getShiftName(shiftCodeMapByCenter, item.getWorkCenterCode(), item.getShiftCode()));
                }
            }
        }
        return new ListPager(produceSnRepairModelList, pager);
    }

    private Map<String, List<MesShift>> getShiftCodeMapByCenter(String organizeCode) {
        List<MesShift> shiftList = shiftExtService.queryShiftList(organizeCode);

        return CollectionUtils.isEmpty(shiftList) ? null :
                shiftList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkCenterCode()) && !StringUtils.isEmpty(o.getShiftCode())))
                        .collect(Collectors.groupingBy(o -> new StringJoiner(MesExtConstWords.AND).add(o.getWorkCenterCode()).add(o.getShiftCode()).toString()));
    }

    private String getShiftName(Map<String, List<MesShift>> shiftCodeMapByCenter, String workCenterCode, String shiftCode) {
        return (CollectionUtils.isEmpty(shiftCodeMapByCenter) || StringUtils.isEmpty(workCenterCode) || StringUtils.isEmpty(shiftCode)) ? null :
                (!shiftCodeMapByCenter.containsKey(new StringJoiner(MesExtConstWords.AND).add(workCenterCode).add(shiftCode).toString()) ? null :
                        shiftCodeMapByCenter.get(new StringJoiner(MesExtConstWords.AND).add(workCenterCode).add(shiftCode).toString()).get(0).getShiftName());
    }

    @Override
    public ListPager<UnWorkTimeDetailModel> queryUnWorkTimeDetailPager(UnWorkTimeDetailModel model, Pager pager) {
        List<UnWorkTimeDetailModel> recordModelList = new ArrayList<>();
        DdlPackBean hqlPack = MesExtHqlPack.getUnWorkTimeDetail(model);
        pager = PagerHelper.getPager(pager, shiftProdCenterRecordRepository.findByHqlWhereCount(hqlPack));
        hqlPack.setOrderByStr(" order by workTime, workCenterCode, shiftCode, prodType, prodCode ");
        List<MesShiftProdCenterRecord> shiftProdCenterRecordList = shiftProdCenterRecordRepository.findByHqlWherePage(hqlPack, pager);
        if (!CollectionUtils.isEmpty(shiftProdCenterRecordList)) {

            List<MesWorkCenterExt> workCenterExtList = prodOrgExtService.queryWorkCenterExtList(model.getOrganizeCode());
            Map<String, List<MesWorkCenterExt>> workCenterCodeMap = CollectionUtils.isEmpty(workCenterExtList) ? null :
                    workCenterExtList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesWorkCenter::getWorkCenterCode));

            for (MesShiftProdCenterRecord record : shiftProdCenterRecordList) {
                if (null == record) {
                    continue;
                }
                UnWorkTimeDetailModel detailModel = new UnWorkTimeDetailModel();
                BeanUtils.copyProperties(record, detailModel);
                detailModel.setWorkCenterName(
                        (!CollectionUtils.isEmpty(workCenterCodeMap) && workCenterCodeMap.containsKey(record.getWorkCenterCode())) ?
                                workCenterCodeMap.get(record.getWorkCenterCode()).get(0).getWorkCenterName() : record.getWorkCenterCode());
                detailModel.setProdTypeName(StringUtils.isEmpty(record.getProdType()) ?
                        null : MesExtEnumUtil.SHIFT_PROD_TYPE.valueOfDescription(record.getProdType()));
                detailModel.setDuration(getDuration(record.getStartTime(), record.getEndTime()));
                detailModel.setLossHour(MathOperation.mul(detailModel.getDuration(), record.getWorkerQty()));

                recordModelList.add(detailModel);
            }
        }
        return new ListPager(recordModelList, pager);
    }

    private Double getDuration(String startTime, String endTime) {
        try {
            return new Double(TimeTool.getSecoundsBetweenTime(1, startTime, endTime) / 60);
        } catch (Exception e) {
            return new Double(0);
        }
    }

    @Override
    public List<UnWorkTimeStatisticsModel> queryUnWorkTimeStatistics(UnWorkTimeStatisticsModel model) {
        List<UnWorkTimeStatisticsModel> resultList = null;
        List<UnWorkTimeStatisticsModel> modelList = unWorkTimeStatisticsDao.queryUnWorkTimeStatistics(model);
        if (CollectionUtils.isEmpty(modelList)) {
            log.info("非作业时间汇总未查询到数据,维度[{}][{}]",
                    MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
            return resultList;
        }
        log.info("非作业时间汇总已查询到数据,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
        packUnWorkTimeStatisticsWorkTime(modelList, model);

        Map<String, List<UnWorkTimeStatisticsModel>> modelMap = packUnWorkTimeStatisticsMap(modelList, model.getDimension1());
        if (CollectionUtils.isEmpty(modelMap)) {
            return resultList;
        }
        log.info("非作业时间汇总根据维度封装数据成功,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));

        for (String key : modelMap.keySet()) {
            if (StringUtils.isEmpty(key)) {
                continue;
            }
            List<UnWorkTimeStatisticsModel> itemList = modelMap.get(key);
            if (CollectionUtils.isEmpty(itemList)) {
                continue;
            }

            String[] keyArr = key.split(MesExtConstWords.AND);
            UnWorkTimeStatisticsModel result = new UnWorkTimeStatisticsModel();
            packWorkTimeStatisticsResult(result, keyArr, model.getDimension1(), itemList.get(0));

            //总勤务时间=班次时长(常规生产类型)*人数汇总+加班时长(非常规生产类型)*人数汇总
            result.setTotalServiceTime(getTotalServiceTime(itemList));
            //非作业时间=停机时长（异常结束时间-开始时间）*人数然后汇总
            result.setTotalUnWorkTime(getTotalUnWorkTime(itemList, model.getProdType()));
            //非作业率=非作业时间/总勤务时间*100%,保留2位小数
            result.setUnWorkTimeRate(getRateDecimalTwo(result.getTotalUnWorkTime(), result.getTotalServiceTime()));

            UnWorkTimeStatisticsModel statisticsModel = itemList.stream().sorted(Comparator.comparing(k -> k.getCreateDatetime())).findFirst().get();
            result.setWorkerQty(statisticsModel.getWorkerQty());
            result.setAtHomeNum(statisticsModel.getAtHomeNum());
            if (CollectionUtils.isEmpty(resultList)) {
                resultList = new ArrayList<>();
            }
            resultList.add(result);
        }

        log.info("非作业时间汇总数据开始重新排序,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
        if (!CollectionUtils.isEmpty(resultList)) {
            resultList = sortWorkTimeStatisticsResult(resultList, model.getDimension1());
            log.info("非作业时间汇总数据重新排序成功,维度[{}][{}]",
                    MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
        }
        return resultList;
    }

    public void packUnWorkTimeStatisticsWorkTime(List<UnWorkTimeStatisticsModel> modelList, UnWorkTimeStatisticsModel model) {
        if (MesExtEnumUtil.REPORT_DIMENSION_DATE.ONE.getValue() == model.getDimension()) {
            List<UnWorkTimeStatisticsModel> modelListOrder = modelList.stream()
                    .filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()))).sorted(Comparator.comparing(UnWorkTimeStatisticsModel::getWorkTime)).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(modelListOrder)) {
                String workTime = new StringJoiner(MesExtConstWords.TO)
                        .add(!StringUtils.isEmpty(model.getWorkTimeStart()) ? model.getWorkTimeStart() : modelListOrder.get(0).getWorkTime())
                        .add(!StringUtils.isEmpty(model.getWorkTimeEnd()) ? model.getWorkTimeEnd() : modelListOrder.get(modelListOrder.size() - 1).getWorkTime()).toString();
                modelList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()))).forEach(o -> {
                    o.setWorkTime(workTime);
                });
            }
        } else if (MesExtEnumUtil.REPORT_DIMENSION_DATE.YEAR.getValue() == model.getDimension()) {
            modelList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()))).forEach(o -> {
                o.setWorkTime(o.getWorkTime().substring(0, 4));
            });
        } else if (MesExtEnumUtil.REPORT_DIMENSION_DATE.MONTH.getValue() == model.getDimension()) {
            modelList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()))).forEach(o -> {
                o.setWorkTime(o.getWorkTime().substring(0, 7));
            });
        }
    }

    public Map<String, List<UnWorkTimeStatisticsModel>> packUnWorkTimeStatisticsMap(List<UnWorkTimeStatisticsModel> modelList, Integer dimension) {
        Map<String, List<UnWorkTimeStatisticsModel>> modelMap;
        if (CollectionUtils.isEmpty(modelList)) {
            return null;
        }
        switch (MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.getByValue(dimension)) {
            case DATE:
                modelMap = modelList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkTime())))
                        .collect(Collectors.groupingBy(UnWorkTimeStatisticsModel::getWorkTime));
                break;
            case IS_DONT:
                modelMap = modelList.stream().filter(
                                o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()) && !StringUtils.isEmpty(o.getIsDont())))
                        .collect(Collectors.groupingBy(o -> (new StringJoiner(MesExtConstWords.AND)
                                .add(o.getWorkTime()).add(o.getIsDont()).toString())));
                break;
            case DONT_CLASS:
                modelMap = modelList.stream().filter(
                                o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()) && !StringUtils.isEmpty(o.getIsDont())
                                        && !StringUtils.isEmpty(o.getDontClass())))
                        .collect(Collectors.groupingBy(o -> (new StringJoiner(MesExtConstWords.AND)
                                .add(o.getWorkTime()).add(o.getIsDont()).add(o.getDontClass()).toString())));
                break;
            case CENTER:
                modelMap = modelList.stream().filter(
                                o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()) && !StringUtils.isEmpty(o.getIsDont())
                                        && !StringUtils.isEmpty(o.getDontClass()) && !StringUtils.isEmpty(o.getWorkCenterCode())))
                        .collect(Collectors.groupingBy(o -> (new StringJoiner(MesExtConstWords.AND)
                                .add(o.getWorkTime()).add(o.getIsDont()).add(o.getDontClass()).add(o.getWorkCenterCode()).toString())));
                break;
            case SHIFT:
            default:
                modelMap = modelList.stream().filter(
                                o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()) && !StringUtils.isEmpty(o.getIsDont())
                                        && !StringUtils.isEmpty(o.getDontClass()) && !StringUtils.isEmpty(o.getWorkCenterCode()) && !StringUtils.isEmpty(o.getShiftCode())))
                        .collect(Collectors.groupingBy(o -> (new StringJoiner(MesExtConstWords.AND)
                                .add(o.getWorkTime()).add(o.getIsDont()).add(o.getDontClass()).add(o.getWorkCenterCode()).add(o.getShiftCode()).toString())));
                break;
        }
        return modelMap;
    }

    public void packWorkTimeStatisticsResult(UnWorkTimeStatisticsModel result, String[] keyArr, Integer dimension, UnWorkTimeStatisticsModel model) {
        result.setWorkTime(keyArr[0]);
        switch (MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.getByValue(dimension)) {
            case DATE:
                break;
            case IS_DONT:
                result.setIsDont(keyArr[1]);
                break;
            case DONT_CLASS:
                result.setIsDont(keyArr[1]);
                result.setDontClass(keyArr[2]);
                break;
            case CENTER:
                result.setIsDont(keyArr[1]);
                result.setDontClass(keyArr[2]);
                result.setWorkCenterCode(keyArr[3]);
                result.setWorkCenterName(model.getWorkCenterName());
                result.setNoWorkTarget(model.getNoWorkTarget());
                break;
            case SHIFT:
            default:
                result.setIsDont(keyArr[1]);
                result.setDontClass(keyArr[2]);
                result.setWorkCenterCode(keyArr[3]);
                result.setWorkCenterName(model.getWorkCenterName());
                result.setNoWorkTarget(model.getNoWorkTarget());
                result.setShiftCode(keyArr[4]);
                result.setShiftName(model.getShiftName());
                break;
        }
    }

    public List<UnWorkTimeStatisticsModel> sortWorkTimeStatisticsResult(List<UnWorkTimeStatisticsModel> resultList, Integer dimension) {
        switch (MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.getByValue(dimension)) {
            case DATE:
                resultList = resultList.stream().sorted(Comparator.comparing(UnWorkTimeStatisticsModel::getWorkTime)).collect(Collectors.toList());
                break;
            case IS_DONT:
                resultList = resultList.stream().sorted(Comparator.comparing(UnWorkTimeStatisticsModel::getWorkTime)
                        .thenComparing(UnWorkTimeStatisticsModel::getIsDont)).collect(Collectors.toList());
                break;
            case DONT_CLASS:
                resultList = resultList.stream().sorted(Comparator.comparing(UnWorkTimeStatisticsModel::getWorkTime)
                        .thenComparing(UnWorkTimeStatisticsModel::getIsDont)
                        .thenComparing(UnWorkTimeStatisticsModel::getDontClass)).collect(Collectors.toList());
                break;
            case CENTER:
                resultList = resultList.stream().sorted(Comparator.comparing(UnWorkTimeStatisticsModel::getWorkTime)
                        .thenComparing(UnWorkTimeStatisticsModel::getIsDont)
                        .thenComparing(UnWorkTimeStatisticsModel::getDontClass)
                        .thenComparing(UnWorkTimeStatisticsModel::getWorkCenterCode)).collect(Collectors.toList());
                break;
            case SHIFT:
            default:
                resultList = resultList.stream().sorted(Comparator.comparing(UnWorkTimeStatisticsModel::getWorkTime)
                        .thenComparing(UnWorkTimeStatisticsModel::getIsDont)
                        .thenComparing(UnWorkTimeStatisticsModel::getDontClass)
                        .thenComparing(UnWorkTimeStatisticsModel::getWorkCenterCode)
                        .thenComparing(UnWorkTimeStatisticsModel::getShiftCode)).collect(Collectors.toList());
                break;
        }
        return resultList;
    }

    public Double getTotalServiceTime(List<UnWorkTimeStatisticsModel> modelList) {
        List<UnWorkTimeStatisticsModel> serviceList = modelList.stream().filter(
                o -> (null != o && (o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.NORMAL_PROD.getValue()
                        || o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.UNNORMAL_PROD.getValue()))).collect(Collectors.toList());
        return getTotalTimeAmount(serviceList);
    }

    private Double getTotalTimeAmount(List<UnWorkTimeStatisticsModel> modelList) {
        return modelList.stream().filter(o -> (null != o &&
                        !StringUtils.isEmpty(o.getStartTime()) && !StringUtils.isEmpty(o.getEndTime()) && !StringUtils.isEmpty(o.getWorkerQty()))).
                mapToDouble(o -> MathOperation.mul(getDuration(o.getStartTime(), o.getEndTime()), o.getWorkerQty())).sum();
    }

    public Double getTotalUnWorkTime(List<UnWorkTimeStatisticsModel> modelList, Integer prodType) {
        List<UnWorkTimeStatisticsModel> models;
        if (StringUtils.isEmpty(prodType)) {
            models = modelList.stream().
                    filter(o -> (null != o && (o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.UNNORMAL_STOP_CENTER.getValue() ||
                            o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.NORMAL_STOP_CENTER.getValue()))).collect(Collectors.toList());
        } else {
            models = modelList.stream().
                    filter(o -> (null != o && o.getProdType() == prodType)).collect(Collectors.toList());
        }
        return getTotalTimeAmount(models);
    }

    @Override
    public String getRateDecimalTwo(Double d1, Double d2) {
        if (StringUtils.isEmpty(d2) || MathOperation.compareTo(d2, new Double(0)) == 0) {
            log.info("作业时间月绩未查询到数据,维度[{}][{}]", d1,d2);
            return null;
        }
        return MathOperation.div(MathOperation.mul(d1, 100), d2, 2) + MesExtConstWords.PERCENT;
    }

    @Override
    public List<UnWorkTimeStatisticsModel> queryWorkTimeMonthlyPerformance(UnWorkTimeStatisticsModel model) {
        List<UnWorkTimeStatisticsModel> resultList = null;
        List<UnWorkTimeStatisticsModel> modelList = unWorkTimeStatisticsDao.queryUnWorkTimeStatistics(model);
        if (CollectionUtils.isEmpty(modelList)) {
            log.info("作业时间月绩未查询到数据,维度[{}][{}]",
                    MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
            return resultList;
        }
        log.info("作业时间月绩已查询到数据,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
        packUnWorkTimeStatisticsWorkTime(modelList, model);

        Map<String, List<UnWorkTimeStatisticsModel>> modelMap = packUnWorkTimeStatisticsMap(modelList, model.getDimension1());
        if (CollectionUtils.isEmpty(modelMap)) {
            return resultList;
        }

        log.info("作业时间月绩根据维度封装数据成功,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));

        // todo 暂时修改原有接口逻辑 国庆后还原切换至新接口
        model.setWorkOrderType(MesExtEnumUtil.WORK_ORDER_TYPE.STANDARD_ORDER.getValue());
        List<UnWorkTimeStatisticsModel> outPutStatisticsList = outPutStatisticsDao.queryOutPutStatisticsForReportForm(model);
        if (!CollectionUtils.isEmpty(outPutStatisticsList)) {
            packUnWorkTimeStatisticsWorkTime(outPutStatisticsList, model);
        } else {
            log.info("作业时间月绩未查询到产量数据,维度[{}][{}]",
                    MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
        }

        log.info("作业时间月绩已查询到产量数据,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));

        Map<String, List<UnWorkTimeStatisticsModel>> outPutStatisticsMap = packUnWorkTimeStatisticsMap(outPutStatisticsList, model.getDimension1());

        log.info("作业时间月绩根据维度封装产量数据成功,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));

        for (String key : modelMap.keySet()) {
            if (StringUtils.isEmpty(key)) {
                continue;
            }
            List<UnWorkTimeStatisticsModel> itemList = modelMap.get(key);
            if (CollectionUtils.isEmpty(itemList)) {
                continue;
            }

            String[] keyArr = key.split(MesExtConstWords.AND);
            UnWorkTimeStatisticsModel result = new UnWorkTimeStatisticsModel();
            packWorkTimeStatisticsResult(result, keyArr, model.getDimension1(), itemList.get(0));

            //总勤务时间=班次时长(常规生产类型)*人数汇总+加班时长(非常规生产类型)*人数汇总
            result.setTotalServiceTime(getTotalServiceTime(itemList));
            //非作业时间=停机时长（异常结束时间-开始时间）*人数然后汇总
            result.setTotalUnWorkTime(getTotalUnWorkTime(itemList, null));
            //非作业率=非作业时间/总勤务时间*100%,保留2位小数
            result.setUnWorkTimeRate(getRateDecimalTwo(result.getTotalUnWorkTime(), result.getTotalServiceTime()));
            //总作业时间=勤务时间-非作业时间
            result.setTotalWorkTime(MathOperation.sub(result.getTotalServiceTime(), result.getTotalUnWorkTime()));
            //总标准作业时间=各产品实绩数量*产品标准工时然后进行汇总
            result.setTotalStandardWorkTime(getTotalStandardWorkTime(outPutStatisticsMap, key));
            //St能率=标准作业时间/作业时间,以百分比显示,取2位小数
            result.setStRate(getRateDecimalTwo(result.getTotalStandardWorkTime(), result.getTotalWorkTime()));
            //综合能率=标准作业时间/勤务时间,以百分比显示,取2位小数
            result.setSynthesizeRate(getRateDecimalTwo(result.getTotalStandardWorkTime(), result.getTotalServiceTime()));
            //能率损失=作业时间-标准作业时间,如果是负数则显示0
            result.setLoseWorkTime(getLoseWorkTime(result.getTotalWorkTime(), result.getTotalStandardWorkTime()));
            //稼动率=作业时间/勤务时间,以百分比显示,取2位小数
            result.setUtilizationRate(getRateDecimalTwo(result.getTotalWorkTime(), result.getTotalServiceTime()));

            if (CollectionUtils.isEmpty(resultList)) {
                resultList = new ArrayList<>();
            }
            resultList.add(result);
        }

        log.info("作业时间月绩数据开始重新排序,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
        if (!CollectionUtils.isEmpty(resultList)) {
            resultList = sortWorkTimeStatisticsResult(resultList, model.getDimension1());
            log.info("作业时间月绩数据重新排序成功,维度[{}][{}]",
                    MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
        }
        return resultList;
    }

    public Double getTotalStandardWorkTime(Map<String, List<UnWorkTimeStatisticsModel>> outPutStatisticsMap, String key) {
        if (CollectionUtils.isEmpty(outPutStatisticsMap) || !outPutStatisticsMap.containsKey(key)) {
            return new Double(0);
        }
        return outPutStatisticsMap.get(key).stream()
                .filter(o -> (null != o && !StringUtils.isEmpty(o.getQty()) && !StringUtils.isEmpty(o.getStandardWork())))
                .mapToDouble(o -> MathOperation.mul(MathOperation.sub(o.getQty(), o.getRemakeQty() == null ? 0 : o.getRemakeQty()), o.getStandardWork())).sum();
    }

    public Double getLoseWorkTime(Double totalWorkTime, Double totalStandardWorkTime) {
        Double zero = new Double(0);
        Double loseWorkTime = MathOperation.sub(totalWorkTime, totalStandardWorkTime);
        if (MathOperation.compareTo(loseWorkTime, zero) < 0) {
            return zero;
        } else {
            return loseWorkTime;
        }
    }

    @Override
    public List<UnWorkTimeStatisticsModel> queryUnWorkTimeCategoryStatistics(UnWorkTimeStatisticsModel model) {
        List<UnWorkTimeStatisticsModel> resultList = null;
        List<UnWorkTimeStatisticsModel> modelList = unWorkTimeStatisticsDao.queryUnWorkTimeCategoryStatistics(model);
        if (CollectionUtils.isEmpty(modelList)) {
            log.info("非作业时间类别统计未查询到数据,维度[{}][{}]",
                    MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
            return resultList;
        }
        log.info("非作业时间类别统计已查询到数据,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
        packUnWorkTimeStatisticsWorkTime(modelList, model);

        Map<String, List<UnWorkTimeStatisticsModel>> modelMap = packUnWorkTimeStatisticsMap(modelList, model.getDimension1());
        if (CollectionUtils.isEmpty(modelMap)) {
            return resultList;
        }
        log.info("非作业时间类别统计根据维度封装数据成功,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
        for (String key : modelMap.keySet()) {
            if (StringUtils.isEmpty(key)) {
                continue;
            }
            List<UnWorkTimeStatisticsModel> itemModelList = modelMap.get(key);
            if (CollectionUtils.isEmpty(itemModelList)) {
                continue;
            }

            List<UnWorkTimeStatisticsModel> unWorkTimeList = itemModelList.stream().filter(
                    o -> (null != o && (o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.NORMAL_STOP_CENTER.getValue()
                            || o.getProdType() == MesExtEnumUtil.SHIFT_PROD_TYPE.UNNORMAL_STOP_CENTER.getValue()))).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(unWorkTimeList)) {
                continue;
            }

            Map<String, List<UnWorkTimeStatisticsModel>> itemListMap = unWorkTimeList.stream().filter(
                            o -> (null != o && !StringUtils.isEmpty(o.getProdType()) && !StringUtils.isEmpty(o.getProdCode())))
                    .collect(Collectors.groupingBy(o -> new StringJoiner(MesExtConstWords.AND).add(o.getProdType().toString()).add(o.getProdCode()).toString()));
            if (CollectionUtils.isEmpty(itemListMap)) {
                continue;
            }

            String[] keyArr = key.split(MesExtConstWords.AND);
            Double totalServiceTime = getTotalServiceTime(itemModelList);
            for (String itemKey : itemListMap.keySet()) {
                if (StringUtils.isEmpty(itemKey)) {
                    continue;
                }

                String[] itemKeyArr = itemKey.split(MesExtConstWords.AND);
                if (!StringUtils.isEmpty(model.getProdType()) && !model.getProdType().toString().equals(itemKeyArr[0])) {
                    continue;
                }
                if (!StringUtils.isEmpty(model.getProdCode()) && !model.getProdCode().equals(itemKeyArr[1])) {
                    continue;
                }

                List<UnWorkTimeStatisticsModel> itemList = itemListMap.get(itemKey);
                if (CollectionUtils.isEmpty(itemList)) {
                    continue;
                }

                UnWorkTimeStatisticsModel result = new UnWorkTimeStatisticsModel();
                packWorkTimeStatisticsResult(result, keyArr, model.getDimension1(), itemList.get(0));
                result.setProdType(itemList.get(0).getProdType());
                result.setProdTypeName(StringUtils.isEmpty(itemList.get(0).getProdType()) ?
                        null : MesExtEnumUtil.SHIFT_PROD_TYPE.valueOfDescription(itemList.get(0).getProdType()));
                result.setProdCode(itemList.get(0).getProdCode());
                result.setProdName(itemList.get(0).getProdName());
                result.setPlanRateStr(StringUtils.isEmpty(itemList.get(0).getPlanRate())? null : itemList.get(0).getPlanRate() + MesExtConstWords.PERCENT);
                result.setTotalServiceTime(totalServiceTime);
                result.setTotalCategoryTime(getTotalTimeAmount(itemList));
                result.setCategoryRate(getRateDecimalTwo(result.getTotalCategoryTime(), result.getTotalServiceTime()));
                result.setJudgeResult(getJudgeResult(result.getCategoryRate(), result.getPlanRateStr(),itemList.get(0).getProdCode()));

                if (CollectionUtils.isEmpty(resultList)) {
                    resultList = new ArrayList<>();
                }
                resultList.add(result);
            }
        }

        log.info("非作业时间类别统计数据开始重新排序,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
        if (!CollectionUtils.isEmpty(resultList)) {
            resultList = sortWorkTimeCategoryStatisticsResult(resultList, model.getDimension1());
            log.info("非作业时间类别统计数据重新排序成功,维度[{}][{}]",
                    MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.valueOfDescription(model.getDimension1()));
        }
        return resultList;
    }

    private String getJudgeResult(String categoryRate, String planRateStr,String prodCode) {
        log.info("getJudgeResult非作业时间类别统计数据编号,[{}]",prodCode);
        if (StringUtils.isEmpty(planRateStr) || StringUtils.isEmpty(categoryRate)) return null;
        if (Double.compare(Double.valueOf(categoryRate.substring(0, categoryRate.length() - 1)), Double.valueOf(planRateStr.substring(0, planRateStr.length() - 1))) <= 0) {
            return "O";
        } else {
            return "X";
        }
    }

    private List<UnWorkTimeStatisticsModel> sortWorkTimeCategoryStatisticsResult(List<UnWorkTimeStatisticsModel> resultList, Integer dimension) {
        switch (MesExtEnumUtil.REPORT_DIMENSION_UN_WORK_TIME_STATISTICS.getByValue(dimension)) {
            case DATE:
                resultList = resultList.stream().sorted(Comparator.comparing(UnWorkTimeStatisticsModel::getWorkTime)
                        .thenComparing(UnWorkTimeStatisticsModel::getProdType)).collect(Collectors.toList());
                break;
            case IS_DONT:
                resultList = resultList.stream().sorted(Comparator.comparing(UnWorkTimeStatisticsModel::getWorkTime)
                        .thenComparing(UnWorkTimeStatisticsModel::getIsDont)
                        .thenComparing(UnWorkTimeStatisticsModel::getProdType)).collect(Collectors.toList());
                break;
            case DONT_CLASS:
                resultList = resultList.stream().sorted(Comparator.comparing(UnWorkTimeStatisticsModel::getWorkTime)
                        .thenComparing(UnWorkTimeStatisticsModel::getIsDont)
                        .thenComparing(UnWorkTimeStatisticsModel::getDontClass)
                        .thenComparing(UnWorkTimeStatisticsModel::getProdType)).collect(Collectors.toList());
                break;
            case CENTER:
                resultList = resultList.stream().sorted(Comparator.comparing(UnWorkTimeStatisticsModel::getWorkTime)
                        .thenComparing(UnWorkTimeStatisticsModel::getIsDont)
                        .thenComparing(UnWorkTimeStatisticsModel::getDontClass)
                        .thenComparing(UnWorkTimeStatisticsModel::getWorkCenterCode)
                        .thenComparing(UnWorkTimeStatisticsModel::getProdType)).collect(Collectors.toList());
                break;
            case SHIFT:
            default:
                resultList = resultList.stream().sorted(Comparator.comparing(UnWorkTimeStatisticsModel::getWorkTime)
                        .thenComparing(UnWorkTimeStatisticsModel::getIsDont)
                        .thenComparing(UnWorkTimeStatisticsModel::getDontClass)
                        .thenComparing(UnWorkTimeStatisticsModel::getWorkCenterCode)
                        .thenComparing(UnWorkTimeStatisticsModel::getShiftCode)
                        .thenComparing(UnWorkTimeStatisticsModel::getProdType)).collect(Collectors.toList());
                break;
        }
        return resultList;
    }

    @Override
    public List<CompleteRateChartModel> queryAttainmentRateChart(CompleteRateChartModel model) {
        List<CompleteRateChartModel> resultList = null;
        List<CompleteRateChartModel> workOrderModelList = workOrderExtDao.queryCompleteRateChart(model);
        //Map<String, CompleteRateChartModel> orderRemoveMap = workOrderModelList.stream().filter(completeRateChartModel -> completeRateChartModel.getWorkOrderStatus() == MesExtEnumUtil.WORK_ORDER_STATUS.REMOVE.getValue()).collect(Collectors.toMap(CompleteRateChartModel::getWorkOrderNo, supplier -> supplier));
        workOrderModelList = workOrderModelList.stream().filter(completeRateChartModel -> completeRateChartModel.getWorkOrderStatus() != MesExtEnumUtil.WORK_ORDER_STATUS.REMOVE.getValue()
                && completeRateChartModel.getWorkOrderStatus() != MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue()).collect(Collectors.toList());
        List<CompleteRateChartModel> modelList = outPutStatisticsDao.queryCompleteRateChart(model);
        //modelList = modelList.stream().filter(m -> !orderRemoveMap.containsKey(m.getWorkOrderNo())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(modelList) && CollectionUtils.isEmpty(workOrderModelList)) {
            log.info("达成率一览表未查询到数据,维度[{}][{}]",
                    MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.valueOfDescription(model.getDimension1()));
            return resultList;
        }
        log.info("达成率一览表已查询到数据,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.valueOfDescription(model.getDimension1()));

        Map<String, CompleteRateChartModel> workOrderMapByNoAndTime = workOrderModelList.stream().collect(Collectors.toMap(workOrderModel -> new StringJoiner(MesExtConstWords.AND).add(workOrderModel.getWorkOrderNo()).add(workOrderModel.getWorkTime().substring(0,10)).toString(), Function.identity() ));
        List<String> workOrderNoAndTimeList = modelList.stream().map(outPutStatisticsModel -> new StringJoiner(MesExtConstWords.AND).add(outPutStatisticsModel.getWorkOrderNo()).add(outPutStatisticsModel.getWorkTime()).toString()).collect(Collectors.toList());

        for (String wo : workOrderNoAndTimeList) {
            if(workOrderMapByNoAndTime.containsKey(wo)){
                workOrderMapByNoAndTime.remove(wo);
            }
        }
        if(!CollectionUtils.isEmpty(workOrderMapByNoAndTime)){
            modelList.addAll(workOrderMapByNoAndTime.values());
        }

        packAttainmentRateChartWorkTime(modelList, model);

        Map<String, List<CompleteRateChartModel>> modelMap = packAttainmentRateChartMap(modelList, model.getDimension1());
        if (CollectionUtils.isEmpty(modelMap)) {
            return resultList;
        }

        log.info("达成率一览表根据维度封装数据成功,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.valueOfDescription(model.getDimension1()));

        Map<String, List<MesPartCategory>> categoryCodeMap = getCategoryCode3List(model.getOrganizeCode());

        for (String key : modelMap.keySet()) {
            if (StringUtils.isEmpty(key)) {
                continue;
            }
            List<CompleteRateChartModel> itemList = modelMap.get(key);
            if (CollectionUtils.isEmpty(itemList)) {
                continue;
            }
            if (!StringUtils.isEmpty(model.getPartNo()) && !model.getPartNo().equals(itemList.get(0).getPartNo())) {
                continue;
            }

            String[] keyArr = key.split(MesExtConstWords.AND);
            CompleteRateChartModel result = new CompleteRateChartModel();
            packAttainmentRateChartResult(result, keyArr, model.getDimension1(), itemList.get(0), categoryCodeMap);
            result.setPartNo(itemList.get(0).getPartNo());
            result.setPartNameRdd(itemList.get(0).getPartNameRdd());

            result.setPlanQty(getAttainmentRateChartPlanQty(itemList, keyArr[0], model.getDimension()));
            result.setQty(getAttainmentRateChartQty(itemList));
            result.setAttainmentRate(getRateDecimalTwo(result.getQty(), result.getPlanQty()));

            if (CollectionUtils.isEmpty(resultList)) {
                resultList = new ArrayList<>();
            }
            resultList.add(result);
        }

        log.info("达成率一览表数据开始重新排序,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.valueOfDescription(model.getDimension1()));
        if (!CollectionUtils.isEmpty(resultList)) {
            resultList = sortAttainmentRateChartResult(resultList, model.getDimension1());
            log.info("达成率一览表数据重新排序成功,维度[{}][{}]",
                    MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.valueOfDescription(model.getDimension1()));
        }
        return resultList;
    }

    private Map<String, List<MesPartCategory>> getCategoryCode3List(String organizeCode) {
        Map<String, List<MesPartCategory>> codeMap = null;
        List<MesPartCategory> partCategoryList = partCategoryRepository.findByProperty(
                new String[]{MesExtConstWords.ORGANIZE_CODE, MesExtConstWords.IS_DELETED, MesExtConstWords.IS_VALID, MesExtConstWords.CATEGORY_TYPE},
                new Object[]{organizeCode, CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue(), CommonEnumUtil.IS_VAILD.VAILD.getValue(), MesEnumUtil.PART_CATEGORY_TYPE.CATEGORY_THREE.getValue()});
        if (!CollectionUtils.isEmpty(partCategoryList)) {
            codeMap = partCategoryList.stream().filter(o -> null != o).collect(Collectors.groupingBy(MesPartCategory::getCategoryCode));
        }
        return codeMap;
    }

    private void packAttainmentRateChartWorkTime(List<CompleteRateChartModel> modelList, CompleteRateChartModel model) {
        if (MesExtEnumUtil.REPORT_DIMENSION_DATE.ONE.getValue() == model.getDimension()) {
            List<CompleteRateChartModel> modelListOrder = modelList.stream()
                    .filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()))).sorted(Comparator.comparing(CompleteRateChartModel::getWorkTime)).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(modelListOrder)) {
                String workTime = new StringJoiner(MesExtConstWords.TO)
                        .add(!StringUtils.isEmpty(model.getWorkTimeStart()) ? model.getWorkTimeStart() : modelListOrder.get(0).getWorkTime().substring(0,10))
                        .add(!StringUtils.isEmpty(model.getWorkTimeEnd()) ? model.getWorkTimeEnd() : modelListOrder.get(modelListOrder.size() - 1).getWorkTime().substring(0,10)).toString();
                modelList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()))).forEach(o -> {
                    o.setWorkTime(workTime);
                });
            }
        } else if (MesExtEnumUtil.REPORT_DIMENSION_DATE.YEAR.getValue() == model.getDimension()) {
            modelList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()))).forEach(o -> {
                o.setWorkTime(o.getWorkTime().substring(0, 4));
            });
        } else if (MesExtEnumUtil.REPORT_DIMENSION_DATE.MONTH.getValue() == model.getDimension()) {
            modelList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()))).forEach(o -> {
                o.setWorkTime(o.getWorkTime().substring(0, 7));
            });
        }
    }

    private Map<String, List<CompleteRateChartModel>> packAttainmentRateChartMap(List<CompleteRateChartModel> modelList, Integer dimension) {
        Map<String, List<CompleteRateChartModel>> modelMap;
        if (CollectionUtils.isEmpty(modelList)) {
            return null;
        }
        switch (MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.getByValue(dimension)) {
            case DATE:
                modelMap = modelList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()) && !StringUtils.isEmpty(o.getPartNo())))
                        .collect(Collectors.groupingBy(o -> (new StringJoiner(MesExtConstWords.AND)
                                .add(o.getWorkTime()).add(o.getPartNo()).toString())));
                break;
            case IS_DONT:
                modelMap = modelList.stream().filter(
                                o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()) && !StringUtils.isEmpty(o.getIsDont())))
                        .collect(Collectors.groupingBy(o -> (new StringJoiner(MesExtConstWords.AND)
                                .add(o.getWorkTime()).add(o.getIsDont()).add(o.getPartNo()).toString())));
                break;
            case DONT_CLASS:
                modelMap = modelList.stream().filter(
                                o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()) && !StringUtils.isEmpty(o.getIsDont())
                                        && !StringUtils.isEmpty(o.getDontClass())))
                        .collect(Collectors.groupingBy(o -> (new StringJoiner(MesExtConstWords.AND)
                                .add(o.getWorkTime()).add(o.getIsDont()).add(o.getDontClass()).add(o.getPartNo()).toString())));
                break;
            case CENTER:
            default:
                modelMap = modelList.stream().filter(
                                o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()) && !StringUtils.isEmpty(o.getIsDont())
                                        && !StringUtils.isEmpty(o.getDontClass()) && !StringUtils.isEmpty(o.getWorkCenterCode())))
                        .collect(Collectors.groupingBy(o -> (new StringJoiner(MesExtConstWords.AND)
                                .add(o.getWorkTime()).add(o.getIsDont()).add(o.getDontClass()).add(o.getWorkCenterCode()).add(o.getPartNo()).toString())));
                break;
        }
        return modelMap;
    }

    private void packAttainmentRateChartResult(CompleteRateChartModel result, String[] keyArr, Integer dimension,
                                               CompleteRateChartModel model, Map<String, List<MesPartCategory>> categoryCodeMap) {
        result.setWorkTime(keyArr[0]);
        if (!StringUtils.isEmpty(model.getCategoryCode3())) {
            result.setCategoryCode3(model.getCategoryCode3());
            result.setCategoryCode3Name((!CollectionUtils.isEmpty(categoryCodeMap) && categoryCodeMap.containsKey(model.getCategoryCode3())) ? categoryCodeMap.get(model.getCategoryCode3()).get(0).getCategoryName() : "");
        } else {
            result.setCategoryCode3("");
            result.setCategoryCode3Name("");
        }
        switch (MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.getByValue(dimension)) {
            case DATE:
                break;
            case IS_DONT:
                result.setIsDont(keyArr[1]);
                break;
            case DONT_CLASS:
                result.setIsDont(keyArr[1]);
                result.setDontClass(keyArr[2]);
                break;
            case CENTER:
            default:
                result.setIsDont(keyArr[1]);
                result.setDontClass(keyArr[2]);
                result.setWorkCenterCode(keyArr[3]);
                result.setWorkCenterName(model.getWorkCenterName());
                break;
        }
    }

    private Double getAttainmentRateChartPlanQty(List<CompleteRateChartModel> modelList, String workTime, Integer dimension) {
        List<CompleteRateChartModel> resultList;
        if (MesExtEnumUtil.REPORT_DIMENSION_DATE.ONE.getValue() == dimension) {
            resultList = modelList.stream().filter(o -> (null != o &&
                    !StringUtils.isEmpty(o.getOrderStartTime()) && !StringUtils.isEmpty(o.getPlanQty()) &&
                    TimeTool.stringParseToDate(o.getOrderStartTime().substring(0, 10), MesExtConstWords.DATE_FORMAT).compareTo(TimeTool.stringParseToDate(modelList.get(0).getWorkTime().split(MesExtConstWords.TO)[0], MesExtConstWords.DATE_FORMAT)) >= 0 &&
                    TimeTool.stringParseToDate(o.getOrderStartTime().substring(0, 10), MesExtConstWords.DATE_FORMAT).compareTo(TimeTool.stringParseToDate(modelList.get(0).getWorkTime().split(MesExtConstWords.TO)[1], MesExtConstWords.DATE_FORMAT)) <= 0)).collect(Collectors.toList());
        } else {
            resultList = modelList.stream().filter(o -> (null != o &&
                    !StringUtils.isEmpty(o.getOrderStartTime()) && o.getOrderStartTime().contains(workTime) && !StringUtils.isEmpty(o.getPlanQty()))).collect(Collectors.toList());
        }
        resultList = CollectionUtils.isEmpty(resultList) ? null :
                resultList.stream().filter(o -> null != o).distinct()
                        .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(CompleteRateChartModel::getWorkOrderNo))), ArrayList::new)
                        );
        return CollectionUtils.isEmpty(resultList) ? new Double(0) :
                resultList.stream().filter(o -> null != o).mapToDouble(CompleteRateChartModel::getPlanQty).sum();
    }

    private Double getAttainmentRateChartQty(List<CompleteRateChartModel> modelList) {
        return CollectionUtils.isEmpty(modelList) ? new Double(0) :
                modelList.stream().filter(o -> null != o).mapToDouble(CompleteRateChartModel::getQty).sum();
    }

    private List<CompleteRateChartModel> sortAttainmentRateChartResult(List<CompleteRateChartModel> resultList, Integer dimension) {
        switch (MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.getByValue(dimension)) {
            case DATE:
                resultList = resultList.stream().sorted(Comparator.comparing(CompleteRateChartModel::getWorkTime)
                        .thenComparing(CompleteRateChartModel::getCategoryCode3)
                        .thenComparing(CompleteRateChartModel::getPartNo)).collect(Collectors.toList());
                break;
            case IS_DONT:
                resultList = resultList.stream().sorted(Comparator.comparing(CompleteRateChartModel::getWorkTime)
                        .thenComparing(CompleteRateChartModel::getIsDont)
                        .thenComparing(CompleteRateChartModel::getCategoryCode3)
                        .thenComparing(CompleteRateChartModel::getPartNo)).collect(Collectors.toList());
                break;
            case DONT_CLASS:
                resultList = resultList.stream().sorted(Comparator.comparing(CompleteRateChartModel::getWorkTime)
                        .thenComparing(CompleteRateChartModel::getIsDont)
                        .thenComparing(CompleteRateChartModel::getDontClass)
                        .thenComparing(CompleteRateChartModel::getCategoryCode3)
                        .thenComparing(CompleteRateChartModel::getPartNo)).collect(Collectors.toList());
                break;
            case CENTER:
            default:
                resultList = resultList.stream().sorted(Comparator.comparing(CompleteRateChartModel::getWorkTime)
                        .thenComparing(CompleteRateChartModel::getIsDont)
                        .thenComparing(CompleteRateChartModel::getDontClass)
                        .thenComparing(CompleteRateChartModel::getWorkCenterCode)
                        .thenComparing(CompleteRateChartModel::getCategoryCode3)
                        .thenComparing(CompleteRateChartModel::getPartNo)).collect(Collectors.toList());
                break;
        }
        return resultList;
    }

    private List<CompleteRateChartModel> sortCompleteRateChartResult(List<CompleteRateChartModel> resultList, Integer dimension) {
        switch (MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.getByValue(dimension)) {
            case DATE:
                resultList = resultList.stream().sorted(Comparator.comparing(CompleteRateChartModel::getWorkTime)
                        .thenComparing(CompleteRateChartModel::getCategoryCode3)).collect(Collectors.toList());
                break;
            case IS_DONT:
                resultList = resultList.stream().sorted(Comparator.comparing(CompleteRateChartModel::getWorkTime)
                        .thenComparing(CompleteRateChartModel::getIsDont)
                        .thenComparing(CompleteRateChartModel::getCategoryCode3)).collect(Collectors.toList());
                break;
            case DONT_CLASS:
                resultList = resultList.stream().sorted(Comparator.comparing(CompleteRateChartModel::getWorkTime)
                        .thenComparing(CompleteRateChartModel::getIsDont)
                        .thenComparing(CompleteRateChartModel::getDontClass)
                        .thenComparing(CompleteRateChartModel::getCategoryCode3)).collect(Collectors.toList());
                break;
            case CENTER:
            default:
                resultList = resultList.stream().sorted(Comparator.comparing(CompleteRateChartModel::getWorkTime)
                        .thenComparing(CompleteRateChartModel::getIsDont)
                        .thenComparing(CompleteRateChartModel::getDontClass)
                        .thenComparing(CompleteRateChartModel::getWorkCenterCode)
                        .thenComparing(CompleteRateChartModel::getCategoryCode3)).collect(Collectors.toList());
                break;
        }
        return resultList;
    }

    @Override
    public List<CompleteRateChartModel> queryCompleteRateChart(CompleteRateChartModel model) {
        List<CompleteRateChartModel> resultList = null;
        List<CompleteRateChartModel> workOrderModelList = workOrderExtDao.queryCompleteRateChart(model);
        //Map<String, CompleteRateChartModel> orderRemoveMap = workOrderModelList.stream().filter(completeRateChartModel -> completeRateChartModel.getWorkOrderStatus() == MesExtEnumUtil.WORK_ORDER_STATUS.REMOVE.getValue()).collect(Collectors.toMap(CompleteRateChartModel::getWorkOrderNo, supplier -> supplier));
        workOrderModelList = workOrderModelList.stream().filter(completeRateChartModel -> completeRateChartModel.getWorkOrderStatus() != MesExtEnumUtil.WORK_ORDER_STATUS.REMOVE.getValue()
                && completeRateChartModel.getWorkOrderStatus() != MesExtEnumUtil.WORK_ORDER_STATUS.CREATE.getValue()).collect(Collectors.toList());
        List<CompleteRateChartModel> modelList = outPutStatisticsDao.queryCompleteRateChart(model);
        if (CollectionUtils.isEmpty(modelList) && CollectionUtils.isEmpty(workOrderModelList)) {
            log.info("完结率一览表未查询到数据,维度[{}][{}]",
                    MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.valueOfDescription(model.getDimension1()));
            return resultList;
        }

        log.info("完结率一览表已查询到数据,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.valueOfDescription(model.getDimension1()));

        Map<String, CompleteRateChartModel> workOrderMapByNoAndTime = workOrderModelList.stream().collect(Collectors.toMap(workOrderModel -> new StringJoiner(MesExtConstWords.AND).add(workOrderModel.getWorkOrderNo()).add(workOrderModel.getWorkTime().substring(0,10)).toString(), Function.identity() ));
        List<String> workOrderNoAndTimeList = modelList.stream().map(outPutStatisticsModel -> new StringJoiner(MesExtConstWords.AND).add(outPutStatisticsModel.getWorkOrderNo()).add(outPutStatisticsModel.getWorkTime()).toString()).collect(Collectors.toList());

        for (String wo : workOrderNoAndTimeList) {
            if(workOrderMapByNoAndTime.containsKey(wo)){
                workOrderMapByNoAndTime.remove(wo);
            }
        }
        if(!CollectionUtils.isEmpty(workOrderMapByNoAndTime)){
            modelList.addAll(workOrderMapByNoAndTime.values());
        }

        packAttainmentRateChartWorkTime(modelList, model);

        Map<String, List<CompleteRateChartModel>> modelMap = packCompleteRateChartMap(modelList, model.getDimension1());
        if (CollectionUtils.isEmpty(modelMap)) {
            return resultList;
        }

        log.info("完结率一览表根据维度封装数据成功,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.valueOfDescription(model.getDimension1()));

        Map<String, List<MesPartCategory>> categoryCodeMap = getCategoryCode3List(model.getOrganizeCode());

        for (String key : modelMap.keySet()) {
            if (StringUtils.isEmpty(key)) {
                continue;
            }
            List<CompleteRateChartModel> itemList = modelMap.get(key);
            if (CollectionUtils.isEmpty(itemList)) {
                continue;
            }

            String[] keyArr = key.split(MesExtConstWords.AND);
            CompleteRateChartModel result = new CompleteRateChartModel();
            packAttainmentRateChartResult(result, keyArr, model.getDimension1(), itemList.get(0), categoryCodeMap);

            result.setPlanQty(getAttainmentRateChartPlanQty(itemList, keyArr[0], model.getDimension()));
            result.setQty(getAttainmentRateChartQty(itemList));
            result.setAttainmentRate(getRateDecimalTwo(result.getQty(), result.getPlanQty()));
            result.setCompleteRate(getChartCompleteRate(itemList, keyArr[0], model.getDimension()));

            if (CollectionUtils.isEmpty(resultList)) {
                resultList = new ArrayList<>();
            }
            resultList.add(result);
        }

        log.info("完结率一览表数据开始重新排序,维度[{}][{}]",
                MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.valueOfDescription(model.getDimension1()));
        if (!CollectionUtils.isEmpty(resultList)) {
            resultList = sortCompleteRateChartResult(resultList, model.getDimension1());
            log.info("完结率一览表数据重新排序成功,维度[{}][{}]",
                    MesExtEnumUtil.REPORT_DIMENSION_DATE.valueOfDescription(model.getDimension()), MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.valueOfDescription(model.getDimension1()));
        }
        return resultList;
    }


    private Map<String, List<CompleteRateChartModel>> packCompleteRateChartMap(List<CompleteRateChartModel> modelList, Integer dimension) {
        Map<String, List<CompleteRateChartModel>> modelMap;
        if (CollectionUtils.isEmpty(modelList)) {
            return null;
        }
        switch (MesExtEnumUtil.REPORT_DIMENSION_ATTAINMENT_RATE_CHART.getByValue(dimension)) {
            case DATE:
                modelMap = modelList.stream().filter(o -> (null != o && !StringUtils.isEmpty(o.getWorkTime())))
                        .collect(Collectors.groupingBy(o -> (new StringJoiner(MesExtConstWords.AND)
                                .add(o.getWorkTime()).add(o.getCategoryCode3()).toString())));
                break;
            case IS_DONT:
                modelMap = modelList.stream().filter(
                                o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()) && !StringUtils.isEmpty(o.getIsDont())))
                        .collect(Collectors.groupingBy(o -> (new StringJoiner(MesExtConstWords.AND)
                                .add(o.getWorkTime()).add(o.getIsDont()).add(o.getCategoryCode3()).toString())));
                break;
            case DONT_CLASS:
                modelMap = modelList.stream().filter(
                                o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()) && !StringUtils.isEmpty(o.getIsDont())
                                        && !StringUtils.isEmpty(o.getDontClass())))
                        .collect(Collectors.groupingBy(o -> (new StringJoiner(MesExtConstWords.AND)
                                .add(o.getWorkTime()).add(o.getIsDont()).add(o.getDontClass()).add(o.getCategoryCode3()).toString())));
                break;
            case CENTER:
            default:
                modelMap = modelList.stream().filter(
                                o -> (null != o && !StringUtils.isEmpty(o.getWorkTime()) && !StringUtils.isEmpty(o.getIsDont())
                                        && !StringUtils.isEmpty(o.getDontClass()) && !StringUtils.isEmpty(o.getWorkCenterCode())))
                        .collect(Collectors.groupingBy(o -> (new StringJoiner(MesExtConstWords.AND)
                                .add(o.getWorkTime()).add(o.getIsDont()).add(o.getDontClass()).add(o.getWorkCenterCode()).add(o.getCategoryCode3()).toString())));
                break;
        }
        return modelMap;
    }

    private String getChartCompleteRate(List<CompleteRateChartModel> modelList, String workTime, Integer dimension) {
        String completeRate = null;
        Double total = new Double(0);
        Double complete = new Double(0);
        Map<String, List<CompleteRateChartModel>> partNoMap = modelList.stream().filter(o -> null != o).collect(Collectors.groupingBy(CompleteRateChartModel::getPartNo));
        for (String partNo : partNoMap.keySet()) {
            if (StringUtils.isEmpty(partNo)) {
                continue;
            }
            List<CompleteRateChartModel> itemList = partNoMap.get(partNo);
            Double planQty = getAttainmentRateChartPlanQty(itemList, workTime, dimension);
            Double qty = getAttainmentRateChartQty(itemList);
            String attainmentRate = getRateDecimalTwo(qty, planQty);
            if (StringUtils.isEmpty(attainmentRate)) {
                continue;
            }
            try {
                Double attainmentRateD = Double.valueOf(attainmentRate.substring(0, attainmentRate.length() - 1));
                if (MathOperation.compareTo(attainmentRateD, 95) >= 0 && MathOperation.compareTo(attainmentRateD, 100) <= 0) {
                    complete = MathOperation.add(complete, new Double(1));
                }
                total = MathOperation.add(total, new Double(1));
            } catch (NumberFormatException e) {
                continue;
            }
        }
        if (MathOperation.compareTo(total, new Double(0)) != 0) {
            completeRate = getRateDecimalTwo(complete, total);
        }
        return completeRate;
    }

    /**
     * @param replacementTravel
     * @param pager
     * @return {@link ListPager< MesReplacementTravel >}
     */
    @Override
    public ListPager<MesReplacementTravel> queryReplacementTravel(MesReplacementTravel replacementTravel, Pager pager) {
        DdlPackBean travelCondition = DdlPackBean.getDdlPackBean(replacementTravel.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(replacementTravel.getSerialNumber(), "serialNumber", travelCondition);
        pager = PagerHelper.getPager(pager, replacementTravelRepository.findByHqlWhereCount(travelCondition));
        List<MesReplacementTravel> travels = replacementTravelRepository.findByHqlWherePage(travelCondition, pager);
        return new ListPager(travels, pager);
    }

    /**
     * @param repairRecordExt
     * @param pager
     * @return {@link ListPager< MesRepairTask >}
     */
    @Override
    public ListPager<MesRepairRecordExt> queryRepairTask(MesRepairRecordExt repairRecordExt, Pager pager) {
        DdlPackBean repairCondition = DdlPackBean.getDdlPackBean(repairRecordExt.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(repairRecordExt.getSerialNumber(), "serialNumber", repairCondition);
        DdlPreparedPack.getStringEqualPack(repairRecordExt.getWorkOrderNo(), "workOrderNo", repairCondition);
        pager = PagerHelper.getPager(pager, repairTaskRepository.findByHqlWhereCount(repairCondition));
        List<MesRepairTask> repairTasks = repairTaskRepository.findByHqlWherePage(repairCondition, pager);
        return new ListPager(repairTasks, pager);
    }

    /**
     * @param jobBooking
     * @param pager
     * @return {@link ListPager<MesContainerJobBooking>}
     */
    @Override
    public ListPager<MesContainerJobBooking> queryJobBooking(MesContainerJobBooking jobBooking, Pager pager) {
        DdlPackBean repairCondition = DdlPackBean.getDdlPackBean(jobBooking.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(jobBooking.getCtNo(), "ctNo", repairCondition);
        DdlPreparedPack.getStringEqualPack(jobBooking.getPartNo(), "partNo", repairCondition);
        DdlPreparedPack.getStringEqualPack(jobBooking.getWorkOrderNo(), "workOrderNo", repairCondition);
        pager = PagerHelper.getPager(pager, jobBookingRepository.findByHqlWhereCount(repairCondition));
        List<MesContainerJobBooking> jobBookings = jobBookingRepository.findByHqlWherePage(repairCondition, pager);
        return new ListPager(jobBookings, pager);
    }

}
