Compare commits

...

8 Commits

Author SHA1 Message Date
aikai
ec3b5b6ece Merge branch 'dev' of http://git.znkjfw.com/ak/zn-cloud-wcs into aikai 2025-03-27 14:48:33 +08:00
aikai
c6569da732 refactor(system): 优化用户注册校验提示信息和错误码描述
- 将用户账号的校验提示信息从"用户账号由 数字、字母 组成"修改为"用户名称由 数字、字母 组成"
-将库区名称重复的错误码描述从"库区名称重复"修改为"物料区域名称重复"
2025-03-27 14:48:25 +08:00
cbs
cb558f7977 修复bug 2025-03-27 09:15:30 +08:00
cbs
2ffbd9a4b8 继续任务 2025-03-26 14:37:09 +08:00
cbs
41ad86f563 清除交管 2025-03-25 16:40:51 +08:00
cbs
cdf1183fb0 修复bug 2025-03-24 15:33:28 +08:00
cbs
24dae58da0 Merge branch 'dev' into cbs 2025-03-24 15:27:24 +08:00
cbs
188c186bbc 修复bug 2025-03-24 15:26:45 +08:00
45 changed files with 1181 additions and 88 deletions

View File

@ -229,4 +229,8 @@ knife4j:
yudao:
info:
version: 1.0.0
version: 1.0.0
spring:
codec:
max-in-memory-size: 20MB

View File

@ -16,5 +16,5 @@ public class RobotAcceptTaskDTO {
//PAUSE(停止)CONTINUE继续DEFAULT执行CANCEL取消
private String executionType = ExecutionTypeEnum.DEFAULT.getType();
private List<RobotAcceptTaskData> data;
// private List<RobotAcceptTaskData> data;
}

View File

@ -174,7 +174,7 @@ public interface ErrorCodeConstants {
// ========== 库区 1-002-031-000 ==========
ErrorCode HOUSE_AREA_NOT_EXISTS = new ErrorCode(1-002-031-001, "库区不存在");
ErrorCode DUPLICATE_RESERVOIR_NAME = new ErrorCode(1-002-031-002, "库区名称重复");
ErrorCode DUPLICATE_RESERVOIR_NAME = new ErrorCode(1-002-031-002, "物料区域名称重复");
// ========== 库位 1-002-032-000 ==========
ErrorCode HOUSE_LOCATION_NOT_EXISTS = new ErrorCode(1-002-032-001, "库位不存在");
@ -187,6 +187,10 @@ public interface ErrorCodeConstants {
ErrorCode ROBOT_INFORMATION_NOT_EXISTS = new ErrorCode(1-002-034-001, "车辆信息不存在");
ErrorCode ROBOT_MAC_ADDRESS_EXISTS = new ErrorCode(1-002-034-002, "MAC地址重复");
ErrorCode ROBOT_ROBOT_NO_EXISTS = new ErrorCode(1-002-034-003, "机器人编号重复");
ErrorCode ROBOT_LAST_TASK_NO_EXISTS = new ErrorCode(1-002-034-004, "机器人前一个任务不存在或已经完成");
ErrorCode ROBOT_LAST_TASK_DELETE = new ErrorCode(1-002-034-005, "超过限制的时间,无法继续执行前一个任务");
ErrorCode ROBOT_NOT_FOUND_WAIT_ITEM = new ErrorCode(1-002-034-006, "没有空闲的停车点");
ErrorCode ROBOT_NOT_FOUND_FREE_CHARGING_STATION = new ErrorCode(1-002-034-007, "没有空闲的充电桩");
// ========== 机器人任务主表 1-002-035-000 ==========
ErrorCode TASK_NOT_EXISTS = new ErrorCode(1-002-035-001, "机器人任务主表不存在");
@ -200,6 +204,12 @@ public interface ErrorCodeConstants {
ErrorCode TASK_CHECK_UPDATE_STATUS = new ErrorCode(1-002-035-101, "订单更新失败");
ErrorCode TASK_CHECK_EXIST_NO = new ErrorCode(1-002-035-102, "订单号已存在");
ErrorCode TASK_TYPE_UN_EXIST = new ErrorCode(1-002-035-103, "找不到对应的任务类型");
ErrorCode TASK_TAKE_LOCATION_EMPTY = new ErrorCode(1-002-035-104, "取货库位没有库存");
ErrorCode TASK_TAKE_LOCATION_UPPER_LEVELS_NOT_EMPTY = new ErrorCode(1-002-035-105, "取货库位上层不为空");
ErrorCode TASK_RELEASE_LOCATION_NOT_EMPTY = new ErrorCode(1-002-035-106, "放货库位不为空");
ErrorCode TASK_RELEASE_LOCATION_LOWER_LEVELS_EMPTY = new ErrorCode(1-002-035-107, "放货库位下层为空");
ErrorCode TASK_TAKE_LOCATION_HAVE_OTHER_TASK = new ErrorCode(1-002-035-108, "取货库位已经分配了其他任务");
ErrorCode TASK_RELEASE_LOCATION_HAVE_OTHER_TASK = new ErrorCode(1-002-035-109, "放货库位已经分配了其他任务");
// ========== 机器人任务明细 1-002-036-000 ==========
ErrorCode TASK_DETAIL_NOT_EXISTS = new ErrorCode(1-002-036-001, "机器人任务明细不存在");
@ -250,4 +260,6 @@ public interface ErrorCodeConstants {
ErrorCode OPERATION_LOG_NOT_EXISTS = new ErrorCode(1_002_049_001, "机器人动作记录不存在");
// ========== 用户操作记录 1_002_050_001 ==========
ErrorCode USER_OPERATION_LOG_NOT_EXISTS = new ErrorCode(1_002_050_001, "用户操作记录不存在");
// ========== 车辆衔接任务 1_002_051_001 ==========
ErrorCode TASK_PROCEED_NOT_EXISTS = new ErrorCode(1_002_051_001, "车辆衔接任务不存在");
}

View File

@ -49,10 +49,9 @@ public class RobotGenericsStatusApiImpl implements RobotGenericsStatusApi {
RobotStatusDataPoseDTO robotStatusDataPoseDTO= JSONUtil.toBean((String)object, RobotStatusDataPoseDTO.class);
String batSoc = robotStatusData.getHwStates().getBatSoc();
if (ObjectUtil.isNotEmpty(batSoc)) {
BigDecimal a = new BigDecimal(batSoc);
BigDecimal b = new BigDecimal("100");
BigDecimal multiply = a.multiply(b);
robotStatusDataPoseDTO.setBatSoc(multiply.toString());
String[] split = batSoc.split("\\.");
batSoc = split[1].substring(0,2);
robotStatusDataPoseDTO.setBatSoc(batSoc);
}
redisUtil.set(pose2dKey,JSON.toJSONString(robotStatusDataPoseDTO),robotPositionCacheTime);

View File

@ -75,7 +75,7 @@ public class SystemRateLimiterAspect {
obj = joinPoint.proceed();
} else {
// 请求过于频繁
logger.info("请求过于频繁 {}", key);
// logger.info("请求过于频繁 {}", key);
}
return obj;
}

View File

@ -0,0 +1,9 @@
package cn.iocoder.yudao.module.system.constant.path;
/**
* 路径规划相关缓存
*/
public class PathPlanningChcheConstant {
//发送给路径规划的任务 (拼接的是任务id)
public static String PATH_PLANNING_TASK = "path:planning:task";
}

View File

@ -16,7 +16,7 @@ public class AuthRegisterReqVO {
@Schema(description = "用户账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao")
@NotBlank(message = "用户账号不能为空")
@Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户账号由 数字、字母 组成")
@Pattern(regexp = "^[a-zA-Z0-9]{4,30}$", message = "用户名称由 数字、字母 组成")
@Size(min = 4, max = 30, message = "用户账号长度为 4-30 个字符")
private String username;
@ -37,4 +37,4 @@ public class AuthRegisterReqVO {
@NotEmpty(message = "验证码不能为空", groups = AuthLoginReqVO.CodeEnableGroup.class)
private String captchaVerification;
}
}

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.houselocation.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.Size;
import java.math.BigDecimal;
@Schema(description = "管理后台 - 库位新增/修改 Request VO")
@ -34,6 +35,7 @@ public class WareHouseLocationSaveReqVO {
private String locationYaw;
@Schema(description = "物料信息")
@Size(min = 0,max = 100 ,message = "物料信息长度超过限制")
private String skuInfo;
@Schema(description = "物料批次号")

View File

@ -131,4 +131,13 @@ public class DeviceInformationController {
List<DeviceInformationRespVO> list = informationService.getInformationList(pageReqVO);
return success(BeanUtils.toBean(list, DeviceInformationRespVO.class));
}
@GetMapping("/getMapImageUrl")
@Operation(summary = "获得设备图标URL")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('device:information:getMapImageUrl')")
public CommonResult<String> getMapImageUrl(@RequestParam("deviceType") Integer deviceType) {
String str = informationService.getMapImageUrl(deviceType);
return success(str);
}
}

View File

@ -41,12 +41,14 @@ public class DeviceInformationSaveReqVO {
private Integer deviceType;
@Schema(description = "设备编号")
@Size(min = 0, max = 50 ,message = "设备编号长度超过限制")
private String deviceNo;
@Schema(description = "设备位置")
private String deviceLocation;
@Schema(description = "mac地址")
@Size(min = 0, max = 50 ,message = "Mac地址长度超过限制")
private String macAddress;
@Schema(description = "设备在地图上图标")
@ -77,9 +79,11 @@ public class DeviceInformationSaveReqVO {
private Integer deviceAttribute;
@Schema(description = "设备IP")
@Size(min = 0, max = 20 ,message = "设备IP长度超过限制")
private String deviceIp;
@Schema(description = "端口")
@Size(min = 0, max = 10 ,message = "端口长度超过限制")
private String devicePort;
@Schema(description = "最后使用者")

View File

@ -140,4 +140,20 @@ public class RobotInformationController {
informationService.test(dto);
return success(true);
}
@PostMapping("/cleanTrafficManagement")
@Operation(summary = "清除交管")
@PreAuthorize("@ss.hasPermission('robot:information:cleanTrafficManagement')")
public CommonResult<Boolean> cleanTrafficManagement(@RequestParam("robotNo") String robotNo) {
informationService.cleanTrafficManagement(robotNo);
return success(true);
}
@PostMapping("/doTaskContinue")
@Operation(summary = "继续做任务")
@PreAuthorize("@ss.hasPermission('robot:information:doTaskContinue')")
public CommonResult<Boolean> doTaskContinue(@RequestParam("robotNo") String robotNo) {
informationService.doTaskContinue(robotNo);
return success(true);
}
}

View File

@ -0,0 +1,94 @@
package cn.iocoder.yudao.module.system.controller.admin.robot;
import cn.iocoder.yudao.module.system.controller.admin.robot.proceed.*;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskProceedDO;
import cn.iocoder.yudao.module.system.service.robot.proceed.RobotTaskProceedService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 车辆衔接任务")
@RestController
@RequestMapping("/robot/task-proceed")
@Validated
public class RobotTaskProceedController {
@Resource
private RobotTaskProceedService taskProceedService;
@PostMapping("/create")
@Operation(summary = "创建车辆衔接任务")
@PreAuthorize("@ss.hasPermission('robot:task-proceed:create')")
public CommonResult<Long> createTaskProceed(@Valid @RequestBody RobotTaskProceedSaveReqVO createReqVO) {
return success(taskProceedService.createTaskProceed(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新车辆衔接任务")
@PreAuthorize("@ss.hasPermission('robot:task-proceed:update')")
public CommonResult<Boolean> updateTaskProceed(@Valid @RequestBody RobotTaskProceedSaveReqVO updateReqVO) {
taskProceedService.updateTaskProceed(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除车辆衔接任务")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('robot:task-proceed:delete')")
public CommonResult<Boolean> deleteTaskProceed(@RequestParam("id") Long id) {
taskProceedService.deleteTaskProceed(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得车辆衔接任务")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('robot:task-proceed:query')")
public CommonResult<RobotTaskProceedRespVO> getTaskProceed(@RequestParam("id") Long id) {
RobotTaskProceedDO taskProceed = taskProceedService.getTaskProceed(id);
return success(BeanUtils.toBean(taskProceed, RobotTaskProceedRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得车辆衔接任务分页")
@PreAuthorize("@ss.hasPermission('robot:task-proceed:query')")
public CommonResult<PageResult<RobotTaskProceedRespVO>> getTaskProceedPage(@Valid RobotTaskProceedPageReqVO pageReqVO) {
PageResult<RobotTaskProceedDO> pageResult = taskProceedService.getTaskProceedPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, RobotTaskProceedRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出车辆衔接任务 Excel")
@PreAuthorize("@ss.hasPermission('robot:task-proceed:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportTaskProceedExcel(@Valid RobotTaskProceedPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<RobotTaskProceedDO> list = taskProceedService.getTaskProceedPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "车辆衔接任务.xls", "数据", RobotTaskProceedRespVO.class,
BeanUtils.toBean(list, RobotTaskProceedRespVO.class));
}
}

View File

@ -0,0 +1,43 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.proceed;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 车辆衔接任务分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class RobotTaskProceedPageReqVO extends PageParam {
@Schema(description = "任务号")
private String taskNo;
@Schema(description = "机器人任务主表id", example = "25623")
private Long robotTaskId;
@Schema(description = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型", example = "2")
private Integer taskType;
@Schema(description = "出现异常时的任务阶段(0:待执行、1前往取货、2取货中、3前往放货、4放货中、5结束、6移动中、7:正在充电)")
private Long taskStage;
@Schema(description = "robot_task_detail的id", example = "30327")
private Long taskDetailId;
@Schema(description = "首次执行的AGV编号")
private String robotNo;
@Schema(description = "接力的AGV编号")
private String proceedRobotNo;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,51 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.proceed;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 车辆衔接任务 Response VO")
@Data
@ExcelIgnoreUnannotated
public class RobotTaskProceedRespVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2854")
@ExcelProperty("主键ID")
private Long id;
@Schema(description = "任务号")
@ExcelProperty("任务号")
private String taskNo;
@Schema(description = "机器人任务主表id", example = "25623")
@ExcelProperty("机器人任务主表id")
private Long robotTaskId;
@Schema(description = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型", example = "2")
@ExcelProperty("任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型")
private Integer taskType;
@Schema(description = "出现异常时的任务阶段(0:待执行、1前往取货、2取货中、3前往放货、4放货中、5结束、6移动中、7:正在充电)")
@ExcelProperty("出现异常时的任务阶段(0:待执行、1前往取货、2取货中、3前往放货、4放货中、5结束、6移动中、7:正在充电)")
private Long taskStage;
@Schema(description = "robot_task_detail的id", example = "30327")
@ExcelProperty("robot_task_detail的id")
private Long taskDetailId;
@Schema(description = "首次执行的AGV编号")
@ExcelProperty("首次执行的AGV编号")
private String robotNo;
@Schema(description = "接力的AGV编号")
@ExcelProperty("接力的AGV编号")
private String proceedRobotNo;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.system.controller.admin.robot.proceed;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 车辆衔接任务新增/修改 Request VO")
@Data
@Builder
public class RobotTaskProceedSaveReqVO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "2854")
private Long id;
@Schema(description = "任务号")
private String taskNo;
@Schema(description = "机器人任务主表id", example = "25623")
private Long robotTaskId;
@Schema(description = "任务类型1取放货、2停车、 3充电、4移动、5仅取货、6仅放货、7扫描码、8检测托盘类型", example = "2")
private Integer taskType;
@Schema(description = "出现异常时的任务阶段(0:待执行、1前往取货、2取货中、3前往放货、4放货中、5结束、6移动中、7:正在充电)")
private Long taskStage;
@Schema(description = "robot_task_detail的id", example = "30327")
private Long taskDetailId;
@Schema(description = "首次执行的AGV编号")
private String robotNo;
@Schema(description = "接力的AGV编号")
private String proceedRobotNo;
}

View File

@ -24,6 +24,9 @@ public class TaskAssignDTO {
@Schema(description = "AGV编号")
private String robotNo;
@Schema(description = "等待点id")
private String waitId;
/**
* 获取机器人要做的任务描述
* @return

View File

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.system.dal.dataobject.robot;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 车辆衔接任务 DO
*
* @author 陈宾顺
*/
@TableName("robot_task_proceed")
@KeySequence("robot_task_proceed_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RobotTaskProceedDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 任务号
*/
private String taskNo;
/**
* 机器人任务主表id
*/
private Long robotTaskId;
/**
* 任务类型1取放货2停车 3充电4移动5仅取货6仅放货7扫描码8检测托盘类型
*/
private Integer taskType;
/**
* 出现异常时的任务阶段(0:待执行1前往取货2取货中3前往放货4放货中5结束6移动中7:正在充电)
*/
private Long taskStage;
/**
* robot_task_detail的id
*/
private Long taskDetailId;
/**
* 首次执行的AGV编号
*/
private String robotNo;
/**
* 接力的AGV编号
*/
private String proceedRobotNo;
}

View File

@ -32,7 +32,20 @@ public interface DeviceInformationMapper extends BaseMapperX<DeviceInformationDO
.orderByDesc(DeviceInformationDO::getId));
}
/**
* 更新设备使用中
* @param deviceNo
* @param deviceUseStatus
* @param lastUser
*/
void updateDeviceUseStatus(@Param("deviceNo") String deviceNo,
@Param("deviceUseStatus") String deviceUseStatus,
@Param("deviceEnable") Integer deviceEnable);
@Param("lastUser") String lastUser);
/**
* 设置设备空闲
* @param lastUser
*/
void setDeviceReleaseByLastUser(@Param("lastUser") String lastUser,
@Param("deviceUseStatus") String deviceUseStatus);
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.system.dal.mysql.robot;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.module.system.controller.admin.robot.proceed.RobotTaskProceedPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskProceedDO;
import org.apache.ibatis.annotations.Mapper;
/**
* 车辆衔接任务 Mapper
*
* @author 陈宾顺
*/
@Mapper
public interface RobotTaskProceedMapper extends BaseMapperX<RobotTaskProceedDO> {
default PageResult<RobotTaskProceedDO> selectPage(RobotTaskProceedPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<RobotTaskProceedDO>()
.eqIfPresent(RobotTaskProceedDO::getTaskNo, reqVO.getTaskNo())
.eqIfPresent(RobotTaskProceedDO::getRobotTaskId, reqVO.getRobotTaskId())
.eqIfPresent(RobotTaskProceedDO::getTaskType, reqVO.getTaskType())
.eqIfPresent(RobotTaskProceedDO::getTaskStage, reqVO.getTaskStage())
.eqIfPresent(RobotTaskProceedDO::getTaskDetailId, reqVO.getTaskDetailId())
.eqIfPresent(RobotTaskProceedDO::getRobotNo, reqVO.getRobotNo())
.eqIfPresent(RobotTaskProceedDO::getProceedRobotNo, reqVO.getProceedRobotNo())
.betweenIfPresent(RobotTaskProceedDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(RobotTaskProceedDO::getId));
}
}

View File

@ -24,4 +24,24 @@ public enum DeviceTypeEnum {
* 说明
*/
private final String msg;
public static Integer getConfigType (Integer type) {
if (CHARGING_STATION.type.equals(type)) {
return 5;
}if (CONVEYOR_LINE.type.equals(type)) {
return 6;
}if (PALLETIZER.type.equals(type)) {
return 7;
}if (AUTOMATIC_DOOR.type.equals(type)) {
return 8;
}if (HOIST.type.equals(type)) {
return 9;
}if (SIGNAL_LIGHT.type.equals(type)) {
return 10;
}if (BUTTON_BOX.type.equals(type)) {
return 11;
}else {
return 12;
}
}
}

View File

@ -1,26 +0,0 @@
/*
package cn.iocoder.yudao.module.system.enums.robot.task;
import lombok.AllArgsConstructor;
import lombok.Getter;
*/
/**
* RobotAcceptTaskDTO的order_type
*//*
@Getter
@AllArgsConstructor
public enum RobotTaksOrderTypeEnum {
AUTO_MOVE("AUTO_MOVE"), //自动移库任务
TASK("TASK"), //客户下发的任务
AUTO_CHARGE("AUTO_CHARGE"); //自动充电任务
*/
/**
* 类型
*//*
private final String type;
}
*/

View File

@ -13,7 +13,8 @@ public enum RobotTaskStageEnum {
RELEASEING(4L,"放货中"),
DONE(5L,"结束"),
MOVE(6L,"移动中"),
CHARGEING(7L,"待执行正在充电");
CHARGEING(7L,"待执行正在充电"),
CLOSE(8L,"任务已取消");
/**
* 类型
*/

View File

@ -60,7 +60,7 @@ public class HouseLocationServiceImpl extends ServiceImpl<WareHouseLocationMappe
public void updateHouseLocation(WareHouseLocationSaveReqVO updateReqVO) {
// 校验存在
validateHouseLocationExists(updateReqVO.getId());
String str = "";
String str = "修改库位信息 ";
WareHouseLocationDO wareHouseLocationDO = houseLocationMapper.selectById(updateReqVO.getId());
if (!wareHouseLocationDO.getLocationEnable().equals(updateReqVO.getLocationEnable())) {
if (LocationEnableEnum.YES.getType().equals(updateReqVO.getLocationEnable())) {

View File

@ -130,4 +130,11 @@ public interface DeviceInformationService extends IService<DeviceInformationDO>
* @param deviceNo
*/
void chargeDeviceShrink(String deviceNo);
/**
* 获取图标URL
* @param deviceType
* @return
*/
String getMapImageUrl(Integer deviceType);
}

View File

@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInfo
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationRespVO;
import cn.iocoder.yudao.module.system.controller.admin.information.vo.DeviceInformationSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.log.vo.UserOperationLogSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.config.CommonConfigDO;
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO;
@ -22,6 +23,7 @@ import cn.iocoder.yudao.module.system.enums.device.DeviceAttributeEnum;
import cn.iocoder.yudao.module.system.enums.device.DeviceStatusEnum;
import cn.iocoder.yudao.module.system.enums.device.DeviceTypeEnum;
import cn.iocoder.yudao.module.system.enums.device.PictureConfigEnum;
import cn.iocoder.yudao.module.system.service.config.CommonConfigService;
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
import cn.iocoder.yudao.module.system.service.log.UserOperationLogService;
import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService;
@ -78,6 +80,9 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
@Resource
private RobotWarnMsgService warnMsgService;
@Resource
private CommonConfigService configService;
@Override
public Long createInformation(DeviceInformationSaveReqVO createReqVO) {
// -- 先判断库里是否有相通的mac地址数据
@ -138,6 +143,12 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
validateInformationExists(id);
// 删除
informationMapper.deleteById(id);
DeviceInformationDO deviceInformationDO = informationMapper.selectById(id);
UserOperationLogSaveReqVO operationLog = UserOperationLogSaveReqVO.builder()
.operateAction("删除设备 " + deviceInformationDO.getDeviceNo())
.nickName(SecurityFrameworkUtils.getLoginUserNickname()).build();
userOperationLogService.createUserOperationLog(operationLog);
}
private void validateInformationExists(Long id) {
@ -384,17 +395,35 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
shrink(deviceInformationDO.getDeviceIp(), Integer.parseInt(deviceInformationDO.getDevicePort()), deviceNo);
}
@Override
public String getMapImageUrl(Integer deviceType) {
Integer configType = DeviceTypeEnum.getConfigType(deviceType);
if (ObjectUtil.isEmpty(configType)) {
return "";
}
CommonConfigDO config = configService.getConfig(configType.longValue());
if (ObjectUtil.isEmpty(config)) {
return "";
}
return config.getConfigStr();
}
public void shrink(String ip, int port, String deviceNo) {
boolean success = true;
short[] shrinkArr = {0};
for (int i = 0; i < 3; i++) {
ModbusMaster asciiMaster = null;
try {
ModbusMaster asciiMaster = ModbusUtils.getMaster(ip, port);
asciiMaster = ModbusUtils.getMaster(ip, port);
ModbusUtils.writeHoldingRegisters(asciiMaster, 1, 0, shrinkArr);
} catch (ModbusInitException | ModbusTransportException e) {
log.info("充电设备缩回时,出现异常 :{}", ip);
warnMsgService.addWarnMsg(deviceNo + " 充电设备缩回失败");
success = false;
}finally {
if (ObjectUtil.isNotEmpty(asciiMaster)) {
asciiMaster.destroy();
}
}
if (success) {
@ -413,8 +442,9 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
short[] extendArr = {1};
short[] shrinkArr = {0};
for (int i = 0; i < 3; i++) {
ModbusMaster asciiMaster = null;
try {
ModbusMaster asciiMaster = ModbusUtils.getMaster(ip, port);
asciiMaster = ModbusUtils.getMaster(ip, port);
ModbusUtils.writeHoldingRegisters(asciiMaster, 1, 0, shrinkArr);
Thread.sleep(2500);
ModbusUtils.writeHoldingRegisters(asciiMaster, 1, 0, extendArr);
@ -422,6 +452,10 @@ public class DeviceInformationServiceImpl extends ServiceImpl<DeviceInformationM
log.info("充电设备伸出时,出现异常 :{}", ip);
warnMsgService.addWarnMsg(deviceNo + " 充电设备伸出失败");
success = false;
}finally {
if (ObjectUtil.isNotEmpty(asciiMaster)) {
asciiMaster.destroy();
}
}
if (success) {

View File

@ -57,4 +57,11 @@ public interface RobotTaskDetailActionLogService {
* @param logs
*/
void addLogInCache(List<RobotTaskDetailActionLogDO> logs);
/**
* 获取车辆的最后一条任务
* @param robotNo
* @return
*/
RobotTaskDetailActionLogDO getLastTaskByRobotNo(String robotNo);
}

View File

@ -1,10 +1,13 @@
package cn.iocoder.yudao.module.system.service.log;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.log.vo.RobotTaskDetailActionLogPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.log.vo.RobotTaskDetailActionLogSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.log.RobotTaskDetailActionLogDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
import cn.iocoder.yudao.module.system.dal.mysql.log.RobotTaskDetailActionLogMapper;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskStatusEnum;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Value;
@ -91,4 +94,13 @@ public class RobotTaskDetailActionLogServiceImpl implements RobotTaskDetailActio
}
}
@Override
public RobotTaskDetailActionLogDO getLastTaskByRobotNo(String robotNo) {
return taskDetailActionLogMapper.selectOne(new LambdaQueryWrapperX<RobotTaskDetailActionLogDO>()
.eq(RobotTaskDetailActionLogDO::getRobotNo, robotNo)
.eq(RobotTaskDetailActionLogDO::getCommandId, -1)
.orderByDesc(RobotTaskDetailActionLogDO::getCreateTime)
.last("limit 1"));
}
}

View File

@ -101,4 +101,6 @@ public interface PositionMapItemService extends IService<PositionMapItemDO> {
* @return
*/
Object getAGVPointInformation(String macAddress);
void setMapItemIdle(Long id);
}

View File

@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMa
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapItemMapper;
import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@ -122,4 +123,11 @@ public class PositionMapItemServiceImpl extends ServiceImpl<PositionMapItemMappe
}
return redisUtil.get(pose2dKey);
}
@Override
public void setMapItemIdle(Long id) {
PositionMapItemDO item = PositionMapItemDO.builder().id(id).useStatus(ZeroOneEnum.ZERO.getType()).build();
positionMapItemMapper.updateById(item);
}
}

View File

@ -138,4 +138,16 @@ public interface RobotInformationService extends IService<RobotInformationDO> {
* 维护车机心跳
*/
void rcsHeartBeat();
/**
* 清除交管
* @param robotNo
*/
void cleanTrafficManagement(String robotNo);
/**
* 继续做任务
* @param robotNo
*/
void doTaskContinue(String robotNo);
}

View File

@ -7,35 +7,78 @@ import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.mqtt.api.common.CommonApi;
import cn.iocoder.yudao.module.mqtt.api.path.PathPlanningApi;
import cn.iocoder.yudao.module.mqtt.api.path.task.TaskRobotNoLimittationAreaDTO;
import cn.iocoder.yudao.module.mqtt.api.path.task.TaskToPathPlanningDTO;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskDTO;
import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotRcsHeartBeatDTO;
import cn.iocoder.yudao.module.mqtt.enums.task.ExecutionTypeEnum;
import cn.iocoder.yudao.module.system.api.robot.RequestProcessor;
import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.api.robot.vo.RobotInformationVO;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningChcheConstant;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTopicConstant;
import cn.iocoder.yudao.module.system.controller.admin.log.vo.UserOperationLogSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.proceed.RobotTaskProceedSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.*;
import cn.iocoder.yudao.module.system.controller.admin.tool.dto.CleanAgvDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.informationmapassociation.InformationMapAssociationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.log.RobotTaskDetailActionLogDO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotModelDO;
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.wait.MoveToWaitDO;
import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.information.DeviceInformationMapper;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapItemMapper;
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.RobotModelMapper;
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.enums.common.ZeroOneEnum;
import cn.iocoder.yudao.module.system.enums.device.DeviceTypeEnum;
import cn.iocoder.yudao.module.system.enums.device.DeviceUseStatusEnum;
import cn.iocoder.yudao.module.system.enums.item.PositionMapItemEnum;
import cn.iocoder.yudao.module.system.enums.path.PathTaskTypeEnum;
import cn.iocoder.yudao.module.system.enums.path.PathTaskTypeToRobotEnum;
import cn.iocoder.yudao.module.system.enums.redis.RobotCacheLockEnum;
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.RobotTaskModelEnum;
import cn.iocoder.yudao.module.system.enums.robot.actionlog.ActionStatusEnum;
import cn.iocoder.yudao.module.system.enums.robot.information.RobotStatisticsTypeEnum;
import cn.iocoder.yudao.module.system.enums.robot.task.RobotTaskStageEnum;
import cn.iocoder.yudao.module.system.service.informationmapassociation.InformationMapAssociationService;
import cn.iocoder.yudao.module.system.service.log.RobotTaskDetailActionLogService;
import cn.iocoder.yudao.module.system.service.log.UserOperationLogService;
import cn.iocoder.yudao.module.system.service.positionmap.PositionMapItemService;
import cn.iocoder.yudao.module.system.service.robot.pathplanning.RobotPathPlanningService;
import cn.iocoder.yudao.module.system.service.robot.proceed.RobotTaskProceedService;
import cn.iocoder.yudao.module.system.service.wait.MoveToWaitService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import cn.iocoder.yudao.module.system.util.redis.RedissonUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
@ -44,6 +87,7 @@ import java.util.function.Function;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
/**
@ -53,6 +97,7 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
*/
@Service
@Validated
@Slf4j
public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMapper, RobotInformationDO> implements RobotInformationService {
@Resource
@ -69,6 +114,33 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
@Resource
private UserOperationLogService userOperationLogService;
@Resource
private RobotTaskDetailActionLogService taskDetailActionLogService;
@Resource
private DeviceInformationMapper deviceInformationMapper;
@Resource
private RobotTaskDetailMapper taskDetailMapper;
@Resource
private PositionMapItemService positionMapItemService;
@Resource
private MoveToWaitService moveToWaitService;
@Resource
private RobotTaskProceedService taskProceedService;
@Resource
private RobotTaskMapper taskMapper;
@Autowired
private RobotPathPlanningService robotPathPlanningService;
@Resource
private PositionMapItemMapper positionMapItemMapper;
@Resource
private RedisUtil redisUtil;
@Resource
@ -77,6 +149,14 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
private InformationMapAssociationService informationMapAssociationService;
// -- 获取所有的设备信息key
public static final String key = RobotTaskChcheConstant.ROBOT_GET_ROBOT_INFO;
@Autowired
private WareHouseLocationMapper wareHouseLocationMapper;
@Resource
private PathPlanningApi pathPlanningApi;
@Resource
private RedissonUtils redissonUtils;
@Override
public Long createInformation(RobotInformationSaveReqVO createReqVO) {
@ -116,7 +196,7 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
}
UserOperationLogSaveReqVO operationLog = UserOperationLogSaveReqVO.builder()
.operateAction("新增车辆 "+createReqVO.getRobotNo())
.operateAction("新增车辆 " + createReqVO.getRobotNo())
.nickName(SecurityFrameworkUtils.getLoginUserNickname()).build();
userOperationLogService.createUserOperationLog(operationLog);
// 返回
@ -164,15 +244,15 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
String str = "";
if (!robotInformationDO.getRobotTaskModel().equals(updateReqVO.getRobotTaskModel())
&& RobotTaskModelEnum.REJECTION.getType().equals(updateReqVO.getRobotTaskModel())) {
&& RobotTaskModelEnum.REJECTION.getType().equals(updateReqVO.getRobotTaskModel())) {
str = ",且设置车辆锁定";
}else if (!robotInformationDO.getRobotTaskModel().equals(updateReqVO.getRobotTaskModel())
} else if (!robotInformationDO.getRobotTaskModel().equals(updateReqVO.getRobotTaskModel())
&& RobotTaskModelEnum.NORMAL.getType().equals(updateReqVO.getRobotTaskModel())) {
str = ",且设置车辆非锁定";
}
UserOperationLogSaveReqVO operationLog = UserOperationLogSaveReqVO.builder()
.operateAction("更新车辆信息"+str)
.operateAction("更新车辆信息" + str)
.nickName(SecurityFrameworkUtils.getLoginUserNickname()).build();
userOperationLogService.createUserOperationLog(operationLog);
}
@ -186,7 +266,7 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
RobotInformationDO robotInformationDO = informationMapper.selectById(id);
UserOperationLogSaveReqVO operationLog = UserOperationLogSaveReqVO.builder()
.operateAction("删除车辆 "+robotInformationDO.getRobotNo())
.operateAction("删除车辆 " + robotInformationDO.getRobotNo())
.nickName(SecurityFrameworkUtils.getLoginUserNickname()).build();
userOperationLogService.createUserOperationLog(operationLog);
}
@ -530,12 +610,12 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
if (ObjectUtil.isNotEmpty(o)) {
// 化作列表
List<RobotInformationVO> list = JSONUtil.toList(o.toString(), RobotInformationVO.class);
return list.stream().collect(Collectors.toMap(RobotInformationVO::getMacAddress, Function.identity()));
return list.stream().collect(Collectors.toMap(RobotInformationVO::getMacAddress, Function.identity(), (v1, v2) -> v1));
} else {
List<RobotInformationDO> allRobotInfoList = this.list();
List<RobotInformationVO> list = BeanUtil.copyToList(allRobotInfoList, RobotInformationVO.class);
redisUtil.set(key, JSONUtil.toJsonStr(list));
return list.stream().collect(Collectors.toMap(RobotInformationVO::getMacAddress, Function.identity()));
return list.stream().collect(Collectors.toMap(RobotInformationVO::getMacAddress, Function.identity(), (v1, v2) -> v1));
}
}
@ -621,4 +701,343 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
commonApi.commonMethod(new RobotRcsHeartBeatDTO(), topic);
}
}
/**
* 清除交管
*
* @param robotNo
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void cleanTrafficManagement(String robotNo) {
UserOperationLogSaveReqVO operationLog = UserOperationLogSaveReqVO.builder()
.operateAction("清除交管 " + robotNo)
.nickName(SecurityFrameworkUtils.getLoginUserNickname()).build();
userOperationLogService.createUserOperationLog(operationLog);
RobotTaskDetailActionLogDO log = closeTask(robotNo);
if (ObjectUtil.isEmpty(log)) {
return;
}
RobotTaskDetailDO robotTaskDetail = taskDetailMapper.selectById(log.getTaskDetailId());
//移动充电任务需手动关闭
if (PathTaskTypeEnum.CHARGE.getType().equals(log.getCommandType())
|| PathTaskTypeEnum.AUTO_CHARGE.getType().equals(log.getCommandType())) {
deviceInformationMapper.setDeviceReleaseByLastUser(robotNo, DeviceUseStatusEnum.IDLE.getType());
} else if (PathTaskTypeEnum.MOVE_TO_WAIT_STOP.getType().equals(log.getCommandType())) {
if (ObjectUtil.isNotEmpty(robotTaskDetail)) {
positionMapItemService.setMapItemIdle(robotTaskDetail.getToLocationId());
}
} else if (PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(log.getCommandType())) {
MoveToWaitDO moveToWait = moveToWaitService.getMoveToWait(log.getTaskDetailId());
if (ObjectUtil.isNotEmpty(moveToWait)) {
positionMapItemService.setMapItemIdle(moveToWait.getPositionMapItemId());
}
} else if (PathTaskTypeEnum.TAKE_RELEASE.getType().equals(log.getCommandType())
|| PathTaskTypeEnum.TAKE.getType().equals(log.getCommandType())
|| PathTaskTypeEnum.RELEASE.getType().equals(log.getCommandType())) {
takeReleaseCleanTrafficManagement(robotTaskDetail);
}
//不释放机器人状态怕机器人接新任务
}
public RobotTaskDetailActionLogDO closeTask(String robotNo) {
CleanAgvDTO build = CleanAgvDTO.builder().robotNo(robotNo).build();
commonApi.commonMethod(build, PathPlanningTopicConstant.CLEAN_AGV);
RobotTaskDetailActionLogDO log = taskDetailActionLogService.getLastTaskByRobotNo(robotNo);
if (ObjectUtil.isEmpty(log) || ActionStatusEnum.DONE.getType().equals(log.getActionStatus())) {
return null;
}
String mac = getMacByRobotNo(robotNo);
robotCloseTaskDetail(log.getTaskDetailId() + "", mac, log.getCommandType());
return log;
}
/**
* 继续做任务
*
* @param robotNo
*/
@Override
public void doTaskContinue(String robotNo) {
UserOperationLogSaveReqVO operationLog = UserOperationLogSaveReqVO.builder()
.operateAction("继续做任务 " + robotNo)
.nickName(SecurityFrameworkUtils.getLoginUserNickname()).build();
userOperationLogService.createUserOperationLog(operationLog);
RobotTaskDetailActionLogDO actionLog = closeTask(robotNo);
if (ObjectUtil.isEmpty(actionLog) || ActionStatusEnum.DONE.getType().equals(actionLog.getActionStatus())) {
throw exception(ROBOT_LAST_TASK_NO_EXISTS);
}
String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + actionLog.getTaskDetailId();
Object o = redisUtil.get(key);
if (ObjectUtil.isEmpty(o)) {
throw exception(ROBOT_LAST_TASK_DELETE);
}
TaskToPathPlanningDTO pathPlanning = JSONUtil.toBean((String) o, TaskToPathPlanningDTO.class);
RLock lock = redissonUtils.getLock(RobotCacheLockEnum.ROBOT_TASK_DISTRIBUTE_LOCK.getKey());
String msg = "";
if (lock.tryLock()){
try {
resendToPP(pathPlanning,actionLog);
} catch (Exception e) {
log.error("下发任务给路径规划现异常 :{}",e);
msg = ObjectUtil.isNotEmpty(e.getMessage()) ? e.getMessage(): "任务下发失败";
} finally {
lock.unlock();
}
}else {
log.info("下发任务给路径规划未获取到锁");
throw exception(REDISSON_NOT_OBTAIN_LOCK);
}
if (ObjectUtil.isNotEmpty(msg)) {
throw exception0(TASK_CHECK_EXCEPTION.getCode(), msg);
}
}
/**
* 将任务重新发给PP
* @param pathPlanning
* @param actionLog
*/
private void resendToPP(TaskToPathPlanningDTO pathPlanning, RobotTaskDetailActionLogDO actionLog) {
RobotInformationDO robotInformationDO = informationMapper.selectOne(new LambdaQueryWrapper<RobotInformationDO>()
.eq(RobotInformationDO::getRobotNo, actionLog.getRobotNo()));
TaskRobotNoLimittationAreaDTO taskRobotNoLimittationAreaDTO =
robotPathPlanningService.getRobotNoLimitationArea(Collections.singletonList(robotInformationDO)).get(0);
List<TaskRobotNoLimittationAreaDTO> robotNoLimitions = Arrays.asList(taskRobotNoLimittationAreaDTO);
pathPlanning.setRobotNoLimitationAreaDTOS(robotNoLimitions);
if (PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(actionLog.getCommandType())
|| PathTaskTypeEnum.MOVE_TO_WAIT_STOP.getType().equals(actionLog.getCommandType())) {
moveToWaitTask(pathPlanning, actionLog.getRobotNo());
} else if (PathTaskTypeEnum.CHARGE.getType().equals(actionLog.getCommandType())
|| PathTaskTypeEnum.AUTO_CHARGE.getType().equals(actionLog.getCommandType())) {
chargeTask(pathPlanning,robotInformationDO);
} else if (PathTaskTypeEnum.TAKE_RELEASE.getType().equals(actionLog.getCommandType())) {
takeReleaseTask(pathPlanning);
} else if (PathTaskTypeEnum.TAKE.getType().equals(actionLog.getCommandType())) {
takeTask(pathPlanning);
}else if (PathTaskTypeEnum.RELEASE.getType().equals(actionLog.getCommandType())) {
releaseTask(pathPlanning);
}else if (PathTaskTypeEnum.MOVE.getType().equals(actionLog.getCommandType())) {
}
List<TaskToPathPlanningDTO> pathPlanningList = new ArrayList<>();
pathPlanningList.add(pathPlanning);
log.info("任务下发给PP :{}", JSON.toJSONString(pathPlanningList));
pathPlanningApi.synchronousLineObject(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST);
}
/**
* 仅放货
* @param pathPlanning
*/
private void releaseTask(TaskToPathPlanningDTO pathPlanning) {
RobotTaskDetailDO robotTaskDetail = checkTaskDone(pathPlanning.getOrderId());
releaseCheck(robotTaskDetail.getToLocationId(), robotTaskDetail.getRobotTaskId());
}
/**
* 仅取货
* @param pathPlanning
*/
private void takeTask(TaskToPathPlanningDTO pathPlanning) {
RobotTaskDetailDO robotTaskDetail = checkTaskDone(pathPlanning.getOrderId());
takeCheck(robotTaskDetail.getFromLocationId(),robotTaskDetail.getRobotTaskId());
}
public RobotTaskDetailDO checkTaskDone(String id){
RobotTaskDetailDO robotTaskDetail = taskDetailMapper.selectById(id);
if (RobotTaskStageEnum.DONE.getType().equals(robotTaskDetail.getTaskStage())) {
throw exception(ROBOT_LAST_TASK_NO_EXISTS);
}
return robotTaskDetail;
}
/**
* 取放货
* @param pathPlanning
*/
private void takeReleaseTask(TaskToPathPlanningDTO pathPlanning) {
RobotTaskDetailDO robotTaskDetail = checkTaskDone(pathPlanning.getOrderId());
if (!RobotTaskStageEnum.TAKEING.getType().equals(robotTaskDetail.getTaskStage())
&& !RobotTaskStageEnum.GO_TAKE.getType().equals(robotTaskDetail.getTaskStage())
&& !RobotTaskStageEnum.UN_START.getType().equals(robotTaskDetail.getTaskStage())) {
//只要放货
pathPlanning.setTakeLevel(null);
pathPlanning.setTakeGroupId(null);
pathPlanning.setTakeLocationNumber(null);
pathPlanning.setTakePointId(null);
pathPlanning.setTakeOffsetHeight(null);
pathPlanning.setTakeOffsetHeight(null);
pathPlanning.setTaskType(PathTaskTypeToRobotEnum.DROP_OFF_GOODS.getType());
}else {
takeCheck(robotTaskDetail.getFromLocationId(), robotTaskDetail.getRobotTaskId());
}
releaseCheck(robotTaskDetail.getToLocationId(),robotTaskDetail.getRobotTaskId());
}
/**
* 校验放货任务
*
* @param id
* @param takeId
*/
private void releaseCheck(Long id, Long takeId) {
WareHouseLocationDO wareHouseLocation = wareHouseLocationMapper.selectById(id);
if (ZeroOneEnum.ONE.getType().equals(wareHouseLocation.getLocationUseStatus())) {
throw exception(TASK_RELEASE_LOCATION_NOT_EMPTY);
}
if (!wareHouseLocation.getTaskId().equals(takeId)) {
throw exception(TASK_RELEASE_LOCATION_HAVE_OTHER_TASK);
}
List<WareHouseLocationDO> locations = wareHouseLocationMapper.selectList(new LambdaQueryWrapperX<WareHouseLocationDO>()
.eq(WareHouseLocationDO::getMapItemId, wareHouseLocation.getMapItemId())
.ne(WareHouseLocationDO::getId,id));
if (ObjectUtil.isEmpty(locations)) {
return;
}
List<WareHouseLocationDO> bigNumbers = locations.stream()
.filter(v -> v.getLocationNumber() > wareHouseLocation.getLocationNumber()
&& ZeroOneEnum.ZERO.getType().equals(v.getLocationUseStatus()))
.collect(Collectors.toList());
if (ObjectUtil.isNotEmpty(bigNumbers)) {
throw exception(TASK_RELEASE_LOCATION_LOWER_LEVELS_EMPTY);
}
}
/**
* 取货校验
*
* @param id
* @param takeId
*/
private void takeCheck(Long id, Long takeId) {
WareHouseLocationDO wareHouseLocation = wareHouseLocationMapper.selectById(id);
if (ZeroOneEnum.ZERO.getType().equals(wareHouseLocation.getLocationUseStatus())) {
throw exception(TASK_TAKE_LOCATION_EMPTY);
}
if (!wareHouseLocation.getTaskId().equals(takeId)) {
throw exception(TASK_TAKE_LOCATION_HAVE_OTHER_TASK);
}
List<WareHouseLocationDO> locations = wareHouseLocationMapper.selectList(new LambdaQueryWrapperX<WareHouseLocationDO>()
.eq(WareHouseLocationDO::getMapItemId, wareHouseLocation.getMapItemId())
.ne(WareHouseLocationDO::getId,id));
if (ObjectUtil.isEmpty(locations)) {
return;
}
List<WareHouseLocationDO> bigNumbers = locations.stream()
.filter(v -> v.getLocationNumber() < wareHouseLocation.getLocationNumber()
&& ZeroOneEnum.ONE.getType().equals(v.getLocationUseStatus()))
.collect(Collectors.toList());
if (ObjectUtil.isNotEmpty(bigNumbers)) {
throw exception(TASK_TAKE_LOCATION_UPPER_LEVELS_NOT_EMPTY);
}
}
/**
* 充电任务
* @param pathPlanning
* @param robot
*/
private void chargeTask(TaskToPathPlanningDTO pathPlanning, RobotInformationDO robot) {
List<DeviceInformationDO> deviceInformations = deviceInformationMapper.selectList(new LambdaQueryWrapperX<DeviceInformationDO>()
.eq(DeviceInformationDO::getDeviceEnable, ZeroOneEnum.ONE.getType())
.eq(DeviceInformationDO::getDeviceUseStatus, DeviceUseStatusEnum.IDLE.getType())
.eq(DeviceInformationDO::getDeviceType, DeviceTypeEnum.CHARGING_STATION.getType()));
if (ObjectUtil.isEmpty(deviceInformations)) {
log.info("没有空闲的充电桩 :{}",robot.getRobotNo());
throw exception(ROBOT_NOT_FOUND_FREE_CHARGING_STATION);
}
DeviceInformationDO deviceInformationDO = deviceInformations.stream()
.filter(v -> v.getDeviceAttribute().equals(robot.getChargeType())
&& robot.getFloorAreaJson().contains(v.getPositionMapId()))
.findFirst()
.orElse(new DeviceInformationDO());
if (ObjectUtil.isEmpty(deviceInformationDO.getDeviceNo())) {
log.info("当前机器人查不到对应的充电桩类型、或者机器人不能在此区域充电 :{}",robot.getRobotNo());
throw exception(ROBOT_NOT_FOUND_FREE_CHARGING_STATION);
}
pathPlanning.setReleaseGroupId("POINT_" + deviceInformationDO.getPositionMapItemId());
pathPlanning.setReleasePointId(deviceInformationDO.getPositionMapItemId());
}
/**
* 移动到等待点
*
* @param pathPlanning
*/
private void moveToWaitTask(TaskToPathPlanningDTO pathPlanning, String robotNo) {
List<PositionMapItemDO> positionMapItems = positionMapItemMapper.selectList(new LambdaQueryWrapperX<PositionMapItemDO>()
.eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType())
.eq(PositionMapItemDO::getUseStatus, ZeroOneEnum.ZERO.getType()));
if (ObjectUtil.isEmpty(positionMapItems)) {
log.info("------没有空闲的停车点----- :{}", robotNo);
throw exception(ROBOT_NOT_FOUND_WAIT_ITEM);
}
List<String> waitIds = positionMapItems
.stream()
.map(u -> u.getId() + "")
.collect(Collectors.toList());
pathPlanning.setWaitIds(waitIds);
}
/**
* 取放货清除交管
*
* @param robotTaskDetail
*/
private void takeReleaseCleanTrafficManagement(RobotTaskDetailDO robotTaskDetail) {
if (RobotTaskStageEnum.UN_START.getType().equals(robotTaskDetail.getTaskStage())
|| RobotTaskStageEnum.GO_TAKE.getType().equals(robotTaskDetail.getTaskStage())) {
log.info("清除交管--任务阶段是前往取货/待执行/前往放货 :{}", robotTaskDetail.getRobotNo());
robotTaskDetail.setTaskStatus(RobotTaskDetailStatusEnum.NEW.getType());
robotTaskDetail.setRobotNo(null);
taskDetailMapper.updateById(robotTaskDetail);
return;
}
RobotTaskDO robotTaskDO = taskMapper.selectById(robotTaskDetail.getRobotTaskId());
RobotTaskProceedSaveReqVO proceed = RobotTaskProceedSaveReqVO.builder()
.taskNo(robotTaskDO.getTaskNo())
.robotTaskId(robotTaskDO.getId())
.taskType(robotTaskDetail.getTaskType())
.taskStage(robotTaskDetail.getTaskStage())
.taskDetailId(robotTaskDetail.getId())
.robotNo(robotTaskDetail.getRobotNo())
.build();
taskProceedService.createTaskProceed(proceed);
}
/**
* 车机关闭任务
*
* @param id
* @param mac
* @param orderType
*/
public void robotCloseTaskDetail(String id, String mac, String orderType) {
RobotAcceptTaskDTO robotTask = new RobotAcceptTaskDTO();
robotTask.setOrderId(id);
robotTask.setOrderType(orderType);
robotTask.setTopic(RobotTopicConstant.ROBOT_TASK_MOVE_TOPIC + mac);
robotTask.setExecutionType(ExecutionTypeEnum.CANCEL.getType());
commonApi.commonMethod(robotTask, robotTask.getTopic());
}
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.robot;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotTaskDetailLogResoVO;
@ -60,6 +61,7 @@ public interface RobotTaskService extends IService<RobotTaskDO> {
/**
* 获取任务号
*
* @return
*/
String getTaskNo();
@ -72,13 +74,15 @@ public interface RobotTaskService extends IService<RobotTaskDO> {
/**
* 任务日志分页
*
* @param pageReqVO
* @return
*/
PageResult<RobotTaskDetailLogResoVO> logPage( RobotTaskDetailLogVO pageReqVO);
PageResult<RobotTaskDetailLogResoVO> logPage(RobotTaskDetailLogVO pageReqVO);
/**
* 添加循环任务点位
*
* @param id
* @param taskDetailList
*/
@ -88,14 +92,16 @@ public interface RobotTaskService extends IService<RobotTaskDO> {
/**
* PP分配任务
*
* @param message
*/
void assignTasks(String message);
/**
* 发送关闭任务
*
* @param id
* @param mac
*/
void closeTaskDetail(String id, String mac);
void closeTaskDetail(String id, String mac, String orderType);
}

View File

@ -50,6 +50,7 @@ import cn.iocoder.yudao.module.system.enums.robot.*;
import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeTaskStatusEnum;
import cn.iocoder.yudao.module.system.enums.robot.task.RobotCommandTypeEnum;
//import cn.iocoder.yudao.module.system.service.robot.job.RobotCommonTaskService;
import cn.iocoder.yudao.module.system.enums.robot.task.RobotTaskStageEnum;
import cn.iocoder.yudao.module.system.enums.wait.WaitStatusEnum;
import cn.iocoder.yudao.module.system.service.information.DeviceInformationService;
import cn.iocoder.yudao.module.system.service.log.UserOperationLogService;
@ -183,7 +184,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
addResult = addTask(createReqVO);
} catch (Exception e) {
log.error("下发任务出现异常 :{}", e);
addResult = e.getMessage();
addResult = ObjectUtil.isNotEmpty(e.getMessage()) ? e.getMessage(): "创建任务失败";
} finally {
lock.unlock();
}
@ -389,6 +390,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
}
//后期需做状态映射
taskDetailDO.setTaskStatus(updateReqVO.getTaskStatus());
taskDetailDO.setTaskStage(RobotTaskStageEnum.CLOSE.getType());
if (RobotTaskTypeEnum.CHARGE.getType().equals(taskDetailDO.getTaskType())
&& RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType())) {
@ -409,7 +411,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
String mac = robotInformationService.getMacByRobotNo(taskDetailDO.getRobotNo());
closeTaskDetail(taskDetailDO.getId().toString(),mac);
closeTaskDetail(taskDetailDO.getId().toString(), mac, PathTaskTypeEnum.getTaskType(taskDetailDO.getTaskType()));
RobotClosePathPlantingDTO closePathPlanting = RobotClosePathPlantingDTO.builder()
.robotNo(taskDetailDO.getRobotNo())
@ -456,9 +458,10 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
}
@Override
public void closeTaskDetail(String id, String mac) {
public void closeTaskDetail(String id, String mac, String orderType) {
RobotAcceptTaskDTO robotTask = new RobotAcceptTaskDTO();
robotTask.setOrderId(id);
robotTask.setOrderType(orderType);
robotTask.setTopic(RobotTopicConstant.ROBOT_TASK_MOVE_TOPIC + mac);
robotTask.setExecutionType(ExecutionTypeEnum.CANCEL.getType());
commonApi.commonMethod(robotTask, robotTask.getTopic());
@ -483,8 +486,10 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
Map<Long, String> deviceNoMap = new HashMap<>();
Integer robotStatus = RobotStatusEnum.DOING.getType();
if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(taskAssignDTO.getOrderType())) {
RobotChargeLogDO robotChargeLogs = chargeLogMapper.selectById(taskAssignDTO.getOrderId());
RobotChargeLogDO robotChargeLogs = null;
if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(taskAssignDTO.getOrderType())
|| PathTaskTypeEnum.CHARGE.getType().equals(taskAssignDTO.getOrderType())) {
robotChargeLogs = chargeLogMapper.selectById(taskAssignDTO.getOrderId());
robotChargeLogs.setTaskStatus(ChargeTaskStatusEnum.DOING.getType());
chargeLogMapper.updateById(robotChargeLogs);
@ -492,26 +497,26 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
robotStatus = RobotStatusEnum.CHARGE.getType();
if (ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId())) {
deviceNoMap.put(robotChargeLogs.getTaskDetailId(), robotChargeLogs.getDeviceNo());
detailId = robotChargeLogs.getTaskDetailId();
}
detailId = ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId()) ? robotChargeLogs.getTaskDetailId() : null;
} else if (PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(taskAssignDTO.getOrderType())) {
chargeDone(taskAssignDTO.getRobotNo());
moveToWaitService.updateWaitStatus(taskAssignDTO.getOrderId(), WaitStatusEnum.GO_TO_WAIT.getType());
} else if (PathTaskTypeEnum.CHARGE.getType().equals(taskAssignDTO.getOrderType())) {
robotStatus = RobotStatusEnum.CHARGE.getType();
detailId = taskAssignDTO.getOrderId();
moveToWaitService.updateWaitStatusAndItrmId(taskAssignDTO.getOrderId(), WaitStatusEnum.GO_TO_WAIT.getType(), taskAssignDTO.getWaitId());
} else {
chargeDone(taskAssignDTO.getRobotNo());
detailId = taskAssignDTO.getOrderId();
}
chargeDone(taskAssignDTO.getRobotNo());
robotInformationMapper.updateRobotListStatus(taskAssignDTO.getRobotNo(), robotStatus, taskAssignDTO.getOrderId());
if (ObjectUtil.isNotEmpty(detailId)) {
setTaskDoing(detailId, taskAssignDTO.getRobotNo(), deviceNoMap);
setTaskDoing(detailId, taskAssignDTO.getRobotNo(), deviceNoMap, taskAssignDTO.getWaitId());
}
if (ObjectUtil.isNotEmpty(robotChargeLogs)) {
setDeviceUseing(robotChargeLogs.getDeviceNo(), taskAssignDTO.getRobotNo());
}
RobotTaskDetailActionLogDO logOne = new RobotTaskDetailActionLogDO();
logOne.setCommandType(taskAssignDTO.getOrderType());
@ -525,6 +530,16 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
}
/**
* 更新设备使用中
*
* @param deviceNo
* @param robotNo
*/
private void setDeviceUseing(String deviceNo, String robotNo) {
deviceInformationMapper.updateDeviceUseStatus(deviceNo, DeviceUseStatusEnum.USEING.getType(), robotNo);
}
/**
* 发送任务给车机
*
@ -606,18 +621,24 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
build.setHeight(height);
}
public RobotTaskDetailDO setTaskDoing(Long detailId, String robotNo, Map<Long, String> deviceNoMap) {
public RobotTaskDetailDO setTaskDoing(Long detailId, String robotNo, Map<Long, String> deviceNoMap,
String waitId) {
RobotTaskDetailDO taskDetailDO = taskDetailMapper.selectById(detailId);
taskDetailDO.setTaskStatus(RobotTaskDetailStatusEnum.DOING.getType());
taskDetailDO.setStartTime(LocalDateTime.now());
if (ObjectUtil.isEmpty(taskDetailDO.getRobotNo())) {
taskDetailDO.setRobotNo(robotNo);
}
if (ObjectUtil.isEmpty(taskDetailDO.getToLocationNo())
if (RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType())
&& ObjectUtil.isNotEmpty(deviceNoMap.get(taskDetailDO.getId()))) {
taskDetailDO.setToLocationNo(deviceNoMap.get(taskDetailDO.getId()));
}
if (RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType())
&& ObjectUtil.isNotEmpty(waitId)) {
taskDetailDO.setToLocationId(Long.valueOf(waitId));
}
taskDetailMapper.updateById(taskDetailDO);
RobotTaskDO task = taskMapper.selectById(taskDetailDO.getRobotTaskId());
task.setTaskStatus(RobotTaskStatusEnum.DOING.getType());
@ -1323,6 +1344,7 @@ public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper, RobotTask
DeviceInformationDO deviceInformationDO = deviceInformationMapper.selectOne(new LambdaQueryWrapperX<DeviceInformationDO>()
.eq(DeviceInformationDO::getDeviceNo, robotChargeLogDO.getDeviceNo()));
deviceInformationDO.setDeviceUseStatus(DeviceUseStatusEnum.IDLE.getType());
deviceInformationDO.setLastUser(null);
deviceInformationMapper.updateById(deviceInformationDO);
log.info("充电桩设置为空闲 :{}", deviceInformationDO.getDeviceNo());

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.system.service.robot.pathplanning;
import cn.iocoder.yudao.module.mqtt.api.path.task.TaskRobotNoLimittationAreaDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotChargeLogDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO;
@ -14,4 +15,6 @@ public interface RobotPathPlanningService {
void sendChargeTaskToPP(List<RobotChargeLogDO> logs,
List<RobotTaskDetailDO> taskDetailDOS,
List<RobotInformationDO> robots);
List<TaskRobotNoLimittationAreaDTO> getRobotNoLimitationArea(List<RobotInformationDO> robots);
}

View File

@ -10,6 +10,7 @@ import cn.iocoder.yudao.module.mqtt.api.path.task.TaskRobotNoLimittationAreaDTO;
import cn.iocoder.yudao.module.mqtt.api.path.task.TaskToPathPlanningDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningChcheConstant;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.RobotPositionMapDTO;
@ -92,6 +93,9 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
@Value("${zn.robot_config.offset_height}")
private Double offsetHeight;
@Value("${zn.path_planning.task_chche_time:604800}")
private Long taskChcheTime;
@Resource
private MoveToWaitMapper moveToWaitMapper;
@ -136,6 +140,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
/**
* 处理停车不锁车的任务
*
* @param taskDetailDOS
* @return
*/
@ -144,9 +149,9 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
List<RobotTaskDetailDO> detailList = new ArrayList<>();
for (RobotTaskDetailDO v : taskDetailDOS) {
if (RobotTaskTypeEnum.PARK.getType().equals(v.getTaskType())
&& ZeroOneEnum.ZERO.getType().equals(v.getNeedLock())) {
&& ZeroOneEnum.ZERO.getType().equals(v.getNeedLock())) {
parkList.add(v);
}else if (!RobotTaskTypeEnum.CHARGE.getType().equals(v.getTaskType())){
} else if (!RobotTaskTypeEnum.CHARGE.getType().equals(v.getTaskType())) {
detailList.add(v);
}
}
@ -298,6 +303,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
.taskType(PathTaskTypeToRobotEnum.MOVE.getType())
.waitIds(waitIds)
.build();
String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId();
redisUtil.set(key, JSON.toJSONString(pathPlanning), taskChcheTime);
pathPlanningList.add(pathPlanning);
}
@ -354,6 +361,10 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
pathPlanning.setReleaseGroupId("POINT_" + v.getPositionMapItemId());
pathPlanning.setReleaseLocationNumber(releaseLocationNumberConfig);
pathPlanning.setReleasePointId(v.getPositionMapItemId());
String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId();
redisUtil.set(key, JSON.toJSONString(pathPlanning), taskChcheTime);
pathPlanningList.add(pathPlanning);
}
@ -418,10 +429,10 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
.build();
if (RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType())
&& (ObjectUtil.isEmpty(waitIds) || waitIds.size() < i)) {
log.info("停车任务,没有多余的空闲点位 {}",taskDetailDO.getId());
&& (ObjectUtil.isEmpty(waitIds) || waitIds.size() < i)) {
log.info("停车任务,没有多余的空闲点位 {}", taskDetailDO.getId());
return;
}else if (RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType())) {
} else if (RobotTaskTypeEnum.PARK.getType().equals(taskDetailDO.getTaskType())) {
pathPlanning.setWaitIds(waitIds);
i++;
}
@ -460,12 +471,12 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
pathPlanning.setTakeOffsetHeight(offsetHeight);
if (ObjectUtil.isNotEmpty(taskDetailDO.getFromLaneId())) {
pathPlanning.setTakeGroupId("LINE_" + taskDetailDO.getFromLaneId());
}else {
} else {
pathPlanning.setTakeGroupId("POINT_" + taskDetailDO.getFromMapItemId());
}
}
if (ObjectUtil.isNotEmpty(taskDetailDO.getToLocationId())){
if (ObjectUtil.isNotEmpty(taskDetailDO.getToLocationId())) {
pathPlanning.setReleaseLocationNumber(taskDetailDO.getToLocationNumber());
pathPlanning.setReleasePointId(toLocation.getMapItemId());
if (ObjectUtil.isNotEmpty(toLocation.getLocationTrayHeight())) {
@ -473,12 +484,16 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
}
pathPlanning.setReleaseLevel(toLocation.getLocationStorey());
pathPlanning.setReleaseOffsetHeight(offsetHeight);
if (ObjectUtil.isNotEmpty(taskDetailDO.getToLaneId())){
if (ObjectUtil.isNotEmpty(taskDetailDO.getToLaneId())) {
pathPlanning.setReleaseGroupId("LINE_" + taskDetailDO.getToLaneId());
}else {
} else {
pathPlanning.setReleaseGroupId("POINT_" + taskDetailDO.getToMapItemId());
}
}
String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId();
redisUtil.set(key, JSON.toJSONString(pathPlanning), taskChcheTime);
pathPlanningList.add(pathPlanning);
}
@ -544,7 +559,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
*
* @param robots
*/
private List<TaskRobotNoLimittationAreaDTO> getRobotNoLimitationArea(List<RobotInformationDO> robots) {
@Override
public List<TaskRobotNoLimittationAreaDTO> getRobotNoLimitationArea(List<RobotInformationDO> robots) {
List<PositionMapDO> positionMapDOS = positionMapMapper.selectList(new LambdaQueryWrapperX<PositionMapDO>());
List<TaskRobotNoLimittationAreaDTO> robotNoLimitationAreaDTOS = new ArrayList<>();
@ -664,7 +680,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService {
} else if (RobotTaskTypeEnum.TAKE.getType().equals(v.getTaskType())) {
//仅取货
takeSetTask(list, v, fromLane, toLane, fromLocation, toLocation, toHaveFrom, fromHaveTo);
}else if (RobotTaskTypeEnum.PARK.getType().equals(v.getTaskType())) {
} else if (RobotTaskTypeEnum.PARK.getType().equals(v.getTaskType())) {
list.add(v);
}
}

View File

@ -0,0 +1,54 @@
package cn.iocoder.yudao.module.system.service.robot.proceed;
import java.util.*;
import javax.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.controller.admin.robot.proceed.*;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskProceedDO;
/**
* 车辆衔接任务 Service 接口
*
* @author 陈宾顺
*/
public interface RobotTaskProceedService {
/**
* 创建车辆衔接任务
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createTaskProceed(@Valid RobotTaskProceedSaveReqVO createReqVO);
/**
* 更新车辆衔接任务
*
* @param updateReqVO 更新信息
*/
void updateTaskProceed(@Valid RobotTaskProceedSaveReqVO updateReqVO);
/**
* 删除车辆衔接任务
*
* @param id 编号
*/
void deleteTaskProceed(Long id);
/**
* 获得车辆衔接任务
*
* @param id 编号
* @return 车辆衔接任务
*/
RobotTaskProceedDO getTaskProceed(Long id);
/**
* 获得车辆衔接任务分页
*
* @param pageReqVO 分页查询
* @return 车辆衔接任务分页
*/
PageResult<RobotTaskProceedDO> getTaskProceedPage(RobotTaskProceedPageReqVO pageReqVO);
}

View File

@ -0,0 +1,71 @@
package cn.iocoder.yudao.module.system.service.robot.proceed;
import cn.iocoder.yudao.module.system.controller.admin.robot.proceed.*;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskProceedDO;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskProceedMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TASK_PROCEED_NOT_EXISTS;
/**
* 车辆衔接任务 Service 实现类
*
* @author 陈宾顺
*/
@Service
@Validated
public class RobotTaskProceedServiceImpl implements RobotTaskProceedService {
@Resource
private RobotTaskProceedMapper taskProceedMapper;
@Override
public Long createTaskProceed(RobotTaskProceedSaveReqVO createReqVO) {
// 插入
RobotTaskProceedDO taskProceed = BeanUtils.toBean(createReqVO, RobotTaskProceedDO.class);
taskProceedMapper.insert(taskProceed);
// 返回
return taskProceed.getId();
}
@Override
public void updateTaskProceed(RobotTaskProceedSaveReqVO updateReqVO) {
// 校验存在
validateTaskProceedExists(updateReqVO.getId());
// 更新
RobotTaskProceedDO updateObj = BeanUtils.toBean(updateReqVO, RobotTaskProceedDO.class);
taskProceedMapper.updateById(updateObj);
}
@Override
public void deleteTaskProceed(Long id) {
// 校验存在
validateTaskProceedExists(id);
// 删除
taskProceedMapper.deleteById(id);
}
private void validateTaskProceedExists(Long id) {
if (taskProceedMapper.selectById(id) == null) {
throw exception(TASK_PROCEED_NOT_EXISTS);
}
}
@Override
public RobotTaskProceedDO getTaskProceed(Long id) {
return taskProceedMapper.selectById(id);
}
@Override
public PageResult<RobotTaskProceedDO> getTaskProceedPage(RobotTaskProceedPageReqVO pageReqVO) {
return taskProceedMapper.selectPage(pageReqVO);
}
}

View File

@ -119,7 +119,7 @@ public class ToolsServiceImpl implements ToolsService {
RobotAcceptTaskDTO robotTask = new RobotAcceptTaskDTO();
robotTask.setOrderId(taskDetailId);
String mac = robotInformationService.getMacByRobotNo(informationDO.getRobotNo());
robotTask.setTopic(RobotTopicConstant.ROBOT_TASK_TOPIC + mac);
robotTask.setTopic(RobotTopicConstant.ROBOT_TASK_MOVE_TOPIC + mac);
robotTask.setExecutionType(ExecutionTypeEnum.CANCEL.getType());
commonApi.commonMethod(robotTask, robotTask.getTopic());

View File

@ -51,4 +51,6 @@ public interface MoveToWaitService {
PageResult<MoveToWaitDO> getMoveToWaitPage(MoveToWaitPageReqVO pageReqVO);
void updateWaitStatus(Long orderId, Integer status);
void updateWaitStatusAndItrmId(Long orderId, Integer type, String waitId);
}

View File

@ -79,4 +79,13 @@ public class MoveToWaitServiceImpl implements MoveToWaitService {
moveToWaitMapper.updateById(updateObj);
}
@Override
public void updateWaitStatusAndItrmId(Long orderId, Integer status, String waitId) {
MoveToWaitDO updateObj = new MoveToWaitDO();
updateObj.setId(orderId);
updateObj.setPositionMapItemId(Long.valueOf(waitId));
updateObj.setWaitStatus(status);
moveToWaitMapper.updateById(updateObj);
}
}

View File

@ -18,13 +18,13 @@ public class ModbusUtils {
/**
* 工厂
*/
static ModbusFactory modbusFactory;
/*static ModbusFactory modbusFactory;
static {
if (modbusFactory == null) {
modbusFactory = new ModbusFactory();
}
}
}*/
/**
* 获取master
@ -40,13 +40,14 @@ public class ModbusUtils {
// modbusFactory.createRtuMaster(wapper); //RTU 协议
// modbusFactory.createUdpMaster(params);//UDP 协议
// modbusFactory.createAsciiMaster(wrapper);//ASCII 协议
ModbusFactory modbusFactory = new ModbusFactory();
ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议
master.init();
return master;
}
public static ModbusMaster getRtuIpMaster(String host, int port) throws ModbusInitException {
public static ModbusMaster getRtuIpMaster(ModbusFactory modbusFactory, String host, int port) throws ModbusInitException {
IpParameters params = new IpParameters();
params.setHost(host);
params.setPort(port);
@ -75,7 +76,8 @@ public class ModbusUtils {
* @return
* @throws ModbusInitException
*/
public static ModbusMaster getSerialPortRtuMaster(String portName, Integer baudRate, Integer dataBits,
public static ModbusMaster getSerialPortRtuMaster(ModbusFactory modbusFactory,String portName, Integer baudRate,
Integer dataBits,
Integer stopBits, Integer parity){
// 设置串口参数串口是COM1波特率是9600
// SerialPortWrapperImpl wrapper = new SerialPortWrapperImpl("COM2", 9600,SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE, 0, 0);
@ -106,7 +108,7 @@ public class ModbusUtils {
* @throws ModbusInitException
*/
public static ModbusMaster getSerialPortAsciiMaster(String portName, Integer baudRate, Integer dataBits,
Integer stopBits, Integer parity){
Integer stopBits, Integer parity,ModbusFactory modbusFactory){
// 设置串口参数串口是COM1波特率是9600
// SerialPortWrapperImpl wrapper = new SerialPortWrapperImpl("COM2", 9600,SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE, 0, 0);
SerialPortWrapperImpl wrapper = new SerialPortWrapperImpl(portName, baudRate,

View File

@ -240,4 +240,5 @@ zn:
offset_height: 0.1 #叉起货需要在原来高度基础上偏移的高度
default_tray_height: 1.1 #默认每层高度
open_rate_limiter: true #是否开启限流
path_planning:
task_chche_time: 604800 #任务缓存的时间, 默认一星期

View File

@ -14,8 +14,18 @@
device_information
set
device_use_status = #{deviceUseStatus},
device_enable = #{deviceEnable}
last_user = #{lastUser}
where
device_no = #{deviceNo}
</update>
<update id="setDeviceReleaseByLastUser">
update
device_information
set
device_use_status = #{deviceUseStatus}
where
last_user = #{lastUser}
</update>
</mapper>

View File

@ -264,12 +264,13 @@
t1.task_status,
t1.task_stage,
t1.start_time,
t1.end_time
t1.end_time,
t1.create_time
from
robot_task t1 left join robot_task_detail t2
on t1.id = t2.robot_task_id
robot_task t1 left join robot_task_detail t2
on t1.id = t2.robot_task_id
<where>
t1.deleted = '0'
t1.deleted = '0'
and t2.deleted = '0'
<if test="pageReqVO.taskNo != null and pageReqVO.taskNo != ''">
and t1.task_no like concat('%', #{pageReqVO.taskNo}, '%')

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskProceedMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
</mapper>