zhoushihao
2024-06-26 79cddf75458ebc5d8855f66ea9bf9ef073327b03
hangzhoumesParent/moduleService/UnLoadGlassModule/src/main/java/com/mes/job/DownLoadCacheGlassTask.java
@@ -3,6 +3,7 @@
import cn.hutool.core.lang.Assert;
import cn.smallbun.screw.core.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.mes.common.S7object;
import com.mes.common.config.Const;
import com.mes.device.PlcParameterObject;
@@ -11,22 +12,26 @@
import com.mes.downglassinfo.service.DownGlassInfoService;
import com.mes.downglassinfo.service.DownGlassTaskService;
import com.mes.downstorage.entity.DownStorageCage;
import com.mes.downstorage.entity.DownStorageCageDetails;
import com.mes.downstorage.service.DownStorageCageDetailsService;
import com.mes.downstorage.service.DownStorageCageService;
import com.mes.downworkstation.entity.DownWorkstation;
import com.mes.downworkstation.entity.dto.DownGlassInfoDTO;
import com.mes.downworkstation.service.DownWorkstationService;
import com.mes.downworkstation.service.DownWorkstationTaskService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
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;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * @Author : zhoush
@@ -49,14 +54,21 @@
    DownWorkstationService downWorkstationService;
    @Autowired
    DownGlassInfoService downGlassInfoService;
    @Autowired
    private DownWorkstationTaskService downWorkstationTaskService;
    @Value("${mes.threshold}")
    private Integer threshold;
    @Value("${mes.maxWidth}")
    private Integer maxWidth;
    @Value("${mes.maxHeight}")
    private Integer maxHeight;
    @Scheduled(fixedDelay = 1000)
    public void plcHomeEdgTask() {
        PlcParameterObject plcParameterObject = S7object.getinstance().PlcMesObject;
        String taskRequestTypeValue = plcParameterObject.getPlcParameter("RequestWord").getValue();
        String requestWord = plcParameterObject.getPlcParameter("RequestWord").getValue();
        String glassIdeValue = plcParameterObject.getPlcParameter("G04ID").getValue();
        String confirmationWrodValue = plcParameterObject.getPlcParameter("MES_confirmation_word").getValue();
        //A08  A09表示线路相同  可做等价  无数据转int异常
@@ -66,9 +78,9 @@
        String currentSlot = plcParameterObject.getPlcParameter("Current_slot").getValue();
        log.info("1、获取到的请求字为:{},获取到的扫描ID为:{},获取到的确认字为:{},获取到的出片状态分别为:A09:{}、A10:{},当前格子号为:{}",
                taskRequestTypeValue, glassIdeValue, confirmationWrodValue, out08Glassstate, out10Glassstate, currentSlot);
                requestWord, glassIdeValue, confirmationWrodValue, out08Glassstate, out10Glassstate, currentSlot);
        if ("0".equals(taskRequestTypeValue)) {
        if ("0".equals(requestWord)) {
            if ("0".equals(confirmationWrodValue)) {
                log.info("2、获取到的请求字为0,且确认字为0,不执行任务");
                return;
@@ -81,54 +93,69 @@
            log.info("2、获取到的请求字不为0,将确认字不为0,直接结束");
            return;
        }
        if ("1".equals(taskRequestTypeValue)) {
        if ("1".equals(requestWord)) {
            log.info("2、进片请求,且确认字为0,执行进片任务");
            inTo(glassIdeValue, confirmationWrodAddress, currentSlot);
        } else if ("2".equals(taskRequestTypeValue)) {
        } else if ("2".equals(requestWord)) {
            //09空闲 :1      10空闲 :2        都空闲:3    其他0
            log.info("2、出片请求,且确认字为0,执行进片任务");
//            outTo(Integer.parseInt(out08Glassstate),
//                    Integer.parseInt(out10Glassstate), confirmationWrodAddress, "", 0);
        } else if ("3".equals(taskRequestTypeValue)) {
            outTo(Integer.parseInt(out08Glassstate),
                    Integer.parseInt(out10Glassstate), confirmationWrodAddress, "", 0);
        } else if ("3".equals(requestWord)) {
            log.info("2、进片和出片都空闲,执行出片任务");
            //加笼子里面是否有玻璃,有先出,无玻璃先进
//            boolean outFlase = outTo(Integer.parseInt(out08Glassstate),
//                    Integer.parseInt(out10Glassstate), confirmationWrodAddress, glassIdeValue, Integer.parseInt(currentSlot));
//            log.info("出片任务是否完成:{},失败且玻璃id:{}不为空则执行进片任务", outFlase, glassIdeValue);
//            if (!outFlase && StringUtils.isNotBlank(glassIdeValue)) {
//                inTo(glassIdeValue, confirmationWrodAddress, currentSlot);
//            }
            boolean outFlase = outTo(Integer.parseInt(out08Glassstate),
                    Integer.parseInt(out10Glassstate), confirmationWrodAddress, glassIdeValue, Integer.parseInt(currentSlot));
            log.info("出片任务是否完成:{},失败且玻璃id:{}不为空则执行进片任务", outFlase, glassIdeValue);
            if (!outFlase && StringUtils.isNotBlank(glassIdeValue)) {
                inTo(glassIdeValue, confirmationWrodAddress, currentSlot);
        }
    }
    }
    private void inTo(String glassId, String confirmationWrodAddress, String currentSlot) {
        log.info("1、按照玻璃id:{}获取玻璃小片信息,当前格子为:{}", glassId, currentSlot);
        //添加进片任务  查找空格
        DownStorageCage nearestEmpty = downStorageCageService.selectCacheEmpty(Integer.parseInt(currentSlot), Boolean.FALSE);
        Assert.isTrue(null != nearestEmpty, "格子已满");
        Assert.isTrue(null != nearestEmpty, "格子已满,无法执行进片操作");
        log.info("2、查询卧式理片笼里面的空格:{}", nearestEmpty);
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
        Assert.isFalse(null == glassInfo, "玻璃信息不存在");
        Boolean checkFlag = Boolean.FALSE;
        //todo:玻璃尺寸是否走人工下片
        if (glassInfo.getWidth() > maxWidth || glassInfo.getHeight() > maxHeight) {
            log.info("该玻璃尺寸走人工下片,直接进片");
        } else {
            log.info("该玻璃尺寸非人工下片");
        //获取该玻璃的流程卡是否已绑定架子
        DownWorkstation one = downWorkstationService.getOne(new LambdaQueryWrapper<DownWorkstation>()
                .eq(DownWorkstation::getLayer, glassInfo.getLayer())
                .eq(DownWorkstation::getFlowCardId, glassInfo.getFlowCardId()));
        Boolean checkFlag = Boolean.TRUE;
        GlassInfo tempGlassInfo = null;
            Boolean isBind = Boolean.FALSE;
        if (null != one) {
            log.info("该流程卡已绑定架子");
                isBind = Boolean.TRUE;
            checkFlag = multilayerCheck(glassInfo);
        } else {
            }
            if (!checkFlag && !isBind) {
            log.info("该玻璃的流程卡未绑定架子,获取是否有空架子");
            List<DownWorkstation> list = downWorkstationService.list(new LambdaQueryWrapper<DownWorkstation>().isNull(DownWorkstation::getFlowCardId));
                List<DownWorkstation> list = downWorkstationService.list(new LambdaQueryWrapper<DownWorkstation>()
                        .isNull(DownWorkstation::getFlowCardId));
            if (CollectionUtils.isNotEmpty(list)) {
                log.info("有空架子,将流程卡与架子好绑定,执行进片任务 结束");
                    //绑定流程卡
                    downWorkstationService.update(new LambdaUpdateWrapper<DownWorkstation>().set(DownWorkstation::getFlowCardId, glassInfo.getFlowCardId())
                            .eq(DownWorkstation::getWorkstationId, list.get(0).getWorkstationId()));
                checkFlag = Boolean.TRUE;
            } else {
                }
            }
            if (!checkFlag) {
                log.info("无空架子,获取已绑定架子的流程卡信息,查看玻璃信息是否可被对调");
                List<DownGlassInfoDTO> downGlassInfoDTOList = downGlassInfoService.queryWorkStationNotIn();
                List<DownGlassInfoDTO> downGlassInfoDTOList = downGlassInfoService.queryWorkStationIsIn(Boolean.FALSE);
                log.info("获取架子上已绑定流程卡落架的数量及未落架的玻璃数据:{}", downGlassInfoDTOList);
                Assert.isTrue(CollectionUtils.isNotEmpty(downGlassInfoDTOList), "已绑定流程卡均无未落架玻璃,请及时处理架子上的玻璃,清除流程卡");
                //替换玻璃信息
                endLoop:
                for (DownGlassInfoDTO e : downGlassInfoDTOList) {
                    List<GlassInfo> glassInfoList = e.getGlassInfoList();
@@ -144,7 +171,7 @@
                                String flowCardId = glassInfo.getFlowCardId();
                                Integer layer = glassInfo.getLayer();
                                log.info("替换流程卡信息,当前玻璃信息:{}的流程卡号{}及层数{},替换后玻璃信息:{}的流程卡号{}及层数{}",
                                        tempGlassInfo, glassInfo, flowCardId, layer, tempFlowCardId, tempLayer);
                                        item, glassInfo, flowCardId, layer, tempFlowCardId, tempLayer);
                                glassInfo.setFlowCardId(tempFlowCardId);
                                glassInfo.setLayer(tempLayer);
                                glassInfoService.updateById(glassInfo);
@@ -156,29 +183,145 @@
                        }
                    }
                }
            }
            if (checkFlag) {
                //生成进片任务 执行进片操作
        }
        //将任务插入理片笼详情表
        DownStorageCageDetails downStorageCageDetails = new DownStorageCageDetails();
        BeanUtils.copyProperties(glassInfo, downStorageCageDetails);
        downStorageCageDetails.setState(Const.GLASS_STATE_IN);
        downStorageCageDetailsService.save(downStorageCageDetails);
//        生成进片任务
                initDownGlassTask(glassInfo, nearestEmpty.getSlot() + "", null, Const.GLASS_CACHE_TYPE_IN);
            }
        }
//                log.info("3、将玻璃信息插入卧式理片笼,当前玻璃信息:{}", 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);
//        log.info("4、玻璃信息已存入理片笼详情表,玻璃信息为{}", details);
//        //添加进片任务
//        boolean taskCache = saveTaskCache(details.getGlassId(), 0, nearestEmpty.getSlot(), Const.GLASS_CACHE_TYPE_IN);
//        log.info("5、生成进片任务信息存入任务表是否完成:{}", taskCache);
//
//        S7object.getinstance().plccontrol.writeWord(confirmationWrodAddress, (short) 1);
//        log.info("6、发送确认字完成");
    }
    private Boolean outTo(int parseInt, int parseInt1, String confirmationWrodAddress, String s, int i) {
        //定义笼内无法出片玻璃数量
        int glassCount = 0;
        String glassId = null;
        Boolean isBind = Boolean.FALSE;
        List<DownStorageCageDetails> list = downStorageCageDetailsService.list(new LambdaQueryWrapper<DownStorageCageDetails>()
                .eq(DownStorageCageDetails::getState, Const.GLASS_STATE_IN));
        log.info("笼内玻璃的数据有:{}", list);
        if (CollectionUtils.isEmpty(list)) {
            log.info("笼内没有玻璃,无法执行出片");
            return Boolean.FALSE;
        }
        for (DownStorageCageDetails item : list) {
            if (item.getWidth() > maxWidth || item.getHeight() > maxHeight) {
                log.info("玻璃宽度或高度超出阈值,执行人工下片");
                glassId = item.getGlassId();
                break;
            }
        }
        loop:
        if (glassId == null) {
            //获取正在落架的绑定流程卡的信息
            List<DownGlassInfoDTO> downGlassInfoDTOList = downGlassInfoService.queryWorkStationIsIn(Boolean.TRUE);
            List<String> downGlassFlowList = downGlassInfoDTOList.stream().map(item -> item.getFlowCardId() + ":" + item.getLayer()).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(downGlassFlowList)) {
                //获取架子玻璃都为空,出笼内子数量最多尺寸最大的玻璃
                DownStorageCageDetails downStorageCageDetails = downStorageCageDetailsService.getGlassInfoMaxCount();
                //绑定流程卡,更新玻璃状态,生成出片任务,
                glassId = downStorageCageDetails.getGlassId();
                isBind = Boolean.TRUE;
                break loop;
            }
            //将笼子内的玻璃进行过滤,仅获取无法落架的流程卡玻璃
            List<DownStorageCageDetails> noDownLoadList = list.stream().filter(item -> !downGlassFlowList.contains(item.getFlowCardId() + ":" + item.getLayer())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(noDownLoadList)) {
                //是否有空架子
                List<DownWorkstation> emptyShelfList = downWorkstationService.list(new LambdaQueryWrapper<DownWorkstation>()
                        .isNull(DownWorkstation::getFlowCardId));
                if (CollectionUtils.isNotEmpty(emptyShelfList)) {
                    DownStorageCageDetails downStorageCageDetails = downStorageCageDetailsService.getGlassInfoMaxCount();
                    //绑定流程卡,更新玻璃状态,生成出片任务
                    glassId = downStorageCageDetails.getGlassId();
                    isBind = Boolean.TRUE;
                    break loop;
                }
                glassCount = noDownLoadList.size();
                if (glassCount > threshold) {
                    //更新玻璃状态,生成出片人工下片任务
                    glassId = noDownLoadList.get(0).getGlassId();
                    isBind = Boolean.FALSE;
                    break loop;
                }
            }
            //将笼子内的玻璃进行过滤,仅获取可落架的流程卡玻璃
            List<DownStorageCageDetails> downLoadList = list.stream().filter(item -> downGlassFlowList.contains(item.getFlowCardId() + ":" + item.getLayer())).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(downLoadList)) {
                //不执行出片任务,笼内没有合适的出片玻璃
                return Boolean.FALSE;
            }
            //将笼内玻璃的流程卡+层号 和落架的流程卡 去重,得出展示无法落架的玻璃,判断玻璃数是否超过阈值
            //笼内玻璃是否可落架:笼内是否有需要中空的
            List<DownStorageCageDetails> multiLayerList = list.stream().filter(item -> item.getTotalLayer() >= 2).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(multiLayerList)) {
                for (DownStorageCageDetails item : multiLayerList) {
                    DownGlassInfoDTO downGlassInfoDTO = downGlassInfoService.queryDownGlassMaxLayer(item.getFlowCardId());
                    if (null == downGlassInfoDTO) {
//                    落架玻璃查到相关流程卡玻璃信息,表明当前流程卡玻璃未落架
                        log.info("");
                        return Boolean.FALSE;
                    }
                    if (downGlassInfoDTO.getLayer().equals(downGlassInfoDTO.getLayer())) {
                        log.info("当前玻璃的流程在架子上落架最多,直接出片");
                        //更新玻璃状态,生成出片任务
                        glassId = noDownLoadList.get(0).getGlassId();
                        isBind = Boolean.FALSE;
                        break loop;
                    }
                    Integer sequence = downGlassInfoService.queryMaxSequence(item.getFlowCardId(), item.getLayer());
                    log.info("获取当前玻璃需要放的次序:笼内同流程 同层数的通达次序+1:{}", sequence);
                    DownGlassInfo downGlassInfo = downGlassInfoService.getOne(new LambdaQueryWrapper<DownGlassInfo>()
                            .eq(DownGlassInfo::getFlowCardId, downGlassInfoDTO.getFlowCardId())
                            .eq(DownGlassInfo::getLayer, downGlassInfoDTO.getLayer()).eq(DownGlassInfo::getSequence, sequence));
                    if (null != downGlassInfoDTO && downGlassInfo.getWidth().equals(item.getWidth()) && downGlassInfo.getHeight().equals(item.getHeight())) {
                        log.info("相同次序玻璃对应上,可执行进片任务");
                        //更新玻璃状态,生成出片任务
                        glassId = noDownLoadList.get(0).getGlassId();
                        isBind = Boolean.FALSE;
                        break loop;
                    } else {
                        log.info("同次序玻璃对应不上,需执行替换玻璃的操作");
                        glassCount += 1;
                        if (glassCount > threshold) {
                            glassId = noDownLoadList.get(0).getGlassId();
                            isBind = Boolean.FALSE;
                            break loop;
                        }
                        continue;
                    }
                }
            }
            Map<String, List<DownStorageCageDetails>> singleLayerMap = list.stream().filter(item -> item.getTotalLayer() == 1)
                    .collect(Collectors.groupingBy(item -> item.getFlowCardId() + item.getLayer(), Collectors.toList()));
            if (glassId == null) {
                if (CollectionUtils.isNotEmpty(singleLayerMap)) {
                    //获取已落架流程卡信息,按落架数量排序
                    for (DownGlassInfoDTO e : downGlassInfoDTOList) {
                        List<DownStorageCageDetails> downStorageCageDetails = singleLayerMap.get(e.getFlowCardId() + e.getLayer());
                        if (CollectionUtils.isNotEmpty(downStorageCageDetails)) {
                            glassId = downStorageCageDetails.get(0).getGlassId();
                            isBind = Boolean.FALSE;
                            break;
                        }
                    }
                }
            }
        }
        if (glassId == null) {
            log.info("没有找到可以下片的的玻璃,结束任务");
            return Boolean.FALSE;
        } else {
            //todo:按照出片的玻璃id更新笼内的玻璃状态为已出片
            return generateDownGlassOutTask(glassId, Const.GLASS_CACHE_TYPE_OUT, isBind);
        }
    }
    private Boolean multilayerCheck(GlassInfo glassInfo) {
@@ -213,7 +356,46 @@
        }
    }
    private Boolean generateDownGlassOutTask(String glassId, Integer taskType, Boolean isBind) {
        //按玻璃id获取玻璃信息
        DownStorageCageDetails downStorageCageDetails = downStorageCageDetailsService.getOne(new LambdaQueryWrapper<DownStorageCageDetails>()
                .eq(DownStorageCageDetails::getGlassId, glassId));
        String endCell = null;
        if (isBind) {
            //获取空架子信息,将空架子信息绑定流程卡
            DownWorkstation emptyDownWorkstation = downWorkstationService.getOne(new LambdaQueryWrapper<DownWorkstation>()
                    .isNull(DownWorkstation::getFlowCardId).orderByDesc(DownWorkstation::getWorkstationId).last("limit 1"));
            if (null != emptyDownWorkstation) {
                log.info("获取到空架子信息,绑定流程卡");
                emptyDownWorkstation.setFlowCardId(downStorageCageDetails.getFlowCardId());
                emptyDownWorkstation.setLayer(downStorageCageDetails.getLayer());
                downWorkstationService.updateById(emptyDownWorkstation);
                endCell = emptyDownWorkstation.getWorkstationId() + "";
            } else {
                log.info("没有空架子信息,无法绑定流程卡");
                return Boolean.FALSE;
            }
        } else {
            DownWorkstation workstation = downWorkstationService.getOne(new LambdaUpdateWrapper<DownWorkstation>()
                    .eq(DownWorkstation::getFlowCardId, downStorageCageDetails.getFlowCardId()).eq(DownWorkstation::getLayer, downStorageCageDetails.getLayer()));
            endCell = workstation.getWorkstationId() + "";
        }
        //更新详情表内的状态
        if (downStorageCageDetailsService.update(new LambdaUpdateWrapper<DownStorageCageDetails>()
                .set(DownStorageCageDetails::getState, Const.GLASS_STATE_OUT).eq(DownStorageCageDetails::getGlassId, glassId))) {
            log.info("更新详情表内的状态成功");
        } else {
            log.info("更新详情表内的状态失败");
            return Boolean.FALSE;
        }
        //生成任务信息
        GlassInfo glassInfo = new GlassInfo();
        BeanUtils.copyProperties(downStorageCageDetails, glassInfo);
        return initDownGlassTask(glassInfo, downStorageCageDetails.getSlot() + "", endCell, taskType);
    }
    private Boolean initDownGlassTask(GlassInfo glassInfo, String startCell, String endCell, Integer taskType) {
        log.info("玻璃{}生成进片任务", glassInfo.getGlassId());
        DownGlassTask downGlassTask = new DownGlassTask();
        BeanUtils.copyProperties(glassInfo, downGlassTask);
        downGlassTask.setStartCell(startCell);