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

import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesPartService;
import cn.estsh.i3plus.ext.mes.pcn.api.base.IMesTemplateService;
import cn.estsh.i3plus.ext.mes.pcn.api.busi.*;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi.printqueue.IPrintQueueStrategyService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.print.IPrintTemplateStrategyService;
import cn.estsh.i3plus.ext.mes.pcn.apiservice.util.MesPcnException;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesProduceSnPrintDataModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesProduceSnPrintModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesWorkOrderCutPrintModel;
import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords;
import cn.estsh.i3plus.mes.pcn.api.iservice.base.IConfigService;
import cn.estsh.i3plus.platform.common.convert.ConvertBean;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.pojo.base.bean.DdlPackBean;
import cn.estsh.i3plus.pojo.base.common.Pager;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack;
import cn.estsh.i3plus.pojo.mes.bean.*;
import cn.estsh.i3plus.pojo.mes.model.GenSerialNoModel;
import cn.estsh.i3plus.pojo.mes.repository.*;
import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.util.SpringContextsUtil;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StopWatch;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description : 条码补打
 * @Reference :
 * @Author : junsheng.li
 * @CreateDate 2024/6/13 15:52
 * @Modify:
 **/
@Slf4j
@Service
public class MesProduceSnPrintService implements IMesProduceSnPrintService {

    @Autowired
    private MesPackingDefineDetailsRepository mesPackingDefineDetailsRDao;

    @Autowired
    private MesPackingDefineRepository mesPackingDefineRDao;

    @Autowired
    private MesProduceSnRepository mesProduceSnRDao;

    @Autowired
    private IMesPartService mesPartService;

    @Autowired
    private IMesTemplateService mesTemplateService;

    @Autowired
    private MesCustomerPartRepository mesCustomerPartRDao;

    @Autowired
    private MesProductionAssemblyRepository mesProductionAssemblyRepository;

    @Autowired
    private IConfigService configService;

    @Autowired
    private MesNumberRuleRepository mesNumberRuleRDao;

    @Autowired
    private IMesPrintedSnLogRepository mesPrintedSnRao;

    @Autowired
    private MesWorkOrderCutRepository workOrderCutRepository;

    @Autowired
    private IMesWorkOrderCutService workOrderCutService;

    @Autowired
    private MesCutSchemeFgRepository cutSchemeFgRepository;

    @Autowired
    private MesCutSchemeMaterialRepository cutSchemeMaterialRepository;

    @Autowired
    private MesCutSchemeEquipmentRepository cutSchemeEquipmentRepository;

    @Autowired
    private MesCutSchemeEquipmentDetailRepository cutSchemeEquipmentDetailRepository;

    @Autowired
    private IMesPrintedSnLogRepository printedSnLogRepository;

    @Autowired
    private IMesPrintedSnLogService mesPrintedSnLogService;

    @Autowired
    private IMesWorkOrderService mesWorkOrderService;

    @Autowired
    private IMesPackageExtService packageExtService;

    // 仅查询
    public static final Integer CUT_QUERY_MODE_BY_QUERY = 1;
    // 打印
    public static final Integer CUT_QUERY_MODE_BY_PRINT = 2;

    @Override
    public MesProduceSnPrintModel findMesPackingDefine(MesProduceSnPrintModel mesProduceSnPrintModel) {
        //查询SAP下发物料信息
        MesPartSap mesPartSap = mesPartService.getMesPartSapByPartNo(mesProduceSnPrintModel.getPartNo(), mesProduceSnPrintModel.getOrganizeCode());
        mesProduceSnPrintModel.setQty(mesPartSap.getSnp());
        mesProduceSnPrintModel.setPartName(mesPartSap.getPartName());
        //查询包装定义明细
        DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(mesProduceSnPrintModel.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(mesProduceSnPrintModel.getPartNo(), "partNo", ddlPackBean);
        List<MesPackingDefineDetails> packingDefineDetails = mesPackingDefineDetailsRDao.findByHqlWhere(ddlPackBean);
        if (CollectionUtils.isEmpty(packingDefineDetails)) {
            MesPcnException.throwMesBusiException("物料【%s】未维护包装定义信息", mesProduceSnPrintModel.getPartNo());
        }
        //查询包装定义主表
        ddlPackBean = DdlPackBean.getDdlPackBean(mesProduceSnPrintModel.getOrganizeCode());
        DdlPreparedPack.getInPackList(packingDefineDetails.stream().map(MesPackingDefineDetails::getPackCode).collect(Collectors.toList()), "packCode", ddlPackBean);
        mesProduceSnPrintModel.setMesPackingDefineList(mesPackingDefineRDao.findByHqlWhere(ddlPackBean));
        return mesProduceSnPrintModel;
    }

    @Override
    public MesProduceSn findMesProduceSn(MesProduceSnPrintModel mesProduceSnPrintModel) {
        DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(mesProduceSnPrintModel.getOrganizeCode());
        ddlPackBean.setWhereAppend(ddlPackBean.getWhereAppend() + " and (model.productSn = '"+mesProduceSnPrintModel.getProductSn()+"' or model.custSn = '"+mesProduceSnPrintModel.getProductSn()+"' or model.workOrderNo = '"+mesProduceSnPrintModel.getProductSn()+"')");
        MesProduceSn mesProduceSn = mesProduceSnRDao.getByProperty(ddlPackBean);
        if (Objects.isNull(mesProduceSn)) {
            MesPcnException.throwMesBusiException("条码【%s】信息不存在", mesProduceSnPrintModel.getProductSn());
        }
        return mesProduceSn;
    }

    @Override
    public MesProduceSnPrintModel doPrint(MesProduceSnPrintModel mesProduceSnPrintModel) {
        String organizeCode = mesProduceSnPrintModel.getOrganizeCode();
        //获取产线信息
        String workCenterCode = getWorkCenterCode(organizeCode);

        //物料信息
        MesPart mesPart = mesPartService.getMesPartByPartNo(mesProduceSnPrintModel.getPartNo(), organizeCode);
        //条码生成
        if (StringUtils.isEmpty(mesProduceSnPrintModel.getProductSn())) {
            //打印模板
            String printTemplate = mesProduceSnPrintModel.getPrintTemplate();
            //打印规则
            MesNumberRule numberRule = getMesNumberRule(mesProduceSnPrintModel.getSnRule(), organizeCode, mesPart.getPartNo());
            // 获取打印模板
            MesLabelTemplate mesLabelTemplate = mesTemplateService.getMesLabelTemplate(printTemplate,organizeCode);
            String methodCode = mesLabelTemplate.getMethodCode();
            if (StringUtils.isEmpty(methodCode)) {
                throw ImppExceptionBuilder.newInstance().setSystemID(CommonEnumUtil.SOFT_TYPE.MES_PCN.getCode())
                        .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION_DATA_ERROR.getCode())
                        .setErrorDetail(String.format("当前打印模板【%s】未维护方法名", printTemplate)).build();
            }

            MesCustomerPart mesCustomerPart = getMesCustomerPart(mesProduceSnPrintModel);
            GenSerialNoModel genSerialNoModel = new GenSerialNoModel();
            genSerialNoModel.setRuleCode(numberRule.getRuleCode());
            genSerialNoModel.setPartNo(mesPart.getPartNo());
            genSerialNoModel.putDataMap(MesPart.class.getSimpleName(), mesPart);
            genSerialNoModel.putDataMap(MesCustomerPart.class.getSimpleName(), mesCustomerPart);
            genSerialNoModel.setShiftCode(mesProduceSnPrintModel.getShiftCode());
            genSerialNoModel.setOrganizeCode(organizeCode);
            genSerialNoModel.setCustPartNo(mesCustomerPart == null ? null : mesCustomerPart.getCustPartNo());
            IPrintTemplateStrategyService templateStrategy = (IPrintTemplateStrategyService) SpringContextsUtil.getBean(methodCode);

            MesProduceSnPrintModel resultModel = templateStrategy.execute(genSerialNoModel, mesProduceSnPrintModel, numberRule,null,null,false);

            resultModel.getMesProduceSnList().forEach(mesProduceSn -> {
                mesProduceSn.setWorkCenterCode(workCenterCode);
                mesProduceSn.setPrintCount(MesPcnExtConstWords.ONE);
                mesProduceSn.setPrintStatus(MesExtEnumUtil.PRINT_STATUS.PRINTED.getValue());
                mesProduceSn.setFid(UUID.randomUUID().toString());
                //保存条码
                mesProduceSnRDao.insert(mesProduceSn);
            });
            resultModel.getMesPrintedSnLogList().forEach(snLog -> {
                //保存打印记录
                mesPrintedSnRao.insert(snLog);
            });

            resultModel.setMesLabelTemplate(mesLabelTemplate);
            resultModel.setMesPrintedSnLogList(null);
            resultModel.setMesProduceSnList(null);
            return resultModel;
            //条码补打
        } else {
            //获取打印模板信息
            mesProduceSnPrintModel.setMesLabelTemplate(mesTemplateService.getMesLabelTemplate(StringUtils.isEmpty(mesProduceSnPrintModel.getPrintTemplate()) ? mesPart.getCustLabelTemplate() : mesProduceSnPrintModel.getPrintTemplate(), organizeCode));

            //查找打印记录
            DdlPackBean snLogPackBean = DdlPackBean.getDdlPackBean(organizeCode);
            DdlPreparedPack.getStringEqualPack(mesProduceSnPrintModel.getProductSn(), "barcode", snLogPackBean);
            MesPrintedSnLog snLog = mesPrintedSnRao.getByProperty(snLogPackBean);
            if (Objects.isNull(snLog)) {
                //扫描条码
                MesWorkOrder workOrder = mesWorkOrderService.getWorkOrderNoByCustSn(organizeCode, mesProduceSnPrintModel.getProductSn());
                //扫描工单
                if(Objects.isNull(workOrder)){
                    workOrder = mesWorkOrderService.getWorkOrderNoByWorkOrderNo(organizeCode, mesProduceSnPrintModel.getProductSn());
                }
                if(Objects.isNull(workOrder)){
                    MesPcnException.throwMesBusiException("条码【%s】查询不到打印记录!", mesProduceSnPrintModel.getProductSn());
                }
                //根据客户条码查询工单信息
                mesProduceSnPrintModel = getMesProduceSnPrintModel(mesProduceSnPrintModel, organizeCode, mesPart, workOrder);
                snLog = getMesPrintedSnLog(workOrder, JSONObject.toJSONString(mesProduceSnPrintModel.getPrintContextList().iterator().next().get(MesPcnExtConstWords.TEMPLATE_DATA)),mesProduceSnPrintModel.getUserName());
            }
            MesProduceSnPrintDataModel model = new MesProduceSnPrintDataModel();
            BeanUtil.copyProperties(snLog, model);
            if (CollectionUtils.isEmpty(snLog.getPrintContext())) {
                model.setPrintDate(TimeTool.getNowTime(true));
                mesProduceSnPrintModel.getMesProduceSnPrintDataModelList().add(model);
            } else {
                snLog.getPrintContext().put(MesPcnExtConstWords.PRINT_DATE, TimeTool.getNowTime(true));
                mesProduceSnPrintModel.getPrintContextList().add(snLog.getPrintContext());
            }
            //记录打印日志
            mesPrintedSnLogService.insertMesPrintedSnLog(snLog, model.getUserName());
            return mesProduceSnPrintModel;
        }
    }

    private MesProduceSnPrintModel getMesProduceSnPrintModel(MesProduceSnPrintModel mesProduceSnPrintModel, String organizeCode, MesPart mesPart, MesWorkOrder workOrderNoByCustSn) {
        mesProduceSnPrintModel.setSourceData(workOrderNoByCustSn);
        // 获取打印模板
        MesLabelTemplate mesLabelTemplate = mesTemplateService.getMesLabelTemplate(mesPart.getCustLabelTemplate(), organizeCode);
        if (Objects.isNull(mesLabelTemplate) || StringUtils.isEmpty(mesLabelTemplate.getMethodCode())) {
            MesPcnException.throwMesBusiException(String.format("当前打印模板【%s】未维护方法名", mesProduceSnPrintModel.getPrintTemplate()));
        }
        IPrintTemplateStrategyService templateStrategy = (IPrintTemplateStrategyService) SpringContextsUtil.getBean(mesLabelTemplate.getMethodCode());

        mesProduceSnPrintModel = templateStrategy.execute(null, mesProduceSnPrintModel, getMesNumberRule(mesPart.getCustMatchRule(), organizeCode, mesPart.getPartNo()),null,null,false);
        return mesProduceSnPrintModel;
    }

    private MesNumberRule getMesNumberRule(String ruleCode, String organizeCode, String partNo) {
        DdlPackBean mesRulePackBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getStringEqualPack(ruleCode, "ruleCode", mesRulePackBean);
        MesNumberRule numberRule = mesNumberRuleRDao.getByProperty(mesRulePackBean);
        if (StringUtils.isEmpty(ruleCode) || StringUtils.isEmpty(organizeCode) || Objects.isNull(numberRule)) {
            MesPcnException.throwMesBusiException("零件号【%s】打印规则查询不到!", partNo);
        }
        return numberRule;
    }

    private String getWorkCenterCode(String organizeCode) {
        List<MesConfig> mesConfigList = configService.findMesConfigByCfgCode(MesPcnExtConstWords.PRINT_WORK_CENTER_COED, organizeCode);
        if(CollectionUtils.isEmpty(mesConfigList)){
            MesPcnException.throwMesBusiException("条码打印产线参数【%s】未维护",MesPcnExtConstWords.PRINT_WORK_CENTER_COED);
        }
        return mesConfigList.iterator().next().getCfgValue();
    }

    private MesCustomerPart getMesCustomerPart(MesProduceSnPrintModel mesProduceSnPrintModel) {
        DdlPackBean ddlPackBean = DdlPackBean.getDdlPackBean(mesProduceSnPrintModel.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(mesProduceSnPrintModel.getPartNo(), "erpPartNo", ddlPackBean);
        return mesCustomerPartRDao.getByProperty(ddlPackBean);
    }

    @Override
    public List<MesProductionAssembly> findMesProductionAssembly(MesProductionAssembly requestModel) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(requestModel.getOrganizeCode());
        DdlPreparedPack.getStringEqualPack(requestModel.getAssemblySn(), "assemblySn", packBean);
        if (!StringUtils.isEmpty(requestModel.getPartNo())) {
            DdlPreparedPack.getStringEqualPack(requestModel.getPartNo(), "partNo", packBean);
        }
        if (!StringUtils.isEmpty(requestModel.getAssemblyPartNo())) {
            DdlPreparedPack.getStringEqualPack(requestModel.getAssemblyPartNo(), "assemblyPartNo", packBean);
        }
        List<MesProductionAssembly> mesProductionAssemblies = mesProductionAssemblyRepository.findByHqlWhere(packBean);
        if (CollectionUtils.isEmpty(mesProductionAssemblies)) {
            MesPcnException.throwMesBusiException("扫描的装配件条码【%s】条码不存在，请扫描其他的装配件！！！",requestModel.getAssemblySn());
        }
        return mesProductionAssemblies;
    }

    @Override
    public List<MesWorkOrderCut> findMesWorkOrderCut(MesWorkOrderCut workOrderCut) {

        Pager pager = new Pager();
        pager.setStartRow(1);
        pager.setCurrentPage(1);
        pager.setPageSize(30);
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(workOrderCut.getOrganizeCode());
        DdlPreparedPack.getInPackList(Arrays.asList(workOrderCut.getWorkCenterCodeQuery().split(MesPcnExtConstWords.COMMA)), MesPcnExtConstWords.WORK_CENTER_CODE, packBean);
        DdlPreparedPack.getIsNull(MesPcnExtConstWords.REMARK, packBean);
        DdlPreparedPack.getNumEqualPack(MesExtEnumUtil.PRINT_STATUS.UNPRINT.getValue(), MesPcnExtConstWords.PRINT_STATUS, packBean);
        List<MesWorkOrderCut> workOrderCutList = workOrderCutRepository.findByHqlWherePage(packBean, pager);

        // model 不为空 并= 1 时 仅仅查询裁片工单数据
        // model 不为空时则 查询裁片工单数据并封装打印模板和打印数据，封装完后修改打印状态为已打印
        // model 为空时,该情况为异常情况,mode由前端返回,不会为空,该情况下返回数据为空
        if (workOrderCut.getMode() != null && workOrderCut.getMode().equals(CUT_QUERY_MODE_BY_QUERY)) {

            workOrderCutList.forEach(o -> o.setWorkOrderStatusName(MesExtEnumUtil.CUT_ORDER_STATUS.valueOfDescription(o.getWorkOrderStatus())));

            return workOrderCutList;

        } else if (workOrderCut.getMode() != null) {

            List<String> cutCodeList = workOrderCutList.stream().map(MesWorkOrderCut::getCutCode).distinct().collect(Collectors.toList());
            // 根据 裁片方案代码 获取裁片方案设备
            List<MesCutScheme> mesCutSchemeList = workOrderCutService.queryCutSchemeList(cutCodeList, workOrderCut.getOrganizeCode());
            // 根据 裁片方案代码 获取裁片方案设备
            List<MesCutSchemeEquipment> cutSchemeEquipmentList = getMesCutSchemeEquipments(workOrderCut, cutCodeList);
            // 根据 裁片方案代码 对 裁片方案信息 分组
            Map<String, MesCutScheme> cutSchemeMapByCutCode = mesCutSchemeList.stream().collect(Collectors.toMap(MesCutScheme::getCutCode, Function.identity(), (x, y) -> y));
            // 根据 裁片方案代码 对 裁片方案成品信息 分组
            Map<String, List<MesCutSchemeFg>> cutSchemeFgMapByCutCode = getCutSchemeFgMapByCutCode(cutCodeList,workOrderCut.getOrganizeCode());
            // 根据 裁片方案代码 对 裁片方案原材料信息 分组
            Map<String, List<MesCutSchemeMaterial>> cutSchemeMaterialMapByCutCode = getCutSchemeMaterialMapByCutCode(cutCodeList,workOrderCut.getOrganizeCode());
            // 根据 裁片方案代码 对 裁片设备信息 分组
            Map<String, List<MesCutSchemeEquipment>> cutSchemeEquipmentMapByCutCode = CollectionUtils.isEmpty(cutSchemeEquipmentList) ? new HashMap<>() : cutSchemeEquipmentList.stream().collect(Collectors.groupingBy(MesCutSchemeEquipment::getCutCode));
            // 根据pid对 设备参数 分组
            Map<Long, List<MesCutSchemeEquipmentDetail>> cutSchemeEquipmentDetailMapByPid = getCutSchemeEquipmentDetailMapByPid(workOrderCut.getOrganizeCode(), cutSchemeEquipmentList);

            List<MesWorkOrderCut> workOrderCutShowList = new ArrayList<>();

            for (MesWorkOrderCut workOrderCutDb : workOrderCutList) {

                MesCutScheme cutScheme = cutSchemeMapByCutCode.get(workOrderCutDb.getCutCode());

                MesLabelTemplate labelTemplate = mesTemplateService.getLabelTemplate(cutScheme.getTemplateCode(), workOrderCut.getOrganizeCode());

                //模板信息丢失抛出异常
                if (labelTemplate == null) {
                    workOrderCutDb.setRemark(String.format("请检查裁片方案,裁片方案[%s]模板代码[%s]无效!", cutScheme.getCutCode(), cutScheme.getTemplateCode()));
                    workOrderCutDb.setSystemSyncStatus(CommonEnumUtil.FALSE);
                    ConvertBean.serviceModelUpdate(workOrderCutDb, workOrderCut.getModifyUser());
                    continue;
                }

                //根据反射获取策略类--封装打印数据
                String methodCode = labelTemplate.getMethodCode();

                //模板信息丢失抛出异常
                if (StringUtils.isEmpty(methodCode)) {
                    workOrderCutDb.setRemark(String.format("裁片方案[%s]模板代码[%s]方法类为空,请配置!", cutScheme.getCutCode(), labelTemplate.getTemplateCode()));
                    workOrderCutDb.setSystemSyncStatus(CommonEnumUtil.FALSE);
                    ConvertBean.serviceModelUpdate(workOrderCutDb, workOrderCut.getModifyUser());
                    continue;
                }

                MesProduceSnPrintModel mesProduceSnPrintModel = new MesProduceSnPrintModel();
                mesProduceSnPrintModel.setMesLabelTemplate(labelTemplate);
                mesProduceSnPrintModel.setSourceData(Stream.of(packMesWorkOrderCutPrintModel(cutSchemeMapByCutCode, cutSchemeFgMapByCutCode, cutSchemeMaterialMapByCutCode, cutSchemeEquipmentMapByCutCode, cutSchemeEquipmentDetailMapByPid, workOrderCutDb, cutScheme)).collect(Collectors.toList()));
                mesProduceSnPrintModel.setPrinter(cutScheme.getPrinter());

                MesProduceSnPrintModel snPrintModel = null;
                try {
                    IPrintTemplateStrategyService strategyService = (IPrintTemplateStrategyService) SpringContextsUtil.getBean(methodCode);
                    snPrintModel = strategyService.execute(null, mesProduceSnPrintModel, null, null, null ,false);
                } catch (BeansException e) {
                    workOrderCutDb.setRemark(String.format("裁片方案[%s]模板代码[%s]方法类[%s]执行异常,请配置!", cutScheme.getCutCode(), labelTemplate.getTemplateCode(), labelTemplate.getMethodCode()));
                    ConvertBean.serviceModelUpdate(workOrderCutDb, workOrderCut.getModifyUser());
                    workOrderCutDb.setSystemSyncStatus(CommonEnumUtil.FALSE);
                    continue;
                }

                workOrderCutDb.setPrintStatus(MesExtEnumUtil.PRINT_STATUS.PRINTED.getValue());
                workOrderCutDb.setPrintTime(TimeTool.getNowTime(true));
                workOrderCutDb.setWorkOrderStatusName(MesExtEnumUtil.CUT_ORDER_STATUS.valueOfDescription(workOrderCutDb.getWorkOrderStatus()));
                ConvertBean.serviceModelUpdate(workOrderCutDb, workOrderCut.getModifyUser());
                workOrderCutRepository.save(workOrderCutDb);
                workOrderCutDb.setPrintContent(snPrintModel.getPrintContextList());
                workOrderCutShowList.add(workOrderCutDb);

                MesPrintedSnLog printedSnLog = new MesPrintedSnLog();
                printedSnLog.setOrganizeCode(workOrderCut.getOrganizeCode());
                printedSnLog.setCutWorkOrderNo(workOrderCut.getCutWorkOrderNo());
                printedSnLog.setBarcode(workOrderCut.getCutWorkOrderNo());
                ConvertBean.serviceModelInitialize(printedSnLog, workOrderCut.getModifyUser());
                printedSnLogRepository.save(printedSnLog);

            }

            return workOrderCutShowList;
        }

        return new ArrayList<>();
    }

    @Override
    public List<MesPrintQueue> findMesPrintQueueList(MesPrintQueue printQueue) {

        StopWatch stopWatch = new StopWatch();

        stopWatch.start();

        String clazz = MesExtEnumUtil.PRINT_QUEUE_TYPE.valueOfClazz(printQueue.getPrintQueueType());

        List<MesPrintQueue> printQueueList = null;

        try {

            IPrintQueueStrategyService strategyService = (IPrintQueueStrategyService) SpringContextsUtil.getBean(clazz);

            printQueueList = strategyService.execute(printQueue);

        } catch (Exception e) {

            log.info("打印队列查询 --- {} --- 执行异常 --- {}", MesExtEnumUtil.PRINT_QUEUE_TYPE.valueOfDescription(printQueue.getPrintQueueType()), e.toString());

        } finally {

            stopWatch.stop();

            if (!CollectionUtils.isEmpty(printQueueList)) log.info("打印队列查询 --- {} --- 执行耗时: {} ms ---", MesExtEnumUtil.PRINT_QUEUE_TYPE.valueOfDescription(printQueue.getPrintQueueType()), stopWatch.getTotalTimeMillis());
        }

        return printQueueList;
    }

    private List<MesCutSchemeEquipment> getMesCutSchemeEquipments(MesWorkOrderCut workOrderCut, List<String> cutCodeList) {
        List<MesCutSchemeEquipment> cutSchemeEquipmentList = getMesCutSchemeEquipments(workOrderCut.getOrganizeCode(), cutCodeList);
        // 过滤出只需要打印的裁片方案设备
        cutSchemeEquipmentList = cutSchemeEquipmentList.stream().filter(o -> o.getIsPrint() != null && o.getIsPrint() == CommonEnumUtil.VALID).collect(Collectors.toList());
        return cutSchemeEquipmentList;
    }

    private static MesWorkOrderCutPrintModel packMesWorkOrderCutPrintModel(Map<String, MesCutScheme> cutSchemeMapByCutCode, Map<String, List<MesCutSchemeFg>> cutSchemeFgMapByCutCode, Map<String, List<MesCutSchemeMaterial>> cutSchemeMaterialMapByCutCode, Map<String, List<MesCutSchemeEquipment>> cutSchemeEquipmentMapByCutCode, Map<Long, List<MesCutSchemeEquipmentDetail>> cutSchemeEquipmentDetailMapByPid, MesWorkOrderCut workOrderCutDb, MesCutScheme cutScheme) {
        MesWorkOrderCutPrintModel printModel = new MesWorkOrderCutPrintModel();
        BeanUtils.copyProperties(workOrderCutDb, printModel);
        printModel.setCutScheme(cutSchemeMapByCutCode.get(cutScheme.getCutCode()));
        printModel.setCutSchemeFgList(cutSchemeFgMapByCutCode.get(cutScheme.getCutCode()));
        printModel.setCutSchemeMaterialList(cutSchemeMaterialMapByCutCode.get(cutScheme.getCutCode()));
        printModel.setCutSchemeEquipmentList(cutSchemeEquipmentMapByCutCode.get(cutScheme.getCutCode()));
        printModel.setCutSchemeEquipmentDetailMapByPid(cutSchemeEquipmentDetailMapByPid);
        return printModel;
    }

    private List<MesCutSchemeEquipmentDetail> getMesCutSchemeEquipmentDetails(String organizeCode, List<MesCutSchemeEquipment> cutSchemeEquipmentList) {
        if (!CollectionUtils.isEmpty(cutSchemeEquipmentList)) {
            List<Long> idList = cutSchemeEquipmentList.stream().map(MesCutSchemeEquipment::getId).collect(Collectors.toList());
            DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
            DdlPreparedPack.getInPackList(idList, MesPcnExtConstWords.PID, packBean);
            return cutSchemeEquipmentDetailRepository.findByHqlWhere(packBean);
        }
        return null;
    }

    private Map<Long, List<MesCutSchemeEquipmentDetail>> getCutSchemeEquipmentDetailMapByPid(String organizeCode, List<MesCutSchemeEquipment> cutSchemeEquipmentList) {
        List<MesCutSchemeEquipmentDetail> cutSchemeEquipmentDetailList = getMesCutSchemeEquipmentDetails(organizeCode, cutSchemeEquipmentList);

        return  CollectionUtils.isEmpty(cutSchemeEquipmentDetailList) ? null : cutSchemeEquipmentDetailList.stream().collect(Collectors.groupingBy(MesCutSchemeEquipmentDetail::getPid));
    }

    private List<MesCutSchemeEquipment> getMesCutSchemeEquipments(String organizeCode, List<String> cutCodeList) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(cutCodeList, MesPcnExtConstWords.CUT_CODE, packBean);
        return cutSchemeEquipmentRepository.findByHqlWhere(packBean);
    }

    private List<MesCutSchemeMaterial> getMesCutSchemeMaterials(List<String> cutCodeList,String orgnaizeCode) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(orgnaizeCode);
        DdlPreparedPack.getInPackList(cutCodeList, MesPcnExtConstWords.CUT_CODE, packBean);
        return cutSchemeMaterialRepository.findByHqlWhere(packBean);
    }

    private Map<String, List<MesCutSchemeMaterial>> getCutSchemeMaterialMapByCutCode(List<String> cutCodeList,String orgnaizeCode) {
        List<MesCutSchemeMaterial> cutSchemeMaterialList = getMesCutSchemeMaterials(cutCodeList,orgnaizeCode);
        //根据裁片方案代码对裁片方案原材料分组
        return cutSchemeMaterialList.stream().collect(Collectors.groupingBy(MesCutSchemeMaterial::getCutCode));
    }

    private List<MesCutSchemeFg> getMesCutSchemeFgs(List<String> cutCodeList, String organizeCode) {
        DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode);
        DdlPreparedPack.getInPackList(cutCodeList, MesPcnExtConstWords.CUT_CODE, packBean);
        return cutSchemeFgRepository.findByHqlWhere(packBean);
    }

    private Map<String, List<MesCutSchemeFg>> getCutSchemeFgMapByCutCode(List<String> cutCodeList, String organizeCode) {
        List<MesCutSchemeFg> cutSchemeFgList = getMesCutSchemeFgs(cutCodeList,organizeCode);

        //根据裁片方案代码对裁片方案成品明细分组
        return cutSchemeFgList.stream().collect(Collectors.groupingBy(MesCutSchemeFg::getCutCode));
    }

    private MesPrintedSnLog getMesPrintedSnLog(MesWorkOrder workOrder, String printData,String userName) {
        MesPrintedSnLog snLog = new MesPrintedSnLog();
        snLog.setBarcode(workOrder.getCustSn());
        snLog.setCustPartNo(workOrder.getCustPartNo());
        snLog.setWorkOrderNo(workOrder.getWorkOrderNo());
        snLog.setPartNo(workOrder.getPartNo());
        snLog.setPartName(workOrder.getPartName());
        snLog.setPrintData(printData);
        ConvertBean.serviceModelInitialize(snLog, userName);
        snLog.setOrganizeCode(workOrder.getOrganizeCode());
        return snLog;
    }

    @Override
    public MesProduceSnPrintModel doRePrintPackByPackageNo(MesProduceSnPrintModel mesProduceSnPrintModel) {
        //根据包装条码查询包装信息
        MesPackage packageDb = packageExtService.getPackageDb(mesProduceSnPrintModel.getOrganizeCode(), mesProduceSnPrintModel.getPackageNo());
        if (null == packageDb) MesPcnException.throwBusiException("包装条码[%s]信息不存在!", mesProduceSnPrintModel.getPackageNo());
        if (StringUtils.isEmpty(packageDb.getPackageLabelTemplate())) MesPcnException.throwBusiException("包装条码[%s]信息未关联包装条码模版代码!", mesProduceSnPrintModel.getPackageNo());
        if (StringUtils.isEmpty(packageDb.getIsSealed()) || packageDb.getIsSealed().compareTo(CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) == 0)
            MesPcnException.throwBusiException("包装条码[%s]当前状态[未封装],不支持补打印!", mesProduceSnPrintModel.getPackageNo());

        //查询模版信息
        MesLabelTemplate labelTemplate = mesTemplateService.getMesLabelTemplate(packageDb.getPackageLabelTemplate(), mesProduceSnPrintModel.getOrganizeCode());
        if (StringUtils.isEmpty(labelTemplate.getMethodCode()))
            MesPcnException.throwBusiException("包装条码[%s]关联的包装条码模版代码[%s]未维护方法策略!", mesProduceSnPrintModel.getPackageNo(), packageDb.getPackageLabelTemplate());

        IPrintTemplateStrategyService strategyService = (IPrintTemplateStrategyService) SpringContextsUtil.getBean(labelTemplate.getMethodCode());
        if (null == strategyService) MesPcnException.throwBusiException("包装条码[%s]关联的包装条码模版代码[%s]未维护有效的方法策略!", mesProduceSnPrintModel.getPackageNo(), packageDb.getPackageLabelTemplate());

        mesProduceSnPrintModel.setMesLabelTemplate(labelTemplate);
        mesProduceSnPrintModel.setPartNo(packageDb.getPartNo());
        mesProduceSnPrintModel.setPartName(packageDb.getPartName());
        mesProduceSnPrintModel.getPackageList().addAll(Stream.of(packageDb).collect(Collectors.toList()));

        mesProduceSnPrintModel = strategyService.execute(null, mesProduceSnPrintModel, null, null, null, false);

        //保存打印记录日志
        printedSnLogRepository.saveAll(mesProduceSnPrintModel.getMesPrintedSnLogList());

        return mesProduceSnPrintModel;

    }

}
