From 5f8add5b1064fa68e661434e18670891b5488402 Mon Sep 17 00:00:00 2001 From: lsymicc Date: Sat, 12 Sep 2026 09:33:11 +0800 Subject: [PATCH] =?UTF-8?q?=E7=8E=B0=E5=9C=BA=E8=B0=83=E8=AF=95=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/service/impl/ApiServiceImpl.java | 8 +- .../schedule/scheduleTask/TaskHandler.java | 4 +- .../scheduleTask/ddj/DdjThread_1.java | 2 +- .../scheduleTask/ddj/DdjThread_2.java | 2 +- .../scheduleTask/ssj/RoadConvThread.java | 244 +++++++++++++++++- 5 files changed, 238 insertions(+), 22 deletions(-) diff --git a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ApiServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ApiServiceImpl.java index d4ed52f..85c8d32 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ApiServiceImpl.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/api/service/impl/ApiServiceImpl.java @@ -208,17 +208,17 @@ public class ApiServiceImpl implements IApiService { // mydoJob.setCargoSpaceId(stockoutReceive.getCargoSpaceId()); // mydoJob.setTrayCode(receiveOutJob.getTrayCode()); mydoJob.setInOrOut(stockoutReceive.getInOrOut()); - mydoJob.setTraySize(mydoJobService.getTraytypeByTrayCode(mydoJob.getTrayCode())); +// mydoJob.setTraySize(mydoJobService.getTraytypeByTrayCode(mydoJob.getTrayCode())); mydoJob.setStatus(TASK_STATUS_CREATED); mydoJob.setPriority(10); mydoJob.setRoadwayId(cargoSpace.getRoadwayId()); String exitId; if (cargoSpace.getCargoAreaId().equals("02")){ - exitId = ROADWAY2_PORTCONV_2; + exitId = ROADWAY2_ROADCONV_2; }else if (cargoSpace.getCargoAreaId().equals("03")){ - exitId = ROADWAY2_PORTCONV_3; + exitId = ROADWAY2_ROADCONV_4; }else if (cargoSpace.getCargoAreaId().equals("04")){ - exitId = ROADWAY3_EXIT; + exitId = ROADWAY3_ENTRANCE; }else{ // exitId = ROADWAY1_EXIT; exitId = ROADWAY1_ENTRANCE; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/TaskHandler.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/TaskHandler.java index f4b4a13..71baeba 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/TaskHandler.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/TaskHandler.java @@ -294,7 +294,7 @@ public class TaskHandler { /** * 【更新作业状态】 - 巷道口到位生成堆垛机【取货】作业 */ - @Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT) +// @Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT) public void updateStackerPickStatus() { List jobs = mydoJobService.selectMydoJobList( new MydoJob().builder().status(TASK_STATUS_RUNNING).executionPhase(TASK_EP_ROADWAY_SSJ).build() @@ -359,7 +359,7 @@ public class TaskHandler { /** * 【更新作业状态】 - 取货完成--→请求wms并生成堆垛机放货任务 */ - @Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT) +// @Scheduled(fixedDelay = TIMEINTERVAL_DEFAULT) public void updateStackerPutStatus(){ List jobs = mydoJobService.selectMydoJobList( diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/ddj/DdjThread_1.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/ddj/DdjThread_1.java index 4f5b881..4201fe3 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/ddj/DdjThread_1.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/ddj/DdjThread_1.java @@ -135,7 +135,7 @@ public class DdjThread_1 implements Runnable { if (ddjDeviceExecutionQueue != null && !"1".equals(ddjDeviceExecutionQueue.getSpare1())) { //修改队列执行阶段 ddjDeviceExecutionQueue.setRwzt(ddj.getJdbz()); - ddjDeviceExecutionQueue.setSpare1("1"); +// ddjDeviceExecutionQueue.setSpare1("1"); ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue); } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/ddj/DdjThread_2.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/ddj/DdjThread_2.java index a82550e..7979da3 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/ddj/DdjThread_2.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/ddj/DdjThread_2.java @@ -136,7 +136,7 @@ public class DdjThread_2 implements Runnable { if (ddjDeviceExecutionQueue != null && !"1".equals(ddjDeviceExecutionQueue.getSpare1())) { //修改队列执行阶段 ddjDeviceExecutionQueue.setRwzt(ddj.getJdbz()); - ddjDeviceExecutionQueue.setSpare1("1"); +// ddjDeviceExecutionQueue.setSpare1("1"); ddjDeviceExecutionQueueService.updateDdjDeviceExecutionQueue(ddjDeviceExecutionQueue); } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/ssj/RoadConvThread.java b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/ssj/RoadConvThread.java index f1e60c3..5fa7da7 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/ssj/RoadConvThread.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/schedule/scheduleTask/ssj/RoadConvThread.java @@ -1,15 +1,24 @@ package com.ruoyi.schedule.scheduleTask.ssj; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.lang.UUID; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson2.JSON; +import com.ruoyi.api.domain.agv.ResponseBase; +import com.ruoyi.api.domain.wcs2wms.stockin.StockinReceive; import com.ruoyi.api.service.IApiService; +import com.ruoyi.api.service.IRequestLogService; import com.ruoyi.bas.cargospace.domain.BasCargoSpace; import com.ruoyi.bas.cargospace.service.IBasCargoSpaceService; import com.ruoyi.common.ConvType; +import com.ruoyi.common.TaskType; +import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.utils.spring.SpringUtils; import com.ruoyi.device.ssj.domain.DeviceSsj; import com.ruoyi.job.domain.MydoJob; @@ -38,6 +47,7 @@ public class RoadConvThread implements Runnable { private IMydoJobService mydoJobService; private IBasCargoSpaceService basCargoSpaceService; private IDdjDeviceExecutionQueueService ddjDeviceExecutionQueueService; + private IRequestLogService requestLogService; public boolean isRun = true; @@ -60,8 +70,8 @@ public class RoadConvThread implements Runnable { //todo 核对堆垛机取放位置的货位编码 roadwayMap.put("L1001", Arrays.asList(2, 0, 1)); roadwayMap.put("L1003", Arrays.asList(3, 0, 1)); - roadwayMap.put("L1005", Arrays.asList(5, 0, 1)); - roadwayMap.put("L1007", Arrays.asList(7, 0, 1)); + roadwayMap.put("L1005", Arrays.asList(5, 1, 1)); + roadwayMap.put("L1007", Arrays.asList(7, 1, 1)); roadwayMap.put("L1010", Arrays.asList(10, 0, 1)); roadwayMap.put("L1008", Arrays.asList(11, 0, 1)); log.info("初始化服务 {},{}", apiService, agvQueueService); @@ -109,15 +119,20 @@ public class RoadConvThread implements Runnable { //到位校验 if (roadConvCheckedForStockin(roadSsjDevice)) { + //生成堆垛机取货队列 + sendStackerIn(roadSsjDevice); //更新入库任务阶段 updateMydoJob(roadSsjDevice); - //生成wcs本地作业 - generateWcsMydoJob(roadSsjDevice); +// generateWcsMydoJob(roadSsjDevice); + //巷道口到位请求 + requestMydoJob(roadSsjDevice); }; - //请求wms获取入库任务 - //requestMydoJob(deviceSsj); + if (roadConvCheckedForStackerin(roadSsjDevice)) { + //生成堆垛机取货队列 + sendStackerIn(roadSsjDevice); + }; if (roadConvCheckedForStockout(roadSsjDevice)) { sendStackerOut(roadSsjDevice); @@ -147,9 +162,17 @@ public class RoadConvThread implements Runnable { //更新入库任务阶段 updateMydoJob(roadSsjDevice); //生成wcs本地作业 - generateWcsMydoJob(roadSsjDevice); +// generateWcsMydoJob(roadSsjDevice); + //巷道口到位请求 + requestMydoJob(roadSsjDevice); + } + if (roadConvCheckedForStackerin(roadSsjDevice)) { + //生成堆垛机取货队列 + sendStackerIn(roadSsjDevice); + }; + if (roadConvCheckedForStockout(roadSsjDevice)) { sendStackerOut(roadSsjDevice); } @@ -199,16 +222,35 @@ public class RoadConvThread implements Runnable { /** - * 输送机到位判断校验 - 出库 + * 输送机到位判断校验 - 堆垛机入库 * @param inSsjDevice * @return */ - private boolean roadConvCheckedForStockout(DeviceSsj inSsjDevice){ + private boolean roadConvCheckedForStackerin(DeviceSsj inSsjDevice){ boolean flag = false; //---------------------------巷道口取放货输送机--------------------------- //输送机【任务号】和【到位】校验 - if (inSsjDevice.getTaskNo() == 0 && inSsjDevice.getDw() == 0) flag = true; + if (inSsjDevice.getTaskNo() == 0 || inSsjDevice.getDw() == 0) return flag; + + //输送机条码不能为空 + if (StrUtil.isBlank(inSsjDevice.getTrayCode())) return flag; + + return true; + } + + + /** + * 输送机到位判断校验 - 出库 + * @param outSsjDevice + * @return + */ + private boolean roadConvCheckedForStockout(DeviceSsj outSsjDevice){ + + boolean flag = false; + //---------------------------巷道口取放货输送机--------------------------- + //输送机【任务号】和【到位】校验 + if (outSsjDevice.getTaskNo() == 0 && outSsjDevice.getDw() == 0) flag = true; return flag; } @@ -267,6 +309,108 @@ public class RoadConvThread implements Runnable { } + /** + * 请求wms获取wcs任务参数 + * @param inSsjDevice + */ + private void requestMydoJob(DeviceSsj inSsjDevice){ + + //如果已经生成wcs任务则不继续执行后续请求操作 + //包括请求成功生成作业和wms推送成功的情况 + int count = mydoJobService.selectInOrOutMydoJobList( + new MydoJob().builder().trayCode(inSsjDevice.getTrayCode()).build() + ).size(); + + if (count > 0) { + return; + } + + String errorMessage = ""; + + AjaxResult ajaxResult; + + //初始化请求wms参数 + HashMap paramMap = new HashMap<>(); + paramMap.put("reqCode", UUID.randomUUID().toString());//请求码 + paramMap.put("trayCode", inSsjDevice.getTrayCode().trim());//容器编号 + paramMap.put("entranceId", inSsjDevice.getDeviceCode());//入口输送机编号 + paramMap.put("cargoAreaId", ConvType.CONV_ROAD_AREA.get(inSsjDevice.getDeviceCode()));//入口输送机编号对应巷道/区域 + int height = mydoJobService.getTraytypeByTrayCode(inSsjDevice.getTrayCode()); + if (height == 0){ + log.warn("【请求入库】参数异常,高度不符合入库条件,可能是条码格式错误,条码:{},高度:{}", inSsjDevice.getTrayCode(), height); + return; + } + paramMap.put("height", height);//高度 +// paramMap.put("remark", errorMessage); + + + //-----------------警告校验:条码已有库存----------------- + BasCargoSpace cargoSpace = new BasCargoSpace(); + cargoSpace.setTrayCode(inSsjDevice.getTrayCode()); + if (!basCargoSpaceService.selectBasCargoSpaceList(cargoSpace).isEmpty()) { + log.warn("【警告】该托盘号已有库存,托盘条码:{}",inSsjDevice.getTrayCode()); + } + + + /*-----------------请求生成wcs任务----------------- */ + ajaxResult = apiService.createMydoJobForStockin(paramMap); + if (ajaxResult.isSuccess()) { + + //解析wms下发的响应参数(任务号和货位) + ResponseBase res = JSON.parseObject(ajaxResult.get("msg").toString(), ResponseBase.class); + StockinReceive result = BeanUtil.toBean(res.getData(), StockinReceive.class); + + //校验:wms分配的货位(排列层)是否合法 + if (ObjUtil.isNull(basCargoSpaceService.selectBasCargoSpaceByCargoSpaceId(result.getCargoSpaceId()))) { + errorMessage = "wms下发货位错误,任务生成失败!"; + paramMap.put("remark", errorMessage); + apiService.createInMydoJobException(paramMap); + log.info("【响应参数异常】分配货位:null,无法生成作业,托盘条码:{}",inSsjDevice.getTrayCode()); + writeToSsj(inSsjDevice.getPlcDbWriteAddress(), "99", 2, 1); + return; + } + + int priority = result.getInOrOut() == TaskType.TASKTYPE_MOVE_STR ? 0 : 10; + + //初始化要生成的任务 + MydoJob mydoJob = new MydoJob().builder() + .jobId(result.getJobId()) + .taskNo(mydoJobService.getTaskNo("2"))//如果需要用wms下发的任务号作为wcs的任务号使用 + .status(TASK_STATUS_CREATED) + .trayCode(result.getTrayCode()) + .cargoSpaceId(result.getCargoSpaceId()) +// .wmsTaskNo(mydoJobService.getTaskNo("1")) + .traySize(height) + .inOrOut(result.getInOrOut()) + .roadwayId(basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(result.getCargoSpaceId()).getRoadwayId())//获取货位表货位对应的巷道号 + .entranceId(inSsjDevice.getDeviceCode()) + .executionPhase(TASK_EP_CREATED) + .faultFlag("0") + .priority(priority) + .build(); + + + //如果还没有wcs任务 - 生成一条任务 + if (mydoJobService.selectInOrOutMydoJobList(mydoJob).isEmpty()) { + mydoJobService.insertMydoJob(mydoJob); + log.info("【入库请求】请求生成wcs作业成功,wms任务号:{}, wcs任务号:{},托盘条码:{},分配货位:{}", mydoJob.getWmsTaskNo(), mydoJob.getTaskNo(), mydoJob.getTrayCode(), mydoJob.getCargoSpaceId()); + } + + }else{ + + // 请求生成wcs任务失败 + // 向输送机下发退回 + int i = writeToSsj(inSsjDevice.getPlcDbWriteAddress(), "99", 6, 2); + if(i == 1){ + // 接口调用失败处理 + log.info("【入库请求】请求生成wcs作业失败退回,请检查网络或请求参数,请求内容:{}", JSON.toJSONString(paramMap)); + log.info("【错误信息】{}", requestLogService.selectRequestLogByLatestTask().getErrorDetails()); + } + + } + } + + /** * 更新入库任务阶段 * @param inSsjDevice @@ -302,7 +446,6 @@ public class RoadConvThread implements Runnable { } - /** * 向堆垛机发送【出库】任务 * @param roadSsjDevice @@ -320,6 +463,12 @@ public class RoadConvThread implements Runnable { if (ObjUtil.isNotNull(mydoJob)) { //如果有出库任务 - 检查货位编码是否合法 BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId()); + + int devId = 1; + if (!basCargoSpace.getRoadwayId().equals("1")){ + devId = 2; + } + if (ObjUtil.isNull(basCargoSpace)) { log.error("【任务异常】货位不存在 cargoSpaceId{}", mydoJob.getCargoSpaceId()); } else { @@ -332,8 +481,8 @@ public class RoadConvThread implements Runnable { DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue(); ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID()); ddjDeviceExecutionQueue.setRwh(Convert.toLong(mydoJob.getTaskNo())); - ddjDeviceExecutionQueue.setDevName(mydoJob.getRoadwayId()); - ddjDeviceExecutionQueue.setDevId(Convert.toInt(mydoJob.getRoadwayId())); + ddjDeviceExecutionQueue.setDevName(String.valueOf("ddj" + devId)); + ddjDeviceExecutionQueue.setDevId(devId); ddjDeviceExecutionQueue.setRwzt(0); ddjDeviceExecutionQueue.setYph(Convert.toInt(basCargoSpace.getThePlatoon())); ddjDeviceExecutionQueue.setYlh(Convert.toInt(basCargoSpace.getTheColumn())); @@ -343,7 +492,7 @@ public class RoadConvThread implements Runnable { ddjDeviceExecutionQueue.setMbch(pclList.get(2)); ddjDeviceExecutionQueue.setDdjxf("0"); ddjDeviceExecutionQueue.setMlfs(5); - ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize().toString());//货物高度 +// ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize().toString());//货物高度 ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date())); // ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_2); ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue); @@ -352,6 +501,8 @@ public class RoadConvThread implements Runnable { mydoJob.setExecutionPhase(TASK_EP_DDJ); mydoJob.setStartTime(DateUtil.formatDateTime(DateUtil.date())); mydoJobService.updateMydoJob(mydoJob); + + log.info("【堆垛机出库】输送机:{}空闲,等待堆垛机执行,更新任务状态,任务号:{}", roadSsjDevice.getDeviceCode(), mydoJob.getTaskNo()); } } }else{ @@ -363,4 +514,69 @@ public class RoadConvThread implements Runnable { } + /** + * 向堆垛机发送【入库】任务 + * @param roadSsjDevice + */ + private void sendStackerIn(DeviceSsj roadSsjDevice){ +//---------------------------出库任务--------------------------- + + //检查是否有入库任务 + MydoJob mydoJob = mydoJobService.selectMydoJobByTaskNo(Long.valueOf(roadSsjDevice.getTaskNo())); + if (ObjUtil.isNotNull(mydoJob)) { + + //检查执行阶段 + if (!mydoJob.getExecutionPhase().equals(TASK_EP_ROADWAY_SSJ)) return; + + //如果有入库任务 - 检查货位编码是否合法 + BasCargoSpace basCargoSpace = basCargoSpaceService.selectBasCargoSpaceByWmsCargoSpaceId(mydoJob.getCargoSpaceId()); + + int devId = 1; + if (!basCargoSpace.getRoadwayId().equals("1")){ + devId = 2; + } + + if (ObjUtil.isNull(basCargoSpace)) { + log.error("【任务异常】货位不存在 cargoSpaceId{}", mydoJob.getCargoSpaceId()); + } else { + //生成队列 + List list = ddjDeviceExecutionQueueService.selectDdjDeviceExecutionQueueList( + new DdjDeviceExecutionQueue().builder().devId(Convert.toInt(mydoJob.getRoadwayId())).build() + ); + List pclList = roadwayMap.get(roadSsjDevice.getDeviceCode()); + if (CollUtil.isEmpty(list) && CollUtil.isNotEmpty(pclList)) { + DdjDeviceExecutionQueue ddjDeviceExecutionQueue = new DdjDeviceExecutionQueue(); + ddjDeviceExecutionQueue.setUuid(IdUtil.simpleUUID()); + ddjDeviceExecutionQueue.setRwh(Convert.toLong(mydoJob.getTaskNo())); + ddjDeviceExecutionQueue.setDevName("ddj" + devId); + ddjDeviceExecutionQueue.setDevId(devId); + ddjDeviceExecutionQueue.setRwzt(0); + ddjDeviceExecutionQueue.setYph(pclList.get(0)); + ddjDeviceExecutionQueue.setYlh(pclList.get(1)); + ddjDeviceExecutionQueue.setYch(pclList.get(2)); + ddjDeviceExecutionQueue.setMbph(Convert.toInt(basCargoSpace.getThePlatoon())); + ddjDeviceExecutionQueue.setMblh(Convert.toInt(basCargoSpace.getTheColumn())); + ddjDeviceExecutionQueue.setMbch(Convert.toInt(basCargoSpace.getTheFloor())); + ddjDeviceExecutionQueue.setDdjxf("0"); + ddjDeviceExecutionQueue.setMlfs(5); +// ddjDeviceExecutionQueue.setSpare1(mydoJob.getTraySize().toString());//货物高度 + ddjDeviceExecutionQueue.setScsj(DateUtil.formatDateTime(DateUtil.date())); +// ddjDeviceExecutionQueue.setRwlx(DDJ_RWLX_2); + ddjDeviceExecutionQueueService.insertDdjDeviceExecutionQueue(ddjDeviceExecutionQueue); + //修改作业状态 + mydoJob.setStatus(TASK_STATUS_RUNNING); + mydoJob.setExecutionPhase(TASK_EP_DDJ); + mydoJob.setStartTime(DateUtil.formatDateTime(DateUtil.date())); + mydoJobService.updateMydoJob(mydoJob); + + log.info("【巷道口入库】输送机:{}入库到位,更新任务状态,等待堆垛机执行,任务号:{}", roadSsjDevice.getDeviceCode(), mydoJob.getTaskNo()); + } + } + }else{ +// log.info("【出库警告】当前出口"+ exitId +"存在入库任务,无法出库!"); + } + + } + + }