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.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; /** * 对外暴露接口 * 提供任务生成、设备运动等接口 */ @RestController @RequestMapping("/openapi") 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; //生成入库任务 @PostMapping("/createInTask") public R createInTask(@RequestBody CreateInTaskParam param) { //获取入库任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper() .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().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() .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() .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() .eq(BasConveyorSta::getSiteNo, destSite)); if (!basConveyorSta.getWorkMode().equals((int) WorkModeType.PAKIN_MODE.id)) { //不是入库模式,检测是否可切换入库 //获取出库任务类型 TaskCtg taskInCtg = taskCtgService.getOne(new LambdaQueryWrapper() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.OUT)) .eq(TaskCtg::getStatus, 1)); if (taskInCtg == null) { return R.error("任务类型异常"); } List tasks = taskService.list(new LambdaQueryWrapper() .eq(Task::getTaskCtg, taskInCtg.getId())); if (!tasks.isEmpty()) { return R.error("当前存在出库任务,无法切换入库模式"); } BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper().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(); } //生成出库任务 @PostMapping("/createOutTask") public R createOutTask(@RequestBody CreateOutTaskParam param) { //获取出库任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper() .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().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() .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() .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().eq(BasLift::getLiftNo, deviceNo).eq(BasLift::getHostId, hostId)); if(basLift == null) { return R.error("提升机对象不存在"); } List 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() .eq(BasConveyorSta::getSiteNo, originSite)); if (!basConveyorSta.getWorkMode().equals((int) WorkModeType.PAKOUT_MODE.id)) { //不是出库模式,检测是否可切换出库 //获取入库任务类型 TaskCtg taskInCtg = taskCtgService.getOne(new LambdaQueryWrapper() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.IN)) .eq(TaskCtg::getStatus, 1)); if (taskInCtg == null) { return R.error("任务类型异常"); } List tasks = taskService.list(new LambdaQueryWrapper() .eq(Task::getTaskCtg, taskInCtg.getId())); if (!tasks.isEmpty()) { return R.error("当前存在入库任务,无法切换出库模式"); } BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper().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(); } //生成手动取放货任务 @PostMapping("/createManualTakeTask") public R createManualTakeTask(@RequestBody CreateManualTakeTaskParam param) { //获取手动任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.MANUAL)) .eq(TaskCtg::getStatus, 1)); if (taskCtg == null) { return R.error("任务类型异常"); } Task one = taskService.getOne(new LambdaQueryWrapper() .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(); } //生成载货移动任务 @PostMapping("/createLadenMoveTakeTask") public R createLadenMoveTakeTask(@RequestBody CreateManualTakeTaskParam param) { //获取手动任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.MOVE)) .eq(TaskCtg::getStatus, 1)); if (taskCtg == null) { return R.error("任务类型异常"); } Task one = taskService.getOne(new LambdaQueryWrapper() .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_LADEN_MOVE.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(); } //生成小车移动任务 @PostMapping("/createMoveTask") public R createMoveTask(@RequestBody CreateMoveTaskParam param) { //获取出库任务类型 TaskCtg taskCtg = taskCtgService.getOne(new LambdaQueryWrapper() .eq(TaskCtg::getFlag, String.valueOf(TaskCtgType.MOVE)) .eq(TaskCtg::getStatus, 1)); if (taskCtg == null) { return R.error("任务类型异常"); } Device device = deviceService.getOne(new LambdaQueryWrapper() .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() .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(); } //切换工作模式 @PostMapping("/switchWorkMode") public R switchWorkMode(@RequestBody SwitchWorkModeParam param) { BasConveyor basConveyor = basConveyorService.getOne(new LambdaQueryWrapper().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(); } }