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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xisc.pm.api.dto.AssemblyStoveActualPerformanceDTO;
import com.xisc.pm.api.dto.FurnaceNumDeterminationEventDTO;
import com.xisc.pm.api.dto.FurnaceNumDeterminationOutEventDTO;
import com.xisc.pm.api.dto.FurnaceNumberDeterminationDTO;
import com.xisc.pm.api.dto.PmCompositeBoardDTO;
import com.xisc.pm.api.dto.PmPdMscLineChangeDTO;
import com.xisc.pm.api.dto.PmPreSubstitutionDTO;
import com.xisc.pm.api.dto.PmProContFilterRequestDTO;
import com.xisc.pm.api.dto.PmProContYieldDTO;
import com.xisc.pm.api.dto.PmProContYieldRequestDTO;
import com.xisc.pm.api.dto.PmProductionPlanReqDTO;
import com.xisc.pm.api.dto.PmProductionPlanResDTO;
import com.xisc.pm.api.dto.PmQueryIsSampleDTO;
import com.xisc.pm.api.dto.PmRemoveBoardsFromOrderDTO;
import com.xisc.pm.api.dto.PmRollingWasteCompositeDTO;
import com.xisc.pm.api.dto.PmTwoRollInterimRequestDTO;
import com.xisc.pm.api.dto.PmUpdateSlabDTO;
import com.xisc.pm.api.dto.ctevent.PmLineNoChangeDTO;
import com.xisc.pm.api.dto.ctevent.PmSlabPreCastingDTO;
import com.xisc.pm.app.service.ApiService;
import com.xisc.pm.app.service.PmCmdLargePltService;
import com.xisc.pm.app.service.PmPdSlabInfoService;
import com.xisc.pm.app.service.PmPdSlabService;
import com.xisc.pm.app.service.PmProContService;
import com.xisc.pm.app.service.strategy.FormPlateModeStrategyFactory;
import com.xisc.pm.app.service.strategy.PdMatTypeStrategyFactory;
import com.xisc.pm.app.service.strategy.SecondaryDesignHelper;
import com.xisc.pm.app.service.strategy.SecondaryDesignStrategyFactory;
import com.xisc.pm.app.service.strategy.formplatemode.FormPlateModeStrategy;
import com.xisc.pm.app.service.strategy.pdmattype.PdMatTypeStrategy;
import com.xisc.pm.app.service.strategy.secondarydesign.SecondaryDesignStrategy;
import com.xisc.pm.domain.entity.MmSlab;
import com.xisc.pm.domain.entity.PmCmdCont;
import com.xisc.pm.domain.entity.PmCmdContTra;
import com.xisc.pm.domain.entity.PmCmdLargePlt;
import com.xisc.pm.domain.entity.PmCmdLargePltTra;
import com.xisc.pm.domain.entity.PmCmdSlab;
import com.xisc.pm.domain.entity.PmCmdSlabTra;
import com.xisc.pm.domain.entity.PmCmdSmallPlt;
import com.xisc.pm.domain.entity.PmCmdSmallPltTra;
import com.xisc.pm.domain.entity.PmCompositeSlab;
import com.xisc.pm.domain.entity.PmCompositeSlabDiv;
import com.xisc.pm.domain.entity.PmCompositeSlabList;
import com.xisc.pm.domain.entity.PmPdBlockPos;
import com.xisc.pm.domain.entity.PmPdBlockPosTra;
import com.xisc.pm.domain.entity.PmPdCcSlab;
import com.xisc.pm.domain.entity.PmPdCcSlabTra;
import com.xisc.pm.domain.entity.PmPdContSum;
import com.xisc.pm.domain.entity.PmPdContSumTra;
import com.xisc.pm.domain.entity.PmPdPlate;
import com.xisc.pm.domain.entity.PmPdPlateInfo;
import com.xisc.pm.domain.entity.PmPdPlateInfoTra;
import com.xisc.pm.domain.entity.PmPdPlateTra;
import com.xisc.pm.domain.entity.PmPdSlab;
import com.xisc.pm.domain.entity.PmPdSlabInfo;
import com.xisc.pm.domain.entity.PmPdSlabInfoTra;
import com.xisc.pm.domain.entity.PmPdSlabTra;
import com.xisc.pm.domain.entity.PmPonoWtInfo;
import com.xisc.pm.domain.entity.PmProContProdTtr;
import com.xisc.pm.domain.entity.PmSlabEstaPlan;
import com.xisc.pm.domain.entity.PmSlabEstaPlanHis;
import com.xisc.pm.domain.entity.PmSlabMerge;
import com.xisc.pm.domain.entity.PmSlabPoolIn;
import com.xisc.pm.domain.entity.PmSlabPoolInHis;
import com.xisc.pm.domain.entity.PmSmallPltPos;
import com.xisc.pm.domain.entity.PmSmallPltPosTra;
import com.xisc.pm.domain.entity.PmSteelCastHeat;
import com.xisc.pm.domain.entity.PmSteelCastSlab;
import com.xisc.pm.domain.repository.MmSlabRepository;
import com.xisc.pm.domain.repository.PmCmdContRepository;
import com.xisc.pm.domain.repository.PmCmdContTraRepository;
import com.xisc.pm.domain.repository.PmCmdLargePltRepository;
import com.xisc.pm.domain.repository.PmCmdLargePltTraRepository;
import com.xisc.pm.domain.repository.PmCmdSlabRepository;
import com.xisc.pm.domain.repository.PmCmdSlabTraRepository;
import com.xisc.pm.domain.repository.PmCmdSmallPltRepository;
import com.xisc.pm.domain.repository.PmCmdSmallPltTraRepository;
import com.xisc.pm.domain.repository.PmCompositeSlabDivRepository;
import com.xisc.pm.domain.repository.PmCompositeSlabListRepository;
import com.xisc.pm.domain.repository.PmCompositeSlabRepository;
import com.xisc.pm.domain.repository.PmPdBlockPosRepository;
import com.xisc.pm.domain.repository.PmPdBlockPosTraRepository;
import com.xisc.pm.domain.repository.PmPdCcSlabRepository;
import com.xisc.pm.domain.repository.PmPdCcSlabTraRepository;
import com.xisc.pm.domain.repository.PmPdContSumRepository;
import com.xisc.pm.domain.repository.PmPdContSumTraRepository;
import com.xisc.pm.domain.repository.PmPdPlateCutRepository;
import com.xisc.pm.domain.repository.PmPdPlateInfoRepository;
import com.xisc.pm.domain.repository.PmPdPlateInfoTraRepository;
import com.xisc.pm.domain.repository.PmPdPlateRepository;
import com.xisc.pm.domain.repository.PmPdPlateTraRepository;
import com.xisc.pm.domain.repository.PmPdRecRepository;
import com.xisc.pm.domain.repository.PmPdSlabInfoRepository;
import com.xisc.pm.domain.repository.PmPdSlabInfoTraRepository;
import com.xisc.pm.domain.repository.PmPdSlabRepository;
import com.xisc.pm.domain.repository.PmPdSlabTraRepository;
import com.xisc.pm.domain.repository.PmPonoWtInfoRepository;
import com.xisc.pm.domain.repository.PmProContProdTtrRepository;
import com.xisc.pm.domain.repository.PmQdToPoOrderRepository;
import com.xisc.pm.domain.repository.PmSlabEstaPlanHisRepository;
import com.xisc.pm.domain.repository.PmSlabEstaPlanRepository;
import com.xisc.pm.domain.repository.PmSlabMergeRepository;
import com.xisc.pm.domain.repository.PmSlabPoolInHisRepository;
import com.xisc.pm.domain.repository.PmSlabPoolInRepository;
import com.xisc.pm.domain.repository.PmSmallPltPosRepository;
import com.xisc.pm.domain.repository.PmSmallPltPosTraRepository;
import com.xisc.pm.domain.repository.PmSteelCastHeatRepository;
import com.xisc.pm.domain.repository.PmSteelCastSlabRepository;
import com.xisc.pm.domain.vo.MmAutoHeatPlanVO;
import com.xisc.pm.domain.vo.MmCutSeqVO;
import com.xisc.pm.domain.vo.MmPlateVO;
import com.xisc.pm.domain.vo.PmCmdVO;
import com.xisc.pm.domain.vo.QdToPoLineCombVO;
import com.xisc.pm.domain.vo.QdToPoOrderVO1;
import com.xisc.pm.domain.vo.QeResvReplaceTriggerVO;
import com.xisc.pm.domain.vo.SlabNoCorrespondingBigLotReturnVo;
import com.xisc.pm.domain.vo.SlabNoCorrespondingBigLotVo;
import com.xisc.pm.infra.client.EventClient;
import com.xisc.pm.infra.client.HeApiClient;
import com.xisc.pm.infra.client.LgApiClient;
import com.xisc.pm.infra.client.MmEventClient;
import com.xisc.pm.infra.client.QeApiClient;
import com.xisc.pm.infra.constant.Constants;
import com.xisc.pm.infra.constant.Constants.PdStatusHp;
import com.xisc.pm.infra.constant.CtEventConstants;
import com.xisc.pm.infra.constant.PmPlateConstants;
import com.xisc.pm.infra.enums.FormPlateMode;
import com.xisc.pm.infra.enums.PdMatType;
import com.xisc.pm.infra.mapper.PmMmPlateMapper;
import com.xisc.pm.infra.util.BeanUtils;
import com.xisc.pm.infra.util.Utils;
import io.choerodon.core.exception.CommonException;
import io.choerodon.core.oauth.DetailsHelper;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.hzero.core.base.BaseConstants;
import org.hzero.mybatis.domian.Condition;
import org.hzero.mybatis.util.Sqls;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 蒋雨航 yuhang.jiang02@hand-china.com
 */
@Service
@Slf4j
public class ApiServiceImpl implements ApiService {

    @Autowired
    private PmSteelCastHeatRepository pmSteelCastHeatRepository;

    @Autowired
    private PmSlabEstaPlanRepository pmSlabEstaPlanRepository;

    @Autowired
    private PmSlabMergeRepository pmSlabMergeRepository;

    @Autowired
    private PmPdContSumRepository pmPdContSumRepository;

    @Autowired
    private PmPdCcSlabRepository pmPdCcSlabRepository;

    @Autowired
    private PmSlabEstaPlanHisRepository pmSlabEstaPlanHisRepository;

    @Autowired
    private PmSlabPoolInRepository pmSlabPoolInRepository;

    @Autowired
    private PmSlabPoolInHisRepository pmSlabPoolInHisRepository;

    @Autowired
    private PmCmdLargePltRepository pmCmdLargePltRepository;
    
    @Autowired
    private PmCmdLargePltService pmCmdLargePltService;
    
    @Autowired
    private PmPdSlabService pmPdSlabService;
    
    @Autowired
    private PmCmdSlabRepository pmCmdSlabRepository;
    
    @Autowired
    private PmPdPlateCutRepository pmPdPlateCutRepository;

    @Autowired
    private PmSmallPltPosRepository pmSmallPltPosRepository;
    
    @Autowired
    private PmProContProdTtrRepository pmProContProdTtrRepository;
    
    @Autowired
    private PmPdBlockPosRepository pmPdBlockPosRepository;
    
    @Autowired
    private PmProContService pmProContService;
    
    @Autowired
    private PmPdSlabInfoService pmPdSlabInfoService;

    @Autowired
    private EventClient eventClient;

    @Autowired
    private PmCompositeSlabRepository pmCompositeSlabRepository;

    @Autowired
    private MmSlabRepository mmSlabRepository;

    @Autowired
    private HeApiClient heApiClient;

    @Autowired
    private LgApiClient lgApiClient;

    @Autowired
    private MmEventClient mmEventClient;

    @Autowired
    private QeApiClient qeApiClient;

    @Autowired
    private PmPonoWtInfoRepository pmPonoWtInfoRepository;

    @Autowired
    private PmPdSlabRepository pmPdSlabRepository;
    @Autowired
    private PmPdSlabTraRepository pmPdSlabTraRepository;
    @Autowired
    private PmPdSlabInfoRepository pmPdSlabInfoRepository;
    @Autowired
    private PmPdSlabInfoTraRepository pmPdSlabInfoTraRepository;
    @Autowired
    private PmPdPlateRepository pmPdPlateRepository;
    @Autowired
    private PmPdPlateTraRepository pmPdPlateTraRepository;
    @Autowired
    private PmPdPlateInfoRepository pmPdPlateInfoRepository;
    @Autowired
    private PmPdPlateInfoTraRepository pmPdPlateInfoTraRepository;
    @Autowired
    private PmPdBlockPosTraRepository pmPdBlockPosTraRepository;
    @Autowired
    private PmSmallPltPosTraRepository pmSmallPltPosTraRepository;
    @Autowired
    private PmPdContSumTraRepository pmPdContSumTraRepository;
    @Autowired
    private PmPdCcSlabTraRepository pmPdCcSlabTraRepository;
    @Autowired
    private PmCmdSmallPltRepository pmCmdSmallPltRepository;

    @Autowired
    private PmPdRecRepository pmPdRecRepository;

    @Autowired
    private PmCmdContRepository pmCmdContRepository;

    @Autowired
    private PmCmdContTraRepository pmCmdContTraRepository;
    @Autowired
    private PmCmdSmallPltTraRepository pmCmdSmallPltTraRepository;
    @Autowired
    private PmCmdLargePltTraRepository pmCmdLargePltTraRepository;
    @Autowired
    private PmCmdSlabTraRepository pmCmdSlabTraRepository;
    @Autowired
    private PmCompositeSlabListRepository pmCompositeSlabListRepository;
    @Autowired
    private PmCompositeSlabDivRepository pmCompositeSlabDivRepository;
    @Autowired
    private PmMmPlateMapper pmMmPlateMapper;
    @Autowired
    private PmSteelCastSlabRepository pmSteelCastSlabRepository;
    @Autowired
    private PmQdToPoOrderRepository pmQdToPoOrderRepository;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void furnaceNumberDetermination(List<FurnaceNumberDeterminationDTO> dtoList, Long organizationId) {
        if (CollectionUtils.isEmpty(dtoList)) {
            return;
        }
        List<String> ponoList = new ArrayList<>(dtoList.size());
        Map<String, FurnaceNumberDeterminationDTO> dtoMap = new HashMap<>();
        for (FurnaceNumberDeterminationDTO dto : dtoList) {
            ponoList.add(dto.getPono());
            dtoMap.put(dto.getPono(), dto);
        }
        //查询
        List<PmSteelCastHeat> pmSteelCastHeatList = pmSteelCastHeatRepository.selectByCondition(Condition.builder(PmSteelCastHeat.class)
                .andWhere(Sqls.custom().andEqualTo(PmSteelCastHeat.FIELD_TENANT_ID, organizationId).andIn(PmSteelCastHeat.FIELD_PONO, ponoList)).build());

        //方坯
        List<PmSteelCastHeat> steelCastHeatOneList = pmSteelCastHeatList.stream().filter(x -> x.getIsBloom().compareTo(1L) == 0).collect(Collectors.toList());
        //板坯
        List<PmSteelCastHeat> steelCastHeatHzeroList = pmSteelCastHeatList.stream().filter(x -> x.getIsBloom().compareTo(1L) != 0).collect(Collectors.toList());

        //板坯处理 逻辑
        List<PmSlabEstaPlan> slabEstaPlanUpdateList = new ArrayList<>(16);
        List<PmPdContSum> pdContSumUpdateList = new ArrayList<>(16);
        List<PmPdCcSlab> pdCcSlabUpdateList = new ArrayList<>(16);
        List<PmSlabPoolIn> slabPoolInList = new ArrayList<>(16);
        List<PmCmdLargePlt> updateLargePltList = new ArrayList<>(16);
        List<PmCmdSlab> updatePmCmdSlabList = new ArrayList<>(16);
        List<FurnaceNumDeterminationOutEventDTO> furnaceNumDeterminationOutEventList = new ArrayList<>(16);
        List<FurnaceNumDeterminationEventDTO> furnaceNumDeterminationEventList = new ArrayList<>(16);
        //将以下字段作为入参，调用轧钢模块“热装计划撤销”接口：
        List<MmAutoHeatPlanVO> mmAutoHeatPlanVOList = new ArrayList<>();
        List<QeResvReplaceTriggerVO> resvReplaceTriggerVOList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(steelCastHeatHzeroList)) {
            //查询组炉编制
            List<PmSlabEstaPlan> slabEstaPlanList = pmSlabEstaPlanRepository.selectByCondition(Condition.builder(PmSlabEstaPlan.class)
                    .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_TENANT_ID, organizationId)
                            .andIn(PmSlabEstaPlan.FIELD_PONO, ponoList)).build());
            if (CollectionUtils.isEmpty(slabEstaPlanList)) {
                throw new CommonException("pm.furnace_casting_014", StringUtils.join(ponoList, BaseConstants.Symbol.COMMA));
            }
            Map<String, List<PmSlabEstaPlan>> slabEstaPlanMap = slabEstaPlanList.stream().collect(Collectors.groupingBy(PmSlabEstaPlan::getPono));

            //获取虚拟板坯相关信息
            List<String> virtualSlabNoList = slabEstaPlanList.stream().map(PmSlabEstaPlan::getVirtualSlabNo).distinct().collect(Collectors.toList());
            List<String> precSlabNoList = slabEstaPlanList.stream().map(PmSlabEstaPlan::getPrecSlabNo).collect(Collectors.toList());
            List<String> mergeVirtualSlabNoList = virtualSlabNoList.stream().filter(x -> Utils.isMergeSlab(x)).collect(Collectors.toList());
            Map<String, List<PmSlabMerge>> pmSlabMergeMap = new HashMap<>(16);
            //合并板坯信息
            if (CollectionUtils.isNotEmpty(mergeVirtualSlabNoList)) {
                List<PmSlabMerge> pmSlabMergeList = pmSlabMergeRepository.selectByCondition(Condition.builder(PmSlabMerge.class)
                        .andWhere(Sqls.custom().andIn(PmSlabMerge.FIELD_MERGE_SLAB_NO, mergeVirtualSlabNoList)
                                .andEqualTo(PmSlabMerge.FIELD_TENANT_ID, organizationId)).build());
                virtualSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getVirtualSlabNo).distinct().collect(Collectors.toList()));
                pmSlabMergeMap = pmSlabMergeList.stream().collect(Collectors.groupingBy(PmSlabMerge::getMergeSlabNo));
                precSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getPrecSlabNo).collect(Collectors.toList()));
            }
            //组板合同总量
            List<PmPdContSum> pdContSumList = pmPdContSumRepository.selectByCondition(Condition.builder(PmPdContSum.class)
                    .andWhere(Sqls.custom()
                            .andEqualTo(PmPdContSum.FIELD_TENANT_ID, organizationId)
                            .andIn(PmPdContSum.FIELD_PD_MAT_NO, virtualSlabNoList)).build());
            Map<String, List<PmPdContSum>> pdContSumMap = pdContSumList.stream().collect(Collectors.groupingBy(PmPdContSum::getPdMatNo));
            //组板连铸板坯
            List<PmPdCcSlab> pmPdCcSlabList = pmPdCcSlabRepository.selectByCondition(Condition.builder(PmPdCcSlab.class).andWhere(Sqls.custom()
                    .andEqualTo(PmPdCcSlab.FIELD_TENANT_ID, organizationId)
                    .andIn(PmPdCcSlab.FIELD_VIRTUAL_SLAB_NO, virtualSlabNoList)).build());
            Map<String, PmPdCcSlab> pmPdCcSlabMap = pmPdCcSlabList.stream().collect(Collectors.toMap(PmPdCcSlab::getVirtualSlabNo, x -> x));
            //组炉收池
            slabPoolInList = pmSlabPoolInRepository.selectByCondition(Condition.builder(PmSlabPoolIn.class).andWhere(Sqls.custom()
                    .andEqualTo(PmSlabPoolIn.FIELD_TENANT_ID, organizationId)
                    .andIn(PmSlabPoolIn.FIELD_VIRTUAL_SLAB_NO, virtualSlabNoList)).build());
            Map<String, PmSlabPoolIn> slabPoolInMap = slabPoolInList.stream().collect(Collectors.toMap(PmSlabPoolIn::getVirtualSlabNo, x -> x));
            //组板小板位置
            List<PmSmallPltPos> smallPltPosList = pmSmallPltPosRepository.selectByCondition(Condition.builder(PmSmallPltPos.class)
                    .andWhere(Sqls.custom().andIn(PmSmallPltPos.FIELD_PD_MAT_NO, virtualSlabNoList))
                    .andWhere(Sqls.custom().andEqualTo(PmSmallPltPos.FIELD_TENANT_ID, organizationId))
                    .build());
            Map<String, List<PmSmallPltPos>> smallPltPosMap = smallPltPosList.stream().collect(Collectors.groupingBy(PmSmallPltPos::getPdMatNo));
            //板坯主数据
            List<MmSlab> slabList = mmSlabRepository.selectByCondition(Condition.builder(MmSlab.class)
                    .select(MmSlab.FIELD_PONO_SLAB, MmSlab.FIELD_WHOLE_BACKLOG_CODE, MmSlab.FIELD_PROC_CD, MmSlab.FIELD_SLAB_NO)
                    .andWhere(Sqls.custom().andIn(MmSlab.FIELD_PONO_SLAB, precSlabNoList))
                    .andWhere(Sqls.custom().andEqualTo(MmSlab.FIELD_TENANT_ID, organizationId))
                    .build());
            Map<String, MmSlab> slabMap = slabList.stream().collect(Collectors.toMap(MmSlab::getPonoSlab, x -> x));
            // 命令大板表
            List<PmCmdLargePlt> largePltList = pmCmdLargePltRepository.selectByPonoSlabList(precSlabNoList, organizationId);
            Map<String, PmCmdLargePlt> largePltMap = largePltList.stream().collect(Collectors.toMap(PmCmdLargePlt::getPonoSlabNo, x -> x));
            // 命令板坯表
            List<PmCmdSlab> pmCmdSlabList = pmCmdSlabRepository.selectByPonoSlabList(precSlabNoList, organizationId);
            Map<String, PmCmdSlab> smallPltMap = pmCmdSlabList.stream().collect(Collectors.toMap(PmCmdSlab::getPonoSlabNo, x -> x));

            //循环处理数据
//            List<String> ccType = Arrays.asList("1", "5");
            for (Entry<String, List<PmSlabEstaPlan>> entry : slabEstaPlanMap.entrySet()) {
                FurnaceNumberDeterminationDTO determinationDTO = dtoList.stream().filter(x -> entry.getKey().equals(x.getPono())).findFirst().orElse(null);
                //为空不处理
                if (Objects.isNull(determinationDTO)) {
                    continue;
                }
                //已产出
                List<PmSlabEstaPlan> existsSlabEstaPlanList = entry.getValue().stream().filter(x -> determinationDTO.getPrecSlabNoList().contains(x.getPrecSlabNo())).collect(Collectors.toList());
                //已产出
                if (CollectionUtils.isNotEmpty(existsSlabEstaPlanList)) {
                    //循环封装数据
                    for (PmSlabEstaPlan estaPlan : existsSlabEstaPlanList) {
                        //更新组炉编制表
                        estaPlan.setHeatConfmFlag("1");
                        estaPlan.setSteelEndTime(new Date());
                        estaPlan.setCsPrecPlanStatus("12");
                        slabEstaPlanUpdateList.add(estaPlan);
                        String virtualSlabNo = estaPlan.getVirtualSlabNo();
                        //是否为合并板坯
                        if (Utils.isMergeSlab(estaPlan.getVirtualSlabNo())) {
                            for (PmSlabMerge pmSlabMerge : pmSlabMergeMap.get(estaPlan.getVirtualSlabNo())) {
                                //更新组板合同总量表
                                if (CollectionUtils.isNotEmpty(pdContSumMap.get(pmSlabMerge.getVirtualSlabNo()))) {
                                    List<PmPdContSum> pmPdContSumList = pdContSumMap.get(pmSlabMerge.getVirtualSlabNo());
                                    for (PmPdContSum pmPdContSum : pmPdContSumList) {
                                        pmPdContSum.setPdStatus("28");
                                        pdContSumUpdateList.add(pmPdContSum);
                                    }
                                }
                                //更新组板连铸板坯表
                                if (Objects.nonNull(pmPdCcSlabMap.get(pmSlabMerge.getVirtualSlabNo()))) {
                                    PmPdCcSlab pdCcSlab = pmPdCcSlabMap.get(pmSlabMerge.getVirtualSlabNo());
                                    pdCcSlab.setPdStatusHp("28");
                                    pdCcSlabUpdateList.add(pdCcSlab);
                                }
                                if (Objects.nonNull(largePltMap.get(pmSlabMerge.getPrecSlabNo()))) {
                                    PmCmdLargePlt pmCmdLargePlt = largePltMap.get(pmSlabMerge.getPrecSlabNo());
                                    pmCmdLargePlt.setPdStatusHp("28");
                                    updateLargePltList.add(pmCmdLargePlt);
                                }
                                if (Objects.nonNull(smallPltMap.get(pmSlabMerge.getPrecSlabNo()))) {
                                    PmCmdSlab pmCmdSlab = smallPltMap.get(pmSlabMerge.getPrecSlabNo());
                                    pmCmdSlab.setPdStatusHp("28");
                                    updatePmCmdSlabList.add(pmCmdSlab);
                                }
                            }
                        } else {
                            //更新组板合同总量表
                            if (CollectionUtils.isNotEmpty(pdContSumMap.get(virtualSlabNo))) {
                                List<PmPdContSum> pmPdContSumList = pdContSumMap.get(virtualSlabNo);
                                for (PmPdContSum pmPdContSum : pmPdContSumList) {
                                    pmPdContSum.setPdStatus("28");
                                    pdContSumUpdateList.add(pmPdContSum);
                                }
                            }
                            //更新组板连铸板坯表
                            if (Objects.nonNull(pmPdCcSlabMap.get(virtualSlabNo))) {
                                PmPdCcSlab pdCcSlab = pmPdCcSlabMap.get(virtualSlabNo);
                                pdCcSlab.setPdStatusHp("28");
                                pdCcSlabUpdateList.add(pdCcSlab);
                            }
                        }
                        if (Objects.nonNull(largePltMap.get(estaPlan.getPrecSlabNo()))) {
                            PmCmdLargePlt pmCmdLargePlt = largePltMap.get(estaPlan.getPrecSlabNo());
                            pmCmdLargePlt.setPdStatusHp("28");
                            updateLargePltList.add(pmCmdLargePlt);
                        }
                        if (Objects.nonNull(smallPltMap.get(estaPlan.getPrecSlabNo()))) {
                            PmCmdSlab pmCmdSlab = smallPltMap.get(estaPlan.getPrecSlabNo());
                            pmCmdSlab.setPdStatusHp("28");
                            updatePmCmdSlabList.add(pmCmdSlab);
                        }

                        //合同跟踪 封装参数
                        FurnaceNumDeterminationOutEventDTO eventDTO = new FurnaceNumDeterminationOutEventDTO();
                        eventDTO.setPono(estaPlan.getPono());
                        eventDTO.setPonoSlab(estaPlan.getPrecSlabNo());
                        String ppFlag = "";
                        if ("5".equals(estaPlan.getCcType())) {
                            ppFlag = "8";
                        } else {
                            ppFlag = "5";
                        }
                        eventDTO.setPpFlag(ppFlag);
                        eventDTO.setPdMatStatus("28");
                        eventDTO.setCsPrecPlanStatus("12");
                        //轧钢获取对应数据
                        if (slabMap.containsKey(estaPlan.getPrecSlabNo())) {
                            eventDTO.setMatNo(slabMap.get(estaPlan.getPrecSlabNo()).getSlabNo());
                            eventDTO.setWholeBacklogCode(slabMap.get(estaPlan.getPrecSlabNo()).getWholeBacklogCode());
                            eventDTO.setProcCd(slabMap.get(estaPlan.getPrecSlabNo()).getProcCd());
                        }
                        furnaceNumDeterminationOutEventList.add(eventDTO);
                    }
                }
                //未产出
                List<PmSlabEstaPlan> notExistsSlabEstaPlanList = entry.getValue().stream().filter(x ->
                        !determinationDTO.getPrecSlabNoList().contains(x.getPrecSlabNo())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(notExistsSlabEstaPlanList)) {
                    //循环封装数据
                    for (PmSlabEstaPlan estaPlan : notExistsSlabEstaPlanList) {
                        //更新组炉编制表
                        estaPlan.setHeatConfmFlag("1");
                        estaPlan.setSteelEndTime(new Date());
                        estaPlan.setCsPrecPlanStatus("11");
                        slabEstaPlanUpdateList.add(estaPlan);
                        String virtualSlabNo = estaPlan.getVirtualSlabNo();
                        //是否为合并板坯
                        if (Utils.isMergeSlab(estaPlan.getVirtualSlabNo())) {
                            for (PmSlabMerge pmSlabMerge : pmSlabMergeMap.get(estaPlan.getVirtualSlabNo())) {
                                PmSlabPoolIn slabPoolIn = slabPoolInMap.getOrDefault(pmSlabMerge.getVirtualSlabNo(), new PmSlabPoolIn());
                                //更新组板合同总量表
                                if (CollectionUtils.isNotEmpty(pdContSumMap.get(pmSlabMerge.getVirtualSlabNo())) && StringUtils.isNotBlank(estaPlan.getOrderNo())) {
                                    List<PmPdContSum> pmPdContSumList = pdContSumMap.get(pmSlabMerge.getVirtualSlabNo());
                                    for (PmPdContSum pmPdContSum : pmPdContSumList) {
                                        pmPdContSum.setPdStatus("29");
                                        pdContSumUpdateList.add(pmPdContSum);
                                    }
                                }
                                //更新组板连铸板坯表
                                if (Objects.nonNull(pmPdCcSlabMap.get(pmSlabMerge.getVirtualSlabNo())) && StringUtils.isNotBlank(estaPlan.getOrderNo())) {
                                    PmPdCcSlab pdCcSlab = pmPdCcSlabMap.get(pmSlabMerge.getVirtualSlabNo());
                                    pdCcSlab.setPdStatusHp("29");
                                    pdCcSlabUpdateList.add(pdCcSlab);
                                }
                                if (Objects.nonNull(largePltMap.get(pmSlabMerge.getPrecSlabNo()))) {
                                    PmCmdLargePlt pmCmdLargePlt = largePltMap.get(pmSlabMerge.getPrecSlabNo());
                                    pmCmdLargePlt.setPdStatusHp("29");
                                    updateLargePltList.add(pmCmdLargePlt);
                                }
                                if (Objects.nonNull(smallPltMap.get(pmSlabMerge.getPrecSlabNo()))) {
                                    PmCmdSlab pmCmdSlab = smallPltMap.get(pmSlabMerge.getPrecSlabNo());
                                    pmCmdSlab.setPdStatusHp("29");
                                    updatePmCmdSlabList.add(pmCmdSlab);
                                }
                            }
                        } else {
                            PmSlabPoolIn slabPoolIn = slabPoolInMap.getOrDefault(virtualSlabNo, new PmSlabPoolIn());
                            //更新组板合同总量表
                            if (CollectionUtils.isNotEmpty(pdContSumMap.get(virtualSlabNo)) && StringUtils.isNotBlank(estaPlan.getOrderNo())) {
                                List<PmPdContSum> pmPdContSumList = pdContSumMap.get(virtualSlabNo);
                                for (PmPdContSum pmPdContSum : pmPdContSumList) {
                                    pmPdContSum.setPdStatus("29");
                                    pdContSumUpdateList.add(pmPdContSum);
                                }
                            }
                            //更新组板连铸板坯表
                            if (Objects.nonNull(pmPdCcSlabMap.get(virtualSlabNo)) && StringUtils.isNotBlank(estaPlan.getOrderNo())) {
                                PmPdCcSlab pdCcSlab = pmPdCcSlabMap.get(virtualSlabNo);
                                pdCcSlab.setPdStatusHp("29");
                                pdCcSlabUpdateList.add(pdCcSlab);
                            }
                        }
                        if (Objects.nonNull(largePltMap.get(estaPlan.getPrecSlabNo()))) {
                            PmCmdLargePlt pmCmdLargePlt = largePltMap.get(estaPlan.getPrecSlabNo());
                            pmCmdLargePlt.setPdStatusHp("29");
                            updateLargePltList.add(pmCmdLargePlt);
                        }
                        if (Objects.nonNull(smallPltMap.get(estaPlan.getPrecSlabNo()))) {
                            PmCmdSlab pmCmdSlab = smallPltMap.get(estaPlan.getPrecSlabNo());
                            pmCmdSlab.setPdStatusHp("29");
                            updatePmCmdSlabList.add(pmCmdSlab);
                        }

                        //封装参数
                        FurnaceNumDeterminationEventDTO eventDTO = new FurnaceNumDeterminationEventDTO();
                        eventDTO.setMatNo(estaPlan.getVirtualSlabNo());
                        eventDTO.setPpFlag(0L);
                        eventDTO.setEnableFlag(0L);
                        eventDTO.setPdMatStatus("29");
                        eventDTO.setCsPrecPlanStatus("11");
                        eventDTO.setWholeBacklogCode(estaPlan.getWholeBacklogCode());
                        furnaceNumDeterminationEventList.add(eventDTO);
                        FurnaceNumDeterminationEventDTO eventTwoDTO = new FurnaceNumDeterminationEventDTO();
                        eventTwoDTO.setMatNo(estaPlan.getVirtualSlabNo());
                        eventTwoDTO.setPpFlag(1L);
                        eventTwoDTO.setEnableFlag(0L);
                        eventTwoDTO.setPdMatStatus("29");
                        eventTwoDTO.setCsPrecPlanStatus("11");
                        eventTwoDTO.setWholeBacklogCode(estaPlan.getWholeBacklogCode());
                        furnaceNumDeterminationEventList.add(eventTwoDTO);
                        if (Objects.nonNull(smallPltPosMap.get(virtualSlabNo)) && StringUtils.isNotBlank(estaPlan.getOrderNo())) {
                            for (PmSmallPltPos smallPltPos : smallPltPosMap.get(virtualSlabNo)) {
                                FurnaceNumDeterminationEventDTO numDeterminationEventDTO = new FurnaceNumDeterminationEventDTO();
                                numDeterminationEventDTO.setMatNo(estaPlan.getVirtualSlabNo() + smallPltPos.getSmallPlateDivNo());
                                numDeterminationEventDTO.setPpFlag(2L);
                                numDeterminationEventDTO.setEnableFlag(0L);
                                numDeterminationEventDTO.setPdMatStatus("29");
                                numDeterminationEventDTO.setCsPrecPlanStatus("11");
                                numDeterminationEventDTO.setWholeBacklogCode(estaPlan.getWholeBacklogCode());
                                furnaceNumDeterminationEventList.add(numDeterminationEventDTO);
                            }
                        }
                        //质量接口数据组装
                        if (Utils.isMergeSlab(estaPlan.getVirtualSlabNo())) {
                            for (PmSlabMerge pmSlabMerge : pmSlabMergeMap.get(estaPlan.getVirtualSlabNo())) {
                                QeResvReplaceTriggerVO qeResvReplaceTriggerVO = new QeResvReplaceTriggerVO();
                                qeResvReplaceTriggerVO.setPonoSlab(pmSlabMerge.getPrecSlabNo());
                                qeResvReplaceTriggerVO.setSupersedCaUse("1");
                                resvReplaceTriggerVOList.add(qeResvReplaceTriggerVO);

                                //轧钢接口数据组装
                                MmAutoHeatPlanVO autoHeatPlanVO = new MmAutoHeatPlanVO();
                                autoHeatPlanVO.setPonoSlabNo(pmSlabMerge.getPrecSlabNo());
                                mmAutoHeatPlanVOList.add(autoHeatPlanVO);
                            }
                        } else {
                            QeResvReplaceTriggerVO qeResvReplaceTriggerVO = new QeResvReplaceTriggerVO();
                            qeResvReplaceTriggerVO.setPonoSlab(estaPlan.getPrecSlabNo());
                            qeResvReplaceTriggerVO.setSupersedCaUse("1");
                            resvReplaceTriggerVOList.add(qeResvReplaceTriggerVO);

                            //轧钢接口数据组装
                            MmAutoHeatPlanVO autoHeatPlanVO = new MmAutoHeatPlanVO();
                            autoHeatPlanVO.setPonoSlabNo(estaPlan.getPrecSlabNo());
                            mmAutoHeatPlanVOList.add(autoHeatPlanVO);

                        }
                    }
                }
            }
        }

            //方坯处理 逻辑
            if (CollectionUtils.isNotEmpty(steelCastHeatOneList)) {
                for (PmSteelCastHeat steelCastHeat : steelCastHeatOneList) {
                    FurnaceNumberDeterminationDTO dto = dtoMap.get(steelCastHeat.getPono());
                    if (Objects.nonNull(dto)) {
                        steelCastHeat.setDectStNo(dto.getDectStNo());
                        steelCastHeat.setHeatGrade(dto.getHeatGrade());
                        steelCastHeat.setFlag(dto.getFlag());
                        steelCastHeat.setHeatComfmFlag(dto.getHeatComfmFlag());
                        steelCastHeat.setHeatConfmTime(dto.getHeatConfmTime());
                    }
                }
                if (Constants.MainBacklogCode.CODE_A.equals(steelCastHeatOneList.get(0).getMainBacklogCode())) {
                    // 同时调用线板材MES接口，电文（HEXB02）
                    heApiClient.callSecondPlanAssign(steelCastHeatOneList, organizationId, "HEXB02", true);
                } else {
                    // 五米板
                    lgApiClient.callSecondPlanAssign(steelCastHeatOneList, organizationId, "LGXB02", true);
                }

            }

            //更新炉次表
            pmSteelCastHeatList.forEach(x -> x.setPonoStatus(Constants.PonoStatus.STATUS_91));
            pmSteelCastHeatRepository.batchUpdateByPrimaryKeySelective(pmSteelCastHeatList);
            //更新组炉编制表
            pmSlabEstaPlanRepository.batchUpdateByPrimaryKeySelective(slabEstaPlanUpdateList);
            List<PmSlabEstaPlanHis> pmSlabEstaPlanHisList = new ArrayList<>();
            for (PmSlabEstaPlan pmSlabEstaPlan : slabEstaPlanUpdateList) {
                PmSlabEstaPlanHis pmSlabEstaPlanHis = new PmSlabEstaPlanHis();
                BeanUtils.copy(pmSlabEstaPlan, pmSlabEstaPlanHis);
                pmSlabEstaPlanHisList.add(pmSlabEstaPlanHis);
            }
            pmSlabEstaPlanHisRepository.batchInsertSelective(pmSlabEstaPlanHisList);
        // 刪除炉重信息表
        List<String> precPonoList = slabEstaPlanUpdateList.stream().map(PmSlabEstaPlan::getPrecPono).distinct().collect(Collectors.toList());
        if(precPonoList != null && !precPonoList.isEmpty()) {
            List<PmPonoWtInfo> pmPonoWtInfoList = pmPonoWtInfoRepository.selectByCondition(Condition.builder(PmPonoWtInfo.class)
                    .andWhere(Sqls.custom().andIn(PmPonoWtInfo.FIELD_PREC_PONO, precPonoList))
                    .andWhere(Sqls.custom().andEqualTo(PmPonoWtInfo.FIELD_TENANT_ID, organizationId)).build());
            pmPonoWtInfoRepository.batchDeleteByPrimaryKey(pmPonoWtInfoList);
        }

        pmSlabEstaPlanRepository.batchDeleteByPrimaryKey(slabEstaPlanUpdateList);
        pmPdContSumRepository.batchUpdateByPrimaryKeySelective(pdContSumUpdateList);
        pmPdCcSlabRepository.batchUpdateByPrimaryKeySelective(pdCcSlabUpdateList);
        pmCmdLargePltRepository.batchUpdateByPrimaryKey(updateLargePltList);
        pmCmdSlabRepository.batchUpdateByPrimaryKey(updatePmCmdSlabList);
            List<PmSlabPoolInHis> pmSlabPoolInHisList = new ArrayList<>();
            for (PmSlabPoolIn pmSlabPoolIn : slabPoolInList) {
                PmSlabPoolInHis pmSlabPoolInHis = new PmSlabPoolInHis();
                BeanUtils.copy(pmSlabPoolIn, pmSlabPoolInHis);
                pmSlabPoolInHisList.add(pmSlabPoolInHis);
            }
            pmSlabPoolInHisRepository.batchInsertSelective(pmSlabPoolInHisList);
            pmSlabPoolInRepository.batchDelete(slabPoolInList);
            //调用合同跟踪
            try {
                eventClient.addEvent("PM_PROD_CFM", furnaceNumDeterminationOutEventList);
                log.info("<=====炼钢炉次产出事件，入参为{}=====>", JSON.toJSONString(furnaceNumDeterminationOutEventList));
                eventClient.addEvent("PM_SM_NOT_PROD", furnaceNumDeterminationEventList);
                log.info("<=====炼钢炉次未产出事件，入参为{}=====>", JSON.toJSONString(furnaceNumDeterminationEventList));
                eventClient.sendEvent(organizationId);
            } finally {
                eventClient.remove();
            }
            // 调用质量模块“板坯未产出”接口
            if (CollectionUtils.isNotEmpty(resvReplaceTriggerVOList)) {
               qeApiClient.resvReplaceTriggerBatchApi(organizationId, resvReplaceTriggerVOList);
            }
            //将命令板坯号（PREC_SLAB_NO）、事件标识（event_id）=2作为入参，调用轧钢模块“热装计划撤销”接口，作轧制热装计划撤销操作；
            if (CollectionUtils.isNotEmpty(mmAutoHeatPlanVOList)) {
                mmEventClient.autoHeatPlan(organizationId, mmAutoHeatPlanVOList);
            }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AssemblyStoveActualPerformanceDTO assemblyStoveActualPerformance(String orderNo, Long organizationId) {
        //根据合同号（ORDER_NO）查询【组板合同总量表（PM_PD_CONT_SUM），获取组板材料号（PD_MAT_NO）；
        PmPdContSum pmPdContSumQuery = new PmPdContSum();
        pmPdContSumQuery.setOrderNo(orderNo);
        pmPdContSumQuery.setTenantId(organizationId);
        PmPdContSum pmPdContSum = pmPdContSumRepository.selectOne(pmPdContSumQuery);
        String pdMatNo = pmPdContSum.getPdMatNo();
        PmSlabEstaPlan slabEstaPlanQuery = new PmSlabEstaPlan();
        slabEstaPlanQuery.setVirtualSlabNo(pdMatNo);
        slabEstaPlanQuery.setTenantId(organizationId);
        PmSlabEstaPlan pmSlabEstaPlan = pmSlabEstaPlanRepository.selectOne(slabEstaPlanQuery);
        String precSlabNo = pmSlabEstaPlan.getPrecSlabNo();
        String csPrecPlanStatus = pmSlabEstaPlan.getCsPrecPlanStatus();
        //将组板材料号（PD_MAT_NO）、命令板坯号（PREC_SLAB_NO）、连铸预定计划状态（CS_PREC_PLAN_STATUS）返回给合同跟踪
        AssemblyStoveActualPerformanceDTO dto = new AssemblyStoveActualPerformanceDTO();
        dto.setPdMatNo(pdMatNo);
        dto.setPrecSlabNo(precSlabNo);
        dto.setCsPrecPlanStatus(csPrecPlanStatus);
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @GlobalTransactional(rollbackFor = Exception.class)
    public void successfulPreSubstitution(List<PmPreSubstitutionDTO> preSubstitutionDTOs, Long organizationId) {
        List<String> ponoSlabNoList = new ArrayList<String>();
        for (PmPreSubstitutionDTO pmPreSubstitutionDTO : preSubstitutionDTOs) {
            ponoSlabNoList.add(pmPreSubstitutionDTO.getOrgRepresentPonoSlabNo());
            ponoSlabNoList.add(pmPreSubstitutionDTO.getReplaceSlabNo());
        }
        List<PmCmdLargePlt> pmCmdLargePlts = pmCmdLargePltRepository.selectByCondition(Condition.builder(PmCmdLargePlt.class).andWhere(
                Sqls.custom().andEqualTo(PmCmdLargePlt.FIELD_TENANT_ID, organizationId)
                             .andIn(PmCmdLargePlt.FIELD_PONO_SLAB_NO, ponoSlabNoList)).build());
        if(pmCmdLargePlts == null || pmCmdLargePlts.isEmpty()) {
            return ;
        }
        List<PmCmdSmallPlt> cmdSmallPltList = pmCmdSmallPltRepository.selectByCondition(Condition.builder(PmCmdSmallPlt.class).andWhere(
                Sqls.custom().andEqualTo(PmCmdSmallPlt.FIELD_TENANT_ID, organizationId)
                        .andIn(PmCmdSmallPlt.FIELD_PONO_SLAB_NO, ponoSlabNoList)).build());
        log.info("<=====pmCmdLargePlts:{}", JSON.toJSONString(pmCmdLargePlts));
        log.info("<=====cmdSmallPltList:{}", JSON.toJSONString(cmdSmallPltList));
        Map<String, List<PmCmdSmallPlt>> cmdSmallPltMap = new HashMap<>(cmdSmallPltList.size());
        if (CollectionUtils.isNotEmpty(cmdSmallPltList)) {
            cmdSmallPltMap = cmdSmallPltList.stream().collect(Collectors.groupingBy(PmCmdSmallPlt::getPonoSlabNo));
        }
        Map<String , PmCmdLargePlt> pmCmdLargePltMap = Maps.uniqueIndex(pmCmdLargePlts, PmCmdLargePlt::getPonoSlabNo);
        List<PmCmdLargePlt> updatePmCmdLargePlts = Lists.newArrayList();
        List<PmCmdSmallPlt> updatePmCmdSmallPlts = Lists.newArrayList();
        Map<String , List<PmCmdLargePlt>> matDesignKindGroupMap = new HashMap<String, List<PmCmdLargePlt>>();
        for (PmPreSubstitutionDTO pmPreSubstitution : preSubstitutionDTOs) {
            // 新的
            PmCmdLargePlt replaceResult = pmCmdLargePltMap.get(pmPreSubstitution.getReplaceSlabNo());
            // 旧的
            PmCmdLargePlt orgRepresentResult = pmCmdLargePltMap.get(pmPreSubstitution.getOrgRepresentPonoSlabNo());
            PmCmdLargePlt updateReplaceResult = new PmCmdLargePlt();
            PmCmdLargePlt updateOrgRepresentResult = new PmCmdLargePlt();
            updateReplaceResult.setSampleLenHead(orgRepresentResult.getSampleLenHead());
            updateReplaceResult.setSampleLenTail(orgRepresentResult.getSampleLenTail());
            updateReplaceResult.setSampleLenMid(orgRepresentResult.getSampleLenMid());
            updateReplaceResult.setSampleLen(orgRepresentResult.getSampleLen());
            updateReplaceResult.setSampleLenGive(orgRepresentResult.getSampleLenGive());
            updateReplaceResult.setSampleHeadLenFree(orgRepresentResult.getSampleHeadLenFree());
            updateReplaceResult.setSampleTailLenFree(orgRepresentResult.getSampleTailLenFree());
            updateReplaceResult.setSampleHeadLenPlate(orgRepresentResult.getSampleHeadLenPlate());
            updateReplaceResult.setSampleTailLenPlate(orgRepresentResult.getSampleTailLenPlate());
            updateReplaceResult.setPmCmdLargePltId(replaceResult.getPmCmdLargePltId());
            updateReplaceResult.setObjectVersionNumber(replaceResult.getObjectVersionNumber());
            updateReplaceResult.setReplaceFlag(BaseConstants.FlagChar.YES);
            updateOrgRepresentResult.setSampleLenHead(BigDecimal.ZERO);
            updateOrgRepresentResult.setSampleLenTail(BigDecimal.ZERO);
            updateOrgRepresentResult.setSampleLenMid(BigDecimal.ZERO);
            updateOrgRepresentResult.setSampleLen(BigDecimal.ZERO);
            updateOrgRepresentResult.setSampleLenGive(BigDecimal.ZERO);
            updateOrgRepresentResult.setSampleHeadLenFree(BigDecimal.ZERO);
            updateOrgRepresentResult.setSampleTailLenFree(BigDecimal.ZERO);
            updateOrgRepresentResult.setSampleHeadLenPlate(BigDecimal.ZERO);
            updateOrgRepresentResult.setSampleTailLenPlate(BigDecimal.ZERO);
            updateOrgRepresentResult.setPmCmdLargePltId(orgRepresentResult.getPmCmdLargePltId());
            updateOrgRepresentResult.setObjectVersionNumber(orgRepresentResult.getObjectVersionNumber());
            updateOrgRepresentResult.setReplaceFlag(BaseConstants.FlagChar.NO);
            updatePmCmdLargePlts.add(updateOrgRepresentResult);
            updatePmCmdLargePlts.add(updateReplaceResult);
            if(!matDesignKindGroupMap.containsKey(replaceResult.getMatDesignKind())) {
                matDesignKindGroupMap.put(replaceResult.getMatDesignKind()  , new ArrayList<>());
            }
            matDesignKindGroupMap.get(replaceResult.getMatDesignKind()).add(replaceResult);
            if(!matDesignKindGroupMap.containsKey(orgRepresentResult.getMatDesignKind())) {
                matDesignKindGroupMap.put(orgRepresentResult.getMatDesignKind()  , new ArrayList<>());
            }
            matDesignKindGroupMap.get(orgRepresentResult.getMatDesignKind()).add(orgRepresentResult);

            // 更新命令小板表
            List<PmCmdSmallPlt> smallReplaceResult = cmdSmallPltMap.get(pmPreSubstitution.getReplaceSlabNo());
            List<PmCmdSmallPlt> orgSmallRepresentResult = cmdSmallPltMap.get(pmPreSubstitution.getOrgRepresentPonoSlabNo());
            if (CollectionUtils.isEmpty(smallReplaceResult) != CollectionUtils.isEmpty(orgSmallRepresentResult)) {
                throw new CommonException("pm.cmd_small_plt_001", pmPreSubstitution.getOrgRepresentPonoSlabNo(),
                        pmPreSubstitution.getReplaceSlabNo());
            }
            if (CollectionUtils.isEmpty(smallReplaceResult) && CollectionUtils.isEmpty(orgSmallRepresentResult)) {
                continue;
            }

            List<PmCmdSmallPlt> sortSmallReplaceResult = smallReplaceResult.stream()
                    .sorted(Comparator.comparing(PmCmdSmallPlt::getSmallPlateDivNo)).collect(Collectors.toList());

            List<PmCmdSmallPlt> sortOrgSmallRepresentResult = orgSmallRepresentResult.stream()
                    .sorted(Comparator.comparing(PmCmdSmallPlt::getSmallPlateDivNo)).collect(Collectors.toList());

            for (int i = 0; i < sortSmallReplaceResult.size(); i++) {
                if (i == 0) {
                    // 第一条数据赋值
                    PmCmdSmallPlt orgPmCmdSmallPltDivMin = sortOrgSmallRepresentResult.get(i);
                    PmCmdSmallPlt pmCmdSmallPltDivMin = sortSmallReplaceResult.get(i);
                    pmCmdSmallPltDivMin.setSampleHeadLenPlate(orgPmCmdSmallPltDivMin.getSampleHeadLenPlate());
                    pmCmdSmallPltDivMin.setSampleTailLenPlate(BigDecimal.ZERO);

                    if (i == (sortSmallReplaceResult.size() - 1)) {
                        if (sortOrgSmallRepresentResult.size() > 1) {
                            pmCmdSmallPltDivMin.setSampleTailLenPlate(sortOrgSmallRepresentResult.get(sortOrgSmallRepresentResult.size() - 1).getSampleTailLenPlate());
                        } else {
                            pmCmdSmallPltDivMin.setSampleTailLenPlate(orgPmCmdSmallPltDivMin.getSampleTailLenPlate());
                        }
                    }

                    updatePmCmdSmallPlts.add(pmCmdSmallPltDivMin);
                } else if (sortSmallReplaceResult.size() > 1 && i == sortSmallReplaceResult.size() - 1) {
                    // 最后一条数据赋值
                    PmCmdSmallPlt pmCmdSmallPltDivMax = sortSmallReplaceResult.get(i);
                    pmCmdSmallPltDivMax.setSampleTailLenPlate(sortOrgSmallRepresentResult.get(sortOrgSmallRepresentResult.size() - 1).getSampleTailLenPlate());
                    pmCmdSmallPltDivMax.setSampleHeadLenPlate(BigDecimal.ZERO);
                    updatePmCmdSmallPlts.add(pmCmdSmallPltDivMax);
                } else {
                    PmCmdSmallPlt pmCmdSmallPltDiv = sortSmallReplaceResult.get(i);
                    updatePmCmdSmallPlts.add(pmCmdSmallPltDiv);
                }
            }

            for (int i = 0; i < sortOrgSmallRepresentResult.size(); i++) {
                PmCmdSmallPlt orgPmCmdSmallPltDiv = sortOrgSmallRepresentResult.get(i);
                if (i == 0 || i == sortOrgSmallRepresentResult.size() - 1) {
                    orgPmCmdSmallPltDiv.setSampleTailLenPlate(BigDecimal.ZERO);
                    orgPmCmdSmallPltDiv.setSampleHeadLenPlate(BigDecimal.ZERO);
                    updatePmCmdSmallPlts.add(orgPmCmdSmallPltDiv);
                }
            }

        }
        pmCmdSmallPltRepository.batchUpdateByPrimaryKeySelective(updatePmCmdSmallPlts);
        pmCmdLargePltRepository.batchUpdateByPrimaryKeySelective(updatePmCmdLargePlts);
        for (Entry<String, List<PmCmdLargePlt>> entry : matDesignKindGroupMap.entrySet()) {
            SecondaryDesignStrategy secondaryDesignStrategy = SecondaryDesignStrategyFactory.matchStrategy(entry.getKey());
            if(secondaryDesignStrategy == null) {
                continue;
            }
            try {
                SecondaryDesignHelper.set(false, false, false);
                secondaryDesignStrategy.secondaryDesign(organizationId, entry.getValue());
                secondaryDesignStrategy.commandCreate(organizationId, entry.getValue());
            } finally {
                SecondaryDesignHelper.remove();
            }
        }
        //  调用轧钢代预替代接口，传给轧钢模块：原代表板命令板坯号、替代命令板坯号。
        Map<String, List<PmCmdSmallPlt>> updatePmCmdSmallPltMap = updatePmCmdSmallPlts.stream()
                .collect(Collectors.groupingBy(PmCmdSmallPlt::getPonoSlabNo));
        List<MmCutSeqVO> mmCutSeqDTOList = new ArrayList<>(preSubstitutionDTOs.size());
        
        Map<String , PmCmdVO> pmCmdVoMap = pmCmdLargePltService.queryCmdVo(ponoSlabNoList, organizationId, true);
        
        for (PmPreSubstitutionDTO pmPreSubstitution : preSubstitutionDTOs) {
            MmCutSeqVO mmCutSeqDTO = new MmCutSeqVO();
            mmCutSeqDTO.setOldPoNoSlab(pmPreSubstitution.getOrgRepresentPonoSlabNo());
            mmCutSeqDTO.setNewPoNoSlab(pmPreSubstitution.getReplaceSlabNo());
            List<PmCmdSmallPlt> pmCmdSmallPltList = Lists.newLinkedList();
            if (CollectionUtils.isNotEmpty(updatePmCmdSmallPltMap.get(pmPreSubstitution.getOrgRepresentPonoSlabNo()))) {
                pmCmdSmallPltList.addAll(updatePmCmdSmallPltMap.get(pmPreSubstitution.getOrgRepresentPonoSlabNo()));
            }
            if (CollectionUtils.isNotEmpty(updatePmCmdSmallPltMap.get(pmPreSubstitution.getReplaceSlabNo()))) {
                pmCmdSmallPltList.addAll(updatePmCmdSmallPltMap.get(pmPreSubstitution.getReplaceSlabNo()));
            }
            if(pmCmdVoMap != null && !pmCmdVoMap.isEmpty()) {
                mmCutSeqDTO.setCmdVOList(new ArrayList<>(2));
                if(pmCmdVoMap.containsKey(pmPreSubstitution.getOrgRepresentPonoSlabNo())) {
                    mmCutSeqDTO.getCmdVOList().add(pmCmdVoMap.get(pmPreSubstitution.getOrgRepresentPonoSlabNo()));
                }
                if(pmCmdVoMap.containsKey(pmPreSubstitution.getReplaceSlabNo())) {
                    mmCutSeqDTO.getCmdVOList().add(pmCmdVoMap.get(pmPreSubstitution.getReplaceSlabNo()));
                }
            }
            mmCutSeqDTOList.add(mmCutSeqDTO);
        }
        mmEventClient.batchUpdateCutSeq(organizationId, mmCutSeqDTOList);
    }
    
    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    public Boolean createTwoRollInterim(List<PmTwoRollInterimRequestDTO> requestList , Long organizationId) {
        for (PmTwoRollInterimRequestDTO pmTwoRollInterimRequestDTO : requestList) {
            pmTwoRollInterimRequestDTO.setTenantId(organizationId);
            pmPdSlabService.createTwoRollInterim(pmTwoRollInterimRequestDTO , PdMatType.S);
        }
        return true;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean mscLineNoChange(List<PmPdMscLineChangeDTO> changeRequestList , Long organizationId) {
        Set<String> ponoSLabNoList = new HashSet<>();
        List<SlabNoCorrespondingBigLotVo> dtoList = new ArrayList<>();
        for (PmPdMscLineChangeDTO pmPdMscLineChangeDTO : changeRequestList) {
            for (String ponoSlab : pmPdMscLineChangeDTO.getPonoSlabNo().split(",")) {
                ponoSLabNoList.add(ponoSlab);
                SlabNoCorrespondingBigLotVo slabNoCorrespondingBigLotVo = new SlabNoCorrespondingBigLotVo();
                slabNoCorrespondingBigLotVo.setPonoSlab(ponoSlab);
                dtoList.add(slabNoCorrespondingBigLotVo);
            }
        }
        List<SlabNoCorrespondingBigLotReturnVo> result = qeApiClient.slabNoCorrespondingBigLot(organizationId, dtoList);
        for (SlabNoCorrespondingBigLotReturnVo slabNoCorrespondingBigLotReturnVo : result) {
            if(slabNoCorrespondingBigLotReturnVo.getPonoSlabList() == null || slabNoCorrespondingBigLotReturnVo.getPonoSlabList().isEmpty()) {
                throw new CommonException(String.format("命令板坯号【%s】无试批组信息", slabNoCorrespondingBigLotReturnVo.getPonoSlab()));
            }
            for (String ponoSlabNo : slabNoCorrespondingBigLotReturnVo.getPonoSlabList()) {
                if(!ponoSLabNoList.contains(ponoSlabNo)) {
                    throw new CommonException(String.format("根据命令板坯号【%s】所选试坯组不属于同一个试坯组，不能产线变更", ponoSlabNo));
                }
            }
        }
        
        List<PmCmdSlab> pmCmdSlabs = pmCmdSlabRepository.selectByPonoSlabList(Lists.newArrayList(ponoSLabNoList), organizationId);
        Map<String , PmCmdSlab> pmCmdSlabMap = new HashMap<>();
        for (PmCmdSlab pmCmdSlab : pmCmdSlabs) {
            pmCmdSlabMap.put(pmCmdSlab.getPonoSlabNo() , pmCmdSlab);
        }
        
        List<String> pmCmdLargePltTmpSlabNo = new ArrayList<>();
        Map<String ,PmCmdSlab> updateListMap = new HashMap<>();
        List<PmCmdSlab> updateList = new ArrayList<>();
        List<PmCmdCont> updatePmCmdContList = new ArrayList<>();
        List<PmCmdSmallPlt> pmCmdSmallPltList = new ArrayList<>();
        List<PmUpdateSlabDTO> pmUpdateSlabDTO = new ArrayList<>();
        
        List<String> slabBoardList = new ArrayList<>(); 
        Map<String ,String> mscLineNoChangeMapping = new HashMap<>();
        PdMatType pdMatType = null;
        List<PmLineNoChangeDTO> changeDtos = new ArrayList<>();
        for (PmPdMscLineChangeDTO changeRequest : changeRequestList) {
            changeDtos.add(new PmLineNoChangeDTO(changeRequest.getMatNo(), changeRequest.getMscLineNo(), 5 , changeRequest.getPonoSlabNo()));
            for (String ponoSlab : changeRequest.getPonoSlabNo().split(",")) {
                mscLineNoChangeMapping.put(ponoSlab, changeRequest.getMscLineNo());
                changeRequest.setTenantId(organizationId);
                PmCmdSlab pmCmdSlab = pmCmdSlabMap.get(ponoSlab);
                if(null == pmCmdSlab) {
                    // 命令板坯号【{0}】未匹配号命令板坯数据
                    throw new CommonException("pm.pm_cmd_slab_004", ponoSlab);
                }
                MmSlab mmSlab = mmSlabRepository.selectByPonoSlabNo(ponoSlab, organizationId);
                if(mmSlab == null && "B".equals(pmCmdSlab.getIsMerge())) {
                    throw new CommonException("pm.pm_cmd_slab_007",pmCmdSlab.getPonoSlabNo());
                }
                if(mmSlab != null && !"23".equals(mmSlab.getSlabStatus())) {
                    throw new CommonException("pm.mm_slab_001", mmSlab.getSlabNo() ,mmSlab.getSlabStatus());
                }
                if(mmSlab != null) {
                    mmSlab.setMscLineNo(changeRequest.getMscLineNo());
                    PmUpdateSlabDTO updateSlab = new PmUpdateSlabDTO();
                    updateSlab.setMscLineNo(changeRequest.getMscLineNo());
                    updateSlab.setPonoSlab(ponoSlab);
                    pmUpdateSlabDTO.add(updateSlab);
                }
                
                pmCmdLargePltTmpSlabNo.add(pmCmdSlab.getTmpSlabNo());
                PmCmdSlab updatePmCmdSlab = new PmCmdSlab();
                updateListMap.put(pmCmdSlab.getTmpSlabNo() , updatePmCmdSlab);
                updatePmCmdSlab.setObjectVersionNumber(pmCmdSlab.getObjectVersionNumber());
                updatePmCmdSlab.setMscLineNo(changeRequest.getMscLineNo());
                updatePmCmdSlab.setPmCmdSlabId(pmCmdSlab.getPmCmdSlabId());
                updatePmCmdSlab.setSlabPreProc1("");
                updatePmCmdSlab.setSlabPreProc2("");
                updatePmCmdSlab.setSlabPreProc3("");
                updatePmCmdSlab.setSlabPreProc4("");
                updatePmCmdSlab.setSlabPreProc5("");
                updatePmCmdSlab.setSlabPreProc6("");
                updatePmCmdSlab.setSlabPreProc7("");
                updatePmCmdSlab.setSlabPreProc8("");
                updatePmCmdSlab.setSlabPreProc9("");
                updatePmCmdSlab.setSlabPreProc10("");
                updatePmCmdSlab.setSlabPreProc11("");
                updatePmCmdSlab.setSlabPreProc12("");
                updatePmCmdSlab.setSlabPreProc13("");
                updatePmCmdSlab.setSlabPreProc14("");
                updatePmCmdSlab.setSlabPreProc15("");
                updateList.add(updatePmCmdSlab);
                pdMatType = PdMatType.getByCode(pmCmdSlab.getMatDesignKind());
                if(PdMatType.C.getCode().equals(pmCmdSlab.getMatDesignKind())) {
                    if(!"28".equals(pmCmdSlab.getPdStatusHp())) {
                        throw new CommonException("pm.pm_cmd_slab_006", pmCmdSlab.getPdStatusHp());
                    }
                    List<String> removePdMatNo = new ArrayList<>();
                    removePdMatNo.add(pmCmdSlab.getVirtualSlabNo());
                    PmPdCcSlab pmPdCcSlab = pmPdCcSlabRepository.selectByPdMatNo(changeRequest.getTenantId(), pmCmdSlab.getVirtualSlabNo());
                    List<PmSmallPltPos> pmSmallPltPoss = pmSmallPltPosRepository.selectByPdMatNo(changeRequest.getTenantId(), pmCmdSlab.getVirtualSlabNo());
                    List<PmPdContSum> pmPdContSums =  pmPdContSumRepository.selectByPdMatNo(changeRequest.getTenantId(), pmCmdSlab.getVirtualSlabNo());
                    
                    PmProContYieldRequestDTO pmProContYieldRequest = getSlabCalcRequest(pmPdCcSlab, pmSmallPltPoss, pmPdContSums, changeRequest);
                    pmPdCcSlabRepository.deleteByPrimaryKey(pmPdCcSlab.getVirtualSlabId());
                    pmPdContSumRepository.deleteByMatNo(changeRequest.getTenantId() , removePdMatNo);
                    pmPdPlateCutRepository.deleteByMatNo(changeRequest.getTenantId() , removePdMatNo);
                    pmSmallPltPosRepository.deleteByMatNo(changeRequest.getTenantId() , removePdMatNo);
                    pmPdBlockPosRepository.deleteByMatNo(changeRequest.getTenantId() , removePdMatNo);
                    
                    pmProContYieldRequest.setSendCtEvent(false);
                    // 不抛合同跟踪，不抛履历事件
                    pmProContService.yiledCalcAndExec(pmProContYieldRequest, true);
                    
                    
                } else {
                    if(!"24".equals(pmCmdSlab.getPdStatusHp())) {
                        throw new CommonException("pm.pm_cmd_slab_006", pmCmdSlab.getPdStatusHp());
                    }
                    slabBoardList.add(pmCmdSlab.getVirtualSlabNo());
                }
                List<PmCmdCont> pmCmdContList = pmCmdContRepository.selectByCondition(Condition.builder(PmCmdCont.class)
                        .andWhere(Sqls.custom().andEqualTo(PmCmdCont.FIELD_TENANT_ID, pmCmdSlab.getTenantId())
                                .andEqualTo(PmCmdCont.FIELD_TMP_SLAB_NO, pmCmdSlab.getTmpSlabNo())
                                .andEqualTo(PmCmdCont.FIELD_MSC_LINE_NO, pmCmdSlab.getMscLineNo()))
                        .build());
                for (PmCmdCont pmCmdCont : pmCmdContList) {
                    PmCmdCont updatePmCmdCont = new PmCmdCont();
                    updatePmCmdCont.setPmCmdContId(pmCmdCont.getPmCmdContId());
                    updatePmCmdCont.setObjectVersionNumber(pmCmdCont.getObjectVersionNumber());
                    updatePmCmdCont.setMscLineNo(changeRequest.getMscLineNo());
                    updatePmCmdContList.add(updatePmCmdCont);
                }
                List<PmCmdSmallPlt> pmCmdSmallPlts = pmCmdSmallPltRepository.selectByCondition(Condition.builder(PmCmdSmallPlt.class)
                        .andWhere(Sqls.custom().andEqualTo(PmCmdSmallPlt.FIELD_TENANT_ID, pmCmdSlab.getTenantId())
                                .andEqualTo(PmCmdSmallPlt.FIELD_TMP_SLAB_NO, pmCmdSlab.getTmpSlabNo())
                                .andEqualTo(PmCmdSmallPlt.FIELD_MSC_LINE_NO, pmCmdSlab.getMscLineNo()))
                        .build());
                
                for (PmCmdSmallPlt pmCmdSmallPlt : pmCmdSmallPlts) {
                    PmCmdSmallPlt updatePmCmdSmallPlt = new PmCmdSmallPlt();
                    updatePmCmdSmallPlt.setPmCmdSmallPltId(pmCmdSmallPlt.getPmCmdSmallPltId());
                    updatePmCmdSmallPlt.setObjectVersionNumber(pmCmdSmallPlt.getObjectVersionNumber());
                    updatePmCmdSmallPlt.setMscLineNo(changeRequest.getMscLineNo());
                    pmCmdSmallPltList.add(updatePmCmdSmallPlt);
                }
            }
            
        }
        
        if(!slabBoardList.isEmpty()) {
            List<PmPdSlab> pmPdSlabs = pmPdSlabRepository.selectByVirtualSlabNoList(slabBoardList, organizationId);
            for (PmPdSlab pmPdSlab : pmPdSlabs) {
                if(mscLineNoChangeMapping.containsKey(pmPdSlab.getVirtualSlabNo())) {
                    pmPdSlab.setMscLineNo(mscLineNoChangeMapping.get(pmPdSlab.getVirtualSlabNo()));
                }
            }
            pmPdSlabRepository.batchUpdateByPrimaryKeySelective(pmPdSlabs);
        }
        
        List<PmCmdLargePlt> pmCmdLargePlts = pmCmdLargePltRepository.selectByCondition(Condition.builder(PmCmdLargePlt.class)
                .andWhere(Sqls.custom().andEqualTo(PmCmdLargePlt.FIELD_TENANT_ID, organizationId)
                        .andIn(PmCmdLargePlt.FIELD_TMP_SLAB_NO, pmCmdLargePltTmpSlabNo)).build());
        List<PmCmdLargePlt> updates = new ArrayList<>();
        
        for (PmCmdLargePlt pmCmdLargePlt : pmCmdLargePlts) {
            PmCmdLargePlt upfatePmCmdLargePlt = new PmCmdLargePlt(); 
            PmCmdSlab updatePmCmdSlab = updateListMap.get(pmCmdLargePlt.getTmpSlabNo());
            upfatePmCmdLargePlt.setObjectVersionNumber(pmCmdLargePlt.getObjectVersionNumber());
            upfatePmCmdLargePlt.setPmCmdLargePltId(pmCmdLargePlt.getPmCmdLargePltId());
            upfatePmCmdLargePlt.setMscLineNo(updatePmCmdSlab.getMscLineNo());
            pmCmdLargePlt.setMscLineNo(updatePmCmdSlab.getMscLineNo());
            updates.add(upfatePmCmdLargePlt);
        }
        pmCmdSlabRepository.batchUpdateByPrimaryKeySelective(updateList);
        pmCmdLargePltRepository.batchUpdateByPrimaryKeySelective(updates);
        pmCmdContRepository.batchUpdateByPrimaryKeySelective(updatePmCmdContList);
        if(pmCmdSmallPltList != null && !pmCmdSmallPltList.isEmpty()) {
            pmCmdSmallPltRepository.batchUpdateByPrimaryKeySelective(pmCmdSmallPltList);
        }
        SecondaryDesignStrategy secondaryDesignStrategy = SecondaryDesignStrategyFactory.matchStrategy(pdMatType);
        try {
            SecondaryDesignHelper.set(false, false, false);
            secondaryDesignStrategy.secondaryDesign(organizationId, pmCmdLargePlts);
            secondaryDesignStrategy.commandCreate(organizationId, pmCmdLargePlts);
            eventClient.sendEventWithOutResponse(organizationId, CtEventConstants.PM_MATERIAL_PRODUCTION_LINE_CHANGE, changeDtos);
        } finally {
            SecondaryDesignHelper.remove();
        }
        // 更新轧钢
        mmEventClient.updateSlabMscLineNo(organizationId, pmUpdateSlabDTO);
        return true;
    }


    /**
     * 轧制废料复合材料
     *
     * @param tenantId 租户id
     * @param pmRollingWasteCompositeDTOList pm轧制废料复合dtolist
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Void compositeChange(Long tenantId, List<PmRollingWasteCompositeDTO> pmRollingWasteCompositeDTOList) {
        // 检查输入参数是否有效，如果板坯ID列表或租户ID为空，则抛出异常
        if (CollectionUtils.isEmpty(pmRollingWasteCompositeDTOList) || Objects.isNull(tenantId)) {
            // 参数【{0}】不能为空！
            throw new CommonException("pm.pm_pro_cont_009", "pmRollingWasteCompositeDTOList");
        }
        // 收集唯一的板坯ID列表
        List<Long> slabIds = pmRollingWasteCompositeDTOList.stream().map(PmRollingWasteCompositeDTO::getSlabId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(slabIds)) {
            // 参数【{0}】不能为空！
            throw new CommonException("pm.pm_pro_cont_009", "slabIds");
        }
        // 根据的表ID列表查询行数据
        List<PmCompositeSlab> pmCompositeSlabs = pmCompositeSlabRepository.selectByCondition(Condition.builder(PmCompositeSlab.class)
                .select(PmCompositeSlab.FIELD_SLAB_ID,
                        PmCompositeSlab.FIELD_STATUS_CODE,
                        PmCompositeSlab.FIELD_CORRECTION_FLAG,
                        PmCompositeSlab.FIELD_OBJECT_VERSION_NUMBER)
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlab.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmCompositeSlab.FIELD_SLAB_ID, slabIds)).build());
        if (CollectionUtils.isEmpty(pmCompositeSlabs)) {
            //通过复合/叠轧坯ID【{0}】未匹配到数据！
            throw new CommonException("pm.pm_pro_cont_058", StringUtils.join(slabIds, BaseConstants.Symbol.COMMA));
        }

        // 将查询结果转换为Map，以便快速查找
        Map<Long, PmCompositeSlab> pmCompositeSlabMap = pmCompositeSlabs.stream().collect(Collectors.toMap(PmCompositeSlab::getSlabId, t -> t));

        // 遍历DTO列表，更新复合板坯实体
        for (PmRollingWasteCompositeDTO pmRollingWasteCompositeDTO : pmRollingWasteCompositeDTOList) {
            PmCompositeSlab pmCompositeSlab = pmCompositeSlabMap.get(pmRollingWasteCompositeDTO.getSlabId());
            if (Objects.isNull(pmCompositeSlab)) {
                continue;
            }
            // 更新状态码和校正标志，如果DTO中没有提供，则使用现有值
            pmCompositeSlab.setStatusCode(StringUtils.isNotBlank(pmRollingWasteCompositeDTO.getStatusCode()) ? pmRollingWasteCompositeDTO.getStatusCode() : pmCompositeSlab.getStatusCode());
            pmCompositeSlab.setCorrectionFlag(StringUtils.isNotBlank(pmRollingWasteCompositeDTO.getCorrectionFlag()) ? pmRollingWasteCompositeDTO.getCorrectionFlag() : pmCompositeSlab.getCorrectionFlag());
        }

        // 批量更新板坯的状态码
        pmCompositeSlabRepository.batchUpdateByPrimaryKeySelective(pmCompositeSlabs);
        return null;
    }

    private PmProContYieldRequestDTO getSlabCalcRequest(PmPdCcSlab pmPdCcSlab ,List<PmSmallPltPos> pmSmallPltPoss, List<PmPdContSum> pmPdContSums , PmPdMscLineChangeDTO request) {
        PmProContProdTtr record = new PmProContProdTtr();
        record.setTenantId(request.getTenantId());
        record.setOrderNo(pmPdCcSlab.getOrderNoAxis());
        PmProContProdTtr axisPmProContProdTtr = pmProContProdTtrRepository.selectOne(record);
        PmProContYieldRequestDTO pmProContYieldRequestDTO = new PmProContYieldRequestDTO();
        pmProContYieldRequestDTO.setSendCtEvent(false);
        pmProContYieldRequestDTO.setAxisOrderNo(pmPdCcSlab.getOrderNoAxis());
        pmProContYieldRequestDTO.setVirtualSlabNo(pmPdCcSlab.getVirtualSlabNo());
        pmProContYieldRequestDTO.setTenantId(pmPdCcSlab.getTenantId());
        FormPlateModeStrategy formPlateModeStrategy = FormPlateModeStrategyFactory.matchStrategy(pmPdCcSlab.getFormPlateMode());
        // 组板位置参数
        PmCompositeBoardDTO pmCompositeBoardDTO = formPlateModeStrategy.buildPmCompositeBoard(FormPlateMode.getByCode(pmPdCcSlab.getFormPlateMode()) ,pmSmallPltPoss, axisPmProContProdTtr, request.getMscLineNo(), pmPdCcSlab.getTenantId());
        pmProContYieldRequestDTO.setCompositeBoard(pmCompositeBoardDTO);
        
        List<PmProContYieldDTO> pmProContYieldList = new ArrayList<>();
        
        for (PmPdContSum pmPdContSum : pmPdContSums) {
            PmProContYieldDTO pmProContYieldDTO = new PmProContYieldDTO();
            pmProContYieldDTO.setAxisFlag(pmPdContSum.getAxisFlag() == 1L);
            pmProContYieldDTO.setOrderNo(pmPdContSum.getOrderNo());
            pmProContYieldDTO.setSmallPlateLen(pmPdContSum.getSmallPlateLen());
            pmProContYieldDTO.setSkipCheckQty(true);
            pmProContYieldList.add(pmProContYieldDTO);
        }
        pmProContYieldRequestDTO.setPmProContYieldList(pmProContYieldList);
        PmProContFilterRequestDTO pmContFilterRequest = new PmProContFilterRequestDTO();
        pmContFilterRequest.setMoldThick(pmPdCcSlab.getMoldThick());
        pmContFilterRequest.setMoldWidth(pmPdCcSlab.getMoldWid());
        pmContFilterRequest.setStNo(pmPdCcSlab.getStNo());
        pmContFilterRequest.setSgSign(pmPdCcSlab.getSgSign());
        
        pmContFilterRequest.setFurType(PmPlateConstants.FUR_TYPR_C);
        pmContFilterRequest.setCcType(Constants.CcType.TYPE_1);
        pmContFilterRequest.setMatDesignKind(pmPdCcSlab.getMatDesignKind());
        pmContFilterRequest.setFixSlabLenFlag(pmPdCcSlab.getFixSlabLenFlag());
        pmContFilterRequest.setFixSlabLen(pmPdCcSlab.getFixSlabLen());
        pmContFilterRequest.setMscLineNo(request.getMscLineNo());
        pmContFilterRequest.setFormPlateMode(pmPdCcSlab.getFormPlateMode());
        pmContFilterRequest.setRollDirectCode(pmPdCcSlab.getRollDirectCode());
        pmProContYieldRequestDTO.setPmContFilterRequest(pmContFilterRequest) ;
        
        return pmProContYieldRequestDTO;
    }
    
    @Override
    public Boolean createIngotTwoRollInterim(List<PmTwoRollInterimRequestDTO> requestList , Long organizationId) {
        for (PmTwoRollInterimRequestDTO pmTwoRollInterimRequestDTO : requestList) {
            pmTwoRollInterimRequestDTO.setTenantId(organizationId);
            pmPdSlabService.createTwoRollInterim(pmTwoRollInterimRequestDTO , PdMatType.B);
        }
        return true;
    }
    
    @Override
    public void newTestBatch(Long tenantId, List<String> ponoSlabNoList) {
        if(ponoSlabNoList == null || ponoSlabNoList.isEmpty()) {
            return ;
        }
        List<PmCmdLargePlt> pmCmdLargePlts = pmCmdLargePltRepository.selectByCondition(Condition.builder(PmCmdLargePlt.class)
                .andWhere(Sqls.custom().andEqualTo(PmCmdLargePlt.FIELD_TENANT_ID, tenantId)
                        .andIn(PmCmdLargePlt.FIELD_PONO_SLAB_NO, ponoSlabNoList)).build());
        if(pmCmdLargePlts == null || pmCmdLargePlts.isEmpty()) {
            return ;
        }
        Map<String, List<PmCmdLargePlt>> pmCmdLargePltMap = Maps.newHashMap();
        for (PmCmdLargePlt pmCmdLargePlt : pmCmdLargePlts) {
            if(!pmCmdLargePltMap.containsKey(pmCmdLargePlt.getMatDesignKind())) {
                pmCmdLargePltMap.get(pmCmdLargePlt.getMatDesignKind()).add(pmCmdLargePlt);
            }
        }
        for (Entry<String, List<PmCmdLargePlt>> entry : pmCmdLargePltMap.entrySet()) {
            SecondaryDesignStrategy secondaryDesignStrategy = SecondaryDesignStrategyFactory.matchStrategy(entry.getKey());
            if(secondaryDesignStrategy != null) {
                secondaryDesignStrategy.sampleAddition(tenantId, entry.getValue());
                secondaryDesignStrategy.secondaryDesign(tenantId, entry.getValue());
                secondaryDesignStrategy.commandCreate(tenantId, entry.getValue());
            }
        }
        return ;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeBoardsFromOrder(Long tenantId, List<PmRemoveBoardsFromOrderDTO> dtoList) {
        if (CollectionUtils.isEmpty(dtoList)) {
            return;
        }

        List<PmSlabPreCastingDTO> resList = new ArrayList<>();
        Map<String, String> dtoMap = dtoList.stream().collect(Collectors.toMap(PmRemoveBoardsFromOrderDTO::getPonoSlab, PmRemoveBoardsFromOrderDTO::getMatStatus));
        // 外卖坯直接抛合同跟踪
        if ("20".equals(dtoList.get(0).getSlabDest())) {
            for (PmRemoveBoardsFromOrderDTO item : dtoList) {
                PmSlabPreCastingDTO pmSlabPreCastingDTO = new PmSlabPreCastingDTO();
                pmSlabPreCastingDTO.setMatNo(item.getPonoSlab());
                pmSlabPreCastingDTO.setPpFlag(5);
                pmSlabPreCastingDTO.setMatStatus(dtoMap.get(item.getPonoSlab()));
                pmSlabPreCastingDTO.setOrdFlag("2");
                resList.add(pmSlabPreCastingDTO);
            }
            // 抛合同跟踪，调用“质量-材料脱合同事件”
            log.info("<=====脱合同删除组板信息抛合同: dtoList = {}", JSONObject.toJSON(resList));
            eventClient.sendEventWithOutResponse(tenantId, Constants.EventCode.QE_MATERIAL_BREACH_OF_CONTRACT, resList);
            return ;
        }

        List<String> ponoSlabList = dtoList.stream().map(PmRemoveBoardsFromOrderDTO::getPonoSlab).distinct().collect(Collectors.toList());
        List<PmCmdLargePlt> largePltList = pmCmdLargePltRepository.selectByPonoSlabList(ponoSlabList, tenantId);
        List<String> virtualSlabNoList = new ArrayList<>();
        Map<String, String> ponoVirtualSlabMap = new HashMap<>(16);
        if (CollectionUtils.isEmpty(largePltList)) {
            throw new CommonException("根据命令板坯号:"+ Strings.join(ponoSlabList, ',') + "未在命令大板表获取到数据");
        }

        // 材料设计类型为C时候，组板状态>=27才可以删除
        Optional<PmCmdLargePlt> ccCmdLargePltOptional = largePltList.stream().filter(item -> "C".equals(item.getMatDesignKind()))
                .filter(item -> PdStatusHp.PD_STATUS_HP_27.compareTo(item.getPdStatusHp()) > 0).findFirst();
        if (ccCmdLargePltOptional.isPresent()) {
            throw new CommonException("命令板坯号【"+ ccCmdLargePltOptional.get().getPonoSlabNo()+"】的组板状态<27,尚在生成生产计划，无法删除");
        }

        // 材料设计类型为S,P时候，组板状态>=24才可以删除
        Optional<PmCmdLargePlt> cmdLargePltOptional = largePltList.stream().filter(item -> "S".equals(item.getMatDesignKind()) ||
                        "P".equals(item.getMatDesignKind())).filter(item -> PdStatusHp.PD_STATUS_HP_24.compareTo(item.getPdStatusHp()) > 0).findFirst();
        if (cmdLargePltOptional.isPresent()) {
            throw new CommonException("命令板坯号【"+ cmdLargePltOptional.get().getPonoSlabNo()+"】的组板状态<24,尚在生成生产计划，无法删除");
        }

        // 获取当前时间和用户账号
        Date now = new Date();
        String username = DetailsHelper.getUserDetails().getUsername();
        // 第一步：删除当前命令板坯号的组板信息
        List<PmPdBlockPosTra> insertPmPdBlockPosTraList = new ArrayList<>();
        List<PmPdContSumTra> insertPmPdContSumTraList = new ArrayList<>();
        List<PmSmallPltPosTra> insertPmSmallPltPosTraList = new ArrayList<>();
        List<PmSlabMerge> deleteSlabMergeList = new ArrayList<>();
        List<PmPdSlabTra> insertPmPdSlabTraList = new ArrayList<>();
        List<PmPdSlabInfoTra> insertPmPdSlabInfoTraList = new ArrayList<>();
        String apiCode = "";
        // 出钢材
        List<PmCmdLargePlt> steelPmCmdLargePltList = largePltList.stream().filter(item -> "C".equals(item.getMatDesignKind())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(steelPmCmdLargePltList)) {
            apiCode = Constants.PdProgram.CC_SLAB_DELETE_EVENT;
            List<String> tmpSlabNoList = steelPmCmdLargePltList.stream().map(PmCmdLargePlt::getTmpSlabNo).collect(Collectors.toList());

            List<PmCmdSlab> pmCmdSlabList = pmCmdSlabRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId);
            virtualSlabNoList.addAll(pmCmdSlabList.stream().map(PmCmdSlab::getVirtualSlabNo).collect(Collectors.toList()));

            // 判断是否是合并板坯第三条的命令板坯号-同时删除合并前那两条
            List<String> merTmpSlabNoList = steelPmCmdLargePltList.stream().filter(item -> Constants.MergeStatus.MERGE_A.equals(item.getIsMerge()))
                    .map(PmCmdLargePlt::getTmpSlabNo).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(merTmpSlabNoList)) {
               List<PmSlabMerge> pmSlabMergeList = pmSlabMergeRepository.selectByMerTmpSlabNoList(merTmpSlabNoList, tenantId);
                for (PmSlabMerge pmSlabMerge : pmSlabMergeList) {
                    tmpSlabNoList.add(pmSlabMerge.getTmpSlabNo());
                    ponoSlabList.add(pmSlabMerge.getPrecSlabNo());
                    ponoSlabList.add(pmSlabMerge.getPonoSlabNo());
                    virtualSlabNoList.add(pmSlabMerge.getVirtualSlabNo());
                    deleteSlabMergeList.add(pmSlabMerge);
                }
            }

            // 如果是合并的那两条,只删除自己
            List<String> twoTmpSlabNoList = steelPmCmdLargePltList.stream().filter(item -> Constants.MergeStatus.MERGE_B.equals(item.getIsMerge()))
                    .map(PmCmdLargePlt::getTmpSlabNo).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(twoTmpSlabNoList)) {
                List<PmSlabMerge> pmSlabMergeList = pmSlabMergeRepository.selectByTmpSlabNoList(twoTmpSlabNoList, tenantId);
                Set<String> tmpPonoSlabNoSet = new HashSet<>(pmSlabMergeList.size());
                Map<String, Long> pmSlabMergeMap = new HashMap<>(pmSlabMergeList.size());
                for (PmSlabMerge pmSlabMerge : pmSlabMergeList) {
                    tmpSlabNoList.add(pmSlabMerge.getTmpSlabNo());
                    virtualSlabNoList.add(pmSlabMerge.getVirtualSlabNo());
                    tmpPonoSlabNoSet.add(pmSlabMerge.getTmpPonoSlabNo());
                    ponoSlabList.add(pmSlabMerge.getPrecSlabNo());
                    if (pmSlabMergeMap.containsKey(pmSlabMerge.getTmpPonoSlabNo())) {
                        pmSlabMergeMap.put(pmSlabMerge.getTmpPonoSlabNo(), pmSlabMergeMap.get(pmSlabMerge.getTmpPonoSlabNo()) + 1L);
                    } else {
                        pmSlabMergeMap.put(pmSlabMerge.getTmpPonoSlabNo(), 1L);
                    }
                }
                // 查询表中剩余的合并板坯数据
                Map<String, List<PmSlabMerge>> allSlabMergeMap = pmSlabMergeRepository.selectByMerTmpSlabNoList(new ArrayList<>(tmpPonoSlabNoSet), tenantId)
                        .stream().collect(Collectors.groupingBy(PmSlabMerge::getTmpPonoSlabNo));
                for (String tmpPonoSlabNo : tmpPonoSlabNoSet) {
                    // 如果是合并板坯最后一条或者删除了两条合并板坯，则删除四大命令第三条合并板坯
                    if (allSlabMergeMap.get(tmpPonoSlabNo).size()  == 1 || pmSlabMergeMap.get(tmpPonoSlabNo).equals(2L)) {
                        ponoSlabList.add(allSlabMergeMap.get(tmpPonoSlabNo).get(0).getPonoSlabNo());
                    }
                }
                deleteSlabMergeList.addAll(pmSlabMergeList);
            }

            // Ⅰ根据“命令板坯号=虚拟板坯号”，删除组板连铸板坯表PM_PD_CC_SLAB中的相应记录（删除前存入组板连铸板坯历史表）；
            List<PmPdCcSlab> pmPdCcSlabList = pmPdCcSlabRepository.selectByVirtualSlabList(virtualSlabNoList, tenantId);
//            List<PmPdCcSlab> pmPdCcSlabList = pmPdCcSlabRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId);
            List<PmPdCcSlabTra> insertPmPdCcSlabTraList = pmPdCcSlabTraRepository.PmPdCcSlabTraList(pmPdCcSlabList, "D", now, username);
            pmPdCcSlabList.forEach(item -> {
                PmSlabPreCastingDTO pmSlabPreCastingDTO = new PmSlabPreCastingDTO();
                pmSlabPreCastingDTO.setMatNo(item.getVirtualSlabNo());
                pmSlabPreCastingDTO.setPpFlag(1);
                pmSlabPreCastingDTO.setMatStatus(dtoMap.get(item.getVirtualSlabNo()));
                pmSlabPreCastingDTO.setOrdFlag("2");
                resList.add(pmSlabPreCastingDTO);
            });
            pmPdCcSlabRepository.batchDeleteByPrimaryKey(pmPdCcSlabList);
            pmPdCcSlabTraRepository.batchInsertSelective(insertPmPdCcSlabTraList);
        }

        // 余坯
        List<String> compositePonoSlabNoList = largePltList.stream().filter(item -> "S".equals(item.getMatDesignKind()))
                .map(PmCmdLargePlt::getPonoSlabNo).distinct().collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(compositePonoSlabNoList)) {
            apiCode = Constants.PdProgram.SLAB_DELETE_EVENT;
            // （根据“命令板坯号=虚拟板坯号”，查询组板板坯表PM_PD_SLAB中的板坯号SLAB_NO
            List<PmPdSlab> pmPdSlabList = pmPdSlabRepository.selectByVirtualSlabNoList(compositePonoSlabNoList, tenantId);

            // 获取同一个板坯号的其他组板板坯表数据，并删除对应四大命令
            List<String> slabNoList = pmPdSlabList.stream().map(PmPdSlab::getSlabNo).distinct().collect(Collectors.toList());
            List<PmPdSlab> allPdSlabList = pmPdSlabRepository.selectListBySlabNoList(slabNoList, tenantId);
            if (CollectionUtils.isNotEmpty(allPdSlabList)) {
                ponoSlabList.addAll(allPdSlabList.stream().map(PmPdSlab::getVirtualSlabNo).collect(Collectors.toList()));
            }
            insertPmPdSlabTraList.addAll(pmPdSlabTraRepository.buildPmPdSlabTraList(allPdSlabList, "D", now, username));
            allPdSlabList.forEach(item -> {
                PmSlabPreCastingDTO pmSlabPreCastingDTO = new PmSlabPreCastingDTO();
                pmSlabPreCastingDTO.setMatNo(item.getVirtualSlabNo());
                pmSlabPreCastingDTO.setPpFlag(5);
                pmSlabPreCastingDTO.setMatStatus(dtoMap.get(item.getVirtualSlabNo()));
                pmSlabPreCastingDTO.setOrdFlag("2");
                resList.add(pmSlabPreCastingDTO);
            });
            // 如果是复合坯
            List<PmCompositeSlab> pmCompositeSlabList = pmCompositeSlabRepository.selectBySlabNoList(slabNoList, tenantId);
            if (CollectionUtils.isNotEmpty(pmCompositeSlabList)) {
                apiCode = Constants.PdProgram.COMPOSTITE_DELETE_EVENT;
                // 查询基材数据对应的命令板坯号
                List<Long> slabIdList = pmCompositeSlabList.stream().map(PmCompositeSlab::getSlabId).collect(Collectors.toList());
                List<PmCompositeSlabList> pmCompositeSlabLists = pmCompositeSlabListRepository.selectBySlabIdList(slabIdList, tenantId);
                List<String> baseMatNoList = pmCompositeSlabLists.stream().map(PmCompositeSlabList::getBaseMatNo).collect(Collectors.toList());
                slabNoList.addAll(baseMatNoList);
                List<String> basePonoSlabList = pmCmdLargePltRepository.selectBySlabNoList(baseMatNoList, tenantId).stream().map(PmCmdLargePlt::getPonoSlabNo).collect(Collectors.toList());
                ponoSlabList.addAll(basePonoSlabList);

                // 删除基材的组板板坯数据
                List<PmPdSlab> basePmPdSlabList = pmPdSlabRepository.selectListBySlabNoList(baseMatNoList, tenantId);
                pmPdSlabRepository.batchDeleteByPrimaryKey(basePmPdSlabList);
            }
            // 如果是复合坯，更新复合坯状态为54
            pmCompositeSlabList.forEach(item->item.setStatusCode(Constants.StatusCode.STATUS_CODE_54));
            pmCompositeSlabRepository.batchUpdateByPrimaryKey(pmCompositeSlabList);
            List<PmCompositeSlabDiv> pmCompositeSlabDivList = pmCompositeSlabDivRepository.selectByPonoSlabList(ponoSlabList, tenantId);
            pmCompositeSlabDivRepository.batchDeleteByPrimaryKey(pmCompositeSlabDivList);

            // 根据“板坯号=板坯号”删除板坯信息表PM_PD_SLAB_INFO中的相应记录（删除前存入板坯信息历史表）
            List<PmPdSlabInfo> pmPdSlabInfoList = pmPdSlabInfoRepository.selectBySlabNoList(slabNoList, tenantId);
            insertPmPdSlabInfoTraList.addAll(pmPdSlabInfoTraRepository.buildPmPdSlabInfoTraList(pmPdSlabInfoList, "D", now, username));
            pmPdSlabRepository.batchDeleteByPrimaryKey(allPdSlabList);
            pmPdSlabInfoRepository.batchDeleteByPrimaryKey(pmPdSlabInfoList);
        }

        // 余材
        List<String> platePonoSlabNoList = largePltList.stream().filter(item -> "P".equals(item.getMatDesignKind()))
                .map(PmCmdLargePlt::getPonoSlabNo).distinct().collect(Collectors.toList());
        List<String> plateNoList = largePltList.stream().map(PmCmdLargePlt::getPlateNo).filter(StringUtils::isNotEmpty).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(platePonoSlabNoList)) {
            apiCode = Constants.PdProgram.PLATE_DELETE_EVENT;
            virtualSlabNoList.addAll(platePonoSlabNoList);
            List<PmPdPlateTra> insertPmPdPlateTraList = new ArrayList<>();
            List<PmPdPlateInfoTra> insertPmPdPlateInfoTraList = new ArrayList<>();
            // 获取大板表的钢板号，钢板号PLATE_NO”，删除钢板信息表PM_PD_PLATE_INFO中的相应记录（删除前存入钢板信息历史表）
            List<PmPdPlate> pmPdPlateList = pmPdPlateRepository.selectByPlateNoList(tenantId, plateNoList);
            insertPmPdPlateTraList.addAll(pmPdPlateTraRepository.buildPmPdPlateTraList(pmPdPlateList, "D", now, username));
            pmPdPlateList.forEach(item -> {
                ponoVirtualSlabMap.put(item.getPlateNo(), item.getPlateNo());

                PmSlabPreCastingDTO pmSlabPreCastingDTO = new PmSlabPreCastingDTO();
                pmSlabPreCastingDTO.setMatNo(item.getPlateNo());
                pmSlabPreCastingDTO.setPpFlag(7);
                pmSlabPreCastingDTO.setMatStatus(dtoMap.get(item.getPlateNo()));
                pmSlabPreCastingDTO.setOrdFlag("2");
                resList.add(pmSlabPreCastingDTO);
            });
            List<PmPdPlateInfo> pdPlateInfoList = pmPdPlateInfoRepository.selectByPlateNoList(tenantId, plateNoList);
            insertPmPdPlateInfoTraList.addAll(pmPdPlateInfoTraRepository.buildPmPdPlateInfoTraList(pdPlateInfoList, "D", now, username));

            pmPdPlateRepository.batchDeleteByPrimaryKey(pmPdPlateList);
            pmPdPlateTraRepository.batchInsertSelective(insertPmPdPlateTraList);

            pmPdPlateInfoRepository.batchDeleteByPrimaryKey(pdPlateInfoList);
            pmPdPlateInfoTraRepository.batchInsertSelective(insertPmPdPlateInfoTraList);
        }

        // 删除四大命令表

        List<PmCmdLargePlt> pmCmdLargePltList = pmCmdLargePltRepository.selectByPonoSlabList(ponoSlabList, tenantId);
        List<PmCmdLargePltTra> insertPmCmdLargePltTraList = pmCmdLargePltTraRepository.buildPmCmdLargePltTraList(pmCmdLargePltList, "D", now, username);

        List<PmCmdSlab> pmCmdSlabList = pmCmdSlabRepository.selectByPonoSlabList(ponoSlabList, tenantId);
        virtualSlabNoList.addAll(pmCmdSlabList.stream().map(PmCmdSlab::getVirtualSlabNo).collect(Collectors.toList()));
        pmCmdSlabList.forEach(item -> ponoVirtualSlabMap.put(item.getPonoSlabNo(), item.getVirtualSlabNo()));
        List<PmCmdSlabTra> insertPmCmdSlabTraList = pmCmdSlabTraRepository.buildPmCmdSlabTraList(pmCmdSlabList, "D", now, username);

        List<PmCmdSmallPlt> cmdSmallPltList = pmCmdSmallPltRepository.selectByPonoSlabList(ponoSlabList, tenantId);
        List<PmCmdSmallPltTra> insertPmCmdSmallPltTraList = pmCmdSmallPltTraRepository.buildPmCmdSmallPltTraList(cmdSmallPltList, "D", now, username);

        List<PmCmdCont> pmCmdContList = pmCmdContRepository.selectByPonoSlabList(ponoSlabList, tenantId);
        List<PmCmdContTra> insertPmCmdContTraList = pmCmdContTraRepository.buildPmCmdContTraList(pmCmdContList, "D", now, username);

        List<PmPdBlockPos> pmPdBlockPosList = pmPdBlockPosRepository.selectByPdMatNoList(virtualSlabNoList, tenantId);
        insertPmPdBlockPosTraList.addAll(pmPdBlockPosTraRepository.buildPmPdBlockPosTraList(pmPdBlockPosList, "D", now, username));

        List<PmPdContSum> pmPdContSumList = pmPdContSumRepository.selectByPdMatNoList(tenantId, virtualSlabNoList);
        insertPmPdContSumTraList.addAll(pmPdContSumTraRepository.buildPmPdContSumTraList(pmPdContSumList, "D", now, username));

        List<PmSmallPltPos> pmSmallPltPosList = pmSmallPltPosRepository.selectPmSmallPltPos(tenantId, virtualSlabNoList);
        insertPmSmallPltPosTraList.addAll(pmSmallPltPosTraRepository.buildPmSmallPltPosTraList(pmSmallPltPosList, "D", now, username));


        pmPdSlabInfoTraRepository.batchInsertSelective(insertPmPdSlabInfoTraList);
        pmPdSlabTraRepository.batchInsertSelective(insertPmPdSlabTraList);
        pmPdBlockPosRepository.batchDeleteByPrimaryKey(pmPdBlockPosList);
        pmPdBlockPosTraRepository.batchInsertSelective(insertPmPdBlockPosTraList);
        pmSmallPltPosRepository.batchDeleteByPrimaryKey(pmSmallPltPosList);
        pmSmallPltPosTraRepository.batchInsertSelective(insertPmSmallPltPosTraList);
        pmPdContSumRepository.batchDeleteByPrimaryKey(pmPdContSumList);
        pmPdContSumTraRepository.batchInsertSelective(insertPmPdContSumTraList);
        pmCmdLargePltRepository.batchDeleteByPrimaryKey(pmCmdLargePltList);
        pmCmdLargePltTraRepository.batchInsertSelective(insertPmCmdLargePltTraList);
        pmCmdSlabRepository.batchDeleteByPrimaryKey(pmCmdSlabList);
        pmCmdSlabTraRepository.batchInsertSelective(insertPmCmdSlabTraList);
        pmCmdSmallPltRepository.batchDeleteByPrimaryKey(cmdSmallPltList);
        pmCmdSmallPltTraRepository.batchInsertSelective(insertPmCmdSmallPltTraList);
        pmCmdContRepository.batchDeleteByPrimaryKey(pmCmdContList);
        pmCmdContTraRepository.batchInsertSelective(insertPmCmdContTraList);
        pmSlabMergeRepository.batchDeleteByPrimaryKey(deleteSlabMergeList);


        // 存履历表
        Map<String , List<PmPdContSum>> contSumMap = pmPdContSumList.stream().collect(Collectors.groupingBy(PmPdContSum::getPdMatNo));
        Map<String, PmCmdLargePlt> pmCmdLargePltMap = pmCmdLargePltList.stream().collect(Collectors.toMap(PmCmdLargePlt::getPonoSlabNo, Function.identity()));
        for (Map.Entry<String, PmCmdLargePlt> entry : pmCmdLargePltMap.entrySet()) {
            PdMatTypeStrategy pdMatTypeStrategy = PdMatTypeStrategyFactory.matchStrategy(entry.getValue().getMatDesignKind());
            if (contSumMap.containsKey(ponoVirtualSlabMap.get(entry.getKey()))) {
                pdMatTypeStrategy.pdDeleteEvent(contSumMap.get(ponoVirtualSlabMap.get(entry.getKey())), ponoVirtualSlabMap.get(entry.getKey())
                        ,entry.getValue().getMscLineNo(), apiCode, tenantId, dtoList.get(0).getSystemCode(), dtoList.get(0).getEventMaker());
            }
        }

        // 第二步：抛合同跟踪，调用“质量-材料脱合同事件”
        log.info("<=====脱合同删除组板信息抛合同: dtoList = {}", JSONObject.toJSON(resList));
        eventClient.sendEventWithOutResponse(tenantId, Constants.EventCode.QE_MATERIAL_BREACH_OF_CONTRACT, resList);
    }

    @Override
    public List<PmQueryIsSampleDTO> queryIsSample(List<PmQueryIsSampleDTO> dtoList, Long tenantId) {
        if (CollectionUtils.isEmpty(dtoList)) {
            return Collections.emptyList();
        }
        List<String> ponoSlabNoList = dtoList.stream().map(PmQueryIsSampleDTO::getPonoSlabNo)
                .filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        List<String> plateNoList = dtoList.stream().map(PmQueryIsSampleDTO::getPlateNo)
                .filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        if(CollectionUtils.isEmpty(ponoSlabNoList)){
            return dtoList;
        }

        List<PmCmdLargePlt> cmdLargePltList = pmCmdLargePltRepository.selectByPonoSlabList(ponoSlabNoList, tenantId);

        // 如果是合并板坯，则判断对应另外两块
        Map<String, String> cmdLargePltMap = cmdLargePltList.stream().collect(Collectors.toMap(PmCmdLargePlt::getPonoSlabNo,
                item-> Optional.ofNullable(item.getIsMerge()).orElse(Constants.MergeStatus.MERGE_N)));
        List<String> mergePonoSlabNoList = cmdLargePltList.stream().filter(item -> Constants.MergeStatus.MERGE_A.equals(item.getIsMerge()))
                .map(PmCmdLargePlt::getPonoSlabNo).collect(Collectors.toList());
        Map<String, List<String>> pmSlabMergeMap = new HashMap<>(mergePonoSlabNoList.size());
        if (CollectionUtils.isNotEmpty(mergePonoSlabNoList)) {
            List<PmSlabMerge> pmSlabMergeList = pmSlabMergeRepository.selectByMerPonoSlabNoList(mergePonoSlabNoList, tenantId);
            ponoSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getPrecSlabNo).distinct().collect(Collectors.toList()));
            pmSlabMergeMap = pmSlabMergeList.stream().collect(Collectors.groupingBy(PmSlabMerge::getPonoSlabNo, Collectors.mapping(PmSlabMerge::getPrecSlabNo, Collectors.toList())));
        }

        // 根据命令板坯号，查询命令小板表
        List<PmCmdSmallPlt> cmdSmallPltList = pmCmdSmallPltRepository.selectByPonoSlabList(ponoSlabNoList, tenantId);
        Map<String, List<PmCmdSmallPlt>> cmdSmallPltMap = new HashMap<>(cmdSmallPltList.size());
        if (CollectionUtils.isNotEmpty(cmdSmallPltList)) {
            cmdSmallPltMap = cmdSmallPltList.stream().collect(Collectors.groupingBy(PmCmdSmallPlt::getPonoSlabNo));
        }

        //查询
        List<String> cmdLargePonoSlabNoYesList = cmdLargePltList.stream().filter(x -> BaseConstants.FlagChar.YES.equals(x.getReplaceFlag()))
                .map(PmCmdLargePlt::getPonoSlabNo).distinct().collect(Collectors.toList());
        List<String> cmdLargePonoSlabNoNoList = cmdLargePltList.stream().filter(x -> BaseConstants.FlagChar.NO.equals(x.getReplaceFlag()))
                .map(PmCmdLargePlt::getPonoSlabNo).distinct().collect(Collectors.toList());
        //查询轧钢 大板信息
        List<String> plateNoBPList = new ArrayList<>(16);
        if (CollectionUtils.isNotEmpty(plateNoList)) {
            List<List<String>> plateNoListList = Lists.partition(plateNoList, 1000);
            List<MmPlateVO> mmPlateVOList = new ArrayList<>(plateNoList.size());
            for (List<String> plateNoSplitList : plateNoListList) {
                mmPlateVOList.addAll(pmMmPlateMapper.getMmPlateByMatNo(plateNoSplitList, tenantId));
            }
            plateNoBPList = mmPlateVOList.stream().filter(x -> ("2".equals(x.getRecSts()) || "3".equals(x.getRecSts())) && "BP".equals(x.getProdCd()))
                    .map(MmPlateVO::getMatNo).distinct().collect(Collectors.toList());
        }
        //循环更新返回值
        for (PmQueryIsSampleDTO sampleDTO : dtoList) {
            sampleDTO.setIsSample("0");

            List<PmCmdSmallPlt> smallPltList = new ArrayList<>();
            if (cmdSmallPltMap.containsKey(sampleDTO.getPonoSlabNo())) {
                smallPltList.addAll(cmdSmallPltMap.get(sampleDTO.getPonoSlabNo()));
            }
            // 获取合并板坯另外两块子板命令小板表
            if (Constants.MergeStatus.MERGE_A.equals(cmdLargePltMap.get(sampleDTO.getPonoSlabNo()))) {
                for (String precSlabNo : pmSlabMergeMap.get(sampleDTO.getPonoSlabNo())) {
                    if (cmdSmallPltMap.containsKey(precSlabNo)) {
                        smallPltList.addAll(cmdSmallPltMap.get(precSlabNo));
                    }
                }
            }

            if (CollectionUtils.isEmpty(smallPltList)) {
                continue;
            }
            //是否能匹配到试样信息
            PmCmdSmallPlt cmdSmallPlt = null;
            PmCmdSmallPlt cmdSmallPltGive = null;
            //材料类型 1 为板坯
            if ("1".equals(sampleDTO.getMatType())) {
                cmdSmallPlt = smallPltList.stream().filter(this::isSample).findFirst().orElse(null);
                cmdSmallPltGive = smallPltList.stream().filter(this::isSampleGive).findFirst().orElse(null);
            }
            //材料类型 2 为钢板
            if ("2".equals(sampleDTO.getMatType()) && StringUtils.isNotBlank(sampleDTO.getPlateNo())
                    && sampleDTO.getPlateNo().length() >= 3) {
                //小板分割号 取钢板号后三位
                String smallPlateDivNo = sampleDTO.getPlateNo().substring(sampleDTO.getPlateNo().length() - 3);
                cmdSmallPlt = smallPltList.stream().filter(x -> smallPlateDivNo.equals(x.getSmallPlateDivNo()) && isSample(x)).findFirst().orElse(null);
                cmdSmallPltGive = smallPltList.stream().filter(x -> smallPlateDivNo.equals(x.getSmallPlateDivNo()) && isSampleGive(x)).findFirst().orElse(null);
                if (Objects.isNull(cmdSmallPlt) && plateNoBPList.contains(sampleDTO.getPlateNo())) {
                    cmdSmallPlt = smallPltList.stream().filter(this::isSample).findFirst().orElse(null);
                    cmdSmallPltGive = smallPltList.stream().filter(this::isSampleGive).findFirst().orElse(null);
                }
            }
            if (Objects.nonNull(cmdSmallPlt)) {
                sampleDTO.setIsSample("1");
                if (cmdLargePonoSlabNoYesList.contains(sampleDTO.getPonoSlabNo())) {
                    sampleDTO.setIsSample("2");
                }
            }
            //如果没有试样信息 大表板字段代预标记为N 状态就为3
            if ("0".equals(sampleDTO.getIsSample()) && cmdLargePonoSlabNoNoList.contains(sampleDTO.getPonoSlabNo())) {
                sampleDTO.setIsSample("3");
            }
            //奉送样相关 字段 不管是不是代表板都返回出去
            if (Objects.nonNull(cmdSmallPltGive)) {
                sampleDTO.setSampleLenGive(cmdSmallPltGive.getSampleLenGive());
                sampleDTO.setSampleGiveShp(cmdSmallPltGive.getSampleGiveShp());
            }
        }
        return dtoList;
    }

    /**
     *  判断是否为 代表板
     *
     * @param pmCmdSmallPlt 命令板坯
     * @return boolean
     *
     */
    boolean isSample(PmCmdSmallPlt pmCmdSmallPlt) {
        if (pmCmdSmallPlt.getSampleHeadLenFree() != null && pmCmdSmallPlt.getSampleHeadLenFree().compareTo(BigDecimal.ZERO) != 0) {
            return true;
        }
        if (pmCmdSmallPlt.getSampleTailLenFree() != null && pmCmdSmallPlt.getSampleTailLenFree().compareTo(BigDecimal.ZERO) != 0) {
            return true;
        }
        if (pmCmdSmallPlt.getSampleHeadLenPlate() != null && pmCmdSmallPlt.getSampleHeadLenPlate().compareTo(BigDecimal.ZERO) != 0) {
            return true;
        }
        if (pmCmdSmallPlt.getSampleTailLenPlate() != null && pmCmdSmallPlt.getSampleTailLenPlate().compareTo(BigDecimal.ZERO) != 0) {
            return true;
        }
        if (pmCmdSmallPlt.getSampleHeadLenMb() != null && pmCmdSmallPlt.getSampleHeadLenMb().compareTo(BigDecimal.ZERO) != 0) {
            return true;
        }
        if (pmCmdSmallPlt.getSampleTailLenMb() != null && pmCmdSmallPlt.getSampleTailLenMb().compareTo(BigDecimal.ZERO) != 0) {
            return true;
        }
        return false;
    }

    /**
     * 奉送样
     *
     * @param pmCmdSmallPlt 小型plt
     * @return boolean
     *
     */
    boolean isSampleGive(PmCmdSmallPlt pmCmdSmallPlt) {
        //确认逻辑修改
        if (pmCmdSmallPlt.getSampleLenGive() != null && BigDecimal.ZERO.compareTo(pmCmdSmallPlt.getSampleLenGive()) != 0) {
            return true;
        }
        if (pmCmdSmallPlt.getSampleGiveShp() != null) {
            return true;
        }
        return false;
    }

    @Override
    public List<PmProductionPlanResDTO> queryProductionPlanInfo(List<PmProductionPlanReqDTO> dtoList, Long tenantId) {
        List<PmProductionPlanResDTO> resList = new ArrayList<>(dtoList.size());
        if (CollectionUtils.isEmpty(dtoList)) {
            return resList;
        }

        List<String> allPonoList = new ArrayList<>(dtoList.size());
        List<String> ponoSlabNoList = new ArrayList<>(dtoList.size());
        for (PmProductionPlanReqDTO dto : dtoList) {
            if (StringUtils.isEmpty(dto.getPono())) {
                throw new CommonException("炉号不可为空");
            }
            allPonoList.add(dto.getPono());
            if (StringUtils.isNotEmpty(dto.getPonoSlabNo())) {
                ponoSlabNoList.add(dto.getPonoSlabNo());
            }
        }

        // 数据准备
        Map<String, PmSteelCastSlab> steelCastSlabMap = new HashMap<>(dtoList.size());
        Map<String, List<PmSteelCastSlab>> pmSteelCastSlabMap = new HashMap<>(dtoList.size());
        Set<String> orderNoSet = new HashSet<>(dtoList.size());
        Set<String> mscLineNoSet = new HashSet<>(dtoList.size());
        List<PmSteelCastSlab> pmSteelCastSlabList = pmSteelCastSlabRepository.selectByPonoList(allPonoList, tenantId);
        if (CollectionUtils.isEmpty(pmSteelCastSlabList)) {
            throw new CommonException("根据炉号【"+Strings.join(allPonoList, ',')+"】未获取到命令板坯表数据");
        }
        for (PmSteelCastSlab pmSteelCastSlab : pmSteelCastSlabList) {
            steelCastSlabMap.put(pmSteelCastSlab.getSlabNo(), pmSteelCastSlab);
            if (!pmSteelCastSlabMap.containsKey(pmSteelCastSlab.getPono())) {
                pmSteelCastSlabMap.put(pmSteelCastSlab.getPono(), new ArrayList<>());
            }
            pmSteelCastSlabMap.get(pmSteelCastSlab.getPono()).add(pmSteelCastSlab);
            orderNoSet.add(pmSteelCastSlab.getOrderNo());
            mscLineNoSet.add(pmSteelCastSlab.getMscLineNo());
            ponoSlabNoList.add(pmSteelCastSlab.getSlabNo());
        }
        // 获取命令参数表信息
        List<PmCmdCont> pmCmdContList = pmCmdContRepository.selectByPonoSlabList(ponoSlabNoList, tenantId);
        Map<String, PmCmdCont> pmCmdContMap = new HashMap<>(pmCmdContList.size());
        if (CollectionUtils.isNotEmpty(pmCmdContList)) {
            pmCmdContMap = pmCmdContList.stream().collect(Collectors.toMap(item -> Strings.concat(item.getPonoSlabNo(), item.getOrderNo()), Function.identity()));
        }
        // 获取命令大板表信息
        List<PmCmdLargePlt> cmdLargePltList = pmCmdLargePltRepository.selectByPonoSlabList(ponoSlabNoList, tenantId);
        Map<String, PmCmdLargePlt> cmdLargePltMap = new HashMap<>(cmdLargePltList.size());
        if (CollectionUtils.isNotEmpty(cmdLargePltList)) {
            cmdLargePltMap = cmdLargePltList.stream().collect(Collectors.toMap(PmCmdLargePlt::getPonoSlabNo, Function.identity()));
        }
        // 获取命令板坯表信息
        List<PmCmdSlab> pmCmdSlabList = pmCmdSlabRepository.selectByPonoSlabList(ponoSlabNoList, tenantId);
        List<String> virtualSlabNoList = new ArrayList<>(pmCmdSlabList.size());
        Map<String, String> ponoVirSlabMap = new HashMap<>(pmCmdSlabList.size());
        Map<String, PmPdCcSlab> pmPdCcSlabMap = new HashMap<>(pmCmdSlabList.size());
        Map<String, PmCmdSlab> pmCmdSlabMap = new HashMap<>(pmCmdSlabList.size());
        for (PmCmdSlab pmCmdSlab : pmCmdSlabList) {
            virtualSlabNoList.add(pmCmdSlab.getVirtualSlabNo());
            ponoVirSlabMap.put(pmCmdSlab.getPonoSlabNo(), pmCmdSlab.getVirtualSlabNo());
            pmCmdSlabMap.put(pmCmdSlab.getPonoSlabNo(), pmCmdSlab);
        }
        if (CollectionUtils.isNotEmpty(virtualSlabNoList)) {
            List<PmPdCcSlab> pmPdCcSlabList = pmPdCcSlabRepository.selectByVirtualSlabList(virtualSlabNoList, tenantId);
            pmPdCcSlabMap = pmPdCcSlabList.stream().collect(Collectors.toMap(PmPdCcSlab::getVirtualSlabNo, Function.identity()));
        }
        // 查询质量合同信息
        List<QdToPoOrderVO1> qdToPoOrderVO1List = pmQdToPoOrderRepository.selectQdOrderList(new ArrayList<>(orderNoSet), tenantId);
        Map<String, QdToPoOrderVO1> toPoOrderVO1Map = new HashMap<>(qdToPoOrderVO1List.size());
        if (CollectionUtils.isNotEmpty(qdToPoOrderVO1List)) {
            toPoOrderVO1Map = qdToPoOrderVO1List.stream().collect(Collectors.toMap(QdToPoOrderVO1::getOrderNo, Function.identity()));
        }
        // 查询质量合同产线数据
        List<QdToPoLineCombVO> qdToPoLineCombVOList = pmQdToPoOrderRepository.selectByOrderAndMscLineList(new ArrayList<>(orderNoSet), new ArrayList<>(mscLineNoSet), tenantId);
        Map<String, QdToPoLineCombVO> qdToPoLineCombVOMap = new HashMap<>(qdToPoLineCombVOList.size());
        if (CollectionUtils.isNotEmpty(qdToPoLineCombVOList)) {
            qdToPoLineCombVOMap = qdToPoLineCombVOList.stream().collect(Collectors.toMap(item -> Strings.concat(item.getOrderNo(), item.getMscLineNo()), Function.identity()));
        }

        // 组装返参
        for (PmProductionPlanReqDTO dto : dtoList) {
            PmProductionPlanResDTO planResDTO = new PmProductionPlanResDTO();
            planResDTO.setPono(dto.getPono());
            planResDTO.setSlabNo(dto.getSlabNo());
            planResDTO.setPonoSlabNo(dto.getPonoSlabNo());
            resList.add(planResDTO);

            // 命令板坯号不为空
            if (StringUtils.isNotBlank(dto.getPonoSlabNo())) {
                PmCmdLargePlt largePlt = cmdLargePltMap.get(dto.getPonoSlabNo());
                String orderRemainDiv = "1";
                PmSteelCastSlab pmSteelCastSlab = new PmSteelCastSlab();
                // 如果是合并板坯或者余材，余坯
                if (Objects.nonNull(largePlt) && (Constants.MergeStatus.MERGE_B.equals(largePlt.getIsMerge()) ||
                        PdMatType.S.getCode().equals(largePlt.getMatDesignKind()) || PdMatType.P.getCode().equals(largePlt.getMatDesignKind()))) {
                    PmCmdSlab pmCmdSlab = pmCmdSlabMap.get(dto.getPonoSlabNo());
                    planResDTO.setOrderNo(pmCmdSlab.getOrderNoAxis());
                    planResDTO.setMscLineNo(pmCmdSlab.getMscLineNo());
                    planResDTO.setSgSign(pmCmdSlab.getSgSign());
                    planResDTO.setSlabTargThk(pmCmdSlab.getPreCleanSlabThick());
                    planResDTO.setSlabTargWid(pmCmdSlab.getPreCleanSlabWidth());
                    planResDTO.setSlabTargLen(pmCmdSlab.getPreCleanSlabLen());
                    planResDTO.setHotChargeFlag(pmCmdSlab.getHotChargeFlag());

                    // 组装参数
                    pmSteelCastSlab.setSlabNo(pmCmdSlab.getPonoSlabNo());
                    pmSteelCastSlab.setOrderNo(pmCmdSlab.getOrderNoAxis());
                    pmSteelCastSlab.setMscLineNo(pmCmdSlab.getMscLineNo());
                    pmSteelCastSlab.setSlabDest("10");
                } else {
                    PmSteelCastSlab steelCastSlab = steelCastSlabMap.get(dto.getPonoSlabNo());
                    if (Objects.isNull(steelCastSlab)) {
                        throw new CommonException("根据命令板坯号【"+dto.getPonoSlabNo()+"】未从炼钢连铸制造命令板坯表获取到数据");
                    }
                    planResDTO.setOrderNo(steelCastSlab.getOrderNo());
                    planResDTO.setMscLineNo(steelCastSlab.getMscLineNo());
                    planResDTO.setSgSign(steelCastSlab.getSgSign());
                    planResDTO.setSlabTargThk(steelCastSlab.getSlabThick());
                    planResDTO.setSlabTargWid(steelCastSlab.getSlabWidth());
                    planResDTO.setSlabTargLen(steelCastSlab.getSlabLen());
                    planResDTO.setHotChargeFlag(steelCastSlab.getHotChargeFlag());
                    orderRemainDiv = steelCastSlab.getOrderRemainDiv();

                    BeanUtils.copy(steelCastSlab, pmSteelCastSlab);
                }

                if ("0".equals(orderRemainDiv)) {
                    // 获取当前炉第一块有合同的板坯
                    List<PmSteelCastSlab> steelCastSlabList = pmSteelCastSlabMap.get(dto.getPono()).stream().filter(item -> StringUtils.isNotEmpty(item.getOrderNo()))
                            .sorted(Comparator.comparing(PmSteelCastSlab::getSlabSeqHeat)).collect(Collectors.toList());
                    if (CollectionUtils.isEmpty(steelCastSlabList)) {
                        throw new CommonException("根据炉号【"+dto.getPono()+"】未从炼钢连铸制造命令板坯表获取到第一块有合同板坯数据");
                    }
                    PmSteelCastSlab firstPmSteelCastSlab = steelCastSlabList.get(0);
                    planResDTO.setOldOrderNo(firstPmSteelCastSlab.getOrderNo());
                    planResDTO.setMscLineNo(firstPmSteelCastSlab.getMscLineNo());
                    buildInfoBySlabDest(planResDTO,"0", firstPmSteelCastSlab, pmCmdContMap, cmdLargePltMap, qdToPoLineCombVOMap, pmPdCcSlabMap, ponoVirSlabMap, toPoOrderVO1Map);
                    planResDTO.setBdFlag(null);
                } else  if ("1".equals(orderRemainDiv)) {
                    buildInfoBySlabDest(planResDTO,"1", pmSteelCastSlab, pmCmdContMap, cmdLargePltMap, qdToPoLineCombVOMap, pmPdCcSlabMap, ponoVirSlabMap, toPoOrderVO1Map);
                }
            } else {
                // 获取当前炉第一块有合同的板坯
                List<PmSteelCastSlab> steelCastSlabList = pmSteelCastSlabMap.get(dto.getPono()).stream().filter(item ->  StringUtils.isNotEmpty(item.getOrderNo()))
                        .sorted(Comparator.comparing(PmSteelCastSlab::getSlabSeqHeat)).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(steelCastSlabList)) {
                    throw new CommonException("根据炉号【"+dto.getPono()+"】未从炼钢连铸制造命令板坯表获取到第一块有合同板坯数据");
                }
                PmSteelCastSlab firstPmSteelCastSlab = steelCastSlabList.get(0);
                planResDTO.setSgSign(firstPmSteelCastSlab.getSgSign());
                planResDTO.setMscLineNo(firstPmSteelCastSlab.getMscLineNo());
                planResDTO.setHotChargeFlag(firstPmSteelCastSlab.getHotChargeFlag());
                planResDTO.setOldOrderNo(firstPmSteelCastSlab.getOrderNo());
                buildInfoBySlabDest(planResDTO,"0", firstPmSteelCastSlab, pmCmdContMap, cmdLargePltMap, qdToPoLineCombVOMap, pmPdCcSlabMap, ponoVirSlabMap, toPoOrderVO1Map);
                planResDTO.setBdFlag(null);
            }
        }
        return resList;
    }

    private void buildInfoBySlabDest(PmProductionPlanResDTO planResDTO, String orderRemainDiv, PmSteelCastSlab steelCastSlab,
                                     Map<String, PmCmdCont> pmCmdContMap,   Map<String, PmCmdLargePlt> cmdLargePltMap,
                                     Map<String, QdToPoLineCombVO> qdToPoLineCombVOMap, Map<String, PmPdCcSlab> pmPdCcSlabMap,
                                     Map<String, String> ponoVirSlabMap,  Map<String, QdToPoOrderVO1> toPoOrderVO1Map ) {
        // 获取钢级和计重方式
        QdToPoOrderVO1 qdToPoOrderVO1 = toPoOrderVO1Map.get(steelCastSlab.getOrderNo());
        if (qdToPoOrderVO1 != null) {
            planResDTO.setWtMethodCode(qdToPoOrderVO1.getWtMethodCode());
        }
        QdToPoLineCombVO qdToPoLineCombVO = qdToPoLineCombVOMap.get(Strings.concat(steelCastSlab.getOrderNo(), steelCastSlab.getMscLineNo()));
        if (qdToPoLineCombVO != null) {
            planResDTO.setStGrade(qdToPoLineCombVO.getStGrade());
        }
        // 判断板坯去向SLAB_DEST的值
        if ("10".equals(steelCastSlab.getSlabDest())) {
            // 1.	根据命令板坯号（PONO_SLAB_NO）查询【命令参数表（PM_CMD_CONT）】
            PmCmdCont pmCmdCont = pmCmdContMap.get(Strings.concat(steelCastSlab.getSlabNo(), steelCastSlab.getOrderNo()));
            if (pmCmdCont != null) {
                planResDTO.setPsc(pmCmdCont.getPsc());
                planResDTO.setApn(pmCmdCont.getApn());
                planResDTO.setMsc(pmCmdCont.getMsc());
                planResDTO.setSgStd(pmCmdCont.getSgStd());
                planResDTO.setWholeBacklog(pmCmdCont.getWholeBacklog());
            }
            // 2.	根据命令板坯号（PONO_SLAB_NO）查询【命令大板表（PM_CMD_LARGE_PLT）】
            PmCmdLargePlt largePlt = cmdLargePltMap.get(steelCastSlab.getSlabNo());
            if (largePlt != null) {
                planResDTO.setPlateDtCode(largePlt.getPlateDtCode());
                planResDTO.setProdCodeHp(largePlt.getProdCodeHp());
                planResDTO.setStNo(largePlt.getStNo());
                planResDTO.setSlabFlag(Constants.MergeStatus.MERGE_A.equals(largePlt.getIsMerge()) && "1".equals(orderRemainDiv) ? "1" : null);
            }
            // 3. 获取BD标记
            PmPdCcSlab pmPdCcSlab = pmPdCcSlabMap.get(ponoVirSlabMap.getOrDefault(steelCastSlab.getSlabNo(), steelCastSlab.getSlabNo()));
            if (pmPdCcSlab != null) {
                planResDTO.setBdFlag(pmPdCcSlab.getTwoRollInterimFlag());
            }
        }else if ("20".equals(steelCastSlab.getSlabDest())) {
            // 1.	根据合同号（ORDER_NO）查询QD_TO_PO_ORDER、QD_TO_PO_LINE_COMB、QD_TO_LINEUP_RESULT_ROLLING表表获取如下信息
            if (qdToPoOrderVO1 != null) {
                planResDTO.setPsc(qdToPoOrderVO1.getPsc());
                planResDTO.setApn(qdToPoOrderVO1.getApn());
                planResDTO.setMsc(qdToPoOrderVO1.getMsc());
                planResDTO.setSgStd(qdToPoOrderVO1.getSgStd());
                planResDTO.setWholeBacklog(qdToPoOrderVO1.getWholeBacklog());
                planResDTO.setProdCodeHp(qdToPoOrderVO1.getProdCodeHp());
            }
            if (qdToPoLineCombVO != null) {
                planResDTO.setWholeBacklog(qdToPoLineCombVO.getWholeBacklog());
                planResDTO.setPlateDtCode(qdToPoLineCombVO.getPlateDtCode());
                planResDTO.setStNo(qdToPoLineCombVO.getStNo());
            }
        }
    }
}
