任务列表/修改任务状态、优先级

This commit is contained in:
cbs 2025-01-15 16:35:15 +08:00
parent 0b517511ea
commit d9ac7b7cb6
26 changed files with 452 additions and 121 deletions

View File

@ -191,9 +191,13 @@ public interface ErrorCodeConstants {
ErrorCode TASK_CYCLE_NOT_OPEN = new ErrorCode(1-002-035-003, "循环任务的配置未开启!"); ErrorCode TASK_CYCLE_NOT_OPEN = new ErrorCode(1-002-035-003, "循环任务的配置未开启!");
ErrorCode TASK_ONLY_CHOOSE_LOCATION = new ErrorCode(1-002-035-004, "搬空任务只能选择线库或者区域"); ErrorCode TASK_ONLY_CHOOSE_LOCATION = new ErrorCode(1-002-035-004, "搬空任务只能选择线库或者区域");
ErrorCode TASK_CHECK_EXCEPTION = new ErrorCode(1-002-035-005, "任务下发失败"); ErrorCode TASK_CHECK_EXCEPTION = new ErrorCode(1-002-035-005, "任务下发失败");
ErrorCode TASK_CHECK_ID_EXCEPTION = new ErrorCode(1-002-035-006, "请输入ID");
ErrorCode TASK_CHECK_TASK_PRIORITY = new ErrorCode(1-002-035-007, "非新单据不能修改优先级");
ErrorCode TASK_CHECK_TASK_STATUS = new ErrorCode(1-002-035-100, "订单已完成");
// ========== 机器人任务明细 1-002-036-000 ========== // ========== 机器人任务明细 1-002-036-000 ==========
ErrorCode TASK_DETAIL_NOT_EXISTS = new ErrorCode(1-002-036-001, "机器人任务明细不存在"); ErrorCode TASK_DETAIL_NOT_EXISTS = new ErrorCode(1-002-036-001, "机器人任务明细不存在");
ErrorCode TASK_DETAIL_CHANGE_ROBOT = new ErrorCode(1-002-036-002, "非新单据不能修改车辆");
// ========== 机器人任务明细 1-002-037-000 ========== // ========== 机器人任务明细 1-002-037-000 ==========
ErrorCode REDISSON_NOT_OBTAIN_LOCK = new ErrorCode(1-002-037-001, "有正在下发中的任务请稍后重试!"); ErrorCode REDISSON_NOT_OBTAIN_LOCK = new ErrorCode(1-002-037-001, "有正在下发中的任务请稍后重试!");

View File

@ -3,9 +3,14 @@ package cn.iocoder.yudao.module.system.api.robot;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotCompleteTaskDTO; import cn.iocoder.yudao.module.system.api.robot.dto.RobotCompleteTaskDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotExecutionStateConstant;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskMapper;
import cn.iocoder.yudao.module.system.enums.robot.RobotStatusEnum;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskDetailStatusEnum; import cn.iocoder.yudao.module.system.enums.robot.RobotTaskDetailStatusEnum;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -14,6 +19,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@ -28,6 +34,9 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
@Autowired @Autowired
private RobotTaskMapper robotTaskMapper; private RobotTaskMapper robotTaskMapper;
@Autowired@Resource
private RobotInformationMapper robotInformationMapper;
/** /**
* 机器人完成任务上报 * 机器人完成任务上报
* @param robotCompleteTaskDTO * @param robotCompleteTaskDTO
@ -38,20 +47,36 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi {
public CommonResult<Boolean> robotDoneTask(RobotCompleteTaskDTO robotCompleteTaskDTO) { public CommonResult<Boolean> robotDoneTask(RobotCompleteTaskDTO robotCompleteTaskDTO) {
log.info("机器人完成任务上报 :{}", JSON.toJSONString(robotCompleteTaskDTO)); log.info("机器人完成任务上报 :{}", JSON.toJSONString(robotCompleteTaskDTO));
TenantContextHolder.setTenantId(1L); TenantContextHolder.setTenantId(1L);
if (RobotExecutionStateConstant.UN_DO.equals(robotCompleteTaskDTO.getExecution_state())) {
return CommonResult.success(Boolean.TRUE);
}
//更新任务状态
RobotTaskDetailDO detailDO = new RobotTaskDetailDO(); RobotTaskDetailDO detailDO = new RobotTaskDetailDO();
detailDO.setId(robotCompleteTaskDTO.getOrder_id()); detailDO.setId(robotCompleteTaskDTO.getOrder_id());
detailDO.setEndTime(LocalDateTime.now()); detailDO.setEndTime(LocalDateTime.now());
detailDO.setTaskStatus(robotCompleteTaskDTO.getExecution_state()); detailDO.setTaskStatus(robotCompleteTaskDTO.getExecution_state());
robotTaskDetailMapper.updateRobotDetailById(detailDO); robotTaskDetailMapper.updateRobotDetailById(detailDO);
//更新任务状态
RobotTaskDetailDO robotTaskDetailDO = robotTaskDetailMapper.selectById(robotCompleteTaskDTO.getOrder_id()); RobotTaskDetailDO robotTaskDetailDO = robotTaskDetailMapper.selectById(robotCompleteTaskDTO.getOrder_id());
List<RobotTaskDetailDO> taskDetails = robotTaskDetailMapper.queryByTaskId(robotTaskDetailDO.getRobotTaskId()); List<RobotTaskDetailDO> taskDetails = robotTaskDetailMapper.queryByTaskId(robotTaskDetailDO.getRobotTaskId());
boolean b = boolean done =
taskDetails.stream().allMatch(v -> (v.getTaskStatus().equals(RobotTaskDetailStatusEnum.DONE.getType()) taskDetails.stream().allMatch(v -> (v.getTaskStatus().equals(RobotTaskDetailStatusEnum.DONE.getType())
|| v.getTaskStatus().equals(RobotTaskDetailStatusEnum.CLOSE.getType()) )); || v.getTaskStatus().equals(RobotTaskDetailStatusEnum.CLOSE.getType()) ));
if(b) { if(done) {
robotTaskMapper.updateRobotStatus(taskDetails.get(0).getRobotTaskId(), RobotTaskDetailStatusEnum.DONE.getType()); RobotTaskDO robotTaskDO = new RobotTaskDO();
robotTaskDO.setId(taskDetails.get(0).getRobotTaskId());
robotTaskDO.setEndTime(LocalDateTime.now());
robotTaskDO.setTaskStatus(RobotTaskDetailStatusEnum.DONE.getType());
robotTaskMapper.updateRobot(robotTaskDO);
}
//更新机器人任务状态
if (RobotExecutionStateConstant.DONE.equals(robotCompleteTaskDTO.getExecution_state()) ||
RobotExecutionStateConstant.CLOSE.equals(robotCompleteTaskDTO.getExecution_state())) {
RobotInformationDO query = new RobotInformationDO();
query.setMacAddress(robotCompleteTaskDTO.getMac());
List<RobotInformationDO> existRobotMac = robotInformationMapper.queryAllByLimit(query);
String robotNo = existRobotMac.get(0).getRobotNo();
robotInformationMapper.updateRobotStatus(robotNo, RobotStatusEnum.STAND_BY.getType());
} }
return CommonResult.success(true); return CommonResult.success(true);

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.system.constant.robot;
/**
* 机器人上报的状态
*/
public class RobotExecutionStateConstant {
//未开始
public static Integer UN_DO = 0;
//正在做
public static Integer DOING = 1;
//已完成
public static Integer DONE = 2;
//已取消
public static Integer CLOSE = 3;
//已失败
public static Integer FAIL = 4;
}

View File

@ -101,4 +101,12 @@ public class RobotInformationController {
return success(informationService.statisticsInformation()); return success(informationService.statisticsInformation());
} }
@PostMapping("/getCanUseRobot")
@Operation(summary = "查询能正常使用的车辆")
@PreAuthorize("@ss.hasPermission('robot:information:getCanUseRobot')")
public CommonResult<List<RobotInformationRespVO>> getCanUseRobot() {
List<RobotInformationDO> result = informationService.getCanUseRobot();
return success(BeanUtils.toBean(result, RobotInformationRespVO.class));
}
} }

View File

@ -74,11 +74,19 @@ public class RobotTaskController {
return success(BeanUtils.toBean(task, RobotTaskRespVO.class)); return success(BeanUtils.toBean(task, RobotTaskRespVO.class));
} }
@GetMapping("/getTaskNo")
@Operation(summary = "获得任务号")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('robot:task:getTaskNo')")
public CommonResult<String> getTaskNo() {
return success(taskService.getTaskNo());
}
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得机器人任务主表分页") @Operation(summary = "获得机器人任务主表分页")
@PreAuthorize("@ss.hasPermission('robot:task:query')") @PreAuthorize("@ss.hasPermission('robot:task:query')")
public CommonResult<PageResult<RobotTaskRespVO>> getTaskPage(@Valid RobotTaskPageReqVO pageReqVO) { public CommonResult<PageResult<RobotTaskRespVO>> getTaskPage(@Valid RobotTaskPageReqVO pageReqVO) {
PageResult<RobotTaskDO> pageResult = taskService.getTaskPage(pageReqVO); PageResult<RobotTaskRespVO> pageResult = taskService.getTaskPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, RobotTaskRespVO.class)); return success(BeanUtils.toBean(pageResult, RobotTaskRespVO.class));
} }
@ -89,7 +97,7 @@ public class RobotTaskController {
public void exportTaskExcel(@Valid RobotTaskPageReqVO pageReqVO, public void exportTaskExcel(@Valid RobotTaskPageReqVO pageReqVO,
HttpServletResponse response) throws IOException { HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<RobotTaskDO> list = taskService.getTaskPage(pageReqVO).getList(); List<RobotTaskRespVO> list = taskService.getTaskPage(pageReqVO).getList();
// 导出 Excel // 导出 Excel
ExcelUtils.write(response, "机器人任务主表.xls", "数据", RobotTaskRespVO.class, ExcelUtils.write(response, "机器人任务主表.xls", "数据", RobotTaskRespVO.class,
BeanUtils.toBean(list, RobotTaskRespVO.class)); BeanUtils.toBean(list, RobotTaskRespVO.class));

View File

@ -31,6 +31,11 @@ public class RobotTaskDetailAddVo {
@Schema(description = "AGV编号") @Schema(description = "AGV编号")
private String robotNo; private String robotNo;
@Schema(description = "停车后是否锁定(0:否、1:是)")
private Integer needLock;
@Schema(description = "所选车辆电量(充电模式)")
private Integer electricity;
@Schema(description = "计算后的来源库位编号(前端不用传此字段)") @Schema(description = "计算后的来源库位编号(前端不用传此字段)")
private String fromLocationNo; private String fromLocationNo;
@Schema(description = "计算后的来源库位id(前端不用传此字段)") @Schema(description = "计算后的来源库位id(前端不用传此字段)")

View File

@ -71,4 +71,8 @@ public class RobotTaskDetailPageReqVO extends PageParam {
private Integer toLocationStorey; private Integer toLocationStorey;
@Schema(description = "优先级") @Schema(description = "优先级")
private Long priority; private Long priority;
@Schema(description = "停车后是否锁定(0:否、1:是)")
private Integer needLock;
@Schema(description = "所选车辆电量(充电模式)")
private Integer electricity;
} }

View File

@ -87,5 +87,11 @@ public class RobotTaskDetailRespVO {
@Schema(description = "优先级") @Schema(description = "优先级")
@ExcelProperty("优先级") @ExcelProperty("优先级")
private Long priority; private Long priority;
@Schema(description = "停车后是否锁定(0:否、1:是)")
@ExcelProperty("停车后是否锁定(0:否、1:是)")
private Integer needLock;
@Schema(description = "所选车辆电量(充电模式)")
@ExcelProperty("所选车辆电量(充电模式)")
private Integer electricity;
} }

View File

@ -71,5 +71,9 @@ public class RobotTaskDetailSaveReqVO {
private Integer toLocationStorey; private Integer toLocationStorey;
@Schema(description = "优先级") @Schema(description = "优先级")
private Long priority; private Long priority;
@Schema(description = "停车后是否锁定(0:否、1:是)")
private Integer needLock;
@Schema(description = "所选车辆电量(充电模式)")
private Integer electricity;
} }

View File

@ -52,7 +52,7 @@ public class RobotTaskPageReqVO extends PageParam {
private String taskNo; private String taskNo;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "2") @Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "2")
private Long taskStatus; private Integer taskStatus;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)") @Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")
private Long taskStage; private Long taskStage;

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.vo; package cn.iocoder.yudao.module.system.controller.admin.robot.vo;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import java.util.*; import java.util.*;
@ -7,6 +8,8 @@ import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*; import com.alibaba.excel.annotation.*;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 机器人任务主表 Response VO") @Schema(description = "管理后台 - 机器人任务主表 Response VO")
@Data @Data
@ExcelIgnoreUnannotated @ExcelIgnoreUnannotated
@ -66,7 +69,7 @@ public class RobotTaskRespVO {
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "2") @Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "2")
@ExcelProperty("任务状态(0:未开始、1执行中、2已完成、3已取消)") @ExcelProperty("任务状态(0:未开始、1执行中、2已完成、3已取消)")
private Long taskStatus; private Integer taskStatus;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)") @Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")
@ExcelProperty("任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)") @ExcelProperty("任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")
@ -74,14 +77,19 @@ public class RobotTaskRespVO {
@Schema(description = "开始时间") @Schema(description = "开始时间")
@ExcelProperty("开始时间") @ExcelProperty("开始时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime startTime; private LocalDateTime startTime;
@Schema(description = "结束时间") @Schema(description = "结束时间")
@ExcelProperty("结束时间") @ExcelProperty("结束时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime endTime; private LocalDateTime endTime;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间") @ExcelProperty("创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime createTime; private LocalDateTime createTime;
@Schema(description = "子任务明细")
List<RobotTaskDetailDO> details;
} }

View File

@ -57,7 +57,7 @@ public class RobotTaskSaveReqVO {
private String taskNo; private String taskNo;
@Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "2") @Schema(description = "任务状态(0:未开始、1执行中、2已完成、3已取消)", example = "2")
private Long taskStatus; private Integer taskStatus;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)") @Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3运输中、4放货中、5结束)")
private Long taskStage; private Long taskStage;

View File

@ -80,7 +80,7 @@ public class RobotTaskDO extends BaseDO {
/** /**
* 任务状态(0:未开始1执行中2已完成3已取消) * 任务状态(0:未开始1执行中2已完成3已取消)
*/ */
private Long taskStatus; private Integer taskStatus;
/** /**
* 任务阶段(0:待执行1前往取货2取货中3运输中4放货中5结束) * 任务阶段(0:待执行1前往取货2取货中3运输中4放货中5结束)
*/ */

View File

@ -1,6 +1,5 @@
package cn.iocoder.yudao.module.system.dal.dataobject.robot; package cn.iocoder.yudao.module.system.dal.dataobject.robot;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*; import lombok.*;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -104,5 +103,12 @@ public class RobotTaskDetailDO extends BaseDO {
* 优先级 * 优先级
*/ */
private Long priority; private Long priority;
/**
* 停车后是否锁定(0:1:)
*/
private Integer needLock;
/**
* 所选车辆电量(充电模式)
*/
private Integer electricity;
} }

View File

@ -58,7 +58,7 @@ public interface RobotTaskDetailMapper extends BaseMapperX<RobotTaskDetailDO> {
* 查询未执行的明细任务 * 查询未执行的明细任务
* @return * @return
*/ */
List<RobotTaskDetailDO> getUnDoTask(); List<RobotTaskDetailDO> getUnDoTask(@Param("taskIds") List<Long> taskIds);
List<RobotTaskDetailDO> queryByTaskId(@Param("robotTaskId") Long robotTaskId); List<RobotTaskDetailDO> queryByTaskId(@Param("robotTaskId") Long robotTaskId);

View File

@ -40,12 +40,16 @@ public interface RobotTaskMapper extends BaseMapperX<RobotTaskDO> {
.orderByDesc(RobotTaskDO::getId)); .orderByDesc(RobotTaskDO::getId));
} }
/**
* 更新
* @param robotTaskDO
*/
void updateRobot(RobotTaskDO robotTaskDO);
/** /**
* 更新任务状态 * 获取未完成的订单id
* @param id * @return
* @param taskStatus
*/ */
void updateRobotStatus(@Param("id") Long id, List<Long> getUnDoAndDoingTaskIds();
@Param("taskStatus") Integer taskStatus);
} }

View File

@ -12,6 +12,7 @@ public enum RobotCacheLockEnum {
TASK_NO("task:robot:no", "任务号"), TASK_NO("task:robot:no", "任务号"),
ROBOT_TASK_ADD_LOCK("robot:task:add:lock", "所有创建机器人任务的锁"), ROBOT_TASK_ADD_LOCK("robot:task:add:lock", "所有创建机器人任务的锁"),
//取消订单修改优先级
ROBOT_TASK_DISTRIBUTE_LOCK("robot:task:distribute:lock", "下发任务给机器人的锁"), ROBOT_TASK_DISTRIBUTE_LOCK("robot:task:distribute:lock", "下发任务给机器人的锁"),
ROBOT_TASK_LOCATION_LOCK("robot:task:location:lock", "库位取/放任务下发互斥锁(仅仅锁某个库位)"), ROBOT_TASK_LOCATION_LOCK("robot:task:location:lock", "库位取/放任务下发互斥锁(仅仅锁某个库位)"),
ROBOT_TASK_LANE_LOCK("robot:task:lane:lock", "线库/巷道, 取/放任务下发互斥锁(仅仅锁某个线库/巷道)"), ROBOT_TASK_LANE_LOCK("robot:task:lane:lock", "线库/巷道, 取/放任务下发互斥锁(仅仅锁某个线库/巷道)"),

View File

@ -0,0 +1,30 @@
package cn.iocoder.yudao.module.system.enums.robot;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum RobotTaskTypeEnum {
TAKE_RELEASE(1),//取放货
PARK(2),//停车
CHARGE(3),//充电
MOVE(4),//移动
TAKE(5),//仅取货
RELEASE(6),//仅放货
SCAN(7),//扫描码
DETECTING_TRAYS(8); //检测托盘类型
/**
* 类型
*/
private final Integer type;
public static RobotTaskTypeEnum getRobotTaskType(Integer type) {
for (RobotTaskTypeEnum item : RobotTaskTypeEnum.values()) {
if (item.getType().equals(type)) {
return item;
}
}
return null;
}
}

View File

@ -60,4 +60,10 @@ public interface RobotInformationService {
* @return * @return
*/ */
RobotInformationStatisticsVO statisticsInformation(); RobotInformationStatisticsVO statisticsInformation();
/**
* 查询能正常使用的车辆
* @return
*/
List<RobotInformationDO> getCanUseRobot();
} }

View File

@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapMapper; import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskModelEnum;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil; import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -161,4 +162,15 @@ public class RobotInformationServiceImpl implements RobotInformationService {
return info; return info;
} }
/**
*
* @return
*/
@Override
public List<RobotInformationDO> getCanUseRobot() {
RobotInformationDO query = new RobotInformationDO();
query.setRobotTaskModel(RobotTaskModelEnum.NORMAL.getType());
return informationMapper.queryAllByLimit(query);
}
} }

View File

@ -1,10 +1,12 @@
package cn.iocoder.yudao.module.system.service.robot; package cn.iocoder.yudao.module.system.service.robot;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailAddVo; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailAddVo;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskDetailStatusEnum;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -19,6 +21,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TASK_DETAIL_CHANGE_ROBOT;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TASK_DETAIL_NOT_EXISTS; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TASK_DETAIL_NOT_EXISTS;
@ -47,6 +50,11 @@ public class RobotTaskDetailServiceImpl implements RobotTaskDetailService {
public void updateTaskDetail(RobotTaskDetailSaveReqVO updateReqVO) { public void updateTaskDetail(RobotTaskDetailSaveReqVO updateReqVO) {
// 校验存在 // 校验存在
validateTaskDetailExists(updateReqVO.getId()); validateTaskDetailExists(updateReqVO.getId());
RobotTaskDetailDO robotTaskDetailDO = taskDetailMapper.selectById(updateReqVO.getId());
if (ObjectUtil.isNotEmpty(updateReqVO.getRobotNo()) &&
!RobotTaskDetailStatusEnum.NEW.getType().equals(robotTaskDetailDO.getTaskStatus())) {
throw exception(TASK_DETAIL_CHANGE_ROBOT);
}
// 更新 // 更新
RobotTaskDetailDO updateObj = BeanUtils.toBean(updateReqVO, RobotTaskDetailDO.class); RobotTaskDetailDO updateObj = BeanUtils.toBean(updateReqVO, RobotTaskDetailDO.class);
taskDetailMapper.updateById(updateObj); taskDetailMapper.updateById(updateObj);

View File

@ -5,6 +5,7 @@ import javax.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskRespVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
@ -51,6 +52,11 @@ public interface RobotTaskService {
* @param pageReqVO 分页查询 * @param pageReqVO 分页查询
* @return 机器人任务主表分页 * @return 机器人任务主表分页
*/ */
PageResult<RobotTaskDO> getTaskPage(RobotTaskPageReqVO pageReqVO); PageResult<RobotTaskRespVO> getTaskPage(RobotTaskPageReqVO pageReqVO);
/**
* 获取任务号
* @return
*/
String getTaskNo();
} }

View File

@ -1,11 +1,10 @@
package cn.iocoder.yudao.module.system.service.robot; package cn.iocoder.yudao.module.system.service.robot;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationPageReqVO; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailAddVo; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.*;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
@ -169,7 +168,7 @@ public class RobotTaskServiceImpl implements RobotTaskService {
//查找库位 //查找库位
if (MoveAllEnum.NO.getType().equals(createReqVO.getDoMoveAll())) { if (MoveAllEnum.NO.getType().equals(createReqVO.getDoMoveAll())) {
setSingleLocationIdNo(createReqVO.getTaskDetailList(),task.getId()); setSingleLocationIdNo(createReqVO.getTaskDetailList(),task);
} else { } else {
setAllLocationIdNo(createReqVO,task.getId()); setAllLocationIdNo(createReqVO,task.getId());
} }
@ -323,19 +322,128 @@ public class RobotTaskServiceImpl implements RobotTaskService {
* @return * @return
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void setSingleLocationIdNo(List<RobotTaskDetailAddVo> taskDetailList, Long taskId){ public void setSingleLocationIdNo(List<RobotTaskDetailAddVo> taskDetailList, RobotTaskDO task){
List<Long> locationIds = new ArrayList<>(); List<Long> locationIds = new ArrayList<>();
for (RobotTaskDetailAddVo robotTaskVo : taskDetailList) { for (RobotTaskDetailAddVo robotTaskVo : taskDetailList) {
Set<Long> mapIds = new HashSet<>(); robotTaskVo.setRobotTaskId(task.getId());
if (ObjectUtil.isNotEmpty(robotTaskVo.getRobotNo())) { robotTaskVo.setPriority(task.getPriority());
RobotTaskTypeEnum robotTaskType = RobotTaskTypeEnum.getRobotTaskType(robotTaskVo.getTaskType());
switch (robotTaskType){
case TAKE_RELEASE:
doTakeRelease(robotTaskVo,locationIds);
break;
case PARK:
doPark(robotTaskVo);
break;
case CHARGE:
doCharge(robotTaskVo);
break;
case MOVE:
doMove(robotTaskVo);
break;
case TAKE:
doTake(robotTaskVo);
break;
case RELEASE:
doRelease(robotTaskVo);
break;
case SCAN:
doScan(robotTaskVo);
break;
case DETECTING_TRAYS:
doDetectingTrays(robotTaskVo);
break;
default :
log.error("任务类型不存在 ");
throw new RuntimeException("任务类型不存在");
}
}
}
/**
* 检测托盘类型
* @param robotTaskVo
*/
private void doDetectingTrays(RobotTaskDetailAddVo robotTaskVo) {
}
/**
* 扫描码
* @param robotTaskVo
*/
private void doScan(RobotTaskDetailAddVo robotTaskVo) {
}
/**
* 仅放货
* @param robotTaskVo
*/
private void doRelease(RobotTaskDetailAddVo robotTaskVo) {
locationMapper.updateLocationLockStatus(robotTaskVo.getToLocationId(),0,robotTaskVo.getRobotTaskId());
}
/**
* 仅取货
* @param robotTaskVo
*/
private void doTake(RobotTaskDetailAddVo robotTaskVo) {
locationMapper.updateLocationLockStatus(robotTaskVo.getFromLocationId(),0,robotTaskVo.getRobotTaskId());
}
/**
* 移动
* @param robotTaskVo
*/
private void doMove(RobotTaskDetailAddVo robotTaskVo) {
}
/**
* 充电
* @param robotTaskVo
*/
private void doCharge(RobotTaskDetailAddVo robotTaskVo) {
}
/**
* 停车
* @param robotTaskVo
*/
private void doPark(RobotTaskDetailAddVo robotTaskVo) {
}
/**
* 查询此机器人对应的楼层/区域(json)
* @param robotNo
* @return
*/
public Set<Long> getMapIdsByRobotNo(String robotNo) {
if (ObjectUtil.isNotEmpty(robotNo)) {
RobotInformationPageReqVO pageReqVO = new RobotInformationPageReqVO(); RobotInformationPageReqVO pageReqVO = new RobotInformationPageReqVO();
pageReqVO.setRobotNo(robotTaskVo.getRobotNo()); pageReqVO.setRobotNo(robotNo);
mapIds = informationMapper.selectPage(pageReqVO).getList() return informationMapper.selectPage(pageReqVO).getList()
.stream() .stream()
.findFirst() .findFirst()
.map(RobotInformationDO::getFloorAreaJson) .map(RobotInformationDO::getFloorAreaJson)
.orElse(new HashSet<>()); .orElse(new HashSet<>());
} }
return new HashSet<>();
}
/**
* 取放
* @param robotTaskVo
*/
@Transactional(rollbackFor = Exception.class)
public void doTakeRelease(RobotTaskDetailAddVo robotTaskVo,List<Long> locationIds) {
Set<Long> mapIds = new HashSet<>();
if (ObjectUtil.isNotEmpty(robotTaskVo.getRobotNo())) {
mapIds = getMapIdsByRobotNo(robotTaskVo.getRobotNo());
}
//校验放货库位 //校验放货库位
if (ReleaseTakeEnum.TO_LOCATION.getType().equals(robotTaskVo.getReleaseType())) { if (ReleaseTakeEnum.TO_LOCATION.getType().equals(robotTaskVo.getReleaseType())) {
@ -360,7 +468,6 @@ public class RobotTaskServiceImpl implements RobotTaskService {
robotTaskVo.setToLocationId(wareHouseLocationDO.getId()); robotTaskVo.setToLocationId(wareHouseLocationDO.getId());
robotTaskVo.setToLocationStorey(wareHouseLocationDO.getLocationStorey()); robotTaskVo.setToLocationStorey(wareHouseLocationDO.getLocationStorey());
} }
robotTaskVo.setPriority(robotTaskVo.getPriority());
locationIds.add(robotTaskVo.getToLocationId()); locationIds.add(robotTaskVo.getToLocationId());
//校验取货库位 //校验取货库位
if (ReleaseTakeEnum.TO_LOCATION.getType().equals(robotTaskVo.getTakeType())) { if (ReleaseTakeEnum.TO_LOCATION.getType().equals(robotTaskVo.getTakeType())) {
@ -396,18 +503,49 @@ public class RobotTaskServiceImpl implements RobotTaskService {
} }
//设置为锁定 //设置为锁定
locationMapper.updateLocationLockStatus(robotTaskVo.getToLocationId(),0,taskId); locationMapper.updateLocationLockStatus(robotTaskVo.getToLocationId(),0,robotTaskVo.getRobotTaskId());
locationMapper.updateLocationLockStatus(robotTaskVo.getFromLocationId(),0,taskId); locationMapper.updateLocationLockStatus(robotTaskVo.getFromLocationId(),0,robotTaskVo.getRobotTaskId());
}
} }
@Override @Override
@Transactional(rollbackFor = Exception.class)
public void updateTask(RobotTaskSaveReqVO updateReqVO) { public void updateTask(RobotTaskSaveReqVO updateReqVO) {
RLock lock = redissonUtils.getLock(RobotCacheLockEnum.ROBOT_TASK_DISTRIBUTE_LOCK.getKey());
if (lock.tryLock()){
try {
// 校验存在 // 校验存在
validateTaskExists(updateReqVO.getId()); validateTaskExists(updateReqVO.getId());
if (ObjectUtil.isEmpty(updateReqVO.getId())) {
throw exception(TASK_CHECK_ID_EXCEPTION);
}
// 更新 // 更新
//修改优先级需要订单状态为未开始
RobotTaskDO robotTaskDO = taskMapper.selectById(updateReqVO.getId());
if (ObjectUtil.isNotEmpty(updateReqVO.getPriority())) {
if (!RobotTaskStatusEnum.NEW.getType().equals(robotTaskDO.getTaskStatus())) {
throw exception(TASK_CHECK_TASK_PRIORITY);
}
List<RobotTaskDetailDO> taskDetailDOS = taskDetailMapper.queryByTaskId(updateReqVO.getId());
for (RobotTaskDetailDO taskDetailDO : taskDetailDOS) {
taskDetailDO.setPriority(updateReqVO.getPriority());
taskDetailMapper.updateRobotDetailById(taskDetailDO);
}
}
//修改订单状态
if (ObjectUtil.isNotEmpty(updateReqVO.getTaskStatus()) &&
RobotTaskStatusEnum.DONE.getType().equals(robotTaskDO.getTaskStatus())) {
throw exception(TASK_CHECK_TASK_STATUS);
}
RobotTaskDO updateObj = BeanUtils.toBean(updateReqVO, RobotTaskDO.class); RobotTaskDO updateObj = BeanUtils.toBean(updateReqVO, RobotTaskDO.class);
taskMapper.updateById(updateObj); taskMapper.updateById(updateObj);
} catch (Exception e) {
log.error("下发任务给车机出现异常 :{}",e.getMessage());
} finally {
lock.unlock();
}
} else {
throw exception(REDISSON_NOT_OBTAIN_LOCK);
}
} }
@Override @Override
@ -430,8 +568,23 @@ public class RobotTaskServiceImpl implements RobotTaskService {
} }
@Override @Override
public PageResult<RobotTaskDO> getTaskPage(RobotTaskPageReqVO pageReqVO) { public PageResult<RobotTaskRespVO> getTaskPage(RobotTaskPageReqVO pageReqVO) {
return taskMapper.selectPage(pageReqVO); PageResult<RobotTaskDO> pageResult = taskMapper.selectPage(pageReqVO);
PageResult<RobotTaskRespVO> dataPage = new PageResult<>();
dataPage.setTotal(pageResult.getTotal());
List<RobotTaskDO> list = pageResult.getList();
List<RobotTaskRespVO> targetList = BeanUtil.copyToList(list, RobotTaskRespVO.class);
for (RobotTaskRespVO robotTaskRespVO : targetList) {
robotTaskRespVO.setDetails(taskDetailMapper.queryByTaskId(robotTaskRespVO.getId()));
}
dataPage.setList(targetList);
return dataPage;
}
@Override
public String getTaskNo() {
String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.TASK_NO.getKey());
return taskNo+ DateUtils.getYearMonthDay()+incrementByKey;
} }
} }

View File

@ -1,11 +1,13 @@
package cn.iocoder.yudao.module.system.service.robot.job; package cn.iocoder.yudao.module.system.service.robot.job;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.mqtt.api.task.RobotTaskApi; import cn.iocoder.yudao.module.mqtt.api.task.RobotTaskApi;
import cn.iocoder.yudao.module.mqtt.api.task.dto.Pose2ds; import cn.iocoder.yudao.module.mqtt.api.task.dto.Pose2ds;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskDTO; import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskDTO;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskData; import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskData;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotInformationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper;
@ -51,9 +53,15 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
return; return;
} }
List<RobotTaskDetailDO> taskDetailDOS = robotTaskDetailMapper.getUnDoTask(); List<Long> taskIds = robotTaskMapper.getUnDoAndDoingTaskIds();
if (ObjectUtil.isEmpty(taskIds)) {
log.info("暂无需要处理的主任务");
return;
}
List<RobotTaskDetailDO> taskDetailDOS = robotTaskDetailMapper.getUnDoTask(taskIds);
if (taskDetailDOS.isEmpty()) { if (taskDetailDOS.isEmpty()) {
log.info("暂无需要处理的任务"); log.info("暂无需要处理的明细任务");
return; return;
} }
@ -170,7 +178,12 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
detailDO.setStartTime(LocalDateTime.now()); detailDO.setStartTime(LocalDateTime.now());
detailDO.setTaskStatus(RobotTaskDetailStatusEnum.DOING.getType()); detailDO.setTaskStatus(RobotTaskDetailStatusEnum.DOING.getType());
robotTaskDetailMapper.updateRobotDetailById(detailDO); robotTaskDetailMapper.updateRobotDetailById(detailDO);
robotTaskMapper.updateRobotStatus(taskDetailDO.getRobotTaskId(), RobotTaskStatusEnum.DOING.getType());
RobotTaskDO robotTaskDO = new RobotTaskDO();
robotTaskDO.setId(taskDetailDO.getRobotTaskId());
robotTaskDO.setStartTime(LocalDateTime.now());
robotTaskDO.setTaskStatus(RobotTaskDetailStatusEnum.DOING.getType());
robotTaskMapper.updateRobot(robotTaskDO);
} }

View File

@ -251,6 +251,13 @@
where where
task_status = '0' task_status = '0'
and deleted = '0' and deleted = '0'
<if test="taskIds != null and taskIds.size() > 0">
and robot_task_id in
<foreach collection="taskIds" item="taskId" index="index" open="(" close=")"
separator=",">
#{taskId}
</foreach>
</if>
order by priority, create_time asc order by priority, create_time asc
</select> </select>

View File

@ -227,7 +227,15 @@
</where> </where>
</select> </select>
<select id="getUnDoAndDoingTaskIds" resultType="java.lang.Long">
select
id
from
robot_task
where
deleted = '0'
and task_status in ('0','1')
</select>
<!--新增所有列--> <!--新增所有列-->
@ -294,7 +302,7 @@
</insert> </insert>
<!--通过主键修改数据--> <!--通过主键修改数据-->
<update id="update"> <update id="updateRobot">
update robot_task update robot_task
<set> <set>
<if test="montageTask != null"> <if test="montageTask != null">
@ -360,22 +368,10 @@
<if test="deleted != null"> <if test="deleted != null">
deleted = #{deleted}, deleted = #{deleted},
</if> </if>
<if test="tenantId != null">
tenant_id = #{tenantId},
</if>
</set> </set>
where id = #{id} where id = #{id}
</update> </update>
<update id="updateRobotStatus">
update
robot_task
set
task_status = #{taskStatus}
where id = #{id}
</update>
<!--通过主键删除--> <!--通过主键删除-->
<delete id="deleteById"> <delete id="deleteById">
delete delete