wangfei
2024-11-08 3c7d672fb7d6c34742fb7da6f66616ccf3be2c9a
hangzhoumesParent/moduleService/LoadGlassModule/src/main/java/com/mes/job/OpcLoadGlassTask.java
New file
@@ -0,0 +1,222 @@
package com.mes.job;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mes.common.config.Const;
import com.mes.engineering.entity.Engineering;
import com.mes.engineering.mapper.EngineeringMapper;
import com.mes.opctask.entity.LoadGlassDeviceTask;
import com.mes.opctask.entity.LoadGlassDeviceTaskHistory;
import com.mes.opctask.service.LoadGlassDeviceTaskHistoryService;
import com.mes.opctask.service.LoadGlassDeviceTaskService;
import com.mes.rawglassdetails.entity.RawGlassStorageDetails;
import com.mes.rawglassdetails.service.RawGlassStorageDetailsService;
import com.mes.uppattenusage.entity.UpPattenUsage;
import com.mes.uppattenusage.entity.vo.UpPattenUsageVO;
import com.mes.uppattenusage.mapper.UpPattenUsageMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * @Author : zhoush
 * @Date: 2024/10/23 14:30
 * @Description:
 */
@Component
@Slf4j
public class OpcLoadGlassTask {
    @Resource
    private EngineeringMapper engineeringMapper;
    @Resource
    private LoadGlassDeviceTaskService loadGlassDeviceTaskService;
    @Resource
    private RawGlassStorageDetailsService rawGlassStorageDetailsService;
    @Resource
    private LoadGlassDeviceTaskHistoryService loadGlassDeviceTaskHistoryService;
    @Resource
    private UpPattenUsageMapper upPattenUsageMapper;
    private static final List<Integer> LOAD_STATION_01 = Arrays.asList(101, 102);
    private static final List<Integer> LOAD_STATION_02 = Arrays.asList(103, 104);
    private static final Integer LOAD_GLASS_ONE_DEVICE = 5;
    private static final Integer LOAD_GLASS_TWO_DEVICE = 6;
    private static final String LOAD_GLASS_DEVICE_ONE_TASK = "load_glass_device_one_task";
    private static final String LOAD_GLASS_DEVICE_TWO_TASK = "load_glass_device_two_task";
    //设备id   上片位信息   任务表不一致   历史任务表公用一张 新增任务/任务结束,后会在历史表中新增一条记录并在结束后更新任务  一个任务即可
    //定时任务扫描上片位有没有原片
    //1、是否有在执行的任务
    //2、1号上片位是否有原片,原片尺寸是否和上片待上片的尺寸一致
    //3、1号无原片,且没有架子,2号上片位尺寸是否和带上片尺寸一致
    //4、不一致可能出现玻璃破损导致的上一架原片数量不够
    @Scheduled(fixedDelay = 300)
    public void opcLoadGlassOne() {
        opcLoadGlassChild(LOAD_GLASS_DEVICE_ONE_TASK, LOAD_GLASS_ONE_DEVICE);
    }
    @Scheduled(fixedDelay = 300)
    public void opcLoadGlassTwo() {
        opcLoadGlassChild(LOAD_GLASS_DEVICE_TWO_TASK, LOAD_GLASS_TWO_DEVICE);
    }
    @Scheduled(fixedDelay = 300)
    public void opcLoadGlassOneFinish() {
        opcLoadGlassFinishChid(LOAD_GLASS_DEVICE_ONE_TASK, LOAD_GLASS_ONE_DEVICE);
    }
    @Scheduled(fixedDelay = 300)
    public void opcLoadGlassTwoFinish() {
        opcLoadGlassFinishChid(LOAD_GLASS_DEVICE_TWO_TASK, LOAD_GLASS_TWO_DEVICE);
    }
    private void opcLoadGlassChild(String tableName, Integer deviceId) {
        Engineering engineering = engineeringMapper.selectOne(new LambdaQueryWrapper<Engineering>()
                .eq(Engineering::getState, Const.ENGINEERING_RUNNING).eq(Engineering::getStationCell, deviceId));
        if (null == engineering) {
            log.info("{}上片线,没有工程任务", deviceId);
            return;
        }
        //任务暂停
        LoadGlassDeviceTask task = loadGlassDeviceTaskService.queryTaskMessage(tableName);
        if (task.getTaskRunning().equals(Const.ENGINEERING_RUNNING)) {
            log.info("{}上片线,有正在执行的任务,结束本地上片请求", deviceId);
            return;
        }
        List<UpPattenUsageVO> pattenUsageList = upPattenUsageMapper.queryRawGlassByEngineeringId(engineering.getEngineerId());
        log.info("按照当前获取到正在需要上片的原片信息有:{}", pattenUsageList);
        if (CollectionUtils.isEmpty(pattenUsageList)) {
            log.info("当前工程需要上片的原片信息为空,任务已结束");
            //todo:是否将工程状态改为已完成
            return;
        }
        Map<String, List<UpPattenUsageVO>> upListMap = pattenUsageList.stream()
                .collect(Collectors.groupingBy(UpPattenUsageVO::getGroupNumber));
        log.info("获取当前需要上片的原片数据");
        List<UpPattenUsageVO> usageVOS = upListMap.get("1");
//        获取1号上片位是有架子且有玻璃
        List<Integer> loadStation = LOAD_GLASS_DEVICE_ONE_TASK.equals(tableName) ? LOAD_STATION_01 : LOAD_STATION_02;
        List<RawGlassStorageDetails> loadStationList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1")
                .eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN)
                .eq(RawGlassStorageDetails::getDeviceId, deviceId));
        if (CollectionUtils.isEmpty(loadStationList)) {
            log.info("当前上片线路两个上片位都没有原片信息,结束本次上片任务,等待仓储调度任务");
            return;
        }
        RawGlassStorageDetails oneLoadStation = loadStationList.stream().filter(e -> e.getSlot().equals(loadStation.get(0))).findFirst().orElse(null);
        if (null == oneLoadStation) {
            RawGlassStorageDetails twoLoadStation = loadStationList.stream().filter(e -> e.getSlot().equals(loadStation.get(1))).findFirst().orElse(null);
            if (!compareRawSize(usageVOS.get(0), twoLoadStation)) {
                log.info("二号上片位有架子,原片数量为0或者原片信息与待上片尺寸不一致,结束本次上片任务,等待仓储调度任务");
                return;
            }
            int number = Math.min(twoLoadStation.getRemainQuantity(), usageVOS.size());
            //生成上片任务
            task.setTotalCount(number);
            task.setTaskRunning(Const.ENGINEERING_RUNNING);
            task.setRawGlassWidth((int) usageVOS.get(0).getWidth());
            task.setRawGlassHeight((int) usageVOS.get(0).getHeight());
            task.setSlot(loadStation.get(1));
            loadGlassDeviceTaskService.updateTaskMessage(tableName, task);
            saveHistoryTask(task, deviceId);
            return;
        }
        //尺寸不一样或者原片数量大于0
        if (!compareRawSize(usageVOS.get(0), oneLoadStation)) {
            log.info("一号上片位有架子,原片数量为0或者原片信息与待上片尺寸不一致,结束本次上片任务,等待仓储调度任务");
            return;
        }
        //生成上片任务
        int number = Math.min(oneLoadStation.getRemainQuantity(), usageVOS.size());
        task.setTotalCount(number);
        task.setTaskRunning(Const.ENGINEERING_RUNNING);
        task.setRawGlassWidth((int) usageVOS.get(0).getWidth());
        task.setRawGlassHeight((int) usageVOS.get(0).getHeight());
        task.setSlot(loadStation.get(0));
        loadGlassDeviceTaskService.updateTaskMessage(tableName, task);
        saveHistoryTask(task, deviceId);
    }
    private void opcLoadGlassFinishChid(String tableName, Integer deviceId) {
        LoadGlassDeviceTask task = loadGlassDeviceTaskService.queryTaskMessage(tableName);
        if (task.getTaskRunning().equals(Const.ENGINEERING_NEW)) {
            log.info("无任务,结束");
            return;
        }
        if (task.getTaskState() <= 1) {
            log.info("任务正在执行,结束");
            return;
        }
        //获取任务完成情况
//         已完成数量  破损数量
        Integer finishCount = task.getFinishCount();
        Integer damageCount = task.getDamageCount();
        //更新当前架子上的原片剩余情况
        rawGlassStorageDetailsService.update(new UpdateWrapper<RawGlassStorageDetails>()
                .inSql("slot", "select slot from raw_glass_storage_station where enable_state = 1")
                .eq("slot", task.getSlot())
                .eq("state", Const.RAW_GLASS_STATE_IN)
                .setSql("remain_quantity = remain_quantity - " + (finishCount + damageCount)));
        //更新工程下的原片数量 todo:sql待优化
        List<Integer> ids = upPattenUsageMapper.queryFinishByEngineering(deviceId, finishCount);
        upPattenUsageMapper.update(null, new LambdaUpdateWrapper<UpPattenUsage>()
                .in(UpPattenUsage::getId, ids)
                .set(UpPattenUsage::getState, Const.LOAD_RAW_GLASS_SUCCESS));
        //todo:任务表数据情况
        task.setTaskRunning(0);
        task.setTotalCount(0);
        task.setRawGlassWidth(0);
        task.setRawGlassHeight(0);
        task.setSlot(0);
        loadGlassDeviceTaskService.updateTaskMessage(tableName, task);
        loadGlassDeviceTaskHistoryService.update(new LambdaUpdateWrapper<LoadGlassDeviceTaskHistory>()
                .set(LoadGlassDeviceTaskHistory::getTaskState, Const.RAW_GLASS_TASK_SUCCESS)
                .eq(LoadGlassDeviceTaskHistory::getTaskState, Const.RAW_GLASS_TASK_NEW)
                .eq(LoadGlassDeviceTaskHistory::getStation, deviceId)
        );
    }
    private boolean saveHistoryTask(LoadGlassDeviceTask task, Integer deviceId) {
        LoadGlassDeviceTaskHistory taskHistory = new LoadGlassDeviceTaskHistory();
        BeanUtils.copyProperties(task, taskHistory);
        taskHistory.setStation(deviceId);
        taskHistory.setCreateTime(new Date());
        taskHistory.setTaskState(Const.RAW_GLASS_TASK_NEW);
        loadGlassDeviceTaskHistoryService.save(taskHistory);
        return Boolean.TRUE;
    }
    /**
     * 尺寸一样并且原片数量大于0
     *
     * @param upPattenUsage
     * @param details
     * @return
     */
    private boolean compareRawSize(UpPattenUsage upPattenUsage, RawGlassStorageDetails details) {
        boolean flag = upPattenUsage.getWidth() == details.getPatternWidth() && upPattenUsage.getHeight() == details.getPatternHeight() &&
                upPattenUsage.getThickness() == details.getPatternThickness() && upPattenUsage.getFilmsId().equals(details.getFilmsId());
        return flag && details.getRemainQuantity() > 0;
    }
}