wangfei
2024-10-15 5c2e8a80d739c5659d74bfd2cbe232b5d72ce21f
hangzhoumesParent/moduleService/GlassStorageModule/src/main/java/com/mes/job/RawGlassTask.java
New file
@@ -0,0 +1,235 @@
package com.mes.job;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mes.common.config.Const;
import com.mes.engineering.entity.Engineering;
import com.mes.engineering.mapper.EngineeringMapper;
import com.mes.milo.model.ReadWriteEntity;
import com.mes.milo.service.MiloService;
import com.mes.rawglassdetails.entity.RawGlassStorageDetails;
import com.mes.rawglassdetails.service.RawGlassStorageDetailsService;
import com.mes.rawglassstation.entity.RawGlassStorageStation;
import com.mes.rawglassstation.service.RawGlassStorageStationService;
import com.mes.rawglasstask.entity.RawGlassStorageTask;
import com.mes.rawglasstask.service.RawGlassStorageTaskService;
import com.mes.uppattenusage.entity.vo.UpPattenUsageVO;
import com.mes.uppattenusage.mapper.UpPattenUsageMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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/11 16:13
 * @Description:
 */
@Slf4j
@Component
public class RawGlassTask {
    @Autowired
    private RawGlassStorageStationService rawGlassStorageStationService;
    @Autowired
    private RawGlassStorageDetailsService rawGlassStorageDetailsService;
    @Autowired
    private RawGlassStorageTaskService rawGlassStorageTaskService;
    @Resource
    private EngineeringMapper engineeringMapper;
    @Resource
    private UpPattenUsageMapper upPattenUsageMapper;
    @Autowired
    private MiloService miloService;
    private static final List<String> liftingStation = Arrays.asList("1", "2");
    private static final List<String> loadGlassStation = Arrays.asList("3", "4", "5", "6");
    /**
     * 入库任务:吊装位有玻璃,先去工位表查询空格子,生成入库任务从吊装位到目标格子
     *
     * @throws Exception
     */
    @Scheduled(fixedDelay = 1000)
    public void warehouseTask() throws Exception {
        ReadWriteEntity entity = miloService.readFromOpcUa("rawglass.device.request");
        String value = entity.getValueString();
        if (!"1".equals(value)) {
            log.info("大车忙碌");
            return;
        }
        List<RawGlassStorageDetails> rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN)
                .inSql(RawGlassStorageDetails::getSlotId, "select slot from raw_glass_storage_station where enable_state = 1 and slot in (1,2)"));
        if (CollectionUtil.isEmpty(rawGlassList)) {
            log.info("吊装位被禁用或没有玻璃");
            return;
        }
        //查询工位信息是否有
        List<RawGlassStorageStation> stationList = rawGlassStorageStationService.list(new LambdaQueryWrapper<RawGlassStorageStation>().notInSql(RawGlassStorageStation::getSlot, "select slot_id from raw_glass_storage_details where state = '100'")
                .eq(RawGlassStorageStation::getEnableState, Const.SLOT_ON));
        if (CollectionUtil.isEmpty(stationList)) {
            log.info("没有空的工位");
            return;
        }
        //生成进笼任务
        generateTask(rawGlassList.get(0).getSlotId(), stationList.get(0).getSlot(),
                rawGlassList.get(0).getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_IN);
        //生成工位任务,将吊装位的玻璃状态改位进笼中
    }
    /**
     * 出库任务:1、点出库,立马生成出片任务 2、点出库修改工位详情内的状态为待出库,定时任务扫描生成出库任务
     */
    @Scheduled(fixedDelay = 1000)
    public void outboundTask() throws Exception {
        ReadWriteEntity entity = miloService.readFromOpcUa("rawglass.device.request");
        String value = entity.getValueString();
        if (!"2".equals(value)) {
            log.info("大车忙碌");
            return;
        }
        List<RawGlassStorageDetails> rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_OUT_ING)
                .inSql(RawGlassStorageDetails::getSlotId, "select slot from raw_glass_storage_station where enable_state = 1 and slot not in (1,2)"));
        if (CollectionUtil.isEmpty(rawGlassList)) {
            log.info("系统没有需要出库的原片信息");
            return;
        }
        List<Integer> emptyLeftingList = rawGlassStorageDetailsService.listBySlotState(liftingStation, Arrays.asList(Const.GLASS_STATE_IN));
        if (CollectionUtil.isEmpty(emptyLeftingList)) {
            log.info("吊装位当前都有原片,结束出片任务");
        }
        //生成出库任务
        generateTask(rawGlassList.get(0).getSlotId(), emptyLeftingList.get(0),
                rawGlassList.get(0).getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_OUT);
    }
    /**
     * 原片调度:1、查询工程原片表,按照顺序将原片放入上片1号位,后续原片放上片2号位,出现尺寸替换,判断原上片位是否有玻璃,有 先出后进,无 直接进片
     */
    @Scheduled(fixedDelay = 1000)
    public void rawGlassDispatchTask() throws Exception {
        ReadWriteEntity entity = miloService.readFromOpcUa("rawglass.device.request");
        String value = entity.getValueString();
        if (!"2".equals(value)) {
            log.info("大车忙碌");
            return;
        }
        //查询当前系统正在执行的订单
        Engineering engineering = engineeringMapper.selectOne(new LambdaQueryWrapper<Engineering>().eq(Engineering::getState, Const.ENGINEERING_RUNNING).last("order by id limit 1"));
        if (null == engineering) {
            log.info("没有正在执行的工程");
            return;
        }
        //当前尺寸需要上片的数量
        List<UpPattenUsageVO> pattenUsageList = upPattenUsageMapper.queryRawGlassByEngineeringId(engineering.getEngineerId());
        if (CollectionUtils.isEmpty(pattenUsageList)) {
            log.info("正在执行的工程原片无可上片的原片信息");
            return;
        }
        Map<String, List<UpPattenUsageVO>> upListMap = pattenUsageList.stream()
                .collect(Collectors.groupingBy(UpPattenUsageVO::getGroupNumber));
        //todo:按照工程号按照工程下未完成的尺寸的顺序,当1号上片位架子上的当前尺寸玻璃少于3片且2号上片位无原片玻璃,则将去调度玻璃去2号上片位,
        //todo:当一号上片位架子上的玻璃位空或者当前尺寸用完时时,将2号(有玻璃)上片位调度到1号上片位
        //1、查询4个上片的原片详情
        List<RawGlassStorageDetails> rawGlassDetailsList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN).in(RawGlassStorageDetails::getSlotId, loadGlassStation));
        if (CollectionUtils.isEmpty(rawGlassDetailsList)) {
            //表示1上片位没有原片,直接找原片放入对应的上片位
            List<UpPattenUsageVO> upPattenUsage01VOS = upListMap.get("1");
            UpPattenUsageVO usageVO = upPattenUsage01VOS.get(0);
            RawGlassStorageDetails details = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper<RawGlassStorageDetails>()
                    .eq(RawGlassStorageDetails::getFilmsId, usageVO.getFilmsId())
                    .eq(RawGlassStorageDetails::getPatternWidth, usageVO.getWidth())
                    .eq(RawGlassStorageDetails::getPatternHeight, usageVO.getHeight())
                    .eq(RawGlassStorageDetails::getPatternThickness, usageVO.getThickness())
                    .gt(RawGlassStorageDetails::getRemainQuantity, upPattenUsage01VOS.size())
                    .orderByAsc(RawGlassStorageDetails::getRemainQuantity)
                    .last("limit 1")
            );
            generateTask(details.getSlotId(), 1, details.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
            //结束调度任务
        }
        Map<Integer, List<RawGlassStorageDetails>> listMap = rawGlassDetailsList.stream().collect(Collectors.groupingBy(RawGlassStorageDetails::getSlotId));
        RawGlassStorageDetails rawGlass03Details = listMap.get(3).get(0);
        RawGlassStorageDetails rawGlass04Details = listMap.get(4).get(0);
//        RawGlassStorageDetails rawGlass05Details = listMap.get(5).get(0);
//        RawGlassStorageDetails rawGlass06Details = listMap.get(6).get(0);
        //todo:上片1号位2种清空方式:方式一:原片用完  方式二:当前尺寸用完
        if (null == rawGlass03Details) {
            if (null == rawGlass04Details) {
                //表示1上片位没有原片,直接找原片放入对应的上片位
                List<UpPattenUsageVO> upPattenUsage01VOS = upListMap.get("1");
                UpPattenUsageVO usageVO = upPattenUsage01VOS.get(0);
                RawGlassStorageDetails details = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper<RawGlassStorageDetails>()
                        .eq(RawGlassStorageDetails::getFilmsId, usageVO.getFilmsId())
                        .eq(RawGlassStorageDetails::getPatternWidth, usageVO.getWidth())
                        .eq(RawGlassStorageDetails::getPatternHeight, usageVO.getHeight())
                        .eq(RawGlassStorageDetails::getPatternThickness, usageVO.getThickness())
                        .gt(RawGlassStorageDetails::getRemainQuantity, upPattenUsage01VOS.size())
                        .orderByAsc(RawGlassStorageDetails::getRemainQuantity)
                        .last("limit 1")
                );
                generateTask(details.getSlotId(), 1, details.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
                //结束调度任务
            } else {
                //将2号上片位的原片放入1号上片位
                generateTask(2, 1, rawGlass04Details.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
                //结束调度任务
            }
        } else {
            if (null == rawGlass04Details) {
                List<UpPattenUsageVO> upPattenUsage01VOS = upListMap.get("2");
                if (CollectionUtils.isEmpty(upPattenUsage01VOS)) {
                    return;
                }
                UpPattenUsageVO usageVO = upPattenUsage01VOS.get(0);
                RawGlassStorageDetails details = rawGlassStorageDetailsService.getOne(new LambdaQueryWrapper<RawGlassStorageDetails>()
                        .eq(RawGlassStorageDetails::getFilmsId, usageVO.getFilmsId())
                        .eq(RawGlassStorageDetails::getPatternWidth, usageVO.getWidth())
                        .eq(RawGlassStorageDetails::getPatternHeight, usageVO.getHeight())
                        .eq(RawGlassStorageDetails::getPatternThickness, usageVO.getThickness())
                        .gt(RawGlassStorageDetails::getRemainQuantity, upPattenUsage01VOS.size())
                        .orderByAsc(RawGlassStorageDetails::getRemainQuantity)
                        .last("limit 1")
                );
                generateTask(details.getSlotId(), 2, details.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
            }
        }
    }
    /**
     * 生成原片仓储任务
     *
     * @param startSlot
     * @param endSlot
     * @param patternQuantity
     * @param taskType
     * @return
     */
    private boolean generateTask(int startSlot, int endSlot, Integer patternQuantity, int taskType) {
        RawGlassStorageTask task = RawGlassStorageTask.builder()
                .originateSlot(startSlot)
                .endSlot(endSlot)
                .patternQuantity(patternQuantity)
                .taskType(taskType)
                .createTime(new Date()).build();
        return rawGlassStorageTaskService.save(task);
    }
}