1、卧式理片笼配置参数由配置yml文件改为数据库配置表获取
2、磨边后参数改造,解决plc查询数据异常问题
3、大理片笼配置参数由配置yml文件改为数据库配置表获取
4、钢化配置参数由配置yml文件改为数据库配置表获取
5、配置参数常量类配置修改,提供获取配置参数的方法
21个文件已修改
5588 ■■■■ 已修改文件
hangzhoumesParent/common/servicebase/src/main/java/com/mes/common/config/ConstSysConfig.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/sysconfig/service/SysConfigService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/sysconfig/service/impl/SysConfigServiceImpl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/temperingglass/service/TemperingGlassInfoService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/temperingglass/service/impl/TemperingGlassInfoServiceImpl.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/edgglasstask/service/impl/EdgGlassTaskInfoServiceImpl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/OpcCacheGlassNewTask.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/OpcCacheGlassTask.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/OpcEdgTask.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/opctask/service/impl/EdgStorageDeviceTaskServiceImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageCageDetailsServiceImpl.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageCageServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageGlassInfoServiceImpl.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/service/impl/BigStorageCageFeedTaskServiceImpl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/OpcPlcStorageCageNewTask.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/OpcPlcStorageCageTask.java 1224 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/PlcStorageCageTask.java 2282 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/opccallback/BigStorageStartCallback.java 1642 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/tools/service/impl/BigStorageBaseServiceImpl.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/java/com/mes/job/PlcTemperingGlassTask.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/java/com/mes/job/TemperingTask.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
hangzhoumesParent/common/servicebase/src/main/java/com/mes/common/config/ConstSysConfig.java
@@ -8,43 +8,43 @@
 */
public class ConstSysConfig {
    // 钢化炉数阈值
    public static final Integer CACHE_THRESHOLD = 1;
    // 磨边参数换算率
    public static final Integer CACHE_RATIO = 2;
    // 卧理最大长边
    // 卧理笼最大长边
    public static final Integer CACHE_CACHE_WIDTH = 3;
    // 卧理最大短边
    // 卧理笼最大短边
    public static final Integer CACHE_CACHE_HEIGHT = 4;
    // 磨边二线最大长边
    public static final Integer CACHE_MAX_FIRST_LENGTH = 5;
    // 磨边二线最大短边
    public static final Integer CACHE_MAX_SECOND_LENGTH = 6;
    // 磨边一线最大长边
    // 磨边一线最小长边
    public static final Integer CACHE_MIN_ONE_FIRST_LENGTH = 7;
    // 磨边一线最大短边
    // 磨边一线最小短边
    public static final Integer CACHE_MIN_ONE_SECOND_LENGTH = 8;
    // 磨边二线最大长边
    // 磨边二线最小长边
    public static final Integer CACHE_MIN_TWO_FIRST_LENGTH = 9;
    // 磨边二线最大短边
    // 磨边二线最小短边
    public static final Integer CACHE_MIN_TWO_SECOND_LENGTH = 10;
    // 卧理玻璃间隙
    public static final Integer CACHE_GLASS_GAP = 1;
    public static final Integer CACHE_GLASS_GAP = 11;
    // 卧理格子宽度
    public static final Integer CACHE_CELL_LENGTH = 12;
    // 排序方式
    public static final Integer CACHE_SEQUENCE_ORDER_FALSE = 13;
    // 排序方式
    // 二号线最大厚度(不包括)
    public static final Integer CACHE_MAX_THICKNESS = 13;
    // 钢化出片排序方式
    public static final Integer CACHE_SEQUENCE_ORDER_TRUE = 14;
    // 一炉玻璃占用格子数
    public static final Integer VERTICAL_MINCOUNT = 15;
    // 一炉玻璃占用格子数(调度)
    public static final Integer VERTICAL_MIN_COUNT = 15;
    // 大车宽度
    public static final Integer VERTICAL_CAR_WIDTH = 16;
    // 格子宽度
    public static final Integer VERTICAL_SLOT_WIDTH = 17;
    // 进片车最大玻璃数
    // 进片车最大玻璃数-1
    public static final Integer VERTICAL_IN_CAR_SIZE = 18;
    // 出片车最大玻璃数
    public static final Integer VERTICAL_OUT_CAR_SIZE = 19;
@@ -55,41 +55,32 @@
    // 格子最大高度
    public static final Integer VERTICAL_SLOT_MAX_HEIGHT = 22;
    // 格子最大厚度
    public static final Integer VERTICAL_SLOT_MAXTHICKNESS = 23;
    public static final Integer VERTICAL_SLOT_MAX_THICKNESS = 23;
    // 钢出目标位置
    public static final Integer VERTICAL_TEMPERING_OUT_TARGET_POSITION = 24;
    // 人工下片目标位置
    public static final Integer VERTICAL_ARTIFICIAL_OUT_TARGET_POSITION = 25;
    // 排序方式
    public static final Integer HOLLOW_SEQUENCE_ORDER = 26;
    // 一炉玻璃占用格子数
    public static final Integer HOLLOW_MINCOUNT = 27;
    // 大车宽度
    public static final Integer HOLLOW_CAR_WIDTH = 28;
    public static final Integer HOLLOW_CAR_WIDTH = 26;
    // 格子宽度
    public static final Integer HOLLOW_SLOT_WIDTH = 29;
    // 进片车最大玻璃数
    public static final Integer HOLLOW_IN_CAR_SIZE = 30;
    public static final Integer HOLLOW_SLOT_WIDTH = 27;
    // 进片车最大玻璃数-1
    public static final Integer HOLLOW_IN_CAR_SIZE = 28;
    // 出片车最大玻璃数
    public static final Integer HOLLOW_OUT_CAR_SIZE = 31;
    public static final Integer HOLLOW_OUT_CAR_SIZE = 29;
    // 玻璃间隙
    public static final Integer HOLLOW_GLASS_GAP = 32;
    // 钢化炉长度
    public static final Integer HOLLOW_X_MAX_SIZE = 33;
    // 钢出目标位置
    public static final Integer HOLLOW_TEMPERING_OUT_TARGET_POSITION = 34;
    // 人工下片目标位置
    public static final Integer HOLLOW_ARTIFICIAL_OUT_TARGET_POSITION = 35;
    public static final Integer HOLLOW_GLASS_GAP = 30;
    // 格子最大高度
    public static final Integer HOLLOW_SLOT_MAX_HEIGHT = 36;
    public static final Integer HOLLOW_SLOT_MAX_HEIGHT = 31;
    // 格子最大厚度
    public static final Integer HOLLOW_SLOT_MAXTHICKNESS = 37;
    public static final Integer HOLLOW_SLOT_MAX_THICKNESS = 32;
    // 钢化炉长度
    public static final Integer TEMPERING_WIDTH = 38;
    public static final Integer TEMPERING_WIDTH = 33;
    // 钢化炉宽度
    public static final Integer TEMPERING_HEIGHT = 39;
    public static final Integer TEMPERING_HEIGHT = 34;
hangzhoumesParent/common/servicebase/src/main/java/com/mes/sysconfig/service/SysConfigService.java
@@ -25,7 +25,7 @@
    Boolean deleteConfig(Serializable id);
    String queryConfigValue(Serializable id);
    Integer queryConfigValue(Serializable id);
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/sysconfig/service/impl/SysConfigServiceImpl.java
@@ -65,13 +65,13 @@
    }
    @Override
    public String queryConfigValue(Serializable id) {
    public Integer queryConfigValue(Serializable id) {
        SysConfig sysConfig = this.queryConfigById(id);
        if (sysConfig == null) {
            log.info("系统配置查询为空,请检查该配置是否存在:{}", id);
            return null;
        }
        return sysConfig.getConfigValue();
        return Integer.parseInt(sysConfig.getConfigValue());
    }
}
hangzhoumesParent/common/servicebase/src/main/java/com/mes/temperingglass/service/TemperingGlassInfoService.java
@@ -19,16 +19,28 @@
public interface TemperingGlassInfoService extends MPJBaseService<TemperingGlassInfo> {
    /**
     * 等待中的玻璃
     *
     * @return
     */
    List<TemperingGlassInfo> selectWaitingGlassByOpc();
    /**
     * 等待中的玻璃
     *
     * @return
     */
    List<TemperingGlassInfo> selectWaitingGlass();
    /**
     * 进炉中的玻璃
     *
     * @return
     */
    List<TemperingGlassInfo> selectIntoGlass(TemperingGlassInfo temperingGlassInfo);
    /**
     * 出炉中的玻璃
     *
     * @return
     */
    List<TemperingGlassInfo> selectOutGlass();
hangzhoumesParent/common/servicebase/src/main/java/com/mes/temperingglass/service/impl/TemperingGlassInfoServiceImpl.java
@@ -1,10 +1,13 @@
package com.mes.temperingglass.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.query.MPJQueryWrapper;
import com.kangaroohy.milo.model.ReadWriteEntity;
import com.kangaroohy.milo.service.MiloService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.entity.LoadGlassInfo;
import com.mes.glassinfo.mapper.GlassInfoMapper;
@@ -12,10 +15,12 @@
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.mapper.TemperingGlassInfoMapper;
import com.mes.temperingglass.service.TemperingGlassInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
@@ -28,12 +33,41 @@
 */
@Service
@DS("north_glass_mes")
@Slf4j
public class TemperingGlassInfoServiceImpl extends MPJBaseServiceImpl<TemperingGlassInfoMapper, TemperingGlassInfo> implements TemperingGlassInfoService {
    @Resource
    TemperingGlassInfoMapper temperingMapper;
    @Autowired
    @Resource
    private GlassInfoMapper glassInfoMapper;
    @Autowired(required = false)
    MiloService miloService;
    @Override
    public List<TemperingGlassInfo> selectWaitingGlassByOpc() {
        //获取等待进炉中的玻璃信息
        try {
            ReadWriteEntity engineerEntity = miloService.readFromOpcUa("GH2S7.GH2S7.F09_ENGINEER_ID");
            ReadWriteEntity temperingLayoutIdEntity = miloService.readFromOpcUa("GH2S7.GH2S7.F09_TEMPERING_LAYOUT_ID");
            if (null == engineerEntity || null == temperingLayoutIdEntity) {
                engineerEntity = miloService.readFromOpcUa("GH2S7.GH2S7.F08_ENGINEER_ID");
                temperingLayoutIdEntity = miloService.readFromOpcUa("GH2S7.GH2S7.F08_TEMPERING_LAYOUT_ID");
                if (null == engineerEntity || null == temperingLayoutIdEntity) {
                    log.info("获取参数异常,结束本次任务");
                    return new ArrayList<>();
                }
            }
            return this.list(new LambdaQueryWrapper<TemperingGlassInfo>()
                    .eq(TemperingGlassInfo::getEngineerId, engineerEntity.getValue() + "")
                    .eq(TemperingGlassInfo::getTemperingLayoutId, temperingLayoutIdEntity.getValue() + ""));
        } catch (Exception e) {
            log.info("获取钢化参数异常:{}", e);
            return new ArrayList<>();
        }
    }
    @Override
    public List<TemperingGlassInfo> selectWaitingGlass() {
        //获取等待进炉中的玻璃信息
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/edgglasstask/service/impl/EdgGlassTaskInfoServiceImpl.java
@@ -4,16 +4,18 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mes.common.config.ConstSysConfig;
import com.mes.edgglasstask.entity.EdgGlassTaskInfo;
import com.mes.edgglasstask.entity.request.EdgGlassInfoRequest;
import com.mes.edgglasstask.mapper.EdgGlassTaskInfoMapper;
import com.mes.edgglasstask.service.EdgGlassTaskInfoService;
import com.mes.sysconfig.service.SysConfigService;
import com.mes.tools.DateUtil;
import com.mes.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
@@ -29,13 +31,16 @@
    @Autowired
    RedisUtil redisUtil;
    @Resource
    SysConfigService sysConfigService;
    @Value("${mes.ratio}")
    private int ratio;
//    @Value("${mes.ratio}")
//    private int ratio;
    @Override
    public List<EdgGlassTaskInfo> selectEdgInfo() {
        int ratio = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_RATIO);
        EdgGlassInfoRequest request = redisUtil.getCacheObject("edgGlassRequest");
        if (null == request) {
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/OpcCacheGlassNewTask.java
@@ -8,6 +8,7 @@
import com.kangaroohy.milo.model.ReadWriteEntity;
import com.kangaroohy.milo.service.MiloService;
import com.mes.common.config.Const;
import com.mes.common.config.ConstSysConfig;
import com.mes.damage.service.DamageService;
import com.mes.edgglasstask.entity.EdgGlassTaskInfo;
import com.mes.edgglasstask.service.EdgGlassTaskInfoService;
@@ -21,11 +22,11 @@
import com.mes.opctask.entity.EdgStorageDeviceTaskHistory;
import com.mes.opctask.service.EdgStorageDeviceTaskHistoryService;
import com.mes.opctask.service.EdgStorageDeviceTaskService;
import com.mes.sysconfig.service.SysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@@ -64,35 +65,35 @@
    EdgStorageDeviceTaskHistoryService edgStorageDeviceTaskHistoryService;
    @Resource
    DamageService damageService;
    @Resource
    SysConfigService sysConfigService;
    @Value("${mes.glassGap}")
    private int glassGap;
    @Value("${mes.threshold}")
    //    @Value("${mes.threshold}")
    private int threshold;
    @Value("${mes.cellLength}")
    //    @Value("${mes.cellLength}")
    private int cellLength;
    @Value("${mes.ratio}")
    //    @Value("${mes.ratio}")
    private int ratio;
    @Value("${mes.min.one.firstLength}")
    //    @Value("${mes.min.one.firstLength}")
    private int minOneFirstLength;
    @Value("${mes.min.one.secondLength}")
    //
//    @Value("${mes.min.one.secondLength}")
    private int minOneSecondLength;
    @Value("${mes.min.two.firstLength}")
    //
//    @Value("${mes.min.two.firstLength}")
    private int minTwoFirstLength;
    @Value("${mes.min.two.secondLength}")
    //
//    @Value("${mes.min.two.secondLength}")
    private int minTwoSecondLength;
    @Value("${mes.max.firstLength}")
    //
//    @Value("${mes.max.firstLength}")
    private int maxTwoFirstLength;
    @Value("${mes.max.secondLength}")
    //
//    @Value("${mes.max.secondLength}")
    private int maxTwoSecondLength;
    @Value("${mes.maxThickness}")
    //
//    @Value("${mes.maxThickness}")
    private int maxThickness;
    private String glassInIdOne = "";
@@ -124,6 +125,17 @@
    }
    private void startOneOpcTaskChild(String tableName, int device, int cellFlag) throws Exception {
        threshold = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_THRESHOLD);
        cellLength = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_CELL_LENGTH);
        ratio = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_RATIO);
        minOneFirstLength = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_MIN_ONE_FIRST_LENGTH);
        minOneSecondLength = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_MIN_ONE_SECOND_LENGTH);
        minTwoFirstLength = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_MIN_TWO_FIRST_LENGTH);
        minTwoSecondLength = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_MIN_TWO_SECOND_LENGTH);
        maxTwoFirstLength = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_MAX_FIRST_LENGTH);
        maxTwoSecondLength = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_MAX_SECOND_LENGTH);
        maxThickness = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_MAX_THICKNESS);
        EdgStorageDeviceTask task = edgStorageDeviceTaskService.queryTaskMessage(tableName);
        if (task == null) {
            log.info("任务表基础数据录入失败,请检查数据是否录入成功");
@@ -200,6 +212,7 @@
    }
    private void edgTaskChild(String glassId, int cell) throws Exception {
        ratio = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_RATIO);
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId).last("limit 1"));
        if (glassInfo == null) {
            log.info("对列表中的玻璃id错误,请检查数据,玻璃id:{}", glassId);
@@ -210,11 +223,11 @@
//        list.add(generateReadWriteEntity("MB" + cell + ".MB" + cell + ".mesControl", true));
        list.add(generateReadWriteEntity("MB" + cell + ".MB" + cell + ".glassId", Integer.parseInt(toEndingId)));
        list.add(generateReadWriteEntity("MB" + cell + ".MB" + cell + ".toEdingId", Integer.parseInt(toEndingId)));
        list.add(generateReadWriteEntity("MB" + cell + ".MB" + cell + ".width", (int) Math.max(glassInfo.getWidth() * 10, glassInfo.getHeight() * 10)));
        list.add(generateReadWriteEntity("MB" + cell + ".MB" + cell + ".height", (int) Math.min(glassInfo.getWidth() * 10, glassInfo.getHeight() * 10)));
        list.add(generateReadWriteEntity("MB" + cell + ".MB" + cell + ".width", (int) Math.max(glassInfo.getWidth() * ratio, glassInfo.getHeight() * ratio)));
        list.add(generateReadWriteEntity("MB" + cell + ".MB" + cell + ".height", (int) Math.min(glassInfo.getWidth() * ratio, glassInfo.getHeight() * ratio)));
        miloService.writeToOpcUa(list);
        miloService.writeToOpcWord(generateReadWriteEntity("MB" + cell + ".MB" + cell + ".thickness", (int) glassInfo.getThickness() * 10));
        miloService.writeToOpcWord(generateReadWriteEntity("MB" + cell + ".MB" + cell + ".thickness", (int) glassInfo.getThickness() * ratio));
        //修改磨边对列中的磨边线路及状态
        edgGlassTaskInfoService.update(new LambdaUpdateWrapper<EdgGlassTaskInfo>()
                .set(EdgGlassTaskInfo::getLine, cell)
@@ -715,27 +728,6 @@
        taskHistory.setTaskState(Const.RAW_GLASS_TASK_NEW);
        taskHistory.setDeviceId(deviceId);
        edgStorageDeviceTaskHistoryService.save(taskHistory);
        return Boolean.TRUE;
    }
    public boolean updateCellRemainWidth(int slot, int device, EdgStorageDeviceTaskHistory taskHistory) {
        List<EdgStorageCageDetails> list = edgStorageCageDetailsService.list(new LambdaQueryWrapper<EdgStorageCageDetails>().eq(EdgStorageCageDetails::getSlot, slot)
                .eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN));
        int remainWidth = cellLength;
        if (CollectionUtil.isNotEmpty(list)) {
            if (2 == taskHistory.getTaskType()) {
                remainWidth = 0;
            } else {
                for (EdgStorageCageDetails item : list) {
                    remainWidth = remainWidth - glassGap - (int) Math.max(item.getWidth(), item.getHeight());
                }
                if (remainWidth <= 0) {
                    remainWidth = 0;
                }
            }
        }
        edgStorageCageService.update(new LambdaUpdateWrapper<EdgStorageCage>().
                set(EdgStorageCage::getRemainWidth, remainWidth).eq(EdgStorageCage::getSlot, slot).eq(EdgStorageCage::getDeviceId, device));
        return Boolean.TRUE;
    }
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/OpcCacheGlassTask.java
@@ -26,7 +26,6 @@
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@@ -65,25 +64,25 @@
    @Resource
    DamageService damageService;
    @Value("${mes.glassGap}")
//    @Value("${mes.glassGap}")
    private int glassGap;
    @Value("${mes.threshold}")
    //    @Value("${mes.threshold}")
    private int threshold;
    @Value("${mes.cellLength}")
    //    @Value("${mes.cellLength}")
    private int cellLength;
    @Value("${mes.ratio}")
    //    @Value("${mes.ratio}")
    private int ratio;
    @Value("${mes.min.one.firstLength}")
    //    @Value("${mes.min.one.firstLength}")
    private int minOneFirstLength;
    @Value("${mes.min.one.secondLength}")
    //    @Value("${mes.min.one.secondLength}")
    private int minOneSecondLength;
    @Value("${mes.min.two.firstLength}")
    //    @Value("${mes.min.two.firstLength}")
    private int minTwoFirstLength;
    @Value("${mes.min.two.secondLength}")
    //    @Value("${mes.min.two.secondLength}")
    private int minTwoSecondLength;
    private String glassInIdOne = "";
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/OpcEdgTask.java
@@ -59,11 +59,7 @@
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId).last("limit 1"));
        List<ReadWriteEntity> ualist = new ArrayList<>();
        miloService.writeToOpcUa(
                ReadWriteEntity.builder()
                        .identifier("MB04.MB04.mes_glass_Id_" + cell)
                        .value(glassInfo.getGlassId())
                        .build());
        miloService.writeToOpcUa(generateReadWriteEntity("MB04.MB04.mes_glass_Id_" + cell, glassId));
        ualist.add(generateReadWriteEntity("MB04.MB04.width" + cell, (int) Math.max(glassInfo.getWidth() * 10, glassInfo.getHeight() * 10)));
        ualist.add(generateReadWriteEntity("MB04.MB04.height" + cell, (int) Math.min(glassInfo.getWidth() * 10, glassInfo.getHeight() * 10)));
        ualist.add(generateReadWriteEntity("MB04.MB04.thickness" + cell, (int) glassInfo.getThickness() * 10));
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/opctask/service/impl/EdgStorageDeviceTaskServiceImpl.java
@@ -4,6 +4,7 @@
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.mes.common.config.Const;
import com.mes.common.config.ConstSysConfig;
import com.mes.edgstoragecage.entity.EdgStorageCage;
import com.mes.edgstoragecage.entity.EdgStorageCageDetails;
import com.mes.edgstoragecage.entity.vo.EdgSlotRemainVO;
@@ -14,7 +15,7 @@
import com.mes.opctask.mapper.EdgStorageDeviceTaskMapper;
import com.mes.opctask.service.EdgStorageDeviceTaskHistoryService;
import com.mes.opctask.service.EdgStorageDeviceTaskService;
import org.springframework.beans.factory.annotation.Value;
import com.mes.sysconfig.service.SysConfigService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -41,11 +42,13 @@
    private EdgStorageCageService edgStorageCageService;
    @Resource
    EdgStorageDeviceTaskMapper edgStorageDeviceTaskMapper;
    @Resource
    SysConfigService sysConfigService;
    @Value("${mes.glassGap}")
    private int glassGap;
    @Value("${mes.cellLength}")
    private int cellLength;
//    @Value("${mes.glassGap}")
//    private int glassGap;
//    @Value("${mes.cellLength}")
//    private int cellLength;
    @Override
    public EdgStorageDeviceTask queryTaskMessage(String tableName) {
@@ -121,12 +124,14 @@
    }
    private boolean resetSlotRemainWidth() {
        int cellLength = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_CELL_LENGTH);
        int glassGap = sysConfigService.queryConfigValue(ConstSysConfig.CACHE_GLASS_GAP);
        //将尺寸重置为原始尺寸
        edgStorageCageService.update(new LambdaUpdateWrapper<EdgStorageCage>().set(EdgStorageCage::getRemainWidth, cellLength));
        //获取笼内的详情数据
        List<EdgSlotRemainVO> edgSlotRemainVOS = edgStorageCageDetailsService.querySlotRemainWidth(cellLength, glassGap);
        //按照查询结果对笼内现有玻璃的格子尺寸进行更新
        if(CollectionUtils.isNotEmpty(edgSlotRemainVOS)){
        if (CollectionUtils.isNotEmpty(edgSlotRemainVOS)) {
            edgStorageCageService.resetSlotRemainWidth(edgSlotRemainVOS);
        }
        return Boolean.TRUE;
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageCageDetailsServiceImpl.java
@@ -23,19 +23,20 @@
import com.mes.bigstoragetask.mapper.BigStorageCageFeedTaskMapper;
import com.mes.bigstoragetask.mapper.BigStorageCageOutTaskMapper;
import com.mes.common.config.Const;
import com.mes.common.config.ConstSysConfig;
import com.mes.damage.entity.Damage;
import com.mes.damage.service.DamageService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.mapper.GlassInfoMapper;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.job.PlcStorageCageTask;
import com.mes.sysconfig.entity.SysConfig;
import com.mes.sysconfig.service.SysConfigService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.mapper.TemperingGlassInfoMapper;
import com.mes.temperingglass.service.TemperingGlassInfoService;
import com.mes.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -73,9 +74,11 @@
    @Resource
    private TemperingGlassInfoService temperingGlassInfoService;
    @Resource
    private PlcStorageCageTask plcStorageCageTask;
    private SysConfigService sysConfigService;
//    @Resource
//    private PlcStorageCageTask plcStorageCageTask;
    @Resource
    private DamageService damageService;
@@ -84,18 +87,18 @@
    @Resource
    BigStorageCageHistoryTaskService bigStorageCageHistoryTaskService;
    @Value("${mes.minCount}")
    private int minCount;
    @Value("${mes.slotWidth}")
    private Integer slotWidth;
    @Value("${mes.glassGap}")
    private Integer glassGap;
    @Value("${mes.sequence.order}")
    private boolean sequenceOrder;
//
//    @Value("${mes.minCount}")
//    private int minCount;
//
//    @Value("${mes.slotWidth}")
//    private Integer slotWidth;
//
//    @Value("${mes.glassGap}")
//    private Integer glassGap;
//
//    @Value("${mes.sequence.order}")
//    private boolean sequenceOrder;
    @Override
@@ -171,7 +174,7 @@
        for (BigStorageCageDetails bigStorageCageDetails : bigStorageCageDetailsList
        ) {
            if (bigStorageCageDetails.getBigStorageCageFeedTask().getTaskState() == 0) {
                carWidth = carWidth - bigStorageCageDetails.getWidth() - glassGap;
                carWidth = carWidth - bigStorageCageDetails.getWidth() - 250;
            }
        }
        return carWidth;
@@ -237,7 +240,7 @@
        if (glassInfo != null) {
            BeanUtils.copyProperties(glassInfo, bigStorageCageDetails);
            bigStorageCageDetails.setState(1);
            bigStorageCageDetails.setGap(glassGap);
            bigStorageCageDetails.setGap(250);
            bigStorageCageDetailsList = new ArrayList<>();
            bigStorageCageDetailsList.add(bigStorageCageDetails);
        }
@@ -275,6 +278,7 @@
    @Override
    public BigStorageDTO queryTargetSlotByTempering(GlassInfo glassInfo) {
        BigStorageDTO bigStorageDTO = null;
        int slotWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_WIDTH);
        MPJLambdaWrapper<BigStorageCage> wrapper = new MPJLambdaWrapper<>(BigStorageCage.class)
                .selectAll(BigStorageCage.class)
                .leftJoin(BigStorageCageDetails.class, BigStorageCageDetails::getSlot, BigStorageCage::getSlot)
@@ -386,7 +390,7 @@
    @Override
    public List<TemperingLayoutDTO> queryTemperingOccupySlot() {
        return baseMapper.queryTemperingOccupySlot(minCount);
        return baseMapper.queryTemperingOccupySlot(10);
    }
    @Override
@@ -397,6 +401,8 @@
    @Override
    public boolean temperingGlass(String temperingLayoutId, String engineerId, String temperingFeedSequence) {
        LambdaQueryWrapper<TemperingGlassInfo> temperingGlassInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        SysConfig sysConfig = sysConfigService.queryConfigById(ConstSysConfig.CACHE_SEQUENCE_ORDER_TRUE);
        boolean sequenceOrder = Boolean.parseBoolean(sysConfig.getConfigValue());
        temperingGlassInfoLambdaQueryWrapper
                .eq(TemperingGlassInfo::getState, Const.TEMPERING_NEW);
        List<TemperingGlassInfo> temperingGlassInfoList = temperingGlassInfoMapper.selectList(temperingGlassInfoLambdaQueryWrapper);
@@ -414,7 +420,7 @@
            if (CollectionUtils.isNotEmpty(temperingGlassInfos)) {
                if ("0".equals(temperingFeedSequence)) {
                    if (CollectionUtils.isNotEmpty(temperingGlassInfos)) {
                        plcStorageCageTask.computeOutMoreGlassInfo(temperingGlassInfos, Boolean.FALSE, "");
//                        plcStorageCageTask.computeOutMoreGlassInfo(temperingGlassInfos, Boolean.FALSE, "");
                    }
                } else {
                    temperingGlassInfoService.saveBatch(temperingGlassInfos);
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageCageServiceImpl.java
@@ -17,14 +17,15 @@
import com.mes.bigstorage.mapper.BigStorageCageMapper;
import com.mes.bigstorage.service.BigStorageCageService;
import com.mes.common.config.Const;
import com.mes.common.config.ConstSysConfig;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.largenscreen.entity.PieChartVO;
import com.mes.sysconfig.service.SysConfigService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.service.TemperingGlassInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -55,12 +56,14 @@
    @Resource
    private GlassInfoService glassInfoService;
    @Resource
    private SysConfigService sysConfigService;
    @Value("${mes.glassGap}")
    private Integer glassGap;
    @Value("${mes.slotWidth}")
    private Integer slotWidth;
//    @Value("${mes.glassGap}")
//    private Integer glassGap;
//
//    @Value("${mes.slotWidth}")
//    private Integer slotWidth;
    //进片逻辑
    @Override
@@ -237,7 +240,8 @@
    @Override
    public void updateRemainWidth(int slot) {
        log.info("获取该格子内玻璃信息,计算格子剩余宽度");
        double width = 5000;
        double width = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_WIDTH);
        double glassGap = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_GLASS_GAP);
        LambdaQueryWrapper<BigStorageCageDetails> bigStorageCageDetailsWrapper = new LambdaQueryWrapper();
        bigStorageCageDetailsWrapper
                .eq(BigStorageCageDetails::getSlot, slot)
@@ -286,6 +290,7 @@
    @Override
    public List<Map<String, Object>> selectBigStorageCageUsage() {
        QueryWrapper<BigStorageCage> wrapper = new QueryWrapper<>();
        double slotWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_WIDTH);
        wrapper.select("device_id,ROUND(1 - SUM(CASE WHEN remain_width = " + slotWidth + " THEN 1 ELSE 0 END) / COUNT(device_id), 2)*100 AS percentage,SUM(CASE WHEN remain_width = " + slotWidth + " THEN 1 ELSE 0 END) AS count")
                .eq("enable_state", Const.SLOT_ON)
                .groupBy("device_id");
@@ -316,6 +321,7 @@
    @Override
    public Boolean resetCage() {
        double slotWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_WIDTH);
        bigStorageCageDetailsMapper.delete(Wrappers.<BigStorageCageDetails>lambdaQuery().eq(BigStorageCageDetails::getState, Const.GLASS_STATE_NEW));
        this.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, slotWidth)
                .notInSql(BigStorageCage::getSlot, "select distinct slot from big_storage_cage_details where state in ( 100, 102, 103, 104)"));
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstorage/service/impl/BigStorageGlassInfoServiceImpl.java
@@ -15,11 +15,12 @@
import com.mes.bigstorage.service.BigStorageGlassInfoService;
import com.mes.bigstorage.service.BigStorageGlassRelationInfoService;
import com.mes.common.config.Const;
import com.mes.common.config.ConstSysConfig;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.sysconfig.service.SysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -45,12 +46,14 @@
    BigStorageCageDetailsService bigStorageCageDetailsService;
    @Resource
    BigStorageGlassRelationInfoService bigStorageGlassRelationInfoService;
    @Value("${mes.slotWidth}")
    private Integer slotWidth;
    @Value("${mes.glassGap}")
    private Integer glassGap;
    @Value("${mes.outCarMaxSize}")
    private Integer outCarMaxSize;
    @Resource
    SysConfigService sysConfigService;
//    @Value("${mes.slotWidth}")
//    private Integer slotWidth;
//    @Value("${mes.glassGap}")
//    private Integer glassGap;
//    @Value("${mes.outCarMaxSize}")
//    private Integer outCarMaxSize;
    @Override
    public BigStorageDTO queryBigStorageTargetSlot(String engineerId, Integer temperingLayoutId, Integer temperingFeedSequence) {
@@ -82,6 +85,7 @@
                    .eq(BigStorageGlassRelationInfo::getTemperingLayoutId, temperingLayoutId)
                    .eq(BigStorageGlassRelationInfo::getTemperingFeedSequence, temperingFeedSequence));
        }
        Integer slotWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_WIDTH);
        BigStorageCageDetails bigStorageCageDetails = bigStorageCageDetailsService.getOne(new LambdaQueryWrapper<BigStorageCageDetails>()
                .eq(BigStorageCageDetails::getSlot, relationInfoOne.getSlot()).in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL_ZERO)
                .orderByDesc(BigStorageCageDetails::getSequence).last("limit 1"));
@@ -141,6 +145,9 @@
        if (CollectionUtil.isNotEmpty(list)) {
            return;
        }
        Integer slotWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_WIDTH);
        Integer glassGap = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_GLASS_GAP);
        Integer outCarMaxSize = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_OUT_CAR_SIZE);
//        Engineering engineering = engineeringMapper.selectOne(new LambdaQueryWrapper<Engineering>()
//                .eq(Engineering::getEngineerId, glassInfo.getEngineerId()));
        //获取玻璃的工程id,按照工程id获取工程下的所有玻璃信息
@@ -179,6 +186,7 @@
    @Override
    public int bigStorageSlotPair(BigStorageGlassInfo bigStorageGlassInfo) {
        //获取所有空闲可用的格子号
        Integer slotWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_WIDTH);
        BigStorageCage storageCage = bigStorageCageService.getOne(new LambdaQueryWrapper<BigStorageCage>()
                .eq(BigStorageCage::getEnableState, Const.SLOT_ON).eq(BigStorageCage::getRemainWidth, slotWidth)
                .le(BigStorageCage::getMinThickness, bigStorageGlassInfo.getThickness())
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/bigstoragetask/service/impl/BigStorageCageFeedTaskServiceImpl.java
@@ -7,9 +7,11 @@
import com.mes.bigstoragetask.entity.BigStorageCageFeedTask;
import com.mes.bigstoragetask.mapper.BigStorageCageFeedTaskMapper;
import com.mes.bigstoragetask.service.BigStorageCageFeedTaskService;
import org.springframework.beans.factory.annotation.Value;
import com.mes.common.config.ConstSysConfig;
import com.mes.sysconfig.service.SysConfigService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
@@ -23,8 +25,10 @@
@Service
public class BigStorageCageFeedTaskServiceImpl extends ServiceImpl<BigStorageCageFeedTaskMapper, BigStorageCageFeedTask> implements BigStorageCageFeedTaskService {
    @Value("${mes.glassGap}")
    private Integer glassGap;
    //    @Value("${mes.glassGap}")
//    private Integer glassGap;
    @Resource
    SysConfigService sysConfigService;
    @Override
    public void addFeedTask(BigStorageCageDetails slotInfo, Integer plcFeedReqLine, int taskType) {
@@ -45,6 +49,7 @@
    @Override
    public BigStorageDTO querySitToUpRemainWidth(Integer line) {
        Integer glassGap = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_GLASS_GAP);
        return baseMapper.querySitToUpRemainWidth(line, glassGap);
    }
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/OpcPlcStorageCageNewTask.java
@@ -24,12 +24,14 @@
import com.mes.bigstoragecagetask.service.BigStorageCageTaskService;
import com.mes.bigstoragetask.entity.UpdateBigStorageCageDTO;
import com.mes.common.config.Const;
import com.mes.common.config.ConstSysConfig;
import com.mes.damage.entity.Damage;
import com.mes.damage.service.DamageService;
import com.mes.edgglasstask.entity.EdgGlassTaskInfo;
import com.mes.edgglasstask.service.EdgGlassTaskInfoService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.sysconfig.service.SysConfigService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.service.TemperingGlassInfoService;
import com.mes.utils.RedisUtil;
@@ -37,7 +39,6 @@
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@@ -75,6 +76,9 @@
    @Autowired(required = false)
    MiloService miloService;
    @Resource
    SysConfigService sysConfigService;
    /**
     * 直通格子
     */
@@ -82,27 +86,6 @@
    @Resource
    private RedisUtil redisUtil;
    @Value("${mes.slotWidth}")
    private Integer slotWidth;
    @Value("${mes.glassGap}")
    private Integer glassGap;
    @Value("${mes.carWidth}")
    private Integer carWidth;
    @Value("${mes.outCarMaxSize}")
    private Integer outCarMaxSize;
    @Value("${mes.temperingOutTargetPosition}")
    private Integer temperingOutTargetPosition;
    @Value("${mes.artificialOutTargetPosition}")
    private Integer artificialOutTargetPosition;
    @Value("${mes.slotMaxHeight}")
    private Integer slotMaxHeight;
    @Value("${mes.slotMaxthickness}")
    private Integer slotMaxthickness;
    @Scheduled(fixedDelay = 1000)
    public void inBigStorageTask() throws Exception {
@@ -173,6 +156,10 @@
            miloService.writeToOpcWord(generateReadWriteEntity("DLP1A.DLP1A.alarmSignal", 8));
            return;
        }
        Integer glassGap = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_GLASS_GAP);
        Integer slotMaxthickness = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_MAX_THICKNESS);
        Integer slotWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_WIDTH);
        Integer slotMaxHeight = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_MAX_HEIGHT);
        //按照玻璃厚度分组,判断剩余格子是否可以存放
        Map<Double, Long> thickCountMap = glassInfoList.stream().collect(Collectors.groupingBy(GlassInfo::getThickness, Collectors.counting()));
        if (glassInfoList.get(0).getThickness() < slotMaxthickness) {
@@ -303,6 +290,8 @@
        //是否允许钢化
        //是否有正在钢化的玻璃:钢化小片表关联历史任务表,筛选未出笼的玻璃信息
//            获取当前钢化任务未完成出片的玻璃信息
        Integer temperingOutTargetPosition = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_TEMPERING_OUT_TARGET_POSITION);
        List<TemperingGlassInfo> unFinishTemperingGlassInfoList = temperingGlassInfoService.list(new LambdaQueryWrapper<TemperingGlassInfo>()
                .eq(TemperingGlassInfo::getState, Const.TEMPERING_NEW).orderByAsc(TemperingGlassInfo::getTemperingLayoutId).orderByAsc(TemperingGlassInfo::getTemperingFeedSequence));
        if (CollectionUtil.isNotEmpty(unFinishTemperingGlassInfoList)) {
@@ -354,6 +343,8 @@
            }
        }
        //是否有人工下片任务   有直接出
        Integer artificialOutTargetPosition = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_ARTIFICIAL_OUT_TARGET_POSITION);
        Integer outCarMaxSize = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_OUT_CAR_SIZE);
        List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL)
                .orderByAsc(BigStorageCageDetails::getSlot)
@@ -761,7 +752,9 @@
        //任务数据:获取车子存放玻璃最大数量,玻璃间隔
        List<BigStorageCageTask> bigStorageCageTaskList = new ArrayList<>();
        //打车剩余尺寸
        Integer remainWidth = carWidth;
        Integer outCarMaxSize = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_OUT_CAR_SIZE);
        Integer glassGap = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_GLASS_GAP);
        Integer remainWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_CAR_WIDTH);
        for (T e : list) {
            if (bigStorageCageTaskList.size() >= outCarMaxSize || Math.max((int) e.getWidth(), (int) e.getHeight()) > remainWidth) {
                break;
@@ -811,6 +804,8 @@
        List<BigStorageCageDetails> inSlotGlassList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                .in(BigStorageCageDetails::getSlot, slotList).in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
        Map<Integer, Double> slotRemainMap = new HashMap<>();
        Integer glassGap = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_GLASS_GAP);
        Integer slotWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_WIDTH);
        //是否存在有格子非空的玻璃
        if (CollectionUtil.isNotEmpty(inSlotGlassList)) {
            //存在  将格子内的玻璃分别进行更新
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/OpcPlcStorageCageTask.java
@@ -1,613 +1,613 @@
package com.mes.job;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.yulichang.toolkit.JoinWrappers;
import com.kangaroohy.milo.model.ReadWriteEntity;
import com.kangaroohy.milo.service.MiloService;
import com.mes.base.entity.BigStorageCageBaseInfo;
import com.mes.bigstorage.entity.BigStorageCage;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.dto.BigStorageDTO;
import com.mes.bigstorage.entity.dto.SlotSequenceDTO;
import com.mes.bigstorage.entity.dto.TemperingLayoutDTO;
import com.mes.bigstorage.service.BigStorageCageDetailsService;
import com.mes.bigstorage.service.BigStorageCageService;
import com.mes.bigstoragecagetask.entity.BigStorageCageHistoryTask;
import com.mes.bigstoragecagetask.entity.BigStorageCageTask;
import com.mes.bigstoragecagetask.service.BigStorageCageHistoryTaskService;
import com.mes.bigstoragecagetask.service.BigStorageCageTaskService;
import com.mes.bigstoragetask.entity.UpdateBigStorageCageDTO;
import com.mes.common.config.Const;
import com.mes.damage.entity.Damage;
import com.mes.damage.service.DamageService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.service.TemperingGlassInfoService;
import com.mes.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author SNG-015
 */
@Component
@Slf4j
public class OpcPlcStorageCageTask {
    @Resource
    private BigStorageCageDetailsService bigStorageCageDetailsService;
    @Resource
    private TemperingGlassInfoService temperingGlassInfoService;
    @Resource
    private DamageService damageService;
    @Resource
    private GlassInfoService glassInfoService;
    @Resource
    private BigStorageCageService bigStorageCageService;
    @Resource
    private BigStorageCageHistoryTaskService bigStorageCageHistoryTaskService;
    @Resource
    private BigStorageCageTaskService bigStorageCageTaskService;
    @Autowired(required = false)
    MiloService miloService;
    @Resource
    private RedisUtil redisUtil;
    @Value("${mes.slotWidth}")
    private Integer slotWidth;
    @Value("${mes.glassGap}")
    private Integer glassGap;
    @Value("${mes.carWidth}")
    private Integer carWidth;
    @Value("${mes.outCarMaxSize}")
    private Integer outCarMaxSize;
    @Value("${mes.sequence.order}")
    private boolean sequenceOrder;
    @Value("${mes.temperingOutTargetPosition}")
    private Integer temperingOutTargetPosition;
    @Value("${mes.artificialOutTargetPosition}")
    private Integer artificialOutTargetPosition;
    // @Scheduled(fixedDelay = 1000)
    public void inBigStorageTask() throws Exception {
        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("DLP1A.DLP1A.mesControl");
        if (true != Boolean.parseBoolean(inkageEntity.getValue() + "")) {
            log.info("当前为非联机状态,结束进片任务");
            return;
        }
        ReadWriteEntity requestEntity = miloService.readFromOpcUa("DLP1A.DLP1A.RequestMes");
        if (!"1".equals(requestEntity.getValue() + "")) {
            log.info("当前未收到进片请求,结束进片任务");
            return;
        }
        ReadWriteEntity mesReplyEntity = miloService.readFromOpcUa("DLP1A.DLP1A.MesReply");
        if ("1".equals(mesReplyEntity.getValue() + "")) {
            log.info("有正在执行的任务,结束进片任务");
            return;
        }
        //获取进片任务表
        List<BigStorageCageTask> inTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_in_one_task");
        if (CollectionUtil.isEmpty(inTaskList)) {
            log.info("当前大车无进片玻璃,结束进片任务");
        }
        List<String> glassIdList = inTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
        log.info("获取任务的玻璃id:{}", glassIdList);
        Map<String, Long> glassCountMap = glassIdList.stream().collect(Collectors.groupingBy(e -> e, Collectors.counting()));
        for (Map.Entry<String, Long> entry : glassCountMap.entrySet()) {
            if (entry.getValue() > 1) {
                log.info("进片玻璃{}存在相同,结束本次任务", entry.getKey());
                //todo:向plc发送报警
                return;
            }
        }
        List<BigStorageCageDetails> detailsList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>().in(BigStorageCageDetails::getGlassId, glassIdList)
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
        if (CollectionUtil.isNotEmpty(detailsList)) {
            log.info("理片笼存在相同的进片玻璃{},结束本次任务", detailsList);
            //todo:向plc发送报警
            return;
        }
        List<GlassInfo> glassInfoList = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>().in(GlassInfo::getGlassId, glassIdList));
        Map<String, List<GlassInfo>> glassListMap = glassInfoList.stream().collect(Collectors.groupingBy(GlassInfo::getGlassId));
        //计算目标格子
        List<BigStorageCageHistoryTask> historyTasks = new ArrayList<>();
        for (BigStorageCageTask task : inTaskList) {
            GlassInfo info = glassListMap.get(task.getGlassId()).get(0);
            //获取目标格子信息
            BigStorageDTO bigStorageDTO = bigStorageCageDetailsService.queryTargetSlotByTempering(info);
//            临时更新格子的剩余尺寸:防止相邻玻璃进同一格子造成剩余尺寸不足,玻璃越界的情况,任务完成后再次更新大理片笼表剩余宽度(按照笼内玻璃数量更新大理片笼剩余尺寸)
            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>()
                    .set(BigStorageCage::getRemainWidth, bigStorageDTO.getWidth() - Math.max(info.getWidth(), info.getHeight()) - glassGap)
                    .eq(BigStorageCage::getSlot, bigStorageDTO.getSlot()));
            task.setTargetSlot(bigStorageDTO.getSlot());
            task.setGlassId(info.getGlassId());
            bigStorageCageTaskService.updateTaskMessage("big_storage_cage_in_one_task", task);
            //存放历史任务
            BigStorageCageHistoryTask historyTask = new BigStorageCageHistoryTask();
            BeanUtils.copyProperties(task, historyTask);
            historyTask.setTaskType(Const.BIG_STORAGE_BEFORE_IN);
            historyTask.setGlassCount(glassInfoList.size());
            historyTask.setTaskState(Const.ENGINEERING_NEW);
            historyTasks.add(historyTask);
            BigStorageCageDetails cageDetails = new BigStorageCageDetails();
            BeanUtils.copyProperties(info, cageDetails);
            cageDetails.setSlot(bigStorageDTO.getSlot());
            cageDetails.setState(Const.GLASS_STATE_NEW);
            cageDetails.setDeviceId(bigStorageDTO.getDeviceId());
            cageDetails.setGap(glassGap);
            cageDetails.setId(null);
            bigStorageCageDetailsService.save(cageDetails);
        }
        //历史数据入库
        bigStorageCageHistoryTaskService.saveBatch(historyTasks);
        //向opc发送启动信号
        miloService.writeToOpcWord(generateReadWriteEntity("DLP1A.DLP1A.MesReply", 1));
    }
    // @Scheduled(fixedDelay = 1000)
    public void outBigStorageTask() throws Exception {
        Date startDate = new Date();
        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("DLP1B.DLP1B.mesControl");
        if (true != Boolean.parseBoolean(inkageEntity.getValue() + "")) {
            log.info("当前为非联机状态,结束进片任务");
            return;
        }
        ReadWriteEntity requestEntity = miloService.readFromOpcUa("DLP1B.DLP1B.RequestMes");
        if (!"1".equals(requestEntity.getValue() + "")) {
            log.info("当前未收到出片请求,结束出片任务");
            return;
        }
        //获取出片任务表
        List<BigStorageCageTask> outTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_out_one_task");
        if (CollectionUtil.isNotEmpty(outTaskList)) {
            log.info("有正在执行的出片任务,结束本次出片任务");
            return;
        }
        //todo:是否允许钢化
        if (redisUtil.getCacheObject("temperingSwitch")) {
            //是否有正在钢化的玻璃:钢化小片表关联历史任务表,筛选未出笼的玻璃信息
//            获取当前钢化任务未完成出片的玻璃信息
            List<TemperingGlassInfo> unFinishTemperingGlassInfoList = temperingGlassInfoService.list(new LambdaQueryWrapper<TemperingGlassInfo>().eq(TemperingGlassInfo::getState, Const.TEMPERING_NEW));
            if (CollectionUtil.isNotEmpty(unFinishTemperingGlassInfoList)) {
                List<String> glassIdList = unFinishTemperingGlassInfoList.stream().map(TemperingGlassInfo::getGlassId).collect(Collectors.toList());
                List<BigStorageCageHistoryTask> historyTaskList = bigStorageCageHistoryTaskService.list(new LambdaQueryWrapper<BigStorageCageHistoryTask>()
                        .eq(BigStorageCageHistoryTask::getTaskType, Const.BIG_STORAGE_BEFORE_OUT)
                        .in(BigStorageCageHistoryTask::getGlassId, glassIdList));
                List<TemperingGlassInfo> temperingGlassList = unFinishTemperingGlassInfoList;
                if (CollectionUtil.isNotEmpty(historyTaskList)) {
                    List<String> taskGlassList = historyTaskList.stream().map(BigStorageCageHistoryTask::getGlassId).collect(Collectors.toList());
                    temperingGlassList = unFinishTemperingGlassInfoList.stream().filter(e -> !taskGlassList.contains(e.getGlassId())).collect(Collectors.toList());
                }
                if (CollectionUtil.isNotEmpty(temperingGlassList)) {
                    log.info("有正在出片的钢化任务");
                    computeOutGlassInfo(temperingGlassList, "big_storage_cage_out_one_task", temperingOutTargetPosition, Const.GLASS_STATE_OUT_ING, Const.BIG_STORAGE_BEFORE_OUT);
                    Date endDate = new Date();
                    log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
                    return;
                }
            }
            //钢化优先:获取理片笼  玻璃小片  破损表 数量   判断笼内版图是否到齐
            List<TemperingLayoutDTO> temperingLayoutDTOList = bigStorageCageDetailsService.temperingIsAll();
            if (CollectionUtil.isNotEmpty(temperingLayoutDTOList)) {
                //玻璃到齐包括已出片的
                //到齐,将玻璃小片数据存入钢化小片表,逻辑生成出片任务  结束
                for (TemperingLayoutDTO item : temperingLayoutDTOList) {
//                    if (item.getEngineerId().equals(redisUtil.getCacheObject("temperingengineerId"))) {
                    List<TemperingGlassInfo> temperingGlassInfos = glassInfoService.selectJoinList(TemperingGlassInfo.class, JoinWrappers.lambda(GlassInfo.class)
                            .selectAll(GlassInfo.class)
                            .select("-1 as state")
                            .selectAs(BigStorageCageDetails::getSlot, TemperingGlassInfo::getSlot)
                            .innerJoin(BigStorageCageDetails.class, BigStorageCageDetails::getGlassId, GlassInfo::getGlassId)
                            .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                            .eq(GlassInfo::getTemperingLayoutId, item.getTemperingLayoutId())
                            .eq(GlassInfo::getEngineerId, item.getEngineerId())
                            .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence));
                    if (CollectionUtil.isNotEmpty(temperingGlassInfos)) {
                        temperingGlassInfoService.saveBatch(temperingGlassInfos);
                        computeOutGlassInfo(temperingGlassInfos, "big_storage_cage_out_one_task", temperingOutTargetPosition, Const.GLASS_STATE_OUT_ING, Const.BIG_STORAGE_BEFORE_OUT);
                        Date endDate = new Date();
                        log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
                        return;
                    }
//package com.mes.job;
//
//import cn.hutool.core.collection.CollectionUtil;
//import cn.hutool.core.lang.Assert;
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
//import com.github.yulichang.toolkit.JoinWrappers;
//import com.kangaroohy.milo.model.ReadWriteEntity;
//import com.kangaroohy.milo.service.MiloService;
//import com.mes.base.entity.BigStorageCageBaseInfo;
//import com.mes.bigstorage.entity.BigStorageCage;
//import com.mes.bigstorage.entity.BigStorageCageDetails;
//import com.mes.bigstorage.entity.dto.BigStorageDTO;
//import com.mes.bigstorage.entity.dto.SlotSequenceDTO;
//import com.mes.bigstorage.entity.dto.TemperingLayoutDTO;
//import com.mes.bigstorage.service.BigStorageCageDetailsService;
//import com.mes.bigstorage.service.BigStorageCageService;
//import com.mes.bigstoragecagetask.entity.BigStorageCageHistoryTask;
//import com.mes.bigstoragecagetask.entity.BigStorageCageTask;
//import com.mes.bigstoragecagetask.service.BigStorageCageHistoryTaskService;
//import com.mes.bigstoragecagetask.service.BigStorageCageTaskService;
//import com.mes.bigstoragetask.entity.UpdateBigStorageCageDTO;
//import com.mes.common.config.Const;
//import com.mes.damage.entity.Damage;
//import com.mes.damage.service.DamageService;
//import com.mes.glassinfo.entity.GlassInfo;
//import com.mes.glassinfo.service.GlassInfoService;
//import com.mes.temperingglass.entity.TemperingGlassInfo;
//import com.mes.temperingglass.service.TemperingGlassInfoService;
//import com.mes.utils.RedisUtil;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang.StringUtils;
//import org.springframework.beans.BeanUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.stereotype.Component;
//
//import javax.annotation.Resource;
//import java.util.*;
//import java.util.stream.Collectors;
//
///**
// * @author SNG-015
// */
//@Component
//@Slf4j
//public class OpcPlcStorageCageTask {
//    @Resource
//    private BigStorageCageDetailsService bigStorageCageDetailsService;
//    @Resource
//    private TemperingGlassInfoService temperingGlassInfoService;
//    @Resource
//    private DamageService damageService;
//    @Resource
//    private GlassInfoService glassInfoService;
//    @Resource
//    private BigStorageCageService bigStorageCageService;
//    @Resource
//    private BigStorageCageHistoryTaskService bigStorageCageHistoryTaskService;
//    @Resource
//    private BigStorageCageTaskService bigStorageCageTaskService;
//
//    @Autowired(required = false)
//    MiloService miloService;
//
//    @Resource
//    private RedisUtil redisUtil;
//
//    @Value("${mes.slotWidth}")
//    private Integer slotWidth;
//
//    @Value("${mes.glassGap}")
//    private Integer glassGap;
//
//    @Value("${mes.carWidth}")
//    private Integer carWidth;
//
//    @Value("${mes.outCarMaxSize}")
//    private Integer outCarMaxSize;
//
//    @Value("${mes.sequence.order}")
//    private boolean sequenceOrder;
//
//    @Value("${mes.temperingOutTargetPosition}")
//    private Integer temperingOutTargetPosition;
//    @Value("${mes.artificialOutTargetPosition}")
//    private Integer artificialOutTargetPosition;
//
//
//    // @Scheduled(fixedDelay = 1000)
//    public void inBigStorageTask() throws Exception {
//        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("DLP1A.DLP1A.mesControl");
//        if (true != Boolean.parseBoolean(inkageEntity.getValue() + "")) {
//            log.info("当前为非联机状态,结束进片任务");
//            return;
//        }
//        ReadWriteEntity requestEntity = miloService.readFromOpcUa("DLP1A.DLP1A.RequestMes");
//        if (!"1".equals(requestEntity.getValue() + "")) {
//            log.info("当前未收到进片请求,结束进片任务");
//            return;
//        }
//        ReadWriteEntity mesReplyEntity = miloService.readFromOpcUa("DLP1A.DLP1A.MesReply");
//        if ("1".equals(mesReplyEntity.getValue() + "")) {
//            log.info("有正在执行的任务,结束进片任务");
//            return;
//        }
//        //获取进片任务表
//        List<BigStorageCageTask> inTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_in_one_task");
//        if (CollectionUtil.isEmpty(inTaskList)) {
//            log.info("当前大车无进片玻璃,结束进片任务");
//        }
//
//        List<String> glassIdList = inTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
//        log.info("获取任务的玻璃id:{}", glassIdList);
//        Map<String, Long> glassCountMap = glassIdList.stream().collect(Collectors.groupingBy(e -> e, Collectors.counting()));
//        for (Map.Entry<String, Long> entry : glassCountMap.entrySet()) {
//            if (entry.getValue() > 1) {
//                log.info("进片玻璃{}存在相同,结束本次任务", entry.getKey());
//                //todo:向plc发送报警
//                return;
//            }
//        }
//        List<BigStorageCageDetails> detailsList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>().in(BigStorageCageDetails::getGlassId, glassIdList)
//                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
//        if (CollectionUtil.isNotEmpty(detailsList)) {
//            log.info("理片笼存在相同的进片玻璃{},结束本次任务", detailsList);
//            //todo:向plc发送报警
//            return;
//        }
//        List<GlassInfo> glassInfoList = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>().in(GlassInfo::getGlassId, glassIdList));
//
//        Map<String, List<GlassInfo>> glassListMap = glassInfoList.stream().collect(Collectors.groupingBy(GlassInfo::getGlassId));
//
//        //计算目标格子
//        List<BigStorageCageHistoryTask> historyTasks = new ArrayList<>();
//        for (BigStorageCageTask task : inTaskList) {
//            GlassInfo info = glassListMap.get(task.getGlassId()).get(0);
//            //获取目标格子信息
//            BigStorageDTO bigStorageDTO = bigStorageCageDetailsService.queryTargetSlotByTempering(info);
////            临时更新格子的剩余尺寸:防止相邻玻璃进同一格子造成剩余尺寸不足,玻璃越界的情况,任务完成后再次更新大理片笼表剩余宽度(按照笼内玻璃数量更新大理片笼剩余尺寸)
//            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>()
//                    .set(BigStorageCage::getRemainWidth, bigStorageDTO.getWidth() - Math.max(info.getWidth(), info.getHeight()) - glassGap)
//                    .eq(BigStorageCage::getSlot, bigStorageDTO.getSlot()));
//            task.setTargetSlot(bigStorageDTO.getSlot());
//            task.setGlassId(info.getGlassId());
//            bigStorageCageTaskService.updateTaskMessage("big_storage_cage_in_one_task", task);
//            //存放历史任务
//            BigStorageCageHistoryTask historyTask = new BigStorageCageHistoryTask();
//            BeanUtils.copyProperties(task, historyTask);
//            historyTask.setTaskType(Const.BIG_STORAGE_BEFORE_IN);
//            historyTask.setGlassCount(glassInfoList.size());
//            historyTask.setTaskState(Const.ENGINEERING_NEW);
//            historyTasks.add(historyTask);
//            BigStorageCageDetails cageDetails = new BigStorageCageDetails();
//            BeanUtils.copyProperties(info, cageDetails);
//            cageDetails.setSlot(bigStorageDTO.getSlot());
//            cageDetails.setState(Const.GLASS_STATE_NEW);
//            cageDetails.setDeviceId(bigStorageDTO.getDeviceId());
//            cageDetails.setGap(glassGap);
//            cageDetails.setId(null);
//            bigStorageCageDetailsService.save(cageDetails);
//        }
//        //历史数据入库
//        bigStorageCageHistoryTaskService.saveBatch(historyTasks);
//        //向opc发送启动信号
//        miloService.writeToOpcWord(generateReadWriteEntity("DLP1A.DLP1A.MesReply", 1));
//    }
//
//    // @Scheduled(fixedDelay = 1000)
//    public void outBigStorageTask() throws Exception {
//        Date startDate = new Date();
//        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("DLP1B.DLP1B.mesControl");
//        if (true != Boolean.parseBoolean(inkageEntity.getValue() + "")) {
//            log.info("当前为非联机状态,结束进片任务");
//            return;
//        }
//        ReadWriteEntity requestEntity = miloService.readFromOpcUa("DLP1B.DLP1B.RequestMes");
//        if (!"1".equals(requestEntity.getValue() + "")) {
//            log.info("当前未收到出片请求,结束出片任务");
//            return;
//        }
//        //获取出片任务表
//        List<BigStorageCageTask> outTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_out_one_task");
//        if (CollectionUtil.isNotEmpty(outTaskList)) {
//            log.info("有正在执行的出片任务,结束本次出片任务");
//            return;
//        }
//        //todo:是否允许钢化
//        if (redisUtil.getCacheObject("temperingSwitch")) {
//            //是否有正在钢化的玻璃:钢化小片表关联历史任务表,筛选未出笼的玻璃信息
////            获取当前钢化任务未完成出片的玻璃信息
//            List<TemperingGlassInfo> unFinishTemperingGlassInfoList = temperingGlassInfoService.list(new LambdaQueryWrapper<TemperingGlassInfo>().eq(TemperingGlassInfo::getState, Const.TEMPERING_NEW));
//            if (CollectionUtil.isNotEmpty(unFinishTemperingGlassInfoList)) {
//                List<String> glassIdList = unFinishTemperingGlassInfoList.stream().map(TemperingGlassInfo::getGlassId).collect(Collectors.toList());
//                List<BigStorageCageHistoryTask> historyTaskList = bigStorageCageHistoryTaskService.list(new LambdaQueryWrapper<BigStorageCageHistoryTask>()
//                        .eq(BigStorageCageHistoryTask::getTaskType, Const.BIG_STORAGE_BEFORE_OUT)
//                        .in(BigStorageCageHistoryTask::getGlassId, glassIdList));
//                List<TemperingGlassInfo> temperingGlassList = unFinishTemperingGlassInfoList;
//                if (CollectionUtil.isNotEmpty(historyTaskList)) {
//                    List<String> taskGlassList = historyTaskList.stream().map(BigStorageCageHistoryTask::getGlassId).collect(Collectors.toList());
//                    temperingGlassList = unFinishTemperingGlassInfoList.stream().filter(e -> !taskGlassList.contains(e.getGlassId())).collect(Collectors.toList());
//                }
//                if (CollectionUtil.isNotEmpty(temperingGlassList)) {
//                    log.info("有正在出片的钢化任务");
//                    computeOutGlassInfo(temperingGlassList, "big_storage_cage_out_one_task", temperingOutTargetPosition, Const.GLASS_STATE_OUT_ING, Const.BIG_STORAGE_BEFORE_OUT);
//                    Date endDate = new Date();
//                    log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//                    return;
//                }
//            }
//            //钢化优先:获取理片笼  玻璃小片  破损表 数量   判断笼内版图是否到齐
//            List<TemperingLayoutDTO> temperingLayoutDTOList = bigStorageCageDetailsService.temperingIsAll();
//            if (CollectionUtil.isNotEmpty(temperingLayoutDTOList)) {
//                //玻璃到齐包括已出片的
//                //到齐,将玻璃小片数据存入钢化小片表,逻辑生成出片任务  结束
//                for (TemperingLayoutDTO item : temperingLayoutDTOList) {
////                    if (item.getEngineerId().equals(redisUtil.getCacheObject("temperingengineerId"))) {
//                    List<TemperingGlassInfo> temperingGlassInfos = glassInfoService.selectJoinList(TemperingGlassInfo.class, JoinWrappers.lambda(GlassInfo.class)
//                            .selectAll(GlassInfo.class)
//                            .select("-1 as state")
//                            .selectAs(BigStorageCageDetails::getSlot, TemperingGlassInfo::getSlot)
//                            .innerJoin(BigStorageCageDetails.class, BigStorageCageDetails::getGlassId, GlassInfo::getGlassId)
//                            .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
//                            .eq(GlassInfo::getTemperingLayoutId, item.getTemperingLayoutId())
//                            .eq(GlassInfo::getEngineerId, item.getEngineerId())
//                            .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence));
//                    if (CollectionUtil.isNotEmpty(temperingGlassInfos)) {
//                        temperingGlassInfoService.saveBatch(temperingGlassInfos);
//                        computeOutGlassInfo(temperingGlassInfos, "big_storage_cage_out_one_task", temperingOutTargetPosition, Const.GLASS_STATE_OUT_ING, Const.BIG_STORAGE_BEFORE_OUT);
//                        Date endDate = new Date();
//                        log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//                        return;
//                    }
                }
            }
        }
        //是否有人工下片任务   有直接出
        List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL)
                .orderByAsc(BigStorageCageDetails::getSlot)
                .orderByAsc(BigStorageCageDetails::getId));
        if (CollectionUtil.isNotEmpty(artificialList)) {
            computeOutGlassInfo(artificialList, "big_storage_cage_out_one_task", artificialOutTargetPosition, Const.GLASS_STATE_OUT_ING, Const.BIG_STORAGE_BEFORE_OUT);
            Date endDate = new Date();
            log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
            return;
        }
        //是否存在需要内部调度的格子:执行内部调度任务
        List<TemperingLayoutDTO> temperingOccupySlotList = bigStorageCageDetailsService.queryTemperingOccupySlot();
        if (CollectionUtil.isNotEmpty(temperingOccupySlotList)) {
            loop:
            for (TemperingLayoutDTO temperingOccupySlot : temperingOccupySlotList) {
                List<SlotSequenceDTO> slotSequenceList = bigStorageCageDetailsService.queryGlassMaxAndMin(temperingOccupySlot.getEngineerId(), temperingOccupySlot.getTemperingLayoutId());
                for (int i = 0; i < slotSequenceList.size() - 1; i++) {
                    SlotSequenceDTO first = slotSequenceList.get(i);
                    SlotSequenceDTO second = slotSequenceList.get(i + 1);
                    int slotWidth = carWidth - first.getRemainWidth() - glassGap;
                    int totalCount = first.getGlassCount() + second.getGlassCount();
                    if (totalCount <= 6 && first.getMinSequence() == second.getMaxSequence() + 1
                            && second.getRemainWidth() > slotWidth && slotWidth >= 0) {
                        List<BigStorageCageDetails> list = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                                .eq(BigStorageCageDetails::getSlot, first.getSlot()).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                                .orderBy(Boolean.TRUE, sequenceOrder, BigStorageCageDetails::getTemperingFeedSequence));
                        if (CollectionUtil.isNotEmpty(list)) {
                            computeOutGlassInfo(list, "big_storage_cage_out_one_task", second.getSlot(), Const.GLASS_STATE_SCHEDULE_ING, Const.BIG_STORAGE_BEFORE_DISPATCH);
                        }
                        //使用Arrays.asList() 使用removeAll报错,改为正常使用List
                        List<Integer> slotList = new ArrayList<>();
                        slotList.add(second.getSlot());
                        updateSlotRemainBySlots(slotList);
                        break loop;
                    }
                }
            }
        }
        Date endDate = new Date();
        log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
        return;
    }
    // @Scheduled(fixedDelay = 1000)
    public void finishInBigStorageTask() throws Exception {
        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("DLP1A.DLP1A.mesControl");
        if (true != Boolean.parseBoolean(inkageEntity.getValue() + "")) {
            log.info("当前为非联机状态,结束完成进片任务");
            return;
        }
        //获取进片任务表
        List<BigStorageCageTask> inTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_in_one_task");
        if (CollectionUtil.isEmpty(inTaskList)) {
            log.info("当前大车无进片玻璃,结束完成进片任务");
            return;
        }
        List<BigStorageCageTask> unFinishTaskList = inTaskList.stream().filter(e -> e.getTaskState() <= 1 || e.getStartSlot() == 0).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(unFinishTaskList)) {
            log.info("存在未完成的玻璃信息,玻璃:{}", unFinishTaskList);
            return;
        }
        Map<Integer, List<BigStorageCageTask>> taskMap = inTaskList.stream().collect(Collectors.groupingBy(BigStorageCageTask::getTaskState));
        //按照任务状态修改大理片笼内的玻璃数据
//        重新计算大理片笼内的剩余尺寸
        taskMap.forEach((e1, v) -> {
            if (e1 == 2) {
                //进片完成
                log.info("3、获取进片已完成的玻璃信息id:{}", v);
                List<Integer> inSuccessGlassSlot = v.stream().map(BigStorageCageTask::getTargetSlot).collect(Collectors.toList());
                List<UpdateBigStorageCageDTO> storageCageDTOList = v.stream().map(e -> {
                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
                    BeanUtils.copyProperties(e, storageCageDTO);
                    return storageCageDTO;
                }).collect(Collectors.toList());
                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_IN);
                log.info("4、大理片笼进片状态已完成已完成的玻璃信息id:{}", v);
                updateSlotRemainBySlots(inSuccessGlassSlot);
            } else if (e1 == 3) {
                //破损处理
                dealDamageInTask(v);
            } else {
                //清空理片笼空数据
                noDealInTask(v);
            }
        });
        for (BigStorageCageTask item : inTaskList) {
            //更新历史任务表中的任务状态
            bigStorageCageHistoryTaskService.update(new LambdaUpdateWrapper<BigStorageCageHistoryTask>()
                    .set(BigStorageCageHistoryTask::getTaskState, item.getTaskState())
                    .eq(BigStorageCageHistoryTask::getTaskType, Const.BIG_STORAGE_BEFORE_IN)
                    .eq(BigStorageCageHistoryTask::getTargetSlot, item.getTargetSlot())
                    .eq(BigStorageCageHistoryTask::getGlassId, item.getGlassId()));
            item.setTargetSlot(0);
            //清空任务表数据
            bigStorageCageTaskService.updateTaskMessage("big_storage_cage_in_one_task", item);
        }
        //清空启动状态
        //向opc发送启动信号
        miloService.writeToOpcWord(generateReadWriteEntity("DLP1A.DLP1A.MesReply", 0));
    }
    // @Scheduled(fixedDelay = 1000)
    public void finishOutBigStorageTask() throws Exception {
        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("DLP1B.DLP1B.mesControl");
        if (true != Boolean.parseBoolean(inkageEntity.getValue() + "")) {
            log.info("当前为非联机状态,结束完成出片任务");
            return;
        }
        //获取进片任务表
        List<BigStorageCageTask> outTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_out_one_task");
        if (CollectionUtil.isEmpty(outTaskList)) {
            log.info("当前大车无进片玻璃,结束完成进片任务");
            return;
        }
        List<BigStorageCageTask> unFinishTaskList = outTaskList.stream().filter(e -> e.getTaskState() <= 1 || e.getStartSlot() == 0).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(unFinishTaskList)) {
            log.info("存在未完成的玻璃信息,玻璃:{}", unFinishTaskList);
            return;
        }
        Map<Integer, List<BigStorageCageTask>> taskMap = outTaskList.stream().collect(Collectors.groupingBy(BigStorageCageTask::getTaskState));
        int taskType = 0;
        if (Const.OUT_TARGET_POSITION_ALL.contains(outTaskList.get(0).getTargetSlot())) {
            taskType = Const.BIG_STORAGE_BEFORE_OUT;
        } else {
            taskType = Const.BIG_STORAGE_BEFORE_DISPATCH;
        }
        //按照任务状态修改大理片笼内的玻璃数据
//        重新计算大理片笼内的剩余尺寸
        Integer finalTaskType = taskType;
        taskMap.forEach((e1, v) -> {
            if (e1 == 2) {
                //进片完成
                log.info("3、获取进片已完成的玻璃信息id:{}", v);
                List<Integer> outSuccessGlassSlot = new ArrayList<>();
                if (finalTaskType.equals(Const.BIG_STORAGE_BEFORE_OUT)) {
                    outSuccessGlassSlot = v.stream().map(BigStorageCageTask::getStartSlot).collect(Collectors.toList());
                } else {
                    outSuccessGlassSlot = v.stream().map(BigStorageCageTask::getTargetSlot).collect(Collectors.toList());
                }
                List<UpdateBigStorageCageDTO> storageCageDTOList = v.stream().map(e -> {
                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
                    storageCageDTO.setGlassId(e.getGlassId());
                    if (finalTaskType.equals(Const.BIG_STORAGE_BEFORE_OUT)) {
                        storageCageDTO.setTargetSlot(e.getStartSlot());
                    } else {
                        storageCageDTO.setTargetSlot(e.getTargetSlot());
                    }
                    return storageCageDTO;
                }).collect(Collectors.toList());
                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_OUT);
                log.info("4、大理片笼进片状态已完成已完成的玻璃信息id:{}", v);
                updateSlotRemainBySlots(outSuccessGlassSlot);
            } else if (e1 == 3) {
                //破损处理
                dealDamageOutTask(v);
            } else {
                //清空理片笼空数据
                noDealOutTask(v);
            }
        });
        for (BigStorageCageTask item : outTaskList) {
            //更新历史任务表中的任务状态
            bigStorageCageHistoryTaskService.update(new LambdaUpdateWrapper<BigStorageCageHistoryTask>()
                    .set(BigStorageCageHistoryTask::getTaskState, item.getTaskState())
                    .eq(BigStorageCageHistoryTask::getTaskType, taskType)
                    .eq(BigStorageCageHistoryTask::getGlassId, item.getGlassId()));
            //更新钢化小片表
            Integer taskState = item.getTaskState();
            if (taskState == 2) {
                temperingGlassInfoService.update(new LambdaUpdateWrapper<TemperingGlassInfo>()
                        .set(TemperingGlassInfo::getState, Const.TEMPERING_OUT).eq(TemperingGlassInfo::getGlassId, item.getGlassId()));
            } else if (taskState == 3) {
//                temperingGlassInfoService.remove(new LambdaQueryWrapper<TemperingGlassInfo>().eq(TemperingGlassInfo::getGlassId, item.getGlassId()));
                temperingGlassInfoService.update(new LambdaUpdateWrapper<TemperingGlassInfo>()
                        .set(TemperingGlassInfo::getState, Const.TEMPERING_DAMAGE
                        ).eq(TemperingGlassInfo::getGlassId, item.getGlassId()));
            } else {
//                空执行
            }
        }
//       重置任务表数据
        bigStorageCageTaskService.updateOutTaskMessage("big_storage_cage_out_one_task");
        //清空启动状态
        //向opc发送启动信号
        miloService.writeToOpcWord(generateReadWriteEntity("DLP1B.DLP1B.MesReply", 0));
    }
    private void dealDamageInTask(List<BigStorageCageTask> damageTaskList) {
//        获取进片任务表中状态为破损的数据
        log.info("破损的玻璃信息有:{}", damageTaskList);
        //移除理片笼详情表任务执行过程中破损的玻璃
        bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>()
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_NEW)
                .in(BigStorageCageDetails::getGlassId, damageTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList())));
        //将破损信息新增入破损表
        List<Integer> slotList = new ArrayList<>();
        for (BigStorageCageTask item : damageTaskList) {
            Damage damage = new Damage();
            damage.setGlassId(item.getGlassId());
            damage.setLine(item.getStartSlot());
            damage.setWorkingProcedure("磨边");
            damage.setRemark("进笼前卧转立");
            damage.setStatus(1);
            damage.setType(item.getTaskState());
            damageService.insertDamage(damage);
            slotList.add(item.getTargetSlot());
        }
        //更新格子剩余宽度
        updateSlotRemainBySlots(slotList);
        log.info("进片任务-破损任务执行完成");
    }
    private void dealDamageOutTask(List<BigStorageCageTask> damageTaskList) {
//        获取进片任务表中状态为破损的数据
        log.info("破损的玻璃信息有:{}", damageTaskList);
        //移除理片笼详情表任务执行过程中破损的玻璃
        bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>()
                .in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL_ZERO)
                .in(BigStorageCageDetails::getGlassId, damageTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList())));
        //将破损信息新增入破损表
        List<Integer> slotList = new ArrayList<>();
        for (BigStorageCageTask item : damageTaskList) {
            Damage damage = new Damage();
            damage.setGlassId(item.getGlassId());
            damage.setLine(item.getStartSlot());
            damage.setWorkingProcedure("钢化前");
            damage.setRemark("进笼后卧转立");
            damage.setStatus(1);
            damage.setType(item.getTaskState());
            damageService.insertDamage(damage);
            slotList.add(item.getTargetSlot());
            slotList.add(item.getStartSlot());
        }
        //更新格子剩余宽度
        updateSlotRemainBySlots(slotList);
        log.info("出片任务-破损任务执行完成");
    }
    private void noDealInTask(List<BigStorageCageTask> noDealTaskList) {
//        获取进片任务表中状态为破损的数据
        log.info("破损的玻璃信息有:{}", noDealTaskList);
        //移除理片笼详情表未执行任务的空记录信息
        bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>()
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_NEW)
                .in(BigStorageCageDetails::getGlassId, noDealTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList())));
        //记录格子号,按格子号更新剩余尺寸
        List<Integer> slotList = new ArrayList<>();
        for (BigStorageCageTask item : noDealTaskList) {
            slotList.add(item.getTargetSlot());
            slotList.add(item.getStartSlot());
        }
        //更新格子剩余宽度
        updateSlotRemainBySlots(slotList);
        log.info("进片任务-无动作执行完成");
    }
    private void noDealOutTask(List<BigStorageCageTask> noDealTaskList) {
//        获取进片任务表中状态为破损的数据
        log.info("破损的玻璃信息有:{}", noDealTaskList);
        if (Const.OUT_TARGET_POSITION_ALL.contains(noDealTaskList.get(0).getTargetSlot())) {
            //出片任务:将出片中状态恢复为在笼内
            List<String> glassList = noDealTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
            bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
                    .set(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                    .in(BigStorageCageDetails::getGlassId, glassList));
        } else {
            //调度任务:将调度中状态改为在笼内,格子号恢复为调度前的格子
            for (BigStorageCageTask item : noDealTaskList) {
                bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
                        .set(BigStorageCageDetails::getSlot, item.getStartSlot())
                        .set(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                        .eq(BigStorageCageDetails::getGlassId, item.getGlassId()));
            }
        }
        //将破损信息新增入破损表
        List<Integer> slotList = new ArrayList<>();
        for (BigStorageCageTask item : noDealTaskList) {
            slotList.add(item.getTargetSlot());
            slotList.add(item.getStartSlot());
        }
        //更新格子剩余宽度
        updateSlotRemainBySlots(slotList);
        log.info("出片任务-无动作执行完成");
    }
    /**
     * 出片一次仅生成一车玻璃
     *
     * @param list
     * @param <T>
     * @return
     */
    private <T extends BigStorageCageBaseInfo> Boolean computeOutGlassInfo(List<T> list, String tableName, int targetSlot, int state, int taskType) {
        //任务数据:获取车子存放玻璃最大数量,玻璃间隔
        List<BigStorageCageTask> bigStorageCageTaskList = new ArrayList<>();
        //打车剩余尺寸
        Integer remainWidth = carWidth;
        for (T e : list) {
            if (bigStorageCageTaskList.size() >= outCarMaxSize || Math.max((int) e.getWidth(), (int) e.getHeight()) > remainWidth) {
                break;
            }
            //计算当前出片车剩尺寸
            remainWidth = remainWidth - Math.max((int) e.getWidth(), (int) e.getHeight()) - glassGap;
            bigStorageCageTaskList.add(new BigStorageCageTask(e.getGlassId(), e.getSlot(), targetSlot,
                    0));
        }
        Assert.isFalse(CollectionUtil.isEmpty(bigStorageCageTaskList), "未获取出片数据,结束出片任务");
        log.info("获取出片任务数据{}条,执行保存", bigStorageCageTaskList.size());
        List<String> glassIds = bigStorageCageTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
        int glassCount = bigStorageCageTaskList.size();
        //生成出片任务条数不足6补全
        while (bigStorageCageTaskList.size() < 6) {
            bigStorageCageTaskList.add(new BigStorageCageTask("", 0, 0, 0));
        }
        //清空任务表数据
        bigStorageCageTaskService.removeAll("big_storage_cage_out_one_task");
        bigStorageCageTaskService.saveTaskMessage(tableName, bigStorageCageTaskList);
        List<BigStorageCageHistoryTask> historyList = bigStorageCageTaskList.stream().filter(e -> StringUtils.isNotBlank(e.getGlassId())).map(e -> {
            BigStorageCageHistoryTask history = new BigStorageCageHistoryTask();
            BeanUtils.copyProperties(e, history);
            history.setGlassCount(glassCount);
            history.setTaskType(taskType);
            return history;
        }).collect(Collectors.toList());
        bigStorageCageHistoryTaskService.saveBatch(historyList);
        log.info("将出片玻璃{}玻璃状态改为出片中", glassIds);
        bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
                .set(BigStorageCageDetails::getState, state)
                .set(Const.GLASS_STATE_SCHEDULE_ING.equals(state), BigStorageCageBaseInfo::getSlot, targetSlot)
                .in(BigStorageCageDetails::getGlassId, glassIds));
        try {
            miloService.writeToOpcWord(generateReadWriteEntity("DLP1B.DLP1B.MesReply", 1));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Boolean.TRUE;
    }
    public void updateSlotRemainBySlots(List<Integer> slotList) {
        //获取格子内所有的玻璃信息
        List<BigStorageCageDetails> inSlotGlassList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                .in(BigStorageCageDetails::getSlot, slotList).in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
        Map<Integer, Double> slotRemainMap = new HashMap<>();
        //是否存在有格子非空的玻璃
        if (CollectionUtil.isNotEmpty(inSlotGlassList)) {
            //存在  将格子内的玻璃分别进行更新
            slotRemainMap = inSlotGlassList.stream()
                    .collect(Collectors.groupingBy(BigStorageCageDetails::getSlot, Collectors.summingDouble(item -> Math.max(item.getWidth(), item.getHeight()) + glassGap)));
            slotRemainMap.forEach((e, v) -> {
                double remainWidth = slotWidth - v >= 0 ? slotWidth - v : 0;
                bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, remainWidth)
                        .eq(BigStorageCage::getSlot, e));
            });
        }
        //过滤不存在玻璃的格子 将宽度重置为原始宽度5000
        Set<Integer> remainSlotList = slotRemainMap.keySet();
        slotList.removeAll(remainSlotList);
        if (CollectionUtil.isNotEmpty(slotList)) {
            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, slotWidth)
                    .in(BigStorageCage::getSlot, slotList));
        }
    }
    private ReadWriteEntity generateReadWriteEntity(String identifier, Object value) {
        return ReadWriteEntity.builder()
                .identifier(identifier)
                //Kep中是Long类型,即:Int32,Java中的int类型
                .value(value)
                .build();
    }
}
////                    }
//                }
//            }
//        }
//        //是否有人工下片任务   有直接出
//        List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
//                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL)
//                .orderByAsc(BigStorageCageDetails::getSlot)
//                .orderByAsc(BigStorageCageDetails::getId));
//        if (CollectionUtil.isNotEmpty(artificialList)) {
//            computeOutGlassInfo(artificialList, "big_storage_cage_out_one_task", artificialOutTargetPosition, Const.GLASS_STATE_OUT_ING, Const.BIG_STORAGE_BEFORE_OUT);
//            Date endDate = new Date();
//            log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//            return;
//        }
//        //是否存在需要内部调度的格子:执行内部调度任务
//        List<TemperingLayoutDTO> temperingOccupySlotList = bigStorageCageDetailsService.queryTemperingOccupySlot();
//        if (CollectionUtil.isNotEmpty(temperingOccupySlotList)) {
//            loop:
//            for (TemperingLayoutDTO temperingOccupySlot : temperingOccupySlotList) {
//                List<SlotSequenceDTO> slotSequenceList = bigStorageCageDetailsService.queryGlassMaxAndMin(temperingOccupySlot.getEngineerId(), temperingOccupySlot.getTemperingLayoutId());
//                for (int i = 0; i < slotSequenceList.size() - 1; i++) {
//                    SlotSequenceDTO first = slotSequenceList.get(i);
//                    SlotSequenceDTO second = slotSequenceList.get(i + 1);
//                    int slotWidth = carWidth - first.getRemainWidth() - glassGap;
//                    int totalCount = first.getGlassCount() + second.getGlassCount();
//                    if (totalCount <= 6 && first.getMinSequence() == second.getMaxSequence() + 1
//                            && second.getRemainWidth() > slotWidth && slotWidth >= 0) {
//                        List<BigStorageCageDetails> list = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
//                                .eq(BigStorageCageDetails::getSlot, first.getSlot()).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
//                                .orderBy(Boolean.TRUE, sequenceOrder, BigStorageCageDetails::getTemperingFeedSequence));
//                        if (CollectionUtil.isNotEmpty(list)) {
//                            computeOutGlassInfo(list, "big_storage_cage_out_one_task", second.getSlot(), Const.GLASS_STATE_SCHEDULE_ING, Const.BIG_STORAGE_BEFORE_DISPATCH);
//                        }
//                        //使用Arrays.asList() 使用removeAll报错,改为正常使用List
//                        List<Integer> slotList = new ArrayList<>();
//                        slotList.add(second.getSlot());
//                        updateSlotRemainBySlots(slotList);
//                        break loop;
//                    }
//                }
//            }
//        }
//        Date endDate = new Date();
//        log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//        return;
//    }
//
//    // @Scheduled(fixedDelay = 1000)
//    public void finishInBigStorageTask() throws Exception {
//        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("DLP1A.DLP1A.mesControl");
//        if (true != Boolean.parseBoolean(inkageEntity.getValue() + "")) {
//            log.info("当前为非联机状态,结束完成进片任务");
//            return;
//        }
//        //获取进片任务表
//        List<BigStorageCageTask> inTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_in_one_task");
//        if (CollectionUtil.isEmpty(inTaskList)) {
//            log.info("当前大车无进片玻璃,结束完成进片任务");
//            return;
//        }
//        List<BigStorageCageTask> unFinishTaskList = inTaskList.stream().filter(e -> e.getTaskState() <= 1 || e.getStartSlot() == 0).collect(Collectors.toList());
//        if (CollectionUtil.isNotEmpty(unFinishTaskList)) {
//            log.info("存在未完成的玻璃信息,玻璃:{}", unFinishTaskList);
//            return;
//        }
//        Map<Integer, List<BigStorageCageTask>> taskMap = inTaskList.stream().collect(Collectors.groupingBy(BigStorageCageTask::getTaskState));
//        //按照任务状态修改大理片笼内的玻璃数据
////        重新计算大理片笼内的剩余尺寸
//        taskMap.forEach((e1, v) -> {
//            if (e1 == 2) {
//                //进片完成
//                log.info("3、获取进片已完成的玻璃信息id:{}", v);
//                List<Integer> inSuccessGlassSlot = v.stream().map(BigStorageCageTask::getTargetSlot).collect(Collectors.toList());
//                List<UpdateBigStorageCageDTO> storageCageDTOList = v.stream().map(e -> {
//                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
//                    BeanUtils.copyProperties(e, storageCageDTO);
//                    return storageCageDTO;
//                }).collect(Collectors.toList());
//                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_IN);
//                log.info("4、大理片笼进片状态已完成已完成的玻璃信息id:{}", v);
//                updateSlotRemainBySlots(inSuccessGlassSlot);
//            } else if (e1 == 3) {
//                //破损处理
//                dealDamageInTask(v);
//            } else {
//                //清空理片笼空数据
//                noDealInTask(v);
//            }
//        });
//        for (BigStorageCageTask item : inTaskList) {
//            //更新历史任务表中的任务状态
//            bigStorageCageHistoryTaskService.update(new LambdaUpdateWrapper<BigStorageCageHistoryTask>()
//                    .set(BigStorageCageHistoryTask::getTaskState, item.getTaskState())
//                    .eq(BigStorageCageHistoryTask::getTaskType, Const.BIG_STORAGE_BEFORE_IN)
//                    .eq(BigStorageCageHistoryTask::getTargetSlot, item.getTargetSlot())
//                    .eq(BigStorageCageHistoryTask::getGlassId, item.getGlassId()));
//            item.setTargetSlot(0);
//            //清空任务表数据
//            bigStorageCageTaskService.updateTaskMessage("big_storage_cage_in_one_task", item);
//        }
//        //清空启动状态
//        //向opc发送启动信号
//        miloService.writeToOpcWord(generateReadWriteEntity("DLP1A.DLP1A.MesReply", 0));
//    }
//
//    // @Scheduled(fixedDelay = 1000)
//    public void finishOutBigStorageTask() throws Exception {
//        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("DLP1B.DLP1B.mesControl");
//        if (true != Boolean.parseBoolean(inkageEntity.getValue() + "")) {
//            log.info("当前为非联机状态,结束完成出片任务");
//            return;
//        }
//        //获取进片任务表
//        List<BigStorageCageTask> outTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_out_one_task");
//        if (CollectionUtil.isEmpty(outTaskList)) {
//            log.info("当前大车无进片玻璃,结束完成进片任务");
//            return;
//        }
//        List<BigStorageCageTask> unFinishTaskList = outTaskList.stream().filter(e -> e.getTaskState() <= 1 || e.getStartSlot() == 0).collect(Collectors.toList());
//        if (CollectionUtil.isNotEmpty(unFinishTaskList)) {
//            log.info("存在未完成的玻璃信息,玻璃:{}", unFinishTaskList);
//            return;
//        }
//        Map<Integer, List<BigStorageCageTask>> taskMap = outTaskList.stream().collect(Collectors.groupingBy(BigStorageCageTask::getTaskState));
//        int taskType = 0;
//        if (Const.OUT_TARGET_POSITION_ALL.contains(outTaskList.get(0).getTargetSlot())) {
//            taskType = Const.BIG_STORAGE_BEFORE_OUT;
//        } else {
//            taskType = Const.BIG_STORAGE_BEFORE_DISPATCH;
//        }
//        //按照任务状态修改大理片笼内的玻璃数据
////        重新计算大理片笼内的剩余尺寸
//        Integer finalTaskType = taskType;
//        taskMap.forEach((e1, v) -> {
//            if (e1 == 2) {
//                //进片完成
//                log.info("3、获取进片已完成的玻璃信息id:{}", v);
//                List<Integer> outSuccessGlassSlot = new ArrayList<>();
//                if (finalTaskType.equals(Const.BIG_STORAGE_BEFORE_OUT)) {
//                    outSuccessGlassSlot = v.stream().map(BigStorageCageTask::getStartSlot).collect(Collectors.toList());
//                } else {
//                    outSuccessGlassSlot = v.stream().map(BigStorageCageTask::getTargetSlot).collect(Collectors.toList());
//                }
//                List<UpdateBigStorageCageDTO> storageCageDTOList = v.stream().map(e -> {
//                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
//                    storageCageDTO.setGlassId(e.getGlassId());
//                    if (finalTaskType.equals(Const.BIG_STORAGE_BEFORE_OUT)) {
//                        storageCageDTO.setTargetSlot(e.getStartSlot());
//                    } else {
//                        storageCageDTO.setTargetSlot(e.getTargetSlot());
//                    }
//                    return storageCageDTO;
//                }).collect(Collectors.toList());
//                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_OUT);
//                log.info("4、大理片笼进片状态已完成已完成的玻璃信息id:{}", v);
//                updateSlotRemainBySlots(outSuccessGlassSlot);
//            } else if (e1 == 3) {
//                //破损处理
//                dealDamageOutTask(v);
//            } else {
//                //清空理片笼空数据
//                noDealOutTask(v);
//            }
//        });
//        for (BigStorageCageTask item : outTaskList) {
//            //更新历史任务表中的任务状态
//            bigStorageCageHistoryTaskService.update(new LambdaUpdateWrapper<BigStorageCageHistoryTask>()
//                    .set(BigStorageCageHistoryTask::getTaskState, item.getTaskState())
//                    .eq(BigStorageCageHistoryTask::getTaskType, taskType)
//                    .eq(BigStorageCageHistoryTask::getGlassId, item.getGlassId()));
//            //更新钢化小片表
//            Integer taskState = item.getTaskState();
//            if (taskState == 2) {
//                temperingGlassInfoService.update(new LambdaUpdateWrapper<TemperingGlassInfo>()
//                        .set(TemperingGlassInfo::getState, Const.TEMPERING_OUT).eq(TemperingGlassInfo::getGlassId, item.getGlassId()));
//            } else if (taskState == 3) {
////                temperingGlassInfoService.remove(new LambdaQueryWrapper<TemperingGlassInfo>().eq(TemperingGlassInfo::getGlassId, item.getGlassId()));
//                temperingGlassInfoService.update(new LambdaUpdateWrapper<TemperingGlassInfo>()
//                        .set(TemperingGlassInfo::getState, Const.TEMPERING_DAMAGE
//                        ).eq(TemperingGlassInfo::getGlassId, item.getGlassId()));
//
//            } else {
////                空执行
//            }
//        }
////       重置任务表数据
//        bigStorageCageTaskService.updateOutTaskMessage("big_storage_cage_out_one_task");
//        //清空启动状态
//        //向opc发送启动信号
//        miloService.writeToOpcWord(generateReadWriteEntity("DLP1B.DLP1B.MesReply", 0));
//    }
//
//    private void dealDamageInTask(List<BigStorageCageTask> damageTaskList) {
////        获取进片任务表中状态为破损的数据
//        log.info("破损的玻璃信息有:{}", damageTaskList);
//        //移除理片笼详情表任务执行过程中破损的玻璃
//        bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>()
//                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_NEW)
//                .in(BigStorageCageDetails::getGlassId, damageTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList())));
//        //将破损信息新增入破损表
//        List<Integer> slotList = new ArrayList<>();
//        for (BigStorageCageTask item : damageTaskList) {
//            Damage damage = new Damage();
//            damage.setGlassId(item.getGlassId());
//            damage.setLine(item.getStartSlot());
//            damage.setWorkingProcedure("磨边");
//            damage.setRemark("进笼前卧转立");
//            damage.setStatus(1);
//            damage.setType(item.getTaskState());
//            damageService.insertDamage(damage);
//            slotList.add(item.getTargetSlot());
//        }
//        //更新格子剩余宽度
//        updateSlotRemainBySlots(slotList);
//        log.info("进片任务-破损任务执行完成");
//    }
//
//    private void dealDamageOutTask(List<BigStorageCageTask> damageTaskList) {
////        获取进片任务表中状态为破损的数据
//        log.info("破损的玻璃信息有:{}", damageTaskList);
//        //移除理片笼详情表任务执行过程中破损的玻璃
//        bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>()
//                .in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL_ZERO)
//                .in(BigStorageCageDetails::getGlassId, damageTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList())));
//        //将破损信息新增入破损表
//        List<Integer> slotList = new ArrayList<>();
//        for (BigStorageCageTask item : damageTaskList) {
//            Damage damage = new Damage();
//            damage.setGlassId(item.getGlassId());
//            damage.setLine(item.getStartSlot());
//            damage.setWorkingProcedure("钢化前");
//            damage.setRemark("进笼后卧转立");
//            damage.setStatus(1);
//            damage.setType(item.getTaskState());
//            damageService.insertDamage(damage);
//            slotList.add(item.getTargetSlot());
//            slotList.add(item.getStartSlot());
//        }
//        //更新格子剩余宽度
//        updateSlotRemainBySlots(slotList);
//        log.info("出片任务-破损任务执行完成");
//    }
//
//    private void noDealInTask(List<BigStorageCageTask> noDealTaskList) {
////        获取进片任务表中状态为破损的数据
//        log.info("破损的玻璃信息有:{}", noDealTaskList);
//        //移除理片笼详情表未执行任务的空记录信息
//        bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>()
//                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_NEW)
//                .in(BigStorageCageDetails::getGlassId, noDealTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList())));
//        //记录格子号,按格子号更新剩余尺寸
//        List<Integer> slotList = new ArrayList<>();
//        for (BigStorageCageTask item : noDealTaskList) {
//            slotList.add(item.getTargetSlot());
//            slotList.add(item.getStartSlot());
//        }
//        //更新格子剩余宽度
//        updateSlotRemainBySlots(slotList);
//        log.info("进片任务-无动作执行完成");
//    }
//
//    private void noDealOutTask(List<BigStorageCageTask> noDealTaskList) {
////        获取进片任务表中状态为破损的数据
//        log.info("破损的玻璃信息有:{}", noDealTaskList);
//        if (Const.OUT_TARGET_POSITION_ALL.contains(noDealTaskList.get(0).getTargetSlot())) {
//            //出片任务:将出片中状态恢复为在笼内
//            List<String> glassList = noDealTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
//            bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
//                    .set(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
//                    .in(BigStorageCageDetails::getGlassId, glassList));
//
//        } else {
//            //调度任务:将调度中状态改为在笼内,格子号恢复为调度前的格子
//            for (BigStorageCageTask item : noDealTaskList) {
//                bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
//                        .set(BigStorageCageDetails::getSlot, item.getStartSlot())
//                        .set(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
//                        .eq(BigStorageCageDetails::getGlassId, item.getGlassId()));
//            }
//        }
//        //将破损信息新增入破损表
//        List<Integer> slotList = new ArrayList<>();
//        for (BigStorageCageTask item : noDealTaskList) {
//            slotList.add(item.getTargetSlot());
//            slotList.add(item.getStartSlot());
//        }
//        //更新格子剩余宽度
//        updateSlotRemainBySlots(slotList);
//        log.info("出片任务-无动作执行完成");
//    }
//
//    /**
//     * 出片一次仅生成一车玻璃
//     *
//     * @param list
//     * @param <T>
//     * @return
//     */
//    private <T extends BigStorageCageBaseInfo> Boolean computeOutGlassInfo(List<T> list, String tableName, int targetSlot, int state, int taskType) {
//        //任务数据:获取车子存放玻璃最大数量,玻璃间隔
//        List<BigStorageCageTask> bigStorageCageTaskList = new ArrayList<>();
//        //打车剩余尺寸
//        Integer remainWidth = carWidth;
//        for (T e : list) {
//            if (bigStorageCageTaskList.size() >= outCarMaxSize || Math.max((int) e.getWidth(), (int) e.getHeight()) > remainWidth) {
//                break;
//            }
//            //计算当前出片车剩尺寸
//            remainWidth = remainWidth - Math.max((int) e.getWidth(), (int) e.getHeight()) - glassGap;
//            bigStorageCageTaskList.add(new BigStorageCageTask(e.getGlassId(), e.getSlot(), targetSlot,
//                    0));
//        }
//        Assert.isFalse(CollectionUtil.isEmpty(bigStorageCageTaskList), "未获取出片数据,结束出片任务");
//        log.info("获取出片任务数据{}条,执行保存", bigStorageCageTaskList.size());
//        List<String> glassIds = bigStorageCageTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
//        int glassCount = bigStorageCageTaskList.size();
//        //生成出片任务条数不足6补全
//        while (bigStorageCageTaskList.size() < 6) {
//            bigStorageCageTaskList.add(new BigStorageCageTask("", 0, 0, 0));
//        }
//        //清空任务表数据
//        bigStorageCageTaskService.removeAll("big_storage_cage_out_one_task");
//        bigStorageCageTaskService.saveTaskMessage(tableName, bigStorageCageTaskList);
//        List<BigStorageCageHistoryTask> historyList = bigStorageCageTaskList.stream().filter(e -> StringUtils.isNotBlank(e.getGlassId())).map(e -> {
//            BigStorageCageHistoryTask history = new BigStorageCageHistoryTask();
//            BeanUtils.copyProperties(e, history);
//            history.setGlassCount(glassCount);
//            history.setTaskType(taskType);
//            return history;
//        }).collect(Collectors.toList());
//        bigStorageCageHistoryTaskService.saveBatch(historyList);
//
//        log.info("将出片玻璃{}玻璃状态改为出片中", glassIds);
//        bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
//                .set(BigStorageCageDetails::getState, state)
//                .set(Const.GLASS_STATE_SCHEDULE_ING.equals(state), BigStorageCageBaseInfo::getSlot, targetSlot)
//                .in(BigStorageCageDetails::getGlassId, glassIds));
//        try {
//            miloService.writeToOpcWord(generateReadWriteEntity("DLP1B.DLP1B.MesReply", 1));
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return Boolean.TRUE;
//    }
//
//
//    public void updateSlotRemainBySlots(List<Integer> slotList) {
//        //获取格子内所有的玻璃信息
//        List<BigStorageCageDetails> inSlotGlassList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
//                .in(BigStorageCageDetails::getSlot, slotList).in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
//        Map<Integer, Double> slotRemainMap = new HashMap<>();
//        //是否存在有格子非空的玻璃
//        if (CollectionUtil.isNotEmpty(inSlotGlassList)) {
//            //存在  将格子内的玻璃分别进行更新
//            slotRemainMap = inSlotGlassList.stream()
//                    .collect(Collectors.groupingBy(BigStorageCageDetails::getSlot, Collectors.summingDouble(item -> Math.max(item.getWidth(), item.getHeight()) + glassGap)));
//            slotRemainMap.forEach((e, v) -> {
//                double remainWidth = slotWidth - v >= 0 ? slotWidth - v : 0;
//                bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, remainWidth)
//                        .eq(BigStorageCage::getSlot, e));
//            });
//        }
//        //过滤不存在玻璃的格子 将宽度重置为原始宽度5000
//        Set<Integer> remainSlotList = slotRemainMap.keySet();
//        slotList.removeAll(remainSlotList);
//        if (CollectionUtil.isNotEmpty(slotList)) {
//            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, slotWidth)
//                    .in(BigStorageCage::getSlot, slotList));
//        }
//    }
//
//    private ReadWriteEntity generateReadWriteEntity(String identifier, Object value) {
//        return ReadWriteEntity.builder()
//                .identifier(identifier)
//                //Kep中是Long类型,即:Int32,Java中的int类型
//                .value(value)
//                .build();
//    }
//}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/PlcStorageCageTask.java
@@ -1,1118 +1,1050 @@
package com.mes.job;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.mes.base.entity.BigStorageCageBaseInfo;
import com.mes.bigstorage.entity.BigStorageCage;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.dto.BigStorageDTO;
import com.mes.bigstorage.entity.dto.SlotSequenceDTO;
import com.mes.bigstorage.entity.dto.TemperingLayoutDTO;
import com.mes.bigstorage.service.BigStorageCageDetailsService;
import com.mes.bigstorage.service.BigStorageCageService;
import com.mes.bigstoragetask.entity.BigStorageCageFeedTask;
import com.mes.bigstoragetask.entity.BigStorageCageOutTask;
import com.mes.bigstoragetask.entity.UpdateBigStorageCageDTO;
import com.mes.bigstoragetask.service.BigStorageCageFeedTaskService;
import com.mes.bigstoragetask.service.BigStorageCageOutTaskService;
import com.mes.common.S7object;
import com.mes.common.config.Const;
import com.mes.damage.entity.Damage;
import com.mes.damage.service.DamageService;
import com.mes.device.PlcParameterObject;
import com.mes.edgglasstask.entity.EdgGlassTaskInfo;
import com.mes.edgglasstask.service.EdgGlassTaskInfoService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.service.TemperingGlassInfoService;
import com.mes.tools.S7control;
import com.mes.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author SNG-015
 */
@Component
@Slf4j
public class PlcStorageCageTask {
    @Resource
    private BigStorageCageService bigStorageCageService;
    @Resource
    private BigStorageCageDetailsService bigStorageCageDetailsService;
    @Resource
    private GlassInfoService glassInfoService;
    @Resource
    private BigStorageCageFeedTaskService bigStorageCageFeedTaskService;
    @Resource
    private BigStorageCageOutTaskService bigStorageCageOutTaskService;
    @Resource
    private EdgGlassTaskInfoService edgGlassTaskInfoService;
    @Resource
    private TemperingGlassInfoService temperingGlassInfoService;
    @Resource
    private DamageService damageService;
    @Resource
    private RedisUtil redisUtil;
    private static final String REQUEST_WORD = "1";
    @Value("${mes.sequence.order}")
    private boolean sequenceOrder;
    @Value("${mes.carWidth}")
    private Integer carWidth;
    @Value("${mes.slotWidth}")
    private Integer slotWidth;
    @Value("${mes.inCarMaxSize}")
    private Integer inCarMaxSize;
    @Value("${mes.outCarMaxSize}")
    private Integer outCarMaxSize;
    @Value("${mes.glassGap}")
    private Integer glassGap;
    @Value("${mes.xMaxSize}")
    private Integer xMaxSize;
    private String d01GlassId = "";
    private String d04GlassId = "";
    //    @Scheduled(fixedDelay = 300)
    public void plcToHomeEdgScan() {
        Date startDate = new Date();
        log.info("大理片笼扫码任务开始执行时间:{}", startDate);
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        String d01Id = plcParameterObject.getPlcParameter("D01ID").getValue();
        String d04Id = plcParameterObject.getPlcParameter("D04ID").getValue();
        //D02id判断是否为空  确认是否空闲 允许进片
        String d02State = plcParameterObject.getPlcParameter("D02ID").getValue();
        String d03State = plcParameterObject.getPlcParameter("D03State").getValue();
        String d05State = plcParameterObject.getPlcParameter("D05State").getValue();
        String mesD01Value = plcParameterObject.getPlcParameter("MESToD01").getValue();
        String mesD04Value = plcParameterObject.getPlcParameter("MESToD04").getValue();
        String mesD01Address = plcParameterObject.getPlcParameter("MESToD01").getAddress();
        String mesD04Address = plcParameterObject.getPlcParameter("MESToD04").getAddress();
        String d01ToMES = plcParameterObject.getPlcParameter("D01ToMES").getValue();
        String d04ToMES = plcParameterObject.getPlcParameter("D04ToMES").getValue();
        log.info("1、获取d01Id扫描ID为:{},请求字为{};获取d04Id扫描ID为:{},请求字为{};", d01Id, d01ToMES, d04Id, d04ToMES);
        if (StringUtils.isBlank(d01ToMES) && StringUtils.isBlank(d04ToMES)) {
            log.info("两条线未收到进片任务,结束本次扫描进卧转立任务");
            return;
        }
        if (REQUEST_WORD.equals(d03State) && REQUEST_WORD.equals(d05State)) {
            log.info("两条线卧转立均在执行任务,结束本次扫描进卧转立任务");
            return;
        }
        //按照线路及玻璃id获取相邻两块玻璃 卧转立上的玻璃:  状态为0不操作(D01送片,0不操作,1允许送片),请求字为1, (02玻璃id为空或者卧转立未启动)
        if (!REQUEST_WORD.equals(mesD01Value) && REQUEST_WORD.equals(d01ToMES) && (StringUtils.isBlank(d02State) || !REQUEST_WORD.equals(d03State))) {
            List<BigStorageCageFeedTask> bigStorageCageFeedTasks = bigStorageCageFeedTaskService.list(
                    new LambdaQueryWrapper<BigStorageCageFeedTask>()
                            .gt(BigStorageCageFeedTask::getTargetSlot, 0)
                            .eq(BigStorageCageFeedTask::getLine, Const.A09_OUT_TARGET_POSITION)
                            .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
            );
            if (CollectionUtils.isEmpty(bigStorageCageFeedTasks)) {
                if (!d01GlassId.equals(d01Id)) {
                    judgeGlassTypeStatus(d01Id, Const.A09_OUT_TARGET_POSITION, mesD01Address);
                    edgGlassTaskInfoService.update(new LambdaUpdateWrapper<EdgGlassTaskInfo>()
                            .set(EdgGlassTaskInfo::getState, Const.EDG_GLASS_SUCCESS).eq(EdgGlassTaskInfo::getGlassId, d01Id));
//                d01GlassId = d01Id;
                }
            }
        }
//        状态为0不操作(D01送片,0不操作,1允许送片),请求字为1, 卧转立未启动
        if (!REQUEST_WORD.equals(mesD04Value) && REQUEST_WORD.equals(d04ToMES) && !REQUEST_WORD.equals(d05State)) {
            List<BigStorageCageFeedTask> bigStorageCageFeedTasks = bigStorageCageFeedTaskService.list(
                    new LambdaQueryWrapper<BigStorageCageFeedTask>()
                            .gt(BigStorageCageFeedTask::getTargetSlot, 0)
                            .eq(BigStorageCageFeedTask::getLine, Const.A10_OUT_TARGET_POSITION)
                            .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
            );
            if (CollectionUtils.isEmpty(bigStorageCageFeedTasks)) {
                if (!d04GlassId.equals(d04Id)) {
                    judgeGlassTypeStatus(d04Id, Const.A10_OUT_TARGET_POSITION, mesD04Address);
                    edgGlassTaskInfoService.update(new LambdaUpdateWrapper<EdgGlassTaskInfo>()
                            .set(EdgGlassTaskInfo::getState, Const.EDG_GLASS_SUCCESS).eq(EdgGlassTaskInfo::getGlassId, d04Id));
//                d04GlassId = d04Id;
                }
            }
        }
        Date endDate = new Date();
        log.info("大理片笼扫码任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
    }
    //    @Scheduled(fixedDelay = 300)
    public void plcToHomeEdgFreeCarTask() {
        Date startDate = new Date();
        log.info("大理片笼空车进片任务开始执行时间:{}", startDate);
        PlcParameterObject plcMesObject = S7object.getinstance().PlcMesObject;
        String mesD03Address = plcMesObject.getPlcParameter("MESToD03").getValue();
        String mesD05Address = plcMesObject.getPlcParameter("MESToD05").getValue();
        log.info("MESToD03:{},MESToD05:{}", mesD03Address, mesD05Address);
        if ("2".equals(mesD03Address) || "2".equals(mesD05Address)) {
            log.info("有启动信号,MESToD03:{},MESToD05:{}", mesD03Address, mesD05Address);
        }
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        String e01Status = plcParameterObject.getPlcParameter("E01State").getValue();
        String d03ToMES = plcParameterObject.getPlcParameter("D03ToMES").getValue();
        String d05ToMES = plcParameterObject.getPlcParameter("D05ToMES").getValue();
        log.info("执行空车送片任务,获取到的大车状态为{},卧转立状态分别为d03:{},d05:{}", e01Status, d03ToMES, d05ToMES);
        List<BigStorageCageFeedTask> bigStorageCageFeedTasks = bigStorageCageFeedTaskService.list(
                new LambdaQueryWrapper<BigStorageCageFeedTask>()
                        .ne(BigStorageCageFeedTask::getTargetSlot, 0)
                        .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
        );
        if (bigStorageCageFeedTasks.size() > 0) {
            Date endDate = new Date();
            log.info("大车有正在执行的任务{},结束送片任务,任务结束时间:{},共耗时:{}ms,结束扫码任务", bigStorageCageFeedTasks, endDate, endDate.getTime() - startDate.getTime());
            return;
        }
        if (REQUEST_WORD.equals(e01Status)) {
            Date endDate = new Date();
            log.info("进片大车非空闲,结束送片任务,任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
            return;
        }
        if (!REQUEST_WORD.equals(d03ToMES) && !REQUEST_WORD.equals(d05ToMES)) {
            Date endDate = new Date();
            log.info("卧转立第一次没有送片请求,结束送片任务,任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
            return;
        }
        if (!REQUEST_WORD.equals(d03ToMES) && !REQUEST_WORD.equals(d05ToMES)) {
            Date endDate = new Date();
            log.info("卧转立第二次没有送片请求,结束送片任务,任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
            return;
        }
//        List<Integer> lines=new ArrayList<>();
//        if(REQUEST_WORD.equals(d03ToMES)){
//            lines.add(Const.A09_OUT_TARGET_POSITION);
//package com.mes.job;
//
//import cn.hutool.core.lang.Assert;
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
//import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
//import com.github.yulichang.toolkit.JoinWrappers;
//import com.github.yulichang.wrapper.MPJLambdaWrapper;
//import com.mes.base.entity.BigStorageCageBaseInfo;
//import com.mes.bigstorage.entity.BigStorageCage;
//import com.mes.bigstorage.entity.BigStorageCageDetails;
//import com.mes.bigstorage.entity.dto.BigStorageDTO;
//import com.mes.bigstorage.entity.dto.SlotSequenceDTO;
//import com.mes.bigstorage.entity.dto.TemperingLayoutDTO;
//import com.mes.bigstorage.service.BigStorageCageDetailsService;
//import com.mes.bigstorage.service.BigStorageCageService;
//import com.mes.bigstoragetask.entity.BigStorageCageFeedTask;
//import com.mes.bigstoragetask.entity.BigStorageCageOutTask;
//import com.mes.bigstoragetask.entity.UpdateBigStorageCageDTO;
//import com.mes.bigstoragetask.service.BigStorageCageFeedTaskService;
//import com.mes.bigstoragetask.service.BigStorageCageOutTaskService;
//import com.mes.common.S7object;
//import com.mes.common.config.Const;
//import com.mes.damage.entity.Damage;
//import com.mes.damage.service.DamageService;
//import com.mes.device.PlcParameterObject;
//import com.mes.edgglasstask.entity.EdgGlassTaskInfo;
//import com.mes.edgglasstask.service.EdgGlassTaskInfoService;
//import com.mes.glassinfo.entity.GlassInfo;
//import com.mes.glassinfo.service.GlassInfoService;
//import com.mes.temperingglass.entity.TemperingGlassInfo;
//import com.mes.temperingglass.service.TemperingGlassInfoService;
//import com.mes.tools.S7control;
//import com.mes.utils.RedisUtil;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang.StringUtils;
//import org.springframework.beans.BeanUtils;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.stereotype.Component;
//
//import javax.annotation.Resource;
//import java.util.*;
//import java.util.stream.Collectors;
//
///**
// * @author SNG-015
// */
//@Component
//@Slf4j
//public class PlcStorageCageTask {
//
//    @Resource
//    private BigStorageCageService bigStorageCageService;
//    @Resource
//    private BigStorageCageDetailsService bigStorageCageDetailsService;
//    @Resource
//    private GlassInfoService glassInfoService;
//    @Resource
//    private BigStorageCageFeedTaskService bigStorageCageFeedTaskService;
//    @Resource
//    private BigStorageCageOutTaskService bigStorageCageOutTaskService;
//    @Resource
//    private EdgGlassTaskInfoService edgGlassTaskInfoService;
//    @Resource
//    private TemperingGlassInfoService temperingGlassInfoService;
//    @Resource
//    private DamageService damageService;
//
//    @Resource
//    private RedisUtil redisUtil;
//
//    private static final String REQUEST_WORD = "1";
//
//    @Value("${mes.sequence.order}")
//    private boolean sequenceOrder;
//
//    @Value("${mes.carWidth}")
//    private Integer carWidth;
//
//    @Value("${mes.slotWidth}")
//    private Integer slotWidth;
//
//    @Value("${mes.inCarMaxSize}")
//    private Integer inCarMaxSize;
//
//    @Value("${mes.outCarMaxSize}")
//    private Integer outCarMaxSize;
//
//    @Value("${mes.glassGap}")
//    private Integer glassGap;
//
//    @Value("${mes.xMaxSize}")
//    private Integer xMaxSize;
//
//
//    private String d01GlassId = "";
//    private String d04GlassId = "";
//
//    //    @Scheduled(fixedDelay = 300)
//    public void plcToHomeEdgScan() {
//        Date startDate = new Date();
//        log.info("大理片笼扫码任务开始执行时间:{}", startDate);
//        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
//        String d01Id = plcParameterObject.getPlcParameter("D01ID").getValue();
//        String d04Id = plcParameterObject.getPlcParameter("D04ID").getValue();
//        //D02id判断是否为空  确认是否空闲 允许进片
//        String d02State = plcParameterObject.getPlcParameter("D02ID").getValue();
//        String d03State = plcParameterObject.getPlcParameter("D03State").getValue();
//        String d05State = plcParameterObject.getPlcParameter("D05State").getValue();
//        String mesD01Value = plcParameterObject.getPlcParameter("MESToD01").getValue();
//        String mesD04Value = plcParameterObject.getPlcParameter("MESToD04").getValue();
//        String mesD01Address = plcParameterObject.getPlcParameter("MESToD01").getAddress();
//        String mesD04Address = plcParameterObject.getPlcParameter("MESToD04").getAddress();
//        String d01ToMES = plcParameterObject.getPlcParameter("D01ToMES").getValue();
//        String d04ToMES = plcParameterObject.getPlcParameter("D04ToMES").getValue();
//
//        log.info("1、获取d01Id扫描ID为:{},请求字为{};获取d04Id扫描ID为:{},请求字为{};", d01Id, d01ToMES, d04Id, d04ToMES);
//        if (StringUtils.isBlank(d01ToMES) && StringUtils.isBlank(d04ToMES)) {
//            log.info("两条线未收到进片任务,结束本次扫描进卧转立任务");
//            return;
//        }
//        if(REQUEST_WORD.equals(d05ToMES)){
//            lines.add(Const.A10_OUT_TARGET_POSITION);
//        if (REQUEST_WORD.equals(d03State) && REQUEST_WORD.equals(d05State)) {
//            log.info("两条线卧转立均在执行任务,结束本次扫描进卧转立任务");
//            return;
//        }
        LambdaQueryWrapper<BigStorageCageFeedTask> wrapper = new LambdaQueryWrapper<BigStorageCageFeedTask>()
                .eq(BigStorageCageFeedTask::getTaskType, Const.BIG_STORAGE_IN_RUN)
                .and(e -> e.isNull(BigStorageCageFeedTask::getTargetSlot).or().eq(BigStorageCageFeedTask::getTargetSlot, Const.OUT_TARGET_POSITION_ZERO))
                .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP);
//                .in(BigStorageCageFeedTask::getLine,lines);
        //获取可以启动卧转立的任务线路
        List<BigStorageCageFeedTask> feedTaskList = bigStorageCageFeedTaskService.list(wrapper);
        if (CollectionUtils.isNotEmpty(feedTaskList)) {
            if (feedTaskList.size() == 1) {
                computeTargetByLine(feedTaskList.get(0).getLine());
            } else {
                //比较最早一片任务的版图id及版序 求出卧转立的线路
                Integer startLine = getStartLine();
//            //计算目标格子,发送启动任务
                computeTargetByLine(startLine);
            }
            Date endDate = new Date();
            log.info("大理片笼空车进片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
            return;
        }
        String d01Id = plcParameterObject.getPlcParameter("D01ID").getValue();
        String d04Id = plcParameterObject.getPlcParameter("D04ID").getValue();
        log.info("1、获取d01Id扫描ID为:{};获取d04Id扫描ID为:{};", d01Id, d04Id);
        //获取两条线卧转立是否有玻璃,且任务状态为1/2
        List<Integer> lineList = bigStorageCageFeedTaskService.querySitToUpGlass();
        if (CollectionUtils.isEmpty(lineList)) {
            Date endDate = new Date();
            log.info("两条线卧转立为空或者有进片任务未完成,结束任务,大理片笼空车进片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
            return;
        }
        Integer lineFirst = lineList.get(0);
        String lineGlassId = lineFirst.equals(Const.A09_OUT_TARGET_POSITION) ? d01Id : d04Id;
        //仅有一条先符合启动启动条件
        if (lineList.size() == 1) {
            //如果进片请求但玻璃为空,计算任务表进片格子 发送进片任务
            if (StringUtils.isEmpty(lineGlassId)) {
                computeTargetByLine(lineFirst);
            } else {
                //todo:计算扫描到的玻璃是否可以存进卧转立
                //获取卧转立剩余宽度
                if (computeIsRun(lineFirst, lineGlassId)) {
                    computeTargetByLine(lineFirst);
                } else {
                    log.info("当前线路:{},有扫码玻璃:{}", lineFirst, lineGlassId);
                }
            }
            Date endDate = new Date();
            log.info("大理片笼空车进片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
            return;
        }
        //两条先均可执行进片任务,判断两条线是否进片请求是否都为空
        if (StringUtils.isBlank(d01Id) && StringUtils.isBlank(d04Id)) {
            //比较最早一片任务的版图id及版序 求出卧转立的线路
            Integer line = getStartLine();
            //计算任务表进片格子 发送进片任务
            computeTargetByLine(line);
            Date endDate = new Date();
            log.info("大理片笼空车进片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
            return;
        } else if (StringUtils.isNotBlank(d01Id) && StringUtils.isNotBlank(d04Id)) {
//            todo:两个都有进片玻璃
            if (computeIsRun(Const.A09_OUT_TARGET_POSITION, d01Id) && computeIsRun(Const.A10_OUT_TARGET_POSITION, d04Id)) {
                //比较最早一片任务的版图id及版序 求出卧转立的线路
                Integer line = getStartLine();
                //计算任务表进片格子 发送进片任务
                computeTargetByLine(line);
            } else if (computeIsRun(Const.A09_OUT_TARGET_POSITION, d01Id)) {
                computeTargetByLine(Const.A09_OUT_TARGET_POSITION);
            } else if (computeIsRun(Const.A10_OUT_TARGET_POSITION, d04Id)) {
                computeTargetByLine(Const.A10_OUT_TARGET_POSITION);
            } else {
                Date endDate = new Date();
                log.info("大理片笼空车进片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
                return;
            }
        } else {
            //,或者仅有一条有玻璃
            //一条线为空,一条线有进片请求有玻璃
            int outLine = StringUtils.isBlank(d01Id) ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
            //获取进片请求玻璃为空的,计算任务表进片格子 发送进片任务
            computeTargetByLine(outLine);
        }
        Date endDate = new Date();
        log.info("大理片笼空车进片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
    }
    //    @Scheduled(fixedDelay = 10000)
    public void plcToHomeEdgOutTask() {
        Date startDate = new Date();
        log.info("大理片笼空车进片任务开始执行时间:{}", startDate);
        PlcParameterObject plcMesObject = S7object.getinstance().PlcMesObject;
        String e02State = plcMesObject.getPlcParameter("E02State").getValue();
        if (REQUEST_WORD.equals(e02State)) {
            log.info("出片忙碌,结束出片任务");
            return;
        }
        String mesToPLCAddress = plcMesObject.getPlcParameter("MESToPLC").getAddress();
        List<BigStorageCageOutTask> outingList = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
                .eq(BigStorageCageOutTask::getTaskState, Const.BIG_STORAGE_OUT_NEW));
        if (CollectionUtils.isNotEmpty(outingList)) {
            log.info("有正在执行出片的任务,结束当前出片线程");
            return;
        }
        if (redisUtil.getCacheObject("temperingSwitch")) {
            //是否有正在钢化的玻璃
            List<TemperingGlassInfo> temperingGlassInfoList = temperingGlassInfoService.selectJoinList(TemperingGlassInfo.class, new MPJLambdaWrapper<TemperingGlassInfo>()
                    .selectAll(TemperingGlassInfo.class)
                    .leftJoin(BigStorageCageOutTask.class, BigStorageCageOutTask::getGlassId, TemperingGlassInfo::getGlassId)
                    .eq(TemperingGlassInfo::getState, Const.TEMPERING_NEW)
                    .isNull(BigStorageCageOutTask::getGlassId)
                    .orderBy(Boolean.TRUE, sequenceOrder, TemperingGlassInfo::getTemperingFeedSequence));
            if (CollectionUtils.isNotEmpty(temperingGlassInfoList)) {
                log.info("有正在出片的钢化任务");
                computeOutMoreGlassInfo(temperingGlassInfoList, Boolean.TRUE, mesToPLCAddress);
                Date endDate = new Date();
                log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
                return;
            }
            //是否有人工下片任务   有直接出
//            List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
//                    .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL).orderByDesc(BigStorageCageDetails::getWidth));
            List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                    .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL)
                    .orderByAsc(BigStorageCageDetails::getSlot)
                    .orderByDesc(BigStorageCageDetails::getId));
            if (CollectionUtils.isNotEmpty(artificialList)) {
                computeOutMoreGlassInfo(artificialList, Boolean.FALSE, mesToPLCAddress);
                Date endDate = new Date();
                log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
                return;
            }
            //钢化优先:获取理片笼  玻璃小片  破损表 数量   判断笼内版图是否到齐
            List<TemperingLayoutDTO> temperingLayoutDTOList = bigStorageCageDetailsService.temperingIsAll();
            if (CollectionUtils.isNotEmpty(temperingLayoutDTOList)) {
                //玻璃到齐包括已出片的
                //到齐,将玻璃小片数据存入钢化小片表,逻辑生成出片任务  结束
                for (TemperingLayoutDTO item : temperingLayoutDTOList) {
                    if (redisUtil.getCacheObject("temperingengineerId").equals(item.getEngineerId())) {
                        List<TemperingGlassInfo> temperingGlassInfos = glassInfoService.selectJoinList(TemperingGlassInfo.class, JoinWrappers.lambda(GlassInfo.class)
                                .selectAll(GlassInfo.class)
                                .select("-1 as state")
                                .selectAs(BigStorageCageDetails::getSlot, TemperingGlassInfo::getSlot)
                                .innerJoin(BigStorageCageDetails.class, BigStorageCageDetails::getGlassId, GlassInfo::getGlassId)
                                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                                .eq(GlassInfo::getTemperingLayoutId, item.getTemperingLayoutId())
                                .eq(GlassInfo::getEngineerId, item.getEngineerId())
                                .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence));
                        if (CollectionUtils.isNotEmpty(temperingGlassInfos)) {
                            temperingGlassInfoService.saveBatch(temperingGlassInfos);
                            computeOutMoreGlassInfo(temperingGlassInfoList, Boolean.TRUE, mesToPLCAddress);
                            Date endDate = new Date();
                            log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
                            return;
                        }
                    }
                }
            }
        }
        //执行内部调度任务
        List<TemperingLayoutDTO> temperingOccupySlotList = bigStorageCageDetailsService.queryTemperingOccupySlot();
        if (CollectionUtils.isNotEmpty(temperingOccupySlotList)) {
            loop:
            for (TemperingLayoutDTO temperingOccupySlot : temperingOccupySlotList) {
                List<SlotSequenceDTO> slotSequenceList = bigStorageCageDetailsService.queryGlassMaxAndMin(temperingOccupySlot.getEngineerId(), temperingOccupySlot.getTemperingLayoutId());
                for (int i = 0; i < slotSequenceList.size() - 1; i++) {
                    SlotSequenceDTO first = slotSequenceList.get(i);
                    SlotSequenceDTO second = slotSequenceList.get(i + 1);
                    int slotWidth = carWidth - first.getRemainWidth() - glassGap;
                    if (first.getMinSequence() == second.getMaxSequence() + 1
                            && second.getRemainWidth() > slotWidth && slotWidth >= 0) {
                        List<BigStorageCageDetails> list = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                                .eq(BigStorageCageDetails::getSlot, first.getSlot()).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                                .orderBy(Boolean.TRUE, sequenceOrder, BigStorageCageDetails::getTemperingFeedSequence));
                        if (CollectionUtils.isNotEmpty(list)) {
                            List<BigStorageCageOutTask> outTasks = new ArrayList<>();
                            int serialNumber = 1;
                            for (BigStorageCageDetails item : list) {
                                outTasks.add(new BigStorageCageOutTask(item.getGlassId(), first.getSlot(), second.getSlot(),
                                        item.getWidth() * 10, item.getHeight() * 10, 1, serialNumber++, Const.BIG_STORAGE_OUT_NEW, new Date()));
                            }
                            //新增调度任务
                            bigStorageCageOutTaskService.saveBatch(outTasks);
                            //更新理片笼详情表调度的后的玻璃位置信息:生成任务后先将玻璃格子位置进行调整,玻璃状态改为调度中,新增调度完成任务,处理调度完成后玻璃状态改为100.
                            List<String> glassList = list.stream().map(BigStorageCageDetails::getGlassId).collect(Collectors.toList());
                            bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>().set(BigStorageCageDetails::getState, Const.GLASS_STATE_SCHEDULE_ING)
                                    .set(BigStorageCageBaseInfo::getSlot, second.getSlot()).in(BigStorageCageDetails::getGlassId, glassList));
                            //两次更新笼子的剩余尺寸:第一次防止有玻璃继续进调度后的笼子,第二次更新:计算格子的实际尺寸
                            // 仅更新调度后的格子信息:起始格子完成后更新:防止调度出片过程中有新玻璃进入,
                            updateSlotRemainBySlots(Arrays.asList(second.getSlot()));
                            break loop;
                        }
                    }
                }
            }
//            //向plc写入确认字
//            int returnData = 0;
//            int count = 1;
//            while (returnData == 0) {
//                log.info("已向plc第{}次送协议", count);
//                S7object.getinstance().plccontrol.writeWord(mesToPLCAddress, 1);
//                returnData = S7object.getinstance().plccontrol.readWord(mesToPLCAddress, 1).get(0);
//                log.info("已向plc第{}次发送出片任务确认,地址为:{},写入的内容为{}", count++, mesToPLCAddress, returnData);
//        //按照线路及玻璃id获取相邻两块玻璃 卧转立上的玻璃:  状态为0不操作(D01送片,0不操作,1允许送片),请求字为1, (02玻璃id为空或者卧转立未启动)
//        if (!REQUEST_WORD.equals(mesD01Value) && REQUEST_WORD.equals(d01ToMES) && (StringUtils.isBlank(d02State) || !REQUEST_WORD.equals(d03State))) {
//            List<BigStorageCageFeedTask> bigStorageCageFeedTasks = bigStorageCageFeedTaskService.list(
//                    new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                            .gt(BigStorageCageFeedTask::getTargetSlot, 0)
//                            .eq(BigStorageCageFeedTask::getLine, Const.A09_OUT_TARGET_POSITION)
//                            .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
//            );
//            if (CollectionUtils.isEmpty(bigStorageCageFeedTasks)) {
//                if (!d01GlassId.equals(d01Id)) {
//                    judgeGlassTypeStatus(d01Id, Const.A09_OUT_TARGET_POSITION, mesD01Address);
//                    edgGlassTaskInfoService.update(new LambdaUpdateWrapper<EdgGlassTaskInfo>()
//                            .set(EdgGlassTaskInfo::getState, Const.EDG_GLASS_SUCCESS).eq(EdgGlassTaskInfo::getGlassId, d01Id));
////                d01GlassId = d01Id;
//                }
//            }
            Date endDate = new Date();
            log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
            return;
        }
    }
    //    @Scheduled(fixedDelay = 300)
    public void updateInGlassStateTask() {
        Date startDate = new Date();
        log.info("1、大理片笼进片完成后更新大理片笼数据任务开始执行时间:{}", startDate);
        //因为大理片笼和出片任务是两个库的数据,所以要分开查找
        List<Object> list = bigStorageCageDetailsService.listObjs(new LambdaQueryWrapper<BigStorageCageDetails>()
                .select(BigStorageCageDetails::getGlassId).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_NEW));
        if (CollectionUtils.isNotEmpty(list)) {
            log.info("2、获取所有正在进片的玻璃信息id:{}", list);
            List<String> glassIds = list.stream().map(String::valueOf).collect(Collectors.toList());
            List<BigStorageCageFeedTask> inSuccessGlass = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
                    .in(BigStorageCageFeedTask::getGlassId, glassIds)
                    .in(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT));
            if (CollectionUtils.isNotEmpty(inSuccessGlass)) {
                log.info("3、获取进片已完成的玻璃信息id:{}", inSuccessGlass);
                List<Integer> inSuccessGlassSlot = inSuccessGlass.stream().map(BigStorageCageFeedTask::getTargetSlot).collect(Collectors.toList());
                List<UpdateBigStorageCageDTO> storageCageDTOList = inSuccessGlass.stream().map(e -> {
                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
                    BeanUtils.copyProperties(e, storageCageDTO);
                    return storageCageDTO;
                }).collect(Collectors.toList());
                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_IN);
                log.info("4、大理片笼进片状态已完成已完成的玻璃信息id:{}", inSuccessGlass);
                //更新理片笼玻璃尺寸
                updateSlotRemainBySlots(inSuccessGlassSlot);
                log.info("5、大理片笼进片目标格子尺寸更新完成");
            }
        }
        Date endDate = new Date();
        log.info("end:大理片笼进片完成后更新大理片笼数据任务结束时间:{},共耗时:{}ms,结束任务", endDate, endDate.getTime() - startDate.getTime());
        return;
    }
    //    @Scheduled(fixedDelay = 300)
    public void updateOutGlassStateTask() {
        Date startDate = new Date();
        log.info("1、大理片笼出片完成后更新大理片笼数据任务开始执行时间:{}", startDate);
        //因为大理片笼和出片任务是两个库的数据,所以要分开查找
        List<Object> list = bigStorageCageDetailsService.listObjs(new LambdaQueryWrapper<BigStorageCageDetails>()
                .select(BigStorageCageDetails::getGlassId).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT_ING));
        if (CollectionUtils.isNotEmpty(list)) {
            log.info("2、获取所有正在出片的玻璃信息id:{}", list);
            List<String> glassIds = list.stream().map(String::valueOf).collect(Collectors.toList());
            List<BigStorageCageOutTask> outSuccessGlass = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
                    .in(BigStorageCageOutTask::getGlassId, glassIds).in(BigStorageCageOutTask::getTaskState, Const.BIG_STORAGE_OUT_ALL));
            if (CollectionUtils.isNotEmpty(outSuccessGlass)) {
                for (BigStorageCageOutTask bigStorageCageOutTask : outSuccessGlass
                ) {
                    if (bigStorageCageOutTask.getEndSlot().equals(Const.ARTIFICIAL_OUT_TARGET_POSITION)) {
                        temperingGlassInfoService.update(
                                new LambdaUpdateWrapper<TemperingGlassInfo>()
                                        .set(TemperingGlassInfo::getState, Const.TEMPERING_END)
                                        .eq(TemperingGlassInfo::getGlassId, bigStorageCageOutTask.getGlassId())
                        );
                    }
                }
                log.info("3、获取出片已完成的玻璃信息id:{}", outSuccessGlass);
                List<UpdateBigStorageCageDTO> storageCageDTOList = outSuccessGlass.stream().map(e -> {
                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
                    storageCageDTO.setGlassId(e.getGlassId());
                    storageCageDTO.setTargetSlot(e.getStartSlot());
                    return storageCageDTO;
                }).collect(Collectors.toList());
                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_OUT);
                List<Integer> outSuccessSlotList = outSuccessGlass.stream().map(BigStorageCageOutTask::getStartSlot).collect(Collectors.toList());
                log.info("4、大理片笼出片状态已完成已完成的玻璃信息id:{}", outSuccessGlass);
                //更新理片笼玻璃尺寸
                updateSlotRemainBySlots(outSuccessSlotList);
                log.info("5、大理片笼进片目标格子尺寸更新完成");
            }
        }
        Date endDate = new Date();
        log.info("end:大理片笼出片完成后更新大理片笼数据任务结束时间:{},共耗时:{}ms,结束任务", endDate, endDate.getTime() - startDate.getTime());
        return;
    }
    //    @Scheduled(fixedDelay = 300)
    public void updateScheduleGlassStateTask() {
        Date startDate = new Date();
        log.info("1、大理片笼调度完成后更新大理片笼数据任务开始执行时间:{}", startDate);
        //因为大理片笼和调度任务是两个库的数据,所以要分开查找
        List<Object> list = bigStorageCageDetailsService.listObjs(new LambdaQueryWrapper<BigStorageCageDetails>()
                .select(BigStorageCageDetails::getGlassId).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_SCHEDULE_ING));
        if (CollectionUtils.isNotEmpty(list)) {
            log.info("2、获取所有正在出片的玻璃信息id:{}", list);
            List<String> glassIds = list.stream().map(String::valueOf).collect(Collectors.toList());
            List<BigStorageCageOutTask> scheduleSuccessGlass = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
                    .in(BigStorageCageOutTask::getGlassId, glassIds).eq(BigStorageCageOutTask::getTaskState, Const.BIG_STORAGE_OUT_SUCCESS)
                    .notIn(BigStorageCageOutTask::getEndSlot, Const.TEMPERING_OUT_TARGET_POSITION, Const.ARTIFICIAL_OUT_TARGET_POSITION));
            if (CollectionUtils.isNotEmpty(scheduleSuccessGlass)) {
                log.info("3、获取调度已完成的玻璃信息id:{}", scheduleSuccessGlass);
                List<UpdateBigStorageCageDTO> storageCageDTOList = scheduleSuccessGlass.stream().map(e -> {
                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
                    storageCageDTO.setGlassId(e.getGlassId());
                    storageCageDTO.setTargetSlot(e.getEndSlot());
                    return storageCageDTO;
                }).collect(Collectors.toList());
                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_IN);
                List<String> scheduleSuccessGlassIds = scheduleSuccessGlass.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
                log.info("4、大理片笼出片状态已完成已完成的玻璃信息id:{}", scheduleSuccessGlassIds);
                //更新理片笼玻璃尺寸
                List<Integer> slotList = scheduleSuccessGlass.stream().map(BigStorageCageOutTask::getStartSlot).distinct().collect(Collectors.toList());
                slotList.addAll(scheduleSuccessGlass.stream().map(BigStorageCageOutTask::getEndSlot).distinct().collect(Collectors.toList()));
                updateSlotRemainBySlots(slotList);
                log.info("5、大理片笼进片目标格子尺寸更新完成");
            }
        }
        Date endDate = new Date();
        log.info("end:大理片笼出片完成后更新大理片笼数据任务结束时间:{},共耗时:{}ms,结束任务", endDate, endDate.getTime() - startDate.getTime());
        return;
    }
    /**
     * 处理破损表任务
     */
//    @Scheduled(fixedDelay = 300)
    public void dealDamageTask() {
        Date startDate = new Date();
        log.info("大理片笼破损玻璃清除任务开始执行时间:{}", startDate);
        //获取进片任务表中状态为破损的数据
        List<BigStorageCageFeedTask> inDamageTaskInfoList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
                .in(BigStorageCageFeedTask::getTaskState, Const.GLASS_STATE_DAMAGE_TAKE));
        if (CollectionUtils.isNotEmpty(inDamageTaskInfoList)) {
            log.info("获取进片任务表中破损的玻璃信息{}", inDamageTaskInfoList);
            bigStorageCageFeedTaskService.remove(new LambdaQueryWrapper<BigStorageCageFeedTask>().in(BigStorageCageFeedTask::getTaskState, Const.GLASS_STATE_DAMAGE_TAKE));
            //理片笼详情表数据状态更新
            bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>()
                    .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_NEW).in(BigStorageCageDetails::getGlassId, inDamageTaskInfoList.stream().map(BigStorageCageFeedTask::getGlassId).collect(Collectors.toList())));
            //将破损信息新增入破损表
            List<Integer> slotList = new ArrayList<>();
            for (BigStorageCageFeedTask bigStorageCageFeedTask : inDamageTaskInfoList) {
                Damage damage = new Damage();
                damage.setGlassId(bigStorageCageFeedTask.getGlassId());
                damage.setLine(bigStorageCageFeedTask.getLine());
                damage.setWorkingProcedure("磨边");
                damage.setRemark("进笼前卧转立");
                damage.setStatus(1);
                damage.setType(bigStorageCageFeedTask.getTaskState());
                damageService.insertDamage(damage);
                slotList.add(bigStorageCageFeedTask.getTargetSlot());
            }
            //更新格子剩余宽度
            updateSlotRemainBySlots(slotList);
            log.info("进片任务执行完成");
        }
        //获取出片任务表中状态为破损的数据
        List<BigStorageCageOutTask> outDamageTaskInfoList = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
                .in(BigStorageCageOutTask::getTaskState, Const.GLASS_STATE_DAMAGE_TAKE));
        if (CollectionUtils.isNotEmpty(outDamageTaskInfoList)) {
            log.info("获取出片任务表中破损的玻璃信息{}", outDamageTaskInfoList);
            bigStorageCageOutTaskService.remove(new LambdaQueryWrapper<BigStorageCageOutTask>().in(BigStorageCageOutTask::getTaskState, Const.GLASS_STATE_DAMAGE_TAKE));
            List<String> glassIdList = outDamageTaskInfoList.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
            //移除钢化下片表数据
            temperingGlassInfoService.remove(new LambdaQueryWrapper<TemperingGlassInfo>().in(TemperingGlassInfo::getGlassId, glassIdList));
            //理片笼详情表数据状态删除
            bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>().in(BigStorageCageDetails::getGlassId, glassIdList));
            //将破损信息新增入破损表
            List<Integer> slotList = new ArrayList<>();
            for (BigStorageCageOutTask bigStorageCageOutTask : outDamageTaskInfoList) {
                Damage damage = new Damage();
                damage.setGlassId(bigStorageCageOutTask.getGlassId());
                damage.setLine(bigStorageCageOutTask.getEndSlot());
                damage.setWorkingProcedure("钢化");
                damage.setRemark("出片后卧转立");
                damage.setStatus(1);
                damage.setType(bigStorageCageOutTask.getTaskState());
                damageService.insertDamage(damage);
                slotList.add(bigStorageCageOutTask.getStartSlot());
            }
            //更新格子剩余宽度
            updateSlotRemainBySlots(slotList);
            log.info("出片任务执行完成");
        }
        Date endDate = new Date();
        log.info("大理片笼破损玻璃清除任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
        return;
    }
    /**
     * 确认字清空
     */
//    @Scheduled(fixedDelay = 300)
    public void confirmClear() {
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        String d01ToMES = plcParameterObject.getPlcParameter("D01ToMES").getValue();
        String d04ToMES = plcParameterObject.getPlcParameter("D04ToMES").getValue();
        String mesD01Address = plcParameterObject.getPlcParameter("MESToD01").getAddress();
        String mesD04Address = plcParameterObject.getPlcParameter("MESToD04").getAddress();
//        }
////        状态为0不操作(D01送片,0不操作,1允许送片),请求字为1, 卧转立未启动
//        if (!REQUEST_WORD.equals(mesD04Value) && REQUEST_WORD.equals(d04ToMES) && !REQUEST_WORD.equals(d05State)) {
//            List<BigStorageCageFeedTask> bigStorageCageFeedTasks = bigStorageCageFeedTaskService.list(
//                    new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                            .gt(BigStorageCageFeedTask::getTargetSlot, 0)
//                            .eq(BigStorageCageFeedTask::getLine, Const.A10_OUT_TARGET_POSITION)
//                            .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
//            );
//            if (CollectionUtils.isEmpty(bigStorageCageFeedTasks)) {
//                if (!d04GlassId.equals(d04Id)) {
//                    judgeGlassTypeStatus(d04Id, Const.A10_OUT_TARGET_POSITION, mesD04Address);
//                    edgGlassTaskInfoService.update(new LambdaUpdateWrapper<EdgGlassTaskInfo>()
//                            .set(EdgGlassTaskInfo::getState, Const.EDG_GLASS_SUCCESS).eq(EdgGlassTaskInfo::getGlassId, d04Id));
////                d04GlassId = d04Id;
//                }
//            }
//
//        }
//        Date endDate = new Date();
//        log.info("大理片笼扫码任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//    }
//
//    //    @Scheduled(fixedDelay = 300)
//    public void plcToHomeEdgFreeCarTask() {
//        Date startDate = new Date();
//        log.info("大理片笼空车进片任务开始执行时间:{}", startDate);
//        PlcParameterObject plcMesObject = S7object.getinstance().PlcMesObject;
//        String mesD03Address = plcMesObject.getPlcParameter("MESToD03").getValue();
//        String mesD05Address = plcMesObject.getPlcParameter("MESToD05").getValue();
//        log.info("MESToD03:{},MESToD05:{}", mesD03Address, mesD05Address);
//        if ("2".equals(mesD03Address) || "2".equals(mesD05Address)) {
//            log.info("有启动信号,MESToD03:{},MESToD05:{}", mesD03Address, mesD05Address);
//        }
//        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
//        String e01Status = plcParameterObject.getPlcParameter("E01State").getValue();
//        String d03ToMES = plcParameterObject.getPlcParameter("D03ToMES").getValue();
//        String d05ToMES = plcParameterObject.getPlcParameter("D05ToMES").getValue();
        String d03ToMES = plcParameterObject.getPlcParameter("D03Request").getValue();
        String d05ToMES = plcParameterObject.getPlcParameter("D05Request").getValue();
        String mesD03Address = plcParameterObject.getPlcParameter("MESToD03").getAddress();
        String mesD05Address = plcParameterObject.getPlcParameter("MESToD05").getAddress();
        if (!REQUEST_WORD.equals(d01ToMES)) {
            log.info("地址:{}写入0", mesD01Address);
            S7object.getinstance().plccontrol.writeWord(mesD01Address, 0);
        }
        if (!REQUEST_WORD.equals(d04ToMES)) {
            log.info("地址:{}写入0", mesD04Address);
            S7object.getinstance().plccontrol.writeWord(mesD04Address, 0);
        }
        if (!REQUEST_WORD.equals(d03ToMES)) {
            log.info("地址:{}写入0", mesD03Address);
            S7object.getinstance().plccontrol.writeWord(mesD03Address, 0);
        }
        if (!REQUEST_WORD.equals(d05ToMES)) {
            log.info("地址:{}写入0", mesD05Address);
            S7object.getinstance().plccontrol.writeWord(mesD05Address, 0);
        }
    }
    /**
     * 进片状态修改
     */
//    @Scheduled(fixedDelay = 300)
    public void feedStatusUpdate() {
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        String mesD03Address = plcParameterObject.getPlcParameter("MESToD03").getAddress();
        String mesD05Address = plcParameterObject.getPlcParameter("MESToD05").getAddress();
        List<String> glassIds1 = new ArrayList<>();
        List<String> glassIds2 = new ArrayList<>();
        for (int i = 1; i <= 6; i++) {
            String line1GlassId = plcParameterObject.getPlcParameter("D03ID" + i).getValue();
            if (StringUtils.isNotEmpty(line1GlassId)) {
                glassIds1.add(line1GlassId);
            }
            String line2GlassId = plcParameterObject.getPlcParameter("D05ID" + i).getValue();
            if (StringUtils.isNotEmpty(line2GlassId)) {
                glassIds2.add(line2GlassId);
            }
        }
        List<BigStorageCageFeedTask> bigStorageCageFeedTasks1 = bigStorageCageFeedTaskService.list(
                new LambdaQueryWrapper<BigStorageCageFeedTask>()
                        .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_NEW)
                        .eq(BigStorageCageFeedTask::getLine, Const.A09_OUT_TARGET_POSITION)
        );
        List<BigStorageCageFeedTask> bigStorageCageFeedTasks2 = bigStorageCageFeedTaskService.list(
                new LambdaQueryWrapper<BigStorageCageFeedTask>()
                        .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_NEW)
                        .eq(BigStorageCageFeedTask::getLine, Const.A10_OUT_TARGET_POSITION)
        );
        if (CollectionUtils.isNotEmpty(bigStorageCageFeedTasks1) && CollectionUtils.isNotEmpty(glassIds1)) {
            List<String> matchingIds1 = bigStorageCageFeedTasks1.stream()
                    .map(BigStorageCageFeedTask::getGlassId)
                    .filter(glassIds1::contains)
                    .distinct()
                    .collect(Collectors.toList());
            log.info("D3id{},匹配id:{}", glassIds1, matchingIds1);
            if (CollectionUtils.isNotEmpty(matchingIds1)) {
                bigStorageCageFeedTaskService.update(
                        new LambdaUpdateWrapper<BigStorageCageFeedTask>()
                                .in(BigStorageCageFeedTask::getGlassId, matchingIds1)
                                .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
                                .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
                );
            }
        }
        if (CollectionUtils.isNotEmpty(bigStorageCageFeedTasks2) && CollectionUtils.isNotEmpty(glassIds2)) {
            List<String> matchingIds2 = bigStorageCageFeedTasks2.stream()
                    .map(BigStorageCageFeedTask::getGlassId)
                    .filter(glassIds2::contains)
                    .distinct()
                    .collect(Collectors.toList());
            log.info("D5id{},匹配id:{}", glassIds2, matchingIds2);
            if (CollectionUtils.isNotEmpty(matchingIds2)) {
                bigStorageCageFeedTaskService.update(
                        new LambdaUpdateWrapper<BigStorageCageFeedTask>()
                                .in(BigStorageCageFeedTask::getGlassId, matchingIds2)
                                .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
                                .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
                );
            }
        }
        if (CollectionUtils.isEmpty(glassIds1)) {
            S7object.getinstance().plccontrol.writeWord(mesD03Address, 0);
            log.info("{}线修改玻璃状态为3", Const.A09_OUT_TARGET_POSITION);
            bigStorageCageFeedTaskService.update(
                    new LambdaUpdateWrapper<BigStorageCageFeedTask>()
                            .eq(BigStorageCageFeedTask::getLine, Const.A09_OUT_TARGET_POSITION)
                            .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
                            .gt(BigStorageCageFeedTask::getTargetSlot, 0)
                            .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
                            .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_CAR)
            );
        }
        if (CollectionUtils.isEmpty(glassIds2)) {
            S7object.getinstance().plccontrol.writeWord(mesD05Address, 0);
            log.info("{}线修改玻璃状态为3", Const.A10_OUT_TARGET_POSITION);
            bigStorageCageFeedTaskService.update(
                    new LambdaUpdateWrapper<BigStorageCageFeedTask>()
                            .eq(BigStorageCageFeedTask::getLine, Const.A10_OUT_TARGET_POSITION)
                            .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
                            .gt(BigStorageCageFeedTask::getTargetSlot, 0)
                            .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
                            .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_CAR)
            );
        }
    }
    /**
     * 按照玻璃id判断玻璃状态及卧转立是否可直接启动
     */
    public Boolean judgeGlassTypeStatus(String glassId, Integer line, String mesAddress) {
        //判断此玻璃是在笼内或已生成进片任务
        BigStorageCageFeedTask bigStorageCageFeedTask = bigStorageCageFeedTaskService.getOne(
                new LambdaQueryWrapper<BigStorageCageFeedTask>()
                        .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
                        .eq(BigStorageCageFeedTask::getGlassId, glassId)
        );
        BigStorageCageDetails bigStorageCageDetails = bigStorageCageDetailsService.getOne(
                new LambdaQueryWrapper<BigStorageCageDetails>()
                        .eq(BigStorageCageDetails::getGlassId, glassId)
                        .ne(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
        );
        if (bigStorageCageFeedTask != null || bigStorageCageDetails != null) {
            log.info("此玻璃存任务或已在笼内");
            return Boolean.TRUE;
        }
        //1、获取任务表中相邻玻璃
        List<EdgGlassTaskInfo> edgGlassTaskInfoList;
        edgGlassTaskInfoList = edgGlassTaskInfoService.list(new LambdaQueryWrapper<EdgGlassTaskInfo>()
                .eq(EdgGlassTaskInfo::getLine, line)
                .apply("time >= (select time from edg_glass_task_info where line='" + line + "' and glass_id = '" + glassId + "' and deleted = 0)")
                .orderByAsc(EdgGlassTaskInfo::getCreateTime));
        if (edgGlassTaskInfoList.size() == 0) {
            edgGlassTaskInfoList = edgGlassTaskInfoService.list(new QueryWrapper<EdgGlassTaskInfo>()
                    .select("Top 1 *")
                    .eq("glass_id", glassId)
            );
            log.info("在尺寸表中获取玻璃信息{}", edgGlassTaskInfoList);
            if (edgGlassTaskInfoList.size() == 0) {
                GlassInfo glassInfo = glassInfoService.getOne(
                        new LambdaQueryWrapper<GlassInfo>()
                                .eq(GlassInfo::getGlassId, glassId)
                );
                EdgGlassTaskInfo edgGlassTaskInfo = new EdgGlassTaskInfo();
                BeanUtils.copyProperties(glassInfo, edgGlassTaskInfo);
                edgGlassTaskInfo.setWidth((int) glassInfo.getWidth());
                edgGlassTaskInfo.setHeight((int) glassInfo.getHeight());
                edgGlassTaskInfoList.add(edgGlassTaskInfo);
                log.info("在玻璃信息表中获取玻璃信息{}", edgGlassTaskInfoList);
            }
        }
        Assert.isFalse(CollectionUtils.isEmpty(edgGlassTaskInfoList), "识别玻璃信息未出现在尺寸表中,获取相邻两块玻璃失败");
        //2、获取卧转立剩余宽度
        BigStorageDTO sitToUpRemainWidth = bigStorageCageFeedTaskService.querySitToUpRemainWidth(line);
        Integer remainWidth;
        Integer glassCount;
        if (0 == sitToUpRemainWidth.getGlassCount()) {
            remainWidth = carWidth;
            glassCount = 0;
        } else {
            remainWidth = sitToUpRemainWidth.getWidth();
            glassCount = sitToUpRemainWidth.getGlassCount();
        }
        Boolean flag = Boolean.TRUE;
        //2、获取卧转立
        Integer widthFirst = Math.max(edgGlassTaskInfoList.get(0).getWidth() / 10, edgGlassTaskInfoList.get(0).getHeight() / 10);
        Integer heightFirst = Math.min(edgGlassTaskInfoList.get(0).getWidth() / 10, edgGlassTaskInfoList.get(0).getHeight() / 10);
        if (edgGlassTaskInfoList.size() == 1) {
            if (remainWidth >= widthFirst) {
                if (glassCount < inCarMaxSize) {
                    addFeedTask(glassId, line, Const.BIG_STORAGE_IN_WAIT, widthFirst, heightFirst);
                } else {
                    if (glassCount < inCarMaxSize + 1) {
                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst, heightFirst);
                    } else {
                        return Boolean.FALSE;
                    }
                }
            } else {
                flag = Boolean.FALSE;
            }
        } else {
            Integer widthSecond = Math.max(edgGlassTaskInfoList.get(1).getWidth() / 10, edgGlassTaskInfoList.get(1).getHeight() / 10);
            Integer heightSecond = Math.min(edgGlassTaskInfoList.get(1).getWidth() / 10, edgGlassTaskInfoList.get(1).getHeight() / 10);
            if (remainWidth >= widthFirst) {
                if (remainWidth - widthFirst - glassGap >= widthSecond) {
                    if (glassCount < inCarMaxSize) {
                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_WAIT, widthFirst, heightFirst);
                    } else {
                        if (glassCount < inCarMaxSize + 1) {
                            addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst, heightFirst);
                        } else {
                            return Boolean.FALSE;
                        }
                    }
                } else {
                    if (glassCount < inCarMaxSize + 1) {
                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst, heightFirst);
                    } else {
                        return Boolean.FALSE;
                    }
                }
            } else {
                flag = Boolean.FALSE;
            }
        }
        //向plc发送进片确认
        if (flag) {
            //向plc写入确认字
            PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
            int returnData = 1;
            int count = 1;
            while (returnData != 0) {
                S7object.getinstance().plccontrol.writeWord(mesAddress, 1);
                if (Const.A10_OUT_TARGET_POSITION.equals(line)) {
                    returnData = Integer.parseInt(plcParameterObject.getPlcParameter("D04ToMES").getValue());
                } else {
                    returnData = Integer.parseInt(plcParameterObject.getPlcParameter("D01ToMES").getValue());
                }
//                returnData = S7object.getinstance().plccontrol.readWord(mesAddress, 1).get(0);
                log.info("进卧转立第{}次发送确认字完成,地址为:{},写入的内容为{}", count++, mesAddress, 1);
            }
        }
        //记录无法放下玻璃,后续判断启动
        return flag;
    }
    /**
     * 添加任务信息
     */
    private Boolean addFeedTask(String glassId, Integer line, Integer taskType, Integer width, Integer height) {
        BigStorageCageFeedTask bigStorageCageFeedTask = new BigStorageCageFeedTask();
        bigStorageCageFeedTask.setGlassId(glassId);
        bigStorageCageFeedTask.setTaskState(Const.BIG_STORAGE_IN_NEW);
        bigStorageCageFeedTask.setLine(line);
        bigStorageCageFeedTask.setTaskType(taskType);
        bigStorageCageFeedTask.setWidth(width);
        bigStorageCageFeedTask.setHeight(height);
        bigStorageCageFeedTask.setCreateTime(new Date());
        //删除理片笼表拿走/破损数据数据
        damageService.deleteByGlassId(glassId);
        Damage damage = new Damage();
        damage.setGlassId(glassId);
        damage.setWorkingProcedure("磨边");
        damage.setLine(line);
        damage.setType(1);
        damage.setRemark("进大理片");
        damageService.insertDamage(damage);
        return bigStorageCageFeedTaskService.save(bigStorageCageFeedTask);
    }
    /**
     * 获取需要启动的线路:两条线都可启动 获取第一片玻璃版图id最小 版序最大的线路
     *
     * @return 需要启动的线路
     */
    public Integer getStartLine() {
        List<BigStorageCageFeedTask> taskList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
                .inSql(BigStorageCageFeedTask::getId, "select min(id) from big_storage_cage_feed_task where task_state = 2" +
                        "and (target_slot = 0 or target_slot is null) group by line"));
        Assert.isFalse(CollectionUtils.isEmpty(taskList), "卧转立两条线都没有玻璃进片任务");
        Map<String, Integer> taskMap = taskList.stream().collect(Collectors.toMap(BigStorageCageFeedTask::getGlassId,
                BigStorageCageFeedTask::getLine));
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                .in(GlassInfo::getGlassId, taskMap.keySet())
                .orderByAsc(GlassInfo::getTemperingLayoutId)
                .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence)
                .last("limit 1"));
        return taskMap.get(glassInfo.getGlassId());
    }
    /**
     * 计算任务表进片线路的目标格子,并启动任务
     */
    public boolean computeTargetByLine(Integer line) {
        //1、获取任务表中的所有玻璃(指定线路且已经进卧转立完成)
        List<BigStorageCageFeedTask> taskList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
                .eq(BigStorageCageFeedTask::getLine, line)
                .and(e -> e.isNull(BigStorageCageFeedTask::getTargetSlot).or().eq(BigStorageCageFeedTask::getTargetSlot, Const.OUT_TARGET_POSITION_ZERO))
                .in(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP_ALL)
                .orderByAsc(BigStorageCageFeedTask::getId));
        //2、去笼子内查找是否可以继续存放的笼子
        List<String> glassIds = taskList.stream().map(BigStorageCageFeedTask::getGlassId).collect(Collectors.toList());
        List<GlassInfo> glassInfos = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>().in(GlassInfo::getGlassId, glassIds));
        return computeIsTemperingTargetByLine(glassInfos, taskList, line);
    }
    /**
     * 是否钢化玻璃进笼目标位置
     *
     * @param glassInfos 当条线卧转立所有玻璃
     * @param taskList   当条线卧转立所有任务
     * @param line       任务是哪条线
     */
    private boolean computeIsTemperingTargetByLine(List<GlassInfo> glassInfos, List<BigStorageCageFeedTask> taskList, Integer line) {
        //1、将玻璃信息集合转为glassid为key的map
        Map<String, GlassInfo> glassInfoMap = glassInfos.stream()
                .collect(Collectors.toMap(GlassInfo::getGlassId, p -> p));
        for (BigStorageCageFeedTask e : taskList) {
            GlassInfo info = glassInfoMap.get(e.getGlassId());
            if (info == null) {
                continue;
            }
            BigStorageCageDetails cageDetails = new BigStorageCageDetails();
            BeanUtils.copyProperties(info, cageDetails);
            //2、获取目标格子信息
            BigStorageDTO bigStorageDTO = bigStorageCageDetailsService.queryTargetSlotByTempering(info);
            //3、临时更新格子的剩余尺寸:防止相邻玻璃进同一格子造成剩余尺寸不足,玻璃越界的情况,任务完成后再次更新大理片笼表剩余宽度(按照笼内玻璃数量更新大理片笼剩余尺寸)
            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, bigStorageDTO.getWidth() - Math.max(info.getWidth(), info.getHeight()) - glassGap)
                    .eq(BigStorageCage::getSlot, bigStorageDTO.getSlot()));
            //4、更新进片任务表,目标格子及状态(状态改为2 电气扫到自行处理)  遇到问题:无法批量更新,批量更新无法走指定从库
            e.setTargetSlot(bigStorageDTO.getSlot());
            bigStorageCageFeedTaskService.updateById(e);
            //5、将进片信息存入大理片笼详情表
            cageDetails.setSlot(bigStorageDTO.getSlot());
            cageDetails.setState(Const.GLASS_STATE_NEW);
            cageDetails.setDeviceId(bigStorageDTO.getDeviceId());
            cageDetails.setGap(glassGap);
            bigStorageCageDetailsService.save(cageDetails);
        }
        sendTaskListToPLC(taskList, line);
        return Boolean.TRUE;
    }
    private void sendTaskListToPLC(List<BigStorageCageFeedTask> taskList, Integer line) {
        log.info("送片任务发送进片玻璃信息");
        S7control s7control = S7object.getinstance().plccontrol;
        PlcParameterObject plcMesObject = S7object.getinstance().PlcMesObject;
        String mesD03Address = plcMesObject.getPlcParameter("MESToD03").getAddress();
        String mesD05Address = plcMesObject.getPlcParameter("MESToD05").getAddress();
        String outLine = line.equals(Const.A09_OUT_TARGET_POSITION) ? mesD03Address : mesD05Address;
        List<String> returnData = new ArrayList<>();
        for (int i = 1; i <= taskList.size(); i++) {
            s7control.writeWord(plcMesObject.getPlcParameter("StartAddToImport" + i).getAddress(), taskList.get(i - 1).getLine());
            s7control.writeWord(plcMesObject.getPlcParameter("TargetAddToImport" + i).getAddress(), taskList.get(i - 1).getTargetSlot());
            returnData.add(taskList.get(i - 1).getGlassId());
            log.info("向plc发送第{}片玻璃已完成,起始位置是{},目标位置是", i, taskList.get(i - 1).getLine(), taskList.get(i - 1).getTargetSlot());
        }
//        int returnData = 1;
        int count = 1;
        while (CollectionUtils.isNotEmpty(returnData)) {
            List<String> glassIds1 = new ArrayList<>();
            List<String> glassIds2 = new ArrayList<>();
            s7control.writeWord(outLine, 2);
            for (int i = 1; i <= 6; i++) {
                String line1GlassId = plcMesObject.getPlcParameter("D03ID" + i).getValue();
                if (StringUtils.isNotEmpty(line1GlassId)) {
                    glassIds1.add(line1GlassId);
                }
                String line2GlassId = plcMesObject.getPlcParameter("D05ID" + i).getValue();
                if (StringUtils.isNotEmpty(line2GlassId)) {
                    glassIds2.add(line2GlassId);
                }
            }
            if (line.equals(Const.A09_OUT_TARGET_POSITION)) {
//                returnData = Integer.parseInt(plcMesObject.getPlcParameter("D03ToMES").getValue());
                returnData = glassIds1;
            } else {
//                returnData = Integer.parseInt(plcMesObject.getPlcParameter("D05ToMES").getValue());
                returnData = glassIds2;
            }
//            returnData = s7control.readWord(outLine, 1).get(0);
            log.info("已向plc第{}次发送进片任务确认,地址为:{},写入的内容为{},读到的请求为{}", count++, outLine, 2, returnData);
        }
//        while (returnData != 0) {
//        log.info("执行空车送片任务,获取到的大车状态为{},卧转立状态分别为d03:{},d05:{}", e01Status, d03ToMES, d05ToMES);
//        List<BigStorageCageFeedTask> bigStorageCageFeedTasks = bigStorageCageFeedTaskService.list(
//                new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                        .ne(BigStorageCageFeedTask::getTargetSlot, 0)
//                        .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
//        );
//        if (bigStorageCageFeedTasks.size() > 0) {
//            Date endDate = new Date();
//            log.info("大车有正在执行的任务{},结束送片任务,任务结束时间:{},共耗时:{}ms,结束扫码任务", bigStorageCageFeedTasks, endDate, endDate.getTime() - startDate.getTime());
//            return;
//        }
//        if (REQUEST_WORD.equals(e01Status)) {
//            Date endDate = new Date();
//            log.info("进片大车非空闲,结束送片任务,任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//            return;
//        }
//        if (!REQUEST_WORD.equals(d03ToMES) && !REQUEST_WORD.equals(d05ToMES)) {
//            Date endDate = new Date();
//            log.info("卧转立第一次没有送片请求,结束送片任务,任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//            return;
//        }
//        if (!REQUEST_WORD.equals(d03ToMES) && !REQUEST_WORD.equals(d05ToMES)) {
//            Date endDate = new Date();
//            log.info("卧转立第二次没有送片请求,结束送片任务,任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//            return;
//        }
////        List<Integer> lines=new ArrayList<>();
////        if(REQUEST_WORD.equals(d03ToMES)){
////            lines.add(Const.A09_OUT_TARGET_POSITION);
////        }
////        if(REQUEST_WORD.equals(d05ToMES)){
////            lines.add(Const.A10_OUT_TARGET_POSITION);
////        }
//        LambdaQueryWrapper<BigStorageCageFeedTask> wrapper = new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                .eq(BigStorageCageFeedTask::getTaskType, Const.BIG_STORAGE_IN_RUN)
//                .and(e -> e.isNull(BigStorageCageFeedTask::getTargetSlot).or().eq(BigStorageCageFeedTask::getTargetSlot, Const.OUT_TARGET_POSITION_ZERO))
//                .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP);
////                .in(BigStorageCageFeedTask::getLine,lines);
//        //获取可以启动卧转立的任务线路
//        List<BigStorageCageFeedTask> feedTaskList = bigStorageCageFeedTaskService.list(wrapper);
//        if (CollectionUtils.isNotEmpty(feedTaskList)) {
//            if (feedTaskList.size() == 1) {
//                computeTargetByLine(feedTaskList.get(0).getLine());
//            } else {
//                //比较最早一片任务的版图id及版序 求出卧转立的线路
//                Integer startLine = getStartLine();
////            //计算目标格子,发送启动任务
//                computeTargetByLine(startLine);
//            }
//            Date endDate = new Date();
//            log.info("大理片笼空车进片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//            return;
//        }
//        String d01Id = plcParameterObject.getPlcParameter("D01ID").getValue();
//        String d04Id = plcParameterObject.getPlcParameter("D04ID").getValue();
//        log.info("1、获取d01Id扫描ID为:{};获取d04Id扫描ID为:{};", d01Id, d04Id);
//        //获取两条线卧转立是否有玻璃,且任务状态为1/2
//        List<Integer> lineList = bigStorageCageFeedTaskService.querySitToUpGlass();
//        if (CollectionUtils.isEmpty(lineList)) {
//            Date endDate = new Date();
//            log.info("两条线卧转立为空或者有进片任务未完成,结束任务,大理片笼空车进片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//            return;
//        }
//        Integer lineFirst = lineList.get(0);
//        String lineGlassId = lineFirst.equals(Const.A09_OUT_TARGET_POSITION) ? d01Id : d04Id;
//        //仅有一条先符合启动启动条件
//        if (lineList.size() == 1) {
//            //如果进片请求但玻璃为空,计算任务表进片格子 发送进片任务
//            if (StringUtils.isEmpty(lineGlassId)) {
//                computeTargetByLine(lineFirst);
//            } else {
//                //todo:计算扫描到的玻璃是否可以存进卧转立
//                //获取卧转立剩余宽度
//                if (computeIsRun(lineFirst, lineGlassId)) {
//                    computeTargetByLine(lineFirst);
//                } else {
//                    log.info("当前线路:{},有扫码玻璃:{}", lineFirst, lineGlassId);
//                }
//            }
//            Date endDate = new Date();
//            log.info("大理片笼空车进片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//            return;
//        }
//        //两条先均可执行进片任务,判断两条线是否进片请求是否都为空
//        if (StringUtils.isBlank(d01Id) && StringUtils.isBlank(d04Id)) {
//            //比较最早一片任务的版图id及版序 求出卧转立的线路
//            Integer line = getStartLine();
//            //计算任务表进片格子 发送进片任务
//            computeTargetByLine(line);
//            Date endDate = new Date();
//            log.info("大理片笼空车进片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//            return;
//        } else if (StringUtils.isNotBlank(d01Id) && StringUtils.isNotBlank(d04Id)) {
////            todo:两个都有进片玻璃
//            if (computeIsRun(Const.A09_OUT_TARGET_POSITION, d01Id) && computeIsRun(Const.A10_OUT_TARGET_POSITION, d04Id)) {
//                //比较最早一片任务的版图id及版序 求出卧转立的线路
//                Integer line = getStartLine();
//                //计算任务表进片格子 发送进片任务
//                computeTargetByLine(line);
//            } else if (computeIsRun(Const.A09_OUT_TARGET_POSITION, d01Id)) {
//                computeTargetByLine(Const.A09_OUT_TARGET_POSITION);
//            } else if (computeIsRun(Const.A10_OUT_TARGET_POSITION, d04Id)) {
//                computeTargetByLine(Const.A10_OUT_TARGET_POSITION);
//            } else {
//                Date endDate = new Date();
//                log.info("大理片笼空车进片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//                return;
//            }
//        } else {
//            //,或者仅有一条有玻璃
//            //一条线为空,一条线有进片请求有玻璃
//            int outLine = StringUtils.isBlank(d01Id) ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
//            //获取进片请求玻璃为空的,计算任务表进片格子 发送进片任务
//            computeTargetByLine(outLine);
//        }
//        Date endDate = new Date();
//        log.info("大理片笼空车进片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//    }
//
//    //    @Scheduled(fixedDelay = 10000)
//    public void plcToHomeEdgOutTask() {
//        Date startDate = new Date();
//        log.info("大理片笼空车进片任务开始执行时间:{}", startDate);
//        PlcParameterObject plcMesObject = S7object.getinstance().PlcMesObject;
//        String e02State = plcMesObject.getPlcParameter("E02State").getValue();
//        if (REQUEST_WORD.equals(e02State)) {
//            log.info("出片忙碌,结束出片任务");
//            return;
//        }
//        String mesToPLCAddress = plcMesObject.getPlcParameter("MESToPLC").getAddress();
//        List<BigStorageCageOutTask> outingList = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
//                .eq(BigStorageCageOutTask::getTaskState, Const.BIG_STORAGE_OUT_NEW));
//        if (CollectionUtils.isNotEmpty(outingList)) {
//            log.info("有正在执行出片的任务,结束当前出片线程");
//            return;
//        }
//        if (redisUtil.getCacheObject("temperingSwitch")) {
//            //是否有正在钢化的玻璃
//            List<TemperingGlassInfo> temperingGlassInfoList = temperingGlassInfoService.selectJoinList(TemperingGlassInfo.class, new MPJLambdaWrapper<TemperingGlassInfo>()
//                    .selectAll(TemperingGlassInfo.class)
//                    .leftJoin(BigStorageCageOutTask.class, BigStorageCageOutTask::getGlassId, TemperingGlassInfo::getGlassId)
//                    .eq(TemperingGlassInfo::getState, Const.TEMPERING_NEW)
//                    .isNull(BigStorageCageOutTask::getGlassId)
//                    .orderBy(Boolean.TRUE, sequenceOrder, TemperingGlassInfo::getTemperingFeedSequence));
//            if (CollectionUtils.isNotEmpty(temperingGlassInfoList)) {
//                log.info("有正在出片的钢化任务");
//                computeOutMoreGlassInfo(temperingGlassInfoList, Boolean.TRUE, mesToPLCAddress);
//                Date endDate = new Date();
//                log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//                return;
//            }
//            //是否有人工下片任务   有直接出
////            List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
////                    .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL).orderByDesc(BigStorageCageDetails::getWidth));
//            List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
//                    .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL)
//                    .orderByAsc(BigStorageCageDetails::getSlot)
//                    .orderByDesc(BigStorageCageDetails::getId));
//            if (CollectionUtils.isNotEmpty(artificialList)) {
//                computeOutMoreGlassInfo(artificialList, Boolean.FALSE, mesToPLCAddress);
//                Date endDate = new Date();
//                log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//                return;
//            }
//            //钢化优先:获取理片笼  玻璃小片  破损表 数量   判断笼内版图是否到齐
//            List<TemperingLayoutDTO> temperingLayoutDTOList = bigStorageCageDetailsService.temperingIsAll();
//            if (CollectionUtils.isNotEmpty(temperingLayoutDTOList)) {
//                //玻璃到齐包括已出片的
//                //到齐,将玻璃小片数据存入钢化小片表,逻辑生成出片任务  结束
//                for (TemperingLayoutDTO item : temperingLayoutDTOList) {
//                    if (redisUtil.getCacheObject("temperingengineerId").equals(item.getEngineerId())) {
//                        List<TemperingGlassInfo> temperingGlassInfos = glassInfoService.selectJoinList(TemperingGlassInfo.class, JoinWrappers.lambda(GlassInfo.class)
//                                .selectAll(GlassInfo.class)
//                                .select("-1 as state")
//                                .selectAs(BigStorageCageDetails::getSlot, TemperingGlassInfo::getSlot)
//                                .innerJoin(BigStorageCageDetails.class, BigStorageCageDetails::getGlassId, GlassInfo::getGlassId)
//                                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
//                                .eq(GlassInfo::getTemperingLayoutId, item.getTemperingLayoutId())
//                                .eq(GlassInfo::getEngineerId, item.getEngineerId())
//                                .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence));
//                        if (CollectionUtils.isNotEmpty(temperingGlassInfos)) {
//                            temperingGlassInfoService.saveBatch(temperingGlassInfos);
//                            computeOutMoreGlassInfo(temperingGlassInfoList, Boolean.TRUE, mesToPLCAddress);
//                            Date endDate = new Date();
//                            log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//                            return;
//                        }
//                    }
//                }
//            }
//        }
//        //执行内部调度任务
//        List<TemperingLayoutDTO> temperingOccupySlotList = bigStorageCageDetailsService.queryTemperingOccupySlot();
//        if (CollectionUtils.isNotEmpty(temperingOccupySlotList)) {
//            loop:
//            for (TemperingLayoutDTO temperingOccupySlot : temperingOccupySlotList) {
//                List<SlotSequenceDTO> slotSequenceList = bigStorageCageDetailsService.queryGlassMaxAndMin(temperingOccupySlot.getEngineerId(), temperingOccupySlot.getTemperingLayoutId());
//                for (int i = 0; i < slotSequenceList.size() - 1; i++) {
//                    SlotSequenceDTO first = slotSequenceList.get(i);
//                    SlotSequenceDTO second = slotSequenceList.get(i + 1);
//                    int slotWidth = carWidth - first.getRemainWidth() - glassGap;
//                    if (first.getMinSequence() == second.getMaxSequence() + 1
//                            && second.getRemainWidth() > slotWidth && slotWidth >= 0) {
//                        List<BigStorageCageDetails> list = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
//                                .eq(BigStorageCageDetails::getSlot, first.getSlot()).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
//                                .orderBy(Boolean.TRUE, sequenceOrder, BigStorageCageDetails::getTemperingFeedSequence));
//                        if (CollectionUtils.isNotEmpty(list)) {
//                            List<BigStorageCageOutTask> outTasks = new ArrayList<>();
//                            int serialNumber = 1;
//                            for (BigStorageCageDetails item : list) {
//                                outTasks.add(new BigStorageCageOutTask(item.getGlassId(), first.getSlot(), second.getSlot(),
//                                        item.getWidth() * 10, item.getHeight() * 10, 1, serialNumber++, Const.BIG_STORAGE_OUT_NEW, new Date()));
//                            }
//                            //新增调度任务
//                            bigStorageCageOutTaskService.saveBatch(outTasks);
//                            //更新理片笼详情表调度的后的玻璃位置信息:生成任务后先将玻璃格子位置进行调整,玻璃状态改为调度中,新增调度完成任务,处理调度完成后玻璃状态改为100.
//                            List<String> glassList = list.stream().map(BigStorageCageDetails::getGlassId).collect(Collectors.toList());
//                            bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>().set(BigStorageCageDetails::getState, Const.GLASS_STATE_SCHEDULE_ING)
//                                    .set(BigStorageCageBaseInfo::getSlot, second.getSlot()).in(BigStorageCageDetails::getGlassId, glassList));
//                            //两次更新笼子的剩余尺寸:第一次防止有玻璃继续进调度后的笼子,第二次更新:计算格子的实际尺寸
//                            // 仅更新调度后的格子信息:起始格子完成后更新:防止调度出片过程中有新玻璃进入,
//                            updateSlotRemainBySlots(Arrays.asList(second.getSlot()));
//                            break loop;
//                        }
//                    }
//                }
//            }
////            //向plc写入确认字
////            int returnData = 0;
////            int count = 1;
////            while (returnData == 0) {
////                log.info("已向plc第{}次送协议", count);
////                S7object.getinstance().plccontrol.writeWord(mesToPLCAddress, 1);
////                returnData = S7object.getinstance().plccontrol.readWord(mesToPLCAddress, 1).get(0);
////                log.info("已向plc第{}次发送出片任务确认,地址为:{},写入的内容为{}", count++, mesToPLCAddress, returnData);
////            }
//            Date endDate = new Date();
//            log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//            return;
//        }
//    }
//
//    //    @Scheduled(fixedDelay = 300)
//    public void updateInGlassStateTask() {
//        Date startDate = new Date();
//        log.info("1、大理片笼进片完成后更新大理片笼数据任务开始执行时间:{}", startDate);
//        //因为大理片笼和出片任务是两个库的数据,所以要分开查找
//        List<Object> list = bigStorageCageDetailsService.listObjs(new LambdaQueryWrapper<BigStorageCageDetails>()
//                .select(BigStorageCageDetails::getGlassId).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_NEW));
//        if (CollectionUtils.isNotEmpty(list)) {
//            log.info("2、获取所有正在进片的玻璃信息id:{}", list);
//            List<String> glassIds = list.stream().map(String::valueOf).collect(Collectors.toList());
//            List<BigStorageCageFeedTask> inSuccessGlass = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                    .in(BigStorageCageFeedTask::getGlassId, glassIds)
//                    .in(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT));
//            if (CollectionUtils.isNotEmpty(inSuccessGlass)) {
//                log.info("3、获取进片已完成的玻璃信息id:{}", inSuccessGlass);
//                List<Integer> inSuccessGlassSlot = inSuccessGlass.stream().map(BigStorageCageFeedTask::getTargetSlot).collect(Collectors.toList());
//                List<UpdateBigStorageCageDTO> storageCageDTOList = inSuccessGlass.stream().map(e -> {
//                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
//                    BeanUtils.copyProperties(e, storageCageDTO);
//                    return storageCageDTO;
//                }).collect(Collectors.toList());
//                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_IN);
//                log.info("4、大理片笼进片状态已完成已完成的玻璃信息id:{}", inSuccessGlass);
//                //更新理片笼玻璃尺寸
//                updateSlotRemainBySlots(inSuccessGlassSlot);
//                log.info("5、大理片笼进片目标格子尺寸更新完成");
//            }
//
//        }
//        Date endDate = new Date();
//        log.info("end:大理片笼进片完成后更新大理片笼数据任务结束时间:{},共耗时:{}ms,结束任务", endDate, endDate.getTime() - startDate.getTime());
//        return;
//
//    }
//
//    //    @Scheduled(fixedDelay = 300)
//    public void updateOutGlassStateTask() {
//        Date startDate = new Date();
//        log.info("1、大理片笼出片完成后更新大理片笼数据任务开始执行时间:{}", startDate);
//        //因为大理片笼和出片任务是两个库的数据,所以要分开查找
//        List<Object> list = bigStorageCageDetailsService.listObjs(new LambdaQueryWrapper<BigStorageCageDetails>()
//                .select(BigStorageCageDetails::getGlassId).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT_ING));
//        if (CollectionUtils.isNotEmpty(list)) {
//            log.info("2、获取所有正在出片的玻璃信息id:{}", list);
//            List<String> glassIds = list.stream().map(String::valueOf).collect(Collectors.toList());
//            List<BigStorageCageOutTask> outSuccessGlass = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
//                    .in(BigStorageCageOutTask::getGlassId, glassIds).in(BigStorageCageOutTask::getTaskState, Const.BIG_STORAGE_OUT_ALL));
//            if (CollectionUtils.isNotEmpty(outSuccessGlass)) {
//                for (BigStorageCageOutTask bigStorageCageOutTask : outSuccessGlass
//                ) {
//                    if (bigStorageCageOutTask.getEndSlot().equals(Const.ARTIFICIAL_OUT_TARGET_POSITION)) {
//                        temperingGlassInfoService.update(
//                                new LambdaUpdateWrapper<TemperingGlassInfo>()
//                                        .set(TemperingGlassInfo::getState, Const.TEMPERING_END)
//                                        .eq(TemperingGlassInfo::getGlassId, bigStorageCageOutTask.getGlassId())
//                        );
//                    }
//                }
//                log.info("3、获取出片已完成的玻璃信息id:{}", outSuccessGlass);
//                List<UpdateBigStorageCageDTO> storageCageDTOList = outSuccessGlass.stream().map(e -> {
//                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
//                    storageCageDTO.setGlassId(e.getGlassId());
//                    storageCageDTO.setTargetSlot(e.getStartSlot());
//                    return storageCageDTO;
//                }).collect(Collectors.toList());
//                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_OUT);
//                List<Integer> outSuccessSlotList = outSuccessGlass.stream().map(BigStorageCageOutTask::getStartSlot).collect(Collectors.toList());
//                log.info("4、大理片笼出片状态已完成已完成的玻璃信息id:{}", outSuccessGlass);
//                //更新理片笼玻璃尺寸
//                updateSlotRemainBySlots(outSuccessSlotList);
//                log.info("5、大理片笼进片目标格子尺寸更新完成");
//            }
//        }
//        Date endDate = new Date();
//        log.info("end:大理片笼出片完成后更新大理片笼数据任务结束时间:{},共耗时:{}ms,结束任务", endDate, endDate.getTime() - startDate.getTime());
//        return;
//
//    }
//
//    //    @Scheduled(fixedDelay = 300)
//    public void updateScheduleGlassStateTask() {
//        Date startDate = new Date();
//        log.info("1、大理片笼调度完成后更新大理片笼数据任务开始执行时间:{}", startDate);
//        //因为大理片笼和调度任务是两个库的数据,所以要分开查找
//        List<Object> list = bigStorageCageDetailsService.listObjs(new LambdaQueryWrapper<BigStorageCageDetails>()
//                .select(BigStorageCageDetails::getGlassId).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_SCHEDULE_ING));
//        if (CollectionUtils.isNotEmpty(list)) {
//            log.info("2、获取所有正在出片的玻璃信息id:{}", list);
//            List<String> glassIds = list.stream().map(String::valueOf).collect(Collectors.toList());
//            List<BigStorageCageOutTask> scheduleSuccessGlass = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
//                    .in(BigStorageCageOutTask::getGlassId, glassIds).eq(BigStorageCageOutTask::getTaskState, Const.BIG_STORAGE_OUT_SUCCESS)
//                    .notIn(BigStorageCageOutTask::getEndSlot, Const.TEMPERING_OUT_TARGET_POSITION, Const.ARTIFICIAL_OUT_TARGET_POSITION));
//            if (CollectionUtils.isNotEmpty(scheduleSuccessGlass)) {
//                log.info("3、获取调度已完成的玻璃信息id:{}", scheduleSuccessGlass);
//                List<UpdateBigStorageCageDTO> storageCageDTOList = scheduleSuccessGlass.stream().map(e -> {
//                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
//                    storageCageDTO.setGlassId(e.getGlassId());
//                    storageCageDTO.setTargetSlot(e.getEndSlot());
//                    return storageCageDTO;
//                }).collect(Collectors.toList());
//                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_IN);
//                List<String> scheduleSuccessGlassIds = scheduleSuccessGlass.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
//                log.info("4、大理片笼出片状态已完成已完成的玻璃信息id:{}", scheduleSuccessGlassIds);
//                //更新理片笼玻璃尺寸
//                List<Integer> slotList = scheduleSuccessGlass.stream().map(BigStorageCageOutTask::getStartSlot).distinct().collect(Collectors.toList());
//                slotList.addAll(scheduleSuccessGlass.stream().map(BigStorageCageOutTask::getEndSlot).distinct().collect(Collectors.toList()));
//                updateSlotRemainBySlots(slotList);
//                log.info("5、大理片笼进片目标格子尺寸更新完成");
//            }
//        }
//        Date endDate = new Date();
//        log.info("end:大理片笼出片完成后更新大理片笼数据任务结束时间:{},共耗时:{}ms,结束任务", endDate, endDate.getTime() - startDate.getTime());
//        return;
//
//    }
//
//    /**
//     * 处理破损表任务
//     */
////    @Scheduled(fixedDelay = 300)
//    public void dealDamageTask() {
//        Date startDate = new Date();
//        log.info("大理片笼破损玻璃清除任务开始执行时间:{}", startDate);
//        //获取进片任务表中状态为破损的数据
//        List<BigStorageCageFeedTask> inDamageTaskInfoList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                .in(BigStorageCageFeedTask::getTaskState, Const.GLASS_STATE_DAMAGE_TAKE));
//        if (CollectionUtils.isNotEmpty(inDamageTaskInfoList)) {
//            log.info("获取进片任务表中破损的玻璃信息{}", inDamageTaskInfoList);
//            bigStorageCageFeedTaskService.remove(new LambdaQueryWrapper<BigStorageCageFeedTask>().in(BigStorageCageFeedTask::getTaskState, Const.GLASS_STATE_DAMAGE_TAKE));
//            //理片笼详情表数据状态更新
//            bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>()
//                    .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_NEW).in(BigStorageCageDetails::getGlassId, inDamageTaskInfoList.stream().map(BigStorageCageFeedTask::getGlassId).collect(Collectors.toList())));
//            //将破损信息新增入破损表
//            List<Integer> slotList = new ArrayList<>();
//            for (BigStorageCageFeedTask bigStorageCageFeedTask : inDamageTaskInfoList) {
//                Damage damage = new Damage();
//                damage.setGlassId(bigStorageCageFeedTask.getGlassId());
//                damage.setLine(bigStorageCageFeedTask.getLine());
//                damage.setWorkingProcedure("磨边");
//                damage.setRemark("进笼前卧转立");
//                damage.setStatus(1);
//                damage.setType(bigStorageCageFeedTask.getTaskState());
//                damageService.insertDamage(damage);
//                slotList.add(bigStorageCageFeedTask.getTargetSlot());
//            }
//            //更新格子剩余宽度
//            updateSlotRemainBySlots(slotList);
//            log.info("进片任务执行完成");
//        }
//        //获取出片任务表中状态为破损的数据
//        List<BigStorageCageOutTask> outDamageTaskInfoList = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
//                .in(BigStorageCageOutTask::getTaskState, Const.GLASS_STATE_DAMAGE_TAKE));
//        if (CollectionUtils.isNotEmpty(outDamageTaskInfoList)) {
//            log.info("获取出片任务表中破损的玻璃信息{}", outDamageTaskInfoList);
//            bigStorageCageOutTaskService.remove(new LambdaQueryWrapper<BigStorageCageOutTask>().in(BigStorageCageOutTask::getTaskState, Const.GLASS_STATE_DAMAGE_TAKE));
//            List<String> glassIdList = outDamageTaskInfoList.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
//            //移除钢化下片表数据
//            temperingGlassInfoService.remove(new LambdaQueryWrapper<TemperingGlassInfo>().in(TemperingGlassInfo::getGlassId, glassIdList));
//            //理片笼详情表数据状态删除
//            bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>().in(BigStorageCageDetails::getGlassId, glassIdList));
//            //将破损信息新增入破损表
//            List<Integer> slotList = new ArrayList<>();
//            for (BigStorageCageOutTask bigStorageCageOutTask : outDamageTaskInfoList) {
//                Damage damage = new Damage();
//                damage.setGlassId(bigStorageCageOutTask.getGlassId());
//                damage.setLine(bigStorageCageOutTask.getEndSlot());
//                damage.setWorkingProcedure("钢化");
//                damage.setRemark("出片后卧转立");
//                damage.setStatus(1);
//                damage.setType(bigStorageCageOutTask.getTaskState());
//                damageService.insertDamage(damage);
//                slotList.add(bigStorageCageOutTask.getStartSlot());
//            }
//            //更新格子剩余宽度
//            updateSlotRemainBySlots(slotList);
//            log.info("出片任务执行完成");
//        }
//        Date endDate = new Date();
//        log.info("大理片笼破损玻璃清除任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
//        return;
//    }
//
//    /**
//     * 确认字清空
//     */
////    @Scheduled(fixedDelay = 300)
//    public void confirmClear() {
//        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
//        String d01ToMES = plcParameterObject.getPlcParameter("D01ToMES").getValue();
//        String d04ToMES = plcParameterObject.getPlcParameter("D04ToMES").getValue();
//        String mesD01Address = plcParameterObject.getPlcParameter("MESToD01").getAddress();
//        String mesD04Address = plcParameterObject.getPlcParameter("MESToD04").getAddress();
////        String d03ToMES = plcParameterObject.getPlcParameter("D03ToMES").getValue();
////        String d05ToMES = plcParameterObject.getPlcParameter("D05ToMES").getValue();
//        String d03ToMES = plcParameterObject.getPlcParameter("D03Request").getValue();
//        String d05ToMES = plcParameterObject.getPlcParameter("D05Request").getValue();
//        String mesD03Address = plcParameterObject.getPlcParameter("MESToD03").getAddress();
//        String mesD05Address = plcParameterObject.getPlcParameter("MESToD05").getAddress();
//        if (!REQUEST_WORD.equals(d01ToMES)) {
//            log.info("地址:{}写入0", mesD01Address);
//            S7object.getinstance().plccontrol.writeWord(mesD01Address, 0);
//        }
//        if (!REQUEST_WORD.equals(d04ToMES)) {
//            log.info("地址:{}写入0", mesD04Address);
//            S7object.getinstance().plccontrol.writeWord(mesD04Address, 0);
//        }
//        if (!REQUEST_WORD.equals(d03ToMES)) {
//            log.info("地址:{}写入0", mesD03Address);
//            S7object.getinstance().plccontrol.writeWord(mesD03Address, 0);
//        }
//        if (!REQUEST_WORD.equals(d05ToMES)) {
//            log.info("地址:{}写入0", mesD05Address);
//            S7object.getinstance().plccontrol.writeWord(mesD05Address, 0);
//        }
//    }
//
//    /**
//     * 进片状态修改
//     */
////    @Scheduled(fixedDelay = 300)
//    public void feedStatusUpdate() {
//        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
//        String mesD03Address = plcParameterObject.getPlcParameter("MESToD03").getAddress();
//        String mesD05Address = plcParameterObject.getPlcParameter("MESToD05").getAddress();
//        List<String> glassIds1 = new ArrayList<>();
//        List<String> glassIds2 = new ArrayList<>();
//        for (int i = 1; i <= 6; i++) {
//            String line1GlassId = plcParameterObject.getPlcParameter("D03ID" + i).getValue();
//            if (StringUtils.isNotEmpty(line1GlassId)) {
//                glassIds1.add(line1GlassId);
//            }
//            String line2GlassId = plcParameterObject.getPlcParameter("D05ID" + i).getValue();
//            if (StringUtils.isNotEmpty(line2GlassId)) {
//                glassIds2.add(line2GlassId);
//            }
//        }
//        List<BigStorageCageFeedTask> bigStorageCageFeedTasks1 = bigStorageCageFeedTaskService.list(
//                new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                        .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_NEW)
//                        .eq(BigStorageCageFeedTask::getLine, Const.A09_OUT_TARGET_POSITION)
//        );
//        List<BigStorageCageFeedTask> bigStorageCageFeedTasks2 = bigStorageCageFeedTaskService.list(
//                new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                        .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_NEW)
//                        .eq(BigStorageCageFeedTask::getLine, Const.A10_OUT_TARGET_POSITION)
//        );
//        if (CollectionUtils.isNotEmpty(bigStorageCageFeedTasks1) && CollectionUtils.isNotEmpty(glassIds1)) {
//            List<String> matchingIds1 = bigStorageCageFeedTasks1.stream()
//                    .map(BigStorageCageFeedTask::getGlassId)
//                    .filter(glassIds1::contains)
//                    .distinct()
//                    .collect(Collectors.toList());
//            log.info("D3id{},匹配id:{}", glassIds1, matchingIds1);
//            if (CollectionUtils.isNotEmpty(matchingIds1)) {
//                bigStorageCageFeedTaskService.update(
//                        new LambdaUpdateWrapper<BigStorageCageFeedTask>()
//                                .in(BigStorageCageFeedTask::getGlassId, matchingIds1)
//                                .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
//                                .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
//                );
//            }
//        }
//        if (CollectionUtils.isNotEmpty(bigStorageCageFeedTasks2) && CollectionUtils.isNotEmpty(glassIds2)) {
//            List<String> matchingIds2 = bigStorageCageFeedTasks2.stream()
//                    .map(BigStorageCageFeedTask::getGlassId)
//                    .filter(glassIds2::contains)
//                    .distinct()
//                    .collect(Collectors.toList());
//            log.info("D5id{},匹配id:{}", glassIds2, matchingIds2);
//            if (CollectionUtils.isNotEmpty(matchingIds2)) {
//                bigStorageCageFeedTaskService.update(
//                        new LambdaUpdateWrapper<BigStorageCageFeedTask>()
//                                .in(BigStorageCageFeedTask::getGlassId, matchingIds2)
//                                .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
//                                .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
//                );
//            }
//        }
//        if (CollectionUtils.isEmpty(glassIds1)) {
//            S7object.getinstance().plccontrol.writeWord(mesD03Address, 0);
//            log.info("{}线修改玻璃状态为3", Const.A09_OUT_TARGET_POSITION);
//            bigStorageCageFeedTaskService.update(
//                    new LambdaUpdateWrapper<BigStorageCageFeedTask>()
//                            .eq(BigStorageCageFeedTask::getLine, Const.A09_OUT_TARGET_POSITION)
//                            .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
//                            .gt(BigStorageCageFeedTask::getTargetSlot, 0)
//                            .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
//                            .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_CAR)
//            );
//        }
//        if (CollectionUtils.isEmpty(glassIds2)) {
//            S7object.getinstance().plccontrol.writeWord(mesD05Address, 0);
//            log.info("{}线修改玻璃状态为3", Const.A10_OUT_TARGET_POSITION);
//            bigStorageCageFeedTaskService.update(
//                    new LambdaUpdateWrapper<BigStorageCageFeedTask>()
//                            .eq(BigStorageCageFeedTask::getLine, Const.A10_OUT_TARGET_POSITION)
//                            .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
//                            .gt(BigStorageCageFeedTask::getTargetSlot, 0)
//                            .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
//                            .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_CAR)
//            );
//        }
//    }
//
//    /**
//     * 按照玻璃id判断玻璃状态及卧转立是否可直接启动
//     */
//    public Boolean judgeGlassTypeStatus(String glassId, Integer line, String mesAddress) {
//        //判断此玻璃是在笼内或已生成进片任务
//        BigStorageCageFeedTask bigStorageCageFeedTask = bigStorageCageFeedTaskService.getOne(
//                new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                        .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
//                        .eq(BigStorageCageFeedTask::getGlassId, glassId)
//        );
//        BigStorageCageDetails bigStorageCageDetails = bigStorageCageDetailsService.getOne(
//                new LambdaQueryWrapper<BigStorageCageDetails>()
//                        .eq(BigStorageCageDetails::getGlassId, glassId)
//                        .ne(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
//        );
//        if (bigStorageCageFeedTask != null || bigStorageCageDetails != null) {
//            log.info("此玻璃存任务或已在笼内");
//            return Boolean.TRUE;
//        }
//        //1、获取任务表中相邻玻璃
//        List<EdgGlassTaskInfo> edgGlassTaskInfoList;
//        edgGlassTaskInfoList = edgGlassTaskInfoService.list(new LambdaQueryWrapper<EdgGlassTaskInfo>()
//                .eq(EdgGlassTaskInfo::getLine, line)
//                .apply("time >= (select time from edg_glass_task_info where line='" + line + "' and glass_id = '" + glassId + "' and deleted = 0)")
//                .orderByAsc(EdgGlassTaskInfo::getCreateTime));
//        if (edgGlassTaskInfoList.size() == 0) {
//            edgGlassTaskInfoList = edgGlassTaskInfoService.list(new QueryWrapper<EdgGlassTaskInfo>()
//                    .select("Top 1 *")
//                    .eq("glass_id", glassId)
//            );
//            log.info("在尺寸表中获取玻璃信息{}", edgGlassTaskInfoList);
//            if (edgGlassTaskInfoList.size() == 0) {
//                GlassInfo glassInfo = glassInfoService.getOne(
//                        new LambdaQueryWrapper<GlassInfo>()
//                                .eq(GlassInfo::getGlassId, glassId)
//                );
//                EdgGlassTaskInfo edgGlassTaskInfo = new EdgGlassTaskInfo();
//                BeanUtils.copyProperties(glassInfo, edgGlassTaskInfo);
//                edgGlassTaskInfo.setWidth((int) glassInfo.getWidth());
//                edgGlassTaskInfo.setHeight((int) glassInfo.getHeight());
//                edgGlassTaskInfoList.add(edgGlassTaskInfo);
//                log.info("在玻璃信息表中获取玻璃信息{}", edgGlassTaskInfoList);
//            }
//        }
//        Assert.isFalse(CollectionUtils.isEmpty(edgGlassTaskInfoList), "识别玻璃信息未出现在尺寸表中,获取相邻两块玻璃失败");
//        //2、获取卧转立剩余宽度
//        BigStorageDTO sitToUpRemainWidth = bigStorageCageFeedTaskService.querySitToUpRemainWidth(line);
//        Integer remainWidth;
//        Integer glassCount;
//        if (0 == sitToUpRemainWidth.getGlassCount()) {
//            remainWidth = carWidth;
//            glassCount = 0;
//        } else {
//            remainWidth = sitToUpRemainWidth.getWidth();
//            glassCount = sitToUpRemainWidth.getGlassCount();
//        }
//
//        Boolean flag = Boolean.TRUE;
//        //2、获取卧转立
//        Integer widthFirst = Math.max(edgGlassTaskInfoList.get(0).getWidth() / 10, edgGlassTaskInfoList.get(0).getHeight() / 10);
//        Integer heightFirst = Math.min(edgGlassTaskInfoList.get(0).getWidth() / 10, edgGlassTaskInfoList.get(0).getHeight() / 10);
//        if (edgGlassTaskInfoList.size() == 1) {
//            if (remainWidth >= widthFirst) {
//                if (glassCount < inCarMaxSize) {
//                    addFeedTask(glassId, line, Const.BIG_STORAGE_IN_WAIT, widthFirst, heightFirst);
//                } else {
//                    if (glassCount < inCarMaxSize + 1) {
//                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst, heightFirst);
//                    } else {
//                        return Boolean.FALSE;
//                    }
//                }
//            } else {
//                flag = Boolean.FALSE;
//            }
//        } else {
//            Integer widthSecond = Math.max(edgGlassTaskInfoList.get(1).getWidth() / 10, edgGlassTaskInfoList.get(1).getHeight() / 10);
//            Integer heightSecond = Math.min(edgGlassTaskInfoList.get(1).getWidth() / 10, edgGlassTaskInfoList.get(1).getHeight() / 10);
//            if (remainWidth >= widthFirst) {
//                if (remainWidth - widthFirst - glassGap >= widthSecond) {
//                    if (glassCount < inCarMaxSize) {
//                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_WAIT, widthFirst, heightFirst);
//                    } else {
//                        if (glassCount < inCarMaxSize + 1) {
//                            addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst, heightFirst);
//                        } else {
//                            return Boolean.FALSE;
//                        }
//                    }
//                } else {
//                    if (glassCount < inCarMaxSize + 1) {
//                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst, heightFirst);
//                    } else {
//                        return Boolean.FALSE;
//                    }
//                }
//            } else {
//                flag = Boolean.FALSE;
//            }
//        }
//        //向plc发送进片确认
//        if (flag) {
//            //向plc写入确认字
//            PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
//            int returnData = 1;
//            int count = 1;
//            while (returnData != 0) {
//                S7object.getinstance().plccontrol.writeWord(mesAddress, 1);
//
//                if (Const.A10_OUT_TARGET_POSITION.equals(line)) {
//                    returnData = Integer.parseInt(plcParameterObject.getPlcParameter("D04ToMES").getValue());
//                } else {
//                    returnData = Integer.parseInt(plcParameterObject.getPlcParameter("D01ToMES").getValue());
//                }
////                returnData = S7object.getinstance().plccontrol.readWord(mesAddress, 1).get(0);
//                log.info("进卧转立第{}次发送确认字完成,地址为:{},写入的内容为{}", count++, mesAddress, 1);
//            }
//        }
//        //记录无法放下玻璃,后续判断启动
//        return flag;
//    }
//
//    /**
//     * 添加任务信息
//     */
//    private Boolean addFeedTask(String glassId, Integer line, Integer taskType, Integer width, Integer height) {
//        BigStorageCageFeedTask bigStorageCageFeedTask = new BigStorageCageFeedTask();
//        bigStorageCageFeedTask.setGlassId(glassId);
//        bigStorageCageFeedTask.setTaskState(Const.BIG_STORAGE_IN_NEW);
//        bigStorageCageFeedTask.setLine(line);
//        bigStorageCageFeedTask.setTaskType(taskType);
//        bigStorageCageFeedTask.setWidth(width);
//        bigStorageCageFeedTask.setHeight(height);
//        bigStorageCageFeedTask.setCreateTime(new Date());
//        //删除理片笼表拿走/破损数据数据
//        damageService.deleteByGlassId(glassId);
//        Damage damage = new Damage();
//        damage.setGlassId(glassId);
//        damage.setWorkingProcedure("磨边");
//        damage.setLine(line);
//        damage.setType(1);
//        damage.setRemark("进大理片");
//        damageService.insertDamage(damage);
//        return bigStorageCageFeedTaskService.save(bigStorageCageFeedTask);
//    }
//
//    /**
//     * 获取需要启动的线路:两条线都可启动 获取第一片玻璃版图id最小 版序最大的线路
//     *
//     * @return 需要启动的线路
//     */
//    public Integer getStartLine() {
//        List<BigStorageCageFeedTask> taskList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                .inSql(BigStorageCageFeedTask::getId, "select min(id) from big_storage_cage_feed_task where task_state = 2" +
//                        "and (target_slot = 0 or target_slot is null) group by line"));
//        Assert.isFalse(CollectionUtils.isEmpty(taskList), "卧转立两条线都没有玻璃进片任务");
//        Map<String, Integer> taskMap = taskList.stream().collect(Collectors.toMap(BigStorageCageFeedTask::getGlassId,
//                BigStorageCageFeedTask::getLine));
//        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
//                .in(GlassInfo::getGlassId, taskMap.keySet())
//                .orderByAsc(GlassInfo::getTemperingLayoutId)
//                .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence)
//                .last("limit 1"));
//        return taskMap.get(glassInfo.getGlassId());
//    }
//
//    /**
//     * 计算任务表进片线路的目标格子,并启动任务
//     */
//    public boolean computeTargetByLine(Integer line) {
//        //1、获取任务表中的所有玻璃(指定线路且已经进卧转立完成)
//        List<BigStorageCageFeedTask> taskList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                .eq(BigStorageCageFeedTask::getLine, line)
//                .and(e -> e.isNull(BigStorageCageFeedTask::getTargetSlot).or().eq(BigStorageCageFeedTask::getTargetSlot, Const.OUT_TARGET_POSITION_ZERO))
//                .in(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP_ALL)
//                .orderByAsc(BigStorageCageFeedTask::getId));
//        //2、去笼子内查找是否可以继续存放的笼子
//        List<String> glassIds = taskList.stream().map(BigStorageCageFeedTask::getGlassId).collect(Collectors.toList());
//        List<GlassInfo> glassInfos = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>().in(GlassInfo::getGlassId, glassIds));
//        return computeIsTemperingTargetByLine(glassInfos, taskList, line);
//    }
//
//    /**
//     * 是否钢化玻璃进笼目标位置
//     *
//     * @param glassInfos 当条线卧转立所有玻璃
//     * @param taskList   当条线卧转立所有任务
//     * @param line       任务是哪条线
//     */
//    private boolean computeIsTemperingTargetByLine(List<GlassInfo> glassInfos, List<BigStorageCageFeedTask> taskList, Integer line) {
//        //1、将玻璃信息集合转为glassid为key的map
//        Map<String, GlassInfo> glassInfoMap = glassInfos.stream()
//                .collect(Collectors.toMap(GlassInfo::getGlassId, p -> p));
//        for (BigStorageCageFeedTask e : taskList) {
//            GlassInfo info = glassInfoMap.get(e.getGlassId());
//            if (info == null) {
//                continue;
//            }
//            BigStorageCageDetails cageDetails = new BigStorageCageDetails();
//            BeanUtils.copyProperties(info, cageDetails);
//            //2、获取目标格子信息
//            BigStorageDTO bigStorageDTO = bigStorageCageDetailsService.queryTargetSlotByTempering(info);
//            //3、临时更新格子的剩余尺寸:防止相邻玻璃进同一格子造成剩余尺寸不足,玻璃越界的情况,任务完成后再次更新大理片笼表剩余宽度(按照笼内玻璃数量更新大理片笼剩余尺寸)
//            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, bigStorageDTO.getWidth() - Math.max(info.getWidth(), info.getHeight()) - glassGap)
//                    .eq(BigStorageCage::getSlot, bigStorageDTO.getSlot()));
//            //4、更新进片任务表,目标格子及状态(状态改为2 电气扫到自行处理)  遇到问题:无法批量更新,批量更新无法走指定从库
//            e.setTargetSlot(bigStorageDTO.getSlot());
//            bigStorageCageFeedTaskService.updateById(e);
//
//            //5、将进片信息存入大理片笼详情表
//            cageDetails.setSlot(bigStorageDTO.getSlot());
//            cageDetails.setState(Const.GLASS_STATE_NEW);
//            cageDetails.setDeviceId(bigStorageDTO.getDeviceId());
//            cageDetails.setGap(glassGap);
//            bigStorageCageDetailsService.save(cageDetails);
//
//        }
//        sendTaskListToPLC(taskList, line);
//        return Boolean.TRUE;
//    }
//
//    private void sendTaskListToPLC(List<BigStorageCageFeedTask> taskList, Integer line) {
//        log.info("送片任务发送进片玻璃信息");
//        S7control s7control = S7object.getinstance().plccontrol;
//        PlcParameterObject plcMesObject = S7object.getinstance().PlcMesObject;
//        String mesD03Address = plcMesObject.getPlcParameter("MESToD03").getAddress();
//        String mesD05Address = plcMesObject.getPlcParameter("MESToD05").getAddress();
//        String outLine = line.equals(Const.A09_OUT_TARGET_POSITION) ? mesD03Address : mesD05Address;
//        List<String> returnData = new ArrayList<>();
//
//        for (int i = 1; i <= taskList.size(); i++) {
//            s7control.writeWord(plcMesObject.getPlcParameter("StartAddToImport" + i).getAddress(), taskList.get(i - 1).getLine());
//            s7control.writeWord(plcMesObject.getPlcParameter("TargetAddToImport" + i).getAddress(), taskList.get(i - 1).getTargetSlot());
//            returnData.add(taskList.get(i - 1).getGlassId());
//            log.info("向plc发送第{}片玻璃已完成,起始位置是{},目标位置是", i, taskList.get(i - 1).getLine(), taskList.get(i - 1).getTargetSlot());
//        }
////        int returnData = 1;
//        int count = 1;
//
//
//        while (CollectionUtils.isNotEmpty(returnData)) {
//            List<String> glassIds1 = new ArrayList<>();
//            List<String> glassIds2 = new ArrayList<>();
//            s7control.writeWord(outLine, 2);
//            for (int i = 1; i <= 6; i++) {
//                String line1GlassId = plcMesObject.getPlcParameter("D03ID" + i).getValue();
//                if (StringUtils.isNotEmpty(line1GlassId)) {
//                    glassIds1.add(line1GlassId);
//                }
//                String line2GlassId = plcMesObject.getPlcParameter("D05ID" + i).getValue();
//                if (StringUtils.isNotEmpty(line2GlassId)) {
//                    glassIds2.add(line2GlassId);
//                }
//            }
//            if (line.equals(Const.A09_OUT_TARGET_POSITION)) {
////                returnData = Integer.parseInt(plcMesObject.getPlcParameter("D03ToMES").getValue());
//                returnData = s7control.readWord(plcMesObject.getPlcParameter("D03Request").getAddress(), 1).get(0);
//                returnData = glassIds1;
//            } else {
////                returnData = Integer.parseInt(plcMesObject.getPlcParameter("D05ToMES").getValue());
//                returnData = s7control.readWord(plcMesObject.getPlcParameter("D05Request").getAddress(), 1).get(0);
//                returnData = glassIds2;
//            }
////            returnData = s7control.readWord(outLine, 1).get(0);
//            log.info("已向plc第{}次发送进片任务确认,地址为:{},写入的内容为{},读到的请求为{}", count++, outLine, 2,returnData);
//            log.info("已向plc第{}次发送进片任务确认,地址为:{},写入的内容为{},读到的请求为{}", count++, outLine, 2, returnData);
//        }
    }
    /**
     * 出片一次仅生成一车玻璃
     *
     * @param list
     * @param isTempering
     * @param mesToPLCAddress
     * @param <T>
     * @return
     */
    private <T extends BigStorageCageBaseInfo> Boolean computeOutGlassInfo(List<T> list, Boolean isTempering, String mesToPLCAddress) {
        //任务数据  获取车子存放玻璃最大数量  玻璃间隔
        List<BigStorageCageOutTask> bigStorageCageOutTaskList = new ArrayList<>();
        //打车剩余尺寸
        Integer remainWidth = carWidth;
        int maxX = 0;
        for (T e : list) {
            if (bigStorageCageOutTaskList.size() >= outCarMaxSize || Math.max((int) e.getWidth(), (int) e.getHeight()) > remainWidth) {
                break;
            }
            remainWidth = remainWidth - Math.max((int) e.getWidth(), (int) e.getHeight()) - glassGap;
            if (isTempering) {
                int minLength = Math.min((int) e.getWidth(), (int) e.getHeight());
                if (maxX + minLength <= xMaxSize) {
                    bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
                            e.getWidth() * 10, e.getHeight() * 10, 0, 0, 1, new Date()));
//                    maxX = Math.max(maxX, e.getXCoordinate());
                } else {
                    break;
                }
            } else {
                bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.ARTIFICIAL_OUT_TARGET_POSITION,
                        e.getWidth() * 10, e.getHeight(), 0, 0, 1, new Date()));
            }
        }
        Assert.isFalse(CollectionUtils.isEmpty(bigStorageCageOutTaskList), "未获取出片数据,结束出片任务");
        log.info("获取出片任务数据{}条,执行保存", bigStorageCageOutTaskList.size());
        bigStorageCageOutTaskService.saveBatch(bigStorageCageOutTaskList);
        List<String> glassIds = bigStorageCageOutTaskList.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
        log.info("将出片玻璃{}玻璃状态改为已出片", glassIds);
        bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
                .set(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT_ING)
                .in(BigStorageCageDetails::getGlassId, glassIds));
        int returnData = 0;
        int count = 1;
        while (returnData == 0) {
            S7object.getinstance().plccontrol.writeWord(mesToPLCAddress, 1);
            returnData = S7object.getinstance().plccontrol.readWord(mesToPLCAddress, 1).get(0);
            log.info("已向plc第{}次发送出片任务确认,地址为:{},写入的内容为{}", count++, mesToPLCAddress, returnData);
        }
        return Boolean.TRUE;
    }
    /**
     * 出片一次生成一炉玻璃
     *
     * @param list
     * @param isTempering
     * @param mesToPLCAddress
     * @param <T>
     * @return
     */
    public <T extends BigStorageCageBaseInfo> Boolean computeOutMoreGlassInfo(List<T> list, Boolean isTempering, String mesToPLCAddress) {
        //任务数据  获取车子存放玻璃最大数量  玻璃间隔
        List<BigStorageCageOutTask> bigStorageCageOutTaskList = new ArrayList<>();
        //打车剩余尺寸
        Integer remainWidth = carWidth;
        int trainNumber = 1;
        int serialNumber = 1;
        int maxX = 0;
        for (T e : list) {
            int maxLength = Math.max((int) e.getWidth(), (int) e.getHeight());
            if (serialNumber > outCarMaxSize || maxLength > remainWidth) {
                remainWidth = carWidth;
                trainNumber = trainNumber + 1;
                serialNumber = 1;
                maxX = 0;
            }
            remainWidth = remainWidth - maxLength - glassGap;
            if (isTempering) {
                int minLength = Math.min((int) e.getWidth(), (int) e.getHeight());
                if (maxX + minLength <= xMaxSize) {
                    bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
                            e.getWidth() * 10, e.getHeight() * 10, trainNumber, serialNumber++, 1, new Date()));
//                    maxX = Math.max(maxX, e.getXCoordinate());
                } else {
                    remainWidth = carWidth - maxLength - glassGap;
                    trainNumber = trainNumber + 1;
                    serialNumber = 1;
//                    maxX = e.getXCoordinate();
                    bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
                            e.getWidth() * 10, e.getHeight(), trainNumber, serialNumber++, 1, new Date()));
                }
            } else {
                bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.ARTIFICIAL_OUT_TARGET_POSITION,
                        e.getWidth() * 10, e.getHeight(), trainNumber, serialNumber++, 1, new Date()));
            }
        }
        Assert.isFalse(CollectionUtils.isEmpty(bigStorageCageOutTaskList), "未获取出片数据,结束出片任务");
        log.info("获取出片任务数据{}条,执行保存", bigStorageCageOutTaskList.size());
        for (BigStorageCageOutTask bigStorageCageOutTask : bigStorageCageOutTaskList
        ) {
            bigStorageCageOutTaskService.save(bigStorageCageOutTask);
        }
////        while (returnData != 0) {
////            s7control.writeWord(outLine, 2);
////            if (line.equals(Const.A09_OUT_TARGET_POSITION)) {
//////                returnData = Integer.parseInt(plcMesObject.getPlcParameter("D03ToMES").getValue());
////                returnData = s7control.readWord(plcMesObject.getPlcParameter("D03Request").getAddress(), 1).get(0);
////            } else {
//////                returnData = Integer.parseInt(plcMesObject.getPlcParameter("D05ToMES").getValue());
////                returnData = s7control.readWord(plcMesObject.getPlcParameter("D05Request").getAddress(), 1).get(0);
////            }
//////            returnData = s7control.readWord(outLine, 1).get(0);
////            log.info("已向plc第{}次发送进片任务确认,地址为:{},写入的内容为{},读到的请求为{}", count++, outLine, 2,returnData);
////        }
//    }
//
//    /**
//     * 出片一次仅生成一车玻璃
//     *
//     * @param list
//     * @param isTempering
//     * @param mesToPLCAddress
//     * @param <T>
//     * @return
//     */
//    private <T extends BigStorageCageBaseInfo> Boolean computeOutGlassInfo(List<T> list, Boolean isTempering, String mesToPLCAddress) {
//        //任务数据  获取车子存放玻璃最大数量  玻璃间隔
//        List<BigStorageCageOutTask> bigStorageCageOutTaskList = new ArrayList<>();
//        //打车剩余尺寸
//        Integer remainWidth = carWidth;
//        int maxX = 0;
//        for (T e : list) {
//            if (bigStorageCageOutTaskList.size() >= outCarMaxSize || Math.max((int) e.getWidth(), (int) e.getHeight()) > remainWidth) {
//                break;
//            }
//            remainWidth = remainWidth - Math.max((int) e.getWidth(), (int) e.getHeight()) - glassGap;
//            if (isTempering) {
//                int minLength = Math.min((int) e.getWidth(), (int) e.getHeight());
//                if (maxX + minLength <= xMaxSize) {
//                    bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
//                            e.getWidth() * 10, e.getHeight() * 10, 0, 0, 1, new Date()));
////                    maxX = Math.max(maxX, e.getXCoordinate());
//                } else {
//                    break;
//                }
//
//            } else {
//                bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.ARTIFICIAL_OUT_TARGET_POSITION,
//                        e.getWidth() * 10, e.getHeight(), 0, 0, 1, new Date()));
//            }
//        }
//        Assert.isFalse(CollectionUtils.isEmpty(bigStorageCageOutTaskList), "未获取出片数据,结束出片任务");
//        log.info("获取出片任务数据{}条,执行保存", bigStorageCageOutTaskList.size());
//        bigStorageCageOutTaskService.saveBatch(bigStorageCageOutTaskList);
        List<String> glassIds = bigStorageCageOutTaskList.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
        log.info("将出片玻璃{}玻璃状态改为已出片", glassIds);
        bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
                .set(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT_ING)
                .in(BigStorageCageDetails::getGlassId, glassIds)
                .ne(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT));
//        List<String> glassIds = bigStorageCageOutTaskList.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
//        log.info("将出片玻璃{}玻璃状态改为已出片", glassIds);
//        bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
//                .set(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT_ING)
//                .in(BigStorageCageDetails::getGlassId, glassIds));
//        int returnData = 0;
//        int count = 1;
//        while (returnData == 0) {
@@ -1120,43 +1052,111 @@
//            returnData = S7object.getinstance().plccontrol.readWord(mesToPLCAddress, 1).get(0);
//            log.info("已向plc第{}次发送出片任务确认,地址为:{},写入的内容为{}", count++, mesToPLCAddress, returnData);
//        }
        return Boolean.TRUE;
    }
    public void updateSlotRemainBySlots(List<Integer> slotList) {
        //获取格子内所有的玻璃信息
        List<BigStorageCageDetails> inSlotGlassList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                .in(BigStorageCageDetails::getSlot, slotList).in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
        Map<Integer, Double> slotRemainMap = new HashMap<>();
        //是否存在有格子非空的玻璃
        if (CollectionUtils.isNotEmpty(inSlotGlassList)) {
            //存在  将格子内的玻璃分别进行更新
            slotRemainMap = inSlotGlassList.stream()
                    .collect(Collectors.groupingBy(BigStorageCageDetails::getSlot, Collectors.summingDouble(item -> Math.max(item.getWidth(), item.getHeight()) + glassGap)));
            slotRemainMap.forEach((e, v) -> {
                double remainWidth = slotWidth - v >= 0 ? slotWidth - v : 0;
                bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, remainWidth)
                        .eq(BigStorageCage::getSlot, e));
            });
        }
        //过滤不存在玻璃的格子 将宽度重置为原始宽度5000
        Set<Integer> remainSlotList = slotRemainMap.keySet();
        slotList.removeAll(remainSlotList);
        if (CollectionUtils.isNotEmpty(slotList)) {
            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, slotWidth)
                    .in(BigStorageCage::getSlot, slotList));
        }
    }
    public Boolean computeIsRun(int line, String glassId) {
        //获取卧转立剩余宽度
        BigStorageDTO sitToUpRemainWidth = bigStorageCageFeedTaskService.querySitToUpRemainWidth(line);
        if (sitToUpRemainWidth.getGlassCount() == 0) {
            return Boolean.FALSE;
        }
        //获取玻璃信息
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
        return sitToUpRemainWidth.getWidth() < Math.max(glassInfo.getWidth(), glassInfo.getHeight());
    }
}
//        return Boolean.TRUE;
//    }
//
//    /**
//     * 出片一次生成一炉玻璃
//     *
//     * @param list
//     * @param isTempering
//     * @param mesToPLCAddress
//     * @param <T>
//     * @return
//     */
//    public <T extends BigStorageCageBaseInfo> Boolean computeOutMoreGlassInfo(List<T> list, Boolean isTempering, String mesToPLCAddress) {
//        //任务数据  获取车子存放玻璃最大数量  玻璃间隔
//        List<BigStorageCageOutTask> bigStorageCageOutTaskList = new ArrayList<>();
//        //打车剩余尺寸
//        Integer remainWidth = carWidth;
//        int trainNumber = 1;
//        int serialNumber = 1;
//        int maxX = 0;
//        for (T e : list) {
//            int maxLength = Math.max((int) e.getWidth(), (int) e.getHeight());
//            if (serialNumber > outCarMaxSize || maxLength > remainWidth) {
//                remainWidth = carWidth;
//                trainNumber = trainNumber + 1;
//                serialNumber = 1;
//                maxX = 0;
//            }
//            remainWidth = remainWidth - maxLength - glassGap;
//            if (isTempering) {
//                int minLength = Math.min((int) e.getWidth(), (int) e.getHeight());
//                if (maxX + minLength <= xMaxSize) {
//                    bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
//                            e.getWidth() * 10, e.getHeight() * 10, trainNumber, serialNumber++, 1, new Date()));
////                    maxX = Math.max(maxX, e.getXCoordinate());
//                } else {
//                    remainWidth = carWidth - maxLength - glassGap;
//                    trainNumber = trainNumber + 1;
//                    serialNumber = 1;
////                    maxX = e.getXCoordinate();
//                    bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
//                            e.getWidth() * 10, e.getHeight(), trainNumber, serialNumber++, 1, new Date()));
//                }
//            } else {
//                bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.ARTIFICIAL_OUT_TARGET_POSITION,
//                        e.getWidth() * 10, e.getHeight(), trainNumber, serialNumber++, 1, new Date()));
//            }
//        }
//        Assert.isFalse(CollectionUtils.isEmpty(bigStorageCageOutTaskList), "未获取出片数据,结束出片任务");
//        log.info("获取出片任务数据{}条,执行保存", bigStorageCageOutTaskList.size());
//        for (BigStorageCageOutTask bigStorageCageOutTask : bigStorageCageOutTaskList
//        ) {
//            bigStorageCageOutTaskService.save(bigStorageCageOutTask);
//        }
////        bigStorageCageOutTaskService.saveBatch(bigStorageCageOutTaskList);
//        List<String> glassIds = bigStorageCageOutTaskList.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
//        log.info("将出片玻璃{}玻璃状态改为已出片", glassIds);
//        bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
//                .set(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT_ING)
//                .in(BigStorageCageDetails::getGlassId, glassIds)
//                .ne(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT));
////        int returnData = 0;
////        int count = 1;
////        while (returnData == 0) {
////            S7object.getinstance().plccontrol.writeWord(mesToPLCAddress, 1);
////            returnData = S7object.getinstance().plccontrol.readWord(mesToPLCAddress, 1).get(0);
////            log.info("已向plc第{}次发送出片任务确认,地址为:{},写入的内容为{}", count++, mesToPLCAddress, returnData);
////        }
//        return Boolean.TRUE;
//    }
//
//    public void updateSlotRemainBySlots(List<Integer> slotList) {
//        //获取格子内所有的玻璃信息
//        List<BigStorageCageDetails> inSlotGlassList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
//                .in(BigStorageCageDetails::getSlot, slotList).in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
//        Map<Integer, Double> slotRemainMap = new HashMap<>();
//        //是否存在有格子非空的玻璃
//        if (CollectionUtils.isNotEmpty(inSlotGlassList)) {
//            //存在  将格子内的玻璃分别进行更新
//            slotRemainMap = inSlotGlassList.stream()
//                    .collect(Collectors.groupingBy(BigStorageCageDetails::getSlot, Collectors.summingDouble(item -> Math.max(item.getWidth(), item.getHeight()) + glassGap)));
//            slotRemainMap.forEach((e, v) -> {
//                double remainWidth = slotWidth - v >= 0 ? slotWidth - v : 0;
//                bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, remainWidth)
//                        .eq(BigStorageCage::getSlot, e));
//            });
//        }
//        //过滤不存在玻璃的格子 将宽度重置为原始宽度5000
//        Set<Integer> remainSlotList = slotRemainMap.keySet();
//        slotList.removeAll(remainSlotList);
//        if (CollectionUtils.isNotEmpty(slotList)) {
//            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, slotWidth)
//                    .in(BigStorageCage::getSlot, slotList));
//        }
//    }
//
//    public Boolean computeIsRun(int line, String glassId) {
//        //获取卧转立剩余宽度
//        BigStorageDTO sitToUpRemainWidth = bigStorageCageFeedTaskService.querySitToUpRemainWidth(line);
//        if (sitToUpRemainWidth.getGlassCount() == 0) {
//            return Boolean.FALSE;
//        }
//        //获取玻璃信息
//        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
//        return sitToUpRemainWidth.getWidth() < Math.max(glassInfo.getWidth(), glassInfo.getHeight());
//    }
//
//}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/job/opccallback/BigStorageStartCallback.java
@@ -1,823 +1,823 @@
package com.mes.job.opccallback;
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.kangaroohy.milo.runner.subscription.SubscriptionCallback;
import com.mes.base.entity.BigStorageCageBaseInfo;
import com.mes.bigstorage.entity.BigStorageCage;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.dto.BigStorageDTO;
import com.mes.bigstorage.entity.dto.SlotSequenceDTO;
import com.mes.bigstorage.entity.dto.TemperingLayoutDTO;
import com.mes.bigstorage.service.BigStorageCageDetailsService;
import com.mes.bigstorage.service.BigStorageCageService;
import com.mes.bigstoragetask.entity.BigStorageCageFeedTask;
import com.mes.bigstoragetask.entity.BigStorageCageOutTask;
import com.mes.bigstoragetask.service.BigStorageCageFeedTaskService;
import com.mes.bigstoragetask.service.BigStorageCageOutTaskService;
import com.mes.common.S7object;
import com.mes.common.config.Const;
import com.mes.damage.entity.Damage;
import com.mes.damage.service.DamageService;
import com.mes.device.PlcParameterObject;
import com.mes.edgglasstask.entity.EdgGlassTaskInfo;
import com.mes.edgglasstask.service.EdgGlassTaskInfoService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.service.TemperingGlassInfoService;
import com.mes.tools.S7control;
import com.mes.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * @Author : zhoush
 * @Date: 2024/10/28 21:22
 * @Description:
 */
@Service
@Slf4j
public class BigStorageStartCallback implements SubscriptionCallback {
    @Resource
    private BigStorageCageService bigStorageCageService;
    @Resource
    private BigStorageCageDetailsService bigStorageCageDetailsService;
    @Resource
    private GlassInfoService glassInfoService;
    @Resource
    private BigStorageCageFeedTaskService bigStorageCageFeedTaskService;
    @Resource
    private BigStorageCageOutTaskService bigStorageCageOutTaskService;
    @Resource
    private EdgGlassTaskInfoService edgGlassTaskInfoService;
    @Resource
    private TemperingGlassInfoService temperingGlassInfoService;
    @Resource
    private DamageService damageService;
    @Resource
    private RedisUtil redisUtil;
    private static final String REQUEST_WORD = "1";
    @Value("${mes.sequence.order}")
    private boolean sequenceOrder;
    @Value("${mes.carWidth}")
    private Integer carWidth;
    @Value("${mes.slotWidth}")
    private Integer slotWidth;
    @Value("${mes.inCarMaxSize}")
    private Integer inCarMaxSize;
    @Value("${mes.outCarMaxSize}")
    private Integer outCarMaxSize;
    @Value("${mes.glassGap}")
    private Integer glassGap;
    @Value("${mes.xMaxSize}")
    private Integer xMaxSize;
    private String d01GlassId = "";
    private String d04GlassId = "";
    @Override
    public void onSubscribe(String identifier, Object value) {
        //todo:获取任务列表
        String tableName = "";
        //todo:按照表明获取伍信息
        List<BigStorageCageFeedTask> tasks = new ArrayList<>();
        if (CollectionUtils.isEmpty(tasks)) {
            log.info("卧转立上没有玻璃");
            //todo 与卧转立交互,将请求字大车请求变为0,确保订阅任务可再次执行
            return;
        }
        List<String> glassIds = tasks.stream().map(BigStorageCageFeedTask::getGlassId).collect(Collectors.toList());
        List<GlassInfo> glassInfos = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>().in(GlassInfo::getGlassId, glassIds));
        computeIsTemperingTargetByLine(glassInfos, tasks);
    }
    //    @Scheduled(fixedDelay = 10000)
    public void plcToHomeEdgOutTask() {
        String mesToPLCAddress = "";
        List<BigStorageCageOutTask> outingList = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
                .eq(BigStorageCageOutTask::getTaskState, Const.BIG_STORAGE_OUT_NEW));
        if (CollectionUtils.isNotEmpty(outingList)) {
            log.info("有正在执行出片的任务,结束当前出片线程");
            return;
        }
        if (redisUtil.getCacheObject("temperingSwitch")) {
            //是否有正在钢化的玻璃
            List<TemperingGlassInfo> temperingGlassInfoList = temperingGlassInfoService.selectJoinList(TemperingGlassInfo.class, new MPJLambdaWrapper<TemperingGlassInfo>()
                    .selectAll(TemperingGlassInfo.class)
                    .leftJoin(BigStorageCageOutTask.class, BigStorageCageOutTask::getGlassId, TemperingGlassInfo::getGlassId)
                    .eq(TemperingGlassInfo::getState, Const.TEMPERING_NEW)
                    .isNull(BigStorageCageOutTask::getGlassId)
                    .orderBy(Boolean.TRUE, sequenceOrder, TemperingGlassInfo::getTemperingFeedSequence));
            if (CollectionUtils.isNotEmpty(temperingGlassInfoList)) {
                log.info("有正在出片的钢化任务");
                computeOutMoreGlassInfo(temperingGlassInfoList, Boolean.TRUE, mesToPLCAddress);
                return;
            }
            //是否有人工下片任务   有直接出
//            List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
//                    .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL).orderByDesc(BigStorageCageDetails::getWidth));
            List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                    .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL)
                    .orderByAsc(BigStorageCageDetails::getSlot)
                    .orderByDesc(BigStorageCageDetails::getId));
            if (CollectionUtils.isNotEmpty(artificialList)) {
                computeOutMoreGlassInfo(artificialList, Boolean.FALSE, mesToPLCAddress);
                return;
            }
            //钢化优先:获取理片笼  玻璃小片  破损表 数量   判断笼内版图是否到齐
            List<TemperingLayoutDTO> temperingLayoutDTOList = bigStorageCageDetailsService.temperingIsAll();
            if (CollectionUtils.isNotEmpty(temperingLayoutDTOList)) {
                //玻璃到齐包括已出片的
                //到齐,将玻璃小片数据存入钢化小片表,逻辑生成出片任务  结束
                for (TemperingLayoutDTO item : temperingLayoutDTOList) {
                    if (redisUtil.getCacheObject("temperingengineerId").equals(item.getEngineerId())) {
                        List<TemperingGlassInfo> temperingGlassInfos = glassInfoService.selectJoinList(TemperingGlassInfo.class, JoinWrappers.lambda(GlassInfo.class)
                                .selectAll(GlassInfo.class)
                                .select("-1 as state")
                                .selectAs(BigStorageCageDetails::getSlot, TemperingGlassInfo::getSlot)
                                .innerJoin(BigStorageCageDetails.class, BigStorageCageDetails::getGlassId, GlassInfo::getGlassId)
                                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                                .eq(GlassInfo::getTemperingLayoutId, item.getTemperingLayoutId())
                                .eq(GlassInfo::getEngineerId, item.getEngineerId())
                                .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence));
                        if (CollectionUtils.isNotEmpty(temperingGlassInfos)) {
                            temperingGlassInfoService.saveBatch(temperingGlassInfos);
                            computeOutMoreGlassInfo(temperingGlassInfoList, Boolean.TRUE, mesToPLCAddress);
                            return;
                        }
                    }
                }
            }
        }
        //执行内部调度任务
        List<TemperingLayoutDTO> temperingOccupySlotList = bigStorageCageDetailsService.queryTemperingOccupySlot();
        if (CollectionUtils.isNotEmpty(temperingOccupySlotList)) {
            loop:
            for (TemperingLayoutDTO temperingOccupySlot : temperingOccupySlotList) {
                List<SlotSequenceDTO> slotSequenceList = bigStorageCageDetailsService.queryGlassMaxAndMin(temperingOccupySlot.getEngineerId(), temperingOccupySlot.getTemperingLayoutId());
                for (int i = 0; i < slotSequenceList.size() - 1; i++) {
                    SlotSequenceDTO first = slotSequenceList.get(i);
                    SlotSequenceDTO second = slotSequenceList.get(i + 1);
                    int slotWidth = carWidth - first.getRemainWidth() - glassGap;
                    if (first.getMinSequence() == second.getMaxSequence() + 1
                            && second.getRemainWidth() > slotWidth && slotWidth >= 0) {
                        List<BigStorageCageDetails> list = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                                .eq(BigStorageCageDetails::getSlot, first.getSlot()).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                                .orderBy(Boolean.TRUE, sequenceOrder, BigStorageCageDetails::getTemperingFeedSequence));
                        if (CollectionUtils.isNotEmpty(list)) {
                            List<BigStorageCageOutTask> outTasks = new ArrayList<>();
                            int serialNumber = 1;
                            for (BigStorageCageDetails item : list) {
                                outTasks.add(new BigStorageCageOutTask(item.getGlassId(), first.getSlot(), second.getSlot(),
                                        item.getWidth() * 10, item.getHeight() * 10, 1, serialNumber++, Const.BIG_STORAGE_OUT_NEW, new Date()));
                            }
                            //新增调度任务
                            bigStorageCageOutTaskService.saveBatch(outTasks);
                            //更新理片笼详情表调度的后的玻璃位置信息:生成任务后先将玻璃格子位置进行调整,玻璃状态改为调度中,新增调度完成任务,处理调度完成后玻璃状态改为100.
                            List<String> glassList = list.stream().map(BigStorageCageDetails::getGlassId).collect(Collectors.toList());
                            bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>().set(BigStorageCageDetails::getState, Const.GLASS_STATE_SCHEDULE_ING)
                                    .set(BigStorageCageBaseInfo::getSlot, second.getSlot()).in(BigStorageCageDetails::getGlassId, glassList));
                            //两次更新笼子的剩余尺寸:第一次防止有玻璃继续进调度后的笼子,第二次更新:计算格子的实际尺寸
                            // 仅更新调度后的格子信息:起始格子完成后更新:防止调度出片过程中有新玻璃进入,
//                            todo:临时解决报错
//                            updateSlotRemainBySlots(Arrays.asList(second.getSlot()));
                            break loop;
                        }
                    }
                }
            }
//            //向plc写入确认字
//            int returnData = 0;
//            int count = 1;
//            while (returnData == 0) {
//                log.info("已向plc第{}次送协议", count);
//                S7object.getinstance().plccontrol.writeWord(mesToPLCAddress, 1);
//                returnData = S7object.getinstance().plccontrol.readWord(mesToPLCAddress, 1).get(0);
//                log.info("已向plc第{}次发送出片任务确认,地址为:{},写入的内容为{}", count++, mesToPLCAddress, returnData);
//package com.mes.job.opccallback;
//
//import cn.hutool.core.lang.Assert;
//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
//import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
//import com.github.yulichang.toolkit.JoinWrappers;
//import com.github.yulichang.wrapper.MPJLambdaWrapper;
//import com.kangaroohy.milo.runner.subscription.SubscriptionCallback;
//import com.mes.base.entity.BigStorageCageBaseInfo;
//import com.mes.bigstorage.entity.BigStorageCage;
//import com.mes.bigstorage.entity.BigStorageCageDetails;
//import com.mes.bigstorage.entity.dto.BigStorageDTO;
//import com.mes.bigstorage.entity.dto.SlotSequenceDTO;
//import com.mes.bigstorage.entity.dto.TemperingLayoutDTO;
//import com.mes.bigstorage.service.BigStorageCageDetailsService;
//import com.mes.bigstorage.service.BigStorageCageService;
//import com.mes.bigstoragetask.entity.BigStorageCageFeedTask;
//import com.mes.bigstoragetask.entity.BigStorageCageOutTask;
//import com.mes.bigstoragetask.service.BigStorageCageFeedTaskService;
//import com.mes.bigstoragetask.service.BigStorageCageOutTaskService;
//import com.mes.common.S7object;
//import com.mes.common.config.Const;
//import com.mes.damage.entity.Damage;
//import com.mes.damage.service.DamageService;
//import com.mes.device.PlcParameterObject;
//import com.mes.edgglasstask.entity.EdgGlassTaskInfo;
//import com.mes.edgglasstask.service.EdgGlassTaskInfoService;
//import com.mes.glassinfo.entity.GlassInfo;
//import com.mes.glassinfo.service.GlassInfoService;
//import com.mes.temperingglass.entity.TemperingGlassInfo;
//import com.mes.temperingglass.service.TemperingGlassInfoService;
//import com.mes.tools.S7control;
//import com.mes.utils.RedisUtil;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.lang.StringUtils;
//import org.springframework.beans.BeanUtils;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.stereotype.Service;
//
//import javax.annotation.Resource;
//import java.util.ArrayList;
//import java.util.Date;
//import java.util.List;
//import java.util.Map;
//import java.util.stream.Collectors;
//
///**
// * @Author : zhoush
// * @Date: 2024/10/28 21:22
// * @Description:
// */
//@Service
//@Slf4j
//public class BigStorageStartCallback implements SubscriptionCallback {
//
//
//    @Resource
//    private BigStorageCageService bigStorageCageService;
//    @Resource
//    private BigStorageCageDetailsService bigStorageCageDetailsService;
//    @Resource
//    private GlassInfoService glassInfoService;
//    @Resource
//    private BigStorageCageFeedTaskService bigStorageCageFeedTaskService;
//    @Resource
//    private BigStorageCageOutTaskService bigStorageCageOutTaskService;
//    @Resource
//    private EdgGlassTaskInfoService edgGlassTaskInfoService;
//    @Resource
//    private TemperingGlassInfoService temperingGlassInfoService;
//    @Resource
//    private DamageService damageService;
//
//    @Resource
//    private RedisUtil redisUtil;
//
//    private static final String REQUEST_WORD = "1";
//
//    @Value("${mes.sequence.order}")
//    private boolean sequenceOrder;
//
//    @Value("${mes.carWidth}")
//    private Integer carWidth;
//
//    @Value("${mes.slotWidth}")
//    private Integer slotWidth;
//
//    @Value("${mes.inCarMaxSize}")
//    private Integer inCarMaxSize;
//
//    @Value("${mes.outCarMaxSize}")
//    private Integer outCarMaxSize;
//
//    @Value("${mes.glassGap}")
//    private Integer glassGap;
//
//    @Value("${mes.xMaxSize}")
//    private Integer xMaxSize;
//
//
//    private String d01GlassId = "";
//    private String d04GlassId = "";
//
//    @Override
//    public void onSubscribe(String identifier, Object value) {
//        //todo:获取任务列表
//        String tableName = "";
//        //todo:按照表明获取伍信息
//        List<BigStorageCageFeedTask> tasks = new ArrayList<>();
//        if (CollectionUtils.isEmpty(tasks)) {
//            log.info("卧转立上没有玻璃");
//            //todo 与卧转立交互,将请求字大车请求变为0,确保订阅任务可再次执行
//            return;
//        }
//        List<String> glassIds = tasks.stream().map(BigStorageCageFeedTask::getGlassId).collect(Collectors.toList());
//        List<GlassInfo> glassInfos = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>().in(GlassInfo::getGlassId, glassIds));
//        computeIsTemperingTargetByLine(glassInfos, tasks);
//    }
//
//
//    //    @Scheduled(fixedDelay = 10000)
//    public void plcToHomeEdgOutTask() {
//        String mesToPLCAddress = "";
//        List<BigStorageCageOutTask> outingList = bigStorageCageOutTaskService.list(new LambdaQueryWrapper<BigStorageCageOutTask>()
//                .eq(BigStorageCageOutTask::getTaskState, Const.BIG_STORAGE_OUT_NEW));
//        if (CollectionUtils.isNotEmpty(outingList)) {
//            log.info("有正在执行出片的任务,结束当前出片线程");
//            return;
//        }
//        if (redisUtil.getCacheObject("temperingSwitch")) {
//            //是否有正在钢化的玻璃
//            List<TemperingGlassInfo> temperingGlassInfoList = temperingGlassInfoService.selectJoinList(TemperingGlassInfo.class, new MPJLambdaWrapper<TemperingGlassInfo>()
//                    .selectAll(TemperingGlassInfo.class)
//                    .leftJoin(BigStorageCageOutTask.class, BigStorageCageOutTask::getGlassId, TemperingGlassInfo::getGlassId)
//                    .eq(TemperingGlassInfo::getState, Const.TEMPERING_NEW)
//                    .isNull(BigStorageCageOutTask::getGlassId)
//                    .orderBy(Boolean.TRUE, sequenceOrder, TemperingGlassInfo::getTemperingFeedSequence));
//            if (CollectionUtils.isNotEmpty(temperingGlassInfoList)) {
//                log.info("有正在出片的钢化任务");
//                computeOutMoreGlassInfo(temperingGlassInfoList, Boolean.TRUE, mesToPLCAddress);
//                return;
//            }
            return;
        }
    }
    /**
     * 确认字清空
     */
//    @Scheduled(fixedDelay = 300)
    public void confirmClear() {
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        String d01ToMES = plcParameterObject.getPlcParameter("D01ToMES").getValue();
        String d04ToMES = plcParameterObject.getPlcParameter("D04ToMES").getValue();
        String mesD01Address = plcParameterObject.getPlcParameter("MESToD01").getAddress();
        String mesD04Address = plcParameterObject.getPlcParameter("MESToD04").getAddress();
        String d03ToMES = plcParameterObject.getPlcParameter("D03ToMES").getValue();
        String d05ToMES = plcParameterObject.getPlcParameter("D05ToMES").getValue();
        String mesD03Address = plcParameterObject.getPlcParameter("MESToD03").getAddress();
        String mesD05Address = plcParameterObject.getPlcParameter("MESToD05").getAddress();
        if (!REQUEST_WORD.equals(d01ToMES)) {
            S7object.getinstance().plccontrol.writeWord(mesD01Address, 0);
        }
        if (!REQUEST_WORD.equals(d04ToMES)) {
            S7object.getinstance().plccontrol.writeWord(mesD04Address, 0);
        }
        if (!REQUEST_WORD.equals(d03ToMES)) {
            S7object.getinstance().plccontrol.writeWord(mesD03Address, 0);
        }
        if (!REQUEST_WORD.equals(d05ToMES)) {
            S7object.getinstance().plccontrol.writeWord(mesD05Address, 0);
        }
    }
    /**
     * 进片状态修改
     */
//    @Scheduled(fixedDelay = 300)
    public void feedStatusUpdate() {
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        List<String> glassIds1 = new ArrayList<>();
        List<String> glassIds2 = new ArrayList<>();
        for (int i = 1; i <= 6; i++) {
            String line1GlassId = plcParameterObject.getPlcParameter("D03ID" + i).getValue();
            if (StringUtils.isNotEmpty(line1GlassId)) {
                glassIds1.add(line1GlassId);
            }
            String line2GlassId = plcParameterObject.getPlcParameter("D05ID" + i).getValue();
            if (StringUtils.isNotEmpty(line2GlassId)) {
                glassIds2.add(line2GlassId);
            }
        }
        List<BigStorageCageFeedTask> bigStorageCageFeedTasks1 = bigStorageCageFeedTaskService.list(
                new LambdaQueryWrapper<BigStorageCageFeedTask>()
                        .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_NEW)
                        .eq(BigStorageCageFeedTask::getLine, Const.A09_OUT_TARGET_POSITION)
        );
        List<BigStorageCageFeedTask> bigStorageCageFeedTasks2 = bigStorageCageFeedTaskService.list(
                new LambdaQueryWrapper<BigStorageCageFeedTask>()
                        .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_NEW)
                        .eq(BigStorageCageFeedTask::getLine, Const.A10_OUT_TARGET_POSITION)
        );
        if (CollectionUtils.isNotEmpty(bigStorageCageFeedTasks1) && CollectionUtils.isNotEmpty(glassIds1)) {
            List<String> matchingIds1 = bigStorageCageFeedTasks1.stream()
                    .map(BigStorageCageFeedTask::getGlassId)
                    .filter(glassIds1::contains)
                    .distinct()
                    .collect(Collectors.toList());
            bigStorageCageFeedTaskService.update(
                    new LambdaUpdateWrapper<BigStorageCageFeedTask>()
                            .in(BigStorageCageFeedTask::getGlassId, matchingIds1)
                            .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
                            .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
            );
        }
        if (CollectionUtils.isNotEmpty(bigStorageCageFeedTasks2) && CollectionUtils.isNotEmpty(glassIds2)) {
            List<String> matchingIds2 = bigStorageCageFeedTasks2.stream()
                    .map(BigStorageCageFeedTask::getGlassId)
                    .filter(glassIds2::contains)
                    .distinct()
                    .collect(Collectors.toList());
            bigStorageCageFeedTaskService.update(
                    new LambdaUpdateWrapper<BigStorageCageFeedTask>()
                            .in(BigStorageCageFeedTask::getGlassId, matchingIds2)
                            .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
                            .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
            );
        }
        if (CollectionUtils.isEmpty(glassIds1)) {
            bigStorageCageFeedTaskService.update(
                    new LambdaUpdateWrapper<BigStorageCageFeedTask>()
                            .eq(BigStorageCageFeedTask::getLine, Const.A09_OUT_TARGET_POSITION)
                            .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
                            .gt(BigStorageCageFeedTask::getTargetSlot, 0)
                            .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
                            .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_CAR)
            );
        }
        if (CollectionUtils.isEmpty(glassIds2)) {
            bigStorageCageFeedTaskService.update(
                    new LambdaUpdateWrapper<BigStorageCageFeedTask>()
                            .eq(BigStorageCageFeedTask::getLine, Const.A10_OUT_TARGET_POSITION)
                            .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
                            .gt(BigStorageCageFeedTask::getTargetSlot, 0)
                            .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
                            .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_CAR)
            );
        }
    }
    /**
     * 按照玻璃id判断玻璃状态及卧转立是否可直接启动
     */
    public Boolean judgeGlassTypeStatus(String glassId, Integer line, String mesAddress) {
        //判断此玻璃是在笼内或已生成进片任务
        BigStorageCageFeedTask bigStorageCageFeedTask = bigStorageCageFeedTaskService.getOne(
                new LambdaQueryWrapper<BigStorageCageFeedTask>()
                        .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
                        .eq(BigStorageCageFeedTask::getGlassId, glassId)
        );
        BigStorageCageDetails bigStorageCageDetails = bigStorageCageDetailsService.getOne(
                new LambdaQueryWrapper<BigStorageCageDetails>()
                        .eq(BigStorageCageDetails::getGlassId, glassId)
                        .ne(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
        );
        if (bigStorageCageFeedTask != null || bigStorageCageDetails != null) {
            log.info("此玻璃存任务或已在笼内");
            return Boolean.TRUE;
        }
        //1、获取任务表中相邻玻璃
        List<EdgGlassTaskInfo> edgGlassTaskInfoList;
        edgGlassTaskInfoList = edgGlassTaskInfoService.list(new LambdaQueryWrapper<EdgGlassTaskInfo>()
                .eq(EdgGlassTaskInfo::getLine, line)
                .apply("time >= (select time from edg_glass_task_info where line='" + line + "' and glass_id = '" + glassId + "' and deleted = 0)")
                .orderByAsc(EdgGlassTaskInfo::getCreateTime));
        if (edgGlassTaskInfoList.size() == 0) {
            edgGlassTaskInfoList = edgGlassTaskInfoService.list(new QueryWrapper<EdgGlassTaskInfo>()
                    .select("Top 1 *")
                    .eq("glass_id", glassId)
            );
            log.info("在尺寸表中获取玻璃信息{}", edgGlassTaskInfoList);
            if (edgGlassTaskInfoList.size() == 0) {
                GlassInfo glassInfo = glassInfoService.getOne(
                        new LambdaQueryWrapper<GlassInfo>()
                                .eq(GlassInfo::getGlassId, glassId)
                );
                EdgGlassTaskInfo edgGlassTaskInfo = new EdgGlassTaskInfo();
                BeanUtils.copyProperties(glassInfo, edgGlassTaskInfo);
                edgGlassTaskInfo.setWidth((int) glassInfo.getWidth());
                edgGlassTaskInfo.setHeight((int) glassInfo.getHeight());
                edgGlassTaskInfoList.add(edgGlassTaskInfo);
                log.info("在玻璃信息表中获取玻璃信息{}", edgGlassTaskInfoList);
            }
        }
        Assert.isFalse(CollectionUtils.isEmpty(edgGlassTaskInfoList), "识别玻璃信息未出现在尺寸表中,获取相邻两块玻璃失败");
        //2、获取卧转立剩余宽度
        BigStorageDTO sitToUpRemainWidth = bigStorageCageFeedTaskService.querySitToUpRemainWidth(line);
        Integer remainWidth;
        Integer glassCount;
        if (0 == sitToUpRemainWidth.getGlassCount()) {
            remainWidth = carWidth;
            glassCount = 0;
        } else {
            remainWidth = sitToUpRemainWidth.getWidth();
            glassCount = sitToUpRemainWidth.getGlassCount();
        }
        Boolean flag = Boolean.TRUE;
        //2、获取卧转立
        Integer widthFirst = Math.max(edgGlassTaskInfoList.get(0).getWidth() / 10, edgGlassTaskInfoList.get(0).getHeight() / 10);
        Integer heightFirst = Math.min(edgGlassTaskInfoList.get(0).getWidth() / 10, edgGlassTaskInfoList.get(0).getHeight() / 10);
        if (edgGlassTaskInfoList.size() == 1) {
            if (remainWidth >= widthFirst) {
                if (glassCount < inCarMaxSize) {
                    addFeedTask(glassId, line, Const.BIG_STORAGE_IN_WAIT, widthFirst, heightFirst);
                } else {
                    if (glassCount < inCarMaxSize + 1) {
                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst, heightFirst);
                    } else {
                        return Boolean.FALSE;
                    }
                }
            } else {
                flag = Boolean.FALSE;
            }
        } else {
            Integer widthSecond = Math.max(edgGlassTaskInfoList.get(1).getWidth() / 10, edgGlassTaskInfoList.get(1).getHeight() / 10);
            Integer heightSecond = Math.min(edgGlassTaskInfoList.get(1).getWidth() / 10, edgGlassTaskInfoList.get(1).getHeight() / 10);
            if (remainWidth >= widthFirst) {
                if (remainWidth - widthFirst - glassGap >= widthSecond) {
                    if (glassCount < inCarMaxSize) {
                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_WAIT, widthFirst, heightFirst);
                    } else {
                        if (glassCount < inCarMaxSize + 1) {
                            addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst, heightFirst);
                        } else {
                            return Boolean.FALSE;
                        }
                    }
                } else {
                    if (glassCount < inCarMaxSize + 1) {
                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst, heightFirst);
                    } else {
                        return Boolean.FALSE;
                    }
                }
            } else {
                flag = Boolean.FALSE;
            }
        }
        //向plc发送进片确认
        if (flag) {
            //向plc写入确认字
            PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
            int returnData = 1;
            int count = 1;
            while (returnData != 0) {
                S7object.getinstance().plccontrol.writeWord(mesAddress, 1);
                if (Const.A10_OUT_TARGET_POSITION.equals(line)) {
                    returnData = Integer.parseInt(plcParameterObject.getPlcParameter("D04ToMES").getValue());
                } else {
                    returnData = Integer.parseInt(plcParameterObject.getPlcParameter("D01ToMES").getValue());
                }
//                returnData = S7object.getinstance().plccontrol.readWord(mesAddress, 1).get(0);
                log.info("进卧转立第{}次发送确认字完成,地址为:{},写入的内容为{}", count++, mesAddress, 1);
            }
        }
        //记录无法放下玻璃,后续判断启动
        return flag;
    }
    /**
     * 添加任务信息
     */
    private Boolean addFeedTask(String glassId, Integer line, Integer taskType, Integer width, Integer height) {
        BigStorageCageFeedTask bigStorageCageFeedTask = new BigStorageCageFeedTask();
        bigStorageCageFeedTask.setGlassId(glassId);
        bigStorageCageFeedTask.setTaskState(Const.BIG_STORAGE_IN_NEW);
        bigStorageCageFeedTask.setLine(line);
        bigStorageCageFeedTask.setTaskType(taskType);
        bigStorageCageFeedTask.setWidth(width);
        bigStorageCageFeedTask.setHeight(height);
        bigStorageCageFeedTask.setCreateTime(new Date());
        //删除理片笼表拿走/破损数据数据
        damageService.deleteByGlassId(glassId);
        Damage damage = new Damage();
        damage.setGlassId(glassId);
        damage.setWorkingProcedure("磨边");
        damage.setLine(line);
        damage.setType(1);
        damage.setRemark("进大理片");
        damageService.insertDamage(damage);
        return bigStorageCageFeedTaskService.save(bigStorageCageFeedTask);
    }
    /**
     * 获取需要启动的线路:两条线都可启动 获取第一片玻璃版图id最小 版序最大的线路
     *
     * @return 需要启动的线路
     */
    public Integer getStartLine() {
        List<BigStorageCageFeedTask> taskList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
                .inSql(BigStorageCageFeedTask::getId, "select min(id) from big_storage_cage_feed_task where task_state = 2" +
                        "and (target_slot = 0 or target_slot is null) group by line"));
        Assert.isFalse(CollectionUtils.isEmpty(taskList), "卧转立两条线都没有玻璃进片任务");
        Map<String, Integer> taskMap = taskList.stream().collect(Collectors.toMap(BigStorageCageFeedTask::getGlassId,
                BigStorageCageFeedTask::getLine));
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                .in(GlassInfo::getGlassId, taskMap.keySet())
                .orderByAsc(GlassInfo::getTemperingLayoutId)
                .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence)
                .last("limit 1"));
        return taskMap.get(glassInfo.getGlassId());
    }
    /**
     * 计算任务表进片线路的目标格子,并启动任务
     */
    public boolean computeTargetByLine(Integer line) {
        //1、获取任务表中的所有玻璃(指定线路且已经进卧转立完成)
        List<BigStorageCageFeedTask> taskList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
                .eq(BigStorageCageFeedTask::getLine, line)
                .and(e -> e.isNull(BigStorageCageFeedTask::getTargetSlot).or().eq(BigStorageCageFeedTask::getTargetSlot, Const.OUT_TARGET_POSITION_ZERO))
                .in(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP_ALL)
                .orderByAsc(BigStorageCageFeedTask::getId));
        //2、去笼子内查找是否可以继续存放的笼子
        List<String> glassIds = taskList.stream().map(BigStorageCageFeedTask::getGlassId).collect(Collectors.toList());
        List<GlassInfo> glassInfos = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>().in(GlassInfo::getGlassId, glassIds));
        return computeIsTemperingTargetByLine(glassInfos, taskList);
    }
    /**
     * 是否钢化玻璃进笼目标位置
     *
     * @param glassInfos 当条线卧转立所有玻璃
     * @param taskList   当条线卧转立所有任务
     */
    private boolean computeIsTemperingTargetByLine(List<GlassInfo> glassInfos, List<BigStorageCageFeedTask> taskList) {
        //1、将玻璃信息集合转为glassid为key的map
        Map<String, GlassInfo> glassInfoMap = glassInfos.stream()
                .collect(Collectors.toMap(GlassInfo::getGlassId, p -> p));
        for (BigStorageCageFeedTask e : taskList) {
            GlassInfo info = glassInfoMap.get(e.getGlassId());
            if (info == null) {
                continue;
            }
            BigStorageCageDetails cageDetails = new BigStorageCageDetails();
            BeanUtils.copyProperties(info, cageDetails);
            //todo:2、获取目标格子信息
            BigStorageDTO bigStorageDTO = bigStorageCageDetailsService.queryTargetSlotByTempering(info);
            //3、临时更新格子的剩余尺寸:防止相邻玻璃进同一格子造成剩余尺寸不足,玻璃越界的情况,任务完成后再次更新大理片笼表剩余宽度(按照笼内玻璃数量更新大理片笼剩余尺寸)
            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, bigStorageDTO.getWidth() - Math.max(info.getWidth(), info.getHeight()) - glassGap)
                    .eq(BigStorageCage::getSlot, bigStorageDTO.getSlot()));
            //4、更新进片任务表,目标格子及状态(状态改为2 电气扫到自行处理)  遇到问题:无法批量更新,批量更新无法走指定从库
            e.setTargetSlot(bigStorageDTO.getSlot());
            bigStorageCageFeedTaskService.updateById(e);
            //5、将进片信息存入大理片笼详情表
            cageDetails.setSlot(bigStorageDTO.getSlot());
            cageDetails.setState(Const.GLASS_STATE_NEW);
            cageDetails.setDeviceId(bigStorageDTO.getDeviceId());
            cageDetails.setGap(glassGap);
            bigStorageCageDetailsService.save(cageDetails);
        }
        return Boolean.TRUE;
    }
    private void sendTaskListToPLC(List<BigStorageCageFeedTask> taskList, Integer line) {
        log.info("送片任务发送进片玻璃信息");
        S7control s7control = S7object.getinstance().plccontrol;
        PlcParameterObject plcMesObject = S7object.getinstance().PlcMesObject;
        String mesD03Address = plcMesObject.getPlcParameter("MESToD03").getAddress();
        String mesD05Address = plcMesObject.getPlcParameter("MESToD05").getAddress();
        String outLine = line.equals(Const.A09_OUT_TARGET_POSITION) ? mesD03Address : mesD05Address;
        for (int i = 1; i <= taskList.size(); i++) {
            s7control.writeWord(plcMesObject.getPlcParameter("StartAddToImport" + i).getAddress(), taskList.get(i - 1).getLine());
            s7control.writeWord(plcMesObject.getPlcParameter("TargetAddToImport" + i).getAddress(), taskList.get(i - 1).getTargetSlot());
            log.info("向plc发送第{}片玻璃已完成,起始位置是{},目标位置是", i, taskList.get(i - 1).getLine(), taskList.get(i - 1).getTargetSlot());
        }
        int returnData = 1;
        int count = 1;
        while (returnData != 0) {
            s7control.writeWord(outLine, 2);
            if (line.equals(Const.A09_OUT_TARGET_POSITION)) {
                returnData = Integer.parseInt(plcMesObject.getPlcParameter("D03ToMES").getValue());
            } else {
                returnData = Integer.parseInt(plcMesObject.getPlcParameter("D05ToMES").getValue());
            }
//            returnData = s7control.readWord(outLine, 1).get(0);
            log.info("已向plc第{}次发送进片任务确认,地址为:{},写入的内容为{}", count++, outLine, 2);
        }
    }
    /**
     * 出片一次仅生成一车玻璃
     *
     * @param list
     * @param isTempering
     * @param mesToPLCAddress
     * @param <T>
     * @return
     */
    private <T extends BigStorageCageBaseInfo> Boolean computeOutGlassInfo(List<T> list, Boolean isTempering, String mesToPLCAddress) {
        //任务数据  获取车子存放玻璃最大数量  玻璃间隔
        List<BigStorageCageOutTask> bigStorageCageOutTaskList = new ArrayList<>();
        //打车剩余尺寸
        Integer remainWidth = carWidth;
        int maxX = 0;
        for (T e : list) {
            if (bigStorageCageOutTaskList.size() >= outCarMaxSize || Math.max((int) e.getWidth(), (int) e.getHeight()) > remainWidth) {
                break;
            }
            remainWidth = remainWidth - Math.max((int) e.getWidth(), (int) e.getHeight()) - glassGap;
            if (isTempering) {
                int minLength = Math.min((int) e.getWidth(), (int) e.getHeight());
                if (maxX + minLength <= xMaxSize) {
                    bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
                            e.getWidth() * 10, e.getHeight() * 10, 0, 0, 1, new Date()));
//                    maxX = Math.max(maxX, e.getXCoordinate());
                } else {
                    break;
                }
            } else {
                bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.ARTIFICIAL_OUT_TARGET_POSITION,
                        e.getWidth() * 10, e.getHeight(), 0, 0, 1, new Date()));
            }
        }
        Assert.isFalse(CollectionUtils.isEmpty(bigStorageCageOutTaskList), "未获取出片数据,结束出片任务");
        log.info("获取出片任务数据{}条,执行保存", bigStorageCageOutTaskList.size());
        bigStorageCageOutTaskService.saveBatch(bigStorageCageOutTaskList);
        List<String> glassIds = bigStorageCageOutTaskList.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
        log.info("将出片玻璃{}玻璃状态改为已出片", glassIds);
        bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
                .set(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT_ING)
                .in(BigStorageCageDetails::getGlassId, glassIds));
        int returnData = 0;
        int count = 1;
        while (returnData == 0) {
            S7object.getinstance().plccontrol.writeWord(mesToPLCAddress, 1);
            returnData = S7object.getinstance().plccontrol.readWord(mesToPLCAddress, 1).get(0);
            log.info("已向plc第{}次发送出片任务确认,地址为:{},写入的内容为{}", count++, mesToPLCAddress, returnData);
        }
        return Boolean.TRUE;
    }
    /**
     * 出片一次生成一炉玻璃
     *
     * @param list
     * @param isTempering
     * @param mesToPLCAddress
     * @param <T>
     * @return
     */
    public <T extends BigStorageCageBaseInfo> Boolean computeOutMoreGlassInfo(List<T> list, Boolean isTempering, String mesToPLCAddress) {
        //任务数据  获取车子存放玻璃最大数量  玻璃间隔
        List<BigStorageCageOutTask> bigStorageCageOutTaskList = new ArrayList<>();
        //打车剩余尺寸
        Integer remainWidth = carWidth;
        int trainNumber = 1;
        int serialNumber = 1;
        int maxX = 0;
        for (T e : list) {
            int maxLength = Math.max((int) e.getWidth(), (int) e.getHeight());
            if (serialNumber > outCarMaxSize || maxLength > remainWidth) {
                remainWidth = carWidth;
                trainNumber = trainNumber + 1;
                serialNumber = 1;
                maxX = 0;
            }
            remainWidth = remainWidth - maxLength - glassGap;
            if (isTempering) {
                int minLength = Math.min((int) e.getWidth(), (int) e.getHeight());
                if (maxX + minLength <= xMaxSize) {
                    bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
                            e.getWidth() * 10, e.getHeight() * 10, trainNumber, serialNumber++, 1, new Date()));
//                    maxX = Math.max(maxX, e.getXCoordinate());
                } else {
                    remainWidth = carWidth - maxLength - glassGap;
                    trainNumber = trainNumber + 1;
                    serialNumber = 1;
//                    maxX = e.getXCoordinate();
                    bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
                            e.getWidth() * 10, e.getHeight(), trainNumber, serialNumber++, 1, new Date()));
                }
            } else {
                bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.ARTIFICIAL_OUT_TARGET_POSITION,
                        e.getWidth() * 10, e.getHeight(), trainNumber, serialNumber++, 1, new Date()));
            }
        }
        Assert.isFalse(CollectionUtils.isEmpty(bigStorageCageOutTaskList), "未获取出片数据,结束出片任务");
        log.info("获取出片任务数据{}条,执行保存", bigStorageCageOutTaskList.size());
        for (BigStorageCageOutTask bigStorageCageOutTask : bigStorageCageOutTaskList
        ) {
            bigStorageCageOutTaskService.save(bigStorageCageOutTask);
        }
//            //是否有人工下片任务   有直接出
////            List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
////                    .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL).orderByDesc(BigStorageCageDetails::getWidth));
//            List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
//                    .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL)
//                    .orderByAsc(BigStorageCageDetails::getSlot)
//                    .orderByDesc(BigStorageCageDetails::getId));
//            if (CollectionUtils.isNotEmpty(artificialList)) {
//                computeOutMoreGlassInfo(artificialList, Boolean.FALSE, mesToPLCAddress);
//                return;
//            }
//            //钢化优先:获取理片笼  玻璃小片  破损表 数量   判断笼内版图是否到齐
//            List<TemperingLayoutDTO> temperingLayoutDTOList = bigStorageCageDetailsService.temperingIsAll();
//            if (CollectionUtils.isNotEmpty(temperingLayoutDTOList)) {
//                //玻璃到齐包括已出片的
//                //到齐,将玻璃小片数据存入钢化小片表,逻辑生成出片任务  结束
//                for (TemperingLayoutDTO item : temperingLayoutDTOList) {
//                    if (redisUtil.getCacheObject("temperingengineerId").equals(item.getEngineerId())) {
//                        List<TemperingGlassInfo> temperingGlassInfos = glassInfoService.selectJoinList(TemperingGlassInfo.class, JoinWrappers.lambda(GlassInfo.class)
//                                .selectAll(GlassInfo.class)
//                                .select("-1 as state")
//                                .selectAs(BigStorageCageDetails::getSlot, TemperingGlassInfo::getSlot)
//                                .innerJoin(BigStorageCageDetails.class, BigStorageCageDetails::getGlassId, GlassInfo::getGlassId)
//                                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
//                                .eq(GlassInfo::getTemperingLayoutId, item.getTemperingLayoutId())
//                                .eq(GlassInfo::getEngineerId, item.getEngineerId())
//                                .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence));
//                        if (CollectionUtils.isNotEmpty(temperingGlassInfos)) {
//                            temperingGlassInfoService.saveBatch(temperingGlassInfos);
//                            computeOutMoreGlassInfo(temperingGlassInfoList, Boolean.TRUE, mesToPLCAddress);
//                            return;
//                        }
//                    }
//                }
//            }
//        }
//        //执行内部调度任务
//        List<TemperingLayoutDTO> temperingOccupySlotList = bigStorageCageDetailsService.queryTemperingOccupySlot();
//        if (CollectionUtils.isNotEmpty(temperingOccupySlotList)) {
//            loop:
//            for (TemperingLayoutDTO temperingOccupySlot : temperingOccupySlotList) {
//                List<SlotSequenceDTO> slotSequenceList = bigStorageCageDetailsService.queryGlassMaxAndMin(temperingOccupySlot.getEngineerId(), temperingOccupySlot.getTemperingLayoutId());
//                for (int i = 0; i < slotSequenceList.size() - 1; i++) {
//                    SlotSequenceDTO first = slotSequenceList.get(i);
//                    SlotSequenceDTO second = slotSequenceList.get(i + 1);
//                    int slotWidth = carWidth - first.getRemainWidth() - glassGap;
//                    if (first.getMinSequence() == second.getMaxSequence() + 1
//                            && second.getRemainWidth() > slotWidth && slotWidth >= 0) {
//                        List<BigStorageCageDetails> list = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
//                                .eq(BigStorageCageDetails::getSlot, first.getSlot()).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
//                                .orderBy(Boolean.TRUE, sequenceOrder, BigStorageCageDetails::getTemperingFeedSequence));
//                        if (CollectionUtils.isNotEmpty(list)) {
//                            List<BigStorageCageOutTask> outTasks = new ArrayList<>();
//                            int serialNumber = 1;
//                            for (BigStorageCageDetails item : list) {
//                                outTasks.add(new BigStorageCageOutTask(item.getGlassId(), first.getSlot(), second.getSlot(),
//                                        item.getWidth() * 10, item.getHeight() * 10, 1, serialNumber++, Const.BIG_STORAGE_OUT_NEW, new Date()));
//                            }
//                            //新增调度任务
//                            bigStorageCageOutTaskService.saveBatch(outTasks);
//                            //更新理片笼详情表调度的后的玻璃位置信息:生成任务后先将玻璃格子位置进行调整,玻璃状态改为调度中,新增调度完成任务,处理调度完成后玻璃状态改为100.
//                            List<String> glassList = list.stream().map(BigStorageCageDetails::getGlassId).collect(Collectors.toList());
//                            bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>().set(BigStorageCageDetails::getState, Const.GLASS_STATE_SCHEDULE_ING)
//                                    .set(BigStorageCageBaseInfo::getSlot, second.getSlot()).in(BigStorageCageDetails::getGlassId, glassList));
//                            //两次更新笼子的剩余尺寸:第一次防止有玻璃继续进调度后的笼子,第二次更新:计算格子的实际尺寸
//                            // 仅更新调度后的格子信息:起始格子完成后更新:防止调度出片过程中有新玻璃进入,
////                            todo:临时解决报错
////                            updateSlotRemainBySlots(Arrays.asList(second.getSlot()));
//                            break loop;
//                        }
//                    }
//                }
//            }
////            //向plc写入确认字
////            int returnData = 0;
////            int count = 1;
////            while (returnData == 0) {
////                log.info("已向plc第{}次送协议", count);
////                S7object.getinstance().plccontrol.writeWord(mesToPLCAddress, 1);
////                returnData = S7object.getinstance().plccontrol.readWord(mesToPLCAddress, 1).get(0);
////                log.info("已向plc第{}次发送出片任务确认,地址为:{},写入的内容为{}", count++, mesToPLCAddress, returnData);
////            }
//            return;
//        }
//    }
//
//
//    /**
//     * 确认字清空
//     */
////    @Scheduled(fixedDelay = 300)
//    public void confirmClear() {
//        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
//        String d01ToMES = plcParameterObject.getPlcParameter("D01ToMES").getValue();
//        String d04ToMES = plcParameterObject.getPlcParameter("D04ToMES").getValue();
//        String mesD01Address = plcParameterObject.getPlcParameter("MESToD01").getAddress();
//        String mesD04Address = plcParameterObject.getPlcParameter("MESToD04").getAddress();
//        String d03ToMES = plcParameterObject.getPlcParameter("D03ToMES").getValue();
//        String d05ToMES = plcParameterObject.getPlcParameter("D05ToMES").getValue();
//        String mesD03Address = plcParameterObject.getPlcParameter("MESToD03").getAddress();
//        String mesD05Address = plcParameterObject.getPlcParameter("MESToD05").getAddress();
//        if (!REQUEST_WORD.equals(d01ToMES)) {
//            S7object.getinstance().plccontrol.writeWord(mesD01Address, 0);
//        }
//        if (!REQUEST_WORD.equals(d04ToMES)) {
//            S7object.getinstance().plccontrol.writeWord(mesD04Address, 0);
//        }
//        if (!REQUEST_WORD.equals(d03ToMES)) {
//            S7object.getinstance().plccontrol.writeWord(mesD03Address, 0);
//        }
//        if (!REQUEST_WORD.equals(d05ToMES)) {
//            S7object.getinstance().plccontrol.writeWord(mesD05Address, 0);
//        }
//    }
//
//    /**
//     * 进片状态修改
//     */
////    @Scheduled(fixedDelay = 300)
//    public void feedStatusUpdate() {
//        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
//        List<String> glassIds1 = new ArrayList<>();
//        List<String> glassIds2 = new ArrayList<>();
//        for (int i = 1; i <= 6; i++) {
//            String line1GlassId = plcParameterObject.getPlcParameter("D03ID" + i).getValue();
//            if (StringUtils.isNotEmpty(line1GlassId)) {
//                glassIds1.add(line1GlassId);
//            }
//            String line2GlassId = plcParameterObject.getPlcParameter("D05ID" + i).getValue();
//            if (StringUtils.isNotEmpty(line2GlassId)) {
//                glassIds2.add(line2GlassId);
//            }
//        }
//        List<BigStorageCageFeedTask> bigStorageCageFeedTasks1 = bigStorageCageFeedTaskService.list(
//                new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                        .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_NEW)
//                        .eq(BigStorageCageFeedTask::getLine, Const.A09_OUT_TARGET_POSITION)
//        );
//        List<BigStorageCageFeedTask> bigStorageCageFeedTasks2 = bigStorageCageFeedTaskService.list(
//                new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                        .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_NEW)
//                        .eq(BigStorageCageFeedTask::getLine, Const.A10_OUT_TARGET_POSITION)
//        );
//        if (CollectionUtils.isNotEmpty(bigStorageCageFeedTasks1) && CollectionUtils.isNotEmpty(glassIds1)) {
//            List<String> matchingIds1 = bigStorageCageFeedTasks1.stream()
//                    .map(BigStorageCageFeedTask::getGlassId)
//                    .filter(glassIds1::contains)
//                    .distinct()
//                    .collect(Collectors.toList());
//            bigStorageCageFeedTaskService.update(
//                    new LambdaUpdateWrapper<BigStorageCageFeedTask>()
//                            .in(BigStorageCageFeedTask::getGlassId, matchingIds1)
//                            .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
//                            .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
//            );
//        }
//        if (CollectionUtils.isNotEmpty(bigStorageCageFeedTasks2) && CollectionUtils.isNotEmpty(glassIds2)) {
//            List<String> matchingIds2 = bigStorageCageFeedTasks2.stream()
//                    .map(BigStorageCageFeedTask::getGlassId)
//                    .filter(glassIds2::contains)
//                    .distinct()
//                    .collect(Collectors.toList());
//            bigStorageCageFeedTaskService.update(
//                    new LambdaUpdateWrapper<BigStorageCageFeedTask>()
//                            .in(BigStorageCageFeedTask::getGlassId, matchingIds2)
//                            .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
//                            .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
//            );
//        }
//        if (CollectionUtils.isEmpty(glassIds1)) {
//            bigStorageCageFeedTaskService.update(
//                    new LambdaUpdateWrapper<BigStorageCageFeedTask>()
//                            .eq(BigStorageCageFeedTask::getLine, Const.A09_OUT_TARGET_POSITION)
//                            .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
//                            .gt(BigStorageCageFeedTask::getTargetSlot, 0)
//                            .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
//                            .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_CAR)
//            );
//        }
//        if (CollectionUtils.isEmpty(glassIds2)) {
//            bigStorageCageFeedTaskService.update(
//                    new LambdaUpdateWrapper<BigStorageCageFeedTask>()
//                            .eq(BigStorageCageFeedTask::getLine, Const.A10_OUT_TARGET_POSITION)
//                            .eq(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP)
//                            .gt(BigStorageCageFeedTask::getTargetSlot, 0)
//                            .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
//                            .set(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_CAR)
//            );
//        }
//    }
//
//    /**
//     * 按照玻璃id判断玻璃状态及卧转立是否可直接启动
//     */
//    public Boolean judgeGlassTypeStatus(String glassId, Integer line, String mesAddress) {
//        //判断此玻璃是在笼内或已生成进片任务
//        BigStorageCageFeedTask bigStorageCageFeedTask = bigStorageCageFeedTaskService.getOne(
//                new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                        .lt(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_SLOT)
//                        .eq(BigStorageCageFeedTask::getGlassId, glassId)
//        );
//        BigStorageCageDetails bigStorageCageDetails = bigStorageCageDetailsService.getOne(
//                new LambdaQueryWrapper<BigStorageCageDetails>()
//                        .eq(BigStorageCageDetails::getGlassId, glassId)
//                        .ne(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
//        );
//        if (bigStorageCageFeedTask != null || bigStorageCageDetails != null) {
//            log.info("此玻璃存任务或已在笼内");
//            return Boolean.TRUE;
//        }
//        //1、获取任务表中相邻玻璃
//        List<EdgGlassTaskInfo> edgGlassTaskInfoList;
//        edgGlassTaskInfoList = edgGlassTaskInfoService.list(new LambdaQueryWrapper<EdgGlassTaskInfo>()
//                .eq(EdgGlassTaskInfo::getLine, line)
//                .apply("time >= (select time from edg_glass_task_info where line='" + line + "' and glass_id = '" + glassId + "' and deleted = 0)")
//                .orderByAsc(EdgGlassTaskInfo::getCreateTime));
//        if (edgGlassTaskInfoList.size() == 0) {
//            edgGlassTaskInfoList = edgGlassTaskInfoService.list(new QueryWrapper<EdgGlassTaskInfo>()
//                    .select("Top 1 *")
//                    .eq("glass_id", glassId)
//            );
//            log.info("在尺寸表中获取玻璃信息{}", edgGlassTaskInfoList);
//            if (edgGlassTaskInfoList.size() == 0) {
//                GlassInfo glassInfo = glassInfoService.getOne(
//                        new LambdaQueryWrapper<GlassInfo>()
//                                .eq(GlassInfo::getGlassId, glassId)
//                );
//                EdgGlassTaskInfo edgGlassTaskInfo = new EdgGlassTaskInfo();
//                BeanUtils.copyProperties(glassInfo, edgGlassTaskInfo);
//                edgGlassTaskInfo.setWidth((int) glassInfo.getWidth());
//                edgGlassTaskInfo.setHeight((int) glassInfo.getHeight());
//                edgGlassTaskInfoList.add(edgGlassTaskInfo);
//                log.info("在玻璃信息表中获取玻璃信息{}", edgGlassTaskInfoList);
//            }
//        }
//        Assert.isFalse(CollectionUtils.isEmpty(edgGlassTaskInfoList), "识别玻璃信息未出现在尺寸表中,获取相邻两块玻璃失败");
//        //2、获取卧转立剩余宽度
//        BigStorageDTO sitToUpRemainWidth = bigStorageCageFeedTaskService.querySitToUpRemainWidth(line);
//        Integer remainWidth;
//        Integer glassCount;
//        if (0 == sitToUpRemainWidth.getGlassCount()) {
//            remainWidth = carWidth;
//            glassCount = 0;
//        } else {
//            remainWidth = sitToUpRemainWidth.getWidth();
//            glassCount = sitToUpRemainWidth.getGlassCount();
//        }
//
//        Boolean flag = Boolean.TRUE;
//        //2、获取卧转立
//        Integer widthFirst = Math.max(edgGlassTaskInfoList.get(0).getWidth() / 10, edgGlassTaskInfoList.get(0).getHeight() / 10);
//        Integer heightFirst = Math.min(edgGlassTaskInfoList.get(0).getWidth() / 10, edgGlassTaskInfoList.get(0).getHeight() / 10);
//        if (edgGlassTaskInfoList.size() == 1) {
//            if (remainWidth >= widthFirst) {
//                if (glassCount < inCarMaxSize) {
//                    addFeedTask(glassId, line, Const.BIG_STORAGE_IN_WAIT, widthFirst, heightFirst);
//                } else {
//                    if (glassCount < inCarMaxSize + 1) {
//                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst, heightFirst);
//                    } else {
//                        return Boolean.FALSE;
//                    }
//                }
//            } else {
//                flag = Boolean.FALSE;
//            }
//        } else {
//            Integer widthSecond = Math.max(edgGlassTaskInfoList.get(1).getWidth() / 10, edgGlassTaskInfoList.get(1).getHeight() / 10);
//            Integer heightSecond = Math.min(edgGlassTaskInfoList.get(1).getWidth() / 10, edgGlassTaskInfoList.get(1).getHeight() / 10);
//            if (remainWidth >= widthFirst) {
//                if (remainWidth - widthFirst - glassGap >= widthSecond) {
//                    if (glassCount < inCarMaxSize) {
//                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_WAIT, widthFirst, heightFirst);
//                    } else {
//                        if (glassCount < inCarMaxSize + 1) {
//                            addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst, heightFirst);
//                        } else {
//                            return Boolean.FALSE;
//                        }
//                    }
//                } else {
//                    if (glassCount < inCarMaxSize + 1) {
//                        addFeedTask(glassId, line, Const.BIG_STORAGE_IN_RUN, widthFirst, heightFirst);
//                    } else {
//                        return Boolean.FALSE;
//                    }
//                }
//            } else {
//                flag = Boolean.FALSE;
//            }
//        }
//        //向plc发送进片确认
//        if (flag) {
//            //向plc写入确认字
//            PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
//            int returnData = 1;
//            int count = 1;
//            while (returnData != 0) {
//                S7object.getinstance().plccontrol.writeWord(mesAddress, 1);
//
//                if (Const.A10_OUT_TARGET_POSITION.equals(line)) {
//                    returnData = Integer.parseInt(plcParameterObject.getPlcParameter("D04ToMES").getValue());
//                } else {
//                    returnData = Integer.parseInt(plcParameterObject.getPlcParameter("D01ToMES").getValue());
//                }
////                returnData = S7object.getinstance().plccontrol.readWord(mesAddress, 1).get(0);
//                log.info("进卧转立第{}次发送确认字完成,地址为:{},写入的内容为{}", count++, mesAddress, 1);
//            }
//        }
//        //记录无法放下玻璃,后续判断启动
//        return flag;
//    }
//
//    /**
//     * 添加任务信息
//     */
//    private Boolean addFeedTask(String glassId, Integer line, Integer taskType, Integer width, Integer height) {
//        BigStorageCageFeedTask bigStorageCageFeedTask = new BigStorageCageFeedTask();
//        bigStorageCageFeedTask.setGlassId(glassId);
//        bigStorageCageFeedTask.setTaskState(Const.BIG_STORAGE_IN_NEW);
//        bigStorageCageFeedTask.setLine(line);
//        bigStorageCageFeedTask.setTaskType(taskType);
//        bigStorageCageFeedTask.setWidth(width);
//        bigStorageCageFeedTask.setHeight(height);
//        bigStorageCageFeedTask.setCreateTime(new Date());
//        //删除理片笼表拿走/破损数据数据
//        damageService.deleteByGlassId(glassId);
//        Damage damage = new Damage();
//        damage.setGlassId(glassId);
//        damage.setWorkingProcedure("磨边");
//        damage.setLine(line);
//        damage.setType(1);
//        damage.setRemark("进大理片");
//        damageService.insertDamage(damage);
//        return bigStorageCageFeedTaskService.save(bigStorageCageFeedTask);
//    }
//
//    /**
//     * 获取需要启动的线路:两条线都可启动 获取第一片玻璃版图id最小 版序最大的线路
//     *
//     * @return 需要启动的线路
//     */
//    public Integer getStartLine() {
//        List<BigStorageCageFeedTask> taskList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                .inSql(BigStorageCageFeedTask::getId, "select min(id) from big_storage_cage_feed_task where task_state = 2" +
//                        "and (target_slot = 0 or target_slot is null) group by line"));
//        Assert.isFalse(CollectionUtils.isEmpty(taskList), "卧转立两条线都没有玻璃进片任务");
//        Map<String, Integer> taskMap = taskList.stream().collect(Collectors.toMap(BigStorageCageFeedTask::getGlassId,
//                BigStorageCageFeedTask::getLine));
//        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
//                .in(GlassInfo::getGlassId, taskMap.keySet())
//                .orderByAsc(GlassInfo::getTemperingLayoutId)
//                .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence)
//                .last("limit 1"));
//        return taskMap.get(glassInfo.getGlassId());
//    }
//
//    /**
//     * 计算任务表进片线路的目标格子,并启动任务
//     */
//    public boolean computeTargetByLine(Integer line) {
//        //1、获取任务表中的所有玻璃(指定线路且已经进卧转立完成)
//        List<BigStorageCageFeedTask> taskList = bigStorageCageFeedTaskService.list(new LambdaQueryWrapper<BigStorageCageFeedTask>()
//                .eq(BigStorageCageFeedTask::getLine, line)
//                .and(e -> e.isNull(BigStorageCageFeedTask::getTargetSlot).or().eq(BigStorageCageFeedTask::getTargetSlot, Const.OUT_TARGET_POSITION_ZERO))
//                .in(BigStorageCageFeedTask::getTaskState, Const.BIG_STORAGE_IN_UP_ALL)
//                .orderByAsc(BigStorageCageFeedTask::getId));
//        //2、去笼子内查找是否可以继续存放的笼子
//        List<String> glassIds = taskList.stream().map(BigStorageCageFeedTask::getGlassId).collect(Collectors.toList());
//        List<GlassInfo> glassInfos = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>().in(GlassInfo::getGlassId, glassIds));
//        return computeIsTemperingTargetByLine(glassInfos, taskList);
//    }
//
//    /**
//     * 是否钢化玻璃进笼目标位置
//     *
//     * @param glassInfos 当条线卧转立所有玻璃
//     * @param taskList   当条线卧转立所有任务
//     */
//    private boolean computeIsTemperingTargetByLine(List<GlassInfo> glassInfos, List<BigStorageCageFeedTask> taskList) {
//        //1、将玻璃信息集合转为glassid为key的map
//        Map<String, GlassInfo> glassInfoMap = glassInfos.stream()
//                .collect(Collectors.toMap(GlassInfo::getGlassId, p -> p));
//        for (BigStorageCageFeedTask e : taskList) {
//            GlassInfo info = glassInfoMap.get(e.getGlassId());
//            if (info == null) {
//                continue;
//            }
//            BigStorageCageDetails cageDetails = new BigStorageCageDetails();
//            BeanUtils.copyProperties(info, cageDetails);
//            //todo:2、获取目标格子信息
//            BigStorageDTO bigStorageDTO = bigStorageCageDetailsService.queryTargetSlotByTempering(info);
//            //3、临时更新格子的剩余尺寸:防止相邻玻璃进同一格子造成剩余尺寸不足,玻璃越界的情况,任务完成后再次更新大理片笼表剩余宽度(按照笼内玻璃数量更新大理片笼剩余尺寸)
//            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, bigStorageDTO.getWidth() - Math.max(info.getWidth(), info.getHeight()) - glassGap)
//                    .eq(BigStorageCage::getSlot, bigStorageDTO.getSlot()));
//            //4、更新进片任务表,目标格子及状态(状态改为2 电气扫到自行处理)  遇到问题:无法批量更新,批量更新无法走指定从库
//            e.setTargetSlot(bigStorageDTO.getSlot());
//            bigStorageCageFeedTaskService.updateById(e);
//
//            //5、将进片信息存入大理片笼详情表
//            cageDetails.setSlot(bigStorageDTO.getSlot());
//            cageDetails.setState(Const.GLASS_STATE_NEW);
//            cageDetails.setDeviceId(bigStorageDTO.getDeviceId());
//            cageDetails.setGap(glassGap);
//            bigStorageCageDetailsService.save(cageDetails);
//
//        }
//        return Boolean.TRUE;
//    }
//
//    private void sendTaskListToPLC(List<BigStorageCageFeedTask> taskList, Integer line) {
//        log.info("送片任务发送进片玻璃信息");
//        S7control s7control = S7object.getinstance().plccontrol;
//        PlcParameterObject plcMesObject = S7object.getinstance().PlcMesObject;
//        String mesD03Address = plcMesObject.getPlcParameter("MESToD03").getAddress();
//        String mesD05Address = plcMesObject.getPlcParameter("MESToD05").getAddress();
//        String outLine = line.equals(Const.A09_OUT_TARGET_POSITION) ? mesD03Address : mesD05Address;
//        for (int i = 1; i <= taskList.size(); i++) {
//            s7control.writeWord(plcMesObject.getPlcParameter("StartAddToImport" + i).getAddress(), taskList.get(i - 1).getLine());
//            s7control.writeWord(plcMesObject.getPlcParameter("TargetAddToImport" + i).getAddress(), taskList.get(i - 1).getTargetSlot());
//            log.info("向plc发送第{}片玻璃已完成,起始位置是{},目标位置是", i, taskList.get(i - 1).getLine(), taskList.get(i - 1).getTargetSlot());
//        }
//        int returnData = 1;
//        int count = 1;
//        while (returnData != 0) {
//            s7control.writeWord(outLine, 2);
//            if (line.equals(Const.A09_OUT_TARGET_POSITION)) {
//                returnData = Integer.parseInt(plcMesObject.getPlcParameter("D03ToMES").getValue());
//            } else {
//                returnData = Integer.parseInt(plcMesObject.getPlcParameter("D05ToMES").getValue());
//            }
////            returnData = s7control.readWord(outLine, 1).get(0);
//            log.info("已向plc第{}次发送进片任务确认,地址为:{},写入的内容为{}", count++, outLine, 2);
//        }
//    }
//
//    /**
//     * 出片一次仅生成一车玻璃
//     *
//     * @param list
//     * @param isTempering
//     * @param mesToPLCAddress
//     * @param <T>
//     * @return
//     */
//    private <T extends BigStorageCageBaseInfo> Boolean computeOutGlassInfo(List<T> list, Boolean isTempering, String mesToPLCAddress) {
//        //任务数据  获取车子存放玻璃最大数量  玻璃间隔
//        List<BigStorageCageOutTask> bigStorageCageOutTaskList = new ArrayList<>();
//        //打车剩余尺寸
//        Integer remainWidth = carWidth;
//        int maxX = 0;
//        for (T e : list) {
//            if (bigStorageCageOutTaskList.size() >= outCarMaxSize || Math.max((int) e.getWidth(), (int) e.getHeight()) > remainWidth) {
//                break;
//            }
//            remainWidth = remainWidth - Math.max((int) e.getWidth(), (int) e.getHeight()) - glassGap;
//            if (isTempering) {
//                int minLength = Math.min((int) e.getWidth(), (int) e.getHeight());
//                if (maxX + minLength <= xMaxSize) {
//                    bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
//                            e.getWidth() * 10, e.getHeight() * 10, 0, 0, 1, new Date()));
////                    maxX = Math.max(maxX, e.getXCoordinate());
//                } else {
//                    break;
//                }
//
//            } else {
//                bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.ARTIFICIAL_OUT_TARGET_POSITION,
//                        e.getWidth() * 10, e.getHeight(), 0, 0, 1, new Date()));
//            }
//        }
//        Assert.isFalse(CollectionUtils.isEmpty(bigStorageCageOutTaskList), "未获取出片数据,结束出片任务");
//        log.info("获取出片任务数据{}条,执行保存", bigStorageCageOutTaskList.size());
//        bigStorageCageOutTaskService.saveBatch(bigStorageCageOutTaskList);
        List<String> glassIds = bigStorageCageOutTaskList.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
        log.info("将出片玻璃{}玻璃状态改为已出片", glassIds);
        bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
                .set(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT_ING)
                .in(BigStorageCageDetails::getGlassId, glassIds)
                .ne(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT));
        return Boolean.TRUE;
    }
    private BigStorageDTO queryTargetSlotByTempering(GlassInfo glassInfo) {
        MPJLambdaWrapper<BigStorageCage> wrapper = new MPJLambdaWrapper<>(BigStorageCage.class)
                .selectAll(BigStorageCage.class)
                .leftJoin(BigStorageCageDetails.class, BigStorageCageDetails::getSlot, BigStorageCage::getSlot)
                .eq(BigStorageCage::getEnableState, Const.SLOT_ON)
                .in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL_ZERO)
                .eq(BigStorageCageDetails::getEngineerId, glassInfo.getEngineerId())
                .eq(BigStorageCageDetails::getTemperingLayoutId, glassInfo.getTemperingLayoutId())
                .gt(BigStorageCage::getRemainWidth, Math.max(glassInfo.getWidth(), glassInfo.getHeight()))
                .last("limit 1");
        if (glassInfo.getTemperingLayoutId() == 0) {
            wrapper.eq(BigStorageCageDetails::getFlowCardId, glassInfo.getFlowCardId())
                    .eq(BigStorageCageDetails::getLayer, glassInfo.getLayer());
//            wrapper.eq(BigStorageCageDetails::getWidth, glassInfo.getWidth()).eq(BigStorageCageDetails::getHeight, glassInfo.getHeight());
        } else {
            wrapper.eq(BigStorageCageDetails::getTemperingFeedSequence, glassInfo.getTemperingFeedSequence() + 1);
        }
        BigStorageCage bigStorageCage = bigStorageCageService.selectJoinOne(BigStorageCage.class, wrapper);
        return null;
    }
    //    @Scheduled(fixedDelay = 300)
    public void querySizeByEngineerTask() {
        log.info("查询结果:{}", querySizeByEngineer("P24072402", 1, 10, 8));
        log.info("查询结果:{}", querySizeByEngineer("P24072402", 1, 5, 8));
    }
    public BigStorageDTO querySizeByEngineer(String engineerId, int temperingLayoutId, int temperingFeedSequence, double thickness) {
        BigStorageDTO bigStorageDTO = null;
        BigStorageCage bigStorageCage = null;
        //获取笼内当前版图每个格子已有玻璃的最小版序 获取笼内当前版图的所有玻璃信息
        List<BigStorageCageDetails> cageDetailsList = bigStorageCageDetailsService.list(new QueryWrapper<BigStorageCageDetails>()
                .select("slot", "min(tempering_feed_sequence) as tempering_feed_sequence")
                .eq("engineer_id", engineerId).eq("tempering_layout_id", temperingLayoutId)
                .in("state", Const.GLASS_STATE_IN_ALL_ZERO).groupBy("slot").orderByAsc("min(tempering_feed_sequence)"));
        if (CollectionUtils.isNotEmpty(cageDetailsList)) {
            Integer minLength = cageDetailsList.stream().filter(e -> e.getTemperingFeedSequence() > temperingFeedSequence)
                    .mapToInt(BigStorageCageDetails::getTemperingFeedSequence).min().orElse(1000);
            List<GlassInfo> infoList = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>()
                    .notInSql(GlassInfo::getGlassId, "select glass_id from damage where tempering_layout_id = " + temperingLayoutId + " and engineer_id = '" + engineerId + "'")
                    .eq(GlassInfo::getTemperingLayoutId, temperingLayoutId).eq(GlassInfo::getEngineerId, engineerId).orderByAsc(GlassInfo::getTemperingFeedSequence));
            int remainWidth = carWidth;
            int trainNumber = 1;
            int serialNumber = 0;
            int min = 0;
            int temp = infoList.get(0).getTemperingFeedSequence();
            int slot = 0;
            int resultTrainNumber = 0;
            for (GlassInfo e : infoList) {
                int maxLength = Math.max((int) e.getWidth(), (int) e.getHeight());
                if (serialNumber >= outCarMaxSize || maxLength > remainWidth || e.getTemperingFeedSequence() >= minLength) {
                    if (resultTrainNumber != 0) {
                        min = temp;
                        break;
                    }
                    temp = e.getTemperingFeedSequence();
                    remainWidth = carWidth;
                    trainNumber = trainNumber + 1;
                    serialNumber = 0;
                }
                if (temperingFeedSequence == e.getTemperingFeedSequence()) {
                    resultTrainNumber = trainNumber;
                }
                remainWidth = remainWidth - maxLength - glassGap > 0 ? remainWidth - maxLength - glassGap : 0;
                serialNumber += 1;
                log.info("{},{},{}", trainNumber, remainWidth, serialNumber);
                if (e.getTemperingFeedSequence().equals(infoList.get(infoList.size() - 1).getTemperingFeedSequence())) {
                    min = temp;
                }
            }
            for (BigStorageCageDetails item : cageDetailsList) {
                if (min <= item.getTemperingFeedSequence() && item.getTemperingFeedSequence() < minLength) {
                    slot = item.getSlot();
                    bigStorageCage = bigStorageCageService.getOne(new LambdaQueryWrapper<BigStorageCage>()
                            .eq(BigStorageCage::getSlot, slot).eq(BigStorageCage::getEnableState, Const.SLOT_ON));
                    break;
                }
            }
        }
        if (bigStorageCage != null) {
            bigStorageDTO = new BigStorageDTO();
            bigStorageDTO.setWidth(bigStorageCage.getRemainWidth());
            bigStorageDTO.setSlot(bigStorageCage.getSlot());
            bigStorageDTO.setDeviceId(bigStorageCage.getDeviceId());
            return bigStorageDTO;
        }
        bigStorageCage = bigStorageCageService.getOne(new LambdaQueryWrapper<BigStorageCage>()
                .eq(BigStorageCage::getEnableState, Const.SLOT_ON)
                .eq(BigStorageCage::getRemainWidth, slotWidth).orderByAsc(BigStorageCage::getSlot)
                .inSql(BigStorageCage::getDeviceId,
                        "select distinct device_id from big_storage_cage_details where engineer_id = '" + engineerId + "' and tempering_layout_id = " + temperingLayoutId)
                .last("limit 1"));
        if (null != bigStorageCage) {
            log.info("根据版图id找到笼子内的目标格子:{}", bigStorageCage.getSlot());
            bigStorageDTO = new BigStorageDTO();
            bigStorageDTO.setWidth(bigStorageCage.getRemainWidth());
            bigStorageDTO.setSlot(bigStorageCage.getSlot());
            bigStorageDTO.setDeviceId(bigStorageCage.getDeviceId());
            return bigStorageDTO;
        }
        //获取玻璃的厚度:重新选笼子需要按照笼子可放玻璃厚度进行选择 因为子查询排序对主sql无影响,所以先执行子查询获取顺序,然后一次去查询
        List<Integer> deviceUsedList = bigStorageCageService.queryFreeDeviceByUsed(thickness);
        for (Integer item : deviceUsedList) {
            bigStorageCage = bigStorageCageService.getOne(new LambdaQueryWrapper<BigStorageCage>()
                    .eq(BigStorageCage::getRemainWidth, slotWidth).orderByAsc(BigStorageCage::getSlot)
                    .eq(BigStorageCage::getEnableState, Const.SLOT_ON)
                    .eq(BigStorageCage::getDeviceId, item)
                    .last("limit 1"));
            if (null != bigStorageCage) {
                log.info("按照存笼玻璃格子数占用最少方式获取信息格子为:{}", bigStorageCage.getSlot());
                bigStorageDTO = new BigStorageDTO();
                bigStorageDTO.setWidth(bigStorageCage.getRemainWidth());
                bigStorageDTO.setSlot(bigStorageCage.getSlot());
                bigStorageDTO.setDeviceId(bigStorageCage.getDeviceId());
                return bigStorageDTO;
            }
        }
        Assert.isTrue(null != bigStorageCage, "没有空余的笼子存放玻璃");
        return bigStorageDTO;
    }
}
//        List<String> glassIds = bigStorageCageOutTaskList.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
//        log.info("将出片玻璃{}玻璃状态改为已出片", glassIds);
//        bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
//                .set(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT_ING)
//                .in(BigStorageCageDetails::getGlassId, glassIds));
//        int returnData = 0;
//        int count = 1;
//        while (returnData == 0) {
//            S7object.getinstance().plccontrol.writeWord(mesToPLCAddress, 1);
//            returnData = S7object.getinstance().plccontrol.readWord(mesToPLCAddress, 1).get(0);
//            log.info("已向plc第{}次发送出片任务确认,地址为:{},写入的内容为{}", count++, mesToPLCAddress, returnData);
//        }
//        return Boolean.TRUE;
//    }
//
//    /**
//     * 出片一次生成一炉玻璃
//     *
//     * @param list
//     * @param isTempering
//     * @param mesToPLCAddress
//     * @param <T>
//     * @return
//     */
//    public <T extends BigStorageCageBaseInfo> Boolean computeOutMoreGlassInfo(List<T> list, Boolean isTempering, String mesToPLCAddress) {
//        //任务数据  获取车子存放玻璃最大数量  玻璃间隔
//        List<BigStorageCageOutTask> bigStorageCageOutTaskList = new ArrayList<>();
//        //打车剩余尺寸
//        Integer remainWidth = carWidth;
//        int trainNumber = 1;
//        int serialNumber = 1;
//        int maxX = 0;
//        for (T e : list) {
//            int maxLength = Math.max((int) e.getWidth(), (int) e.getHeight());
//            if (serialNumber > outCarMaxSize || maxLength > remainWidth) {
//                remainWidth = carWidth;
//                trainNumber = trainNumber + 1;
//                serialNumber = 1;
//                maxX = 0;
//            }
//            remainWidth = remainWidth - maxLength - glassGap;
//            if (isTempering) {
//                int minLength = Math.min((int) e.getWidth(), (int) e.getHeight());
//                if (maxX + minLength <= xMaxSize) {
//                    bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
//                            e.getWidth() * 10, e.getHeight() * 10, trainNumber, serialNumber++, 1, new Date()));
////                    maxX = Math.max(maxX, e.getXCoordinate());
//                } else {
//                    remainWidth = carWidth - maxLength - glassGap;
//                    trainNumber = trainNumber + 1;
//                    serialNumber = 1;
////                    maxX = e.getXCoordinate();
//                    bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.TEMPERING_OUT_TARGET_POSITION,
//                            e.getWidth() * 10, e.getHeight(), trainNumber, serialNumber++, 1, new Date()));
//                }
//            } else {
//                bigStorageCageOutTaskList.add(new BigStorageCageOutTask(e.getGlassId(), e.getSlot(), Const.ARTIFICIAL_OUT_TARGET_POSITION,
//                        e.getWidth() * 10, e.getHeight(), trainNumber, serialNumber++, 1, new Date()));
//            }
//        }
//        Assert.isFalse(CollectionUtils.isEmpty(bigStorageCageOutTaskList), "未获取出片数据,结束出片任务");
//        log.info("获取出片任务数据{}条,执行保存", bigStorageCageOutTaskList.size());
//        for (BigStorageCageOutTask bigStorageCageOutTask : bigStorageCageOutTaskList
//        ) {
//            bigStorageCageOutTaskService.save(bigStorageCageOutTask);
//        }
////        bigStorageCageOutTaskService.saveBatch(bigStorageCageOutTaskList);
//        List<String> glassIds = bigStorageCageOutTaskList.stream().map(BigStorageCageOutTask::getGlassId).collect(Collectors.toList());
//        log.info("将出片玻璃{}玻璃状态改为已出片", glassIds);
//        bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
//                .set(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT_ING)
//                .in(BigStorageCageDetails::getGlassId, glassIds)
//                .ne(BigStorageCageDetails::getState, Const.GLASS_STATE_OUT));
//
//        return Boolean.TRUE;
//    }
//
//    private BigStorageDTO queryTargetSlotByTempering(GlassInfo glassInfo) {
//
//        MPJLambdaWrapper<BigStorageCage> wrapper = new MPJLambdaWrapper<>(BigStorageCage.class)
//                .selectAll(BigStorageCage.class)
//                .leftJoin(BigStorageCageDetails.class, BigStorageCageDetails::getSlot, BigStorageCage::getSlot)
//                .eq(BigStorageCage::getEnableState, Const.SLOT_ON)
//                .in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL_ZERO)
//                .eq(BigStorageCageDetails::getEngineerId, glassInfo.getEngineerId())
//                .eq(BigStorageCageDetails::getTemperingLayoutId, glassInfo.getTemperingLayoutId())
//                .gt(BigStorageCage::getRemainWidth, Math.max(glassInfo.getWidth(), glassInfo.getHeight()))
//                .last("limit 1");
//        if (glassInfo.getTemperingLayoutId() == 0) {
//            wrapper.eq(BigStorageCageDetails::getFlowCardId, glassInfo.getFlowCardId())
//                    .eq(BigStorageCageDetails::getLayer, glassInfo.getLayer());
////            wrapper.eq(BigStorageCageDetails::getWidth, glassInfo.getWidth()).eq(BigStorageCageDetails::getHeight, glassInfo.getHeight());
//        } else {
//            wrapper.eq(BigStorageCageDetails::getTemperingFeedSequence, glassInfo.getTemperingFeedSequence() + 1);
//        }
//        BigStorageCage bigStorageCage = bigStorageCageService.selectJoinOne(BigStorageCage.class, wrapper);
//        return null;
//    }
//
//    //    @Scheduled(fixedDelay = 300)
//    public void querySizeByEngineerTask() {
//        log.info("查询结果:{}", querySizeByEngineer("P24072402", 1, 10, 8));
//        log.info("查询结果:{}", querySizeByEngineer("P24072402", 1, 5, 8));
//
//    }
//
//    public BigStorageDTO querySizeByEngineer(String engineerId, int temperingLayoutId, int temperingFeedSequence, double thickness) {
//        BigStorageDTO bigStorageDTO = null;
//        BigStorageCage bigStorageCage = null;
//        //获取笼内当前版图每个格子已有玻璃的最小版序 获取笼内当前版图的所有玻璃信息
//        List<BigStorageCageDetails> cageDetailsList = bigStorageCageDetailsService.list(new QueryWrapper<BigStorageCageDetails>()
//                .select("slot", "min(tempering_feed_sequence) as tempering_feed_sequence")
//                .eq("engineer_id", engineerId).eq("tempering_layout_id", temperingLayoutId)
//                .in("state", Const.GLASS_STATE_IN_ALL_ZERO).groupBy("slot").orderByAsc("min(tempering_feed_sequence)"));
//        if (CollectionUtils.isNotEmpty(cageDetailsList)) {
//            Integer minLength = cageDetailsList.stream().filter(e -> e.getTemperingFeedSequence() > temperingFeedSequence)
//                    .mapToInt(BigStorageCageDetails::getTemperingFeedSequence).min().orElse(1000);
//            List<GlassInfo> infoList = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>()
//                    .notInSql(GlassInfo::getGlassId, "select glass_id from damage where tempering_layout_id = " + temperingLayoutId + " and engineer_id = '" + engineerId + "'")
//                    .eq(GlassInfo::getTemperingLayoutId, temperingLayoutId).eq(GlassInfo::getEngineerId, engineerId).orderByAsc(GlassInfo::getTemperingFeedSequence));
//            int remainWidth = carWidth;
//            int trainNumber = 1;
//            int serialNumber = 0;
//            int min = 0;
//            int temp = infoList.get(0).getTemperingFeedSequence();
//            int slot = 0;
//            int resultTrainNumber = 0;
//            for (GlassInfo e : infoList) {
//                int maxLength = Math.max((int) e.getWidth(), (int) e.getHeight());
//                if (serialNumber >= outCarMaxSize || maxLength > remainWidth || e.getTemperingFeedSequence() >= minLength) {
//                    if (resultTrainNumber != 0) {
//                        min = temp;
//                        break;
//                    }
//                    temp = e.getTemperingFeedSequence();
//                    remainWidth = carWidth;
//                    trainNumber = trainNumber + 1;
//                    serialNumber = 0;
//                }
//                if (temperingFeedSequence == e.getTemperingFeedSequence()) {
//                    resultTrainNumber = trainNumber;
//                }
//                remainWidth = remainWidth - maxLength - glassGap > 0 ? remainWidth - maxLength - glassGap : 0;
//                serialNumber += 1;
//                log.info("{},{},{}", trainNumber, remainWidth, serialNumber);
//                if (e.getTemperingFeedSequence().equals(infoList.get(infoList.size() - 1).getTemperingFeedSequence())) {
//                    min = temp;
//                }
//            }
//            for (BigStorageCageDetails item : cageDetailsList) {
//                if (min <= item.getTemperingFeedSequence() && item.getTemperingFeedSequence() < minLength) {
//                    slot = item.getSlot();
//                    bigStorageCage = bigStorageCageService.getOne(new LambdaQueryWrapper<BigStorageCage>()
//                            .eq(BigStorageCage::getSlot, slot).eq(BigStorageCage::getEnableState, Const.SLOT_ON));
//                    break;
//                }
//            }
//        }
//
//        if (bigStorageCage != null) {
//            bigStorageDTO = new BigStorageDTO();
//            bigStorageDTO.setWidth(bigStorageCage.getRemainWidth());
//            bigStorageDTO.setSlot(bigStorageCage.getSlot());
//            bigStorageDTO.setDeviceId(bigStorageCage.getDeviceId());
//            return bigStorageDTO;
//        }
//
//        bigStorageCage = bigStorageCageService.getOne(new LambdaQueryWrapper<BigStorageCage>()
//                .eq(BigStorageCage::getEnableState, Const.SLOT_ON)
//                .eq(BigStorageCage::getRemainWidth, slotWidth).orderByAsc(BigStorageCage::getSlot)
//                .inSql(BigStorageCage::getDeviceId,
//                        "select distinct device_id from big_storage_cage_details where engineer_id = '" + engineerId + "' and tempering_layout_id = " + temperingLayoutId)
//                .last("limit 1"));
//        if (null != bigStorageCage) {
//            log.info("根据版图id找到笼子内的目标格子:{}", bigStorageCage.getSlot());
//            bigStorageDTO = new BigStorageDTO();
//            bigStorageDTO.setWidth(bigStorageCage.getRemainWidth());
//            bigStorageDTO.setSlot(bigStorageCage.getSlot());
//            bigStorageDTO.setDeviceId(bigStorageCage.getDeviceId());
//            return bigStorageDTO;
//
//        }
//
//        //获取玻璃的厚度:重新选笼子需要按照笼子可放玻璃厚度进行选择 因为子查询排序对主sql无影响,所以先执行子查询获取顺序,然后一次去查询
//        List<Integer> deviceUsedList = bigStorageCageService.queryFreeDeviceByUsed(thickness);
//        for (Integer item : deviceUsedList) {
//            bigStorageCage = bigStorageCageService.getOne(new LambdaQueryWrapper<BigStorageCage>()
//                    .eq(BigStorageCage::getRemainWidth, slotWidth).orderByAsc(BigStorageCage::getSlot)
//                    .eq(BigStorageCage::getEnableState, Const.SLOT_ON)
//                    .eq(BigStorageCage::getDeviceId, item)
//                    .last("limit 1"));
//            if (null != bigStorageCage) {
//                log.info("按照存笼玻璃格子数占用最少方式获取信息格子为:{}", bigStorageCage.getSlot());
//                bigStorageDTO = new BigStorageDTO();
//                bigStorageDTO.setWidth(bigStorageCage.getRemainWidth());
//                bigStorageDTO.setSlot(bigStorageCage.getSlot());
//                bigStorageDTO.setDeviceId(bigStorageCage.getDeviceId());
//                return bigStorageDTO;
//            }
//        }
//        Assert.isTrue(null != bigStorageCage, "没有空余的笼子存放玻璃");
//        return bigStorageDTO;
//    }
//
//}
hangzhoumesParent/moduleService/CacheVerticalGlassModule/src/main/java/com/mes/tools/service/impl/BigStorageBaseServiceImpl.java
@@ -13,13 +13,14 @@
import com.mes.bigstoragetask.entity.BigStorageCageFeedTask;
import com.mes.common.S7object;
import com.mes.common.config.Const;
import com.mes.common.config.ConstSysConfig;
import com.mes.device.PlcParameterObject;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.sysconfig.service.SysConfigService;
import com.mes.tools.S7control;
import com.mes.tools.service.BigStorageBaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -47,22 +48,27 @@
    @Resource
    GlassInfoService glassInfoService;
    @Value("${mes.slotWidth}")
    private Integer slotWidth;
    @Resource
    SysConfigService sysConfigService;
    @Value("${mes.carWidth}")
    private Integer carWidth;
    @Value("${mes.outCarMaxSize}")
    private Integer outCarMaxSize;
    @Value("${mes.glassGap}")
    private Integer glassGap;
//    @Value("${mes.slotWidth}")
//    private Integer slotWidth;
//
//    @Value("${mes.carWidth}")
//    private Integer carWidth;
//
//    @Value("${mes.outCarMaxSize}")
//    private Integer outCarMaxSize;
//
//    @Value("${mes.glassGap}")
//    private Integer glassGap;
    @Override
    public void updateSlotRemainBySlots(List<Integer> slotList) {
        //获取格子内所有的玻璃信息
        Integer slotWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_WIDTH);
        int glassGap = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_GLASS_GAP);
        List<BigStorageCageDetails> inSlotGlassList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                .in(BigStorageCageDetails::getSlot, slotList).in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
        Map<Integer, Double> slotRemainMap = new HashMap<>();
@@ -574,13 +580,16 @@
            List<GlassInfo> infoList = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>()
                    .notInSql(GlassInfo::getGlassId, "select glass_id from damage where tempering_layout_id = " + temperingLayoutId + " and engineer_id = '" + engineerId + "'")
                    .eq(GlassInfo::getTemperingLayoutId, temperingLayoutId).eq(GlassInfo::getEngineerId, engineerId).orderByAsc(GlassInfo::getTemperingFeedSequence));
            int remainWidth = carWidth;
            int remainWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_CAR_WIDTH);
            int trainNumber = 1;
            int serialNumber = 0;
            int min = 0;
            int temp = infoList.get(0).getTemperingFeedSequence();
            int slot = 0;
            int resultTrainNumber = 0;
            int outCarMaxSize = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_OUT_CAR_SIZE);
            int carWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_CAR_WIDTH);
            int glassGap = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_GLASS_GAP);
            for (GlassInfo e : infoList) {
                int maxLength = Math.max((int) e.getWidth(), (int) e.getHeight());
                if (serialNumber >= outCarMaxSize || maxLength > remainWidth || e.getTemperingFeedSequence() >= minLength) {
@@ -620,7 +629,7 @@
            bigStorageDTO.setDeviceId(bigStorageCage.getDeviceId());
            return bigStorageDTO;
        }
        int slotWidth = sysConfigService.queryConfigValue(ConstSysConfig.VERTICAL_SLOT_WIDTH);
        bigStorageCage = bigStorageCageService.getOne(new LambdaQueryWrapper<BigStorageCage>()
                .eq(BigStorageCage::getEnableState, Const.SLOT_ON)
                .eq(BigStorageCage::getRemainWidth, slotWidth).orderByAsc(BigStorageCage::getSlot)
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/java/com/mes/job/PlcTemperingGlassTask.java
@@ -4,12 +4,10 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.mes.common.config.Const;
import com.mes.damage.entity.Damage;
import com.mes.damage.service.DamageService;
import com.mes.engineering.entity.Engineering;
import com.mes.largenscreen.entity.PieChartVO;
import com.mes.temperingglass.service.TemperingGlassInfoService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.service.TemperingGlassInfoService;
import com.mes.tools.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@@ -18,7 +16,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @author SNG-010
@@ -41,7 +38,7 @@
    public void temperingGlassHome() {
        JSONObject jsonObject = new JSONObject();
        //正在等待进片的玻璃
        List<TemperingGlassInfo> waitingGlass = temperingAgoService.selectWaitingGlass();
        List<TemperingGlassInfo> waitingGlass = temperingAgoService.selectWaitingGlassByOpc();
        if (waitingGlass != null) {
            jsonObject.append("waitingGlass", waitingGlass);
        }
hangzhoumesParent/moduleService/TemperingGlassModule/src/main/java/com/mes/job/TemperingTask.java
@@ -5,9 +5,11 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mes.common.S7object;
import com.mes.common.config.Const;
import com.mes.common.config.ConstSysConfig;
import com.mes.damage.entity.Damage;
import com.mes.damage.service.DamageService;
import com.mes.device.PlcParameterObject;
import com.mes.sysconfig.service.SysConfigService;
import com.mes.sysdict.entity.SysDictData;
import com.mes.sysdict.service.SysDictDataService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
@@ -18,7 +20,6 @@
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Comparator;
@@ -47,14 +48,13 @@
    @Autowired
    private SysDictDataService sysDictDataService;
    @Autowired
    private SysConfigService sysConfigService;
    private static final String ALONE_STATE = "0";
    @Value("${mes.width}")
    private Integer temperingWidth;
    @Value("${mes.height}")
    private Integer temperingHeight;
//    @Scheduled(fixedDelay = 1000)
    //    @Scheduled(fixedDelay = 1000)
    public void temperingGlassBefore() {
        Date startDate = new Date();
        log.info("本次任务开始执行时间:{}", startDate);
@@ -105,6 +105,8 @@
        double maxArea = temperingGlassList.stream().mapToDouble(e -> e.getWidth() * e.getHeight()).max().orElse(0.0);
        double minArea = temperingGlassList.stream().mapToDouble(e -> e.getWidth() * e.getHeight()).min().orElse(0.0);
        double areaDifference = (10000 * (maxArea - minArea) / maxArea);
        Integer temperingHeight = sysConfigService.queryConfigValue(ConstSysConfig.TEMPERING_HEIGHT);
        Integer temperingWidth = sysConfigService.queryConfigValue(ConstSysConfig.TEMPERING_HEIGHT);
        double loadingRate = (int) (10000 * sumArea / (temperingHeight * temperingWidth));
        TemperingRecord temperingRecord = new TemperingRecord();
        temperingRecord.setEngineerId(maxGlassInfo.getEngineerId());