zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/controller/OpenController.java
@@ -1,37 +1,14 @@ package com.zy.asrs.wcs.core.controller; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.common.R; import com.zy.asrs.framework.common.SnowflakeIdWorker; import com.zy.asrs.wcs.core.domain.dto.BasLiftStaDto; import com.zy.asrs.wcs.core.domain.param.*; import com.zy.asrs.wcs.core.entity.*; import com.zy.asrs.wcs.core.model.enums.DeviceCtgType; import com.zy.asrs.wcs.core.model.enums.TaskCtgType; import com.zy.asrs.wcs.core.model.enums.TaskStsType; import com.zy.asrs.wcs.core.service.*; import com.zy.asrs.wcs.core.utils.Utils; import com.zy.asrs.wcs.rcs.cache.SlaveConnection; import com.zy.asrs.wcs.rcs.entity.Device; import com.zy.asrs.wcs.rcs.model.enums.SlaveType; import com.zy.asrs.wcs.rcs.model.enums.WorkModeType; import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol; import com.zy.asrs.wcs.rcs.service.DeviceService; import com.zy.asrs.wcs.rcs.thread.DevpThread; import com.zy.asrs.wcs.rcs.thread.ShuttleThread; import com.zy.asrs.wcs.core.utils.OpenUtils; import com.zy.asrs.wcs.system.controller.BaseController; import com.zy.asrs.wcs.system.entity.Dict; import com.zy.asrs.wcs.system.service.DictService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Date; import java.util.List; /** * 对外暴露接口 @@ -42,418 +19,36 @@ public class OpenController extends BaseController { @Autowired private SnowflakeIdWorker snowflakeIdWorker; @Autowired private TaskCtgService taskCtgService; @Autowired private TaskService taskService; @Autowired private DeviceService deviceService; @Autowired private LocService locService; @Autowired private DictService dictService; @Autowired private BasConveyorPathService basConveyorPathService; @Autowired private BasLiftService basLiftService; @Autowired private BasConveyorService basConveyorService; @Autowired private BasConveyorStaService basConveyorStaService; private OpenUtils openUtils; //生成入库任务 @PostMapping("/createInTask") public R createInTask(@RequestBody CreateInTaskParam param) { //获取入库任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.IN)) .eq(TaskCtg::getStatus, 1)); if (taskCtg == null) { return R.error("任务类型异常"); } Long hostId = 1L;//默认主仓库 Loc loc = locService.selectByLocNo(param.getDestLoc()); if (loc == null) { return R.error("库位号不存在"); } //获取严格模式参数 boolean mapStrict = true;//默认严格模式 Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>().eq(Dict::getFlag, "shuttleMapStrict")); if (dict != null) { mapStrict = Boolean.parseBoolean(dict.getValue()); } if (mapStrict && !loc.getLocStsFlag().equals("O")) { return R.error("库位状态不满足入库条件"); } Task one = taskService.getOne(new LambdaQueryWrapper<Task>() .eq(Task::getTaskCtg, taskCtg.getId()) .eq(Task::getOriginSite, param.getOriginSite()) .eq(Task::getDestSite, param.getDestSite()) .eq(Task::getDestLoc, param.getDestLoc())); if (one != null) { return R.error("任务已存在"); } String destSite = param.getDestSite(); if (Cools.isEmpty(param.getDestSite())) { //目标站为空则使用WCS系统内置路径 BasConveyorPath path = basConveyorPathService.getOne(new LambdaQueryWrapper<BasConveyorPath>() .eq(BasConveyorPath::getTypeNo, taskCtg.getId()) .eq(BasConveyorPath::getHostId, hostId) .eq(BasConveyorPath::getStnNo, param.getOriginSite())); if(path == null) { return R.error("内置路径不存在"); } destSite = String.valueOf(path.getDeviceStn()); } // //判断出入库模式 // BasConveyorSta basConveyorSta = basConveyorStaService.getOne(new LambdaQueryWrapper<BasConveyorSta>() // .eq(BasConveyorSta::getSiteNo, destSite)); // if (!basConveyorSta.getWorkMode().equals((int) WorkModeType.PAKIN_MODE.id)) { // //不是入库模式,检测是否可切换入库 // //获取出库任务类型 // TaskCtg taskInCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() // .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.OUT)) // .eq(TaskCtg::getStatus, 1)); // if (taskInCtg == null) { // return R.error("任务类型异常"); // } // List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>() // .eq(Task::getTaskCtg, taskInCtg.getId())); // if (!tasks.isEmpty()) { // return R.error("当前存在出库任务,无法切换入库模式"); // } // // BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper<BasConveyor>().eq(BasConveyor::getConveyorNo, basConveyorSta.getConveyorNo())); // if(basConveyor == null) { // return R.error("输送线不存在"); // } // // DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue()); // if(devpThread == null) { // return R.error("输送线线程不存在"); // } // // boolean result = devpThread.switchWorkMode(Integer.parseInt(destSite), WorkModeType.PAKIN_MODE.id); // if (!result) { // return R.error("模式切换失败"); // } // } //优先级 Integer priority = 10; if (param.getPriority() != null) { priority = param.getPriority(); } Task task = new Task(); task.setUuid(String.valueOf(snowflakeIdWorker.nextId())); task.setTaskNo(String.valueOf(Utils.getTaskNo("IN"))); task.setWmsTaskNo(param.getTaskNo()); task.setTaskSts(TaskStsType.NEW_INBOUND.sts); task.setTaskCtg(taskCtg.getId()); task.setPriority(priority); task.setOriginSite(param.getOriginSite()); task.setOriginLoc(null); task.setDestSite(destSite); task.setDestLoc(param.getDestLoc()); task.setZpallet(param.getBarcode()); task.setIoTime(new Date()); task.setStartTime(new Date()); task.setStatus(1); task.setMemo(""); task.setShuttleNo(null);//等待主线程分配小车 task.setRecordLoc("Y");//记录库存信息 task.setHostId(hostId);//临时控制只允许host为1 boolean result = taskService.save(task); if (!result) { return R.error("生成入库任务失败!"); } return R.ok(); return openUtils.createInTask(param); } //生成出库任务 @PostMapping("/createOutTask") public R createOutTask(@RequestBody CreateOutTaskParam param) { //获取出库任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.OUT)) .eq(TaskCtg::getStatus, 1)); if (taskCtg == null) { return R.error("任务类型异常"); } Long hostId = 1L;//默认主仓库 Loc loc = locService.selectByLocNo(param.getOriginLoc()); if (loc == null) { return R.error("库位号不存在"); } //获取严格模式参数 boolean mapStrict = true;//默认严格模式 Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>().eq(Dict::getFlag, "shuttleMapStrict")); if (dict != null) { mapStrict = Boolean.parseBoolean(dict.getValue()); } if (mapStrict && !loc.getLocStsFlag().equals("F")) { return R.error("库位状态不满足出库条件"); } Task one = taskService.getOne(new LambdaQueryWrapper<Task>() .eq(Task::getTaskCtg, taskCtg.getId()) .eq(Task::getOriginSite, param.getOriginSite()) .eq(Task::getOriginLoc, param.getOriginLoc()) .eq(Task::getDestSite, param.getDestSite())); if (one != null) { return R.error("任务已存在"); } String originSite = param.getOriginSite(); if (Cools.isEmpty(param.getOriginSite())) { //使用WCS系统内置路径 BasConveyorPath path = basConveyorPathService.getOne(new LambdaQueryWrapper<BasConveyorPath>() .eq(BasConveyorPath::getTypeNo, taskCtg.getId()) .eq(BasConveyorPath::getHostId, hostId) .eq(BasConveyorPath::getStnNo, param.getDestSite())); if(path == null) { return R.error("内置路径不存在"); } Integer deviceNo = path.getDeviceNo();//获取提升机号 BasLift basLift = basLiftService.getOne(new LambdaQueryWrapper<BasLift>().eq(BasLift::getLiftNo, deviceNo).eq(BasLift::getHostId, hostId)); if(basLift == null) { return R.error("提升机对象不存在"); } List<BasLiftStaDto> staList = JSON.parseArray(basLift.getSta(), BasLiftStaDto.class); BasLiftStaDto originStaDto = null; for (BasLiftStaDto sta : staList) { if (sta.getLev() == Utils.getLev(param.getOriginLoc())) { originStaDto = sta; break; } } if (originStaDto == null) { return R.error("源站不存在"); } originSite = String.valueOf(originStaDto.getStaNo()); } // //判断出入库模式 // BasConveyorSta basConveyorSta = basConveyorStaService.getOne(new LambdaQueryWrapper<BasConveyorSta>() // .eq(BasConveyorSta::getSiteNo, originSite)); // if (!basConveyorSta.getWorkMode().equals((int) WorkModeType.PAKOUT_MODE.id)) { // //不是出库模式,检测是否可切换出库 // //获取入库任务类型 // TaskCtg taskInCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() // .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.IN)) // .eq(TaskCtg::getStatus, 1)); // if (taskInCtg == null) { // return R.error("任务类型异常"); // } // List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>() // .eq(Task::getTaskCtg, taskInCtg.getId())); // if (!tasks.isEmpty()) { // return R.error("当前存在入库任务,无法切换出库模式"); // } // // BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper<BasConveyor>().eq(BasConveyor::getConveyorNo, basConveyorSta.getConveyorNo())); // if(basConveyor == null) { // return R.error("输送线不存在"); // } // // DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue()); // if(devpThread == null) { // return R.error("输送线线程不存在"); // } // // boolean result = devpThread.switchWorkMode(Integer.parseInt(originSite), WorkModeType.PAKOUT_MODE.id); // if (!result) { // return R.error("模式切换失败"); // } // } //优先级 Integer priority = 10; if (param.getPriority() != null) { priority = param.getPriority(); } Task task = new Task(); task.setUuid(String.valueOf(snowflakeIdWorker.nextId())); task.setTaskNo(String.valueOf(Utils.getTaskNo("OUT"))); task.setWmsTaskNo(param.getTaskNo()); task.setTaskSts(TaskStsType.NEW_OUTBOUND.sts); task.setTaskCtg(taskCtg.getId()); task.setPriority(priority); task.setOriginSite(originSite); task.setOriginLoc(param.getOriginLoc()); task.setDestSite(param.getDestSite()); task.setDestLoc(null); task.setIoTime(new Date()); task.setStartTime(new Date()); task.setStatus(1); task.setMemo(""); task.setShuttleNo(null);//等待主线程分配小车 task.setRecordLoc("Y");//记录库存信息 task.setHostId(hostId);//临时控制只允许host为1 boolean result = taskService.save(task); if (!result) { return R.error("生成出库任务失败!"); } return R.ok(); return openUtils.createOutTask(param); } //生成手动取放货任务 @PostMapping("/createManualTakeTask") public R createManualTakeTask(@RequestBody CreateManualTakeTaskParam param) { //获取手动任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.MANUAL)) .eq(TaskCtg::getStatus, 1)); if (taskCtg == null) { return R.error("任务类型异常"); } Task one = taskService.getOne(new LambdaQueryWrapper<Task>() .eq(Task::getTaskCtg, taskCtg.getId()) .eq(Task::getOriginLoc, param.getOriginLoc()) .eq(Task::getDestLoc, param.getDestLoc())); if (one != null) { return R.error("任务已存在"); } //优先级 Integer priority = 10; if (param.getPriority() != null) { priority = param.getPriority(); } Task task = new Task(); task.setUuid(String.valueOf(snowflakeIdWorker.nextId())); task.setTaskNo(String.valueOf(Utils.getTaskNo("OUT"))); task.setWmsTaskNo(param.getTaskNo()); task.setTaskSts(TaskStsType.NEW_MANUAL.sts); task.setTaskCtg(taskCtg.getId()); task.setPriority(priority); task.setOriginSite(null); task.setOriginLoc(param.getOriginLoc());//源库位 task.setDestSite(null); task.setDestLoc(param.getDestLoc());//目标库位 task.setIoTime(new Date()); task.setStartTime(new Date()); task.setStatus(1); task.setMemo(""); task.setShuttleNo(null);//等待主线程分配小车 task.setRecordLoc(param.getRecord() ? "Y" : "N");//记录库存信息 task.setHostId(1L);//临时控制只允许host为1 boolean result = taskService.save(task); if (!result) { return R.error("生成手动取放货任务失败!"); } return R.ok(); return openUtils.createManualTakeTask(param); } //生成小车移动任务 @PostMapping("/createMoveTask") public R createMoveTask(@RequestBody CreateMoveTaskParam param) { //获取出库任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.MOVE)) .eq(TaskCtg::getStatus, 1)); if (taskCtg == null) { return R.error("任务类型异常"); } Device device = deviceService.getOne(new LambdaQueryWrapper<Device>() .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val()) .eq(Device::getDeviceNo, param.getShuttleNo()) .eq(Device::getHostId, 1) .eq(Device::getStatus, 1)); if (device == null) { return R.error("穿梭车不存在"); } ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); if (shuttleThread == null) { return R.error("穿梭车不在线"); } ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); if (shuttleProtocol == null) { return R.error("穿梭车不在线"); } // if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) != Utils.getLev(param.getDestLoc())) { // return R.error("穿梭车和目标位置不在同一楼层"); // } Task one = taskService.getOne(new LambdaQueryWrapper<Task>() .eq(Task::getTaskCtg, taskCtg.getId()) .eq(Task::getDestLoc, param.getDestLoc())); if (one != null) { return R.error("任务已存在"); } //优先级 Integer priority = 10; if (param.getPriority() != null) { priority = param.getPriority(); } Task task = new Task(); task.setUuid(String.valueOf(snowflakeIdWorker.nextId())); task.setTaskNo(String.valueOf(Utils.getTaskNo("OUT"))); task.setWmsTaskNo(param.getTaskNo()); task.setTaskSts(TaskStsType.NEW_MOVE.sts); task.setTaskCtg(taskCtg.getId()); task.setPriority(priority); task.setOriginSite(null); task.setOriginLoc(null); task.setDestSite(null); task.setDestLoc(param.getDestLoc()); task.setIoTime(new Date()); task.setStartTime(new Date()); task.setStatus(1); task.setMemo(""); task.setShuttleNo(param.getShuttleNo()); task.setRecordLoc("N");//不记录库存信息 task.setHostId(1L);//临时控制只允许host为1 boolean result = taskService.save(task); if (!result) { return R.error("生成小车移动任务失败!"); } return R.ok(); return openUtils.createMoveTask(param); } //切换工作模式 @PostMapping("/switchWorkMode") public R switchWorkMode(@RequestBody SwitchWorkModeParam param) { BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper<BasConveyor>().eq(BasConveyor::getConveyorNo, param.getConveyorNo())); if(basConveyor == null) { return R.error("输送线不存在"); } DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue()); if(devpThread == null) { return R.error("输送线线程不存在"); } boolean result = devpThread.switchWorkMode(param.getSiteId(), param.getWorkMode()); if (!result) { return R.error("模式切换失败"); } return R.ok(); return openUtils.switchWorkMode(param); } } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/kernel/command/LiftCommandService.java
@@ -115,6 +115,11 @@ command = liftThread.getPalletInOutCommand(assignCommand.getDeviceTaskNo(), Integer.parseInt(motion.getOrigin()), Integer.parseInt(motion.getTarget()), motion.getOriDrt(), motion.getTarDrt(), LiftCommandModeType.PALLET_INOUT); list.addAll(command); motion.setTemp(String.valueOf(assignCommand.getDeviceTaskNo())); motion.setUpdateTime(new Date()); motionService.updateById(motion); return liftAction.assignWork(liftThread.getDevice(), assignCommand); case LIFT_WITH_SHUTTLE: //判断提升机是否自动 @@ -247,7 +252,13 @@ return false; } if (!motion.getTaskNo().equals(staProtocol.getWorkNo().intValue())) { return false; if (motion.getTemp() == null) { return false; } if (Integer.parseInt(motion.getTemp()) != staProtocol.getWorkNo().intValue()) { return false; } } if (motion.getReleaseLift() == 1) {//释放提升机 zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/model/enums/TaskStsType.java
@@ -1,10 +1,6 @@ package com.zy.asrs.wcs.core.model.enums; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.framework.common.SpringUtils; import com.zy.asrs.framework.exception.CoolException; import com.zy.asrs.wcs.core.entity.TaskSts; import com.zy.asrs.wcs.core.service.TaskStsService; public enum TaskStsType { zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/service/impl/MainServiceImpl.java
@@ -8,15 +8,18 @@ import com.zy.asrs.common.domain.param.SearchLocParam; import com.zy.asrs.common.utils.HttpHandler; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.common.R; import com.zy.asrs.framework.common.SnowflakeIdWorker; import com.zy.asrs.wcs.core.domain.dto.MatDto; import com.zy.asrs.wcs.core.domain.dto.RedisMapDto; import com.zy.asrs.wcs.core.domain.dto.StaDto; import com.zy.asrs.wcs.core.domain.param.CreateInTaskParam; import com.zy.asrs.wcs.core.entity.*; import com.zy.asrs.wcs.core.kernel.AnalyzeService; import com.zy.asrs.wcs.core.model.MapNode; import com.zy.asrs.wcs.core.model.enums.*; import com.zy.asrs.wcs.core.service.*; import com.zy.asrs.wcs.core.utils.OpenUtils; import com.zy.asrs.wcs.core.utils.RedisUtil; import com.zy.asrs.wcs.core.utils.ShuttleDispatcher; import com.zy.asrs.wcs.core.utils.Utils; @@ -86,6 +89,8 @@ private DeviceBarcodeService deviceBarcodeService; @Autowired private ShuttleChargeStaService shuttleChargeStaService; @Autowired private OpenUtils openUtils; /** * 组托 @@ -191,19 +196,18 @@ } } //获取入库任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.IN)) .eq(TaskCtg::getStatus, 1)); // 判断重复工作档 Task task1 = taskService.getOne(new LambdaQueryWrapper<Task>() .eq(Task::getOriginSite, inSta.getStaNo()) .eq(Task::getTaskCtg, taskCtg.getId()) .in(Task::getTaskSts, 1, 2, 3) .in(Task::getTaskSts, TaskStsType.NEW_INBOUND.sts, TaskStsType.ANALYZE_INBOUND.sts, TaskStsType.EXECUTE_INBOUND.sts) .eq(Task::getZpallet, barcode)); if (task1 != null) { News.error("工作档已存在,工作号={}", task1.getTaskNo()); if (staProtocol.getWorkNo().intValue() != Integer.parseInt(task1.getTaskNo())) { devpThread.writeWorkSta(staProtocol.getSiteId(), Short.parseShort(task1.getTaskNo()), Short.parseShort(task1.getDestSite())); devpThread.setPakMk(staProtocol.getSiteId(), false); News.info("输送线入库命令下发,任务数据={}", JSON.toJSON(task1)); } continue; } @@ -233,17 +237,25 @@ if (code.equals(200)) { StartupDto dto = jsonObject.getObject("data", StartupDto.class); //获取输送路径 BasConveyorPath conveyorPath = basConveyorPathService.getOne(new LambdaQueryWrapper<BasConveyorPath>() .eq(BasConveyorPath::getTypeNo, TaskCtgType.IN.val()) .eq(BasConveyorPath::getDeviceId, devp.getId()) .eq(BasConveyorPath::getStnNo, staProtocol.getSiteId())); if (conveyorPath == null) { News.error("输送路径不存在"); }else { devpThread.writeWorkSta(staProtocol.getSiteId(), dto.getWorkNo().shortValue(), conveyorPath.getDeviceStn().shortValue()); devpThread.setPakMk(staProtocol.getSiteId(), false); } String wmsLocNo = dto.getLocNo(); int row = Integer.parseInt(wmsLocNo.substring(0, 2)); int bay = Integer.parseInt(wmsLocNo.substring(2, 5)); int lev = Integer.parseInt(wmsLocNo.substring(5, 7)); row -= 16; String wcsLocNo = Utils.getLocNo(row, bay, lev); CreateInTaskParam createInTaskParam = new CreateInTaskParam(); createInTaskParam.setTaskNo(String.valueOf(dto.getWorkNo())); createInTaskParam.setDestLoc(wcsLocNo); createInTaskParam.setOriginSite("31002"); createInTaskParam.setDestSite("31004"); createInTaskParam.setPriority(11); createInTaskParam.setBarcode(barcode); R result = openUtils.createInTask(createInTaskParam); News.info("创建入库任务,任务数据={},请求响应={}", JSON.toJSON(param), JSON.toJSON(result)); }else { News.error("入库申请失败,任务数据={},请求响应={}", JSON.toJSON(param), JSON.toJSON(jsonObject)); } } catch (Exception e) { e.printStackTrace(); @@ -455,7 +467,7 @@ if (Cools.isEmpty(basConveyorSta.getTaskNo())){ continue; } if (!basConveyorSta.getTaskNo().toString().equals(task.getWmsTaskNo())){ if (!basConveyorSta.getTaskNo().toString().equals(task.getTaskNo())){ continue; } DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue()); zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/timer/TaskTimer.java
@@ -8,6 +8,7 @@ import com.zy.asrs.wcs.core.model.enums.LocStsType; import com.zy.asrs.wcs.core.model.enums.TaskStsType; import com.zy.asrs.wcs.core.service.*; import com.zy.asrs.wcs.rcs.News; import com.zy.asrs.wcs.system.entity.Dict; import com.zy.asrs.wcs.system.service.DictService; import lombok.extern.slf4j.Slf4j; @@ -51,9 +52,17 @@ .eq(Task::getStatus, 1) .in(Task::getTaskSts, taskSts)); for (Task task : tasks) { if (reportWms != null && reportWms.getFlag().equals("true")) { if (reportWms != null && reportWms.getValue().equals("true")) { //获取WMS地址 Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>().eq(Dict::getFlag, "WMS_URL").eq(Dict::getStatus, 1)); if (dict == null) { News.error("WMS地址未配置"); return; } String wmsUrl = dict.getValue(); if(task.getTaskSts().equals(TaskStsType.COMPLETE_INBOUND.sts) || task.getTaskSts().equals(TaskStsType.COMPLETE_OUTBOUND.sts)){ boolean httpRequest = doHttpRequest(task, "127.0.0.1:8080", "/wms/open/asrs//wrkMast/finish/v1"); boolean httpRequest = doHttpRequest(task, wmsUrl, "/open/asrs//wrkMast/finish/v1"); if (!httpRequest) { return; } zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/LiftDispatcher.java
@@ -81,6 +81,9 @@ String liftLocNo = Utils.getLocNo(Utils.getRow(standby.getDeviceStandbyLoc()), Utils.getBay(standby.getDeviceStandbyLoc()), Utils.getLev(locNo)); List<NavigateNode> nodeList = NavigateUtils.calc(locNo, liftLocNo, NavigationMapType.NONE.id, null); if (nodeList == null) { continue; } Integer originPathAllDistance = NavigateUtils.getOriginPathAllDistance(nodeList);//总距离 if (originPathAllDistance < finalDistance) { finalDistance = originPathAllDistance; zy-asrs-wcs/src/main/java/com/zy/asrs/wcs/core/utils/OpenUtils.java
New file @@ -0,0 +1,438 @@ package com.zy.asrs.wcs.core.utils; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.common.R; import com.zy.asrs.framework.common.SnowflakeIdWorker; import com.zy.asrs.wcs.core.domain.dto.BasLiftStaDto; import com.zy.asrs.wcs.core.domain.param.*; import com.zy.asrs.wcs.core.entity.*; import com.zy.asrs.wcs.core.model.enums.DeviceCtgType; import com.zy.asrs.wcs.core.model.enums.TaskCtgType; import com.zy.asrs.wcs.core.model.enums.TaskStsType; import com.zy.asrs.wcs.core.service.*; import com.zy.asrs.wcs.rcs.cache.SlaveConnection; import com.zy.asrs.wcs.rcs.entity.Device; import com.zy.asrs.wcs.rcs.model.enums.SlaveType; import com.zy.asrs.wcs.rcs.model.protocol.ShuttleProtocol; import com.zy.asrs.wcs.rcs.service.DeviceService; import com.zy.asrs.wcs.rcs.thread.DevpThread; import com.zy.asrs.wcs.rcs.thread.ShuttleThread; import com.zy.asrs.wcs.system.entity.Dict; import com.zy.asrs.wcs.system.service.DictService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Date; import java.util.List; @Component public class OpenUtils { @Autowired private SnowflakeIdWorker snowflakeIdWorker; @Autowired private TaskCtgService taskCtgService; @Autowired private TaskService taskService; @Autowired private DeviceService deviceService; @Autowired private LocService locService; @Autowired private DictService dictService; @Autowired private BasConveyorPathService basConveyorPathService; @Autowired private BasLiftService basLiftService; @Autowired private BasConveyorService basConveyorService; @Autowired private BasConveyorStaService basConveyorStaService; public R createInTask(CreateInTaskParam param) { //获取入库任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.IN)) .eq(TaskCtg::getStatus, 1)); if (taskCtg == null) { return R.error("任务类型异常"); } Long hostId = 1L;//默认主仓库 Loc loc = locService.selectByLocNo(param.getDestLoc()); if (loc == null) { return R.error("库位号不存在"); } //获取严格模式参数 boolean mapStrict = true;//默认严格模式 Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>().eq(Dict::getFlag, "shuttleMapStrict")); if (dict != null) { mapStrict = Boolean.parseBoolean(dict.getValue()); } if (mapStrict && !loc.getLocStsFlag().equals("O")) { return R.error("库位状态不满足入库条件"); } Task one = taskService.getOne(new LambdaQueryWrapper<Task>() .eq(Task::getTaskCtg, taskCtg.getId()) .eq(Task::getOriginSite, param.getOriginSite()) .eq(Task::getDestSite, param.getDestSite()) .eq(Task::getDestLoc, param.getDestLoc())); if (one != null) { return R.error("任务已存在"); } String destSite = param.getDestSite(); if (Cools.isEmpty(param.getDestSite())) { //目标站为空则使用WCS系统内置路径 BasConveyorPath path = basConveyorPathService.getOne(new LambdaQueryWrapper<BasConveyorPath>() .eq(BasConveyorPath::getTypeNo, taskCtg.getId()) .eq(BasConveyorPath::getHostId, hostId) .eq(BasConveyorPath::getStnNo, param.getOriginSite())); if(path == null) { return R.error("内置路径不存在"); } destSite = String.valueOf(path.getDeviceStn()); } // //判断出入库模式 // BasConveyorSta basConveyorSta = basConveyorStaService.getOne(new LambdaQueryWrapper<BasConveyorSta>() // .eq(BasConveyorSta::getSiteNo, destSite)); // if (!basConveyorSta.getWorkMode().equals((int) WorkModeType.PAKIN_MODE.id)) { // //不是入库模式,检测是否可切换入库 // //获取出库任务类型 // TaskCtg taskInCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() // .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.OUT)) // .eq(TaskCtg::getStatus, 1)); // if (taskInCtg == null) { // return R.error("任务类型异常"); // } // List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>() // .eq(Task::getTaskCtg, taskInCtg.getId())); // if (!tasks.isEmpty()) { // return R.error("当前存在出库任务,无法切换入库模式"); // } // // BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper<BasConveyor>().eq(BasConveyor::getConveyorNo, basConveyorSta.getConveyorNo())); // if(basConveyor == null) { // return R.error("输送线不存在"); // } // // DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue()); // if(devpThread == null) { // return R.error("输送线线程不存在"); // } // // boolean result = devpThread.switchWorkMode(Integer.parseInt(destSite), WorkModeType.PAKIN_MODE.id); // if (!result) { // return R.error("模式切换失败"); // } // } //优先级 Integer priority = 10; if (param.getPriority() != null) { priority = param.getPriority(); } Task task = new Task(); task.setUuid(String.valueOf(snowflakeIdWorker.nextId())); task.setTaskNo(String.valueOf(Utils.getTaskNo("IN"))); task.setWmsTaskNo(param.getTaskNo()); task.setTaskSts(TaskStsType.NEW_INBOUND.sts); task.setTaskCtg(taskCtg.getId()); task.setPriority(priority); task.setOriginSite(param.getOriginSite()); task.setOriginLoc(null); task.setDestSite(destSite); task.setDestLoc(param.getDestLoc()); task.setZpallet(param.getBarcode()); task.setIoTime(new Date()); task.setStartTime(new Date()); task.setStatus(1); task.setMemo(""); task.setShuttleNo(null);//等待主线程分配小车 task.setRecordLoc("Y");//记录库存信息 task.setHostId(hostId);//临时控制只允许host为1 boolean result = taskService.save(task); if (!result) { return R.error("生成入库任务失败!"); } return R.ok().add(task); } public R createOutTask(CreateOutTaskParam param) { //获取出库任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.OUT)) .eq(TaskCtg::getStatus, 1)); if (taskCtg == null) { return R.error("任务类型异常"); } Long hostId = 1L;//默认主仓库 Loc loc = locService.selectByLocNo(param.getOriginLoc()); if (loc == null) { return R.error("库位号不存在"); } //获取严格模式参数 boolean mapStrict = true;//默认严格模式 Dict dict = dictService.getOne(new LambdaQueryWrapper<Dict>().eq(Dict::getFlag, "shuttleMapStrict")); if (dict != null) { mapStrict = Boolean.parseBoolean(dict.getValue()); } if (mapStrict && !loc.getLocStsFlag().equals("F")) { return R.error("库位状态不满足出库条件"); } Task one = taskService.getOne(new LambdaQueryWrapper<Task>() .eq(Task::getTaskCtg, taskCtg.getId()) .eq(Task::getOriginSite, param.getOriginSite()) .eq(Task::getOriginLoc, param.getOriginLoc()) .eq(Task::getDestSite, param.getDestSite())); if (one != null) { return R.error("任务已存在"); } String originSite = param.getOriginSite(); if (Cools.isEmpty(param.getOriginSite())) { //使用WCS系统内置路径 BasConveyorPath path = basConveyorPathService.getOne(new LambdaQueryWrapper<BasConveyorPath>() .eq(BasConveyorPath::getTypeNo, taskCtg.getId()) .eq(BasConveyorPath::getHostId, hostId) .eq(BasConveyorPath::getStnNo, param.getDestSite())); if(path == null) { return R.error("内置路径不存在"); } Integer deviceNo = path.getDeviceNo();//获取提升机号 BasLift basLift = basLiftService.getOne(new LambdaQueryWrapper<BasLift>().eq(BasLift::getLiftNo, deviceNo).eq(BasLift::getHostId, hostId)); if(basLift == null) { return R.error("提升机对象不存在"); } List<BasLiftStaDto> staList = JSON.parseArray(basLift.getSta(), BasLiftStaDto.class); BasLiftStaDto originStaDto = null; for (BasLiftStaDto sta : staList) { if (sta.getLev() == Utils.getLev(param.getOriginLoc())) { originStaDto = sta; break; } } if (originStaDto == null) { return R.error("源站不存在"); } originSite = String.valueOf(originStaDto.getStaNo()); } // //判断出入库模式 // BasConveyorSta basConveyorSta = basConveyorStaService.getOne(new LambdaQueryWrapper<BasConveyorSta>() // .eq(BasConveyorSta::getSiteNo, originSite)); // if (!basConveyorSta.getWorkMode().equals((int) WorkModeType.PAKOUT_MODE.id)) { // //不是出库模式,检测是否可切换出库 // //获取入库任务类型 // TaskCtg taskInCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() // .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.IN)) // .eq(TaskCtg::getStatus, 1)); // if (taskInCtg == null) { // return R.error("任务类型异常"); // } // List<Task> tasks = taskService.list(new LambdaQueryWrapper<Task>() // .eq(Task::getTaskCtg, taskInCtg.getId())); // if (!tasks.isEmpty()) { // return R.error("当前存在入库任务,无法切换出库模式"); // } // // BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper<BasConveyor>().eq(BasConveyor::getConveyorNo, basConveyorSta.getConveyorNo())); // if(basConveyor == null) { // return R.error("输送线不存在"); // } // // DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue()); // if(devpThread == null) { // return R.error("输送线线程不存在"); // } // // boolean result = devpThread.switchWorkMode(Integer.parseInt(originSite), WorkModeType.PAKOUT_MODE.id); // if (!result) { // return R.error("模式切换失败"); // } // } //优先级 Integer priority = 10; if (param.getPriority() != null) { priority = param.getPriority(); } Task task = new Task(); task.setUuid(String.valueOf(snowflakeIdWorker.nextId())); task.setTaskNo(String.valueOf(Utils.getTaskNo("OUT"))); task.setWmsTaskNo(param.getTaskNo()); task.setTaskSts(TaskStsType.NEW_OUTBOUND.sts); task.setTaskCtg(taskCtg.getId()); task.setPriority(priority); task.setOriginSite(originSite); task.setOriginLoc(param.getOriginLoc()); task.setDestSite(param.getDestSite()); task.setDestLoc(null); task.setIoTime(new Date()); task.setStartTime(new Date()); task.setStatus(1); task.setMemo(""); task.setShuttleNo(null);//等待主线程分配小车 task.setRecordLoc("Y");//记录库存信息 task.setHostId(hostId);//临时控制只允许host为1 boolean result = taskService.save(task); if (!result) { return R.error("生成出库任务失败!"); } return R.ok(); } public R createManualTakeTask(CreateManualTakeTaskParam param) { //获取手动任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.MANUAL)) .eq(TaskCtg::getStatus, 1)); if (taskCtg == null) { return R.error("任务类型异常"); } Task one = taskService.getOne(new LambdaQueryWrapper<Task>() .eq(Task::getTaskCtg, taskCtg.getId()) .eq(Task::getOriginLoc, param.getOriginLoc()) .eq(Task::getDestLoc, param.getDestLoc())); if (one != null) { return R.error("任务已存在"); } //优先级 Integer priority = 10; if (param.getPriority() != null) { priority = param.getPriority(); } Task task = new Task(); task.setUuid(String.valueOf(snowflakeIdWorker.nextId())); task.setTaskNo(String.valueOf(Utils.getTaskNo("OUT"))); task.setWmsTaskNo(param.getTaskNo()); task.setTaskSts(TaskStsType.NEW_MANUAL.sts); task.setTaskCtg(taskCtg.getId()); task.setPriority(priority); task.setOriginSite(null); task.setOriginLoc(param.getOriginLoc());//源库位 task.setDestSite(null); task.setDestLoc(param.getDestLoc());//目标库位 task.setIoTime(new Date()); task.setStartTime(new Date()); task.setStatus(1); task.setMemo(""); task.setShuttleNo(null);//等待主线程分配小车 task.setRecordLoc(param.getRecord() ? "Y" : "N");//记录库存信息 task.setHostId(1L);//临时控制只允许host为1 boolean result = taskService.save(task); if (!result) { return R.error("生成手动取放货任务失败!"); } return R.ok(); } public R createMoveTask(CreateMoveTaskParam param) { //获取出库任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper<TaskCtg>() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.MOVE)) .eq(TaskCtg::getStatus, 1)); if (taskCtg == null) { return R.error("任务类型异常"); } Device device = deviceService.getOne(new LambdaQueryWrapper<Device>() .eq(Device::getDeviceType, DeviceCtgType.SHUTTLE.val()) .eq(Device::getDeviceNo, param.getShuttleNo()) .eq(Device::getHostId, 1) .eq(Device::getStatus, 1)); if (device == null) { return R.error("穿梭车不存在"); } ShuttleThread shuttleThread = (ShuttleThread) SlaveConnection.get(SlaveType.Shuttle, device.getId().intValue()); if (shuttleThread == null) { return R.error("穿梭车不在线"); } ShuttleProtocol shuttleProtocol = shuttleThread.getStatus(); if (shuttleProtocol == null) { return R.error("穿梭车不在线"); } // if (Utils.getLev(shuttleProtocol.getCurrentLocNo()) != Utils.getLev(param.getDestLoc())) { // return R.error("穿梭车和目标位置不在同一楼层"); // } Task one = taskService.getOne(new LambdaQueryWrapper<Task>() .eq(Task::getTaskCtg, taskCtg.getId()) .eq(Task::getDestLoc, param.getDestLoc())); if (one != null) { return R.error("任务已存在"); } //优先级 Integer priority = 10; if (param.getPriority() != null) { priority = param.getPriority(); } Task task = new Task(); task.setUuid(String.valueOf(snowflakeIdWorker.nextId())); task.setTaskNo(String.valueOf(Utils.getTaskNo("OUT"))); task.setWmsTaskNo(param.getTaskNo()); task.setTaskSts(TaskStsType.NEW_MOVE.sts); task.setTaskCtg(taskCtg.getId()); task.setPriority(priority); task.setOriginSite(null); task.setOriginLoc(null); task.setDestSite(null); task.setDestLoc(param.getDestLoc()); task.setIoTime(new Date()); task.setStartTime(new Date()); task.setStatus(1); task.setMemo(""); task.setShuttleNo(param.getShuttleNo()); task.setRecordLoc("N");//不记录库存信息 task.setHostId(1L);//临时控制只允许host为1 boolean result = taskService.save(task); if (!result) { return R.error("生成小车移动任务失败!"); } return R.ok(); } public R switchWorkMode(SwitchWorkModeParam param) { BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper<BasConveyor>().eq(BasConveyor::getConveyorNo, param.getConveyorNo())); if(basConveyor == null) { return R.error("输送线不存在"); } DevpThread devpThread = (DevpThread) SlaveConnection.get(SlaveType.Conveyor, basConveyor.getDeviceId().intValue()); if(devpThread == null) { return R.error("输送线线程不存在"); } boolean result = devpThread.switchWorkMode(param.getSiteId(), param.getWorkMode()); if (!result) { return R.error("模式切换失败"); } return R.ok(); } }