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

import com.alibaba.fastjson.JSON;
import com.xisc.pm.api.dto.PmCastInfoResDTO;
import com.xisc.pm.api.dto.PmPonoWtInfoResDTO;
import com.xisc.pm.api.dto.PmSlabEstaPlanDissoDTO;
import com.xisc.pm.api.dto.PmSlabEstaPlanReqParamDTO;
import com.xisc.pm.api.dto.ProdPonoSlabRequestDTO;
import com.xisc.pm.api.dto.ctevent.PmDissolveGroupBoardDTO;
import com.xisc.pm.api.dto.ctevent.PmMaterialCommandDTO;
import com.xisc.pm.api.dto.ctevent.PmSlabPreCastingDTO;
import com.xisc.pm.app.service.PmSlabEstaPlanService;
import com.xisc.pm.app.service.PmSlabPoolInService;
import com.xisc.pm.app.service.strategy.PdMatTypeStrategyFactory;
import com.xisc.pm.app.service.strategy.pdmattype.PdMatTypeStrategy;
import com.xisc.pm.domain.entity.PmCmdCont;
import com.xisc.pm.domain.entity.PmCmdLargePlt;
import com.xisc.pm.domain.entity.PmCmdSlab;
import com.xisc.pm.domain.entity.PmCmdSmallPlt;
import com.xisc.pm.domain.entity.PmContMscTech;
import com.xisc.pm.domain.entity.PmPdBlockPos;
import com.xisc.pm.domain.entity.PmPdCcSlab;
import com.xisc.pm.domain.entity.PmPdContSum;
import com.xisc.pm.domain.entity.PmPdPlateCut;
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.PmSteelCastFlow;
import com.xisc.pm.domain.entity.PmSteelCastHeat;
import com.xisc.pm.domain.entity.PmSteelCastLot;
import com.xisc.pm.domain.entity.PmSteelCastSlab;
import com.xisc.pm.domain.entity.PmWmWwBt;
import com.xisc.pm.domain.repository.PmCmdContRepository;
import com.xisc.pm.domain.repository.PmCmdLargePltRepository;
import com.xisc.pm.domain.repository.PmCmdSlabRepository;
import com.xisc.pm.domain.repository.PmCmdSmallPltRepository;
import com.xisc.pm.domain.repository.PmContMscTechRepository;
import com.xisc.pm.domain.repository.PmPdBlockPosRepository;
import com.xisc.pm.domain.repository.PmPdCcSlabRepository;
import com.xisc.pm.domain.repository.PmPdContSumRepository;
import com.xisc.pm.domain.repository.PmPdPlateCutRepository;
import com.xisc.pm.domain.repository.PmPonoWtInfoRepository;
import com.xisc.pm.domain.repository.PmProContProdTtrRepository;
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.PmSteelCastFlowRepository;
import com.xisc.pm.domain.repository.PmSteelCastHeatRepository;
import com.xisc.pm.domain.repository.PmSteelCastLotRepository;
import com.xisc.pm.domain.repository.PmSteelCastSlabRepository;
import com.xisc.pm.domain.repository.PmWmWwBtRepository;
import com.xisc.pm.domain.vo.QeTqSampleGenVO;
import com.xisc.pm.infra.client.EventClient;
import com.xisc.pm.infra.client.QeApiClient;
import com.xisc.pm.infra.constant.Constants;
import com.xisc.pm.infra.constant.CtEventConstants;
import com.xisc.pm.infra.enums.PdMatType;
import com.xisc.pm.infra.mapper.PmSlabEstaPlanMapper;
import com.xisc.pm.infra.util.BeanUtils;
import com.xisc.pm.infra.util.Utils;
import io.choerodon.core.domain.Page;
import io.choerodon.core.exception.CommonException;
import io.choerodon.mybatis.pagehelper.PageHelper;
import io.choerodon.mybatis.pagehelper.domain.PageRequest;
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.boot.platform.code.builder.CodeRuleBuilder;
import org.hzero.boot.platform.code.constant.CodeConstants;
import org.hzero.core.base.AopProxy;
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.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;


/**
 * 组炉编制表(PmSlabEstaPlan)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-08-09 16:31:18
 */
@Service
@Slf4j
public class PmSlabEstaPlanServiceImpl implements AopProxy<PmSlabEstaPlanService>, PmSlabEstaPlanService {

    @Autowired
    private  EventClient eventClient;

    @Autowired
    private PmSlabEstaPlanRepository pmSlabEstaPlanRepository;

    @Autowired
    private PmPonoWtInfoRepository pmPonoWtInfoRepository;

    @Autowired
    private CodeRuleBuilder codeRuleBuilder;

    @Autowired
    private PmSlabPoolInRepository pmSlabPoolInRepository;

    @Autowired
    private PmPdContSumRepository pmPdContSumRepository;

    @Autowired
    private PmPdCcSlabRepository pmPdCcSlabRepository;

    @Autowired
    private PmCmdSlabRepository pmCmdSlabRepository;

    @Autowired
    private PmCmdLargePltRepository pmCmdLargePltRepository;

    @Autowired
    private PmSteelCastLotRepository pmSteelCastLotRepository;

    @Autowired
    private PmSteelCastHeatRepository pmSteelCastHeatRepository;

    @Autowired
    private PmProContProdTtrRepository pmProContProdTtrRepository;

    @Autowired
    private PmContMscTechRepository pmContMscTechRepository;

    @Autowired
    private PmSteelCastSlabRepository pmSteelCastSlabRepository;

    @Autowired
    private PmSteelCastFlowRepository pmSteelCastFlowRepository;

    @Autowired
    private PmSlabEstaPlanHisRepository pmSlabEstaPlanHisRepository;

    @Autowired
    private PmWmWwBtRepository pmWmWwBtRepository;

    @Autowired
    private PmSlabPoolInHisRepository pmSlabPoolInHisRepository;

    @Autowired
    private PmCmdContRepository pmCmdContRepository;

    @Autowired
    private PmCmdSmallPltRepository pmCmdSmallPltRepository;

    @Autowired
    private PmPdPlateCutRepository pmPdPlateCutRepository;

    @Autowired
    private PmPdBlockPosRepository pmPdBlockPosRepository;

    @Autowired
    private PmSmallPltPosRepository pmSmallPltPosRepository;

    @Autowired
    private PmSlabMergeRepository pmSlabMergeRepository;

    @Autowired
    private PmSlabEstaPlanMapper pmSlabEstaPlanMapper;

    @Autowired
    private PmSlabPoolInService pmSlabPoolInService;
    @Autowired
    private QeApiClient qeApiClient;


    @Override
    public Page<PmSlabEstaPlan> selectList(PageRequest pageRequest, PmSlabEstaPlan pmSlabEstaPlan) {
        return PageHelper.doPageAndSort(pageRequest, () -> pmSlabEstaPlanRepository.selectList(pmSlabEstaPlan));
    }

    @Override
    public List<PmCastInfoResDTO> listCast(PmSlabEstaPlanReqParamDTO dto, Long tenantId) {
        // 查询条件查询组炉编制表（PM_SLAB_ESTA_PLAN)
        List<PmSlabEstaPlan> slabEstaPlanList = pmSlabEstaPlanRepository.selectByCondition(Condition.builder(PmSlabEstaPlan.class)
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_MAIN_BACKLOG_CODE, dto.getMainBacklogCode()))
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_SLAB_THICK, dto.getSlabThick(), true))
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_SLAB_WIDTH, dto.getSlabWidth(), true))
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_CS_PREC_PLAN_STATUS, dto.getCsPrecPlanStatus(), true))
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_ST_NO, dto.getStNo(), true))
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_USER_ID, dto.getUserId(), true))
                .andWhere(Sqls.custom().andGreaterThanOrEqualTo(PmSlabEstaPlan.FIELD_STEEL_APP_DATE, dto.getSteelAppDateFrom(), true))
                .andWhere(Sqls.custom().andLessThanOrEqualTo(PmSlabEstaPlan.FIELD_STEEL_APP_DATE, dto.getSteelAppDateTo(), true))
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_CC_TYPE, dto.getCcType(), true))
                .andWhere(Sqls.custom().andGreaterThanOrEqualTo(PmSlabEstaPlan.FIELD_PREC_CAST_LOT_NO, dto.getPrecCastLotNoFrom(), true))
                .andWhere(Sqls.custom().andLessThanOrEqualTo(PmSlabEstaPlan.FIELD_PREC_CAST_LOT_NO, dto.getPrecCastLotNoTo(), true))
                .andWhere(Sqls.custom().andGreaterThanOrEqualTo(PmSlabEstaPlan.FIELD_PONO, dto.getPonoFrom(), true))
                .andWhere(Sqls.custom().andLessThanOrEqualTo(PmSlabEstaPlan.FIELD_PONO, dto.getPonoTo(), true))
                .andWhere(Sqls.custom().andLessThanOrEqualTo(PmSlabEstaPlan.FIELD_CS_PREC_PLAN_STATUS, Constants.CsPrecPlanStatus.STATUS_09))
                .build());
        // 为空，则返回
        if (CollectionUtils.isEmpty(slabEstaPlanList)) {
            return Collections.emptyList();
        }
        // 如果是命令提交状态，就要查询命令提交但是未计划接收状态
        List<PmSlabEstaPlan> pmSlabEstaPlanList = new ArrayList<>();
        pmSlabEstaPlanList.addAll(slabEstaPlanList.stream().filter(item -> !Constants.CsPrecPlanStatus.STATUS_09.equals(item.getCsPrecPlanStatus()))
                .collect(Collectors.toList()));
        List<String> ponoList = slabEstaPlanList.stream().filter(item -> Constants.CsPrecPlanStatus.STATUS_09.equals(item.getCsPrecPlanStatus()))
                .map(PmSlabEstaPlan::getPono).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(ponoList)) {
            List<String> newPonoList = pmSteelCastHeatRepository.selectByCondition(Condition.builder(PmSteelCastHeat.class)
                    .andWhere(Sqls.custom().andIn(PmSteelCastHeat.FIELD_PONO, ponoList))
                    .andWhere(Sqls.custom().andEqualTo(PmSteelCastHeat.FIELD_TENANT_ID, tenantId))
                    .andWhere(Sqls.custom().andEqualTo(PmSteelCastHeat.FIELD_PONO_STATUS, Constants.PonoStatus.STATUS_11))
                    .build()).stream().map(PmSteelCastHeat::getPono).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(newPonoList)) {
                pmSlabEstaPlanList.addAll(slabEstaPlanList.stream().filter(item -> newPonoList.contains(item.getPono())).collect(Collectors.toList()));
            }
        }
        if (CollectionUtils.isEmpty(pmSlabEstaPlanList)) {
            return Collections.emptyList();
        }

        // 获取每一个浇次一条数据即可
        Map<String, PmSlabEstaPlan> estaPlanMap = pmSlabEstaPlanList.stream().collect(Collectors
                .toMap(PmSlabEstaPlan::getPrecCastLotNo, Function.identity(), (k, v) -> k));
        List<PmCastInfoResDTO> resList = new ArrayList<>();
        // 组装数据
        for (Map.Entry<String, PmSlabEstaPlan> entry : estaPlanMap.entrySet()) {
            PmCastInfoResDTO res = new PmCastInfoResDTO();
            res.setPrecCastLotNo(entry.getValue().getPrecCastLotNo());
            res.setCastLotNo(entry.getValue().getCastLotNo());
            res.setCcType(entry.getValue().getCcType());
            res.setCcNum(entry.getValue().getCcNum());
            res.setCsPrecPlanStatus(entry.getValue().getCsPrecPlanStatus());
            res.setSteelAppDate(entry.getValue().getSteelAppDate());
            res.setSlabThick(entry.getValue().getSlabThick());
            res.setSlabWidth(entry.getValue().getSlabWidth());
            resList.add(res);
        }
        return resList;
    }

    @Override
    public List<PmPonoWtInfoResDTO> list(String precCastLotNo, Long tenantId) {
        // 查询条件查询组炉编制表（PM_SLAB_ESTA_PLAN)
        List<PmSlabEstaPlan> pmSlabEstaPlanList = pmSlabEstaPlanRepository.selectByCondition(Condition.builder(PmSlabEstaPlan.class)
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan. FIELD_PREC_CAST_LOT_NO, precCastLotNo))
                .build());
        // 为空，则返回
        if (CollectionUtils.isEmpty(pmSlabEstaPlanList)) {
            return Collections.emptyList();
        }
        // 【炉重信息表（PM_PONO_WT_INFO）】，以预CAST_LOT号关联
        Map<String, List<PmSlabEstaPlan>> pmSlabEstaPlanMap = pmSlabEstaPlanList.stream().collect(Collectors.groupingBy(PmSlabEstaPlan::getPrecPono));
        List<PmPonoWtInfo> pmPonoWtInfoList = pmPonoWtInfoRepository.selectByCondition(Condition.builder(PmPonoWtInfo.class)
                .andWhere(Sqls.custom().andEqualTo(PmPonoWtInfo.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmPonoWtInfo.FIELD_PREC_CAST_LOT_NO, precCastLotNo))
                .build());
        // 为空，则返回
        if (CollectionUtils.isEmpty(pmPonoWtInfoList)) {
            return Collections.emptyList();
        }
        // 组装返回数据
        List<PmPonoWtInfoResDTO> result = new ArrayList<>();
        for (PmPonoWtInfo pmPonoWtInfo : pmPonoWtInfoList) {
            PmPonoWtInfoResDTO resultDto = new PmPonoWtInfoResDTO();
            if (pmSlabEstaPlanMap.containsKey(pmPonoWtInfo.getPrecPono())) {
                PmSlabEstaPlan pmSlabEstaPlan = pmSlabEstaPlanMap.get(pmPonoWtInfo.getPrecPono()).get(0);
                resultDto.setCastLotNo(pmSlabEstaPlan.getCastLotNo());
                resultDto.setPono(pmSlabEstaPlan.getPono());
                resultDto.setCsPrecPlanStatus(pmSlabEstaPlan.getCsPrecPlanStatus());
            }
            resultDto.setPrecCastLotNo(pmPonoWtInfo.getPrecCastLotNo());
            resultDto.setPrecPono(pmPonoWtInfo.getPrecPono());
            resultDto.setStNo(pmPonoWtInfo.getStNo());
            resultDto.setActAimInitWt(pmPonoWtInfo.getActAimInitWt());
            resultDto.setActPonoWt(pmPonoWtInfo.getActPonoWt());
            resultDto.setPonoYield(pmPonoWtInfo.getPonoYield());
            resultDto.setCcType(pmPonoWtInfo.getCcType());
            result.add(resultDto);
        }
        return result;
    }

    @Override
    public List<PmSlabEstaPlan> listLine(String precPono, Long tenantId) {

        List<PmSlabEstaPlan> pmSlabEstaPlanList = pmSlabEstaPlanRepository.selectByCondition(Condition.builder(PmSlabEstaPlan.class)
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_PREC_PONO, precPono))
                .build());
        if (CollectionUtils.isEmpty(pmSlabEstaPlanList)) {
            return pmSlabEstaPlanList;
        }
        // MSC_LINE_NO，根据虚拟板坯号从【组炉收池表】中取
        List<String> virtualSlabNoList = pmSlabEstaPlanList.stream().map(PmSlabEstaPlan::getVirtualSlabNo).filter(item -> !Utils.isMergeSlab(item))
                .collect(Collectors.toList());
        // 截取合并板坯的虚拟板坯号
        List<String> mergeVirtualNoList = pmSlabEstaPlanList.stream().map(PmSlabEstaPlan::getVirtualSlabNo).filter(item -> Utils.isMergeSlab(item))
                .map(item->item.substring(1, item.length())).distinct().collect(Collectors.toList());
        virtualSlabNoList.addAll(mergeVirtualNoList);

        List<PmSlabPoolIn> pmSlabPoolInList = pmSlabPoolInRepository.selectByCondition(Condition.builder(PmSlabPoolIn.class)
                .andWhere(Sqls.custom().andEqualTo(PmSlabPoolIn.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmSlabPoolIn.FIELD_VIRTUAL_SLAB_NO, virtualSlabNoList))
                .build());
        if (CollectionUtils.isNotEmpty(pmSlabPoolInList)) {
            Map<String, String> slabPoolMap = pmSlabPoolInList.stream()
                    .collect(Collectors.toMap(PmSlabPoolIn::getVirtualSlabNo, PmSlabPoolIn::getMscLineNo));
            pmSlabEstaPlanList.forEach(item-> item.setMscLineNo(slabPoolMap.getOrDefault(Utils.isMergeSlab(item.getVirtualSlabNo()) ?
                    item.getVirtualSlabNo().substring(1, item.getVirtualSlabNo().length()) : item.getVirtualSlabNo(), null)));
        }
        return pmSlabEstaPlanList.stream().sorted(Comparator.comparing(PmSlabEstaPlan::getSlabSeqHeat)).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void commit(List<String> precCastLotNoList, Long tenantId) {
        // a)	根据预CAST_LOT号（PREC_CAST_LOT_NO）查询【组炉编制表（PM_SLAB_ESTA_PLAN）】
        List<PmSlabEstaPlan> pmSlabEstaPlanList = pmSlabEstaPlanRepository.selectByCondition(Condition.builder(PmSlabEstaPlan.class)
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmSlabEstaPlan.FIELD_PREC_CAST_LOT_NO, precCastLotNoList))
                .build());
        if (CollectionUtils.isEmpty(pmSlabEstaPlanList)) {
            throw new CommonException("pm.slab_esta_plan_001",precCastLotNoList);
        }
        // 校验是否已经执行组炉完成操作
        pmSlabEstaPlanList.forEach(item->{
            if ((Constants.CcType.TYPE_1.equals(item.getCcType()) || Constants.CcType.TYPE_5.equals(item.getCcType())) &&
                    Constants.CsPrecPlanStatus.STATUS_03.compareTo(item.getCsPrecPlanStatus()) > 0) {
                throw new CommonException("pm.slab_esta_plan_013", item.getPrecCastLotNo());
            }
        });

        // 校验是否已经命令提交
        Optional<PmSlabEstaPlan> first = pmSlabEstaPlanList.stream().filter(item ->
                Constants.CsPrecPlanStatus.STATUS_09.equals(item.getCsPrecPlanStatus())).findFirst();
        if (first.isPresent()) {
            throw new CommonException("pm.slab_esta_plan_007",first.get().getPrecCastLotNo());
        }
        //获取是否有需要命令确认的数据
        List<PmSlabPreCastingDTO> reConfirmList = new ArrayList<>();
        List<PmSlabEstaPlan> noConfrimPlanList = pmSlabEstaPlanList.stream().filter(item ->
                !Constants.CsPrecPlanStatus.STATUS_08.equals(item.getCsPrecPlanStatus())).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(noConfrimPlanList)) {
            // 命令确认
            reConfirmList = self().comfirm(noConfrimPlanList, tenantId);
        }

        // 命令提交
        int year = LocalDate.now().getYear();
        List<String> virtualSlabNoList = pmSlabEstaPlanList.stream().map(PmSlabEstaPlan::getVirtualSlabNo)
                .filter(item -> !Utils.isMergeSlab(item)).collect(Collectors.toList());
        List<String> precPonoList = pmSlabEstaPlanList.stream().map(PmSlabEstaPlan::getPrecPono).collect(Collectors.toList());
        List<String> orderNoList = pmSlabEstaPlanList.stream().map(PmSlabEstaPlan::getOrderNo).distinct().collect(Collectors.toList());
        List<String> estaTmpSlabNoList = pmSlabEstaPlanList.stream().map(PmSlabEstaPlan::getTmpSlabNo).distinct().collect(Collectors.toList());

        // 获取合并板坯的虚拟板坯号
        List<String> merVirtualSlabNoList = pmSlabEstaPlanList.stream().map(PmSlabEstaPlan::getVirtualSlabNo)
                .filter(item -> Utils.isMergeSlab(item)).collect(Collectors.toList());
        Map<String, List<PmSlabMerge>> mergeSlabMap = new HashMap<>(merVirtualSlabNoList.size());
        if (CollectionUtils.isNotEmpty(merVirtualSlabNoList)) {
            List<PmSlabMerge> pmSlabMergeList = pmSlabMergeRepository.selectByMergeSlabNoList(merVirtualSlabNoList, tenantId);
            if (CollectionUtils.isNotEmpty(pmSlabMergeList)) {
                mergeSlabMap = pmSlabMergeList.stream().collect(Collectors.groupingBy(PmSlabMerge::getMergeSlabNo));
                virtualSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getVirtualSlabNo).collect(Collectors.toList()));
                estaTmpSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getTmpSlabNo).collect(Collectors.toList()));
                estaTmpSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getTmpPonoSlabNo).collect(Collectors.toList()));
            } else {
                throw new CommonException("pm.slab_merge_002", merVirtualSlabNoList);
            }
        }
        estaTmpSlabNoList = estaTmpSlabNoList.stream().distinct().collect(Collectors.toList());

        //ii.	验证其是否已经完成命令作成（是否为“25状态”），若不是，则报错（右下角弹窗报错）：PM.FURNACE.CASTING.005，程序结束；
        List<PmPdCcSlab> pmPdCcSlabList = pmPdCcSlabRepository.selectByVirtualSlabList(virtualSlabNoList, tenantId);
        Map<String, String> pmPdCcSlabMap = new HashMap<>(pmPdCcSlabList.size());
        Map<String, PmPdCcSlab> pdCcSlabMap = new HashMap<>(pmPdCcSlabList.size());
        if (CollectionUtils.isNotEmpty(pmPdCcSlabList)) {
            Optional<PmPdCcSlab> pdcCsSlabOptional = pmPdCcSlabList.stream()
                    .filter(item -> !Constants.PdStatusHp.PD_STATUS_HP_25.equals(item.getPdStatusHp())).findFirst();
            if (pdcCsSlabOptional.isPresent()) {
                throw new CommonException("pm.furnace_casting_005",pdcCsSlabOptional.get().getVirtualSlabNo());
            }
            pmPdCcSlabMap = pmPdCcSlabList.stream().collect(Collectors.toMap(PmPdCcSlab::getVirtualSlabNo, PmPdCcSlab::getCcType));
            pdCcSlabMap = pmPdCcSlabList.stream().collect(Collectors.toMap(PmPdCcSlab::getVirtualSlabNo, Function.identity()));
        }

        // 据虚拟板坯号（VIRTUAL_SLAB_NO）查询【组炉收池表（PM_SLAB_POOL_IN）
        List<PmSlabPoolIn> pmSlabPoolInList = pmSlabPoolInRepository.selectByVirtualSlabNoList(virtualSlabNoList, tenantId);
        if (CollectionUtils.isEmpty(pmSlabPoolInList)) {
            log.info("<=====根据虚拟板坯号:{}，未获取到组炉收池表信息", virtualSlabNoList);
            return;
        }
        Map<String, PmSlabPoolIn> pmSlabPoolInMap = new HashMap<>(pmSlabPoolInList.size());
        Set<String> mscLineSet = new HashSet<>(pmSlabPoolInList.size());
        String ingotType = "";
        for (PmSlabPoolIn pmSlabPoolIn : pmSlabPoolInList) {
            pmSlabPoolInMap.put(pmSlabPoolIn.getVirtualSlabNo(), pmSlabPoolIn);
            mscLineSet.add(pmSlabPoolIn.getMscLineNo());
            if (StringUtils.isNotEmpty(pmSlabPoolIn.getIngotType())) {
                ingotType = pmSlabPoolIn.getIngotType();
            }
        }

        // ii.	根据预定制造命令号（PREC_PONO）查询【炉重信息表（PM_PONO_WT_INFO）】获取实际炉重（ACT_PONO_WT）；
        List<PmPonoWtInfo> pmPonoWtInfoList = pmPonoWtInfoRepository.selectByCondition(Condition.builder(PmPonoWtInfo.class)
                .andWhere(Sqls.custom().andEqualTo(PmPonoWtInfo.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmPonoWtInfo.FIELD_PREC_PONO, precPonoList))
                .build());
        Map<String, PmPonoWtInfo> ponoWtInfoMap = new HashMap<>(pmPonoWtInfoList.size());
        if (CollectionUtils.isNotEmpty(pmPonoWtInfoList)) {
            ponoWtInfoMap = pmPonoWtInfoList.stream().collect(Collectors.toMap(PmPonoWtInfo::getPrecPono, Function.identity(), (k, v) -> k));
        }

        // ii.	根据轴合同号（ORDER_NO）查询【生产合同产品属性表（PM_PRO_CONT_PROD_ATTR）】，获取产品最终用途码（APN）
        List<PmProContProdTtr> pmProContProdTtrList =  pmProContProdTtrRepository.selectByOrderNoList(orderNoList, tenantId);
        Map<String, PmProContProdTtr> pmProContProdTtrMap = new HashMap<>(pmPonoWtInfoList.size());
        if (CollectionUtils.isNotEmpty(pmPonoWtInfoList)) {
            pmProContProdTtrMap = pmProContProdTtrList.stream().collect(Collectors.toMap(PmProContProdTtr::getOrderNo, Function.identity(), (k, v) -> k));
        }

        // iii.	根据轴合同号（ORDER_NO）查询【合同产线工艺参数表（PM_CONT_MSC_TECH）】信息，获取如下字段
        List<PmContMscTech> pmContMscTecheList = pmContMscTechRepository.selectByOrderNoAndMscLineNo(orderNoList, new ArrayList<>(mscLineSet), tenantId);
        Map<String, PmContMscTech> pmContMscTecheMap = new HashMap<>(pmPonoWtInfoList.size());
        if (CollectionUtils.isNotEmpty(pmPonoWtInfoList)) {
            pmContMscTecheMap = pmContMscTecheList.stream().collect(Collectors.toMap(t -> Strings.concat(t.getOrderNo(), t.getMscLineNo()),
                    Function.identity(), (k, v) -> k));
        }


        // 根据命令板坯号（PREC_SLAB_NO）查询【试样添加表QE_TQ_SAMPLE_GEN】获取质量试材代预代码
        List<QeTqSampleGenVO> qeTqSampleGenVOList = pmSlabEstaPlanMapper.selectResvCode(estaTmpSlabNoList, tenantId);
        Map<String, String> qeTqSampleGenVOMap = new HashMap<>(qeTqSampleGenVOList.size());
        if (CollectionUtils.isNotEmpty(qeTqSampleGenVOList)) {
            qeTqSampleGenVOMap = qeTqSampleGenVOList.stream().filter(item-> StringUtils.isNotBlank(item.getDeleResvCode()))
                    .collect(Collectors.toMap(QeTqSampleGenVO::getTmpSlabNo, QeTqSampleGenVO::getDeleResvCode));
        }

        List<PmCmdSlab> cmdSlabList = pmCmdSlabRepository.selectByTmpSlabNoList(estaTmpSlabNoList, tenantId);
        Map<String, String> cmdSlabMap = new HashMap<>(cmdSlabList.size());
        if (CollectionUtils.isNotEmpty(cmdSlabList)) {
            cmdSlabMap = cmdSlabList.stream().filter(item->StringUtils.isNotEmpty(item.getVirtualSlabNo())).collect(Collectors.toMap(PmCmdSlab::getVirtualSlabNo, PmCmdSlab::getPonoSlabNo, (k, v) -> k));
        }

        // 查询大板粗切
        List<PmPdPlateCut> pmPdPlateCutList = pmPdPlateCutRepository.selectByPdMatNoList(virtualSlabNoList, tenantId);
        Map<String, List<PmPdPlateCut>> pdPlateCutMap = new HashMap<>(pmPdPlateCutList.size());
        if (CollectionUtils.isNotEmpty(pmPdPlateCutList)) {
            pdPlateCutMap = pmPdPlateCutList.stream().collect(Collectors.groupingBy(PmPdPlateCut::getPdMatNo));
        }

        // 定义炼钢命令表的插入集合
        List<PmSteelCastLot>  insertpmSteelCastLotList = new ArrayList<>();
        List<PmSteelCastHeat> insertPmSteelCastHeatList = new ArrayList<>();
        List<PmSteelCastSlab> insertPmSteelCastSlabList = new ArrayList<>();
        List<PmSteelCastFlow> insertPmSteelCastFlowList = new ArrayList<>();
        List<ProdPonoSlabRequestDTO> slabRequestDTOList = new ArrayList<>();
        List<PmPdPlateCut> insertPmPdPlateCutList = new ArrayList<>(pmPdPlateCutList.size());
        // 根据浇次号分组
        Map<String, List<PmSlabEstaPlan>> castLostPlanMap = pmSlabEstaPlanList.stream()
                .collect(Collectors.groupingBy(PmSlabEstaPlan::getPrecCastLotNo));
        // 根据炉号分组
        Map<String, List<PmSlabEstaPlan>> lotPonoPlanMap = pmSlabEstaPlanList.stream()
                .collect(Collectors.groupingBy(item -> Strings.concat(item.getPrecCastLotNo(), item.getPrecPono())));

        Map<String, String> orderEstaMap = pmSlabEstaPlanList.stream().filter(item -> StringUtils.isNotEmpty(item.getOrderNo()))
                .collect(Collectors.toMap(PmSlabEstaPlan::getPrecPono, PmSlabEstaPlan::getVirtualSlabNo, (k, v) -> k));
        for (PmSlabEstaPlan pmSlabEstaPlan : pmSlabEstaPlanList) {
            // 获取这炉第一块非无委坯的数据
            PmSlabEstaPlan estaPlan = lotPonoPlanMap.get(Strings.concat(pmSlabEstaPlan.getPrecCastLotNo(), pmSlabEstaPlan.getPrecPono())).stream()
                    .filter(item -> !item.getVirtualSlabNo().startsWith("W")).sorted(Comparator.comparing(PmSlabEstaPlan::getSlabSeqHeat))
                    .collect(Collectors.toList()).get(0);
            String noWVirtualSlabNo = estaPlan.getVirtualSlabNo();
            if (Utils.isMergeSlab(estaPlan.getVirtualSlabNo())) {
                noWVirtualSlabNo = estaPlan.getVirtualSlabNo().substring(1, estaPlan.getVirtualSlabNo().length());
            }
            // 判断是否是合并板坯号-slab表
            String virtualSlabNo = pmSlabEstaPlan.getVirtualSlabNo();
            if (Utils.isMergeSlab(pmSlabEstaPlan.getVirtualSlabNo())) {
                virtualSlabNo = pmSlabEstaPlan.getVirtualSlabNo().substring(1, pmSlabEstaPlan.getVirtualSlabNo().length());
            }

            // a)	首先新增【炼钢连铸制造命令LOT表（PM_STEEL_CAST_LOT）】信息
            if (pmSlabEstaPlan.getSlabSeqFlow().equals(1L)) {
                List<PmSlabEstaPlan> slabEstaPlanList = castLostPlanMap.get(pmSlabEstaPlan.getPrecCastLotNo());
                Long slabNum = (long) slabEstaPlanList.size();
                PmSteelCastLot pmSteelCastLot = buildPmSteelCastLot(estaPlan, pmSlabPoolInMap, slabNum, noWVirtualSlabNo, tenantId);
                insertpmSteelCastLotList.add(pmSteelCastLot);
            }

            // 插入到【炼钢连铸制造命令炉次表（PM_STEEL_CAST_HEAT）】
            if (pmSlabEstaPlan.getSlabSeqHeat().equals(1L)) {
                // 获取这炉第一块非无委坯的数据
                PmSteelCastHeat pmSteelCastHeat = buildPmSteelCastHeat(estaPlan, pmSlabPoolInMap, pmContMscTecheMap, ponoWtInfoMap,
                        pmProContProdTtrMap,pdCcSlabMap, noWVirtualSlabNo );
                pmSteelCastHeat.setTenantId(tenantId);
                pmSteelCastHeat.setYearId((long) year);
                insertPmSteelCastHeatList.add(pmSteelCastHeat);
            }

            // c)	新增【炼钢连铸制造命令板坯表（PM_STEEL_CAST_SLAB）】信息，
            PmSteelCastSlab pmSteelCastSlab =  buildPmSteelCastSlab(virtualSlabNo,pmSlabEstaPlan,pmProContProdTtrMap,pdCcSlabMap,
                    pmSlabPoolInMap,pmContMscTecheMap, qeTqSampleGenVOMap, mergeSlabMap);
            pmSteelCastSlab.setTenantId(tenantId);
            pmSteelCastSlab.setIngotType(ingotType);
            // 无委坯板坯去向赋值
            if (pmSlabEstaPlan.getVirtualSlabNo().startsWith("W")) {
                String orVirtualSlabNo = orderEstaMap.get(pmSlabEstaPlan.getPrecPono());
                orVirtualSlabNo = Utils.isMergeSlab(orVirtualSlabNo) ? orVirtualSlabNo.substring(1, orVirtualSlabNo.length()) : orVirtualSlabNo;
                pmSteelCastSlab.setSlabDest(pmSlabPoolInMap.get(orVirtualSlabNo).getSlabDest());
            }
            pmSteelCastSlab.setYearId((long) year);
            insertPmSteelCastSlabList.add(pmSteelCastSlab);

            // d)	新增【炼钢连铸制造命令铸机流表（PM_STEEL_CAST_FLOW）】信息，
            if (pmSlabEstaPlan.getSlabSeqHeat().equals(1L)) {
                List<PmSlabEstaPlan> slabEstaPlanList = lotPonoPlanMap.get(Strings.concat(pmSlabEstaPlan.getPrecCastLotNo(), pmSlabEstaPlan.getPrecPono()));
                long adjustWidthNum = slabEstaPlanList.stream().map(PmSlabEstaPlan::getSlabWidth).distinct().count();
                PmSteelCastFlow pmSteelCastFlow = new PmSteelCastFlow();
                insertPmSteelCastFlowList.add(pmSteelCastFlow);
                pmSteelCastFlow.setTenantId(tenantId);
                pmSteelCastFlow.setMainBacklogCode(estaPlan.getMainBacklogCode());
                pmSteelCastFlow.setPono(estaPlan.getPono());
                pmSteelCastFlow.setHeatSlabNum((long) slabEstaPlanList.size());
                pmSteelCastFlow.setSlabThick(estaPlan.getSlabThick());
                pmSteelCastFlow.setSlabWidth(estaPlan.getSlabWidth());
                pmSteelCastFlow.setAdjustWidthNum(adjustWidthNum);
                if ( pmSlabPoolInMap.containsKey(noWVirtualSlabNo)) {
                    PmSlabPoolIn pmSlabPoolIn = pmSlabPoolInMap.get(noWVirtualSlabNo);
                    List<PmWmWwBt> pmWmWwBtList = pmWmWwBtRepository.selectByCondition(Condition.builder(PmWmWwBt.class)
                            .andWhere(Sqls.custom().andEqualTo(PmWmWwBt.FIELD_TENANT_ID, tenantId))
                            .andWhere(Sqls.custom().andEqualTo(PmWmWwBt.FIELD_MSC_LINE_NO, pmSlabPoolIn.getMscLineNo()))
                            .andWhere(Sqls.custom().andEqualTo(PmWmWwBt.FIELD_CC_TYPE, estaPlan.getCcType()))
                            .andWhere(Sqls.custom().andLessThanOrEqualTo(PmWmWwBt.FIELD_SLAB_THICK_FROM, estaPlan.getSlabThick()))
                            .andWhere(Sqls.custom().andGreaterThanOrEqualTo(PmWmWwBt.FIELD_SLAB_THICK_TO, estaPlan.getSlabThick()))
                            .andWhere(Sqls.custom().andLessThanOrEqualTo(PmWmWwBt.FIELD_SLAB_WIDTH_FROM, estaPlan.getSlabWidth()))
                            .andWhere(Sqls.custom().andGreaterThanOrEqualTo(PmWmWwBt.FIELD_SLAB_WIDTH_TO, estaPlan.getSlabWidth()))
                            .build());
                    if (CollectionUtils.isNotEmpty(pmWmWwBtList)) {
                        pmSteelCastFlow.setUnappSlabLenMax(pmWmWwBtList.get(0).getUnappSlabLenMax());
                        pmSteelCastFlow.setUnappSlabLenMin(pmWmWwBtList.get(0).getUnappSlabLenMin());
                        pmSteelCastFlow.setUnappSlabLen(pmWmWwBtList.get(0).getUnappSlabLen());
                    }
                }
            }
            if (Constants.CcType.TYPE_1.equals(pmSlabEstaPlan.getCcType()) || Constants.CcType.TYPE_5.equals(pmSlabEstaPlan.getCcType())) {
                if (Utils.isMergeSlab(pmSlabEstaPlan.getVirtualSlabNo())) {
                    for (PmSlabMerge pmSlabMerge : mergeSlabMap.get(pmSlabEstaPlan.getVirtualSlabNo())) {
                        ProdPonoSlabRequestDTO prodPonoSlabRequestDTO = new ProdPonoSlabRequestDTO();
                        prodPonoSlabRequestDTO.setTmpSlabNo(pmSlabMerge.getTmpSlabNo());
                        prodPonoSlabRequestDTO.setPonoSlab(cmdSlabMap.get(pmSlabMerge.getVirtualSlabNo()));
                        prodPonoSlabRequestDTO.setPono(pmSlabEstaPlan.getPono());
                        slabRequestDTOList.add(prodPonoSlabRequestDTO);
                    }
                } else {
                    ProdPonoSlabRequestDTO prodPonoSlabRequestDTO = new ProdPonoSlabRequestDTO();
                    prodPonoSlabRequestDTO.setTmpSlabNo(pmSlabEstaPlan.getTmpSlabNo());
                    prodPonoSlabRequestDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
                    prodPonoSlabRequestDTO.setPono(pmSlabEstaPlan.getPono());
                    slabRequestDTOList.add(prodPonoSlabRequestDTO);
                }
            }

            if (Utils.isMergeSlab(pmSlabEstaPlan.getVirtualSlabNo())) {
                for (PmSlabMerge pmSlabMerge : mergeSlabMap.get(pmSlabEstaPlan.getVirtualSlabNo())) {
                    // 复制一份大板粗切
                    if (pdPlateCutMap.containsKey(pmSlabMerge.getVirtualSlabNo())) {
                        pdPlateCutMap.get(pmSlabMerge.getVirtualSlabNo()).forEach(pdPlateCut -> {
                            PmPdPlateCut pmPdPlateCut = buildPmPdPlateCut(pdPlateCut, pmSlabMerge.getPrecSlabNo(), tenantId);
                            insertPmPdPlateCutList.add(pmPdPlateCut);
                        });
                    }
                }
            } else {
                // 复制一份大板粗切
                if (pdPlateCutMap.containsKey(pmSlabEstaPlan.getVirtualSlabNo())) {
                    pdPlateCutMap.get(pmSlabEstaPlan.getVirtualSlabNo()).forEach(pdPlateCut -> {
                        PmPdPlateCut pmPdPlateCut = buildPmPdPlateCut(pdPlateCut, pmSlabEstaPlan.getPrecSlabNo(), tenantId);
                        insertPmPdPlateCutList.add(pmPdPlateCut);
                    });
                }
            }
        }
        pmSteelCastLotRepository.batchInsertSelective(insertpmSteelCastLotList);
        pmSteelCastHeatRepository.batchInsertSelective(insertPmSteelCastHeatList);
        pmSteelCastSlabRepository.batchInsertSelective(insertPmSteelCastSlabList);
        pmSteelCastFlowRepository.batchInsertSelective(insertPmSteelCastFlowList);
        pmPdPlateCutRepository.batchInsertSelective(insertPmPdPlateCutList);

        // 4、	接着根据浇次号（CAST_LOT_NO）更新【组炉编制表（PM_SLAB_ESTA_PLAN）】中连铸预计划状态的值为“09”，表示命令提交完成；
        pmSlabEstaPlanList.forEach(item -> item.setCsPrecPlanStatus(Constants.CsPrecPlanStatus.STATUS_09));
        pmSlabEstaPlanRepository.batchUpdateByPrimaryKeySelective(pmSlabEstaPlanList);

        // 6、	更新厚板组板状态
        // 更新【组板合同总量表（PM_PD_CONT_SUM）】
        List<PmPdContSum> pdContSumList = pmPdContSumRepository.selectByPdMatNoList(tenantId, virtualSlabNoList);
        pdContSumList.forEach(item -> item.setPdStatus(Constants.PdStatusHp.PD_STATUS_HP_26));
        // 更新【组板连铸板坯表（PM_PD_CC_SLAB）】
        pmPdCcSlabList.forEach(item -> item.setPdStatusHp(Constants.PdStatusHp.PD_STATUS_HP_26));
        // c) 更新【命令板坯表（PM_CMD_SLAB）】以及【命令大板表（PM_CMD_LARGE_PLT）】中字段厚板组板状态（PD_STATUS_HP）的值
        cmdSlabList.forEach(pmCmdSlab -> pmCmdSlab.setPdStatusHp(Constants.PdStatusHp.PD_STATUS_HP_26));
        List<String> tmpSlabNoList = cmdSlabList.stream().map(PmCmdSlab::getTmpSlabNo).distinct().collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(tmpSlabNoList)) {
            List<PmCmdLargePlt> pmCmdLargePltList = pmCmdLargePltRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId);
            pmCmdLargePltList.forEach(pmCmdLargePlt -> pmCmdLargePlt.setPdStatusHp(Constants.PdStatusHp.PD_STATUS_HP_26));
            pmCmdLargePltRepository.batchUpdateByPrimaryKey(pmCmdLargePltList);
        }
        pmPdContSumRepository.batchUpdateByPrimaryKey(pdContSumList);
        pmPdCcSlabRepository.batchUpdateByPrimaryKey(pmPdCcSlabList);
        pmCmdSlabRepository.batchUpdateByPrimaryKey(cmdSlabList);

        // 将以下字段作为入参，调用合同跟踪模块“连铸预编制事件”接口，向合同跟踪抛帐
        List<PmSmallPltPos> pmSmallPltPosList = pmSmallPltPosRepository.selectByCondition(Condition.builder(PmSmallPltPos.class)
                .andWhere(Sqls.custom().andIn(PmSmallPltPos.FIELD_PD_MAT_NO, virtualSlabNoList))
                .andWhere(Sqls.custom().andEqualTo(PmSmallPltPos.FIELD_TENANT_ID, tenantId))
                .build());
        Map<String, List<PmSmallPltPos>> pmSmallPltPosMap = new HashMap<>(pmSmallPltPosList.size());
        if (CollectionUtils.isNotEmpty(pmSmallPltPosList)) {
           pmSmallPltPosMap = pmSmallPltPosList.stream().collect(Collectors.groupingBy(PmSmallPltPos::getPdMatNo));
        }

        // 虚拟板坯或者备坯的数据从收池表拿
        Map<String, PmSlabPoolIn> poolInMap = new HashMap<>(virtualSlabNoList.size());
        if (CollectionUtils.isNotEmpty(virtualSlabNoList)) {
            List<PmSlabPoolIn> poolInList = pmSlabPoolInRepository.selectByCondition(Condition.builder(PmSlabPoolIn.class)
                    .andWhere(Sqls.custom().andIn(PmSlabPoolIn.FIELD_VIRTUAL_SLAB_NO, virtualSlabNoList))
                    .andWhere(Sqls.custom().andEqualTo(PmSlabPoolIn.FIELD_TENANT_ID, tenantId))
                    .build());
            if (CollectionUtils.isNotEmpty(poolInList)) {
                poolInMap = poolInList.stream().collect(Collectors.toMap(PmSlabPoolIn::getVirtualSlabNo, Function.identity()));
            }
        }
        List<PmSlabPreCastingDTO> resList =  commandAbandonContract(pmSlabEstaPlanList,mergeSlabMap, pmPdCcSlabMap, pmSmallPltPosMap, poolInMap,
                "26", "09", "14A", "14");

        // 调用质量命令提交接口
        qeApiClient.tmpSlabNoUpdate(tenantId, slabRequestDTOList);

        try{
            // 命令确认抛合同
            if (CollectionUtils.isNotEmpty(reConfirmList)) {
                log.info("<=====命令确认调用连铸预编制事件，入参为{}=====>", JSON.toJSONString(reConfirmList));
                eventClient.addEvent(CtEventConstants.EVENT_PM_PRE_CONTINUOUS_CASTING, reConfirmList);
            }
            // 命令提交抛合同
            log.info("<=====命令提交调用连铸预编制事件，入参为{}=====>", JSON.toJSONString(resList));
            eventClient.addEvent(CtEventConstants.EVENT_PM_PRE_CONTINUOUS_CASTING, resList);
            eventClient.sendEvent(tenantId);
        }finally {
            eventClient.remove();
        }
    }

    private PmSteelCastHeat buildPmSteelCastHeat(PmSlabEstaPlan pmSlabEstaPlan, Map<String, PmSlabPoolIn> pmSlabPoolInMap, Map<String,
            PmContMscTech> pmContMscTecheMap, Map<String, PmPonoWtInfo> ponoWtInfoMap,   Map<String, PmProContProdTtr> pmProContProdTtrMap,
                                                 Map<String, PmPdCcSlab> pdCcSlabMap, String virtualSlabNo) {
        PmSteelCastHeat pmSteelCastHeat = new PmSteelCastHeat();
        pmSteelCastHeat.setMainBacklogCode(pmSlabEstaPlan.getMainBacklogCode());
        pmSteelCastHeat.setPono(pmSlabEstaPlan.getPono());
        pmSteelCastHeat.setPonoStatus(Constants.PonoStatus.STATUS_11);
        pmSteelCastHeat.setCcSeq(0L);
        pmSteelCastHeat.setStNo(pmSlabEstaPlan.getStNo());
        if (pmSlabPoolInMap.containsKey(virtualSlabNo)) {
            PmSlabPoolIn pmSlabPoolIn = pmSlabPoolInMap.get(virtualSlabNo);
            pmSteelCastHeat.setSgSign(pmSlabPoolIn.getSgSign());
            pmSteelCastHeat.setDest(pmSlabPoolIn.getSlabDest());
            pmSteelCastHeat.setSteelPlanDate(pmSlabPoolIn.getSteelPlanDate());
            pmSteelCastHeat.setHotSendFlag(pmSlabPoolIn.getNomHotSendFlag());
            pmSteelCastHeat.setSgSign(pmSlabPoolIn.getSgSign());
            pmSteelCastHeat.setRefineRouteCode(pmSlabPoolIn.getRfPath());
            if (!pmContMscTecheMap.isEmpty() && pmContMscTecheMap.containsKey(Strings.concat(pmSlabEstaPlan.getOrderNo(), pmSlabPoolIn.getMscLineNo()))) {
                PmContMscTech pmContMscTech = pmContMscTecheMap.get(Strings.concat(pmSlabEstaPlan.getOrderNo(), pmSlabPoolIn.getMscLineNo()));
                pmSteelCastHeat.setRefineRouteCode(pmContMscTech.getRfPath());
            }
        }
        pmSteelCastHeat.setCastLotNo(pmSlabEstaPlan.getCastLotNo());
        pmSteelCastHeat.setCastLotDivNo(pmSlabEstaPlan.getCastLotDivNo());
        pmSteelCastHeat.setCastLotSum(pmSlabEstaPlan.getCcNum());
        pmSteelCastHeat.setCcType(pmSlabEstaPlan.getCcType());
        pmSteelCastHeat.setSmeltMode(1L);
        pmSteelCastHeat.setRestrandFlg(null);
        pmSteelCastHeat.setTdChgFlg(0L);
        if (!ponoWtInfoMap.isEmpty() && ponoWtInfoMap.containsKey(pmSlabEstaPlan.getPrecPono())) {
            pmSteelCastHeat.setPlanTapWt(ponoWtInfoMap.get(pmSlabEstaPlan.getPrecPono()).getActPonoWt());
        }
        if (!pmProContProdTtrMap.isEmpty() && pmProContProdTtrMap.containsKey(pmSlabEstaPlan.getOrderNo())) {
            pmSteelCastHeat.setApn(pmProContProdTtrMap.get(pmSlabEstaPlan.getOrderNo()).getApn());
        }
        if ( pdCcSlabMap.containsKey(virtualSlabNo)) {
            PmPdCcSlab pmPdCcSlab = pdCcSlabMap.get(virtualSlabNo);
            pmSteelCastHeat.setNewTestNo(null);
            pmSteelCastHeat.setFlameCleanDiv(pmPdCcSlab.getHpFlameCleanDiv());
        }
        pmSteelCastHeat.setSteelAppDate(pmSlabEstaPlan.getSteelAppDate());
        pmSteelCastHeat.setHotReqTime(pmSlabEstaPlan.getPlanRollTime());
        pmSteelCastHeat.setHotChargeFlag(pmSlabEstaPlan.getActHotChargeFlag());
        pmSteelCastHeat.setPourTime(0L);
        pmSteelCastHeat.setMoldThick(pmSlabEstaPlan.getMoldThick());
        pmSteelCastHeat.setMoldWidth(pmSlabEstaPlan.getMoldWid());
        pmSteelCastHeat.setIsBloom(0L);
        return pmSteelCastHeat;
    }

    private PmSteelCastLot buildPmSteelCastLot(PmSlabEstaPlan pmSlabEstaPlan, Map<String, PmSlabPoolIn> pmSlabPoolInMap, Long slabNum,
                                               String virtualSlabNo, Long tenantId) {
        PmSteelCastLot pmSteelCastLot = new PmSteelCastLot();
        pmSteelCastLot.setMainBacklogCode(pmSlabEstaPlan.getMainBacklogCode());
        pmSteelCastLot.setCastLotNo(pmSlabEstaPlan.getCastLotNo());
        pmSteelCastLot.setBilletType(pmSlabEstaPlan.getBilletType());
        pmSteelCastLot.setCcType(pmSlabEstaPlan.getCcType());
        pmSteelCastLot.setStNo(pmSlabEstaPlan.getStNo());
        pmSteelCastLot.setAppType(pmSlabEstaPlan.getAppType());
        pmSteelCastLot.setSlabThick(pmSlabEstaPlan.getSlabThick());
        if (pmSlabPoolInMap.containsKey(virtualSlabNo)) {
            PmSlabPoolIn pmSlabPoolIn = pmSlabPoolInMap.get(virtualSlabNo);
            pmSteelCastLot.setSgSign(pmSlabPoolIn.getSgSign());
            pmSteelCastLot.setOrderTypeCode(pmSlabPoolIn.getOrderTypeCode());
        }
        pmSteelCastLot.setSlabNum(slabNum);
        pmSteelCastLot.setLotStatus(0L);
        pmSteelCastLot.setSlabGroupSum(0L);
        pmSteelCastLot.setCcPlanMode("2");
        pmSteelCastLot.setTenantId(tenantId);
        return pmSteelCastLot;
    }

    private PmSteelCastSlab buildPmSteelCastSlab(String virtualSlabNo, PmSlabEstaPlan pmSlabEstaPlan, Map<String,
            PmProContProdTtr> pmProContProdTtrMap, Map<String, PmPdCcSlab> pdCcSlabMap, Map<String, PmSlabPoolIn> pmSlabPoolInMap,
                                      Map<String, PmContMscTech> pmContMscTecheMap,  Map<String, String> qeTqSampleGenVOMap,
                                                   Map<String, List<PmSlabMerge>> mergeSlabMap ) {
        PmSteelCastSlab pmSteelCastSlab = new PmSteelCastSlab();
        pmSteelCastSlab.setMainBacklogCode(pmSlabEstaPlan.getMainBacklogCode());
        pmSteelCastSlab.setSlabNo(pmSlabEstaPlan.getPrecSlabNo());
        pmSteelCastSlab.setCastLotNo(pmSlabEstaPlan.getCastLotNo());
        pmSteelCastSlab.setPono(pmSlabEstaPlan.getPono());
        pmSteelCastSlab.setOrderNo(pmSlabEstaPlan.getOrderNo());
        pmSteelCastSlab.setSlabSeqHeat(pmSlabEstaPlan.getSlabSeqHeat());
        pmSteelCastSlab.setPlanType(pmSlabEstaPlan.getPlanType());
        pmSteelCastSlab.setHotChargeFlag(pmSlabEstaPlan.getActHotChargeFlag());
        pmSteelCastSlab.setPrecRollPlanNo(pmSlabEstaPlan.getRollPlanNo());
        pmSteelCastSlab.setPrecRollSeqNo(pmSlabEstaPlan.getMatSeqNo());
        pmSteelCastSlab.setBilletType(pmSlabEstaPlan.getBilletType());
        pmSteelCastSlab.setVarietyCode(null);
        pmSteelCastSlab.setSlabThick(pmSlabEstaPlan.getSlabThick());
        pmSteelCastSlab.setSlabWidth(pmSlabEstaPlan.getSlabWidth());
        pmSteelCastSlab.setSlabLen(pmSlabEstaPlan.getSlabLen());
        pmSteelCastSlab.setSlabMaxLen(pmSlabEstaPlan.getSlabLen());
        pmSteelCastSlab.setSlabMinLen(pmSlabEstaPlan.getSlabLen());
        pmSteelCastSlab.setSlabWt(pmSlabEstaPlan.getSlabWt());
        pmSteelCastSlab.setSlabMaxWt(pmSlabEstaPlan.getSlabWt());
        pmSteelCastSlab.setSlabMinWt(pmSlabEstaPlan.getSlabWt());
        pmSteelCastSlab.setInfurSlabLen(BigDecimal.ZERO);
        pmSteelCastSlab.setInfurSlabLen(BigDecimal.ZERO);
        pmSteelCastSlab.setInfurSlabMaxLen(BigDecimal.ZERO);
        pmSteelCastSlab.setInfurSlabMinLen(BigDecimal.ZERO);
        pmSteelCastSlab.setInfurSlabWt(BigDecimal.ZERO);
        pmSteelCastSlab.setInfurSlabMaxWt(BigDecimal.ZERO);
        pmSteelCastSlab.setInfurSlabMinWt(BigDecimal.ZERO);
        if (pmProContProdTtrMap.containsKey(pmSlabEstaPlan.getOrderNo())) {
            PmProContProdTtr ttr = pmProContProdTtrMap.get(pmSlabEstaPlan.getOrderNo());
            pmSteelCastSlab.setOrderLenMax(ttr.getOrderMaxLen());
            pmSteelCastSlab.setOrderLenMin(ttr.getOrderMinLen());
            pmSteelCastSlab.setOrderShortMax(ttr.getOrderShortMax());
            pmSteelCastSlab.setOrderShortMin(ttr.getOrderShortMin());
            pmSteelCastSlab.setOrderShortRate(ttr.getOrderShortRate());
            pmSteelCastSlab.setSteelLatestDate(ttr.getDelivyDate());
            pmSteelCastSlab.setOrderRemainDiv("1");
        } else {
            pmSteelCastSlab.setOrderLenMax(BigDecimal.ZERO);
            pmSteelCastSlab.setOrderLenMin(BigDecimal.ZERO);
            pmSteelCastSlab.setOrderShortMax(BigDecimal.ZERO);
            pmSteelCastSlab.setOrderShortMin(BigDecimal.ZERO);
            pmSteelCastSlab.setOrderShortRate(BigDecimal.ZERO);
            pmSteelCastSlab.setSteelLatestDate(null);
            pmSteelCastSlab.setOrderRemainDiv("0");
        }

        if (pdCcSlabMap.containsKey(virtualSlabNo)) {
            // 从连铸板坯表查得到
            PmPdCcSlab pmPdCcSlab = pdCcSlabMap.get(virtualSlabNo);
            pmSteelCastSlab.setVarietyCode(pmPdCcSlab.getProdCodeHp());
            pmSteelCastSlab.setSlabThick(pmPdCcSlab.getPreCleanSlabThick());
            pmSteelCastSlab.setSlabWidth(pmPdCcSlab.getPreCleanSlabWidth());
            pmSteelCastSlab.setSlabLen(pmPdCcSlab.getPreCleanSlabLen());
            pmSteelCastSlab.setSlabMaxLen(pmPdCcSlab.getPreCleanSlabMaxLen());
            pmSteelCastSlab.setSlabMinLen(pmPdCcSlab.getPreCleanSlabMinLen());
            pmSteelCastSlab.setSlabWt(pmPdCcSlab.getPreCleanSlabWt());
            pmSteelCastSlab.setSlabMaxWt(pmPdCcSlab.getPreCleanSlabMaxWt());
            pmSteelCastSlab.setSlabMinWt(pmPdCcSlab.getPreCleanSlabMinWt());
            pmSteelCastSlab.setInfurSlabLen(pmPdCcSlab.getInfurSlabLen());
            pmSteelCastSlab.setInfurSlabMaxLen(pmPdCcSlab.getInfurSlabMaxLen());
            pmSteelCastSlab.setInfurSlabMinLen(pmPdCcSlab.getInfurSlabMinLen());
            pmSteelCastSlab.setInfurSlabWt(pmPdCcSlab.getInfurSlabWt());
            pmSteelCastSlab.setInfurSlabMaxWt(pmPdCcSlab.getInfurSlabMaxWt());
            pmSteelCastSlab.setInfurSlabMinWt(pmPdCcSlab.getInfurSlabMinWt());
            pmSteelCastSlab.setSlabFinishCode(pmPdCcSlab.getSlabFinishCode());
            pmSteelCastSlab.setFlameCleanDiv(pmPdCcSlab.getHpFlameCleanDiv());
            pmSteelCastSlab.setSgSign(pmPdCcSlab.getSgSign());
            pmSteelCastSlab.setNewTestNo(null);
        } else if ( pmSlabPoolInMap.containsKey(virtualSlabNo)) {
            PmSlabPoolIn pmSlabPoolIn = pmSlabPoolInMap.get(virtualSlabNo);
            pmSteelCastSlab.setVarietyCode(null);
            pmSteelCastSlab.setSlabThick(pmSlabPoolIn.getNomSlabThick());
            pmSteelCastSlab.setSlabWidth(pmSlabPoolIn.getNomSlabWidth());
            pmSteelCastSlab.setSlabLen(pmSlabPoolIn.getNomSlabLen());
            pmSteelCastSlab.setSlabMaxLen(pmSlabPoolIn.getSlabMaxNomLen());
            pmSteelCastSlab.setSlabMinLen(pmSlabPoolIn.getSlabMinNomLen());
            pmSteelCastSlab.setSlabWt(pmSlabPoolIn.getNomSlabWt());
            pmSteelCastSlab.setSlabMaxWt(pmSlabPoolIn.getSlabMaxNomWt());
            pmSteelCastSlab.setSlabMinWt(pmSlabPoolIn.getSlabMinNomWt());
            pmSteelCastSlab.setInfurSlabLen(BigDecimal.valueOf(0));
            pmSteelCastSlab.setInfurSlabLen(BigDecimal.valueOf(0));
            pmSteelCastSlab.setInfurSlabMaxLen(BigDecimal.valueOf(0));
            pmSteelCastSlab.setInfurSlabMinLen(BigDecimal.valueOf(0));
            pmSteelCastSlab.setInfurSlabWt(BigDecimal.valueOf(0));
            pmSteelCastSlab.setInfurSlabMaxWt(BigDecimal.valueOf(0));
            pmSteelCastSlab.setInfurSlabMinWt(BigDecimal.valueOf(0));
            if (!pmContMscTecheMap.isEmpty() && pmContMscTecheMap.containsKey(Strings.concat(pmSlabEstaPlan.getOrderNo(), pmSlabPoolIn.getMscLineNo()))) {
                PmContMscTech pmContMscTech = pmContMscTecheMap.get(Strings.concat(pmSlabEstaPlan.getOrderNo(), pmSlabPoolIn.getMscLineNo()));
                pmSteelCastSlab.setSlabFinishCode(pmContMscTech.getSlabFinishCode());
                pmSteelCastSlab.setFlameCleanDiv(pmContMscTech.getFlameCleanDiv());
                pmSteelCastSlab.setNewTestNo(null);
            }
        }
        if (pmSlabPoolInMap.containsKey(virtualSlabNo)) {
            PmSlabPoolIn pmSlabPoolIn = pmSlabPoolInMap.get(virtualSlabNo);
            pmSteelCastSlab.setSlabDest(pmSlabPoolIn.getSlabDest());
            pmSteelCastSlab.setSlabPlaceCode(pmSlabPoolIn.getSlabPlaceCode());
            pmSteelCastSlab.setHotSendFlag("H");
            pmSteelCastSlab.setSgSign(pmSlabPoolIn.getSgSign());
            pmSteelCastSlab.setMscLineNo(pmSlabPoolIn.getMscLineNo());
            // 将虚拟板坯号作为入参（若是合并板坯，取虚拟板坯号除首字母之后的字符），调用质量模块接口，获取是否代表板标记（REP_MAT_FLAG） ；
            if (Utils.isMergeSlab(pmSlabEstaPlan.getVirtualSlabNo())) {
                for (PmSlabMerge pmSlabMerge : mergeSlabMap.get(pmSlabEstaPlan.getVirtualSlabNo())) {
                    if (qeTqSampleGenVOMap.containsKey(pmSlabMerge.getTmpSlabNo())) {
                        pmSteelCastSlab.setRepMatFlag(qeTqSampleGenVOMap.get(pmSlabMerge.getTmpSlabNo()));
                    }
                }
            } else {
                pmSteelCastSlab.setRepMatFlag(qeTqSampleGenVOMap.getOrDefault(pmSlabEstaPlan.getTmpSlabNo(), null));
            }
        }

        // 合并板坯的长和厚，取合并数据求和
        if (Utils.isMergeSlab(pmSlabEstaPlan.getVirtualSlabNo())) {
            BigDecimal slabLen = BigDecimal.ZERO;
            BigDecimal slabMaxLen = BigDecimal.ZERO;
            BigDecimal slabMinLen = BigDecimal.ZERO;
            BigDecimal slabWt = BigDecimal.ZERO;
            BigDecimal slabMaxWt = BigDecimal.ZERO;
            BigDecimal slabMinWt = BigDecimal.ZERO;
            BigDecimal infurSlabLen = BigDecimal.ZERO;
            BigDecimal infurSlabMaxLen = BigDecimal.ZERO;
            BigDecimal infurSlabMinLen = BigDecimal.ZERO;
            BigDecimal infurSlabWt = BigDecimal.ZERO;
            BigDecimal infurSlabMaxWt = BigDecimal.ZERO;
            BigDecimal infurSlabMinWt = BigDecimal.ZERO;
            for (PmSlabMerge pmSlabMerge : mergeSlabMap.get(pmSlabEstaPlan.getVirtualSlabNo())) {
                if (pdCcSlabMap.containsKey(pmSlabMerge.getVirtualSlabNo())) {
                    PmPdCcSlab pmPdCcSlab = pdCcSlabMap.get(pmSlabMerge.getVirtualSlabNo());
                    slabLen = slabLen.add(pmPdCcSlab.getPreCleanSlabLen());
                    slabMaxLen = slabMaxLen.add(pmPdCcSlab.getPreCleanSlabMaxLen());
                    slabMinLen = slabMinLen.add(pmPdCcSlab.getPreCleanSlabMinLen());
                    slabWt = slabWt.add(pmPdCcSlab.getPreCleanSlabWt());
                    slabMaxWt = slabMaxWt.add(pmPdCcSlab.getPreCleanSlabMaxWt());
                    slabMinWt = slabMinWt.add(pmPdCcSlab.getPreCleanSlabMinWt());
                    infurSlabLen = infurSlabLen.add(pmPdCcSlab.getInfurSlabLen());
                    infurSlabMaxLen = infurSlabMaxLen.add(pmPdCcSlab.getInfurSlabMaxLen());
                    infurSlabMinLen = infurSlabMinLen.add(pmPdCcSlab.getInfurSlabMinLen());
                    infurSlabWt = infurSlabWt.add(pmPdCcSlab.getInfurSlabWt());
                    infurSlabMaxWt = infurSlabMaxWt.add(pmPdCcSlab.getInfurSlabMaxWt());
                    infurSlabMinWt = infurSlabMinWt.add(pmPdCcSlab.getInfurSlabMinWt());
                } else if (pmSlabPoolInMap.containsKey(pmSlabMerge.getVirtualSlabNo())) {
                    PmSlabPoolIn pmSlabPoolIn = pmSlabPoolInMap.get(pmSlabMerge.getVirtualSlabNo());
                    slabLen = slabLen.add(pmSlabPoolIn.getNomSlabLen());
                    slabMaxLen = slabMaxLen.add(pmSlabPoolIn.getSlabMaxNomLen());
                    slabMinLen = slabMinLen.add(pmSlabPoolIn.getSlabMinNomLen());
                    slabWt = slabWt.add(pmSlabPoolIn.getNomSlabWt());
                    slabMaxWt = slabMaxWt.add(pmSlabPoolIn.getSlabMaxNomWt());
                    slabMinWt = slabMinWt.add(pmSlabPoolIn.getSlabMinNomWt());
                }
            }
            pmSteelCastSlab.setSlabLen(slabLen);
            pmSteelCastSlab.setSlabMaxLen(slabMaxLen);
            pmSteelCastSlab.setSlabMinLen(slabMinLen);
            pmSteelCastSlab.setSlabWt(slabWt);
            pmSteelCastSlab.setSlabMaxWt(slabMaxWt);
            pmSteelCastSlab.setSlabMinWt(slabMinWt);
            pmSteelCastSlab.setInfurSlabLen(infurSlabLen);
            pmSteelCastSlab.setInfurSlabMaxLen(infurSlabMaxLen);
            pmSteelCastSlab.setInfurSlabMinLen(infurSlabMinLen);
            pmSteelCastSlab.setInfurSlabWt(infurSlabWt);
            pmSteelCastSlab.setInfurSlabMaxWt(infurSlabMaxWt);
            pmSteelCastSlab.setInfurSlabMinWt(infurSlabMinWt);
        }
        return pmSteelCastSlab;
    }

    private PmSlabPreCastingDTO buildCommitDeliveryEventDTO(String virtualSlabNo, PmSlabEstaPlan pmSlabEstaPlan,  Map<String, PmSlabPoolIn> poolInMap ) {
        if (poolInMap.containsKey(virtualSlabNo)) {
            PmSlabPoolIn pmSlabPoolIn = poolInMap.get(virtualSlabNo);
            PmSlabPreCastingDTO castingDTO = new PmSlabPreCastingDTO();
            castingDTO.setMatNo(pmSlabPoolIn.getVirtualSlabNo());
            if (Constants.OrderTypeCode.QBP.equals(pmSlabPoolIn.getOrderTypeCode())) {
                castingDTO.setPpFlag(3);
            } else if (Constants.OrderTypeCode.YZA.equals(pmSlabPoolIn.getOrderTypeCode())) {
                castingDTO.setPpFlag(4);
            } else {
                throw new CommonException("pm.slab_pool_in_005",pmSlabPoolIn.getVirtualSlabNo(),pmSlabPoolIn.getOrderTypeCode() );
            }
            castingDTO.setOrdFlag("1");
            castingDTO.setPdMatStatus(null);
            castingDTO.setCsPrecPlanStatus("09");
            castingDTO.setProcCd("14A");
            castingDTO.setWholeBacklogCode("14");
            castingDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
            return castingDTO;
        } else {
            throw new CommonException("pm.slab_pool_in_006", virtualSlabNo);
        }
    }

    private List<PmSlabPreCastingDTO> buildCommitCastEventDTO(String virtualSlabNo, PmSlabEstaPlan pmSlabEstaPlan,
                                                              Map<String, List<PmSmallPltPos>> pmSmallPltPosMap,
                                                              Map<String, String> pmPdCcSlabMap) {
        List<PmSlabPreCastingDTO> resList = new ArrayList<>();
        PmSlabPreCastingDTO castingDTO = new PmSlabPreCastingDTO();
        castingDTO.setMatNo(virtualSlabNo);
        /*if (Constants.CcType.TYPE_5.equals(pmPdCcSlabMap.get(virtualSlabNo))) {
            castingDTO.setPpFlag(0);
        } else {
            castingDTO.setPpFlag(8);
        }*/
        castingDTO.setPpFlag(0);
        castingDTO.setOrdFlag("1");
        castingDTO.setPdMatStatus("26");
        castingDTO.setCsPrecPlanStatus("09");
        castingDTO.setProcCd("14A");
        castingDTO.setWholeBacklogCode("14");
        castingDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
        resList.add(castingDTO);

        // 大板信息
        PmSlabPreCastingDTO preCastingDTO = new PmSlabPreCastingDTO();
        preCastingDTO.setMatNo(virtualSlabNo);
        preCastingDTO.setPpFlag(1);
        preCastingDTO.setOrdFlag("1");
        preCastingDTO.setPdMatStatus("26");
        preCastingDTO.setCsPrecPlanStatus("09");
        preCastingDTO.setProcCd("14A");
        preCastingDTO.setWholeBacklogCode("14");
        preCastingDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
        resList.add(preCastingDTO);

        // 子板信息
        if (!pmSmallPltPosMap.containsKey(virtualSlabNo)) {
            throw new CommonException("pm.small_plt_pos", virtualSlabNo);
        }
        List<PmSmallPltPos> pmSmallPltPos = pmSmallPltPosMap.get(virtualSlabNo);
        for (PmSmallPltPos pmSmallPltPo : pmSmallPltPos) {
            PmSlabPreCastingDTO slabPreCastingDTO = new PmSlabPreCastingDTO();
            slabPreCastingDTO.setMoMatNo(pmSmallPltPo.getPdMatNo());
            slabPreCastingDTO.setMatNo(pmSmallPltPo.getPdMatNo() + pmSmallPltPo.getSmallPlateDivNo());
            slabPreCastingDTO.setPpFlag(2);
            slabPreCastingDTO.setOrdFlag("1");
            slabPreCastingDTO.setPdMatStatus("26");
            slabPreCastingDTO.setCsPrecPlanStatus("09");
            slabPreCastingDTO.setProcCd("14A");
            slabPreCastingDTO.setWholeBacklogCode("14");
            slabPreCastingDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
            resList.add(slabPreCastingDTO);
        }
        return resList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public  List<PmSlabPreCastingDTO> comfirm(List<PmSlabEstaPlan> pmSlabEstaPlanList, Long tenantId) {
        // 获取非无委板坯的虚拟板坯号，合并板坯要获取合并板坯之前的
        List<PmSlabEstaPlan> newEstaPlanList = pmSlabEstaPlanList.stream().filter(esta -> StringUtils.isNotEmpty(esta.getOrderNo()))
                .collect(Collectors.toList());
        List<String> virtualSlabNoList = newEstaPlanList.stream().map(PmSlabEstaPlan::getVirtualSlabNo)
                .filter(item -> !Utils.isMergeSlab(item)).collect(Collectors.toList());

        LocalDate now = LocalDate.now();
        List<PmSlabEstaPlan> updateList = new ArrayList<>();
        Map<String, List<PmSlabEstaPlan>> pmSlabEstaPlanMap = pmSlabEstaPlanList.stream().collect(Collectors.groupingBy(PmSlabEstaPlan::getPrecCastLotNo));

        //  5.  更新【命令板坯表】、【命令大板表】、【命令参数表】、【命令小板表】中命令板坯号的值；
        List<String> tmpSlabNoList = pmSlabEstaPlanList.stream().map(PmSlabEstaPlan::getTmpSlabNo).collect(Collectors.toList());
        // 获取合并板坯的临时命令板坯号
        List<String> merVirtualSlabNoList = pmSlabEstaPlanList.stream().map(PmSlabEstaPlan::getVirtualSlabNo)
                .filter(item -> Utils.isMergeSlab(item)).collect(Collectors.toList());
        Map<String, List<PmSlabMerge>> mergePmSlabMap = new HashMap<>(16);
        List<PmSlabMerge> updateSlabMergellist = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(merVirtualSlabNoList)) {
            List<PmSlabMerge> pmSlabMergeList = pmSlabMergeRepository.selectByMergeSlabNoList(merVirtualSlabNoList, tenantId);
            if (CollectionUtils.isNotEmpty(pmSlabMergeList)) {
                tmpSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getTmpSlabNo).collect(Collectors.toList()));
                tmpSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getTmpPonoSlabNo).collect(Collectors.toList()));
                mergePmSlabMap = pmSlabMergeList.stream().collect(Collectors.groupingBy(PmSlabMerge::getMergeSlabNo));
                virtualSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getVirtualSlabNo).collect(Collectors.toList()));
            } else {
                throw new CommonException("pm.slab_merge_002", merVirtualSlabNoList);
            }
        }

        // 【命令板坯表】
        List<PmCmdSlab> pmCmdSlabList = pmCmdSlabRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId);
        Map<String, List<PmCmdSlab>>  pmCmdSlabMap = new HashMap<>(pmCmdSlabList.size());
        if (CollectionUtils.isNotEmpty(pmCmdSlabList)) {
            pmCmdSlabMap = pmCmdSlabList.stream().collect(Collectors.groupingBy(PmCmdSlab::getTmpSlabNo));
        }
        // 【命令大板表】
        List<PmCmdLargePlt> pmCmdLargePltList = pmCmdLargePltRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId);
        Map<String, List<PmCmdLargePlt>>  pmCmdLargePltMap = new HashMap<>(pmCmdSlabList.size());
        if (CollectionUtils.isNotEmpty(pmCmdLargePltList)) {
            pmCmdLargePltMap = pmCmdLargePltList.stream().collect(Collectors.groupingBy(PmCmdLargePlt::getTmpSlabNo));
        }
        // 【命令参数表】
        List<PmCmdCont> pmCmdContList =  pmCmdContRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId);
        Map<String, List<PmCmdCont>> pmCmdContMap = new HashMap<>(pmCmdSlabList.size());
        if (CollectionUtils.isNotEmpty(pmCmdContList)) {
            pmCmdContMap = pmCmdContList.stream().collect(Collectors.groupingBy(PmCmdCont::getTmpSlabNo));
        }

        // 【命令小板表】
        List<PmCmdSmallPlt> pmCmdSmallPltList = pmCmdSmallPltRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId);
        Map<String, List<PmCmdSmallPlt>> pmCmdSmallPltMap = new HashMap<>(pmCmdSlabList.size());
        if (CollectionUtils.isNotEmpty(pmCmdSmallPltList)) {
            pmCmdSmallPltMap = pmCmdSmallPltList.stream().collect(Collectors.groupingBy(PmCmdSmallPlt::getTmpSlabNo));
        }

        // 定义四大命令的更新集合
        List<PmCmdSlab> updatePmCmdSlabList = new ArrayList<>(pmCmdSlabList.size());
        List<PmCmdLargePlt> updatePmCmdLargePltList = new ArrayList<>(pmCmdSlabList.size());
        List<PmCmdCont> updatePmCmdContList = new ArrayList<>(pmCmdSlabList.size());
        List<PmCmdSmallPlt> updatePmCmdSmallPltList = new ArrayList<>(pmCmdSlabList.size());
        for (Map.Entry<String, List<PmSlabEstaPlan>> entry : pmSlabEstaPlanMap.entrySet()) {
            // 每一个浇次内
            String castLotNo = "";
            boolean flag = true;
            List<String> precPonoList = entry.getValue().stream().sorted(Comparator.comparing(PmSlabEstaPlan::getPrecPono))
                    .map(PmSlabEstaPlan::getPrecPono).distinct().collect(Collectors.toList());
            // 每一炉
            for (String precPono : precPonoList) {
                List<PmSlabEstaPlan> sortPlanList = entry.getValue().stream().filter(item -> precPono.equals(item.getPrecPono()))
                        .sorted(Comparator.comparing(PmSlabEstaPlan::getCastLotDivNo)
                                .thenComparing(PmSlabEstaPlan::getSlabSeqHeat)).collect(Collectors.toList());
                String pono = "";
                for (int i = 0; i < sortPlanList.size(); i++) {
                    PmSlabEstaPlan estaPlan = sortPlanList.get(i);
                    // CAST_LOT号
                    if (flag) {
                        flag = false;
                        castLotNo = generateCastLotNo(estaPlan, tenantId);
                    }
                    // 生成生成制造命令号（PREC_PONO）
                    if (i == 0) {
                        pono = generatePono(estaPlan, tenantId, now);
                    }

                    // 3.	生成命令板坯号（PREC_SLAB_NO）
                    String precSlabNo = pono + estaPlan.getCcType() + "1" + String.format("%03d", estaPlan.getSlabSeqHeat());
                    // 4. 更新【组炉编制表（PM_SLAB_ESTA_PLAN）】并修改连铸预计划状态（CS_PREC_PLAN_STATUS）
                    estaPlan.setCastLotNo(castLotNo);
                    estaPlan.setPono(pono);
                    estaPlan.setPrecSlabNo(precSlabNo);
                    estaPlan.setCsPrecPlanStatus(Constants.CsPrecPlanStatus.STATUS_08);
                    updateList.add(estaPlan);

                    // 更新四大命令表
                    if (Utils.isMergeSlab(estaPlan.getVirtualSlabNo())) {
                        // 获取合并版板坯的临时命令板坯号
                        if (!mergePmSlabMap.containsKey(estaPlan.getVirtualSlabNo())) {
                            throw new CommonException("pm.slab_merge_001", estaPlan.getVirtualSlabNo());
                        }
                        List<PmSlabMerge> pmSlabMergeList = mergePmSlabMap.get(estaPlan.getVirtualSlabNo());
                        // 遍历
                        for (PmSlabMerge pmSlabMerge : pmSlabMergeList) {
                            String mergePrecSlabNo = pono + pmSlabMerge.getTmpSlabNo().substring(7, pmSlabMerge.getTmpSlabNo().length());
                            pmSlabMerge.setPrecSlabNo(mergePrecSlabNo);
                            pmSlabMerge.setPonoSlabNo(precSlabNo);
                            updateSlabMergellist.add(pmSlabMerge);
                            if (pmCmdSlabMap.containsKey(pmSlabMerge.getTmpSlabNo())) {
                                List<PmCmdSlab> cmdSlabList = pmCmdSlabMap.get(pmSlabMerge.getTmpSlabNo());
                                // 命令板坯号的取值逻辑为：命令板坯号 = 制造命令号替换临时命令板坯号的前7位；
                                for (PmCmdSlab pmCmdSlab : cmdSlabList) {
                                    pmCmdSlab.setPonoSlabNo(mergePrecSlabNo);
                                    pmCmdSlab.setPono(pono);
                                    pmCmdSlab.setSlabNo(precSlabNo);
                                }
                                updatePmCmdSlabList.addAll(cmdSlabList);
                            }

                            // 更新【命令大板表】
                            if (pmCmdLargePltMap.containsKey(pmSlabMerge.getTmpSlabNo())) {
                                List<PmCmdLargePlt> cmdLargePltList = pmCmdLargePltMap.get(pmSlabMerge.getTmpSlabNo());
                                for (PmCmdLargePlt pmCmdLargePlt : cmdLargePltList) {
                                    pmCmdLargePlt.setPonoSlabNo(mergePrecSlabNo);
                                    pmCmdLargePlt.setSlabNo(precSlabNo);
                                }
                                updatePmCmdLargePltList.addAll(cmdLargePltList);
                            }

                            // 更新【命令参数表】
                            if (pmCmdContMap.containsKey(pmSlabMerge.getTmpSlabNo())) {
                                List<PmCmdCont> cmdContList = pmCmdContMap.get(pmSlabMerge.getTmpSlabNo());
                                for (PmCmdCont pmCmdCont : cmdContList) {
                                    pmCmdCont.setPonoSlabNo(mergePrecSlabNo);
                                    pmCmdCont.setSlabNo(precSlabNo);
                                }
                                updatePmCmdContList.addAll(cmdContList);
                            }

                            // 更新【命令小板表】
                            if (pmCmdSmallPltMap.containsKey(pmSlabMerge.getTmpSlabNo())) {
                                List<PmCmdSmallPlt> cmdSmallPltList = pmCmdSmallPltMap.get(pmSlabMerge.getTmpSlabNo());
                                for (PmCmdSmallPlt pmCmdSmallPlt : cmdSmallPltList) {
                                    pmCmdSmallPlt.setPonoSlabNo(mergePrecSlabNo);
                                    pmCmdSmallPlt.setSlabNo(precSlabNo);
                                }
                                updatePmCmdSmallPltList.addAll(cmdSmallPltList);
                            }
                        }
                    }

                    if (pmCmdSlabMap.containsKey(estaPlan.getTmpSlabNo())) {
                        List<PmCmdSlab> cmdSlabList = pmCmdSlabMap.get(estaPlan.getTmpSlabNo());
                        // 赋值命令板坯号
                        for (PmCmdSlab pmCmdSlab : cmdSlabList) {
                            pmCmdSlab.setPonoSlabNo(estaPlan.getPrecSlabNo());
                            pmCmdSlab.setPono(estaPlan.getPono());
                        }
                        updatePmCmdSlabList.addAll(cmdSlabList);
                    }
                    // 更新【命令大板表】
                    if (pmCmdLargePltMap.containsKey(estaPlan.getTmpSlabNo())) {
                        List<PmCmdLargePlt> cmdLargePltList = pmCmdLargePltMap.get(estaPlan.getTmpSlabNo());
                        for (PmCmdLargePlt pmCmdLargePlt : cmdLargePltList) {
                            pmCmdLargePlt.setPonoSlabNo(estaPlan.getPrecSlabNo());
                        }
                        updatePmCmdLargePltList.addAll(cmdLargePltList);
                    }

                    // 更新【命令参数表】
                    if (pmCmdContMap.containsKey(estaPlan.getTmpSlabNo())) {
                        List<PmCmdCont> cmdContList = pmCmdContMap.get(estaPlan.getTmpSlabNo());
                        for (PmCmdCont pmCmdCont : cmdContList) {
                            pmCmdCont.setPonoSlabNo(estaPlan.getPrecSlabNo());
                        }
                        updatePmCmdContList.addAll(cmdContList);
                    }

                    // 更新【命令小板表】
                    if (pmCmdSmallPltMap.containsKey(estaPlan.getTmpSlabNo())) {
                        List<PmCmdSmallPlt> cmdSmallPltList = pmCmdSmallPltMap.get(estaPlan.getTmpSlabNo());
                        for (PmCmdSmallPlt pmCmdSmallPlt : cmdSmallPltList) {
                            pmCmdSmallPlt.setPonoSlabNo(estaPlan.getPrecSlabNo());
                        }
                        updatePmCmdSmallPltList.addAll(cmdSmallPltList);
                    }
                }
            }
        }

        // 4.	更新【组炉编制表（PM_SLAB_ESTA_PLAN）】并修改连铸预计划状态（CS_PREC_PLAN_STATUS）
        pmSlabEstaPlanRepository.batchUpdateByPrimaryKeySelective(updateList);
        pmCmdSlabRepository.batchUpdateByPrimaryKey(updatePmCmdSlabList);
        pmCmdLargePltRepository.batchUpdateByPrimaryKey(updatePmCmdLargePltList);
        pmCmdContRepository.batchUpdateByPrimaryKey(updatePmCmdContList);
        pmCmdSmallPltRepository.batchUpdateByPrimaryKey(updatePmCmdSmallPltList);
        pmSlabMergeRepository.batchUpdateByPrimaryKey(updateSlabMergellist);


        List<PmPdCcSlab> pmPdCcSlabList =  pmPdCcSlabRepository.selectByVirtualSlabList(virtualSlabNoList, tenantId);
        List<String> noOutVirtualNoList = new ArrayList<>(pmPdCcSlabList.size());
        Map<String, String> pmcCcSlabMap = new HashMap<>(pmPdCcSlabList.size());
        Map<String, List<PmSmallPltPos>> pmSmallPltPosMap = new HashMap<>(pmPdCcSlabList.size());
        if (CollectionUtils.isNotEmpty(pmPdCcSlabList)) {
            // 非外供板坯或者备坯的虚拟号
            noOutVirtualNoList = pmPdCcSlabList.stream().map(PmPdCcSlab::getVirtualSlabNo).collect(Collectors.toList());
            pmcCcSlabMap = pmPdCcSlabList.stream().collect(Collectors.toMap(PmPdCcSlab::getVirtualSlabNo, PmPdCcSlab::getCcType));

            // 获取组板小板位置表
            List<PmSmallPltPos> pmSmallPltPosList =   pmSmallPltPosRepository.selectByPdMatNoList(noOutVirtualNoList, tenantId);
            if (CollectionUtils.isNotEmpty(pmSmallPltPosList)) {
                pmSmallPltPosMap = pmSmallPltPosList.stream().collect(Collectors.groupingBy(PmSmallPltPos::getPdMatNo));
            }

            // i.	更新组板状态
            // 更新【组板合同总量表（PM_PD_CONT_SUM）】
            List<PmPdContSum> pdContSumList = pmPdContSumRepository.selectByPdMatNoList(tenantId, noOutVirtualNoList);
            pdContSumList.forEach(item -> item.setPdStatus(Constants.PdStatusHp.PD_STATUS_HP_25));

            // 更新【组板连铸板坯表（PM_PD_CC_SLAB）】
            pmPdCcSlabList.forEach(item -> item.setPdStatusHp(Constants.PdStatusHp.PD_STATUS_HP_25));
            pmPdContSumRepository.batchUpdateByPrimaryKey(pdContSumList);
            pmPdCcSlabRepository.batchUpdateByPrimaryKey(pmPdCcSlabList);

            // c) 更新【命令板坯表（PM_CMD_SLAB）】以及【命令大板表（PM_CMD_LARGE_PLT）】中字段厚板组板状态（PD_STATUS_HP）的值
            List<PmCmdSlab> cmdSlabList = pmCmdSlabRepository.selectByVirtualSlabNoList(noOutVirtualNoList, tenantId);
            cmdSlabList.forEach(pmCmdSlab -> pmCmdSlab.setPdStatusHp(Constants.PdStatusHp.PD_STATUS_HP_25));
            pmCmdSlabRepository.batchUpdateByPrimaryKey(cmdSlabList);
            if (CollectionUtils.isNotEmpty(cmdSlabList)) {
                List<String> cmdTempSlabNoList = cmdSlabList.stream().map(PmCmdSlab::getTmpSlabNo).distinct().collect(Collectors.toList());
                List<PmCmdLargePlt> cmdLargePltList = pmCmdLargePltRepository.selectByTmpSlabNoList(cmdTempSlabNoList, tenantId);
                cmdLargePltList.forEach(pmCmdLargePlt -> pmCmdLargePlt.setPdStatusHp(Constants.PdStatusHp.PD_STATUS_HP_25));
                pmCmdLargePltRepository.batchUpdateByPrimaryKey(cmdLargePltList);
            }
        }

        // 若当前板坯是外供板坯或备坯，则直接向合同跟踪抛帐，具体过程如下（若是合并板坯，需要使用合并之前的虚拟板号进行操作）
        virtualSlabNoList.removeAll(noOutVirtualNoList);
        Map<String, PmSlabPoolIn> poolInMap = new HashMap<>(virtualSlabNoList.size());
        if (CollectionUtils.isNotEmpty(virtualSlabNoList)) {
            List<PmSlabPoolIn> poolInList = pmSlabPoolInRepository.selectByCondition(Condition.builder(PmSlabPoolIn.class)
                    .andWhere(Sqls.custom().andIn(PmSlabPoolIn.FIELD_VIRTUAL_SLAB_NO, virtualSlabNoList))
                    .andWhere(Sqls.custom().andEqualTo(PmSlabPoolIn.FIELD_TENANT_ID, tenantId))
                    .build());
            if (CollectionUtils.isNotEmpty(poolInList)) {
                poolInMap = poolInList.stream().collect(Collectors.toMap(PmSlabPoolIn::getVirtualSlabNo, Function.identity()));
            }
        }
        // 将以下字段作为入参，调用合同跟踪模块“连铸预编制事件”接口，向合同跟踪抛帐
        List<PmSlabPreCastingDTO> resList =  commandAbandonContract(pmSlabEstaPlanList,mergePmSlabMap, pmcCcSlabMap, pmSmallPltPosMap, poolInMap,
              "25", "08", "14A", "14");
       return resList;
    }

    private PmPdPlateCut buildPmPdPlateCut(PmPdPlateCut pdPlateCut, String precSlabNo, Long tenantId) {
        PmPdPlateCut pmPdPlateCut = new PmPdPlateCut();
        pmPdPlateCut.setPdMatNo(precSlabNo);
        pmPdPlateCut.setCutType(pdPlateCut.getCutType());
        pmPdPlateCut.setPositionType(pdPlateCut.getPositionType());
        pmPdPlateCut.setPositionSeq(pdPlateCut.getPositionSeq());
        pmPdPlateCut.setCutLength(pdPlateCut.getCutLength());
        pmPdPlateCut.setTenantId(tenantId);
        return pmPdPlateCut;
    }

    private String generatePono(PmSlabEstaPlan estaPlan, Long tenantId, LocalDate now) {
        String pono = Strings.EMPTY;
        Map<String, String> ponoParamsMap = new HashMap<>(4);
        ponoParamsMap.put("wholeBackCode", estaPlan.getMainBacklogCode());
        ponoParamsMap.put("yearLastNum", String.format("%1d", now.getYear() % 10));
        if (Constants.CcType.TYPE_1.equals(estaPlan.getCcType())) {
            pono = codeRuleBuilder.generateCode(tenantId, Constants.CodeRule.PONO,
                    CodeConstants.CodeRuleLevelCode.GLOBAL, Constants.CodeRule.GLOBAL_LEVEL_VALUE, ponoParamsMap);
        } else if (Constants.CcType.TYPE_2.equals(estaPlan.getCcType())) {
            pono = codeRuleBuilder.generateCode(tenantId, Constants.CodeRule.PONO,
                    CodeConstants.CodeRuleLevelCode.CUSTOM, Constants.CodeRule.TYPE_2_LEVEL_CODE, ponoParamsMap);
        } else if (Constants.CcType.TYPE_4.equals(estaPlan.getCcType())) {
            pono = codeRuleBuilder.generateCode(tenantId, Constants.CodeRule.PONO,
                    CodeConstants.CodeRuleLevelCode.CUSTOM, Constants.CodeRule.TYPE_4_LEVEL_CODE, ponoParamsMap);
        } else if (Constants.CcType.TYPE_5.equals(estaPlan.getCcType())) {
            pono = codeRuleBuilder.generateCode(tenantId, Constants.CodeRule.PONO,
                    CodeConstants.CodeRuleLevelCode.CUSTOM, Constants.CodeRule.TYPE_5_LEVEL_CODE, ponoParamsMap);
        }
        return pono;
    }

    private String generateCastLotNo(PmSlabEstaPlan estaPlan, Long tenantId) {
        String castLotNo = "";
        Map<String, String> paramsMap = new HashMap<>(4);
        paramsMap.put("wholeBackCode", estaPlan.getMainBacklogCode());
        if (Constants.CcType.TYPE_1.equals(estaPlan.getCcType())) {
            castLotNo = codeRuleBuilder.generateCode(tenantId, Constants.CodeRule.CAST_LOT_NO,
                    CodeConstants.CodeRuleLevelCode.GLOBAL, Constants.CodeRule.GLOBAL_LEVEL_VALUE, paramsMap);
        } else if (Constants.CcType.TYPE_2.equals(estaPlan.getCcType())) {
            castLotNo = codeRuleBuilder.generateCode(tenantId, Constants.CodeRule.CAST_LOT_NO,
                    CodeConstants.CodeRuleLevelCode.CUSTOM, Constants.CodeRule.TYPE_2_LEVEL_CODE, paramsMap);
        } else if (Constants.CcType.TYPE_4.equals(estaPlan.getCcType())) {
            castLotNo = codeRuleBuilder.generateCode(tenantId, Constants.CodeRule.CAST_LOT_NO,
                    CodeConstants.CodeRuleLevelCode.CUSTOM, Constants.CodeRule.TYPE_4_LEVEL_CODE, paramsMap);
        } else if (Constants.CcType.TYPE_5.equals(estaPlan.getCcType())) {
            castLotNo = codeRuleBuilder.generateCode(tenantId, Constants.CodeRule.CAST_LOT_NO,
                    CodeConstants.CodeRuleLevelCode.CUSTOM, Constants.CodeRule.TYPE_5_LEVEL_CODE, paramsMap);
        }
        return castLotNo;
    }

    private PmSlabPreCastingDTO buildNoOrderCastingDTO(String virtualSlabNo, String precSlabNo, int ppFlag, String ordFlag, String pdMatStatus,
                                        String csPrecPlanStatus, String procCd, String wholeBacklogCode, String cutPonoSlab) {
        PmSlabPreCastingDTO castingDTO = new PmSlabPreCastingDTO();
        castingDTO.setMatNo(virtualSlabNo);
        castingDTO.setPpFlag(ppFlag);
        castingDTO.setOrdFlag(ordFlag);
        castingDTO.setPdMatStatus(pdMatStatus);
        castingDTO.setCsPrecPlanStatus(csPrecPlanStatus);
        castingDTO.setProcCd(procCd);
        castingDTO.setWholeBacklogCode(wholeBacklogCode);
        castingDTO.setPonoSlab(precSlabNo);
        castingDTO.setCutPonoSlab(cutPonoSlab);
        return castingDTO;
    }

    private PmSlabPreCastingDTO buildDeliveryCastingDTO(PmSlabEstaPlan pmSlabEstaPlan, String virtualSlabNo, Map<String, PmSlabPoolIn> poolInMap,
                                                        String pdMatStatus, String csPrecPlanStatus, String procCd, String wholeBacklogCode, String cutPonoSlab) {
        PmSlabPreCastingDTO castingDTO = new PmSlabPreCastingDTO();
        if (poolInMap.containsKey(virtualSlabNo)) {
            PmSlabPoolIn pmSlabPoolIn = poolInMap.get(virtualSlabNo);
            castingDTO.setMatNo(pmSlabPoolIn.getVirtualSlabNo());
            if (Constants.OrderTypeCode.QBP.equals(pmSlabPoolIn.getOrderTypeCode())) {
                castingDTO.setPpFlag(3);
            } else if (Constants.OrderTypeCode.YZA.equals(pmSlabPoolIn.getOrderTypeCode())) {
                castingDTO.setPpFlag(4);
            } else {
                throw new CommonException("pm.slab_pool_in_005",pmSlabPoolIn.getVirtualSlabNo(),pmSlabPoolIn.getOrderTypeCode());
            }
            castingDTO.setOrdFlag("1");
            castingDTO.setPdMatStatus(null);
            castingDTO.setCsPrecPlanStatus(csPrecPlanStatus);
            castingDTO.setProcCd(procCd);
            castingDTO.setWholeBacklogCode(wholeBacklogCode);
            castingDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
            castingDTO.setCutPonoSlab(cutPonoSlab);
            return castingDTO;
        } else {
            throw new CommonException("pm.slab_pool_in_006", virtualSlabNo);
        }
    }

    private List<PmSlabPreCastingDTO> buildPreCastEventData(String virtualSlabNo, PmSlabEstaPlan pmSlabEstaPlan,
                                                            Map<String, String> pmcCcSlabMap, Map<String, List<PmSmallPltPos>> pmSmallPltPosMap,
                                                            String pdMatStatus, String csPrecPlanStatus, String procCd, String wholeBacklogCode, String cutPonoSlab) {
        List<PmSlabPreCastingDTO> resList = new ArrayList<>();
        PmSlabPreCastingDTO castingDTO = new PmSlabPreCastingDTO();
        castingDTO.setMatNo(virtualSlabNo);
        /*if (Constants.CcType.TYPE_5.equals(pmcCcSlabMap.get(virtualSlabNo))) {
            castingDTO.setPpFlag(8);
        } else {
            castingDTO.setPpFlag(0);
        }*/
        castingDTO.setPpFlag(0);
        castingDTO.setOrdFlag("1");
        castingDTO.setPdMatStatus(pdMatStatus);
        castingDTO.setCsPrecPlanStatus(csPrecPlanStatus);
        castingDTO.setProcCd(procCd);
        castingDTO.setWholeBacklogCode(wholeBacklogCode);
        castingDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
        castingDTO.setCutPonoSlab(cutPonoSlab);
        resList.add(castingDTO);

        // 大板信息
        PmSlabPreCastingDTO preCastingDTO = new PmSlabPreCastingDTO();
        preCastingDTO.setMatNo(virtualSlabNo);
        preCastingDTO.setPpFlag(1);
        preCastingDTO.setOrdFlag("1");
        preCastingDTO.setPdMatStatus(pdMatStatus);
        preCastingDTO.setCsPrecPlanStatus(csPrecPlanStatus);
        preCastingDTO.setProcCd(procCd);
        preCastingDTO.setWholeBacklogCode(wholeBacklogCode);
        preCastingDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
        preCastingDTO.setCutPonoSlab(cutPonoSlab);
        resList.add(preCastingDTO);

        // 子板信息
        if (!pmSmallPltPosMap.containsKey(virtualSlabNo)) {
            throw new CommonException("pm.small_plt_pos", virtualSlabNo);
        }
        List<PmSmallPltPos> pmSmallPltPos = pmSmallPltPosMap.get(virtualSlabNo);
        for (PmSmallPltPos pmSmallPltPo : pmSmallPltPos) {
            PmSlabPreCastingDTO slabPreCastingDTO = new PmSlabPreCastingDTO();
            slabPreCastingDTO.setMoMatNo(pmSmallPltPo.getPdMatNo());
            slabPreCastingDTO.setMatNo(pmSmallPltPo.getPdMatNo() + pmSmallPltPo.getSmallPlateDivNo());
            slabPreCastingDTO.setPpFlag(2);
            slabPreCastingDTO.setOrdFlag("1");
            slabPreCastingDTO.setPdMatStatus(pdMatStatus);
            slabPreCastingDTO.setCsPrecPlanStatus(csPrecPlanStatus);
            slabPreCastingDTO.setProcCd(procCd);
            slabPreCastingDTO.setWholeBacklogCode(wholeBacklogCode);
            slabPreCastingDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
            slabPreCastingDTO.setCutPonoSlab(cutPonoSlab);
            resList.add(slabPreCastingDTO);
        }
        return resList;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void recover(List<String> castLotNoList, Long tenantId) {
        // a)	根据CAST_LOT号（PREC_CAST_LOT_NO）查询【组炉编制表（PM_SLAB_ESTA_PLAN）】
        List<PmSlabEstaPlan> pmSlabEstaPlanList = pmSlabEstaPlanRepository.selectByCondition(Condition.builder(PmSlabEstaPlan.class)
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmSlabEstaPlan.FIELD_CAST_LOT_NO, castLotNoList))
                .build());
        if (CollectionUtils.isEmpty(pmSlabEstaPlanList)) {
            throw new CommonException("pm.slab_esta_plan_002", castLotNoList);
        }
        // 判断其值是否为“09”状态（命令提交完成）
        pmSlabEstaPlanList.forEach(item -> {
            if (!item.getCsPrecPlanStatus().equals(Constants.CsPrecPlanStatus.STATUS_09)) {
                throw new CommonException("pm.furnace_casting_011");
            }
        });

        // 2.	根据浇次号（CAST_LOT_NO）到【炼钢连铸制造命令炉次表（PM_STEEL_CAST_HEAT）】中查询制造命令状态（PONO_STATUS）不为“11”状态（命令提交）的信息，
        List<PmSteelCastHeat> pmSteelCastHeatList = pmSteelCastHeatRepository.selectByCondition(Condition.builder(PmSteelCastHeat.class)
                .andWhere(Sqls.custom().andIn(PmSteelCastHeat.FIELD_CAST_LOT_NO, castLotNoList))
                .andWhere(Sqls.custom().andEqualTo(PmSteelCastHeat.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andNotEqualTo(PmSteelCastHeat.FIELD_PONO_STATUS, Constants.PonoStatus.STATUS_11))
                .build());
        if (CollectionUtils.isNotEmpty(pmSteelCastHeatList)) {
            // 如果记录数大于0，则报错（右下角弹窗报错）：PM.FURNACE.CASTING.012，程序结束
            throw new CommonException("pm.furnace_casting_012", pmSteelCastHeatList.get(0).getCastLotNo(), pmSteelCastHeatList.get(0).getPono());
        }

        // 命令板坯号
        List<String> precSlabNoList = pmSlabEstaPlanList.stream().map(PmSlabEstaPlan::getPrecSlabNo).collect(Collectors.toList());
        // 虚拟板坯号
        List<String> virtualSlabList = pmSlabEstaPlanList.stream().filter(item -> StringUtils.isNotEmpty(item.getOrderNo()))
                .map(PmSlabEstaPlan::getVirtualSlabNo).filter(item -> !Utils.isMergeSlab(item)).collect(Collectors.toList());
        // 获取合并板坯的虚拟板坯号
        List<String> merVirtualSlabNoList = pmSlabEstaPlanList.stream().map(PmSlabEstaPlan::getVirtualSlabNo)
                .filter(item -> Utils.isMergeSlab(item)).collect(Collectors.toList());
        Map<String, List<PmSlabMerge>> mergeSlabMap = new HashMap<>(merVirtualSlabNoList.size());
        if (CollectionUtils.isNotEmpty(merVirtualSlabNoList)) {
            List<PmSlabMerge> pmSlabMergeList = pmSlabMergeRepository.selectByMergeSlabNoList(merVirtualSlabNoList, tenantId);
            if (CollectionUtils.isNotEmpty(pmSlabMergeList)) {
                mergeSlabMap = pmSlabMergeList.stream().collect(Collectors.groupingBy(PmSlabMerge::getMergeSlabNo));
                precSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getPrecSlabNo).collect(Collectors.toList()));
                virtualSlabList.addAll( pmSlabMergeList.stream().map(PmSlabMerge::getVirtualSlabNo).collect(Collectors.toList()));
            } else {
                throw new CommonException("pm.slab_merge_002", merVirtualSlabNoList);
            }
        }

        // 3.	根据浇次号（CAST_LOT_NO）依次删除【炼钢连铸制造命令炉次表（PM_STEEL_CAST_HEAT）】、
        // 【炼钢连铸制造命令LOT表（PM_STEEL_CAST_LOT）】、【炼钢连铸制造命令板坯表（PM_STEEL_CAST_SLAB）】对应记录的信息；
        List<String> ponoList = pmSlabEstaPlanList.stream().map(PmSlabEstaPlan::getPono).distinct().collect(Collectors.toList());
        List<PmSteelCastFlow> pmSteelCastFlowList = pmSteelCastFlowRepository.selectByPonoList(ponoList, tenantId);
        List<PmSteelCastHeat> steelCastHeatList = pmSteelCastHeatRepository.selectByCastLotNoList(castLotNoList, tenantId);
        List<PmSteelCastSlab> pmSteelCastSlabList = pmSteelCastSlabRepository.selectByCastLotNoList(castLotNoList, tenantId);
        List<PmSteelCastLot> pmSteelCastLotList = pmSteelCastLotRepository.selectByCastLotNoList(castLotNoList, tenantId);
        // 删除大板粗切位置表
        List<PmPdPlateCut> pmPdPlateCutList = pmPdPlateCutRepository.selectByPdMatNoList(precSlabNoList, tenantId);
        // 5.	更新连铸预计划状态以及组板状态更新【组炉编制表（PM_SLAB_ESTA_PLAN）】中连铸预计划状态（CS_PREC_PLAN_STATUS）为“08”状态（命令确定完成）；
        pmSlabEstaPlanList.forEach(item -> item.setCsPrecPlanStatus(Constants.CsPrecPlanStatus.STATUS_08));
        // 则根据虚拟板坯号更新【组板连铸板坯表（PM_PD_CC_SLAB）】中的厚板组板状态（PD_STATUS_HP）为“25”状态（制造命令确定状态
        List<PmPdCcSlab> pmPdCcSlabList = pmPdCcSlabRepository.selectByVirtualSlabList(virtualSlabList, tenantId);
        Map<String, String> pmPdCcSlabMap = new HashMap<>(pmPdCcSlabList.size());
        if (CollectionUtils.isNotEmpty(pmPdCcSlabList)) {
            pmPdCcSlabMap = pmPdCcSlabList.stream().collect(Collectors.toMap(PmPdCcSlab::getVirtualSlabNo, PmPdCcSlab::getCcType));
        }
        pmPdCcSlabList.forEach(item -> item.setPdStatusHp(Constants.PdStatusHp.PD_STATUS_HP_25));

        List<PmSmallPltPos> pmSmallPltPosList = pmSmallPltPosRepository.selectByPdMatNoList(virtualSlabList, tenantId);
        Map<String, List<PmSmallPltPos>> pmSmallPltPosMap = new HashMap<>(pmSmallPltPosList.size());
        if (CollectionUtils.isNotEmpty(pmSmallPltPosList)) {
            pmSmallPltPosMap = pmSmallPltPosList.stream().collect(Collectors.groupingBy(PmSmallPltPos::getPdMatNo));
        }

        // 虚拟板坯或者备坯
        Map<String, PmSlabPoolIn> poolInMap = new HashMap<>(virtualSlabList.size());
        if (CollectionUtils.isNotEmpty(virtualSlabList)) {
            List<PmSlabPoolIn> poolInList = pmSlabPoolInRepository.selectByVirtualSlabNoList(virtualSlabList, tenantId);
            if (CollectionUtils.isNotEmpty(poolInList)) {
                poolInMap = poolInList.stream().collect(Collectors.toMap(PmSlabPoolIn::getVirtualSlabNo, Function.identity()));
            }
        }

        // 删除和更新
        pmSteelCastHeatRepository.batchDeleteByPrimaryKey(steelCastHeatList);
        pmSteelCastLotRepository.batchDeleteByPrimaryKey(pmSteelCastLotList);
        pmSteelCastSlabRepository.batchDeleteByPrimaryKey(pmSteelCastSlabList);
        pmSteelCastFlowRepository.batchDeleteByPrimaryKey(pmSteelCastFlowList);
        pmPdPlateCutRepository.batchDeleteByPrimaryKey(pmPdPlateCutList);
        pmSlabEstaPlanRepository.batchUpdateByPrimaryKey(pmSlabEstaPlanList);
        pmPdCcSlabRepository.batchUpdateByPrimaryKey(pmPdCcSlabList);

        // 抛合同
        List<PmSlabPreCastingDTO> resList =  commandAbandonContract(pmSlabEstaPlanList,mergeSlabMap, pmPdCcSlabMap, pmSmallPltPosMap, poolInMap,
                "24", "08", "14A", "14");
      // 以下字段作为入参，调用合同跟踪模块“连铸预编制事件”接口，向合同跟踪抛帐：
        log.info("<=====命令收回调用连铸预编制事件，入参为{}=====>", JSON.toJSONString(resList));
        eventClient.sendEventWithOutResponse(tenantId,CtEventConstants.EVENT_PM_PRE_CONTINUOUS_CASTING, resList);
    }

    private PmSlabPreCastingDTO buildRecoverDeliveryCastEventDTO(PmSlabEstaPlan pmSlabEstaPlan, String virtualSlabNo, Map<String, PmSlabPoolIn> poolInMap) {
        if (poolInMap.containsKey(virtualSlabNo)) {
            PmSlabPoolIn pmSlabPoolIn = poolInMap.get(virtualSlabNo);
            PmSlabPreCastingDTO castingDTO = new PmSlabPreCastingDTO();
            castingDTO.setMatNo(pmSlabPoolIn.getVirtualSlabNo());
            if (Constants.OrderTypeCode.QBP.equals(pmSlabPoolIn.getOrderTypeCode())) {
                castingDTO.setPpFlag(3);
            } else if (Constants.OrderTypeCode.YZA.equals(pmSlabPoolIn.getOrderTypeCode())) {
                castingDTO.setPpFlag(4);
            } else {
                throw new CommonException("pm.slab_pool_in_005",pmSlabPoolIn.getVirtualSlabNo(), pmSlabPoolIn.getOrderTypeCode() );
            }
            castingDTO.setOrdFlag("1");
            castingDTO.setPdMatStatus(null);
            castingDTO.setCsPrecPlanStatus("08");
            castingDTO.setProcCd("14A");
            castingDTO.setWholeBacklogCode("14");
            castingDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
            return castingDTO;
        } else {
            throw new CommonException("pm.slab_pool_in_006", virtualSlabNo);
        }
    }

    private List<PmSlabPreCastingDTO> buildRecoverCastEventDTO(String virtualSlabNo, PmSlabEstaPlan pmSlabEstaPlan,
                                                               Map<String, List<PmSmallPltPos>> pmSmallPltPosMap,
                                                               Map<String, String> pmPdCcSlabMap) {
        List<PmSlabPreCastingDTO> resList = new ArrayList<>();
        PmSlabPreCastingDTO castingDTO = new PmSlabPreCastingDTO();
        castingDTO.setMatNo(virtualSlabNo);
        /*if (Constants.CcType.TYPE_5.equals(pmPdCcSlabMap.get(virtualSlabNo))) {
            castingDTO.setPpFlag(0);
        } else {
            castingDTO.setPpFlag(8);
        }*/
        castingDTO.setPpFlag(0);
        castingDTO.setOrdFlag("1");
        castingDTO.setPdMatStatus("24");
        castingDTO.setCsPrecPlanStatus("08");
        castingDTO.setProcCd("14A");
        castingDTO.setWholeBacklogCode("14");
        castingDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
        resList.add(castingDTO);

        // 大板信息
        PmSlabPreCastingDTO preCastingDTO = new PmSlabPreCastingDTO();
        preCastingDTO.setMatNo(virtualSlabNo);
        preCastingDTO.setPpFlag(1);
        preCastingDTO.setOrdFlag("1");
        preCastingDTO.setPdMatStatus("24");
        preCastingDTO.setCsPrecPlanStatus("08");
        preCastingDTO.setProcCd("14A");
        preCastingDTO.setWholeBacklogCode("14");
        preCastingDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
        resList.add(preCastingDTO);

        // 子板信息
        if (!pmSmallPltPosMap.containsKey(virtualSlabNo)) {
            throw new CommonException("pm.small_plt_pos", virtualSlabNo);
        }
        List<PmSmallPltPos> pmSmallPltPos = pmSmallPltPosMap.get(virtualSlabNo);
        for (PmSmallPltPos pmSmallPltPo : pmSmallPltPos) {
            PmSlabPreCastingDTO slabPreCastingDTO = new PmSlabPreCastingDTO();
            slabPreCastingDTO.setMoMatNo(pmSmallPltPo.getPdMatNo());
            slabPreCastingDTO.setMatNo(pmSmallPltPo.getPdMatNo() + pmSmallPltPo.getSmallPlateDivNo());
            slabPreCastingDTO.setPpFlag(2);
            slabPreCastingDTO.setOrdFlag("1");
            slabPreCastingDTO.setPdMatStatus("24");
            slabPreCastingDTO.setCsPrecPlanStatus("08");
            slabPreCastingDTO.setProcCd("14A");
            slabPreCastingDTO.setWholeBacklogCode("14");
            slabPreCastingDTO.setPonoSlab(pmSlabEstaPlan.getPrecSlabNo());
            resList.add(slabPreCastingDTO);
        }
        return resList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @GlobalTransactional(rollbackFor = Exception.class)
    public void dissolution(PmSlabEstaPlanDissoDTO dto, Long tenantId, boolean flag) {
        // 2.	根据预定CAST_LOT号以及预定制造命令号（PREC_PONO）查询【组炉编制表（PM_SLAB_ESTA_PLAN）】信息，
        List<PmSlabEstaPlan> pmSlabEstaPlanList = pmSlabEstaPlanRepository.selectByCondition(Condition.builder(PmSlabEstaPlan.class)
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmSlabEstaPlan.FIELD_PREC_CAST_LOT_NO, dto.getPrecCastLotNoList()))
                .andWhere(Sqls.custom().andIn(PmSlabEstaPlan.FIELD_PREC_PONO, dto.getPrePonoList()))
                .build());
        if (CollectionUtils.isEmpty(pmSlabEstaPlanList)) {
            throw new CommonException("pm.slab_esta_plan_005",dto.getPrecCastLotNoList(),dto.getPrePonoList());
        }

        // 校验是否已经命令提交
        if (flag) {
            Optional<PmSlabEstaPlan> first = pmSlabEstaPlanList.stream()
                    .filter(item -> Constants.CsPrecPlanStatus.STATUS_09.equals(item.getCsPrecPlanStatus())).findFirst();
            if (first.isPresent()) {
                throw new CommonException("pm.slab_esta_plan_009",first.get().getPrecPono());
            }
        }

        List<String> tmpEstaSlabNoList = new ArrayList<>(pmSlabEstaPlanList.size());
        List<String> precSlabNoList = new ArrayList<>(pmSlabEstaPlanList.size());
        Map<String, List<PmSlabEstaPlan>> slabEstaPlanMap = new HashMap<>(pmSlabEstaPlanList.size());
        for (PmSlabEstaPlan estaPlan : pmSlabEstaPlanList) {
            tmpEstaSlabNoList.add(estaPlan.getTmpSlabNo());
            precSlabNoList.add(estaPlan.getPrecSlabNo());
            if (!slabEstaPlanMap.containsKey(estaPlan.getPrecPono())) {
                slabEstaPlanMap.put(estaPlan.getPrecPono(), new ArrayList<>());
            }
            slabEstaPlanMap.get(estaPlan.getPrecPono()).add(estaPlan);
        }

        List<PmPdCcSlab> tmpPmPdccSlabList =  pmPdCcSlabRepository.selectByTmpSlabNoList(tmpEstaSlabNoList, tenantId);
        Map<String, String> tmpPmPdccSlabMap =  tmpPmPdccSlabList.stream().collect(Collectors.toMap(PmPdCcSlab::getTmpSlabNo, PmPdCcSlab::getMatDesignKind));

        // 并将查询出来的信息备份到【组炉编制历史表（HPM_SLAB_ESTA_PLAN）】中；
        List<PmSlabEstaPlanHis> pmSlabEstaPlanHisList = new ArrayList<>();
        for (PmSlabEstaPlan pmSlabEstaPlan : pmSlabEstaPlanList) {
            PmSlabEstaPlanHis pmSlabEstaPlanHis = new PmSlabEstaPlanHis();
            BeanUtils.copy(pmSlabEstaPlan, pmSlabEstaPlanHis);
            pmSlabEstaPlanHisList.add(pmSlabEstaPlanHis);
        }

        // 获取炉重信息表数据
        List<PmPonoWtInfo> pmPonoWtInfoList =  pmPonoWtInfoRepository.selectByPrecCastAndPonoList(dto.getPrecCastLotNoList(), dto.getPrePonoList(), tenantId);

        // 3.1	如果当前板坯不是无委板坯
        List<String> orderVirtualNoList = pmSlabEstaPlanList.stream().filter(item -> StringUtils.isNotEmpty(item.getOrderNo()))
                .filter(item -> !Utils.isMergeSlab(item.getVirtualSlabNo())).map(PmSlabEstaPlan::getVirtualSlabNo).collect(Collectors.toList());
        // 获取合并板坯的虚拟板坯号
        List<String> merVirSlabList = pmSlabEstaPlanList.stream().filter(item -> StringUtils.isNotEmpty(item.getOrderNo()))
                .map(PmSlabEstaPlan::getVirtualSlabNo).filter(item -> Utils.isMergeSlab(item)).collect(Collectors.toList());
        List<PmSlabMerge> pmSlabMergeList = new ArrayList<>(merVirSlabList.size());
        Map<String, List<PmSlabMerge>> mergeSlabMap = new HashMap<>(merVirSlabList.size());
        if (CollectionUtils.isNotEmpty(merVirSlabList)) {
            pmSlabMergeList.addAll(pmSlabMergeRepository.selectByMergeSlabNoList(merVirSlabList, tenantId));
            if (CollectionUtils.isEmpty(pmSlabMergeList)) {
                throw new CommonException("pm.slab_merge_002",merVirSlabList.get(0));
            }
            mergeSlabMap = pmSlabMergeList.stream().collect(Collectors.groupingBy(PmSlabMerge::getMergeSlabNo));
            orderVirtualNoList.addAll( pmSlabMergeList.stream().map(PmSlabMerge::getVirtualSlabNo).collect(Collectors.toList()));
            precSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getPrecSlabNo).collect(Collectors.toList()));
        }

        // a)	根据虚拟板坯号查询【组炉收池表（PM_SLAB_POOL_IN）】信息，并将查询出来的信息备份到【组炉收池历史表（PM_SLAB_POOL_IN）】中；
        List<PmSlabPoolIn> pmSlabPoolInList = pmSlabPoolInRepository.selectByVirtualSlabNoList(orderVirtualNoList, tenantId);
        List<PmSlabPoolInHis> pmSlabPoolInHisList = new ArrayList<>();
        for (PmSlabPoolIn pmSlabPoolIn : pmSlabPoolInList) {
            PmSlabPoolInHis pmSlabPoolInHis = new PmSlabPoolInHis();
            BeanUtils.copy(pmSlabPoolIn, pmSlabPoolInHis);
            pmSlabPoolInHisList.add(pmSlabPoolInHis);
        }

        // b) 判断当前板坯是组板板坯还是外供板坯（备坯）
        List<PmPdCcSlab> pmPdCcSlabList = pmPdCcSlabRepository.selectByVirtualSlabList(orderVirtualNoList, tenantId);

        // 查询子板数据
        List<PmSmallPltPos> pmSmallPltPosList =  pmSmallPltPosRepository.selectByPdMatNoList(orderVirtualNoList, tenantId);
        Map<String, List<PmSmallPltPos>> pmSmallPltPosMap = pmSmallPltPosList.stream().collect(Collectors.groupingBy(PmSmallPltPos::getPdMatNo));

        // 如果是组板板坯
        List<String> slabVirtualNoList = new ArrayList<>(pmPdCcSlabList.size());
        Map<String , String> mscLineNoMap = new HashMap<>(pmPdCcSlabList.size());
        Map<String, String> pmPdCcSlabMap = new HashMap<>(pmPdCcSlabList.size());
        List<PmPdContSum> pmPdContSumList = new ArrayList<>(pmPdCcSlabList.size());
        List<PmCmdSlab> pmCmdSlabList = new ArrayList<>(pmPdCcSlabList.size());
        List<PmCmdLargePlt> pmCmdLargePltList = new ArrayList<>(pmPdCcSlabList.size());
        List<PmCmdCont> pmCmdContList = new ArrayList<>(pmPdCcSlabList.size());
        List<PmCmdSmallPlt> pmCmdSmallPltList = new ArrayList<>(pmPdCcSlabList.size());
        List<PmPdPlateCut> pmPdPlateCutList = new ArrayList<>(pmPdCcSlabList.size());
        List<PmPdBlockPos> pmPdBlockPosList = new ArrayList<>(pmPdCcSlabList.size());
        List<PmSmallPltPos> smallPltPosList = new ArrayList<>(pmPdCcSlabList.size());
        if (CollectionUtils.isNotEmpty(pmPdCcSlabList)) {
            // 1.根据临时命令板坯号（TMP_SLAB_NO）依次删除四大命令表
            List<String>  virtualNoList = pmPdCcSlabList.stream().map(PmPdCcSlab::getVirtualSlabNo).collect(Collectors.toList());
            slabVirtualNoList.addAll(virtualNoList);
            mscLineNoMap = pmPdCcSlabList.stream().collect(Collectors.toMap(PmPdCcSlab::getVirtualSlabNo, PmPdCcSlab::getMscLineNo));
            pmPdCcSlabMap = pmPdCcSlabList.stream().collect(Collectors.toMap(PmPdCcSlab::getVirtualSlabNo, PmPdCcSlab::getCcType));
            List<String> tmpSlabNoList = pmSlabEstaPlanList.stream().filter(item -> virtualNoList.contains(item.getVirtualSlabNo()))
                    .map(PmSlabEstaPlan::getTmpSlabNo).collect(Collectors.toList());
            // 获取合并板坯的临时命令板坯号
            if (CollectionUtils.isNotEmpty(pmSlabMergeList)) {
                tmpSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getTmpSlabNo).collect(Collectors.toList()));
                tmpSlabNoList.addAll(pmSlabMergeList.stream().map(PmSlabMerge::getTmpPonoSlabNo).collect(Collectors.toList()));
            }
            // 【命令板坯表】
             pmCmdSlabList.addAll(pmCmdSlabRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId));

            // 【命令大板表（PM_CMD_LARGE_PLT）】
            pmCmdLargePltList.addAll(pmCmdLargePltRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId));

            // 【命令参数表（PM_CMD_CONT）】
            pmCmdContList.addAll(pmCmdContRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId));

            // 【命令小板表（PM_CMD_SMALL_PLT）】
            pmCmdSmallPltList.addAll(pmCmdSmallPltRepository.selectByTmpSlabNoList(tmpSlabNoList, tenantId));

            // 2.	若用户点击的是【解散到组矩】按钮，则
            if (dto.getIsBoard().equals(BaseConstants.FlagChar.NO)) {
                // a)	根据虚拟板坯号更新【组板连铸板坯表（PM_PD_CC_SLAB）】中的厚板组板状态（PD_STATUS_HP）为“12”状态（组板完成状态）；
                pmPdCcSlabList.forEach(item -> item.setPdStatusHp(Constants.PdStatusHp.PD_STATUS_HP_12));
                pmPdCcSlabRepository.batchUpdateByPrimaryKey(pmPdCcSlabList);

            } else {
                // 【大板粗切位置表（PM_PD_PLATE_CUT）】
                pmPdPlateCutList.addAll(pmPdPlateCutRepository.selectByPdMatNoList(virtualNoList, tenantId));

                // 【组合子板位置表（PM_PD_BLOCK_POS）】
                pmPdBlockPosList.addAll(pmPdBlockPosRepository.selectByPdMatNoList(virtualNoList, tenantId));

                // 【组板合同总量表（PM_PD_CONT_SUM）】
                pmPdContSumList.addAll(pmPdContSumRepository.selectByPdMatNoList(tenantId, virtualNoList));

                // 【组板小板位置表（PM_SMALL_PLT_POS）】
                smallPltPosList.addAll(pmSmallPltPosRepository.selectByPdMatNoList(virtualNoList, tenantId));
                pmPdCcSlabRepository.batchDeleteByPrimaryKey(pmPdCcSlabList);
            }
        }

        // 删除大板粗切位置表
        pmPdPlateCutList.addAll(pmPdPlateCutRepository.selectByPdMatNoList(precSlabNoList, tenantId));

        // d)	接着根据虚拟板坯号删除【组炉收池表（PM_SLAB_POOL_IN）】对应记录信息；
        Map<String, PmSlabPoolIn> poolInMap = pmSlabPoolInList.stream().collect(Collectors.toMap(PmSlabPoolIn::getVirtualSlabNo, Function.identity()));
        pmSlabPoolInRepository.batchDeleteByPrimaryKey(pmSlabPoolInList);
        pmSlabEstaPlanHisRepository.batchInsertSelective(pmSlabEstaPlanHisList);
        pmSlabMergeRepository.batchDeleteByPrimaryKey(pmSlabMergeList);
        pmSlabPoolInHisRepository.batchInsertSelective(pmSlabPoolInHisList);
        pmSlabEstaPlanRepository.batchDeleteByPrimaryKey(pmSlabEstaPlanList);
        pmPonoWtInfoRepository.batchDeleteByPrimaryKey(pmPonoWtInfoList);
        pmPdPlateCutRepository.batchDeleteByPrimaryKey(pmPdPlateCutList);
        pmCmdSlabRepository.batchDeleteByPrimaryKey(pmCmdSlabList);
        pmCmdLargePltRepository.batchDeleteByPrimaryKey(pmCmdLargePltList);
        pmCmdContRepository.batchDeleteByPrimaryKey(pmCmdContList);
        pmCmdSmallPltRepository.batchDeleteByPrimaryKey(pmCmdSmallPltList);
        pmPdBlockPosRepository.batchDeleteByPrimaryKey(pmPdBlockPosList);
        pmPdContSumRepository.batchDeleteByPrimaryKey(pmPdContSumList);
        pmSmallPltPosRepository.batchDeleteByPrimaryKey(smallPltPosList);

        // 预定CAST_LOT号查询【组炉编制表（PM_SLAB_ESTA_PLAN）】信息，若记录数不为0，
        List<PmSlabEstaPlan> slabEstaPlanList =  pmSlabEstaPlanRepository.selectByPreCastLotNoList(tenantId, dto.getPrecCastLotNoList());
        if (CollectionUtils.isNotEmpty(slabEstaPlanList)) {
            // 更新【组炉编制表（PM_SLAB_ESTA_PLAN）】中的浇次分割号（CAST_LOT_DIV_NO），使浇次分割号（CAST_LOT_DIV_NO）保持连续
            List<PmSlabEstaPlan> sortedSlabEstaPlanList = new ArrayList<>();
            Map<String, List<PmSlabEstaPlan>> estaPlanMap = slabEstaPlanList.stream()
                    .collect(Collectors.groupingBy(PmSlabEstaPlan::getPrecCastLotNo));
            for (Map.Entry<String, List<PmSlabEstaPlan>> entry : estaPlanMap.entrySet()) {
                List<PmSlabEstaPlan> sortSlabEstaPlanList = entry.getValue().stream().sorted(Comparator.comparing(PmSlabEstaPlan::getCastLotDivNo))
                        .collect(Collectors.toList());
                // 炉数
                long count = sortSlabEstaPlanList.stream().map(PmSlabEstaPlan::getPrecPono).distinct().count();
                long divNo = 1L;
                for (PmSlabEstaPlan slabEstaPlan : sortSlabEstaPlanList) {
                    slabEstaPlan.setCastLotDivNo(divNo++);
                    slabEstaPlan.setCcNum(count);
                    sortedSlabEstaPlanList.add(slabEstaPlan);
                }
            }
            pmSlabEstaPlanRepository.batchUpdateByPrimaryKey(sortedSlabEstaPlanList);
        }

        // 将预定制造命令号（PREC_PONO）作为入参，调用质量接口，通知质量模块，该炉已解散；一炉炉的发送
        for (Map.Entry<String, List<PmSlabEstaPlan>> entry : slabEstaPlanMap.entrySet()) {
            List<ProdPonoSlabRequestDTO> ponoSlabRequestDTOList = new ArrayList<>();
            for (PmSlabEstaPlan pmSlabEstaPlan : entry.getValue()) {
                if (tmpPmPdccSlabMap.containsKey(pmSlabEstaPlan.getTmpSlabNo())) {
                    ProdPonoSlabRequestDTO ponoSlabRequestDTO = new ProdPonoSlabRequestDTO();
                    ponoSlabRequestDTO.setTmpSlabNo(pmSlabEstaPlan.getTmpSlabNo());
                    ponoSlabRequestDTO.setMatDesignKind(tmpPmPdccSlabMap.get(pmSlabEstaPlan.getTmpSlabNo()));
                    ponoSlabRequestDTOList.add(ponoSlabRequestDTO);
                }
            }
            if (CollectionUtils.isNotEmpty(ponoSlabRequestDTOList)) {
                log.info("解散到组矩、组板调用【sampleGensRemove】，入参为={}", JSON.toJSONString(ponoSlabRequestDTOList));
                qeApiClient.sampleGensRemove(tenantId, ponoSlabRequestDTOList);
            }
        }

        // 解散到组矩
        if (dto.getIsBoard().equals(BaseConstants.FlagChar.NO)) {
            // 如果非外卖坯和备坯，调用合同跟踪模块“解散到组距事件”接口，向合同跟踪抛帐
            List<PmMaterialCommandDTO> resList = new ArrayList<>();
            for (PmPdCcSlab pmPdCcSlab : pmPdCcSlabList) {
                // 虚拟板坯
                PmMaterialCommandDTO castingDTO = new PmMaterialCommandDTO();
                castingDTO.setMatNo(pmPdCcSlab.getVirtualSlabNo());
                /*if (Constants.CcType.TYPE_5.equals(pmPdCcSlab.getVirtualSlabNo())) {
                    castingDTO.setPpFlag(8);
                } else {
                    castingDTO.setPpFlag(0);
                }*/
                castingDTO.setPpFlag(0);
                castingDTO.setOrdFlag("1");
                castingDTO.setPdMatStatus("12");
                castingDTO.setProcCd("14A");
                castingDTO.setWholeBacklogCode("14");
                resList.add(castingDTO);

                // 大板信息
                PmMaterialCommandDTO preCastingDTO = new PmMaterialCommandDTO();
                preCastingDTO.setMatNo(pmPdCcSlab.getVirtualSlabNo());
                preCastingDTO.setPpFlag(1);
                preCastingDTO.setOrdFlag("1");
                preCastingDTO.setPdMatStatus("12");
                preCastingDTO.setProcCd("14A");
                preCastingDTO.setWholeBacklogCode("14");
                resList.add(preCastingDTO);

                // 子板信息
                if (!pmSmallPltPosMap.containsKey(pmPdCcSlab.getVirtualSlabNo())) {
                    throw new CommonException("pm.small_plt_pos", pmPdCcSlab.getVirtualSlabNo());
                }
                List<PmSmallPltPos> pmSmallPltPos = pmSmallPltPosMap.get(pmPdCcSlab.getVirtualSlabNo());
                for (PmSmallPltPos pmSmallPltPo : pmSmallPltPos) {
                    PmMaterialCommandDTO slabPreCastingDTO = new PmMaterialCommandDTO();
                    slabPreCastingDTO.setMoMatNo(pmSmallPltPo.getPdMatNo());
                    slabPreCastingDTO.setMatNo(pmSmallPltPo.getPdMatNo() + pmSmallPltPo.getSmallPlateDivNo());
                    slabPreCastingDTO.setPpFlag(2);
                    slabPreCastingDTO.setOrdFlag("1");
                    slabPreCastingDTO.setPdMatStatus("12");
                    slabPreCastingDTO.setProcCd("14A");
                    slabPreCastingDTO.setWholeBacklogCode("14");
                    resList.add(slabPreCastingDTO);
                }
            }
            log.info("<=====调用解散到组距事件，入参为{}=====>", JSON.toJSONString(resList));
            eventClient.sendEventWithOutResponse(tenantId, CtEventConstants.EVENT_PM_DISSOLVE_GROUP_DISTANCE, resList);

        } else {
            // 调用组板履历“连铸出钢材组板删除事件”接口，根据虚拟板坯号，从组板合同总量表调用组板履历函数，抛组板履历事件-外卖坯合备坯不抛
            if (CollectionUtils.isNotEmpty(pmPdContSumList)) {
                Map<String, List<PmPdContSum>> contSumMap = pmPdContSumList.stream().collect(Collectors.groupingBy(PmPdContSum::getPdMatNo));
                PdMatTypeStrategy pdMatTypeStrategy = PdMatTypeStrategyFactory.matchStrategy(PdMatType.C);
                for (Map.Entry<String, List<PmPdContSum>> entry : contSumMap.entrySet()) {
                    pdMatTypeStrategy.pdDeleteEvent(entry.getValue(), entry.getKey()
                            , mscLineNoMap.get(entry.getKey()), Constants.PdProgram.CC_SLAB_DETAIL_DELETE_PROGRAM, tenantId);
                }
            }

            // 将虚拟板坯号（VIRTUAL_SLAB_NO）作为入参，调用合同跟踪模块“解散到组板事件”接口；
            List<PmDissolveGroupBoardDTO> resList = new ArrayList<>();
            // 虚拟板坯或者备坯
            for (PmSlabEstaPlan pmSlabEstaPlan : pmSlabEstaPlanList) {
                // 虚拟板坯 -合并板坯
                 if (Utils.isMergeSlab(pmSlabEstaPlan.getVirtualSlabNo())) {
                     List<PmSlabMerge> slabMergeList = mergeSlabMap.get(pmSlabEstaPlan.getVirtualSlabNo());
                     for (PmSlabMerge pmSlabMerge : slabMergeList) {
                         // 无委坯
                         if (pmSlabMerge.getVirtualSlabNo().startsWith("W")) {
                             PmDissolveGroupBoardDTO boardDTO = new PmDissolveGroupBoardDTO();
                             boardDTO.setMatNo(pmSlabEstaPlan.getVirtualSlabNo());
                             boardDTO.setPpFlag(0);
//                             boardDTO.setOrdFlag("2");
                             boardDTO.setEnableFlag("0");
                             resList.add(boardDTO);
                             continue;
                         }
                         // 外卖坯、备坯
                         if (Constants.CcType.TYPE_2.equals(pmSlabEstaPlan.getCcType()) ||
                                 Constants.CcType.TYPE_4.equals(pmSlabEstaPlan.getCcType())) {
                             PmDissolveGroupBoardDTO castingDTO = buildDissolutionDelivery(pmSlabEstaPlan, pmSlabMerge.getVirtualSlabNo(),poolInMap);
                             resList.add(castingDTO);
                             // 板坯
                         }else if (pmPdCcSlabMap.containsKey(pmSlabMerge.getVirtualSlabNo())) {
                             List<PmDissolveGroupBoardDTO> dissGroupEventList = buildDissCastEventDTO(pmSlabMerge.getVirtualSlabNo(), pmSlabEstaPlan,
                                     pmSmallPltPosMap, pmPdCcSlabMap);
                             resList.addAll(dissGroupEventList);
                         }else {
                             throw new CommonException("pm.slab_esta_plan_004", pmSlabMerge.getVirtualSlabNo());
                         }
                     }

                 }else {
                     // 无委坯
                     if (pmSlabEstaPlan.getVirtualSlabNo().startsWith("W")) {
                         PmDissolveGroupBoardDTO boardDTO = new PmDissolveGroupBoardDTO();
                         boardDTO.setMatNo(pmSlabEstaPlan.getVirtualSlabNo());
                         boardDTO.setPpFlag(0);
//                         boardDTO.setOrdFlag("2");
                         boardDTO.setEnableFlag("0");
                         resList.add(boardDTO);
                         continue;
                     }
                     // 板坯
                     if (pmPdCcSlabMap.containsKey(pmSlabEstaPlan.getVirtualSlabNo())) {
                         List<PmDissolveGroupBoardDTO> dissGroupEventList = buildDissCastEventDTO(pmSlabEstaPlan.getVirtualSlabNo(), pmSlabEstaPlan,
                                 pmSmallPltPosMap, pmPdCcSlabMap);
                         resList.addAll(dissGroupEventList);
                     } else {
                         // 外卖坯或者备坯
                         PmDissolveGroupBoardDTO castingDTO = buildDissolutionDelivery(pmSlabEstaPlan, pmSlabEstaPlan.getVirtualSlabNo(),poolInMap);
                         resList.add(castingDTO);
                     }
                 }
            }

            log.info("<=====调用解散到组板事件，入参为{}=====>", JSON.toJSONString(resList));
            eventClient.sendEventWithOutResponse(tenantId, CtEventConstants.EVENT_PM_DISSOLVE_GROUP_BOARD, resList);
        }
    }

    private PmDissolveGroupBoardDTO buildDissolutionDelivery(PmSlabEstaPlan pmSlabEstaPlan, String virtualSlabNo, Map<String, PmSlabPoolIn> poolInMap) {
        if (poolInMap.containsKey(virtualSlabNo)) {
            PmSlabPoolIn pmSlabPoolIn = poolInMap.get(virtualSlabNo);
            PmDissolveGroupBoardDTO castingDTO = new PmDissolveGroupBoardDTO();
            castingDTO.setMatNo(pmSlabPoolIn.getVirtualSlabNo());
            if (Constants.OrderTypeCode.QBP.equals(pmSlabPoolIn.getOrderTypeCode())) {
                castingDTO.setPpFlag(3);
            } else if (Constants.OrderTypeCode.YZA.equals(pmSlabPoolIn.getOrderTypeCode())) {
                castingDTO.setPpFlag(4);
            } else {
                throw new CommonException("pm.slab_pool_in_005",pmSlabPoolIn.getVirtualSlabNo(), pmSlabPoolIn.getOrderTypeCode() );
            }
//            castingDTO.setOrdFlag("1");
            castingDTO.setEnableFlag("0");
            return castingDTO;
        } else {
            throw new CommonException("pm.slab_pool_in_006", virtualSlabNo);
        }
    }

    private List<PmDissolveGroupBoardDTO> buildDissCastEventDTO(String virtualSlabNo, PmSlabEstaPlan pmSlabEstaPlan,
                                                                Map<String, List<PmSmallPltPos>> pmSmallPltPosMap,
                                                                Map<String, String> pmPdCcSlabMap) {
        List<PmDissolveGroupBoardDTO> resList = new ArrayList<>();
        PmDissolveGroupBoardDTO boardDTO = new PmDissolveGroupBoardDTO();
        boardDTO.setMatNo(virtualSlabNo);
        /*if (Constants.CcType.TYPE_5.equals(pmPdCcSlabMap.get(virtualSlabNo))) {
            boardDTO.setPpFlag(8);
        } else {
            boardDTO.setPpFlag(0);
        }*/
        boardDTO.setPpFlag(0);
//        boardDTO.setOrdFlag("1");
        boardDTO.setEnableFlag("0");
        resList.add(boardDTO);

        // 大板信息
        PmDissolveGroupBoardDTO boardDTO1 = new PmDissolveGroupBoardDTO();
        boardDTO1.setMatNo(virtualSlabNo);
        boardDTO1.setPpFlag(1);
//        boardDTO1.setOrdFlag("1");
        boardDTO1.setEnableFlag("0");
        resList.add(boardDTO1);

        // 子板信息
        if (!pmSmallPltPosMap.containsKey(virtualSlabNo)) {
            throw new CommonException("pm.small_plt_pos", virtualSlabNo);
        }
        List<PmSmallPltPos> pmSmallPltPos = pmSmallPltPosMap.get(virtualSlabNo);
        for (PmSmallPltPos pmSmallPltPo : pmSmallPltPos) {
            PmDissolveGroupBoardDTO boardDTO2 = new PmDissolveGroupBoardDTO();
//            boardDTO2.setMoMatNo(pmSmallPltPo.getPdMatNo());
            boardDTO2.setMatNo(pmSmallPltPo.getPdMatNo() + pmSmallPltPo.getSmallPlateDivNo());
            boardDTO2.setPpFlag(2);
//            boardDTO2.setOrdFlag("1");
            boardDTO2.setEnableFlag("0");
            resList.add(boardDTO2);
        }
        return resList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @GlobalTransactional(rollbackFor = Exception.class)
    public void complete(List<String> precCastLotNoList, Long tenantId) {
        // 1.	根据预定castLotNo查询【组炉编制表（PM_SLAB_ESTA_PLAN）】中信息，获取预定CAST_LOT号
        List<PmSlabEstaPlan> pmSlabEstaPlanList = pmSlabEstaPlanRepository.selectByCondition(Condition.builder(PmSlabEstaPlan.class)
                .andWhere(Sqls.custom().andEqualTo(PmSlabEstaPlan.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmSlabEstaPlan.FIELD_PREC_CAST_LOT_NO, precCastLotNoList))
                .build());
        if (CollectionUtils.isEmpty(pmSlabEstaPlanList)) {
            throw new CommonException("pm.slab_esta_plan_001", precCastLotNoList);
        }

        // 获取未进行组炉完成的其他炉数据
         List<PmSlabEstaPlan> filterPmSlabEstaPlanList = pmSlabEstaPlanList.stream()
                .filter(item -> Constants.CsPrecPlanStatus.STATUS_02.equals(item.getCsPrecPlanStatus())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(filterPmSlabEstaPlanList)) {
            throw new CommonException("pm.slab_esta_plan_011", precCastLotNoList);
        }

        Optional<PmSlabEstaPlan> planOptionalPlan = pmSlabEstaPlanList.stream()
                .filter(item -> (Constants.CcType.TYPE_2.equals(item.getCcType()) || Constants.CcType.TYPE_4.equals(item.getCcType()))).findFirst();
        if (planOptionalPlan.isPresent()) {
            throw new CommonException("pm.slab_esta_plan_015", planOptionalPlan.get().getPrecCastLotNo());
        }

        // 执行组炉完成二次设计等操作
        pmSlabPoolInService.excuteSecondaryDesign(filterPmSlabEstaPlanList, tenantId);
    }

    @Transactional(rollbackFor = Exception.class)
    public List<PmSlabPreCastingDTO> commandAbandonContract(List<PmSlabEstaPlan> pmSlabEstaPlanList, Map<String, List<PmSlabMerge>> mergePmSlabMap,
                                       Map<String, String> pmcCcSlabMap, Map<String, List<PmSmallPltPos>> pmSmallPltPosMap,
                                       Map<String, PmSlabPoolIn> poolInMap, String pdMatStatus,
                                       String csPrecPlanStatus, String procCd, String wholeBacklogCode) {
        List<PmSlabPreCastingDTO> resList = new ArrayList<>();
        for (PmSlabEstaPlan pmSlabEstaPlan : pmSlabEstaPlanList) {
            // 虚拟板坯 -合并板坯 且不是外卖坯
            if (Utils.isMergeSlab(pmSlabEstaPlan.getVirtualSlabNo())) {
                List<PmSlabMerge> pmSlabMergeList = mergePmSlabMap.get(pmSlabEstaPlan.getVirtualSlabNo());
                // 遍历
                for (PmSlabMerge pmSlabMerge : pmSlabMergeList) {
                    // 无委坯
                    if (pmSlabMerge.getVirtualSlabNo().startsWith("W")) {
                        PmSlabPreCastingDTO castingDTO =  buildNoOrderCastingDTO(pmSlabMerge.getVirtualSlabNo(), pmSlabEstaPlan.getPrecSlabNo(),
                                0, "2", pdMatStatus, csPrecPlanStatus, procCd, wholeBacklogCode, pmSlabMerge.getPrecSlabNo());
                        resList.add(castingDTO);
                        continue;
                    }
                    // 组装板坯大板和子板信息
                    // 外卖坯、备坯
                    if (Constants.CcType.TYPE_2.equals(pmSlabEstaPlan.getCcType()) ||
                            Constants.CcType.TYPE_4.equals(pmSlabEstaPlan.getCcType())) {
                        PmSlabPreCastingDTO castingDTO = buildDeliveryCastingDTO(pmSlabEstaPlan,pmSlabMerge.getVirtualSlabNo(), poolInMap, pdMatStatus, csPrecPlanStatus, procCd, wholeBacklogCode, pmSlabMerge.getPrecSlabNo());
                        resList.add(castingDTO);
                    }else if (pmcCcSlabMap.containsKey(pmSlabMerge.getVirtualSlabNo())) {
                        List<PmSlabPreCastingDTO> castEventDataList = buildPreCastEventData(pmSlabMerge.getVirtualSlabNo(), pmSlabEstaPlan,
                                pmcCcSlabMap, pmSmallPltPosMap,  pdMatStatus, csPrecPlanStatus, procCd, wholeBacklogCode, pmSlabMerge.getPrecSlabNo());
                        resList.addAll(castEventDataList);
                    }else {
                        throw new CommonException("pm.slab_esta_plan_004", pmSlabMerge.getVirtualSlabNo());
                    }
                }
            } else {
                // 无委坯
                if (pmSlabEstaPlan.getVirtualSlabNo().startsWith("W")) {
                    PmSlabPreCastingDTO castingDTO =  buildNoOrderCastingDTO(pmSlabEstaPlan.getVirtualSlabNo(), pmSlabEstaPlan.getPrecSlabNo(),
                            0, "2", pdMatStatus, csPrecPlanStatus, procCd, wholeBacklogCode, null);
                    resList.add(castingDTO);
                    continue;
                }
                // 虚拟板坯
                if (pmcCcSlabMap.containsKey(pmSlabEstaPlan.getVirtualSlabNo())) {
                    List<PmSlabPreCastingDTO> castEventDataList = buildPreCastEventData(pmSlabEstaPlan.getVirtualSlabNo(), pmSlabEstaPlan,
                            pmcCcSlabMap, pmSmallPltPosMap,  pdMatStatus, csPrecPlanStatus, procCd, wholeBacklogCode, null);
                    resList.addAll(castEventDataList);
                } else {
                    // 外卖坯或者备坯
                    PmSlabPreCastingDTO castingDTO = buildDeliveryCastingDTO(pmSlabEstaPlan,pmSlabEstaPlan.getVirtualSlabNo(), poolInMap,
                            pdMatStatus, csPrecPlanStatus, procCd, wholeBacklogCode, null);
                    resList.add(castingDTO);
                }
            }
        }
        return resList;
    }
}

