package com.xisc.pm.app.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.ortools.Loader;
import com.xisc.pm.api.controller.v1.SubController;
import com.xisc.pm.api.dto.*;
import com.xisc.pm.api.dto.ctevent.ProContBoardEndDTO;
import com.xisc.pm.api.dto.model.*;
import com.xisc.pm.app.service.PmPdRecService;
import com.xisc.pm.domain.entity.*;
import com.xisc.pm.domain.repository.*;
import com.xisc.pm.domain.vo.MatStatusModifyVO;
import com.xisc.pm.domain.vo.util.JsonData;
import com.xisc.pm.infra.client.EventClient;
import com.xisc.pm.infra.client.MmEventClient;
import com.xisc.pm.infra.client.QdOrderClient;
import com.xisc.pm.infra.constant.Constants;
import com.xisc.pm.infra.constant.CtEventConstants;
import com.xisc.pm.infra.constant.PmPlateConstants;
import com.xisc.pm.infra.enums.PdProdFlag;
import com.xisc.pm.infra.mapper.SubMapper;
import com.xisc.pm.app.service.SubService;
import com.xisc.pm.infra.util.BeanUtils;
import io.choerodon.core.oauth.CustomUserDetails;
import io.choerodon.core.oauth.DetailsHelper;
import org.apache.commons.lang3.math.NumberUtils;
import org.hzero.core.base.BaseConstants;
import org.hzero.core.redis.RedisHelper;
import org.hzero.mybatis.helper.SecurityTokenHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.xisc.pm.domain.entity.PmSmallPltPos.SMALL_PLATE_DIV_NO;
import static com.xisc.pm.domain.vo.util.Knapsack.solve;
import static com.xisc.pm.tool.Tool.nvl;

@Service
public class SubServiceImpl implements SubService {

//    @Autowired
//    private SubService subService;

    @Autowired
    private QdOrderClient qdOrderClient;

    //    @Autowired
    //    private TransactionService transactionService;

    private final static Logger logger = LoggerFactory.getLogger(SubController.class);

    //region ***全局变量过程数据***
    private static List<GPreOrder> gltOrder = new ArrayList<>();

    //初次订单分组
    private static List<GGrpOrderFir> gltGrpOrderFir = new CopyOnWriteArrayList<>();

    //二次计算分组
    private static List<GCalGrp> gltGCalGrp = new CopyOnWriteArrayList<>();

    //二次计算分组
    private static List<GCalGrp> gltGCal2Grp =new CopyOnWriteArrayList<>();

    //计算结果数据
    private static List<GGrpCalRslt> gltGGrpCalRslt = Collections.synchronizedList(new ArrayList<>());

    //选择结果数据
    private static List<GGrpCalRslt> gltSelGGrpCalRslt = Collections.synchronizedList(new ArrayList<>());

    //组板板坯表
    private static List<PmPdSlab> pmPdSlabDOList = new ArrayList<>();
    //大板粗切位置表
    private static List<PmPdPlateCut> pmPdPlateCutDOList = new ArrayList<>();
    //组合子板位置表
    private static List<PmPdBlockPos> pmPdBlockPosDOList = new ArrayList<>();
    //组板合同总量表
    private static List<PmPdContSum> pmPdContSumDOList = new ArrayList<>();
    //组板小板位置表
    private static List<PmSmallPltPos> pmSmallPltPosDOList = new ArrayList<>();
    //命令板坯表
    private static List<PmCmdSlab> pmCmdSlabDOList = new ArrayList<>();
    //命令大板表
    private static List<PmCmdLargePlt> pmCmdLargePltDOList = new ArrayList<>();
    //命令参数表
    private static List<PmCmdCont> pmCmdContDOList = new ArrayList<>();
    //命令小板表
    private static List<PmCmdSmallPlt> pmCmdSmallPltDOList = new ArrayList<>();
    //组板履历表
    private static List<PmPdRecDTO> pmPdRecs = new ArrayList<>();

    // 全局变量，使用 ConcurrentHashMap 和 AtomicInteger 确保线程安全
    private final ConcurrentHashMap<String, AtomicInteger> counterMap = new ConcurrentHashMap<>();

    private static int intOrdNum = 0;

    private static int intGrpNum = 0;

    private static int intGrp2Num = 0;

    private static int intGrp3Num = 0;
    //endregion

    //region   ***全局变量获取基础数据***

    //板坯信息
    private static List<SlabInfoDO> plistSlab;
    //合同信息
    private static List<PmProCont> plistOrder;
    //生产合同产品属性表
    private static List<PmProContProdTtr> plistPmProContProdAttrDO;
    //合同产线工艺参数表
    private static List<PmContMscTech> plistPmContMscTechDO;
    //组板设计规则集
    private static List<PmPdRuleSet> plistPmPdRuleSetDO;
    //组板设计规则集
    private static List<PmPdRuleItem> plistPmPdRuleItemDO;
    //最小轧制厚度公差范围基准表
    private static List<PmMinThickTolBt> plistPmMinThickTolBtDO;
    //钢板轧制规格对应收得率基准表
    private static List<PmPlateSpecYieldBt> plistPmPlateSpecYieldBtDO;
    //强度级别对照基准表
    private static List<PmStCodeBt> plistPmStCodeBtDO;
    //粗切位置决定基准表
    private static List<PmCutPlaceBt> plistPmCutPlaceBtDO;
    //组板常数基准表
    private static List<PmPdConstBt> plistPmPdConstBtDO;
    //钢板切缝切头尾范围基准表
    private static List<PmPlateCutLenBt> plistPmPlateCutLenBtDO;
    //组板临时收得率基准表
    private static List<PmPdTmpYieldBt> plistPmPdTmpYieldBtDO;
    //钢板切边量基准表
    private static List<PmPlateTrimBt> plistPmPlateTrimBtDO;
    //余材组板内部钢种以优充次对照表
    private static List<PmSlabReplBt> plistPmSlabReplBtDO;
    //热处理炉基准规格表
    private static List<PmHeatTreatFurnaceBt> plistPmHeatTreatFurnaceBtDO;
    //特殊钢种余量增加表
    private static List<PmSpeStAddvBt> plistPmSpeStAddvBtDO;
    //合同处理成分结果数据
    private static List<QdToLineupResultCheDO> plistQdToLineupResultCheDO;
    //合同处理坯料性能要求
    private static List<QdToLineupResultSlabphyDO> plistQdToLineupResultSlabphyDO;
    //炉次工序成分代表实绩表
    private static List<QeTqHeatcheStandResultDO> plistQeTqHeatcheStandResultDO;
    //炉次待委托表
    private static List<QeTqPonoWaitTestDO> plistQeTqPonoWaitTestDO;
    //坯料低倍委托实绩表
    private static List<QeTqSlabMacroResultDO> plistQeTqSlabMacroResultDO;
    //连铸板坯生产规格基准表
    private static List<PmSlabSpecBt> plistPmSlabSpecBtDO;
    //钢板厚度余量基准表
    private static List<PmThickAddvBt> plistPmThickAddvBtDO;
    //板坯信息表
    private static List<PmPdSlabInfo> plistPmPdSlabInfoDO;  //TODO 需要添加此表信息的查询
    //合约信息
    private static List<QdToPoOrder> plistQdToPoOrderDO;  //TODO 需要添加此表信息的查询

    //TODO  需要添加 QD_TO_PO_ORDER 的查询记录
    private static Date now;
    //组板履历表
    private static List<PmSubHis> plistpmSubHisDO = new ArrayList<>();
    //组板订单详细表
    private static List<PmSubOrd> plistpmSubOrdDO = new ArrayList<>();

    //    //加热炉板坯最小长度
    //    private static int gintSlabMinLen;
    //    //加热炉板坯最大长度
    //    private static int gintSlabMaxLen;

    //endregion

    //region ***配置项参数***

    //不可自动组板订单信息
    private static List<PmIrsubableCont> plistpmIrsubableContDO = new ArrayList<>();

    //不可自动组板板坯信息
    private static List<PmIrsubableSlab> plistpmIrsubableSlabDO = new ArrayList<>();

    //自动替代配置参数
    private static List<PmAutoSubSetting> plistpmAutoSubSettingDO = new ArrayList<>();

    //钢种信息配置
    private static List<PmRetainSt> plistpmRetainStDO = new ArrayList<>();

    //仓库信息配置
    private static List<PmRetainStack> plistpmRetainStackDO = new ArrayList<>();

    //自动替代日志
    private static List<PmSubLog> plistpmSubLogDO = new ArrayList<>();

    //记录已被使用的订单号
    private static List<GPreOrder> plistOrdHis = new ArrayList<>();

    private static List<ChkChmResult>  plistChmChkRsult= new ArrayList<>();

    private static List<ChkLowResult>  plistLowChkRsult= new ArrayList<>();
    //endregion

    @Override
    public JsonData SubData(PmSubHis pmSubHis,  Long organizationId) {

        SecurityTokenHelper.validTokenIgnoreInsert(pmSubHis);
        String strSlab = pmSubHis.getSlabNo();

        long subMode = 1;

        if (strSlab == null || strSlab == "") {
            subMode = 2;
        }

        long finalSubMode = subMode;

        SubParams subParams = new SubParams();

        subParams.setSlabNo(strSlab);

//        //测试阶段需要指定板坯号
//        if (strSlab==null || strSlab=="")
//        {
//            return null;
//        }

        //获取所有数据
        GetDataInfo(subParams);

        //数据预处理
        SetPreData();

        logger.info("***初次分组数量***  " + gltGrpOrderFir.size());

        //被使用的订单数据实例化
        plistOrdHis = new ArrayList<>();
//        int intSlabCount = 0;
        // 使用 AtomicInteger 替代 int 类型
        AtomicInteger intSlabCount = new AtomicInteger(0);
        //循环板坯
        plistSlab.forEach(p -> {

                    PmSubLog subLog = new PmSubLog();
                    subLog.setSlabNo(p.getSlabNo());
                    subLog.setSubMode(finalSubMode);
                    subLog.setSubRslt("成功");
                    subLog.setTenantId(organizationId);

                    String subLogStr = "";
                    // 获取当前计数值
                    int intSlabCountAdd = intSlabCount.getAndIncrement();

                    logger.info("*************{}--板坯开始{}*************  ",intSlabCountAdd, p.getSlabNo());

                    logger.info("***板坯信息：{}   厚宽长：{}*{}*{}  钢种：{} ", p.getSlabNo(), p.getSlabActThk(), p.getSlabActWid(), p.getSlabActLen(), p.getStNo());
                    //执行日志保存
                    subLogStr = "板坯信息 厚宽长：" + p.getSlabActThk() + "*" + p.getSlabActWid() + "*" + p.getSlabActLen();

                    //  判断板坯的长度是否在plistpmAutoSubSettingDO配置的范围内
                    if (p.getSlabActLen().compareTo(plistpmAutoSubSettingDO.get(0).getMatLenMin()) < 0 && p.getSlabActLen().compareTo(plistpmAutoSubSettingDO.get(0).getMatLenMax()) > 0) {
                        logger.info("***板坯信息被排除：{}   长度不在范围内 ", p.getSlabNo());
                        return;
                    }

                    //  判断板坯的宽度是否在plistpmAutoSubSettingDO配置的范围内
                    if (p.getSlabActWid().compareTo(plistpmAutoSubSettingDO.get(0).getMatWidthMin()) < 0 && p.getSlabActWid().compareTo(plistpmAutoSubSettingDO.get(0).getMatWidthMax()) > 0) {
                        logger.info("***板坯信息被排除：{}   宽度不在范围内 ", p.getSlabNo());
                        return;
                    }

                    //  判断板坯的厚度是否在plistpmAutoSubSettingDO配置的范围内
                    if (p.getSlabActThk().compareTo(plistpmAutoSubSettingDO.get(0).getMatThickMin()) < 0 && p.getSlabActThk().compareTo(plistpmAutoSubSettingDO.get(0).getMatThickMax()) > 0) {
                        logger.info("***板坯信息被排除：{}   厚度不在范围内 ", p.getSlabNo());
                        return;
                    }

                    //判断plistpmIrsubableSlabDO是否包含P.SlabNO范围内
                    if (plistpmIrsubableSlabDO.stream().anyMatch(x -> x.getSlabNo().equals(p.getSlabNo()))) {
                        logger.info("***板坯信息被排除：{}   不可组板 ", p.getSlabNo());
                        return;
                    }

                    //判断plistpmRetainStDO是否包含P的钢种，判断这个板坯的钢种是否可组板
                    if (plistpmRetainStDO.stream().anyMatch(x -> x.getStNo().equals(p.getStNo()))) {
                        logger.info("***板坯信息被排除：{}   不可组板 ", p.getSlabNo());
                        return;
                    }

                    try {

                        gltGCalGrp = new ArrayList<>();

                        gltGCal2Grp = new ArrayList<>();

                        //低倍化学成分验证
                        chkChmAndLowApi(organizationId,p);

                        //二次分组
                        SetGrpDataBySlab(p);

                        logger.info("***一次次分组1数量***  " + gltGCalGrp.size());

                        //数据小的情况，计算拼板。数据量大不计算
                        if (gltGCalGrp.size()<=100)
                        {
                            try {
                                SetGrpConBinDataBySlab(p);
                            } catch (Exception e) {

                            }
                        }
//
//                        logger.info("***二次分组1数量***  " + gltGCalGrp.size());

                        //执行日志保存
                        subLogStr += "-----二次分组1数量：" + gltGCalGrp.size();

                        logger.info("***二次分组2数量***  " + gltGCal2Grp.size());

                        //执行日志保存
                        subLogStr += "-----二次分组2数量：" + gltGCal2Grp.size();

                        gltGCalGrp.addAll(gltGCal2Grp);

                        //分组设置ID
                        for (int i = 0; i < gltGCalGrp.size(); i++) {

                            gltGCalGrp.get(i).setIDValue(i + 1);

                        }

                        gltGGrpCalRslt = new ArrayList<>();

                        gltSelGGrpCalRslt = new ArrayList<>();

                        plistpmSubHisDO= new ArrayList<>();

                        plistpmSubOrdDO = new ArrayList<>();

                        pmPdSlabDOList = new ArrayList<>();

                        pmPdPlateCutDOList = new ArrayList<>();

                        pmPdBlockPosDOList = new ArrayList<>();

                        pmPdContSumDOList = new ArrayList<>();

                        pmSmallPltPosDOList = new ArrayList<>();

                        pmCmdSlabDOList = new ArrayList<>();

                        pmCmdLargePltDOList = new ArrayList<>();

                        pmCmdContDOList = new ArrayList<>();

                        pmCmdSmallPltDOList = new ArrayList<>();

                        if (gltGCalGrp.size() > 0) {

                            //板坯长度和宽度调换
                            if (p.getSlabActLen().compareTo(p.getSlabActWid()) <= 0) {
                                // 当 p.getSlabActLen() 小于或等于 p.getSlabActWid() 时执行的代码
                                p.setRemLen(p.getSlabActWid());
                                p.setRemWid(p.getSlabActLen());
                            } else {
                                p.setRemLen(p.getSlabActLen());
                                p.setRemWid(p.getSlabActWid());
                            }

                            SetGroupCalRslt(p);

                            logger.info("所有结果数据板坯号：{}；数量：{}", p.getSlabNo(), gltGGrpCalRslt.size());
                            logger.info("选择结果数据板坯号：{}；数量：{}", p.getSlabNo(), gltSelGGrpCalRslt.size());
                            //执行日志保存
                            subLogStr += "-----结果数据数量1" + gltGGrpCalRslt.size() + "-----结果数据数量2" + gltSelGGrpCalRslt.size();
                        }
                        subLog.setSubLog(subLogStr);
                        if (gltSelGGrpCalRslt.size() > 0) {
                            now = new Date();
                            //存储数据，组板结果
                            SaveHisData(p);
                            //数据整理
                            SetSaveDate(p,organizationId);
                            //开启事务
                            //TransactionStatus transactionStatus = transactionService.begin();
                            try {
                                //保存数据
                                SaveData(p,organizationId,subLog);
                                //transactionService.commit(transactionStatus);
                            } catch (Exception e) {
                                logger.error("保存事务回滚：" + p.getSlabNo(), e);
                                //回滚事务
                                //transactionService.rollback(transactionStatus);
                            }
                        }

                    } catch (Exception e) {
                        logger.error("板坯报错：" + p.getSlabNo(), e);
                    }
                    logger.info("*************板坯结束{}*************  ", p.getSlabNo());
                    logger.info("");
                }

        );
        logger.info("*****处理结束*****");
        logger.info("");

        return JsonData.buildSuccess();



    }

    public void SaveHisData(SlabInfoDO SInfo) {
        String strMaxSeq = GetMaxSeq(SInfo.getPono());

        int intSeq = 0;

        if (strMaxSeq.length() >= 4 && strMaxSeq.charAt(strMaxSeq.length() - 4) == '9') {
            intSeq = Integer.parseInt(strMaxSeq.substring(strMaxSeq.length() - 3));
        }

        for (int i = 0; i < plistpmSubHisDO.size(); i++) {

            intSeq+=1;

            String virtualSlabNo = generateVirtualSlabNoSave(SInfo.getPono(), intSeq);

            String strGuid = plistpmSubHisDO.get(i).getRelKey();

            //获取虚拟板坯号
            plistpmSubHisDO.get(i).setVirtualSlabNo(virtualSlabNo);

//            InsertPmSubHisDO(plistpmSubHisDO.get(i));
            //删选plistpmSubOrdDO中虚拟板坯号等于strGuid的信息
            plistpmSubOrdDO.stream()
                    .filter(f -> f.getRelKey().equals(strGuid))
                    .collect(Collectors.toList()).forEach(m -> {
                        m.setVirtualSlabNo(virtualSlabNo);
//                        InsertPmSubOrdDO(m);
                    });
            gltSelGGrpCalRslt.stream()
                    .filter(f -> f.getRelKey().equals(strGuid))
                    .collect(Collectors.toList()).forEach(m -> {
                        m.setVirtualSlabNo(virtualSlabNo);

                    });


        }
//
//        //存储数据，组板结果
//        plistpmSubHisDO.forEach(e -> {
//
//            String virtualSlabNo = generateVirtualSlabNoSave(SInfo.getPono(), intSeq);
//
//            String strGuid = e.getRelKey();
//
//            //获取虚拟板坯号
//            e.setVirtualSlabNo(virtualSlabNo);
//
//            InsertPmSubHisDO(e);
//            //删选plistpmSubOrdDO中虚拟板坯号等于strGuid的信息
//            plistpmSubOrdDO.stream()
//                    .filter(f -> !f.getRelKey().equals(strGuid))
//                    .collect(Collectors.toList()).forEach(m -> {
//                        m.setVirtualSlabNo(virtualSlabNo);
//                        InsertPmSubOrdDO(m);
//                    });
//            gltSelGGrpCalRslt.stream()
//                    .filter(f -> !f.getRelKey().equals(strGuid))
//                    .collect(Collectors.toList()).forEach(m -> {
//                        m.setVirtualSlabNo(virtualSlabNo);
//
//                    });
//
//        });

    }

    /**
     * 获取数据-多线程
     * 板坯数据
     * 订单数据
     * 配置信息
     */
    public void GetDataInfo(SubParams subParams) {

        logger.info("*****开始获取数据******");

        //region  ***多线程获取基础数据***

        // 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(32);

        //初始化方案
        Loader.loadNativeLibraries();
//        System.load("E:/XTGT/ortools-win32-x86-64-9.7.2996/ortools-win32-x86-64/jniortools.dll");

        // 创建多个任务
        List<Callable<Void>> tasks = new ArrayList<>();

        //1板坯数据
        tasks.add(() -> {
            plistSlab = getSlabInfo(subParams);
            //logger.info("******1板坯数据获取完毕*******");
            return null;
        });

        //2订单数据
        tasks.add(() -> {
            plistOrder = getOrderInfo();
            //logger.info("******2订单数据获取完毕*******");
            return null;
        });

        //3生产合同产品属性表
        tasks.add(() -> {
            plistPmProContProdAttrDO = getPmProCountProdAttr();
            //logger.info("******3生产合同产品属性表数据获取完毕*******");
            return null;
        });

        //4合同产线工艺参数表
        tasks.add(() -> {
            plistPmContMscTechDO = getPmContMscTech();
            //logger.info("******4合同产线工艺参数表数据获取完毕*******");
            return null;
        });

        //5生产合同产品属性表
        tasks.add(() -> {
            // plistPmProContProdAttrDO = getPmProCountProdAttr();
            Thread.sleep(1000); // 休眠1秒钟
            //logger.info("******5生产合同产品属性表数据获取完毕*******");
            return null;
        });

        //6组板设计规则集
        tasks.add(() -> {
            plistPmPdRuleSetDO = getPmPdRuleSet();
            //logger.info("******6组板设计规则集数据获取完毕*******");
            return null;
        });

        //7组板设计规则集
        tasks.add(() -> {
            plistPmPdRuleItemDO = getPmPdRuleItem();
            //logger.info("******7组板设计规则集数据获取完毕*******");
            return null;
        });

        //8最小轧制厚度公差范围基准表
        tasks.add(() -> {
            plistPmMinThickTolBtDO = getPmMinThickTolBt();
            //logger.info("******8最小轧制厚度公差范围基准表数据获取完毕*******");
            return null;
        });

        //9钢板轧制规格对应收得率基准表
        tasks.add(() -> {
            plistPmPlateSpecYieldBtDO = getPmPlateSpecYieldBt();
            //logger.info("******9钢板轧制规格对应收得率基准表数据获取完毕*******");
            return null;
        });

        //10强度级别对照基准表
        tasks.add(() -> {
            plistPmStCodeBtDO = getPmStCodeBt();
            //logger.info("******10强度级别对照基准表数据获取完毕*******");
            return null;
        });

        //11粗切位置决定基准表
        tasks.add(() -> {
            plistPmCutPlaceBtDO = getPmCutPlaceBt();
            //logger.info("******11粗切位置决定基准表数据获取完毕*******");
            return null;
        });

        //12组板常数基准表
        tasks.add(() -> {
            plistPmPdConstBtDO = getPmPdConstBt();
            //logger.info("******12组板常数基准表数据获取完毕*******");
            return null;
        });

        //13钢板切缝切头尾范围基准表
        tasks.add(() -> {
            plistPmPlateCutLenBtDO = getPmPlateCutLenBt();
            //logger.info("******13钢板切缝切头尾范围基准表数据获取完毕*******");
            return null;
        });

        //14组板临时收得率基准表
        tasks.add(() -> {
            plistPmPdTmpYieldBtDO = getPmPdTmpYieldBt();
            //logger.info("******14组板临时收得率基准表数据获取完毕*******");
            return null;
        });

        //15钢板切边量基准表
        tasks.add(() -> {
            plistPmPlateTrimBtDO = getPmPlateTrimBt();
            //logger.info("******15钢板切边量基准表数据获取完毕*******");
            return null;
        });

        //16余材组板内部钢种以优充次对照表
        tasks.add(() -> {
            plistPmSlabReplBtDO = getPmSlabReplBt();
            //logger.info("******16余材组板内部钢种以优充次对照表数据获取完毕*******");
            return null;
        });

        //17热处理炉基准规格表
        tasks.add(() -> {
            plistPmHeatTreatFurnaceBtDO = getPmHeatTreatFurnaceBt();
            //logger.info("******17热处理炉基准规格表数据获取完毕*******");
            return null;
        });

        //18特殊钢种余量增加表
        tasks.add(() -> {
            plistPmSpeStAddvBtDO = getPmSpeStAddvBt();
            //logger.info("******18特殊钢种余量增加表数据获取完毕*******");
            return null;
        });

        //19合同处理成分结果数据
        tasks.add(() -> {
            plistQdToLineupResultCheDO = getQdToLineupResultChe();
            //logger.info("******19合同处理成分结果数据获取完毕*******");
            return null;
        });

        //20合同处理坯料性能要求
        tasks.add(() -> {
            plistQdToLineupResultSlabphyDO = getQdToLineupResultSlabphy();
            //logger.info("******20合同处理坯料性能要求数据获取完毕*******");
            return null;
        });

        //21炉次工序成分代表实绩表
        tasks.add(() -> {
            plistQeTqHeatcheStandResultDO = getQeTqHeatcheStandResult();
            //logger.info("******21炉次工序成分代表实绩表数据获取完毕*******");
            return null;
        });

        //22炉次待委托表
        tasks.add(() -> {
            plistQeTqPonoWaitTestDO = getQeTqPonoWaitTest();
            //logger.info("******22炉次待委托表数据获取完毕*******");
            return null;
        });

        //23坯料低倍委托实绩表
        tasks.add(() -> {
            plistQeTqSlabMacroResultDO = getQeTqSlabMacroResult();
            //logger.info("******23坯料低倍委托实绩表数据获取完毕*******");
            return null;
        });

        //24连铸板坯生产规格基准表
        tasks.add(() -> {
            plistPmSlabSpecBtDO = getPmSlabSpecBt();
            return null;
        });

        //25不可自动组板订单信息
        tasks.add(() -> {
            plistpmIrsubableContDO = getPmIrsubableCont();
            return null;
        });

        //26不可自动组板板坯信息
        tasks.add(() -> {
            plistpmIrsubableSlabDO = getPmIrsubableSlab();
            return null;
        });

        //27自动组板配置信息
        tasks.add(() -> {
            plistpmAutoSubSettingDO = getPmAutoSubSetting();
            return null;
        });

        //28钢种配置信息
        tasks.add(() -> {
            plistpmRetainStDO = getPmRetainSt();
            return null;
        });

        //29仓库配置信息
        tasks.add(() -> {
            plistpmRetainStackDO = getPmRetainStack();
            return null;
        });

        //30板坯信息
        tasks.add(() -> {
            plistPmPdSlabInfoDO = getPmPdSlabInfo( subParams);
            return null;
        });

        //31合约信息
        tasks.add(() -> {
            plistQdToPoOrderDO = getQdToPoOrder();
            return null;
        });

        //32厚度余量追加值
        tasks.add(() -> {
            plistPmThickAddvBtDO = getPmThickAddvBt();
            return null;
        });

        // 执行所有任务
        try {
            executorService.invokeAll(tasks);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        logger.info("1:板坯数据：" + plistSlab.size());
        logger.info("2:订单数据：" + plistOrder.size());
        logger.info("3:生产合同产品属性表：" + plistPmProContProdAttrDO.size());
        logger.info("4:合同产线工艺参数表：" + plistPmContMscTechDO.size());
        logger.info("5:组板设计规则集：" + plistPmPdRuleSetDO.size());
        logger.info("6:组板设计规则集详细：" + plistPmPdRuleItemDO.size());
        logger.info("7:最小轧制厚度公差范围基准表：" + plistPmMinThickTolBtDO.size());
        logger.info("8:钢板轧制规格对应收得率基准表：" + plistPmPlateSpecYieldBtDO.size());
        logger.info("9:强度级别对照基准表：" + plistPmStCodeBtDO.size());
        logger.info("10:粗切位置决定基准表：" + plistPmCutPlaceBtDO.size());
        logger.info("11:组板常数基准表：" + plistPmPdConstBtDO.size());
        logger.info("12:钢板切缝切头尾范围基准表：" + plistPmPlateCutLenBtDO.size());
        logger.info("13:组板临时收得率基准表：" + plistPmPdTmpYieldBtDO.size());
        logger.info("14:钢板切边量基准表：" + plistPmPlateTrimBtDO.size());
        logger.info("15:余材组板内部钢种以优充次对照表：" + plistPmSlabReplBtDO.size());
        logger.info("16:热处理炉基准规格表：" + plistPmHeatTreatFurnaceBtDO.size());
        logger.info("17:特殊钢种余量增加表：" + plistPmSpeStAddvBtDO.size());
        logger.info("18:合同处理成分结果数据：" + plistQdToLineupResultCheDO.size());
        logger.info("19:合同处理坯料性能要求：" + plistQdToLineupResultSlabphyDO.size());
        logger.info("20:炉次工序成分代表实绩表：" + plistQeTqHeatcheStandResultDO.size());
        logger.info("21:炉次待委托表：" + plistQeTqPonoWaitTestDO.size());
        logger.info("22:坯料低倍委托实绩表：" + plistQeTqSlabMacroResultDO.size());
        logger.info("23:连铸板坯生产规格基准表：" + plistPmSlabSpecBtDO.size());
        logger.info("24:不可自动组板订单信息：" + plistpmIrsubableContDO.size());
        logger.info("25:不可自动组板板坯信息：" + plistpmIrsubableSlabDO.size());
        logger.info("26:钢种配置信息：" + plistpmRetainStDO.size());
        logger.info("27:仓库配置信息：" + plistpmRetainStackDO.size());
        logger.info("28:自动组板配置信息：" + plistpmAutoSubSettingDO.size());
        logger.info("29:板坯生产信息：" + plistPmPdSlabInfoDO.size());
        logger.info("30:订单合约信息信息：" + plistQdToPoOrderDO.size());

        logger.info("获取基础数据完成");
        if (plistpmAutoSubSettingDO.size() > 0) {
            logger.info("配置信息-》 是否启动      ：{}", plistpmAutoSubSettingDO.get(0).getIsStartFlag());
            logger.info("配置信息-》 启动时间范围   ：{}~{}", plistpmAutoSubSettingDO.get(0).getStartTime(), plistpmAutoSubSettingDO.get(0).getEndTime());
            logger.info("配置信息-》 优先模式      ：{}", plistpmAutoSubSettingDO.get(0).getPriMode());
            logger.info("配置信息-》 最低成材率     ：{}", plistpmAutoSubSettingDO.get(0).getStockRate());
            logger.info("配置信息-》 最大剩余长度   ：{}", plistpmAutoSubSettingDO.get(0).getResidueLen());
            logger.info("配置信息-》 板坯长度范围   ：{}~{}", plistpmAutoSubSettingDO.get(0).getMatLenMin(), plistpmAutoSubSettingDO.get(0).getMatLenMax());
            logger.info("配置信息-》 板坯宽度范围   ：{}~{}", plistpmAutoSubSettingDO.get(0).getMatWidthMin(), plistpmAutoSubSettingDO.get(0).getMatWidthMax());
            logger.info("配置信息-》 板坯厚度范围   ：{}~{}", plistpmAutoSubSettingDO.get(0).getMatThickMin(), plistpmAutoSubSettingDO.get(0).getMatThickMax());
            logger.info("配置信息-》 订单宽度范围   ：{}~{}", plistpmAutoSubSettingDO.get(0).getOrderWidthMin(), plistpmAutoSubSettingDO.get(0).getOrderWidthMax());
            logger.info("配置信息-》 订单厚度范围   ：{}~{}", plistpmAutoSubSettingDO.get(0).getOrderThickMin(), plistpmAutoSubSettingDO.get(0).getOrderThickMax());
            logger.info("配置信息-》 订单交货期范围  ：{}~{}", plistpmAutoSubSettingDO.get(0).getDelivyDateFrom(), plistpmAutoSubSettingDO.get(0).getDelivyDateTo());
            logger.info("配置信息-》 可用仓库      ：{}", plistpmAutoSubSettingDO.get(0).getUseableDstock());
            logger.info("配置信息-》 优先模式      ：{}", plistpmAutoSubSettingDO.get(0).getPriMode());
            logger.info("配置信息-》 超投条件      ：{}", plistpmAutoSubSettingDO.get(0).getOvershootCondition());
            logger.info("配置信息-》 库存最低成材率 ：{}", plistpmAutoSubSettingDO.get(0).getStockRate());
            logger.info("配置信息-》 库存时间      ：{}", plistpmAutoSubSettingDO.get(0).getStockDay());
            logger.info("配置信息-》 交货期最低成材率：{}", plistpmAutoSubSettingDO.get(0).getDeliveryRate());
            logger.info("配置信息-》 交货期偏移量   ：{}", plistpmAutoSubSettingDO.get(0).getDeliveryOffsetDay());
        }


        // 关闭线程池
        executorService.shutdown();

        //endregion  多线程获取基础数据

    }

    /**
     * 数据预处理
     */
    public void SetPreData() {

        //实例化订单列表
        gltOrder = new ArrayList<>();
        //实例化订单分组
        gltGrpOrderFir = new CopyOnWriteArrayList<>();
        //订单数据处理
        SetOrderLackData();

        //订单根据尺寸初次分组
        SetGroupOrderFir();

    }

    /**
     * 二次分组根据板坯性能删选分组
     */
    public void SetGrpDataBySlab(SlabInfoDO SInfo) {

        gltGrpOrderFir.parallelStream().forEach(e -> {

            // gltGCalGrp 产生可计算分组

            //压缩比  Compression ratio

            //宽展比 Wide ratio
            //GCG.getLtInfoGPreOrder().stream().filter(e->e.)
            //最大宽度

            //钢种标准对比

            GCalGrp GCG = new GCalGrp();
            GCG.setLtInfoGPreOrder(new CopyOnWriteArrayList<>());
            e.getLtInfoGPreOrder().forEach(f -> {

                try {

                    //压缩比
                    if (!ChkCompress(SInfo, f)) {
                        return;
                    }

                    //宽展比
                    if (!ChkWid(SInfo, f)) {
                        return;
                    }

                    //同钢种判断  TODO:同钢种验证，低代高需验证效率值
                    if (!SInfo.getStNo().equals(f.getInfoPmContMscTechDO().getStNo()))
                    {
                        return;
                    }

                    //产线相同   TODO：同产线，不同产线需更改后续产线规则
                    if (!SInfo.getMscLineNo().equals(f.getInfoPmContMscTechDO().getMscLineNo())) {
                        return;
                    }

                    //不存在或者合格都是成功，不合格返回false
                    if(plistChmChkRsult.stream().anyMatch(m -> m.getPono().equals(SInfo.getPono()) && m.getOrderNo().equals(f.getOrderNo())))
                    {
                        if (plistChmChkRsult.stream().anyMatch(m -> m.getPono().equals(SInfo.getPono()) && m.getOrderNo().equals(f.getOrderNo()) && m.getChmresult().equals("不合格"))){
                            return;
                        }
                    }
//                      plistChmChkRsult
//                            plistLowChkRsult

//                    //化学成分  chemical composition
//                    if (!ChkChemical(SInfo, f)) {
//                        return;
//                    }

                } catch (Exception e1) {
//                    log.error("化学成分", e1);
                    return;
                }
                try {

                    //不存在或者合格都是成功，不合格返回false
                    if(plistLowChkRsult.stream().anyMatch(m -> m.getPono().equals(SInfo.getPono()) && m.getOrderNo().equals(f.getOrderNo())))
                    {
                        if (plistLowChkRsult.stream().anyMatch(m -> m.getPono().equals(SInfo.getPono()) && m.getOrderNo().equals(f.getOrderNo()) && m.getLowresult().equals("不合格"))){
                            return;
                        }
                    }
//
//                    //低倍检测  low-power check
//                    if (!ChkLowPower(SInfo, f)) {
//                        return;
//                    }
                } catch (Exception e1) {
//                    log.error("低倍检测", e1);
                    return;
                }

                //GCG.setLtInfoGPreOrder(new ArrayList<>());
                GCG.getLtInfoGPreOrder().add(f);//添加订单信息
            });

            try {
                //存在订单，添加可计算分组
                if (GCG.getLtInfoGPreOrder().size() > 0) {

                    //GCG.getLtInfoGPreOrder().stream().filter(e->e.)
                    //最大宽度
                    OptionalInt maxWidth = GCG.getLtInfoGPreOrder().stream()
                            .mapToInt(GPreOrder::getWid)
                            .max();
                    //最大宽度余量
                    OptionalInt maxAddWidth = GCG.getLtInfoGPreOrder().stream()
                            .mapToInt(GPreOrder::getWidthAddv)
                            .max();

                    //宽展比   保留2位小数
                    BigDecimal decWidRate = BigDecimal.valueOf(maxWidth.orElse(0)).divide(SInfo.getSlabActWid(), 2, RoundingMode.HALF_UP);

                    //宽展比
                    GCG.setWid_Rate(decWidRate);

                    BigDecimal decThkOrd = GCG.getLtInfoGPreOrder().get(0).getThk();

                    //厚度
                    GCG.setOrder_Thk(decThkOrd);

                    //标准
                    GCG.setSG_STD(GCG.getLtInfoGPreOrder().get(0).getInfoPmProContProdAttrDO().getSgStd());

                    //内部钢种
                    GCG.setST_NO(GCG.getLtInfoGPreOrder().get(0).getST_NO());

                    //压缩比
                    BigDecimal decThkRate =decThkOrd.divide(SInfo.getSlabActThk(), 2, RoundingMode.HALF_UP);

                    //压缩比
                    GCG.setThk_Rate(decThkRate);

                    //最大厚度公差下限最大值
                    Optional<BigDecimal> maxTolThkMin = GCG.getLtInfoGPreOrder().stream()
                            .map(GPreOrder::getThickTolMin)
                            .reduce(BigDecimal::max);

                    //最大厚度公差上限最小值
                    Optional<BigDecimal> maxTolThkMax = GCG.getLtInfoGPreOrder().stream()
                            .map(GPreOrder::getThickTolMax)
                            .reduce(BigDecimal::min);
                    //厚度公差交集上限
                    GCG.setThickTolMax(maxTolThkMax.orElse(BigDecimal.ZERO));
                    //厚度公差交集上限
                    GCG.setThickTolMin(maxTolThkMin.orElse(BigDecimal.ZERO));

                    //厚度追加值
                    BigDecimal decThkAdd= BigDecimal.ZERO;

                    String strThkTolType;
                    if (GCG.getLtInfoGPreOrder().get(0).getInfoQdToPoOrderDO().getThkTolType() != null) {
                        strThkTolType = GCG.getLtInfoGPreOrder().get(0).getInfoQdToPoOrderDO().getThkTolType();
                    } else {
                        strThkTolType = "*";
                    }
                    //存在数据，判断热处理模式
                    if (plistPmThickAddvBtDO.stream().anyMatch(p -> p.getMscLineNo().equals(SInfo.getMscLineNo())
                            && p.getTolTypeCode().equals(strThkTolType)
                            && p.getPlateThickFrom().compareTo(GCG.getLtInfoGPreOrder().get(0).getThk()) <= 0
                            && p.getPlateThickTo().compareTo(GCG.getLtInfoGPreOrder().get(0).getThk()) >= 0
                            && p.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) <= 0
                            && p.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) >= 0
                    )) {
                        if (GCG.getLtInfoGPreOrder().get(0)==null)
                        {

                        }

                        if (GCG.getLtInfoGPreOrder().get(0).getInfoPmContMscTechDO()==null)
                        {

                        }

                        if (GCG.getLtInfoGPreOrder().get(0).getInfoPmContMscTechDO().getWholeHeatTreatmentType()==null)
                        {

                        }

                        if (GCG.getLtInfoGPreOrder().get(0).getInfoPmContMscTechDO().getWholeHeatTreatmentType() != null
                                && GCG.getLtInfoGPreOrder().get(0).getInfoPmContMscTechDO().getWholeHeatTreatmentType().contains("Q")) {
                            decThkAdd = plistPmThickAddvBtDO.stream().filter(p -> p.getMscLineNo().equals(SInfo.getMscLineNo())
                                    && p.getTolTypeCode().equals(strThkTolType)
                                    && p.getWholeHeatTreatmentType().equals("Q")
                                    && p.getPlateThickFrom().compareTo(GCG.getLtInfoGPreOrder().get(0).getThk()) <= 0
                                    && p.getPlateThickTo().compareTo(GCG.getLtInfoGPreOrder().get(0).getThk()) >= 0
                                    && p.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) <= 0
                                    && p.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) >= 0
                            ).collect(Collectors.toList()).get(0).getThickAddv();
                        } else {
                            decThkAdd = plistPmThickAddvBtDO.stream().filter(p -> p.getMscLineNo().equals(SInfo.getMscLineNo())
                                    && p.getTolTypeCode().equals(strThkTolType)
                                    && p.getWholeHeatTreatmentType().equals("*")
                                    && p.getPlateThickFrom().compareTo(GCG.getLtInfoGPreOrder().get(0).getThk()) <= 0
                                    && p.getPlateThickTo().compareTo(GCG.getLtInfoGPreOrder().get(0).getThk()) >= 0
                                    && p.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) <= 0
                                    && p.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) >= 0
                            ).collect(Collectors.toList()).get(0).getThickAddv();
                        }

                    }

                    //厚度追加值
                    GCG.setThk_Add(decThkAdd);

                    //轧制厚度   厚度+厚度公差下限最大值+厚度追加值
                    BigDecimal decThk = e.getThk().add(maxTolThkMin.orElse(BigDecimal.ZERO)).add(decThkAdd);

                    //轧制宽度   最大宽度+宽度余量
                    int intWid = maxWidth.orElse(0) + maxAddWidth.orElse(0);

                    //切边
                    int intTrimWid = 0;

                    String strWithSideFlag = "C";
                    if (GCG.getLtInfoGPreOrder().get(0).getInfoPmProContProdAttrDO().getProdAMark()==null
                            || GCG.getLtInfoGPreOrder().get(0).getInfoPmProContProdAttrDO().getProdAMark().equals(""))
                    {
                        strWithSideFlag="C";
                    }else{
                        strWithSideFlag=GCG.getLtInfoGPreOrder().get(0).getInfoPmProContProdAttrDO().getProdAMark();
                    }
                    //切边量
                    String finalStrWithSideFlag = strWithSideFlag;
                    if (plistPmPlateTrimBtDO.stream().anyMatch(p -> p.getMscLineNo().equals(SInfo.getMscLineNo())
                            && p.getPlateThickFrom().compareTo(decThk) <= 0
                            && p.getPlateThickTo().compareTo(decThk) >= 0
                            && p.getSmallPlateLenFrom().compareTo(BigDecimal.valueOf(GCG.getLtInfoGPreOrder().get(0).getLen())) <= 0
                            && p.getSmallPlateLenTo().compareTo(BigDecimal.valueOf(GCG.getLtInfoGPreOrder().get(0).getLen())) >= 0
                            && p.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) <= 0
                            && p.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) >= 0
                            && p.getWidenFrom().compareTo(decWidRate) <= 0
                            && p.getWidenTo().compareTo(decWidRate) >= 0
                            && p.getWithSideFlag().equals(finalStrWithSideFlag)
                    )) {

                        String finalStrWithSideFlag1 = strWithSideFlag;
                        intTrimWid = plistPmPlateTrimBtDO.stream().filter(p -> p.getMscLineNo().equals(SInfo.getMscLineNo())
                                && p.getPlateThickFrom().compareTo(decThk) <= 0
                                && p.getPlateThickTo().compareTo(decThk) >= 0
                                && p.getSmallPlateLenFrom().compareTo(BigDecimal.valueOf(GCG.getLtInfoGPreOrder().get(0).getLen())) <= 0
                                && p.getSmallPlateLenTo().compareTo(BigDecimal.valueOf(GCG.getLtInfoGPreOrder().get(0).getLen())) >= 0
                                && p.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) <= 0
                                && p.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) >= 0
                                && p.getWidenFrom().compareTo(decWidRate) <= 0
                                && p.getWidenTo().compareTo(decWidRate) >= 0
                                && p.getWithSideFlag().equals(finalStrWithSideFlag1)
                        ).collect(Collectors.toList()).get(0).getTrimWidth().intValue();
                    }

                    //轧制宽度= 最大宽度 + 最大宽度余量 + 切边量
                    intWid = intWid + intTrimWid;

                    //宽度
                    GCG.setWid(intWid);

                    //厚度
                    GCG.setThk(decThk);

                    //切边
                    GCG.setWid_Add(intTrimWid);

                    gltGCalGrp.add(GCG);
                }
            } catch (Exception ex) {
                logger.error("SetGrpConBinDataBySlab", ex);
            }

        });

    }

    /**
     * 二次分组根据板坯性能删选分组-组合
     */
    public  void SetGrpConBinDataBySlab(SlabInfoDO SInfo) {

        //组合的分组ID+1000000 .parallelStream()
        intGrp2Num=intGrp2Num+1000000;
        synchronized (gltGCal2Grp) {
            gltGCalGrp.parallelStream().forEach(e -> {

                gltGCalGrp.forEach(f -> {

                    List<String> ltInfoOrder = new ArrayList<>();

                    //宽度满足要求和厚度相同
                    if (f.getWid()+e.getWid()<4980
                            && e.getThk().compareTo(f.getThk())==0
                            && e.getST_NO().equals(f.getST_NO())
                            && e.getThickTolMin().compareTo(f.getThickTolMin())==0
                            && e.getThickTolMax().compareTo(f.getThickTolMax())==0
                    ){

                        e.getLtInfoGPreOrder().forEach(i -> {

                            f.getLtInfoGPreOrder().forEach(j -> {

                                //排己
                                if (i.getIDValue()==j.getIDValue())
                                {
                                    return;
                                }

                                GPreOrder GPO1=i;

                                GPreOrder GPO2=j;

                                //组合数据的数量，提升效率,大于二十
                                if(ltInfoOrder.stream().filter(m->m.equals(GPO1.getOrderNo()+"_"+GPO2.getOrderNo())).count()>20)
                                {
                                    return;
                                }

                                //产生新的订单数据组合板
                                GPreOrder GPO=new GPreOrder();
                                //主键等于两个订单主键之和
                                GPO.setIDValue(GPO1.getIDValue()+GPO2.getIDValue());

                                GPO.setOrderNo(GPO1.getOrderNo() + "_" + GPO2.getOrderNo());

                                //实例化订单集合
                                GPO.setLtInfoCombGPreOrder(new CopyOnWriteArrayList<>());

                                GComBOrder GCB1=new GComBOrder();

                                GCB1.setWid(i.getWid());
                                GCB1.setLen(i.getLen());
                                GCB1.setThk(i.getThk());

                                GCB1.setInfoGPreOrder(i);

                                GComBOrder GCB2 = new GComBOrder();

                                GCB2.setWid(j.getWid());
                                GCB2.setLen(j.getLen());
                                GCB2.setThk(j.getThk());

                                GCB2.setInfoGPreOrder(j);

                                GPO.getLtInfoCombGPreOrder().add(GCB1);

                                GPO.getLtInfoCombGPreOrder().add(GCB2);

                                //内部钢种
                                GPO.setST_NO(GPO1.getST_NO());

                                // 设置厚度
                                GPO.setThk(GPO1.getInfoPmProContProdAttrDO().getOrderThick());
                                // 设置宽度
                                GPO.setWid(GPO1.getInfoPmProContProdAttrDO().getOrderWidth().intValue()+GPO2.getInfoPmProContProdAttrDO().getOrderWidth().intValue());
                                // 设置宽度余量
                                GPO.setWidthAddv(Math.max( GPO1.getInfoPmProContProdAttrDO().getWidthAddv().intValue(),GPO2.getInfoPmProContProdAttrDO().getWidthAddv().intValue()));
                                // 设置长度
                                GPO.setLen(Math.max(GPO1.getInfoPmProContProdAttrDO().getOrderLen().intValue(),GPO2.getInfoPmProContProdAttrDO().getOrderLen().intValue()));
                                // 设置厚度公差下限
                                GPO.setThickTolMin(GPO1.getInfoPmProContProdAttrDO().getThickTolMin());
                                // 设置厚度公差上限
                                GPO.setThickTolMax(GPO1.getInfoPmProContProdAttrDO().getThickTolMax());
                                //// 设置订单号
                                //GPO.setOrderNo(GPO1.getOrderNo());
                                // 关联订单信息对象
                                GPO.setInfoPmProContDo(GPO1.getInfoPmProContDo());
                                // 关联订单产品属性对象
                                GPO.setInfoPmProContProdAttrDO(GPO1.getInfoPmProContProdAttrDO());
                                // 关联订单次要技术信息对象
                                GPO.setInfoPmContMscTechDO(GPO1.getInfoPmContMscTechDO());
                                //合同
                                GPO.setInfoQdToPoOrderDO(GPO1.getInfoQdToPoOrderDO());
                                //组合标识
                                GPO.setCombinationFlag(1);
                                //记录组合数据的数量，提升效率
                                ltInfoOrder.add(GPO1.getOrderNo() + "_" + GPO2.getOrderNo());

                                try {

                                    try {
                                        if (gltGCal2Grp.stream().filter(p -> p.getLtInfoGPreOrder().stream().anyMatch(q -> q.getOrderNo().contains(GPO1.getOrderNo())
                                                && q.getOrderNo().contains(GPO2.getOrderNo())
                                                && (q.getOrderNo().equals(GPO1.getOrderNo() + "_" + GPO2.getOrderNo())
                                                || q.getOrderNo().equals(GPO2.getOrderNo() + "_" + GPO1.getOrderNo())))
                                        ).count() > 0) {

                                        }
                                    } catch (Exception ex) {
                                        return;
                                    }

                                    if (gltGCal2Grp.stream().filter(p ->
                                            p.getLtInfoGPreOrder()!=null
                                                    && p.getLtInfoGPreOrder().size()>0
                                                    && p.getLtInfoGPreOrder().stream().anyMatch(q -> q.getOrderNo().contains(GPO1.getOrderNo())
                                                    && q.getOrderNo().contains(GPO2.getOrderNo())
                                                    && (q.getOrderNo().equals(GPO1.getOrderNo() + "_" + GPO2.getOrderNo())
                                                    || q.getOrderNo().equals(GPO2.getOrderNo() + "_" + GPO1.getOrderNo())))
                                    ).count() > 0) {

                                        try {

                                            Optional<GCalGrp> GCG = gltGCal2Grp.stream().filter(p ->
                                                    p.getLtInfoGPreOrder() != null
                                                            && p.getLtInfoGPreOrder().size() > 0
                                                            && p.getLtInfoGPreOrder().stream().anyMatch(q -> q.getOrderNo().contains(GPO1.getOrderNo())
                                                            && q.getOrderNo().contains(GPO2.getOrderNo())
                                                            && (q.getOrderNo().equals(GPO1.getOrderNo() + "_" + GPO2.getOrderNo())
                                                            || q.getOrderNo().equals(GPO2.getOrderNo() + "_" + GPO1.getOrderNo())))).collect(Collectors.toList()).stream().findFirst();

                                            GCG.ifPresent(gcg -> {
                                                gcg.getLtInfoGPreOrder().add(GPO);
                                            });

                                        } catch (Exception ex) {
                                            logger.info("添加2分组报错！");
                                        }

                                    } else {

                                        // 不存在同时包含 i 和 j 的分组
                                        GCalGrp GCG = new GCalGrp();

                                        GCG.setLtInfoGPreOrder(new CopyOnWriteArrayList<>());

                                        //相同组合信息
                                        GCG.getLtInfoGPreOrder().add(GPO);

                                        //内部钢种
                                        GCG.setST_NO(GPO.getST_NO());

                                        //标准
                                        GCG.setSG_STD(GPO.getInfoPmProContProdAttrDO().getSgStd());

                                        //宽度两个宽度的和
                                        int maxWidth = GPO.getLtInfoCombGPreOrder().stream()
                                                .mapToInt(GComBOrder::getWid)
                                                .sum();

                                        //最大宽度余量
                                        OptionalInt maxAddWidth = GCG.getLtInfoGPreOrder().stream()
                                                .mapToInt(GPreOrder::getWidthAddv)
                                                .max();

                                        //宽展比   保留2位小数
                                        BigDecimal decWidRate = BigDecimal.valueOf(maxWidth).divide(SInfo.getSlabActWid(), 2, RoundingMode.HALF_UP);

                                        //最大厚度公差最小值
                                        Optional<BigDecimal> maxTolThkMin = GCG.getLtInfoGPreOrder().stream()
                                                .map(GPreOrder::getThickTolMin)
                                                .reduce(BigDecimal::max);

                                        //宽展比
                                        GCG.setWid_Rate(decWidRate);

                                        BigDecimal decThkOrd = GCG.getLtInfoGPreOrder().get(0).getThk();

                                        GCG.setOrder_Thk(decThkOrd);

                                        //压缩比
                                        BigDecimal decThkRate =decThkOrd.divide(SInfo.getSlabActThk(), 2, RoundingMode.HALF_UP);

                                        //压缩比
                                        GCG.setThk_Rate(decThkRate);

                                        //最大厚度公差上限最小值
                                        Optional<BigDecimal> maxTolThkMax = GCG.getLtInfoGPreOrder().stream()
                                                .map(GPreOrder::getThickTolMax)
                                                .reduce(BigDecimal::min);
                                        //厚度公差交集上限
                                        GCG.setThickTolMax(maxTolThkMax.orElse(BigDecimal.ZERO));
                                        //厚度公差交集上限
                                        GCG.setThickTolMin(maxTolThkMin.orElse(BigDecimal.ZERO));

                                        //厚度追加值
                                        BigDecimal decThkAdd = BigDecimal.ZERO;

                                        String strThkTolType;
                                        if (GCG.getLtInfoGPreOrder().get(0).getInfoQdToPoOrderDO().getThkTolType() != null) {
                                            strThkTolType = GCG.getLtInfoGPreOrder().get(0).getInfoQdToPoOrderDO().getThkTolType();
                                        } else {
                                            strThkTolType = "*";
                                        }
                                        //存在数据，判断热处理模式
                                        if (plistPmThickAddvBtDO.stream().anyMatch(p -> p.getMscLineNo().equals(SInfo.getMscLineNo())
                                                && p.getTolTypeCode().equals(strThkTolType)
                                                && p.getPlateThickFrom().compareTo(GCG.getLtInfoGPreOrder().get(0).getThk()) <= 0
                                                && p.getPlateThickTo().compareTo(GCG.getLtInfoGPreOrder().get(0).getThk()) >= 0
                                                && p.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth + maxAddWidth.orElse(0))) <= 0
                                                && p.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth + maxAddWidth.orElse(0))) >= 0
                                        )) {

                                            if (GCG.getLtInfoGPreOrder().get(0)==null)
                                            {

                                            }

                                            if (GCG.getLtInfoGPreOrder().get(0).getInfoPmContMscTechDO()==null)
                                            {

                                            }

                                            if (GCG.getLtInfoGPreOrder().get(0).getInfoPmContMscTechDO().getWholeHeatTreatmentType()==null)
                                            {

                                            }

                                            if (GCG.getLtInfoGPreOrder().get(0).getInfoPmContMscTechDO().getWholeHeatTreatmentType()!=null &&
                                                    GCG.getLtInfoGPreOrder().get(0).getInfoPmContMscTechDO().getWholeHeatTreatmentType().contains("Q")) {
                                                decThkAdd = plistPmThickAddvBtDO.stream().filter(p -> p.getMscLineNo().equals(SInfo.getMscLineNo())
                                                        && p.getTolTypeCode().equals(strThkTolType)
                                                        && p.getWholeHeatTreatmentType().equals("Q")
                                                        && p.getPlateThickFrom().compareTo(GCG.getLtInfoGPreOrder().get(0).getThk()) <= 0
                                                        && p.getPlateThickTo().compareTo(GCG.getLtInfoGPreOrder().get(0).getThk()) >= 0
                                                        && p.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth + maxAddWidth.orElse(0))) <= 0
                                                        && p.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth + maxAddWidth.orElse(0))) >= 0
                                                ).collect(Collectors.toList()).get(0).getThickAddv();
                                            } else {
                                                decThkAdd = plistPmThickAddvBtDO.stream().filter(p -> p.getMscLineNo().equals(SInfo.getMscLineNo())
                                                        && p.getTolTypeCode().equals(strThkTolType)
                                                        && p.getWholeHeatTreatmentType().equals("*")
                                                        && p.getPlateThickFrom().compareTo(GCG.getLtInfoGPreOrder().get(0).getThk()) <= 0
                                                        && p.getPlateThickTo().compareTo(GCG.getLtInfoGPreOrder().get(0).getThk()) >= 0
                                                        && p.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth + maxAddWidth.orElse(0))) <= 0
                                                        && p.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth + maxAddWidth.orElse(0))) >= 0
                                                ).collect(Collectors.toList()).get(0).getThickAddv();
                                            }

                                        }

                                        //厚度追加值
                                        GCG.setThk_Add(decThkAdd);

                                        //轧制厚度   厚度+厚度公差下限最大值+厚度追加值  订单厚度+厚度追加值
                                        BigDecimal decThk = e.getOrder_Thk().add(maxTolThkMin.orElse(BigDecimal.ZERO)).add(decThkAdd);

                                        //轧制宽度   最大宽度+宽度余量
                                        int intWid = maxWidth + maxAddWidth.orElse(0);

                                        //切边
                                        int intTrimWid = 0;

                                        String strWithSideFlag = "C";
                                        if (GCG.getLtInfoGPreOrder().get(0).getInfoPmProContProdAttrDO().getProdAMark() == null
                                                || GCG.getLtInfoGPreOrder().get(0).getInfoPmProContProdAttrDO().getProdAMark().equals("")) {
                                            strWithSideFlag = "C";
                                        } else {
                                            strWithSideFlag = GCG.getLtInfoGPreOrder().get(0).getInfoPmProContProdAttrDO().getProdAMark();
                                        }
                                        //切边量
                                        String finalStrWithSideFlag = strWithSideFlag;
                                        if (plistPmPlateTrimBtDO.stream().anyMatch(p -> p.getMscLineNo().equals(SInfo.getMscLineNo())
                                                && p.getPlateThickFrom().compareTo(decThk) <= 0
                                                && p.getPlateThickTo().compareTo(decThk) >= 0
                                                && p.getSmallPlateLenFrom().compareTo(BigDecimal.valueOf(GCG.getLtInfoGPreOrder().get(0).getLen())) <= 0
                                                && p.getSmallPlateLenTo().compareTo(BigDecimal.valueOf(GCG.getLtInfoGPreOrder().get(0).getLen())) >= 0
                                                && p.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth + maxAddWidth.orElse(0))) <= 0
                                                && p.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth + maxAddWidth.orElse(0))) >= 0
                                                && p.getWidenFrom().compareTo(decWidRate) <= 0
                                                && p.getWidenTo().compareTo(decWidRate) >= 0
                                                && p.getWithSideFlag().equals(finalStrWithSideFlag)
                                        )) {

                                            String finalStrWithSideFlag1 = strWithSideFlag;
                                            intTrimWid = plistPmPlateTrimBtDO.stream().filter(p -> p.getMscLineNo().equals(SInfo.getMscLineNo())
                                                    && p.getPlateThickFrom().compareTo(decThk) <= 0
                                                    && p.getPlateThickTo().compareTo(decThk) >= 0
                                                    && p.getSmallPlateLenFrom().compareTo(BigDecimal.valueOf(GCG.getLtInfoGPreOrder().get(0).getLen())) <= 0
                                                    && p.getSmallPlateLenTo().compareTo(BigDecimal.valueOf(GCG.getLtInfoGPreOrder().get(0).getLen())) >= 0
                                                    && p.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth + maxAddWidth.orElse(0))) <= 0
                                                    && p.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth + maxAddWidth.orElse(0))) >= 0
                                                    && p.getWidenFrom().compareTo(decWidRate) <= 0
                                                    && p.getWidenTo().compareTo(decWidRate) >= 0
                                                    && p.getWithSideFlag().equals(finalStrWithSideFlag1)
                                            ).collect(Collectors.toList()).get(0).getTrimWidth().intValue();
                                        }

                                        //轧制宽度= 最大宽度 + 最大宽度余量 + 切边量
                                        intWid = intWid + intTrimWid;

                                        if (intWid >= 4999) {
                                            return;
                                        }

                                        //宽度
                                        GCG.setWid(intWid);

                                        //厚度
                                        GCG.setThk(decThk);

                                        //切边
                                        GCG.setWid_Add(intTrimWid);

                                        //添加唯一ID
                                        GCG.setIDValue(intGrp2Num++);

                                        gltGCal2Grp.add(GCG);

                                    }
                                } catch (Exception ex) {
//                                    logger.info("分组处理报错：{}",ex);
//                                    logger.info("分组处理报错：{}",GPO1.getOrderNo());
//                                    logger.info("分组处理报错：{}",GPO2.getOrderNo());
//
//                                    gltGCal2Grp.forEach(n -> {
//                                        if (n.getLtInfoGPreOrder().size() > 0) {
////                                            logger.info(n.getIDValue().toString());
//                                            n.getLtInfoGPreOrder().forEach(g -> {
//                                                logger.info(n.getIDValue()+ "--" + g.getOrderNo());
//                                            });
//                                        }
//                                    });

                                }

                            });


                        });

                    }
                });
            });
        }

    }

    /**
     * 验证是否需要验证化学和低倍
     * @param organizationId
     */
    public void chkChmAndLowApi(Long organizationId, SlabInfoDO p) {
//        plistSlab.forEach(p -> {

        try {
            List<List<QdMatchParamDTO>> listOfDtoLists = new ArrayList<>();
            List<QdMatchParamDTO> dtoListChm = new ArrayList<QdMatchParamDTO>();
            for (PmProCont gpo : plistOrder) {

                if (gpo.getOrderNo() == null || gpo.getOrderNo().equals("")) {

                }

                //验证过不需要再验证
                if (plistChmChkRsult.stream().anyMatch(dto -> dto.getOrderNo().equals(gpo.getOrderNo()) && dto.getPono().equals(p.getPono()))) {
                    continue;
                }
                QdMatchParamDTO phyFurnaceChemicalMatchDTO = new QdMatchParamDTO();
                phyFurnaceChemicalMatchDTO.setOrderNo(gpo.getOrderNo());
                phyFurnaceChemicalMatchDTO.setPono(p.getPono());
                dtoListChm.add(phyFurnaceChemicalMatchDTO);
                if (dtoListChm.size() == 500) {
                    listOfDtoLists.add(new ArrayList<>(dtoListChm));
                    dtoListChm.clear();
                }
            }

            // 如果 dtoListChm 中还有剩余的元素，将其添加到 listOfDtoLists 中
            if (!dtoListChm.isEmpty()) {
                listOfDtoLists.add(new ArrayList<>(dtoListChm));
            }

            listOfDtoLists.forEach(dtoList -> {

                List<QdMatchParamDTO> reslutChm = qdOrderClient.phyFurnaceChemicalMatchApi(organizationId,
                        dtoList);
                if (reslutChm != null && !reslutChm.isEmpty()) {
                    if (reslutChm != null && !reslutChm.isEmpty()) {
                        for (QdMatchParamDTO qdMatchParamDTO : reslutChm) {
                            if (!plistChmChkRsult.stream().anyMatch(m -> m.getPono().equals(p.getPono()) && m.getOrderNo().equals(qdMatchParamDTO.getOrderNo()))) {
                                ChkChmResult CR = new ChkChmResult();
                                CR.setPono(p.getPono());
                                CR.setOrderNo(qdMatchParamDTO.getOrderNo());
                                CR.setChmresult(qdMatchParamDTO.getResult());
                                plistChmChkRsult.add(CR);
                            }
                        }
                    }
                }

            });

        } catch (Exception e) {
            logger.info("错误信息：" + e);
        }

        try {
            List<List<QdSurplusLowMagnificationDTO>> listOfDtoLists = new ArrayList<>();
            List<QdSurplusLowMagnificationDTO> dtoListLow = new ArrayList<QdSurplusLowMagnificationDTO>();
            for (PmProCont gpo : plistOrder) {
                if (gpo.getOrderNo() == null || gpo.getOrderNo().equals("")) {
                    continue;
                }
                //验证过不需要再验证
                if (plistLowChkRsult.stream().anyMatch(dto -> dto.getOrderNo().equals(gpo.getOrderNo()) && dto.getPono().equals(p.getPono()))) {
                    continue;
                }
                QdSurplusLowMagnificationDTO phyFurnaceChemicalMatchDTO = new QdSurplusLowMagnificationDTO();
                phyFurnaceChemicalMatchDTO.setOrderNo(gpo.getOrderNo());
                phyFurnaceChemicalMatchDTO.setPono(p.getPono());
                dtoListLow.add(phyFurnaceChemicalMatchDTO);
                if (dtoListLow.size() == 500) {
                    listOfDtoLists.add(new ArrayList<>(dtoListLow));
                    dtoListLow.clear();
                }
            }
            // 如果 dtoListChm 中还有剩余的元素，将其添加到 listOfDtoLists 中
            if (!dtoListLow.isEmpty()) {
                listOfDtoLists.add(new ArrayList<>(dtoListLow));
            }

            listOfDtoLists.forEach(dtoList -> {
                List<QdSurplusLowMagnificationDTO> reslutLow = qdOrderClient.surplusLowMagnificationMatchApi(organizationId,
                        dtoList);

                if (reslutLow != null && !reslutLow.isEmpty()) {
                    if (reslutLow != null && !reslutLow.isEmpty()) {
                        for (QdSurplusLowMagnificationDTO qdSurplusLowMagnificationDTO : reslutLow) {
                            if (!plistLowChkRsult.stream().anyMatch(m -> m.getPono().equals(p.getPono()) && m.getOrderNo().equals(qdSurplusLowMagnificationDTO.getOrderNo()))) {
                                ChkLowResult CR = new ChkLowResult();
                                CR.setPono(p.getPono());
                                CR.setOrderNo(qdSurplusLowMagnificationDTO.getOrderNo());
                                CR.setLowresult(qdSurplusLowMagnificationDTO.getResult());
                                plistLowChkRsult.add(CR);
                            }
                        }
                    }
                }
            });

        } catch (Exception e) {
            logger.info("错误信息：" + e);
        }

//        });
    }


    //region  验证方法

    /**
     * 化学成分判断
     */
    public boolean ChkChemical(SlabInfoDO SInfo, GPreOrder GrpOrd) {

        //        - 炉次工序成分代表实绩表QE_TQ_HEATCHE_STAND_RESULT      =>  制造命令号PONO
        //        - 合同处理成分结果数据表QD_TO_LINEUP_RESULT_CHE  =>合同号+成分类型CHE_TYPE=RX

        //炉次化学成分

        if (!plistQeTqHeatcheStandResultDO.stream().anyMatch(p -> p.getPono().equals(SInfo.getPono()))) {
            //ltQthsr=plistQeTqHeatcheStandResultDO.stream().filter(p->p.getPono().equals(SInfo.getPono())).collect(Collectors.toList());
            return false;
        }

        //订单要求化学成分
        // logger.info("化学成分订单号：" + GrpOrd.getOrderNo());
        List<QdToLineupResultCheDO> ltLrc = new ArrayList<>();
        int intOrd = plistQdToLineupResultCheDO.stream().filter(p -> p.getOrderNo().equals(null)).collect(Collectors.toList()).size();
        int intRX = plistQdToLineupResultCheDO.stream().filter(p -> p.getCheType().equals(null)).collect(Collectors.toList()).size();
        if (intOrd > 0 || intRX > 0) {
            logger.info("*************************化学成分订单号：{}-{}-{}", GrpOrd.getOrderNo(), intOrd, intRX);
        }
        if (plistQdToLineupResultCheDO == null) {
            logger.info("*************************化学成分订单号：{}-{}-{}", GrpOrd.getOrderNo(), intOrd, intRX);
        }
        if (plistQdToLineupResultCheDO.stream().anyMatch(p -> p.getOrderNo().equals(GrpOrd.getOrderNo()) && p.getCheType().equals("RX"))) {
            ltLrc = plistQdToLineupResultCheDO.stream().filter(p -> p.getOrderNo().equals(GrpOrd.getOrderNo()) && p.getCheType().equals("RX")).collect(Collectors.toList());
        }

        //信息不存在返回  TODO:订单信息不存在，化学成分验证成功
        if (ltLrc.size() == 0) {
            return true;
        }

        List<QeTqHeatcheStandResultDO> ltQthsr = plistQeTqHeatcheStandResultDO.stream().filter(p -> p.getPono().equals(SInfo.getPono())).collect(Collectors.toList());

        try {
            //判断合同的每个化学成分是否满足条件
            boolean blnChk = ltLrc.stream().anyMatch(p -> {
                if (!ltQthsr.stream().anyMatch(e -> e.getElm().equals(p.getElm())
                        && (e.getTestOriginalResult().compareTo(NumberUtils.createBigDecimal(p.getElmMin())) >= 0
                        && e.getTestOriginalResult().compareTo(NumberUtils.createBigDecimal(p.getElmMax())) <= 0))) {
                    return false;
                }
                return true;
            });

            if (!blnChk) {
                return false;
            }
        }catch (Exception ex)
        {
            return false;
        }

        return true;
    }

    /**
     * 低倍检测
     */
    public boolean ChkLowPower(SlabInfoDO SInfo, GPreOrder GrpOrd) {

        // - 委托  QE_TQ_PONO_WAIT_TEST => 制造命令号PONO
        // - 坯料低倍委托实绩表QE_TQ_SLAB_MACRO_RESULT => 制造命令号PONO
        // - 合同处理坯料性能要求表QD_TO_LINEUP_RESULT_SLABPHY = > 合同号

        //  1、先通过制造命令号PONO查询QE_TQ_PONO_WAIT_TEST是否存在委托原因(该字段为多选字段内容)TEST_REASON=1的数据
        //    ，如未查询出数据则RESULT=1，如存在则通过制造命令号PONO抓取坯料低倍委托实绩表QE_TQ_SLAB_MACRO_RESULT
        //    ，获取实绩低倍数据，遍历合同号，再通过合同号查询合同处理坯料性能要求表QD_TO_LINEUP_RESULT_SLABPHY，获取该合同下低倍数据。
        //  2、对查出的数据进行对比，例如：合同中心偏析A字段等于1表示有要求，如中心偏析A实绩无数据则合同校验结果为不合格
        //    ，如对应实绩有数据则判断合同中心偏析A上限字段是否大于中心偏析A实绩，如大于则这个合同中心偏析A子项目合格
        //    ，如小于则合同校验结果为不合格，如合同中心偏析A字段等于0表示无要求，则不进行判断，依次判断到等轴晶率
        //    ，判断到合同其他缺陷A时需要特殊处理，如其他缺陷A等于1，之后拿合同其他缺陷A类型字段与实绩的其他缺陷A、B、C、D、E进行对比
        //    ，判断是否有相同的值，如无则合同校验结果为不合格，有则拿对应的其他缺陷A、B、C、D、E实绩与合同其他缺陷A上限进行比较
        //    ，如合同其他缺陷A上限大于其他缺陷A、B、C、D、E实绩，则这个合同其他缺陷A子项目合格，如小于则合同校验结果为不合格
        //    ，依次判断合同其他缺陷A、B、C、D、E，判定到合同校验结果为不合格时可以终止此层的循环，记录对应数据
        //    ，进入下一个合同号的循环，合格的数据也需要记录。

        //低倍合同要求表
        List<QdToLineupResultSlabphyDO> ltQthsr = plistQdToLineupResultSlabphyDO.stream().filter(p -> p.getOrderNo().equals(GrpOrd.getOrderNo())).collect(Collectors.toList());

        //判断合同是否需要判断低倍
        if (ltQthsr.size() == 0) {
            return true;
        }

        //委托  是否存在委托
        if (!plistQeTqPonoWaitTestDO.stream().anyMatch(p -> p.getPono().equals(SInfo.getPono()) && p.getTestReason().equals("1"))) {
            //ltQthsr=plistQeTqHeatcheStandResultDO.stream().filter(p->p.getPono().equals(SInfo.getPono())).collect(Collectors.toList());
            return false;
        }

        //坯料低倍委托实绩表
        List<QeTqSlabMacroResultDO> ltSmr = new ArrayList<>();
        if (plistQeTqSlabMacroResultDO.stream().anyMatch(p -> p.getPono().equals(SInfo.getPono()))) {
            ltSmr = plistQeTqSlabMacroResultDO.stream().filter(p -> p.getPono().equals(SInfo.getPono())).collect(Collectors.toList());
        }

        //信息不存在返回
        if (ltSmr.size() == 0) {
            return false;
        }
        //实例一个新的结果数据
        List<QeTqSlabMacroResultDO> ltSmrReslt = ltSmr;

        //中心偏析A
        if (ltQthsr.stream().anyMatch(p -> p.getCenterSgrgA().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getCenterSgrgAResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getCenterSgrgAMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getCenterSgrgAResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }

        //        中心偏析B
        if (ltQthsr.stream().anyMatch(p -> p.getCenterSgrgB().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getCenterSgrgBResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getCenterSgrgBMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getCenterSgrgBResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        中心偏析C
        if (ltQthsr.stream().anyMatch(p -> p.getCenterSgrgC().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getCenterSgrgCResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getCenterSgrgCMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getCenterSgrgCResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        中心疏松
        if (ltQthsr.stream().anyMatch(p -> p.getCenterPorosity().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getCenterPorosityResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getCenterPorosityMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getCenterPorosityResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        白亮带
        if (ltQthsr.stream().anyMatch(p -> p.getWhiteBand().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getWhiteBandResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getWhiteBandMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getWhiteBandResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        中间裂纹
        if (ltQthsr.stream().anyMatch(p -> p.getCrackCenter().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getCrackCenterResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getCrackCenterMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getCrackCenterResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        三角区裂纹级别
        if (ltQthsr.stream().anyMatch(p -> p.getTriCrackGrade().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getTriCrackGradeResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getTriCrackGradeMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getTriCrackGradeResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        角裂级别
        if (ltQthsr.stream().anyMatch(p -> p.getAngleCrackGrade().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getAngleCrackGradeResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getAngleCrackGradeMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getAngleCrackGradeResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        三氧化二铝夹杂
        if (ltQthsr.stream().anyMatch(p -> p.getInclu().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getIncluResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getIncluMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getIncluResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        缩孔
        if (ltQthsr.stream().anyMatch(p -> p.getHore().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getHoreResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getHoreMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getHoreResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        蜂窝状气泡
        if (ltQthsr.stream().anyMatch(p -> p.getCellularBubble().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getCellularBubbleResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getCellularBubbleMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getCellularBubbleResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        等轴晶率
        if (ltQthsr.stream().anyMatch(p -> p.getWafer().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getWaferResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getWaferMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getWaferResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        其他缺陷A
        if (ltQthsr.stream().anyMatch(p -> p.getOtherDefectA().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getOtherDefectAResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getOtherDefectAMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getOtherDefectAResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        其他缺陷B
        if (ltQthsr.stream().anyMatch(p -> p.getOtherDefectB().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getOtherDefectBResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getOtherDefectBMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getOtherDefectBResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        其他缺陷C
        if (ltQthsr.stream().anyMatch(p -> p.getOtherDefectC().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getOtherDefectCResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getOtherDefectCMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getOtherDefectCResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        其他缺陷D
        if (ltQthsr.stream().anyMatch(p -> p.getOtherDefectD().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getOtherDefectDResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getOtherDefectDMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getOtherDefectDResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }
        //        其他缺陷E
        if (ltQthsr.stream().anyMatch(p -> p.getOtherDefectE().equals("1"))) {
            if (ltSmrReslt.stream().anyMatch(p -> {
                String result = p.getOtherDefectEResult();
                return result != null && !result.isEmpty();
            })) {
                if (!ltQthsr.stream().anyMatch(p -> {
                    String strReqMax = p.getOtherDefectEMax();
                    String strRslt = ltSmrReslt.stream().findFirst().map(e -> e.getOtherDefectEResult()).orElse("");
                    int num1 = Integer.parseInt(strReqMax);
                    int num2 = Integer.parseInt(strRslt);
                    //结果大于上限
                    if (num2 > num1) {
                        return false;
                    }
                    return true;
                })) {
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * 压缩比判断
     * <p>
     * 本方法用于检查给定的板坯信息和订单信息之间的压缩比是否满足要求
     * 压缩比是通过比较订单的厚度和板坯的实际厚度计算得出的
     *
     * @param SInfo  板坯信息对象，包含板坯的实际厚度等信息
     * @param GrpOrd 订单信息对象，包含订单的厚度和压缩比下限等信息
     * @return 如果压缩比满足要求，则返回true；否则返回false
     */
    public boolean ChkCompress(SlabInfoDO SInfo, GPreOrder GrpOrd) {
        try {
            //判断GGrpOrderFir的压缩比下限
            BigDecimal decCompressRate = new BigDecimal(0);

            //SInfo的厚度除以GrpOrd的厚度等于压缩比decCompressRate
            decCompressRate = SInfo.getSlabActThk().divide(GrpOrd.getThk(), 2, BigDecimal.ROUND_HALF_UP);

            if (nvl(GrpOrd.getInfoPmContMscTechDO().getSlabThkMin(), new BigDecimal(0)).compareTo(new BigDecimal(0))!=0 ) {
                if (decCompressRate.compareTo( nvl(GrpOrd.getInfoPmContMscTechDO().getSlabThkMin(), new BigDecimal(0))) < 0) {
                    return false;
                }
            }
            if (nvl(GrpOrd.getInfoPmContMscTechDO().getSlabThkMax(), new BigDecimal(0)).compareTo(new BigDecimal(0))!=0 ) {
                if (decCompressRate.compareTo( nvl(GrpOrd.getInfoPmContMscTechDO().getSlabThkMax(), new BigDecimal(0))) > 0) {
                    return false;
                }
            }

            return true;

        } catch (Exception e) {
            logger.error("压缩比验证出错", e);
            return false;
        }

    }

    /**
     * 宽展比判断
     */
    public boolean ChkWid(SlabInfoDO SInfo, GPreOrder GrpOrd) {

        try {
            //宽展比   保留2位小数
            BigDecimal decWidRate = BigDecimal.valueOf(GrpOrd.getWid()).divide(SInfo.getSlabActWid(), 2, RoundingMode.HALF_UP);

            if(nvl(GrpOrd.getInfoPmContMscTechDO().getWidenMin(),new BigDecimal(0)).compareTo(new BigDecimal(0))!=0){
                //展宽比小于最小值
                if (decWidRate.compareTo( nvl(GrpOrd.getInfoPmContMscTechDO().getWidenMin(),new BigDecimal(0))) < 0) {
                    return false;
                }
            }

            return true;
        } catch (Exception e) {
            logger.error("展宽比验证出错", e);
            return false;
        }
    }

    //endregion

    /**
     * 根据缺乏数量创建相应数量的订单对象，并设置其属性
     * 此方法是同步的，以确保在多线程环境中对gltOrder的线程安全访问
     *
     * @param prPmProContDO 主合同信息对象，包含订单的基本信息和缺乏数量
     * @param ppcpa         订单产品属性对象，包含订单产品的详细属性
     * @param pcmt          订单次要技术信息对象，包含订单的次要技术要求
     */
    public static synchronized void SetAllOrder(PmProCont prPmProContDO, PmProContProdTtr ppcpa, PmContMscTech pcmt,QdToPoOrder qtpo) {

        // 获取缺乏的数量
        BigDecimal lackNum =prPmProContDO.getPdTotQty().add(prPmProContDO.getPdLackQty());
        // 如果缺乏数量大于0，则根据缺乏数量创建相应数量的订单对象
        if (lackNum.intValue() > 0) {
            for (int i = 0; i < lackNum.intValue(); i++) {
                // 创建一个新的GPreOrder对象
                GPreOrder GPO = new GPreOrder();
                // 设置订单号，自增确保唯一性
                GPO.setIDValue(intOrdNum++);
                // 设置厚度
                GPO.setThk(ppcpa.getOrderThick());
                // 设置宽度
                GPO.setWid(ppcpa.getOrderWidth().intValue());
                // 设置宽度余量
                GPO.setWidthAddv(ppcpa.getWidthAddv().intValue());
                // 设置长度
                GPO.setLen(ppcpa.getOrderLen().intValue());
                // 设置厚度公差下限
                GPO.setThickTolMin(ppcpa.getThickTolMin());
                // 设置厚度公差上限
                GPO.setThickTolMax(ppcpa.getThickTolMax());
                // 设置订单号
                GPO.setOrderNo(prPmProContDO.getOrderNo());
                // 关联订单信息对象
                GPO.setInfoPmProContDo(prPmProContDO);
                // 关联订单产品属性对象
                GPO.setInfoPmProContProdAttrDO(ppcpa);
                // 关联订单次要技术信息对象
                GPO.setInfoPmContMscTechDO(pcmt);
                //合同
                GPO.setInfoQdToPoOrderDO(qtpo);
                //内部钢种
                GPO.setST_NO(pcmt.getStNo());
                //产线
                GPO.setLine(pcmt.getMscLineNo());

                // 将创建的订单对象添加到全局订单列表中
                gltOrder.add(GPO);
            }
        }
    }

    /**
     * 订单数据欠量处理
     */
    public void SetOrderLackData() {

        //TODO:箭头函数订单多线程处理数据，升序，降序，重组。
        //使用 Stream.parallel() 来并行执行 for 循环  OrderNo  升序   PdLackQty 降序
//        plistOrder.parallelStream()
//                .sorted(Comparator.comparing(PmProContDO::getOrderNo)
//                        .thenComparing(Comparator.comparing(PmProContDO::getPdLackQty).reversed()))
        plistOrder.parallelStream().forEach(i -> {
            PmProContProdTtr ppcpa = new PmProContProdTtr();

//            PmContMscTech pcmt = new PmContMscTech();

            QdToPoOrder  qtpo = new QdToPoOrder();
            try {

                //判断是否在不可组板订单范围内  plistpmIrsubableContDO 中存在就返回return
                if (plistpmIrsubableContDO.stream().filter(p -> p.getOrderNo().equals(i.getOrderNo())).count() > 0) {
                    logger.info("订单：{} 不可自动组板", i.getOrderNo());
                    return;
                }

                if (plistPmProContProdAttrDO.stream().filter(p -> p.getOrderNo().equals(i.getOrderNo())).count() > 0) {
                    ppcpa = plistPmProContProdAttrDO.stream().filter(p -> p.getOrderNo().equals(i.getOrderNo())).findFirst().orElseThrow(() -> new NoSuchElementException("No PmProContProdAttrDO found with name Charlie " + i.getOrderNo()));

                    //判断尺寸是否存在  宽度不在 plistpmAutoSubSettingDO的订单宽度范围内或者厚度不在plistpmAutoSubSettingDO的订单厚度范围内就return或者交货期不在plistpmAutoSubSettingDO的订单交货期范围内就return
                    PmProContProdTtr finalPpcpa = ppcpa;
                    if (plistpmAutoSubSettingDO.stream().filter(p ->
                            p.getOrderWidthMin().intValue() <= finalPpcpa.getOrderWidth().intValue()
                                    && finalPpcpa.getOrderWidth().intValue() <= p.getOrderWidthMax().intValue()
                                    && p.getOrderThickMin().intValue() <= finalPpcpa.getOrderThick().intValue()
                                    && finalPpcpa.getOrderThick().intValue() <= p.getOrderThickMax().intValue()
                                    && p.getDelivyDateFrom().compareTo(finalPpcpa.getDelivyDate()) <= 0
                                    && finalPpcpa.getDelivyDate().compareTo(p.getDelivyDateTo()) <= 0).count() <= 0) {
//                                logger.info("订单：{} 不可自动组板，尺寸厚度{},宽度{},交货期{} 不在范围内", i.getOrderNo(), finalPpcpa.getOrderThick(), finalPpcpa.getOrderWidth(), new SimpleDateFormat("yyyy-MM-dd").format(finalPpcpa.getDelivyDate()));
                        return;
                    }

                    if (plistQdToPoOrderDO.stream().anyMatch(e -> e.getOrderNo().equals(i.getOrderNo()))) {

                        qtpo = plistQdToPoOrderDO.stream().filter(e -> e.getOrderNo().equals(i.getOrderNo())).findFirst().orElseThrow(() -> new NoSuchElementException("No PmContMscTechDO found with name Charlie  " + i.getOrderNo()));
                        QdToPoOrder  finalqtpo = qtpo;
                        if (plistPmContMscTechDO.stream().filter(p -> p.getOrderNo().equals(i.getOrderNo())).count() > 0) {

                            plistPmContMscTechDO.stream().filter(p -> p.getOrderNo().equals(i.getOrderNo())).collect(Collectors.toList()).forEach( pcmt -> {

                                SetAllOrder(i, finalPpcpa, pcmt, finalqtpo);

                            });

                        }

                    } else {
//                                logger.info("缺少产线信息：" + i.getOrderNo());
                    }
                } else {
//                            logger.info("缺少属性信息：" + i.getOrderNo());
                }

            } catch (Exception ex1) {
                System.out.println("错误信息：" + ex1.getMessage());
            }
        });

        //        //排序后产生新的List
        //      List<PmProContDO>  ltNewProContDO =   plistOrder.parallelStream()
        //                .sorted(Comparator.comparing(PmProContDO ::getOrderNo)
        //                        .thenComparing(Comparator.comparing(PmProContDO::getPdLackQty).reversed()))
        //                .collect(Collectors.toList());

        System.out.println("订单欠量数：" + gltOrder.size());
    }

    /**
     * 根据尺寸和钢种对订单进行初次分组
     * 该方法通过并行流处理订单列表，根据订单的宽度、厚度和钢种标准进行分组
     * 分组结果存储在gltGrpOrderFir列表中，每个分组内的订单共享相同的尺寸和钢种特性
     */
    public void SetGroupOrderFir() {

        //region 多线程  数据流处理订单分组

        gltOrder.forEach(p -> {

            // 检查当前订单是否与已有的分组匹配
            if (gltGrpOrderFir.stream().anyMatch(e -> e.getWid().equals(p.getInfoPmProContProdAttrDO().getOrderWidth()) &&
                    e.getThk().equals(p.getInfoPmProContProdAttrDO().getOrderThick()) &&
                    e.getST_NO().equals(p.getInfoPmContMscTechDO().getStNo()) &&
                    e.getLine().equals(p.getInfoPmContMscTechDO().getMscLineNo()))) {

                // 如果匹配成功，将订单添加到相应的分组中
                GGrpOrderFir GGOF = gltGrpOrderFir.stream().filter(e -> e.getWid().equals(p.getInfoPmProContProdAttrDO().getOrderWidth())
                        && e.getThk().equals(p.getInfoPmProContProdAttrDO().getOrderThick())
                        && e.getST_NO().equals(p.getInfoPmContMscTechDO().getStNo())&&
                        e.getLine().equals(p.getInfoPmContMscTechDO().getMscLineNo())
                ).findFirst().orElse(null);
                if (GGOF.getLtInfoGPreOrder() == null) {
                    GGOF.setLtInfoGPreOrder(new ArrayList<>());  // 确保列表已初始化
                }
                GGOF.getLtInfoGPreOrder().add(p);

            } else {

                // 如果没有匹配的分组，创建一个新的分组并添加该订单
                GGrpOrderFir GGOF = new GGrpOrderFir();
                GGOF.setIDValue(intGrpNum++);
                GGOF.setWid(p.getInfoPmProContProdAttrDO().getOrderWidth());
                GGOF.setThk(p.getInfoPmProContProdAttrDO().getOrderThick());
                //GGOF.setLen(p.getInfoPmProContProdAttrDO().getOrderLen());
                GGOF.setSG_STD(p.getInfoPmProContProdAttrDO().getSgStd());
                GGOF.setST_NO(p.getInfoPmContMscTechDO().getStNo());
                GGOF.setLine(p.getInfoPmContMscTechDO().getMscLineNo());
                GGOF.setLtInfoGPreOrder(new ArrayList<>());  // 初始化列表
                GGOF.getLtInfoGPreOrder().add(p);
                gltGrpOrderFir.add(GGOF);
            }

        });

        //endregion

        // 输出初始分组数量
        logger.info("***初始分组数量：" + gltGrpOrderFir.size());

    }

    /**
     * 设置组计算结果
     * 根据提供的板坯信息和生产配置，计算出每个组的最大可轧制长度，并筛选出可行的订单组合
     *
     * @param SInfo 包含板坯实际长度、宽度、厚度等信息的SlabInfoDO对象
     */
    public void SetGroupCalRslt(SlabInfoDO SInfo) {

        //剩余长度小于加热炉最小长度
        if (SInfo.getRemLen().compareTo(BigDecimal.valueOf(2200)) < 0) {
            return;
        }

        //剩余宽度小于加热炉最小宽度
        if (SInfo.getRemWid().compareTo(BigDecimal.valueOf(1200)) < 0) {
            return;
        }

        //轧机最大长度
        int intRollMaxLen = plistPmPdConstBtDO.stream().filter(p -> p.getRollLineNo().equals("30")).findFirst().orElse(null).getHpmMaxPLen().intValue();
        //轧机最小长度
        int intRollMinLen = plistPmPdConstBtDO.stream().filter(p -> p.getRollLineNo().equals("30")).findFirst().orElse(null).getHpmMinPLen().intValue();

        //初始化分组数据
        gltGGrpCalRslt = new CopyOnWriteArrayList<>();

        //原始分组
        gltGCalGrp.parallelStream().forEach(e -> {
            try {
                //实例化计算结果数组
                GGrpCalRslt GGCR = new GGrpCalRslt();
                //可轧制最大长度
                int intMaxLen = 0;
                //轧制最大宽度
                int intWid = e.getWid();
                //轧制最大厚度
                BigDecimal intThk = e.getThk();
                //板坯长度
                int intSlabLen = SInfo.getRemLen().intValue();

                //判断可轧制最大长度 TODO：厚度计算Decimal取整计算，会有误差，后续判断误差值修正计算
                if ((SInfo.getRemLen().multiply(SInfo.getSlabActThk()).multiply(SInfo.getRemWid()).divide(intThk.multiply(BigDecimal.valueOf(intWid)), RoundingMode.HALF_UP)).compareTo(BigDecimal.valueOf(intRollMaxLen)) > 0) {
                    intMaxLen = intRollMaxLen;
                } else {
                    //①	氧化铁皮损失率取固定值：0.01；
                    intMaxLen = (SInfo.getRemLen().multiply(BigDecimal.valueOf(0.99)).multiply(SInfo.getSlabActThk()).multiply(SInfo.getRemWid()).divide(intThk.multiply(BigDecimal.valueOf(intWid)), RoundingMode.HALF_UP)).intValue();
                }

                //不能小于可轧制的最小长度
                if (intMaxLen < intRollMinLen) {
                    return;
                }
                //轧制宽度
                GGCR.setCal_Wid(intWid);
                //轧制厚度
                GGCR.setCal_Thk(intThk);
                //订单厚度
                GGCR.setThk(e.getLtInfoGPreOrder().get(0).getThk());
                //最大长度
                GGCR.setCal_Len(intMaxLen);
                GGCR.setLtInfoGPreOrder(e.getLtInfoGPreOrder());
                gltGGrpCalRslt.add(GGCR);
            } catch (Exception ex) {
                logger.info("***计算结果异常：" + ex.getMessage());
            }
        });

//        //临时交叉分组集合
//        List<GCalGrp> ltTempGrp = new CopyOnWriteArrayList<>();

        //临时分组数据
        List<GGrpCalRslt>  ltTempGrp = new CopyOnWriteArrayList<>();

        //交叉分组 .parallelStream() .parallelStream()
        gltGCalGrp.parallelStream().forEach(e -> {

            gltGCalGrp.forEach(f -> {

                try {
                    //排己
                    if(e.getIDValue()==f.getIDValue())
                    {
                        return;
                    }

//                    logger.info("***交叉分组ID：" + e.getIDValue() + "--" + f.getIDValue());
//                    logger.info("***交叉分组Wid：" + e.getWid() + "--" + f.getWid());
                    //e和f的宽度差绝对值小于500，宽度合小于4980，厚度相同
                    if (Math.abs(e.getWid() - f.getWid()) <200
                            && Math.max(e.getWid(),f.getWid())  < 4900
                            && e.getThk().compareTo(f.getThk()) == 0
                            && e.getST_NO().equals(f.getST_NO())
                    ) {

                        //实例化计算结果数组
                        GCalGrp GCP1=e;

                        //实例化计算结果数组
                        GCalGrp GCP2=f;

                        //实例化计算结果数组
                        GGrpCalRslt GGCR = new GGrpCalRslt();
                        //可轧制最大长度
                        int intMaxLen = 0;
                        //轧制最大宽度
                        int intWid = e.getWid()+f.getWid();
                        //轧制最大厚度
                        BigDecimal intThk = e.getThk();
                        //板坯长度
                        int intSlabLen = SInfo.getRemLen().intValue();

                        //判断可轧制最大长度 TODO：厚度计算Decimal取整计算，会有误差，后续判断误差值修正计算
                        if ((SInfo.getRemLen().multiply(SInfo.getSlabActThk()).multiply(SInfo.getRemWid()).divide(intThk.multiply(BigDecimal.valueOf(intWid)), RoundingMode.HALF_UP)).compareTo(BigDecimal.valueOf(intRollMaxLen)) > 0) {
                            intMaxLen = intRollMaxLen;
                        } else {
                            //①	氧化铁皮损失率取固定值：0.01；
                            intMaxLen = (SInfo.getRemLen().multiply(BigDecimal.valueOf(0.99)).multiply(SInfo.getSlabActThk()).multiply(SInfo.getRemWid()).divide(intThk.multiply(BigDecimal.valueOf(intWid)), RoundingMode.HALF_UP)).intValue();
                        }

                        //不能小于可轧制的最小长度
                        if (intMaxLen < intRollMinLen) {
                            return;
                        }
                        //轧制宽度
                        GGCR.setCal_Wid(intWid);
                        //轧制厚度
                        GGCR.setCal_Thk(intThk);
                        //订单厚度
                        GGCR.setThk(e.getLtInfoGPreOrder().get(0).getThk());
                        //最大长度
                        GGCR.setCal_Len(intMaxLen);

                        // 合并 e 和 f 的 LtInfoGPreOrder 列表
                        CopyOnWriteArrayList<GPreOrder> combinedList = new CopyOnWriteArrayList<>(e.getLtInfoGPreOrder());
                        combinedList.addAll(f.getLtInfoGPreOrder());

                        // 设置合并后的列表到 GGCR
                        GGCR.setLtInfoGPreOrder(combinedList);
//
//                        //合并订单信息
//                        GGCR.setLtInfoGPreOrder(e.getLtInfoGPreOrder()   (f.getLtInfoGPreOrder()));
//                        //合并订单信息
//                        GGCR.getLtInfoGPreOrder().addAll();

                        ltTempGrp.add(GGCR);

                    }


                } catch (Exception ex) {
                    logger.info("***计算结果异常：" + ex.getMessage());
                }

            });

        });

        gltGGrpCalRslt.addAll(ltTempGrp);

        if (gltGGrpCalRslt.size() == 0) {
            return;
        }
        //分组计算
        //gltGGrpCalRslt.parallelStream().forEach(p -> {
        gltGGrpCalRslt.parallelStream().forEach(p -> {
            try {
                // 测试数据
                //处理数据多处理
                List<Integer> ltValues = new ArrayList<>();
                List<Integer> ltweights = new ArrayList<>();
                List<String> ltOrder = new ArrayList<>();

                //logger.info( "订单总数量：" + p.getLtInfoGPreOrder().size());
                if (p == null) {
                    return;
                }
                if (p.getLtInfoGPreOrder() == null) {
                    return;
                }
                //计算可处理数据最大值
                p.getLtInfoGPreOrder().forEach(e -> {

                    int intOrdCount = p.getCal_Len() / e.getLen();

                    if (ltOrder.stream().filter(f -> f.equals(e.getOrderNo())).count() == intOrdCount) {
                        return;
                    }

                    //被使用过的订单ID排除在外
                    if (plistOrdHis.stream().filter(f -> f.getIDValue() == e.getIDValue()).count() > 0) {
                        return;
                    }

                    //测试代码
                    if (e.getOrderNo()=="52500096071" )
                    {

                    }
                    ltOrder.add(e.getOrderNo());//添加订单号
                    ltValues.add(e.getIDValue());//价值
                    ltweights.add(e.getLen());//长度
                });

                // 生成 values 和 weights 数组
                long[] values = new long[ltValues.size()];
                long[][] weights = new long[1][ltweights.size()];

                for (int i = 0; i < ltValues.size(); i++) {
                    values[i] = ltValues.get(i);       // 从订单中获取 value
                    weights[0][i] = ltweights.get(i) + 5;   // 从订单中获取 weights
                }

                //是否展宽
                //String brnNeed="";
                //if (p.getCal_Wid()>SInfo.getSlabActWid().intValue()){
                //    brnNeed="1";//展宽
                //}else {
                //    brnNeed="0";//不展宽
                //}

                //TODO：轧制方向，轧制模式 没有其他值暂不考虑，之后数据完善后需要考虑
                PmPlateCutLenBt PPCLB = plistPmPlateCutLenBtDO.stream().
                        filter(f -> f.getMscLineNo().equals(SInfo.getMscLineNo())
                                && f.getBrrNeed().equals((p.getCal_Wid() > SInfo.getRemWid().intValue()) ? "1" : "0")
                                && f.getPlateThickFrom().compareTo(p.getCal_Thk()) <= 0
                                && f.getPlateThickTo().compareTo(p.getCal_Thk()) >= 0
                                && f.getSlabThickFrom().compareTo(SInfo.getSlabActThk()) <= 0
                                && f.getSlabThickTo().compareTo(SInfo.getSlabActThk()) >= 0
                                && f.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(p.getCal_Wid())) <= 0
                                && f.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(p.getCal_Wid())) >= 0
                        ).findFirst().orElse(null);

                if (PPCLB == null) {
                    return;
                }

                //切缝长度
                int intPlateCutWidth = PPCLB.getPlateCutWidth().intValue();

                //切头
                int intHead = PPCLB.getHeadCut().intValue();
                //切尾
                int intTail = PPCLB.getTailCut().intValue();

                //去掉切头尾长度  300为预留式样长度
                int intCap = p.getCal_Len() - intHead - intTail-300;

                long[] capacities = {intCap};

                //初始化方案
                Loader.loadNativeLibraries();

                //logger.info("values  Size:{}", p.getLtInfoGPreOrder().size());
                //for (int i = 0; i < ltweights.size(); i++) {
                //
                //    logger.info("weights:{}", ltweights.get(i));
                //
                //}

                // 调用 solve 方法来解决问题
                ArrayList<Long> ltInt = solve(values, weights, capacities);

                //实例化实际订单号
                p.setLtActInfoGPreOrder(new ArrayList<>());
                //循环返回的订单插入到实际数组中
                for (int i = 0; i < ltInt.size(); i++) {
                    int indexi = i;
                    p.getLtActInfoGPreOrder().add(p.getLtInfoGPreOrder().stream().filter(m -> m.getIDValue() == ltInt.get(indexi)).collect(Collectors.toList()).get(0));
                }

                //根据实际订单再计算
                //

                if (p.getLtActInfoGPreOrder().size() == 0) {
                    return;
                }

                //最大宽度
                OptionalInt maxWidth = p.getLtActInfoGPreOrder().stream()
                        .mapToInt(GPreOrder::getWid)
                        .max();
                //最大宽度余量
                OptionalInt maxAddWidth = p.getLtActInfoGPreOrder().stream()
                        .mapToInt(GPreOrder::getWidthAddv)
                        .max();

                //宽展比   保留2位小数
                BigDecimal decWidRate = BigDecimal.valueOf(maxWidth.orElse(0)).divide(SInfo.getRemWid(), 2, RoundingMode.HALF_UP);

                //最大厚度公差最小值
                Optional<BigDecimal> maxTolThkMin = p.getLtActInfoGPreOrder().stream()
                        .map(GPreOrder::getThickTolMin)
                        .reduce(BigDecimal::max);

                //厚度追加值
                BigDecimal decThkAdd= BigDecimal.ZERO;

                String strThkTolType;
                if (p.getLtInfoGPreOrder().get(0).getInfoQdToPoOrderDO().getThkTolType() != null) {
                    strThkTolType = p.getLtInfoGPreOrder().get(0).getInfoQdToPoOrderDO().getThkTolType();
                } else {
                    strThkTolType = "*";
                }

                //存在数据，判断热处理模式
                if (plistPmThickAddvBtDO.stream().anyMatch(e -> e.getMscLineNo().equals(SInfo.getMscLineNo())
                                && e.getTolTypeCode().equals(strThkTolType)
//                        && e.getTolTypeCode().equals(p.getLtInfoGPreOrder().get(0).getInfoQdToPoOrderDO().getThkTolType())
                                && e.getPlateThickFrom().compareTo(p.getLtInfoGPreOrder().get(0).getThk()) <= 0
                                && e.getPlateThickTo().compareTo(p.getLtInfoGPreOrder().get(0).getThk()) >= 0
                                && e.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) <= 0
                                && e.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) >= 0
                )) {
                    if (p.getLtInfoGPreOrder().get(0).getInfoPmContMscTechDO().getWholeHeatTreatmentType()!=null &&
                            p.getLtInfoGPreOrder().get(0).getInfoPmContMscTechDO().getWholeHeatTreatmentType().contains("Q")) {
                        decThkAdd = plistPmThickAddvBtDO.stream().filter(e -> e.getMscLineNo().equals(SInfo.getMscLineNo())
                                        && e.getTolTypeCode().equals(strThkTolType)
//                                && e.getTolTypeCode().equals(p.getLtInfoGPreOrder().get(0).getInfoQdToPoOrderDO().getThkTolType())
                                        && e.getWholeHeatTreatmentType().equals("Q")
                                        && e.getPlateThickFrom().compareTo(p.getLtInfoGPreOrder().get(0).getThk()) <= 0
                                        && e.getPlateThickTo().compareTo(p.getLtInfoGPreOrder().get(0).getThk()) >= 0
                                        && e.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) <= 0
                                        && e.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) >= 0
                        ).collect(Collectors.toList()).get(0).getThickAddv();
                    } else {
                        decThkAdd = plistPmThickAddvBtDO.stream().filter(e -> e.getMscLineNo().equals(SInfo.getMscLineNo())
                                        && e.getTolTypeCode().equals(strThkTolType)
//                                && e.getTolTypeCode().equals(p.getLtInfoGPreOrder().get(0).getInfoQdToPoOrderDO().getThkTolType())
                                        && e.getWholeHeatTreatmentType().equals("*")
                                        && e.getPlateThickFrom().compareTo(p.getLtInfoGPreOrder().get(0).getThk()) <= 0
                                        && e.getPlateThickTo().compareTo(p.getLtInfoGPreOrder().get(0).getThk()) >= 0
                                        && e.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) <= 0
                                        && e.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) >= 0
                        ).collect(Collectors.toList()).get(0).getThickAddv();
                    }

                }

                //轧制厚度   厚度+厚度公差下限最大值
                BigDecimal decThk = p.getThk().add(maxTolThkMin.orElse(BigDecimal.ZERO)).add(decThkAdd);

                //轧制宽度   最大宽度+宽度余量
                int intWid = maxWidth.orElse(0) + maxAddWidth.orElse(0);

                //切边
                int intTrimWid = 0;
                String strWithSideFlag = "C";
                if (p.getLtInfoGPreOrder().get(0).getInfoPmProContProdAttrDO().getProdAMark()==null
                        || p.getLtInfoGPreOrder().get(0).getInfoPmProContProdAttrDO().getProdAMark().equals(""))
                {
                    strWithSideFlag="C";
                }else{
                    strWithSideFlag=p.getLtInfoGPreOrder().get(0).getInfoPmProContProdAttrDO().getProdAMark();
                }
                //切边量
                String finalStrWithSideFlag = strWithSideFlag;
                //切边量
                if (plistPmPlateTrimBtDO.stream().anyMatch(f -> f.getMscLineNo().equals(SInfo.getMscLineNo())
                        && f.getPlateThickFrom().compareTo(decThk) <= 0
                        && f.getPlateThickTo().compareTo(decThk) >= 0
                        && f.getSmallPlateLenFrom().compareTo(BigDecimal.valueOf(p.getLtInfoGPreOrder().get(0).getLen())) <= 0
                        && f.getSmallPlateLenTo().compareTo(BigDecimal.valueOf(p.getLtInfoGPreOrder().get(0).getLen())) >= 0
                        && f.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) <= 0
                        && f.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) >= 0
                        && f.getWidenFrom().compareTo(decWidRate) <= 0
                        && f.getWidenTo().compareTo(decWidRate) >= 0
                        && f.getWithSideFlag().equals(finalStrWithSideFlag)
                )) {
                    intTrimWid = plistPmPlateTrimBtDO.stream().filter(f -> f.getMscLineNo().equals(SInfo.getMscLineNo())
                            && f.getPlateThickFrom().compareTo(decThk) <= 0
                            && f.getPlateThickTo().compareTo(decThk) >= 0
                            && f.getSmallPlateLenFrom().compareTo(BigDecimal.valueOf(p.getLtInfoGPreOrder().get(0).getLen())) <= 0
                            && f.getSmallPlateLenTo().compareTo(BigDecimal.valueOf(p.getLtInfoGPreOrder().get(0).getLen())) >= 0
                            && f.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) <= 0
                            && f.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(maxWidth.orElse(0) + maxAddWidth.orElse(0))) >= 0
                            && f.getWidenFrom().compareTo(decWidRate) <= 0
                            && f.getWidenTo().compareTo(decWidRate) >= 0
                            && f.getWithSideFlag().equals(finalStrWithSideFlag)
                    ).collect(Collectors.toList()).get(0).getTrimWidth().intValue();
                }
                //轧制宽度= 最大宽度 + 最大宽度余量 + 切边量
                intWid = intWid + intTrimWid;

                //厚度  获取p.getLtActInfoGPreOrder()中厚度公差最小值+厚度
                p.setCal_Thk(decThk);
                //宽度  获取p.getLtActInfoGPreOrder() 中宽度的最大值
                p.setCal_Wid(intWid);
                //宽度余量  获取p.getLtActInfoGPreOrder() 中宽度的最大值
                p.setWid_Add(maxAddWidth.orElse(0));
                //切边余量
                p.setTrimming(intTrimWid);
                //切缝
                p.setPlate_Cut_Wid(intPlateCutWidth);

                //订单合计长度+切缝   TODO：取样长度是否加入计算，后续再优化
                int intSumOrderLen = p.getLtActInfoGPreOrder().stream().mapToInt(GPreOrder::getLen).sum();
                int intSumPlateCutWid = p.getLtActInfoGPreOrder().size() * intPlateCutWidth;
                p.setEff_Len(intSumOrderLen + intSumPlateCutWid);

                PmPlateCutLenBt PPCLB_Act = plistPmPlateCutLenBtDO.stream().
                        filter(f -> f.getMscLineNo().equals(SInfo.getMscLineNo())
                                && f.getBrrNeed().equals((p.getCal_Wid() > SInfo.getRemWid().intValue()) ? "1" : "0")
                                && f.getPlateThickFrom().compareTo(p.getCal_Thk()) <= 0
                                && f.getPlateThickTo().compareTo(p.getCal_Thk()) >= 0
                                && f.getSlabThickFrom().compareTo(SInfo.getSlabActThk()) <= 0
                                && f.getSlabThickTo().compareTo(SInfo.getSlabActThk()) >= 0
                                && f.getCombinePlateWidthFrom().compareTo(BigDecimal.valueOf(p.getCal_Wid())) <= 0
                                && f.getCombinePlateWidthTo().compareTo(BigDecimal.valueOf(p.getCal_Wid())) >= 0
                        ).findFirst().orElse(null);

                if (PPCLB_Act == null) {
                    return;
                }

                //订单最大切头
                int intOrdHeadMax= p.getLtActInfoGPreOrder().stream().mapToInt(GPreOrder::getCutHeadLen).max().orElse(0);
                //订单最大切尾
                int intOrdTailMax= p.getLtActInfoGPreOrder().stream().mapToInt(GPreOrder::getCutTailLen).max().orElse(0);

                //切头
                p.setHead_Len(PPCLB_Act.getHeadCut().intValue());
                //切尾
                p.setTail_Len(PPCLB_Act.getTailCut().intValue());
                //轧制长度
                p.setCal_Len((int) ((p.getEff_Len() + PPCLB_Act.getHeadCut().intValue() + PPCLB_Act.getTailCut().intValue()+intOrdHeadMax+intOrdTailMax)/0.99));
                //轧制长度
                p.setNeedCal_Len((int) ((p.getEff_Len() + PPCLB_Act.getHeadCut().intValue() + PPCLB_Act.getTailCut().intValue()+intOrdHeadMax+intOrdTailMax)/0.99));

                //板坯厚度
                p.setVirtualSlab_Thk(SInfo.getSlabActThk());
                //板坯宽度
                p.setVirtualSlab_Wid(SInfo.getRemWid().intValue());
                //板坯长度
                BigDecimal virtualSlabLen = p.getCal_Thk()
                        .multiply(BigDecimal.valueOf(p.getCal_Wid()))
                        .multiply(BigDecimal.valueOf(p.getCal_Len()))
                        .divide(SInfo.getSlabActThk().multiply(SInfo.getRemWid()), 0, RoundingMode.CEILING);
                p.setVirtualSlab_Len(virtualSlabLen.intValue());
                //板坯重量
                p.setVirtualSlab_Wgt(p.getVirtualSlab_Thk().multiply(BigDecimal.valueOf(p.getVirtualSlab_Len())).multiply(BigDecimal.valueOf(p.getVirtualSlab_Wid())).multiply(BigDecimal.valueOf(7.85)).divide(BigDecimal.valueOf(1000000000), 2, RoundingMode.HALF_UP));

                //需要板坯长度
                p.setNeedSlab_Len(virtualSlabLen.intValue());
                //需要板坯重量
                p.setNeedSlab_Wgt(p.getVirtualSlab_Thk().multiply(BigDecimal.valueOf(p.getVirtualSlab_Len())).multiply(BigDecimal.valueOf(p.getVirtualSlab_Wid())).multiply(BigDecimal.valueOf(7.85)).divide(BigDecimal.valueOf(1000000000), 2, RoundingMode.HALF_UP));

                //板坯可轧最大长度
                int intSlabMaxLen=(SInfo.getRemLen().multiply(SInfo.getSlabActThk()).multiply(SInfo.getRemWid()).divide(decThk.multiply(BigDecimal.valueOf(intWid)), RoundingMode.HALF_UP)).intValue();

                //TODO:补长判断
                //短坯料计算总长度小于轧线最大长度不切割
                if (intSlabMaxLen < intRollMaxLen) {

                    //板坯最大长度
                    p.setVirtualSlab_Len(SInfo.getRemLen().intValue());

                    //轧制长度
                    p.setCal_Len( SInfo.getSlabActThk()
                            .multiply(SInfo.getRemWid())
                            .multiply(SInfo.getRemLen())
                            .divide(decThk.multiply(BigDecimal.valueOf(intWid)), 0, RoundingMode.CEILING).intValue());

                    //板坯重量
                    p.setVirtualSlab_Wgt(p.getVirtualSlab_Thk().multiply(BigDecimal.valueOf(p.getVirtualSlab_Len())).multiply(BigDecimal.valueOf(p.getVirtualSlab_Wid())).multiply(BigDecimal.valueOf(7.85)).divide(BigDecimal.valueOf(1000000000), 2, RoundingMode.HALF_UP));

                }

                //成材率计算
                BigDecimal rolledVolume =new BigDecimal(0) ;
                // p.getCal_Thk()
                //         .multiply(BigDecimal.valueOf(p.getCal_Wid()))
                //         .multiply(BigDecimal.valueOf(p.getEff_Len()));
                for (int i = 0; i < p.getLtActInfoGPreOrder().size(); i++) {
                    rolledVolume=rolledVolume.add( BigDecimal.valueOf(p.getLtActInfoGPreOrder().get(i).getLen())
                            .multiply(p.getCal_Thk())
                            .multiply(BigDecimal.valueOf(p.getLtActInfoGPreOrder().get(i).getWid())));
                }



                BigDecimal slabVolume = SInfo.getSlabActThk()
                        .multiply(SInfo.getRemWid())
                        .multiply(BigDecimal.valueOf(p.getVirtualSlab_Len()));

                BigDecimal yieldRate = rolledVolume.divide(slabVolume, 4, RoundingMode.HALF_UP); // 保留4位小数

                // 设置成材率到 p 对象中
                p.setRate(yieldRate);
            } catch (Exception e) {
//                log.error("new1", e);
            }
        });
        logger.info("计算gltGGrpCalRslt:" + gltGGrpCalRslt.size());

        //判断结果数据是否存在
        if (gltGGrpCalRslt.size() == 0) {
            return;
        }
        //判断结算结果长度和成材率是否可用
        gltGGrpCalRslt.parallelStream().forEach(p -> {
            try {

                //没有成材率
                if (p.getRate() == null) {
                    p.setIntUseFlg(0);
                    return;
                }

                //TODO:成材率最小限制
//                //成材率大于90%
//                if (p.getRate().compareTo(BigDecimal.valueOf(0.7)) <= 0) {
//                    p.setIntUseFlg(0);
//                    return;
//                }

                int minWid = Math.min(p.getVirtualSlab_Wid(), p.getVirtualSlab_Len());
                int maxLen = Math.max(p.getVirtualSlab_Wid(), p.getVirtualSlab_Len());

                //	板坯厚度起止SLAB_THICK_FROM/TO包含余坯实际厚度;
                //	板坯宽度起止SLAB_WIDTH_FROM/TO包含余坯实际宽度;
                //	加热炉类型为‘C’，轧制产线号等于产线号后两位，连铸机类型等于1；
                if (plistPmSlabSpecBtDO.stream().filter(e -> e.getSlabThickFrom().compareTo(p.getVirtualSlab_Thk()) <= 0
                        && e.getSlabThickTo().compareTo(p.getVirtualSlab_Thk()) >= 0
                        && e.getSlabWidthFrom().compareTo(BigDecimal.valueOf(minWid)) <= 0
                        && e.getSlabWidthTo().compareTo(BigDecimal.valueOf(minWid)) >= 0
                        && e.getFurType().equals("C")
                        && e.getRollLineNo().equals(SInfo.getMscLineNo().substring(SInfo.getMscLineNo().length() - 2))
                        && e.getCcType().equals("1")
                ).count() > 0) {

                    int intSlanLenMin = plistPmSlabSpecBtDO.stream().filter(e -> e.getSlabThickFrom().compareTo(p.getVirtualSlab_Thk()) <= 0
                            && e.getSlabThickTo().compareTo(p.getVirtualSlab_Thk()) >= 0
                            && e.getSlabWidthFrom().compareTo(BigDecimal.valueOf(minWid)) <= 0
                            && e.getSlabWidthTo().compareTo(BigDecimal.valueOf(minWid)) >= 0
                            && e.getFurType().equals("C")
                            && e.getRollLineNo().equals(SInfo.getMscLineNo().substring(SInfo.getMscLineNo().length() - 2))
                            && e.getCcType().equals("1")
                    ).findFirst().orElse(null).getSlabMinLen().intValue();

                    int intSlanLenMax = plistPmSlabSpecBtDO.stream().filter(e -> e.getSlabThickFrom().compareTo(p.getVirtualSlab_Thk()) <= 0
                            && e.getSlabThickTo().compareTo(p.getVirtualSlab_Thk()) >= 0
                            && e.getSlabWidthFrom().compareTo(BigDecimal.valueOf(minWid)) <= 0
                            && e.getSlabWidthTo().compareTo(BigDecimal.valueOf(minWid)) >= 0
                            && e.getFurType().equals("C")
                            && e.getRollLineNo().equals(SInfo.getMscLineNo().substring(SInfo.getMscLineNo().length() - 2))
                            && e.getCcType().equals("1")
                    ).findFirst().orElse(null).getSlabMaxLen().intValue();

                    //不能小于最小值
                    if (maxLen <= intSlanLenMin) {
                        p.setIntUseFlg(0);
                        return;
                    }

                    //不能大于最大值
                    if (maxLen >= intSlanLenMax) {
                        p.setIntUseFlg(0);
                        return;
                    }

                } else {
                    //数据不可用
                    p.setIntUseFlg(0);
                    return;
                }

                //数据可用
                p.setIntUseFlg(1);
            } catch (Exception e) {
//                log.error("new2", e);
                return;
            }
        });

        //选择最优结果
        ChosBestRsl(SInfo);

        if(gltSelGGrpCalRslt.size()==0){
            return;
        }

        //递归
        SetGroupCalRslt(SInfo);

        //递归
        ////小于最小入炉尺寸
        //if (SInfo.getRemLen().intValue() <2200)
        //{
        //
        //}else{
        //    SetGroupCalRslt(SInfo);
        //}
    }

    public void ChosBestRsl(SlabInfoDO SInfo) {

        //gltGGrpCalRslt  的 getIntUseF

// 筛选 UseFlg == 1 的数据
        List<GGrpCalRslt> filteredList = gltGGrpCalRslt.stream()
                .filter(g -> Objects.nonNull(g)
                                && Objects.nonNull(g.getIntUseFlg())
                                && g.getIntUseFlg() == 1
//                        && g.getLtActInfoGPreOrder().stream().anyMatch(m->m.getCombinationFlag()==1)
//                        && g.getLtActInfoGPreOrder().stream().anyMatch(m->m.getCombinationFlag()==0)
                )
                .collect(Collectors.toList());

        // 找到重量最大成材率最大的数据
        Optional<GGrpCalRslt> maxWeightMaxYieldRate = filteredList.stream()
                .max(Comparator.comparing((GGrpCalRslt g) -> g.getVirtualSlab_Wgt())
                        .thenComparing(GGrpCalRslt::getRate)
                        .thenComparing(GGrpCalRslt::getVirtualSlab_Len));

        // 将筛选出的数据添加到 gltSelGGrpCalRslt 中
        maxWeightMaxYieldRate.ifPresent(gltSelGGrpCalRslt::add);

        if (maxWeightMaxYieldRate.isPresent()) {

            GGrpCalRslt maxRate = maxWeightMaxYieldRate.get();

            PmSubHis pmSubHisDO = new PmSubHis();
            pmSubHisDO.setSlabNo(SInfo.getSlabNo()); // 板坯号
            // 生成虚拟板坯号
            String virtualSlabNo = generateVirtualSlabNo(SInfo.getPono());
            pmSubHisDO.setVirtualSlabNo(virtualSlabNo); // 虚拟板坯号
            pmSubHisDO.setRelKey(virtualSlabNo); // 关系号

            maxWeightMaxYieldRate.get().setSlabNo(SInfo.getSlabNo());
            maxWeightMaxYieldRate.get().setVirtualSlabNo(virtualSlabNo);
            maxWeightMaxYieldRate.get().setRelKey(virtualSlabNo);

            // 手动为每个字段赋值
            pmSubHisDO.setSlabThick(maxRate.getVirtualSlab_Thk()); // 厚度
            pmSubHisDO.setSlabWid(BigDecimal.valueOf(maxRate.getVirtualSlab_Wid())); // 宽度
            pmSubHisDO.setSlabLen(BigDecimal.valueOf(maxRate.getVirtualSlab_Len())); // 长度
            pmSubHisDO.setSlabWt(maxRate.getVirtualSlab_Wgt()); // 重量
            pmSubHisDO.setSubYield(maxRate.getRate()); // 替代率
            pmSubHisDO.setRelYield(maxRate.getRate()); // 利用率，假设没有对应字段，设置为默认值
            pmSubHisDO.setSubResult(""); // 处理结果，假设没有对应字段，设置为默认值
            pmSubHisDO.setSubInfo(""); // 处理内容，假设没有对应字段，设置为默认值
            pmSubHisDO.setProcessCode(""); // 进程代码，假设没有对应字段，设置为默认值
            pmSubHisDO.setFormPlateMode(""); // 组板方式，假设没有对应字段，设置为默认值
            pmSubHisDO.setStNo(SInfo.getStNo()); // 内部钢种，假设没有对应字段，设置为默认值
            pmSubHisDO.setSubTime(new Date()); // 替代时间，假设没有对应字段，设置为当前时间
            pmSubHisDO.setCreationDate(new Date()); // 创建时间
            pmSubHisDO.setCreatedBy(781L); // 创建人ID，假设没有对应字段，设置为默认值
            pmSubHisDO.setLastUpdatedBy(781L); // 最近更新人ID，假设没有对应字段，设置为默认值
            pmSubHisDO.setLastUpdateDate(new Date()); // 最近更新时间
            //pmSubHisDO.setTenantId(BigDecimal.ZERO); // 租户ID，假设没有对应字段，设置为默认值
            //pmSubHisDO.setObjectVersionNumber(BigDecimal.ZERO); // 行版本号，用来处理锁，假设没有对应字段，设置为默认值
            pmSubHisDO.setAttribute1(""); // 假设没有对应字段，设置为默认值
            pmSubHisDO.setAttribute2(""); // 假设没有对应字段，设置为默认值
            pmSubHisDO.setAttribute3(""); // 假设没有对应字段，设置为默认值
            pmSubHisDO.setAttribute4(""); // 假设没有对应字段，设置为默认值
            pmSubHisDO.setAttribute5(""); // 假设没有对应字段，设置为默认值
            pmSubHisDO.setRollThk(maxRate.getCal_Thk()); // 轧件厚
            pmSubHisDO.setRollWid(BigDecimal.valueOf(maxRate.getCal_Wid())); // 轧件宽
            pmSubHisDO.setRollLen(BigDecimal.valueOf(maxRate.getCal_Len())); // 轧件长
            pmSubHisDO.setHeadCut(BigDecimal.valueOf(maxRate.getHead_Len())); // 头部切舍量
            pmSubHisDO.setTailCut(BigDecimal.valueOf(maxRate.getTail_Len())); // 尾部切舍量
            pmSubHisDO.setWidCut(BigDecimal.valueOf(maxRate.getTrimming())); // 切边宽度，假设没有对应字段，设置为默认值
            pmSubHisDO.setSlitLen(BigDecimal.valueOf(maxRate.getPlate_Cut_Wid())); // 切缝长度
            pmSubHisDO.setNeedSlabLen(BigDecimal.valueOf(maxRate.getVirtualSlab_Len())); // 必要板坯长度
            pmSubHisDO.setNeedSlabWt(maxRate.getVirtualSlab_Wgt()); // 必要板坯重量

            plistpmSubHisDO.add(pmSubHisDO);
            //子表信息
            // 使用 AtomicInteger 获取索引
            AtomicInteger index = new AtomicInteger(0);
            AtomicInteger intX = new AtomicInteger(maxRate.getHead_Len());
            boolean Firstflag = true;
            for(int m = 0; m < maxRate.getLtActInfoGPreOrder().size(); m++)
            {
                GPreOrder   gPreOrder=maxRate.getLtActInfoGPreOrder().get(m);
                if (gPreOrder.getCombinationFlag()==1)
                {

                    BigDecimal intY = BigDecimal.valueOf(0);
                    for (int i = 0; i < gPreOrder.getLtInfoCombGPreOrder().size(); i++) {
                        int currentIndex = index.getAndIncrement();

                        // 实例化 PmSubOrdDO 对象
                        PmSubOrd pmSubOrdDO = new PmSubOrd();

                        // 生成虚拟板坯号
                        pmSubOrdDO.setVirtualSlabNo(virtualSlabNo); // 虚拟板坯号
                        pmSubOrdDO.setRelKey(virtualSlabNo); // 关系号
                        pmSubOrdDO.setSlabNo(SInfo.getSlabNo()); // 板坯号

                        // 手动为每个字段赋值
                        pmSubOrdDO.setOrderNo(gPreOrder.getLtInfoCombGPreOrder().get(i).getInfoGPreOrder().getOrderNo()); // 合同号
                        pmSubOrdDO.setSgSign(gPreOrder.getLtInfoCombGPreOrder().get(i).getInfoGPreOrder().getInfoPmProContProdAttrDO().getSgSign()); // 牌号
                        pmSubOrdDO.setStNo(SInfo.getStNo()); // 内部钢种
                        pmSubOrdDO.setOrderThick(gPreOrder.getLtInfoCombGPreOrder().get(i).getInfoGPreOrder().getThk()); // 订货厚度
                        pmSubOrdDO.setOrderWidth(BigDecimal.valueOf(gPreOrder.getLtInfoCombGPreOrder().get(i).getInfoGPreOrder().getWid())); // 订货宽度
                        pmSubOrdDO.setLenAim(BigDecimal.valueOf(gPreOrder.getLtInfoCombGPreOrder().get(i).getInfoGPreOrder().getLen())); // 订货长度

                        pmSubOrdDO.setPosX(BigDecimal.valueOf(intX.intValue())); // X坐标，假设默认为0
                        //第一块
                        if (i == 0) {
                            intY = BigDecimal.valueOf(maxRate.getTrimming() + gPreOrder.getLtInfoCombGPreOrder().get(i).getInfoGPreOrder().getWidthAddv());
                            pmSubOrdDO.setPosY(intY); // Y坐标，假设默认为0
                            intY = intY.add(BigDecimal.valueOf(gPreOrder.getLtInfoCombGPreOrder().get(i).getInfoGPreOrder().getWid()));
                        } else {
                            pmSubOrdDO.setPosY(intY); // Y坐标，假设默认为0
                        }

                        pmSubOrdDO.setDelivyDate(new Date()); // 交货日期，假设默认为当前时间

                        if (Firstflag) {
                            pmSubOrdDO.setAxisOrd("1"); // 轴合同
                            Firstflag = false;
                        } else {
                            pmSubOrdDO.setAxisOrd("0"); // 轴合同
                        }
                        pmSubOrdDO.setAxisOrd("0"); // 轴合同
                        pmSubOrdDO.setLackNum(BigDecimal.ZERO); // 欠量，假设默认为0
                        pmSubOrdDO.setOverNum(BigDecimal.ZERO); // 超投，假设默认为0
                        pmSubOrdDO.setCreationDate(new Date()); // 创建时间
                        pmSubOrdDO.setCreatedBy(781L); // 创建人ID，假设默认为781
                        pmSubOrdDO.setLastUpdatedBy(781L); // 最近更新人ID，假设默认为781
                        pmSubOrdDO.setLastUpdateDate(new Date()); // 最近更新时间
                        pmSubOrdDO.setTenantId(1L); // 租户ID，假设默认为0
                        pmSubOrdDO.setObjectVersionNumber(1L); // 行版本号，假设默认为0
                        pmSubOrdDO.setAttribute1(""); // 假设没有对应字段，设置为默认值
                        pmSubOrdDO.setAttribute2(""); // 假设没有对应字段，设置为默认值
                        pmSubOrdDO.setAttribute3(""); // 假设没有对应字段，设置为默认值
                        pmSubOrdDO.setAttribute4(""); // 假设没有对应字段，设置为默认值
                        pmSubOrdDO.setAttribute5(""); // 假设没有对应字段，设置为默认值
                        pmSubOrdDO.setOrderSeqNo(Long.valueOf(currentIndex)); // 合同顺序号，假设使用合同号作为顺序号

                        // 将 PmSubOrdDO 对象添加到列表中
                        plistpmSubOrdDO.add(pmSubOrdDO);

                        //记录被使用的订单数据
                        plistOrdHis.add(gPreOrder.getLtInfoCombGPreOrder().get(i).getInfoGPreOrder());
                    }

                    intX.addAndGet(gPreOrder.getLen() + 5);//X坐标
                } else {
                    int currentIndex = index.getAndIncrement();

                    // 实例化 PmSubOrdDO 对象
                    PmSubOrd pmSubOrdDO = new PmSubOrd();

                    // 生成虚拟板坯号
                    pmSubOrdDO.setVirtualSlabNo(virtualSlabNo); // 虚拟板坯号
                    pmSubOrdDO.setRelKey(virtualSlabNo); // 关系号
                    pmSubOrdDO.setSlabNo(SInfo.getSlabNo()); // 板坯号

                    // 手动为每个字段赋值
                    pmSubOrdDO.setOrderNo(gPreOrder.getOrderNo()); // 合同号
                    pmSubOrdDO.setSgSign(gPreOrder.getInfoPmProContProdAttrDO().getSgSign()); // 牌号
                    pmSubOrdDO.setStNo(SInfo.getStNo()); // 内部钢种
                    pmSubOrdDO.setOrderThick(gPreOrder.getThk()); // 订货厚度
                    pmSubOrdDO.setOrderWidth(BigDecimal.valueOf(gPreOrder.getWid())); // 订货宽度
                    pmSubOrdDO.setLenAim(BigDecimal.valueOf(gPreOrder.getLen())); // 订货长度

                    pmSubOrdDO.setPosX(BigDecimal.valueOf(intX.intValue())); // X坐标，假设默认为0
                    intX.addAndGet(gPreOrder.getLen() + 5);//X坐标
                    pmSubOrdDO.setPosY(BigDecimal.valueOf(maxRate.getTrimming() + gPreOrder.getWidthAddv())); // Y坐标，假设默认为0

                    pmSubOrdDO.setDelivyDate(new Date()); // 交货日期，假设默认为当前时间
                    pmSubOrdDO.setAxisOrd("0"); // 轴合同
                    pmSubOrdDO.setLackNum(BigDecimal.ZERO); // 欠量，假设默认为0
                    pmSubOrdDO.setOverNum(BigDecimal.ZERO); // 超投，假设默认为0
                    pmSubOrdDO.setCreationDate(new Date()); // 创建时间
                    pmSubOrdDO.setCreatedBy(781L); // 创建人ID，假设默认为781
                    pmSubOrdDO.setLastUpdatedBy(781L); // 最近更新人ID，假设默认为781
                    pmSubOrdDO.setLastUpdateDate(new Date()); // 最近更新时间
                    pmSubOrdDO.setTenantId(1L); // 租户ID，假设默认为0
                    pmSubOrdDO.setObjectVersionNumber(1L); // 行版本号，假设默认为0
                    pmSubOrdDO.setAttribute1(""); // 假设没有对应字段，设置为默认值
                    pmSubOrdDO.setAttribute2(""); // 假设没有对应字段，设置为默认值
                    pmSubOrdDO.setAttribute3(""); // 假设没有对应字段，设置为默认值
                    pmSubOrdDO.setAttribute4(""); // 假设没有对应字段，设置为默认值
                    pmSubOrdDO.setAttribute5(""); // 假设没有对应字段，设置为默认值
                    pmSubOrdDO.setOrderSeqNo(Long.valueOf(currentIndex)); // 合同顺序号，假设使用合同号作为顺序号

                    // 将 PmSubOrdDO 对象添加到列表中
                    plistpmSubOrdDO.add(pmSubOrdDO);

                    //记录被使用的订单数据
                    plistOrdHis.add(gPreOrder);
                }
            }

            //判断长宽大小
            BigDecimal decLen = BigDecimal.valueOf(SInfo.getRemLen().intValue() - maxRate.getVirtualSlab_Len());
            BigDecimal DecWid = SInfo.getRemWid();
            if (decLen.compareTo(DecWid) <= 0) {
                // 当 p.getSlabActLen() 小于或等于 p.getSlabActWid() 时执行的代码
                SInfo.setRemLen(DecWid);
                SInfo.setRemWid(decLen);
            } else {
                SInfo.setRemLen(decLen);
                SInfo.setRemWid(DecWid);
            }

        }

        //存储数据，组板结果
        // plistpmSubHisDO.forEach(p->{
        //
        //     InsertPmSubHisDO(p);
        //
        // });
        //
        // plistpmSubOrdDO.forEach(p->{
        //
        //     InsertPmSubOrdDO(p);
        //
        // });

    }

    // 生成虚拟板坯号的方法
    private String generateVirtualSlabNo(String pono) {
        //AtomicInteger counter = counterMap.computeIfAbsent(pono, k -> new AtomicInteger(0));
        //int currentCounter = counter.incrementAndGet();
        //return pono + "S9" + String.format("%03d", currentCounter);
        UUID guid = UUID.randomUUID();
        return guid.toString();
    }

    // 生成虚拟板坯号的方法保存
    private String generateVirtualSlabNoSave(String pono, int i) {

        return pono + "S9" + String.format("%03d", i );

    }


    //设置保存数据
    public void SetSaveDate(SlabInfoDO SInfo, Long organizationId) {
        SetPmPdSlab(SInfo,organizationId);//组板板坯表 命令板坯表 命令大板表 大板粗切位置表
        SetPmPdBlockPos(organizationId);//组合子板位置表
        SetPmPdContSum(organizationId);//组板合同总量表  命令参数表
        SetPmSmallPltPos(SInfo.getMscLineNo(),organizationId);//组板小板位置表  命令小板表
//        SetPmCmdSlab();//命令板坯表
//        SetPmCmdLargePlt();//命令大板表
//        SetPmCmdCont();//命令参数表
//        SetPmCmdSmallPlt();//命令小板表
    }

    //组板板坯表
    public void SetPmPdSlab(SlabInfoDO SInfo, Long organizationId) {
        for (int i = 0; i < gltSelGGrpCalRslt.size(); i++) {
            GGrpCalRslt ggcr = gltSelGGrpCalRslt.get(i);
            PmPdSlab pmPdSlabDO = new PmPdSlab();
            pmPdSlabDO.setPono(SInfo.getPono());
            pmPdSlabDO.setSlabDivNo(BigDecimal.valueOf(i+1)); //TODO 板坯分割号 未赋值  查询板坯号等于slab_no的组板板坯表的记录数+1
            pmPdSlabDO.setVirtualSlabNo(ggcr.getVirtualSlabNo());
            pmPdSlabDO.setSlabNo(ggcr.getSlabNo());
            pmPdSlabDO.setMatDesignKind("S");
            pmPdSlabDO.setPdStatusHp("18");
            pmPdSlabDO.setPdResp("781"); // TODO 组板责任者 未赋值  操作人id
            String formplateMode = "";
            if(ggcr.getLtActInfoGPreOrder().stream().filter(item -> item.getCombinationFlag() == 1).count() == 0){ //无组合情况 为A
                if(ggcr.getLtActInfoGPreOrder().stream().map(element -> element.getWid()).distinct().count() == 1){ //宽度相同为A1
                    formplateMode = "A1";
                }else{//宽度不同为A2
                    formplateMode = "A2";
                }
            }else if(ggcr.getLtActInfoGPreOrder().stream().filter(item -> item.getSpecialFlag() == 1).count() == ggcr.getLtActInfoGPreOrder().size()){//全为22组合 为S或G
                boolean checkS1 = true;//S1判断标识
                boolean checkS3 = true;//S3判断标识
                boolean checkS = true;//S判断标识
                Integer checkWid1 = ggcr.getLtActInfoGPreOrder().get(0).getLtInfoCombGPreOrder().get(0).getInfoGPreOrder().getWid();//第一组合第一块的宽度
                Integer checkWid2 = ggcr.getLtActInfoGPreOrder().get(0).getLtInfoCombGPreOrder().get(1).getInfoGPreOrder().getWid();//第一组合第二块的宽度
                Integer checkLen = ggcr.getLtActInfoGPreOrder().get(0).getLtInfoCombGPreOrder().get(0).getInfoGPreOrder().getLen();//第一组合第一块的长度
                for(GPreOrder gPreOrder : ggcr.getLtActInfoGPreOrder()){
                    if(gPreOrder.getLtInfoCombGPreOrder().get(0).getLen() != gPreOrder.getLtInfoCombGPreOrder().get(1).getLen()){  //上下不同长 非S
                        checkS = false;
                        break;
                    }
                    if(gPreOrder.getLtInfoCombGPreOrder().get(0).getWid() != checkWid1 || gPreOrder.getLtInfoCombGPreOrder().get(1).getWid() != checkWid2){//左右不同宽 非S
                        checkS = false;
                        break;
                    }
                    for(GComBOrder gComBOrder : gPreOrder.getLtInfoCombGPreOrder()){
                        if(gComBOrder.getWid() != checkWid1){//宽不全相同 非S1 S3
                            checkS1 = false;
                            checkS3 = false;
                        }
                        if(gComBOrder.getLen() != checkLen){// 长不全相同 非S1
                            checkS1 = false;
                        }
                    }

                }
                if(checkS){
                    if(checkS1){
                        formplateMode = "S1";
                    }else if(checkS3){
                        formplateMode = "S3";
                    }else{
                        if(checkWid1 > checkWid2){
                            formplateMode = "S7";
                        }else{
                            formplateMode = "S2";
                        }
                    }
                }else{
                    formplateMode = "G";
                }
//                if(checkS1){
//                    formplateMode = "S1";
//                }else if(checkS3){
//                    formplateMode = "S3";
//                }else if(checkS){
//                    if(checkWid1 > checkWid2){
//                        formplateMode = "S7";
//                    }else{
//                        formplateMode = "S2";
//                    }
//                }else {
//                    formplateMode = "G";
//                }
            }else{
                if(ggcr.getLtActInfoGPreOrder().stream().filter(item -> item.getCombinationFlag() == 2).count() > 0){//存在特殊标记为2的情况 一拖多为G1
                    formplateMode = "G1";
                }else{//其余情况均为G
                    formplateMode = "G";
                }
            }
            pmPdSlabDO.setFormPlateMode(formplateMode);
            pmPdSlabDO.setPickModeLenDir(BigDecimal.valueOf(ggcr.getLtActInfoGPreOrder().size()));
            BigDecimal widDir = ggcr.getLtActInfoGPreOrder().stream().filter(item -> item.getCombinationFlag() == 0).count() > 0? BigDecimal.ONE: BigDecimal.valueOf(2);
            pmPdSlabDO.setPickModeWidDir(widDir);
            pmPdSlabDO.setFurType("C");// TODO 加热炉类型 暂时赋值为C
            pmPdSlabDO.setAutoManualFlag("M");
            pmPdSlabDO.setOrderRemainDiv("1");
            pmPdSlabDO.setCanDelFlag("1");
            //TODO：合同个数，取所有合同的数量
            List<String> unOrderNoList = new ArrayList<>();
            Integer zubanNum = 0;
            for(int j = 0; j < ggcr.getLtActInfoGPreOrder().size(); j++){
                if (ggcr.getLtActInfoGPreOrder().get(j).getCombinationFlag() == 0){
                    unOrderNoList.add(ggcr.getLtActInfoGPreOrder().get(j).getOrderNo());
                    zubanNum += 1;
                }else {
                    for (int k = 0; k < ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().size(); k++){
                        unOrderNoList.add(ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().get(k).getInfoGPreOrder().getOrderNo());
                        zubanNum += ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().size() ;
                    }
                }
            }
            List<String> orderNoList =  unOrderNoList.stream().distinct().collect(Collectors.toList());
            pmPdSlabDO.setOrderNumInPlate(BigDecimal.valueOf(orderNoList.size()));
            //TODO:合同数量，取所有小板的数据量
            pmPdSlabDO.setTotSmallPlateNum(BigDecimal.valueOf(zubanNum));
            //TODO：轴合同获取
            GPreOrder axleGPreOrder = ggcr.getLtActInfoGPreOrder().get(0);
            if(ggcr.getLtActInfoGPreOrder().get(0).getCombinationFlag() == 1){
                axleGPreOrder = ggcr.getLtActInfoGPreOrder().get(0).getLtInfoCombGPreOrder().get(0).getInfoGPreOrder();
            }
            String axleOrderNo = axleGPreOrder.getOrderNo(); //轴合同
            Optional<PmContMscTech> resultPmContMscTechDO = plistPmContMscTechDO.stream()
                    .filter(item -> axleOrderNo.equals(item.getOrderNo())) //TODO 根据轴合同号查询合同工艺表  暂时取第一条合同
                    .findFirst();
            pmPdSlabDO.setAdTypeCode(resultPmContMscTechDO.get().getAdTypeCode());
            pmPdSlabDO.setAdModeCode(resultPmContMscTechDO.get().getAdModeCode());
            pmPdSlabDO.setCtrlRollCode(resultPmContMscTechDO.get().getCtrlRollCode());
            pmPdSlabDO.setCutModeCode(resultPmContMscTechDO.get().getCutModeCode());

            //TODO 缺少质量模块MES合同主档QD_TO_PO_ORDER
            pmPdSlabDO.setUltCode(resultPmContMscTechDO.get().getUltCode());
            //TODO 遍历组板合同，根据合同号从质量模块MES合同主档QD_TO_PO_ORDER读取ERP_UT_SPEC1探伤标准1、ERP_UT_SPEC2超声探伤标2、ERP_UT_SPEC3超声探伤标3，去重后所有数据拼接成一条记录
            //遍历 orderNoList 拿每一条orderNo查询plistQdToPoOrderDO 获取ERP_UT_SPEC1，ERP_UT_SPEC2，ERP_UT_SPEC3 ，将获取的每一个探伤标准 去重后拼接成一条记录
            StringBuilder ultDetectMethodCodeBuilder = new StringBuilder();
            String ultCode = "";
            for (String orderNo : orderNoList) {
                Optional<QdToPoOrder> resultQdToPoOrderDO = plistQdToPoOrderDO.stream()
                        .filter(item -> orderNo.equals(item.getOrderNo()))
                        .findFirst();
                String erpUtSpec1 = "";
                String erpUtSpec2 = "";
                String erpUtSpec3 = "";
                if (resultQdToPoOrderDO.isPresent()) {
                    erpUtSpec1 = nvl(resultQdToPoOrderDO.get().getErpUtSpec1(), "");
                    erpUtSpec2 = nvl(resultQdToPoOrderDO.get().getErpUtSpec2(), "");
                    erpUtSpec3 = nvl(resultQdToPoOrderDO.get().getErpUtSpec3(), "");
                    if (!erpUtSpec1.isEmpty()) {
                        if (!ultDetectMethodCodeBuilder.toString().contains(erpUtSpec1)) {
                            ultDetectMethodCodeBuilder.append(erpUtSpec1).append("-");
                        }
                    }
                    if (!erpUtSpec2.isEmpty()) {
                        if (!ultDetectMethodCodeBuilder.toString().contains(erpUtSpec2)) {
                            ultDetectMethodCodeBuilder.append(erpUtSpec2).append("-");
                        }
                    }
                    if (!erpUtSpec3.isEmpty()) {
                        if (!ultDetectMethodCodeBuilder.toString().contains(erpUtSpec3)) {
                            ultDetectMethodCodeBuilder.append(erpUtSpec3).append("-");
                        }
                    }
                }
                ultCode = ultDetectMethodCodeBuilder.toString();
                if (!ultCode.isEmpty()) {
                    ultCode = ultCode.substring(0, ultCode.length() - 1);
                }
                pmPdSlabDO.setUltCode(ultCode);
            }

            String ultDetectMethodCode = "";
            String coolCode = "";
            // 遍历 组板合同列表
            for (GPreOrder gPreOrder : ggcr.getLtActInfoGPreOrder()) {
                if(gPreOrder.getCombinationFlag() == 1){
                    for (GComBOrder gComBOrder : gPreOrder.getLtInfoCombGPreOrder()) {
                        String orderNo = gComBOrder.getInfoGPreOrder().getOrderNo();
                        String mscLineNo = gComBOrder.getInfoGPreOrder().getInfoPmContMscTechDO().getMscLineNo();
                        Optional<PmContMscTech> matchingItem = plistPmContMscTechDO.stream()
                                .filter(item -> orderNo.equals(item.getOrderNo()) && mscLineNo.equals(item.getMscLineNo()))
                                .findFirst();
                        if (!ultDetectMethodCode.isEmpty()) {
                            if (!coolCode.isEmpty()) {
                                break;
                            } else {
                                coolCode = nvl(matchingItem.get().getCoolCode(), "");
                            }
                        } else {
                            ultDetectMethodCode = nvl(matchingItem.get().getUltDetectMethodCode(), "");
                            if (coolCode.isEmpty()) {
                                coolCode = nvl(matchingItem.get().getCoolCode(), "");
                            }
                        }
                    }
                }else{
                    String orderNo = gPreOrder.getOrderNo();
                    String mscLineNo = gPreOrder.getInfoPmContMscTechDO().getMscLineNo();

                    // 根据 orderNo 和 mscLineNo 在 plistPmContMscTechDO 中查找匹配项
                    Optional<PmContMscTech> matchingItem = plistPmContMscTechDO.stream()
                            .filter(item -> orderNo.equals(item.getOrderNo()) && mscLineNo.equals(item.getMscLineNo()))
                            .findFirst();
                    if (!ultDetectMethodCode.isEmpty()) {
                        if (!coolCode.isEmpty()) {
                            break;
                        } else {
                            coolCode = nvl(matchingItem.get().getCoolCode(), "");
                        }
                    } else {
                        ultDetectMethodCode = nvl(matchingItem.get().getUltDetectMethodCode(), "");
                        if (coolCode.isEmpty()) {
                            coolCode = nvl(matchingItem.get().getCoolCode(), "");
                        }
                    }
                }
            }
            pmPdSlabDO.setUltDetectMethodCode(ultDetectMethodCode);
            pmPdSlabDO.setCoolCode(coolCode);

            Optional<PmProContProdTtr> resultPmProContProdAttrDO = plistPmProContProdAttrDO.stream()
                    .filter(item -> axleOrderNo.equals(item.getOrderNo())) //TODO 根据轴合同号查询生产合同产品属性表  暂时取第一条合同
                    .findFirst();
            pmPdSlabDO.setWithSideFlag(resultPmProContProdAttrDO.get().getProdSideMark());

            pmPdSlabDO.setHeadCut(BigDecimal.valueOf(ggcr.getHead_Len()));
            pmPdSlabDO.setTailCut(BigDecimal.valueOf(ggcr.getTail_Len()));

            String urgOrderFlag = "";
            for (GPreOrder gPreOrder : ggcr.getLtActInfoGPreOrder()) {
                if(gPreOrder.getCombinationFlag() == 1){
                    for (GComBOrder gComBOrder : gPreOrder.getLtInfoCombGPreOrder()) {
                        String orderNo = gComBOrder.getInfoGPreOrder().getOrderNo();
                        String mscLineNo = gComBOrder.getInfoGPreOrder().getInfoPmContMscTechDO().getMscLineNo();
                        Optional<PmProContProdTtr> pmProContProdAttrDOItem = plistPmProContProdAttrDO.stream()
                                .filter(item -> orderNo.equals(item.getOrderNo()))
                                .findFirst();
                        urgOrderFlag = String.valueOf(nvl(pmProContProdAttrDOItem.get().getUrgOrderFlag(), ""));
                        if (!urgOrderFlag.isEmpty()) {
                            break;
                        }
                    }

                }else{
                    String orderNo = gPreOrder.getOrderNo();

                    // 根据 orderNo 和 mscLineNo 在 plistPmContMscTechDO 中查找匹配项
                    Optional<PmProContProdTtr> pmProContProdAttrDOItem = plistPmProContProdAttrDO.stream()
                            .filter(item -> orderNo.equals(item.getOrderNo()))
                            .findFirst();
                    urgOrderFlag = String.valueOf(nvl(pmProContProdAttrDOItem.get().getUrgOrderFlag(), ""));
                    if (!urgOrderFlag.isEmpty()) {
                        break;
                    }
                }
            }
            pmPdSlabDO.setUrgOrderFlag(urgOrderFlag);

            pmPdSlabDO.setSgSign(SInfo.getSgSign());
            pmPdSlabDO.setStNo(SInfo.getStNo());
            pmPdSlabDO.setOutSgNo(SInfo.getStNo());
            pmPdSlabDO.setIngotType(SInfo.getSlabType());
            pmPdSlabDO.setPreCleanSlabThick(SInfo.getSlabActThk());
            pmPdSlabDO.setPreCleanSlabWidth(SInfo.getSlabActWid());
            pmPdSlabDO.setPreCleanSlabLen(BigDecimal.valueOf(ggcr.getVirtualSlab_Len()));
            pmPdSlabDO.setPreCleanSlabMaxLen(BigDecimal.valueOf(ggcr.getVirtualSlab_Len()));
            pmPdSlabDO.setPreCleanSlabMinLen(BigDecimal.valueOf(ggcr.getVirtualSlab_Len()));
            BigDecimal weight = SInfo.getSlabActThk().multiply(SInfo.getSlabActWid()).multiply(BigDecimal.valueOf(ggcr.getVirtualSlab_Len())).multiply(BigDecimal.valueOf(7.85)).divide(BigDecimal.valueOf(1000000000),3,RoundingMode.HALF_UP);
            pmPdSlabDO.setPreCleanSlabWt(weight);
            pmPdSlabDO.setPreCleanSlabMaxWt(weight);
            pmPdSlabDO.setPreCleanSlabMinWt(weight);

            pmPdSlabDO.setInfurSlabThick(SInfo.getSlabActThk());
            pmPdSlabDO.setInfurSlabWid(SInfo.getSlabActWid());
            pmPdSlabDO.setInfurSlabLen(BigDecimal.valueOf(ggcr.getVirtualSlab_Len()));
            pmPdSlabDO.setInfurSlabMaxLen(BigDecimal.valueOf(ggcr.getVirtualSlab_Len()));
            pmPdSlabDO.setInfurSlabMinLen(BigDecimal.valueOf(ggcr.getVirtualSlab_Len()));
            pmPdSlabDO.setInfurSlabWt(weight);
            pmPdSlabDO.setInfurSlabMaxWt(weight);
            pmPdSlabDO.setInfurSlabMinWt(weight);

            pmPdSlabDO.setNeedSlabLen(BigDecimal.valueOf(ggcr.getVirtualSlab_Len()));
            pmPdSlabDO.setNeedSlabWt(weight);
            pmPdSlabDO.setAddSlabFlag("1"); //TODO 暂时写死
            pmPdSlabDO.setFixSlabLenFlag(0L);
            pmPdSlabDO.setFixSlabLen(BigDecimal.valueOf(ggcr.getVirtualSlab_Len()));

            Optional<PmContMscTech> resultPmContMscTechDO1 = plistPmContMscTechDO.stream()
                    .filter(item -> axleOrderNo.equals(item.getOrderNo()) && ggcr.getLtActInfoGPreOrder().get(0).getInfoPmContMscTechDO().getMscLineNo().equals(item.getMscLineNo())) //TODO 根据轴合同号和产线号查询合同工艺表  暂时取第一条合同
                    .findFirst();

            pmPdSlabDO.setHpFlameCleanDiv(resultPmContMscTechDO1.get().getFlameCleanDiv());
            pmPdSlabDO.setSlabFinishCode(resultPmContMscTechDO1.get().getSlabFinishCode());
            Long slabPdQty = plistPmPdSlabInfoDO.stream()
                    .filter(item -> item != null && ggcr != null && ggcr.getSlabNo() != null && ggcr.getSlabNo().equals(item.getSlabNo()))
                    .count();
            if (slabPdQty > 0) {
                Optional<PmPdSlabInfo> resultPmPdSlabInfoDO = plistPmPdSlabInfoDO.stream()
                        .filter(item -> ggcr.getSlabNo().equals(item.getSlabNo()))
                        .findFirst();
                pmPdSlabDO.setSlabPlaceCode(resultPmPdSlabInfoDO.get().getSlabPlaceCode());
            }

            pmPdSlabDO.setRollAimThick(ggcr.getCal_Thk());
            pmPdSlabDO.setRollAimWidth(BigDecimal.valueOf(ggcr.getCal_Wid()));
            pmPdSlabDO.setRollAimLen(BigDecimal.valueOf(ggcr.getCal_Len()));
            pmPdSlabDO.setOrderThickAxis(axleGPreOrder.getThk());
            pmPdSlabDO.setCombinePlateWidth(BigDecimal.valueOf(axleGPreOrder.getWid()));
            Integer lenSum = ggcr.getLtActInfoGPreOrder().stream().mapToInt(GPreOrder::getLen).sum();
            pmPdSlabDO.setCombinePlateLen(BigDecimal.valueOf(lenSum));
            pmPdSlabDO.setRollWtHp(weight);

            BigDecimal minThickTolMax = ggcr.getLtActInfoGPreOrder().stream()
                    .map(GPreOrder::getThickTolMax)
                    .min(BigDecimal::compareTo)
                    .orElse(BigDecimal.ZERO);
            pmPdSlabDO.setRollThickTolMax(minThickTolMax);
            BigDecimal maxThickTolMin = ggcr.getLtActInfoGPreOrder().stream()
                    .map(GPreOrder::getThickTolMin)
                    .max(BigDecimal::compareTo)
                    .orElse(BigDecimal.ZERO);
            pmPdSlabDO.setRollThickTolMin(maxThickTolMin);

            BigDecimal yield = BigDecimal.ZERO;
            for(int l = 0; l < ggcr.getLtActInfoGPreOrder().size(); l++){
                if(ggcr.getLtActInfoGPreOrder().get(l).getCombinationFlag() == 1){
                    List<GComBOrder> gComBOrders = ggcr.getLtActInfoGPreOrder().get(l).getLtInfoCombGPreOrder();
                    for(int m = 0; m < ggcr.getLtActInfoGPreOrder().get(l).getLtInfoCombGPreOrder().size(); m++){
                        yield = yield.add(BigDecimal.valueOf(gComBOrders.get(m).getWid()).multiply(gComBOrders.get(m).getThk()).multiply(BigDecimal.valueOf(gComBOrders.get(m).getLen())));
                    }
                }else{
                    yield = yield.add(BigDecimal.valueOf(ggcr.getLtActInfoGPreOrder().get(l).getWid()).multiply(ggcr.getLtActInfoGPreOrder().get(l).getThk()).multiply(BigDecimal.valueOf(ggcr.getLtActInfoGPreOrder().get(l).getLen())));
                }
            }


            yield = yield.multiply(BigDecimal.valueOf(7.85)).divide(weight.multiply( BigDecimal.valueOf(1000000000)), 4, RoundingMode.HALF_UP);
            pmPdSlabDO.setCommandYield(yield);
            pmPdSlabDO.setNormYield(yield);
            pmPdSlabDO.setRollYield(yield);

            pmPdSlabDO.setEdgerUseFlag("Y");
            pmPdSlabDO.setBroadMasUseFlag("N");
            pmPdSlabDO.setFormMasUseFlag("N");
            pmPdSlabDO.setRollDirectCode("L"); //TODO 轧制方向代码 横轧C纵轧L  暂时默认L
            pmPdSlabDO.setSampleLenHead(BigDecimal.valueOf(ggcr.getSmp_Len()));//TODO 头尾中 试样长度 暂时默认试样长度
            pmPdSlabDO.setSampleLenTail(BigDecimal.valueOf(ggcr.getSmp_Len()));
            pmPdSlabDO.setSampleLenMid(BigDecimal.valueOf(ggcr.getSmp_Len()));
            pmPdSlabDO.setRsCode("0");
            if (BigDecimal.valueOf(ggcr.getCal_Wid()).compareTo(SInfo.getSlabActWid()) > 0) {
                pmPdSlabDO.setBroadFlag("1");  //需要展宽
            } else {
                pmPdSlabDO.setBroadFlag("0");
            }

            pmPdSlabDO.setOrderNoAxis(axleGPreOrder.getOrderNo());//TODO 轴合同号 暂时取第一个订单号
            pmPdSlabDO.setMscLineNo(SInfo.getMscLineNo()); //TODO 产线号，暂时默认板坯产线号

            pmPdSlabDO.setTransFlag(BigDecimal.valueOf(0));

            pmPdSlabDO.setSlabCleanWtLossRateSt(BigDecimal.valueOf(0));
            pmPdSlabDO.setSlabCleanWtLossRateFr(BigDecimal.valueOf(0));

            pmPdSlabDO.setCreatedBy(781L);//TODO 创建人修改人，暂时默认781  BKGY
            pmPdSlabDO.setLastUpdatedBy(781L);
            pmPdSlabDO.setCreationDate(now);
            pmPdSlabDO.setLastUpdateDate(now);
            pmPdSlabDO.setLastSlabFlag(1L);
            pmPdSlabDO.setTwoRollInterimFlag(1L);

            pmPdSlabDO.setTenantId(organizationId);
//            pmPdSlabDO.setObjectVersionNumber(1L);

            SetPmCmdSlab(pmPdSlabDO,resultPmProContProdAttrDO.get(),organizationId);//命令板坯表
            SetPmCmdLargePlt(pmPdSlabDO, ggcr,resultPmContMscTechDO1.get(),resultPmProContProdAttrDO.get(),organizationId);//命令大板表
            SetPmPdPlateCut(organizationId,formplateMode,SInfo.getMscLineNo().substring(SInfo.getMscLineNo().length()-2));//大板粗切位置表

            SetPmPdRecDTO(orderNoList,organizationId,SInfo.getMscLineNo(),ggcr.getVirtualSlabNo());//组板履历表

            pmPdSlabDOList.add(pmPdSlabDO);
        }
    }


    //大板粗切位置表
    public void SetPmPdPlateCut(Long organizationId, String formplateMode, String mscLineNo) {
        if(formplateMode.equals("A1") || formplateMode.equals("A2")){
            formplateMode = "A";
        }else if(formplateMode.equals("S1") || formplateMode.equals("S2")|| formplateMode.equals("S3")|| formplateMode.equals("S7")){
            formplateMode = "S";
        }else{
            formplateMode = "G";
        }
        String formplateModeFirst = formplateMode;
        Integer wid = gltSelGGrpCalRslt.get(0).getLtActInfoGPreOrder().get(0).getWid();
        List<PmCutPlaceBt> filteredList = plistPmCutPlaceBtDO.stream()
                .filter(p -> p.getPlateThickFrom().compareTo(BigDecimal.valueOf(wid)) < 0
                        && p.getPlateThickTo().compareTo(BigDecimal.valueOf(wid)) > 0
                        && p.getFormPlateModeFirst().equals(formplateModeFirst)
                        && p.getRollLineNo().equals(mscLineNo))
                .collect(Collectors.toList());
        BigDecimal cutMax = BigDecimal.valueOf(40000);
        if(!filteredList.isEmpty()) {
            cutMax = filteredList.get(0).getNormalCutLenTo();
        }

        for (int i = 0; i < gltSelGGrpCalRslt.size(); i++) {//  异宽判断  长度判断 热处理
            GGrpCalRslt ggcr = gltSelGGrpCalRslt.get(i);
            Integer lastWid = 0;
            Integer lastLen = 0;
            for(int j = 0; j < ggcr.getLtActInfoGPreOrder().size(); j++){
                if(j == 0){
                    lastWid = ggcr.getLtActInfoGPreOrder().get(j).getWid();
                    lastLen = ggcr.getLtActInfoGPreOrder().get(j).getLen();
                }else{
                    if(BigDecimal.valueOf(lastLen).compareTo(cutMax) > 0){
                        SetPmPdPlateCutFM(ggcr.getVirtualSlabNo(), "P", Long.valueOf(j),organizationId);
                        lastLen = 0;
                    }else{
                        if(lastWid != ggcr.getLtActInfoGPreOrder().get(j).getWid()){
                            SetPmPdPlateCutFM(ggcr.getVirtualSlabNo(), "D", Long.valueOf(j+1),organizationId);
                            lastLen = 0;
                        }else{
                            lastLen += ggcr.getLtActInfoGPreOrder().get(j).getLen();
                        }
                    }
                    lastWid = ggcr.getLtActInfoGPreOrder().get(j).getWid();
                }
            }
        }
    }

    public void SetPmPdPlateCutFM(String virtualSlabNo, String cutType,Long positionSeq, Long organizationId) {
        PmPdPlateCut pmPdPlateCutDOF = new PmPdPlateCut();
        pmPdPlateCutDOF.setPdMatNo(virtualSlabNo);
        pmPdPlateCutDOF.setCutType(cutType);  //粗切类型（M:搬送用；D:异宽用；P：命令用；H：热分切用）
        pmPdPlateCutDOF.setPositionType("F");
        pmPdPlateCutDOF.setPositionSeq(positionSeq);
        pmPdPlateCutDOF.setCreatedBy(781L);//TODO 创建人修改人，暂时默认781  BKGY
        pmPdPlateCutDOF.setLastUpdatedBy(781L);
        pmPdPlateCutDOF.setCreationDate(now);
        pmPdPlateCutDOF.setLastUpdateDate(now);
        pmPdPlateCutDOF.setTenantId(organizationId);

        PmPdPlateCut pmPdPlateCutDOM = new PmPdPlateCut();
        pmPdPlateCutDOM.setPdMatNo(virtualSlabNo);
        pmPdPlateCutDOM.setCutType(cutType);  //粗切类型（M:搬送用；D:异宽用；P：命令用；H：热分切用）
        pmPdPlateCutDOM.setPositionType("M");
        pmPdPlateCutDOM.setPositionSeq(positionSeq);
        pmPdPlateCutDOM.setCreatedBy(781L);//TODO 创建人修改人，暂时默认781  BKGY
        pmPdPlateCutDOM.setLastUpdatedBy(781L);
        pmPdPlateCutDOM.setCreationDate(now);
        pmPdPlateCutDOM.setLastUpdateDate(now);
        pmPdPlateCutDOM.setTenantId(organizationId);

        pmPdPlateCutDOList.add(pmPdPlateCutDOF);
        pmPdPlateCutDOList.add(pmPdPlateCutDOM);
    }

    //组合子板位置表
    public void SetPmPdBlockPos(Long organizationId) {
        for (int i = 0; i < gltSelGGrpCalRslt.size(); i++) {
            GGrpCalRslt ggcr = gltSelGGrpCalRslt.get(i);
            List<String> unOrderNoList = new ArrayList<>();
            Integer zubanNum = 0;
            for(int j = 0; j < ggcr.getLtActInfoGPreOrder().size(); j++){
                if (ggcr.getLtActInfoGPreOrder().get(j).getCombinationFlag() == 0){
                    unOrderNoList.add(ggcr.getLtActInfoGPreOrder().get(j).getOrderNo());
                    zubanNum += 1;
                }else {
                    for (int k = 0; k < ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().size(); k++){
                        unOrderNoList.add(ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().get(k).getInfoGPreOrder().getOrderNo());
                        zubanNum += ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().size() ;
                    }
                }
            }
            List<String> orderNoList =  unOrderNoList.stream().distinct().collect(Collectors.toList());
            for (int j = 0; j < orderNoList.size(); j++) {
                PmPdBlockPos pmPdBlockPosDO = new PmPdBlockPos();
                pmPdBlockPosDO.setPdMatNo(ggcr.getVirtualSlabNo());
                pmPdBlockPosDO.setOrderNo(orderNoList.get(j));
                pmPdBlockPosDO.setOrderSeqNo(Long.valueOf(j + 1));//TODO 订单序号 暂时以实际订单信息列表顺序
                List<GPreOrder> resultGPreOrder = new ArrayList<>();
                for(int k = 0; k < ggcr.getLtActInfoGPreOrder().size(); k++){
                    if(ggcr.getLtActInfoGPreOrder().get(j).getCombinationFlag() == 1){
                        for (int l = 0; l < ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().size(); l++){
                            if(ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().get(l).getInfoGPreOrder().getOrderNo().equals(pmPdBlockPosDO.getOrderNo())){
                                resultGPreOrder.add(ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().get(l).getInfoGPreOrder());
                            }
                        }
                    }else{
                        resultGPreOrder.add(ggcr.getLtActInfoGPreOrder().get(j));
                    }
                }
//                List<GPreOrder> resultGPreOrder = ggcr.getLtActInfoGPreOrder().stream()
//                        .filter(item -> item.getOrderNo().equals(pmPdBlockPosDO.getOrderNo()))
//                        .collect(Collectors.toList());
                Integer blockPlateNum = resultGPreOrder.size();

                pmPdBlockPosDO.setBlockPlateNum(BigDecimal.valueOf(blockPlateNum));
                pmPdBlockPosDO.setSlabNo(ggcr.getSlabNo());
                pmPdBlockPosDO.setProContId(resultGPreOrder.get(0).getInfoPmProContDo().getProContId());
                pmPdBlockPosDO.setOrderBlockNo(Long.valueOf(i+1)); //TODO 厚板组板块号 暂时不知如何赋值

                pmPdBlockPosDO.setCreatedBy(781L);//TODO 创建人修改人，暂时默认781  BKGY
                pmPdBlockPosDO.setLastUpdatedBy(781L);
                pmPdBlockPosDO.setCreationDate(now);
                pmPdBlockPosDO.setLastUpdateDate(now);

                pmPdBlockPosDO.setTenantId(organizationId);
//                pmPdBlockPosDO.setObjectVersionNumber(1L);

                pmPdBlockPosDOList.add(pmPdBlockPosDO);
            }
        }
    }

    //组板合同总量表
    public void SetPmPdContSum(Long organizationId) {
        for (int i = 0; i < gltSelGGrpCalRslt.size(); i++) {
            GGrpCalRslt ggcr = gltSelGGrpCalRslt.get(i);
            List<String> unOrderNoList = new ArrayList<>();
            Integer zubanNum = 0;
            for(int j = 0; j < ggcr.getLtActInfoGPreOrder().size(); j++){
                if (ggcr.getLtActInfoGPreOrder().get(j).getCombinationFlag() == 0){
                    unOrderNoList.add(ggcr.getLtActInfoGPreOrder().get(j).getOrderNo());
                    zubanNum += 1;
                }else {
                    for (int k = 0; k < ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().size(); k++){
                        unOrderNoList.add(ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().get(k).getInfoGPreOrder().getOrderNo());
                        zubanNum += ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().size() ;
                    }
                }
            }
            List<String> orderNoList =  unOrderNoList.stream().distinct().collect(Collectors.toList());
            for (int j = 0; j < orderNoList.size(); j++) {
                PmPdContSum pmPdContSumDO = new PmPdContSum();

                pmPdContSumDO.setPdMatNo(ggcr.getVirtualSlabNo());
                pmPdContSumDO.setOrderNo(orderNoList.get(j));
                pmPdContSumDO.setOrderSeqNo(BigDecimal.valueOf(j + 1));

                List<GPreOrder> gPreOrders = new ArrayList<>();
                for(int k = 0; k < ggcr.getLtActInfoGPreOrder().size(); k++){
                    if(ggcr.getLtActInfoGPreOrder().get(j).getCombinationFlag() == 1){
                        for (int l = 0; l < ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().size(); l++){
                            if(ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().get(l).getInfoGPreOrder().getOrderNo().equals(pmPdContSumDO.getOrderNo())){
                                gPreOrders.add(ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().get(l).getInfoGPreOrder());
                            }
                        }
                    }else{
                        gPreOrders.add(ggcr.getLtActInfoGPreOrder().get(j));
                    }
                }

//                List<GPreOrder> gPreOrders = ggcr.getLtActInfoGPreOrder().stream() // 当前合同号在实际合同列表中的条数
//                        .filter(item -> item.getOrderNo().equals(pmPdContSumDO.getOrderNo()))
//                        .collect(Collectors.toList());
                Integer orderPlateNum = gPreOrders.size();
                pmPdContSumDO.setOrderPlateNum(BigDecimal.valueOf(orderPlateNum));
                pmPdContSumDO.setSlabNo(ggcr.getSlabNo());
                pmPdContSumDO.setPdMatType("S");
                pmPdContSumDO.setPdStatus("12");
                pmPdContSumDO.setProContId(gPreOrders.get(0).getInfoPmProContDo().getProContId());
                pmPdContSumDO.setOrderThick(gPreOrders.get(0).getThk());
                pmPdContSumDO.setOrderWidth(BigDecimal.valueOf(gPreOrders.get(0).getWid()));
                pmPdContSumDO.setOrderLen(BigDecimal.valueOf(gPreOrders.get(0).getLen())); //20250212

                pmPdContSumDO.setOrderLenMax(gPreOrders.get(0).getInfoPmProContProdAttrDO().getOrderMaxLen());
                pmPdContSumDO.setOrderLenMin(gPreOrders.get(0).getInfoPmProContProdAttrDO().getOrderMinLen());

                pmPdContSumDO.setSmallPlateThick(gPreOrders.get(0).getThk());
                pmPdContSumDO.setSmallPlateWidth(BigDecimal.valueOf(gPreOrders.get(0).getWid()));
                pmPdContSumDO.setSmallPlateLen(BigDecimal.valueOf(gPreOrders.get(0).getLen()));//TODO 长度不确定用实际长度还是长度

                pmPdContSumDO.setCreatedBy(781L);//TODO 创建人修改人，暂时默认781  BKGY
                pmPdContSumDO.setLastUpdatedBy(781L);
                pmPdContSumDO.setCreationDate(now);
                pmPdContSumDO.setLastUpdateDate(now);

                pmPdContSumDO.setAxisFlag(0L);
                if(j == 0){
                    pmPdContSumDO.setAxisFlag(1L);//TODO 轴合同标记，暂时取第一条为轴合同
                }

                pmPdContSumDO.setTenantId(organizationId);
//                pmPdContSumDO.setObjectVersionNumber(1L);
                SetPmCmdCont(pmPdContSumDO, gPreOrders.get(0),zubanNum,organizationId);//命令参数表
                pmPdContSumDOList.add(pmPdContSumDO);
            }
        }
    }

    //组板小板位置表
    public void SetPmSmallPltPos(String mscLineNo, Long organizationId) {
        for (int i = 0; i < gltSelGGrpCalRslt.size(); i++) {
            GGrpCalRslt ggcr = gltSelGGrpCalRslt.get(i);
            Integer smallPlateNum = 0;
            for (int j = 0; j < ggcr.getLtActInfoGPreOrder().size(); j++) {
                if(ggcr.getLtActInfoGPreOrder().get(j).getCombinationFlag() == 1){
                    for (int k = 0; k < ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().size(); k++) {
                        GPreOrder gpo = ggcr.getLtActInfoGPreOrder().get(j).getLtInfoCombGPreOrder().get(k).getInfoGPreOrder();
                        PmSmallPltPos pmSmallPltPosDO = new PmSmallPltPos();
                        pmSmallPltPosDO.setPdMatNo(ggcr.getVirtualSlabNo());
                        pmSmallPltPosDO.setOrderNo(gpo.getOrderNo());
                        pmSmallPltPosDO.setProContId(gpo.getInfoPmProContDo().getProContId());
                        pmSmallPltPosDO.setOrderSeqNo(Long.valueOf(j + 1));
                        pmSmallPltPosDO.setSlabNo(ggcr.getSlabNo());
                        Optional<PmProContProdTtr> resultPmProContProdAttrDO = plistPmProContProdAttrDO.stream()
                                .filter(item -> gpo.getOrderNo().equals(item.getOrderNo())) //根据合同号查询生产合同产品属性表
                                .findFirst();
                        if (resultPmProContProdAttrDO.get().getTrimCode().equals("0")) {
                            pmSmallPltPosDO.setSmallPlateDivNo("000");
                        }  else {
                            pmSmallPltPosDO.setSmallPlateDivNo(SMALL_PLATE_DIV_NO[smallPlateNum]);
                        }
                        pmSmallPltPosDO.setPickModeLenDir(Long.valueOf(j+1));
                        pmSmallPltPosDO.setPickModeWidDir(Long.valueOf(k+1));
                        pmSmallPltPosDO.setOrderThick(gpo.getThk());
                        pmSmallPltPosDO.setOrderWidth(BigDecimal.valueOf(gpo.getWid()));
                        pmSmallPltPosDO.setOrderLen(BigDecimal.valueOf(gpo.getLen())); //TODO 长度不确定用实际长度还是长度
                        pmSmallPltPosDO.setOrderLenMax(gpo.getInfoPmProContProdAttrDO().getOrderMaxLen());
                        pmSmallPltPosDO.setOrderLenMin(gpo.getInfoPmProContProdAttrDO().getOrderMinLen());

                        pmSmallPltPosDO.setSmallPlateThick(gpo.getThk());
                        pmSmallPltPosDO.setSmallPlateWidth(BigDecimal.valueOf(gpo.getWid()));
                        pmSmallPltPosDO.setSmallPlateLen(BigDecimal.valueOf(gpo.getLen())); //TODO 长度不确定用实际长度还是长度


                        pmSmallPltPosDO.setCreatedBy(781L);//TODO 创建人修改人，暂时默认781  BKGY
                        pmSmallPltPosDO.setLastUpdatedBy(781L);
                        pmSmallPltPosDO.setCreationDate(now);
                        pmSmallPltPosDO.setLastUpdateDate(now);

                        pmSmallPltPosDO.setTenantId(organizationId);
//                pmSmallPltPosDO.setObjectVersionNumber(1L);

                        SetPmCmdSmallPlt(pmSmallPltPosDO,resultPmProContProdAttrDO.get(),mscLineNo,organizationId);
                        pmSmallPltPosDOList.add(pmSmallPltPosDO);
                        smallPlateNum += 1;
                    }
                }else{
                    GPreOrder gpo = ggcr.getLtActInfoGPreOrder().get(j);

                    PmSmallPltPos pmSmallPltPosDO = new PmSmallPltPos();
                    pmSmallPltPosDO.setPdMatNo(ggcr.getVirtualSlabNo());
                    pmSmallPltPosDO.setOrderNo(gpo.getOrderNo());
                    pmSmallPltPosDO.setProContId(gpo.getInfoPmProContDo().getProContId());
                    pmSmallPltPosDO.setOrderSeqNo(Long.valueOf(j + 1));
                    pmSmallPltPosDO.setSlabNo(ggcr.getSlabNo());
                    Optional<PmProContProdTtr> resultPmProContProdAttrDO = plistPmProContProdAttrDO.stream()
                            .filter(item -> gpo.getOrderNo().equals(item.getOrderNo())) //根据合同号查询生产合同产品属性表
                            .findFirst();
                    if (resultPmProContProdAttrDO.get().getTrimCode().equals("0")) {
                        pmSmallPltPosDO.setSmallPlateDivNo("000");
                    } else {
                        pmSmallPltPosDO.setSmallPlateDivNo(SMALL_PLATE_DIV_NO[smallPlateNum]);
                    }
                    pmSmallPltPosDO.setPickModeLenDir(Long.valueOf(j+1));//TODO 取板方式 长度方向 列数累加
                    pmSmallPltPosDO.setPickModeWidDir(1L);//TODO 取板方式 宽度方向 第一行
                    pmSmallPltPosDO.setOrderThick(gpo.getThk());
                    pmSmallPltPosDO.setOrderWidth(BigDecimal.valueOf(gpo.getWid()));
                    pmSmallPltPosDO.setOrderLen(BigDecimal.valueOf(gpo.getLen())); //TODO 长度不确定用实际长度还是长度
                    pmSmallPltPosDO.setOrderLenMax(gpo.getInfoPmProContProdAttrDO().getOrderMaxLen());
                    pmSmallPltPosDO.setOrderLenMin(gpo.getInfoPmProContProdAttrDO().getOrderMinLen());

                    pmSmallPltPosDO.setSmallPlateThick(gpo.getThk());
                    pmSmallPltPosDO.setSmallPlateWidth(BigDecimal.valueOf(gpo.getWid()));
                    pmSmallPltPosDO.setSmallPlateLen(BigDecimal.valueOf(gpo.getLen())); //TODO 长度不确定用实际长度还是长度


                    pmSmallPltPosDO.setCreatedBy(781L);//TODO 创建人修改人，暂时默认781  BKGY
                    pmSmallPltPosDO.setLastUpdatedBy(781L);
                    pmSmallPltPosDO.setCreationDate(now);
                    pmSmallPltPosDO.setLastUpdateDate(now);

                    pmSmallPltPosDO.setTenantId(organizationId);
//                pmSmallPltPosDO.setObjectVersionNumber(1L);

                    SetPmCmdSmallPlt(pmSmallPltPosDO,resultPmProContProdAttrDO.get(),mscLineNo,organizationId);
                    pmSmallPltPosDOList.add(pmSmallPltPosDO);
                    smallPlateNum += 1;
                }
            }
        }
    }

    //命令板坯表
    public void SetPmCmdSlab(PmPdSlab pmPdSlabDO, PmProContProdTtr pmProContProdTtr, Long organizationId) {
        PmCmdSlab pmCmdSlabDO = new PmCmdSlab();
        pmCmdSlabDO.setPonoSlabNo(pmPdSlabDO.getVirtualSlabNo());
        pmCmdSlabDO.setTmpSlabNo(pmPdSlabDO.getVirtualSlabNo());
        pmCmdSlabDO.setSlabNo(pmPdSlabDO.getSlabNo());
        pmCmdSlabDO.setVirtualSlabNo(pmPdSlabDO.getVirtualSlabNo());
        pmCmdSlabDO.setPdStatusHp("18");
        pmCmdSlabDO.setShortSlabNumInLong(Long.valueOf(gltSelGGrpCalRslt.size()));
        pmCmdSlabDO.setBigPlateNum(Long.valueOf(gltSelGGrpCalRslt.size()));
        pmCmdSlabDO.setSlabDivNo(Long.valueOf(pmPdSlabDO.getSlabDivNo().intValue()));
        pmCmdSlabDO.setOrderNumInPlate(Long.valueOf(pmPdSlabDO.getOrderNumInPlate().intValue()));
        pmCmdSlabDO.setOrderRemainDiv(pmPdSlabDO.getOrderRemainDiv());
        pmCmdSlabDO.setMatDesignKind("S");
        pmCmdSlabDO.setProdCodeHp(pmProContProdTtr.getProdCodeHp());
        pmCmdSlabDO.setSgSign(pmPdSlabDO.getSgSign());
        pmCmdSlabDO.setStNo(pmPdSlabDO.getStNo());
        pmCmdSlabDO.setPreCleanSlabThick(pmPdSlabDO.getPreCleanSlabThick());
        pmCmdSlabDO.setPreCleanSlabWidth(pmPdSlabDO.getPreCleanSlabWidth());
        pmCmdSlabDO.setPreCleanSlabLen(pmPdSlabDO.getPreCleanSlabLen());
        pmCmdSlabDO.setPreCleanSlabMaxLen(pmPdSlabDO.getPreCleanSlabMaxLen());
        pmCmdSlabDO.setPreCleanSlabMinLen(pmPdSlabDO.getPreCleanSlabMinLen());
        pmCmdSlabDO.setPreCleanSlabWt(pmPdSlabDO.getPreCleanSlabWt());
        pmCmdSlabDO.setPreCleanSlabMaxWt(pmPdSlabDO.getPreCleanSlabMaxWt());
        pmCmdSlabDO.setPreCleanSlabMinWt(pmPdSlabDO.getPreCleanSlabMinWt());
        Long slabPdQty = plistPmPdSlabInfoDO.stream()
                .filter(item -> item != null && pmPdSlabDO != null && pmPdSlabDO.getSlabNo() != null && pmPdSlabDO.getSlabNo().equals(item.getSlabNo()))
                .count();
        if (slabPdQty > 0) {
            Optional<PmPdSlabInfo> resultPmPdSlabInfoDO = plistPmPdSlabInfoDO.stream()
                    .filter(item -> pmPdSlabDO.getSlabNo().equals(item.getSlabNo()))
                    .findFirst();
            pmCmdSlabDO.setMoldThick(resultPmPdSlabInfoDO.get().getMatActThick());
            pmCmdSlabDO.setMoldWid(resultPmPdSlabInfoDO.get().getMatActWidth());
        }
        pmCmdSlabDO.setSlabCleanWtLossRateSt(pmPdSlabDO.getSlabCleanWtLossRateSt());
        pmCmdSlabDO.setSlabCleanWtLossRateFr(pmPdSlabDO.getSlabCleanWtLossRateFr());
        pmCmdSlabDO.setAddSlabFlag(pmPdSlabDO.getAddSlabFlag());

        pmCmdSlabDO.setInfurSlabThick(pmPdSlabDO.getInfurSlabThick());
        pmCmdSlabDO.setInfurSlabWid(pmPdSlabDO.getInfurSlabWid());
        pmCmdSlabDO.setInfurSlabLen(pmPdSlabDO.getInfurSlabLen());
        pmCmdSlabDO.setInfurSlabMaxLen(pmPdSlabDO.getInfurSlabMaxLen());
        pmCmdSlabDO.setInfurSlabMinLen(pmPdSlabDO.getInfurSlabMinLen());
        pmCmdSlabDO.setInfurSlabWt(pmPdSlabDO.getInfurSlabWt());
        pmCmdSlabDO.setInfurSlabMaxWt(pmPdSlabDO.getInfurSlabMaxWt());
        pmCmdSlabDO.setInfurSlabMinWt(pmPdSlabDO.getInfurSlabLen());
        pmCmdSlabDO.setNeedSlabLen(pmPdSlabDO.getInfurSlabLen());
        pmCmdSlabDO.setNeedSlabWt(pmPdSlabDO.getInfurSlabWt());
        pmCmdSlabDO.setFixSlabLenFlag(String.valueOf(pmPdSlabDO.getFixSlabLenFlag()));
        pmCmdSlabDO.setFixSlabLen(pmPdSlabDO.getFixSlabLen());
        pmCmdSlabDO.setSlabPlaceCode(pmPdSlabDO.getSlabPlaceCode());
        pmCmdSlabDO.setHpFlameCleanDiv(pmPdSlabDO.getHpFlameCleanDiv());
        pmCmdSlabDO.setSlabFinishCode(pmPdSlabDO.getSlabFinishCode());
        pmCmdSlabDO.setCoolCode(pmPdSlabDO.getCoolCode());
        pmCmdSlabDO.setLastSlabFlag(String.valueOf(pmPdSlabDO.getLastSlabFlag()));
        pmCmdSlabDO.setAddSlabFlag(pmPdSlabDO.getAddSlabFlag());
        pmCmdSlabDO.setSlabPreProc1(""); //TODO  板坯预定通过工序1  文档中没有 有取合同分割值逻辑 暂时默认为空
        pmCmdSlabDO.setHotSendDiv("H");
        pmCmdSlabDO.setFurType(pmPdSlabDO.getFurType());
        pmCmdSlabDO.setHotChargeFlag("0");
        pmCmdSlabDO.setFormPlateTime(now); //TODO  组板时间 创建时间 暂时默认为当前时间
        pmCmdSlabDO.setPono(pmPdSlabDO.getPono());
        pmCmdSlabDO.setMscLineNo(pmPdSlabDO.getMscLineNo());
        pmCmdSlabDO.setIngotType(pmPdSlabDO.getIngotType());
        pmCmdSlabDO.setIgMatDesignKind(pmPdSlabDO.getIgMatDesignKind());
        pmCmdSlabDO.setOrderNoAxis(pmPdSlabDO.getOrderNoAxis());
        pmCmdSlabDO.setCreatedBy(781L);//TODO 创建人修改人，暂时默认781  BKGY
        pmCmdSlabDO.setLastUpdatedBy(781L);
        pmCmdSlabDO.setCreationDate(now);
        pmCmdSlabDO.setLastUpdateDate(now);

        pmCmdSlabDO.setTenantId(organizationId);
//        pmCmdSlabDO.setObjectVersionNumber(1L);

        pmCmdSlabDOList.add(pmCmdSlabDO);
    }

    //命令大板表
    public void SetPmCmdLargePlt(PmPdSlab pmPdSlabDO, GGrpCalRslt gGrpCalRslt, PmContMscTech pmContMscTechDO, PmProContProdTtr pmProContProdTtr, Long organizationId) {
        PmCmdLargePlt pmCmdLargePltDO = new PmCmdLargePlt();
        pmCmdLargePltDO.setRollMode(pmContMscTechDO.getRollMode());
        pmCmdLargePltDO.setHotRectifyFlag(String.valueOf(pmContMscTechDO.getHotChargeFlag()));
        pmCmdLargePltDO.setPonoSlabNo(pmPdSlabDO.getVirtualSlabNo());
        pmCmdLargePltDO.setTmpSlabNo(pmPdSlabDO.getVirtualSlabNo());
        pmCmdLargePltDO.setSlabNo(pmPdSlabDO.getSlabNo());
        pmCmdLargePltDO.setSlabDivNo(pmPdSlabDO.getSlabDivNo().longValue());
        pmCmdLargePltDO.setPdStatusHp("18");
        pmCmdLargePltDO.setFormPlateMode(pmPdSlabDO.getFormPlateMode());
        pmCmdLargePltDO.setPickModeLenDir(pmPdSlabDO.getPickModeLenDir().longValue());
        pmCmdLargePltDO.setPickModeWidDir(pmPdSlabDO.getPickModeWidDir().longValue());
        pmCmdLargePltDO.setFurType(pmPdSlabDO.getFurType());
        pmCmdLargePltDO.setAutoManualFlag(pmPdSlabDO.getAutoManualFlag());
        pmCmdLargePltDO.setOrderRemainDiv(pmPdSlabDO.getOrderRemainDiv());
        pmCmdLargePltDO.setMatDesignKind(pmPdSlabDO.getMatDesignKind());
        pmCmdLargePltDO.setOrderNumInPlate(pmPdSlabDO.getOrderNumInPlate().longValue());
        pmCmdLargePltDO.setTotSmallPlateNum(pmPdSlabDO.getTotSmallPlateNum().longValue());
        pmCmdLargePltDO.setProdCodeHp(pmProContProdTtr.getProdCodeHp());
        pmCmdLargePltDO.setAdTypeCode(pmPdSlabDO.getAdTypeCode());
        pmCmdLargePltDO.setAdModeCode(pmPdSlabDO.getAdModeCode());
        pmCmdLargePltDO.setUltCode(pmPdSlabDO.getUltCode());
        pmCmdLargePltDO.setCoolCode(pmPdSlabDO.getCoolCode());
        pmCmdLargePltDO.setCtrlRollCode(pmPdSlabDO.getCtrlRollCode());
        //TODO PM_PD_SLAB虚拟板坯号等于virtual_slab_no的PROD_SIDE_MARK，若为空或‘0’，则为‘C’，否则为PROD_SIDE_MARK  无PROD_SIDE_MARK这个字段
//        if(pmPdSlabDO.getProdSideMark() == null || pmPdSlabDO.getProdSideMark().equals("") || pmPdSlabDO.getProdSideMark().equals("0")){
//            pmCmdLargePltDO.setProdSideMark("C");
//        }else{
//            pmCmdLargePltDO.setProdSideMark(pmPdSlabDO.getProdSideMark());
//        }
        //TODO PM_PD_SLAB虚拟板坯号等于virtual_slab_no的PROD_SIDE_MARK，若为空或‘0’，则为‘C’，否则为PROD_SIDE_MARK  无PROD_SIDE_MARK这个字段
        pmCmdLargePltDO.setCutModeCode(pmPdSlabDO.getCutModeCode());
        pmCmdLargePltDO.setHeadCut(pmPdSlabDO.getHeadCut());
        pmCmdLargePltDO.setTailCut(pmPdSlabDO.getTailCut());
        pmCmdLargePltDO.setSgSign(gGrpCalRslt.getLtActInfoGPreOrder().get(0).getInfoPmProContProdAttrDO().getSgSign());//TODO 轴合同的标准牌号 暂时取第一条合同信息
        pmCmdLargePltDO.setStNo(pmPdSlabDO.getStNo());
        pmCmdLargePltDO.setTwoRollInterimFlag(String.valueOf(pmPdSlabDO.getTwoRollInterimFlag()));
        pmCmdLargePltDO.setRollAimThick(pmPdSlabDO.getRollAimThick());
        pmCmdLargePltDO.setRollAimWidth(pmPdSlabDO.getRollAimWidth());
        pmCmdLargePltDO.setRollAimLen(pmPdSlabDO.getRollAimLen());
        pmCmdLargePltDO.setRollThickTolMax(pmPdSlabDO.getRollThickTolMax());
        pmCmdLargePltDO.setRollThickTolMin(pmPdSlabDO.getRollThickTolMin());

        BigDecimal minThickTolMax = gGrpCalRslt.getLtActInfoGPreOrder().stream()
                .map(order -> order.getThickTolMax().add(order.getThk()))
                .min(BigDecimal::compareTo)
                .orElse(BigDecimal.ZERO);
        pmCmdLargePltDO.setMaxRollThick(minThickTolMax);
        BigDecimal maxThickTolMin = gGrpCalRslt.getLtActInfoGPreOrder().stream()
                .map(order -> order.getThickTolMin().add(order.getThk()))
                .max(BigDecimal::compareTo)
                .orElse(BigDecimal.ZERO);
        pmCmdLargePltDO.setMinRollThick(maxThickTolMin);

        pmCmdLargePltDO.setOrder1Thick(pmPdSlabDO.getOrderThickAxis());
        pmCmdLargePltDO.setCombinePlateWidth(pmPdSlabDO.getCombinePlateWidth());
        pmCmdLargePltDO.setCombinePlateLen(pmPdSlabDO.getCombinePlateLen());
        pmCmdLargePltDO.setRollWtHp(pmPdSlabDO.getRollWtHp());
        pmCmdLargePltDO.setNormYield(pmPdSlabDO.getNormYield());
        pmCmdLargePltDO.setCommandYield(pmPdSlabDO.getCommandYield());
        pmCmdLargePltDO.setRollYield(pmPdSlabDO.getRollYield());
        pmCmdLargePltDO.setEdgerUseFlag(pmPdSlabDO.getEdgerUseFlag());
        pmCmdLargePltDO.setBroadMasUseFlag(pmPdSlabDO.getBroadMasUseFlag());
        pmCmdLargePltDO.setFormMasUseFlag(pmPdSlabDO.getFormMasUseFlag());
        pmCmdLargePltDO.setRollDirectCode(pmPdSlabDO.getRollDirectCode());
        pmCmdLargePltDO.setSampleLenHead(pmPdSlabDO.getSampleLenHead());
        pmCmdLargePltDO.setSampleLenTail(pmPdSlabDO.getSampleLenTail());
        pmCmdLargePltDO.setSampleLenMid(pmPdSlabDO.getSampleLenMid());

        Optional<PmProContProdTtr> resultPmProContProdAttrDO = plistPmProContProdAttrDO.stream()
                .filter(item -> gGrpCalRslt.getLtActInfoGPreOrder().get(0).getOrderNo().equals(item.getOrderNo())) //TODO 根据轴合同号查询生产合同产品属性表  暂时取第一条合同
                .findFirst();
        if (resultPmProContProdAttrDO.isPresent()){
            pmCmdLargePltDO.setSampleLenGive(resultPmProContProdAttrDO.get().getSampleLenGive());
            pmCmdLargePltDO.setProdDensity(resultPmProContProdAttrDO.get().getProdDensity());
            pmCmdLargePltDO.setWithSideFlag(resultPmProContProdAttrDO.get().getProdSideMark());
        }

        pmCmdLargePltDO.setPlateDtCode(pmContMscTechDO.getPlateDtCode());

        pmCmdLargePltDO.setRsCode(pmPdSlabDO.getRsCode());
        pmCmdLargePltDO.setBroadFlag(pmPdSlabDO.getBroadFlag());
        pmCmdLargePltDO.setGFlag("");//TODO 气切可否 文档描述不清楚 暂时默认为空
        pmCmdLargePltDO.setCsFlag(""); //TODO pmPdSlabDO 无 CsFlag() 暂时默认为空
        pmCmdLargePltDO.setDsFlag(""); //TODO 若为G型组板，为‘0’；否则  取PM_PD_SLAB虚拟板坯号等于virtual_slab_no的同字段值 pmPdSlabDO 无 DsFlag() 暂时默认为空
        pmCmdLargePltDO.setDssFlag("");//TODO  若为G型组板，为‘0’；否则取PM_PD_SLAB虚拟板坯号等于virtual_slab_no的同字段值 pmPdSlabDO 无 DssFlag() 暂时默认为空
        pmCmdLargePltDO.setSsFlag("");//TODO 若为G型或A型组板，为‘0’；否则取PM_PD_SLAB虚拟板坯号等于virtual_slab_no的同字段值 pmPdSlabDO 无 SsFlag() 暂时默认为空
        pmCmdLargePltDO.setFormPlateTime(now);
        int count = gGrpCalRslt.getLtActInfoGPreOrder().size();
        pmCmdLargePltDO.setOtherPlateNo1(SMALL_PLATE_DIV_NO[count]);
        pmCmdLargePltDO.setOtherPlateNo2(SMALL_PLATE_DIV_NO[count + 1]);
        pmCmdLargePltDO.setOtherPlateNo3(SMALL_PLATE_DIV_NO[count + 2]);
        pmCmdLargePltDO.setOtherPlateNo4(SMALL_PLATE_DIV_NO[count + 3]);
        pmCmdLargePltDO.setMscLineNo(pmPdSlabDO.getMscLineNo());

        pmCmdLargePltDO.setCreatedBy(781L);//TODO 创建人修改人，暂时默认781  BKGY
        pmCmdLargePltDO.setLastUpdatedBy(781L);
        pmCmdLargePltDO.setCreationDate(now);
        pmCmdLargePltDO.setLastUpdateDate(now);

        pmCmdLargePltDO.setTenantId(organizationId);
//        pmCmdLargePltDO.setObjectVersionNumber(1L);

        pmCmdLargePltDOList.add(pmCmdLargePltDO);
    }

    //命令参数表
    public void SetPmCmdCont(PmPdContSum pmPdContSumDO, GPreOrder gPreOrder, Integer smallPlateNum, Long organizationId) {
        PmCmdCont pmCmdContDO = new PmCmdCont();
        pmCmdContDO.setSmallPlateNum(Long.valueOf(smallPlateNum));
        pmCmdContDO.setPonoSlabNo(pmPdContSumDO.getPdMatNo());
        pmCmdContDO.setTmpSlabNo(pmPdContSumDO.getPdMatNo());
        pmCmdContDO.setOrderNo(pmPdContSumDO.getOrderNo());
        pmCmdContDO.setOrderSeqNo(pmPdContSumDO.getOrderSeqNo().longValue());

        String orderNo = pmPdContSumDO.getOrderNo();
        String mscLineNo = gPreOrder.getInfoPmContMscTechDO().getMscLineNo();
        Optional<PmContMscTech> pmContMscTechDOItem = plistPmContMscTechDO.stream()
                .filter(item -> orderNo.equals(item.getOrderNo()) && mscLineNo.equals(item.getMscLineNo()))
                .findFirst();
        pmCmdContDO.setWholeBacklog(pmContMscTechDOItem.get().getWholeBacklog());
        pmCmdContDO.setStNo(pmContMscTechDOItem.get().getStNo());
        pmCmdContDO.setRollMode(pmContMscTechDOItem.get().getRollMode());

        Optional<PmPdSlab> pmPdSlabDOItem = pmPdSlabDOList.stream()
                .filter(item -> pmPdContSumDO.getPdMatNo().equals(item.getVirtualSlabNo()))
                .findFirst();
        pmCmdContDO.setMatDesignKind(pmPdSlabDOItem.get().getMatDesignKind());
        pmCmdContDO.setSlabNo(pmPdSlabDOItem.get().getSlabNo());

        pmCmdContDO.setOrderTypeCode(gPreOrder.getInfoPmProContProdAttrDO().getOrderTypeCode());
        pmCmdContDO.setExportFlag(String.valueOf(gPreOrder.getInfoPmProContProdAttrDO().getExportFlag()));
        pmCmdContDO.setFinCustCode(gPreOrder.getInfoPmProContProdAttrDO().getFinCustCode());
        pmCmdContDO.setPsc(gPreOrder.getInfoPmProContProdAttrDO().getPsc());
        pmCmdContDO.setApn(gPreOrder.getInfoPmProContProdAttrDO().getApn());
        pmCmdContDO.setMsc(gPreOrder.getInfoPmProContProdAttrDO().getMsc());
        pmCmdContDO.setProdCodeHp(gPreOrder.getInfoPmProContProdAttrDO().getProdCodeHp());
        pmCmdContDO.setSgStd(gPreOrder.getInfoPmProContProdAttrDO().getSgStd());
        pmCmdContDO.setSmallPlateLen(pmPdContSumDO.getOrderPlateNum());
        pmCmdContDO.setProdSrMark(gPreOrder.getInfoPmProContProdAttrDO().getProdSrMark());
        pmCmdContDO.setProdSideMark(gPreOrder.getInfoPmProContProdAttrDO().getProdSideMark());
        pmCmdContDO.setProdShotMark(gPreOrder.getInfoPmProContProdAttrDO().getProdShotMark());
        pmCmdContDO.setProdNMark(gPreOrder.getInfoPmProContProdAttrDO().getProdNMark());
        pmCmdContDO.setProdQMark(gPreOrder.getInfoPmProContProdAttrDO().getProdQMark());
        pmCmdContDO.setProdTMark(gPreOrder.getInfoPmProContProdAttrDO().getProdTMark());
        pmCmdContDO.setProdAMark(gPreOrder.getInfoPmProContProdAttrDO().getProdAMark());
        pmCmdContDO.setBacklogUtMark(gPreOrder.getInfoPmProContProdAttrDO().getBacklogUtMark());
        pmCmdContDO.setBacklogQMark(gPreOrder.getInfoPmProContProdAttrDO().getBacklogQMark());
        pmCmdContDO.setBacklogTMark(gPreOrder.getInfoPmProContProdAttrDO().getBacklogTMark());
        pmCmdContDO.setBacklogAMark(gPreOrder.getInfoPmProContProdAttrDO().getBacklogAMark());
        pmCmdContDO.setBacklogNMark(gPreOrder.getInfoPmProContProdAttrDO().getBacklogNMark());
        pmCmdContDO.setBacklogDemagMark(gPreOrder.getInfoPmProContProdAttrDO().getBacklogDemagMark());
        pmCmdContDO.setBacklogPtMark(gPreOrder.getInfoPmProContProdAttrDO().getBacklogPtMark());
        pmCmdContDO.setBacklogMtMark(gPreOrder.getInfoPmProContProdAttrDO().getBacklogMtMark());
        pmCmdContDO.setBacklogTmcpMark(gPreOrder.getInfoPmProContProdAttrDO().getBacklogTmcpMark());
        pmCmdContDO.setUnitWtMax(gPreOrder.getInfoPmProContProdAttrDO().getOrderUnitMaxWt());
        pmCmdContDO.setUnitWtMin(gPreOrder.getInfoPmProContProdAttrDO().getOrderUnitMinWt());
        pmCmdContDO.setUnitWtAim(gPreOrder.getInfoPmProContProdAttrDO().getOrderUnitAimWt());
        pmCmdContDO.setOrderThick(gPreOrder.getInfoPmProContProdAttrDO().getOrderThick());
        pmCmdContDO.setOrderLen(gPreOrder.getInfoPmProContProdAttrDO().getOrderLen());
        pmCmdContDO.setOrderWidth(gPreOrder.getInfoPmProContProdAttrDO().getOrderWidth());
        pmCmdContDO.setWidthDiv(String.valueOf(gPreOrder.getInfoPmProContProdAttrDO().getWidthDiv()));
        pmCmdContDO.setWidthMin(gPreOrder.getInfoPmProContProdAttrDO().getWidthMin());
        pmCmdContDO.setWidthMax(gPreOrder.getInfoPmProContProdAttrDO().getWidthMax());
        pmCmdContDO.setLenDiv(String.valueOf(gPreOrder.getInfoPmProContProdAttrDO().getLenDiv()));
        pmCmdContDO.setOrderLenMin(gPreOrder.getInfoPmProContProdAttrDO().getOrderMinLen());
        pmCmdContDO.setOrderLenMax(gPreOrder.getInfoPmProContProdAttrDO().getOrderMaxLen());
        pmCmdContDO.setSmallPlateThick(pmPdContSumDO.getSmallPlateThick());
        pmCmdContDO.setSgSign(pmPdSlabDOItem.get().getSgSign());
        pmCmdContDO.setSmallPlateWidth(pmPdContSumDO.getSmallPlateWidth());
        pmCmdContDO.setSmallPlateLen(pmPdContSumDO.getSmallPlateLen());
        pmCmdContDO.setTrimCode(gPreOrder.getInfoPmProContProdAttrDO().getTrimCode());
        pmCmdContDO.setWidenMin(pmContMscTechDOItem.get().getWidenMin());
        pmCmdContDO.setCompressMin(pmContMscTechDOItem.get().getCompressMin());
        pmCmdContDO.setRollDirectCode(pmContMscTechDOItem.get().getRollDirectCode());
        pmCmdContDO.setCtrlRollCode(pmContMscTechDOItem.get().getCtrlRollCode());
        pmCmdContDO.setAdTypeCode(pmContMscTechDOItem.get().getAdTypeCode());
        pmCmdContDO.setAdModeCode(pmContMscTechDOItem.get().getAdModeCode());
        pmCmdContDO.setHotRectifyFlag(String.valueOf(pmContMscTechDOItem.get().getHotRectifyFlag()));
        pmCmdContDO.setHeadCut(pmPdSlabDOItem.get().getHeadCut());
        pmCmdContDO.setTailCut(pmPdSlabDOItem.get().getTailCut());
        pmCmdContDO.setCutModeCode(pmContMscTechDOItem.get().getAdModeCode());
        if (pmContMscTechDOItem.get().getGFlag() != null) {
            pmCmdContDO.setGFlag(String.valueOf(pmContMscTechDOItem.get().getGFlag()));
        }
        if (pmContMscTechDOItem.get().getCsFlag() != null) {
            pmCmdContDO.setCsFlag(String.valueOf(pmContMscTechDOItem.get().getCsFlag()));
        }
        if (pmContMscTechDOItem.get().getDssFlag() != null) {
            pmCmdContDO.setDssFlag(String.valueOf(pmContMscTechDOItem.get().getDssFlag()));
        }
        if (pmContMscTechDOItem.get().getDsFlag() != null) {
            pmCmdContDO.setDsFlag(String.valueOf(pmContMscTechDOItem.get().getDsFlag()));
        }
        if (pmContMscTechDOItem.get().getSsFlag() != null) {
            pmCmdContDO.setSsFlag(String.valueOf(pmContMscTechDOItem.get().getSsFlag()));
        }
        pmCmdContDO.setHeatTreatMode(pmContMscTechDOItem.get().getHeatTreatMode());
        pmCmdContDO.setUltDetectMethodCode(pmContMscTechDOItem.get().getUltDetectMethodCode());
        pmCmdContDO.setUrgOrderFlag(pmPdSlabDOItem.get().getUrgOrderFlag());
        pmCmdContDO.setUltCode(pmPdSlabDOItem.get().getUltCode());//TODO 遍根据合同号从质量模块MES合同主档QD_TO_PO_ORDER读取超声探伤标准1、超声探伤标2、超声探伤标3、超声探伤标4、超声探伤标5，去重后所有数据用‘-’拼接成一条记录
        pmCmdContDO.setMscLineNo(mscLineNo);
        pmCmdContDO.setAxisFlag(0L);//TODO 轴合同标记，暂时默认0

        pmCmdContDO.setCreatedBy(781L);//TODO 创建人修改人，暂时默认781  BKGY
        pmCmdContDO.setLastUpdatedBy(781L);
        pmCmdContDO.setCreationDate(now);
        pmCmdContDO.setLastUpdateDate(now);

        pmCmdContDO.setTenantId(organizationId);
//        pmCmdContDO.setObjectVersionNumber(1L);

        pmCmdContDOList.add(pmCmdContDO);
    }

    //命令小板表
    public void SetPmCmdSmallPlt(PmSmallPltPos pmSmallPltPosDO, PmProContProdTtr pmProContProdAttrDO, String mscLineNo, Long organizationId) {
        PmCmdSmallPlt pmCmdSmallPltDO = new PmCmdSmallPlt();
        pmCmdSmallPltDO.setPonoSlabNo(pmSmallPltPosDO.getPdMatNo());
        pmCmdSmallPltDO.setTmpSlabNo(pmSmallPltPosDO.getPdMatNo());
        pmCmdSmallPltDO.setSmallPlateDivNo(pmSmallPltPosDO.getSmallPlateDivNo());
        pmCmdSmallPltDO.setOrderNo(pmSmallPltPosDO.getOrderNo());
        pmCmdSmallPltDO.setOrderSeqNo(Long.valueOf(pmSmallPltPosDO.getOrderSeqNo()));
        pmCmdSmallPltDO.setSlabNo(pmSmallPltPosDO.getSlabNo());
        pmCmdSmallPltDO.setPickModeWidDir(pmSmallPltPosDO.getPickModeWidDir());
        pmCmdSmallPltDO.setPickModeLenDir(pmSmallPltPosDO.getPickModeLenDir());
        pmCmdSmallPltDO.setOrderThick(pmSmallPltPosDO.getOrderThick());
        pmCmdSmallPltDO.setOrderWidth(pmSmallPltPosDO.getOrderWidth());
        pmCmdSmallPltDO.setOrderLen(pmSmallPltPosDO.getOrderLen());
        pmCmdSmallPltDO.setOrderLenMin(pmSmallPltPosDO.getOrderLenMin());
        pmCmdSmallPltDO.setOrderLenMax(pmSmallPltPosDO.getOrderLenMax());
        pmCmdSmallPltDO.setSmallPlateThick(pmSmallPltPosDO.getSmallPlateThick());
        pmCmdSmallPltDO.setSmallPlateWidth(pmSmallPltPosDO.getSmallPlateWidth());
        pmCmdSmallPltDO.setSmallPlateLen(pmSmallPltPosDO.getSmallPlateLen());
//        pmCmdSmallPltDO.setSampleLenGive(BigDecimal.valueOf(pmProContProdAttrDO.getSampleLenGive())); //TODO 对比数据手动组板为空
        pmCmdSmallPltDO.setMscLineNo(mscLineNo);
        pmCmdSmallPltDO.setCreatedBy(781L);//TODO 创建人修改人，暂时默认781  BKGY
        pmCmdSmallPltDO.setLastUpdatedBy(781L);
        pmCmdSmallPltDO.setCreationDate(now);
        pmCmdSmallPltDO.setLastUpdateDate(now);

        pmCmdSmallPltDO.setTenantId(organizationId);
//        pmCmdSmallPltDO.setObjectVersionNumber(1L);

        pmCmdSmallPltDOList.add(pmCmdSmallPltDO);
    }

    public void SetPmPdRecDTO(List<String> orderNoList, Long organizationId,String mscLineNo,String virtualSlabNo) {
        CustomUserDetails userDetails = DetailsHelper.getUserDetails();
        for (String orderNo : orderNoList) {
            PmPdRecDTO pmPdRecDTO = new PmPdRecDTO();
            pmPdRecDTO.setOrderNo(orderNo);
            pmPdRecDTO.setEventMaker(userDetails == null ? "": userDetails.getUserId().toString());
            pmPdRecDTO.setMscLineNo(mscLineNo);
            pmPdRecDTO.setKeyvalue1Desc(PmPdRecDTO.DESC_VIRTUAL_SLAB_NO);
            pmPdRecDTO.setKeyvalue1(virtualSlabNo);
            pmPdRecDTO.setMatNo(virtualSlabNo);
            pmPdRecDTO.setQty(BigDecimal.ZERO);
            pmPdRecs.add(pmPdRecDTO);
        }
        //抛合同
//        zbCtEventRec(orderNoList, organizationId,mscLineNo,virtualSlabNo,pmSmallPltPosDOList);

    }

    public void SaveData(SlabInfoDO p, Long organizationId, PmSubLog subLog) {
//        batchInsertPmPdSlab(pmPdSlabDOList);
//        System.out.println("PmPdSlab表一保存成功");
//        batchInsertPmCmdSlab(pmCmdSlabDOList);
//        System.out.println("PmCmdSlab表二保存成功");
//        batchInsertPmCmdLargePlt(pmCmdLargePltDOList);
//        System.out.println("pmCmdLargePltDO 命令大板 保存成功");
//        batchInsertPmPdPlateCut(pmPdPlateCutDOList);
//        System.out.println("PmPdPlateCut 大板粗切位置表 保存成功");
//        batchInsertPmPdBlockPos(pmPdBlockPosDOList);
//        System.out.println("PmPdBlockPos 组合子板位置表 保存成功");
//        batchInsertPmPdContSum(pmPdContSumDOList);
//        System.out.println("PmPdContSum 合同总量表 保存成功");
//        batchInsertPmSmallPltPos(pmSmallPltPosDOList);
//        System.out.println("PmSmallPltPos 命令小板位置表 保存成功");
//        batchInsertPmCmdSmallPlt(pmCmdSmallPltDOList);
//        System.out.println("PmCmdSmallPlt 命令小板表 保存成功");
//        batchInsertPmCmdCont(pmCmdContDOList);
//        System.out.println("PmCmdCont 命令参数 保存成功");

        SaveData(p,pmPdSlabDOList, pmPdPlateCutDOList, pmPdBlockPosDOList, pmPdContSumDOList, pmSmallPltPosDOList, pmCmdSlabDOList, pmCmdLargePltDOList, pmCmdContDOList, pmCmdSmallPltDOList,plistpmSubHisDO,plistpmSubOrdDO,pmPdRecs,organizationId);
    }

    @Autowired
    private SubMapper subMapper;

    @Autowired
    private PmPdSlabRepository pmPdSlabRepository;

    @Autowired
    private PmCmdSlabRepository pmCmdSlabRepository;

    @Autowired
    private PmCmdLargePltRepository pmCmdLargePltRepository;

    @Autowired
    private PmPdContSumRepository pmPdContSumRepository;

    @Autowired
    private PmPdBlockPosRepository pmPdBlockPosRepository;

    @Autowired
    private PmPdPlateCutRepository pmPdPlateCutRepository;

    @Autowired
    private PmSmallPltPosRepository pmSmallPltPosRepository;

    @Autowired
    private PmCmdSmallPltRepository pmCmdSmallPltRepository;

    @Autowired
    private PmCmdContRepository pmCmdContRepository;

    @Autowired
    private PmSubHisRepository pmSubHisRepository;

    @Autowired
    private PmSubOrdRepository pmSubOrdRepository;

    @Autowired
    private PmPdSlabInfoRepository pmPdSlabInfoRepository;

    @Autowired
    private MmEventClient mmEventClient;

    @Autowired
    private RedisHelper redisHelper;

    @Autowired
    private PmPdRecService pmPdRecService;

    @Autowired
    private PmProContRepository pmProContRepository;

    @Autowired
    private PmSubLogRepository pmSubLogRepository;

    @Autowired
    protected EventClient eventClient;

    //    获取板坯信息
    @Override
    public List<SlabInfoDO> getSlabInfo(SubParams subParams) {

        return subMapper.getSlabInfo(subParams);

    }

    //    获取订单信息
    @Override
    public List<PmProCont> getOrderInfo() {

        return subMapper.getOrderInfo();

    }

    //    生产合同产品属性表
    @Override
    public List<PmProContProdTtr> getPmProCountProdAttr() {

        return subMapper.getPmProCountProdAttr();

    }

    //    合同产线工艺参数表
    @Override
    public List<PmContMscTech> getPmContMscTech() {

        return subMapper.getPmContMscTech();

    }

    //    组板设计规则集
    @Override
    public List<PmPdRuleSet> getPmPdRuleSet() {

        return subMapper.getPmPdRuleSet();

    }

    //    组板设计规则集详细
    @Override
    public List<PmPdRuleItem> getPmPdRuleItem() {

        return subMapper.getPmPdRuleItem();

    }

    //    最小轧制厚度公差范围基准表
    @Override
    public List<PmMinThickTolBt> getPmMinThickTolBt() {

        return subMapper.getPmMinThickTolBt();

    }

    //    钢板轧制规格对应收得率基准表
    @Override
    public List<PmPlateSpecYieldBt> getPmPlateSpecYieldBt() {

        return subMapper.getPmPlateSpecYieldBt();

    }

    //    强度级别对照基准表
    @Override
    public List<PmStCodeBt> getPmStCodeBt() {

        return subMapper.getPmStCodeBt();

    }

    //    粗切位置决定基准表
    @Override
    public List<PmCutPlaceBt> getPmCutPlaceBt() {

        return subMapper.getPmCutPlaceBt();

    }

    //    组板常数基准表
    @Override
    public List<PmPdConstBt> getPmPdConstBt() {

        return subMapper.getPmPdConstBt();

    }

    //    钢板切缝切头尾范围基准表
    @Override
    public List<PmPlateCutLenBt> getPmPlateCutLenBt() {

        return subMapper.getPmPlateCutLenBt();

    }

    //    组板临时收得率基准表
    @Override
    public List<PmPdTmpYieldBt> getPmPdTmpYieldBt() {

        return subMapper.getPmPdTmpYieldBt();

    }

    //    钢板切边量基准表
    @Override
    public List<PmPlateTrimBt> getPmPlateTrimBt() {

        return subMapper.getPmPlateTrimBt();

    }

    //    余材组板内部钢种以优充次对照表
    @Override
    public List<PmSlabReplBt> getPmSlabReplBt() {

        return subMapper.getPmSlabReplBt();

    }

    //    热处理炉基准规格表
    @Override
    public List<PmHeatTreatFurnaceBt> getPmHeatTreatFurnaceBt() {

        return subMapper.getPmHeatTreatFurnaceBt();

    }

    //    特殊钢种余量增加表
    @Override
    public List<PmSpeStAddvBt> getPmSpeStAddvBt() {

        return subMapper.getPmSpeStAddvBt();

    }

    //合同处理成分结果数据
    @Override
    public List<QdToLineupResultCheDO> getQdToLineupResultChe() {
        return subMapper.getQdToLineupResultChe();
    }

    //合同处理坯料性能要求
    @Override
    public List<QdToLineupResultSlabphyDO> getQdToLineupResultSlabphy() {
        return subMapper.getQdToLineupResultSlabphy();
    }

    //炉次工序成分代表实绩表
    @Override
    public List<QeTqHeatcheStandResultDO> getQeTqHeatcheStandResult() {
        return subMapper.getQeTqHeatcheStandResult();
    }

    //炉次待委托表
    @Override
    public List<QeTqPonoWaitTestDO> getQeTqPonoWaitTest() {
        return subMapper.getQeTqPonoWaitTest();
    }

    //坯料低倍委托实绩表
    @Override
    public List<QeTqSlabMacroResultDO> getQeTqSlabMacroResult() {
        return subMapper.getQeTqSlabMacroResult();
    }

    //连铸板坯生产规格基准表
    @Override
    public List<PmSlabSpecBt> getPmSlabSpecBt() {
        return subMapper.getPmSlabSpecBt();
    }

    @Override
    public void batchInsert(List<PmSubOrd> pmSubOrdDOList) {
        subMapper.batchInsert(pmSubOrdDOList);
    }

    @Override
    public void batchInsertPmSubHisDO(List<PmSubHis> pmSubHisDOList) {
        subMapper.batchInsertPmSubHisDO(pmSubHisDOList);
    }

    @Override
    public void InsertPmSubHisDO(PmSubHis p) {
        subMapper.InsertPmSubHisDO(p);
    }

    @Override
    public void InsertPmSubOrdDO(PmSubOrd p) {
        subMapper.InsertPmSubOrdDO(p);
    }

    @Override
    public List<PmIrsubableCont> getPmIrsubableCont() {
        return subMapper.getPmIrsubableCont();
    }

    @Override
    public List<PmIrsubableSlab> getPmIrsubableSlab() {
        return subMapper.getPmIrsubableSlab();
    }

    @Override
    public List<PmAutoSubSetting> getPmAutoSubSetting() {
        return subMapper.getPmAutoSubSetting();
    }

    @Override
    public List<PmRetainSt> getPmRetainSt() {
        return subMapper.getPmRetainSt();
    }

    @Override
    public List<PmRetainStack> getPmRetainStack() {
        return subMapper.getPmRetainStack();
    }

    @Override
    public List<PmPdSlabInfo> getPmPdSlabInfo(SubParams subParams) {
        return subMapper.getPmPdSlabInfo(subParams);
    }

    @Override
    public List<QdToPoOrder> getQdToPoOrder() {
        return subMapper.getQdToPoOrder();
    }


//    @Override
//    public void batchInsertPmPdSlab(List<PmPdSlab> pmPdSlabDOList) {
////        BigDecimal id = subMapper.getMaxPmPdSlabId();
//        for (int i = 0 ; i < pmPdSlabDOList.size() ; i++){
////            pmPdSlabDOList.get(i).setPmPdSlabId(id.add(BigDecimal.valueOf(i+1)));
//            pmPdSlabDOList.get(i).setTenantId(1L);
//            pmPdSlabDOList.get(i).setObjectVersionNumber(1L);
//            subMapper.insertPmPdSlab(pmPdSlabDOList.get(i));
//        }
////        subMapper.batchInsertPmPdSlab(pmPdSlabDOList);
//    }
//
//    @Override
//    public void batchInsertPmCmdSlab(List<PmCmdSlab> pmCmdSlabDOList) {
////        BigDecimal id = subMapper.getMaxPmCmdSlabId();
//        for (int i = 0 ; i < pmCmdSlabDOList.size() ; i++){
////            pmCmdSlabDOList.get(i).setPmCmdSlabId(id.add(BigDecimal.valueOf(i+1)));
//            pmCmdSlabDOList.get(i).setTenantId(1L);
//            pmCmdSlabDOList.get(i).setObjectVersionNumber(1L);
//            subMapper.insertPmCmdSlab(pmCmdSlabDOList.get(i));
//        }
////        subMapper.batchInsertPmCmdSlab(pmCmdSlabDOList);
//    }
//
//    @Override
//    public void insertPmPdSlab(PmPdSlab p) {
//        subMapper.insertPmPdSlab(p);
//    }
//
//    @Override
//    public void batchInsertPmCmdLargePlt(List<PmCmdLargePlt> pmCmdLargePltDOList) {
////        BigDecimal id = subMapper.getMaxPmCmdLargePltId();
//        for (int i = 0 ; i < pmCmdLargePltDOList.size() ; i++){
////            pmCmdLargePltDOList.get(i).setPmCmdLargePltId(id.add(BigDecimal.valueOf(i+1)));
//            pmCmdLargePltDOList.get(i).setTenantId(1L);
//            pmCmdLargePltDOList.get(i).setObjectVersionNumber(1L);
//            subMapper.insertPmCmdLargePlt(pmCmdLargePltDOList.get(i));
//        }
//    }
//
//    @Override
//    public void batchInsertPmPdPlateCut(List<PmPdPlateCut> pmPdPlateCutDOList) {
////        BigDecimal id = subMapper.getMaxPmPdPlateCutId();
//        for (int i = 0 ; i < pmPdPlateCutDOList.size() ; i++){
////            pmPdPlateCutDOList.get(i).setCutId(id.add(BigDecimal.valueOf(i+1)));
//            pmPdPlateCutDOList.get(i).setTenantId(1L);
//            pmPdPlateCutDOList.get(i).setObjectVersionNumber(1L);
//            subMapper.insertPmPdPlateCut(pmPdPlateCutDOList.get(i));
//        }
//    }
//
//    @Override
//    public void batchInsertPmPdBlockPos(List<PmPdBlockPos> pmPdBlockPosDOList) {
////        BigDecimal id = subMapper.getMaxPmPdBlockPosId();
//        for (int i = 0 ; i < pmPdBlockPosDOList.size() ; i++){
////            pmPdBlockPosDOList.get(i).setPdBlockPosId(id.add(BigDecimal.valueOf(i+1)));
//            pmPdBlockPosDOList.get(i).setTenantId(1L);
//            pmPdBlockPosDOList.get(i).setObjectVersionNumber(1L);
//            subMapper.insertPmPdBlockPos(pmPdBlockPosDOList.get(i));
//        }
//    }
//
//    @Override
//    public void batchInsertPmPdContSum(List<PmPdContSum> pmPdContSumDOList) {
////        BigDecimal id = subMapper.getMaxPmPdContSumId();
//        for (int i = 0 ; i < pmPdContSumDOList.size() ; i++){
////            pmPdContSumDOList.get(i).setPpcsId(id.add(BigDecimal.valueOf(i+1)));
//            pmPdContSumDOList.get(i).setTenantId(1L);
//            pmPdContSumDOList.get(i).setObjectVersionNumber(1L);
//            subMapper.insertPmPdContSum(pmPdContSumDOList.get(i));
//        }
//    }
//
//    @Override
//    public void batchInsertPmSmallPltPos(List<PmSmallPltPos> pmSmallPltPosDOList) {
////        BigDecimal id = subMapper.getMaxPmSmallPltPosId();
//        for (int i = 0 ; i < pmSmallPltPosDOList.size() ; i++){
////            pmSmallPltPosDOList.get(i).setPsppId(id.add(BigDecimal.valueOf(i+1)));
//            pmSmallPltPosDOList.get(i).setTenantId(1L);
//            pmSmallPltPosDOList.get(i).setObjectVersionNumber(1L);
//            subMapper.insertPmSmallPltPos(pmSmallPltPosDOList.get(i));
//        }
//    }
//
//    @Override
//    public void batchInsertPmCmdSmallPlt(List<PmCmdSmallPlt> pmCmdSmallPltDOList) {
////        BigDecimal id = subMapper.getMaxPmCmdSmallPltId();
//        for (int i = 0 ; i < pmCmdSmallPltDOList.size() ; i++){
////            pmCmdSmallPltDOList.get(i).setPmCmdSmallPltId(id.add(BigDecimal.valueOf(i+1)));
//            pmCmdSmallPltDOList.get(i).setTenantId(1L);
//            pmCmdSmallPltDOList.get(i).setObjectVersionNumber(1L);
//            subMapper.insertPmCmdSmallPlt(pmCmdSmallPltDOList.get(i));
//        }
//    }
//
//    @Override
//    public void batchInsertPmCmdCont(List<PmCmdCont> pmCmdContDOList) {
////        BigDecimal id = subMapper.getMaxPmCmdContId();
//        for (int i = 0 ; i < pmCmdContDOList.size() ; i++){
////            pmCmdContDOList.get(i).setPmCmdContId(id.add(BigDecimal.valueOf(i+1)));
//            pmCmdContDOList.get(i).setTenantId(1L);
//            pmCmdContDOList.get(i).setObjectVersionNumber(1L);
//            subMapper.insertPmCmdCont(pmCmdContDOList.get(i));
//        }
//    }

    @Override
    public String GetMaxSeq(String pono) {
        return subMapper.GetMaxSeq(pono);
    }

    @Override
    public List<PmThickAddvBt> getPmThickAddvBt() {
        return subMapper.getPmThickAddvBt();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void SaveData(SlabInfoDO p, List<PmPdSlab> pmPdSlabDOList, List<PmPdPlateCut> pmPdPlateCutDOList, List<PmPdBlockPos> pmPdBlockPosDOList, List<PmPdContSum> pmPdContSumDOList, List<PmSmallPltPos> pmSmallPltPosDOList, List<PmCmdSlab> pmCmdSlabDOList, List<PmCmdLargePlt> pmCmdLargePltDOList, List<PmCmdCont> pmCmdContDOList, List<PmCmdSmallPlt> pmCmdSmallPltDOList, List<PmSubHis> plistpmSubHisDO, List<PmSubOrd> plistpmSubOrdDO, List<PmPdRecDTO> pmPdRecDTOList, Long organizationId) {


//        //抛合同事件
//        String bizId = pmPdRecDTOList.get(0).getKeyvalue1();
//        String key = String.format(PmPlateConstants.YIELD_EXEC_LOCK_KEY, organizationId.toString(), bizId);
//        if (redisHelper.hasKey(key)) {
//            throw new CommonException("pm.pm_pro_cont_043", bizId);
//        }
//
//        PdMatTypeStrategy pdMatTypeStrategy = PdMatTypeStrategyFactory.matchStrategy("S");
//        try {
//            // 抛合同组板事件
//            pmPdRecService.createEvent(organizationId, pmPdRecDTOList
//                    , PdEventType.HP04, Constants.SYSTEM_PD_CODE, pdMatTypeStrategy.pdProgram());
//            redisHelper.strSet(key, "1", 30L, TimeUnit.SECONDS);
//            // 抛组板履历事件
//            List<PmPdRecDTO> pmPdRecs = new ArrayList<>();
//            CustomUserDetails userDetails = DetailsHelper.getUserDetails();
//            for (PmPdContSum contSum : pmPdContSumDOList) {
//                PmPdRecDTO pmPdRecDTO = new PmPdRecDTO();
//                pmPdRecDTO.setOrderNo(contSum.getOrderNo());
//                pmPdRecDTO.setEventMaker(userDetails == null ? "" : userDetails.getUserId().toString());
//                pmPdRecDTO.setMscLineNo(pmPdRecDTOList.get(0).getMscLineNo());
//                pmPdRecDTO.setKeyvalue1(bizId);
//                pmPdRecDTO.setKeyvalue1Desc(PmPdRecDTO.DESC_VIRTUAL_SLAB_NO);
//                pmPdRecDTO.setMatNo(bizId);
//                pmPdRecDTO.setQty(contSum.getOrderPlateNum());
//                pmPdRecs.add(pmPdRecDTO);
//            }
//            pmPdRecService.createEvent(organizationId, pmPdRecs, PdEventType.HP10,
//                    Constants.SYSTEM_PD_CODE, "余材板坯组板");
//            System.out.println("抛合同组板事件 执行成功");
//            // 抛合同
//
//
//        } finally {
//            // 抛合同组板释放事件
//            pmPdRecService.createEvent(organizationId, pmPdRecDTOList
//                    , PdEventType.HP05, Constants.SYSTEM_PD_CODE, pdMatTypeStrategy.pdProgram());
//            redisHelper.delKey(key);
//        }


        if (plistpmSubHisDO.size() > 0) {
            pmSubHisRepository.batchInsertSelective(plistpmSubHisDO);
            System.out.println("pmSubHis表 保存成功");
        }
        if (plistpmSubOrdDO.size() > 0) {
            pmSubOrdRepository.batchInsertSelective(plistpmSubOrdDO);
            System.out.println("pmSubOrd表 保存成功");
        }
////
//        if (pmPdSlabDOList.size() > 0) {
//            pmPdSlabRepository.batchInsertSelective(pmPdSlabDOList);
//            System.out.println("PmPdSlab表 保存成功");
//        }
//        if (pmPdPlateCutDOList.size() > 0) {
//            pmPdPlateCutRepository.batchInsertSelective(pmPdPlateCutDOList);
//            System.out.println("PmPdPlateCut 大板粗切位置 保存成功");
//        }
//        if (pmPdBlockPosDOList.size() > 0) {
//            pmPdBlockPosRepository.batchInsertSelective(pmPdBlockPosDOList);
//            System.out.println("PmPdBlockPos 组合子板位置表 保存成功");
//        }
//        if (pmPdContSumDOList.size() > 0) {
//            pmPdContSumRepository.batchInsertSelective(pmPdContSumDOList);
//            System.out.println("PmPdContSum 合同总量表 保存成功");
//        }
//        if (pmSmallPltPosDOList.size() > 0) {
//            pmSmallPltPosRepository.batchInsertSelective(pmSmallPltPosDOList);
//            System.out.println("PmSmallPltPos 命令小板位置表  保存成功");
//        }
//        if (pmCmdSlabDOList.size() > 0) {
//            pmCmdSlabRepository.batchInsertSelective(pmCmdSlabDOList);
//            System.out.println("PmCmdSlab 保存成功");
//        }
//        if (pmCmdLargePltDOList.size() > 0) {
//            pmCmdLargePltRepository.batchInsertSelective(pmCmdLargePltDOList);
//            System.out.println("pmCmdLargePltDO 命令大板 保存成功");
//        }
//        if (pmCmdContDOList.size() > 0) {
//            pmCmdContRepository.batchInsertSelective(pmCmdContDOList);
//            System.out.println("PmCmdCont 命令参数 保存成功");
//        }
//        if (pmCmdSmallPltDOList.size() > 0) {
//            pmCmdSmallPltRepository.batchInsertSelective(pmCmdSmallPltDOList);
//            System.out.println("PmCmdSmallPlt 命令小板表 保存成功");
//        }
//
//        // 调用mm接口
//        // 查询MM_SLAB 信息获取板坯信息
//        PmPdSlabSplitDTO pmPdSlabSplitDTO = pmPdSlabRepository.selectMmSlabBySlabId(p.getSlabId(), p.getTenantId());
//        // 查询板坯信息表。第一次查询可能无值
//        PmPdSlabInfo pmPdSlabInfo = pmPdSlabInfoRepository.selectBySlabNo(p.getSlabNo(), p.getTenantId());
//
//        pmPdSlabInfo = buildPmPdSlabInfo(pmPdSlabSplitDTO, p.getSlabNo(), p.getMscLineNo(), p.getTenantId());
//        pmPdSlabInfoRepository.insertSelective(pmPdSlabInfo);
//        System.out.println("pmPdSlabInfo表 保存成功");
//
//        // 轧钢模块“在制品材料管理封锁事件接口"
//        callMatStatusModify(pmPdSlabInfo);
//        System.out.println("mm模块接口 调用成功");
//        System.out.println("程序执行完成！");
//
//        //抛合同
//        zbCtEventRec(organizationId, pmPdSlabDOList, pmCmdLargePltDOList, pmCmdSlabDOList, pmSmallPltPosDOList);
//        System.out.println("抛合同事件完成");
//


    }

    @Override
    public void saveSubLog(String slabNo, long subMode, String subRslt, String subLog, Long organizationId) {
        PmSubLog pmSubLog = new PmSubLog();
        pmSubLog.setSubDate(new java.util.Date());
        pmSubLog.setSlabNo(slabNo);
        pmSubLog.setSubMode(subMode);
        pmSubLog.setSubRslt(subRslt);
        pmSubLog.setSubLog(subLog);
        pmSubLog.setTenantId(organizationId);
        pmSubLogRepository.insertSelective(pmSubLog);
    }

    public void zbCtEventRec(Long organizationId, List<PmPdSlab> pmPdSlabDOList, List<PmCmdLargePlt> pmCmdLargePltDOList, List<PmCmdSlab> pmCmdSlabDOList, List<PmSmallPltPos> pmSmallPltPosDOList) {
        for (PmPdSlab pmPdSlab : pmPdSlabDOList) {
            List<PmSmallPltPos> smallPltPosList = pmSmallPltPosDOList.stream()
                    .filter(p -> p.getPdMatNo().equals(pmPdSlab.getVirtualSlabNo()))
                    .collect(Collectors.toList());
            List<PmCmdLargePlt> largePltList = pmCmdLargePltDOList.stream()
                    .filter(p -> p.getPonoSlabNo().equals(pmPdSlab.getVirtualSlabNo()))
                    .collect(Collectors.toList());
            List<PmCmdSlab> slabList = pmCmdSlabDOList.stream()
                    .filter(p -> p.getVirtualSlabNo().equals(pmPdSlab.getVirtualSlabNo()))
                    .collect(Collectors.toList());
            List<String> orderNoList = smallPltPosList.stream().map(p -> p.getOrderNo()).collect(Collectors.toList());
            Map<String, PmProContFilterResposeDTO> filterOrderMap = pmProContRepository.orderFilterMap(orderNoList, organizationId, pmPdSlab.getMscLineNo());
            List<ProContBoardEndDTO> boardEndEventList = new ArrayList<>();
            PmProContFilterResposeDTO axisPmProCont = filterOrderMap.get(orderNoList.get(0));

            // 虚拟板坯维度
            boardEndEventList.add(new ProContBoardEndDTO(axisPmProCont.getOrderNo()).setMatNo(pmPdSlab.getVirtualSlabNo())
                    .setLen(pmPdSlab.getPreCleanSlabLen()).setMoMatNo(pmPdSlab.getSlabNo())
                    .setMscLineNo(pmPdSlab.getMscLineNo())
                    .setPdMatStatus(Constants.PdStatusHp.PD_STATUS_HP_12).setPpFlag(PdProdFlag.VIRTUAL_SLAB.getCode())
                    .setThk(pmPdSlab.getPreCleanSlabThick())
                    .setWid(pmPdSlab.getPreCleanSlabWidth())
                    .setWgt(pmPdSlab.getPreCleanSlabWt())
                    .setWholeBacklogCode(axisPmProCont.getWholeBacklogCode())
                    .setStNo(axisPmProCont.getStNo())
                    .setSgSign(axisPmProCont.getSgSign())
                    .setProcCd(Constants.ProdcCd.CD_13B));

            BigDecimal weight = largePltList.get(0).getRollAimLen().multiply(largePltList.get(0).getRollAimThick()).multiply(largePltList.get(0).getRollAimWidth()).multiply(new BigDecimal(7.85)).divide(new BigDecimal(1000000000), PmPlateConstants.WT_SCALE, RoundingMode.HALF_UP);
            // 大板维度
            boardEndEventList.add(new ProContBoardEndDTO(axisPmProCont.getOrderNo()).setMatNo(pmPdSlab.getVirtualSlabNo())
                    .setLen(largePltList.get(0).getRollAimLen()).setMoMatNo(pmPdSlab.getSlabNo())
                    .setMscLineNo(pmPdSlab.getMscLineNo())
                    .setPdMatStatus(Constants.PdStatusHp.PD_STATUS_HP_12).setPpFlag(PdProdFlag.VIRTUAL_COMPOSITE_SLAB.getCode())
                    .setThk(largePltList.get(0).getRollAimThick())
                    .setWid(largePltList.get(0).getRollAimWidth())
                    .setWgt(weight)
                    .setWholeBacklogCode(axisPmProCont.getWholeBacklogCode())
                    .setStNo(axisPmProCont.getStNo())
                    .setSgSign(axisPmProCont.getSgSign())
                    .setProcCd(Constants.ProdcCd.CD_13B));
            for (PmSmallPltPos pmSmallPltPos : pmSmallPltPosDOList) {
                PmProContFilterResposeDTO pmProContFilterResposeDTO = filterOrderMap.get(pmSmallPltPos.getOrderNo());
                // 小板维度
                boardEndEventList
                        .add(new ProContBoardEndDTO(pmSmallPltPos.getOrderNo()).setMatNo(pmPdSlab.getVirtualSlabNo() + pmSmallPltPos.getSmallPlateDivNo())
                                .setLen(pmSmallPltPos.getOrderLen())
                                .setMoMatNo(pmPdSlab.getSlabNo())
                                .setMscLineNo(pmPdSlab.getMscLineNo())
                                .setPdMatStatus(Constants.PdStatusHp.PD_STATUS_HP_12)
                                .setPpFlag(PdProdFlag.SMALL_POS_VIRTUAL_SLAB.getCode())
                                .setThk(pmSmallPltPos.getOrderThick())
                                .setWid(pmSmallPltPos.getOrderWidth())
                                .setWgt(pmProContFilterResposeDTO.getOrderUnitAimWt())
                                .setWholeBacklogCode(axisPmProCont.getWholeBacklogCode())
                                .setStNo(pmProContFilterResposeDTO.getStNo())
                                .setSgSign(pmProContFilterResposeDTO.getSgSign())
                                .setProcCd(Constants.ProdcCd.CD_13B));
            }
            eventClient.addEvent(CtEventConstants.PM_CONTRACT_RESIDUE_BOARD_END, boardEndEventList);
            eventClient.sendEvent(organizationId);
            System.out.println("抛合同接口 执行成功");
        }
    }

    /**
     * 组装板坯信息表数据
     *
     * @param pmPdSlabSplitDTO
     * @return
     */
    private PmPdSlabInfo buildPmPdSlabInfo(PmPdSlabSplitDTO pmPdSlabSplitDTO, String slabNo, String mscLineNo, Long tenantId) {
        PmPdSlabInfo pmPdSlabInfo = BeanUtils.copy(pmPdSlabSplitDTO, PmPdSlabInfo.class);
        pmPdSlabInfo.setOuBacklogCode("3");
        pmPdSlabInfo.setOuBacklogSeq(13L);
        pmPdSlabInfo.setMatStatus(pmPdSlabSplitDTO.getSlabStatus());
//        pmPdSlabInfo.setSlabFlag(pmPdSlabSplitDTO.getSlabFlag());
        pmPdSlabInfo.setSlabFlag("S");
        pmPdSlabInfo.setPdStatusHp(Constants.PdStatusHp.PD_STATUS_HP_11);
        pmPdSlabInfo.setAutoManualFlag(Constants.AutoManualFlag.AUTO_MANUA_FLAG_M);
        pmPdSlabInfo.setPrecStNo(pmPdSlabSplitDTO.getPreStNo());
//        pmPdSlabInfo.setFinStNo(finStNo);
        pmPdSlabInfo.setAutoManualFlag(Constants.AutoManualFlag.AUTO_MANUA_FLAG_M);
        pmPdSlabInfo.setCanAssignFlag(BaseConstants.Flag.YES.toString());
        pmPdSlabInfo.setMatActThick(pmPdSlabSplitDTO.getSlabActThk());
        pmPdSlabInfo.setMatActLen(pmPdSlabSplitDTO.getSlabActLen());
        pmPdSlabInfo.setMatActWidth(pmPdSlabSplitDTO.getSlabActWid());
        pmPdSlabInfo.setMatActWt(pmPdSlabSplitDTO.getSlabActWgt());
        pmPdSlabInfo.setIngotType(pmPdSlabSplitDTO.getSlabType());
        pmPdSlabInfo.setOldMscLine(pmPdSlabSplitDTO.getMscLineNo());
        pmPdSlabInfo.setSlabNo(slabNo);
        pmPdSlabInfo.setTwoRollInterimFlag(BaseConstants.Flag.NO.longValue());
        pmPdSlabInfo.setTenantId(tenantId);
        // 若MAT_NO首位为‘G’或第三位为‘5’，则为‘A’，否则为‘1’
        String matNo = pmPdSlabSplitDTO.getSlabNo();
        if (matNo.charAt(0) == 'G' || matNo.charAt(2) == '5') {
            pmPdSlabInfo.setCcType("A");
        } else {
            pmPdSlabInfo.setCcType(Constants.CcType.TYPE_1);
        }
        pmPdSlabInfo.setMscLineNo(mscLineNo);
        pmPdSlabInfo.setPono(pmPdSlabSplitDTO.getPono());
        pmPdSlabInfo.setPsc(pmPdSlabSplitDTO.getPsc());
        pmPdSlabInfo.setSgSign(pmPdSlabSplitDTO.getSgSign());
        pmPdSlabInfo.setStNo(pmPdSlabSplitDTO.getStNo());
        pmPdSlabInfo.setApn(pmPdSlabSplitDTO.getApn());
        pmPdSlabInfo.setMsc(pmPdSlabSplitDTO.getMsc());
        return pmPdSlabInfo;
    }

    private void callMatStatusModify(PmPdSlabInfo pmPdSlabInfo) {
        MatStatusModifyVO matStatusModifyVO = new MatStatusModifyVO();
        matStatusModifyVO.setMatNo(pmPdSlabInfo.getSlabNo());
        matStatusModifyVO.setPpFlag(Constants.PpFlag.SM);
        Map<String, Object> informationMap = new HashMap<>(16);
        informationMap.put("holdCauseCode", Constants.HoldCauseCode.PM01);
        informationMap.put("holdCauseCodeMeaning", "余材板坯智能组板");
        informationMap.put("holdTime", new Date());
        informationMap.put("holdMaker", DetailsHelper.getUserDetails().getUserId());
        informationMap.put("plateLockRegion", "Q77");
        matStatusModifyVO.setMatInformationString(JSONObject.toJSONString(informationMap));
        mmEventClient.matStatusModify(pmPdSlabInfo.getTenantId(), Constants.EventCode.MM_PM_PROD_MANAGEMENT_BLOCKED_IN_PROCESS_MATERIAL, matStatusModifyVO);
    }


}
