wangfei
2025-04-21 09402133807b1e774e658a13ad365b2e6efca25b
hangzhoumesParent/moduleService/CacheGlassModule/src/main/java/com/mes/job/CacheGlassTask.java
@@ -1,875 +1,873 @@
package com.mes.job;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.json.JSONObject;
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.query.MPJQueryWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
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.edgstoragecage.entity.EdgStorageCage;
import com.mes.edgstoragecage.entity.EdgStorageCageDetails;
import com.mes.edgstoragecage.service.EdgStorageCageDetailsService;
import com.mes.edgstoragecage.service.EdgStorageCageService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.taskcache.entity.TaskCache;
import com.mes.taskcache.service.TaskCacheService;
import com.mes.tools.WebSocketServer;
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 java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * @Author : zhoush
 * @Date: 2024/5/8 8:17
 * @Description:
 */
@Component
@Slf4j
public class CacheGlassTask {
    @Autowired
    TaskCacheService taskCacheService;
    @Autowired
    GlassInfoService glassInfoService;
    @Autowired
    EdgStorageCageService edgStorageCageService;
    @Autowired
    EdgStorageCageDetailsService edgStorageCageDetailsService;
    @Autowired
    EdgGlassTaskInfoService edgGlassTaskInfoService;
    @Autowired
    WebSocketServer webServerService;
    @Autowired
    DamageService damageService;
    @Value("${mes.threshold}")
    private int threshold;
    @Value("${mes.ratio}")
    private int ratio;
    @Value("${mes.sequence.order}")
    private boolean sequenceOrder;
    @Value("${mes.max.firstLength}")
    private String firstLength;
    @Value("${mes.max.secondLength}")
    private String secondLength;
    @Value("${mes.cache.cacheWidth}")
    private double cacheWidth;
    @Value("${mes.cache.cacheHeight}")
    private double cacheHeight;
    @Value("${mes.min.one.firstLength}")
    private String minOneFirstLength;
    @Value("${mes.min.one.secondLength}")
    private String minOneSecondLength;
    @Value("${mes.min.two.firstLength}")
    private String minTwoFirstLength;
    @Value("${mes.min.two.secondLength}")
    private String minTwoSecondLength;
    public static String engineerId = "";
    //    @Scheduled(fixedDelay = 1000)
    public void plcHomeEdgTask() {
        Date startDate = new Date();
        log.info("本次任务开始执行时间:{}", startDate);
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        String taskRequestTypeValue = plcParameterObject.getPlcParameter("A06_request_word").getValue();
        String glassIdeValue = plcParameterObject.getPlcParameter("A05_scanning_ID").getValue();
        String confirmationWrodValue = plcParameterObject.getPlcParameter("MES_confirmation_word").getValue();
        //A08  A09表示线路相同  可做等价  无数据转int异常
        String out08Glassstate = plcParameterObject.getPlcParameter("A08_glass_status").getValue();
        String out10Glassstate = plcParameterObject.getPlcParameter("A10_glass_status").getValue();
        String confirmationWrodAddress = plcParameterObject.getPlcParameter("MES_confirmation_word").getAddress();
        String currentSlot = plcParameterObject.getPlcParameter("Current_slot").getValue();
//        taskRequestTypeValue = "2";
//        out08Glassstate = "1";
//        out10Glassstate = "1";
//        currentSlot = "5";
//        confirmationWrodValue = "0";
//        glassIdeValue = "P24092706|15|5";
        log.info("1、获取到的请求字为:{},获取到的扫描ID为:{},获取到的确认字为:{},获取到的出片状态分别为:A09:{}、A10:{},当前格子号为:{}",
                taskRequestTypeValue, glassIdeValue, confirmationWrodValue, out08Glassstate, out10Glassstate, currentSlot);
        if ("0".equals(taskRequestTypeValue)) {
            if ("0".equals(confirmationWrodValue)) {
                log.info("2、获取到的请求字为0,且确认字为0,不执行任务");
                return;
            }
            log.info("2、获取到的请求字为0,将确认字改为0");
            S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 0);
            return;
        }
        if (!"0".equals(confirmationWrodValue)) {
            log.info("2、获取到的请求字不为0,将确认字不为0,直接结束");
            return;
        }
        boolean result = edgStorageCageDetailsService.inToVerify(glassIdeValue);
        if ("1".equals(taskRequestTypeValue) && result) {
            log.info("2、进片请求,且确认字为0,执行进片任务,扫码重复ID验证【有重复=false,无重复=true】:{}", result);
            inTo(glassIdeValue, confirmationWrodAddress, currentSlot);
        } else if ("2".equals(taskRequestTypeValue)) {
            //09空闲 :1      10空闲 :2        都空闲:3    其他0
            log.info("2、出片请求,且确认字为0,执行出片任务");
            outTo(Integer.parseInt(out08Glassstate),
                    Integer.parseInt(out10Glassstate), confirmationWrodAddress, "", Integer.parseInt(currentSlot));
        } else if ("3".equals(taskRequestTypeValue)) {
            log.info("2、进片和出片都空闲,执行出片任务");
            //加笼子里面是否有玻璃,有先出,无玻璃先进
            boolean outFlase = outTo(Integer.parseInt(out08Glassstate),
                    Integer.parseInt(out10Glassstate), confirmationWrodAddress, glassIdeValue, Integer.parseInt(currentSlot));
            log.info("出片任务是否完成:{},且玻璃id:{}不为空则执行进片任务,扫码重复ID验证【有重复=false,无重复=true】:{}", outFlase, glassIdeValue, result);
            if (!outFlase && StringUtils.isNotBlank(glassIdeValue) && result) {
                inTo(glassIdeValue, confirmationWrodAddress, currentSlot);
            }
        }
        Date endDate = new Date();
        log.info("本次任务结束时间:{},共耗时:{}ms", endDate, endDate.getTime() - startDate.getTime());
    }
    //    @Scheduled(fixedDelay = 1000)
    public void dealDamageTask() {
        Date startDate = new Date();
        log.info("卧式理片破损玻璃清除任务开始执行时间:{}", startDate);
        List<TaskCache> taskCacheList = taskCacheService.list(new LambdaQueryWrapper<TaskCache>().in(TaskCache::getTaskStatus, Const.GLASS_STATE_DAMAGE_TAKE)
                .in(TaskCache::getTaskType, Const.GLASS_CACHE_TYPE_OUT_ALL));
        if (CollectionUtils.isNotEmpty(taskCacheList)) {
            //获取破损/拿走玻璃id
            List<String> glassList = taskCacheList.stream().map(TaskCache::getGlassId).collect(Collectors.toList());
            //将磨边队列的数据删除
            edgGlassTaskInfoService.remove(new LambdaQueryWrapper<EdgGlassTaskInfo>().in(EdgGlassTaskInfo::getGlassId, glassList));
            //将任务表中的数据删除
            taskCacheService.remove(new LambdaQueryWrapper<TaskCache>().in(TaskCache::getGlassId, glassList).in(TaskCache::getTaskType, Const.GLASS_CACHE_TYPE_OUT_ALL));
            List<Damage> damageList = taskCacheList.stream().map(e -> {
                Damage damage = new Damage();
                damage.setGlassId(e.getGlassId());
                damage.setLine(e.getEndCell());
                damage.setWorkingProcedure("磨边");
                damage.setRemark("磨边前卧式理片");
                damage.setStatus(1);
                damage.setType(e.getTaskStatus());
                return damage;
            }).collect(Collectors.toList());
            damageService.batchInsertDamage(damageList);
        }
        Date endDate = new Date();
        log.info("本次任务结束时间:{},共耗时:{}ms", endDate, endDate.getTime() - startDate.getTime());
    }
    /**
     * 进片任务
     *
     * @param glassId
     * @param confirmationWrodAddress
     * @param currentSlot
     */
    public void inTo(String glassId, String confirmationWrodAddress, String currentSlot) {
        log.info("1、按照玻璃id:{}获取玻璃小片信息,当前格子为:{}", glassId, currentSlot);
        GlassInfo feedGlassInfo = glassInfoService.getOne(
                new LambdaQueryWrapper<GlassInfo>()
                        .eq(GlassInfo::getGlassId, glassId)
        );
        if (Math.max(feedGlassInfo.getWidth(), feedGlassInfo.getHeight()) > cacheWidth || Math.min(feedGlassInfo.getWidth(), feedGlassInfo.getHeight()) > cacheHeight) {
            log.info("1.1、玻璃超过卧式理片最大尺寸:{}", feedGlassInfo);
            return;
        }
        //添加进片任务  查找空格
        EdgStorageCage nearestEmpty = edgStorageCageService.selectNearestEmpty(Integer.parseInt(currentSlot), Boolean.FALSE);
        Assert.isTrue(null != nearestEmpty, "格子已满");
        log.info("2、查询卧式理片笼里面的空格:{}", nearestEmpty);
        //查询玻璃信息
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
        if (glassInfo == null) {
            return;
        }
        if ((glassInfo.getWidth() < Double.parseDouble(minTwoFirstLength) && glassInfo.getHeight() < Double.parseDouble(minTwoSecondLength)) || (glassInfo.getWidth() < Double.parseDouble(minTwoSecondLength) && glassInfo.getHeight() < Double.parseDouble(minTwoFirstLength))) {
            log.info("3、玻璃信息不符合进入理片笼最小尺寸,玻璃信息为{}", glassInfo);
            return;
        }
        log.info("4、将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
        EdgStorageCageDetails details = new EdgStorageCageDetails();
        BeanUtils.copyProperties(glassInfo, details);
        details.setState(Const.GLASS_STATE_IN);
        details.setSlot(nearestEmpty.getSlot());
        details.setDeviceId(nearestEmpty.getDeviceId());
        edgStorageCageDetailsService.save(details);
        damageService.deleteByGlassId(glassId);
        log.info("5、玻璃信息已存入理片笼详情表,玻璃信息为{}", details);
        //添加进片任务
        boolean taskCache = saveTaskCache(details.getGlassId(), 0, nearestEmpty.getSlot(), Const.GLASS_CACHE_TYPE_IN);
        log.info("6、生成进片任务信息存入任务表是否完成:{}", taskCache);
        S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 1);
        log.info("7、发送确认字完成");
    }
    /**
     * 查询玻璃并进行交换
     *
     * @param glassId
     * @return
     */
    public String queryAndChangeGlass(String glassId) {
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
//                .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1"));
        Assert.isFalse(null == glassInfo, "玻璃信息不存在");        //按照玻璃尺寸
        LambdaQueryWrapper<GlassInfo> queryWrapper = new LambdaQueryWrapper<GlassInfo>()
                .eq(GlassInfo::getWidth, glassInfo.getWidth())
                .eq(GlassInfo::getHeight, glassInfo.getHeight())
                .eq(GlassInfo::getThickness, glassInfo.getThickness())
                .eq(GlassInfo::getFilmsid, glassInfo.getFilmsid())
                .eq(GlassInfo::getFlowCardId, glassInfo.getFlowCardId())
                .eq(GlassInfo::getTotalLayer, glassInfo.getTotalLayer())
                .eq(GlassInfo::getLayer, glassInfo.getLayer())
                .eq(GlassInfo::getEngineerId, glassInfo.getEngineerId())
                .notInSql(GlassInfo::getGlassId, "select distinct glass_id from edg_storage_cage_details " +
                        "where engineer_id = '" + glassInfo.getEngineerId() + "' and width = " + glassInfo.getWidth() + " and height = " + glassInfo.getHeight()
                        + " and state != 100")
                .orderByAsc(GlassInfo::getTemperingLayoutId)
                .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence)
                .last("Limit 1");
        GlassInfo swapGlassInfo = glassInfoService.getOne(queryWrapper);
        if (swapGlassInfo != null && !glassInfo.getGlassId().equals(swapGlassInfo.getGlassId())) {
            String swapGlassId = swapGlassInfo.getGlassId();
            log.info("将玻璃{}和玻璃{},信息互换,进玻璃 {}", glassInfo, swapGlassInfo, swapGlassInfo);
            swapGlassInfo.setGlassId(glassId);
            glassInfo.setGlassId(swapGlassId);
            glassInfoService.updateById(swapGlassInfo);
            glassInfoService.updateById(glassInfo);
            return swapGlassId;
        }
        return "";
    }
    /**
     * 查询卧式理片玻璃并进行交换
     *
     * @param glassId
     * @return
     */
    public void queryEdgAndChangeGlass(String glassId, String swapGlassId) {
        if (StringUtils.isBlank(swapGlassId)) {
            log.info("当前出笼玻璃不存在需要替换的玻璃");
            return;
        }
        //获取待出笼的玻璃
        EdgStorageCageDetails glassInfo = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                .eq(EdgStorageCageDetails::getGlassId, glassId).eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN));
//        获取待出笼的玻璃需要替换的玻璃信息
        EdgStorageCageDetails swapGlassDetailInfo = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                .eq(EdgStorageCageDetails::getGlassId, swapGlassId).eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN));
//      玻璃小片表中玻璃已经替换,更新卧理笼内现有的准备出笼的玻璃信息,
        if (null == swapGlassDetailInfo) {
            GlassInfo glassInfoBase = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                    .eq(GlassInfo::getGlassId, glassId));
            //需要替换的玻璃为存进卧理,仅需更新当前需要出笼的玻璃信息即可
            edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getGlassId, glassId)
                    .set(EdgStorageCageDetails::getTemperingLayoutId, glassInfoBase.getTemperingLayoutId())
                    .set(EdgStorageCageDetails::getTemperingFeedSequence, glassInfoBase.getTemperingFeedSequence()));
        } else {
            //需要替换的玻璃都在卧理内,按照玻璃id对调玻璃信息:对调玻璃id即可
            edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getId, glassInfo.getId())
                    .set(EdgStorageCageDetails::getTemperingLayoutId, swapGlassDetailInfo.getTemperingLayoutId())
                    .set(EdgStorageCageDetails::getTemperingFeedSequence, swapGlassDetailInfo.getTemperingFeedSequence())
            );
            edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getId, swapGlassDetailInfo.getId())
                    .set(EdgStorageCageDetails::getTemperingLayoutId, glassInfo.getTemperingLayoutId())
                    .set(EdgStorageCageDetails::getTemperingFeedSequence, glassInfo.getTemperingFeedSequence())
            );
        }
    }
    /**
     * 出片任务
     *
     * @param out08Glassstate
     * @param out10Glassstate
     * @param confirmationWrodAddress
     * @param glassId
     * @param currentSlot
     */
    public boolean outTo(int out08Glassstate, int out10Glassstate, String confirmationWrodAddress, String glassId, int currentSlot) {
        //逻辑步骤:
//        0、A09、A10是否空闲,是否可以执行出片任务
//        1、获取钢化版图是否超过阈值
//        1.1、超过阈值:获取当前最小版图需要出片的玻璃信息
//        1.1.1、获取两条线最后一次出片的任务信息
//        1.1.2、按照出片信息去详情表查询格子在笼子里面剩余相同尺寸的玻璃数据
//        1.1.3、判断哪条线玻璃数量在理片笼内的数据最少,决定最小版图走该条线(问题:如果这条线非空闲,直接结束)
//        1.2、未超过阈值:
//        1.2.1、获取程序那条线空闲
//        1.2.2、获取该条线最后一次出片的任务信息
//        1.2.3、按照出片信息去详情表查询格子在笼子里面剩余相同尺寸的玻璃数据且以版图id、版序升序排序  取第一块玻璃出片
//        2、如果没有历史出片任务
//        2.1、出当前版图id最小版序最小的玻璃(问题:两条线都没有历史任务,出片时两条线的玻璃尺寸相同,是否找尺寸不同的)
        if ((out08Glassstate == 2 && out10Glassstate == 2) || (out08Glassstate == 0 && out10Glassstate == 0)) {
            log.info("A09、A10为{},{}非自动状态,无法出片", out08Glassstate, out10Glassstate);
            return Boolean.FALSE;
        }
        log.info("0、出片任务出的状态:A09:【{}】;A10:【{}】)", out08Glassstate, out10Glassstate);
        //定义出片玻璃信息
        int endcell = 0;
        EdgStorageCageDetails glassInfo = null;
        boolean flag = queryMaxMinDiff(threshold);
        log.info("1、获取钢化版图是否超过阈值:{}", flag);
        if (flag) {
            //获取当前最小版图需要出片的玻璃信息
            glassInfo = queryMinGlass(0.0, 0.0, glassId);
            log.info("1.1、超过阈值:获取当前最小版图需要出片的玻璃信息:{}", glassInfo);
            if (glassInfo == null) {
                log.info("笼子内和待进片没有玻璃");
                return Boolean.FALSE;
            }
            EdgStorageCageDetails a09EdgGlass = queryGlassByTaskCache(Const.A09_OUT_TARGET_POSITION, Const.GLASS_CACHE_TYPE_OUT_ALL);
            EdgStorageCageDetails a10EdgGlass = queryGlassByTaskCache(Const.A10_OUT_TARGET_POSITION, Const.GLASS_CACHE_TYPE_OUT_ALL);
            endcell = queryLineByGlassInfo(a09EdgGlass, a10EdgGlass, glassInfo, out08Glassstate, out10Glassstate);
        } else {
            //按照状态判断两条线走那条线
            endcell = computerLineByState(out08Glassstate, out10Glassstate);
            if (out08Glassstate == 1 && out10Glassstate == 1) {
                EdgStorageCageDetails a09EdgGlass = queryGlassByTaskCache(Const.A09_OUT_TARGET_POSITION, Const.GLASS_CACHE_TYPE_OUT_ALL);
                EdgStorageCageDetails a10EdgGlass = queryGlassByTaskCache(Const.A10_OUT_TARGET_POSITION, Const.GLASS_CACHE_TYPE_OUT_ALL);
                if (a09EdgGlass == null && a10EdgGlass == null) {
                    MPJQueryWrapper<EdgStorageCageDetails> wrapper = new MPJQueryWrapper<>();
                    wrapper.select("count(t.glass_id), t.width, t.height")
                            .eq("t.state", Const.GLASS_STATE_IN)
                            .inSql("t.slot", "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON)
                            .groupBy("t.width, t.height");
                    if (endcell == Const.A10_OUT_TARGET_POSITION) {
                        wrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
                                "case when width < height then width else height end as second_length from edg_storage_cage_details) t1 " +
                                "on t.glass_id = t1.glass_id and (t1.first_length between " + minTwoFirstLength + " and " + firstLength
                                + " and t1.second_length between " + minTwoSecondLength + " and " + secondLength + ") ");
                    } else {
                        wrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
                                "case when width < height then width else height end as second_length from edg_storage_cage_details) t1 " +
                                "on t.glass_id = t1.glass_id and (t1.first_length >=" + minOneFirstLength + " and t1.second_length>=" + minOneSecondLength + ") ");
                    }
                    wrapper.last("order by count(t.glass_id) desc  limit 2");
                    List<EdgStorageCageDetails> list = edgStorageCageDetailsService.list(wrapper);
                    if (CollectionUtil.isEmpty(list)) {
                        MPJQueryWrapper<GlassInfo> queryWrapper = new MPJQueryWrapper<GlassInfo>()
                                .selectAll(GlassInfo.class).eq("t.glass_id", glassId);
                        if (endcell == Const.A10_OUT_TARGET_POSITION) {
                            queryWrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
                                    "case when width < height then width else height end as second_length from edg_storage_cage_details) t1 " +
                                    "on t.glass_id = t1.glass_id and (t1.first_length between " + minTwoFirstLength + " and " + firstLength
                                    + " and t1.second_length between " + minTwoSecondLength + " and " + secondLength + ") ");
                        } else {
                            queryWrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
                                    "case when width < height then width else height end as second_length from edg_storage_cage_details) t1 " +
                                    "on t.glass_id = t1.glass_id and (t1.first_length >=" + minOneFirstLength + " and t1.second_length>=" + minOneSecondLength + ") ");
                        }
                        GlassInfo one = glassInfoService.getOne(queryWrapper);
                        if (one != null) {
                            EdgStorageCageDetails resultDetails = new EdgStorageCageDetails();
                            BeanUtils.copyProperties(one, resultDetails);
                            glassInfo = resultDetails;
                        } else {
                            log.info("获取笼内玻璃和待进片玻璃为空或者不符合磨边尺寸");
                        }
                    } else {
                        glassInfo = queryMinGlass(list.get(0).getWidth(), list.get(0).getHeight(), glassId);
                    }
                } else if (a09EdgGlass != null && a10EdgGlass != null) {
                    List<EdgStorageCageDetails> a09Count = queryGlassByTaskLine(Const.A09_OUT_TARGET_POSITION);
                    List<EdgStorageCageDetails> a10Count = queryGlassByTaskLine(Const.A10_OUT_TARGET_POSITION);
                    endcell = a09Count.size() > a10Count.size() ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
                    glassInfo = a09Count.size() > a10Count.size() ? queryMinGlass(a09EdgGlass.getWidth(), a09EdgGlass.getHeight(), glassId)
                            : queryMinGlass(a10EdgGlass.getWidth(), a10EdgGlass.getHeight(), glassId);
                } else {
                    //按照历史任务获取需要执行的路线,如果该条线笼内无玻璃 走其他逻辑
                    endcell = a09EdgGlass == null ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
                    List<EdgStorageCageDetails> details = queryGlassByTaskLine(endcell);
                    if (CollectionUtil.isEmpty(details)) {
                        int othercell = endcell == Const.A10_OUT_TARGET_POSITION ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
                        glassInfo = queryChangeGlassInfo(othercell, glassId);
                    } else {
                        glassInfo = a09EdgGlass != null ? queryMinGlass(a09EdgGlass.getWidth(), a09EdgGlass.getHeight(), glassId)
                                : queryMinGlass(a10EdgGlass.getWidth(), a10EdgGlass.getHeight(), glassId);
                    }
                }
            } else {
                List<EdgStorageCageDetails> edgStorageCageDetails = queryGlassByTaskLine(endcell);
                if (CollectionUtil.isNotEmpty(edgStorageCageDetails)) {
                    glassInfo = edgStorageCageDetails.get(0);
                } else {
                    //获取笼内所有玻璃信息,包括待进片的
                    List<EdgStorageCageDetails> glassList = queryEdgAllGlass(glassId);
                    if (CollectionUtil.isEmpty(glassList)) {
                        log.info("笼内和待进片都没有玻璃");
                        return Boolean.FALSE;
                    }
                    if (glassList.size() == 1 && glassId.equals(glassList.get(0).getGlassId())) {
                        glassInfo = glassList.get(0);
                    } else {
                        int othercell = endcell == Const.A10_OUT_TARGET_POSITION ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
                        glassInfo = queryChangeGlassInfo(othercell, glassId);
                    }
                }
            }
        }
        return saveOutGlassMessageBySlot(glassInfo, endcell, confirmationWrodAddress, glassId, currentSlot);
    }
    /**
     * 获取笼子内所有玻璃信息,包括待进片的
     *
     * @param glassId
     */
    private List<EdgStorageCageDetails> queryEdgAllGlass(String glassId) {
        List<EdgStorageCageDetails> glassList = new ArrayList<>();
        //获取待进片玻璃
        //todo: 获取正在执行的工程信息
        if (StringUtils.isNotBlank(glassId)) {
            GlassInfo one = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                    .eq(GlassInfo::getGlassId, glassId));
//                    .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1"));
            EdgStorageCageDetails resultDetails = new EdgStorageCageDetails();
            BeanUtils.copyProperties(one, resultDetails);
            glassList.add(resultDetails);
        }
        //获取笼内玻璃
        List<EdgStorageCageDetails> details = edgStorageCageDetailsService.selectJoinList(EdgStorageCageDetails.class, new MPJLambdaWrapper<EdgStorageCageDetails>().selectAll(EdgStorageCageDetails.class)
                .leftJoin(EdgStorageCage.class, on -> on.eq(EdgStorageCage::getSlot, EdgStorageCageDetails::getSlot).eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN))
                .eq(EdgStorageCage::getEnableState, Const.SLOT_ON));
        glassList.addAll(details);
        return glassList;
    }
    /**
     * 获取详情表内最大最小版图id的差值,判断是否出最小版图玻璃
     *
     * @return
     */
    public boolean queryMaxMinDiff(int threshold) {
        //获取笼子内最大版图id和最小版图id插值,判断是否大于阈值,大于阈值直接出最小版图玻璃
        QueryWrapper<EdgStorageCageDetails> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("max(tempering_layout_id)-min(tempering_layout_id) as diff")
                .eq("state", Const.GLASS_STATE_IN)
                .inSql("slot", "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON);
        List<Object> list = edgStorageCageDetailsService.listObjs(queryWrapper);
        //获取笼内玻璃版图差值是否大于阈值
        if (CollectionUtil.isNotEmpty(list)) {
            Long diff = (Long) list.get(0);
            return diff > threshold;
        } else {
            return Boolean.FALSE;
        }
    }
    /**
     * 获取当前最小版图需要出片的玻璃信息
     *
     * @param width
     * @param height
     */
    private EdgStorageCageDetails queryMinGlass(double width, double height, String glassId) {
        //获取表内版图id最小的玻璃信息
        EdgStorageCageDetails glassDetails = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                .eq(EdgStorageCageDetails::getState, 100)
                .eq(width != 0, EdgStorageCageDetails::getWidth, width)
                .eq(height != 0, EdgStorageCageDetails::getHeight, height)
                .inSql(EdgStorageCageDetails::getSlot, "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON)
                .orderByAsc(EdgStorageCageDetails::getTemperingLayoutId)
                .orderBy(Boolean.TRUE, sequenceOrder, EdgStorageCageDetails::getTemperingFeedSequence)
                .last("limit 1"));
        if (StringUtils.isBlank(glassId)) {
            return glassDetails;
        }
        GlassInfo one = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                        .eq(GlassInfo::getGlassId, glassId)
//                .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1")
        );
        EdgStorageCageDetails resultDetails = new EdgStorageCageDetails();
        BeanUtils.copyProperties(one, resultDetails);
        if (null == glassDetails) {
            return resultDetails;
        }
        return resultDetails.getTemperingLayoutId() <= glassDetails.getTemperingLayoutId() && resultDetails.getTemperingFeedSequence() > glassDetails.getTemperingFeedSequence() ?
                resultDetails : glassDetails;
    }
    /**
     * 获取任务表中指定线路笼子内还剩余的玻璃信息
     */
    private List<EdgStorageCageDetails> queryGlassByTaskLine(int line) {
        //获取任务表中最后一次出片的玻璃id
        TaskCache taskCache = taskCacheService.queryGlassByTaskCache(line, Const.GLASS_CACHE_TYPE_OUT_ALL);
        if (null == taskCache) {
            log.info("没有找到{}线任务信息", line);
            return new ArrayList<>();
        }
        MPJQueryWrapper<EdgStorageCageDetails> mpjLambdaWrapper = new MPJQueryWrapper<>();
        mpjLambdaWrapper.select("t1.*")
                .innerJoin("edg_storage_cage_details t1 on t.width = t1.width and t.height = t1.height")
                .eq("t.glass_id", taskCache.getGlassId())
                .ne("t1.glass_id", taskCache.getGlassId())
                .eq("t1.state", Const.GLASS_STATE_IN)
                .inSql("t1.slot", "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON)
                .orderByAsc("t1.tempering_layout_id")
                .orderBy(Boolean.TRUE, sequenceOrder, "t1.tempering_feed_sequence");
        List<EdgStorageCageDetails> details = edgStorageCageDetailsService.selectJoinList(EdgStorageCageDetails.class, mpjLambdaWrapper);
        if (CollectionUtil.isEmpty(details)) {
            return new ArrayList<>();
        }
        return details;
    }
    /**
     * 按照任务类型、线号获取任务信息
     *
     * @param line
     * @param taskTypes
     * @return
     */
    private EdgStorageCageDetails queryGlassByTaskCache(int line, List<Integer> taskTypes) {
        TaskCache taskCache = taskCacheService.queryGlassByTaskCache(line, taskTypes);
        if (null == taskCache) {
            log.info("没有找到{}线任务信息", line);
            return null;
        }
        return edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>().eq(EdgStorageCageDetails::getGlassId, taskCache.getGlassId())
                .inSql(EdgStorageCageDetails::getSlot, "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON)
                .last(" limit 1 "));
    }
    /**
     * 按照任务玻璃信息和待出片玻璃信息获取出片路径
     *
     * @param a08EdgStorageCageDetails 09号线出片玻璃信息
     * @param a10EdgStorageCageDetails 10号线出片玻璃信息
     * @param glassInfo                带出片玻璃信息
     * @param out08Glassstate          09号线空闲状态
     * @param out10Glassstate          10号线空闲状态
     * @return
     */
    private Integer queryLineByGlassInfo(EdgStorageCageDetails a08EdgStorageCageDetails, EdgStorageCageDetails a10EdgStorageCageDetails,
                                         EdgStorageCageDetails glassInfo, int out08Glassstate, int out10Glassstate) {
        //存在出片任务 07为空
        if (out08Glassstate == 1 && out10Glassstate == 1) {
            boolean b08 = a08EdgStorageCageDetails != null && a08EdgStorageCageDetails.getHeight() == glassInfo.getHeight()
                    && a08EdgStorageCageDetails.getWidth() == glassInfo.getWidth();
            boolean b10 = a10EdgStorageCageDetails != null && a10EdgStorageCageDetails.getHeight() == glassInfo.getHeight()
                    && a10EdgStorageCageDetails.getWidth() == glassInfo.getWidth();
            if (b08) {
                return Const.A09_OUT_TARGET_POSITION;
            }
            if (b10) {
                return Const.A10_OUT_TARGET_POSITION;
            }
        }
        return computerLineByState(out08Glassstate, out10Glassstate);
    }
    /**
     * 按照尺寸出玻璃
     *
     * @param endcell endcell = out08Glassstate == 1 ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
     * @param glassId
     * @return
     */
    public EdgStorageCageDetails queryChangeGlassInfo(int endcell, String glassId) {
        //获取笼子内数量前二的玻璃数量
        MPJQueryWrapper<EdgStorageCageDetails> wrapper = new MPJQueryWrapper<>();
        wrapper.select("count(t.glass_id) as count, t.width, t.height")
                .eq("t.state", Const.GLASS_STATE_IN)
                .inSql("t.slot", "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON)
                .groupBy("t.width, t.height");
        if (endcell == Const.A10_OUT_TARGET_POSITION) {
            wrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
                    "case when width < height then width else height end as second_length from edg_storage_cage_details) t1 " +
                    "on t.glass_id = t1.glass_id and (t1.first_length >= " + minOneFirstLength + " and t1.second_length >= " + minOneSecondLength + ")");
        } else {
            wrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
                    "case when width < height then width else height end as second_length from edg_storage_cage_details) t1 " +
                    "on t.glass_id = t1.glass_id and (t1.first_length between " + minTwoFirstLength + " and " + firstLength
                    + " and t1.second_length between " + minTwoSecondLength + " and " + secondLength + ") ");
        }
        wrapper.last("order by count(t.glass_id) desc  limit 2");
        List<EdgStorageCageDetails> list = edgStorageCageDetailsService.list(wrapper);
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        log.info("获取笼子内数量前二的玻璃数量:{}", list);
        //获取宽高拍第一的玻璃信息
        EdgStorageCageDetails firstSize = list.get(0);
        Integer firstCount = firstSize.getCount();
        double firstWidth = firstSize.getWidth();
        double firstHeight = firstSize.getHeight();
        if (list.size() == 1) {
            return queryMinGlass(firstWidth, firstHeight, glassId);
        }
        //获取宽高拍第二的玻璃信息
        EdgStorageCageDetails secondSize = list.get(1);
        Integer secondCount = secondSize.getCount();
        double secondWidth = secondSize.getWidth();
        double secondHeight = secondSize.getHeight();
        //获取数量前2的玻璃数量比例
        Integer mix = firstCount / secondCount;
        log.info("获取玻璃数量前2的玻璃占比为:{}", mix);
        if (mix >= 2) {
            log.info("获取玻璃数量前2的玻璃占比为{},大于2,直接出玻璃数据的最多的,宽:{},高:{}", mix, firstWidth, firstHeight);
            return queryMinGlass(firstWidth, firstHeight, glassId);
        } else {
            log.info("获取玻璃数量前2的玻璃占比为{},小于2", mix);
            //获取任务表中最后一次出片的玻璃id
            TaskCache taskCache = taskCacheService.queryGlassByTaskCache(endcell, Const.GLASS_CACHE_TYPE_OUT_ALL);
            log.info("获取任务表中{}线最后一次出片的玻璃任务信息:{}", endcell, taskCache);
            if (null == taskCache) {
                log.info("{}线没有出片任务信息,直接出片", endcell);
                return queryMinGlass(firstSize.getWidth(), firstSize.getHeight(), glassId);
            }
            EdgStorageCageDetails outGlassInfo = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getGlassId, taskCache.getGlassId()).last("limit 1"));
            log.info("{}线有出片任务信息,任务信息为{},玻璃信息为{}", endcell, taskCache, outGlassInfo);
            if (outGlassInfo.getWidth() == firstWidth && outGlassInfo.getHeight() == firstHeight) {
                log.info("数量最多的宽{}高{}和{}线任务的宽{}高{}相同,出数量排第二的玻璃,宽{}高{}",
                        firstWidth, firstHeight, endcell, outGlassInfo.getWidth(), outGlassInfo.getHeight(), secondWidth, secondHeight);
                return queryMinGlass(secondWidth, secondHeight, glassId);
            } else {
                log.info("数量第二多的宽{}高{}和{}线任务的宽{}高{}相同,出数量排第二的玻璃,宽{}高{}",
                        secondWidth, secondHeight, endcell, outGlassInfo.getWidth(), outGlassInfo.getHeight(), firstWidth, firstHeight);
                return queryMinGlass(firstWidth, firstHeight, glassId);
            }
        }
    }
    /**
     * 保存出片任务相关信息
     *
     * @param glassInfo
     * @param endcell
     * @param confirmationWrodAddress
     * @param glassId
     * @return
     */
    private boolean saveOutGlassMessage(EdgStorageCageDetails glassInfo, int endcell, String confirmationWrodAddress, String glassId, Integer currentSlot) {
        if (glassInfo != null) {
            log.info("4、添加出片任务,玻璃id:{},任务类型:{},起始位置:{},结束位置:{}", glassInfo.getGlassId(),
                    2, glassInfo.getSlot(), endcell);
            if (glassInfo.getGlassId().equals(glassId)) {
                log.info("5、直通任务,将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
                EdgStorageCageDetails details = new EdgStorageCageDetails();
                BeanUtils.copyProperties(glassInfo, details);
                EdgStorageCage nearestEmpty = edgStorageCageService.selectNearestEmpty(currentSlot, Boolean.TRUE);
                Assert.isTrue(null != nearestEmpty, "格子已满,无法执行直通任务");
                log.info("3、查询卧式理片笼里面的空格:{}", nearestEmpty);
                details.setSlot(nearestEmpty.getSlot());
                details.setState(Const.GLASS_STATE_OUT);
                edgStorageCageDetailsService.save(details);
                boolean taskCacheStatus = saveTaskCache(glassInfo.getGlassId(), nearestEmpty.getSlot(), endcell, Const.GLASS_CACHE_TYPE_THROUGH);
                log.info("6、添加出片任务是否完成:{}", taskCacheStatus);
            } else {
                log.info("5、非直通任务,将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
                LambdaUpdateWrapper<EdgStorageCageDetails> wrapper = new LambdaUpdateWrapper<>();
                wrapper.eq(EdgStorageCageDetails::getGlassId, glassInfo.getGlassId()).set(EdgStorageCageDetails::getState, Const.GLASS_STATE_OUT);
                edgStorageCageDetailsService.update(wrapper);
                log.info("5、更新出片玻璃的状态为{}", Const.GLASS_STATE_OUT);
                boolean taskCacheStatus = saveTaskCache(glassInfo.getGlassId(), glassInfo.getSlot(), endcell, Const.GLASS_CACHE_TYPE_OUT);
                log.info("6、添加出片任务是否完成:{}", taskCacheStatus);
            }
            boolean glassSizeStatus = saveGlassSize(glassInfo, endcell);
            log.info("7、添加出片玻璃尺寸信息到磨边前玻璃表是否完成:{}", glassSizeStatus);
            S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 1);
            log.info("8、发送确认字已完成");
            Damage damage = new Damage();
            damage.setGlassId(glassInfo.getGlassId());
            damage.setWorkingProcedure("切割");
            damage.setLine(1001);
            damage.setType(1);
            damage.setRemark("过卧式理片");
            damageService.insertDamage(damage);
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
    /**
     * 保存出片任务相关信息
     *
     * @param glassInfo
     * @param endcell
     * @param confirmationWrodAddress
     * @param glassId
     * @return
     */
    private boolean saveOutGlassMessageBySlot(EdgStorageCageDetails glassInfo, int endcell, String confirmationWrodAddress, String glassId, Integer currentSlot) {
        if (glassInfo != null) {
            log.info("4、添加出片任务,玻璃id:{},任务类型:{},起始位置:{},结束位置:{}", glassInfo.getGlassId(),
                    2, glassInfo.getSlot(), endcell);
            if (glassInfo.getGlassId().equals(glassId)) {
                log.info("5、直通任务,将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
                EdgStorageCageDetails details = new EdgStorageCageDetails();
                //玻璃信息替换
                String glassIdChange = queryAndChangeGlass(glassId);
                if (StringUtils.isBlank(glassIdChange)) {
                    BeanUtils.copyProperties(glassInfo, details);
                } else {
                    GlassInfo one = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
                    BeanUtils.copyProperties(one, details);
                }
                EdgStorageCage nearestEmpty = edgStorageCageService.selectNearestEmpty(currentSlot, Boolean.TRUE);
                Assert.isTrue(null != nearestEmpty, "格子已满,无法执行直通任务");
                log.info("3、查询卧式理片笼里面的空格:{}", nearestEmpty);
                details.setSlot(nearestEmpty.getSlot());
                details.setState(Const.GLASS_STATE_OUT);
                edgStorageCageDetailsService.save(details);
                boolean taskCacheStatus = saveTaskCache(glassInfo.getGlassId(), nearestEmpty.getSlot(), endcell, Const.GLASS_CACHE_TYPE_THROUGH);
                log.info("6、添加出片任务是否完成:{}", taskCacheStatus);
            } else {
                log.info("5、非直通任务,将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
                if (!glassInfo.getSlot().equals(currentSlot)) {
                    EdgStorageCageDetails currentGlass = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                            .eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN)
                            .eq(EdgStorageCageDetails::getSlot, currentSlot).eq(EdgStorageCageDetails::getWidth, glassInfo.getWidth())
                            .eq(EdgStorageCageDetails::getHeight, glassInfo.getHeight()).eq(EdgStorageCageDetails::getThickness, glassInfo.getThickness())
                    );
                    if (null != currentGlass) {
                        glassInfo = currentGlass;
                    }
                }
                //玻璃信息替换
                String glassIdChange = queryAndChangeGlass(glassInfo.getGlassId());
                //处理在卧理内的玻璃信息:笼内的数据处理
                queryEdgAndChangeGlass(glassInfo.getGlassId(), glassIdChange);
                LambdaUpdateWrapper<EdgStorageCageDetails> wrapper = new LambdaUpdateWrapper<>();
                wrapper.eq(EdgStorageCageDetails::getGlassId, glassInfo.getGlassId()).set(EdgStorageCageDetails::getState, Const.GLASS_STATE_OUT);
                edgStorageCageDetailsService.update(wrapper);
                log.info("5、更新出片玻璃的状态为{}", Const.GLASS_STATE_OUT);
                boolean taskCacheStatus = saveTaskCache(glassInfo.getGlassId(), glassInfo.getSlot(), endcell, Const.GLASS_CACHE_TYPE_OUT);
                log.info("6、添加出片任务是否完成:{}", taskCacheStatus);
            }
            boolean glassSizeStatus = saveGlassSize(glassInfo, endcell);
            log.info("7、添加出片玻璃尺寸信息到磨边前玻璃表是否完成:{}", glassSizeStatus);
            S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 1);
            log.info("8、发送确认字已完成");
            Damage damage = new Damage();
            damage.setGlassId(glassInfo.getGlassId());
            damage.setWorkingProcedure("切割");
            damage.setLine(1001);
            damage.setType(1);
            damage.setRemark("过卧式理片");
            damageService.insertDamage(damage);
            damageService.deleteByGlassId(glassId);
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
    /**
     * 添加理片笼任务
     *
     * @param glassId
     * @param startcell
     * @param endcell
     * @param taskType
     * @return
     */
    private boolean saveTaskCache(String glassId, int startcell, int endcell, int taskType) {
        TaskCache taskCache = new TaskCache();
        taskCache.setGlassId(glassId);
        taskCache.setTaskStatus(0);
        taskCache.setStartCell(startcell);
        taskCache.setEndCell(endcell);
        taskCache.setTaskType(taskType);
        taskCache.setCreateTime(new Date());
        return taskCacheService.save(taskCache);
    }
    /**
     * 添加磨边队列信息
     *
     * @param glassInfo
     * @param endcell
     * @return
     */
    private boolean saveGlassSize(EdgStorageCageDetails glassInfo, int endcell) {
        EdgGlassTaskInfo edgGlassTaskInfo = new EdgGlassTaskInfo();
        BeanUtils.copyProperties(glassInfo, edgGlassTaskInfo);
        edgGlassTaskInfo.setHeight((int) (glassInfo.getHeight() * ratio));
        edgGlassTaskInfo.setWidth((int) (glassInfo.getWidth() * ratio));
        edgGlassTaskInfo.setThickness((int) (glassInfo.getThickness() * ratio));
        edgGlassTaskInfo.setState(Const.EDG_GLASS_BEFORE);
        edgGlassTaskInfo.setLine(endcell);
        edgGlassTaskInfo.setCreateTime(new Date());
        edgGlassTaskInfo.setUpdateTime(new Date());
        //先将历史对列表中本玻璃的数据删除,重新新增一份最新的数据
        edgGlassTaskInfoService.remove(new LambdaQueryWrapper<EdgGlassTaskInfo>().eq(EdgGlassTaskInfo::getGlassId, glassInfo.getGlassId()));
        return edgGlassTaskInfoService.save(edgGlassTaskInfo);
    }
    /**
     * 计算出片线路
     * 已排除都为2  都为0 的情况
     *
     * @param out08Glassstate
     * @param out10Glassstate
     * @return
     */
    private int computerLineByState(int out08Glassstate, int out10Glassstate) {
        if (out08Glassstate == 0) {
            if (out10Glassstate == 2) {
                return Const.A09_OUT_TARGET_POSITION;
            } else {
                return Const.A10_OUT_TARGET_POSITION;
            }
        } else if (out08Glassstate == 1) {
            return Const.A09_OUT_TARGET_POSITION;
        } else {
            return Const.A10_OUT_TARGET_POSITION;
        }
    }
}
//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.query.QueryWrapper;
//import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
//import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
//import com.github.yulichang.query.MPJQueryWrapper;
//import com.github.yulichang.wrapper.MPJLambdaWrapper;
//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.edgstoragecage.entity.EdgStorageCage;
//import com.mes.edgstoragecage.entity.EdgStorageCageDetails;
//import com.mes.edgstoragecage.service.EdgStorageCageDetailsService;
//import com.mes.edgstoragecage.service.EdgStorageCageService;
//import com.mes.glassinfo.entity.GlassInfo;
//import com.mes.glassinfo.service.GlassInfoService;
//import com.mes.taskcache.entity.TaskCache;
//import com.mes.taskcache.service.TaskCacheService;
//import com.mes.tools.WebSocketServer;
//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 java.util.ArrayList;
//import java.util.Date;
//import java.util.List;
//import java.util.stream.Collectors;
//
///**
// * @Author : zhoush
// * @Date: 2024/5/8 8:17
// * @Description:
// */
//@Component
//@Slf4j
//public class CacheGlassTask {
//
//    @Autowired
//    TaskCacheService taskCacheService;
//    @Autowired
//    GlassInfoService glassInfoService;
//    @Autowired
//    EdgStorageCageService edgStorageCageService;
//    @Autowired
//    EdgStorageCageDetailsService edgStorageCageDetailsService;
//
//    @Autowired
//    EdgGlassTaskInfoService edgGlassTaskInfoService;
//
//    @Autowired
//    WebSocketServer webServerService;
//    @Autowired
//    DamageService damageService;
//
//    @Value("${mes.threshold}")
//    private int threshold;
//
//    @Value("${mes.ratio}")
//    private int ratio;
//
//    @Value("${mes.sequence.order}")
//    private boolean sequenceOrder;
//
//    @Value("${mes.max.firstLength}")
//    private String firstLength;
//
//    @Value("${mes.max.secondLength}")
//    private String secondLength;
//
//    @Value("${mes.cache.cacheWidth}")
//    private double cacheWidth;
//
//    @Value("${mes.cache.cacheHeight}")
//    private double cacheHeight;
//
//    @Value("${mes.min.one.firstLength}")
//    private String minOneFirstLength;
//
//    @Value("${mes.min.one.secondLength}")
//    private String minOneSecondLength;
//
//    @Value("${mes.min.two.firstLength}")
//    private String minTwoFirstLength;
//
//    @Value("${mes.min.two.secondLength}")
//    private String minTwoSecondLength;
//
//    public static String engineerId = "";
//
//    //    @Scheduled(fixedDelay = 1000)
//    public void plcHomeEdgTask() {
//        Date startDate = new Date();
//        log.info("本次任务开始执行时间:{}", startDate);
//        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
//        String taskRequestTypeValue = plcParameterObject.getPlcParameter("A06_request_word").getValue();
//        String glassIdeValue = plcParameterObject.getPlcParameter("A05_scanning_ID").getValue();
//        String confirmationWrodValue = plcParameterObject.getPlcParameter("MES_confirmation_word").getValue();
//        //A08  A09表示线路相同  可做等价  无数据转int异常
//        String out08Glassstate = plcParameterObject.getPlcParameter("A08_glass_status").getValue();
//        String out10Glassstate = plcParameterObject.getPlcParameter("A10_glass_status").getValue();
//        String confirmationWrodAddress = plcParameterObject.getPlcParameter("MES_confirmation_word").getAddress();
//        String currentSlot = plcParameterObject.getPlcParameter("Current_slot").getValue();
//
////        taskRequestTypeValue = "2";
////        out08Glassstate = "1";
////        out10Glassstate = "1";
////        currentSlot = "5";
////        confirmationWrodValue = "0";
////        glassIdeValue = "P24092706|15|5";
//
//        log.info("1、获取到的请求字为:{},获取到的扫描ID为:{},获取到的确认字为:{},获取到的出片状态分别为:A09:{}、A10:{},当前格子号为:{}",
//                taskRequestTypeValue, glassIdeValue, confirmationWrodValue, out08Glassstate, out10Glassstate, currentSlot);
//
//        if ("0".equals(taskRequestTypeValue)) {
//            if ("0".equals(confirmationWrodValue)) {
//                log.info("2、获取到的请求字为0,且确认字为0,不执行任务");
//                return;
//            }
//            log.info("2、获取到的请求字为0,将确认字改为0");
//            S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 0);
//            return;
//        }
//        if (!"0".equals(confirmationWrodValue)) {
//            log.info("2、获取到的请求字不为0,将确认字不为0,直接结束");
//            return;
//        }
//        boolean result = edgStorageCageDetailsService.inToVerify(glassIdeValue);
//        if ("1".equals(taskRequestTypeValue) && result) {
//            log.info("2、进片请求,且确认字为0,执行进片任务,扫码重复ID验证【有重复=false,无重复=true】:{}", result);
////            inTo(glassIdeValue, confirmationWrodAddress, currentSlot);
//        } else if ("2".equals(taskRequestTypeValue)) {
//            //09空闲 :1      10空闲 :2        都空闲:3    其他0
//            log.info("2、出片请求,且确认字为0,执行出片任务");
//            outTo(Integer.parseInt(out08Glassstate),
//                    Integer.parseInt(out10Glassstate), confirmationWrodAddress, "", Integer.parseInt(currentSlot));
//        } else if ("3".equals(taskRequestTypeValue)) {
//            log.info("2、进片和出片都空闲,执行出片任务");
//            //加笼子里面是否有玻璃,有先出,无玻璃先进
//            boolean outFlase = outTo(Integer.parseInt(out08Glassstate),
//                    Integer.parseInt(out10Glassstate), confirmationWrodAddress, glassIdeValue, Integer.parseInt(currentSlot));
//            log.info("出片任务是否完成:{},且玻璃id:{}不为空则执行进片任务,扫码重复ID验证【有重复=false,无重复=true】:{}", outFlase, glassIdeValue, result);
//            if (!outFlase && StringUtils.isNotBlank(glassIdeValue) && result) {
////                inTo(glassIdeValue, confirmationWrodAddress, currentSlot);
//            }
//        }
//        Date endDate = new Date();
//        log.info("本次任务结束时间:{},共耗时:{}ms", endDate, endDate.getTime() - startDate.getTime());
//    }
//
//
//    //    @Scheduled(fixedDelay = 1000)
//    public void dealDamageTask() {
//        Date startDate = new Date();
//        log.info("卧式理片破损玻璃清除任务开始执行时间:{}", startDate);
//        List<TaskCache> taskCacheList = taskCacheService.list(new LambdaQueryWrapper<TaskCache>().in(TaskCache::getTaskStatus, Const.GLASS_STATE_DAMAGE_TAKE)
//                .in(TaskCache::getTaskType, Const.GLASS_CACHE_TYPE_OUT_ALL));
//        if (CollectionUtils.isNotEmpty(taskCacheList)) {
//            //获取破损/拿走玻璃id
//            List<String> glassList = taskCacheList.stream().map(TaskCache::getGlassId).collect(Collectors.toList());
//            //将磨边队列的数据删除
//            edgGlassTaskInfoService.remove(new LambdaQueryWrapper<EdgGlassTaskInfo>().in(EdgGlassTaskInfo::getGlassId, glassList));
//            //将任务表中的数据删除
//            taskCacheService.remove(new LambdaQueryWrapper<TaskCache>().in(TaskCache::getGlassId, glassList).in(TaskCache::getTaskType, Const.GLASS_CACHE_TYPE_OUT_ALL));
//            List<Damage> damageList = taskCacheList.stream().map(e -> {
//                Damage damage = new Damage();
//                damage.setGlassId(e.getGlassId());
//                damage.setLine(e.getEndCell());
//                damage.setWorkingProcedure("磨边");
//                damage.setRemark("磨边前卧式理片");
//                damage.setStatus(1);
//                damage.setType(e.getTaskStatus());
//                return damage;
//            }).collect(Collectors.toList());
//            damageService.batchInsertDamage(damageList);
//        }
//        Date endDate = new Date();
//        log.info("本次任务结束时间:{},共耗时:{}ms", endDate, endDate.getTime() - startDate.getTime());
//    }
//
//
//    /**
//     * 进片任务
//     *
//     * @param glassId
//     * @param confirmationWrodAddress
//     * @param currentSlot
//     */
////    public void inTo(String glassId, String confirmationWrodAddress, String currentSlot) {
////        log.info("1、按照玻璃id:{}获取玻璃小片信息,当前格子为:{}", glassId, currentSlot);
////
////        GlassInfo feedGlassInfo = glassInfoService.getOne(
////                new LambdaQueryWrapper<GlassInfo>()
////                        .eq(GlassInfo::getGlassId, glassId)
////        );
////        if (Math.max(feedGlassInfo.getWidth(), feedGlassInfo.getHeight()) > cacheWidth || Math.min(feedGlassInfo.getWidth(), feedGlassInfo.getHeight()) > cacheHeight) {
////            log.info("1.1、玻璃超过卧式理片最大尺寸:{}", feedGlassInfo);
////            return;
////        }
////
////        //添加进片任务  查找空格
////        EdgStorageCage nearestEmpty = edgStorageCageService.selectNearestEmpty(task.getCurrentCell(), Integer.parseInt(currentSlot), Boolean.FALSE);
////        Assert.isTrue(null != nearestEmpty, "格子已满");
////        log.info("2、查询卧式理片笼里面的空格:{}", nearestEmpty);
////
////        //查询玻璃信息
////        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
////        if (glassInfo == null) {
////            return;
////        }
////        if ((glassInfo.getWidth() < Double.parseDouble(minTwoFirstLength) && glassInfo.getHeight() < Double.parseDouble(minTwoSecondLength)) || (glassInfo.getWidth() < Double.parseDouble(minTwoSecondLength) && glassInfo.getHeight() < Double.parseDouble(minTwoFirstLength))) {
////            log.info("3、玻璃信息不符合进入理片笼最小尺寸,玻璃信息为{}", glassInfo);
////            return;
////        }
////        log.info("4、将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
////        EdgStorageCageDetails details = new EdgStorageCageDetails();
////        BeanUtils.copyProperties(glassInfo, details);
////        details.setState(Const.GLASS_STATE_IN);
////        details.setSlot(nearestEmpty.getSlot());
////        details.setDeviceId(nearestEmpty.getDeviceId());
////        edgStorageCageDetailsService.save(details);
////        damageService.deleteByGlassId(glassId);
////        log.info("5、玻璃信息已存入理片笼详情表,玻璃信息为{}", details);
////        //添加进片任务
////        boolean taskCache = saveTaskCache(details.getGlassId(), 0, nearestEmpty.getSlot(), Const.GLASS_CACHE_TYPE_IN);
////        log.info("6、生成进片任务信息存入任务表是否完成:{}", taskCache);
////
////        S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 1);
////        log.info("7、发送确认字完成");
////
////    }
//
//    /**
//     * 查询玻璃并进行交换
//     *
//     * @param glassId
//     * @return
//     */
//    public String queryAndChangeGlass(String glassId) {
//        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
////                .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1"));
//        Assert.isFalse(null == glassInfo, "玻璃信息不存在");        //按照玻璃尺寸
//        LambdaQueryWrapper<GlassInfo> queryWrapper = new LambdaQueryWrapper<GlassInfo>()
//                .eq(GlassInfo::getWidth, glassInfo.getWidth())
//                .eq(GlassInfo::getHeight, glassInfo.getHeight())
//                .eq(GlassInfo::getThickness, glassInfo.getThickness())
//                .eq(GlassInfo::getFilmsid, glassInfo.getFilmsid())
//                .eq(GlassInfo::getFlowCardId, glassInfo.getFlowCardId())
//                .eq(GlassInfo::getTotalLayer, glassInfo.getTotalLayer())
//                .eq(GlassInfo::getLayer, glassInfo.getLayer())
//                .eq(GlassInfo::getEngineerId, glassInfo.getEngineerId())
//                .notInSql(GlassInfo::getGlassId, "select distinct glass_id from edg_storage_cage_details " +
//                        "where engineer_id = '" + glassInfo.getEngineerId() + "' and width = " + glassInfo.getWidth() + " and height = " + glassInfo.getHeight()
//                        + " and state != 100")
//                .orderByAsc(GlassInfo::getTemperingLayoutId)
//                .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence)
//                .last("Limit 1");
//        GlassInfo swapGlassInfo = glassInfoService.getOne(queryWrapper);
//        if (swapGlassInfo != null && !glassInfo.getGlassId().equals(swapGlassInfo.getGlassId())) {
//            String swapGlassId = swapGlassInfo.getGlassId();
//            log.info("将玻璃{}和玻璃{},信息互换,进玻璃 {}", glassInfo, swapGlassInfo, swapGlassInfo);
//            swapGlassInfo.setGlassId(glassId);
//            glassInfo.setGlassId(swapGlassId);
//            glassInfoService.updateById(swapGlassInfo);
//            glassInfoService.updateById(glassInfo);
//            return swapGlassId;
//        }
//        return "";
//    }
//
//
//    /**
//     * 查询卧式理片玻璃并进行交换
//     *
//     * @param glassId
//     * @return
//     */
//    public void queryEdgAndChangeGlass(String glassId, String swapGlassId) {
//        if (StringUtils.isBlank(swapGlassId)) {
//            log.info("当前出笼玻璃不存在需要替换的玻璃");
//            return;
//        }
//        //获取待出笼的玻璃
//        EdgStorageCageDetails glassInfo = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
//                .eq(EdgStorageCageDetails::getGlassId, glassId).eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN));
////        获取待出笼的玻璃需要替换的玻璃信息
//        EdgStorageCageDetails swapGlassDetailInfo = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
//                .eq(EdgStorageCageDetails::getGlassId, swapGlassId).eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN));
//
////      玻璃小片表中玻璃已经替换,更新卧理笼内现有的准备出笼的玻璃信息,
//        if (null == swapGlassDetailInfo) {
//            GlassInfo glassInfoBase = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
//                    .eq(GlassInfo::getGlassId, glassId));
//            //需要替换的玻璃为存进卧理,仅需更新当前需要出笼的玻璃信息即可
//            edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
//                    .eq(EdgStorageCageDetails::getGlassId, glassId)
//                    .set(EdgStorageCageDetails::getTemperingLayoutId, glassInfoBase.getTemperingLayoutId())
//                    .set(EdgStorageCageDetails::getTemperingFeedSequence, glassInfoBase.getTemperingFeedSequence()));
//        } else {
//            //需要替换的玻璃都在卧理内,按照玻璃id对调玻璃信息:对调玻璃id即可
//            edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
//                    .eq(EdgStorageCageDetails::getId, glassInfo.getId())
//                    .set(EdgStorageCageDetails::getTemperingLayoutId, swapGlassDetailInfo.getTemperingLayoutId())
//                    .set(EdgStorageCageDetails::getTemperingFeedSequence, swapGlassDetailInfo.getTemperingFeedSequence())
//            );
//            edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
//                    .eq(EdgStorageCageDetails::getId, swapGlassDetailInfo.getId())
//                    .set(EdgStorageCageDetails::getTemperingLayoutId, glassInfo.getTemperingLayoutId())
//                    .set(EdgStorageCageDetails::getTemperingFeedSequence, glassInfo.getTemperingFeedSequence())
//            );
//        }
//    }
//
//    /**
//     * 出片任务
//     *
//     * @param out08Glassstate
//     * @param out10Glassstate
//     * @param confirmationWrodAddress
//     * @param glassId
//     * @param currentSlot
//     */
//    public boolean outTo(int out08Glassstate, int out10Glassstate, String confirmationWrodAddress, String glassId, int currentSlot) {
//        //逻辑步骤:
////        0、A09、A10是否空闲,是否可以执行出片任务
////        1、获取钢化版图是否超过阈值
////        1.1、超过阈值:获取当前最小版图需要出片的玻璃信息
////        1.1.1、获取两条线最后一次出片的任务信息
////        1.1.2、按照出片信息去详情表查询格子在笼子里面剩余相同尺寸的玻璃数据
////        1.1.3、判断哪条线玻璃数量在理片笼内的数据最少,决定最小版图走该条线(问题:如果这条线非空闲,直接结束)
////        1.2、未超过阈值:
////        1.2.1、获取程序那条线空闲
////        1.2.2、获取该条线最后一次出片的任务信息
////        1.2.3、按照出片信息去详情表查询格子在笼子里面剩余相同尺寸的玻璃数据且以版图id、版序升序排序  取第一块玻璃出片
////        2、如果没有历史出片任务
////        2.1、出当前版图id最小版序最小的玻璃(问题:两条线都没有历史任务,出片时两条线的玻璃尺寸相同,是否找尺寸不同的)
//        if ((out08Glassstate == 2 && out10Glassstate == 2) || (out08Glassstate == 0 && out10Glassstate == 0)) {
//            log.info("A09、A10为{},{}非自动状态,无法出片", out08Glassstate, out10Glassstate);
//            return Boolean.FALSE;
//        }
//        log.info("0、出片任务出的状态:A09:【{}】;A10:【{}】)", out08Glassstate, out10Glassstate);
//        //定义出片玻璃信息
//        int endcell = 0;
//        EdgStorageCageDetails glassInfo = null;
//
//
//        boolean flag = queryMaxMinDiff(threshold);
//        log.info("1、获取钢化版图是否超过阈值:{}", flag);
//        if (flag) {
//            //获取当前最小版图需要出片的玻璃信息
//            glassInfo = queryMinGlass(0.0, 0.0, glassId);
//            log.info("1.1、超过阈值:获取当前最小版图需要出片的玻璃信息:{}", glassInfo);
//            if (glassInfo == null) {
//                log.info("笼子内和待进片没有玻璃");
//                return Boolean.FALSE;
//            }
//            EdgStorageCageDetails a09EdgGlass = queryGlassByTaskCache(Const.A09_OUT_TARGET_POSITION, Const.GLASS_CACHE_TYPE_OUT_ALL);
//            EdgStorageCageDetails a10EdgGlass = queryGlassByTaskCache(Const.A10_OUT_TARGET_POSITION, Const.GLASS_CACHE_TYPE_OUT_ALL);
//            endcell = queryLineByGlassInfo(a09EdgGlass, a10EdgGlass, glassInfo, out08Glassstate, out10Glassstate);
//        } else {
//            //按照状态判断两条线走那条线
//            endcell = computerLineByState(out08Glassstate, out10Glassstate);
//
//            if (out08Glassstate == 1 && out10Glassstate == 1) {
//                EdgStorageCageDetails a09EdgGlass = queryGlassByTaskCache(Const.A09_OUT_TARGET_POSITION, Const.GLASS_CACHE_TYPE_OUT_ALL);
//                EdgStorageCageDetails a10EdgGlass = queryGlassByTaskCache(Const.A10_OUT_TARGET_POSITION, Const.GLASS_CACHE_TYPE_OUT_ALL);
//                if (a09EdgGlass == null && a10EdgGlass == null) {
//                    MPJQueryWrapper<EdgStorageCageDetails> wrapper = new MPJQueryWrapper<>();
//                    wrapper.select("count(t.glass_id), t.width, t.height")
//                            .eq("t.state", Const.GLASS_STATE_IN)
//                            .inSql("t.slot", "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON)
//                            .groupBy("t.width, t.height");
//                    if (endcell == Const.A10_OUT_TARGET_POSITION) {
//                        wrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
//                                "case when width < height then width else height end as second_length from edg_storage_cage_details) t1 " +
//                                "on t.glass_id = t1.glass_id and (t1.first_length between " + minTwoFirstLength + " and " + firstLength
//                                + " and t1.second_length between " + minTwoSecondLength + " and " + secondLength + ") ");
//                    } else {
//                        wrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
//                                "case when width < height then width else height end as second_length from edg_storage_cage_details) t1 " +
//                                "on t.glass_id = t1.glass_id and (t1.first_length >=" + minOneFirstLength + " and t1.second_length>=" + minOneSecondLength + ") ");
//                    }
//                    wrapper.last("order by count(t.glass_id) desc  limit 2");
//                    List<EdgStorageCageDetails> list = edgStorageCageDetailsService.list(wrapper);
//                    if (CollectionUtil.isEmpty(list)) {
//                        MPJQueryWrapper<GlassInfo> queryWrapper = new MPJQueryWrapper<GlassInfo>()
//                                .selectAll(GlassInfo.class).eq("t.glass_id", glassId);
//                        if (endcell == Const.A10_OUT_TARGET_POSITION) {
//                            queryWrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
//                                    "case when width < height then width else height end as second_length from edg_storage_cage_details) t1 " +
//                                    "on t.glass_id = t1.glass_id and (t1.first_length between " + minTwoFirstLength + " and " + firstLength
//                                    + " and t1.second_length between " + minTwoSecondLength + " and " + secondLength + ") ");
//                        } else {
//                            queryWrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
//                                    "case when width < height then width else height end as second_length from edg_storage_cage_details) t1 " +
//                                    "on t.glass_id = t1.glass_id and (t1.first_length >=" + minOneFirstLength + " and t1.second_length>=" + minOneSecondLength + ") ");
//                        }
//                        GlassInfo one = glassInfoService.getOne(queryWrapper);
//                        if (one != null) {
//                            EdgStorageCageDetails resultDetails = new EdgStorageCageDetails();
//                            BeanUtils.copyProperties(one, resultDetails);
//                            glassInfo = resultDetails;
//                        } else {
//                            log.info("获取笼内玻璃和待进片玻璃为空或者不符合磨边尺寸");
//                        }
//                    } else {
//                        glassInfo = queryMinGlass(list.get(0).getWidth(), list.get(0).getHeight(), glassId);
//                    }
//                } else if (a09EdgGlass != null && a10EdgGlass != null) {
//                    List<EdgStorageCageDetails> a09Count = queryGlassByTaskLine(Const.A09_OUT_TARGET_POSITION);
//                    List<EdgStorageCageDetails> a10Count = queryGlassByTaskLine(Const.A10_OUT_TARGET_POSITION);
//                    endcell = a09Count.size() > a10Count.size() ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
//                    glassInfo = a09Count.size() > a10Count.size() ? queryMinGlass(a09EdgGlass.getWidth(), a09EdgGlass.getHeight(), glassId)
//                            : queryMinGlass(a10EdgGlass.getWidth(), a10EdgGlass.getHeight(), glassId);
//                } else {
//                    //按照历史任务获取需要执行的路线,如果该条线笼内无玻璃 走其他逻辑
//                    endcell = a09EdgGlass == null ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
//                    List<EdgStorageCageDetails> details = queryGlassByTaskLine(endcell);
//                    if (CollectionUtil.isEmpty(details)) {
//                        int othercell = endcell == Const.A10_OUT_TARGET_POSITION ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
//                        glassInfo = queryChangeGlassInfo(othercell, glassId);
//                    } else {
//                        glassInfo = a09EdgGlass != null ? queryMinGlass(a09EdgGlass.getWidth(), a09EdgGlass.getHeight(), glassId)
//                                : queryMinGlass(a10EdgGlass.getWidth(), a10EdgGlass.getHeight(), glassId);
//                    }
//                }
//            } else {
//                List<EdgStorageCageDetails> edgStorageCageDetails = queryGlassByTaskLine(endcell);
//                if (CollectionUtil.isNotEmpty(edgStorageCageDetails)) {
//                    glassInfo = edgStorageCageDetails.get(0);
//                } else {
//                    //获取笼内所有玻璃信息,包括待进片的
//                    List<EdgStorageCageDetails> glassList = queryEdgAllGlass(glassId);
//                    if (CollectionUtil.isEmpty(glassList)) {
//                        log.info("笼内和待进片都没有玻璃");
//                        return Boolean.FALSE;
//                    }
//                    if (glassList.size() == 1 && glassId.equals(glassList.get(0).getGlassId())) {
//                        glassInfo = glassList.get(0);
//                    } else {
//                        int othercell = endcell == Const.A10_OUT_TARGET_POSITION ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
//                        glassInfo = queryChangeGlassInfo(othercell, glassId);
//                    }
//                }
//            }
//        }
//        return saveOutGlassMessageBySlot(glassInfo, endcell, confirmationWrodAddress, glassId, currentSlot);
//    }
//
//    /**
//     * 获取笼子内所有玻璃信息,包括待进片的
//     *
//     * @param glassId
//     */
//    private List<EdgStorageCageDetails> queryEdgAllGlass(String glassId) {
//        List<EdgStorageCageDetails> glassList = new ArrayList<>();
//        //获取待进片玻璃
//        //todo: 获取正在执行的工程信息
//        if (StringUtils.isNotBlank(glassId)) {
//            GlassInfo one = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
//                    .eq(GlassInfo::getGlassId, glassId));
////                    .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1"));
//            EdgStorageCageDetails resultDetails = new EdgStorageCageDetails();
//            BeanUtils.copyProperties(one, resultDetails);
//            glassList.add(resultDetails);
//        }
//        //获取笼内玻璃
//        List<EdgStorageCageDetails> details = edgStorageCageDetailsService.selectJoinList(EdgStorageCageDetails.class, new MPJLambdaWrapper<EdgStorageCageDetails>().selectAll(EdgStorageCageDetails.class)
//                .leftJoin(EdgStorageCage.class, on -> on.eq(EdgStorageCage::getSlot, EdgStorageCageDetails::getSlot).eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN))
//                .eq(EdgStorageCage::getEnableState, Const.SLOT_ON));
//        glassList.addAll(details);
//        return glassList;
//
//    }
//
//    /**
//     * 获取详情表内最大最小版图id的差值,判断是否出最小版图玻璃
//     *
//     * @return
//     */
//    public boolean queryMaxMinDiff(int threshold) {
//        //获取笼子内最大版图id和最小版图id插值,判断是否大于阈值,大于阈值直接出最小版图玻璃
//        QueryWrapper<EdgStorageCageDetails> queryWrapper = new QueryWrapper<>();
//        queryWrapper.select("max(tempering_layout_id)-min(tempering_layout_id) as diff")
//                .eq("state", Const.GLASS_STATE_IN)
//                .inSql("slot", "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON);
//        List<Object> list = edgStorageCageDetailsService.listObjs(queryWrapper);
//        //获取笼内玻璃版图差值是否大于阈值
//        if (CollectionUtil.isNotEmpty(list)) {
//            Long diff = (Long) list.get(0);
//            return diff > threshold;
//        } else {
//            return Boolean.FALSE;
//        }
//    }
//
//    /**
//     * 获取当前最小版图需要出片的玻璃信息
//     *
//     * @param width
//     * @param height
//     */
//    private EdgStorageCageDetails queryMinGlass(double width, double height, String glassId) {
//        //获取表内版图id最小的玻璃信息
//        EdgStorageCageDetails glassDetails = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
//                .eq(EdgStorageCageDetails::getState, 100)
//                .eq(width != 0, EdgStorageCageDetails::getWidth, width)
//                .eq(height != 0, EdgStorageCageDetails::getHeight, height)
//                .inSql(EdgStorageCageDetails::getSlot, "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON)
//                .orderByAsc(EdgStorageCageDetails::getTemperingLayoutId)
//                .orderBy(Boolean.TRUE, sequenceOrder, EdgStorageCageDetails::getTemperingFeedSequence)
//                .last("limit 1"));
//        if (StringUtils.isBlank(glassId)) {
//            return glassDetails;
//        }
//        GlassInfo one = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
//                        .eq(GlassInfo::getGlassId, glassId)
////                .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1")
//        );
//        EdgStorageCageDetails resultDetails = new EdgStorageCageDetails();
//        BeanUtils.copyProperties(one, resultDetails);
//        if (null == glassDetails) {
//            return resultDetails;
//        }
//        return resultDetails.getTemperingLayoutId() <= glassDetails.getTemperingLayoutId() && resultDetails.getTemperingFeedSequence() > glassDetails.getTemperingFeedSequence() ?
//                resultDetails : glassDetails;
//    }
//
//    /**
//     * 获取任务表中指定线路笼子内还剩余的玻璃信息
//     */
//    private List<EdgStorageCageDetails> queryGlassByTaskLine(int line) {
//        //获取任务表中最后一次出片的玻璃id
//        TaskCache taskCache = taskCacheService.queryGlassByTaskCache(line, Const.GLASS_CACHE_TYPE_OUT_ALL);
//        if (null == taskCache) {
//            log.info("没有找到{}线任务信息", line);
//            return new ArrayList<>();
//        }
//        MPJQueryWrapper<EdgStorageCageDetails> mpjLambdaWrapper = new MPJQueryWrapper<>();
//        mpjLambdaWrapper.select("t1.*")
//                .innerJoin("edg_storage_cage_details t1 on t.width = t1.width and t.height = t1.height")
//                .eq("t.glass_id", taskCache.getGlassId())
//                .ne("t1.glass_id", taskCache.getGlassId())
//                .eq("t1.state", Const.GLASS_STATE_IN)
//                .inSql("t1.slot", "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON)
//                .orderByAsc("t1.tempering_layout_id")
//                .orderBy(Boolean.TRUE, sequenceOrder, "t1.tempering_feed_sequence");
//        List<EdgStorageCageDetails> details = edgStorageCageDetailsService.selectJoinList(EdgStorageCageDetails.class, mpjLambdaWrapper);
//        if (CollectionUtil.isEmpty(details)) {
//            return new ArrayList<>();
//        }
//        return details;
//    }
//
//    /**
//     * 按照任务类型、线号获取任务信息
//     *
//     * @param line
//     * @param taskTypes
//     * @return
//     */
//    private EdgStorageCageDetails queryGlassByTaskCache(int line, List<Integer> taskTypes) {
//        TaskCache taskCache = taskCacheService.queryGlassByTaskCache(line, taskTypes);
//        if (null == taskCache) {
//            log.info("没有找到{}线任务信息", line);
//            return null;
//        }
//        return edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>().eq(EdgStorageCageDetails::getGlassId, taskCache.getGlassId())
//                .inSql(EdgStorageCageDetails::getSlot, "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON)
//                .last(" limit 1 "));
//    }
//
//    /**
//     * 按照任务玻璃信息和待出片玻璃信息获取出片路径
//     *
//     * @param a08EdgStorageCageDetails 09号线出片玻璃信息
//     * @param a10EdgStorageCageDetails 10号线出片玻璃信息
//     * @param glassInfo                带出片玻璃信息
//     * @param out08Glassstate          09号线空闲状态
//     * @param out10Glassstate          10号线空闲状态
//     * @return
//     */
//    private Integer queryLineByGlassInfo(EdgStorageCageDetails a08EdgStorageCageDetails, EdgStorageCageDetails a10EdgStorageCageDetails,
//                                         EdgStorageCageDetails glassInfo, int out08Glassstate, int out10Glassstate) {
//        //存在出片任务 07为空
//        if (out08Glassstate == 1 && out10Glassstate == 1) {
//            boolean b08 = a08EdgStorageCageDetails != null && a08EdgStorageCageDetails.getHeight() == glassInfo.getHeight()
//                    && a08EdgStorageCageDetails.getWidth() == glassInfo.getWidth();
//            boolean b10 = a10EdgStorageCageDetails != null && a10EdgStorageCageDetails.getHeight() == glassInfo.getHeight()
//                    && a10EdgStorageCageDetails.getWidth() == glassInfo.getWidth();
//            if (b08) {
//                return Const.A09_OUT_TARGET_POSITION;
//            }
//            if (b10) {
//                return Const.A10_OUT_TARGET_POSITION;
//            }
//        }
//        return computerLineByState(out08Glassstate, out10Glassstate);
//    }
//
//    /**
//     * 按照尺寸出玻璃
//     *
//     * @param endcell endcell = out08Glassstate == 1 ? Const.A09_OUT_TARGET_POSITION : Const.A10_OUT_TARGET_POSITION;
//     * @param glassId
//     * @return
//     */
//    public EdgStorageCageDetails queryChangeGlassInfo(int endcell, String glassId) {
//        //获取笼子内数量前二的玻璃数量
//        MPJQueryWrapper<EdgStorageCageDetails> wrapper = new MPJQueryWrapper<>();
//        wrapper.select("count(t.glass_id) as count, t.width, t.height")
//                .eq("t.state", Const.GLASS_STATE_IN)
//                .inSql("t.slot", "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON)
//                .groupBy("t.width, t.height");
//        if (endcell == Const.A10_OUT_TARGET_POSITION) {
//            wrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
//                    "case when width < height then width else height end as second_length from edg_storage_cage_details) t1 " +
//                    "on t.glass_id = t1.glass_id and (t1.first_length >= " + minOneFirstLength + " and t1.second_length >= " + minOneSecondLength + ")");
//        } else {
//            wrapper.innerJoin("(select glass_id, case when height <= width then width else height end as first_length, " +
//                    "case when width < height then width else height end as second_length from edg_storage_cage_details) t1 " +
//                    "on t.glass_id = t1.glass_id and (t1.first_length between " + minTwoFirstLength + " and " + firstLength
//                    + " and t1.second_length between " + minTwoSecondLength + " and " + secondLength + ") ");
//        }
//        wrapper.last("order by count(t.glass_id) desc  limit 2");
//        List<EdgStorageCageDetails> list = edgStorageCageDetailsService.list(wrapper);
//        if (CollectionUtil.isEmpty(list)) {
//            return null;
//        }
//        log.info("获取笼子内数量前二的玻璃数量:{}", list);
//        //获取宽高拍第一的玻璃信息
//        EdgStorageCageDetails firstSize = list.get(0);
//        Integer firstCount = firstSize.getCount();
//        double firstWidth = firstSize.getWidth();
//        double firstHeight = firstSize.getHeight();
//        if (list.size() == 1) {
//            return queryMinGlass(firstWidth, firstHeight, glassId);
//        }
//        //获取宽高拍第二的玻璃信息
//        EdgStorageCageDetails secondSize = list.get(1);
//        Integer secondCount = secondSize.getCount();
//        double secondWidth = secondSize.getWidth();
//        double secondHeight = secondSize.getHeight();
//        //获取数量前2的玻璃数量比例
//        Integer mix = firstCount / secondCount;
//        log.info("获取玻璃数量前2的玻璃占比为:{}", mix);
//
//        if (mix >= 2) {
//            log.info("获取玻璃数量前2的玻璃占比为{},大于2,直接出玻璃数据的最多的,宽:{},高:{}", mix, firstWidth, firstHeight);
//            return queryMinGlass(firstWidth, firstHeight, glassId);
//        } else {
//            log.info("获取玻璃数量前2的玻璃占比为{},小于2", mix);
//            //获取任务表中最后一次出片的玻璃id
//            TaskCache taskCache = taskCacheService.queryGlassByTaskCache(endcell, Const.GLASS_CACHE_TYPE_OUT_ALL);
//            log.info("获取任务表中{}线最后一次出片的玻璃任务信息:{}", endcell, taskCache);
//            if (null == taskCache) {
//                log.info("{}线没有出片任务信息,直接出片", endcell);
//                return queryMinGlass(firstSize.getWidth(), firstSize.getHeight(), glassId);
//            }
//            EdgStorageCageDetails outGlassInfo = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
//                    .eq(EdgStorageCageDetails::getGlassId, taskCache.getGlassId()).last("limit 1"));
//            log.info("{}线有出片任务信息,任务信息为{},玻璃信息为{}", endcell, taskCache, outGlassInfo);
//            if (outGlassInfo.getWidth() == firstWidth && outGlassInfo.getHeight() == firstHeight) {
//                log.info("数量最多的宽{}高{}和{}线任务的宽{}高{}相同,出数量排第二的玻璃,宽{}高{}",
//                        firstWidth, firstHeight, endcell, outGlassInfo.getWidth(), outGlassInfo.getHeight(), secondWidth, secondHeight);
//                return queryMinGlass(secondWidth, secondHeight, glassId);
//            } else {
//                log.info("数量第二多的宽{}高{}和{}线任务的宽{}高{}相同,出数量排第二的玻璃,宽{}高{}",
//                        secondWidth, secondHeight, endcell, outGlassInfo.getWidth(), outGlassInfo.getHeight(), firstWidth, firstHeight);
//                return queryMinGlass(firstWidth, firstHeight, glassId);
//            }
//        }
//    }
//
//    /**
//     * 保存出片任务相关信息
//     *
//     * @param glassInfo
//     * @param endcell
//     * @param confirmationWrodAddress
//     * @param glassId
//     * @return
//     */
//    private boolean saveOutGlassMessage(EdgStorageCageDetails glassInfo, int endcell, String confirmationWrodAddress, String glassId, Integer currentSlot) {
//        if (glassInfo != null) {
//            log.info("4、添加出片任务,玻璃id:{},任务类型:{},起始位置:{},结束位置:{}", glassInfo.getGlassId(),
//                    2, glassInfo.getSlot(), endcell);
//            if (glassInfo.getGlassId().equals(glassId)) {
//
//                log.info("5、直通任务,将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
//                EdgStorageCageDetails details = new EdgStorageCageDetails();
//                BeanUtils.copyProperties(glassInfo, details);
//                EdgStorageCage nearestEmpty = edgStorageCageService.selectNearestEmpty(task.getCurrentCell(), currentSlot, Boolean.TRUE);
//                Assert.isTrue(null != nearestEmpty, "格子已满,无法执行直通任务");
//                log.info("3、查询卧式理片笼里面的空格:{}", nearestEmpty);
//                details.setSlot(nearestEmpty.getSlot());
//                details.setState(Const.GLASS_STATE_OUT);
//                edgStorageCageDetailsService.save(details);
//                boolean taskCacheStatus = saveTaskCache(glassInfo.getGlassId(), nearestEmpty.getSlot(), endcell, Const.GLASS_CACHE_TYPE_THROUGH);
//                log.info("6、添加出片任务是否完成:{}", taskCacheStatus);
//            } else {
//                log.info("5、非直通任务,将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
//                LambdaUpdateWrapper<EdgStorageCageDetails> wrapper = new LambdaUpdateWrapper<>();
//                wrapper.eq(EdgStorageCageDetails::getGlassId, glassInfo.getGlassId()).set(EdgStorageCageDetails::getState, Const.GLASS_STATE_OUT);
//                edgStorageCageDetailsService.update(wrapper);
//                log.info("5、更新出片玻璃的状态为{}", Const.GLASS_STATE_OUT);
//
//                boolean taskCacheStatus = saveTaskCache(glassInfo.getGlassId(), glassInfo.getSlot(), endcell, Const.GLASS_CACHE_TYPE_OUT);
//                log.info("6、添加出片任务是否完成:{}", taskCacheStatus);
//            }
//            boolean glassSizeStatus = saveGlassSize(glassInfo, endcell);
//            log.info("7、添加出片玻璃尺寸信息到磨边前玻璃表是否完成:{}", glassSizeStatus);
//            S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 1);
//            log.info("8、发送确认字已完成");
//            Damage damage = new Damage();
//            damage.setGlassId(glassInfo.getGlassId());
//            damage.setWorkingProcedure("切割");
//            damage.setLine(1001);
//            damage.setType(1);
//            damage.setRemark("过卧式理片");
//            damageService.insertDamage(damage);
//            return Boolean.TRUE;
//        }
//        return Boolean.FALSE;
//    }
//
//    /**
//     * 保存出片任务相关信息
//     *
//     * @param glassInfo
//     * @param endcell
//     * @param confirmationWrodAddress
//     * @param glassId
//     * @return
//     */
//    private boolean saveOutGlassMessageBySlot(EdgStorageCageDetails glassInfo, int endcell, String confirmationWrodAddress, String glassId, Integer currentSlot) {
//        if (glassInfo != null) {
//            log.info("4、添加出片任务,玻璃id:{},任务类型:{},起始位置:{},结束位置:{}", glassInfo.getGlassId(),
//                    2, glassInfo.getSlot(), endcell);
//            if (glassInfo.getGlassId().equals(glassId)) {
//                log.info("5、直通任务,将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
//                EdgStorageCageDetails details = new EdgStorageCageDetails();
//                //玻璃信息替换
//                String glassIdChange = queryAndChangeGlass(glassId);
//                if (StringUtils.isBlank(glassIdChange)) {
//                    BeanUtils.copyProperties(glassInfo, details);
//                } else {
//                    GlassInfo one = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
//                    BeanUtils.copyProperties(one, details);
//                }
//                EdgStorageCage nearestEmpty = edgStorageCageService.selectNearestEmpty(task.getCurrentCell(), currentSlot, Boolean.TRUE);
//                Assert.isTrue(null != nearestEmpty, "格子已满,无法执行直通任务");
//                log.info("3、查询卧式理片笼里面的空格:{}", nearestEmpty);
//                details.setSlot(nearestEmpty.getSlot());
//                details.setState(Const.GLASS_STATE_OUT);
//                edgStorageCageDetailsService.save(details);
//                boolean taskCacheStatus = saveTaskCache(glassInfo.getGlassId(), nearestEmpty.getSlot(), endcell, Const.GLASS_CACHE_TYPE_THROUGH);
//                log.info("6、添加出片任务是否完成:{}", taskCacheStatus);
//            } else {
//                log.info("5、非直通任务,将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
//                if (!glassInfo.getSlot().equals(currentSlot)) {
//                    EdgStorageCageDetails currentGlass = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
//                            .eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN)
//                            .eq(EdgStorageCageDetails::getSlot, currentSlot).eq(EdgStorageCageDetails::getWidth, glassInfo.getWidth())
//                            .eq(EdgStorageCageDetails::getHeight, glassInfo.getHeight()).eq(EdgStorageCageDetails::getThickness, glassInfo.getThickness())
//                    );
//                    if (null != currentGlass) {
//                        glassInfo = currentGlass;
//                    }
//                }
//                //玻璃信息替换
//                String glassIdChange = queryAndChangeGlass(glassInfo.getGlassId());
//                //处理在卧理内的玻璃信息:笼内的数据处理
//                queryEdgAndChangeGlass(glassInfo.getGlassId(), glassIdChange);
//                LambdaUpdateWrapper<EdgStorageCageDetails> wrapper = new LambdaUpdateWrapper<>();
//                wrapper.eq(EdgStorageCageDetails::getGlassId, glassInfo.getGlassId()).set(EdgStorageCageDetails::getState, Const.GLASS_STATE_OUT);
//                edgStorageCageDetailsService.update(wrapper);
//                log.info("5、更新出片玻璃的状态为{}", Const.GLASS_STATE_OUT);
//
//                boolean taskCacheStatus = saveTaskCache(glassInfo.getGlassId(), glassInfo.getSlot(), endcell, Const.GLASS_CACHE_TYPE_OUT);
//                log.info("6、添加出片任务是否完成:{}", taskCacheStatus);
//            }
//            boolean glassSizeStatus = saveGlassSize(glassInfo, endcell);
//            log.info("7、添加出片玻璃尺寸信息到磨边前玻璃表是否完成:{}", glassSizeStatus);
//            S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, 1);
//            log.info("8、发送确认字已完成");
//            Damage damage = new Damage();
//            damage.setGlassId(glassInfo.getGlassId());
//            damage.setWorkingProcedure("切割");
//            damage.setLine(1001);
//            damage.setType(1);
//            damage.setRemark("过卧式理片");
//            damageService.insertDamage(damage);
//            damageService.deleteByGlassId(glassId);
//            return Boolean.TRUE;
//        }
//        return Boolean.FALSE;
//    }
//
//    /**
//     * 添加理片笼任务
//     *
//     * @param glassId
//     * @param startcell
//     * @param endcell
//     * @param taskType
//     * @return
//     */
//    private boolean saveTaskCache(String glassId, int startcell, int endcell, int taskType) {
//        TaskCache taskCache = new TaskCache();
//        taskCache.setGlassId(glassId);
//        taskCache.setTaskStatus(0);
//        taskCache.setStartCell(startcell);
//        taskCache.setEndCell(endcell);
//        taskCache.setTaskType(taskType);
//        taskCache.setCreateTime(new Date());
//        return taskCacheService.save(taskCache);
//    }
//
//    /**
//     * 添加磨边队列信息
//     *
//     * @param glassInfo
//     * @param endcell
//     * @return
//     */
//    private boolean saveGlassSize(EdgStorageCageDetails glassInfo, int endcell) {
//        EdgGlassTaskInfo edgGlassTaskInfo = new EdgGlassTaskInfo();
//        BeanUtils.copyProperties(glassInfo, edgGlassTaskInfo);
//        edgGlassTaskInfo.setHeight((int) (glassInfo.getHeight() * ratio));
//        edgGlassTaskInfo.setWidth((int) (glassInfo.getWidth() * ratio));
//        edgGlassTaskInfo.setThickness((int) (glassInfo.getThickness() * ratio));
//        edgGlassTaskInfo.setState(Const.EDG_GLASS_BEFORE);
//        edgGlassTaskInfo.setLine(endcell);
//        edgGlassTaskInfo.setCreateTime(new Date());
//        edgGlassTaskInfo.setUpdateTime(new Date());
//        //先将历史对列表中本玻璃的数据删除,重新新增一份最新的数据
//        edgGlassTaskInfoService.remove(new LambdaQueryWrapper<EdgGlassTaskInfo>().eq(EdgGlassTaskInfo::getGlassId, glassInfo.getGlassId()));
//        return edgGlassTaskInfoService.save(edgGlassTaskInfo);
//    }
//
//    /**
//     * 计算出片线路
//     * 已排除都为2  都为0 的情况
//     *
//     * @param out08Glassstate
//     * @param out10Glassstate
//     * @return
//     */
//    private int computerLineByState(int out08Glassstate, int out10Glassstate) {
//        if (out08Glassstate == 0) {
//            if (out10Glassstate == 2) {
//                return Const.A09_OUT_TARGET_POSITION;
//            } else {
//                return Const.A10_OUT_TARGET_POSITION;
//            }
//        } else if (out08Glassstate == 1) {
//            return Const.A09_OUT_TARGET_POSITION;
//        } else {
//            return Const.A10_OUT_TARGET_POSITION;
//        }
//    }
//
//}