package com.xisc.pm.app.service.strategy.secondarydesign;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.xisc.pm.api.dto.PmProContFilterRequestDTO;
import com.xisc.pm.api.dto.PmProContYieldRequestDTO;
import com.xisc.pm.api.dto.PmProContYieldResposeDTO;
import com.xisc.pm.api.dto.ctevent.PmSlabApplyMakeDTO;
import com.xisc.pm.app.service.strategy.SecondaryDesignHelper;
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.PmContMscTech;
import com.xisc.pm.domain.entity.PmHotConfig;
import com.xisc.pm.domain.entity.PmPdConstBt;
import com.xisc.pm.domain.entity.PmPdContSum;
import com.xisc.pm.domain.entity.PmPdSlab;
import com.xisc.pm.domain.entity.PmPdSlabInfo;
import com.xisc.pm.domain.entity.PmProContProdTtr;
import com.xisc.pm.domain.entity.PmSmallPltPos;
import com.xisc.pm.domain.repository.PmContMscTechRepository;
import com.xisc.pm.domain.repository.PmHotConfigRepository;
import com.xisc.pm.domain.repository.PmPdConstBtRepository;
import com.xisc.pm.domain.repository.PmPdSlabInfoRepository;
import com.xisc.pm.domain.repository.PmPdSlabRepository;
import com.xisc.pm.domain.repository.PmSlabHeatDestRepository;
import com.xisc.pm.domain.vo.EventFeignVO;
import com.xisc.pm.domain.vo.MatStatusModifyVO;
import com.xisc.pm.domain.vo.MmSlabVO;
import com.xisc.pm.domain.vo.PmCmdVO;
import com.xisc.pm.infra.client.EventClient;
import com.xisc.pm.infra.client.MmEventClient;
import com.xisc.pm.infra.constant.Constants;
import com.xisc.pm.infra.constant.CtEventConstants;
import com.xisc.pm.infra.constant.PmPlateConstants;
import com.xisc.pm.infra.enums.PdMatType;
import com.xisc.pm.infra.enums.PdProdFlag;
import com.xisc.pm.infra.enums.PdRuleSetType;
import com.xisc.pm.infra.mapper.WmMatPileMapper;
import com.xisc.pm.infra.util.PlatePreProcUtils;
import com.xisc.pm.infra.util.Utils;
import io.choerodon.core.exception.CommonException;
import io.choerodon.core.oauth.DetailsHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
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.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * (余坯)二次设计
 * 
 * @author jun.zeng
 *
 */
@Slf4j
@Component
public class SlabSecondaryDesignStrategy extends DefaultSecondaryDesignStrategy<PmPdSlab> {

    @Autowired
    private PmPdSlabRepository pmPdSlabRepository;

    @Autowired
    private PmPdSlabInfoRepository pmPdSlabInfoRepository;

    @Autowired
    private PmPdConstBtRepository pmPdConstBtRepository;

    @Autowired
    private WmMatPileMapper wmMatPileMapper;
    
    @Autowired
    private PmHotConfigRepository pmHotConfigRepository;

    @Autowired
    private EventClient eventClient;
    
    @Autowired
    private PmSlabHeatDestRepository pmSlabHeatDestRepository ;
    
    @Autowired
    private PmContMscTechRepository pmContMscTechRepository;

     @Autowired
    private MmEventClient mmEventClient;
    @Override
    protected boolean hasPmCmdSlab() {
        return true;
    }

    @Override
    protected void remove() {
        PM_PD_CONST_LOCAL.remove();
        PM_PD_SLAB_INFO_LOCAL.remove();
        PM_PD_SLAB_INFO_REMAIN_LEN_LOCAL.remove();
        super.remove();
    }

    // 本地变量
    private static final ThreadLocal<Map<String, PmPdSlabInfo>> PM_PD_SLAB_INFO_LOCAL = new ThreadLocal<>();
    // 余坯剩余板坯长
    private static final ThreadLocal<Map<String, BigDecimal>> PM_PD_SLAB_INFO_REMAIN_LEN_LOCAL = new ThreadLocal<>();
    // 组板常量配置表
    private static final ThreadLocal<Map<String, PmPdConstBt>> PM_PD_CONST_LOCAL = new ThreadLocal<>();

    @Override
    protected Map<String, PmPdSlab> selectByMatNo(List<String> virtualSlabNo, Long tenantId) {
        List<PmPdSlab> pmPdSlabs = pmPdSlabRepository.selectByCondition(
                Condition.builder(PmPdSlab.class).andWhere(Sqls.custom().andEqualTo(PmPdSlab.FIELD_TENANT_ID, tenantId)
                        .andIn(PmPdSlab.FIELD_VIRTUAL_SLAB_NO, virtualSlabNo)).build());
        Map<String, PmPdSlab> pmPdSlabMap = Maps.newHashMap();
        Map<String, PmPdSlabInfo> pmPdSlabInfoMap = Maps.newHashMap();
        Map<String, BigDecimal> remainSlabLenMap = Maps.newHashMap();
        Map<String, PmPdConstBt> pmPdConstBtMap = Maps.newHashMap();
        if (pmPdSlabs == null || pmPdSlabs.isEmpty()) {
            PM_PD_SLAB_INFO_LOCAL.set(pmPdSlabInfoMap);
            return pmPdSlabMap;
        }
        List<String> slabNoList = Lists.newArrayList();
        for (PmPdSlab pmPdSlab : pmPdSlabs) {
            pmPdSlabMap.put(pmPdSlab.getVirtualSlabNo(), pmPdSlab);
            slabNoList.add(pmPdSlab.getSlabNo());
        }
        List<PmPdSlabInfo> pmPdSlabInfos = pmPdSlabInfoRepository.selectByCondition(Condition
                .builder(PmPdSlabInfo.class).andWhere(Sqls.custom().andEqualTo(PmPdSlabInfo.FIELD_TENANT_ID, tenantId)
                        .andIn(PmPdSlabInfo.FIELD_SLAB_NO, slabNoList))
                .build());
        List<String> rollLineNoList = Lists.newArrayList();
        if (pmPdSlabInfos != null && !pmPdSlabInfos.isEmpty()) {
            for (PmPdSlabInfo pmPdSlabInfo : pmPdSlabInfos) {
                pmPdSlabInfoMap.put(pmPdSlabInfo.getSlabNo(), pmPdSlabInfo);
                remainSlabLenMap.put(pmPdSlabInfo.getSlabNo(), pmPdSlabInfo.getMatActLen());
                rollLineNoList.add(Utils.mscLineNoToRoolLineNo(pmPdSlabInfo.getMscLineNo()));
            }
        }

        List<PmPdSlab> allPmPdSlabs = pmPdSlabRepository.selectByCondition(Condition.builder(PmPdSlab.class).andWhere(
                Sqls.custom().andEqualTo(PmPdSlab.FIELD_TENANT_ID, tenantId).andIn(PmPdSlab.FIELD_SLAB_NO, slabNoList))
                .build());
        for (PmPdSlab pmPdSlab : allPmPdSlabs) {
            if (!pmPdSlabMap.containsKey(pmPdSlab.getVirtualSlabNo()) && !BaseConstants.Flag.NO.toString().equals(pmPdSlab.getOrderRemainDiv())) {
                // 余坯组版二次设计，必须选中全部分割坯，余坯【{0}】的分割坯【{1}】未选中。
                throw new CommonException("pm.pm_pd_slab_001", pmPdSlab.getSlabNo(), pmPdSlab.getVirtualSlabNo());
            }
        }

        List<PmPdConstBt> pmPdConstBtList = pmPdConstBtRepository.selectByCondition(Condition.builder(PmPdConstBt.class)
                .andWhere(Sqls.custom().andIn(PmPdConstBt.FIELD_ROLL_LINE_NO, rollLineNoList))
                .andWhere(Sqls.custom().andEqualTo(PmPdConstBt.FIELD_TENANT_ID, tenantId)).build());
        if (pmPdConstBtList != null && !pmPdConstBtList.isEmpty()) {
            for (PmPdConstBt pmPdConstBt : pmPdConstBtList) {
                pmPdConstBtMap.put(pmPdConstBt.getRollLineNo(), pmPdConstBt);
            }
        }
        PM_PD_CONST_LOCAL.set(pmPdConstBtMap);
        PM_PD_SLAB_INFO_LOCAL.set(pmPdSlabInfoMap);
        PM_PD_SLAB_INFO_REMAIN_LEN_LOCAL.set(remainSlabLenMap);
        return pmPdSlabMap;
    }
    
    private List<PmCmdLargePlt> selectAlllPmCmdLargePltBySlabNo(List<PmCmdLargePlt> pmCmdLargePltList , Long tenantId) {
        List<String> slabNoList = new ArrayList<>();
        for (PmCmdLargePlt pmCmdLargePlt : pmCmdLargePltList) {
            slabNoList.add(pmCmdLargePlt.getSlabNo());
        }
        List<PmCmdLargePlt> pmCmdLargePlts = pmCmdLargePltRepository.selectByCondition(Condition.builder(PmCmdLargePlt.class)
                .andWhere(Sqls.custom().andIn(PmCmdLargePlt.FIELD_SLAB_NO, slabNoList))
                .andWhere(Sqls.custom().andEqualTo(PmCmdLargePlt.FIELD_TENANT_ID, tenantId)).build());
        return pmCmdLargePlts;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void secondaryDesign(Long tenantId, List<PmCmdLargePlt> pmCmdLargePltList) {
        if (pmCmdLargePltList == null || pmCmdLargePltList.isEmpty()) {
            return;
        }
        List<PmCmdLargePlt> pmCmdLargePlts = selectAlllPmCmdLargePltBySlabNo(pmCmdLargePltList, tenantId);
        // 按小板分割序排序
        pmCmdLargePlts.sort(new Comparator<PmCmdLargePlt>() {
            @Override
            public int compare(PmCmdLargePlt o1, PmCmdLargePlt o2) {
                return o1.getSlabDivNo().compareTo(o2.getSlabDivNo());
            }
        });
        super.secondaryDesign(tenantId, pmCmdLargePlts);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void secondaryDesignRollback(Long tenantId, List<PmCmdLargePlt> pmCmdLargePltList) {
        List<PmCmdLargePlt> pmCmdLargePlts = selectAlllPmCmdLargePltBySlabNo(pmCmdLargePltList, tenantId);
        super.secondaryDesignRollback(tenantId, pmCmdLargePlts);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void commandCreate(Long tenantId, List<PmCmdLargePlt> pmCmdLargePltList) {
        List<PmCmdLargePlt> pmCmdLargePlts = selectAlllPmCmdLargePltBySlabNo(pmCmdLargePltList, tenantId);
        super.commandCreate(tenantId, pmCmdLargePlts);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void generateHeatDest(List<PmCmdLargePlt> pmCmdLargePltDbList,Map<String, PmCmdSlab> pmCmdSlabMap , Map<String, List<PmPdContSum>> pmPdContSumListMap) {
        // 按板坯维度生成热处理去向
        Map<String ,List<PmCmdLargePlt>> cmdLargePltMap = pmCmdLargePltDbList.stream().collect(Collectors.groupingBy(PmCmdLargePlt::getSlabNo));
        
        for (Entry<String, List<PmCmdLargePlt>> entry : cmdLargePltMap.entrySet()) {
            
            String slabNo = entry.getKey();
            String mscLineNo = null;
            Long tenantId = null;
            boolean hasSampleInfo = false ;
            List<String> orderNoList = new ArrayList<>();
            Map<String , PmPdContSum> contSumMap = new HashMap<>();
            for (PmCmdLargePlt pmCmdLargePlt : entry.getValue()) {
                // 同一个板坯号产线号和租户一定相同，任取一条记录即可
                mscLineNo = pmCmdLargePlt.getMscLineNo();
                tenantId = pmCmdLargePlt.getTenantId();
                if(pmCmdLargePlt.getSampleLen() != null && BigDecimal.ZERO.compareTo(pmCmdLargePlt.getSampleLen()) != 0) {
                    hasSampleInfo = true; 
                }
                PmCmdSlab pmCmdSlab = pmCmdSlabMap.get(pmCmdLargePlt.getTmpSlabNo());
                List<PmPdContSum> pmPdContSums = pmPdContSumListMap.get(pmCmdSlab.getVirtualSlabNo());
                for (PmPdContSum pmPdContSum : pmPdContSums) {
                    orderNoList.add(pmPdContSum.getOrderNo());
                    contSumMap.put(pmPdContSum.getOrderNo(), pmPdContSum);
                }
                
            }
            if(hasSampleInfo && orderNoList.size() > 0) {
                List<PmContMscTech> pmContMscTechs = pmContMscTechRepository.selectByOrderNoAndMscLineNo(orderNoList, mscLineNo, tenantId);
                Map<String , String> heatTreatMentModeMap = new HashMap<>(); 
                List<String> heatTreatMentModeList = new ArrayList<>();
                for (PmContMscTech pmContMscTech : pmContMscTechs) {
                    if(StringUtils.isNotBlank(pmContMscTech.getWholeHeatTreatmentType())) {
                        for(int i = 0 ; i < pmContMscTech.getWholeHeatTreatmentType().length() ; i++) {
                            heatTreatMentModeList.add(""+pmContMscTech.getWholeHeatTreatmentType().charAt(i));
                        }
                    }
                }
                List<PmHotConfig> pmHotConfigs = Lists.newArrayList();
                if(hasSampleInfo && !heatTreatMentModeList.isEmpty()) {
                    // 如果板坯存在试样信息且存在需要热处理的合同
                    pmHotConfigs = pmHotConfigRepository.selectByCondition(Condition.builder(PmHotConfig.class)
                            .andWhere(Sqls.custom().andEqualTo(PmHotConfig.FIELD_TENANT_ID, tenantId)
                                    .andEqualTo(PmHotConfig.FIELD_MSC_LINE_NO, mscLineNo)
                                    .andIn(PmHotConfig.FIELD_HEAT_TREAT_MODE, heatTreatMentModeList)).build());
                }
                    
                for (PmContMscTech pmContMscTech : pmContMscTechs) {
                    if(StringUtils.isNotBlank(pmContMscTech.getWholeHeatTreatmentType())) {
                        PmPdContSum pmPdContSum = contSumMap.get(pmContMscTech.getOrderNo());
                        for(int i = 0 ; i < pmContMscTech.getWholeHeatTreatmentType().length() ; i++) {
                            String dest = null;
                            for (PmHotConfig pmHotConfig : pmHotConfigs) {
                                if(pmHotConfig.getHeatTreatMode().equals((pmContMscTech.getWholeHeatTreatmentType().charAt(i)+"")) && 
                                        pmPdContSum.getOrderWidth().compareTo(pmHotConfig.getPlateWidTo()) <= 0 && pmPdContSum.getOrderWidth().compareTo(pmHotConfig.getPlateWidFrom()) >= 0 &&
                                        pmPdContSum.getOrderThick().compareTo(pmHotConfig.getPlateThickTo()) <= 0 && pmPdContSum.getOrderThick().compareTo(pmHotConfig.getPlateThickFrom()) >= 0 &&
                                        pmPdContSum.getOrderLen().compareTo(pmHotConfig.getPlateLenTo()) <= 0 && pmPdContSum.getOrderLen().compareTo(pmHotConfig.getPlateLenFrom()) >= 0) {
                                    dest = pmHotConfig.getDefaultDest();
                                }
                            }
                            if(StringUtils.isBlank(dest)) {
                                // 板坯【{0}】没有获取到默认热处理去向，合同号【{1}】，订货厚度【{2}】，订货宽度【{3}】，订货长度【{4}】，全程热处理类型【{5}】。
                                throw new CommonException("pm.pm_slab_heat_dest_001", slabNo , pmContMscTech.getOrderNo() , pmPdContSum.getOrderThick().toPlainString() 
                                        , pmPdContSum.getOrderWidth().toPlainString() , pmPdContSum.getOrderLen().toPlainString() , pmContMscTech.getWholeHeatTreatmentType());
                            }
                            heatTreatMentModeMap.put(pmContMscTech.getWholeHeatTreatmentType().charAt(i)+"", dest);
                        }
                    }
                }
                pmSlabHeatDestRepository.saveSlabHeatDestBySlab(slabNo, heatTreatMentModeMap, tenantId);
            }
        }
        
    }
    
    @Override
    protected PmProContYieldResposeDTO yiledCalc(PmCmdLargePlt pmCmdLargePlt, PmProContYieldRequestDTO pmProContYield,
            PmProContProdTtr axisPmProContProdTtr) {
        PmProContYieldResposeDTO resposeDTO = super.yiledCalc(pmCmdLargePlt, pmProContYield, axisPmProContProdTtr);
        // 计算完成之后更新剩余板坯长
        BigDecimal remainSlabLen = PM_PD_SLAB_INFO_REMAIN_LEN_LOCAL.get().get(pmCmdLargePlt.getSlabNo());
        PmPdConstBt pmPdConstBt = PM_PD_CONST_LOCAL.get()
                .get(Utils.mscLineNoToRoolLineNo(pmCmdLargePlt.getMscLineNo()));
        BigDecimal preCleanSlabLen = resposeDTO.getPreCleanSlabLen() == null ? BigDecimal.ZERO : resposeDTO.getPreCleanSlabLen();
        remainSlabLen = remainSlabLen.subtract(preCleanSlabLen);
        if (pmPdConstBt != null && pmPdConstBt.getSlabCutGap() != null) {
            remainSlabLen = remainSlabLen.subtract(pmPdConstBt.getSlabCutGap());
        }
        PM_PD_SLAB_INFO_REMAIN_LEN_LOCAL.get().put(pmCmdLargePlt.getSlabNo(), remainSlabLen);
        return resposeDTO;
    }

    @Override
    protected PmProContFilterRequestDTO buildPmProContFilterRequestDTO(
            PmProContYieldRequestDTO pmProContYieldRequestDTO, PmPdSlab salbInfo, PmCmdLargePlt pmCmdLargePlt) {
        pmProContYieldRequestDTO.setPmPdSlab(salbInfo);
        Map<String, PmPdSlabInfo> pmPdSlabInfoMap = PM_PD_SLAB_INFO_LOCAL.get();
        PmPdSlabInfo pmPdSlabInfo = pmPdSlabInfoMap.get(salbInfo.getSlabNo());
        PmProContFilterRequestDTO pmContFilterRequest = new PmProContFilterRequestDTO();
        pmContFilterRequest.setTransFlag(salbInfo.getTransFlag() == null ? null : salbInfo.getTransFlag().toString());
        pmContFilterRequest.setMoldThick(pmPdSlabInfo.getMatActThick());
        pmContFilterRequest.setMoldWidth(pmPdSlabInfo.getMatActWidth());
        pmContFilterRequest.setStNo(salbInfo.getStNo());
        pmContFilterRequest.setSgSign(salbInfo.getSgSign());
        pmContFilterRequest.setFurType(salbInfo.getFurType());
        pmContFilterRequest.setCcType(pmPdSlabInfo.getCcType());
        pmContFilterRequest.setMatDesignKind(salbInfo.getMatDesignKind());
        pmContFilterRequest.setFixSlabLenFlag(salbInfo.getFixSlabLenFlag());
        pmContFilterRequest.setFixSlabLen(salbInfo.getFixSlabLen());
        pmContFilterRequest.setSampleLenGice(salbInfo.getFixSlabLen());
        pmContFilterRequest.setMscLineNo(salbInfo.getMscLineNo());
        pmContFilterRequest.setFormPlateMode(salbInfo.getFormPlateMode());
        pmContFilterRequest.setRollDirectCode(salbInfo.getRollDirectCode());
        pmContFilterRequest.setRemainSlabLen(PM_PD_SLAB_INFO_REMAIN_LEN_LOCAL.get().get(salbInfo.getSlabNo()));
        return pmContFilterRequest;
    }

    @Override
    protected PmPdSlab updateSlabInfo(PmPdSlab salbInfo, PmProContYieldResposeDTO pmProContYieldRespose,
            String pdStatusHp) {
        PmPdSlab updatePmPdSlab = new PmPdSlab();
        if (pmProContYieldRespose != null) {
            updatePmPdSlab.setPreCleanSlabLen(pmProContYieldRespose.getPreCleanSlabLen());
            updatePmPdSlab.setPreCleanSlabMaxLen(pmProContYieldRespose.getPreCleanSlabMaxLen());
            updatePmPdSlab.setPreCleanSlabMinLen(pmProContYieldRespose.getPreCleanSlabMinLen());
            updatePmPdSlab.setPreCleanSlabWt(pmProContYieldRespose.getPreCleanSlabWt());
            updatePmPdSlab.setPreCleanSlabMaxWt(pmProContYieldRespose.getPreCleanSlabMaxWt());
            updatePmPdSlab.setPreCleanSlabMinWt(pmProContYieldRespose.getPreCleanSlabMinWt());
            updatePmPdSlab.setInfurSlabLen(pmProContYieldRespose.getInfurSlabLen());
            updatePmPdSlab.setInfurSlabMaxLen(pmProContYieldRespose.getInfurSlabMaxLen());
            updatePmPdSlab.setInfurSlabMinLen(pmProContYieldRespose.getInfurSlabMinLen());
            updatePmPdSlab.setInfurSlabWt(pmProContYieldRespose.getInfurSlabWt());
            updatePmPdSlab.setInfurSlabMaxWt(pmProContYieldRespose.getInfurSlabMaxWt());
            updatePmPdSlab.setInfurSlabMinWt(pmProContYieldRespose.getInfurSlabMinWt());
            updatePmPdSlab.setNeedSlabLen(pmProContYieldRespose.getNeedSlabLen());
            updatePmPdSlab.setNeedSlabWt(pmProContYieldRespose.getNeedSlabWt());
            updatePmPdSlab.setRollAimThick(pmProContYieldRespose.getTaim());
            updatePmPdSlab.setRollAimWidth(pmProContYieldRespose.getWaim());
            updatePmPdSlab.setRollAimLen(pmProContYieldRespose.getLaim());
            updatePmPdSlab.setRollYield(pmProContYieldRespose.getRollYield());
            updatePmPdSlab.setCommandYield(pmProContYieldRespose.getCommandYield());
            updatePmPdSlab.setNormYield(pmProContYieldRespose.getNormYield());
            updatePmPdSlab.setHeadCut(pmProContYieldRespose.getHeadCut());
            updatePmPdSlab.setTailCut(pmProContYieldRespose.getTailCut());
            if(SecondaryDesignHelper.isTwoRollFlag() && updatePmPdSlab.getFixSlabLenFlag() != null 
                    && updatePmPdSlab.getFixSlabLenFlag() != 0L) {
                // 如果是二次开坯，为指定长，必要板坯长等于指定长
                updatePmPdSlab.setFixSlabLen(pmProContYieldRespose.getNeedSlabLen());
            }
        }
        updatePmPdSlab.setPdStatusHp(pdStatusHp);
        updatePmPdSlab.setObjectVersionNumber(salbInfo.getObjectVersionNumber());
        updatePmPdSlab.setPmPdSlabId(salbInfo.getPmPdSlabId());
        updatePmPdSlab.setSlabNo(salbInfo.getSlabNo());
        updatePmPdSlab.setTenantId(salbInfo.getTenantId());
        return updatePmPdSlab;
    }
    
    /**
     * 二次设计如果存在余材/无合同区分，需要更新最后一块板坯
     * @param pmPdSlab
     * @return
     */
    private PmCmdSlab dealOrderRemainFiv(PmPdSlab pmPdSlab) {
        List<PmCmdSlab> pmCmdSlabs = this.pmCmdSlabRepository.selectByCondition(Condition.builder(PmCmdSlab.class)
                .andWhere(Sqls.custom().andEqualTo(PmCmdSlab.FIELD_TENANT_ID, pmPdSlab.getTenantId()).andEqualTo(PmCmdSlab.FIELD_SLAB_NO
                        , pmPdSlab.getSlabNo()).andEqualTo(PmCmdSlab.FIELD_ORDER_REMAIN_DIV, BaseConstants.Flag.NO.toString())).build());
        if(pmCmdSlabs == null || pmCmdSlabs.isEmpty()) {
            return null;
        }
        BigDecimal remainLen = PM_PD_SLAB_INFO_REMAIN_LEN_LOCAL.get().get(pmPdSlab.getSlabNo());
        pmPdSlab.setPreCleanSlabLen(remainLen);
        pmPdSlab.setPreCleanSlabMaxLen(pmPdSlab.getPreCleanSlabLen());
        pmPdSlab.setPreCleanSlabMinLen(pmPdSlab.getPreCleanSlabLen());
        // 体积
        BigDecimal volume = pmPdSlab.getPreCleanSlabLen().multiply(pmPdSlab.getPreCleanSlabThick()).multiply(pmPdSlab.getPreCleanSlabWidth());
        // 立方毫米转化为立方厘米
        volume = volume.divide(PmPlateConstants.CM3_TO_MM3).setScale(PmPlateConstants.TEM_SCALE, RoundingMode.HALF_UP);
        // 体积*密度 再转化为吨；
        BigDecimal wt = volume.multiply(PmPlateConstants.DEFAULT_PROD_DENCITY).divide(PmPlateConstants.GRAM_TO_TON).setScale(PmPlateConstants.WT_SCALE, RoundingMode.HALF_UP);
        pmPdSlab.setPreCleanSlabWt(wt);
        pmPdSlab.setPreCleanSlabMaxWt(wt);
        pmPdSlab.setPreCleanSlabMinWt(wt);
        
        pmPdSlab.setInfurSlabLen(pmPdSlab.getPreCleanSlabLen());
        pmPdSlab.setInfurSlabMaxLen(pmPdSlab.getPreCleanSlabLen());
        pmPdSlab.setInfurSlabMinLen(pmPdSlab.getPreCleanSlabLen());
        pmPdSlab.setInfurSlabWt(wt);
        pmPdSlab.setInfurSlabMaxWt(wt);
        pmPdSlab.setInfurSlabMinWt(wt);
        pmPdSlab.setNeedSlabLen(pmPdSlab.getPreCleanSlabLen());
        pmPdSlab.setNeedSlabWt(wt);
        PmCmdSlab newPmCmdSlab = new PmCmdSlab();
        newPmCmdSlab.setPreCleanSlabLen(pmPdSlab.getPreCleanSlabLen());
        newPmCmdSlab.setPreCleanSlabMaxLen(pmPdSlab.getPreCleanSlabMaxLen());
        newPmCmdSlab.setPreCleanSlabMinLen(pmPdSlab.getPreCleanSlabMinLen());
        newPmCmdSlab.setPreCleanSlabWt(pmPdSlab.getPreCleanSlabWt());
        newPmCmdSlab.setPreCleanSlabMaxWt(pmPdSlab.getPreCleanSlabMaxWt());
        newPmCmdSlab.setPreCleanSlabMinWt(pmPdSlab.getPreCleanSlabMinWt());
        newPmCmdSlab.setInfurSlabLen(pmPdSlab.getInfurSlabLen());
        newPmCmdSlab.setInfurSlabMaxLen(pmPdSlab.getInfurSlabMaxLen());
        newPmCmdSlab.setInfurSlabMinLen(pmPdSlab.getInfurSlabMinLen());
        newPmCmdSlab.setInfurSlabWt(pmPdSlab.getInfurSlabWt());
        newPmCmdSlab.setInfurSlabMaxWt(pmPdSlab.getInfurSlabMaxWt());
        newPmCmdSlab.setInfurSlabMinWt(pmPdSlab.getInfurSlabMinWt());
        newPmCmdSlab.setNeedSlabLen(pmPdSlab.getNeedSlabLen());
        newPmCmdSlab.setNeedSlabWt(pmPdSlab.getNeedSlabWt());
        newPmCmdSlab.setPdStatusHp(Constants.PdStatusHp.PD_STATUS_HP_23);
        newPmCmdSlab.setObjectVersionNumber(pmCmdSlabs.get(0).getObjectVersionNumber());
        newPmCmdSlab.setPmCmdSlabId(pmCmdSlabs.get(0).getPmCmdSlabId());
        return newPmCmdSlab;
    }

    @Override
    protected void execUpdateSlabInfo(List<PmPdSlab> slabInfoList) {
        List<PmPdSlab> deduplicatedList = slabInfoList.stream()
                .collect(Collectors.toMap(PmPdSlab::getPmPdSlabId, Function.identity(), (k, v) -> k)).values().stream().collect(Collectors.toList());
        String pdStatusHp =  deduplicatedList.get(0).getPdStatusHp();
        List<String> slabNoList = deduplicatedList.stream().map(PmPdSlab::getSlabNo).distinct().collect(Collectors.toList());

        // 更新余坯的无合同区分，更新最后一块板坯表和命令板坯表的状态
        List<PmPdSlab> pdSlabList = pmPdSlabRepository.selectByCondition(Condition.builder(PmPdSlab.class)
                .andWhere(Sqls.custom().andEqualTo(PmPdSlab.FIELD_TENANT_ID, deduplicatedList.get(0).getTenantId())
                        .andIn(PmPdSlab.FIELD_SLAB_NO, slabNoList)
                        .andEqualTo(PmPdSlab.FIELD_ORDER_REMAIN_DIV, BaseConstants.Flag.NO.toString())).build());
        if (CollectionUtils.isNotEmpty(pdSlabList)) {
            pdSlabList.forEach(pmPdSlab -> {
                pmPdSlab.setPdStatusHp(pdStatusHp);
                deduplicatedList.add(pmPdSlab);
            });
        }
//        List<String> slabNoList = new ArrayList<>();
        List<PmCmdSlab> pmCmdSlabs = new ArrayList<>();
        for (PmPdSlab pmPdSlab : deduplicatedList) {
//            slabNoList.add(pmPdSlab.getSlabNo());
            if(Constants.PdStatusHp.PD_STATUS_HP_23.equals(pmPdSlab.getPdStatusHp()) && BaseConstants.Flag.NO.toString().equals(pmPdSlab.getOrderRemainDiv())) {
                // 如果是二次设计状态
                PmCmdSlab pmCmdSlab = dealOrderRemainFiv(pmPdSlab);
                if(pmCmdSlab != null) {
                    pmCmdSlabs.add(pmCmdSlab);
                }
            }
        }
        List<PmPdSlabInfo> updatePmPdSlabInfos = new ArrayList<PmPdSlabInfo>();
        if (PM_PD_SLAB_INFO_LOCAL.get() != null && PM_PD_SLAB_INFO_LOCAL.get().values() != null
                && !PM_PD_SLAB_INFO_LOCAL.get().values().isEmpty()) {
            for (PmPdSlabInfo pmPdSlabInfo : PM_PD_SLAB_INFO_LOCAL.get().values()) {
                PmPdSlabInfo updatePmPdSlabInfo = new PmPdSlabInfo();
                updatePmPdSlabInfo.setPdStatusHp(pdStatusHp);
                updatePmPdSlabInfo.setPmPdSlabInfoId(pmPdSlabInfo.getPmPdSlabInfoId());
                updatePmPdSlabInfo.setObjectVersionNumber(pmPdSlabInfo.getObjectVersionNumber());
                updatePmPdSlabInfos.add(updatePmPdSlabInfo);
            }
            pmPdSlabInfoRepository.batchUpdateByPrimaryKeySelective(updatePmPdSlabInfos);
        }

        // 更新余坯的无合同区分，更新最后一块板坯表和命令板坯表的状态
        if(!Constants.PdStatusHp.PD_STATUS_HP_23.equals(pdStatusHp)) {
            List<PmCmdSlab> cmdSlabs = pmCmdSlabRepository.selectByCondition(Condition.builder(PmCmdSlab.class)
                    .andWhere(Sqls.custom().andEqualTo(PmCmdSlab.FIELD_TENANT_ID, deduplicatedList.get(0).getTenantId())
                            .andIn(PmCmdSlab.FIELD_SLAB_NO, slabNoList)
                            .andEqualTo(PmCmdSlab.FIELD_ORDER_REMAIN_DIV, BaseConstants.Flag.NO.toString())).build());
            if (CollectionUtils.isNotEmpty(cmdSlabs)) {
                cmdSlabs.forEach(cmdSlab -> {
                    cmdSlab.setPdStatusHp(pdStatusHp);
                    pmCmdSlabs.add(cmdSlab);
                });
            }
        }

        pmPdSlabRepository.batchUpdateByPrimaryKeySelective(deduplicatedList);
        if(pmCmdSlabs != null) {
            // 如果命令板坯表不为空，需要更新命令板坯数据
            pmCmdSlabRepository.batchUpdateByPrimaryKeySelective(pmCmdSlabs);
        }
    }
    

    @Override
    protected void checkSlabInfo(PmPdSlab salbInfo, String virtualSlabNo) {
        if (salbInfo == null) {
            throw new CommonException("pm.pm_pd_slab_41", virtualSlabNo);
        }
    }

    @Override
    protected PdMatType getMatDesignKind() {
        return PdMatType.S;
    }

    @Override
    protected PdRuleSetType buildRuleParam() {
        return PdRuleSetType.S06;
    }

    @Override
    protected void updatePmCmdSlabProcInfo(PmPdSlab pmPdSlab, PmCmdLargePlt pmCmdLargePltDb, PmCmdSlab updatePmCmdSlab, PmContMscTech axisPmContMscTech,
            PmProContProdTtr axisPmProContProdTtr) {
//        PmPdSlabInfo pmPdSlabInfo = null;
//        WmStockInfoVO wmStockInfoVO = null;
//        if (PM_PD_SLAB_INFO_LOCAL.get() != null) {
//            pmPdSlabInfo = PM_PD_SLAB_INFO_LOCAL.get().get(pmCmdLargePltDb.getSlabNo());
//        }
//        if (pmPdSlabInfo != null) {
//            List<String> matNoList = new ArrayList<>();
//            matNoList.add(pmCmdLargePltDb.getSlabNo());
//            List<WmMatPileVo> mmSlabVOList = wmMatPileMapper.selectWmMatPileByMatNo(pmCmdLargePltDb.getSlabNo(), pmCmdLargePltDb.getTenantId());
//            if(mmSlabVOList != null && !mmSlabVOList.isEmpty()) {
//                List<WmStockInfoVO> wmStockInfoVOs = wmMatPileMapper.getStockLineByCode(mmSlabVOList.get(0).getStockCode(),
//                        pmCmdLargePltDb.getTenantId());
//                if (wmStockInfoVOs != null && !wmStockInfoVOs.isEmpty()) {
//                    wmStockInfoVO = wmStockInfoVOs.get(0);
//                }
//            }
//        }
        // 切断工序
        List<PmPdSlab> pmPdSlabList = pmPdSlabRepository.selectListBySlabNo(pmPdSlab.getSlabNo(), pmCmdLargePltDb.getTenantId());
        if (pmPdSlabList != null && pmPdSlabList.size() > 1) {
            switch (Utils.mscLineNoToRoolLineNo(axisPmContMscTech.getMscLineNo())) {
                case "10":
                    updatePmCmdSlab.setSlabPreProc1("1B2");
                    break;
                case "20":
                    updatePmCmdSlab.setSlabPreProc1("2B2");
                    break;
                case "30":
                    updatePmCmdSlab.setSlabPreProc1("5B2");
                    break;
                default:
            }
        }
//        if (wmStockInfoVO != null) {
//            updatePmCmdSlab.setSlabPreProc1(PlatePreProcUtils.secondaryCuttingProc(pmCmdLargePltDb.getMscLineNo(),
//                    pmPdSlab.getSlabNo(), pmPdSlab.getIngotType(), wmStockInfoVO.getStockLine(),
//                    pmPdSlabInfo.getMatActLen(), pmPdSlab.getInfurSlabLen()));
//        }
        if (StringUtils.isEmpty(updatePmCmdSlab.getSlabPreProc1())) {
            updatePmCmdSlab.setSlabPreProc1(
                    PlatePreProcUtils.rollSmallProc(Utils.mscLineNoToRoolLineNo(axisPmContMscTech.getMscLineNo())));
        } else {
            updatePmCmdSlab.setSlabPreProc2(
                    PlatePreProcUtils.rollSmallProc(Utils.mscLineNoToRoolLineNo(axisPmContMscTech.getMscLineNo())));
        }
    }
    
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void abandonContractEventCommand(List<String> virtualSlabNoList ,Map<String ,PmPdSlab> slabInfo , Map<String, List<PmPdContSum>> pmPdContSumListMap , Long tenantId) {
        List<PmSmallPltPos> pmSmallPltPosList = pmSmallPltPosRepository.selectByPdMatNoList(virtualSlabNoList, tenantId);
        Map<String, List<PmSmallPltPos>> pmSmallPltPosMap = pmSmallPltPosList.stream().collect(Collectors.groupingBy(PmSmallPltPos::getPdMatNo));
        List<PmSlabApplyMakeDTO> resList = new ArrayList<>();
        for (PmPdSlab pmPdSlab : slabInfo.values()) {
            PmSlabApplyMakeDTO applyMakeDTO = new PmSlabApplyMakeDTO();
            applyMakeDTO.setMatNo(pmPdSlab.getVirtualSlabNo());
            applyMakeDTO.setPpFlag(PdProdFlag.VIRTUAL_SLAB.getCode().intValue());
            applyMakeDTO.setOrdFlag(BaseConstants.Flag.YES.toString());
            applyMakeDTO.setPdMatStatus(Constants.PdStatusHp.PD_STATUS_HP_24);
            applyMakeDTO.setProcCd(Constants.ProdcCd.CD_P1A);
            applyMakeDTO.setWholeBacklogCode(Constants.WholeBacklogCode.CODE_P1);
            applyMakeDTO.setMoMatNo(pmPdSlab.getSlabNo());
            resList.add(applyMakeDTO);
            
            PmSlabApplyMakeDTO applyMakeDTO2 = new PmSlabApplyMakeDTO();
            applyMakeDTO2.setMatNo(pmPdSlab.getVirtualSlabNo());
            applyMakeDTO2.setPpFlag(PdProdFlag.VIRTUAL_COMPOSITE_SLAB.getCode().intValue());
            applyMakeDTO2.setOrdFlag(BaseConstants.Flag.YES.toString());
            applyMakeDTO2.setPdMatStatus(Constants.PdStatusHp.PD_STATUS_HP_24);
            applyMakeDTO2.setProcCd(Constants.ProdcCd.CD_P1A);
            applyMakeDTO2.setWholeBacklogCode(Constants.WholeBacklogCode.CODE_P1);
            applyMakeDTO2.setMoMatNo(pmPdSlab.getSlabNo());
            resList.add(applyMakeDTO2);
            
            List<PmSmallPltPos> pmSmallPltPoss = pmSmallPltPosMap.get(pmPdSlab.getVirtualSlabNo());
            for (PmSmallPltPos pmSmallPltPos : pmSmallPltPoss) {
                PmSlabApplyMakeDTO applyMakeDTO3 = new PmSlabApplyMakeDTO();
                applyMakeDTO3.setMatNo(pmPdSlab.getVirtualSlabNo() + pmSmallPltPos.getSmallPlateDivNo());
                applyMakeDTO3.setPpFlag(PdProdFlag.SMALL_POS_VIRTUAL_SLAB.getCode().intValue());
                applyMakeDTO3.setOrdFlag(BaseConstants.Flag.YES.toString());
                applyMakeDTO3.setPdMatStatus(Constants.PdStatusHp.PD_STATUS_HP_24);
                applyMakeDTO3.setProcCd(Constants.ProdcCd.CD_P1A);
                applyMakeDTO3.setWholeBacklogCode(Constants.WholeBacklogCode.CODE_P1);
                applyMakeDTO3.setMoMatNo(pmPdSlab.getSlabNo());
                resList.add(applyMakeDTO3);
            }
        }
        log.info("<=====余材板坯调用命令作成事件，事件编码:{}, 入参为{}=====>", "PM_RESIDUE_COMMAND_MADE", JSON.toJSONString(resList));
        eventClient.sendEventWithOutResponse(tenantId, "PM_RESIDUE_COMMAND_MADE", resList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void abandonContractEvent(List<String> virtualSlabNoList, Long tenantId, String pdMatStatus, String prodcCd,
                                     String wholeBacklogCode, String eventCode) {
        List<PmPdSlab> pmPdSlabList = pmPdSlabRepository.selectByCondition(Condition.builder(PmPdSlab.class)
                .andWhere(Sqls.custom().andEqualTo(PmPdSlab.FIELD_TENANT_ID, tenantId)
                        .andIn(PmPdSlab.FIELD_VIRTUAL_SLAB_NO, virtualSlabNoList))
                .build());
        List<PmSlabApplyMakeDTO> resList = new ArrayList<>();
        for (PmPdSlab pmPdSlab : pmPdSlabList) {
            PmSlabApplyMakeDTO applyMakeDTO = new PmSlabApplyMakeDTO();
            applyMakeDTO.setMatNo(pmPdSlab.getVirtualSlabNo());
            applyMakeDTO.setPpFlag(5);
            applyMakeDTO.setOrdFlag("2");
            applyMakeDTO.setPdMatStatus(pdMatStatus);
            applyMakeDTO.setProcCd(Constants.ProdcCd.CD_13B);
            applyMakeDTO.setWholeBacklogCode(Constants.WholeBacklogCode.CODE_13);
            if(CtEventConstants.PM_COMMAND_MADE.equals(eventCode)) {
                applyMakeDTO.setProcCd(Constants.ProdcCd.CD_P1A);
                applyMakeDTO.setWholeBacklogCode(Constants.WholeBacklogCode.CODE_P1);
            }
            resList.add(applyMakeDTO);
        }
        if(CtEventConstants.PM_SAMPLE_ADDITION_CANCEL.equals(eventCode)) {
            eventCode = "PM_RESIDUE_SAMPLE_ADDITION_CANCEL";
        } else if(CtEventConstants.PM_SAMPLE_ADDITION.equals(eventCode)){
            eventCode = "PM_RESIDUE_SAMPLE_ADDITION";
        } else if(CtEventConstants.PM_SECONDARY_DESIGN_CANCEL.equals(eventCode)){
            eventCode = "PM_RESIDUE_SECONDARY_DESIGN_CANCEL";
        } else if(CtEventConstants.PM_SECONDARY_DESIGN.equals(eventCode)){
            eventCode = "PM_RESIDUE_SECONDARY_DESIGN";
        } else if(CtEventConstants.PM_COMMAND_MADE.equals(eventCode)) {
            eventCode = "PM_RESIDUE_COMMAND_MADE";
        }
//        log.info("<=====余材板坯调用试样添加事件，事件编码:{}, 入参为{}=====>", eventCode, JSON.toJSONString(resList));
//        eventClient.sendEventWithOutResponse(tenantId, eventCode, resList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void callMmMatStatusModify(Long tenantId, List<PmPdSlab> slabInfoList, List<String> tmpSlabNoList) {
             List<String> virtualSlabNoList = slabInfoList.stream().map(PmPdSlab::getVirtualSlabNo).distinct().collect(Collectors.toList());
        List<PmCmdCont> pmCmdContList = pmCmdContRepository.selectByCondition(Condition.builder(PmCmdCont.class)
                .andWhere(Sqls.custom().andIn(PmCmdCont.FIELD_PONO_SLAB_NO, virtualSlabNoList))
                .andWhere(Sqls.custom().andEqualTo(PmCmdCont.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmCmdCont.FIELD_AXIS_FLAG, 1L))
                .build());
        List<PmPdContSum> pdContSumList = pmPdContSumRepository.selectByCondition(Condition.builder(PmPdContSum.class)
                .andWhere(Sqls.custom()
                        .andIn(PmPdContSum.FIELD_PD_MAT_NO, virtualSlabNoList)
                        .andEqualTo(PmPdContSum.FIELD_TENANT_ID, tenantId)
                        .andEqualTo(PmPdContSum.FIELD_ORDER_SEQ_NO, 1L))
                .build());
         Map<String, String> pmCmdContMap = new HashMap<>(pmCmdContList.size());
        if (CollectionUtils.isNotEmpty(pmCmdContList)) {
            pmCmdContMap = pmCmdContList.stream().collect(Collectors.toMap(PmCmdCont::getPonoSlabNo, PmCmdCont::getOrderNo, (v1, v2) -> v1));
        }
        Map<String, String> pdContSumMap = new HashMap<>(pmCmdContList.size());
        if (CollectionUtils.isNotEmpty(pdContSumList)) {
            pdContSumMap = pdContSumList.stream().collect(Collectors.toMap(PmPdContSum::getPdMatNo, PmPdContSum::getOrderNo));
        }
        List<String> ponoSlabNoList = new ArrayList<>();
        Map<String , List<String>> ponoSlabNoBySlabNoMap = new HashMap<>();
        for (PmPdSlab pmPdSlab : slabInfoList) {
            if(!ponoSlabNoBySlabNoMap.containsKey(pmPdSlab.getSlabNo())) {
                ponoSlabNoBySlabNoMap.put(pmPdSlab.getSlabNo(), new ArrayList<>());
            }
            ponoSlabNoBySlabNoMap.get(pmPdSlab.getSlabNo()).add(pmPdSlab.getVirtualSlabNo());
            ponoSlabNoList.add(pmPdSlab.getVirtualSlabNo());
        }
        Map<String , PmCmdVO> pmCmdVoMap = pmCmdLargePltService.queryCmdVo(ponoSlabNoList, tenantId, true);
        List<MatStatusModifyVO> matStatusModifyVOList = new ArrayList<>();
        for (PmPdSlab pmPdSlab : slabInfoList) {
            if(pmPdSlab.getSlabDivNo() != new BigDecimal(1)) {
                continue;
            }
            MatStatusModifyVO matStatusModifyVO = new MatStatusModifyVO();
            matStatusModifyVO.setMatNo(pmPdSlab.getSlabNo());
            matStatusModifyVO.setPpFlag(Constants.PpFlag.SM);
            Map<String, Object> jsonMap = new HashMap<>(2);
            jsonMap.put("ponoSlab", pmPdSlab.getVirtualSlabNo());
            String orderNo = pdContSumMap.getOrDefault(pmPdSlab.getVirtualSlabNo(), null);
            jsonMap.put("contractCode", orderNo);
            jsonMap.put("relTime", new Date());
            jsonMap.put("relMaker", DetailsHelper.getUserDetails().getUserId());
            
            if(pmPdSlab.getSlabDivNo() == new BigDecimal(1)) {
                // 组装材料挂合同事件
                Map<String, Object> eventMap = new HashMap<>(16);
                List<EventFeignVO> ctEventList = new ArrayList<>();
                EventFeignVO eventFeignVO = new EventFeignVO();
                eventMap.put("contractNum", Utils.removeLastThreeChars(orderNo));
                eventMap.put("orderNo", orderNo);
                eventMap.put("matNo", pmPdSlab.getSlabNo());
                eventMap.put("ppFlag", PdProdFlag.ACTUAL_SLAB.getCode());
                eventMap.put("ordFlag", BaseConstants.Flag.YES.toString());
                eventMap.put("matStatus", Constants.PdStatusHp.PD_STATUS_HP_23);
                if(ponoSlabNoBySlabNoMap != null && !ponoSlabNoBySlabNoMap.isEmpty() && ponoSlabNoBySlabNoMap.containsKey(pmPdSlab.getSlabNo())) {
                    eventMap.put("ponoSlab", String.join(",", ponoSlabNoBySlabNoMap.get(pmPdSlab.getSlabNo())));
                }
                eventMap.put("mscLineNo", pmPdSlab.getMscLineNo());
                eventFeignVO.setEventContext(JSONObject.toJSONString(Collections.singletonList(eventMap)));
                eventFeignVO.setEventCode(Constants.EventCode.PM_MATERIAL_HANGING_CONTRACT);
                ctEventList.add(eventFeignVO);
                matStatusModifyVO.setCtEventList(ctEventList);
                matStatusModifyVO.setCmdVOList(new ArrayList<>());
                if(pmCmdVoMap != null && !pmCmdVoMap.isEmpty() && pmCmdVoMap.containsKey(pmPdSlab.getVirtualSlabNo())) {
                    matStatusModifyVO.getCmdVOList().add(pmCmdVoMap.get(pmPdSlab.getVirtualSlabNo()));
                }
            }
            matStatusModifyVO.setMatInformationString(JSONObject.toJSONString(jsonMap));
            matStatusModifyVOList.add(matStatusModifyVO);
        }
        // 对板坯号去重，只取一条
//        Map<String, MatStatusModifyVO> matStatusModifyVOMap = matStatusModifyVOList.stream().collect(Collectors.toMap(MatStatusModifyVO::getMatNo, Function.identity(), (k, v) -> k));
        mmEventClient.batchMatStatusModify(tenantId, Constants.EventCode.MM_RESIDUE_IN_PROCESS_BLOCKED_MATERIAL_BOARD_HANG_CONTRACT, matStatusModifyVOList);
    }

    @Override
    protected Map<String, String> queryProdYearByMatNo(Map<String, String> tmpSlabNoMap, List<String> matNoList, Long tenantId) {
        Map<String, String> resultMap = new HashMap<>(matNoList.size());
         List<MmSlabVO> mmSlabVOList = wmMatPileMapper.getProdYearByMmSlab(matNoList, tenantId);
         if (CollectionUtils.isEmpty(mmSlabVOList)) {
             return resultMap;
         }
        Map<String, String> mmSlabVOMap = mmSlabVOList.stream().collect(Collectors.toMap(MmSlabVO::getSlabNo, MmSlabVO::getProdYear));
        for (Map.Entry<String, String> entry : tmpSlabNoMap.entrySet()) {
            resultMap.put(entry.getKey(), mmSlabVOMap.getOrDefault(entry.getValue(), null));
         }
        return resultMap;
    }
}
