package com.huaheng.api.acs.service; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.huaheng.api.acs.domain.AgvPort; import com.huaheng.api.acs.domain.AgvTask; import com.huaheng.api.acs.domain.ToAgvTask; import com.huaheng.api.acs.mapper.AgvTaskCsMapper; import com.huaheng.common.constant.QuantityConstant; import com.huaheng.common.exception.service.ServiceException; import com.huaheng.common.utils.StringUtils; import com.huaheng.common.utils.http.HttpUtils; import com.huaheng.common.utils.security.ShiroUtils; import com.huaheng.framework.web.domain.AjaxResult; import com.huaheng.framework.web.service.ConfigService; import com.huaheng.pc.config.address.service.AddressService; import com.huaheng.pc.config.container.domain.Container; import com.huaheng.pc.config.container.service.ContainerService; import com.huaheng.pc.task.taskHeader.domain.TaskHeader; import com.huaheng.pc.task.taskHeader.service.TaskHeaderService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.util.*; @Service public class AgvTaskServiceImpl extends ServiceImpl<AgvTaskCsMapper, AgvTask> implements AgvTaskService { @Resource private AgvPortService agvPortService; @Resource private ContainerService containerService; @Resource private ConfigService configService; @Resource private AddressService addressService; @Resource private TaskHeaderService taskHeaderService; @Override public AjaxResult createAGVTask(AgvTask agvTask) { if (StringUtils.isEmpty(agvTask.getPreTaskNo())) { //校验请求参数 checkAgvTaskPosition(agvTask); //校验托盘是否存在任务及是否锁定 checkContainerAndPositionStatus(agvTask); //校验自己生成的任务中源点位的托盘和实际托盘一不一致 checkContainerAndPositionLove(agvTask); } agvTask.setStatus(QuantityConstant.TASK_STATUS_BUILD); agvTask.setCreatedBy(ShiroUtils.getLoginName()); agvTask.setTaskType(QuantityConstant.STATUS_TASK_CARRY); agvTask.setCreatedTime(new Date()); agvTask.setUpdated(new Date()); agvTask.setUpdatedBy(ShiroUtils.getLoginName()); agvTask.setWarehouseCode("CS0001"); if (save(agvTask)) { agvPortService.updateStatus(agvTask.getToPort(), QuantityConstant.STATUS_POSITION_LOCK); } else { throw new ServiceException("AGV创建任务失败"); } return AjaxResult.success("执行生成任务成功"); } @Override @Transactional public AjaxResult sendTaskToAGV(Integer[] agvTaskIds) { AjaxResult result = null; boolean finished = false; AgvTask task = null; for (Integer taskId : agvTaskIds) { task = getById(taskId); if (task.getStatus() >= QuantityConstant.TASK_STATUS_RELEASE) { result = AjaxResult.error("任务" + taskId + "已经下发,请不要重复下发,操作中止"); finished = true; break; } if (StringUtils.isEmpty(task.getToPort())) { result = AjaxResult.error("任务没有目标点位,不允许下发"); finished = true; break; } LambdaQueryWrapper<AgvTask> agvTaskLambdaQueryWrapper = new LambdaQueryWrapper(); agvTaskLambdaQueryWrapper.eq(AgvTask::getToPort, task.getToPort()) .eq(AgvTask::getWarehouseCode, task.getWarehouseCode()) .ge(AgvTask::getStatus, QuantityConstant.TASK_STATUS_RELEASE) .lt(AgvTask::getStatus, QuantityConstant.TASK_STATUS_COMPLETED); List<AgvTask> list = list(agvTaskLambdaQueryWrapper); if (list != null && list.size() > 0) { result = AjaxResult.error("目标点位存在任务,请更换目标点位"); finished = true; break; } // 给AGV传递任务 AjaxResult ajaxResult = agvTaskAssign(task); if (ajaxResult != null && ajaxResult.hasErr()) { result = AjaxResult.error(ajaxResult.getMsg()); finished = true; break; } //修改任务头表 task.setId(taskId); task.setStatus(QuantityConstant.TASK_STATUS_RELEASE); task.setUpdated(new Date()); task.setUpdatedBy(ShiroUtils.getLoginName()); saveOrUpdate(task); } if (!finished) { result = AjaxResult.success("执行下发任务成功", task); }else { throw new RuntimeException("下发失败"); } return result; } @Transactional(rollbackFor = Exception.class) public AjaxResult agvTaskAssign(AgvTask agvTask) { //1、判断agvHeader是否为空 if (agvTask == null) { return AjaxResult.error("Agv任务为空"); } //2、判断必填字段是否满足 if (agvTask.getId() == null) { return AjaxResult.error("Agv任务号Id为空"); } if (agvTask.getTaskType() == null) { return AjaxResult.error("Agv任务类型为空"); } String containerCode = agvTask.getContainerCode(); if (StringUtils.isEmpty(containerCode)) { return AjaxResult.error("Agv任务中容器为空"); } String warehouseCode = agvTask.getWarehouseCode(); //3、转换实体,初始化Agv任务实体 ToAgvTask toAgvTask = new ToAgvTask(); toAgvTask.setTaskNo(String.valueOf(agvTask.getId())); toAgvTask.setTaskType(agvTask.getTaskType()); toAgvTask.setContainerCode(agvTask.getContainerCode()); toAgvTask.setFromPort(agvTask.getFromPort()); toAgvTask.setToPort(agvTask.getToPort()); toAgvTask.setPriority(100); //4、发送数据 return sendDataToAgv(1, warehouseCode, "1", toAgvTask); } @Override public AjaxResult cancelAGVTask(Integer[] agvTaskIds) { for (int taskId : agvTaskIds) { AgvTask agvTask = getById(taskId); if (agvTask == null) { return AjaxResult.error("任务" + taskId + "未找到,操作中止"); } if (agvTask.getStatus() > QuantityConstant.TASK_STATUS_RELEASE) { return AjaxResult.error("存在任务" + agvTask.getId() + "已下发或执行,操作中止"); } int preTaskNo = taskId; LambdaQueryWrapper<AgvTask> agvLambdaQueryWrapper = Wrappers.lambdaQuery(); agvLambdaQueryWrapper.eq(AgvTask::getPreTaskNo, preTaskNo); AgvTask agvTaskHeader = getOne(agvLambdaQueryWrapper); if (agvTaskHeader != null) { return AjaxResult.error("取消任务失败, 有前置任务" + agvTask.getId()); } //查出任务明细 //删除子任务 //删除主任务 removeById(taskId); //盘点取消任务,恢复明细状态为1 int taskType = agvTask.getTaskType().intValue(); cancelPositionStatus(agvTask); cancelContainerStatus(agvTask); } return AjaxResult.success("取消任务成功!"); } @Override public AjaxResult cancelTask(Integer id, String warehouseCode, String area) { //1、判断参数是否为空 if (id == null) { throw new ServiceException("任务号为空"); } HashMap<String, Object> map = new HashMap(); List<Integer> list = new ArrayList<>(); list.add(id); map.put("taskNo", list); //2、发送数据 return sendDataToAgv(2, warehouseCode, area, map); } @Override public AjaxResult notifyAGVTask(Map map) { AgvTask agvTask = new AgvTask(); if (map.isEmpty()) { return AjaxResult.error("请求数据为空"); } Object o1 = map.get("taskNo"); Object o2 = map.get("carNo"); Object o3 = map.get("status"); if (StringUtils.isNull(o1)) { return AjaxResult.error("任务号为空"); } Integer taskNo = Integer.valueOf(o1.toString()); List<AgvTask> list = list(new LambdaQueryWrapper<AgvTask>().eq(AgvTask::getId, taskNo)); if (CollectionUtils.isNotEmpty(list)) { AgvTask agvTask1 = list.get(0); if (agvTask1.getStatus().equals(100)) { return AjaxResult.success("任务已经是完成了的"); } } else { return AjaxResult.success("任务不存在"); } if (StringUtils.isNotNull(o2)) { String carNo = o2.toString(); agvTask.setCarNo(carNo); } if (StringUtils.isNull(o3)) { return AjaxResult.error("任务状态为空"); } Integer status = Integer.valueOf(o3.toString()); agvTask.setId(taskNo); agvTaskStatusNowStart(status, agvTask); return AjaxResult.success(); } /** * 将参数传输给AGV * * @param * @param warehouseCode * @param area * @param object * @return */ private AjaxResult sendDataToAgv(int i, String warehouseCode, String area, Object object) { String value = configService.getKey(QuantityConstant.RULE_CONNECT_AGV); int connectAGV = Integer.parseInt(value); String url = null; if (connectAGV == QuantityConstant.RULE_AGV_CONNECT) { if (i == 1) { url = addressService.selectAddress(QuantityConstant.ADDRESS_AGV_TASK_ASSIGN, warehouseCode, area); } else if (i == 2) { url = addressService.selectAddress(QuantityConstant.ADDRESS_AGV_TASK_CANCEL, warehouseCode, area); } else { } String JsonParam = JSON.toJSONString(object); System.out.println(JsonParam); String result = HttpUtils.bodypost(url, JsonParam, "CS0001"); if (result == null) { throw new ServiceException("调用失败"); } else { return AjaxResult.success(result); } } return AjaxResult.success("下发成功"); } //根据agv的任务状态来判断 private AjaxResult agvTaskStatusNowStart(Integer o3, AgvTask agvTask) { AgvTask task = getById(agvTask.getId()); if (task == null) { return AjaxResult.error("任务号" + agvTask.getId() + "不存在"); } if (task.getStatus()==QuantityConstant.TASK_STATUS_COMPLETED) { return AjaxResult.error("任务" + agvTask.getId() + "已经完成"); } if (o3.equals(QuantityConstant.STATUS_TASK_AGV_START)) { agvTask.setStatus(20); updateById(agvTask); } if (o3.equals(QuantityConstant.STATUS_TASK_AGV_TASKOVER)) { agvTask.setStatus(50); updateById(agvTask); } if (o3.equals(QuantityConstant.STATUS_TASK_FINISH)) { task.setStatus(100); updateById(task); agvPortService.updateStatus(task.getToPort(), QuantityConstant.STATUS_POSITION_EMPTY); return AjaxResult.success(); } return AjaxResult.success(); } //根据任务类型检验参数 private void checkAgvTaskPosition(AgvTask agvTask) { if (StringUtils.isNull(agvTask)) { throw new ServiceException("任务数据为空,请重新下发"); } if (StringUtils.isEmpty(agvTask.getContainerCode())) { throw new ServiceException("托盘为空"); } AgvPort sourcePosition = agvPortService.getAgvportByCode(agvTask.getFromPort()); AgvPort desPosition = agvPortService.getAgvportByCode(agvTask.getToPort()); if (StringUtils.isEmpty(agvTask.getFromPort())) { throw new ServiceException("源点位为空"); } if (StringUtils.isNull(sourcePosition)) { throw new ServiceException("源点位:" + sourcePosition.getName() + "未找到"); } // if(sourcePosition.getStatus().equals(QuantityConstant.STATUS_POSITION_LOCK)){ // throw new ServiceException("源点位:" + sourcePosition.getName() + "禁用"); // } if (StringUtils.isEmpty(agvTask.getToPort())) { throw new ServiceException("目标点位为空"); } if (StringUtils.isNull(desPosition)) { throw new ServiceException("目标点位:" + desPosition.getName() + "未找到"); } if (!desPosition.getUserDef1()) { return; } if (desPosition.getStatus().equals(QuantityConstant.STATUS_POSITION_LOCK)) { throw new ServiceException("目标点位:" + desPosition.getName() + "禁用"); } // if (StringUtils.isNotEmpty(desPosition.getContainerCode())) { // throw new ServiceException("目标点位:" + desPosition.getName() + "存在托盘:" + desPosition.getContainerCode()); // } if (QuantityConstant.STATUS_CONTAINER_FULL.equals(desPosition.getStatus())) { throw new ServiceException("目标点位:" + desPosition.getName() + "已满"); } } /** * 检查托盘和点位是否存在未完成的任务 * * @param agvTask */ private void checkContainerAndPositionStatus(AgvTask agvTask) { TaskHeader containerLKTaskStatus = taskHeaderService.getOne(new LambdaQueryWrapper<TaskHeader>() .eq(TaskHeader::getContainerCode, agvTask.getContainerCode()) .lt(TaskHeader::getStatus, QuantityConstant.TASK_STATUS_COMPLETED)); AgvTask containerAgvTaskStatus = getOne(new LambdaQueryWrapper<AgvTask>() .eq(AgvTask::getContainerCode, agvTask.getContainerCode()) .lt(AgvTask::getStatus, QuantityConstant.TASK_STATUS_COMPLETED)); if (StringUtils.isNotNull(containerLKTaskStatus) || StringUtils.isNotNull(containerAgvTaskStatus)) { throw new ServiceException("托盘" + agvTask.getContainerCode() + "存在未完成的任务"); } Container containerStatus = containerService.getContainerByCode(agvTask.getContainerCode(),"CS0001"); if (StringUtils.isNull(containerStatus)) { throw new ServiceException("托盘" + agvTask.getContainerCode() + "不存在"); } if (QuantityConstant.STATUS_CONTAINER_LOCK.equals(containerStatus.getStatus())) { throw new ServiceException("托盘" + agvTask.getContainerCode() + "已锁定"); } AgvPort pointPosition = agvPortService.getOne(new LambdaQueryWrapper<AgvPort>() .eq(AgvPort::getContainerCode, agvTask.getContainerCode()) .eq(AgvPort::getStatus, QuantityConstant.STATUS_CONTAINER_LOCK) .orderByAsc(AgvPort::getType).last("limit 1")); if (pointPosition != null) { throw new ServiceException("点位" + pointPosition.getCode() + "已锁定,托盘在此位置不能生成任务"); } } //校验自己生成的任务中源点位的托盘和实际托盘一不一致 @SuppressWarnings("AlibabaCommentsMustBeJavadocFormat") private void checkContainerAndPositionLove(AgvTask agvTask) { AgvPort agvPort = agvPortService.getAgvportByCode(agvTask.getFromPort()); if (agvPort != null && StringUtils.isNotEmpty(agvPort.getContainerCode())) { if (!agvTask.getContainerCode().equals(agvPort.getContainerCode())) { throw new ServiceException("源点位上托盘数据和分配的托盘不一致,请核对"); } } } //更新点位状态 @SuppressWarnings("AlibabaCommentsMustBeJavadocFormat") private void cancelPositionStatus(AgvTask agvTask) { if (agvTask.getFromPort() != null) { //更新点位状态 AgvPort agvPort = agvPortService.getAgvportByCode(agvTask.getFromPort()); if (agvPort != null && StringUtils.isNotEmpty(agvPort.getContainerCode())) { agvPortService.updateStatus(agvTask.getFromPort(), QuantityConstant.STATUS_POSITION_EMPTY); } else { agvPortService.updateStatus(agvTask.getFromPort(), QuantityConstant.STATUS_POSITION_EMPTY); } } if (agvTask.getToPort() != null) { //更新点位状态 AgvPort agvPort = agvPortService.getAgvportByCode(agvTask.getToPort()); if (agvPort != null && StringUtils.isNotEmpty(agvPort.getContainerCode())) { agvPortService.updateStatus(agvTask.getToPort(), QuantityConstant.STATUS_POSITION_EMPTY); } else { agvPortService.updateStatus(agvTask.getToPort(), QuantityConstant.STATUS_POSITION_EMPTY); } } } //更新容器状态 @SuppressWarnings("AlibabaCommentsMustBeJavadocFormat") private void cancelContainerStatus(AgvTask agvTask) { Container container = new Container(); container.setStatus(QuantityConstant.STATUS_CONTAINER_EMPTY); LambdaUpdateWrapper<Container> containerUpdateWrapper = Wrappers.lambdaUpdate(); containerUpdateWrapper.eq(Container::getCode, agvTask.getContainerCode()); containerService.update(container, containerUpdateWrapper); } }