|  |  |  | 
|---|
|  |  |  | package com.zy.asrs.wcs.core.controller; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import com.alibaba.fastjson.JSON; | 
|---|
|  |  |  | import com.alibaba.fastjson.JSONArray; | 
|---|
|  |  |  | import com.alibaba.fastjson.JSONObject; | 
|---|
|  |  |  | import com.alibaba.fastjson.serializer.SerializerFeature; | 
|---|
|  |  |  | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 
|---|
|  |  |  | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 
|---|
|  |  |  | import com.fasterxml.jackson.core.JsonProcessingException; | 
|---|
|  |  |  | import com.fasterxml.jackson.databind.ObjectMapper; | 
|---|
|  |  |  | import com.zy.asrs.framework.common.Cools; | 
|---|
|  |  |  | import com.zy.asrs.framework.common.R; | 
|---|
|  |  |  | import com.zy.asrs.wcs.common.annotation.OperationLog; | 
|---|
|  |  |  | import com.zy.asrs.wcs.common.domain.BaseParam; | 
|---|
|  |  |  | import com.zy.asrs.wcs.common.domain.KeyValVo; | 
|---|
|  |  |  | import com.zy.asrs.wcs.common.domain.PageParam; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.domain.param.ShuttleCommandParam; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.domain.param.ShuttleCommandRollbackParam; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.domain.param.ShuttleCommandUpdateCompleteParam; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.entity.Motion; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.entity.MotionLog; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.entity.Task; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.entity.TaskLog; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.model.NavigateNode; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.model.command.ShuttleAssignCommand; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.model.command.ShuttleCommand; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.model.command.ShuttleRedisCommand; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.model.enums.ShuttleCommandModeType; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.model.enums.TaskStsType; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.service.MotionLogService; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.service.MotionService; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.service.TaskLogService; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.service.TaskService; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.utils.RedisUtil; | 
|---|
|  |  |  | import com.zy.asrs.wcs.core.utils.Utils; | 
|---|
|  |  |  | import com.zy.asrs.wcs.rcs.constant.DeviceRedisConstant; | 
|---|
|  |  |  | import com.zy.asrs.wcs.system.controller.BaseController; | 
|---|
|  |  |  | import com.zy.asrs.wcs.utils.ExcelUtil; | 
|---|
|  |  |  | import org.springframework.beans.factory.annotation.Autowired; | 
|---|
|  |  |  | import org.springframework.security.access.prepost.PreAuthorize; | 
|---|
|  |  |  | import org.springframework.transaction.annotation.Transactional; | 
|---|
|  |  |  | import org.springframework.web.bind.annotation.*; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | import javax.servlet.http.HttpServletResponse; | 
|---|
|  |  |  | import java.util.ArrayList; | 
|---|
|  |  |  | import java.util.Arrays; | 
|---|
|  |  |  | import java.util.List; | 
|---|
|  |  |  | import java.util.Map; | 
|---|
|  |  |  | import java.util.*; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @RestController | 
|---|
|  |  |  | @RequestMapping("/api") | 
|---|
|  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private TaskService taskService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private TaskLogService taskLogService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private MotionService motionService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private MotionLogService motionLogService; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private RedisUtil redisUtil; | 
|---|
|  |  |  | @Autowired | 
|---|
|  |  |  | private ObjectMapper objectMapper; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @PreAuthorize("hasAuthority('core:task:list')") | 
|---|
|  |  |  | @PostMapping("/task/page") | 
|---|
|  |  |  | 
|---|
|  |  |  | ExcelUtil.build(ExcelUtil.create(taskService.list(), Task.class), response); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @PreAuthorize("hasAuthority('core:task:complete')") | 
|---|
|  |  |  | @OperationLog("手动完成任务") | 
|---|
|  |  |  | @PostMapping("/task/complete/{id}") | 
|---|
|  |  |  | @Transactional | 
|---|
|  |  |  | public synchronized R complete(@PathVariable Long id) { | 
|---|
|  |  |  | Task task = taskService.getById(id); | 
|---|
|  |  |  | if (task == null) { | 
|---|
|  |  |  | return R.error("任务不存在"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | switch (TaskStsType.query(task.getTaskSts())) { | 
|---|
|  |  |  | case NEW_INBOUND: | 
|---|
|  |  |  | case ANALYZE_INBOUND: | 
|---|
|  |  |  | case EXECUTE_INBOUND: | 
|---|
|  |  |  | task.setTaskSts(TaskStsType.COMPLETE_INBOUND.sts); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case NEW_OUTBOUND: | 
|---|
|  |  |  | case ANALYZE_OUTBOUND: | 
|---|
|  |  |  | case EXECUTE_OUTBOUND: | 
|---|
|  |  |  | task.setTaskSts(TaskStsType.COMPLETE_OUTBOUND.sts); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case NEW_CHARGE: | 
|---|
|  |  |  | case ANALYZE_CHARGE: | 
|---|
|  |  |  | case EXECUTE_CHARGE: | 
|---|
|  |  |  | task.setTaskSts(TaskStsType.CHARGE_WORKING.sts); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case NEW_MOVE: | 
|---|
|  |  |  | case ANALYZE_MOVE: | 
|---|
|  |  |  | case EXECUTE_MOVE: | 
|---|
|  |  |  | task.setTaskSts(TaskStsType.COMPLETE_MOVE.sts); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | case NEW_MANUAL: | 
|---|
|  |  |  | case ANALYZE_MANUAL: | 
|---|
|  |  |  | case EXECUTE_MANUAL: | 
|---|
|  |  |  | task.setTaskSts(TaskStsType.COMPLETE_MANUAL.sts); | 
|---|
|  |  |  | break; | 
|---|
|  |  |  | default: | 
|---|
|  |  |  | return R.error("当前状态不可被完成"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | task.setUpdateTime(new Date()); | 
|---|
|  |  |  | task.setUpdateBy(getLoginUserId()); | 
|---|
|  |  |  | if (!taskService.updateById(task)) { | 
|---|
|  |  |  | return R.error("完成失败"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | return R.ok("任务完成"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @PreAuthorize("hasAuthority('core:task:cancel')") | 
|---|
|  |  |  | @OperationLog("手动取消任务") | 
|---|
|  |  |  | @PostMapping("/task/cancel/{id}") | 
|---|
|  |  |  | @Transactional | 
|---|
|  |  |  | public synchronized R cancel(@PathVariable Long id) { | 
|---|
|  |  |  | Task task = taskService.getById(id); | 
|---|
|  |  |  | if (task == null) { | 
|---|
|  |  |  | return R.error("任务不存在"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //创建历史档 | 
|---|
|  |  |  | TaskLog taskLog = new TaskLog(); | 
|---|
|  |  |  | taskLog.sync(task); | 
|---|
|  |  |  | taskLog.setUpdateTime(new Date()); | 
|---|
|  |  |  | taskLog.setUpdateBy(getLoginUserId()); | 
|---|
|  |  |  | taskLog.setHostId(null); | 
|---|
|  |  |  | taskLogService.save(taskLog); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | List<Motion> motions = motionService.list(new LambdaQueryWrapper<Motion>().eq(Motion::getTaskNo, task.getTaskNo()).eq(Motion::getHostId, task.getHostId())); | 
|---|
|  |  |  | for (Motion motion : motions) { | 
|---|
|  |  |  | //创建动作历史档 | 
|---|
|  |  |  | MotionLog motionLog = new MotionLog(); | 
|---|
|  |  |  | motionLog.sync(motion); | 
|---|
|  |  |  | motionLog.setUpdateTime(new Date()); | 
|---|
|  |  |  | motionLog.setHostId(null); | 
|---|
|  |  |  | motionLogService.save(motionLog); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | //删除源任务 | 
|---|
|  |  |  | taskService.removeById(task.getId()); | 
|---|
|  |  |  | //删除动作 | 
|---|
|  |  |  | motionService.remove(new LambdaQueryWrapper<Motion>().eq(Motion::getTaskNo, task.getTaskNo()).eq(Motion::getHostId, task.getHostId())); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return R.ok("取消成功"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @PreAuthorize("hasAuthority('core:task:list')") | 
|---|
|  |  |  | @PostMapping("/task/shuttleCommand") | 
|---|
|  |  |  | public R shuttleCommand(@RequestBody ShuttleCommandParam param) { | 
|---|
|  |  |  | Object object = redisUtil.get(DeviceRedisConstant.SHUTTLE_WORK_FLAG + param.getTaskNo()); | 
|---|
|  |  |  | if (object == null) { | 
|---|
|  |  |  | return R.ok(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ShuttleRedisCommand redisCommand = null; | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | redisCommand = objectMapper.readValue(String.valueOf(object), ShuttleRedisCommand.class); | 
|---|
|  |  |  | } catch (JsonProcessingException e) { | 
|---|
|  |  |  | throw new RuntimeException(e); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (redisCommand == null) { | 
|---|
|  |  |  | return R.ok(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | HashMap<String, Object> hashMap = new HashMap<>(); | 
|---|
|  |  |  | ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand(); | 
|---|
|  |  |  | List<ShuttleCommand> commands = assignCommand.getCommands(); | 
|---|
|  |  |  | Integer commandStep = redisCommand.getCommandStep();//当前步序 | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ArrayList<JSONObject> list = new ArrayList<>(); | 
|---|
|  |  |  | int index = 0; | 
|---|
|  |  |  | for (ShuttleCommand command : commands) { | 
|---|
|  |  |  | JSONObject data = JSON.parseObject(JSON.toJSONString(command)); | 
|---|
|  |  |  | data.put("index", index++); | 
|---|
|  |  |  | data.put("commandStep", commandStep); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ShuttleCommandModeType type = ShuttleCommandModeType.get(command.getMode()); | 
|---|
|  |  |  | if (type == null) { | 
|---|
|  |  |  | data.put("mode$", command.getMode()); | 
|---|
|  |  |  | }else { | 
|---|
|  |  |  | data.put("mode$", type.desc); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (command.getNodes() != null) { | 
|---|
|  |  |  | List<NavigateNode> nodes = command.getNodes(); | 
|---|
|  |  |  | NavigateNode start = nodes.get(0); | 
|---|
|  |  |  | NavigateNode target = nodes.get(nodes.size() - 1); | 
|---|
|  |  |  | data.put("start", Utils.getLocNo(start.getX(), start.getY(), start.getZ())); | 
|---|
|  |  |  | data.put("target", Utils.getLocNo(target.getX(), target.getY(), target.getZ())); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | list.add(data); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | hashMap.put("total", commands.size()); | 
|---|
|  |  |  | hashMap.put("records", list); | 
|---|
|  |  |  | hashMap.put("commandStep", commandStep); | 
|---|
|  |  |  | return R.ok().add(hashMap); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @PreAuthorize("hasAuthority('core:task:list')") | 
|---|
|  |  |  | @PostMapping("/task/shuttleCommand/completeSwitch") | 
|---|
|  |  |  | public R shuttleCommandCompleteSwitch(@RequestBody ShuttleCommandUpdateCompleteParam param) { | 
|---|
|  |  |  | Object object = redisUtil.get(DeviceRedisConstant.SHUTTLE_WORK_FLAG + param.getTaskNo()); | 
|---|
|  |  |  | if (object == null) { | 
|---|
|  |  |  | return R.error("指令不存在"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ShuttleRedisCommand redisCommand = null; | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | redisCommand = objectMapper.readValue(String.valueOf(object), ShuttleRedisCommand.class); | 
|---|
|  |  |  | } catch (JsonProcessingException e) { | 
|---|
|  |  |  | throw new RuntimeException(e); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (redisCommand == null) { | 
|---|
|  |  |  | return R.error("指令不存在"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ShuttleAssignCommand assignCommand = redisCommand.getAssignCommand(); | 
|---|
|  |  |  | List<ShuttleCommand> commands = assignCommand.getCommands(); | 
|---|
|  |  |  | ShuttleCommand command = commands.get(param.getIndex()); | 
|---|
|  |  |  | command.setComplete(param.getComplete()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | redisUtil.set(DeviceRedisConstant.SHUTTLE_WORK_FLAG + param.getTaskNo(), JSON.toJSONString(redisCommand, SerializerFeature.DisableCircularReferenceDetect)); | 
|---|
|  |  |  | return R.ok(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @PreAuthorize("hasAuthority('core:task:list')") | 
|---|
|  |  |  | @PostMapping("/task/shuttleCommand/commandRollback") | 
|---|
|  |  |  | public R shuttleCommandRollback(@RequestBody ShuttleCommandRollbackParam param) { | 
|---|
|  |  |  | Object object = redisUtil.get(DeviceRedisConstant.SHUTTLE_WORK_FLAG + param.getTaskNo()); | 
|---|
|  |  |  | if (object == null) { | 
|---|
|  |  |  | return R.error("指令不存在"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ShuttleRedisCommand redisCommand = null; | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | redisCommand = objectMapper.readValue(String.valueOf(object), ShuttleRedisCommand.class); | 
|---|
|  |  |  | } catch (JsonProcessingException e) { | 
|---|
|  |  |  | throw new RuntimeException(e); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (redisCommand == null) { | 
|---|
|  |  |  | return R.error("指令不存在"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | redisCommand.setCommandStep(param.getIndex()); | 
|---|
|  |  |  | redisUtil.set(DeviceRedisConstant.SHUTTLE_WORK_FLAG + param.getTaskNo(), JSON.toJSONString(redisCommand, SerializerFeature.DisableCircularReferenceDetect)); | 
|---|
|  |  |  | return R.ok(); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } | 
|---|