hangzhoumesParent/common/opcuaClient/src/main/java/com/mes/milo/model/ReadWriteEntity.java
@@ -23,4 +23,8 @@ private Object value; private DataValue dataValue; public String getValueString() { return (String) this.value; } } hangzhoumesParent/common/servicebase/src/main/java/com/mes/common/config/Const.java
@@ -180,4 +180,23 @@ public static final Integer UNLOAD_GLASS_OUT = 1; public static final Integer UNLOAD_GLASS_DOWN = 2; /** * 原片仓储任务类型 * 进片任务1 * 出片任务2 */ public static final Integer RAW_GLASS_TASK_TYPE_IN = 1; public static final Integer RAW_GLASS_TASK_TYPE_OUT = 2; public static final Integer RAW_GLASS_TASK_TYPE_DISPATCH = 3; /** * 原片仓储任务类型 * 进片任务1 * 出片任务2 */ public static final Integer ENGINEERING_NEW = 0; public static final Integer ENGINEERING_RUNNING = 1; } hangzhoumesParent/common/servicebase/src/main/java/com/mes/uppattenusage/entity/vo/UpPattenUsageVO.java
New file @@ -0,0 +1,14 @@ package com.mes.uppattenusage.entity.vo; import com.mes.uppattenusage.entity.UpPattenUsage; import lombok.Data; /** * @Author : zhoush * @Date: 2024/10/12 15:43 * @Description: */ @Data public class UpPattenUsageVO extends UpPattenUsage { private String groupNumber; } hangzhoumesParent/common/servicebase/src/main/java/com/mes/uppattenusage/mapper/UpPattenUsageMapper.java
@@ -2,7 +2,10 @@ import com.github.yulichang.base.MPJBaseMapper; import com.mes.uppattenusage.entity.UpPattenUsage; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.mes.uppattenusage.entity.vo.UpPattenUsageVO; import org.apache.ibatis.annotations.Param; import java.util.List; /** * <p> @@ -14,4 +17,5 @@ */ public interface UpPattenUsageMapper extends MPJBaseMapper<UpPattenUsage> { List<UpPattenUsageVO> queryRawGlassByEngineeringId(@Param("engineeringId") String engineerId); } hangzhoumesParent/common/servicebase/src/main/resources/mapper/UpPattenUsageMapper.xml
New file @@ -0,0 +1,32 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.mes.uppattenusage.mapper.UpPattenUsageMapper"> <resultMap id="baseMap" type="com.mes.uppattenusage.entity.vo.UpPattenUsageVO"> <result column="id" property="id"/> <result column="engineering_id" property="engineeringId"/> <result column="films_id" property="filmsId"/> <result column="width" property="width"/> <result column="height" property="height"/> <result column="thickness" property="thickness"/> <result column="layout_sequence" property="layoutSequence"/> <result column="state" property="state"/> <result column="group_number" property="groupNumber"/> </resultMap> <select id="queryRawGlassByEngineeringId" resultType="com.mes.uppattenusage.entity.vo.UpPattenUsageVO"> SET @prev_width := NULL; SET @prev_height := NULL; SET @counter := 0; SELECT t.*, @counter := IF(@prev_width = width and @prev_height = height, @counter, @counter + 1) AS group_number, @prev_width := width, @prev_height := height FROM up_patten_usage t where t.engineering_id = #{engineeringId} and t.state = 0 ORDER BY t.layout_sequence </select> </mapper> hangzhoumesParent/moduleService/GlassStorageModule/src/main/java/com/mes/job/RawGlassPushMessage.java
@@ -2,10 +2,7 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.json.JSONObject; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.mes.rawglassdetails.entity.RawGlassStorageDetails; import com.mes.rawglassdetails.service.RawGlassStorageDetailsService; import com.mes.rawglassstation.service.RawGlassStorageStationService; import com.mes.rawglasstask.entity.RawGlassStorageTask; import com.mes.rawglasstask.service.RawGlassStorageTaskService; @@ -16,7 +13,6 @@ import javax.annotation.Resource; import java.util.List; import java.util.stream.Collectors; /** * @author wangfei @@ -25,56 +21,26 @@ @Component public class RawGlassPushMessage { @Resource private RawGlassStorageStationService rawGlassStorageStationService; @Resource private RawGlassStorageStationService rawGlassStorageStationService; @Resource private RawGlassStorageTaskService rawGlassStorageTaskService; @Resource private RawGlassStorageTaskService rawGlassStorageTaskService; @Resource private RawGlassStorageDetailsService rawGlassStorageDetailsService; @Scheduled(fixedDelay = 2000) public void sendRawGlassMessage() { log.info("发送任务信息和架子信息"); JSONObject jsonObject = new JSONObject(); List<RawGlassStorageDetails> rawStationDetailsList = rawGlassStorageStationService.listRawGlassDetails(); List<RawGlassStorageTask> tasks = rawGlassStorageTaskService.listRawGlassTask(); jsonObject.append("rawStationDetailsList", rawStationDetailsList); jsonObject.append("tasks", tasks); // log.info("获取到的工位详情及任务信息为:{}", jsonObject); List<WebSocketServer> sendwServer = WebSocketServer.sessionMap.get("rawGlass"); if (CollectionUtil.isNotEmpty(sendwServer)) { sendwServer.stream().forEach(e->{ e.sendMessage(String.valueOf(jsonObject)); }); @Scheduled(fixedDelay = 2000) public void sendRawGlassMessage() { log.info("发送任务信息和架子信息"); JSONObject jsonObject = new JSONObject(); List<RawGlassStorageDetails> rawStationDetailsList = rawGlassStorageStationService.listRawGlassDetails(); List<RawGlassStorageTask> tasks = rawGlassStorageTaskService.listRawGlassTask(); jsonObject.append("rawStationDetailsList", rawStationDetailsList); jsonObject.append("tasks", tasks); List<WebSocketServer> sendwServer = WebSocketServer.sessionMap.get("rawGlass"); if (CollectionUtil.isNotEmpty(sendwServer)) { sendwServer.stream().forEach(e -> { e.sendMessage(String.valueOf(jsonObject)); }); } } } /** todo:入库任务:吊装位有玻璃,先去工位表查询空格子,生成入库任务从吊装位到目标格子 */ // @Scheduled(fixedDelay = 1000) // public void sendRawGlassMessage() { //// List<RawGlassStorageDetails> rawGlassStorageDetailsList = rawGlassStorageDetailsService.List(new RawGlassStorageDetails()) // Wrapper<RawGlassStorageDetails> queryWrapper = null; // List<RawGlassStorageDetails> detailsList = rawGlassStorageDetailsService.list(null); // queryWrapper.eq(RawGlassStorageDetails::getState, 100); // if(detailsList.size() >0){ // //查找格子表details空格子 // List<String> slotIds = detailsList.stream() // .map(RawGlassStorageDetails::getSlotId) // .collect(Collectors.toList()); // list(new LambdaQueryWrapper<RawGlassStorageTask>() // .in(CollectionUtil.isNotEmpty(request.getState()), RawGlassStorageTask::getState, request.getState()) // .in(CollectionUtil.isNotEmpty(request.getSlotId()), RawGlassStorageTask::getSlotId, request.getSlotId()) // .orderByDesc(RawGlassStorageTask::getCreateTime)); // }if(slotIds.size()>0){ // //生成入库任务 // } // // } /** todo:出库任务:1、点出库,立马生成出片任务 2、点出库修改工位详情内的状态为待出库,定时任务扫描生成出库任务 */ /** todo:原片调度:1、查询工程原片表,按照顺序将原片放入上片1号位,后续原片放上片2号位,出现尺寸替换,判断原上片位是否有玻璃,有 先出后进,无 直接进片 */ } hangzhoumesParent/moduleService/GlassStorageModule/src/main/java/com/mes/job/RawGlassTask.java
New file @@ -0,0 +1,201 @@ 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()); 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上片位没有原片,直接找原片放入对应的上片位 //结束调度任务 } 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上片位没有原片,直接找原片放入对应的上片位 //结束调度任务 } else { //将2号上片位的原片放入1号上片位 //结束调度任务 } } else { //原片剩余数量 Integer quantity = rawGlass03Details.getRemainQuantity(); List<UpPattenUsageVO> upPattenUsage01VOS = upListMap.get("1"); if (null == rawGlass04Details) { //todo:判断2号上片位需要的原片信息 if (quantity < upPattenUsage01VOS.size()) { //todo:继续上一号上片位当前的尺寸 } else { //todo:切换尺寸,上后续组的尺寸 List<UpPattenUsageVO> upPattenUsage02VOS = upListMap.get("2"); } } } } /** * 生成原片仓储任务 * * @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); } } hangzhoumesParent/moduleService/GlassStorageModule/src/main/java/com/mes/rawglassdetails/entity/RawGlassStorageDetails.java
@@ -33,7 +33,7 @@ /** * 格子id */ private String slotId; private Integer slotId; /** * 原片宽 @@ -63,7 +63,7 @@ /** * 剩余数量 */ private String remainQuantity; private Integer remainQuantity; /** hangzhoumesParent/moduleService/GlassStorageModule/src/main/java/com/mes/rawglassdetails/mapper/RawGlassStorageDetailsMapper.java
@@ -1,11 +1,14 @@ package com.mes.rawglassdetails.mapper; import com.mes.rawglassdetails.entity.RawGlassStorageDetails; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.mes.rawglassdetails.entity.RawGlassStorageDetails; import org.apache.ibatis.annotations.Param; import java.util.List; /** * <p> * Mapper 接口 * Mapper 接口 * </p> * * @author wf @@ -13,4 +16,12 @@ */ public interface RawGlassStorageDetailsMapper extends BaseMapper<RawGlassStorageDetails> { /** * 按照吊装位和详情表状态查询空闲的吊装位 * * @param liftingStation * @param state * @return */ List<Integer> listBySlotState(@Param("leftingStation") List<String> liftingStation, @Param("state") List<Integer> state); } hangzhoumesParent/moduleService/GlassStorageModule/src/main/java/com/mes/rawglassdetails/mapper/xml/RawGlassStorageDetailsMapper.xml
@@ -1,5 +1,19 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="glassdetails.mapper.RawGlassStorageDetailsMapper"> <mapper namespace="com.mes.rawglassdetails.mapper.RawGlassStorageDetailsMapper"> <select id="listBySlotState" resultType="java.lang.Integer"> select t.slot from raw_glass_storage_station t inner JOIN raw_glass_storage_details t1 on t.slot = t1.slot_id and t.enable_state = 1 and t.slot in <foreach collection="leftingStation" item="item" open='(' close=')' separator=','> #{item} </foreach> and t1.state not in <foreach collection="state" item="item" open='(' close=')' separator=','> #{item} </foreach> </select> </mapper> hangzhoumesParent/moduleService/GlassStorageModule/src/main/java/com/mes/rawglassdetails/service/RawGlassStorageDetailsService.java
@@ -1,10 +1,8 @@ package com.mes.rawglassdetails.service; import com.baomidou.mybatisplus.extension.service.IService; import com.mes.entity.request.GeneralRequest; import com.mes.rawglassdetails.entity.RawGlassStorageDetails; import com.mes.rawglassdetails.entity.request.RawGlassRequest; import com.mes.userinfo.entity.vo.SysUserVO; import java.util.List; @@ -39,4 +37,6 @@ String deleteWarehousing(Long slotId); String outWarehousing(Long slotId); List<Integer> listBySlotState(List<String> liftingStation, List<Integer> state); } hangzhoumesParent/moduleService/GlassStorageModule/src/main/java/com/mes/rawglassdetails/service/impl/RawGlassStorageDetailsServiceImpl.java
@@ -8,8 +8,6 @@ import com.mes.rawglassdetails.entity.request.RawGlassRequest; import com.mes.rawglassdetails.mapper.RawGlassStorageDetailsMapper; import com.mes.rawglassdetails.service.RawGlassStorageDetailsService; import com.mes.rawglassstation.entity.RawGlassStorageStation; import com.mes.userinfo.entity.vo.SysUserVO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; @@ -24,8 +22,8 @@ @Service @Slf4j public class RawGlassStorageDetailsServiceImpl extends ServiceImpl<RawGlassStorageDetailsMapper, RawGlassStorageDetails> implements RawGlassStorageDetailsService { @Override public boolean deleteRawGlassStorageDetails(String device_id) { @Override public boolean deleteRawGlassStorageDetails(String device_id) { QueryWrapper<RawGlassStorageDetails> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("device_id", device_id); return remove(queryWrapper);//remove才是删除,delete得用另外的依赖,默认方法是remove返回bool @@ -60,17 +58,24 @@ .eq(RawGlassStorageDetails::getSlotId, request.getSlotId())); return "success"; } @Override public String deleteWarehousing(Long slotId) { update(new LambdaUpdateWrapper<RawGlassStorageDetails>().eq(RawGlassStorageDetails::getSlotId, slotId) .set(RawGlassStorageDetails::getState,Const.GLASS_STATE_OUT)); .set(RawGlassStorageDetails::getState, Const.GLASS_STATE_OUT)); return "success"; } @Override public String outWarehousing(Long slotId) { update(new LambdaUpdateWrapper<RawGlassStorageDetails>().eq(RawGlassStorageDetails::getSlotId, slotId) .set(RawGlassStorageDetails::getState,Const.GLASS_STATE_OUT_ING)); .set(RawGlassStorageDetails::getState, Const.GLASS_STATE_OUT_ING)); return "success"; } @Override public List<Integer> listBySlotState(List<String> liftingStation, List<Integer> state) { return baseMapper.listBySlotState(liftingStation, state); } } hangzhoumesParent/moduleService/GlassStorageModule/src/main/java/com/mes/rawglasstask/entity/RawGlassStorageTask.java
@@ -2,20 +2,23 @@ import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Builder; import lombok.Data; import lombok.EqualsAndHashCode; import java.io.Serializable; import java.util.Date; /** * <p> * * * </p> * * @author wf * @since 2024-09-10 */ @Data @Builder @EqualsAndHashCode(callSuper = false) public class RawGlassStorageTask implements Serializable { @@ -38,7 +41,7 @@ /** * 原片数量 */ private String patternQuantity; private Integer patternQuantity; /** * 任务类型 @@ -53,7 +56,7 @@ /** * 创建时间 */ private String createTime; private Date createTime; }