package com.mes.job;
|
|
import cn.hutool.core.collection.CollectionUtil;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.kangaroohy.milo.model.ReadWriteEntity;
|
import com.kangaroohy.milo.service.MiloService;
|
import com.mes.common.config.Const;
|
import com.mes.engineering.entity.Engineering;
|
import com.mes.engineering.mapper.EngineeringMapper;
|
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> LIFTING_STATION = Arrays.asList("4");
|
private static final List<String> LOAD_STATION_01 = Arrays.asList("101", "102");
|
private static final List<String> LOAD_STATION_02 = Arrays.asList("103", "104");
|
private static final List<Integer> LOAD_STATION_MAX = Arrays.asList(102, 104);
|
|
/**
|
* 入库任务:吊装位有玻璃,先去工位表查询空格子,生成入库任务从吊装位到目标格子
|
*
|
* @throws Exception
|
*/
|
@Scheduled(fixedDelay = 1000)
|
public void warehouseTask() throws Exception {
|
ReadWriteEntity entity = miloService.readFromOpcUa("rawglass.device.request");
|
String value = entity.getValue() + "";
|
if (!"1".equals(value)) {
|
log.info("大车忙碌");
|
return;
|
}
|
List<RawGlassStorageDetails> rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
|
.eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN)
|
.inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1 and device_id = 4"));
|
if (CollectionUtil.isEmpty(rawGlassList)) {
|
log.info("吊装位被禁用或没有玻璃");
|
return;
|
}
|
//查询工位信息是否有
|
List<RawGlassStorageStation> stationList = rawGlassStorageStationService.list(new LambdaQueryWrapper<RawGlassStorageStation>().notInSql(RawGlassStorageStation::getSlot, "select slot from raw_glass_storage_details where " +
|
"state in('100','102','103')")
|
.eq(RawGlassStorageStation::getEnableState, Const.SLOT_ON));
|
if (CollectionUtil.isEmpty(stationList)) {
|
log.info("没有空的工位");
|
return;
|
}
|
//生成进笼任务
|
generateTask(rawGlassList.get(0).getSlot(), stationList.get(0).getSlot(),
|
rawGlassList.get(0).getRemainQuantity(), Const.RAW_GLASS_STATE_RUNNING);
|
//生成工位任务,将吊装位的玻璃状态改位进笼中
|
// 修改吊装位的原片状态为103 出片中
|
//修改出片任务状态
|
rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
|
.eq(RawGlassStorageDetails::getSlot, rawGlassList.get(0).getSlot())
|
.eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN)
|
.set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
|
// RawGlassStorageDetails details = new RawGlassStorageDetails();
|
// BeanUtils.copyProperties(rawGlassList.get(0), details);
|
}
|
|
|
/**
|
* 出库任务:1、点出库,立马生成出片任务 2、点出库修改工位详情内的状态为待出库,定时任务扫描生成出库任务
|
*/
|
@Scheduled(fixedDelay = 1000)
|
public void outboundTask() throws Exception {
|
ReadWriteEntity entity = miloService.readFromOpcUa("rawglass.device.request");
|
String value = entity.getValue() + "";
|
if (!"2".equals(value)) {
|
log.info("大车忙碌");
|
return;
|
}
|
List<RawGlassStorageDetails> rawGlassList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
|
.eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_WAIT_OUT));
|
// .inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1 and device_id = 4"));
|
if (CollectionUtil.isEmpty(rawGlassList)) {
|
log.info("系统没有需要出库的原片信息");
|
return;
|
}
|
List<Integer> emptyLeftingList = rawGlassStorageDetailsService.listBySlotState(LIFTING_STATION, Arrays.asList(Const.RAW_GLASS_STATE_IN, Const.RAW_GLASS_STATE_RUNNING));
|
if (CollectionUtil.isEmpty(emptyLeftingList)) {
|
log.info("吊装位当前都有原片,结束出片任务");
|
return;
|
}
|
//生成出库任务
|
generateTask(rawGlassList.get(0).getSlot(), emptyLeftingList.get(0),
|
rawGlassList.get(0).getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_OUT);
|
//修改出片任务状态
|
rawGlassStorageDetailsService.update(new LambdaUpdateWrapper<RawGlassStorageDetails>()
|
.eq(RawGlassStorageDetails::getSlot, rawGlassList.get(0).getSlot())
|
.eq(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_WAIT_OUT)
|
.set(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_RUNNING));
|
}
|
|
/**
|
* 原片调度:1、查询工程原片表,按照顺序将原片放入上片1号位,后续原片放上片2号位,出现尺寸替换,判断原上片位是否有玻璃,有 先出后进,无 直接进片
|
*/
|
@Scheduled(fixedDelay = 1000)
|
public void rawGlassDispatchTask() throws Exception {
|
ReadWriteEntity entity = miloService.readFromOpcUa("rawglass.device.request");
|
String value = entity.getValue() + "";
|
if (!"2".equals(value)) {
|
log.info("大车忙碌");
|
return;
|
}
|
//查询当前系统正在执行的订单
|
List<Engineering> engineeringList = engineeringMapper.selectList(new LambdaQueryWrapper<Engineering>()
|
.eq(Engineering::getState, Const.ENGINEERING_RUNNING).last("order by id"));
|
if (CollectionUtils.isEmpty(engineeringList)) {
|
log.info("没有正在执行的工程");
|
return;
|
}
|
//线路 + 工程后
|
//todo:按照路线及工程号,进行出片任务
|
String stationCell = engineeringList.get(0).getStationCell();
|
String enginneerId = engineeringList.get(0).getEngineerId();
|
|
//当前尺寸需要上片的数量
|
List<UpPattenUsageVO> pattenUsageList = upPattenUsageMapper.queryRawGlassByEngineeringId(enginneerId);
|
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::getSlot, LOAD_STATION_01));
|
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.getSlot(), 1, details.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
|
//结束调度任务
|
}
|
Map<Integer, List<RawGlassStorageDetails>> listMap = rawGlassDetailsList.stream().collect(Collectors.groupingBy(RawGlassStorageDetails::getSlot));
|
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.getSlot(), 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.getSlot(), 2, details.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
|
}
|
}
|
|
|
}
|
|
private boolean queryDispatchTask(String stationCell, String enginneerId) {
|
//todo:按照工程号按照工程下未完成的尺寸的顺序,当1号上片位架子上的当前尺寸玻璃少于3片且2号上片位无原片玻璃,则将去调度玻璃去2号上片位,
|
//todo:当一号上片位架子上的玻璃位空或者当前尺寸用完时时,将2号(有玻璃)上片位调度到1号上片位
|
//1、查询上片线路对应工位的原片信息
|
LambdaQueryWrapper<RawGlassStorageDetails> wrapper = new LambdaQueryWrapper<>();
|
wrapper.eq(RawGlassStorageDetails::getState, Const.GLASS_STATE_IN);
|
if ("1".equals(stationCell)) {
|
wrapper.in(RawGlassStorageDetails::getSlot, LOAD_STATION_01);
|
} else {
|
wrapper.in(RawGlassStorageDetails::getSlot, LOAD_STATION_02);
|
}
|
List<RawGlassStorageDetails> rawGlassDetailsList = rawGlassStorageDetailsService.list(wrapper);
|
if (CollectionUtils.isEmpty(rawGlassDetailsList)) {
|
//直接生成调度任务
|
generateTask(1, 2, 34, 4);
|
return Boolean.TRUE;
|
}
|
if (rawGlassDetailsList.size() == 2) {
|
return Boolean.FALSE;
|
}
|
int maxStationSlot = rawGlassDetailsList.stream().mapToInt(RawGlassStorageDetails::getSlot).max().orElse(0);
|
if (LOAD_STATION_MAX.contains(maxStationSlot)) {
|
return Boolean.FALSE;
|
}
|
//二号上片:直接生成调度任务
|
generateTask(1, 2, 34, 4);
|
return Boolean.TRUE;
|
|
|
//当前尺寸需要上片的数量
|
List<UpPattenUsageVO> pattenUsageList = upPattenUsageMapper.queryRawGlassByEngineeringId(enginneerId);
|
if (CollectionUtils.isEmpty(pattenUsageList)) {
|
log.info("正在执行的工程原片无可上片的原片信息");
|
return Boolean.FALSE;
|
}
|
Map<String, List<UpPattenUsageVO>> upListMap = pattenUsageList.stream()
|
.collect(Collectors.groupingBy(UpPattenUsageVO::getGroupNumber));
|
|
|
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.getSlot(), 1, details.getRemainQuantity(), Const.RAW_GLASS_TASK_TYPE_DISPATCH);
|
//结束调度任务
|
}
|
Map<Integer, List<RawGlassStorageDetails>> listMap = rawGlassDetailsList.stream().collect(Collectors.groupingBy(RawGlassStorageDetails::getSlot));
|
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.getSlot(), 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.getSlot(), 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()
|
.startSlot(startSlot)
|
.endSlot(endSlot)
|
.patternQuantity(patternQuantity)
|
.taskType(taskType)
|
.createTime(new Date()).build();
|
return rawGlassStorageTaskService.save(task);
|
}
|
}
|