package com.sw.mes.yb.fls.service.impl;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.sw.mes.base.factory.init.service.FactoryModelService;
import com.sw.mes.base.factory.inspect.entity.DefaultCrystalAttrs;
import com.sw.mes.base.factory.inspect.entity.ProductAssemblyRule;
import com.sw.mes.base.factory.inspect.entity.RoundSpellRule;
import com.sw.mes.base.factory.inspect.entity.SquareSpellRule;
import com.sw.mes.base.factory.inspect.service.DefaultCrystalAttrService;
import com.sw.mes.base.factory.inspect.service.ProductAssemblyRuleService;
import com.sw.mes.base.factory.inspect.service.RoundSpellRuleService;
import com.sw.mes.base.factory.material.entity.MaterialCleanModel;
import com.sw.mes.base.factory.material.service.MaterialCleanModelService;
import com.sw.mes.base.factory.material.service.MaterialModelService;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.entity.SysLog;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.base.system.service.SysLogService;
import com.sw.mes.base.workinprocess.dto.CurrentWipStorageStatusDto;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
import com.sw.mes.base.workinprocess.service.PlanProcessingOrderService;
import com.sw.mes.base.workinprocess.service.WipStorageService;
import com.sw.mes.core.api.materialclean.MaterialCleanFeignClients;
import com.sw.mes.core.api.system.FbFeignClients;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.FbDeviceSchedule;
import com.sw.mes.core.dto.FbDeviceScheduleParam;
import com.sw.mes.core.dto.TrayPostDto;
import com.sw.mes.core.dto.TurnstoreTrayDto;
import com.sw.mes.core.dto.materialCleanDto.MaterialStoreSignBoxDto;
import com.sw.mes.core.dto.mes.pc.yb.ProductionBindingTrayDto;
import com.sw.mes.core.entity.FbCheckOutData;
import com.sw.mes.core.entity.TurnstoreTrayItem;
import com.sw.mes.core.enums.CleanFactoryCodeEnum;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.enums.ReclaimedMaterialsEnum;
import com.sw.mes.core.enums.SectionIndexRangeEnum;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.response.ResultWms;
import com.sw.mes.core.utils.BeanUtil;
import com.sw.mes.core.utils.IpUtils;
import com.sw.mes.core.utils.NumberUtil;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.enumvalue.EnumValuesServer;
import com.sw.mes.inspect.entity.YbInspectData;
import com.sw.mes.inspect.service.YbInspectDataService;
import com.sw.mes.issue.dto.YbIssueDetialDto;
import com.sw.mes.issue.dto.YbIssueDto;
import com.sw.mes.issue.entity.YbIssue;
import com.sw.mes.issue.entity.YbIssueDetial;
import com.sw.mes.issue.service.YbIssueDetialService;
import com.sw.mes.issue.service.YbIssueService;
import com.sw.mes.redis.server.RedissonUtils;
import com.sw.mes.wipstorage.service.WipStorageYbService;
import com.sw.mes.yb.accessory.dto.RecycledMaterialInDto;
import com.sw.mes.yb.fls.dto.*;
import com.sw.mes.yb.fls.service.FlsToMesService;
import com.sw.mes.yb.mcs.dto.CrystalTrayBindInfoDto;
import com.sw.mes.yb.mcs.dto.CrystalTrayUnBindInfoDto;
import com.sw.mes.yb.mcs.dto.McsFbInventoryDto;
import com.sw.mes.yb.mcs.dto.SpellBindingDto;
import com.sw.mes.yb.mcs.entity.McsSquareInventoryLog;
import com.sw.mes.yb.mcs.event.EventPublishService;
import com.sw.mes.yb.mcs.service.McsSquareInventoryLogService;
import com.sw.mes.yb.mcs.service.YbMesToMcsService;
import com.sw.mes.yb.mcs.utils.ResultDto;
import com.sw.mes.yb.pad.entity.ProductionBackCuttingRecord;
import com.sw.mes.yb.pad.entity.ProductionPaintingLine;
import com.sw.mes.yb.pad.entity.ProductionPaintingLineDetail;
import com.sw.mes.yb.pad.entity.SectionNoDetail;
import com.sw.mes.yb.pad.service.*;
import com.sw.mes.yb.pc.entity.Section;
import com.sw.mes.yb.pc.entity.SpellInfo;
import com.sw.mes.yb.pc.service.HeadTailMaterialRuleService;
import com.sw.mes.yb.pc.service.SectionService;
import com.sw.mes.yb.pc.service.SpellInfoService;
import com.sw.mes.yb.production.dto.RecycledMaterialManageDto;
import com.sw.mes.yb.production.entity.LongCrystal;
import com.sw.mes.yb.production.entity.RecycledMaterialManage;
import com.sw.mes.yb.production.entity.RecycledMaterialManageDetail;
import com.sw.mes.yb.production.service.LongCrystalService;
import com.sw.mes.yb.production.service.RecycledMaterialManageDetailService;
import com.sw.mes.yb.production.service.RecycledMaterialManageService;
import com.sw.mes.yb.turnstore.dao.TurnstoreTrayDao;
import com.sw.mes.yb.turnstore.entity.ProductionBindingTray;
import com.sw.mes.yb.turnstore.entity.ProductionBindingTrayLog;
import com.sw.mes.yb.turnstore.entity.TurnstoreTray;
import com.sw.mes.yb.turnstore.service.ProductionBindingTrayLogService;
import com.sw.mes.yb.turnstore.service.ProductionBindingTrayService;
import com.sw.mes.yb.turnstore.service.TurnstoreTrayItemService;
import com.sw.mes.yb.turnstore.service.TurnstoreTrayService;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: GaoXinJian
 * @Date: 2022-01-18 15:54
 */
@Service
@Transactional
@Slf4j
public class FlsToMesServiceImpl implements FlsToMesService {
    private static final List<String> CURRENT_WIP_STORAGE = new ArrayList<>();
    private static final List<String> CURRENT_WIP_STORAGE_NAME = new ArrayList<>();

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private YbMesToMcsService ybMesToMcsService;

    public FlsToMesServiceImpl() {
        //绑定站点
        //用作判断
        CURRENT_WIP_STORAGE.add(EnumValuesFactory.WipStorageCode.圆棒检验.getKey() + EnumValuesFactory.WipStorageStatus.已进站.getKey());
        CURRENT_WIP_STORAGE.add(EnumValuesFactory.WipStorageCode.粘圆棒.getKey() + EnumValuesFactory.WipStorageStatus.已进站.getKey());
        //用作提示
        CURRENT_WIP_STORAGE_NAME.add(EnumValuesFactory.WipStorageCode.圆棒检验.getValue() + EnumValuesFactory.WipStorageStatus.已进站.getValue());
        CURRENT_WIP_STORAGE_NAME.add(EnumValuesFactory.WipStorageCode.粘圆棒.getValue() + EnumValuesFactory.WipStorageStatus.已进站.getValue());
        map.put("Y","A");
        map.put("A","B");
        map.put("B","C");
        map.put("C","D");
        map.put("D","E");
        map.put("E","F");
        map.put("F","G");
        map.put("G","H");
        map.put("H","I");
        map.put("I","J");
        map.put("J","K");
        map.put("K","L");
        map.put("L","M");
        map.put("M","N");
        map.put("N","O");
        map.put("O","P");
        map.put("P","Q");
        map.put("Q","R");
        map.put("R","S");
        map.put("S","T");
        map.put("T","U");
        map.put("U","V");
        map.put("V","W");
        map.put("W","X");
    }

    /**
     * 晶段信息service
     */
    @Autowired
    private SectionNoDetailService sectionNoDetailService;
    /**
     * 托盘绑定service
     */
    @Autowired
    private ProductionBindingTrayService productionBindingTrayService;
    /**
     * 画线信息service
     */
    @Autowired
    private ProductionPaintingLineService productionPaintingLineService;
    /**
     * 画线/反切画线信息详情service
     */
    @Autowired
    private ProductionPaintingLineDetailService productionPaintingLineDetailService;
    /**
     * 反切画线信息service
     */
    @Autowired
    private ProductionRecutService productionRecutService;
    /**
     * 加工工单service
     */
    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;
    @Autowired
    @Qualifier("eventPublishService")
    private EventPublishService publishService;
    @Autowired
    ModelMapper modelMapper;

    @Autowired
    YbInspectDataService inspectDataBaseService;

    @Autowired
    private LongCrystalService longCrystalService;

    @Autowired
    private MaterialCleanFeignClients materialCleanFeignClients;

    @Autowired
    DefaultCrystalAttrService defaultCrystalAttrService;
    @Autowired
    private WipStorageService wipStorageService;
    @Autowired
    private DictionaryItemService dictionaryItemService;
    @Autowired
    private TurnstoreTrayService turnstoreTrayService;
    @Autowired
    private TurnstoreTrayDao turnstoreTrayDao;
    @Autowired
    private TurnstoreTrayItemService turnstoreTrayItemService;
    @Resource
    private FbFeignClients fbFeignClients;
    @Autowired
    private YbMesToMcsService mesToMcsService;

    @Autowired
    private RecycledMaterialManageDetailService recycledMaterialManageDetailService;


    @Autowired
    private SectionService sectionService;
    @Autowired
    private ProductionBindingTrayLogService productionBindingTrayLogService;
    @Autowired
    private FactoryModelService factoryModelService;
    @Autowired
    private WipStorageYbService wipStorageYbService;
    @Autowired
    private SysLogService sysLogService;
    @Autowired
    private SpellInfoService spellInfoService;
    @Autowired
    private RoundSpellRuleService roundSpellRuleService;
    @Autowired
    private McsSquareInventoryLogService mcsSquareInventoryLogService;
    @Autowired
    private ProductAssemblyRuleService productAssemblyRuleService;
    @Autowired
    private YbIssueService ybIssueService;
    @Autowired
    private YbIssueDetialService ybIssueDetialService;
    @Autowired
    private HeadTailMaterialRuleService headTailMaterialRuleService;

    @Autowired
    private MaterialModelService materialModelService;

    @Autowired
    private RecycledMaterialManageService recycledMaterialManageService;

    private static final Map<String,String> map = new HashMap<>();

    @Autowired
    private FbReCutService fbReCutService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private MaterialCleanModelService materialCleanModelService;

    @Value("${spring.wmsServiceUrl}")
    private String wmsServiceUrl;

    private final String recycleToWms = "/api/InboundRecycledMaterial";


    @Override
    public Result bindingInfo(BindingInfoDto bindingInfoDto) {


        // TODO: 2022/1/18  接口加id，判断是否为重复发


        //验证晶段编号是否存在
        SectionNoDetail sectionNoDetail = sectionNoDetailService.findBySectionNo(bindingInfoDto.getYbSectionNo());
        if (sectionNoDetail == null) {
            return ResultGenerator.message(106, "晶段编号不存在", null);
        }

        // 绑定校验重复：校验晶段绑定是否重复
        ProductionBindingTray byCrystalNo2 = productionBindingTrayService.getByTrayNoAndLocationNo(bindingInfoDto.getYbSectionNo(), "1");
        if (byCrystalNo2 != null) {
            return ResultGenerator.message(106, "该晶段已经绑定", null);
        }

        //初始化绑定信息
        ProductionBindingTrayDto productionBindingTrayDto = this.initProductionBindingTrayDto(bindingInfoDto);
        //绑定
        productionBindingTrayDto.setCheckReback("无");
        Result result = productionBindingTrayService.bindingCrystal(productionBindingTrayDto);

        //绑定结果，200成功，其它失败
        if (result.getCode() != 200) {
            return ResultGenerator.message(104, "绑定异常：" + result.getMessage(), null);
        }

//        this.execJd(bindingInfoDto.getCrystalNo(), bindingInfoDto.getYbSectionNo());


        return ResultGenerator.message(200, "绑定成功", null);
    }

    @Override
    public Result bindingInfoVerify(BindingInfoDto bindingInfoDto) {
        //验证晶段编号是否存在
        SectionNoDetail sectionNoDetail = sectionNoDetailService.findBySectionNo(bindingInfoDto.getYbSectionNo());
        if (sectionNoDetail == null) {
            return ResultGenerator.message(106, "晶段编号不存在", null);
        }

        // 绑定校验重复：校验晶段绑定是否重复
        ProductionBindingTray byCrystalNo2 = productionBindingTrayService.getByTrayNoAndLocationNo(bindingInfoDto.getYbSectionNo(), "1");
        if (byCrystalNo2 != null) {
            return ResultGenerator.message(106, "该晶段已经绑定", null);
        }

        //初始化绑定信息
        ProductionBindingTrayDto productionBindingTrayDto = this.initProductionBindingTrayDto(bindingInfoDto);
        //绑定
        Result result = productionBindingTrayService.bindingCrystalVerify(productionBindingTrayDto);
        //绑定结果，200成功，其它失败
        if (result.getCode() != 200) {
            return ResultGenerator.message(104, "绑定异常：" + result.getMessage(), null);
        }

        return ResultGenerator.message(200, "可以绑定！", null);
    }

    @Override
    public Result getPaintingLineInfo(String code) {
        //查询绑定信息
        List<ProductionBindingTray> productionBindingTrayList = productionBindingTrayService.getByTrayNo(code);
        if (productionBindingTrayList.size() == 0) {
//            return ResultGenerator.message(101, "绑定信息不存在", null);
            ProductionBindingTray productionBindingTray = new ProductionBindingTray();
            productionBindingTray.setCrystalNo(code);
            productionBindingTray.setLocationNo("1");
            productionBindingTrayList.add(productionBindingTray);
        }
        List<PaintingLineInfoDto> paintingLineInfoDtoList = new ArrayList<>();

        //晶段编号时查询检验信息，临时用位数判断
        if(code.length()>10){
            YbInspectData ybInspectData = inspectDataBaseService.getSectionNo(code);
            if(null == ybInspectData){
                return ResultGenerator.fail("检验信息不存在！");
            }
            String gradeType = ybInspectData.getGradeType();
            List<PaintingLineInfoDetailDto> paintingLineInfoDetailDtoList1 = new ArrayList<>();
            if("外观反切".equals(gradeType) || "回收料".equals(gradeType)){
                // 模拟画线信息(给母晶棒、且长度大于10)
                String crystalNo = ybInspectData.getCrystalNo();
                LongCrystal byCrystalNo = longCrystalService.findByCrystalNo(crystalNo);
                PaintingLineInfoDto paintingLineInfoDto1 = new PaintingLineInfoDto();
                BigDecimal weight = BigDecimal.ZERO;
                String specification = "";
                BigDecimal length = BigDecimal.ZERO;
                String dopant = null;
                String conductionType = null;
                Integer recut = 0;
                weight = ybInspectData.getTheoryWeight();
                specification = ybInspectData.getProductTypeSecond();
                length = ybInspectData.getActualLength();
                recut = 1;
                dopant = ybInspectData.getDopant();
                conductionType = ybInspectData.getConductiveType();
                paintingLineInfoDto1.setWeight(weight);
//                //BCS提新需求，去掉规格中的“吋”
//                String specification1 = "";
//                if (specification != null && specification.length() >= 2) {
//                    specification1 = specification.substring(0, specification.length() - 1);
//                }
//                paintingLineInfoDto1.setSpecification(specification1);
                paintingLineInfoDto1.setSpecification(specification);
                paintingLineInfoDto1.setWindUp(byCrystalNo.getWindUp());
                paintingLineInfoDto1.setTime(new Date());
                paintingLineInfoDto1.setDirec(0);
                paintingLineInfoDto1.setLength(length);
                paintingLineInfoDto1.setRecut(recut);
                paintingLineInfoDto1.setCrystalNo(code);
                paintingLineInfoDto1.setLocationNo("1");
                paintingLineInfoDto1.setConductionType(conductionType);
                PaintingLineInfoDetailDto paintingLineInfoDetailDto1 = new PaintingLineInfoDetailDto();
                String substring = code.substring(code.length() - 1);
                String sn = code.substring(0,code.length() - 1);
                if(map.containsKey(substring)){
                    sn = sn + map.get(substring);
                } else {
                    return ResultGenerator.message(105, "当前外观反切晶编异常，已超过X", null);
                }
                paintingLineInfoDetailDto1.setNo(sn);
                paintingLineInfoDetailDto1.setCrystalType(0);
                paintingLineInfoDetailDto1.setSegmentNum(1);
                // 默认给0 晶段
                paintingLineInfoDetailDto1.setType(EnumValuesServer.LineType.晶段.getKey());
                paintingLineInfoDetailDto1.setLength(new BigDecimal(20));
                paintingLineInfoDetailDto1.setSequence(1);
                paintingLineInfoDetailDto1.setSampleType(0);
                paintingLineInfoDetailDto1.setIsCut(0);
//                paintingLineInfoDetailDto1.setDiameter(specification1);
                paintingLineInfoDetailDto1.setDiameter(specification);
                paintingLineInfoDetailDtoList1.add(paintingLineInfoDetailDto1);
                paintingLineInfoDto1.setPaintingLineInfoDetailDtoList(paintingLineInfoDetailDtoList1);
                paintingLineInfoDto1.setLocationNo("1");
                paintingLineInfoDtoList.add(paintingLineInfoDto1);
                return ResultGenerator.success(paintingLineInfoDtoList);
            }
        }
        //根据绑定信息查询查询画线信息
        for (ProductionBindingTray productionBindingTray : productionBindingTrayList) {
            if (!"1".equals(productionBindingTray.getLocationNo()) && !"2".equals(productionBindingTray.getLocationNo())
                    && !"3".equals(productionBindingTray.getLocationNo()) && !"4".equals(productionBindingTray.getLocationNo())) {
                return ResultGenerator.message(102, "工位信息异常，截断机自动上料仅支持工位1、工位2、工位3、工位4", null);
            }
            String crystalNo = productionBindingTray.getCrystalNo();
            List<PlanProcessingOrder> planProcessingOrderList = planProcessingOrderService.findByCodeOrderByIdDesc(crystalNo);
            if (planProcessingOrderList.size() <= 0) {
                return ResultGenerator.message(102, "编号不存在", null);
            }
            PlanProcessingOrder planProcessingOrder = planProcessingOrderList.get(0);
            Integer orderType = planProcessingOrder.getOrderType();
            BigDecimal weight = BigDecimal.ZERO;
            String specification = "";
            BigDecimal length = BigDecimal.ZERO;
            String dopant = null;
            String conductionType = null;
            Integer recut = 0;
            List<ProductionPaintingLineDetail> productionPaintingLineDetailList;
            PaintingLineInfoDto paintingLineInfoDto = new PaintingLineInfoDto();
            //头长
            BigDecimal headLen = new BigDecimal(0);
            //尾长
            BigDecimal tailLen = new BigDecimal(0);
            //长晶棒产出时间
            Date createTime = null;
            if (orderType.equals(EnumValuesFactory.PlanProcessingOrderOrderType.单晶.getKey())) {
                //长棒类型查询画线记录
                ProductionPaintingLine productionPaintingLine = productionPaintingLineService.findByCrystalNo(crystalNo);
                if (productionPaintingLine == null) {
                    return ResultGenerator.message(103, "【" + crystalNo + "】画线信息不存在", null);
                }

                //查询查询画线详情
                productionPaintingLineDetailList = productionPaintingLineDetailService.findByOperateDrawId(productionPaintingLine.getId());
                //查询长棒产出表，获取长棒信息
                LongCrystal byCrystalNo = longCrystalService.findByCrystalNo(productionPaintingLine.getCrystalNo());
                if (byCrystalNo != null) {
                    paintingLineInfoDto.setWindUp(byCrystalNo.getWindUp());
                    weight = byCrystalNo.getWeight();
                    specification = byCrystalNo.getSpecs();
                    length = byCrystalNo.getLength();
                    recut = 0;
                    dopant = byCrystalNo.getDopant();
                    conductionType = byCrystalNo.getConductiveType();
                    if (byCrystalNo.getHeadLen() != null) {
                        headLen = byCrystalNo.getHeadLen();
                    }
                    if (byCrystalNo.getTailLen() != null) {
                        tailLen = byCrystalNo.getTailLen();
                    }
                    createTime = byCrystalNo.getGmtCreate();
//                    if (byCrystalNo.getGmtUpdate() != null){
//                        createTime = byCrystalNo.getGmtUpdate();
//                    }
                }

                //去头长度
                if (productionPaintingLine.getNoTopLength() != null && productionPaintingLine.getNoTopLength().compareTo(headLen) > 0) {
                    headLen = productionPaintingLine.getNoTopLength();
                }
                //如果未采集到尾段长度（例如断苞单晶）赋值画线记录的画线去尾长度
                if (productionPaintingLine.getLineTailLength() != null && productionPaintingLine.getLineTailLength().compareTo(tailLen) > 0) {
                    tailLen = productionPaintingLine.getLineTailLength();
                }
                String drawLine = productionPaintingLine.getDrawLine();
                if (StringUtils.equals(drawLine, "从头至尾")) {
                    paintingLineInfoDto.setDirec(0);
                } else {
                    paintingLineInfoDto.setDirec(1);
                }
            } else {
                //短棒查询反切画线记录
                ProductionBackCuttingRecord productionBackCuttingRecord = productionRecutService.findTopBySegmentNoOrderByIdDesc(crystalNo);
                if (productionBackCuttingRecord == null) {
                    return ResultGenerator.message(104, "【" + crystalNo + "】返切画线信息不存在", null);
                }
                //查询查询画线详情
                productionPaintingLineDetailList = productionPaintingLineDetailService.findByOperateReversecutDrawId(productionBackCuttingRecord.getId());
                //查询晶棒检验信息，获取短棒信息
                YbInspectData inspectDataBase = inspectDataBaseService.findBySectionNo(productionBackCuttingRecord.getSegmentNo());
                if (inspectDataBase != null) {
                    weight = inspectDataBase.getTheoryWeight();
                    specification = inspectDataBase.getProductTypeSecond();
                    length = inspectDataBase.getActualLength();
                    recut = 1;
                    dopant = inspectDataBase.getDopant();
                    conductionType = inspectDataBase.getConductiveType();
                }
            }

            if (productionPaintingLineDetailList.size() <= 0) {
                return ResultGenerator.message(105, "画线详情不存在", null);
            }

            paintingLineInfoDto.setWeight(weight);
//            String specification1 = "";
//            if (specification != null && specification.length() >= 2) {
//                specification1 = specification.substring(0, specification.length() - 1);
//            }
//            paintingLineInfoDto.setSpecification(specification1);
            paintingLineInfoDto.setSpecification(specification);
            paintingLineInfoDto.setLength(length);
            paintingLineInfoDto.setRecut(recut);
            paintingLineInfoDto.setCrystalNo(crystalNo);
            paintingLineInfoDto.setLocationNo(productionBindingTray.getLocationNo());
            paintingLineInfoDto.setConductionType(conductionType);
            paintingLineInfoDto.setTime(createTime);
            List<PaintingLineInfoDetailDto> paintingLineInfoDetailDtoList = productionPaintingLineDetailList.stream().map(this::toLazyDto).collect(Collectors.toList());
            DefaultCrystalAttrs defaultCrystalAttrList = defaultCrystalAttrService.getDefaultCrystalAttrs(dopant, specification, null);
            for (PaintingLineInfoDetailDto paintingLineInfoDetailDto : paintingLineInfoDetailDtoList) {
                if (paintingLineInfoDetailDto != null) {
                    if (paintingLineInfoDetailDto.getType() != null && paintingLineInfoDetailDto.getType() == 0) {
                        //type 为0 时：【晶段类型- 0：标棒 1：非标棒 2：线体免检 3：回收料（正常晶段，长度小于八十）】
                        //页面：圆棒生产管理》默认值维护》晶棒属性 根据 规格参杂剂长度判 断
                        String type;
                        try {
                            type = defaultCrystalAttrService.getDefaultCrystalAttrManyTimes(defaultCrystalAttrList, paintingLineInfoDetailDto.getLength());
                            if ("标棒".equals(type)) {
                                paintingLineInfoDetailDto.setSampleType(0);
                            } else if ("非标棒".equals(type)) {
                                paintingLineInfoDetailDto.setSampleType(1);
                            } else if ("线体免检".equals(type)) {
                                paintingLineInfoDetailDto.setSampleType(2);
                            } else if ("回收料".equals(type)) {
                                paintingLineInfoDetailDto.setSampleType(3);
                            }
                        } catch (Exception e) {
                            throw new RuntimeException("查询晶棒类型异常：" + e.getMessage());
                        }
                    }
                    //头尾料赋值长度
                    if (paintingLineInfoDetailDto.getType() != null && paintingLineInfoDetailDto.getType() == 4) {
                        if (paintingLineInfoDetailDto.getNo() != null && paintingLineInfoDetailDto.getNo().charAt(paintingLineInfoDetailDto.getNo().length() - 1) == 'T') {
                            paintingLineInfoDetailDto.setLength(headLen);
                        }
                        if (paintingLineInfoDetailDto.getNo() != null && paintingLineInfoDetailDto.getNo().charAt(paintingLineInfoDetailDto.getNo().length() - 1) == 'W') {
                            paintingLineInfoDetailDto.setLength(tailLen);
                        }
                    }
                }
            }

            paintingLineInfoDto.setPaintingLineInfoDetailDtoList(paintingLineInfoDetailDtoList);
            paintingLineInfoDtoList.add(paintingLineInfoDto);
        }
        return ResultGenerator.success(paintingLineInfoDtoList);
    }


    @Override
    public Result getPaintingLineInfoManual(String crystalNo) {
        //查询绑定信息
        //List<ProductionBindingTray> productionBindingTrayList = productionBindingTrayService.getByTrayNo(code);
        ProductionBindingTray bindingTrayByCrystalNo = productionBindingTrayService.getByCrystalNo(crystalNo);
        //if (productionBindingTrayList.size() <= 0) {
        //    return ResultGenerator.message(101, "绑定信息不存在", null);
        //}
        if (bindingTrayByCrystalNo == null) {
            return ResultGenerator.message(101, "绑定信息不存在", null);
        }
        List<PaintingLineInfoDto> paintingLineInfoDtoList = new ArrayList<>();
        //根据绑定信息查询查询画线信息
        //for (ProductionBindingTray productionBindingTray : productionBindingTrayList) {//for循环开始
        if (!"1".equals(bindingTrayByCrystalNo.getLocationNo()) && !"2".equals(bindingTrayByCrystalNo.getLocationNo())
                && !"3".equals(bindingTrayByCrystalNo.getLocationNo()) && !"4".equals(bindingTrayByCrystalNo.getLocationNo())) {
            return ResultGenerator.message(102, "工位信息异常，截断机自动上料仅支持工位1、工位2、工位3、工位4", null);
        }
        //String crystalNo = productionBindingTray.getCrystalNo();
        List<PlanProcessingOrder> planProcessingOrderList = planProcessingOrderService.findByCodeOrderByIdDesc(crystalNo);
        if (planProcessingOrderList.size() <= 0) {
            return ResultGenerator.message(102, "编号不存在", null);
        }
        PlanProcessingOrder planProcessingOrder = planProcessingOrderList.get(0);
        Integer orderType = planProcessingOrder.getOrderType();
        BigDecimal weight = BigDecimal.ZERO;
        String specification = "";
        BigDecimal length = BigDecimal.ZERO;
        String dopant = null;
        String conductionType = null;
        Integer recut = 0;
        List<ProductionPaintingLineDetail> productionPaintingLineDetailList;
        //头长
        BigDecimal headLen = new BigDecimal(0);
        //尾长
        BigDecimal tailLen = new BigDecimal(0);
        //长晶棒产出时间
        Date createTime = null;
        if (orderType.equals(EnumValuesFactory.PlanProcessingOrderOrderType.单晶.getKey())) {
            //长棒类型查询画线记录
            ProductionPaintingLine productionPaintingLine = productionPaintingLineService.findByCrystalNo(crystalNo);
            if (productionPaintingLine == null) {
                return ResultGenerator.message(103, "【" + crystalNo + "】画线信息不存在", null);
            }

            //查询查询画线详情
            productionPaintingLineDetailList = productionPaintingLineDetailService.findByOperateDrawId(productionPaintingLine.getId());
            //查询长棒产出表，获取长棒信息
            LongCrystal byCrystalNo = longCrystalService.findByCrystalNo(productionPaintingLine.getCrystalNo());
            if (byCrystalNo != null) {
                weight = byCrystalNo.getWeight();
                specification = byCrystalNo.getSpecs();
                length = byCrystalNo.getLength();
                recut = 0;
                dopant = byCrystalNo.getDopant();
                conductionType = byCrystalNo.getConductiveType();
                if (byCrystalNo.getHeadLen() != null) {
                    headLen = byCrystalNo.getHeadLen();
                }
                if (byCrystalNo.getTailLen() != null) {
                    tailLen = byCrystalNo.getTailLen();
                }
                createTime = byCrystalNo.getGmtCreate();
//                    if (byCrystalNo.getGmtUpdate() != null){
//                        createTime = byCrystalNo.getGmtUpdate();
//                    }
            }

            //去头长度
            if (productionPaintingLine.getNoTopLength() != null && productionPaintingLine.getNoTopLength().compareTo(headLen) > 0) {
                headLen = productionPaintingLine.getNoTopLength();
            }
            //如果未采集到尾段长度（例如断苞单晶）赋值画线记录的画线去尾长度
            if (productionPaintingLine.getLineTailLength() != null && productionPaintingLine.getLineTailLength().compareTo(tailLen) > 0) {
                tailLen = productionPaintingLine.getLineTailLength();
            }
        } else {
            //短棒查询反切画线记录
            ProductionBackCuttingRecord productionBackCuttingRecord = productionRecutService.findTopBySegmentNoOrderByIdDesc(crystalNo);
            if (productionBackCuttingRecord == null) {
                return ResultGenerator.message(104, "【" + crystalNo + "】返切画线信息不存在", null);
            }
            //查询查询画线详情
            productionPaintingLineDetailList = productionPaintingLineDetailService.findByOperateReversecutDrawId(productionBackCuttingRecord.getId());
            //查询晶棒检验信息，获取短棒信息
            YbInspectData inspectDataBase = inspectDataBaseService.findBySectionNo(productionBackCuttingRecord.getSegmentNo());
            if (inspectDataBase != null) {
                weight = inspectDataBase.getTheoryWeight();
                specification = inspectDataBase.getProductTypeSecond();
                length = inspectDataBase.getActualLength();
                recut = 1;
                dopant = inspectDataBase.getDopant();
                conductionType = inspectDataBase.getConductiveType();
            }
        }


        if (productionPaintingLineDetailList.size() <= 0) {
            return ResultGenerator.message(105, "画线详情不存在", null);
        }


        PaintingLineInfoDto paintingLineInfoDto = new PaintingLineInfoDto();
        paintingLineInfoDto.setWeight(weight);
        //BCS提新需求，去掉规格中的“吋”
        String specification1 = "";
        if (specification != null && specification.length() >= 2) {
            specification1 = specification.substring(0, specification.length() - 1);
        }
        paintingLineInfoDto.setSpecification(specification1);
        paintingLineInfoDto.setLength(length);
        paintingLineInfoDto.setRecut(recut);
        paintingLineInfoDto.setCrystalNo(crystalNo);
        paintingLineInfoDto.setLocationNo(bindingTrayByCrystalNo.getLocationNo());
        paintingLineInfoDto.setConductionType(conductionType);
        paintingLineInfoDto.setTime(createTime);
        List<PaintingLineInfoDetailDto> paintingLineInfoDetailDtoList = productionPaintingLineDetailList.stream().map(this::toLazyDto).collect(Collectors.toList());
        DefaultCrystalAttrs defaultCrystalAttrList = defaultCrystalAttrService.getDefaultCrystalAttrs(dopant, specification, null);
        for (PaintingLineInfoDetailDto paintingLineInfoDetailDto : paintingLineInfoDetailDtoList) {
            if (paintingLineInfoDetailDto != null) {
                if (paintingLineInfoDetailDto.getType() != null && paintingLineInfoDetailDto.getType() == 0) {
                    //type 为0 时：【晶段类型- 0：标棒 1：非标棒 2：线体免检 3：回收料（正常晶段，长度小于八十）】
                    //页面：圆棒生产管理》默认值维护》晶棒属性 根据 规格参杂剂长度判 断
                    String type;
                    try {
                        type = defaultCrystalAttrService.getDefaultCrystalAttrManyTimes(defaultCrystalAttrList, paintingLineInfoDetailDto.getLength());
                        if ("标棒".equals(type)) {
                            paintingLineInfoDetailDto.setSampleType(0);
                        } else if ("非标棒".equals(type)) {
                            paintingLineInfoDetailDto.setSampleType(1);
                        } else if ("线体免检".equals(type)) {
                            paintingLineInfoDetailDto.setSampleType(2);
                        } else if ("回收料".equals(type)) {
                            paintingLineInfoDetailDto.setSampleType(3);
                        }
                    } catch (Exception e) {
                        throw new RuntimeException("查询晶棒类型异常：" + e.getMessage());
                    }
                }
                //头尾料赋值长度
                if (paintingLineInfoDetailDto.getType() != null && paintingLineInfoDetailDto.getType() == 4) {
                    if (paintingLineInfoDetailDto.getNo() != null && paintingLineInfoDetailDto.getNo().charAt(paintingLineInfoDetailDto.getNo().length() - 1) == 'T') {
                        paintingLineInfoDetailDto.setLength(headLen);
                    }
                    if (paintingLineInfoDetailDto.getNo() != null && paintingLineInfoDetailDto.getNo().charAt(paintingLineInfoDetailDto.getNo().length() - 1) == 'W') {
                        paintingLineInfoDetailDto.setLength(tailLen);
                    }
                }
            }
        }
        paintingLineInfoDto.setPaintingLineInfoDetailDtoList(paintingLineInfoDetailDtoList);
        paintingLineInfoDtoList.add(paintingLineInfoDto);
        //}//for 循环结束
        return ResultGenerator.success(paintingLineInfoDtoList);
    }


    @Override
    public Result sampleInfo(SampleInfoDto sampleInfoDto) {

        return null;
    }

    @Override
    public YbEntersSortingPortDto ybEntersSortingPort(String trayCode) {
        ProductionBindingTray productionBindingTray = productionBindingTrayService.getByTrayNoAndLocationNo(trayCode, "1");
        if (productionBindingTray == null) {
            throw new RuntimeException("该托盘未绑定圆棒");
        }
        YbEntersSortingPortDto ybEntersSortingPortDto = new YbEntersSortingPortDto();
        ybEntersSortingPortDto.setSectionNoYb(productionBindingTray.getCrystalNo());
        if (StringUtils.isEmpty(ybEntersSortingPortDto.getSectionNoYb())) {
            throw new BusinessException("托盘为空");
        }
        //检验数据库查拼数，=1整棒
        YbInspectData inspectDataBase = inspectDataBaseService.findBySectionNo(ybEntersSortingPortDto.getSectionNoYb());
        if (inspectDataBase == null) {
            throw new RuntimeException("检验数据为空");
        }
        Integer sticksType;
        if (inspectDataBase.getSticksCount() > 1) {
            sticksType = 2;
            ybEntersSortingPortDto.setIsWhole(false);
        } else {
            sticksType = 1;
            ybEntersSortingPortDto.setIsWhole(true);
        }
//        if ("标棒".equals(inspectDataBase.getSectionType())) {
        FbDeviceScheduleParam fbDeviceScheduleParam = new FbDeviceScheduleParam();
        fbDeviceScheduleParam.setSpecs(inspectDataBase.getProductTypeSecond());
        fbDeviceScheduleParam.setConductiveType(inspectDataBase.getConductiveType());
        fbDeviceScheduleParam.setDopant(inspectDataBase.getDopant());
        fbDeviceScheduleParam.setProductLevel(inspectDataBase.getProductLevel());
        fbDeviceScheduleParam.setSticksType(sticksType);
        fbDeviceScheduleParam.setSectionNo(inspectDataBase.getSectionNo());
        Result<FbDeviceSchedule> result = fbFeignClients.findFbDeviceSchedule(fbDeviceScheduleParam);
        if (result.getCode() != ResultCode.SUCCESS.getCode()) {
            throw new RuntimeException(result.getMessage());
        }
        ybEntersSortingPortDto.setOrderNo(result.getData().getOrderCode());
        ybEntersSortingPortDto.setDeviceCodes(result.getData().getDeviceCodes());
//        }
        return ybEntersSortingPortDto;

    }


    @Override
    public Result ybSortingPortUpload(YbSortingPortUploadDto ybSortingPortUploadDto) {

        this.enterYbMaterialIssue(ybSortingPortUploadDto);

        return ResultGenerator.success();


    }

    private void enterYbMaterialIssue(YbSortingPortUploadDto ybSortingPortUploadDto) {
        //查询晶段信息
        String sectionNo = ybSortingPortUploadDto.getSectionNo();
        YbInspectData inspectData = inspectDataBaseService.findBySectionNo(sectionNo);
        if (null == inspectData) {
            throw new BusinessException("当前晶段信息不存在");
        }
        //查询当前站点
        Result<CurrentWipStorageStatusDto> currentWipStorageStatusDtoResult = wipStorageService.selectWipStorageResult(sectionNo);
        if (currentWipStorageStatusDtoResult.getCode() != ResultCode.SUCCESS.getCode() || currentWipStorageStatusDtoResult.getData() == null) {
            throw new BusinessException("查询站点信息失败");
        }
        CurrentWipStorageStatusDto currentWipStorageStatusDto = currentWipStorageStatusDtoResult.getData();
        if (currentWipStorageStatusDto.getWipStorageCode().equals(EnumValuesFactory.WipStorageCode.圆棒检验.getKey())
                && currentWipStorageStatusDto.getWipStorageStatus() == EnumValuesFactory.WipStorageStatus.已进站.getKey()
        ) {
            YbIssueDetial byIssueIdByCrystalNo = null;
            try {
                YbIssueDto ybIssueDto = new YbIssueDto();
                List<YbIssueDetialDto> detialDtoList = new ArrayList<>();
                YbIssueDetialDto ybIssueDetialDto = new YbIssueDetialDto();
                ybIssueDetialDto.setCrystalNo(sectionNo);
                ybIssueDetialDto.setCurrentSite(currentWipStorageStatusDto.getWipStorageCodeName());
                ybIssueDetialDto.setProductLevel(inspectData.getProductLevel());
                detialDtoList.add(ybIssueDetialDto);
                ybIssueDto.setDetialDtoList(detialDtoList);
                ybIssueService.saveYbIssue(ybIssueDto);
                //查询圆棒发料单据明细
                byIssueIdByCrystalNo = ybIssueDetialService.findByIssueIdByCrystalNo(sectionNo);
                if (byIssueIdByCrystalNo != null) {
                    YbIssueDto updateState = new YbIssueDto();
                    updateState.setId(byIssueIdByCrystalNo.getIssueId());
                    ybIssueService.updateState(updateState);
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException(e.getMessage());
            }

            YbIssue entity = new YbIssue();
            entity.setId(byIssueIdByCrystalNo.getIssueId());
            entity.setStatus(3);
            ybIssueService.updateIssueStatus(entity);
        } else {
            throw new BusinessException("当前站点为：" + currentWipStorageStatusDto.getWipStorageCodeName() + currentWipStorageStatusDto.getWipStorageStatusName());
        }

    }

    @Override
    public void enterCutSquare(YbSortingPortUploadDto ybSortingPortUploadDto) {
        //查询晶段信息
        YbInspectData inspectData = inspectDataBaseService.findBySectionNo(ybSortingPortUploadDto.getSectionNo());
        if (null == inspectData) {
            throw new BusinessException("当前晶段信息不存在");
        }
//        CIGC2952204B1511D61N02W,CIGC2952203F5411D51N02W
        List<String> listSectionNo = new ArrayList<>();
        if (inspectData.getSticksCount() != null && inspectData.getSticksCount() > 1 && StringUtils.isNotEmpty(inspectData.getSectionCompose())) {
            listSectionNo = Arrays.asList(inspectData.getSectionCompose().split(","));
        } else {
            listSectionNo.add(inspectData.getSectionNo());
        }
        for (String sectionNo : listSectionNo) {
            //查询晶段信息
            YbInspectData inspectData2 = null;
            if (!sectionNo.equals(ybSortingPortUploadDto.getSectionNo())) {
                inspectData2 = inspectDataBaseService.findBySectionNo(sectionNo);
            } else {
                inspectData2 = inspectData;
            }
            if (null == inspectData2) {
                throw new BusinessException("当前晶段信息不存在");
            }
            //查询当前站点
            Result<CurrentWipStorageStatusDto> currentWipStorageStatusDtoResult = wipStorageService.selectWipStorageResult(sectionNo);
            if (currentWipStorageStatusDtoResult.getCode() != ResultCode.SUCCESS.getCode()) {
                throw new BusinessException("查询站点信息失败");
            }
            if (currentWipStorageStatusDtoResult.getData() == null) {
                throw new BusinessException("站点信息为空");
            }
            CurrentWipStorageStatusDto currentWipStorageStatusDto = currentWipStorageStatusDtoResult.getData();

            if (currentWipStorageStatusDto.getWipStorageCode().equals(EnumValuesFactory.WipStorageCode.圆棒检验.getKey())
                    && currentWipStorageStatusDto.getWipStorageStatus() == EnumValuesFactory.WipStorageStatus.已进站.getKey()
            ) {
                //查询是否存在
                TurnstoreTrayItem trayItem = turnstoreTrayItemService.findBySectionNoAndState(sectionNo, 9);
                if (null != trayItem) {
                    throw new BusinessException("该晶段已进行组托，不能重复组托,所在托号为: " + trayItem.getTrayNo());
                }
                //组装组托详情
                TurnstoreTrayItem turnstoreTrayItem = new TurnstoreTrayItem();
                BeanUtils.copyProperties(inspectData2, turnstoreTrayItem, BeanUtil.getIgnoreProperties(inspectData2, "id", null));
                //料号
                turnstoreTrayItem.setItemNo(inspectData2.getMaterialCode());
                //异常
//                turnstoreTrayItem.setErrorMsg(inspectData2.getAnomaly());
                //工厂
                String factory = turnstoreTrayItem.getSectionNo().substring(1, 2);
                DictionaryItem factoryCate = dictionaryItemService.findByThemeValueAndValueAndEnable("FactoryCate", factory, true);
                if (null != factoryCate) {
                    factory = factoryCate.getName();
                }
                turnstoreTrayItem.setFactory(factory);
                //库存地点
                turnstoreTrayItem.setStockPlace("Q001");
                turnstoreTrayItem.setSectionCompose(inspectData2.getSectionCompose());
                turnstoreTrayItem.setItemNo(inspectData2.getMaterialCode());
                turnstoreTrayItem.setState(1);
                List<TurnstoreTrayItem> turnstoreTrayItemList = new ArrayList<>();
                turnstoreTrayItemList.add(turnstoreTrayItem);

                //创建圆棒入库记录
                TurnstoreTrayDto turnstoreTrayDto = new TurnstoreTrayDto();
                turnstoreTrayDto.setHasGone("方棒加工");
                turnstoreTrayDto.setProductLevel(inspectData2.getProductLevel());
                turnstoreTrayDto.setSpecs(inspectData2.getProductTypeSecond());
                turnstoreTrayDto.setUser("自动");
                turnstoreTrayDto.setStatus("1");
                turnstoreTrayDto.setState(1);
                turnstoreTrayDto.setCount(turnstoreTrayItemList.size());
                TurnstoreTray turnstoreTray = JSONObject.parseObject(JSONObject.toJSONString(turnstoreTrayDto), TurnstoreTray.class);
                //自动组托，返回托号
                String trayNo = turnstoreTrayService.createTrayNo(null, turnstoreTray);
                turnstoreTrayDto.setTrayNo(trayNo);
                //发起入库
                turnstoreTrayService.initiateReceipt(turnstoreTrayDto, turnstoreTrayItemList, true);
                //晶段与托盘解绑
                //过站啊处理，拼棒的每一根都需过站,圆棒检验直接过站到开放已进站
                //单晶集合
                wipStorageService.outStation(sectionNo, "B", EnumValuesFactory.WipStorageStatus.已进站.getKey());
            } else if (currentWipStorageStatusDto.getWipStorageCode().equals(EnumValuesFactory.WipStorageCode.开方.getKey())) {
                if (currentWipStorageStatusDto.getWipStorageStatus() == EnumValuesFactory.WipStorageStatus.待进站.getKey()) {
                    //操作进站
                    wipStorageService.inStation(sectionNo, "开方", false);
                }
            } else {
                throw new BusinessException("当前站点为：" + currentWipStorageStatusDto.getWipStorageCodeName() + currentWipStorageStatusDto.getWipStorageStatusName());
            }
        }


    }


    /**
     * 初始化绑定信息
     *
     * @param bindingInfoDto 绑定信息
     * @return
     */
    private ProductionBindingTrayDto initProductionBindingTrayDto(BindingInfoDto bindingInfoDto) {
        ProductionBindingTrayDto productionBindingTrayDto = new ProductionBindingTrayDto();
        productionBindingTrayDto.setCrystalNo(bindingInfoDto.getYbSectionNo());
        productionBindingTrayDto.setBindingPeople("mcs");
        productionBindingTrayDto.setBindingSite("截断自动下料");
        productionBindingTrayDto.setBindingTime(new Date());
        //自动绑定
        productionBindingTrayDto.setIsBinding(0);
        //只有一个工位，默认为空
        productionBindingTrayDto.setLocationNo("1");
        productionBindingTrayDto.setTrayNo(bindingInfoDto.getTrayCode());
        productionBindingTrayDto.setCrystalDirection(bindingInfoDto.getOrientation());
        productionBindingTrayDto.setType("圆棒");
        productionBindingTrayDto.setPoint("JD");
        return productionBindingTrayDto;
    }

    /**
     * 初始化mcs所需信息
     *
     * @param
     * @return
     */
    @Override
    public CrystalTrayBindInfoDto initCrystalTrayBindInfoDto(String trayNo, String sectionNo) {

//        CrystalTrayBindInfoDto crystalTrayBindInfoDto = new CrystalTrayBindInfoDto();
//        crystalTrayBindInfoDto.setTrayCode(productionBindingTrayDto.getTrayNo());
//        crystalTrayBindInfoDto.setSectionNo(productionBindingTrayDto.getCrystalNo());
//        crystalTrayBindInfoDto.setTail(Integer.valueOf(productionBindingTrayDto.getCrystalDirection()));
//
//        crystalTrayBindInfoDto.setProductType(sectionNoDetail.getProductType());

//画线
//        @ApiModelProperty(value = "规格（223、295）")
//        String productType;

        //晶段类型根据晶段规格、参杂剂、长度判断，圆棒生产管理》检验数据管理》辨准与规则维护》默认值维护》晶棒属性
//        @ApiModelProperty(value = "类型（标棒TYPE_S，非标TYPE_N，返切TYPE_R）")
//        String type;
//        @ApiModelProperty(value = "是否MES单晶，1代表是，默认0")
//        Integer mes;
//        @ApiModelProperty(value = "PN型")
//        String pn;
//        @ApiModelProperty(value = "掺杂剂")
//        String mix;

        return null;
    }

    @Override
    public void trayAutoUnBinding(TrayAutoUnBinding trayAutoUnBinding, String source) {
        this.UnBinding(trayAutoUnBinding.getTrayNo(), trayAutoUnBinding.getSectionNo(),
                trayAutoUnBinding.getReason(), trayAutoUnBinding.getPoint(), source);
    }

    @Override
    public void autoInitiateReceipt(String sectionNo) {
        Date date = new Date();
        //查询晶段信息
        YbInspectData inspectData = inspectDataBaseService.findBySectionNo(sectionNo);
        if (null == inspectData) {
            throw new BusinessException("当前晶段信息不存在");
        }


        //查询当前站点
        Result<CurrentWipStorageStatusDto> currentWipStorageStatusDtoResult = wipStorageService.selectWipStorageResult(sectionNo);
        if (currentWipStorageStatusDtoResult.getCode() != ResultCode.SUCCESS.getCode()) {
            throw new BusinessException("查询站点信息失败");
        }
        if (currentWipStorageStatusDtoResult.getData() == null) {
            throw new BusinessException("站点信息为空");
        }
//            CurrentWipStorageStatusDto currentWipStorageStatusDto = currentWipStorageStatusDtoResult.getData();

        //查询是否存在
        TurnstoreTrayItem trayItem = turnstoreTrayItemService.findBySectionNoAndState(inspectData.getSectionNo(), 9);
        if (null != trayItem) {
            throw new BusinessException("该晶段已进行组托，不能重复组托,所在托号为: " + trayItem.getTrayNo());
        }
        //组装组托详情
        TurnstoreTrayItem turnstoreTrayItem = new TurnstoreTrayItem();
        BeanUtils.copyProperties(inspectData, turnstoreTrayItem, BeanUtil.getIgnoreProperties(inspectData, "id", null));
        //料号
        turnstoreTrayItem.setItemNo(inspectData.getMaterialCode());
        //异常
//        turnstoreTrayItem.setErrorMsg(inspectData.getAnomaly());
        //工厂
        String factory = turnstoreTrayItem.getSectionNo().substring(1, 2);
        DictionaryItem factoryCate = dictionaryItemService.findByThemeValueAndValueAndEnable("FactoryCate", factory, true);
        if (null != factoryCate) {
            factory = factoryCate.getName();
        }
        turnstoreTrayItem.setFactory(factory);
        //库存地点
        turnstoreTrayItem.setStockPlace("Q001");
        turnstoreTrayItem.setSectionCompose(inspectData.getSectionCompose());
        turnstoreTrayItem.setItemNo(inspectData.getMaterialCode());
        turnstoreTrayItem.setState(1);
        turnstoreTrayItem.setOrderNo(inspectData.getOrderNo());
        turnstoreTrayItem.setConfirmTime(date);
        turnstoreTrayItem.setConfirmUser("自动确认");
        turnstoreTrayItem.setHasGone("方棒加工");

        turnstoreTrayItem.setState(1);
        turnstoreTrayItem.setTime(new Date());
        List<TurnstoreTrayItem> turnstoreTrayItemList = new ArrayList<>();
        turnstoreTrayItemList.add(turnstoreTrayItem);

        //创建圆棒入库记录
        TurnstoreTray turnstoreTray = new TurnstoreTray();
        turnstoreTray.setHasGone("方棒加工");
        turnstoreTray.setProductLevel(inspectData.getProductLevel());
        turnstoreTray.setSpecs(inspectData.getProductTypeSecond());
        turnstoreTray.setUser("自动");
        turnstoreTray.setStatus("1");
        turnstoreTray.setState(1);
        turnstoreTray.setCount(turnstoreTrayItemList.size());
        turnstoreTray.setOperationTime(date);
        //自动组托，返回托号
        String trayNo = turnstoreTrayService.createTrayNo(null, turnstoreTray);
        turnstoreTrayItem.setTrayNo(trayNo);

        //发起入库


        //根据去向调用不同接口
        TrayPostDto trayPostDto = new TrayPostDto();

        trayPostDto.setAutoReceive(true);
        turnstoreTray.setConfirmTime(date);
        turnstoreTray.setState(1);
        turnstoreTray.setTime(new Date());
        turnstoreTray.setConfirmUser("自动确认");
        turnstoreTray.setTrayNo(trayNo);
        turnstoreTray.setIsToWms(0);

        TurnstoreTrayDto turnstoreTrayDto = JSONObject.parseObject(JSONObject.toJSONString(turnstoreTray), TurnstoreTrayDto.class);
        trayPostDto.setTrayDto(turnstoreTrayDto);
        trayPostDto.setTrayItems(turnstoreTrayItemList);
        //发送至方棒
        Result<String> receive = fbFeignClients.receive(trayPostDto);
        if (receive.getCode() != ResultCode.SUCCESS.getCode()) {
            throw new BusinessException(receive.getMessage());
        }

        turnstoreTrayService.saveOrUpdate(turnstoreTray);
        //更新详情数据
        turnstoreTrayService.updateItem(turnstoreTray, turnstoreTrayItemList, true);

    }

    public PaintingLineInfoDetailDto toLazyDto(ProductionPaintingLineDetail entity) {
        return modelMapper.map(entity, PaintingLineInfoDetailDto.class);
    }

    @Override
    public Result spellValidation(SpellValidationDto spellValidationDto) {
        List<String> sectionNos = Arrays.asList(spellValidationDto.getBody().getSectionNos().split(","));
        if (sectionNos == null || sectionNos.size() < 2) {
            return ResultGenerator.fail("错误,至少要填写两个单晶编号");
        }

        List<String> sectionNoList = new ArrayList<>();
        for (String sectionNo : sectionNos) {
            if (org.apache.commons.lang3.StringUtils.isNotBlank(sectionNo)) {
                sectionNoList.add(sectionNo);
            }
        }

        String sectionNoGroup = null;
        String wipStorageCode = null;
        String wipStorageUuidCode = null;
        for (String sectionNo : sectionNoList) {
            Result<CurrentWipStorageStatusDto> currentWipStorageStatusDtoResult = wipStorageService.selectWipStorageResult(sectionNo);
            if (currentWipStorageStatusDtoResult.getCode() == ResultCode.SUCCESS.getCode()) {
                CurrentWipStorageStatusDto currentWipStorageStatusDto = currentWipStorageStatusDtoResult.getData();
                String wipStorageCodeStatus = currentWipStorageStatusDto.getWipStorageCode() + currentWipStorageStatusDto.getWipStorageStatus();
                if (!CURRENT_WIP_STORAGE.contains(wipStorageCodeStatus)) {
                    return ResultGenerator.fail("当前站点为：" + currentWipStorageStatusDto.getWipStorageCodeName()
                            + currentWipStorageStatusDto.getWipStorageStatusName()
                            + "，只有为（" + org.apache.commons.lang3.StringUtils.join(CURRENT_WIP_STORAGE_NAME, "，") + "）这些站点才能拼棒");
                }
                if (sectionNoGroup == null) {
                    sectionNoGroup = sectionNo;
                    wipStorageCode = currentWipStorageStatusDto.getWipStorageCode() + currentWipStorageStatusDto.getWipStorageStatus();
                    wipStorageUuidCode = currentWipStorageStatusDto.getWipStorageUuid();
                } else {
                    if (!wipStorageCode.equals(wipStorageCodeStatus) || !wipStorageUuidCode.equals(currentWipStorageStatusDto.getWipStorageUuid())) {
                        return ResultGenerator.fail(sectionNo + "与" + sectionNoGroup + "站点状态不一致，请确认");
                    }
                }
            } else {
                return ResultGenerator.fail(currentWipStorageStatusDtoResult.getMessage());
            }

            PlanProcessingOrder planProcessingOrder = planProcessingOrderService.findByCode(sectionNo);
            if (null == planProcessingOrder) {
                return ResultGenerator.fail(sectionNo + "工单号不存在");
            }
            if (planProcessingOrder.getStatus().equals(EnumValuesFactory.PlanProcessingOrderStatus.组托.getKey())) {
                return ResultGenerator.fail(sectionNo + "在组托状态，不允许粘棒");
            }
        }

        //验证晶段编号重复
        Set<String> set = new HashSet<String>(sectionNos);
        boolean checkResult = sectionNos.size() == set.size();
        if (!checkResult) {
            return ResultGenerator.fail("晶段编号重复");
        }

        //查询是否绑定过 - zhxx_yb_data_spell_info
        List<SpellInfo> spellInfoCheckList = spellInfoService.findBySectionNos(sectionNoList);
        if (spellInfoCheckList != null && spellInfoCheckList.size() > 0) {
            StringBuilder sectionNoError = new StringBuilder();
            for (SpellInfo entity : spellInfoCheckList) {
                sectionNoError.append(entity.getSectionNo()).append(",");
            }
            return ResultGenerator.fail("错误," + sectionNoError + "单晶已绑定");
        }

        //验证晶棒是否存在检验记录
        List<YbInspectData> inspectList = inspectDataBaseService.findBySections(sectionNoList);
        if (inspectList == null || inspectList.size() == 0) {
            return ResultGenerator.fail("错误,查不到圆棒检验信息");
        }
        StringBuilder sectionNoError = new StringBuilder();
        List<String> inspectSectionNos = new ArrayList<>();
        Set<String> specsSet = new HashSet<>();
        if (inspectList.size() != sectionNoList.size()) {
            for (YbInspectData inspect : inspectList) {
                inspectSectionNos.add(inspect.getSectionNo());
                if (inspect.getProductTypeSecond() == null || inspect.getProductTypeSecond().equals("")) {
                    return ResultGenerator.fail("错误，" + inspect.getSectionNo() + "没有检验信息");
                }
                specsSet.add(inspect.getProductTypeSecond());
            }
            if (specsSet.size() > 1) {
                return ResultGenerator.fail("错误，选择的圆棒圆棒规则不相等");
            }
            for (String sectionNoCheck : sectionNoList) {
                if (!inspectSectionNos.contains(sectionNoCheck)) {
                    sectionNoError.append(sectionNoCheck).append(",");
                }
            }
            return ResultGenerator.fail("错误," + sectionNoError + "等单晶无检验信息");
        }
        //获取规则
        List<RoundSpellRule> list2 = roundSpellRuleService.findRuleBySpecs(inspectList.get(0).getProductTypeSecond(), 1);
        //计算拼棒总长
        BigDecimal totalLength = inspectList.stream().map(e -> e.getActualLength() == null ? new BigDecimal(0) : e.getActualLength()).reduce(BigDecimal.ZERO, BigDecimal::add);
        totalLength.add(BigDecimal.valueOf(2 * (sectionNoList.size() - 1)));
        //计算总重量
//        BigDecimal totalWeight = inspectList.stream().map(e -> e.getActualWeight() == null ? new BigDecimal(0) : e.getActualWeight()).reduce(BigDecimal.ZERO, BigDecimal::add);
        //计算总理论重量
        BigDecimal theoryWeight = inspectList.stream().map(e -> e.getTheoryWeight() == null ? new BigDecimal(0) : e.getTheoryWeight()).reduce(BigDecimal.ZERO, BigDecimal::add);
        RoundSpellRule ruleBySpecs = null;
        if (list2.size() > 0) {
            lab:
            for (RoundSpellRule roundSpellRule : list2) {
                boolean flag1 = false;
                for (int w = 0; w < inspectList.size(); w++) {
                    boolean flag = false;
                    boolean flag2 = true;
                    //验证产品等级
                    if (inspectList.get(w).getProductLevel() == null) {
                        return ResultGenerator.fail("错误," + inspectList.get(w).getSectionNo() + "单晶无产品等级");
                    }
                    if (roundSpellRule.getProductGrade() != null) {
                        String[] str1 = roundSpellRule.getProductGrade().split(",");
                        for (String s : str1) {
                            if (s.equals(inspectList.get(w).getProductLevel())) {
                                flag2 = false;
                                break;
                            }
                        }
                    }
                    if (flag2) {
                        continue lab;
                    }
                    //验证实验等级
                    if (roundSpellRule.getExperimentGrade() != null && !roundSpellRule.getExperimentGrade().equals(inspectList.get(w).getProductLevelExperiment())) {
                        continue lab;
                    }
                    //验证直径差
                    if (inspectList.get(w).getDiameterMax().subtract(inspectList.get(w == inspectList.size() - 1 ? w - 1 : w + 1).getDiameterMax()).abs().floatValue() > roundSpellRule.getDiamDiff() && inspectList.get(w).getDiameterMin().subtract(inspectList.get(w == inspectList.size() - 1 ? w - 1 : w + 1).getDiameterMin()).abs().floatValue() > roundSpellRule.getDiamDiff()) {
                        continue lab;
                    }
                    //验证扭（如果规则扭是验证条件，检验数据中扭有值判定为不可拼棒）
                    if (roundSpellRule.getTwist() == 0 && inspectList.get(w).getDistortion() != null && inspectList.get(w).getDistortion().intValue() > 0) {
                        continue lab;
                    }
//                    //验证细（如果规则细是验证条件，检验数据中细总长有值判定为不可拼棒）
//                    if (roundSpellRule.getThin() == 0 && inspectList.get(w).getFineDiameter() != null && inspectList.get(w).getFineDiameter().intValue() > 0) {
//                        continue lab;
//                    }
//                    //验证细减（如果规则细减是验证条件，检验数据中细减有值判定为不可拼棒）
//                    if (roundSpellRule.getThinCut() == 0 && inspectList.get(w).getFineCutLength() != null && inspectList.get(w).getFineCutLength().intValue() > 0) {
//                        continue lab;
//                    }
                    //验证细斜（如果规则斜是验证条件，检验数据中斜有值判定为不可拼棒）
                    if (roundSpellRule.getThinCut() == 0 && inspectList.get(w).getIsBevel() != null && inspectList.get(w).getIsBevel() > 0) {
                        continue lab;
                    }
                    //验证长度范围
                    String length = roundSpellRule.getLength();

                    if (length != null && !length.equals("")) {
                        String[] str = length.split(",");
                        for (String s : str) {
                            List<String> list;
                            String[] str1 = s.split("-");
                            list = Arrays.asList(str1);
                            if (totalLength.floatValue() >= Integer.parseInt(list.get(0)) && totalLength.floatValue() <= Integer.parseInt(list.get(1))) {
                                flag = true;
                                break;
                            }
                        }
                    }
                    flag1 = flag;
                }
                if (flag1) {
                    ruleBySpecs = roundSpellRule;
                    break;
                }
            }
        }

        if (ruleBySpecs != null) {
        } else {
            return ResultGenerator.fail("错误，没有可匹配的拼棒规则");
        }

        return ResultGenerator.success("200", "成功！");
    }

    @Override
    public void autoInitiateReceiptData(String sectionNo) {
        Date date = new Date();
        //查询晶段信息
        YbInspectData inspectData = inspectDataBaseService.findBySectionNo(sectionNo);
        if (null == inspectData) {
            throw new BusinessException("当前晶段信息不存在");
        }
        //组装组托详情
        TurnstoreTrayItem turnstoreTrayItem = new TurnstoreTrayItem();
        BeanUtils.copyProperties(inspectData, turnstoreTrayItem, BeanUtil.getIgnoreProperties(inspectData, "id", null));
        //料号
        turnstoreTrayItem.setItemNo(inspectData.getMaterialCode());
        //异常
//        turnstoreTrayItem.setErrorMsg(inspectData.getAnomaly());
        //工厂
        String factory = turnstoreTrayItem.getSectionNo().substring(1, 2);
        DictionaryItem factoryCate = dictionaryItemService.findByThemeValueAndValueAndEnable("FactoryCate", factory, true);
        if (null != factoryCate) {
            factory = factoryCate.getName();
        }
        turnstoreTrayItem.setFactory(factory);
        //库存地点
        turnstoreTrayItem.setStockPlace("Q001");
        turnstoreTrayItem.setSectionCompose(inspectData.getSectionCompose());
        turnstoreTrayItem.setItemNo(inspectData.getMaterialCode());
        turnstoreTrayItem.setState(1);
        turnstoreTrayItem.setOrderNo(inspectData.getOrderNo());
        turnstoreTrayItem.setConfirmTime(date);
        turnstoreTrayItem.setConfirmUser("自动确认");
        turnstoreTrayItem.setHasGone("方棒加工");

        turnstoreTrayItem.setState(1);
        turnstoreTrayItem.setTime(new Date());
        List<TurnstoreTrayItem> turnstoreTrayItemList = new ArrayList<>();
        turnstoreTrayItemList.add(turnstoreTrayItem);
        //创建圆棒入库记录
        TurnstoreTray turnstoreTray = new TurnstoreTray();
        turnstoreTray.setHasGone("方棒加工");
        turnstoreTray.setProductLevel(inspectData.getProductLevel());
        turnstoreTray.setSpecs(inspectData.getProductTypeSecond());
        turnstoreTray.setUser("自动");
        turnstoreTray.setStatus("1");
        turnstoreTray.setState(1);
        turnstoreTray.setCount(turnstoreTrayItemList.size());
        turnstoreTray.setOperationTime(date);
        //自动组托，返回托号
        String trayNo = turnstoreTrayService.createTrayNo(null, turnstoreTray);
        turnstoreTrayItem.setTrayNo(trayNo);
        //根据去向调用不同接口
        TrayPostDto trayPostDto = new TrayPostDto();
        trayPostDto.setAutoReceive(true);
        turnstoreTray.setConfirmTime(date);
        turnstoreTray.setState(1);
        turnstoreTray.setTime(new Date());
        turnstoreTray.setConfirmUser("自动确认");
        turnstoreTray.setTrayNo(trayNo);
        turnstoreTray.setIsToWms(0);
        TurnstoreTrayDto turnstoreTrayDto = JSONObject.parseObject(JSONObject.toJSONString(turnstoreTray), TurnstoreTrayDto.class);
        trayPostDto.setTrayDto(turnstoreTrayDto);
        trayPostDto.setTrayItems(turnstoreTrayItemList);
        //发送至方棒
        Result<String> receive = fbFeignClients.receive(trayPostDto);
        if (receive.getCode() != ResultCode.SUCCESS.getCode()) {
            throw new BusinessException(receive.getMessage());
        }
        TurnstoreTray tray = turnstoreTrayDao.save(turnstoreTray);
        //查询详情列表
        turnstoreTrayItem.setTrayId(tray.getId());
        turnstoreTrayItem.setIsToWms(turnstoreTray.getIsToWms());
        turnstoreTrayItemService.saveOrUpdate(turnstoreTrayItem);
    }

    @Override
    public Result joinCircleFinish(JoinCircleFinishDto joinCircleFinishDto) {

        List<String> list = Arrays.asList(joinCircleFinishDto.getSectionNos().split(","));
        if (list == null || list.size() <= 0) {
            return ResultGenerator.fail("晶段信息不能为空");
        }

        Section section = null;
        //存储拼棒信息
        Result mes = sectionService.stickTogether(list, "mes", 1);
        if (mes.getCode() == 200 && mes.getData() != null && mes.getData() != "") {
            section = (Section) mes.getData();
        } else {
            return mes;
        }

        //托盘解绑
        this.UnBinding(joinCircleFinishDto.getTrayCode(), joinCircleFinishDto.getSectionNo(), "(拼棒完成自动解绑)", "(拼棒下料)", "SMCS");

        //初始化绑定信息
        ProductionBindingTrayDto productionBindingTrayDto = new ProductionBindingTrayDto();
        productionBindingTrayDto.setCrystalNo(joinCircleFinishDto.getSectionNo());
        productionBindingTrayDto.setBindingPeople("SMCS自动拼棒");
        productionBindingTrayDto.setBindingSite("拼棒托盘绑定");
        productionBindingTrayDto.setBindingTime(new Date());
        //自动绑定:设置为0，可以将绑定信息下发给mcs
        productionBindingTrayDto.setIsBinding(0);
        //只有一个工位，默认为空
        productionBindingTrayDto.setLocationNo("1");
        productionBindingTrayDto.setTrayNo(joinCircleFinishDto.getTrayCode());
        productionBindingTrayDto.setType("圆棒");

        //托盘绑定
        Result result = productionBindingTrayService.bindingCrystal(productionBindingTrayDto);
        //绑定结果，200成功，其它失败
        if (result.getCode() != 200) {
            return ResultGenerator.fail("绑定异常：" + result.getMessage());
        }

        //自动拼棒完成晶棒，如果是粘圆棒的进站状态，则出站变成开方待进站
        for (String sectionNo : list) {
            //查询当前站点
            Result<CurrentWipStorageStatusDto> currentWipStorageStatusDtoResult = wipStorageService.selectWipStorageResult(sectionNo);
            if (currentWipStorageStatusDtoResult.getCode() != ResultCode.SUCCESS.getCode()) {
                throw new BusinessException("查询站点信息失败");
            }
            if (currentWipStorageStatusDtoResult.getData() == null) {
                throw new BusinessException("站点信息为空");
            }
            //如果是粘圆棒的进站状态（E路线进圆棒检验），则出站变成圆棒检验已进站
            CurrentWipStorageStatusDto currentWipStorageStatusDto = currentWipStorageStatusDtoResult.getData();
            if (currentWipStorageStatusDto.getWipStorageCode().equals(EnumValuesFactory.WipStorageCode.粘圆棒.getKey())
                    && currentWipStorageStatusDto.getWipStorageStatus() == EnumValuesFactory.WipStorageStatus.已进站.getKey()
            ) {
                wipStorageService.outStation(sectionNo, "A", EnumValuesFactory.WipStorageStatus.已进站.getKey());
            }
        }

        //推送MCS
        SpellBindingDto spellBindingDto = new SpellBindingDto();
        spellBindingDto.setSectionNo(joinCircleFinishDto.getSectionNo());
        spellBindingDto.setType("拼棒");
        spellBindingDto.setTrayCode(joinCircleFinishDto.getTrayCode());
        spellBindingDto.setSectionNo1("");
        spellBindingDto.setSectionNo2("");
        String productType = ybMesToMcsService.productTypeConversion(section.getSpecs());
        spellBindingDto.setProductType(productType);
        spellBindingDto.setPn(section.getConductiveType());
        spellBindingDto.setProductRank(section.getProductRank());
        spellBindingDto.setSectionNos(section.getSectionNoGroup());
        spellBindingDto.setSpellCount(section.getStickCount());
        spellBindingDto.setTotalLength(section.getTotalLength());
        spellBindingDto.setTotalWeight(section.getActualWeight());
        spellBindingDto.setSpellLength(section.getLengthGroup());
        spellBindingDto.setSpellWeight(section.getWeightGroup());
        //推送mcs绑定信息
        Thread thread = new Thread(() -> {
            ResultDto resultDto = mesToMcsService.spellBinding(spellBindingDto);
        });
        thread.start();
//        ResultDto resultDto = mesToMcsService.spellBinding(spellBindingDto);
//        if (resultDto.getStatus() != 100) {
//            return ResultGenerator.fail("拼棒托盘绑定,推送MCS失败！" + resultDto.getMessage());
//        }

        return ResultGenerator.success("200", "成功！");
    }

    /**
     * 托盘自动解绑
     *
     * @param trayNo 托盘号
     * @param reason 原因
     * @param point  点位
     * @param source 来源
     */
    public void UnBinding(String trayNo, String sn, String reason, String point, String source) {
        boolean hasContains = false;
        List<ProductionBindingTray> productionBindingTrayList = productionBindingTrayService.getByTrayNo(trayNo);
        for (ProductionBindingTray bindingTray : productionBindingTrayList) {
            if (bindingTray != null && bindingTray.getCrystalNo().equals(sn)) {
                hasContains = true;
            }
            if (bindingTray != null && StringUtils.isNotBlank(bindingTray.getCrystalNo())) {
                // 解绑需要同时改变长棒表载具号中AGV送验状态
                bindingTray.setBindingSite(point);
                bindingTray.setCrystalNo(null);
                bindingTray.setToWhere("");
                bindingTray.setIsBinding(0);
                productionBindingTrayService.saveOrUpdate(bindingTray);
                //添加绑定载具记录
                Date currentDate = new Date();
                ProductionBindingTrayLog log = new ProductionBindingTrayLog();
                log.setTrayNo(trayNo);
                log.setBindingTime(currentDate);
                log.setBindingSite(source + "自动解绑");
                log.setIsBinding(2);//解绑
                log.setGmtCreate(currentDate);
                log.setLocationNo(bindingTray.getLocationNo());
                log.setReason(source + point + "自动解绑" + reason);
                //mcs自动解绑时，解绑记录中写入晶编
                log.setCrystalNo(sn);
                productionBindingTrayLogService.saveOrUpdate(log);
            }
            //托盘解绑信息下发mcs
            if (StringUtils.isNotEmpty(trayNo)) {
                trayNo = trayNo.toUpperCase();
                if (trayNo.startsWith("T") && !trayNo.startsWith("TPT")) {
                    CrystalTrayUnBindInfoDto crystalTrayUnBindInfoDto = new CrystalTrayUnBindInfoDto();
                    crystalTrayUnBindInfoDto.setTrayCode(trayNo);
                    mesToMcsService.crystalTrayUnBindInfo(crystalTrayUnBindInfoDto);
                }
            }
        }

        if (!hasContains && StringUtils.isNoneBlank(sn)) {
            ProductionBindingTray byCrystalNo = productionBindingTrayService.getByCrystalNo(sn);
            if (byCrystalNo != null) {
                trayNo = byCrystalNo.getTrayNo();
                // 解绑需要同时改变长棒表载具号中AGV送验状态
                byCrystalNo.setBindingSite(point);
                byCrystalNo.setCrystalNo(null);
                byCrystalNo.setIsBinding(0);
                byCrystalNo.setToWhere("");
                productionBindingTrayService.saveOrUpdate(byCrystalNo);
                //添加绑定载具记录
                Date currentDate = new Date();
                ProductionBindingTrayLog log = new ProductionBindingTrayLog();
                log.setTrayNo(trayNo);
                log.setBindingTime(currentDate);
                log.setBindingSite(source + "自动解绑");
                log.setIsBinding(2);//解绑
                log.setGmtCreate(currentDate);
                log.setLocationNo(byCrystalNo.getLocationNo());
                log.setReason(source + point + "自动解绑" + reason);
                //mcs自动解绑时，解绑记录中写入晶编
                log.setCrystalNo(sn);
                productionBindingTrayLogService.saveOrUpdate(log);
                if (byCrystalNo != null && StringUtils.isNoneBlank(trayNo)) {
                    trayNo = trayNo.toUpperCase();
                    if (trayNo.startsWith("T") && !trayNo.startsWith("TPT")) {
                        CrystalTrayUnBindInfoDto crystalTrayUnBindInfoDto = new CrystalTrayUnBindInfoDto();
                        crystalTrayUnBindInfoDto.setTrayCode(trayNo);
                        mesToMcsService.crystalTrayUnBindInfo(crystalTrayUnBindInfoDto);
                    }
                }
            }
        }
    }

    @Override
    public Result trayBinding(BindingDto bindingDto) {
        ProductionBindingTrayDto productionBindingTrayDto = new ProductionBindingTrayDto();
        productionBindingTrayDto.setCrystalNo(bindingDto.getSectionNo());
        productionBindingTrayDto.setBindingPeople("SMCS");
        productionBindingTrayDto.setBindingSite("方棒退料");
        productionBindingTrayDto.setBindingTime(new Date());
        //自动绑定
        productionBindingTrayDto.setIsBinding(0);
        //只有一个工位，默认为空
        productionBindingTrayDto.setLocationNo("1");
        productionBindingTrayDto.setTrayNo(bindingDto.getTrayCode());
        productionBindingTrayDto.setType("圆棒");
        productionBindingTrayDto.setToWhere("方棒退料");
        //绑定
        Result result = productionBindingTrayService.bindingCrystal(productionBindingTrayDto);
        //绑定结果，200成功，其它失败
        if (result.getCode() != 200) {
            return ResultGenerator.message(400, "绑定异常：" + result.getMessage(), null);
        }
        return ResultGenerator.success();
    }

    @Override
    public Result matchMakeTrayRule(BindingDto bindingDto) {
//        String trayCode = bindingDto.getTrayCode();
//        if (StringUtils.isEmpty(trayCode)) {
//            return ResultGenerator.fail("托盘号不能为空");
//        }
//        //根据托盘查询单晶信息
//        TrayRuleDto trayRuleDto = new TrayRuleDto();
//        List<String> crystalNoByTrayNo = productionBindingTrayService.findCrystalNoByTrayNo(trayCode);
//        if (CollectionUtils.isEmpty(crystalNoByTrayNo)) {
//            return ResultGenerator.fail("托盘号绑定的单晶信息不存在！");
//        }
//        String crystalNo = crystalNoByTrayNo.get(0);
//        //查询晶棒信息
//        if (StringUtils.isEmpty(crystalNo)) {
//            return ResultGenerator.fail("托盘绑定对应的单晶编号为空！");
//        }
        String crystalNo = bindingDto.getSectionNo();
        if (StringUtils.isEmpty(crystalNo)) {
            return ResultGenerator.fail("单晶编号不能为空！");
        }
        TrayRuleDto trayRuleDto = new TrayRuleDto();
        //查询规格对应数据
        List<DictionaryItem> toMCSProductSpec = dictionaryItemService.findByThemeValueAndEnable("ToMCSProductSpec", true);
        Map<String, DictionaryItem> specMap = toMCSProductSpec.stream().collect(Collectors.toMap(DictionaryItem::getName, Function.identity(), (t1, t2) -> t1));
        Result<FbCheckOutData> fbCheckOutDataByFbSectionNo = fbFeignClients.findFbCheckOutDataByFbSectionNo(crystalNo);
        //查询MCS出库记录
        McsSquareInventoryLog mcsSquareInventoryLog = mcsSquareInventoryLogService.queryByCrystalNo(crystalNo, "out");
        //查询成品组托规则
        List<ProductAssemblyRule> productAssemblyRules = productAssemblyRuleService.queryRuleByOnePiece();
        if (fbCheckOutDataByFbSectionNo.getCode() != ResultCode.SUCCESS.getCode() || fbCheckOutDataByFbSectionNo.getData() == null) {
            return ResultGenerator.fail(crystalNo + "该晶棒对应的检验数据不存在！");
        }
        FbCheckOutData fbCheckOutData = fbCheckOutDataByFbSectionNo.getData();
        //todo 实际如果评级非正常的都入库
        if(null == fbCheckOutData.getGradeType() || "".equals(fbCheckOutData.getGradeType()) || (!"正常".equals(fbCheckOutData.getGradeType()) && !"反切".equals(fbCheckOutData.getGradeType()))){
            trayRuleDto.setHasGone(1);
            trayRuleDto.setJoinCount(fbCheckOutData.getSticksCount());
            trayRuleDto.setLength(fbCheckOutData.getLength());
            trayRuleDto.setSectionType(1);
            trayRuleDto.setSectionNo(crystalNo);
            trayRuleDto.setTrayName(new ArrayList<>());
            trayRuleDto.setConductionType(fbCheckOutData.getConductionType());
            trayRuleDto.setProductLevelFb(fbCheckOutData.getProductLevel());
            //记录整棒入库记录
            sendMcsSquareIn(trayRuleDto, fbCheckOutData, "in");
            return ResultGenerator.success(trayRuleDto);
        }


        // 判断是否是校验棒的场景，赋值逻辑: mcsSquareInventoryLog为空，入库；不为空，判断打包托位字段是否为空
        if (null != fbCheckOutData.getGradeType() && "校验棒".equals(fbCheckOutData.getGradeType())){
            //出库记录不为空
            if (null != mcsSquareInventoryLog){

                String packBox = mcsSquareInventoryLog.getPackBox();
                String[] split = packBox.split(",");
                //  打包托位不为空
                if(null != split && split.length > 0){
                    List<Integer> integers = new ArrayList<>();
                    for (String s : split) {
                        integers.add(Integer.valueOf(s));
                    }
                    trayRuleDto.setHasGone(2);
                    trayRuleDto.setTrayName(integers);
                }else {
                    // 打包托位为空，赋值
                    trayRuleDto.setHasGone(1);
                    trayRuleDto.setTrayName(new ArrayList<>());
                }
            }else {
                trayRuleDto.setHasGone(1);
                trayRuleDto.setTrayName(new ArrayList<>());
            }
            trayRuleDto.setSectionNo(crystalNo);
            trayRuleDto.setSpecification(fbCheckOutData.getSpecification());
            trayRuleDto.setLength(fbCheckOutData.getLength());
            trayRuleDto.setProductLevelFb(fbCheckOutData.getGradeType());
            trayRuleDto.setConductionType(fbCheckOutData.getConductionType());
            trayRuleDto.setSectionType(2);
            //记录整棒入库记录
            sendMcsSquareIn(trayRuleDto, fbCheckOutData, "in");
            return ResultGenerator.success(trayRuleDto);
        }

        //如果当前托盘上面的单晶在MCS出库记录存在，那么再次校验成品组托规则。如果不存在判断是不是标棒，是标棒再次校验成品组托规则是否符合要求，符合要求去要打托，否则入库。
        if (mcsSquareInventoryLog == null) {
            //没有找到出库数据需要在次判断是否符合整棒打托规则，如果符合就直发
            if (!CollectionUtils.isEmpty(productAssemblyRules)) {
                //判断单晶是否符合打托规则
                String specification = fbCheckOutData.getSpecification();
                String conductionType = fbCheckOutData.getConductionType();
                String productType = fbCheckOutData.getProductType();
                BigDecimal length = fbCheckOutData.getLength();
                String ybLevel = fbCheckOutData.getYbLevel();
                for (int i = 0; i < productAssemblyRules.size(); i++) {
                    ProductAssemblyRule productAssemblyRule = productAssemblyRules.get(i);
                    if (!productAssemblyRule.getSticksCount().equals("1")) {
                        continue;
                    }
                    String ruleConductionType = productAssemblyRule.getConductiveType();
                    String ruleProductType = productAssemblyRule.getProductType();
                    String ruleSpecs = productAssemblyRule.getSpecs();
                    String ruleProductGrade = productAssemblyRule.getProductGrade();
                    boolean lengthFlag = isLength(length, productAssemblyRule);
                    boolean judgmentSideLengthRangeFlag = judgmentSideLengthRange(productAssemblyRule, fbCheckOutData);
                    if (judgmentSideLengthRangeFlag && lengthFlag && StringUtils.equals(specification, ruleSpecs) && StringUtils.equals(conductionType, ruleConductionType) && ruleProductType.contains(productType) && StringUtils.equals(ybLevel, ruleProductGrade)) {
                        trayRuleDto.setHasGone(0);
                        trayRuleDto.setJoinCount(Integer.parseInt(productAssemblyRule.getSticksCount()));
                        trayRuleDto.setLength(length);
                        String issuePoint = productAssemblyRule.getIssuePoint();
                        String[] split = issuePoint.split(",");
                        List<Integer> integers = new ArrayList<>();
                        for (String s : split) {
                            integers.add(Integer.valueOf(s));
                        }
                        trayRuleDto.setTrayName(integers);
//                        trayRuleDto.setTrayName(Arrays.asList(Integer.parseInt(productAssemblyRule.getIssuePoint())));
                        trayRuleDto.setConductionType(productAssemblyRule.getConductiveType());
                        trayRuleDto.setProductLevelFb(productAssemblyRule.getProductGrade());
                        String specs = productAssemblyRule.getSpecs();
                        if (specMap.containsKey(specs)) {
                            trayRuleDto.setSpecification(specMap.get(specs).getValue());
                        } else {
                            trayRuleDto.setSpecification("0");
                        }
                        trayRuleDto.setSectionType(1);
                        trayRuleDto.setSectionNo(crystalNo);
                        trayRuleDto.setProductType(productType);
                        //记录整棒出库记录
                        sendMcsSquareIn(trayRuleDto, fbCheckOutData, "out");
                        return ResultGenerator.success(trayRuleDto);
                    }
                }
            }
            trayRuleDto.setHasGone(1);
            trayRuleDto.setJoinCount(fbCheckOutData.getSticksCount());
            trayRuleDto.setLength(fbCheckOutData.getLength());
            trayRuleDto.setSectionType(1);
            trayRuleDto.setSectionNo(crystalNo);
            trayRuleDto.setTrayName(new ArrayList<>());
            trayRuleDto.setConductionType(fbCheckOutData.getConductionType());
            trayRuleDto.setProductLevelFb(fbCheckOutData.getProductLevel());
            String specs = fbCheckOutData.getSpecification();
            if (specMap.containsKey(specs)) {
                trayRuleDto.setSpecification(specMap.get(specs).getValue());
            } else {
                trayRuleDto.setSpecification("0");
            }
            //记录整棒入库记录
            sendMcsSquareIn(trayRuleDto, fbCheckOutData, "in");
            return ResultGenerator.success(trayRuleDto);
        } else {
            //需要再次判断出库数据，是否符合打托规则，防止人为修改规则。
            String packBox = mcsSquareInventoryLog.getPackBox();
            String specification = mcsSquareInventoryLog.getSpecification();
            String sticksCount = mcsSquareInventoryLog.getSticksCount();
            String conductionType = mcsSquareInventoryLog.getConductionType();
            String productLevelFb = mcsSquareInventoryLog.getProductLevelFb();
            String productType = mcsSquareInventoryLog.getProductType();
            if (specMap.containsKey(specification)) {
                trayRuleDto.setSpecification(specMap.get(specification).getValue());
            } else {
                trayRuleDto.setSpecification("0");
            }
            trayRuleDto.setJoinCount(Integer.parseInt(sticksCount));
            trayRuleDto.setLength(new BigDecimal(mcsSquareInventoryLog.getLength()));

//            String[] split = packBox.split(",");
//            if(null != split && split.length > 0){
//                List<Integer> integers = new ArrayList<>();
//                for (String s : split) {
//                    integers.add(Integer.valueOf(s));
//                }
//                trayRuleDto.setTrayName(integers);
//            }else {
            trayRuleDto.setTrayName(new ArrayList<>());
//            }
            //trayRuleDto.setTrayName(Arrays.asList(Integer.parseInt(packBox)));
            trayRuleDto.setConductionType(conductionType);
            trayRuleDto.setProductLevelFb(productLevelFb);
            trayRuleDto.setSectionType(1);
            trayRuleDto.setSectionNo(crystalNo);
            trayRuleDto.setProductType(productType);
            //根据任务组号查询该单晶同一批的数据
            String groupId = mcsSquareInventoryLog.getGroupId();
            List<McsSquareInventoryLog> mcsSquareInventoryLogList = mcsSquareInventoryLogService.queryByGroupId(groupId);
            BigDecimal totalLen = BigDecimal.ZERO;
            if (!CollectionUtils.isEmpty(mcsSquareInventoryLogList)) {
                totalLen = mcsSquareInventoryLogList.stream().map(e -> e.getLength() == null ? BigDecimal.ZERO : new BigDecimal(e.getLength())).reduce(BigDecimal.ZERO, BigDecimal::add);
            } else {
                totalLen = fbCheckOutData.getLength();
            }
            // List<ProductAssemblyRule> productAssemblyRules1 = productAssemblyRuleService.queryRuleBySingel(packBox, specification, conductionType, productLevelFb, productType, sticksCount);
            //todo:重新用方棒检验数据库数据匹配规则
            // List<ProductAssemblyRule> productAssemblyRules = productAssemblyRuleService.queryRuleByOnePiece();
            ProductAssemblyRule productAssemblyRule1 = null;
            String fbSpecification = fbCheckOutData.getSpecification();
            String fbConductionType = fbCheckOutData.getConductionType();
            String fbProductType = fbCheckOutData.getProductType();
            BigDecimal fbLength = fbCheckOutData.getLength();
            String fbYbLevel = fbCheckOutData.getYbLevel();
            String packBox1 = "%" + packBox + "%";
            String productType1 = "%" + productType + "%";
            List<ProductAssemblyRule> productAssemblyRules1 = productAssemblyRuleService.queryRuleBySingel(packBox1, specification, conductionType, productLevelFb, productType1, sticksCount);
            List<ProductAssemblyRule> collect = productAssemblyRules1.stream().filter(productAssemblyRule -> productAssemblyRule.getSticksCount().equals(sticksCount)).collect(Collectors.toList());
            for (int i = 0; i < collect.size(); i++) {
                ProductAssemblyRule productAssemblyRule = collect.get(i);
                String ruleConductionType = productAssemblyRule.getConductiveType();
                String ruleProductType = productAssemblyRule.getProductType();
                String ruleSpecs = productAssemblyRule.getSpecs();
                String ruleProductGrade = productAssemblyRule.getProductGrade();
                boolean lengthFlag = isLength(totalLen, productAssemblyRule);
                boolean judgmentSideLengthRangeFlag = judgmentSideLengthRange(productAssemblyRule, fbCheckOutData);
                if (judgmentSideLengthRangeFlag && lengthFlag && StringUtils.equals(fbSpecification, ruleSpecs)
                        && StringUtils.equals(fbConductionType, ruleConductionType)
                        && ruleProductType.contains(fbProductType)
                        && StringUtils.equals(fbYbLevel, ruleProductGrade)) {
                    productAssemblyRule1 = productAssemblyRule;
                    break;
                }
            }
            Integer relationId = mcsSquareInventoryLog.getRelationId();
//            if(null == relationId || relationId < 1){
//                productAssemblyRule1 = null;
//            }

            if (null == productAssemblyRule1) {
                trayRuleDto.setHasGone(1);
                //记录整棒入库记录
                sendMcsSquareIn(trayRuleDto, fbCheckOutData, "in");
            } else {
                trayRuleDto.setHasGone(0);
                trayRuleDto.setJoinCount(Integer.parseInt(productAssemblyRule1.getSticksCount()));
                trayRuleDto.setLength(fbLength);
                String issuePoint = productAssemblyRule1.getIssuePoint();
                String[] split1 = issuePoint.split(",");
                List<Integer> integers = new ArrayList<>();

                List<McsSquareInventoryLog> mcsSquareInventoryLogs = mcsSquareInventoryLogService.queryAllByCrystalNo(crystalNo);
                int count = 0;
                if (!CollectionUtils.isEmpty(mcsSquareInventoryLogs)) {
                    for (McsSquareInventoryLog squareInventoryLog : mcsSquareInventoryLogs) {
                        if (!StringUtils.isEmpty(squareInventoryLog.getCreateUser()) && squareInventoryLog.getCreateUser().equals("mcs")) {
                            count++;
                        }
                    }
                }
                //mcs出库的才走这套逻辑，否则正常逻辑
                if (count > 0 && null != relationId && !sticksCount.equals("1")) {
                    for (String s : split1) {
                        //relationId：2：一标段方棒库（北），3：一标段方棒库（南），5：二标段方棒库（北），6：二标段方棒库（南）
                        //点位开头：1开头是南，2是北 3是南，4是北
                        if ((mcsSquareInventoryLog.getRelationId() == 2 || mcsSquareInventoryLog.getRelationId() == 5) && (s.startsWith("2") || s.startsWith("4"))) {
                            integers.add(Integer.valueOf(s));
                            break;
                        }
                        if ((mcsSquareInventoryLog.getRelationId() == 3 || mcsSquareInventoryLog.getRelationId() == 6) && (s.startsWith("1") || s.startsWith("3"))) {
                            integers.add(Integer.valueOf(s));
                            break;
                        }
                        if (integers.size() < 1 && !sticksCount.equals("1")) {
                            integers.add(Integer.valueOf(s));
                            break;
                        }
                    }
                } else {
                    if (sticksCount.equals("1")) {
                        for (String s : split1) {
                            integers.add(Integer.valueOf(s));
                        }
                    } else {
                        for (String s : split1) {
                            integers.add(Integer.valueOf(s));
                            break;
                        }
                    }
                }
                trayRuleDto.setTrayName(integers);
//                        trayRuleDto.setTrayName(Arrays.asList(Integer.parseInt(productAssemblyRule.getIssuePoint())));
                trayRuleDto.setConductionType(productAssemblyRule1.getConductiveType());
                trayRuleDto.setProductLevelFb(productAssemblyRule1.getProductGrade());
                String specs = productAssemblyRule1.getSpecs();
                if (specMap.containsKey(specs)) {
                    trayRuleDto.setSpecification(specMap.get(specs).getValue());
                } else {
                    trayRuleDto.setSpecification("0");
                }
                trayRuleDto.setSectionType(1);
                trayRuleDto.setSectionNo(crystalNo);
                trayRuleDto.setProductType(fbProductType);
                //更新整棒出库记录
                McsSquareInventoryLog inventoryLog = new McsSquareInventoryLog();
                String sectionNo = trayRuleDto.getSectionNo();
                inventoryLog.setId(mcsSquareInventoryLog.getId());
                inventoryLog.setCrystalNo(sectionNo);
                inventoryLog.setPackBox(trayRuleDto.getTrayName().stream().map((t) -> {
                    return String.valueOf(t);
                }).collect(Collectors.joining(",")));
                inventoryLog.setProductLevelFb(trayRuleDto.getProductLevelFb());
                inventoryLog.setProductType(trayRuleDto.getProductType());
                inventoryLog.setSpecification(specs);
                inventoryLog.setSticksCount(trayRuleDto.getJoinCount().toString());
                inventoryLog.setInventoryType("out");
                inventoryLog.setCreateTime(new Date());
                inventoryLog.setDelFlag(0);
                inventoryLog.setRelationId(mcsSquareInventoryLog.getRelationId());
                inventoryLog.setCreateUser("FLS");
                inventoryLog.setCreateTime(new Date());
                inventoryLog.setLength(String.valueOf(trayRuleDto.getLength()));
                inventoryLog.setConductionType(trayRuleDto.getConductionType());
                inventoryLog.setGroupId(groupId);
                mcsSquareInventoryLogService.saveOrUpdate(inventoryLog);

            }
            return ResultGenerator.success(trayRuleDto);
        }
    }

    @Override
    public Result matchMakeTrayRuleV2(BindingDto bindingDto) {
        TrayRuleDto trayRuleDto = new TrayRuleDto();
        try {
            String crystalNo = bindingDto.getSectionNo();
            // 默认给NG
            trayRuleDto.setHasGone(1);
            if (StringUtils.isEmpty(crystalNo)) {
                trayRuleDto.setErrorMessage("单晶编号不能为空");
                return ResultGenerator.success(trayRuleDto);
            }

            trayRuleDto.setSectionNo(crystalNo);
            Result<FbCheckOutData> fbCheckOutDataByFbSectionNo = fbFeignClients.findFbCheckOutDataByFbSectionNo(crystalNo);
            //查询成品组托规则
            List<ProductAssemblyRule> productAssemblyRules = productAssemblyRuleService.queryRuleByOnePiece();
            if (fbCheckOutDataByFbSectionNo.getCode() != ResultCode.SUCCESS.getCode() || fbCheckOutDataByFbSectionNo.getData() == null) {
                trayRuleDto.setErrorMessage("该晶棒对应的方棒检验数据不存在！");
                return ResultGenerator.success(trayRuleDto);
            }
            //查询规格对应数据
            List<DictionaryItem> toMCSProductSpec = dictionaryItemService.findByThemeValueAndEnable("ToMCSProductSpec", true);
            Map<String, DictionaryItem> specMap = toMCSProductSpec.stream().collect(Collectors.toMap(DictionaryItem::getName, Function.identity(), (t1, t2) -> t1));
            FbCheckOutData fbCheckOutData = fbCheckOutDataByFbSectionNo.getData();
            boolean flag = false;
            //判断单晶是否符合打托规则
            String specification = fbCheckOutData.getSpecification();
            String conductionType = fbCheckOutData.getConductionType();
            String productType = fbCheckOutData.getProductType();
            BigDecimal length = fbCheckOutData.getLength();
            String ybLevel = fbCheckOutData.getYbLevel();
            List<Integer> integers = new ArrayList<>();
            if (specMap.containsKey(specification)) {
                trayRuleDto.setSpecification(specMap.get(specification).getValue());
            } else {
                trayRuleDto.setSpecification("0");
            }
//        trayRuleDto.setSectionType(1);
            trayRuleDto.setSectionNo(crystalNo);
            trayRuleDto.setProductType(productType);
            trayRuleDto.setConductionType(conductionType);
            trayRuleDto.setProductLevelFb(ybLevel);
            trayRuleDto.setLength(length);
            if (!CollectionUtils.isEmpty(productAssemblyRules)) {
                for (int i = 0; i < productAssemblyRules.size(); i++) {
                    ProductAssemblyRule productAssemblyRule = productAssemblyRules.get(i);
//                if (!productAssemblyRule.getSticksCount().equals("1")) {
//                    continue;
//                }
                    String ruleConductionType = productAssemblyRule.getConductiveType();
                    String ruleSpecs = productAssemblyRule.getSpecs();
                    String ruleProductGrade = productAssemblyRule.getProductGrade();
                    boolean lengthFlag = isLength(length, productAssemblyRule);
                    boolean judgmentSideLengthRangeFlag = judgmentSideLengthRangeV2(productAssemblyRule, fbCheckOutData);
                    boolean judgmentProductTypeFlag = judgmentProductType(productAssemblyRule, fbCheckOutData);
                    boolean conductionTypeFlag = StringUtils.equals(conductionType, ruleConductionType);
//                boolean ybLevelFlag = StringUtils.equals(ybLevel, ruleProductGrade);
                    boolean specificationFlag = StringUtils.equals(specification, ruleSpecs);
                    boolean ybLevelFlag = judgmentYbLevel(productAssemblyRule, fbCheckOutData);
                    if (judgmentSideLengthRangeFlag && judgmentProductTypeFlag && lengthFlag && specificationFlag
                            && conductionTypeFlag && ybLevelFlag) {
                        int sticksCount = NumberUtil.Object2Integer(productAssemblyRule.getSticksCount(), 4);
                        trayRuleDto.setJoinCount(sticksCount);
                        String issuePoint = productAssemblyRule.getIssuePoint();
                        trayRuleDto.setHasGone(0);
                        String[] split = issuePoint.split(",");
                        for (String s : split) {
                            integers.add(Integer.valueOf(s));
                        }
                        trayRuleDto.setTrayName(integers);
//                    trayRuleDto.setTrayName(Arrays.asList(Integer.parseInt(productAssemblyRule.getIssuePoint())));
                        flag = true;
                        break;
                    }
                }
            } else {
                trayRuleDto.setErrorMessage("打托成品组托规则不存在！");
                return ResultGenerator.success(trayRuleDto);
            }
            if (!flag) {
                integers.add(-1);
                trayRuleDto.setTrayName(integers);
            }
        } catch (Exception e){
            e.printStackTrace();
            trayRuleDto.setErrorMessage(e.getMessage());
        }
        return ResultGenerator.success(trayRuleDto);
    }



    private void sendMcsSquareIn(TrayRuleDto trayRuleDto, FbCheckOutData fbCheckOutData, String inventoryType) {
        //记录整棒入库记录
        TrayRuleDto inTrayRuleDto = new TrayRuleDto();
        BeanUtil.copyProperties(inTrayRuleDto, trayRuleDto);
        inTrayRuleDto.setSpecification(fbCheckOutData.getSpecification());
        handlerInventoryLog(inTrayRuleDto, inventoryType);

    }

    private void handlerInventoryLog(TrayRuleDto trayRuleDto, String inventoryType) {
        if (!StringUtils.isEmpty(trayRuleDto.getSectionNo()) && StringUtils.equals(inventoryType,"in")) {
            mcsSquareInventoryLogService.updateInventoryType(trayRuleDto.getSectionNo(),"del-out","out");
            mcsSquareInventoryLogService.updateInventoryType(trayRuleDto.getSectionNo(),"del-in","in");
        }
        McsSquareInventoryLog inventoryLog = new McsSquareInventoryLog();
        String sectionNo = trayRuleDto.getSectionNo();
        inventoryLog.setCrystalNo(sectionNo);
        inventoryLog.setPackBox(trayRuleDto.getTrayName().stream().map((t) -> {
            return String.valueOf(t);
        }).collect(Collectors.joining(",")));
        inventoryLog.setProductLevelFb(trayRuleDto.getProductLevelFb());
        inventoryLog.setProductType(trayRuleDto.getProductType());
        inventoryLog.setSpecification(trayRuleDto.getSpecification());
        inventoryLog.setSticksCount(trayRuleDto.getJoinCount().toString());
        inventoryLog.setInventoryType(inventoryType);
        inventoryLog.setCreateTime(new Date());
        inventoryLog.setDelFlag(0);
        inventoryLog.setCreateUser("FLS");
        inventoryLog.setCreateTime(new Date());
        inventoryLog.setLength(String.valueOf(trayRuleDto.getLength()));
        inventoryLog.setConductionType(trayRuleDto.getConductionType());
        mcsSquareInventoryLogService.saveOrUpdate(inventoryLog);
    }

    @Override
    public Result suspendTrayRule(List<McsFbInventoryDto> fbInventoryDto) {
        try {
            mcsSquareInventoryLogService.deleteByCrystalNoList(fbInventoryDto);
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
        return ResultGenerator.success();
    }

    @Override
    public Result queryMcsSquareLog(BindingDto bindingDto) {
        return ResultGenerator.success(mcsSquareInventoryLogService.queryMcsSquareLog(bindingDto));
    }

    @Override
    public Result<List<SectionRecycledResultDto>> sendSectionForInfo(SectionRequestDto gainSectionRequestDto) {

        return ResultGenerator.success(headTailMaterialRuleService.findHeadTailMaterialRuleBySection(gainSectionRequestDto));
    }

    @Override
    public Result recycledMaterialUpload(RecycledMaterialUploadDto recycledMaterialUploadDto) {
        RecycledMaterialManage recycledMaterialInfo = new RecycledMaterialManage();

        //生成新的批次号和托号
        String batchNoForFls = creatProduceBatchNoForFls(recycledMaterialUploadDto);
        String trayNo = creatTrayNoForFls(recycledMaterialUploadDto);

        //追溯标识赋值
        if (!batchNoForFls.isEmpty()&& batchNoForFls.length()>=2){
            recycledMaterialInfo.setFromMark(batchNoForFls.substring(ReclaimedMaterialsEnum.追溯标识.getBeginIndex(),ReclaimedMaterialsEnum.追溯标识.getEndIndex()));
        }
        recycledMaterialInfo.setWeight(recycledMaterialUploadDto.getWeight());
        String materialName = StringUtils.trim(recycledMaterialUploadDto.getRecoveryName() + recycledMaterialUploadDto.getMaterialName());
        //查询物料主数据
        String materialCode = materialModelService.findCodeByName(materialName);
        recycledMaterialInfo.setRecycledMaterialType("可用回收料");
        recycledMaterialInfo.setMaterialName(recycledMaterialUploadDto.getMaterialName());
        recycledMaterialInfo.setMaterialCode(recycledMaterialUploadDto.getMaterialCode());
        recycledMaterialInfo.setCreateBy("fls");
        recycledMaterialInfo.setCreateTime(new Date());
        recycledMaterialInfo.setSource("截断及开方");
        recycledMaterialInfo.setProductionCategory(recycledMaterialUploadDto.getProductType());
        recycledMaterialInfo.setGrade(recycledMaterialUploadDto.getProductGrade());
        recycledMaterialInfo.setNum(0);
        recycledMaterialInfo.setUnitName("公斤");
        recycledMaterialInfo.setGear(recycledMaterialUploadDto.getMaterialGear());
        recycledMaterialInfo.setFactory(recycledMaterialUploadDto.getArea());

        //批次号
        recycledMaterialInfo.setProduceBatchNo(batchNoForFls);
        //托号
        recycledMaterialInfo.setTrayNo(trayNo);

        recycledMaterialInfo.setStatus(4);
        recycledMaterialInfo.setBoxNo(recycledMaterialUploadDto.getBoxNo());
        recycledMaterialInfo.setSpecification(recycledMaterialUploadDto.getDopant());
        recycledMaterialManageService.saveOrUpdate(recycledMaterialInfo);
        //新增详情
        List<RecycledMaterialManageDetail> recycledMaterialManageDetails = bulidRecycledList(recycledMaterialUploadDto, recycledMaterialInfo);
        recycledMaterialManageDetailService.saveAll(recycledMaterialManageDetails);

        //回收料管理的数据存到清洗待领料表中
        MaterialStoreSignBoxDto materialStoreSignBoxDto = buildMaterialStoreSignBoxDto(recycledMaterialUploadDto, recycledMaterialInfo);
        //todo 晶编Fls 增加字段
        materialCleanFeignClients.create(materialStoreSignBoxDto);
        //todo:根据发送到wms过账是否成功判断状态: 1 待入库,4已接收,
        // 增加卡板箱,点位等属性(需要在清洗待领料表中增加)!
        //2023-10-11 优化为清洗回收料领料时候 wms入库/过账
//        RecycledMaterialInDto recycledMaterialInDto = buildRecycledMaterialInDto(recycledMaterialInfo);

//        String url = wmsServiceUrl + recycleToWms;
//        try {
//            ResultWms resultJson = requestRecycleMaterialToWMS(url, recycledMaterialInDto, "fls上传mes可回收料重量过账到WMS");
//            if (null != resultJson) {
//                if (!resultJson.getCode().equals("1")) {
//                    log.info("回收料托号:{}过账到wms失败", recycledMaterialInfo.getTrayNo());
//                    throw new BusinessException("fls上传mes可回收料重量过账到WMS失败,请求接口失败");
//                } else {
//                    recycledMaterialInfo.setStatus(4);
//                }
//            } else {
//                log.info("回收料托号:{}过账到wms异常", recycledMaterialInfo.getTrayNo());
//                throw new BusinessException("fls上传mes可回收料重量过账到WMS失败,请求接口异常");
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//            log.error("fls上传mes可回收料重量过账到WMS: ", e);
//        }

        return ResultGenerator.success();
    }



    /**
     * 封装由回收料生成的清洗待领料信息
     * @param recycledMaterialUploadDto
     * @param recycledMaterialInfo
     * @return
     */
    private MaterialStoreSignBoxDto buildMaterialStoreSignBoxDto(RecycledMaterialUploadDto recycledMaterialUploadDto,RecycledMaterialManage recycledMaterialInfo) {

        //称重后回收料管理的数据同步存到清洗待领料表中
        MaterialCleanModel materialCleanModel = materialCleanModelService.findByCode(recycledMaterialUploadDto.getMaterialCode());

        MaterialStoreSignBoxDto materialStoreSignBoxDto = new MaterialStoreSignBoxDto();
        //托号和批次号
        materialStoreSignBoxDto.setProductBatchNo(recycledMaterialInfo.getProduceBatchNo());
        materialStoreSignBoxDto.setTrayNo(recycledMaterialInfo.getTrayNo());
        materialStoreSignBoxDto.setMaterialType(2);
        materialStoreSignBoxDto.setPickingStatus(0);
        //卡板箱码当做待领料箱码
        materialStoreSignBoxDto.setBoxNo(recycledMaterialUploadDto.getBoxNo());
        materialStoreSignBoxDto.setMaterialModel(recycledMaterialInfo.getSpecification());
        materialStoreSignBoxDto.setWeight(recycledMaterialInfo.getWeight());
        materialStoreSignBoxDto.setMaterialCode(recycledMaterialInfo.getMaterialCode());
        materialStoreSignBoxDto.setMaterialName(recycledMaterialInfo.getMaterialName());
        materialStoreSignBoxDto.setMaterialLevel(recycledMaterialInfo.getGrade());
        materialStoreSignBoxDto.setMaterialModel(recycledMaterialInfo.getSpecification());
        materialStoreSignBoxDto.setMaterialGear(recycledMaterialInfo.getGear());
        materialStoreSignBoxDto.setCreateUser(recycledMaterialInfo.getCreateBy());
        materialStoreSignBoxDto.setCreateTime(Instant.ofEpochMilli(new Date().getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime());
        materialStoreSignBoxDto.setUpdateUser(recycledMaterialInfo.getUpdateBy());
        materialStoreSignBoxDto.setUpdateTime(Instant.ofEpochMilli(new Date().getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime());
        materialStoreSignBoxDto.setAufnr(recycledMaterialInfo.getErpOrder());
        return materialStoreSignBoxDto;
    }



    /**
     * 封装回收料详情
     * @param recycledMaterialUploadDto
     * @param recycledMaterialInfo
     * @return
     */
    public List<RecycledMaterialManageDetail> bulidRecycledList(RecycledMaterialUploadDto recycledMaterialUploadDto, RecycledMaterialManage recycledMaterialInfo) {

        ArrayList<RecycledMaterialManageDetail> recycledMaterialManageDetails = new ArrayList<>();
        if (null != recycledMaterialUploadDto.getSectionNo() && !"".equals(recycledMaterialUploadDto.getSectionNo())) {

            List<String> sectionNos = Arrays.asList(recycledMaterialUploadDto.getSectionNo().split(","));

            for (String sectionNo : sectionNos) {
                RecycledMaterialManageDetail recycledMaterialManageDetail = new RecycledMaterialManageDetail();
                recycledMaterialManageDetail.setRecycleNo(sectionNo);
                recycledMaterialManageDetail.setBoxNo(recycledMaterialUploadDto.getBoxNo());
                recycledMaterialManageDetail.setBracketNo(recycledMaterialUploadDto.getBracketNo());
                recycledMaterialManageDetail.setProductionType(recycledMaterialUploadDto.getProductType());
                recycledMaterialManageDetail.setProductLevel(recycledMaterialUploadDto.getProductGrade());
                recycledMaterialManageDetail.setManageId(recycledMaterialInfo.getId());
                //追溯标识
                recycledMaterialManageDetail.setFromMark(recycledMaterialInfo.getFromMark());
                recycledMaterialManageDetail.setStatus(1);
                recycledMaterialManageDetails.add(recycledMaterialManageDetail);
            }

        }
        return recycledMaterialManageDetails;
    }




    /**
     * 新托号生成方法20231014，按照新规则生成14位
     * @param recycledMaterialUploadDto
     * @return
     */
    private String creatTrayNoForFls(RecycledMaterialUploadDto recycledMaterialUploadDto) {
        //批次号加三位流水号
        String produceBatchNo = creatProduceBatchNoForFls(recycledMaterialUploadDto);
        String key = "FLSshengchengpicihaoNew";
        String serialNumber = genSerialNumber(key);
        return produceBatchNo + serialNumber;
    }


    /**
     * 生成当日3位流水号-10进制3位
     *
     * @return
     */
    public String genSerialNumber(String key) {
        String serialNumber = redisTemplate.opsForValue().get(key);
        log.info("生成编码前缀:{},当前完整编码:{}", key, serialNumber);
        if(StringUtils.isBlank(serialNumber)){

            RLock rLock = RedissonUtils.getRLock(redissonClient, "&" + key);
            if (RedissonUtils.getRLockExpireTime(rLock, 5L)){
                try {
                    serialNumber="1";
                    redisTemplate.opsForValue().set(key, serialNumber, redisKeyExpireTime(), TimeUnit.SECONDS);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                } finally {
                    rLock.unlock();
                }
            }else {
                throw new RuntimeException("流水号初始化中, 请稍后再试");
            }

        } else {

            Long increment = redisTemplate.opsForValue().increment(key);
            redisTemplate.expire(key, redisKeyExpireTime(), TimeUnit.SECONDS);
            serialNumber = Convert.toStr(increment);
            log.info("生成编码前缀:{},重置后的完整编码:{}", key, serialNumber);
        }

        int sequence = Convert.toInt(serialNumber);
        String strSequence = Convert.toStr(sequence);
        if (sequence < 1000) {
            strSequence = StringUtils.leftPad(strSequence, 3, "0");
        } else {
            //strSequence = Integer.toHexString(sequence);
            //if (strSequence.length() > 4){
            throw new RuntimeException("生成 生产批次号的流水号超出3位，无法生成！");
            // }
        }
        return strSequence;
    }


    //8点半之后自动删除当前key
    private int redisKeyExpireTime() {
        Calendar calendar = Calendar.getInstance();
        //判断当前时间时分秒是否大于8:30
        if (timeCompare("08:30:00")) {
            calendar.add(Calendar.DAY_OF_YEAR, 1);
        }
        calendar.set(Calendar.HOUR_OF_DAY, 8);
        calendar.set(Calendar.MINUTE, 30);
        calendar.set(Calendar.SECOND, 0);
        long expireTime = ((calendar.getTimeInMillis() - System.currentTimeMillis()) / 1000);
        return (int) expireTime;
    }


    public static boolean timeCompare(String time) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
        LocalTime localTime = LocalTime.parse(time, dateTimeFormatter);
        return LocalTime.now().isAfter(localTime);
    }


    /**
     * 新批次号生成规则
     * @param recycledMaterialUploadDto
     * @return
     */
    private String creatProduceBatchNoForFls(RecycledMaterialUploadDto recycledMaterialUploadDto){
        //================新写逻辑   追溯标识、型号NP、日期年月日、硅料等级、硅料代码、电阻档位、车间代码
        String produceBatchNo = "";
//        String fromMarkAndCzxh = ""; //溯源标识 和 掺杂 N/P型号
        String fromMark = "";//追溯标识
        String czxh = "";    // 掺杂 N/P型号
        String sectionNos = recycledMaterialUploadDto.getSectionNo();
        if (null != sectionNos && !StringUtils.isEmpty(sectionNos)) {
            String[] sectionsArray = sectionNos.split(",");
            String section = sectionsArray[0];
//            fromMarkAndCzxh = section.substring(1,3);
            fromMark = section.substring(SectionIndexRangeEnum.追溯标识.getBeginIndex(), SectionIndexRangeEnum.追溯标识.getEndIndex());

        }
        String gldm = "";   // 硅料代码
        String grade = "";  //等级
//        List<MaterialCleanModel> materialCleanModels = materialCleanModelService.findByName(recycledMaterialUploadDto.getMaterialName());
        List<MaterialCleanModel> materialCleanModels = materialCleanModelService.findByNameAccurate(recycledMaterialUploadDto.getMaterialName());
        if (null != materialCleanModels && materialCleanModels.size()>0){
            MaterialCleanModel materialCleanModel = materialCleanModels.get(0);
            if (!StringUtils.isEmpty(materialCleanModel.getSiliconCode()) && !StringUtils.isEmpty(materialCleanModel.getDopedTypeCode()) ){
                gldm = materialCleanModel.getSiliconCode();
                grade = materialCleanModel.getLevel();
                czxh = materialCleanModel.getDopedTypeCode();
            }
        }
        //四位时间
        String time = dateStringNew();
        //档位
        String gear = recycledMaterialUploadDto.getMaterialGear();
        // todo 车间代码 暂时写死
//        String factory = recycledMaterialUploadDto.getArea();
        String factory = String.valueOf(CleanFactoryCodeEnum.机加车间.getKey());
        produceBatchNo = fromMark+czxh+time+grade+gldm+gear+factory;
        return produceBatchNo;
    }





    /**
     * 获取日期 例如： 年份：22年
     *               月份：1-9月用数字表示，10-12月用A/B/C表示
     *               日期：1-31号
     *               22A23  --  22年10月23日
     * @return
     */
    private String dateStringNew(){
        Calendar instance = Calendar.getInstance();
        instance.setTime(new Date());
        String yearAll = Convert.toStr(instance.get(Calendar.YEAR));
        //取最后一位
        String strYear = yearAll.substring(yearAll.length() - 1);
        int intMonth = instance.get(Calendar.MONTH) + 1;
        String strMonth = Convert.toStr(intMonth);
        if (intMonth>9){
            switch (intMonth){
                case 10:
                    strMonth="A";
                    break;
                case 11:
                    strMonth="B";
                    break;
                case 12:
                    strMonth="C";
                    break;
            }
        }
        String strDay = Convert.toStr(instance.get(Calendar.DAY_OF_MONTH));
        //给 1月3日 补充0；3 -> 03
        String supplementZeroStrDay = StringUtils.leftPad(strDay, 2, "0");
        return strYear + strMonth + supplementZeroStrDay;
    }



    /**
     * 生成回收料托标
     *
     * @param recycledMaterialManageDto
     * @return
     */
    private String creatTrayNo(RecycledMaterialManage recycledMaterialManageDto) {
        //厂区车间
        //String factory = recycledMaterialManageDto.getFactory();
        //todo:暂时三期写死 3
        String factory = "3";
        if (StringUtils.isNotBlank(recycledMaterialManageDto.getProductionCategory())) {
            factory = factory + "-" + recycledMaterialManageDto.getProductionCategory();
        }
        String today = LocalDate.now().toString();
        String key = "(" + factory + ")" + today;
        Integer times = recycledMaterialManageService.countTimeByParam(key) + 1;
        String materialName = recycledMaterialManageDto.getMaterialName();
        String grade = recycledMaterialManageDto.getGrade();
        if (StringUtils.isNotBlank(recycledMaterialManageDto.getGear())) {
            grade = grade + "-" + recycledMaterialManageDto.getGear();
        }
        String materialTypeValue = null;
        if (StringUtils.isBlank(materialName)) {
            throw new BusinessException("请输入物料名称!");
        } else {
            materialTypeValue = dictionaryItemService.findValueByThemeValueAndItemName("ReduceTypeName", materialName);
        }
        //String sheetStock = recycledMaterialManageDto.getSheetStock();
        String trayNo = key + "/" + times + materialTypeValue + "(" + grade + ")";
        return trayNo;
    }
    /**
     * 封装可回收料数据
     *
     * @param recycledMaterialManageDto
     * @return
     */
    private RecycledMaterialInDto buildRecycledMaterialInDto(RecycledMaterialManage recycledMaterialManageDto) {
        RecycledMaterialInDto recycledMaterialInDto = new RecycledMaterialInDto();
        recycledMaterialInDto.setBatchNo(recycledMaterialManageDto.getTrayNo());
        recycledMaterialInDto.setInQty(recycledMaterialManageDto.getWeight());
        recycledMaterialInDto.setLevelID(recycledMaterialManageDto.getGrade());
        if (recycledMaterialManageDto.getRecycledMaterialType().equals("可回收料")) {
            recycledMaterialInDto.setMaterialClassID("3");
        } else {
            recycledMaterialInDto.setMaterialClassID("1");
        }
        recycledMaterialInDto.setMaterialNo(recycledMaterialManageDto.getMaterialCode());
        recycledMaterialInDto.setOperateDT(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
        recycledMaterialInDto.setOperator(BaseContextHandler.getUsername());
        recycledMaterialInDto.setOutQty(recycledMaterialManageDto.getWeight());
        recycledMaterialInDto.setPlanNo(recycledMaterialManageDto.getTrayNo());
        recycledMaterialInDto.setRemark(null);
        recycledMaterialInDto.setSpecification(recycledMaterialManageDto.getSpecification());
        recycledMaterialInDto.setUnit(recycledMaterialManageDto.getUnitName());
        return recycledMaterialInDto;
    }


    private ResultWms requestRecycleMaterialToWMS(String url, RecycledMaterialInDto recycledMaterialInDto, String requestName) {
        String resultJson;
        boolean isErr = false;
        try {
            HttpHeaders headers = new HttpHeaders();
            MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
            headers.setContentType(mediaType);
            headers.add("Accept", MediaType.APPLICATION_JSON.toString());
            List<RecycledMaterialInDto> recycledMaterialInDtos = new ArrayList<>();
            recycledMaterialInDtos.add(recycledMaterialInDto);
            HttpEntity<List<RecycledMaterialInDto>> httpEntity = new HttpEntity<>(recycledMaterialInDtos, headers);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
            resultJson = responseEntity.getBody();
        } catch (Exception e) {
            e.printStackTrace();
            resultJson = e.getMessage();
            isErr = true;
        }
        try {
            SysLog syslog = new SysLog();
            syslog.setCreateTime(new Date());
            syslog.setType("info");
            syslog.setCreateUserId(BaseContextHandler.getUserID());
            syslog.setCreateUserName("SYSTEM");
            syslog.setContent(JSON.toJSONString(recycledMaterialInDto));
            syslog.setResult(resultJson);
            syslog.setMethodName("requestRecycleMaterialToWMS()");
            syslog.setStatus(1);
            syslog.setName(requestName);
            syslog.setServerAddr(url);
            syslog.setReqType("HTTP");
            syslog.setReqIp(IpUtils.getLocalIP());
            sysLogService.save(syslog);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (isErr) {
            return null;
        } else {
            return JSON.parseObject(resultJson, new TypeReference<ResultWms>() {
            });
        }

    }

    private boolean isLength(BigDecimal crystalLength, ProductAssemblyRule productAssemblyRule) {
        boolean flag = false;
        String ruleLength = productAssemblyRule.getLength();
        BigDecimal shortestLength = productAssemblyRule.getShortestLength();
//        int sticksCount = Integer.parseInt(productAssemblyRule.getSticksCount());
        int sticksCount = NumberUtil.Object2Integer(productAssemblyRule.getSticksCount(),4);
        if (null != crystalLength) {
            String[] lengths = ruleLength.split("-");
            if (lengths.length != 2) {
                return flag;
            }
            BigDecimal minLength = new BigDecimal(lengths[0]);
            BigDecimal maxLength = new BigDecimal(lengths[1]);
            if (sticksCount > 1) {
                minLength = shortestLength;
            }
            if (crystalLength.compareTo(minLength) >= 0 && maxLength.compareTo(crystalLength) >= 0) {
                flag = true;
            }
        }
        return flag;

    }


    /**
     * 判断边长是否相同
     * @param productAssemblyRule
     * @param fbCheckOutData
     * @return
     */
    private boolean judgmentSideLengthRange(ProductAssemblyRule productAssemblyRule, FbCheckOutData fbCheckOutData) {
        boolean flag = false;
        String sideLengthRange = productAssemblyRule.getSideLengthRange();
        //判断边长
        if (null != sideLengthRange && !"".equals(sideLengthRange)) {
            if (null != fbCheckOutData.getSideLengthRange() && !"".equals(fbCheckOutData.getSideLengthRange()) && !sideLengthRange.equals(fbCheckOutData.getSideLengthRange())) {
                flag = false;
            } else {
                flag = true;

            }
        } else {
            flag = true;
        }
        return flag;
    }

    private boolean judgmentSideLengthRangeV2(ProductAssemblyRule productAssemblyRule, FbCheckOutData fbCheckOutData) {
        boolean flag = false;
        String sideLengthRange = productAssemblyRule.getSideLengthRange();
        String sideLengthRangeFb = fbCheckOutData.getSideLengthRange();
        if(!StringUtils.isEmpty(sideLengthRange) && !StringUtils.isEmpty(sideLengthRangeFb)){
            if(sideLengthRange.equals(sideLengthRangeFb)){
                flag = true;
            }
        }
        return flag;
    }

    private boolean judgmentProductType(ProductAssemblyRule productAssemblyRule, FbCheckOutData fbCheckOutData) {
        boolean flag = false;
        String productType = productAssemblyRule.getProductType();
        String productTypeFb = fbCheckOutData.getProductType();
        if(!StringUtils.isEmpty(productType) && !StringUtils.isEmpty(productTypeFb)){
            String[] split = productType.split(",");
            for (int i = 0; i < split.length; i++) {
                if(split[i].equals(productTypeFb)){
                    flag = true;
                    break;
                }
            }
        }
        return flag;
    }

    private boolean judgmentYbLevel(ProductAssemblyRule productAssemblyRule, FbCheckOutData fbCheckOutData) {
        boolean flag = false;
        String productGrade = productAssemblyRule.getProductGrade();
        String ybLevel = fbCheckOutData.getYbLevel();
        if(!StringUtils.isEmpty(productGrade) && !StringUtils.isEmpty(ybLevel)){
            String[] split = productGrade.split(",");
            for (int i = 0; i < split.length; i++) {
                if(split[i].equals(ybLevel)){
                    flag = true;
                    break;
                }
            }
        }
        return flag;
    }
}
