package com.sw.mes.plan.service.impl;

import com.alibaba.fastjson.JSON;
import com.sw.mes.base.factory.init.entity.Equipment;
import com.sw.mes.base.factory.init.entity.MachineCapacity;
import com.sw.mes.base.factory.init.entity.MachineCapacityKf;
import com.sw.mes.base.factory.init.service.EquipmentService;
import com.sw.mes.base.factory.init.service.MachineCapacityKfService;
import com.sw.mes.base.factory.init.service.MachineCapacityKfinfoService;
import com.sw.mes.base.factory.product.entity.FbProductModel;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.core.base.BaseServiceImpl;
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.RankResultDto;
import com.sw.mes.core.enums.EnumValues;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.utils.NumberUtil;
import com.sw.mes.enumvalue.EnumValuesFbServer;
import com.sw.mes.fb.utils.StringUtils;
import com.sw.mes.plan.dao.FbProductionScheduleDao;
import com.sw.mes.plan.dto.BatchSchedulingDto;
import com.sw.mes.plan.dto.ProductionOrderCountDto;
import com.sw.mes.plan.dto.SchedulingInfoDto;
import com.sw.mes.plan.entity.FbOrderMatchingInfo;
import com.sw.mes.plan.entity.FbProductionOrder;
import com.sw.mes.plan.entity.FbProductionSchedule;
import com.sw.mes.plan.service.FbOrderMatchingInfoService;
import com.sw.mes.plan.service.FbProductionOrderService;
import com.sw.mes.plan.service.FbProductionScheduleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;

;
;

/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Transactional
@Service
@Slf4j
public class FbProductionScheduleServiceImpl extends BaseServiceImpl<FbProductionSchedule> implements FbProductionScheduleService {
    FbProductionScheduleDao dao;

    @Autowired
    public void setDao(FbProductionScheduleDao dao) {
        super.setBaseDao(dao);
        this.dao = dao;
    }

    @Autowired
    private EquipmentService equipmentService;

    @Autowired
    private MachineCapacityKfService machineCapacityKfService;

    @Autowired
    private FbProductionOrderService productionOrderService;

    @Autowired
    private DictionaryItemService dictionaryItemService;

    @Override
    public void batchScheduling(BatchSchedulingDto dto) {
        // 可排程订单类型
        List<DictionaryItem> itemList = dictionaryItemService.findByThemeValueAndEnable("scheduleOrderType", true);
        List<String> scheduleOrderTypes = itemList.stream().map(DictionaryItem::getValue).collect(Collectors.toList());

        FbProductionOrder order = productionOrderService.findByAufnr(dto.getCode());
        if (order == null) {
            throw new RuntimeException("订单编号不存在");
        }
        String orderType = order.getAuart();
        if (StringUtils.isEmpty(orderType)) {
            throw new RuntimeException("订单类型未知，请联系管理员");
        }
        if (!scheduleOrderTypes.contains(orderType)){
            throw new RuntimeException("订单类型【"+orderType+"】不可排程，请联系管理员");
        }
        Date now = new Date();
        if (now.compareTo(order.getGstrp()) <= 0 || now.compareTo(order.getGltrp()) >=0){
            throw new RuntimeException("订单执行周期不符");
        }
        if (!order.getProductionStatus()) {
            throw new RuntimeException("当前订单不是生产状态");
        }
        FbProductModel fbProductModel = order.getFbProductModel();
        if (order.getFbProductModel() == null) {
            throw new RuntimeException("当前订单产品信息异常");
        }
        List<FbProductionSchedule> scheduleList = new ArrayList<>();
        for (Long deviceId : dto.getDeviceIds()) {
            Equipment equipment = equipmentService.get(deviceId);
            if (equipment == null) {
                throw new RuntimeException("设备ID【" + deviceId + "】不存在，请刷新页面重试");
            }
            FbProductionSchedule scheduleS1 = dao.findByDeviceIdAndStatus(deviceId.intValue(), EnumValuesFbServer.ProductionScheduleStatus.进行中.getKey());
            if (scheduleS1 != null){
                throw new RuntimeException("设备【" + equipment.getCode() + "】已有正在进行中的排程");
            }
            if (!equipment.getEnableState()) {
                throw new RuntimeException("设备【" + equipment.getCode() + "】未启用");
            }
            if (!dto.getCategory().equals(equipment.getDevice().getCategory())) {
                throw new RuntimeException("设备【" + equipment.getCode() + "】不是" + EnumValuesFactory.DeviceCategory.getText(dto.getCategory()));
            }
            MachineCapacityKf capacity = machineCapacityKfService.findByEquipmentId(equipment.getId());
            if (capacity == null) {
                throw new RuntimeException("设备【" + equipment.getCode() + "】加工能力没有维护，不允许排产");
            }
            if (StringUtils.isBlank(capacity.getConductionType())
                || StringUtils.isBlank(capacity.getSpecification())
                || StringUtils.isBlank(capacity.getZorientationind())){
                throw new RuntimeException("设备【" + equipment.getCode() + "】加工能力：规格、型号、定向标识不能为空");
            }

            //创建即将开始的，下一个排产的，
            FbProductionSchedule schedule = dao.findByDeviceIdAndStatus(deviceId.intValue(), EnumValuesFbServer.ProductionScheduleStatus.未开始.getKey());

            if (schedule != null && schedule.getFbProductModel() != null){
                if (EnumValuesFbServer.ProductionOrderType.ZRB4.getKey().equals(orderType)){
                    capacity.setRdlogo(true);
                    capacity.setRdonlylogo(order.getRdonlylogo());
                }else {
                    capacity.setRdlogo(false);
                }

                // 工单非定向需要转换为F
                String zorientationind = order.getZorientationind();
                if (ObjectUtils.isEmpty(zorientationind) || StringUtils.isBlank(zorientationind)){
                    zorientationind = "F";
                }

                if (dto.getCategory().equals(EnumValuesFactory.DeviceCategory.截断机.getKey())){
                    if (!capacity.getConductionType().equals(schedule.getFbProductModel().getConductiveType())
                            || !capacity.getSpecification().equals(schedule.getFbProductModel().getSpecs())
                            || !capacity.getZorientationind().equals(zorientationind)
                    ) {
                        // 修改设备加工能力
                        capacity.setProductType(order.getProductType());
                        capacity.setConductionType(fbProductModel.getConductiveType());
                        capacity.setSpecification(fbProductModel.getSpecs());
                        capacity.setSideLength(fbProductModel.getSideLength());
                        capacity.setZorientationind(zorientationind);

                        machineCapacityKfService.save(capacity);
                    }
                }else if (dto.getCategory().equals(EnumValuesFactory.DeviceCategory.开方机.getKey())){
                    if (!capacity.getConductionType().equals(schedule.getFbProductModel().getConductiveType())
                            || !capacity.getSpecification().equals(schedule.getFbProductModel().getSpecs())
                            || !capacity.getZorientationind().equals(zorientationind)
                    ) {
                        // 修改设备加工能力
                        capacity.setProductType(order.getProductType());
                        capacity.setConductionType(fbProductModel.getConductiveType());
                        capacity.setSpecification(fbProductModel.getSpecs());
                        capacity.setResistivity(fbProductModel.getResistivity());
                        capacity.setStickCount(fbProductModel.getSticksCount());
                        capacity.setZorientationind(zorientationind);

                        machineCapacityKfService.save(capacity);
                    }
                }
            }

            schedule = getProductionSchedule(order, equipment, schedule);
            if (schedule == null) {
                continue;
            }

            schedule.setCapacityId(capacity.getId());
            schedule.setProductionOrder(order);
            schedule.setFbProductModel(order.getFbProductModel());
            schedule.setCreateUserId(BaseContextHandler.getUserID());
            schedule.setCreateUserName(BaseContextHandler.getUsername());
            schedule.setCreateTime(new Date());
            schedule.setCategory(dto.getCategory());
            schedule.setCount(Integer.MAX_VALUE);
            schedule.setStatusInfo("手动排产");
            scheduleList.add(schedule);
        }
        dao.saveAll(scheduleList);

        // 修改订单排程状态
        if (scheduleList.size() > 0){
            this.setOrderSchedule(order, 1);
        }

    }

    @Override
    public Map<Long, ProductionOrderCountDto> getProductionScheduleData() {
        List<Map<String, Object>> productionOrderCountsObj = dao.getProductionScheduleData(EnumValuesFbServer.ProductionScheduleStatus.未开始.getKey());
        List<ProductionOrderCountDto> productionOrderCountDtos = JSON.parseArray(JSON.toJSONString(productionOrderCountsObj), ProductionOrderCountDto.class);
        Map<Long, ProductionOrderCountDto> map = new HashMap<>();
        for (ProductionOrderCountDto productionOrderCountDto : productionOrderCountDtos)
            map.put(productionOrderCountDto.getFbProductionOrderId(), productionOrderCountDto);
        return map;
    }

    private FbProductionSchedule getProductionSchedule(FbProductionOrder productionOrder, Equipment equipment, FbProductionSchedule productionSchedule) {
        if (productionSchedule == null) {
            productionSchedule = new FbProductionSchedule();
            productionSchedule.setDeviceId(equipment.getId().intValue());
            productionSchedule.setDeviceNo(equipment.getCode());
            productionSchedule.setStatus(EnumValuesFbServer.ProductionScheduleStatus.进行中.getKey());
        } else {
            if (productionSchedule.getProductionOrder().getId().intValue() == productionOrder.getId()) return null;
            productionSchedule.setProductionOrder(productionOrder);
        }
        return productionSchedule;
    }

    /**
     * 自动排程
     */
    @Override
    public void autoScheduling() {
        // 删除不符合规则的排程
        List<FbProductionSchedule> productionSchedules = dao.findByStatus(
                EnumValuesFbServer.ProductionScheduleStatus.未开始.getKey()
        );
        for (FbProductionSchedule schedule : productionSchedules) {
            if (schedule == null) {
                continue;
            }
            FbProductionOrder productionOrder = schedule.getProductionOrder();
            //检查订单信息
            if (productionOrder == null) {
                dao.delete(schedule);
                continue;
            }
            //检查订单生产状态
            if (!productionOrder.getProductionStatus()) {
                dao.delete(schedule);
                continue;
            }
            //检查订单开始结束时间
            Date nowTime = new Date();
            if (nowTime.compareTo(productionOrder.getGstrp()) <= 0 || nowTime.compareTo(productionOrder.getGltrp()) >=0){
                dao.delete(schedule);
                continue;
            }
            Equipment equipment = equipmentService.get(schedule.getDeviceId().longValue());
            // 检查设备属性
            if (equipment == null || !equipment.getEnableState() || equipment.getDevice() == null || equipment.getDevice().getCategory() == null) {
                dao.delete(schedule);
                continue;
            }
            // 检查设备加工能力配置
            MachineCapacityKf machineCapacityKf = machineCapacityKfService.findByEquipmentId(equipment.getId());
            if (machineCapacityKf == null) {
                dao.delete(schedule);
                continue;
            }

            // 工单非定向需要转换为F
            String zorientationind = productionOrder.getZorientationind();
            if (ObjectUtils.isEmpty(zorientationind) || StringUtils.isBlank(zorientationind)){
                zorientationind = "F";
            }

            // 检查设备加工能力配置
            if (machineCapacityKf.getCategory().equals(EnumValuesFactory.DeviceCategory.截断机.getKey())){
                if (!machineCapacityKf.getConductionType().equals(schedule.getFbProductModel().getConductiveType())
                        || !machineCapacityKf.getSpecification().equals(schedule.getFbProductModel().getSpecs())
                        || !zorientationind.equals(machineCapacityKf.getZorientationind())) {
                    dao.delete(schedule);
                }
            }else if (machineCapacityKf.getCategory().equals(EnumValuesFactory.DeviceCategory.开方机.getKey())){
                if (!machineCapacityKf.getConductionType().equals(schedule.getFbProductModel().getConductiveType())
                        || !machineCapacityKf.getSpecification().equals(schedule.getFbProductModel().getSpecs())
                        || !zorientationind.equals(machineCapacityKf.getZorientationind())) {
                    dao.delete(schedule);
                }
            }else {
                dao.delete(schedule);
            }
        }

        // 可排程订单类型
        List<DictionaryItem> itemList = dictionaryItemService.findByThemeValueAndEnable("scheduleOrderType", true);
        List<String> scheduleOrderTypes = itemList.stream().map(DictionaryItem::getValue).collect(Collectors.toList());

        // 获取待排程订单及其汇总数据
        List<Map<String, Object>> maps = dao.getProductionScheduleData(EnumValuesFbServer.ProductionScheduleStatus.未开始.getKey());
        List<ProductionOrderCountDto> countDtoList = JSON.parseArray(JSON.toJSONString(maps), ProductionOrderCountDto.class);
        List<FbProductionSchedule> productionScheduleList = new ArrayList<>();
        for (ProductionOrderCountDto orderDto : countDtoList) {
            String zorientationind = orderDto.getZorientationind();
            if (ObjectUtils.isEmpty(zorientationind) || StringUtils.isBlank(zorientationind)){
                zorientationind = "F";
            }
            // 订单类型不可排程
            if (!scheduleOrderTypes.contains(orderDto.getOrderType())) continue;

            int scheduleCount = 0;

            // 加工能力集合
            List<MachineCapacityKf> capacityList = null;
            // 空闲设备集合
            List<Equipment> equipmentList = null;
            // 根据订单工作空间（factoryWorkType）判断设备类型：截断机、开方机
            if (3 == orderDto.getWorkType()){       // 截断机
                capacityList = machineCapacityKfService.getJdFreeDevice(
                        orderDto.getConductionType(),
                        orderDto.getSpecification(),
                        zorientationind);
                equipmentList  = equipmentService.findByFactoryCodeAndCategory(orderDto.getWorkShop(),
                        String.valueOf(EnumValuesFactory.DeviceCategory.截断机.getKey()));

            }else if (4 == orderDto.getWorkType()){     // 开方机
                capacityList = machineCapacityKfService.getKfFreeDevice(
                        orderDto.getConductionType(),
                        orderDto.getSpecification(),
                        zorientationind);
                equipmentList  = equipmentService.findByFactoryCodeAndCategory(orderDto.getWorkShop(),
                        String.valueOf(EnumValuesFactory.DeviceCategory.开方机.getKey()));
            }else {
                continue;
            }
            if (CollectionUtils.isEmpty(capacityList)) continue;
            if (CollectionUtils.isEmpty(equipmentList)) continue;

            // 删除不匹配设备的加工能力
            Map<Long, Equipment> equipmentMap = equipmentList.stream().collect(Collectors.toMap(Equipment::getId, Equipment -> Equipment));
            for (int i = 0; i < capacityList.size(); i++) {
                MachineCapacityKf capacity = capacityList.get(i);
                if (equipmentMap.get(capacity.getEquipment().getId()) == null){
                    capacityList.remove(i);
                    i--;
                    continue;
                }
                // 研发工单
                if (EnumValuesFbServer.ProductionOrderType.ZRB4.getKey().equals(orderDto.getOrderType())){
                    if (!capacity.getRdlogo() || (StringUtils.isNotBlank(capacity.getRdonlylogo())
                            && capacity.getRdonlylogo().equals(orderDto.getRdonlylogo()))){
                        capacityList.remove(i);
                        i--;
                    }
                }
            }

            // 将存在的加工能力全部分配给当前订单
            for (MachineCapacityKf machineCapacityKf : capacityList) {
                try {
                    // 检查设备加工能力配置
                    FbProductionSchedule productionSchedule = getProductionSchedule(new FbProductionOrder(orderDto.getFbProductionOrderId()), machineCapacityKf.getEquipment(), null);
                    assert productionSchedule != null;
                    productionSchedule.setProductionOrder(new FbProductionOrder(orderDto.getFbProductionOrderId()));
                    productionSchedule.setFbProductModel(new FbProductModel(orderDto.getFbProductModelId()));
                    productionSchedule.setStatusInfo("自动排程");
                    productionSchedule.setCreateUserId(BaseContextHandler.getUserID());
                    productionSchedule.setCreateUserName(BaseContextHandler.getUsername());
                    productionSchedule.setCreateTime(new Date());
                    productionSchedule.setCount(Integer.MAX_VALUE);
                    productionSchedule.setCapacityId(machineCapacityKf.getId());
                    productionSchedule.setCategory(machineCapacityKf.getCategory());
                    productionScheduleList.add(productionSchedule);
                } catch (Exception e) {
                    log.error("自动排产发生错误：", e);
                    e.printStackTrace();
                }
                if (productionScheduleList.size() >= 100) {
                    dao.saveAll(productionScheduleList);
                    scheduleCount += productionScheduleList.size();
                    productionScheduleList = new ArrayList<>();
                }
            }
            if (productionScheduleList.size() > 0) {
                dao.saveAll(productionScheduleList);
                scheduleCount += productionScheduleList.size();
                productionScheduleList = new ArrayList<>();
            }

            // 修改订单排程状态
            if (scheduleCount > 0){
                FbProductionOrder order = productionOrderService.get(orderDto.getFbProductionOrderId());
                this.setOrderSchedule(order, 1);
            }
        }
    }

    @Override
    public void setOrderSchedule(FbProductionOrder order, int state){
        order.setScheduled(state);
        productionOrderService.saveOrUpdate(order);
    }

    @Override
    public void autoCloseScheduling() {
        // 关单
        List<FbProductionSchedule> execScheduleList = dao.findByStatus(
                EnumValuesFbServer.ProductionScheduleStatus.进行中.getKey()
        );
        for (FbProductionSchedule schedule : execScheduleList) {
            FbProductionOrder order = schedule.getProductionOrder();
            Date nowTime1 = new Date();
            if (nowTime1.compareTo(order.getGstrp()) <= 0 || nowTime1.compareTo(order.getGltrp()) >=0){
                order.setProductionStatus(false);
                productionOrderService.saveOrUpdate(order);

                schedule.setStatus(EnumValuesFbServer.ProductionScheduleStatus.已完成.getKey());
                schedule.setStatusInfo("自动关闭");
                saveOrUpdate(schedule);
            }
        }
    }

    @Override
    public void cutAutoScheduling() {

    }

    @Override
    public void trimAutoScheduling() {

    }

    @Override
    public List<SchedulingInfoDto> getSchedulingInfo() {
        List<Map<String, Object>> mapDatas = dao.getSchedulingInfo();
        Map<String, SchedulingInfoDto> schedulingInfoDtoMap = new LinkedHashMap<>();
        for (Map<String, Object> map1 : mapDatas) {
            String area = map1.get("area").toString();
            SchedulingInfoDto schedulingInfoDto = schedulingInfoDtoMap.get(area);
            if (schedulingInfoDto == null) {
                schedulingInfoDto = new SchedulingInfoDto();
                schedulingInfoDto.setArea(area);
                schedulingInfoDto.setScheduleCount(0);
                schedulingInfoDto.setFreeCount(0);
                schedulingInfoDtoMap.put(area, schedulingInfoDto);
            }
            if (NumberUtil.Object2Integer(map1.get("type"), 0) == 0) { // 空闲
                schedulingInfoDto.setFreeCount(NumberUtil.Object2Integer(map1.get("counts"), 0));
            } else {
                schedulingInfoDto.setScheduleCount(NumberUtil.Object2Integer(map1.get("counts"), 0));
            }
        }
        List<SchedulingInfoDto> schedulingInfoDtos = new LinkedList<>();
        for (Map.Entry<String, SchedulingInfoDto> map : schedulingInfoDtoMap.entrySet()) {
            schedulingInfoDtos.add(map.getValue());
        }

        return schedulingInfoDtos;
    }

    /**
     * 圆棒匹配方棒加工订单
     *
     * @param specs          规格
     * @param conductiveType 导电型号
     * @param dopant         掺杂剂
     * @param productLevel   产品等级
     * @return 方棒订单号
     * todo 更新后删除
     */
    @Override
    public String findProductionScheduleCode(String specs, String conductiveType, String dopant, String productLevel) {
        List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndValueAndEnables("LevelCorre", productLevel, true);
        List<String> productLevels = new ArrayList<>();
        dictionaryItems.forEach(dictionaryItem -> productLevels.add(dictionaryItem.getName()));
        String orderNo = null;
        if (productLevels.size() > 0) {
            List<Map<String, Object>> orderNoMaps = dao.findProductionScheduleCode(specs, conductiveType, dopant, productLevels);
            if (orderNoMaps.size() > 0) {
                int index = new Random().nextInt(orderNoMaps.size());
                if (StringUtils.isNotBlank(NumberUtil.object2String(orderNoMaps.get(index).get("aufnr"), null))) {
                    orderNo = NumberUtil.object2String(orderNoMaps.get(index).get("aufnr"), null);
                }
            }
        }
        return orderNo;
    }

    //TODO yqe 圆棒匹配方棒生产订单号，和可生产的设备
    @Override
    public FbDeviceSchedule findFbDeviceSchedule(FbDeviceScheduleParam fbDeviceScheduleParam) {
        RankResultDto rankResultDto = new RankResultDto();
        rankResultDto.setConductiveType(fbDeviceScheduleParam.getConductiveType());
        rankResultDto.setSpecs(fbDeviceScheduleParam.getSpecs());
        rankResultDto.setDopant(fbDeviceScheduleParam.getDopant());
        rankResultDto.setProductRank(fbDeviceScheduleParam.getProductLevel());
        rankResultDto.setSectionNo(fbDeviceScheduleParam.getSectionNo());
        //匹配方棒递给你的那
        String orderNo = findProductionScheduleCodePro(rankResultDto);
        //通过匹配的订单找到，适合生产的设备
        List<Map<String, Object>> maps = dao.findFbDeviceSchedule(orderNo, "%," + fbDeviceScheduleParam.getProductLevel() + ",%", fbDeviceScheduleParam.getSticksType());
        Set<String> deviceCodeSet = new LinkedHashSet<>();
        maps.forEach(map -> {
            String deviceCode = NumberUtil.object2String(map.get("device_no"), null);
            if (StringUtils.isNotBlank(deviceCode)) {
                deviceCodeSet.add(deviceCode);
            }
        });
        String deviceCodes = StringUtils.join(deviceCodeSet, ",");
        FbDeviceSchedule fbDeviceSchedule = new FbDeviceSchedule();
        fbDeviceSchedule.setOrderCode(orderNo);
        fbDeviceSchedule.setDeviceCodes(deviceCodes);
        return fbDeviceSchedule;
    }

    @Autowired
    private FbOrderMatchingInfoService fbOrderMatchingInfoService;

    //TODO yqe 圆棒匹配方棒生产订单号
    @Override
    public String findProductionScheduleCodePro(RankResultDto rankResultDto) {
        //根据晶段编号订单匹配信息
        List<FbOrderMatchingInfo> fbOrderMatchingInfos = fbOrderMatchingInfoService.findBySectionNo(rankResultDto.getSectionNo());
        FbOrderMatchingInfo fbOrderMatchingInfo;
        if (fbOrderMatchingInfos.size() > 0) {
            fbOrderMatchingInfo = fbOrderMatchingInfos.get(0);
            fbOrderMatchingInfo.setGmtUpdate(new Date());
            fbOrderMatchingInfo.setUserUpdate(BaseContextHandler.getUsername());
        } else {
            fbOrderMatchingInfo = new FbOrderMatchingInfo();
            fbOrderMatchingInfo.setGmtCreate(new Date());
            fbOrderMatchingInfo.setUserCreate(BaseContextHandler.getUsername());
        }
        // 【非标加工】 或者 不是【非标棒】 才进行匹配订单  TODO 标棒非标棒匹配订单
        if (rankResultDto.getMatchingType() == EnumValuesFbServer.MatchingType.非标加工.getKey()
                || NumberUtil.Object2Integer(fbOrderMatchingInfo.getMatchingType(), 0) == EnumValuesFbServer.MatchingType.非标加工.getKey()
                || !"非标棒".equals(rankResultDto.getType())) {
            String orderNo = null;
            Map<String, Long> orderNoMap = new HashMap<>();
            //有产品等级
            if (StringUtils.isNotBlank(rankResultDto.getProductRank())) {
                //字典圆方评级对应（方—圆）
                List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndValueAndEnables("LevelCorre", rankResultDto.getProductRank(), true);
                Set<String> productLevels = new HashSet<>();
                productLevels.add(rankResultDto.getProductRank());
                dictionaryItems.forEach(dictionaryItem -> productLevels.add(dictionaryItem.getName()));
                //当前评级的其对应的所有的方棒的评级
                List<String> productLevelss = new ArrayList<>(productLevels);
                //去通过 单晶规格 导电型号 掺杂剂 对应的方棒评级类型 去方棒计划工单匹配 查询出id和订单编号
                List<Map<String, Object>> orderNoMaps = dao.findProductionScheduleCode(rankResultDto.getSpecs(), rankResultDto.getConductiveType(), rankResultDto.getDopant(), productLevelss);
                if (orderNoMaps.size() > 0) {
                    //订单编号对应id
                    orderNoMaps.forEach(orderNoItem -> {
                        if (StringUtils.isNotBlank(NumberUtil.object2String(orderNoItem.get("aufnr"), null))) {
                            orderNoMap.put(NumberUtil.object2String(orderNoItem.get("aufnr"), null), NumberUtil.Object2Long(orderNoItem.get("id"), null));
                        }
                    });
                    //原来存在并且list包括
                    if (StringUtils.isNotBlank(fbOrderMatchingInfo.getFbOrderNo()) && orderNoMap.containsKey(fbOrderMatchingInfo.getFbOrderNo())) {
                        orderNo = fbOrderMatchingInfo.getFbOrderNo();
                    } else {
                        //随便取一个
                        int index = new Random().nextInt(orderNoMaps.size());
                        if (StringUtils.isNotBlank(NumberUtil.object2String(orderNoMaps.get(index).get("aufnr"), null))) {
                            orderNo = NumberUtil.object2String(orderNoMaps.get(index).get("aufnr"), null);
                        }
                    }
                }
            }
            // 只有非标加工才去改变他的值，因为第三方触发匹配订单，不知道是不会非标加工，所以默认普通加工，如果修改，则无法再次触发匹配
            // 因此只有非标加工状态，才需要改变此字段的状态
            // 只要被标记为非标加工，则无法取消
            if (rankResultDto.getMatchingType() == EnumValuesFbServer.MatchingType.非标加工.getKey()) {
                fbOrderMatchingInfo.setMatchingType(EnumValuesFbServer.MatchingType.非标加工.getKey());
            }
            fbOrderMatchingInfo.setFbOrderNo(orderNo);
            if (orderNo != null) {
                fbOrderMatchingInfo.setFbOrderId(orderNoMap.get(orderNo));
            } else {
                fbOrderMatchingInfo.setFbOrderId(null);
            }
            //同步订单匹配记录
            fbOrderMatchingInfoService.saveAsync(rankResultDto, fbOrderMatchingInfo);
            return orderNo;
        } else {
            return null;
        }
    }

    @Override
    public FbProductionSchedule findByDeviceNoAndStatus(String deviceNo, Integer status) {
        return dao.findTopByDeviceNoAndStatusOrderByIdDesc(deviceNo, status);
    }
}
