diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java index 45b6bad7a..069402ff0 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.framework.common.util.date; import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.ObjectUtil; +import java.text.SimpleDateFormat; import java.time.*; import java.time.format.DateTimeFormatter; import java.util.Calendar; @@ -33,6 +35,21 @@ public class DateUtils { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd"); return currentDate.format(formatter); } + + public static String getYearMonthDayHourMinuteSecon() { + LocalDateTime currentDate = LocalDateTime.now(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND); + return currentDate.format(formatter); + } + + public static String getYYYMMDD(Date date) { + if (ObjectUtil.isEmpty(date)) { + date = new Date(); + } + SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd"); + return simpleDateFormat.format(date); + } + /** * 将 LocalDateTime 转换成 Date * diff --git a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java index 63ef69ebf..e4062bbc0 100644 --- a/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java +++ b/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java @@ -251,6 +251,7 @@ public class GlobalExceptionHandler { for (StackTraceElement stackTrace : stackTraces) { if (ObjUtil.notEqual(stackTrace.getClassName(), ServiceExceptionUtil.class.getName())) { log.warn("[serviceExceptionHandler]\n\t{}", stackTrace); + log.warn("异常信息 :{}",ex.getMessage()); break; } } diff --git a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/PathPlanningApi.java b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/PathPlanningApi.java index 8961ea493..2724353a0 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/PathPlanningApi.java +++ b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/PathPlanningApi.java @@ -17,7 +17,7 @@ import java.util.List; public interface PathPlanningApi { String PREFIX = ApiConstants.PREFIX + "/config"; - @PostMapping(PREFIX + "/synchronousPoint") + /* @PostMapping(PREFIX + "/synchronousPoint") @Operation(summary = "同步ware_position_map_line的点位信息") void synchronousPointToPP(@RequestBody PositionMapLinePathDTO relatedPathNode, @RequestParam("topic") String topic); @@ -28,5 +28,5 @@ public interface PathPlanningApi { @PostMapping(PREFIX + "/synchronousLineObject") @Operation(summary = "同步Object信息给PP") - void synchronousLineObject(@RequestBody Object obj, @RequestParam("topic") String topic); + void synchronousLineObject(@RequestBody Object obj, @RequestParam("topic") String topic);*/ } diff --git a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathToRobotArgDTO.java b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathToRobotArgDTO.java new file mode 100644 index 000000000..21f27c839 --- /dev/null +++ b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathToRobotArgDTO.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.mqtt.api.path.dto; + +import lombok.Data; + +@Data +public class PathToRobotArgDTO { + private Long floor; + private String areaId; + private String mapName; + private String poseId; + private PathToRobotArgPoseDTO pose2d; + +} diff --git a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathToRobotArgPoseDTO.java b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathToRobotArgPoseDTO.java new file mode 100644 index 000000000..55de6598c --- /dev/null +++ b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathToRobotArgPoseDTO.java @@ -0,0 +1,12 @@ +package cn.iocoder.yudao.module.mqtt.api.path.dto; + +import lombok.Data; + +@Data +public class PathToRobotArgPoseDTO { + private Double x; + + private Double y; + + private Double yaw; +} diff --git a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathToRobotDTO.java b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathToRobotDTO.java new file mode 100644 index 000000000..fcd675e58 --- /dev/null +++ b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PathToRobotDTO.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.mqtt.api.path.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PathToRobotDTO { + + //这个实体类的信息,不能修改 + //这个实体类的信息,不能修改 + //这个实体类的信息,不能修改 + //这个实体类的信息,不能修改 + //这个实体类的信息,不能修改 + //这个实体类的信息,不能修改 + private String orderType; + private Integer isCommandEnd; + private String robotNo; + private String commandType; + private PathToRobotArgDTO arg; +} diff --git a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PositionMapItemSynDTO.java b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PositionMapItemSynDTO.java index 3d4a9decb..48f5af244 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PositionMapItemSynDTO.java +++ b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/path/dto/PositionMapItemSynDTO.java @@ -15,7 +15,7 @@ import java.util.List; public class PositionMapItemSynDTO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "31007") - private Long id; + private String id; @Schema(description = "坐标x轴") private Double x; diff --git a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/task/RobotTaskApi.java b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/task/RobotTaskApi.java index f926fbb56..79dbc8130 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/task/RobotTaskApi.java +++ b/yudao-module-mqtt/yudao-module-mqtt-api/src/main/java/cn/iocoder/yudao/module/mqtt/api/task/RobotTaskApi.java @@ -18,7 +18,7 @@ public interface RobotTaskApi { String PREFIX = ApiConstants.PREFIX + "/config"; - @PostMapping(PREFIX + "/distribute/tasks") + /*@PostMapping(PREFIX + "/distribute/tasks") @Operation(summary = "下发任务给车机") - void sendTaskToRobot(@Valid @RequestBody List robotTaskDOS ); + void sendTaskToRobot(@Valid @RequestBody List robotTaskDOS );*/ } diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/common/CommonApiImpl.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/common/CommonApiImpl.java index 0a2e3902d..4ce25ce8b 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/common/CommonApiImpl.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/common/CommonApiImpl.java @@ -1,6 +1,7 @@ package cn.iododer.yudao.module.mqtt.api.common; import cn.iocoder.yudao.module.mqtt.api.common.CommonApi; +import cn.iododer.yudao.module.mqtt.config.MqttFactory; import cn.iododer.yudao.module.mqtt.util.MqttUtils; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/path/PathPlanningApiImpl.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/path/PathPlanningApiImpl.java index 2d647ee96..965fbd35b 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/path/PathPlanningApiImpl.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/path/PathPlanningApiImpl.java @@ -26,7 +26,7 @@ public class PathPlanningApiImpl implements PathPlanningApi { * @param relatedPathNode * @param topic */ - @Override + /*@Override public void synchronousPointToPP(PositionMapLinePathDTO relatedPathNode, String topic) { try { mqttUtils.pub(topic, JSON.toJSONString(relatedPathNode)); @@ -36,11 +36,11 @@ public class PathPlanningApiImpl implements PathPlanningApi { } } - /** + *//** * 同步ware_position_map_item的点位信息 * @param positionMapItemSynDTOS * @param topic - */ + *//* @Override public void synchronousAllItemToPP(List positionMapItemSynDTOS, String topic) { try { @@ -59,5 +59,5 @@ public class PathPlanningApiImpl implements PathPlanningApi { } catch (MqttException e) { log.info("同步信息给PP--完成--异常 :{}",e); } - } + }*/ } diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/task/RobotTaskApiImpl.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/task/RobotTaskApiImpl.java index 2dc1862c4..09e516815 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/task/RobotTaskApiImpl.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/api/task/RobotTaskApiImpl.java @@ -23,7 +23,7 @@ public class RobotTaskApiImpl implements RobotTaskApi { @Autowired private MqttUtils mqttUtils; - @Override + /*@Override public void sendTaskToRobot(List robotTaskDOS) { for (RobotAcceptTaskDTO robotTaskDO : robotTaskDOS) { log.info("发送MQTT消息 :{}",JSON.toJSONString(robotTaskDO)); @@ -33,5 +33,5 @@ public class RobotTaskApiImpl implements RobotTaskApi { log.info("消息发送异常 :{}",e.getMessage()); } } - } + }*/ } diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttCallBack.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttCallBack.java index 46406e7b3..4fe8dcb99 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttCallBack.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttCallBack.java @@ -1,15 +1,15 @@ package cn.iododer.yudao.module.mqtt.config; import cn.iododer.yudao.module.mqtt.service.MqttService; -import cn.iododer.yudao.module.mqtt.service.RobotTaskStatusServiceImpl; import lombok.extern.slf4j.Slf4j; import org.eclipse.paho.client.mqttv3.IMqttAsyncClient; import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken; import org.eclipse.paho.client.mqttv3.MqttCallback; import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; +import java.nio.charset.StandardCharsets; + /** * MQTT回调 */ @@ -35,7 +35,7 @@ public class MqttCallBack implements MqttCallback { */ @Override public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception { - String msg = new String(mqttMessage.getPayload()); + String msg = new String(mqttMessage.getPayload(), StandardCharsets.UTF_8); // log.info("[MQTT]接收当前消息为 :{}", msg); try { diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttFactory.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttFactory.java index 789ede9fb..9c1e14f3c 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttFactory.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/config/MqttFactory.java @@ -147,6 +147,8 @@ public class MqttFactory { return BeanUtils.getBean(RobotUpdatePalletHeightServiceImpl.class); case ROBOT_OBSTACLES_STATUS: return BeanUtils.getBean(RobotObstaclesStatusServiceImpl.class); + case ROBOT_WIRELESS_SIGNAL_STATUS: + return BeanUtils.getBean(RobotWirelessSignalStatusServiceImpl.class); case PLANNING_INIT_DATA: return BeanUtils.getBean(PathPlanningInitDataServiceImpl.class); case PLANNING_DISTRIBUTION_TASK: diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/enums/DefineSubTopicEnum.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/enums/DefineSubTopicEnum.java index daaf5a186..5e5d8ac7b 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/enums/DefineSubTopicEnum.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/enums/DefineSubTopicEnum.java @@ -22,6 +22,7 @@ public enum DefineSubTopicEnum { ROBOT_WORK_STATUS("ROBOT_WORK_STATUS", 2,"作业实时行为上报"), ROBOT_UPDATE_PALLET_HEIGHT("UPDATE_PALLET_HEIGHT", 2,"放货后货物高度反馈和取货后货物高度反馈"), ROBOT_OBSTACLES_STATUS("ROBOT_OBSTACLES_STATUS", 2,"障碍物状态上报"), + ROBOT_WIRELESS_SIGNAL_STATUS("ROBOT_WIRELESS_SIGNAL_STATUS", 2,"信号强度上报"), PLANNING_INIT_DATA("SYNCHRONOUS_ALL_MAP_REQUEST", 2,"路径规划需要初始数据上报"), PLANNING_DISTRIBUTION_TASK("TASK_ASSIGNMENT_FEEDBACK", 2,"路径规划任务分配上报"), PLANNING_DISTRIBUTION_FAIL("TASK_ASSIGNMENT_FAIL", 2,"路径规划失败上报"), diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/RobotStatusServiceImpl.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/RobotStatusServiceImpl.java index bcb25c607..2eb8a125b 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/RobotStatusServiceImpl.java +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/RobotStatusServiceImpl.java @@ -22,7 +22,7 @@ public class RobotStatusServiceImpl implements MqttService { */ @Override public void analysisMessage(String message) { - log.info("处理RobotStatusServiceImpl的消息 :{}", message); +// log.info("处理RobotStatusServiceImpl的消息 :{}", message); RobotPoseStatusDTO robotStatusData = JSON.parseObject(message, RobotPoseStatusDTO.class); robotStatusApi.robotStatusUpdate(robotStatusData); } diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/RobotWirelessSignalStatusServiceImpl.java b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/RobotWirelessSignalStatusServiceImpl.java new file mode 100644 index 000000000..5d7e4a70a --- /dev/null +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/java/cn/iododer/yudao/module/mqtt/service/RobotWirelessSignalStatusServiceImpl.java @@ -0,0 +1,22 @@ +package cn.iododer.yudao.module.mqtt.service; + + +import cn.iocoder.yudao.module.remote.api.path.RemotePathApi; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@Slf4j +@Service +public class RobotWirelessSignalStatusServiceImpl implements MqttService{ + + @Resource + private RemotePathApi remotePathApi; + + @Override + public void analysisMessage(String message) { + log.info("车辆信号上报 :{}",message); + remotePathApi.wirelessSignalStatus(message); + } +} diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/application-dev.yaml b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/application-dev.yaml index b72803406..8ba2b5460 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/application-dev.yaml +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/application-dev.yaml @@ -12,6 +12,8 @@ spring: config: # 【注册中心】配置项 namespace: dev # 命名空间。这里使用 dev 开发环境 group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + mqtt: + charset: UTF-8 # Lock4j 配置项 lock4j: diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/application-local.yaml b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/application-local.yaml index 0686a4ca6..2d0c482cd 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/application-local.yaml +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/application-local.yaml @@ -12,6 +12,8 @@ spring: config: # 【注册中心】配置项 namespace: dev # 命名空间。这里使用 dev 开发环境 group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + mqtt: + charset: UTF-8 # Lock4j 配置项 lock4j: @@ -33,6 +35,7 @@ management: mqtt: # host: tcp://123.57.12.40:1883 host: tcp://127.0.0.1:1883 +# host: tcp://10.10.7.195:1883 username: adminuser password: adminuser qos: 2 diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/application-test.yaml b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/application-test.yaml index 3e04ea507..81cfa37a8 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/application-test.yaml +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/application-test.yaml @@ -12,6 +12,8 @@ spring: config: # 【注册中心】配置项 namespace: dev # 命名空间。这里使用 dev 开发环境 group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP + mqtt: + charset: UTF-8 # Lock4j 配置项 lock4j: @@ -31,7 +33,7 @@ management: # MQTT mqtt: -# host: tcp://192.168.0.54:1883 +# host: tcp://123.57.12.40:1883 host: tcp://127.0.0.1:1883 username: adminuser password: adminuser diff --git a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/logback-spring.xml b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/logback-spring.xml index b1b9f3faf..7ba7f8595 100644 --- a/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/logback-spring.xml +++ b/yudao-module-mqtt/yudao-module-mqtt-biz/src/main/resources/logback-spring.xml @@ -31,7 +31,7 @@ ${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false} - ${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB} + 50MB ${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0} diff --git a/yudao-module-remote/yudao-module-remote-api/src/main/java/cn/iocoder/yudao/module/remote/api/path/RemotePathApi.java b/yudao-module-remote/yudao-module-remote-api/src/main/java/cn/iocoder/yudao/module/remote/api/path/RemotePathApi.java index 17d6b7fa3..3fdfde4b2 100644 --- a/yudao-module-remote/yudao-module-remote-api/src/main/java/cn/iocoder/yudao/module/remote/api/path/RemotePathApi.java +++ b/yudao-module-remote/yudao-module-remote-api/src/main/java/cn/iocoder/yudao/module/remote/api/path/RemotePathApi.java @@ -16,4 +16,7 @@ public interface RemotePathApi { @Operation(summary = "远遥同步车辆导航行走路程信息") void remoteDistanceInformation(@RequestParam("message") String message); + @PostMapping(PREFIX + "/wirelessSignalStatus") + @Operation(summary = "车辆信号信息") + void wirelessSignalStatus(@RequestParam("message") String message); } diff --git a/yudao-module-remote/yudao-module-remote-api/src/main/java/cn/iocoder/yudao/module/remote/api/path/dto/RemoteRobotWirelessSignalDTO.java b/yudao-module-remote/yudao-module-remote-api/src/main/java/cn/iocoder/yudao/module/remote/api/path/dto/RemoteRobotWirelessSignalDTO.java new file mode 100644 index 000000000..383e4ace1 --- /dev/null +++ b/yudao-module-remote/yudao-module-remote-api/src/main/java/cn/iocoder/yudao/module/remote/api/path/dto/RemoteRobotWirelessSignalDTO.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.remote.api.path.dto; + +import lombok.Data; + +@Data +public class RemoteRobotWirelessSignalDTO { + + private String mac; + + /** + * 整型,单位dBm + */ + private String wirelessSignal; + +} diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/api/path/RemotePathApiImpl.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/api/path/RemotePathApiImpl.java index 2b6e2873c..8a8922d22 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/api/path/RemotePathApiImpl.java +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/api/path/RemotePathApiImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.remote.api.path; import cn.iocoder.yudao.module.remote.api.path.dto.RemoteRobotDistanceInformationDTO; +import cn.iocoder.yudao.module.remote.api.path.dto.RemoteRobotWirelessSignalDTO; import cn.iocoder.yudao.module.remote.service.robot.RemoteRobotService; import cn.iocoder.yudao.module.remote.util.redis.RedisUtil; import com.alibaba.fastjson.JSON; @@ -31,5 +32,15 @@ public class RemotePathApiImpl implements RemotePathApi{ remoteRobotService.remoteDistanceInformation(data); } + /** + * 车辆信号信息 + * @param message + */ + @Override + public void wirelessSignalStatus(String message) { + RemoteRobotWirelessSignalDTO data = JSON.parseObject(message, RemoteRobotWirelessSignalDTO.class); + remoteRobotService.sendRobotWirelessSignalStatus(data); + } + } diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/api/robot/RemoteControllerProcessor.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/api/robot/RemoteControllerProcessor.java index a61dfd0aa..a4de8237c 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/api/robot/RemoteControllerProcessor.java +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/api/robot/RemoteControllerProcessor.java @@ -1,13 +1,14 @@ package cn.iocoder.yudao.module.remote.api.robot; import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.module.remote.config.ip.IpProperties; +import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.Cockpit; import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.RemoteControllerSocketDTO; import cn.iocoder.yudao.module.remote.enums.robot.RemoteIpTypeEnum; import cn.iocoder.yudao.module.remote.util.crc.CRCUtil; import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotTransferDTO; -import com.alibaba.fastjson.JSON; -import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -28,18 +29,13 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.REMOTE_ROB @Component @Slf4j public class RemoteControllerProcessor { - private final ConcurrentHashMap cache = new ConcurrentHashMap<>(); + public final ConcurrentHashMap cache = new ConcurrentHashMap<>(); - private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + public final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); @Value("${remote.msg}") private String defaultMsg; - @Value("${remote.controller-ip}") - private String remoteControllerIp; - - @Value("${remote.controller-port}") - private int remoteControllerPort; @Value("${remote.cockpit-time-out}") private int cockpitTimeOut; @@ -53,35 +49,43 @@ public class RemoteControllerProcessor { private final String ONE = "01"; private final String TWO = "02"; - public void addCache(RemoteRobotTransferDTO dto) { - RemoteControllerSocketDTO remoteControllerSocketDTO = cache.get(remoteControllerIp); - log.info("缓存的数据 :{}", JSON.toJSONString(remoteControllerSocketDTO)); + @Autowired + private IpProperties ipProperties; + + public void addCache(RemoteRobotTransferDTO dto,String ip) { + Cockpit cockpit = ipProperties.getCockpitByIp(ip); + String cockpitIp = cockpit.getControllerIp(); + int cockpitPort = cockpit.getControllerPort(); + + RemoteControllerSocketDTO remoteControllerSocketDTO = cache.get(cockpitIp); + log.info("是否为空 :{}",ObjectUtil.isEmpty(remoteControllerSocketDTO)); if (ObjectUtil.isNotEmpty(remoteControllerSocketDTO)) { try { Socket socket = remoteControllerSocketDTO.getSocket(); if (socket != null && !socket.isClosed()) { socket.close(); } - log.info("关闭socket :{}", remoteControllerIp); + log.info("关闭socket :{}", cockpitIp); } catch (IOException e) { - log.error("关闭socket出现异常 :{}", remoteControllerIp); + log.error("关闭socket出现异常 :{}", cockpitIp); throw new RuntimeException(e); } } else { remoteControllerSocketDTO = new RemoteControllerSocketDTO(); } - remoteControllerSocketDTO.setHost(remoteControllerIp); - remoteControllerSocketDTO.setPort(remoteControllerPort); + remoteControllerSocketDTO.setControllerIp(cockpitIp); + remoteControllerSocketDTO.setControllerPort(cockpitPort); Socket socket = new Socket(); try { - socket.connect(new InetSocketAddress(remoteControllerIp, remoteControllerPort), 1000); + socket.setKeepAlive(true); + socket.connect(new InetSocketAddress(cockpitIp, cockpitPort), 500); remoteControllerSocketDTO.setSocket(socket); } catch (IOException e) { log.error("添加socket失败 :{}", e); throw exception(REMOTE_ROBOT_CONNECT_FAIL); } setMsg(remoteControllerSocketDTO, RemoteIpTypeEnum.ONE.getType(), dto); - cache.put(remoteControllerIp, remoteControllerSocketDTO); + cache.put(cockpitIp, remoteControllerSocketDTO); } /** @@ -108,7 +112,7 @@ public class RemoteControllerProcessor { String portHex = Integer.toHexString(dto.getRobotPort().intValue()); String portHexOne = portHex.substring(0, 2); String portHexTwo = portHex.substring(2); - msg = msg + " " + portHexOne + " " + portHexTwo; + msg = msg + " " + portHexTwo + " " + portHexOne; if (cockpitTimeOut > 0) { msg = msg + " " + ONE + " " + Integer.toHexString(cockpitTimeOut); } else { @@ -136,34 +140,38 @@ public class RemoteControllerProcessor { remoteControllerSocket.setMsg(msg); } - public void remoteCache(RemoteRobotTransferDTO dto) { - RemoteControllerSocketDTO remoteControllerSocketDTO = cache.get(remoteControllerIp); + public void remoteCache(RemoteRobotTransferDTO dto,String ip) { + Cockpit cockpit = ipProperties.getCockpitByIp(ip); + String cockpitIp = cockpit.getControllerIp(); + RemoteControllerSocketDTO remoteControllerSocketDTO = cache.get(cockpitIp); if (ObjectUtil.isEmpty(remoteControllerSocketDTO)) { return; } setMsg(remoteControllerSocketDTO, RemoteIpTypeEnum.THREE.getType(), dto); - cache.remove(remoteControllerIp); + cache.remove(cockpitIp); Socket socket = remoteControllerSocketDTO.getSocket(); - if (socket == null ||socket.isClosed()) { + if (socket == null || socket.isClosed()) { try { socket = new Socket(); - socket.connect(new InetSocketAddress(remoteControllerIp, remoteControllerPort), 1000); + log.info("连接新的的socket"); + socket.setKeepAlive(true); + socket.connect(new InetSocketAddress(cockpitIp, cockpit.getControllerPort()), 1000); } catch (IOException e) { - log.error("连接socket出现异常 :{}", remoteControllerIp); + log.error("连接socket出现异常 :{}", cockpitIp); } } OutputStream os = null; try { os = socket.getOutputStream(); - log.info("断开连接 :{} ,对应的IP :{}", remoteControllerSocketDTO.getMsg(), remoteControllerSocketDTO.getHost()); + log.info("断开连接 :{} ,对应的IP :{}", remoteControllerSocketDTO.getMsg(), remoteControllerSocketDTO.getControllerIp()); os.write(remoteControllerSocketDTO.getMsg().getBytes()); socket.shutdownInput(); socket.close(); - log.info("关闭socket :{}", remoteControllerIp); + log.info("关闭socket :{}", cockpitIp); } catch (IOException e) { - log.error("关闭socket出现异常 :{}", remoteControllerIp); + log.error("关闭socket出现异常 :{}", cockpitIp); } finally { if (ObjectUtil.isNotEmpty(os)) { try { @@ -173,41 +181,28 @@ public class RemoteControllerProcessor { } } - remoteCache(dto); + remoteCache(dto,ip); } - public RemoteControllerProcessor() { + /*public RemoteControllerProcessor() { // 每秒执行一次 - 处理并发送数据 - 避免数据丢失 scheduler.scheduleAtFixedRate(this::processAndSend, 150, 150, TimeUnit.MILLISECONDS); - } + }*/ - private void processAndSend() { + public void processAndSend() { if (ObjectUtil.isEmpty(cache)) { return; } - log.info("socket发送数据开始"); +// log.info("socket发送数据开始"); for (Map.Entry v : cache.entrySet()) { RemoteControllerSocketDTO remoteControllerSocketDTO = v.getValue(); - if (ObjectUtil.isEmpty(remoteControllerSocketDTO)) { - remoteControllerSocketDTO = new RemoteControllerSocketDTO(); - remoteControllerSocketDTO.setHost(v.getKey()); - remoteControllerSocketDTO.setPort(remoteControllerPort); - try { - Socket socket = new Socket(); - socket.connect(new InetSocketAddress(v.getKey(), remoteControllerPort), 1000); - remoteControllerSocketDTO.setSocket(socket); - } catch (IOException e) { - throw new RuntimeException(e); - } - cache.put(v.getKey(), remoteControllerSocketDTO); - } Socket socket = remoteControllerSocketDTO.getSocket(); if (socket == null || socket.isClosed()) { socket = new Socket(); try { - socket.connect(new InetSocketAddress(v.getKey(), remoteControllerPort), 1000); + socket.connect(new InetSocketAddress(v.getKey(), remoteControllerSocketDTO.getControllerPort()), 1000); remoteControllerSocketDTO.setSocket(socket); } catch (IOException e) { log.error("socket重连异常 :{}", e); @@ -218,8 +213,8 @@ public class RemoteControllerProcessor { try { os = socket.getOutputStream(); String str = remoteControllerSocketDTO.getMsg(); - log.info("socket推送的数据 :{}", str); os.write(remoteControllerSocketDTO.getMsg().getBytes()); + log.info("socket推送的数据 :{}", str); } catch (IOException e) { log.error("socket发送异常 :{}", e); } finally { @@ -230,7 +225,6 @@ public class RemoteControllerProcessor { } } } - log.info("socket发送数据成功"); } } diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/api/robot/RemoteScheduledTasks.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/api/robot/RemoteScheduledTasks.java new file mode 100644 index 000000000..6e1d13280 --- /dev/null +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/api/robot/RemoteScheduledTasks.java @@ -0,0 +1,36 @@ +package cn.iocoder.yudao.module.remote.api.robot; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +@EnableScheduling +@Component +@Slf4j +public class RemoteScheduledTasks { + + private static final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); + + @Resource + private RemoteControllerProcessor remoteControllerProcessor; + + // 这个方法将每200毫秒执行一次 + @Scheduled(fixedDelay = 300, timeUnit = TimeUnit.MILLISECONDS) + public void executeTask() { + fixedThreadPool.execute(new Runnable() { + @Override + public void run() { + remoteControllerProcessor.processAndSend(); + } + }); + } + + + +} diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/config/ip/IpProperties.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/config/ip/IpProperties.java new file mode 100644 index 000000000..d99b51635 --- /dev/null +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/config/ip/IpProperties.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.remote.config.ip; + + +import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.Cockpit; +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@ConfigurationProperties(prefix ="remote",ignoreInvalidFields = true) +@Getter +@Setter +public class IpProperties { + + private List cockpit; + + public Cockpit getCockpitByIp(String ip) { + for (Cockpit v : cockpit) { + if (ip.equals(v.getIpcIp())){ + return v; + } + } + Cockpit data = new Cockpit(); + data.setControllerIp("127.0.0.1"); + data.setControllerPort(9000); + return data; + } +} diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/constant/robot/RobotTaskChcheConstant.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/constant/robot/RobotTaskChcheConstant.java index d5c13baf7..36f58c44b 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/constant/robot/RobotTaskChcheConstant.java +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/constant/robot/RobotTaskChcheConstant.java @@ -8,4 +8,6 @@ public class RobotTaskChcheConstant { //机器人编号和mac地址映射(通过机器人编号。查询mac地址) (拼接的是机器人编号) public static String ROBOT_GET_MAC_BY_NO = "robot:information:getMac:ByNo"; + //机器人mac地址和机器人编号映射(通过mac地址。查询机器人编号) (拼接的是mac地址) + public static String ROBOT_GET_ROBOTNO_BY_MAC = "robot:information:getRobotNo:ByMac"; } diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/Cockpit.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/Cockpit.java new file mode 100644 index 000000000..0c5bc2924 --- /dev/null +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/Cockpit.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.remote.controller.admin.robot.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class Cockpit { + @Schema(description = "工控机IP") + private String ipcIp; + @Schema(description = "驾舱端口") + private int controllerPort; + @Schema(description = "驾舱IP") + private String controllerIp; +} diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/RemoteControllerSocketDTO.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/RemoteControllerSocketDTO.java index 55ab45522..2bc4c1968 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/RemoteControllerSocketDTO.java +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/RemoteControllerSocketDTO.java @@ -1,13 +1,16 @@ package cn.iocoder.yudao.module.remote.controller.admin.robot.dto; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import java.net.Socket; @Data public class RemoteControllerSocketDTO { - private String host; - private int port; + @Schema(description = "驾舱IP") + private String controllerIp; + @Schema(description = "驾舱端口") + private int controllerPort; private Socket socket; private String msg; } diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/RemoteRobotChangeModeDTO.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/RemoteRobotChangeModeDTO.java index fd3cd0ee9..187682cdd 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/RemoteRobotChangeModeDTO.java +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/controller/admin/robot/dto/RemoteRobotChangeModeDTO.java @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.remote.controller.admin.robot.dto; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @@ -10,6 +12,8 @@ import javax.validation.constraints.NotNull; public class RemoteRobotChangeModeDTO { @Schema(description = "远遥模式(0:自动模式, 1:手动模式, 2:自由模式)") @NotNull(message = "请选择远遥模式") + @Max(value = 2,message = "请选择远遥模式") + @Min(value = 0,message = "请选择远遥模式") private Integer remoteMode = 0; @Schema(description = "车辆编号") diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/login/LoginServiceImpl.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/login/LoginServiceImpl.java index b3d148436..4e62fb171 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/login/LoginServiceImpl.java +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/login/LoginServiceImpl.java @@ -37,7 +37,7 @@ public class LoginServiceImpl implements LoginService { @Override public Boolean checkCommunication(LoginCheckDTO loginCheckDTO) { HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); - factory.setConnectTimeout(5 * 1000); + factory.setConnectTimeout(2 * 1000); RestTemplate restTemplate = new RestTemplate(factory); String url = "http://" + loginCheckDTO.getSystemIp() + ":" + loginCheckDTO.getSystemPort() + checkUrl; LinkedMultiValueMap headers = new LinkedMultiValueMap<>(); diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotService.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotService.java index 2505eca72..68dec3952 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotService.java +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotService.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.remote.service.robot; import cn.iocoder.yudao.module.remote.api.path.dto.RemoteRobotDistanceInformationDTO; +import cn.iocoder.yudao.module.remote.api.path.dto.RemoteRobotWirelessSignalDTO; import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.PositionMapRespDTO; import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.RemoteRobotChangeModeDTO; import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.RemoteRobotTaskDoneDTO; @@ -76,4 +77,10 @@ public interface RemoteRobotService { * @param data */ void remoteDistanceInformation(RemoteRobotDistanceInformationDTO data); + + /** + * 上报车辆信号信息 + * @param data + */ + void sendRobotWirelessSignalStatus(RemoteRobotWirelessSignalDTO data); } diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotServiceImpl.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotServiceImpl.java index 395e60b67..e96a312cd 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotServiceImpl.java +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/robot/RemoteRobotServiceImpl.java @@ -5,9 +5,12 @@ import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.module.remote.api.path.dto.RemoteRobotDistanceInformationDTO; +import cn.iocoder.yudao.module.remote.api.path.dto.RemoteRobotWirelessSignalDTO; import cn.iocoder.yudao.module.remote.api.robot.RemoteControllerProcessor; import cn.iocoder.yudao.module.remote.api.webSocket.RequestProcessor; +import cn.iocoder.yudao.module.remote.config.ip.IpProperties; import cn.iocoder.yudao.module.remote.constant.robot.RobotTaskChcheConstant; +import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.Cockpit; import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.PositionMapRespDTO; import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.RemoteRobotChangeModeDTO; import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.RemoteRobotTaskDoneDTO; @@ -22,6 +25,7 @@ import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotTransferDTO; import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -42,17 +46,11 @@ public class RemoteRobotServiceImpl implements RemoteRobotService { @Resource private RedisUtil redisUtil; - @Resource - private RequestProcessor processor; - @Resource private RemoteControllerProcessor remoteControllerProcessor; - @Value("${remote.controller-port}") - private int remoteControllerPort; - - @Value("${remote.controller-ip}") - private String remoteControllerIp; + @Autowired + private IpProperties ipProperties; /** * 获取地图区域对应的机器人信息 @@ -127,15 +125,16 @@ public class RemoteRobotServiceImpl implements RemoteRobotService { @Override public void robotChangeMode(RemoteRobotChangeModeDTO data, HttpServletRequest request) { String ip = IpUtils.getIp(request); - CommonResult result = remoteRobotApi.robotChangeMode(data.getRemoteMode(), ip, data.getRobotNo(),remoteControllerPort,remoteControllerIp); + Cockpit cockpit = ipProperties.getCockpitByIp(ip); + CommonResult result = remoteRobotApi.robotChangeMode(data.getRemoteMode(), ip, data.getRobotNo(),cockpit.getControllerPort(),cockpit.getControllerIp()); if (!result.isSuccess()) { throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg()); } //非自动模式 if (0!= data.getRemoteMode()) { - remoteControllerProcessor.addCache(result.getData()); + remoteControllerProcessor.addCache(result.getData(),ip); }else { - remoteControllerProcessor.remoteCache(result.getData()); + remoteControllerProcessor.remoteCache(result.getData(),ip); } } @@ -162,7 +161,7 @@ public class RemoteRobotServiceImpl implements RemoteRobotService { return; } - remoteControllerProcessor.remoteCache(result.getData()); + remoteControllerProcessor.remoteCache(result.getData(),ip); } /** @@ -203,8 +202,23 @@ public class RemoteRobotServiceImpl implements RemoteRobotService { RobotDistanceInformationDTO build = RobotDistanceInformationDTO.builder().linearSpeed(floorZone.getLinearSpeed()).robotNo(data.getRobotNo()) .endDistance(data.getEndDistance()).nextRadian(data.getNextRadian()).message(msg).build(); - processor.handleRequest(floorZone.getFloor() + "_" + floorZone.getArea(), - mac, JSONUtil.toJsonStr(build)); + /*processor.handleRequest(floorZone.getFloor() + "_" + floorZone.getArea(), + mac, JSONUtil.toJsonStr(build));*/ + } + + /** + * 上报车辆信息信息 + * @param data + */ + @Override + public void sendRobotWirelessSignalStatus(RemoteRobotWirelessSignalDTO data) { + TenantContextHolder.setTenantId(1L); + String robotNo = (String) redisUtil.get(RobotTaskChcheConstant.ROBOT_GET_ROBOTNO_BY_MAC + data.getMac()); + if (ObjectUtil.isEmpty(robotNo)) { + robotNo = remoteRobotApi.getRobotNoByMac(data.getMac()); + } + log.info("车辆编号 :{}",robotNo); + } /** diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/speed/RemoteRobotMaxSpeedServiceImpl.java b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/speed/RemoteRobotMaxSpeedServiceImpl.java index 8aade9c26..ec6b69c65 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/speed/RemoteRobotMaxSpeedServiceImpl.java +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/java/cn/iocoder/yudao/module/remote/service/speed/RemoteRobotMaxSpeedServiceImpl.java @@ -1,14 +1,20 @@ package cn.iocoder.yudao.module.remote.service.speed; +import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.module.system.api.remote.RemoteRobotMaxSpeedApi; import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotMaxSpeedDTO; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Collections; 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.exception0; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; + @Slf4j @Service public class RemoteRobotMaxSpeedServiceImpl implements RemoteRobotMaxSpeedService{ @@ -16,6 +22,9 @@ public class RemoteRobotMaxSpeedServiceImpl implements RemoteRobotMaxSpeedServic @Resource private RemoteRobotMaxSpeedApi remoteRobotMaxSpeedApi; + @Value("${remote.robot-max-speed:5}") + private int robotMaxSpeed; + @Override public List getRobotMaxSpeedPage() { return remoteRobotMaxSpeedApi.getRobotMaxSpeedPage(); @@ -23,6 +32,15 @@ public class RemoteRobotMaxSpeedServiceImpl implements RemoteRobotMaxSpeedServic @Override public void updateRobotMaxSpeedPage(List list) { + for (RemoteRobotMaxSpeedDTO remoteRobotMaxSpeedDTO : list) { + int speed = ObjectUtil.isEmpty(remoteRobotMaxSpeedDTO.getMaxSpeed()) ? 0 : Integer.parseInt(remoteRobotMaxSpeedDTO.getMaxSpeed()); + if (speed <= 0) { + throw exception(REMOTE_ROBOT_SPEED_EMPTY); + }else if (speed > robotMaxSpeed) { + String str = REMOTE_ROBOT_MAX_SPEED_LIMIT.getMsg() + " 最大限速为 " +robotMaxSpeed +" m/s"; + throw exception0(REMOTE_ROBOT_MAX_SPEED_LIMIT.getCode(),str); + } + } remoteRobotMaxSpeedApi.updateRobotMaxSpeedPage(list); } diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/resources/application-dev.yaml b/yudao-module-remote/yudao-module-remote-biz/src/main/resources/application-dev.yaml index ab71ccb74..a80b73994 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/resources/application-dev.yaml +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/resources/application-dev.yaml @@ -53,9 +53,15 @@ logging: name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径 remote: - controller-port: 9000 - controller-ip: 127.0.0.1 + cockpit: # 远遥控制车辆IP和端口 + - controllerPort: 9002 + controllerIp: 127.0.0.2 + ipcIp: 127.0.0.1 + - controllerPort: 9001 + controllerIp: 127.0.0.3 + ipcIp: 127.0.0.1 msg: AA 55 13 04 01 88 88 # 驾舱socket头信息 cockpit-time-out: 120 # 驾舱超时报警时间 industrial-control-time-out: 120 # 工控通信超时报警时间 - robot-communication-time-out: 120 # 车辆通信超时报警时间 \ No newline at end of file + robot-communication-time-out: 120 # 车辆通信超时报警时间 + robot-max-speed: 5 # 远遥控制车辆最大速度 m/s \ No newline at end of file diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/resources/application-local.yaml b/yudao-module-remote/yudao-module-remote-biz/src/main/resources/application-local.yaml index b91a5e505..66c68fb66 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/resources/application-local.yaml +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/resources/application-local.yaml @@ -53,10 +53,16 @@ logging: name: C:\system\install\log/${spring.application.name}.log remote: - controller-port: 9000 - controller-ip: 127.0.0.1 + cockpit: # 远遥控制车辆IP和端口 + - controllerPort: 9002 + controllerIp: 127.0.0.2 + ipcIp: 127.0.0.1 + - controllerPort: 9001 + controllerIp: 127.0.0.3 + ipcIp: 127.0.0.1 msg: AA 55 13 04 01 88 88 # 驾舱socket头信息 cockpit-time-out: 120 # 驾舱超时报警时间 industrial-control-time-out: 120 # 工控通信超时报警时间 robot-communication-time-out: 120 # 车辆通信超时报警时间 + robot-max-speed: 5 # 远遥控制车辆最大速度 m/s diff --git a/yudao-module-remote/yudao-module-remote-biz/src/main/resources/application-test.yaml b/yudao-module-remote/yudao-module-remote-biz/src/main/resources/application-test.yaml index 6beea06c3..b04e07382 100644 --- a/yudao-module-remote/yudao-module-remote-biz/src/main/resources/application-test.yaml +++ b/yudao-module-remote/yudao-module-remote-biz/src/main/resources/application-test.yaml @@ -34,9 +34,15 @@ logging: name: D:/project/rcs/logs/${spring.application.name}.log remote: - controller-port: 9000 - controller-ip: 10.10.110.17 + cockpit: # 远遥控制车辆IP和端口 + - controllerPort: 9002 + controllerIp: 127.0.0.2 + ipcIp: 127.0.0.1 + - controllerPort: 9001 + controllerIp: 127.0.0.3 + ipcIp: 127.0.0.1 msg: AA 55 13 04 01 88 88 # 驾舱socket头信息 cockpit-time-out: 120 # 驾舱超时报警时间 industrial-control-time-out: 120 # 工控通信超时报警时间 - robot-communication-time-out: 120 # 车辆通信超时报警时间 \ No newline at end of file + robot-communication-time-out: 120 # 车辆通信超时报警时间 + robot-max-speed: 5 # 远遥控制车辆最大速度 m/s \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApi.java index ad3eeea72..2a7efd720 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApi.java @@ -62,4 +62,8 @@ public interface RemoteRobotApi { @PostMapping(PREFIX + "/getMacByRobotNo") @Operation(summary = "根据车辆编号获取MAC地址") String getMacByRobotNo( @RequestParam(value = "robotNo") String robotNo); + + @PostMapping(PREFIX + "/getRobotNoByMac") + @Operation(summary = "根据车辆MAC地址获取车辆编号") + String getRobotNoByMac( @RequestParam(value = "mac") String mac); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/remote/dto/RemoteRobotStatusDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/remote/dto/RemoteRobotStatusDTO.java index 3b153051f..ede959e80 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/remote/dto/RemoteRobotStatusDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/remote/dto/RemoteRobotStatusDTO.java @@ -18,7 +18,7 @@ public class RemoteRobotStatusDTO { private Integer remoteMode = 0; @Schema(description = "协控(0:关闭协控, 1:开启协控, 2:不显示协控)") - private Integer collaborativeControl = 0; + private Integer collaborativeControl = 2; @Schema(description = "车辆任务状态(3:待命 , 其他都是任务中)") private Integer robotStatus = 2; diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotObstaclesStatusDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotObstaclesStatusDTO.java index 211d68a95..65d83c4d7 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotObstaclesStatusDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotObstaclesStatusDTO.java @@ -14,4 +14,29 @@ public class RobotObstaclesStatusDTO { * true表示有障碍物,false表示没有障碍物 */ public Boolean obstacles; + + /** + * 左前方障碍物距离 float,单位是米 + */ + private String frontLeft; + + /** + * 右前方障碍物距离 float,单位是米 + */ + private String frontRight; + + /** + * 左后方障碍物距离 float,单位是米 + */ + private String reaLeft; + + /** + * 右后方障碍物距离 float,单位是米 + */ + private String reaRight; + + /** + * 正后方障碍物距离 float,单位是米 + */ + private String rearCenter; } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotPoseStatusDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotPoseStatusDTO.java index f1a75d584..b46864b87 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotPoseStatusDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotPoseStatusDTO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.system.api.robot.dto; +import cn.iocoder.yudao.module.system.api.robot.websocket.RobotStatusDataPoseDTO; import lombok.Data; @Data diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotStatusDataDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotStatusDataDTO.java index 6b97943c6..828066fe0 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotStatusDataDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotStatusDataDTO.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.system.api.robot.dto; +import cn.iocoder.yudao.module.system.api.robot.websocket.RobotStatusDataPoseDTO; import lombok.Data; import java.util.List; diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotStatusDataErrorDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotStatusDataErrorDTO.java index 880ab6a3a..df538ccb4 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotStatusDataErrorDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotStatusDataErrorDTO.java @@ -11,8 +11,5 @@ public class RobotStatusDataErrorDTO { * 错误码 */ public String errorCode; - /** - * 错误等级 - */ - public String codeLevel; + } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/vo/RobotInformationVO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/websocket/RobotInformationVO.java similarity index 75% rename from yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/vo/RobotInformationVO.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/websocket/RobotInformationVO.java index 0d93d450f..849348c05 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/vo/RobotInformationVO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/websocket/RobotInformationVO.java @@ -1,6 +1,5 @@ -package cn.iocoder.yudao.module.system.api.robot.vo; +package cn.iocoder.yudao.module.system.api.robot.websocket; -import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; import lombok.Data; import java.util.List; @@ -31,4 +30,9 @@ public class RobotInformationVO { * 车辆即将走的点位 */ private List data; + + /** + * 车辆身上的物料信息和数量 + */ + private Object skuInfo; } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/websocket/RobotSkuInfoDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/websocket/RobotSkuInfoDTO.java new file mode 100644 index 000000000..b90902880 --- /dev/null +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/websocket/RobotSkuInfoDTO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.system.api.robot.websocket; + +import lombok.Data; + +@Data +public class RobotSkuInfoDTO { + + /** + * 1:有物料, 0:没有物料 + */ + private Integer haveSku = 1; + + /** + * 物料信息 + */ + private String skuInfo; + + /** + * 物料数量 + */ + private Long skuNumber; + + /** + * 层数 + */ + private Integer locationStorey; +} diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotStatusDataPoseDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/websocket/RobotStatusDataPoseDTO.java similarity index 55% rename from yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotStatusDataPoseDTO.java rename to yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/websocket/RobotStatusDataPoseDTO.java index f85c7e694..9061ecd3d 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/dto/RobotStatusDataPoseDTO.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/websocket/RobotStatusDataPoseDTO.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.system.api.robot.dto; +package cn.iocoder.yudao.module.system.api.robot.websocket; import lombok.Data; @@ -16,6 +16,8 @@ public class RobotStatusDataPoseDTO { public String floor; //区域 public String area; - //电池剩余容量 - public String batSoc; + //货叉高度 + public Double forkHeight; + //电池剩余容量 废弃 从ROBOT_INFORMATION_SOC 获取电量 +// public String batSoc; } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/websocket/WsWareHouseLocationDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/websocket/WsWareHouseLocationDTO.java new file mode 100644 index 000000000..503377ac8 --- /dev/null +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/robot/websocket/WsWareHouseLocationDTO.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.system.api.robot.websocket; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class WsWareHouseLocationDTO { + + @Schema(description = "实际坐标x轴") + private String actualLocationX; + + @Schema(description = "实际坐标y轴") + private String actualLocationY; + + @Schema(description = "类型: 1:添加, 0:减少") + private Integer type = 1; + + @Schema(description = "所在楼") + public String floor; + + @Schema(description = "所在区") + public String area; +} diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index 8516246ef..bf930a7e3 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -224,26 +224,29 @@ public interface ErrorCodeConstants { ErrorCode TASK_CREATE_FAIL = new ErrorCode(1-002-035-110, "任务创建失败:"); ErrorCode ROBOT_DO_TASK_FAIL = new ErrorCode(1-002-035-112, "车机反馈不能接任务"); ErrorCode TASK_COMMONG_FAIL = new ErrorCode(1-002-035-113, "下发失败"); + ErrorCode TASK_ASSIGN_OTHER_ROBOT = new ErrorCode(1-002-035-114, "此任务已经转移给其他车辆"); // ========== 机器人任务明细 1-002-036-000 ========== ErrorCode TASK_DETAIL_NOT_EXISTS = new ErrorCode(1-002-036-001, "车辆任务明细不存在"); ErrorCode TASK_DETAIL_CHANGE_ROBOT = new ErrorCode(1-002-036-002, "非新单据不能修改车辆"); - ErrorCode TASK_NOT_TAKE_RELEASE = new ErrorCode(1-002-036-003, "非取货任务,不能点击取货完成"); + ErrorCode TASK_NOT_TAKE_RELEASE = new ErrorCode(1-002-036-003, "已经取完货,不能点击取货完成,只能点击任务完成"); // ========== 机器人任务明细 1-002-037-000 ========== ErrorCode REDISSON_NOT_OBTAIN_LOCK = new ErrorCode(1-002-037-001, "有正在下发中的任务请稍后重试!"); ErrorCode PATH_PLANNING_DOING_DISTRIBUTE = new ErrorCode(1-002-037-002, "有正在分配的PP任务!"); // ========== 地图信息 1-002-038-000 ========== - ErrorCode AGV_UPLOAD_INFORMATION_DOES_NOT_INCLUDE_FLOOR_OR_AREA_INFORMATION = new ErrorCode(1_002_038_001, "AGV上传信息未包含楼层或区域信息"); - ErrorCode AGV_FILE_UPLOAD_CONTENT_IS_EMPTY = new ErrorCode(1_002_038_002, "AGV文件上传内容为空"); + ErrorCode AGV_UPLOAD_INFORMATION_DOES_NOT_INCLUDE_FLOOR_OR_AREA_INFORMATION = new ErrorCode(1_002_038_001, "车辆上传信息未包含楼层或区域信息"); + ErrorCode AGV_FILE_UPLOAD_CONTENT_IS_EMPTY = new ErrorCode(1_002_038_002, "车辆文件上传内容为空"); ErrorCode PLEASE_UPLOAD_PNG_AND_YAML_FILES = new ErrorCode(1_002_038_003, "请上传png和yaml两个文件并且文件内容不为空"); - ErrorCode AGV_MAP_NOT_FOUND = new ErrorCode(1_002_038_004, "找不到AGV地图信息"); - ErrorCode AGV_IMAGE_CONVERSION_TO_BASE64_FAILED = new ErrorCode(1_002_038_005, "AGV图片转base64失败"); + ErrorCode AGV_MAP_NOT_FOUND = new ErrorCode(1_002_038_004, "找不到车辆地图信息"); + ErrorCode AGV_IMAGE_CONVERSION_TO_BASE64_FAILED = new ErrorCode(1_002_038_005, "车辆图片转base64失败"); ErrorCode THE_LINE_LIBRARY_POINTS_ARE_NOT_LOCATED_IN_THE_SAME_AREA = new ErrorCode(1_002_038_006, "线库点位不在同一区域内"); ErrorCode THERE_ARE_ALREADY_STORAGE_LOCATIONS_IN_OTHER_LINE_WAREHOUSES = new ErrorCode(1_002_038_007, "已有库位在其他线库内"); ErrorCode THERE_ARE_ALREADY_STORAGE_LOCATIONS_IN_OTHER_STORAGE_AREAS = new ErrorCode(1_002_038_008, "已有库位在其它区域内"); ErrorCode MAP_DOES_NOT_EXIST_AGV = new ErrorCode(1_002_038_009, "此楼层区域不存在车辆需要暂停或恢复"); + ErrorCode MAP_EXIST_TASK_EXIST_TASK = new ErrorCode(1_002_038_010, "修改地图:此楼层区域存在处理中的任务或者库位上还有货物"); + ErrorCode MAP_EXIST_BINDING_POINT = new ErrorCode(1_002_038_011, "修改地图:此楼层区域的地图交换点尚未解绑"); // ========== 机器人自动移库 1-002-039-000 ========== ErrorCode TASK_AUTO_MOVE_NOT_EXISTS = new ErrorCode(1_002_039_001, "车辆自动移库不存在"); @@ -292,7 +295,6 @@ public interface ErrorCodeConstants { ErrorCode REMOTE_NOT_HAVE_PATH_MATCH = new ErrorCode(1_002_053_007, "车辆未匹配路网"); ErrorCode REMOTE_AUTOMATIC_CAN_NOT_CHANGE_TO_FREE = new ErrorCode(1_002_053_008, "手动模式只能切换到自动模式"); ErrorCode REMOTE_FREE_CAN_NOT_CHANGE_TO_HAND_MOVEMENT = new ErrorCode(1_002_053_009, "自由模式只能切换到自动模式"); - ErrorCode REMOTE_NOT_HAVE_BINDING_ROBOT = new ErrorCode(1_002_053_010, "远遥设备未选择车辆"); ErrorCode REMOTE_TASK_HAVE_CHOOSE = new ErrorCode(1_002_053_011, "此任务已经被远遥设备选中"); ErrorCode REMOTE_TASK_NOT_OCCUR_ERROR = new ErrorCode(1_002_053_012, "此任务未发发生4级异常"); ErrorCode REMOTE_TASK_NOT_TAKE_RELEASE = new ErrorCode(1_002_053_013, "非取货或者放货任务,不能转移"); @@ -300,6 +302,12 @@ public interface ErrorCodeConstants { ErrorCode REMOTE_ROBOT_HAVE_MORE_TASK = new ErrorCode(1_002_053_015, "此车辆有一个以上的处理中任务,请先检查数据"); ErrorCode REMOTE_ROBOT_HAVE_NOT_TASK = new ErrorCode(1_002_053_016, "此车辆没有处理中的任务"); ErrorCode REMOTE_ROBOT_CONNECT_FAIL = new ErrorCode(1_002_053_017, "与远遥工控机连接失败"); + ErrorCode REMOTE_TRANSFER_NOT_SAME_ROBOT = new ErrorCode(1_002_053_018, "任务转移车辆与发生异常的车辆,不能是同一台车"); + ErrorCode REMOTE_ROBOT_HAVE_TASK = new ErrorCode(1_002_053_019, "此车辆有处理中的任务,不能进行任务转移。请选择其他车辆"); + ErrorCode REMOTE_ROBOT_SPEED_EMPTY = new ErrorCode(1_002_053_020, "车辆速度必须大于0m/s"); + ErrorCode REMOTE_ROBOT_MAX_SPEED_LIMIT = new ErrorCode(1_002_053_021, "车辆速度超过最大速度限制"); + ErrorCode REMOTE_NOT_HAVE_SPEED = new ErrorCode(1_002_053_022, "查询不到车辆速度信息"); + ErrorCode REMOTE_SPEED_MORE_THAN_ZERO = new ErrorCode(1_002_053_023, "车辆未停稳"); // ========== 车辆摄像头信息 1_002_054_001 ========== ErrorCode CAMERA_NOT_EXISTS = new ErrorCode(1_002_054_001, "车辆摄像头信息不存在"); @@ -317,4 +325,7 @@ public interface ErrorCodeConstants { ErrorCode POSITION_CHANGE_POINT_BINDING_NOT_EXISTS = new ErrorCode(1_002_057_001, "区域变更点绑定不存在"); ErrorCode POSITION_CHANGE_POINT_SAME_MAP = new ErrorCode(1_002_057_002, "区域变更点绑定,不能是同一张地图"); ErrorCode POSITION_CHANGE_POINT_ALREADY_BINDING = new ErrorCode(1_002_057_003, "请勿重复绑定区域变更点"); + + // ========== 车辆工作时长统计 1_002_058_001 ========== + ErrorCode ROBOT_WORKING_HOURS_STATISTICS_NOT_EXISTS = new ErrorCode(1_002_058_001, "车辆工作时长统计不存在"); } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/oauth2/OAuth2ClientConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/oauth2/OAuth2ClientConstants.java index a123d57b9..8169ff072 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/oauth2/OAuth2ClientConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/oauth2/OAuth2ClientConstants.java @@ -8,5 +8,6 @@ package cn.iocoder.yudao.module.system.enums.oauth2; public interface OAuth2ClientConstants { String CLIENT_ID_DEFAULT = "default"; + String CLIENT_ID_REMOTE = "remote"; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApiImpl.java index 3d23f68fe..1cf6c2f8a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/path/PathApiImpl.java @@ -4,13 +4,18 @@ package cn.iocoder.yudao.module.system.api.path; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter; +import cn.iocoder.yudao.module.system.constant.CommonConstant; +import cn.iocoder.yudao.module.system.controller.admin.path.dto.GraphMatchDataDTO; import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapSaveReqVO; +import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnMsgSaveReqVO; import cn.iocoder.yudao.module.system.service.path.PathPlanningService; import cn.iocoder.yudao.module.system.service.positionmap.PositionChangePointBindingService; import cn.iocoder.yudao.module.system.service.robot.RobotTaskService; import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService; import cn.iocoder.yudao.module.system.service.tool.ToolsService; +import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; +import org.slf4j.MDC; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @@ -18,6 +23,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import java.util.UUID; @Slf4j @RestController // 提供 RESTful API 接口,给 Feign 调用 @@ -40,12 +46,11 @@ public class PathApiImpl implements PathApi { private RobotWarnMsgService warnMsgService; - /** * 发送初始化信息给PP */ @Override - @SystemRateLimiter(time = 10, count = 1, keyArg = "pathInitData",message = "路径规划初始化数据频繁") + @SystemRateLimiter(time = 10, count = 1, keyArg = "pathInitData", message = "路径规划初始化数据频繁") public void pathInitData() { taskExecutor.execute(() -> { TenantContextHolder.setTenantId(1L); @@ -69,26 +74,36 @@ public class PathApiImpl implements PathApi { /** * PP分配任务 + * * @param message */ @Override public void ppDistributionTask(String message) { taskExecutor.execute(() -> { TenantContextHolder.setTenantId(1L); - taskService.assignTasks(message); -// taskService.ppDistributionTask(message); 废弃了 + String requestId = UUID.randomUUID().toString().replace("-", ""); + MDC.put(CommonConstant.REQUEST_ID, requestId); + try { + taskService.assignTasks(message); + } finally { + MDC.clear(); + } }); } /** * PP处理任务失败 + * * @param message */ @Override public void ppDistributionTaskFail(String message) { TenantContextHolder.setTenantId(1L); - warnMsgService.addWarnMsg(message); - warnMsgService.sendWarnMsgToWebsocket(message); + RobotWarnMsgSaveReqVO data = JSON.parseObject(message, RobotWarnMsgSaveReqVO.class); + warnMsgService.createWarnMsg(data); + if (ObjectUtil.isNotEmpty(data.getWarnLevel()) && data.getWarnLevel() > 3) { + warnMsgService.sendWarnMsgToWebsocket(message); + } } @Override @@ -102,6 +117,7 @@ public class PathApiImpl implements PathApi { /** * 车辆即将走的点位 + * * @param message */ @Override @@ -112,6 +128,7 @@ public class PathApiImpl implements PathApi { /** * 仿真点位信息 + * * @param message */ @Override @@ -122,11 +139,13 @@ public class PathApiImpl implements PathApi { /** * 路网匹配实时数据 + * * @param message */ @Override public void graphMatchData(String message) { TenantContextHolder.setTenantId(1L); + log.info("匹配路网的消息 :{}",message); pathPlanningService.graphMatchData(message); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApiImpl.java index f2e7dcd7c..02be86295 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/remote/RemoteRobotApiImpl.java @@ -142,5 +142,10 @@ public class RemoteRobotApiImpl implements RemoteRobotApi { return robotInformationService.getMacByRobotNo(robotNo); } + @Override + public String getRobotNoByMac(String mac) { + return robotInformationService.getRobotNoByMac(mac); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotGenericsStatusApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotGenericsStatusApiImpl.java index 802d4c051..26a3a33e8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotGenericsStatusApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotGenericsStatusApiImpl.java @@ -3,15 +3,11 @@ package cn.iocoder.yudao.module.system.api.robot; import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.module.system.api.robot.dto.RobotGenericsDataDTO; -import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; import cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.util.redis.RedisUtil; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RestController; @@ -26,8 +22,6 @@ public class RobotGenericsStatusApiImpl implements RobotGenericsStatusApi { @Resource private RedisUtil redisUtil; - @Resource@Value("${zn.robot_position_cache_time:10}") - private Long robotPositionCacheTime; @Override @SystemRateLimiter(time = 1, count = 20, keyArg = "updateRobotCommonStatus",message = "机器人上报车辆其他信息") @@ -36,24 +30,27 @@ public class RobotGenericsStatusApiImpl implements RobotGenericsStatusApi { } public void doUpdateRobotCommonStatus(RobotGenericsDataDTO robotStatusData) { - log.info("车机每3秒上报其他状态信息 :{}", JSONUtil.toJsonStr(robotStatusData)); +// log.info("车机每3秒上报其他状态信息 :{}", JSONUtil.toJsonStr(robotStatusData)); if (ObjectUtil.isEmpty(robotStatusData) || ObjectUtil.isEmpty(robotStatusData.getHwStates()) || ObjectUtil.isEmpty(robotStatusData.getMac())) { log.info("参数不全 :{}", JSON.toJSONString(robotStatusData)); } String mac = robotStatusData.getMac(); - String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC +mac; + String socKey = RobotTaskChcheConstant.ROBOT_INFORMATION_SOC +mac; - Object object = redisUtil.get(pose2dKey); - RobotStatusDataPoseDTO robotStatusDataPoseDTO= JSONUtil.toBean((String)object, RobotStatusDataPoseDTO.class); String batSoc = robotStatusData.getHwStates().getBatSoc(); if (ObjectUtil.isNotEmpty(batSoc)) { String[] split = batSoc.split("\\."); - batSoc = split[1].substring(0,2); - robotStatusDataPoseDTO.setBatSoc(batSoc); - } + batSoc = split[1]; + if (batSoc.length() > 2) { + batSoc = batSoc.substring(0,2); + } - redisUtil.set(pose2dKey,JSON.toJSONString(robotStatusDataPoseDTO),robotPositionCacheTime); + if (batSoc.startsWith("0")) { + batSoc = batSoc.substring(1); + } + redisUtil.set(socKey,batSoc); + } } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotObstaclesStatusApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotObstaclesStatusApiImpl.java index 895389f97..5a9c7b4cc 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotObstaclesStatusApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotObstaclesStatusApiImpl.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO; import cn.iocoder.yudao.module.system.api.robot.dto.RobotObstaclesStatusDTO; import cn.iocoder.yudao.module.system.api.robot.vo.RobotUpdatePalletHeightDTO; +import cn.iocoder.yudao.module.system.constant.CommonConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.constant.webSocket.WebSocketConstant; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnMsgSaveReqVO; @@ -51,7 +52,6 @@ public class RobotObstaclesStatusApiImpl implements RobotObstaclesStatusApi{ Object floorAreaObject = redisUtil.get(floorAreaKey); FloorZoneDTO floorZoneDTO = JSONUtil.toBean((String) floorAreaObject, FloorZoneDTO.class); - String robotNo = robotInformationService.getRobotNoByMac(data.getMac()); RobotWarnMsgSaveReqVO warnMsg = new RobotWarnMsgSaveReqVO(); @@ -61,7 +61,7 @@ public class RobotObstaclesStatusApiImpl implements RobotObstaclesStatusApi{ warnMsg.setWarnMsg(robotNo +" 机器人遇到障碍物"); warnMsgService.createWarnMsg(warnMsg); - webSocketSenderApi.sendObject(floorZoneDTO.getFloor() + "_" + floorZoneDTO.getArea(), + webSocketSenderApi.sendObject(floorZoneDTO.getFloor() + CommonConstant.SYMBOL + floorZoneDTO.getArea(), WebSocketConstant.AGV_WARN, warnMsg.getWarnMsg()); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotReactiveStatusApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotReactiveStatusApiImpl.java index d3ff5c433..a29d20572 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotReactiveStatusApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotReactiveStatusApiImpl.java @@ -1,12 +1,12 @@ package cn.iocoder.yudao.module.system.api.robot; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO; import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataErrorDTO; -import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; import cn.iocoder.yudao.module.system.api.robot.vo.RobotReactiveStatusDTO; +import cn.iocoder.yudao.module.system.constant.CommonConstant; +import cn.iocoder.yudao.module.system.constant.area.FloorAreaConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.dal.dataobject.log.RobotTaskDetailActionLogDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnCodeMappingDO; @@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotWarnCodeMappingMapper import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotWarnMsgMapper; import cn.iocoder.yudao.module.system.enums.robot.RobotWarnType; import cn.iocoder.yudao.module.system.enums.robot.actionlog.ActionStatusEnum; +import cn.iocoder.yudao.module.system.enums.robot.actionlog.CommandIdEnum; import cn.iocoder.yudao.module.system.service.log.RobotTaskDetailActionLogService; import cn.iocoder.yudao.module.system.service.robot.RobotInformationService; import cn.iocoder.yudao.module.system.service.robot.RobotTaskDetailService; @@ -24,16 +25,12 @@ import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.function.Function; import java.util.stream.Collectors; @Slf4j @@ -65,6 +62,7 @@ public class RobotReactiveStatusApiImpl implements RobotReactiveStatusApi { @Override public void robotReactiveStatus(String message) { TenantContextHolder.setTenantId(1L); +// log.info("车辆所在楼层和异常信息 :{}", message); RobotReactiveStatusDTO data = JSON.parseObject(message, RobotReactiveStatusDTO.class); String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + data.getMac(); String robotNo = robotInformationService.getRobotNoByMac(data.getMac()); @@ -73,8 +71,14 @@ public class RobotReactiveStatusApiImpl implements RobotReactiveStatusApi { FloorZoneDTO floorZone = new FloorZoneDTO(); if (ObjectUtil.isNotEmpty(o)) { floorZone = JSON.parseObject((String) o, FloorZoneDTO.class); - String oldFloorArea = floorZone.getFloor()+"-"+floorZone.getArea(); - redisUtil.hdel(oldFloorArea,robotNo); + String oldFloorArea = floorZone.getFloor() + CommonConstant.SYMBOL + floorZone.getArea(); + redisUtil.hdel(oldFloorArea, robotNo); + + String newFloorArea = data.getFloorZone().getFloor() + CommonConstant.SYMBOL + data.getFloorZone().getArea(); + String key = FloorAreaConstant.FLOOR_AREA_ROBOT + floorZone.getFloor() + CommonConstant.SYMBOL + floorZone.getArea(); + if (!oldFloorArea.equals(newFloorArea)) { + redisUtil.hdel(key, robotNo); + } } floorZone.setArea(data.getFloorZone().getArea()); @@ -83,9 +87,12 @@ public class RobotReactiveStatusApiImpl implements RobotReactiveStatusApi { redisUtil.set(floorAreaKey, JSON.toJSONString(floorZone)); Map map = new HashMap<>(); - String value = floorZone.getFloor() + "-" + floorZone.getArea(); - map.put(robotNo,value); - redisUtil.hmset(value,map); + String value = floorZone.getFloor() + CommonConstant.SYMBOL + floorZone.getArea(); + map.put(robotNo, value); + redisUtil.hmset(value, map); + + String speedKey = RobotTaskChcheConstant.ROBOT_SPEED_FORK_HEIGHT + robotNo; + redisUtil.set(speedKey, message); // -- get 老的数据 - 看有没有 - 有的话 - 对比下 - 如果相同 - 更新hashMap中key的value // - 如果不相同的话 - 更新当前redis数据 - 然后 - 根据老的数据 去 hashMapRedis 中删除 这个key的数据 @@ -110,46 +117,41 @@ public class RobotReactiveStatusApiImpl implements RobotReactiveStatusApi { private void addRobotErrorMsg(RobotReactiveStatusDTO data) { String robotNo = robotInformationService.getRobotNoByMac(data.getMac()); List errCode = data.getErrCode(); - List warnCodes = - errCode.stream().map(RobotStatusDataErrorDTO::getErrorCode).collect(Collectors.toList()); + Set warnCodes = + errCode.stream().map(RobotStatusDataErrorDTO::getErrorCode).collect(Collectors.toSet()); List robotWarnCodeMappingDOS = warnCodeMappingMapper.selectList(new LambdaQueryWrapper() .in(RobotWarnCodeMappingDO::getWarnCode, warnCodes)); if (ObjectUtil.isEmpty(robotWarnCodeMappingDOS)) { - log.info("查不对应编号的告警信息 :{}", JSON.toJSONString(warnCodes)); + log.info("查不对应编号的告警信息 :{}", JSON.toJSONString(data)); return; } - Map> warnCodeMapping = - robotWarnCodeMappingDOS.stream().collect(Collectors.groupingBy(RobotWarnCodeMappingDO::getWarnCode)); + Map warnCodeMapping = + robotWarnCodeMappingDOS.stream().collect(Collectors.toMap(RobotWarnCodeMappingDO::getWarnCode, Function.identity())); List warnMsgDOS = new ArrayList<>(); //机器人异常等级 String errorLevelKey = RobotTaskChcheConstant.ROBOT_ERROR_LEVEL + data.getMac(); - Object errorLevel = redisUtil.get(errorLevelKey); String errorMsgKey = RobotTaskChcheConstant.ROBOT_ERROR_MSG + data.getMac(); - Object errorMsg = redisUtil.get(errorMsgKey); - - Integer level = ObjectUtil.isEmpty(errorLevel) ? 0 : Integer.valueOf(errorLevel.toString()); - - RobotTaskDetailActionLogDO lastTaskByRobotNo = taskDetailActionLogService.getLastTaskByRobotNo(robotNo); + RobotTaskDetailActionLogDO lastTaskByRobotNo = taskDetailActionLogService.getLastTaskByRobotNo(robotNo, CommandIdEnum.TASK.getType()); + int level = 0; String msg = ""; - int i = 0; for (RobotStatusDataErrorDTO robotStatusData : errCode) { - List mappingDOS = warnCodeMapping.get(robotStatusData.getErrorCode()); + RobotWarnCodeMappingDO mappingDOS = warnCodeMapping.get(robotStatusData.getErrorCode()); if (ObjectUtil.isEmpty(mappingDOS)) { log.info("当前告警类型查不到对应的告警信息 :{}", robotStatusData.getErrorCode()); continue; } - RobotWarnMsgDO warnMsg = RobotWarnMsgDO.builder().warnLevel(Integer.valueOf(robotStatusData.getCodeLevel())) + RobotWarnMsgDO warnMsg = RobotWarnMsgDO.builder().warnLevel(mappingDOS.getWarnLevel()) .warnCode(robotStatusData.getErrorCode()) .robotNo(robotNo) .warnType(RobotWarnType.ROBOT_WARN.getType()) - .warnMsg(robotNo + "_" + mappingDOS.get(0).getWarnMsg()) - .warnSolve(mappingDOS.get(0).getWarnSolve()) + .warnMsg(robotNo + CommonConstant.SYMBOL + mappingDOS.getWarnMsg()) + .warnSolve(mappingDOS.getWarnSolve()) .build(); if (ObjectUtil.isNotEmpty(lastTaskByRobotNo) && ActionStatusEnum.DOING.getType().equals(lastTaskByRobotNo.getActionStatus())) { @@ -159,20 +161,16 @@ public class RobotReactiveStatusApiImpl implements RobotReactiveStatusApi { warnMsgDOS.add(warnMsg); - if (level.intValue() < Integer.valueOf(robotStatusData.getCodeLevel()).intValue()) { - level = Integer.valueOf(robotStatusData.getCodeLevel()); - errorMsg = warnMsg.getWarnMsg(); - } - if (i < Integer.valueOf(robotStatusData.getCodeLevel()).intValue()) { - i = Integer.valueOf(robotStatusData.getCodeLevel()); + if (level < mappingDOS.getWarnLevel()) { + level = mappingDOS.getWarnLevel(); msg = warnMsg.getWarnMsg(); } } redisUtil.set(errorLevelKey, level); - redisUtil.set(errorMsgKey, errorMsg); + redisUtil.set(errorMsgKey, msg); if (ObjectUtil.isNotEmpty(lastTaskByRobotNo) && ActionStatusEnum.DOING.getType().equals(lastTaskByRobotNo.getActionStatus()) - && 4 == i && ObjectUtil.isNotEmpty(lastTaskByRobotNo.getTaskDetailId())) { + && 4 == level && ObjectUtil.isNotEmpty(lastTaskByRobotNo.getTaskDetailId())) { taskDetailService.setTaskDetailError(lastTaskByRobotNo.getTaskDetailId()); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotStatusApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotStatusApiImpl.java index 9960a6e79..1108715ef 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotStatusApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotStatusApiImpl.java @@ -3,35 +3,32 @@ package cn.iocoder.yudao.module.system.api.robot; import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.module.mqtt.api.path.PathPlanningApi; +import cn.iocoder.yudao.module.mqtt.api.common.CommonApi; import cn.iocoder.yudao.module.system.api.robot.dto.*; -import cn.iocoder.yudao.module.system.api.robot.vo.RobotInformationVO; +import cn.iocoder.yudao.module.system.api.robot.processor.RequestProcessor; +import cn.iocoder.yudao.module.system.api.robot.websocket.RobotInformationVO; +import cn.iocoder.yudao.module.system.api.robot.vo.RobotReactiveStatusDTO; +import cn.iocoder.yudao.module.system.api.robot.websocket.RobotStatusDataPoseDTO; import cn.iocoder.yudao.module.system.config.ratelimiter.SystemRateLimiter; +import cn.iocoder.yudao.module.system.constant.CommonConstant; +import cn.iocoder.yudao.module.system.constant.area.FloorAreaConstant; import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; -import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnCodeMappingDO; -import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnMsgDO; -import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotWarnCodeMappingMapper; -import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotWarnMsgMapper; -import cn.iocoder.yudao.module.system.enums.robot.RobotWarnType; import cn.iocoder.yudao.module.system.service.robot.RobotInformationService; -import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService; import cn.iocoder.yudao.module.system.util.redis.RedisUtil; import com.alibaba.fastjson.JSON; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; import java.util.Map; -import java.util.stream.Collectors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; @Slf4j @RestController // 提供 RESTful API 接口,给 Feign 调用 @@ -50,11 +47,10 @@ public class RobotStatusApiImpl implements RobotStatusApi { @Resource private RequestProcessor processor; - @Resource - private PathPlanningApi pathPlanningApi; + private static final ExecutorService executorService = Executors.newFixedThreadPool(5); - @Autowired - private ThreadPoolTaskExecutor taskExecutor; + @Resource + private CommonApi commonApi; /** * 更新机器人点位/异常/能否做任务 @@ -63,13 +59,16 @@ public class RobotStatusApiImpl implements RobotStatusApi { * @return */ @Override - @SystemRateLimiter(time = 1, count = 150, keyArg = "robotStatusUpdate",message = "机器人上报点位超过限流") + @SystemRateLimiter(time = 1, count = 150, keyArg = "robotStatusUpdate", message = "机器人上报点位超过限流") public void robotStatusUpdate(RobotPoseStatusDTO robotStatusDataDTO) { - updateRobotPosed(robotStatusDataDTO); + executorService.execute(() -> { + updateRobotPosed(robotStatusDataDTO); + }); } /** * 更新点位信息 + * * @param robotStatusDataDTO */ private void updateRobotPosed(RobotPoseStatusDTO robotStatusDataDTO) { @@ -82,18 +81,32 @@ public class RobotStatusApiImpl implements RobotStatusApi { Object floorAreaObject = redisUtil.get(floorAreaKey); FloorZoneDTO floorZoneDTO = JSONUtil.toBean((String) floorAreaObject, FloorZoneDTO.class); String robotNo = robotInformationService.getRobotNoByMac(robotStatusDataDTO.getMac()); - String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + robotStatusDataDTO.getMac(); + String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT + robotStatusDataDTO.getMac(); Object object = redisUtil.get(pose2dKey); RobotStatusDataPoseDTO robotStatusDataPoseDTO = JSONUtil.toBean((String) object, RobotStatusDataPoseDTO.class); if (ObjectUtil.isNotEmpty(robotStatusDataDTO.getPose2d())) { robotStatusDataPoseDTO.setX(robotStatusDataDTO.getPose2d().getX()); robotStatusDataPoseDTO.setY(robotStatusDataDTO.getPose2d().getY()); - robotStatusDataPoseDTO.setYaw(robotStatusDataDTO.getPose2d().getYaw()); + if (robotStatusDataDTO.getPose2d().getYaw().length()>7) { + String yaw = robotStatusDataDTO.getPose2d().getYaw().substring(0, 7); + robotStatusDataPoseDTO.setYaw(yaw); + }else { + robotStatusDataPoseDTO.setYaw(robotStatusDataDTO.getPose2d().getYaw()); + } + } robotStatusDataPoseDTO.setRobotNo(robotNo); robotStatusDataPoseDTO.setFloor(floorZoneDTO.getFloor()); robotStatusDataPoseDTO.setArea(floorZoneDTO.getArea()); + + String speedKey = RobotTaskChcheConstant.ROBOT_SPEED_FORK_HEIGHT + robotNo; + Object speedObject = redisUtil.get(speedKey); + if (ObjectUtil.isNotEmpty(speedObject)) { + RobotReactiveStatusDTO data = JSON.parseObject(speedObject.toString(), RobotReactiveStatusDTO.class); + robotStatusDataPoseDTO.setForkHeight(data.getForkHeight()); + } + redisUtil.set(pose2dKey, JSON.toJSONString(robotStatusDataPoseDTO), robotPositionCacheTime); //机器人身上是否有货 @@ -110,15 +123,18 @@ public class RobotStatusApiImpl implements RobotStatusApi { } robotInformationVO.setPose2d(robotStatusDataPoseDTO); + Map map = new HashMap<>(); + String value = FloorAreaConstant.FLOOR_AREA_ROBOT + floorZoneDTO.getFloor() + CommonConstant.SYMBOL + floorZoneDTO.getArea(); + map.put(robotStatusDataDTO.getMac(), JSON.toJSONString(robotInformationVO)); + redisUtil.hmset(value, map, 20); + // 合并请求 - 这里接受到的数据都丢给 RequestProcessor - 再整合数据通过WebSocket丢给前端 - processor.handleRequest(floorZoneDTO.getFloor() + "_" + floorZoneDTO.getArea(), + processor.handleRequest(floorZoneDTO.getFloor() + CommonConstant.SYMBOL + floorZoneDTO.getArea(), robotStatusDataDTO.getMac(), JSONUtil.toJsonStr(robotInformationVO)); sendToPP(robotStatusDataPoseDTO); } private void sendToPP(RobotStatusDataPoseDTO robotStatusDataPoseDTO) { - taskExecutor.execute(()->{ - pathPlanningApi.synchronousLineObject(robotStatusDataPoseDTO, PathPlanningTopicConstant.AGV_POSE); - }); + commonApi.commonMethod(robotStatusDataPoseDTO, PathPlanningTopicConstant.AGV_POSE); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotTaskStatusApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotTaskStatusApiImpl.java index 9830a80e8..a4846ccd9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotTaskStatusApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotTaskStatusApiImpl.java @@ -1,16 +1,26 @@ package cn.iocoder.yudao.module.system.api.robot; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; import cn.iocoder.yudao.module.mqtt.api.common.CommonApi; import cn.iocoder.yudao.module.system.api.path.vo.RobotClosePathPlantingDTO; +import cn.iocoder.yudao.module.system.api.robot.dto.FloorZoneDTO; import cn.iocoder.yudao.module.system.api.robot.dto.RobotCommandStateDTO; import cn.iocoder.yudao.module.system.api.robot.dto.RobotCompleteTaskDTO; +import cn.iocoder.yudao.module.system.api.robot.websocket.RobotSkuInfoDTO; +import cn.iocoder.yudao.module.system.api.robot.websocket.WsWareHouseLocationDTO; import cn.iocoder.yudao.module.system.constant.CommonConstant; +import cn.iocoder.yudao.module.system.constant.area.FloorAreaConstant; +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.RobotExecutionStateConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; +import cn.iocoder.yudao.module.system.constant.webSocket.WebSocketConstant; +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.houselocation.WareHouseLocationDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.*; @@ -26,14 +36,12 @@ import cn.iocoder.yudao.module.system.enums.robot.actionlog.ActionStatusEnum; import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeTaskStatusEnum; import cn.iocoder.yudao.module.system.enums.robot.task.RobotStatusCodeEnum; 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.RobotTaskDetailActionLogService; import cn.iocoder.yudao.module.system.service.path.PathPlanningService; import cn.iocoder.yudao.module.system.service.robot.RobotInformationService; import cn.iocoder.yudao.module.system.service.robot.RobotTaskDetailService; import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService; -import cn.iocoder.yudao.module.system.service.wait.MoveToWaitService; import cn.iocoder.yudao.module.system.util.redis.RedisUtil; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; @@ -50,6 +58,8 @@ import java.time.LocalDateTime; import java.util.List; import java.util.UUID; +import static cn.iocoder.yudao.module.system.service.robot.RobotInformationServiceImpl.key; + @Slf4j @RestController // 提供 RESTful API 接口,给 Feign 调用 @Validated @@ -92,6 +102,9 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { @Resource private CommonApi commonApi; + @Resource + public WebSocketSenderApi webSocketSenderApi; + @Resource private RobotTaskDetailService taskDetailService; @@ -101,9 +114,6 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { @Resource private RobotWarnMsgService warnMsgService; - @Resource - private MoveToWaitService moveToWaitService; - @Resource private PathPlanningService pathPlanningService; @@ -113,6 +123,9 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { @Value("${zn.robot_doing_action.doing_action_cache_time:2*24*60*60}") private Long doingActionCacheTime; + @Value("${zn.is_simulation:false}") + private Boolean isSimulation; + @Transactional(rollbackFor = Exception.class) public void doRobotDoneTask(RobotCompleteTaskDTO robotCompleteTaskDTO) { log.info("机器人完成任务上报 :{}", JSON.toJSONString(robotCompleteTaskDTO)); @@ -138,6 +151,10 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { } else if (RobotExecutionStateConstant.DONE.equals(robotCompleteTaskDTO.getExecutionState())) { robotTaskDone(robotCompleteTaskDTO); redisUtil.del(robotDoingActionKey); + String robotNo = robotInformationService.getRobotNoByMac(robotCompleteTaskDTO.getMac()); + String freeTimeKey = RobotTaskChcheConstant.ROBOT_LAST_FREE_TIME + robotNo; + String timeStr = DateUtils.getYearMonthDayHourMinuteSecon(); + redisUtil.set(freeTimeKey, timeStr); } else if (RobotExecutionStateConstant.DOING.equals(robotCompleteTaskDTO.getExecutionState())) { robotTaskDoing(robotCompleteTaskDTO, robotDoingActionKey); } @@ -156,27 +173,8 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { * @param robotCompleteTaskDTO */ private void robotTaskDoing(RobotCompleteTaskDTO robotCompleteTaskDTO, String robotDoingActionKey) { - String robotNo = robotInformationService.getRobotNoByMac(robotCompleteTaskDTO.getMac()); - RobotTaskDetailActionLogDO lastLog = setLastLogDone(robotCompleteTaskDTO.getOrderId()); - if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) { - chargeDoing(robotCompleteTaskDTO, robotDoingActionKey, lastLog); - } else if (PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(robotCompleteTaskDTO.getOrderType())) { - RobotTaskDetailActionLogDO logOne = new RobotTaskDetailActionLogDO(); - logOne.setActionMsg("车辆正在前往等待点"); - logOne.setRobotNo(robotNo); - logOne.setStartTime(LocalDateTime.now()); - logOne.setTaskDetailId(robotCompleteTaskDTO.getOrderId()); - if (ObjectUtil.isNotEmpty(lastLog)) { - logOne.setCommandType(lastLog.getCommandType()); - logOne.setTaskNo(lastLog.getTaskNo()); - } - taskDetailActionLogMapper.insert(logOne); - redisUtil.set(robotDoingActionKey, logOne.getActionMsg(), doingActionCacheTime); - moveToWaitService.updateWaitStatus(robotCompleteTaskDTO.getOrderId(), WaitStatusEnum.GO_TO_WAIT.getType()); - } else { - taskDoing(robotCompleteTaskDTO, robotDoingActionKey); - } + taskDoing(robotCompleteTaskDTO, robotDoingActionKey); if ((PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()) || PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) @@ -193,6 +191,11 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { taskDetailActionLogMapper.updateActionStatus(robotCompleteTaskDTO.getOrderId(), ActionStatusEnum.DOING.getType() , null); + + if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()) + || PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()) ) { + chargeDoing(robotCompleteTaskDTO); + } } /** @@ -218,9 +221,24 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { */ private void robotTaskDone(RobotCompleteTaskDTO robotCompleteTaskDTO) { setLastLogDone(robotCompleteTaskDTO.getOrderId()); + + //释放库位数据 + if (PathTaskTypeEnum.TAKE.getType().equals(robotCompleteTaskDTO.getOrderType()) + || (PathTaskTypeEnum.TAKE_RELEASE.getType().equals(robotCompleteTaskDTO.getOrderType()) + && CommandTypeEnum.WORK_PICK_UP_GOODS.getType().equals(robotCompleteTaskDTO.getCommandStatus().getCommandType()))) { + releaseFromLocationAndSetRobotSkuInfo(robotCompleteTaskDTO); + } else if (PathTaskTypeEnum.RELEASE.getType().equals(robotCompleteTaskDTO.getOrderType()) + || PathTaskTypeEnum.TAKE_RELEASE.getType().equals(robotCompleteTaskDTO.getOrderType())) { + releaseToLocation(robotCompleteTaskDTO); + redisUtil.del(RobotTaskChcheConstant.ROBOT_TASK_SKU_INFO + robotCompleteTaskDTO.getMac()); + } else { + redisUtil.del(RobotTaskChcheConstant.ROBOT_TASK_SKU_INFO + robotCompleteTaskDTO.getMac()); + } //todo 后面考虑下充电,车机目前对充电的逻辑未定义 if (PathTaskTypeEnum.MOVE.getType().equals(robotCompleteTaskDTO.getOrderType()) || PathTaskTypeEnum.MOVE_TO_WAIT_STOP.getType().equals(robotCompleteTaskDTO.getOrderType()) + || PathTaskTypeEnum.MOVE_TO_POINT.getType().equals(robotCompleteTaskDTO.getOrderType()) + || PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(robotCompleteTaskDTO.getOrderType()) || PathTaskTypeEnum.TAKE.getType().equals(robotCompleteTaskDTO.getOrderType()) || PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()) || PathTaskTypeEnum.RELEASE.getType().equals(robotCompleteTaskDTO.getOrderType())) { @@ -238,17 +256,114 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { } else if (CommandTypeEnum.WORK_DROP_OFF_GOODS.getType().equals(robotCompleteTaskDTO.getCommandStatus().getCommandType())) { taskDone(robotCompleteTaskDTO); } - } else if (PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(robotCompleteTaskDTO.getOrderType())) { - moveToWaitService.updateWaitStatus(robotCompleteTaskDTO.getOrderId(), WaitStatusEnum.REACH_WAIT.getType()); - } else if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) { - RobotChargeLogDO build = RobotChargeLogDO - .builder() - .id(robotCompleteTaskDTO.getOrderId()) - .taskStatus(ChargeTaskStatusEnum.CHARGEING.getType()) - .build(); - chargeLogMapper.updateById(build); + } + + if (PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()) + || PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) { + chargeLogMapper.updateChargStatusByTaskId(robotCompleteTaskDTO.getOrderId(),ChargeTaskStatusEnum.DONE.getType()); } taskDetailActionLogMapper.updateActionStatus(robotCompleteTaskDTO.getOrderId(), ActionStatusEnum.DONE.getType(), LocalDateTime.now()); + + } + + /** + * 释放放货库位 + * + * @param robotCompleteTaskDTO + */ + private void releaseToLocation(RobotCompleteTaskDTO robotCompleteTaskDTO) { + RobotTaskDetailDO robotTaskDetailDO = robotTaskDetailMapper.selectById(robotCompleteTaskDTO.getOrderId()); + if (ObjectUtil.isEmpty(robotTaskDetailDO) || ObjectUtil.isEmpty(robotTaskDetailDO.getToLocationId())) { + return; + } + WareHouseLocationDO toWareHouseLocation = locationMapper.selectById(robotTaskDetailDO.getToLocationId()); + if (ObjectUtil.isEmpty(toWareHouseLocation)) { + return; + } + //查询最近一起取货任务 + WareHouseLocationDO fromWareHouseLocation = getFromLocation(robotTaskDetailDO); + if (ObjectUtil.isNotEmpty(fromWareHouseLocation)) { + toWareHouseLocation.setSkuNumber(fromWareHouseLocation.getSkuNumber()); + toWareHouseLocation.setSkuInfo(fromWareHouseLocation.getSkuInfo()); + } + toWareHouseLocation.setLocationLock(LocationLockEnum.YES.getType()); + toWareHouseLocation.setLocationUseStatus(LocationUseStatusEnum.YES.getType()); + locationMapper.updateById(toWareHouseLocation); + pushWareLocation(toWareHouseLocation,robotCompleteTaskDTO.getMac(),ZeroOneEnum.ONE.getType()); + } + + /** + * 查询最近一次取货任务 + * + * @param robotTaskDetailDO + * @return + */ + private WareHouseLocationDO getFromLocation(RobotTaskDetailDO robotTaskDetailDO) { + if (RobotTaskTypeEnum.TAKE_RELEASE.getType().equals(robotTaskDetailDO.getTaskType()) + && ObjectUtil.isNotEmpty(robotTaskDetailDO.getFromLocationId())) { + return locationMapper.selectById(robotTaskDetailDO.getFromLocationId()); + } + List actionLogs = taskDetailActionLogMapper.getLastTwoTask(robotTaskDetailDO.getRobotNo()); + if (ObjectUtil.isEmpty(actionLogs)) { + return null; + } + for (RobotTaskDetailActionLogDO actionLog : actionLogs) { + if (!robotTaskDetailDO.getId().equals(actionLog.getTaskDetailId())) { + RobotTaskDetailDO taskDetail = robotTaskDetailMapper.selectById(actionLog.getTaskDetailId()); + if (ObjectUtil.isEmpty(taskDetail) || !RobotTaskTypeEnum.TAKE.getType().equals(taskDetail.getTaskType()) + || ObjectUtil.isEmpty(taskDetail.getFromLocationId())) { + continue; + } + locationMapper.selectById(taskDetail.getFromLocationId()); + } + } + return null; + } + + /** + * 设置车辆上的物料信息,释放取货库位 + * + * @param robotCompleteTaskDTO + */ + private void releaseFromLocationAndSetRobotSkuInfo(RobotCompleteTaskDTO robotCompleteTaskDTO) { + RobotTaskDetailDO robotTaskDetailDO = robotTaskDetailMapper.selectById(robotCompleteTaskDTO.getOrderId()); + if (ObjectUtil.isEmpty(robotTaskDetailDO) || ObjectUtil.isEmpty(robotTaskDetailDO.getFromLocationId())) { + return; + } + WareHouseLocationDO wareHouseLocationDO = locationMapper.selectById(robotTaskDetailDO.getFromLocationId()); + if (ObjectUtil.isEmpty(wareHouseLocationDO)) { + return; + } + RobotSkuInfoDTO robotSkuInfo = new RobotSkuInfoDTO(); + robotSkuInfo.setHaveSku(ZeroOneEnum.ONE.getType()); + robotSkuInfo.setSkuNumber(wareHouseLocationDO.getSkuNumber()); + robotSkuInfo.setSkuInfo(wareHouseLocationDO.getSkuInfo()); + robotSkuInfo.setLocationStorey(wareHouseLocationDO.getLocationStorey()); + redisUtil.set(RobotTaskChcheConstant.ROBOT_TASK_SKU_INFO + robotCompleteTaskDTO.getMac(), JSON.toJSONString(robotSkuInfo)); + wareHouseLocationDO.setSkuInfo(null); + wareHouseLocationDO.setSkuNumber(0L); + wareHouseLocationDO.setLocationLock(LocationLockEnum.YES.getType()); + wareHouseLocationDO.setLocationUseStatus(LocationUseStatusEnum.NO.getType()); + locationMapper.updateById(wareHouseLocationDO); + pushWareLocation(wareHouseLocationDO,robotCompleteTaskDTO.getMac(),ZeroOneEnum.ZERO.getType()); + } + + public void pushWareLocation(WareHouseLocationDO wareHouseLocationDO, String mac, Integer type) { + String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + mac; + Object floorAreaObject = redisUtil.get(floorAreaKey); + if (ObjectUtil.isEmpty(floorAreaObject)) { + return; + } + FloorZoneDTO floorZoneDTO = JSONUtil.toBean((String) floorAreaObject, FloorZoneDTO.class); + String floorAreaStr = floorZoneDTO.getFloor() + CommonConstant.SYMBOL + floorZoneDTO.getArea(); + WsWareHouseLocationDTO wsWareHouseLocation = new WsWareHouseLocationDTO(); + wsWareHouseLocation.setActualLocationX(wareHouseLocationDO.getActualLocationX()); + wsWareHouseLocation.setActualLocationY(wareHouseLocationDO.getActualLocationY()); + wsWareHouseLocation.setType(type); + wsWareHouseLocation.setFloor(floorZoneDTO.getFloor()); + wsWareHouseLocation.setArea(floorZoneDTO.getArea()); + log.info("让3D推送修改库存 :{}", JSON.toJSONString(wsWareHouseLocation)); + webSocketSenderApi.sendObject(floorAreaStr, WebSocketConstant.THREE_D_CHANGE_STOCK, JSON.toJSONString(wsWareHouseLocation)); } @@ -324,8 +439,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { String solve = ""; String taskNo = ""; - if (!PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(robotCompleteTaskDTO.getOrderType()) - && !PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()) + if (!PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()) && ObjectUtil.isEmpty(msg)) { taskNo = taskDetailService.getTaskNoByDetailId(robotCompleteTaskDTO.getOrderId()); solve = " 并且到任务列表关闭任务 " + taskNo; @@ -348,63 +462,26 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { warnMsgService.sendWarnMsgToWebsocket(warnMsg.getWarnMsg()); } - /** - * 关闭订单 - * - * @param taskDetailId - */ - public RobotTaskDetailDO closeTaskDetail(Long taskDetailId) { - return taskDetailService.closeTaskDetail(taskDetailId); - } - /** * 处理充电中 * * @param robotCompleteTaskDTO */ - private void chargeDoing(RobotCompleteTaskDTO robotCompleteTaskDTO, String robotDoingActionKey, RobotTaskDetailActionLogDO lastLog) { - RobotTaskDetailActionLogDO logOne = new RobotTaskDetailActionLogDO(); - RobotCommandStateDTO commandStatus = robotCompleteTaskDTO.getCommandStatus(); - Integer taskStatus = ChargeTaskStatusEnum.CHARGEING.getType(); - if (ObjectUtil.isNotEmpty(commandStatus) && CommandTypeEnum.MOVE_POSES.getType().equals(commandStatus.getCommandType())) { - RobotChargeLogDO robotChargeLogDO = chargeLogMapper.selectById(robotCompleteTaskDTO.getOrderId()); - logOne.setActionMsg("车辆正在前往充电点" + robotChargeLogDO.getDeviceNo()); - logOne.setTaskStage(RobotTaskStageEnum.MOVE.getType()); - taskStatus = ChargeTaskStatusEnum.DOING.getType(); - } else if (ObjectUtil.isNotEmpty(commandStatus)) { - logOne.setActionMsg("车辆正在充电"); - logOne.setTaskStage(RobotTaskStageEnum.CHARGEING.getType()); - } + private void chargeDoing(RobotCompleteTaskDTO robotCompleteTaskDTO) { - //编辑地图会判断这表的状态,所以自动充电任务,移动到充电点就改为完成 + RobotCommandStateDTO commandStatus = robotCompleteTaskDTO.getCommandStatus(); + + //自动充电任务,移动到充电点就改为完成 if (ObjectUtil.isNotEmpty(commandStatus) && CommandTypeEnum.MOVE_POSES.getType().equals(commandStatus.getCommandType()) && RobotExecutionStateConstant.DONE.equals(commandStatus.getExecutionState())) { taskDetailActionLogMapper.updateActionStatus(robotCompleteTaskDTO.getOrderId(), ActionStatusEnum.DONE.getType(), LocalDateTime.now()); + setTaskDone(robotCompleteTaskDTO); } - String robotNo = robotInformationService.getRobotNoByMac(robotCompleteTaskDTO.getMac()); - logOne.setRobotNo(robotNo); - logOne.setTaskDetailId(robotCompleteTaskDTO.getOrderId()); - - logOne.setCommandType(lastLog.getCommandType()); - logOne.setTaskNo(lastLog.getTaskNo()); - logOne.setStartTime(LocalDateTime.now()); - taskDetailActionLogMapper.insert(logOne); - redisUtil.set(robotDoingActionKey, logOne.getActionMsg(), doingActionCacheTime); - RobotChargeLogDO build = RobotChargeLogDO - .builder() - .id(robotCompleteTaskDTO.getOrderId()) - .taskStatus(taskStatus) - .build(); - chargeLogMapper.updateById(build); + chargeLogMapper.updateChargStatusByTaskId(robotCompleteTaskDTO.getOrderId(),ChargeTaskStatusEnum.CHARGEING.getType()); } - /** - * 任务完成 - * - * @param robotCompleteTaskDTO - */ - private void taskDone(RobotCompleteTaskDTO robotCompleteTaskDTO) { + public RobotTaskDetailDO setTaskDone(RobotCompleteTaskDTO robotCompleteTaskDTO) { //更新任务状态 RobotTaskDetailDO detailDO = new RobotTaskDetailDO(); detailDO.setId(robotCompleteTaskDTO.getOrderId()); @@ -416,7 +493,8 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { RobotTaskDetailDO robotTaskDetailDO = robotTaskDetailMapper.selectById(robotCompleteTaskDTO.getOrderId()); List taskDetails = robotTaskDetailMapper.queryByTaskId(robotTaskDetailDO.getRobotTaskId()); boolean done = - taskDetails.stream().noneMatch(v -> (v.getTaskStatus().equals(RobotTaskDetailStatusEnum.NEW.getType()))); + taskDetails.stream().noneMatch(v -> (v.getTaskStatus().equals(RobotTaskDetailStatusEnum.NEW.getType()) || + v.getTaskStatus().equals(RobotTaskDetailStatusEnum.DOING.getType()))); if (done) { RobotTaskDO robotTaskDO = new RobotTaskDO(); robotTaskDO.setId(taskDetails.get(0).getRobotTaskId()); @@ -425,6 +503,17 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { robotTaskMapper.updateRobot(robotTaskDO); taskCycleMapper.deletByRobotTaskId(taskDetails.get(0).getRobotTaskId()); } + return robotTaskDetailDO; + } + + /** + * 任务完成 + * + * @param robotCompleteTaskDTO + */ + private void taskDone(RobotCompleteTaskDTO robotCompleteTaskDTO) { + + RobotTaskDetailDO robotTaskDetailDO = setTaskDone(robotCompleteTaskDTO); RobotInformationDO robotInformationDO = robotInformationMapper.selectOne(new LambdaQueryWrapperX() .eq(RobotInformationDO::getRobotNo, robotTaskDetailDO.getRobotNo())); @@ -438,6 +527,11 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { //同步任务完成给PP pathPlanningService.updateBehavior(String.valueOf(robotCompleteTaskDTO.getOrderId()), robotTaskDetailDO.getRobotNo() , "", PathIsReachEnum.END_WORK.getType()); + + if (!isSimulation) { + String plantingKey = PathPlanningChcheConstant.PATH_PLANNING_TASK + robotCompleteTaskDTO.getOrderId(); + redisUtil.del(plantingKey); + } } @@ -457,7 +551,7 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { RobotCommandStateDTO commandStatus = robotCompleteTaskDTO.getCommandStatus(); String commandType = commandStatus.getCommandType(); - RobotTaskDetailActionLogDO logOne = new RobotTaskDetailActionLogDO(); + RobotTaskDetailActionLogSaveReqVO logOne = new RobotTaskDetailActionLogSaveReqVO(); if (PathTaskTypeEnum.TAKE_RELEASE.getType().equals(robotCompleteTaskDTO.getOrderType())) { if (CommandTypeEnum.MOVE_POSES.getType().equals(commandType) && RobotTaskStageEnum.UN_START.getType().equals(taskStage)) { logOne.setActionMsg("车辆正在前往" + robotTaskDetailDO.getFromLocationNo() + "取货"); @@ -473,7 +567,8 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.GO_RELEASE.getType()); } - } else if (PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) { + } else if (PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()) + || PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) { RobotChargeLogDO robotChargeLogDO = chargeLogMapper.selectById(robotCompleteTaskDTO.getOrderId()); if (CommandTypeEnum.MOVE_POSES.getType().equals(commandType)) { logOne.setActionMsg("车辆正在前往" + robotChargeLogDO.getDeviceNo() + "充电"); @@ -483,7 +578,9 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.CHARGEING.getType()); } - } else if (PathTaskTypeEnum.MOVE.getType().equals(robotCompleteTaskDTO.getOrderType())) { + } else if (PathTaskTypeEnum.MOVE.getType().equals(robotCompleteTaskDTO.getOrderType()) + || PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(robotCompleteTaskDTO.getOrderType()) + || PathTaskTypeEnum.MOVE_TO_POINT.getType().equals(robotCompleteTaskDTO.getOrderType())) { if (CommandTypeEnum.MOVE_POSES.getType().equals(commandType)) { logOne.setActionMsg("车辆正在前往" + robotTaskDetailDO.getToLocationNo()); robotTaskDetailDO.setTaskStage(RobotTaskStageEnum.MOVE.getType()); @@ -515,19 +612,25 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { //编辑地图会判断这表的状态,所以自动充电任务,移动到充电点就改为完成 if (ObjectUtil.isNotEmpty(commandStatus) && CommandTypeEnum.MOVE_POSES.getType().equals(commandStatus.getCommandType()) && RobotExecutionStateConstant.DONE.equals(commandStatus.getExecutionState()) - && PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType())) { + && (PathTaskTypeEnum.CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()) + || PathTaskTypeEnum.AUTO_CHARGE.getType().equals(robotCompleteTaskDTO.getOrderType()))) { taskDetailActionLogMapper.updateActionStatus(robotCompleteTaskDTO.getOrderId(), ActionStatusEnum.DONE.getType(), LocalDateTime.now()); } String robotNo = robotInformationService.getRobotNoByMac(robotCompleteTaskDTO.getMac()); logOne.setRobotNo(robotNo); + logOne.setOriginalRobotNo(robotNo); logOne.setTaskDetailId(robotCompleteTaskDTO.getOrderId()); logOne.setTaskStage(robotTaskDetailDO.getTaskStage()); logOne.setCommandType(PathTaskTypeEnum.getTaskType(robotTaskDetailDO.getTaskType())); logOne.setTaskNo(robotTask.getTaskNo()); logOne.setActionStatus(ActionStatusEnum.DOING.getType()); logOne.setStartTime(LocalDateTime.now()); - taskDetailActionLogMapper.insert(logOne); + Long mapId = robotInformationService.getRobotMapIdByRobotNo(robotNo); + if (ObjectUtil.isNotEmpty(mapId)) { + logOne.setPositionMapId(mapId); + } + taskDetailActionLogService.createTaskDetailActionLog(logOne); redisUtil.set(robotDoingActionKey, logOne.getActionMsg(), doingActionCacheTime); robotTaskDetailMapper.updateById(robotTaskDetailDO); } @@ -570,7 +673,6 @@ public class RobotTaskStatusApiImpl implements RobotTaskStatusApi { public void robotDoneTask(RobotCompleteTaskDTO robotCompleteTaskDTO) { taskExecutor.execute(() -> { String requestId = UUID.randomUUID().toString().replace("-", ""); - ; MDC.put(CommonConstant.REQUEST_ID, requestId); try { doRobotDoneTask(robotCompleteTaskDTO); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotUpdatePalletHeightApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotUpdatePalletHeightApiImpl.java index cd1f06e23..407c62f6e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotUpdatePalletHeightApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RobotUpdatePalletHeightApiImpl.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.api.robot; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.module.system.api.robot.vo.RobotUpdatePalletHeightDTO; +import cn.iocoder.yudao.module.system.constant.CommonConstant; import cn.iocoder.yudao.module.system.dal.dataobject.config.CommonConfigDO; import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO; @@ -101,7 +102,7 @@ public class RobotUpdatePalletHeightApiImpl implements RobotUpdatePalletHeightAp .warnCode(WARN_CODE) .robotNo(robotNo) .warnType(RobotWarnType.ROBOT_WARN.getType()) - .warnMsg(data.getOrderId() + "_" + "不需要更新库位高度") + .warnMsg(data.getOrderId() + CommonConstant.SYMBOL + "不需要更新库位高度") .build(); warnMsgMapper.insert(warnMsg); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RequestProcessor.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/processor/RequestProcessor.java similarity index 87% rename from yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RequestProcessor.java rename to yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/processor/RequestProcessor.java index fcf562561..08e9489a2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/RequestProcessor.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/robot/processor/RequestProcessor.java @@ -1,7 +1,8 @@ -package cn.iocoder.yudao.module.system.api.robot; +package cn.iocoder.yudao.module.system.api.robot.processor; import cn.hutool.core.map.MapUtil; import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; +import cn.iocoder.yudao.module.system.constant.webSocket.WebSocketConstant; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -46,8 +47,8 @@ public class RequestProcessor { private void sendData(String map, Map data) { // -- 发送给对应的websocket // System.out.println("key:" + map + "发送数据:" + data); - log.info("key:" + map + "发送数据:" + data); - webSocketSenderApi.sendObject(map, "map_push", data); +// log.info("key:" + map + "发送数据:" + data); + webSocketSenderApi.sendObject(map, WebSocketConstant.MAP_PUSH, data); } public void shutdown() { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/CommonConstant.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/CommonConstant.java index 6c76bd863..9b64c87f2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/CommonConstant.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/CommonConstant.java @@ -6,4 +6,9 @@ public class CommonConstant { * MDC请求常亮 */ public static final String REQUEST_ID = "requestId"; + + /** + * 拼接的符号 (不能改) + */ + public static final String SYMBOL = "_"; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/area/FloorAreaConstant.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/area/FloorAreaConstant.java new file mode 100644 index 000000000..f58e4616c --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/area/FloorAreaConstant.java @@ -0,0 +1,13 @@ +package cn.iocoder.yudao.module.system.constant.area; + +public class FloorAreaConstant { + + //楼层区域的KEY,通过这个KEY,可以查这个楼层下所有的机器人 + //仅限给WEBSOCKET推送给前端使用,缓存15秒 + public static String FLOOR_AREA_ROBOT = "floor:area:robot"; + + //所有的楼层区域 + public static String FLOOR_AREA_ALL = "floor:area:all"; + + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/robot/RobotTaskChcheConstant.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/robot/RobotTaskChcheConstant.java index ed24eb3eb..f15b5c986 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/robot/RobotTaskChcheConstant.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/robot/RobotTaskChcheConstant.java @@ -9,7 +9,10 @@ public class RobotTaskChcheConstant { public static String ROBOT_CARGO_DETECTED = "robot:information:cargo:detected"; //机器人点位和电量 (拼接的是mac地址) - public static String ROBOT_INFORMATION_POSE_BAT_SOC = "robot:information:pose:bat:soc"; + public static String ROBOT_INFORMATION_POSE_BAT = "robot:information:pose:bat"; + + //机器人电量 + public static String ROBOT_INFORMATION_SOC = "robot:information:soc"; //机器人楼层和区域 (拼接的是mac地址) public static String ROBOT_FLOOR_AREA = "robot:floor:area"; @@ -35,15 +38,15 @@ public class RobotTaskChcheConstant { //机器人mac地址和机器人id以及机器人类型映射(通过mac地址。获取机器人基本信息) public static String ROBOT_GET_ROBOT_INFO = "robot:information:getRobotInfo"; - //机器人正在做的任务整体信息(拼接common_id) -// public static String ROBOT_ACTION_LOG_ENTITY = "robot:action:log:entity"; - - //机器人取货完成(拼接robot_task_detail的id) -// public static String ROBOT_ACTION_TAKE_GOODS = "robot:take:"; - - //机器人放货完成(拼接robot_task_detail的id) -// public static String ROBOT_ACTION_RELEASE_GOODS = "robot:release:"; - //机器人点位 public static String ROBOT_ADDRESS = "robot:information:address"; + + //机器人速度和货叉高度 (拼接的是车辆编号robotNo) + public static String ROBOT_SPEED_FORK_HEIGHT = "robot:speed:fork:height"; + + //机器人开始空闲的时间 (拼接的是车辆编号robotNo) + public static String ROBOT_LAST_FREE_TIME = "robot:last:free:time"; + + //机器人物料数量(拼接的是mac地址) + public static String ROBOT_TASK_SKU_INFO = "robot:task:sku:info"; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/webSocket/WebSocketConstant.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/webSocket/WebSocketConstant.java index 9d82541e1..446971559 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/webSocket/WebSocketConstant.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/constant/webSocket/WebSocketConstant.java @@ -7,4 +7,19 @@ public class WebSocketConstant { * webSocket推送车机要走的点位id */ public static String PLANNING_MOVE_POSE = "planning_move_pose"; + + /** + * 3D地图的信息 + */ + public static String THREE_D_MAP_PUSH = "3d_map_push"; + + /** + * 3D地图修改库存 + */ + public static String THREE_D_CHANGE_STOCK = "3d_change_stock"; + + /** + * 推送地图点位信息 + */ + public static String MAP_PUSH = "map_push"; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java index 2009a9e44..26ba0c8fd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/vo/AuthLoginReqVO.java @@ -51,6 +51,9 @@ public class AuthLoginReqVO { @Schema(description = "state", requiredMode = Schema.RequiredMode.REQUIRED, example = "9b2ffbc1-7425-4155-9894-9d5c08541d62") private String socialState; + @Schema(description = "登录来源地址, 远遥传: remote") + private String clientid; + /** * 开启验证码的 Group */ diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/houselocation/WareHouseLocationController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/houselocation/WareHouseLocationController.java index 05364f78c..7df6a1869 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/houselocation/WareHouseLocationController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/houselocation/WareHouseLocationController.java @@ -6,10 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationPageReqVO; -import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationRespVO; -import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationSaveReqVO; -import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationVO; +import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.*; import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; import cn.iocoder.yudao.module.system.service.houselocation.HouseLocationService; import io.swagger.v3.oas.annotations.Operation; @@ -123,4 +120,12 @@ public class WareHouseLocationController { houseLocationService.updateHouseLocationList(list); return success(true); } + + @GetMapping("/getLocationsXYByMapId") + @Operation(summary = "根据地图id查询,此地图对应的所有库位,包括库位坐标") + @Parameter(name = "mapId", description = "地图id", required = true, example = "1024") + public CommonResult> getLocationsXYByMapId(@RequestParam("mapId") Long mapId) { + List list = houseLocationService.getLocationsXYByMapId(mapId); + return success(list); + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/houselocation/vo/WareHouseLocationItemRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/houselocation/vo/WareHouseLocationItemRespVO.java new file mode 100644 index 000000000..9d537de29 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/houselocation/vo/WareHouseLocationItemRespVO.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.system.controller.admin.houselocation.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Schema(description = "管理后台 - 库位和坐标 Response VO") +@Data +public class WareHouseLocationItemRespVO { + + @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "31866") + private Long id; + + @Schema(description = "库位编号") + private String locationNo; + + @Schema(description = "物料信息") + private String skuInfo; + + @Schema(description = "物料数量") + private Long skuNumber; + + @Schema(description = "启用/禁用(0:禁用、1:启用)") + private Integer locationEnable; + + @Schema(description = "锁定/正常(0:锁定、1:正常)") + private Integer locationLock; + + @Schema(description = "状态(0:空闲、1:占用)", example = "2") + private Integer locationUseStatus; + + @Schema(description = "宽度") + private BigDecimal locationWide; + + @Schema(description = "长度") + private BigDecimal locationDeep; + + @Schema(description = "层数") + private Integer locationStorey; + + @Schema(description = "实际坐标x轴") + private String actualLocationX; + + @Schema(description = "实际坐标y轴") + private String actualLocationY; + + + + + + + + + + + + + + + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationPageReqVO.java index d64fd51e9..5c5d2480b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationPageReqVO.java @@ -35,7 +35,7 @@ public class DeviceInformationPageReqVO extends PageParam { @Schema(description = "深度") private BigDecimal locationDeep; - //1:充电桩,2:输送线,3:码垛机,4:自动门,5:提升机,6:信号灯,7:按钮盒,8:拆垛机 + //1:充电桩,2:输送线,3:码垛机,4:自动门,5:提升机,6:信号灯,7:按钮盒,8:拆垛机, 9:摄像头 @Schema(description = "设备类型 字典device_type", example = "2") private Integer deviceType; @@ -74,8 +74,8 @@ public class DeviceInformationPageReqVO extends PageParam { @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) private LocalDateTime[] createTime; - @Schema(description = "设备使用状态(IDLE:空闲、USEING:使用中)") - private String deviceUseStatus; + @Schema(description = "设备使用状态(0:空闲、1:使用中)") + private Integer deviceUseStatus; @Schema(description = "设备专有属性(1:自动充电类型充电桩、2:手动充电类型充电桩)") private Integer deviceAttribute; @@ -89,4 +89,10 @@ public class DeviceInformationPageReqVO extends PageParam { @Schema(description = "最后使用者") private String lastUser; + @Schema(description = "摄像头类型(1 枪机 2半球 3球机 4云台枪机)") + private String cameraType; + + @Schema(description = "摄像头编号") + private String cameraCode; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationRespVO.java index 265291dd3..5e1ec65dc 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationRespVO.java @@ -42,7 +42,7 @@ public class DeviceInformationRespVO { @ExcelProperty("深度") private BigDecimal locationDeep; - //1:充电桩,2:输送线,3:码垛机,4:自动门,5:提升机,6:信号灯,7:按钮盒,8:拆垛机 + //1:充电桩,2:输送线,3:码垛机,4:自动门,5:提升机,6:信号灯,7:按钮盒,8:拆垛机, 9:摄像头 @Schema(description = "设备类型 字典device_type", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @ExcelProperty("设备类型 字典device_type") private Integer deviceType; @@ -91,9 +91,9 @@ public class DeviceInformationRespVO { @ExcelProperty("创建时间") private LocalDateTime createTime; - @Schema(description = "设备使用状态(IDLE:空闲、USEING:使用中)") - @ExcelProperty("设备使用状态(IDLE:空闲、USEING:使用中)") - private String deviceUseStatus; + @Schema(description = "设备使用状态(0:空闲、1:使用中)") + @ExcelProperty("设备使用状态(0:空闲、1:使用中)") + private Integer deviceUseStatus; @Schema(description = "设备专有属性(1:自动充电类型充电桩、2:手动充电类型充电桩)") @ExcelProperty("设备专有属性(1:自动充电类型充电桩、2:手动充电类型充电桩)") @@ -120,4 +120,11 @@ public class DeviceInformationRespVO { @ExcelProperty("最后使用者") private String lastUser; + @Schema(description = "摄像头类型(1 枪机 2半球 3球机 4云台枪机)") + @ExcelProperty("摄像头类型(1 枪机 2半球 3球机 4云台枪机)") + private String cameraType; + + @Schema(description = "摄像头编号") + @ExcelProperty("摄像头编号") + private String cameraCode; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationSaveReqVO.java index 0efe4c7da..8afad94bd 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/information/vo/DeviceInformationSaveReqVO.java @@ -35,7 +35,7 @@ public class DeviceInformationSaveReqVO { @Schema(description = "深度") private BigDecimal locationDeep; - //1:充电桩,2:输送线,3:码垛机,4:自动门,5:提升机,6:信号灯,7:按钮盒,8:拆垛机 + //1:充电桩,2:输送线,3:码垛机,4:自动门,5:提升机,6:信号灯,7:按钮盒,8:拆垛机 9:摄像头 @Schema(description = "设备类型 字典device_type", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @NotNull(message = "设备类型不能为空") private Integer deviceType; @@ -72,8 +72,8 @@ public class DeviceInformationSaveReqVO { @Schema(description = "设备最后通讯时间") private LocalDateTime deviceLastTime; - @Schema(description = "设备使用状态(IDLE:空闲、USEING:使用中)") - private String deviceUseStatus; + @Schema(description = "设备使用状态(0:空闲、1:使用中)") + private Integer deviceUseStatus; @Schema(description = "设备专有属性(1:自动充电类型充电桩、2:手动充电类型充电桩)") private Integer deviceAttribute; @@ -89,4 +89,9 @@ public class DeviceInformationSaveReqVO { @Schema(description = "最后使用者") private String lastUser; + @Schema(description = "摄像头类型(1 枪机 2半球 3球机 4云台枪机)") + private String cameraType; + + @Schema(description = "摄像头编号") + private String cameraCode; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/log/vo/RobotTaskDetailActionLogPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/log/vo/RobotTaskDetailActionLogPageReqVO.java index 6d49d4036..5d28a6c8c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/log/vo/RobotTaskDetailActionLogPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/log/vo/RobotTaskDetailActionLogPageReqVO.java @@ -14,7 +14,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_ @ToString(callSuper = true) public class RobotTaskDetailActionLogPageReqVO extends PageParam { - @Schema(description = "下发给车机的任务id", example = "18544") + @Schema(description = "-1代表是任务,其他的是操作的明细", example = "18544") private Long commandId; @Schema(description = "下发给车机的任务类型", example = "2") @@ -51,4 +51,12 @@ public class RobotTaskDetailActionLogPageReqVO extends PageParam { @Schema(description = "结束时间") private LocalDateTime endTime; + @Schema(description = "车辆做任务时,所在的仓库点位地图表id") + private Long positionMapId; + + @Schema(description = "是否已经统计(0:未统计、1:已经统计)") + private Integer alreadyCounted; + + @Schema(description = "这条任务第一次执行的AGV编号") + private String originalRobotNo; } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/log/vo/RobotTaskDetailActionLogRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/log/vo/RobotTaskDetailActionLogRespVO.java index fdc740e06..5fd6ca7f0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/log/vo/RobotTaskDetailActionLogRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/log/vo/RobotTaskDetailActionLogRespVO.java @@ -15,8 +15,8 @@ public class RobotTaskDetailActionLogRespVO { @ExcelProperty("主键ID") private Long id; - @Schema(description = "下发给车机的任务id", example = "18544") - @ExcelProperty("下发给车机的任务id") + @Schema(description = "-1代表是任务,其他的是操作的明细", example = "18544") + @ExcelProperty("-1代表是任务,其他的是操作的明细") private Long commandId; @Schema(description = "下发给车机的任务类型", example = "2") @@ -61,4 +61,15 @@ public class RobotTaskDetailActionLogRespVO { @ExcelProperty("结束时间") private LocalDateTime endTime; + @Schema(description = "车辆做任务时,所在的仓库点位地图表id") + @ExcelProperty("车辆做任务时,所在的仓库点位地图表id") + private Long positionMapId; + + @Schema(description = "是否已经统计(0:未统计、1:已经统计)") + @ExcelProperty("是否已经统计(0:未统计、1:已经统计)") + private Integer alreadyCounted; + + @Schema(description = "这条任务第一次执行的AGV编号") + @ExcelProperty("这条任务第一次执行的AGV编号") + private String originalRobotNo; } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/log/vo/RobotTaskDetailActionLogSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/log/vo/RobotTaskDetailActionLogSaveReqVO.java index 484f5d03a..876f9dbb2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/log/vo/RobotTaskDetailActionLogSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/log/vo/RobotTaskDetailActionLogSaveReqVO.java @@ -13,7 +13,7 @@ public class RobotTaskDetailActionLogSaveReqVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "25503") private Long id; - @Schema(description = "下发给车机的任务id", example = "18544") + @Schema(description = "-1代表是任务,其他的是操作的明细", example = "18544") private Long commandId; @Schema(description = "下发给车机的任务类型", example = "2") @@ -26,7 +26,7 @@ public class RobotTaskDetailActionLogSaveReqVO { private String actionMsg; @Schema(description = "动作状态(0:未开始、1:执行中、2:已完成、3:已取消、4:异常)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - @NotNull(message = "动作状态(0:未开始、1:执行中、2:已完成、3:已取消、4:异常)不能为空") +// @NotNull(message = "动作状态(0:未开始、1:执行中、2:已完成、3:已取消、4:异常)不能为空") 不要了 private Integer actionStatus; @Schema(description = "AGV编号") @@ -35,6 +35,9 @@ public class RobotTaskDetailActionLogSaveReqVO { @Schema(description = "robot_task_detail的id") private Long taskDetailId; + @Schema(description = "任务阶段(0:待执行、1:前往取货、2:取货中、3:前往放货、4:放货中、5:结束、6:移动中、7:正在充电、8:取消、9:人工完成、10:异常)") + private Long taskStage; + @Schema(description = "任务号") private String taskNo; @@ -44,4 +47,12 @@ public class RobotTaskDetailActionLogSaveReqVO { @Schema(description = "结束时间") private LocalDateTime endTime; + @Schema(description = "车辆做任务时,所在的仓库点位地图表id") + private Long positionMapId; + + @Schema(description = "是否已经统计(0:未统计、1:已经统计)") + private Integer alreadyCounted; + + @Schema(description = "这条任务第一次执行的AGV编号") + private String originalRobotNo; } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/PositionMapItemController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/PositionMapItemController.java index 9b851ac6e..ebc6f5b4b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/PositionMapItemController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/PositionMapItemController.java @@ -22,6 +22,7 @@ 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.positionmap.PositionMapLineService; import cn.iocoder.yudao.module.system.service.robot.RobotTaskService; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -35,6 +36,7 @@ import javax.annotation.Resource; import javax.validation.Valid; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -136,7 +138,7 @@ public class PositionMapItemController { @PostMapping("/lineAddItem") @Operation(summary = "线上加点保存点位") @PreAuthorize("@ss.hasPermission('system:position-map-item:lineAddItem')") - public CommonResult lineAddItem(@Valid @RequestBody List list) { + public CommonResult> lineAddItem(@Valid @RequestBody List list) { PositionMapItemSaveReqVO positionMapItem = BeanUtils.toBean(list.get(0), PositionMapItemSaveReqVO.class); positionMapItemService.createPositionMapItem(positionMapItem); @@ -144,10 +146,23 @@ public class PositionMapItemController { positionMapLineService.deletePositionMapLine(list.get(0).getOldLineId()); List positionMapLines = list.get(0).getPositionMapLines(); List lineList = BeanUtils.toBean(positionMapLines, PositionMapLineDO.class); + List itemIds = new ArrayList<>(); + for (PositionMapLineDO positionMapLineDO : lineList) { + itemIds.add(positionMapLineDO.getStartingPointId()); + itemIds.add(positionMapLineDO.getEndPointId()); + } + + Map sortNumMap = positionMapItemService.getSortNumMapByIds(itemIds); + for (PositionMapLineDO positionMapLineDO : lineList) { positionMapLineDO.setPositionMapId(positionMapItem.getPositionMapId()); + positionMapLineDO.setStartingSortNum(sortNumMap.get(positionMapLineDO.getStartingPointId()).intValue()); + positionMapLineDO.setEndPointSortNum(sortNumMap.get(positionMapLineDO.getEndPointId()).intValue()); } positionMapLineService.batchSaveLines(lineList); - return success(true); + Map map = new HashMap<>(); + map.put("ITEM",positionMapItemService.getPositionMapItem(positionMapItem.getId())); + map.put("LINE",lineList); + return success(map); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/vo/PositionMapItemPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/vo/PositionMapItemPageReqVO.java index d90bcc21a..487ff7091 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/vo/PositionMapItemPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/vo/PositionMapItemPageReqVO.java @@ -8,6 +8,7 @@ import lombok.EqualsAndHashCode; import lombok.ToString; import org.springframework.format.annotation.DateTimeFormat; +import javax.validation.constraints.NotEmpty; import java.time.LocalDateTime; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; @@ -52,7 +53,9 @@ public class PositionMapItemPageReqVO extends PageParam { @Schema(description = "排序的位置,越大越优先堆放") private Long locationNumber; - @Schema(description = "等待点使用状态(0.空闲 1.使用中)") + @Schema(description = "等待点使用状态, 0:空闲 ,1:前往停车点(预占用停车点) ,2.使用中(已经在停车位上)") private Integer useStatus; + @Schema(description = "AGV编号") + private String robotNo; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/vo/PositionMapItemRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/vo/PositionMapItemRespVO.java index ca1d05c7c..ddf4b1b96 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/vo/PositionMapItemRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/vo/PositionMapItemRespVO.java @@ -70,8 +70,12 @@ public class PositionMapItemRespVO { @ExcelProperty("排序的位置,越大越优先堆放") private Long locationNumber; - @Schema(description = "等待点使用状态(0.空闲 1.使用中)") - @ExcelProperty("等待点使用状态(0.空闲 1.使用中)") + @Schema(description = "等待点使用状态, 0:空闲 ,1:前往停车点(预占用停车点) ,2.使用中(已经在停车位上)") + @ExcelProperty("等待点使用状态, 0:空闲 ,1:前往停车点(预占用停车点) ,2.使用中(已经在停车位上)") private Integer useStatus; + @Schema(description = "AGV编号") + @ExcelProperty("等待点使用状态(0.空闲 1.使用中)") + private String robotNo; + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/vo/PositionMapItemSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/vo/PositionMapItemSaveReqVO.java index eb927a3af..828a7ff07 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/vo/PositionMapItemSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/positionmap/vo/PositionMapItemSaveReqVO.java @@ -43,6 +43,9 @@ public class PositionMapItemSaveReqVO { @Schema(description = "排序的位置,越大越优先堆放") private Long locationNumber; - @Schema(description = "等待点使用状态(0.空闲 1.使用中)") + @Schema(description = "等待点使用状态, 0:空闲 ,1:前往停车点(预占用停车点) ,2.使用中(已经在停车位上)") private Integer useStatus; + + @Schema(description = "AGV编号") + private String robotNo; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/RobotTaskController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/RobotTaskController.java index af73f15d2..e93bcefdf 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/RobotTaskController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/RobotTaskController.java @@ -121,4 +121,13 @@ public class RobotTaskController { return success(pageResult); } + @PostMapping("/checkHaveTask") + @Operation(summary = "判断是否存在任务") + @PreAuthorize("@ss.hasPermission('robot:task:checkHaveTask')") + public CommonResult checkHaveTask() { + //校验是否存在未完成的任务 + taskService.checkHaveDoingTask(); + return success(true); + } + } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/RobotTaskDetailController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/RobotTaskDetailController.java index 451802efd..e72821b0e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/RobotTaskDetailController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/RobotTaskDetailController.java @@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailP import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailRespVO; 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.enums.robot.task.RobotTaskManualInterventionEnum; import cn.iocoder.yudao.module.system.service.robot.RobotTaskDetailService; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -96,7 +97,7 @@ public class RobotTaskDetailController { @Operation(summary = "人工完成") @PreAuthorize("@ss.hasPermission('robot:task-detail:manuallyCompleted')") public CommonResult manuallyCompleted(@RequestParam("id") Long id) { - taskDetailService.manuallyCompleted(id,"人工完成"); + taskDetailService.manuallyCompleted(id,"人工完成", RobotTaskManualInterventionEnum.RCS_DONE.getType()); return success(true); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/camera/RobotCameraRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/camera/RobotCameraRespVO.java index 24101887b..017d2d607 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/camera/RobotCameraRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/camera/RobotCameraRespVO.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.camera; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; @@ -13,6 +15,7 @@ import com.alibaba.excel.annotation.*; public class RobotCameraRespVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30856") + @JsonSerialize(using = ToStringSerializer.class) @ExcelProperty("主键ID") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/chargelog/RobotChargeLogRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/chargelog/RobotChargeLogRespVO.java index 539d27a30..7699894c4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/chargelog/RobotChargeLogRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/chargelog/RobotChargeLogRespVO.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.chargelog; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; @@ -14,6 +16,7 @@ public class RobotChargeLogRespVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "6554") @ExcelProperty("主键ID") + @JsonSerialize(using = ToStringSerializer.class) private Long id; @Schema(description = "AGV编号") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/detail/RobotTaskDetailLogResoVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/detail/RobotTaskDetailLogResoVO.java index f7aecf0ef..2c15656f2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/detail/RobotTaskDetailLogResoVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/detail/RobotTaskDetailLogResoVO.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.detail; import com.alibaba.excel.annotation.ExcelProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -9,6 +11,7 @@ import java.time.LocalDateTime; @Data public class RobotTaskDetailLogResoVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26224") + @JsonSerialize(using = ToStringSerializer.class) private Long id; @Schema(description = "任务号") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/mapstop/RobotMapStopRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/mapstop/RobotMapStopRespVO.java index 6caef8f39..d1e5d9b67 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/mapstop/RobotMapStopRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/mapstop/RobotMapStopRespVO.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.mapstop; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; @@ -14,6 +16,7 @@ public class RobotMapStopRespVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1220") @ExcelProperty("主键ID") + @JsonSerialize(using = ToStringSerializer.class) private Long id; @Schema(description = "急停仓库点位地图表id", example = "20550") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotInformationPageRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotInformationPageRespVO.java index 08e5d6006..6e0e2d934 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotInformationPageRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotInformationPageRespVO.java @@ -2,10 +2,11 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.vo; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; -import javax.validation.constraints.NotNull; import java.util.Set; @@ -14,6 +15,7 @@ import java.util.Set; @ExcelIgnoreUnannotated public class RobotInformationPageRespVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "21881") + @JsonSerialize(using = ToStringSerializer.class) @ExcelProperty("主键ID") private Long id; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotInformationRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotInformationRespVO.java index 9625e8c4d..92f58b211 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotInformationRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotInformationRespVO.java @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.vo; import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler; import cn.iocoder.yudao.module.system.controller.admin.robot.camera.RobotCameraAddVO; import com.baomidou.mybatisplus.annotation.TableField; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.time.LocalDateTime; @@ -17,6 +19,7 @@ public class RobotInformationRespVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "21881") @ExcelProperty("主键ID") + @JsonSerialize(using = ToStringSerializer.class) private Long id; @Schema(description = "车辆类型表id", example = "28234") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotInformationSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotInformationSaveReqVO.java index 27c875b4a..8f612698b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotInformationSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotInformationSaveReqVO.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.vo; import cn.iocoder.yudao.module.system.controller.admin.robot.camera.RobotCameraAddVO; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.hibernate.validator.constraints.Range; @@ -16,6 +18,7 @@ import java.util.Set; public class RobotInformationSaveReqVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "21881") + @JsonSerialize(using = ToStringSerializer.class) private Long id; @Schema(description = "车辆类型表id", example = "28234") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotModelRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotModelRespVO.java index 6888a45af..d7efaffed 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotModelRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotModelRespVO.java @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.vo; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -14,6 +16,7 @@ public class RobotModelRespVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "15571") @ExcelProperty("主键ID") + @JsonSerialize(using = ToStringSerializer.class) private Long id; @Schema(description = "车辆类型", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskAutoMoveRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskAutoMoveRespVO.java index 9661a85b7..d0ab6d114 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskAutoMoveRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskAutoMoveRespVO.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.vo; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; @@ -14,6 +16,7 @@ public class RobotTaskAutoMoveRespVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30110") @ExcelProperty("主键ID") + @JsonSerialize(using = ToStringSerializer.class) private Long id; @Schema(description = "机器人任务主表id", example = "24553") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailAddVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailAddVO.java index bab918c20..b524b2b19 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailAddVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailAddVO.java @@ -9,6 +9,7 @@ import javax.validation.constraints.NotNull; @Data @Schema(description = "子列表") public class RobotTaskDetailAddVO { + private Long id; @Schema(description = "任务类型(1:取放货、2:停车、 3:充电、4:移动、5:仅取货、6:仅放货、7:扫描码、8:检测托盘类型、9:移动到点位)", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") @NotNull(message = "任务类型(1:取放货、2:停车、 3:充电、4:移动、5:仅取货、6:仅放货、7:扫描码、8:检测托盘类型、9:移动到点位)不能为空") private Integer taskType; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailPageReqVO.java index 35555b6e2..aa258ca81 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailPageReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailPageReqVO.java @@ -96,4 +96,10 @@ public class RobotTaskDetailPageReqVO extends PageParam { @Schema(description = "是否发生异常(0:正常、1:异常)") private Integer occurError; + + @Schema(description = "是否人工干预(0:未干预、1:RCS关闭、2:RCS人工完成、3:远遥取货完成、4:远遥任务完成、5:远遥取货完成和远遥任务完成)") + private Integer manualIntervention; + + @Schema(description = "人工干预时间") + private LocalDateTime manualInterventionTime; } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailRespVO.java index fdd1ba1e1..d05b82205 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailRespVO.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.vo; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; @@ -13,6 +15,7 @@ public class RobotTaskDetailRespVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26224") @ExcelProperty("主键ID") + @JsonSerialize(using = ToStringSerializer.class) private Long id; @Schema(description = "机器人任务主表id", requiredMode = Schema.RequiredMode.REQUIRED, example = "9241") @@ -118,4 +121,10 @@ public class RobotTaskDetailRespVO { @Schema(description = "是否发生异常(0:正常、1:异常)") private Integer occurError; + + @Schema(description = "是否人工干预(0:未干预、1:RCS关闭、2:RCS人工完成、3:远遥取货完成、4:远遥任务完成、5:远遥取货完成和远遥任务完成)") + private Integer manualIntervention; + + @Schema(description = "人工干预时间") + private LocalDateTime manualInterventionTime; } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailSaveReqVO.java index f702ff832..4a090dc0e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailSaveReqVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskDetailSaveReqVO.java @@ -97,4 +97,10 @@ public class RobotTaskDetailSaveReqVO { @Schema(description = "是否发生异常(0:正常、1:异常)") private Integer occurError; + @Schema(description = "是否人工干预(0:未干预、1:RCS关闭、2:RCS人工完成、3:远遥取货完成、4:远遥任务完成、5:远遥取货完成和远遥任务完成)") + private Integer manualIntervention; + + @Schema(description = "人工干预时间") + private LocalDateTime manualInterventionTime; + } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskRespVO.java index 34abc01a3..889bb4229 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotTaskRespVO.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.vo; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; @@ -17,6 +19,7 @@ public class RobotTaskRespVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "15306") @ExcelProperty("主键ID") + @JsonSerialize(using = ToStringSerializer.class) private Long id; @Schema(description = "是否拼接任务(0:不拼接、1:拼接)", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotWarnCodeMappingRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotWarnCodeMappingRespVO.java index f813545d5..64df30a11 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotWarnCodeMappingRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotWarnCodeMappingRespVO.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.vo; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; @@ -14,6 +16,7 @@ public class RobotWarnCodeMappingRespVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "15754") @ExcelProperty("主键ID") + @JsonSerialize(using = ToStringSerializer.class) private Long id; @Schema(description = "告警等级 (1,2,3,4)") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotWarnMsgRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotWarnMsgRespVO.java index 453752a37..dd2f921e8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotWarnMsgRespVO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/robot/vo/RobotWarnMsgRespVO.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.system.controller.admin.robot.vo; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; import java.util.*; @@ -14,6 +16,7 @@ public class RobotWarnMsgRespVO { @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26180") @ExcelProperty("主键ID") + @JsonSerialize(using = ToStringSerializer.class) private Long id; @Schema(description = "AGV编号") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/RobotWorkingHoursStatisticsController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/RobotWorkingHoursStatisticsController.java new file mode 100644 index 000000000..cbe59d421 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/RobotWorkingHoursStatisticsController.java @@ -0,0 +1,95 @@ +package cn.iocoder.yudao.module.system.controller.admin.statistics; + +import cn.iocoder.yudao.module.system.controller.admin.statistics.vo.*; +import cn.iocoder.yudao.module.system.dal.dataobject.statistics.RobotWorkingHoursStatisticsDO; +import cn.iocoder.yudao.module.system.service.statistics.RobotWorkingHoursStatisticsService; +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.constraints.*; +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("/system/statistics/robot-working-hours-statistics") +@Validated +public class RobotWorkingHoursStatisticsController { + + @Resource + private RobotWorkingHoursStatisticsService robotWorkingHoursStatisticsService; + + @PostMapping("/create") + @Operation(summary = "创建车辆工作时长统计") + @PreAuthorize("@ss.hasPermission('statistics:robot-working-hours-statistics:create')") + public CommonResult createRobotWorkingHoursStatistics(@Valid @RequestBody RobotWorkingHoursStatisticsSaveReqVO createReqVO) { + return success(robotWorkingHoursStatisticsService.createRobotWorkingHoursStatistics(createReqVO)); + } + + @PutMapping("/update") + @Operation(summary = "更新车辆工作时长统计") + @PreAuthorize("@ss.hasPermission('statistics:robot-working-hours-statistics:update')") + public CommonResult updateRobotWorkingHoursStatistics(@Valid @RequestBody RobotWorkingHoursStatisticsSaveReqVO updateReqVO) { + robotWorkingHoursStatisticsService.updateRobotWorkingHoursStatistics(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除车辆工作时长统计") + @Parameter(name = "id", description = "编号", required = true) + @PreAuthorize("@ss.hasPermission('statistics:robot-working-hours-statistics:delete')") + public CommonResult deleteRobotWorkingHoursStatistics(@RequestParam("id") Long id) { + robotWorkingHoursStatisticsService.deleteRobotWorkingHoursStatistics(id); + return success(true); + } + + @GetMapping("/get") + @Operation(summary = "获得车辆工作时长统计") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + @PreAuthorize("@ss.hasPermission('statistics:robot-working-hours-statistics:query')") + public CommonResult getRobotWorkingHoursStatistics(@RequestParam("id") Long id) { + RobotWorkingHoursStatisticsDO robotWorkingHoursStatistics = robotWorkingHoursStatisticsService.getRobotWorkingHoursStatistics(id); + return success(BeanUtils.toBean(robotWorkingHoursStatistics, RobotWorkingHoursStatisticsRespVO.class)); + } + + @GetMapping("/page") + @Operation(summary = "获得车辆工作时长统计分页") + @PreAuthorize("@ss.hasPermission('statistics:robot-working-hours-statistics:query')") + public CommonResult> getRobotWorkingHoursStatisticsPage(@Valid RobotWorkingHoursStatisticsPageReqVO pageReqVO) { + PageResult pageResult = robotWorkingHoursStatisticsService.getRobotWorkingHoursStatisticsPage(pageReqVO); + return success(BeanUtils.toBean(pageResult, RobotWorkingHoursStatisticsRespVO.class)); + } + + @GetMapping("/export-excel") + @Operation(summary = "导出车辆工作时长统计 Excel") + @PreAuthorize("@ss.hasPermission('statistics:robot-working-hours-statistics:export')") + @ApiAccessLog(operateType = EXPORT) + public void exportRobotWorkingHoursStatisticsExcel(@Valid RobotWorkingHoursStatisticsPageReqVO pageReqVO, + HttpServletResponse response) throws IOException { + pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); + List list = robotWorkingHoursStatisticsService.getRobotWorkingHoursStatisticsPage(pageReqVO).getList(); + // 导出 Excel + ExcelUtils.write(response, "车辆工作时长统计.xls", "数据", RobotWorkingHoursStatisticsRespVO.class, + BeanUtils.toBean(list, RobotWorkingHoursStatisticsRespVO.class)); + } + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/StatisticsController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/StatisticsController.java new file mode 100644 index 000000000..6f32d1f5e --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/StatisticsController.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.system.controller.admin.statistics; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.system.controller.admin.statistics.dto.RobotStatusClassificationDTO; +import cn.iocoder.yudao.module.system.controller.admin.statistics.dto.RobotTaskManualInterventionDTO; +import cn.iocoder.yudao.module.system.controller.admin.statistics.dto.RobotWarnMsgClassificationDTO; +import cn.iocoder.yudao.module.system.controller.admin.statistics.dto.RobotWorkHourStatisticsDTO; +import cn.iocoder.yudao.module.system.service.robot.RobotInformationService; +import cn.iocoder.yudao.module.system.service.robot.RobotTaskDetailService; +import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService; +import cn.iocoder.yudao.module.system.service.statistics.RobotWorkingHoursStatisticsService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +import java.util.List; +import java.util.Map; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Tag(name = "管理后台 - 统计") +@RestController +@RequestMapping("/system/statistics") +@Validated +public class StatisticsController { + + @Resource + private RobotInformationService informationService; + + @Resource + private RobotTaskDetailService taskDetailService; + + @Resource + private RobotWarnMsgService warnMsgService; + + @Resource + private RobotWorkingHoursStatisticsService robotWorkingHoursStatisticsService; + + @GetMapping("/robotStatusClassification") + @Operation(summary = "统计车辆状态分类") + @PreAuthorize("@ss.hasPermission('robot:information:robotStatusClassification')") + public CommonResult robotStatusClassification() { + return success(informationService.robotStatusClassification()); + } + + @GetMapping("/robotTaskAutomaticArtificial") + @Operation(summary = "统计任务人工完成/自动完成" ,description = "type 1:周, 2:月, 3:季度") + @PreAuthorize("@ss.hasPermission('robot:information:robotTaskAutomaticArtificial')") + public CommonResult robotTaskAutomaticArtificial(@RequestParam("type") String type) { + return success(taskDetailService.robotTaskAutomaticArtificial(type)); + } + + @GetMapping("/robotWarnMsgClassification") + @Operation(summary = "统计故障根因分析" ,description = "type 1:周, 2:月, 3:季度") + @PreAuthorize("@ss.hasPermission('robot:information:robotWarnMsgClassification')") + public CommonResult>> robotWarnMsgClassification(@RequestParam("type") String type) { + return success(warnMsgService.robotWarnMsgClassification(type)); + } + + @GetMapping("/robotWorkHourStatistics") + @Operation(summary = "车辆工作时长统计" ,description = "type 1:周, 2:月, 3:季度 ; positionMapId 地图Id") + @PreAuthorize("@ss.hasPermission('robot:information:robotWorkHourStatistics')") + public CommonResult> robotWorkHourStatistics(@RequestParam("type") String type, + @RequestParam("positionMapId") String positionMapId) { + return success(robotWorkingHoursStatisticsService.robotWorkHourStatistics(type,positionMapId)); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/dto/RobotStatusClassificationDTO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/dto/RobotStatusClassificationDTO.java new file mode 100644 index 000000000..f451548f6 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/dto/RobotStatusClassificationDTO.java @@ -0,0 +1,35 @@ +package cn.iocoder.yudao.module.system.controller.admin.statistics.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class RobotStatusClassificationDTO { + + @Schema(description = "空闲车辆百分比") + private Integer idle ; + + @Schema(description = "空闲车辆数量") + private Integer idleNum = 0; + + @Schema(description = "执行任务车辆百分比") + private Integer doingTask; + + @Schema(description = "执行任务车辆数量") + private Integer doingTaskNum = 0; + + @Schema(description = "充电车辆百分比") + private Integer charge ; + + @Schema(description = "充电车辆数量") + private Integer chargeNum = 0; + + @Schema(description = "故障车辆百分比") + private Integer fault; + + @Schema(description = "故障车辆数量") + private Integer faultNum = 0; + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/dto/RobotTaskManualInterventionDTO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/dto/RobotTaskManualInterventionDTO.java new file mode 100644 index 000000000..74f10d571 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/dto/RobotTaskManualInterventionDTO.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.system.controller.admin.statistics.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class RobotTaskManualInterventionDTO { + + @Schema(description = "人工完成任务的百分比") + private Integer artificialDone = 0; + + @Schema(description = "人工完成任务的数量") + private Integer artificialDoneNum = 0; + + @Schema(description = "自动完成任务的百分比") + private Integer automaticDone = 0; + + @Schema(description = "自动完成任务的数量") + private Integer automaticDoneNum = 0; + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/dto/RobotWarnMsgClassificationDTO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/dto/RobotWarnMsgClassificationDTO.java new file mode 100644 index 000000000..12844b2a4 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/dto/RobotWarnMsgClassificationDTO.java @@ -0,0 +1,17 @@ +package cn.iocoder.yudao.module.system.controller.admin.statistics.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class RobotWarnMsgClassificationDTO { + + @Schema(description = "时间") + private String warnTime; + + @Schema(description = "告警等级, 1,2,3,4") + private String warnLevel; + + @Schema(description = "数量") + private Integer num; +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/dto/RobotWorkHourStatisticsDTO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/dto/RobotWorkHourStatisticsDTO.java new file mode 100644 index 000000000..e8f353361 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/dto/RobotWorkHourStatisticsDTO.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.system.controller.admin.statistics.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class RobotWorkHourStatisticsDTO { + + @Schema(description = "车辆编号", example = "28478") + private String robotNo; + + @Schema(description = "空闲时长 单位小时", example = "28478") + private String freeTimeNum; + + @Schema(description = "工作时长 单位小时", example = "28478") + private String taskTimeNum; + + @Schema(description = "充电时长 单位小时", example = "28478") + private String chargeTimeNum; +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/vo/RobotWorkingHoursStatisticsPageReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/vo/RobotWorkingHoursStatisticsPageReqVO.java new file mode 100644 index 000000000..75d75e3e5 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/vo/RobotWorkingHoursStatisticsPageReqVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.system.controller.admin.statistics.vo; + +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 RobotWorkingHoursStatisticsPageReqVO extends PageParam { + + @Schema(description = "仓库点位地图表id", example = "28478") + private Long positionMapId; + + @Schema(description = "AGV编号") + private String robotNo; + + @Schema(description = "时长,单位分钟") + private Long duration; + + @Schema(description = "类型(0:空闲时长, 1:任务时长, 2:充电时长)", example = "1") + private Integer durationType; + + @Schema(description = "创建时间") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/vo/RobotWorkingHoursStatisticsRespVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/vo/RobotWorkingHoursStatisticsRespVO.java new file mode 100644 index 000000000..f0a51b238 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/vo/RobotWorkingHoursStatisticsRespVO.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.system.controller.admin.statistics.vo; + +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 RobotWorkingHoursStatisticsRespVO { + + @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "7218") + @ExcelProperty("主键ID") + private Long id; + + @Schema(description = "仓库点位地图表id", example = "28478") + @ExcelProperty("仓库点位地图表id") + private Long positionMapId; + + @Schema(description = "AGV编号") + @ExcelProperty("AGV编号") + private String robotNo; + + @Schema(description = "时长,单位分钟", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("时长,单位分钟") + private Long duration; + + @Schema(description = "类型(0:空闲时长, 1:任务时长, 2:充电时长)", example = "1") + @ExcelProperty("类型(0:空闲时长, 1:任务时长, 2:充电时长)") + private Integer durationType; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + @ExcelProperty("创建时间") + private LocalDateTime createTime; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/vo/RobotWorkingHoursStatisticsSaveReqVO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/vo/RobotWorkingHoursStatisticsSaveReqVO.java new file mode 100644 index 000000000..0c9f5712d --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/statistics/vo/RobotWorkingHoursStatisticsSaveReqVO.java @@ -0,0 +1,28 @@ +package cn.iocoder.yudao.module.system.controller.admin.statistics.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; +import java.util.*; +import javax.validation.constraints.*; + +@Schema(description = "管理后台 - 车辆工作时长统计新增/修改 Request VO") +@Data +public class RobotWorkingHoursStatisticsSaveReqVO { + + @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "7218") + private Long id; + + @Schema(description = "仓库点位地图表id", example = "28478") + private Long positionMapId; + + @Schema(description = "AGV编号") + private String robotNo; + + @Schema(description = "时长,单位分钟", requiredMode = Schema.RequiredMode.REQUIRED) + @NotNull(message = "时长,单位分钟不能为空") + private Long duration; + + @Schema(description = "类型(0:空闲时长, 1:任务时长, 2:充电时长)", example = "1") + private Integer durationType; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tool/ToolsController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tool/ToolsController.java index 15eba3e08..b934dbde7 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tool/ToolsController.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tool/ToolsController.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.tool; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationSaveReqVO; +import cn.iocoder.yudao.module.system.controller.admin.tool.dto.SendMsgToMqttDTO; import cn.iocoder.yudao.module.system.service.tool.ToolsService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -55,4 +56,12 @@ public class ToolsController { toolsService.simulationPose(); return success("同步完成"); } + + @PostMapping("/sendMsgToMQTT") + @Operation(summary = "发送消息给MQTT") + @PermitAll + public CommonResult sendMsgToMQTT( @RequestBody SendMsgToMqttDTO dto) { + toolsService.sendMsgToMQTT(dto); + return success("发送完成"); + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tool/dto/SendMsgToMqttDTO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tool/dto/SendMsgToMqttDTO.java new file mode 100644 index 000000000..5e6c06c4e --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/tool/dto/SendMsgToMqttDTO.java @@ -0,0 +1,14 @@ +package cn.iocoder.yudao.module.system.controller.admin.tool.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class SendMsgToMqttDTO { + + @Schema(description = "消息") + private String msg; + + @Schema(description = "主题topic") + private String topic; +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/information/DeviceInformationDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/information/DeviceInformationDO.java index df185bc94..48e9d492d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/information/DeviceInformationDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/information/DeviceInformationDO.java @@ -67,7 +67,7 @@ public class DeviceInformationDO extends BaseDO { */ private BigDecimal locationDeep; /** - * 1:充电桩,2:输送线,3:码垛机,4:自动门,5:提升机,6:信号灯,7:按钮盒,8:拆垛机 + * 1:充电桩,2:输送线,3:码垛机,4:自动门,5:提升机,6:信号灯,7:按钮盒,8:拆垛机, 9:摄像头 * 设备类型 字典device_type */ private Integer deviceType; @@ -112,9 +112,9 @@ public class DeviceInformationDO extends BaseDO { */ private LocalDateTime deviceLastTime; /** - * 设备使用状态(IDLE:空闲、USEING:使用中) + * 设备使用状态(0:空闲、1:使用中) */ - private String deviceUseStatus; + private Integer deviceUseStatus; /** * 设备专有属性(1:自动充电类型充电桩、2:手动充电类型充电桩) */ @@ -135,4 +135,13 @@ public class DeviceInformationDO extends BaseDO { */ private String lastUser; + /** + * 摄像头类型(1 枪机 2半球 3球机 4云台枪机) + */ + private String cameraType; + + /** + * 摄像头编号 + */ + private String cameraCode; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/log/RobotTaskDetailActionLogDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/log/RobotTaskDetailActionLogDO.java index 3061aeb55..5539a6ab0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/log/RobotTaskDetailActionLogDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/log/RobotTaskDetailActionLogDO.java @@ -28,7 +28,7 @@ public class RobotTaskDetailActionLogDO extends BaseDO { @TableId(type = IdType.ASSIGN_ID) private Long id; /** - * 下发给车机的任务id + * -1代表是任务,其他的是操作的明细 */ private Long commandId; /** @@ -75,5 +75,21 @@ public class RobotTaskDetailActionLogDO extends BaseDO { * 结束时间 */ private LocalDateTime endTime; + /** + * 车辆做任务时,所在的仓库点位地图表id + */ + private Long positionMapId; + /** + * 是否已经统计(0:未统计、1:已经统计) + */ + private Integer alreadyCounted; + /** + * 时长,单位分钟 + */ + private Long duration; + /** + * 这条任务第一次执行的AGV编号 + */ + private String originalRobotNo; } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/positionmap/PositionMapDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/positionmap/PositionMapDO.java index 7099a5160..d2d002890 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/positionmap/PositionMapDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/positionmap/PositionMapDO.java @@ -25,7 +25,6 @@ public class PositionMapDO extends BaseDO { /** * 主键ID */ - @TableId(type = IdType.ASSIGN_ID) private Long id; /** * 楼层 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/positionmap/PositionMapItemDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/positionmap/PositionMapItemDO.java index 727432fd1..eca00f0db 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/positionmap/PositionMapItemDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/positionmap/PositionMapItemDO.java @@ -78,8 +78,12 @@ public class PositionMapItemDO extends BaseDO { */ private Long locationNumber; /** - * 等待点使用状态(0.空闲 1.使用中) + * 等待点使用状态, 0:空闲 ,1:前往停车点(预占用停车点) ,2.使用中(已经在停车位上) */ private Integer useStatus; + /** + * AGV编号 + */ + private String robotNo; } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/robot/RobotTaskDetailDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/robot/RobotTaskDetailDO.java index dc331e323..20e4ce81f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/robot/RobotTaskDetailDO.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/robot/RobotTaskDetailDO.java @@ -142,5 +142,13 @@ public class RobotTaskDetailDO extends BaseDO { */ private Integer occurError; - //todo 需要改为ware_position_map_item的id + /** + * 是否人工干预(0:未干预、1:RCS关闭、2:RCS人工完成、3:远遥取货完成、4:远遥任务完成、5:远遥取货完成和远遥任务完成) + */ + private Integer manualIntervention; + + /** + * 人工干预时间 + */ + private LocalDateTime manualInterventionTime; } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/statistics/RobotWorkingHoursStatisticsDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/statistics/RobotWorkingHoursStatisticsDO.java new file mode 100644 index 000000000..0e2cd7bcb --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/statistics/RobotWorkingHoursStatisticsDO.java @@ -0,0 +1,47 @@ +package cn.iocoder.yudao.module.system.dal.dataobject.statistics; + +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_working_hours_statistics") +@KeySequence("robot_working_hours_statistics_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class RobotWorkingHoursStatisticsDO extends BaseDO { + + /** + * 主键ID + */ + @TableId(type = IdType.ASSIGN_ID) + private Long id; + /** + * 仓库点位地图表id + */ + private Long positionMapId; + /** + * AGV编号 + */ + private String robotNo; + /** + * 时长,单位分钟 + */ + private Long duration; + /** + * 类型(0:空闲时长, 1:任务时长, 2:充电时长) + */ + private Integer durationType; + +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/housearea/HouseAreaMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/housearea/HouseAreaMapper.java index a9c373ef1..d045f9f53 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/housearea/HouseAreaMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/housearea/HouseAreaMapper.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.system.controller.admin.housearea.vo.HouseAreaPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.housearea.HouseAreaDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; /** * 库区 Mapper @@ -24,4 +25,9 @@ public interface HouseAreaMapper extends BaseMapperX { .orderByDesc(HouseAreaDO::getId)); } + /** + * 根据地图id删除 + * @param mapId + */ + void deleteHouseAreaByMapId(@Param("mapId") Long mapId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/houselane/WareHouseLaneMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/houselane/WareHouseLaneMapper.java index e8a21f24e..8516cace2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/houselane/WareHouseLaneMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/houselane/WareHouseLaneMapper.java @@ -27,4 +27,9 @@ public interface WareHouseLaneMapper extends BaseMapperX { .orderByDesc(WareHouseLaneDO::getId)); } + /** + * 根据地图id删除 + * @param mapId + */ + void deleteHouseLaneByMapId(@Param("mapId") Long mapId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/houselocation/WareHouseLocationMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/houselocation/WareHouseLocationMapper.java index cc7d3c875..bcf0a0aa5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/houselocation/WareHouseLocationMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/houselocation/WareHouseLocationMapper.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.dal.mysql.houselocation; 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.houselocation.vo.WareHouseLocationItemRespVO; import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationRespVO; import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationVO; @@ -161,4 +162,24 @@ public interface WareHouseLocationMapper extends BaseMapperX queryLowerLevelsByMapItemId(@Param("mapItemId") Long mapItemId, @Param("locationStorey") Integer locationStorey); + + /** + * 获取这个地图对应的库位和坐标信息 + * @param mapId + * @return + */ + List getLocationsXYByMapId(@Param("mapId") Long mapId); + + /** + * 根据地图id删除 + * @param mapId + */ + void deleteHouseLocationByMapId(@Param("mapId") Long mapId); + + /** + * 查询有货或者有锁定的库位 + * @param mapId + * @return + */ + List getInStockLockLocationByMapId(@Param("mapId") Long mapId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/information/DeviceInformationMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/information/DeviceInformationMapper.java index ae248e6e9..1e9cc28ce 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/information/DeviceInformationMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/information/DeviceInformationMapper.java @@ -39,7 +39,7 @@ public interface DeviceInformationMapper extends BaseMapperX getMistakeTaskByCommandType(@Param("commandTypes") List commandTypes); + + /** + * 获取未统计过的任务操作日志 + * @return + */ + List getUnStatisticsDurationLog(); + + /** + * 查询机器人最后两条任务 + * @param robotNo + * @return + */ + List getLastTwoTask(@Param("robotNo") String robotNo); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/parkingspot/ParkingSpotMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/parkingspot/ParkingSpotMapper.java index 9d1dc1d3f..c444636b8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/parkingspot/ParkingSpotMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/parkingspot/ParkingSpotMapper.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.system.controller.admin.parkingspot.vo.ParkingSpotPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.parkingspot.ParkingSpotDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; /** * 停车点 Mapper @@ -30,4 +31,9 @@ public interface ParkingSpotMapper extends BaseMapperX { .orderByDesc(ParkingSpotDO::getId)); } + /** + * 根据地图id删除 + * @param mapId + */ + void deleteParkingByMapId(@Param("mapId") Long mapId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionChangePointBindingMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionChangePointBindingMapper.java index ad88be360..cc3a65d89 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionChangePointBindingMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionChangePointBindingMapper.java @@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.mqtt.api.path.dto.PositionAllChangePointBindingDT import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionChangePointBindingPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionChangePointBindingDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; /** * 区域变更点绑定 Mapper @@ -33,4 +34,10 @@ public interface PositionChangePointBindingMapper extends BaseMapperX getAllPositionChangePointBinding(); + + /** + * 根据地图id删除 + * @param mapId + */ + void deleteBindIngByMapId(@Param("mapId") Long mapId); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionMapItemMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionMapItemMapper.java index a09a2aaec..ff6e9dfb0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionMapItemMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionMapItemMapper.java @@ -68,4 +68,23 @@ public interface PositionMapItemMapper extends BaseMapperX { * @return */ List selectInWaitList(@Param("list") List list); + + /** + * 删除这个地图的点 + * @param mapId + */ + void deleteByMapId(@Param("mapId") Long mapId); + + /** + * 更新车辆编号 + * @param oldRobotNo + * @param newRobotNo + */ + void updateRobotNo(@Param("oldRobotNo") String oldRobotNo, @Param("newRobotNo") String newRobotNo); + + /** + * 释放车辆 + * @param robotNo + */ + void clearRobotNo(@Param("robotNo") String robotNo); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionMapLineMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionMapLineMapper.java index 5164edd0b..4e03a45be 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionMapLineMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/positionmap/PositionMapLineMapper.java @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.mqtt.api.path.dto.PositionMapLineDTO; import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapLinePageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapLineDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; import java.util.List; @@ -32,4 +33,10 @@ public interface PositionMapLineMapper extends BaseMapperX { * @return */ List getAllPositionMapLine(PositionMapLineDO positionMapLineDO); + + /** + * 根据地图id删除 + * @param mapId + */ + void deleteByMapId(@Param("mapId") Long mapId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/remote/RemoteControllerInformationMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/remote/RemoteControllerInformationMapper.java index 0a8bc73dc..76afd62b2 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/remote/RemoteControllerInformationMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/remote/RemoteControllerInformationMapper.java @@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.module.system.controller.admin.remote.vo.RemoteControllerInformationPageReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.remote.RemoteControllerInformationDO; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; /** * 远遥设备信息 Mapper @@ -33,4 +34,12 @@ public interface RemoteControllerInformationMapper extends BaseMapperX getRemoteControllerRobotNos(); + + /** + * 更新车辆编号 + * @param oldRobotNo + * @param newRobotNo + */ + void updateRobotNo(@Param("oldRobotNo") String oldRobotNo, @Param("newRobotNo") String newRobotNo); + } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotChargeLogMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotChargeLogMapper.java index 8ef7e42f7..b2d7d8a12 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotChargeLogMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotChargeLogMapper.java @@ -36,4 +36,11 @@ public interface RobotChargeLogMapper extends BaseMapperX { */ List getChargeFullRobotNos(@Param("chanceCycle") Integer chanceCycle, @Param("robotNos") List robotNos); + + /** + * + * @param taskDetailId + * @param taskStatus + */ + void updateChargStatusByTaskId(@Param("taskDetailId") Long taskDetailId, @Param("taskStatus") Integer taskStatus); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotMapStopMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotMapStopMapper.java index 5f862fa00..9342af7b4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotMapStopMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotMapStopMapper.java @@ -38,4 +38,11 @@ public interface RobotMapStopMapper extends BaseMapperX { * @param robotNos */ void deleteRobotMapStopByRobotNos(@Param("robotNos") List robotNos); + + /** + * 更新车辆编号 + * @param oldRobotNo + * @param newRobotNo + */ + void updateRobotNo(@Param("oldRobotNo") String oldRobotNo, @Param("newRobotNo") String newRobotNo); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotTaskDetailMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotTaskDetailMapper.java index 07e3fc0a0..9a4e0ab93 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotTaskDetailMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotTaskDetailMapper.java @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotDoingTa 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.RobotTaskPageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.statistics.dto.RobotTaskManualInterventionDTO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO; import com.baomidou.mybatisplus.core.metadata.IPage; import org.apache.ibatis.annotations.Mapper; @@ -159,4 +160,11 @@ public interface RobotTaskDetailMapper extends BaseMapperX { */ IPage getExceptionTaskDetail(@Param("mpPage") IPage mpPage, @Param("pageReqVO") RemoteTaskQueryDTO pageReqVO); + + /** + * 统计任务人工完成/自动完成 + * @param type + * @return + */ + RobotTaskManualInterventionDTO getRobotTaskAutomaticArtificial(@Param("type") String type); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotWarnMsgMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotWarnMsgMapper.java index f727ec3b0..49e1dde1c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotWarnMsgMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/robot/RobotWarnMsgMapper.java @@ -6,6 +6,7 @@ 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.vo.RobotWarnMsgPageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.statistics.dto.RobotWarnMsgClassificationDTO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnMsgDO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -48,4 +49,20 @@ public interface RobotWarnMsgMapper extends BaseMapperX { * @return */ List getFourLevelWarnMsgByDetailIds(@Param("detailIds") List detailIds); + + /** + * 统计故障根因分析 type 1:周, 2:月, 3:季度 + * @param type + * @return + */ + List getRobotWarnMsgClassification(@Param("type") String type); + + /** + * 查询某个时间段的故障原因 + * @param startTime + * @param endTime + * @return + */ + List getRobotWarnMsgByTime(@Param("startTime") String startTime, + @Param("endTime") String endTime); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/statistics/RobotWorkingHoursStatisticsMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/statistics/RobotWorkingHoursStatisticsMapper.java new file mode 100644 index 000000000..ff58f3704 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/statistics/RobotWorkingHoursStatisticsMapper.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.system.dal.mysql.statistics; + +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.statistics.vo.RobotWorkingHoursStatisticsPageReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.statistics.RobotWorkingHoursStatisticsDO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * 车辆工作时长统计 Mapper + * + * @author 陈宾顺 + */ +@Mapper +public interface RobotWorkingHoursStatisticsMapper extends BaseMapperX { + + default PageResult selectPage(RobotWorkingHoursStatisticsPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(RobotWorkingHoursStatisticsDO::getPositionMapId, reqVO.getPositionMapId()) + .eqIfPresent(RobotWorkingHoursStatisticsDO::getRobotNo, reqVO.getRobotNo()) + .eqIfPresent(RobotWorkingHoursStatisticsDO::getDuration, reqVO.getDuration()) + .eqIfPresent(RobotWorkingHoursStatisticsDO::getDurationType, reqVO.getDurationType()) + .betweenIfPresent(RobotWorkingHoursStatisticsDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(RobotWorkingHoursStatisticsDO::getId)); + } + + /** + * 查询工作时间 + * @param type type 1:周, 2:月, 3:季度 + * @param positionMapId 地图Id + * @return + */ + List getRobotWorkHourStatistics(@Param("type") String type, + @Param("positionMapId") String positionMapId); +} \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/wait/MoveToWaitMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/wait/MoveToWaitMapper.java index 0aa57f816..27476cd19 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/wait/MoveToWaitMapper.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/wait/MoveToWaitMapper.java @@ -9,6 +9,8 @@ import org.apache.ibatis.annotations.Mapper; import cn.iocoder.yudao.module.system.controller.admin.wait.vo.*; import cn.iocoder.yudao.module.system.dal.dataobject.wait.MoveToWaitDO; +import org.apache.ibatis.annotations.Param; + /** * 车辆前往等待点记录 Mapper * @@ -26,4 +28,10 @@ public interface MoveToWaitMapper extends BaseMapperX { .orderByDesc(MoveToWaitDO::getId)); } + /** + * 更新车辆编号 + * @param oldRobotNo + * @param newRobotNo + */ + void updateRobotNo(@Param("oldRobotNo") String oldRobotNo, @Param("newRobotNo") String newRobotNo); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/device/DeviceTypeEnum.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/device/DeviceTypeEnum.java index 3e39d0a5c..c426c0eca 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/device/DeviceTypeEnum.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/device/DeviceTypeEnum.java @@ -14,7 +14,8 @@ public enum DeviceTypeEnum { HOIST(5, "提升机"), SIGNAL_LIGHT(6, "信号灯"), BUTTON_BOX(7, "按钮盒"), - DISMANTLING_MACHINE(8, "拆垛机"); + DISMANTLING_MACHINE(8, "拆垛机"), + CAMERA(9, "摄像头"); /** * 类型 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/device/DeviceUseStatusEnum.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/device/DeviceUseStatusEnum.java index 33d62cb85..d3825d2fe 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/device/DeviceUseStatusEnum.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/device/DeviceUseStatusEnum.java @@ -9,13 +9,13 @@ import lombok.Getter; @Getter @AllArgsConstructor public enum DeviceUseStatusEnum { - IDLE("IDLE", "空闲"), - USEING("USEING", "使用中"); + IDLE(0, "空闲"), + USEING(1, "使用中"); /** * 类型 */ - private final String type; + private final Integer type; /** * 说明 */ diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/item/UseStatusEnum.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/item/UseStatusEnum.java new file mode 100644 index 000000000..760fc893b --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/item/UseStatusEnum.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.system.enums.item; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum UseStatusEnum { + + FREE(0,"空闲"), + PRE_OCCUPANCY(1,"前往停车点(预占用停车点)"), + USEING(2,"使用中(已经在停车位上)"); + /** + * 类型 + */ + private final Integer type; + + private final String msg; + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/redis/RobotCacheLockEnum.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/redis/RobotCacheLockEnum.java index fc06d6712..c075ce4f4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/redis/RobotCacheLockEnum.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/redis/RobotCacheLockEnum.java @@ -11,8 +11,11 @@ import lombok.Getter; public enum RobotCacheLockEnum { TASK_NO("task:robot:no", "任务号"), + MOVE_TASK_NO("task:robot:no:move", "移动任务号"), + CHARGE_TASK_NO("task:robot:no:charge", "自动充电任务号"), ROBOT_TASK_ADD_LOCK("robot:task:add:lock", "所有创建机器人任务的锁"), ROBOT_RCS_HEART_BEAT_LOCK("robot:rcs:heart:beat:lock", "RCS维持与车机心跳的锁"), + ROBOT_STATISTICS_DURATION_LOCK("robot:statistics:duration:lock", "统计车辆工作时长的锁"), //取消订单、修改优先级 ROBOT_TASK_DISTRIBUTE_LOCK("robot:task:distribute:lock", "下发任务给机器人的锁"), ROBOT_TASK_LOCATION_LOCK("robot:task:location:lock", "库位取/放任务下发互斥锁(仅仅锁某个库位)"), diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/actionlog/CommandIdEnum.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/actionlog/CommandIdEnum.java new file mode 100644 index 000000000..54113786b --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/actionlog/CommandIdEnum.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.system.enums.robot.actionlog; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum CommandIdEnum { + + // 只有任务的是 -1, 其他的明细都是空 + TASK(-1,"任务"); + /** + * 类型 + */ + private final Integer type; + /** + * 说明 + */ + private final String msg; +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/statistics/DurationTypeEnum.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/statistics/DurationTypeEnum.java new file mode 100644 index 000000000..68be4121b --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/statistics/DurationTypeEnum.java @@ -0,0 +1,33 @@ +package cn.iocoder.yudao.module.system.enums.robot.statistics; + +import cn.iocoder.yudao.module.system.enums.path.PathTaskTypeEnum; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum DurationTypeEnum { + FREE_TIME(0,"空闲时长"), + TASK_TIME(1,"任务时长"), + CHARGE_TIME(2,"充电时长"); + /** + * 类型 + */ + private final Integer type; + /** + * 说明 + */ + private final String msg; + + /** + * 获取工作时长的类型 + * @return + */ + public static Integer getDurationTypeByTaskType(String commonType) { + if (PathTaskTypeEnum.CHARGE.getType().equals(commonType) + || PathTaskTypeEnum.AUTO_CHARGE.getType().equals(commonType)) { + return CHARGE_TIME.type; + } + return CHARGE_TIME.type; + } +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/statistics/TimeTypeEnum.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/statistics/TimeTypeEnum.java new file mode 100644 index 000000000..7c2b11364 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/statistics/TimeTypeEnum.java @@ -0,0 +1,20 @@ +package cn.iocoder.yudao.module.system.enums.robot.statistics; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public enum TimeTypeEnum { + WEEK("1","周"), + MONTH("2","月"), + QUARTER("3","季度"); + /** + * 类型 + */ + private final String type; + /** + * 说明 + */ + private final String msg; +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/task/RobotTaskManualInterventionEnum.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/task/RobotTaskManualInterventionEnum.java new file mode 100644 index 000000000..75639f520 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/enums/robot/task/RobotTaskManualInterventionEnum.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.system.enums.robot.task; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * robot_task_detail 的 manual_intervention 是否人工干预(0:未干预、1:RCS关闭、2:RCS人工完成、3:远遥取货完成、4:远遥任务完成、5:远遥取货完成和远遥任务完成)', + * + */ +@Getter +@AllArgsConstructor +public enum RobotTaskManualInterventionEnum { + + UN_DO(0,"未干预"), + RCS_CLOSE(1,"RCS关闭"), + RCS_DONE(2,"RCS人工完成"), + REMOTE_DO_TAKE(3,"远遥取货完成"), + REMOTE_TASK_DONE(4,"远遥任务完成"), + REMOTE_TAKE_TASK(5,"远遥取货完成和远遥任务完成"); + /** + * 类型 + */ + private final Integer type; + private final String msg; +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/robot/RobotJob.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/robot/RobotJob.java index 93df86e1e..06e8faf9f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/robot/RobotJob.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/job/robot/RobotJob.java @@ -4,12 +4,12 @@ import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.framework.tenant.core.job.TenantJob; import cn.iocoder.yudao.module.system.enums.redis.RobotCacheLockEnum; import cn.iocoder.yudao.module.system.service.robot.RobotInformationService; -import cn.iocoder.yudao.module.system.service.robot.RobotTaskService; import cn.iocoder.yudao.module.system.service.robot.job.AutoChargeService; import cn.iocoder.yudao.module.system.service.robot.job.CycleService; import cn.iocoder.yudao.module.system.service.robot.job.DistributeTasksService; import cn.iocoder.yudao.module.system.service.robot.job.RobotTaskAutoMoveService; import cn.iocoder.yudao.module.system.service.robot.pathplanning.RobotPathPlanningService; +import cn.iocoder.yudao.module.system.service.statistics.RobotWorkingHoursStatisticsService; import cn.iocoder.yudao.module.system.util.redis.RedissonUtils; import com.xxl.job.core.handler.annotation.XxlJob; import lombok.extern.slf4j.Slf4j; @@ -51,6 +51,9 @@ public class RobotJob { @Resource private RobotInformationService informationService; + @Resource + private RobotWorkingHoursStatisticsService robotWorkingHoursStatisticsService; + //下发自动移库任务--- 废弃---产品不要自动移库 // @XxlJob("DistributeAutoMoveJob") @@ -157,4 +160,24 @@ public class RobotJob { throw exception(REDISSON_NOT_OBTAIN_LOCK); } } + + /** + * 统计车辆工作时长 + */ + @XxlJob("StatisticsDurationJob") + @TenantJob + public void statisticsDuration() { + RLock lock = redissonUtils.getLock(RobotCacheLockEnum.ROBOT_STATISTICS_DURATION_LOCK.getKey()); + if (lock.tryLock()){ + try { + log.info("----统计时长开始----"); + TenantContextHolder.setTenantId(1L); + robotWorkingHoursStatisticsService.statisticsRobotDuration(); + } finally { + lock.unlock(); + } + }else { + throw exception(REDISSON_NOT_OBTAIN_LOCK); + } + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/schedul/ScheduledTasks.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/schedul/ScheduledTasks.java new file mode 100644 index 000000000..0a1f30b37 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/schedul/ScheduledTasks.java @@ -0,0 +1,119 @@ +package cn.iocoder.yudao.module.system.schedul; + +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; +import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; +import cn.iocoder.yudao.module.system.api.robot.websocket.RobotInformationVO; +import cn.iocoder.yudao.module.system.constant.CommonConstant; +import cn.iocoder.yudao.module.system.constant.area.FloorAreaConstant; +import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; +import cn.iocoder.yudao.module.system.constant.webSocket.WebSocketConstant; +import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO; +import cn.iocoder.yudao.module.system.service.positionmap.PositionMapService; +import cn.iocoder.yudao.module.system.util.redis.RedisUtil; +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +@EnableScheduling +@Component +@Slf4j +public class ScheduledTasks { + + @Resource + private PositionMapService positionMapService; + + @Resource + private RedisUtil redisUtil; + + @Resource + public WebSocketSenderApi webSocketSenderApi; + + private static final ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); + + // 这个方法将每200毫秒执行一次 +// @Scheduled(fixedDelay = 300, timeUnit = TimeUnit.MILLISECONDS) + public void executeTask() { + fixedThreadPool.execute(new Runnable() { + @Override + public void run() { + sendData(); + } + }); + } + + public void sendData() { + TenantContextHolder.setTenantId(1L); + Object o = redisUtil.get(FloorAreaConstant.FLOOR_AREA_ALL); + List allMap = null; + if (ObjectUtil.isEmpty(o)) { + allMap = positionMapService.getAllMap(); + if (ObjectUtil.isEmpty(allMap)) { + return; + } + redisUtil.set(FloorAreaConstant.FLOOR_AREA_ALL,JSON.toJSONString(allMap),60); + }else { + allMap = JSON.parseArray(String.valueOf(o), PositionMapDO.class); + } + + for (PositionMapDO positionMap : allMap) { + String key = FloorAreaConstant.FLOOR_AREA_ROBOT + positionMap.getFloor() + CommonConstant.SYMBOL + positionMap.getArea(); + Map data = redisUtil.hmget(key); + if (ObjectUtil.isEmpty(data)) { + continue; + } + + Map map = new HashMap<>(); + data.forEach((k,v) ->{ + Object skuInfo = redisUtil.get(RobotTaskChcheConstant.ROBOT_TASK_SKU_INFO + k); + if (ObjectUtil.isNotEmpty(skuInfo)) { + RobotInformationVO informationVO = JSON.parseObject(v.toString(), RobotInformationVO.class); + informationVO.setSkuInfo(skuInfo); + map.put(k,informationVO); + }else { + map.put(k,v); + } + }); + +// log.info("3D发送数据:{}", JSON.toJSONString(map)); + webSocketSenderApi.sendObject(positionMap.getFloor() + CommonConstant.SYMBOL + positionMap.getArea(), WebSocketConstant.THREE_D_MAP_PUSH, map); + } + } + + + + + + + + + + + + + + + + + + + + + + + + + + + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java index 791a3ef1d..817ff95d8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java @@ -105,8 +105,11 @@ public class AdminAuthServiceImpl implements AdminAuthService { socialUserService.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); } + + String clientId = ObjectUtil.isNotEmpty(reqVO.getClientid()) ? reqVO.getClientid() : OAuth2ClientConstants.CLIENT_ID_DEFAULT; + // 创建 Token 令牌,记录登录日志 - return createTokenAfterLoginSuccess(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME); + return createTokenAfterLoginSuccess(user.getId(), reqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME, clientId); } @Override @@ -131,7 +134,7 @@ public class AdminAuthServiceImpl implements AdminAuthService { } // 创建 Token 令牌,记录登录日志 - return createTokenAfterLoginSuccess(user.getId(), reqVO.getMobile(), LoginLogTypeEnum.LOGIN_MOBILE); + return createTokenAfterLoginSuccess(user.getId(), reqVO.getMobile(), LoginLogTypeEnum.LOGIN_MOBILE, OAuth2ClientConstants.CLIENT_ID_DEFAULT); } private void createLoginLog(Long userId, String username, @@ -169,7 +172,7 @@ public class AdminAuthServiceImpl implements AdminAuthService { } // 创建 Token 令牌,记录登录日志 - return createTokenAfterLoginSuccess(user.getId(), user.getUsername(), LoginLogTypeEnum.LOGIN_SOCIAL); + return createTokenAfterLoginSuccess(user.getId(), user.getUsername(), LoginLogTypeEnum.LOGIN_SOCIAL,OAuth2ClientConstants.CLIENT_ID_DEFAULT); } @VisibleForTesting @@ -191,12 +194,12 @@ public class AdminAuthServiceImpl implements AdminAuthService { } } - private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType) { + private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId, String username, LoginLogTypeEnum logType, String clientId) { // 插入登陆日志 createLoginLog(userId, username, logType, LoginResultEnum.SUCCESS); // 创建访问令牌 OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(userId, getUserType().getValue(), - OAuth2ClientConstants.CLIENT_ID_DEFAULT, null); + clientId, null); // 构建返回结果 return AuthConvert.INSTANCE.convert(accessTokenDO); } @@ -256,7 +259,7 @@ public class AdminAuthServiceImpl implements AdminAuthService { Long userId = userService.registerUser(registerReqVO); // 3. 创建 Token 令牌,记录登录日志 - return createTokenAfterLoginSuccess(userId, registerReqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME); + return createTokenAfterLoginSuccess(userId, registerReqVO.getUsername(), LoginLogTypeEnum.LOGIN_USERNAME,OAuth2ClientConstants.CLIENT_ID_DEFAULT); } @VisibleForTesting diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/bulletinboard/BulletinBoardServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/bulletinboard/BulletinBoardServiceImpl.java index cc6ce95db..50435c3e3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/bulletinboard/BulletinBoardServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/bulletinboard/BulletinBoardServiceImpl.java @@ -4,9 +4,10 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; +import cn.iocoder.yudao.module.system.api.robot.websocket.RobotStatusDataPoseDTO; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.controller.admin.bulletinboard.vo.BulletinBoardVO; import cn.iocoder.yudao.module.system.controller.admin.bulletinboard.vo.RobotElectricityLevelVO; @@ -19,6 +20,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformati 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.RobotWarnMsgDO; +import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum; import cn.iocoder.yudao.module.system.enums.robot.RobotTaskDetailStatusEnum; import cn.iocoder.yudao.module.system.service.dict.DictDataService; import cn.iocoder.yudao.module.system.service.information.DeviceInformationService; @@ -116,7 +118,7 @@ public class BulletinBoardServiceImpl implements BulletinBoardService { map = agvListStatusInfo.stream().collect(Collectors.toMap(RobotInfoStatusVO::getMacAddress, Function.identity())); } for (RobotInformationDO robotInformationDO : allRobot) { - String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + robotInformationDO.getMacAddress(); + String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT + robotInformationDO.getMacAddress(); Object object = redisUtil.get(pose2dKey); RobotStatusDataPoseDTO robotStatusDataPoseDTO = JSONUtil.toBean((String) object, RobotStatusDataPoseDTO.class); if (robotStatusDataPoseDTO != null) { @@ -127,7 +129,10 @@ public class BulletinBoardServiceImpl implements BulletinBoardService { BeanUtil.copyProperties(item, robotElectricityLevelVO); } robotElectricityLevelVO.setRobotNo(robotInformationDO.getRobotNo()); - robotElectricityLevelVO.setBatSoc(robotStatusDataPoseDTO.getBatSoc()); + String socByMac = robotInformationService.getSocByMac(robotInformationDO.getMacAddress(), ZeroOneEnum.ONE.getType()); + if (ObjectUtil.isNotEmpty(socByMac)) { + robotElectricityLevelVO.setBatSoc(socByMac); + } robotElectricityLevelVOS.add(robotElectricityLevelVO); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/housearea/HouseAreaService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/housearea/HouseAreaService.java index 2bfd7e4cd..1dcdf3714 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/housearea/HouseAreaService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/housearea/HouseAreaService.java @@ -75,4 +75,10 @@ public interface HouseAreaService extends IService { * @param id */ void delete(Long id); + + /** + * 根据地图id删除 + * @param mapId + */ + void deleteHouseAreaByMapId(Long mapId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/housearea/HouseAreaServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/housearea/HouseAreaServiceImpl.java index 90a9fde38..354a2a32b 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/housearea/HouseAreaServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/housearea/HouseAreaServiceImpl.java @@ -187,4 +187,9 @@ public class HouseAreaServiceImpl extends ServiceImpl { * @param id */ void delete(Long id); + + /** + * 根据地图id删除 + * @param mapId + */ + void deleteHouseLaneByMapId(Long mapId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/houselane/WareHouseLaneServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/houselane/WareHouseLaneServiceImpl.java index 262b98bde..bfdb71f9c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/houselane/WareHouseLaneServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/houselane/WareHouseLaneServiceImpl.java @@ -157,4 +157,9 @@ public class WareHouseLaneServiceImpl extends ServiceImpl { * @param id */ void updateLocationAreaNameEmptyByAreaId(Long areaId); + + /** + * 获取这个地图对应的库位和坐标信息 + * @param mapId + * @return + */ + List getLocationsXYByMapId(Long mapId); + + /** + * 根据地图id删除 + * @param mapId + */ + void deleteHouseLocationByMapId(Long mapId); + + List getInStockLockLocationByMapId(Long mapId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/houselocation/HouseLocationServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/houselocation/HouseLocationServiceImpl.java index 02443e242..b2afc07c0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/houselocation/HouseLocationServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/houselocation/HouseLocationServiceImpl.java @@ -5,28 +5,22 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.module.system.api.robot.vo.RobotInformationVO; -import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationPageReqVO; -import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationRespVO; -import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationSaveReqVO; -import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.WareHouseLocationVO; +import cn.iocoder.yudao.module.system.constant.CommonConstant; +import cn.iocoder.yudao.module.system.controller.admin.houselocation.vo.*; import cn.iocoder.yudao.module.system.controller.admin.log.vo.UserOperationLogSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper; -import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum; import cn.iocoder.yudao.module.system.enums.robot.LocationEnableEnum; import cn.iocoder.yudao.module.system.enums.robot.LocationLockEnum; import cn.iocoder.yudao.module.system.enums.robot.LocationUseStatusEnum; import cn.iocoder.yudao.module.system.service.log.UserOperationLogService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; -import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -80,7 +74,7 @@ public class HouseLocationServiceImpl extends ServiceImpl getLocationsXYByMapId(Long mapId) { + return houseLocationMapper.getLocationsXYByMapId(mapId); + } + + @Override + public void deleteHouseLocationByMapId(Long mapId) { + houseLocationMapper.deleteHouseLocationByMapId(mapId); + } + + /** + * 查询有货或者有锁定的库位 + * @param mapId + * @return + */ + @Override + public List getInStockLockLocationByMapId(Long mapId) { + return houseLocationMapper.getInStockLockLocationByMapId(mapId); + } + @Override @Transactional(rollbackFor = Exception.class) public void updateHouseLocationList(List list) { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationService.java index ae3f59198..ce787b454 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationService.java @@ -137,4 +137,10 @@ public interface DeviceInformationService extends IService * @return */ String getMapImageUrl(Integer deviceType); + + /** + * 根据地图ID删除 + * @param id + */ + void deleteDeviceByMapId(Long id); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationServiceImpl.java index 9c6c1eca8..8932804a6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/information/DeviceInformationServiceImpl.java @@ -32,6 +32,7 @@ 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.positionmap.PositionMapItemService; import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService; +import cn.iocoder.yudao.module.system.util.aes.AESEncryptionUtil; import cn.iocoder.yudao.module.system.util.modbus3.ModbusUtils; import cn.iocoder.yudao.module.system.util.redis.RedisUtil; import com.alibaba.fastjson.JSON; @@ -42,6 +43,7 @@ import com.serotonin.modbus4j.ModbusMaster; import com.serotonin.modbus4j.exception.ModbusInitException; import com.serotonin.modbus4j.exception.ModbusTransportException; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -92,6 +94,9 @@ public class DeviceInformationServiceImpl extends ServiceImpl map = new HashMap(); + Map map = new HashMap(); map = gson.fromJson(dataJson, map.getClass()); - map.put("deviceType",updateObj.getDeviceType()); - map.put("deviceNo",updateObj.getDeviceNo()); - map.put("mapImageUrl",updateObj.getMapImageUrl()); + map.put("deviceType", updateObj.getDeviceType()); + map.put("deviceNo", updateObj.getDeviceNo()); + map.put("mapImageUrl", updateObj.getMapImageUrl()); positionMapItem.setDataJson(JSON.toJSONString(map)); positionMapItemService.updateById(positionMapItem); @@ -228,7 +247,7 @@ public class DeviceInformationServiceImpl extends ServiceImpl { + list.get(2).forEach(a -> { a.setPositionMapItemId(null); a.setPositionMapId(null); }); @@ -349,7 +368,9 @@ public class DeviceInformationServiceImpl extends ServiceImpl getTaskDetailActionLogPage(RobotTaskDetailActionLogPageReqVO pageReqVO); - /** - * 添加到缓存 - * @param logs - */ - void addLogInCache(List logs); - /** * 设置上一条数据完成(非主任务) * @param robotNo @@ -66,11 +60,11 @@ public interface RobotTaskDetailActionLogService { RobotTaskDetailActionLogDO setPreviousTaskDoneByOrderId(Long orderId); /** - * 获取车辆的最后一条任务 + * 获取车辆的最后一条任务(限处理中的任务使用) * @param robotNo * @return */ - RobotTaskDetailActionLogDO getLastTaskByRobotNo(String robotNo); + RobotTaskDetailActionLogDO getLastTaskByRobotNo(String robotNo, Integer commandId); /** * 根据任务id查询 @@ -83,4 +77,17 @@ public interface RobotTaskDetailActionLogService { * @param taskDetailActionLog */ void updateTaskDetailActionLogs(List taskDetailActionLog); + + /** + * 获取未统计过的任务操作日志 + * @return + */ + List getUnStatisticsDurationLog(); + + /** + * 获取这台车最后一次执行的任务(查真实的分配记录) + * @param robotNo + * @return + */ + RobotTaskDetailActionLogDO getOriginalLastTaskByRobotNo(String robotNo); } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/log/RobotTaskDetailActionLogServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/log/RobotTaskDetailActionLogServiceImpl.java index 66c515009..e43ef1f68 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/log/RobotTaskDetailActionLogServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/log/RobotTaskDetailActionLogServiceImpl.java @@ -2,18 +2,12 @@ package cn.iocoder.yudao.module.system.service.log; import cn.hutool.core.util.ObjectUtil; 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.enums.robot.actionlog.ActionStatusEnum; -import cn.iocoder.yudao.module.system.util.redis.RedisUtil; -import com.alibaba.fastjson.JSON; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Async; +import cn.iocoder.yudao.module.system.enums.robot.actionlog.CommandIdEnum; import org.springframework.stereotype.Service; import javax.annotation.Resource; import org.springframework.validation.annotation.Validated; @@ -39,11 +33,6 @@ public class RobotTaskDetailActionLogServiceImpl implements RobotTaskDetailActio @Resource private RobotTaskDetailActionLogMapper taskDetailActionLogMapper; - @Resource - private RedisUtil redisUtil; - - @Value("${zn.robot_doing_action.action_entity_cache_time:3600*8}") - private Long robotPositionCacheTime; @Override public Long createTaskDetailActionLog(RobotTaskDetailActionLogSaveReqVO createReqVO) { @@ -87,34 +76,33 @@ public class RobotTaskDetailActionLogServiceImpl implements RobotTaskDetailActio return taskDetailActionLogMapper.selectPage(pageReqVO); } - @Override - public void addLogInCache(List logs) { - /*for (RobotTaskDetailActionLogDO v : logs) { - redisUtil.set(RobotTaskChcheConstant.ROBOT_ACTION_LOG_ENTITY+v.getCommandId(), - JSON.toJSONString(v),robotPositionCacheTime); - }*/ - } @Override public RobotTaskDetailActionLogDO setPreviousTaskDoneByOrderId(Long orderId) { - RobotTaskDetailActionLogDO lastLog = taskDetailActionLogMapper.selectOne(new LambdaQueryWrapperX() + List lastLogs = taskDetailActionLogMapper.selectList(new LambdaQueryWrapperX() + .eq(RobotTaskDetailActionLogDO::getTaskDetailId, orderId) + .isNull(RobotTaskDetailActionLogDO::getCommandId) + .isNull(RobotTaskDetailActionLogDO::getEndTime)); + if (ObjectUtil.isNotEmpty(lastLogs)) { + for (RobotTaskDetailActionLogDO lastLog : lastLogs) { + lastLog.setEndTime(LocalDateTime.now()); + lastLog.setActionStatus(ActionStatusEnum.DONE.getType()); + } + taskDetailActionLogMapper.updateById(lastLogs); + return lastLogs.get(0); + } + + return taskDetailActionLogMapper.selectOne(new LambdaQueryWrapperX() .eq(RobotTaskDetailActionLogDO::getTaskDetailId, orderId) - .ne(RobotTaskDetailActionLogDO::getCommandId, -1) .orderByDesc(RobotTaskDetailActionLogDO::getCreateTime) .last("limit 1")); - if (ObjectUtil.isNotEmpty(lastLog) && ObjectUtil.isEmpty(lastLog.getCommandId())) { - lastLog.setEndTime(LocalDateTime.now()); - lastLog.setActionStatus(ActionStatusEnum.DONE.getType()); - taskDetailActionLogMapper.updateById(lastLog); - } - return lastLog; } @Override - public RobotTaskDetailActionLogDO getLastTaskByRobotNo(String robotNo) { + public RobotTaskDetailActionLogDO getLastTaskByRobotNo(String robotNo, Integer commandId) { return taskDetailActionLogMapper.selectOne(new LambdaQueryWrapperX() .eq(RobotTaskDetailActionLogDO::getRobotNo, robotNo) - .eq(RobotTaskDetailActionLogDO::getCommandId, -1) + .eqIfPresent(RobotTaskDetailActionLogDO::getCommandId, commandId) .orderByDesc(RobotTaskDetailActionLogDO::getCreateTime) .last("limit 1")); } @@ -130,4 +118,27 @@ public class RobotTaskDetailActionLogServiceImpl implements RobotTaskDetailActio taskDetailActionLogMapper.updateById(taskDetailActionLog); } + /** + * 获取未统计过的任务操作日志 + * @return + */ + @Override + public List getUnStatisticsDurationLog() { + return taskDetailActionLogMapper.getUnStatisticsDurationLog(); + } + + /** + * 查这台车最后一次分配的任务 + * @param robotNo + * @return + */ + @Override + public RobotTaskDetailActionLogDO getOriginalLastTaskByRobotNo(String robotNo) { + return taskDetailActionLogMapper.selectOne(new LambdaQueryWrapperX() + .eq(RobotTaskDetailActionLogDO::getOriginalRobotNo, robotNo) + .eq(RobotTaskDetailActionLogDO::getCommandId, CommandIdEnum.TASK.getType()) + .orderByDesc(RobotTaskDetailActionLogDO::getCreateTime) + .last("limit 1")); + } + } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/parkingspot/ParkingSpotService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/parkingspot/ParkingSpotService.java index 89710fa7b..dcaf84786 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/parkingspot/ParkingSpotService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/parkingspot/ParkingSpotService.java @@ -68,4 +68,10 @@ public interface ParkingSpotService extends IService { * @param list */ void batchSaveOrEditOrDel(Long positionMapId, List> list); + + /** + * 根据地图id删除 + * @param mapId + */ + void deleteParkingByMapId(Long mapId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/parkingspot/ParkingSpotServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/parkingspot/ParkingSpotServiceImpl.java index 3deabc52d..b53d5ea96 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/parkingspot/ParkingSpotServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/parkingspot/ParkingSpotServiceImpl.java @@ -84,4 +84,9 @@ public class ParkingSpotServiceImpl extends ServiceImpl positionLines = positionMapLineMapper.getAllPositionMapLine(positionMapLineDO); -// List positionLines = positionMapLineMapper.selectList(new LambdaQueryWrapperX()); if (ObjectUtil.isEmpty(positionLines)) { throw exception(PATH_PLANNING_NOT_EXISTS); } @@ -150,7 +157,7 @@ public class PathPlanningServiceImpl implements PathPlanningService { assembleDataToPP(relatedPathNode, positionMapLineDOS); } - pathPlanningApi.synchronousLineObject(new PositionMapLineDTO(), PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_LINE_END); + commonApi.commonMethod(new PositionMapLineDTO(), PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_LINE_END); } /** @@ -160,7 +167,7 @@ public class PathPlanningServiceImpl implements PathPlanningService { */ @Override public void synchronousAllItem(PositionMapSaveReqVO data) { - log.info("synchronousAllItem----start"); + log.info("开始同步点位信息"); List positionMapDOS = positionMapMapper.selectList(new LambdaQueryWrapperX() .eq(ObjectUtil.isNotEmpty(data.getFloor()), PositionMapDO::getFloor, data.getFloor()) .eq(ObjectUtil.isNotEmpty(data.getArea()), PositionMapDO::getArea, data.getArea())); @@ -180,11 +187,10 @@ public class PathPlanningServiceImpl implements PathPlanningService { relatedPathNode.setType(PathTypeEnum.INIT.getType()); relatedPathNode.setControl_nodes(positionMapItemSynDTOS); - log.info("synchronousAllItem----doing"); - pathPlanningApi.synchronousLineObject(relatedPathNode, PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_NODE); + commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_NODE); } - log.info("synchronousAllItem----end"); + log.info("同步点位信息结束"); } /** @@ -230,7 +236,7 @@ public class PathPlanningServiceImpl implements PathPlanningService { relatedPathNode.setArea(positionMapDO.getArea()); relatedPathNode.setControl_nodes(list); - pathPlanningApi.synchronousLineObject(relatedPathNode, PathPlanningTopicConstant.ADD_MAP_LINE); + commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.ADD_MAP_LINE); } /** @@ -260,7 +266,7 @@ public class PathPlanningServiceImpl implements PathPlanningService { ids.add(data.getId()); relatedPathNode.setIds(ids); - pathPlanningApi.synchronousLineObject(relatedPathNode, PathPlanningTopicConstant.DELETE_MAP_LINE); + commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.DELETE_MAP_LINE); } @@ -308,7 +314,7 @@ public class PathPlanningServiceImpl implements PathPlanningService { relatedPathNode.setType(PathTypeEnum.UPDATE.getType()); relatedPathNode.setControl_nodes(list); - pathPlanningApi.synchronousLineObject(relatedPathNode, PathPlanningTopicConstant.UPDATE_MAP_LINE); + commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.UPDATE_MAP_LINE); } /** @@ -342,7 +348,7 @@ public class PathPlanningServiceImpl implements PathPlanningService { .y(Double.valueOf(positionMapItemDO.getActualLocationY())) .sortNum(positionMapItemDO.getSortNum()) .yaw(Double.parseDouble(positionMapItemDO.getLocationYaw())) - .id(positionMapItemDO.getId()).build(); + .id(positionMapItemDO.getId()+"").build(); PositionMapItemPathDTO PositionMapItemPathDTO = new PositionMapItemPathDTO(); PositionMapItemPathDTO.setFloor(positionMapDO.getFloor()); @@ -350,7 +356,7 @@ public class PathPlanningServiceImpl implements PathPlanningService { PositionMapItemPathDTO.setType(PathTypeEnum.ADD.getType()); PositionMapItemPathDTO.setControl_nodes(Arrays.asList(build)); - pathPlanningApi.synchronousLineObject(PositionMapItemPathDTO, PathPlanningTopicConstant.ADD_MAP_NODE); + commonApi.commonMethod(PositionMapItemPathDTO, PathPlanningTopicConstant.ADD_MAP_NODE); } /** @@ -384,7 +390,7 @@ public class PathPlanningServiceImpl implements PathPlanningService { PositionMapItemPathDTO.setType(PathTypeEnum.DELETE.getType()); PositionMapItemPathDTO.setIds(Arrays.asList(data.getId())); - pathPlanningApi.synchronousLineObject(PositionMapItemPathDTO, PathPlanningTopicConstant.DELETE_MAP_NODE); + commonApi.commonMethod(PositionMapItemPathDTO, PathPlanningTopicConstant.DELETE_MAP_NODE); } @Override @@ -413,7 +419,7 @@ public class PathPlanningServiceImpl implements PathPlanningService { .y(Double.valueOf(positionMapItemDO.getActualLocationY())) .sortNum(positionMapItemDO.getSortNum()) .yaw(Double.parseDouble(positionMapItemDO.getLocationYaw())) - .id(positionMapItemDO.getId()).build(); + .id(positionMapItemDO.getId()+"").build(); PositionMapItemPathDTO PositionMapItemPathDTO = new PositionMapItemPathDTO(); PositionMapItemPathDTO.setFloor(positionMapDO.getFloor()); @@ -421,13 +427,13 @@ public class PathPlanningServiceImpl implements PathPlanningService { PositionMapItemPathDTO.setType(PathTypeEnum.UPDATE.getType()); PositionMapItemPathDTO.setControl_nodes(Arrays.asList(build)); - pathPlanningApi.synchronousLineObject(PositionMapItemPathDTO, PathPlanningTopicConstant.UPDATE_MAP_NODE); + commonApi.commonMethod(PositionMapItemPathDTO, PathPlanningTopicConstant.UPDATE_MAP_NODE); } @Override public void robotDimensions() { List list = informationMapper.selectRobotDimensions(); - pathPlanningApi.synchronousLineObject(list, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS); + commonApi.commonMethod(list, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS); } /** @@ -437,12 +443,39 @@ public class PathPlanningServiceImpl implements PathPlanningService { */ @Override public void sendPosedsToRobot(String message) { - PathPosedsDTO pathPosedsDTO = JSON.parseObject(message, PathPosedsDTO.class); - String mac = robotInformationService.getMacByRobotNo(pathPosedsDTO.getRobotNo()); + PathToRobotDTO pathRobotDTO = JSON.parseObject(message, PathToRobotDTO.class); + String mac = robotInformationService.getMacByRobotNo(pathRobotDTO.getRobotNo()); String topic = RobotTopicConstant.ROBOT_TASK_MOVE_TOPIC + mac; - commonApi.commonMethodStr(message, topic); - if(RobotCommandTypeEnum.SWITCH_MAP.getType().equals(pathPosedsDTO.getCommandType())) { - controllerInformationService.robotChangeSpeed(pathPosedsDTO); + if(RobotCommandTypeEnum.SWITCH_MAP.getType().equals(pathRobotDTO.getCommandType())) { + String mapFileName = positionMapService.getMapFileNameByFloorAndAreaName(pathRobotDTO.getArg().getFloor(),pathRobotDTO.getArg().getAreaId()); + pathRobotDTO.getArg().setMapName(mapFileName); + controllerInformationService.robotChangeSpeed(pathRobotDTO); + commonApi.commonMethodStr(JSON.toJSONString(pathRobotDTO), topic); + RobotTaskDetailActionLogDO actionLog = taskDetailActionLogService.getLastTaskByRobotNo(pathRobotDTO.getRobotNo(),null); + if (ObjectUtil.isNotEmpty(actionLog)) { + //为了统计各个地图的工作时间 + RobotTaskDetailActionLogSaveReqVO data = new RobotTaskDetailActionLogSaveReqVO(); + data.setActionMsg(actionLog.getRobotNo() + " 切换为 " + pathRobotDTO.getArg().getFloor()+"层 " + pathRobotDTO.getArg().getAreaId()); + data.setRobotNo(actionLog.getRobotNo()); + data.setTaskDetailId(actionLog.getTaskDetailId()); + data.setTaskStage(actionLog.getTaskStage()); + data.setCommandType(actionLog.getCommandType()); + data.setTaskNo(actionLog.getTaskNo()); + data.setActionStatus(actionLog.getActionStatus()); + data.setStartTime(LocalDateTime.now()); + Long mapId = robotInformationService.getRobotMapIdByRobotNo(actionLog.getRobotNo()); + if (ObjectUtil.isNotEmpty(mapId)) { + data.setPositionMapId(mapId); + } + taskDetailActionLogService.createTaskDetailActionLog(data); + } + if (ObjectUtil.isNotEmpty(actionLog) && ObjectUtil.isNotEmpty(actionLog.getStartTime())) { + Duration duration = Duration.between(actionLog.getCreateTime(), LocalDateTime.now()); + actionLog.setDuration(duration.toMinutes()); + taskDetailActionLogService.updateTaskDetailActionLogs(Collections.singletonList(actionLog)); + } + }else { + commonApi.commonMethodStr(message, topic); } } @@ -466,12 +499,13 @@ public class PathPlanningServiceImpl implements PathPlanningService { */ @Override public void pathPlanningMovePose(String message) { + log.info("车辆即将行走的点位 :{}",message); PathPlanningMovePoseVO robotStatusData = JSON.parseObject(message, PathPlanningMovePoseVO.class); String mac = robotInformationService.getMacByRobotNo(robotStatusData.getRobotNo()); String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + mac; Object floorAreaObject = redisUtil.get(floorAreaKey); FloorZoneDTO floorZoneDTO = JSONUtil.toBean((String) floorAreaObject, FloorZoneDTO.class); - webSocketSenderApi.sendObject(floorZoneDTO.getFloor() + "_" + floorZoneDTO.getArea(), + webSocketSenderApi.sendObject(floorZoneDTO.getFloor() + CommonConstant.SYMBOL + floorZoneDTO.getArea(), WebSocketConstant.PLANNING_MOVE_POSE, message); } @@ -481,12 +515,16 @@ public class PathPlanningServiceImpl implements PathPlanningService { @Override public void simulationRobotPoseRequest() { - if (!isSimulation) { - log.info("非仿真环境,不同步初始点位信息"); + if (!sendRobotInitPose) { + log.info("不同步初始点位信息"); return; } CommonConfigDO config = configService.getConfig(CommandConfigTypeEnum.SIMULATION_CONFIG.getType().longValue()); + if (ObjectUtil.isEmpty(config)) { + log.info("未配置默认地图"); + return; + } PositionMapDO positionMap = null; if (ObjectUtil.isEmpty(config) || ObjectUtil.isEmpty(config.getConfigStr())) { List maps = positionMapService.getAllMap(); @@ -509,13 +547,14 @@ public class PathPlanningServiceImpl implements PathPlanningService { return; } - List itemDOList = new ArrayList<>(); - List items = positionMapItemService.getPositionMapItemByMapAndType(positionMap.getId(), PositionMapItemEnum.WAIT.getType()); - if (ObjectUtil.isEmpty(items) || items.size() < robots.size()) { + List itemDOList = new LinkedList<>(); + List items = positionMapItemService.getPositionMapItemByMapAndType(positionMap.getId(), PositionMapItemEnum.STOP.getType()); + if (ObjectUtil.isNotEmpty(items)) { + itemDOList.addAll(items); + } + if ( itemDOList.size() < robots.size()) { List itemPoses = positionMapItemService.getPositionMapItemByMapAndType(positionMap.getId(), PositionMapItemEnum.PATH.getType()); itemDOList.addAll(itemPoses); - } else { - itemDOList = items; } List simulationList = new ArrayList<>(); @@ -628,7 +667,7 @@ public class PathPlanningServiceImpl implements PathPlanningService { relatedPathNode.setControl_nodes(list); - pathPlanningApi.synchronousPointToPP(relatedPathNode, PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_LINE); + commonApi.commonMethod(relatedPathNode, PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_LINE); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionChangePointBindingService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionChangePointBindingService.java index 40c6e0d5c..9f840bf5e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionChangePointBindingService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionChangePointBindingService.java @@ -90,4 +90,10 @@ public interface PositionChangePointBindingService extends IService getByMapIdAndStartPointIds(Long positionMapId, List endPointIds, List startPointIds); + + /** + * 根据地图ID删除 + * @param mapId + */ + void deleteBindingByMapId(Long mapId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionChangePointBindingServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionChangePointBindingServiceImpl.java index 9ace0837a..ff4f594e9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionChangePointBindingServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionChangePointBindingServiceImpl.java @@ -169,5 +169,10 @@ public class PositionChangePointBindingServiceImpl extends ServiceImpl { /** * 批量查询 - * @param pointList + * @param ids * @return */ - List getPositionMapItemByIds(List pointList); + List getPositionMapItemByIds(List ids); /** * 获取随机数id @@ -131,4 +132,23 @@ public interface PositionMapItemService extends IService { * @return */ List getItemBySortNum(Long sortNum); + + /** + * 根据ID获取排序的MAP + * @param itemIds + * @return + */ + Map getSortNumMapByIds(List itemIds); + + /** + * 删除这个地图的点 + * @param mapId + */ + void deleteByMapId(Long mapId); + + /** + * 校验此地图的交换点,有没有被其他地图绑定 + * @param mapId + */ + void checkHaveBindChangePoint(Long mapId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapItemServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapItemServiceImpl.java index 811a21c85..e279d91c1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapItemServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapItemServiceImpl.java @@ -6,28 +6,42 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; 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.module.mqtt.api.task.dto.Pose2ds; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.controller.admin.log.vo.UserOperationLogSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.PositionMapConditionDTO; import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemSaveReqVO; +import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnMsgSaveReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; +import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionChangePointBindingDO; import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO; +import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionChangePointBindingMapper; 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.enums.item.PositionMapItemEnum; +import cn.iocoder.yudao.module.system.enums.item.UseStatusEnum; import cn.iocoder.yudao.module.system.service.log.UserOperationLogService; +import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService; import cn.iocoder.yudao.module.system.util.redis.RedisUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import java.time.LocalDateTime; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import static cn.hutool.core.collection.CollUtil.isNotEmpty; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAP_EXIST_BINDING_POINT; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.MAP_EXIST_TASK_EXIST_TASK; /** * 仓库点位地图子表 Service 实现类 @@ -46,6 +60,12 @@ public class PositionMapItemServiceImpl extends ServiceImpl getPositionMapItemByMapAndType(Long mapId, Integer type) { return positionMapItemMapper.selectList(new LambdaQueryWrapperX() .eq(PositionMapItemDO::getPositionMapId, mapId) - .eq(PositionMapItemDO::getType, type)); + .eq(PositionMapItemDO::getType, type) + .orderByDesc(PositionMapItemDO::getId)); } /** @@ -184,4 +211,60 @@ public class PositionMapItemServiceImpl extends ServiceImpl getSortNumMapByIds(List idList) { + List list = positionMapItemMapper.selectList(new LambdaQueryWrapperX() + .in(PositionMapItemDO::getId, idList)); + return list.stream().collect(Collectors.toMap(PositionMapItemDO::getId, PositionMapItemDO::getSortNum)); + } + + @Override + public void deleteByMapId(Long mapId) { + positionMapItemMapper.deleteByMapId(mapId); + } + + /** + * 校验此地图的交换点,有没有被其他地图绑定 + * @param mapId + */ + @Override + public void checkHaveBindChangePoint(Long mapId) { + List list = positionMapItemMapper.selectList(new LambdaQueryWrapperX() + .eq(PositionMapItemDO::getPositionMapId, mapId) + .eq(PositionMapItemDO::getType,PositionMapItemEnum.CHANGE.getType())); + if (ObjectUtil.isEmpty(list)) { + return; + } + + List ids = list.stream().map(PositionMapItemDO::getId).collect(Collectors.toList()); + + List bindingList = positionChangePointBindingMapper.selectList(new LambdaQueryWrapperX() + .ne(PositionChangePointBindingDO::getPositionMapId, mapId) + .in(PositionChangePointBindingDO::getEndPointId, ids)); + + if (ObjectUtil.isEmpty(bindingList)) { + return; + } + + List sortNums = bindingList.stream().map(PositionChangePointBindingDO::getStartingPointSortNum).collect(Collectors.toList()); + + warnMsgService.sendWarnMsgToWebsocket(MAP_EXIST_TASK_EXIST_TASK.getMsg()); + RobotWarnMsgSaveReqVO warnMsgSaveReqVO = new RobotWarnMsgSaveReqVO(); + String locationStr = StringUtils.join(sortNums, ","); + if (locationStr.length() > 160) { + locationStr = locationStr.substring(0,160); + } + warnMsgSaveReqVO.setWarnMsg(MAP_EXIST_BINDING_POINT.getMsg()+locationStr); + warnMsgSaveReqVO.setWarnLevel(4); + warnMsgSaveReqVO.setWarnCode("MAP"); + warnMsgSaveReqVO.setSolveTime(LocalDateTime.now()); + warnMsgService.createWarnMsg(warnMsgSaveReqVO); + throw exception(MAP_EXIST_BINDING_POINT); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapLineService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapLineService.java index ffef1b87b..9742a00b5 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapLineService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapLineService.java @@ -68,4 +68,10 @@ public interface PositionMapLineService extends IService { * @param lineList */ void batchSaveLines(List lineList); + + /** + * 根据地图ID删除 + * @param id + */ + void deleteByMapId(Long mapId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapLineServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapLineServiceImpl.java index 70ad8aa73..a88859c7f 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapLineServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapLineServiceImpl.java @@ -83,4 +83,9 @@ public class PositionMapLineServiceImpl extends ServiceImpl { * @return */ List getRemoteAreaRobotByMapId(Long mapId); + + /** + * 获取地图的文件名 + * @param floor + * @param areaId + * @return + */ + String getMapFileNameByFloorAndAreaName(Long floor, String areaId); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapServiceImpl.java index 7e8ba2354..413173f5c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/positionmap/PositionMapServiceImpl.java @@ -16,24 +16,34 @@ import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMa import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotDoingTaskDTO; import cn.iocoder.yudao.module.system.controller.admin.robot.mapstop.RobotMapStopSaveReqVO; +import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnMsgSaveReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO; import cn.iocoder.yudao.module.system.dal.dataobject.remote.RemoteControllerInformationDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotMapStopDO; +import cn.iocoder.yudao.module.system.dal.mysql.information.DeviceInformationMapper; import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapMapper; import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum; import cn.iocoder.yudao.module.system.enums.robot.RobotStatusEnum; import cn.iocoder.yudao.module.system.enums.robot.remote.RemoteModeEnum; import cn.iocoder.yudao.module.system.enums.robot.task.RobotCommandTypeEnum; +import cn.iocoder.yudao.module.system.service.housearea.HouseAreaService; +import cn.iocoder.yudao.module.system.service.houselane.WareHouseLaneService; +import cn.iocoder.yudao.module.system.service.houselocation.HouseLocationService; +import cn.iocoder.yudao.module.system.service.information.DeviceInformationService; import cn.iocoder.yudao.module.system.service.log.UserOperationLogService; +import cn.iocoder.yudao.module.system.service.parkingspot.ParkingSpotService; import cn.iocoder.yudao.module.system.service.remote.RemoteControllerInformationService; import cn.iocoder.yudao.module.system.service.robot.RobotInformationService; import cn.iocoder.yudao.module.system.service.robot.RobotTaskDetailService; +import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService; import cn.iocoder.yudao.module.system.service.robot.mapstop.RobotMapStopService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.annotation.Cacheable; import org.springframework.http.HttpHeaders; @@ -53,6 +63,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.time.LocalDateTime; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -98,6 +109,33 @@ public class PositionMapServiceImpl extends ServiceImpl() + .eq(PositionMapDO::getFloor, floorInt) + .eq(PositionMapDO::getArea, areaStr)); + if (ObjectUtil.isNotEmpty(positionMap)) { + positionMapMapper.deleteById(positionMap.getId()); + List locationDOList = houseLocationService.getInStockLockLocationByMapId(positionMap.getId()); + if (ObjectUtil.isNotEmpty(locationDOList)) { + warnMsgService.sendWarnMsgToWebsocket(MAP_EXIST_TASK_EXIST_TASK.getMsg()); + RobotWarnMsgSaveReqVO warnMsgSaveReqVO = new RobotWarnMsgSaveReqVO(); + List locationNos = locationDOList.stream().map(WareHouseLocationDO::getLocationNo).collect(Collectors.toList()); + String locationStr = StringUtils.join(locationNos, ","); + if (locationStr.length() > 160) { + locationStr = locationStr.substring(0,160); + } + warnMsgSaveReqVO.setWarnMsg(MAP_EXIST_TASK_EXIST_TASK.getMsg()+locationStr); + warnMsgSaveReqVO.setWarnLevel(4); + warnMsgSaveReqVO.setWarnCode("MAP"); + warnMsgSaveReqVO.setSolveTime(LocalDateTime.now()); + warnMsgService.createWarnMsg(warnMsgSaveReqVO); + throw exception(MAP_EXIST_TASK_EXIST_TASK); + } + positionMapItemService.checkHaveBindChangePoint(positionMap.getId()); + positionMapItemService.deleteByMapId(positionMap.getId()); + positionMapLineService.deleteByMapId(positionMap.getId()); + houseLocationService.deleteHouseLocationByMapId(positionMap.getId()); + deviceInformationMapper.deleteDeviceByMapId(positionMap.getId()); + positionChangePointBindingService.deleteBindingByMapId(positionMap.getId()); + houseAreaService.deleteHouseAreaByMapId(positionMap.getId()); + houseLaneService.deleteHouseLaneByMapId(positionMap.getId()); + parkingSpotService.deleteParkingByMapId(positionMap.getId()); + } + // 处理 PNG 文件 try { pngUrl = url + pngFile.getOriginalFilename(); @@ -199,18 +270,11 @@ public class PositionMapServiceImpl extends ServiceImpl() - .eq(PositionMapDO::getFloor, floorInt) - .eq(PositionMapDO::getArea, areaStr)); - if (positionMap != null) { - positionMapMapper.updateById(positionMap.setYamlJson(yamlJson).setPngUrl(pngUrl).setYamlUrl(yamlUrl)); - // todo 异步通知所有该楼层区域内所有AGV车地图有更改 - 这个时候AGV应当重新获取地图信息 - } else { - positionMap = new PositionMapDO().setFloor(floorInt).setArea(areaStr) - .setYamlJson(yamlJson).setPngUrl(pngUrl).setYamlUrl(yamlUrl); - positionMapMapper.insert(positionMap); - } + // todo 异步通知所有该楼层区域内所有AGV车地图有更改 - 这个时候AGV应当重新获取地图信息 + positionMap = new PositionMapDO().setFloor(floorInt).setArea(areaStr) + .setYamlJson(yamlJson).setPngUrl(pngUrl).setYamlUrl(yamlUrl); + positionMapMapper.insert(positionMap); } @Override @@ -478,9 +542,36 @@ public class PositionMapServiceImpl extends ServiceImpl() + .eq(PositionMapDO::getFloor, floor) + .eq(PositionMapDO::getArea, area) + .last("limit 1")); + if (ObjectUtil.isEmpty(positionMapDO)) { + return null; + } + String pngUrl = positionMapDO.getPngUrl(); + int startOne = pngUrl.lastIndexOf("\\"); + int startTwo = pngUrl.lastIndexOf("/"); + if (ObjectUtil.isNotEmpty(startTwo)) { + startTwo = startTwo + 1; + } + int start = Math.max(startOne, startTwo); + int end = pngUrl.lastIndexOf("."); + return pngUrl.substring(start, end); + } + private List getRemoteSingleMapInfomation(Map robotMap, List robotNos, - Map robotDoingTaskMap, - Map remoteMap) { + Map robotDoingTaskMap, + Map remoteMap) { RemoteRobotDTO automatic = new RemoteRobotDTO(); RemoteRobotDTO handMovement = new RemoteRobotDTO(); RemoteRobotDTO free = new RemoteRobotDTO(); @@ -508,9 +599,9 @@ public class PositionMapServiceImpl extends ServiceImpl() - .eq(RemoteControllerInformationDO::getRobotNo, pathPosedsDTO.getRobotNo()) + .eq(RemoteControllerInformationDO::getRobotNo, pathRobotDTO.getRobotNo()) .last("limit 1")); if (ObjectUtil.isEmpty(information)) { return; @@ -441,7 +459,7 @@ public class RemoteControllerInformationServiceImpl extends ServiceImpl robotDoingTaskNo = taskDetailService.getRobotDoingTaskNo(information.getRobotNo()); + if (ObjectUtil.isNotEmpty(robotDoingTaskNo)) { + throw exception(REMOTE_ROBOT_HAVE_TASK); + } if (ZeroOneEnum.ZERO.getType().equals(taskDetail.getOccurError())) { throw exception(REMOTE_TASK_NOT_OCCUR_ERROR); } + if (information.getRobotNo().equals(oldRobotNo)) { + throw exception(REMOTE_TRANSFER_NOT_SAME_ROBOT); + } taskDetail.setRobotNo(information.getRobotNo()); if (!RobotTaskTypeEnum.TAKE_RELEASE.getType().equals(taskDetail.getTaskType()) && !RobotTaskTypeEnum.TAKE.getType().equals(taskDetail.getTaskType()) @@ -562,7 +587,6 @@ public class RemoteControllerInformationServiceImpl extends ServiceImpl { */ RobotInformationStatisticsVO statisticsInformation(); + /** + * 车机mac地址获取电量 + * @param str + * type 1:是mac, 0 :是车辆编号 + * @return + */ + String getSocByMac(String str, Integer type); + /** * 获取所有AGV状态 * @return @@ -233,4 +242,17 @@ public interface RobotInformationService extends IService { * @param updateObj */ void checkIpAndPort(RobotInformationDO updateObj); + + /** + * 统计车辆状态分类 + * @return + */ + RobotStatusClassificationDTO robotStatusClassification(); + + /** + * 查询车辆所在的地图id + * @param robotNo + * @return + */ + Long getRobotMapIdByRobotNo(String robotNo); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationServiceImpl.java index d26e25c14..c039d4a81 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotInformationServiceImpl.java @@ -11,7 +11,6 @@ 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.dto.RobotDimensionsDTO; import cn.iocoder.yudao.module.mqtt.api.path.task.TaskRobotNoLimittationAreaDTO; import cn.iocoder.yudao.module.mqtt.api.path.task.TaskToPathPlanningDTO; @@ -19,11 +18,12 @@ 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.api.task.dto.RobotSimulationPoseDTO; 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.processor.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.api.robot.websocket.RobotStatusDataPoseDTO; +import cn.iocoder.yudao.module.system.api.robot.websocket.RobotInformationVO; +import cn.iocoder.yudao.module.system.constant.CommonConstant; 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.RobotStatusCodeConstant; @@ -33,6 +33,7 @@ import cn.iocoder.yudao.module.system.controller.admin.config.vo.CommonConfigVO; import cn.iocoder.yudao.module.system.controller.admin.log.vo.UserOperationLogSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.camera.RobotCameraAddVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.*; +import cn.iocoder.yudao.module.system.controller.admin.statistics.dto.RobotStatusClassificationDTO; import cn.iocoder.yudao.module.system.controller.admin.tool.dto.CleanAgvDTO; import cn.iocoder.yudao.module.system.dal.dataobject.config.CommonConfigDO; import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; @@ -43,24 +44,29 @@ 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.remote.RemoteControllerInformationDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.*; -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.remote.RemoteControllerInformationMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.*; +import cn.iocoder.yudao.module.system.dal.mysql.statistics.RobotWorkingHoursStatisticsMapper; +import cn.iocoder.yudao.module.system.dal.mysql.wait.MoveToWaitMapper; 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.item.UseStatusEnum; 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.LocationLockEnum; +import cn.iocoder.yudao.module.system.enums.robot.LocationUseStatusEnum; 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.actionlog.CommandIdEnum; import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeModelEnum; import cn.iocoder.yudao.module.system.enums.robot.information.RobotStatisticsTypeEnum; import cn.iocoder.yudao.module.system.enums.robot.task.RobotCommandTypeEnum; @@ -71,7 +77,6 @@ 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.camera.RobotCameraService; import cn.iocoder.yudao.module.system.service.robot.pathplanning.RobotPathPlanningService; -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; @@ -92,6 +97,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.*; /** @@ -130,9 +136,6 @@ public class RobotInformationServiceImpl extends ServiceImpl list = informationMapper.selectRobotDimensions(); - pathPlanningApi.synchronousLineObject(list, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS); + commonApi.commonMethod(list, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS); redisUtil.del(key); // 返回 @@ -263,8 +274,86 @@ public class RobotInformationServiceImpl extends ServiceImpl robotInformationDOS = informationMapper.selectList(); + if (ObjectUtil.isEmpty(robotInformationDOS)) { + return null; + } + + int idleNum = 0; + int doingTaskNum = 0; + int chargeNum = 0; + int faultNum = 0; + int total = robotInformationDOS.size(); + + for (RobotInformationDO robotInformation : robotInformationDOS) { + String errorLevelKey = RobotTaskChcheConstant.ROBOT_ERROR_LEVEL + robotInformation.getMacAddress(); + Object errorLevel = redisUtil.get(errorLevelKey); + if (ObjectUtil.isNotEmpty(errorLevel)) { + int level = Integer.parseInt(errorLevel.toString()); + if (level > 3) { + faultNum = faultNum + 1; + continue; + } + } + + if (RobotStatusEnum.STAND_BY.getType().equals(robotInformation.getRobotStatus())) { + idleNum = idleNum + 1; + } else if (RobotStatusEnum.DOING.getType().equals(robotInformation.getRobotStatus())) { + doingTaskNum = doingTaskNum + 1; + } else if (RobotStatusEnum.CHARGE.getType().equals(robotInformation.getRobotStatus())) { + chargeNum = chargeNum + 1; + } + } + + int idle = idleNum * 100 / total; + int doingTask = doingTaskNum * 100 / total; + int charge = chargeNum * 100 / total; + int fault = faultNum * 100 / total; + + return RobotStatusClassificationDTO.builder() + .idle(idle) + .idleNum(idleNum) + .doingTask(doingTask) + .doingTaskNum(doingTaskNum) + .charge(charge) + .chargeNum(chargeNum) + .fault(fault) + .faultNum(faultNum).build(); + } + + /** + * 查询车辆所在的地图id + * + * @param robotNo + * @return + */ + @Override + public Long getRobotMapIdByRobotNo(String robotNo) { + FloorZoneDTO floorZoneDTO = getFloorZoneDTOByRobotNo(robotNo); + if (ObjectUtil.isEmpty(floorZoneDTO) && ObjectUtil.isNotEmpty(floorZoneDTO.getFloor()) && ObjectUtil.isNotEmpty(floorZoneDTO.getArea())) { + return null; + } + PositionMapDO positionMap = positionMapMapper.selectOne(new LambdaQueryWrapper() + .eq(PositionMapDO::getArea, floorZoneDTO.getArea()) + .eq(PositionMapDO::getFloor, floorZoneDTO.getFloor()) + .last("limit 1")); + if (ObjectUtil.isEmpty(positionMap)) { + return null; + } + return positionMap.getId(); + } + + /** * 校验IP地址是否合法 + * * @param ipAddress IP地址字符串 * @return 是否合法 */ @@ -335,16 +424,12 @@ public class RobotInformationServiceImpl extends ServiceImpl robotMapStops = mapStopMapper.selectList(new LambdaQueryWrapperX() - .eq(RobotMapStopDO::getRobotNo, robotInformationDO.getRobotNo())); - if (ObjectUtil.isNotEmpty(robotMapStops)) { - robotMapStops.forEach(v -> v.setRobotNo(updateReqVO.getRobotNo())); - mapStopMapper.updateById(robotMapStops); - } - } // 更新AGV于地图关系表 ----- List> list = CollectionUtils.compareLists( @@ -373,14 +458,14 @@ public class RobotInformationServiceImpl extends ServiceImpl map = new HashMap<>(); - String value = floorZone.getFloor() + "-" + floorZone.getArea(); + String value = floorZone.getFloor() + CommonConstant.SYMBOL + floorZone.getArea(); map.put(updateReqVO.getRobotNo(), value); redisUtil.hmset(value, map); } @@ -393,7 +478,37 @@ public class RobotInformationServiceImpl extends ServiceImpl RobotDimensions = informationMapper.selectRobotDimensions(); - pathPlanningApi.synchronousLineObject(RobotDimensions, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS); + commonApi.commonMethod(RobotDimensions, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS); + } + + /** + * 跟新车辆编号 + * @param oldRobotNo + * @param newRobotNo + */ + @Transactional(rollbackFor = Exception.class) + public void updateRobotNo(String oldRobotNo, String newRobotNo) { + + deviceInformationMapper.updateRobotNo(oldRobotNo,newRobotNo); + + controllerInformationMapper.updateRobotNo(oldRobotNo,newRobotNo); + + RobotChargeLogDO robotChargeLog = chargeLogMapper.selectOne(new LambdaQueryWrapperX() + .eq(RobotChargeLogDO::getRobotNo, oldRobotNo) + .orderByDesc(RobotChargeLogDO::getCreateTime) + .last("limit 1")); + if (ObjectUtil.isNotEmpty(robotChargeLog)) { + robotChargeLog.setRobotNo(newRobotNo); + chargeLogMapper.updateById(robotChargeLog); + } + + //这表暂时不改 +// robotWorkingHoursStatisticsMapper + mapStopMapper.updateRobotNo(oldRobotNo,newRobotNo); + + moveToWaitMapper.updateRobotNo(oldRobotNo,newRobotNo); + + positionMapItemMapper.updateRobotNo(oldRobotNo,newRobotNo); } @Override @@ -403,6 +518,13 @@ public class RobotInformationServiceImpl extends ServiceImpl() + .eq(RemoteControllerInformationDO::getRobotNo, robotInformationDO.getRobotNo()) + .last("limit 1")); + if (ObjectUtil.isNotEmpty(remoteControllerInformation)) { + throw exception(ROBOT_DOING_REMOTE); + } + cameraService.deleteCameraByRobotNo(robotInformationDO.getRobotNo()); List list = taskMapper.selectDoingTaskByRobotNo(robotInformationDO.getRobotNo()); @@ -425,7 +547,10 @@ public class RobotInformationServiceImpl extends ServiceImpl RobotDimensions = informationMapper.selectRobotDimensions(); - pathPlanningApi.synchronousLineObject(RobotDimensions, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS); + commonApi.commonMethod(RobotDimensions, PathPlanningTopicConstant.SEND_ROBOT_DIMENSIONS); + + String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT + robotInformationDO.getMacAddress(); + redisUtil.del(pose2dKey); redisUtil.del(key); //地图相关 @@ -433,10 +558,17 @@ public class RobotInformationServiceImpl extends ServiceImpl getAGVListStatusInfo() { List list = new ArrayList<>(); @@ -706,7 +862,7 @@ public class RobotInformationServiceImpl extends ServiceImpl getAllRobot() { - RobotInformationDO query = new RobotInformationDO(); - return informationMapper.queryAllByLimit(query); + return informationMapper.selectList(new LambdaQueryWrapper()); } /** @@ -799,12 +954,12 @@ public class RobotInformationServiceImpl extends ServiceImpl pathPlanningList = new ArrayList<>(); pathPlanningList.add(pathPlanning); + + String plantingKey = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId(); + redisUtil.set(plantingKey, JSON.toJSONString(pathPlanning), taskChcheTime); + log.info("任务下发给PP :{}", JSON.toJSONString(pathPlanningList)); - pathPlanningApi.synchronousLineObject(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST); + commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST); } private void resendToPPData(TaskToPathPlanningDTO pathPlanning, RobotTaskDetailActionLogDO actionLog, RobotInformationDO robotInformationDO, Boolean isRemote) { @@ -1077,12 +1241,13 @@ public class RobotInformationServiceImpl extends ServiceImpl positionMapItems = positionMapItemMapper.selectList(new LambdaQueryWrapperX() + PositionMapItemDO positionMapItems = positionMapItemMapper.selectOne(new LambdaQueryWrapperX() .eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType()) - .eq(PositionMapItemDO::getUseStatus, ZeroOneEnum.ZERO.getType())); + .eq(PositionMapItemDO::getRobotNo, robotNo) + .last("limit 1")); + + if (ObjectUtil.isEmpty(positionMapItems)) { + positionMapItems = positionMapItemMapper.selectOne(new LambdaQueryWrapperX() + .eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType()) + .eq(PositionMapItemDO::getUseStatus, UseStatusEnum.FREE.getType()) + .last("limit 1")); + } if (ObjectUtil.isEmpty(positionMapItems)) { log.info("------没有空闲的停车点----- :{}", robotNo); throw exception(ROBOT_NOT_FOUND_WAIT_ITEM); } - List waitIds = positionMapItems - .stream() - .map(u -> u.getId() + "") - .collect(Collectors.toList()); - pathPlanning.setWaitIds(waitIds); + pathPlanning.setWaitIds(Collections.singletonList(positionMapItems.getId() + "")); } @@ -1304,7 +1484,7 @@ public class RobotInformationServiceImpl extends ServiceImpl robotNos = robots.stream().map(RobotInformationDO::getRobotNo).collect(Collectors.toList()); List list = new ArrayList<>(); - String floorArea = floor + "-" + area; + String floorArea = floor + CommonConstant.SYMBOL + area; Map hmget = redisUtil.hmget(floorArea); if (ObjectUtil.isEmpty(hmget)) { return new ArrayList<>(); @@ -1369,20 +1549,14 @@ public class RobotInformationServiceImpl extends ServiceImpl robotNoLimitions = Arrays.asList(taskRobotNoLimittationAreaDTO); pathPlanning.setRobotNoLimitationAreaDTOS(robotNoLimitions); - resendToPPData(pathPlanning, actionLog, robotInformationDO,true); + resendToPPData(pathPlanning, actionLog, robotInformationDO, true); + + String plantingKey = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId(); + redisUtil.set(plantingKey, JSON.toJSONString(pathPlanning), taskChcheTime); List pathPlanningList = new ArrayList<>(); pathPlanningList.add(pathPlanning); log.info("远遥任务转移, 任务下发给PP :{}", JSON.toJSONString(pathPlanningList)); - pathPlanningApi.synchronousLineObject(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST); + commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST); } /** * 设置车辆空闲 + * * @param robotNo */ @Override @@ -1490,13 +1669,13 @@ public class RobotInformationServiceImpl extends ServiceImpl taskDetailDOS = taskDetailMapper.selectList(new LambdaQueryWrapperX() @@ -186,7 +200,7 @@ public class RobotTaskDetailServiceImpl implements RobotTaskDetailService { .nickName(SecurityFrameworkUtils.getLoginUserNickname()).build(); userOperationLogService.createUserOperationLog(build); - RobotTaskDetailActionLogDO actionLog = taskDetailActionLogService.getLastTaskByRobotNo(robotTaskDetailDO.getRobotNo()); + RobotTaskDetailActionLogDO actionLog = taskDetailActionLogService.getLastTaskByRobotNo(robotTaskDetailDO.getRobotNo(), CommandIdEnum.TASK.getType()); if (ObjectUtil.isEmpty(actionLog) || !actionLog.getTaskDetailId().equals(taskDetailId)) { return; } @@ -194,7 +208,7 @@ public class RobotTaskDetailServiceImpl implements RobotTaskDetailService { informationService.setRobotFree(robotTaskDetailDO.getRobotNo()); actionLog.setActionStatus(ActionStatusEnum.DONE.getType()); - taskDetailActionLogService.updateTaskDetailActionLogs(Arrays.asList(actionLog)); + taskDetailActionLogService.updateTaskDetailActionLogs(Collections.singletonList(actionLog)); taskDetailActionLogService.setPreviousTaskDoneByOrderId(taskDetailId); if (RobotTaskStageEnum.DONE.getType().equals(taskStage) @@ -274,7 +288,7 @@ public class RobotTaskDetailServiceImpl implements RobotTaskDetailService { List warnMsgs = warnMsgService.getWarnMsgByDetailIds(detailIds); Map warnMsgMap = null; if (ObjectUtil.isNotEmpty(warnMsgs)) { - warnMsgMap = warnMsgs.stream().collect(Collectors.toMap(RobotWarnMsgDO::getTaskDetailId, RobotWarnMsgDO::getWarnMsg,(existingValue, newValue) -> existingValue)); + warnMsgMap = warnMsgs.stream().collect(Collectors.toMap(RobotWarnMsgDO::getTaskDetailId, RobotWarnMsgDO::getWarnMsg, (existingValue, newValue) -> existingValue)); } for (RemoteExceptionTaskDetailDTO record : page.getRecords()) { @@ -299,7 +313,7 @@ public class RobotTaskDetailServiceImpl implements RobotTaskDetailService { RobotTaskDetailDO robotTaskDetailDO = taskDetailMapper.selectById(taskDetailId); String str = " 远遥点击取货完成 "; if (RobotTaskTypeEnum.TAKE.getType().equals(robotTaskDetailDO.getTaskType())) { - manuallyCompleted(taskDetailId, str); + manuallyCompleted(taskDetailId, str, RobotTaskManualInterventionEnum.REMOTE_DO_TAKE.getType()); } else if (RobotTaskTypeEnum.TAKE_RELEASE.getType().equals(robotTaskDetailDO.getTaskType())) { if (!RobotTaskStageEnum.UN_START.getType().equals(robotTaskDetailDO.getTaskStage()) @@ -327,5 +341,35 @@ public class RobotTaskDetailServiceImpl implements RobotTaskDetailService { } + /** + * 统计任务人工完成/自动完成 + * + * @param type type 1:周, 2:月, 3:季度 + * @return + */ + @Override + public RobotTaskManualInterventionDTO robotTaskAutomaticArtificial(String type) { + RobotTaskManualInterventionDTO data = taskDetailMapper.getRobotTaskAutomaticArtificial(type); + if (ObjectUtil.isEmpty(data)) { + return new RobotTaskManualInterventionDTO(); + } + int total = data.getArtificialDoneNum() + data.getAutomaticDoneNum(); + if (total == 0) { + return new RobotTaskManualInterventionDTO(); + } + int artificialDone = data.getArtificialDoneNum() * 100 / total; + int automaticDone = data.getAutomaticDoneNum() * 100 / total; + + if ((automaticDone + artificialDone) < 100 && artificialDone > 0) { + artificialDone = artificialDone + 1; + } else if ((automaticDone + artificialDone) < 100 && automaticDone > 0) { + automaticDone = automaticDone + 1; + } + + data.setArtificialDone(artificialDone); + data.setAutomaticDone(automaticDone); + return data; + } + } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotTaskService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotTaskService.java index 48e793387..c9a1eacf9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotTaskService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotTaskService.java @@ -109,4 +109,10 @@ public interface RobotTaskService extends IService { * 校验是否存在未完成的任务 */ void checkHaveDoingTask(); + + /** + * 设置车辆充电完成 + * @param robotNo + */ + void chargeDone(String robotNo); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotTaskServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotTaskServiceImpl.java index 84dc17d10..7ba1e26a0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotTaskServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotTaskServiceImpl.java @@ -1,9 +1,7 @@ package cn.iocoder.yudao.module.system.service.robot; import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; @@ -14,10 +12,10 @@ import cn.iocoder.yudao.module.mqtt.api.common.CommonApi; import cn.iocoder.yudao.module.mqtt.api.task.dto.*; import cn.iocoder.yudao.module.mqtt.enums.task.ExecutionTypeEnum; import cn.iocoder.yudao.module.system.api.path.vo.RobotClosePathPlantingDTO; -import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; 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.RobotTaskDetailActionLogSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.log.vo.UserOperationLogSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapItemSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.detail.RobotTaskDetailLogResoVO; @@ -47,19 +45,22 @@ 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.DeviceUseStatusEnum; +import cn.iocoder.yudao.module.system.enums.item.UseStatusEnum; import cn.iocoder.yudao.module.system.enums.path.PathTaskTypeEnum; import cn.iocoder.yudao.module.system.enums.redis.RobotCacheLockEnum; import cn.iocoder.yudao.module.system.enums.robot.*; +import cn.iocoder.yudao.module.system.enums.robot.actionlog.ActionStatusEnum; +import cn.iocoder.yudao.module.system.enums.robot.actionlog.CommandIdEnum; 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.RobotTaskManualInterventionEnum; 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.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.wait.MoveToWaitService; +import cn.iocoder.yudao.module.system.service.statistics.RobotWorkingHoursStatisticsService; import cn.iocoder.yudao.module.system.util.redis.RedisUtil; import cn.iocoder.yudao.module.system.util.redis.RedissonUtils; import com.alibaba.fastjson.JSON; @@ -138,7 +139,7 @@ public class RobotTaskServiceImpl extends ServiceImpl pointList = new ArrayList<>(); + List takeRobotNos = new ArrayList<>(); + List releaseRobotNos = new ArrayList<>(); + for (RobotTaskDetailAddVO robotTaskDetail : createReqVO.getTaskDetailList()) { - if (!RobotTaskTypeEnum.MOVE_TO_POINT.getType().equals(robotTaskDetail.getTaskType())) { - continue; + if (RobotTaskTypeEnum.MOVE_TO_POINT.getType().equals(robotTaskDetail.getTaskType())) { + if (pointList.contains(robotTaskDetail.getReleaseId())) { + PositionMapItemDO positionMapItem = positionMapItemService.getPositionMapItem(robotTaskDetail.getReleaseId()); + throw exception0(TASK_CHECK_EXCEPTION.getCode(), "以下移动的点位重复 " + positionMapItem.getSortNum(), positionMapItem.getSortNum()); + } + pointList.add(robotTaskDetail.getReleaseId()); + }else if (RobotTaskTypeEnum.TAKE.getType().equals(robotTaskDetail.getTaskType())) { + if (takeRobotNos.contains(robotTaskDetail.getRobotNo())) { + throw exception0(TASK_CHECK_EXCEPTION.getCode(), "一辆车只能有一个仅取货任务 " + robotTaskDetail.getRobotNo(), robotTaskDetail.getRobotNo()); + } + takeRobotNos.add(robotTaskDetail.getRobotNo()); + }else if (RobotTaskTypeEnum.RELEASE.getType().equals(robotTaskDetail.getTaskType())) { + if (releaseRobotNos.contains(robotTaskDetail.getRobotNo())) { + throw exception0(TASK_CHECK_EXCEPTION.getCode(), "一辆车只能有一个仅放货任务 " + robotTaskDetail.getRobotNo(), robotTaskDetail.getRobotNo()); + } + releaseRobotNos.add(robotTaskDetail.getRobotNo()); } - if (pointList.contains(robotTaskDetail.getReleaseId())) { - PositionMapItemDO positionMapItem = positionMapItemService.getPositionMapItem(robotTaskDetail.getReleaseId()); - throw exception0(TASK_CHECK_EXCEPTION.getCode(), "以下移动的点位重复 " + positionMapItem.getSortNum(), positionMapItem.getSortNum()); - } - pointList.add(robotTaskDetail.getReleaseId()); } if (ObjectUtil.isNotEmpty(pointList)) { List positionMapItemList = positionMapItemService.getPositionMapItemByIds(pointList); List list = positionMapItemList.stream() - .filter(v -> ZeroOneEnum.ONE.getType().equals(v.getUseStatus())) + .filter(v -> !UseStatusEnum.FREE.getType().equals(v.getUseStatus())) .map(PositionMapItemDO::getSortNum) .collect(Collectors.toList()); if (ObjectUtil.isNotEmpty(list)) { @@ -284,6 +297,28 @@ public class RobotTaskServiceImpl extends ServiceImpl() + .in(RobotTaskDetailDO::getRobotNo, takeRobotNos) + .in(RobotTaskDetailDO::getTaskStatus,RobotTaskStatusEnum.NEW.getType(), RobotTaskStatusEnum.DOING.getType()) + .eq(RobotTaskDetailDO::getTaskType, RobotTaskTypeEnum.TAKE.getType()) + .last("limit 1")); + if (ObjectUtil.isNotEmpty(takeTask)) { + throw exception0(TASK_CHECK_EXCEPTION.getCode(), "一辆车只能有一个仅取货任务 " + takeTask.getRobotNo(), takeTask.getRobotNo()); + } + } + + if (ObjectUtil.isNotEmpty(releaseRobotNos)) { + RobotTaskDetailDO releaseTask = taskDetailMapper.selectOne(new LambdaQueryWrapperX() + .in(RobotTaskDetailDO::getRobotNo, releaseRobotNos) + .in(RobotTaskDetailDO::getTaskStatus,RobotTaskStatusEnum.NEW.getType(), RobotTaskStatusEnum.DOING.getType()) + .eq(RobotTaskDetailDO::getTaskType, RobotTaskTypeEnum.RELEASE.getType()) + .last("limit 1")); + if (ObjectUtil.isNotEmpty(releaseTask)) { + throw exception0(TASK_CHECK_EXCEPTION.getCode(), "一辆车只能有一个仅放货任务 " + releaseTask.getRobotNo(), releaseTask.getRobotNo()); + } + } } public String getSortNumStr(List pointList) { @@ -430,6 +465,8 @@ public class RobotTaskServiceImpl extends ServiceImpl commandTypes = PathTaskTypeEnum.getMistakeTaskTypes(); + /*List commandTypes = PathTaskTypeEnum.getMistakeTaskTypes(); List actionLogDOList = taskDetailActionLogMapper.getMistakeTaskByCommandType(commandTypes); if (ObjectUtil.isNotEmpty(actionLogDOList)) { log.info("编辑地图存在未完成的移动到等待点/自动充电任务"); throw exception(TASK_CHECK_HAVE_DOING_TASK); - } + }*/ } /** @@ -539,67 +576,56 @@ public class RobotTaskServiceImpl extends ServiceImpl deviceNoMap = new HashMap<>(); Integer robotStatus = RobotStatusEnum.DOING.getType(); - //释放ware_position_map_item的使用状态 + //释放ware_position_map_item的使用状态,并且将ActionLog设置为完成 releaseMapItemUseStatus(taskAssignDTO.getRobotNo()); RobotChargeLogDO robotChargeLogs = null; - String taskNo = ""; + 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); + robotChargeLogs = chargeLogMapper.selectOne(new LambdaQueryWrapperX() + .eq(RobotChargeLogDO::getTaskDetailId, taskAssignDTO.getOrderId()) + .orderByDesc(RobotChargeLogDO::getCreateTime) + .last("limit 1")); + chargeLogMapper.updateChargStatusByTaskId(taskAssignDTO.getOrderId(),ChargeTaskStatusEnum.CHARGEING.getType()); robotStatus = RobotStatusEnum.CHARGE.getType(); - - if (ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId())) { + if (ObjectUtil.isNotEmpty(robotChargeLogs) && ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId())) { deviceNoMap.put(robotChargeLogs.getTaskDetailId(), robotChargeLogs.getDeviceNo()); - } else { - String signDate = DateUtil.date().setTimeZone(TimeZone.getTimeZone("UTC")).toString("yyyyMMdd'T'HHmmss'Z'"); - taskNo = "AUTO_CHARGE_" + signDate; } - detailId = ObjectUtil.isNotEmpty(robotChargeLogs.getTaskDetailId()) ? robotChargeLogs.getTaskDetailId() : null; - } else if (PathTaskTypeEnum.MOVE_TO_WAIT.getType().equals(taskAssignDTO.getOrderType())) { - moveToWaitService.updateWaitStatusAndItrmId(taskAssignDTO.getOrderId(), WaitStatusEnum.GO_TO_WAIT.getType(), taskAssignDTO.getWaitId()); - String signDate = DateUtil.date().setTimeZone(TimeZone.getTimeZone("UTC")).toString("yyyyMMdd'T'HHmmss'Z'"); - taskNo = "MOVE_TO_WAIT_" + signDate; - } else { - detailId = taskAssignDTO.getOrderId(); + if (ObjectUtil.isNotEmpty(robotChargeLogs) && ObjectUtil.isNotEmpty(robotChargeLogs.getDeviceNo())) { + setDeviceUseing(robotChargeLogs.getDeviceNo(), taskAssignDTO.getRobotNo()); + } } - chargeDone(taskAssignDTO.getRobotNo()); +// chargeDone(taskAssignDTO.getRobotNo()); robotInformationMapper.updateRobotListStatus(taskAssignDTO.getRobotNo(), robotStatus, taskAssignDTO.getOrderId()); - if (ObjectUtil.isNotEmpty(detailId)) { - RobotTaskDO robotTaskDO = setTaskDoing(detailId, taskAssignDTO.getRobotNo(), deviceNoMap, taskAssignDTO.getWaitId()); - taskNo = robotTaskDO.getTaskNo(); - } + RobotTaskDO robotTaskDO = setTaskDoing(taskAssignDTO.getOrderId(), taskAssignDTO.getRobotNo(), deviceNoMap, taskAssignDTO.getWaitId()); - if (ObjectUtil.isNotEmpty(robotChargeLogs)) { - setDeviceUseing(robotChargeLogs.getDeviceNo(), taskAssignDTO.getRobotNo()); - } - - RobotTaskDetailActionLogDO logOne = new RobotTaskDetailActionLogDO(); + RobotTaskDetailActionLogSaveReqVO logOne = new RobotTaskDetailActionLogSaveReqVO(); logOne.setCommandType(taskAssignDTO.getOrderType()); - String actionMsg = ObjectUtil.isEmpty(taskNo) ? taskAssignDTO.getRobotActionMsg() : taskAssignDTO.getRobotActionMsg() + taskNo; + String actionMsg = taskAssignDTO.getRobotActionMsg() + robotTaskDO.getTaskNo(); logOne.setActionMsg(actionMsg); logOne.setRobotNo(taskAssignDTO.getRobotNo()); + logOne.setOriginalRobotNo(taskAssignDTO.getRobotNo()); logOne.setStartTime(LocalDateTime.now()); - logOne.setTaskNo(taskNo); + logOne.setTaskNo(robotTaskDO.getTaskNo()); logOne.setCommandId(-1L); logOne.setTaskDetailId(taskAssignDTO.getOrderId()); - taskDetailActionLogMapper.insert(logOne); - -// sendTaskToRobot(robotTaskDetailDO, taskAssignDTO); + Long mapId = robotInformationService.getRobotMapIdByRobotNo(taskAssignDTO.getRobotNo()); + if (ObjectUtil.isNotEmpty(mapId)) { + logOne.setPositionMapId(mapId); + } + taskDetailActionLogService.createTaskDetailActionLog(logOne); + robotWorkingHoursStatisticsService.createFreeTime(taskAssignDTO.getRobotNo()); } /** @@ -608,8 +634,15 @@ public class RobotTaskServiceImpl extends ServiceImpl() .eq(RobotInformationDO::getRobotNo, robotNo)); if (!RobotStatusEnum.CHARGE.getType().equals(robotInformationDO.getRobotStatus())) { + log.info("车辆非充电状态:{}",robotNo); return; } + RobotChargeLogDO robotChargeLogDO = chargeLogMapper.selectOne(new LambdaQueryWrapperX() .eq(RobotChargeLogDO::getRobotNo, robotNo) .orderByDesc(RobotChargeLogDO::getCreateTime) @@ -1470,36 +1509,41 @@ public class RobotTaskServiceImpl extends ServiceImpl() + .eq(DeviceInformationDO::getLastUser, robotNo) + .eq(DeviceInformationDO::getDeviceNo, robotChargeLogDO.getDeviceNo())); + log.info("结束充电任务 :{}", robotNo); robotChargeLogDO.setEndTime(LocalDateTime.now()); - deviceInformationService.chargeDeviceShrink(robotChargeLogDO.getDeviceNo()); + if (ObjectUtil.isNotEmpty(deviceInformationDO)) { + log.info("充电桩设置为空闲 :{}", deviceInformationDO.getDeviceNo()); + deviceInformationService.chargeDeviceShrink(robotChargeLogDO.getDeviceNo()); + deviceInformationDO.setDeviceUseStatus(DeviceUseStatusEnum.IDLE.getType()); + deviceInformationDO.setLastUser(null); + deviceInformationMapper.updateById(deviceInformationDO); + } - String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + robotInformationDO.getMacAddress(); - Object object = redisUtil.get(pose2dKey); - RobotStatusDataPoseDTO robotStatusDataPoseDTO = JSONUtil.toBean((String) object, RobotStatusDataPoseDTO.class); + String socKey = RobotTaskChcheConstant.ROBOT_INFORMATION_SOC + robotInformationDO.getMacAddress(); + Object socObject = redisUtil.get(socKey); - if (ObjectUtil.isNotEmpty(object) && ObjectUtil.isNotEmpty(robotStatusDataPoseDTO)) { - robotChargeLogDO.setEndElectricity(Integer.valueOf(robotStatusDataPoseDTO.getBatSoc())); + if (ObjectUtil.isNotEmpty(socObject)) { + robotChargeLogDO.setEndElectricity(Integer.valueOf(socObject.toString())); } robotChargeLogDO.setTaskStatus(ChargeTaskStatusEnum.DONE.getType()); chargeLogMapper.updateById(robotChargeLogDO); - DeviceInformationDO deviceInformationDO = deviceInformationMapper.selectOne(new LambdaQueryWrapperX() - .eq(DeviceInformationDO::getDeviceNo, robotChargeLogDO.getDeviceNo())); - deviceInformationDO.setDeviceUseStatus(DeviceUseStatusEnum.IDLE.getType()); - deviceInformationDO.setLastUser(null); - deviceInformationMapper.updateById(deviceInformationDO); - log.info("充电桩设置为空闲 :{}", deviceInformationDO.getDeviceNo()); - if (ObjectUtil.isEmpty(robotChargeLogDO.getTaskDetailId())) { return; } RobotTaskDetailDO taskDetail = taskDetailMapper.selectById(robotChargeLogDO.getTaskDetailId()); - taskDetail.setTaskStatus(RobotTaskDetailStatusEnum.DONE.getType()); - taskDetailMapper.updateById(taskDetail); - RobotTaskDO robotTask = taskMapper.selectById(taskDetail.getRobotTaskId()); - robotTask.setTaskStatus(RobotTaskStatusEnum.DONE.getType()); - taskMapper.updateById(robotTask); + if (ObjectUtil.isNotEmpty(taskDetail) && RobotTaskTypeEnum.CHARGE.getType().equals(taskDetail.getTaskType())) { + taskDetail.setTaskStatus(RobotTaskDetailStatusEnum.DONE.getType()); + taskDetailMapper.updateById(taskDetail); + RobotTaskDO robotTask = taskMapper.selectById(taskDetail.getRobotTaskId()); + robotTask.setTaskStatus(RobotTaskStatusEnum.DONE.getType()); + taskMapper.updateById(robotTask); + } } /** diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotWarnCodeMappingServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotWarnCodeMappingServiceImpl.java index c27722cf3..8584e9154 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotWarnCodeMappingServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotWarnCodeMappingServiceImpl.java @@ -1,16 +1,12 @@ package cn.iocoder.yudao.module.system.service.robot; import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; -import cn.iocoder.yudao.module.system.api.robot.vo.RobotInformationVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnCodeMappingPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnCodeMappingSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.warn.RobotWarnCodeMappingVO; -import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnCodeMappingDO; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotWarnCodeMappingMapper; import com.alibaba.fastjson.JSON; -import com.baomidou.mybatisplus.core.metadata.IPage; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -18,18 +14,11 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import org.springframework.validation.annotation.Validated; -import org.springframework.transaction.annotation.Transactional; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; -import org.apache.commons.io.FileUtils; -import org.springframework.context.annotation.PropertySource; -import org.springframework.web.multipart.MultipartFile; -import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.HashMap; import java.util.Map; import java.util.*; @@ -37,7 +26,6 @@ import java.util.function.Function; import java.util.stream.Collectors; import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotWarnMsgService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotWarnMsgService.java index ec03b4840..e56d9e420 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotWarnMsgService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotWarnMsgService.java @@ -6,6 +6,8 @@ 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.vo.RobotWarnMsgPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnMsgSaveReqVO; +import cn.iocoder.yudao.module.system.controller.admin.statistics.dto.RobotWarnMsgClassificationDTO; +import cn.iocoder.yudao.module.system.controller.admin.statistics.dto.RobotWorkHourStatisticsDTO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnMsgDO; import com.baomidou.mybatisplus.extension.service.IService; @@ -67,4 +69,11 @@ public interface RobotWarnMsgService extends IService { String allRead(); List getWarnMsgByDetailIds(List detailIds); + + /** + * 统计故障根因分析 type 1:周, 2:月, 3:季度 + * @param type + * @return + */ + Map> robotWarnMsgClassification(String type); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotWarnMsgServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotWarnMsgServiceImpl.java index 6418ba47f..27e04c644 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotWarnMsgServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/RobotWarnMsgServiceImpl.java @@ -3,31 +3,36 @@ package cn.iocoder.yudao.module.system.service.robot; import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; 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.module.infra.api.websocket.WebSocketSenderApi; +import cn.iocoder.yudao.module.system.constant.CommonConstant; import cn.iocoder.yudao.module.system.constant.webSocket.WebSocketConstant; import cn.iocoder.yudao.module.system.controller.admin.log.vo.UserOperationLogSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnMsgPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnMsgSaveReqVO; +import cn.iocoder.yudao.module.system.controller.admin.statistics.dto.RobotWarnMsgClassificationDTO; import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnMsgDO; import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotWarnMsgMapper; import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum; import cn.iocoder.yudao.module.system.enums.robot.RobotWarnType; +import cn.iocoder.yudao.module.system.enums.robot.statistics.TimeTypeEnum; import cn.iocoder.yudao.module.system.service.log.UserOperationLogService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.WARN_MSG_NOT_EXISTS; @@ -54,7 +59,13 @@ public class RobotWarnMsgServiceImpl extends ServiceImpl positionMapDOS = positionMapMapper.selectList(new LambdaQueryWrapperX()); - if (ObjectUtil.isEmpty(positionMapDOS)){ + if (ObjectUtil.isEmpty(positionMapDOS)) { log.info("暂无楼层/区域信息,无法推送数据给前端"); return; } for (PositionMapDO positionMapDO : positionMapDOS) { - webSocketSenderApi.sendObject(positionMapDO.getFloor() + "_" + positionMapDO.getArea(), + webSocketSenderApi.sendObject(positionMapDO.getFloor() + CommonConstant.SYMBOL + positionMapDO.getArea(), WebSocketConstant.AGV_WARN, JSONUtil.toJsonStr(errorMsg)); } @@ -116,11 +127,11 @@ public class RobotWarnMsgServiceImpl extends ServiceImpl 200 ) { - message = message.substring(0,200); + if (message.length() > 200) { + message = message.substring(0, 200); } RobotWarnMsgDO warnMsg = RobotWarnMsgDO.builder().warnLevel(4) - .warnCode("PP") + .warnCode("DEVICE") .robotNo("") .warnType(RobotWarnType.PATH.getType()) .warnMsg(message) @@ -149,6 +160,7 @@ public class RobotWarnMsgServiceImpl extends ServiceImpl> robotWarnMsgClassification(String type) { + + if (TimeTypeEnum.WEEK.getType().equals(type)) { + List data = warnMsgMapper.getRobotWarnMsgClassification(type); + if (ObjectUtil.isEmpty(data)) { + return null; + } + + Map> map = + data.stream().collect(Collectors.groupingBy(RobotWarnMsgClassificationDTO::getWarnTime)); + + Calendar now = Calendar.getInstance(); + now.setTime(new Date()); + for (int i = 0; i < 7; i++) { + String timeStr = DateUtils.getYYYMMDD(now.getTime()); + if (!map.containsKey(timeStr)) { + map.put(timeStr,new ArrayList<>()); + } + now.set(Calendar.DATE, now.get(Calendar.DATE) - 1); + } + + return map; + } + + //季度是90天,分成10份,是9. getMonthData已经扣了1,所以是8 + int i = 8; + if (TimeTypeEnum.MONTH.getType().equals(type)) { + i= 2; + } + + return getMonthData(i); + } + + /** + * 按月查询 + * + * @param day + * @return + */ + private LinkedHashMap> getMonthData(int day) { + + Calendar now = Calendar.getInstance(); + now.setTime(new Date()); + now.set(Calendar.DATE, now.get(Calendar.DATE) + 1); + + LinkedHashMap> map = new LinkedHashMap<>(); + + for (int i = 0; i < 10; i++) { + Date startDate = now.getTime(); + now.set(Calendar.DATE, now.get(Calendar.DATE) - 1); + Date startKeyDate = now.getTime(); + String startKeyDateStr = DateUtils.getYYYMMDD(startKeyDate); + now.set(Calendar.DATE, now.get(Calendar.DATE) - day); + String startTime = DateUtils.getYYYMMDD(startDate); + Date endDate = now.getTime(); + String endTime = DateUtils.getYYYMMDD(endDate); + List data = warnMsgMapper.getRobotWarnMsgByTime(startTime, endTime); + + String key = startKeyDateStr + CommonConstant.SYMBOL + endTime; + map.put(key, data); + } + return map; + } + + + + + + + + + + + + + + + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/camera/RobotCameraServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/camera/RobotCameraServiceImpl.java index ceff33824..67593b3af 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/camera/RobotCameraServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/camera/RobotCameraServiceImpl.java @@ -15,7 +15,9 @@ import com.google.common.collect.Sets; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; + import javax.annotation.Resource; + import org.springframework.validation.annotation.Validated; import org.springframework.transaction.annotation.Transactional; @@ -90,6 +92,7 @@ public class RobotCameraServiceImpl extends ServiceImpl ips = robotCameraDOs.stream().map(RobotCameraDO::getCameraIp).collect(Collectors.toList()); String join = StringUtils.join(ips, ","); - throw exception(CAMERA_IP_EXIST,"以下摄像头IP已经存在 "+join); + throw exception(CAMERA_IP_EXIST, "以下摄像头IP已经存在 " + join); } @Override @@ -116,20 +119,32 @@ public class RobotCameraServiceImpl extends ServiceImpl cameraDOList = BeanUtils.toBean(cameraAddVOList, RobotCameraDO.class); for (RobotCameraDO robotCameraDO : cameraDOList) { try { - if (ObjectUtil.isEmpty(robotCameraDO.getId())) { - robotCameraDO.setCameraAccount(AESEncryptionUtil.encrypt(robotCameraDO.getCameraAccount(),cameraSecretKey)); - robotCameraDO.setCameraPassword(AESEncryptionUtil.encrypt(robotCameraDO.getCameraPassword(),cameraSecretKey)); - } + setCameraAccountAndPassword(robotCameraDO); } catch (Exception e) { - throw new RuntimeException(e); + throw exception(CAMERA_DECRYPTION_FAILED); } robotCameraDO.setRobotNo(robotNo); } cameraMapper.insert(cameraDOList); } + private void setCameraAccountAndPassword(RobotCameraDO robotCameraDO) { + if (ObjectUtil.isEmpty(robotCameraDO.getId())) { + try { + robotCameraDO.setCameraAccount(AESEncryptionUtil.encrypt(robotCameraDO.getCameraAccount(), cameraSecretKey)); + robotCameraDO.setCameraPassword(AESEncryptionUtil.encrypt(robotCameraDO.getCameraPassword(), cameraSecretKey)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + robotCameraDO.setCameraAccount(AESEncryptionUtil.getEncrypt(robotCameraDO.getCameraAccount(),cameraSecretKey)); + robotCameraDO.setCameraPassword(AESEncryptionUtil.getEncrypt(robotCameraDO.getCameraPassword(),cameraSecretKey)); + } + } + /** * 根据车辆编号删除 + * * @param robotNo */ @Override diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/AutoChargeServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/AutoChargeServiceImpl.java index 528e05212..385e74cfc 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/AutoChargeServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/AutoChargeServiceImpl.java @@ -1,16 +1,22 @@ package cn.iocoder.yudao.module.system.service.robot.job; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; +import cn.iocoder.yudao.module.system.api.robot.websocket.RobotStatusDataPoseDTO; +import cn.iocoder.yudao.module.system.constant.robot.RobotStatusCodeConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.controller.admin.config.vo.CommonConfigVO; +import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailAddVO; import cn.iocoder.yudao.module.system.dal.dataobject.config.CommonConfigDO; import cn.iocoder.yudao.module.system.dal.dataobject.information.DeviceInformationDO; 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.RobotTaskDO; import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDetailDO; import cn.iocoder.yudao.module.system.dal.mysql.config.CommonConfigMapper; import cn.iocoder.yudao.module.system.dal.mysql.information.DeviceInformationMapper; @@ -22,6 +28,7 @@ import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum; import cn.iocoder.yudao.module.system.enums.config.CommandConfigTypeEnum; 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.redis.RobotCacheLockEnum; import cn.iocoder.yudao.module.system.enums.robot.*; import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeModelEnum; import cn.iocoder.yudao.module.system.service.robot.pathplanning.RobotPathPlanningService; @@ -37,10 +44,10 @@ import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; +import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @Service @Slf4j @@ -70,6 +77,9 @@ public class AutoChargeServiceImpl implements AutoChargeService { @Value("${zn.full_electricity:100}") private String fullElectricity; + @Value("${zn.charge-no:CHARGE}") + private String chargeNo; + @Autowired private RobotPathPlanningService robotPathPlanningService; @@ -89,7 +99,7 @@ public class AutoChargeServiceImpl implements AutoChargeService { return; } - CommonConfigVO chargeConfig= JSONUtil.toBean(commonConfigDO.getConfigStr(),CommonConfigVO.class); + CommonConfigVO chargeConfig = JSONUtil.toBean(commonConfigDO.getConfigStr(), CommonConfigVO.class); List robots = robotInformationMapper.selectList(new LambdaQueryWrapperX() .eq(RobotInformationDO::getRobotStatus, RobotStatusEnum.STAND_BY.getType()) @@ -101,11 +111,30 @@ public class AutoChargeServiceImpl implements AutoChargeService { List deviceInformationDOS = deviceInformationMapper.selectList(new LambdaQueryWrapperX() .eq(DeviceInformationDO::getDeviceEnable, ZeroOneEnum.ONE.getType()) - .eq(DeviceInformationDO::getDeviceUseStatus, DeviceUseStatusEnum.IDLE.getType()) + .eq(DeviceInformationDO::getDeviceUseStatus, ZeroOneEnum.ZERO.getType()) .eq(DeviceInformationDO::getDeviceType, DeviceTypeEnum.CHARGING_STATION.getType())); if (ObjectUtil.isEmpty(deviceInformationDOS)) { log.info("充电任务,没有空闲的充电桩"); + robots = getNeedChargeRobot(robots, chargeConfig); + log.info("需要充电的车辆 :{}", JSON.toJSONString(robots)); + if (ObjectUtil.isEmpty(robots)) { + return; + } + + List chargeIngRobots = robotInformationMapper.selectList(new LambdaQueryWrapperX() + .eq(RobotInformationDO::getRobotStatus, RobotStatusEnum.CHARGE.getType()) + .eq(RobotInformationDO::getRobotTaskModel, RobotTaskModelEnum.NORMAL.getType())); + if (ObjectUtil.isEmpty(chargeIngRobots)) { + log.info("没有充电中的车辆"); + return; + } + List moveToWaitRobots = getCanLeaveChargingRobots(chargeIngRobots, chargeConfig, robots.size()); + if (ObjectUtil.isEmpty(moveToWaitRobots)) { + log.info("充电中的车辆未达到离开的阀值"); + return; + } + robotPathPlanningService.moveRobotToWait(moveToWaitRobots); return; } @@ -116,7 +145,7 @@ public class AutoChargeServiceImpl implements AutoChargeService { List chargeFullNos = new ArrayList<>(); if (ObjectUtil.isNotEmpty(chargeConfig.getChanceCycle())) { //查询充满电 - chargeFullNos = chargeLogMapper.getChargeFullRobotNos(chargeConfig.getChanceCycle(),robotNos); + chargeFullNos = chargeLogMapper.getChargeFullRobotNos(chargeConfig.getChanceCycle(), robotNos); } List taskDetailDOS = robotTaskDetailMapper.getChargeTaskDetail(); @@ -126,28 +155,189 @@ public class AutoChargeServiceImpl implements AutoChargeService { } List logs = new ArrayList<>(); + List tasks = new ArrayList<>(); + List taskDetails = new ArrayList<>(); //组装充电任务 - assembleChargeTask(robots,deviceInformationDOS,chargeConfig,chargeFullNos,logs,detailMap); + assembleChargeTask(robots, deviceInformationDOS, chargeConfig, chargeFullNos, logs, detailMap, tasks, taskDetails); if (ObjectUtil.isEmpty(logs)) { log.info("没有需要执行的充电任务"); return; } - - chargeLogMapper.insertBatch(logs); - robotPathPlanningService.sendChargeTaskToPP(logs,taskDetailDOS,robots); + if (ObjectUtil.isNotEmpty(tasks)) { + robotTaskMapper.insertBatch(tasks); + List bean = BeanUtils.toBean(taskDetails, RobotTaskDetailDO.class); + robotTaskDetailMapper.insertBatch(bean); + } + + chargeLogMapper.insert(logs); + + robotPathPlanningService.sendChargeTaskToPP(logs, taskDetailDOS, robots); //改成异步 logs.stream().forEach(v -> { - String chargeModelKey = RobotTaskChcheConstant.ROBOT_CHARGE_MODEL +v.getRobotNo(); - redisUtil.set(chargeModelKey,v.getChargeModel()); + String chargeModelKey = RobotTaskChcheConstant.ROBOT_CHARGE_MODEL + v.getRobotNo(); + redisUtil.set(chargeModelKey, v.getChargeModel()); }); } + /** + * 查询充电达到阀值,能离开的车辆 + * + * @param robots + * @param chargeConfig sum 需要移动的车辆数量 + * @return + */ + private List getCanLeaveChargingRobots(List robots, CommonConfigVO chargeConfig, int sum) { + List needChargeRobots = new ArrayList<>(); + Map map = new HashMap<>(); + Map robotMap = new HashMap<>(); + for (RobotInformationDO robot : robots) { + String taskStatusKey = RobotTaskChcheConstant.ROBOT_TASK_STATUS + robot.getMacAddress(); + String cargoDetectedKey = RobotTaskChcheConstant.ROBOT_CARGO_DETECTED + robot.getMacAddress(); + Object taskStatus = redisUtil.get(taskStatusKey); + if (ObjectUtil.isEmpty(taskStatus) || !RobotStatusCodeConstant.CAN_DO_TASK.equals(Boolean.parseBoolean(String.valueOf(taskStatus)))) { + robot.setRobotStatus(RobotStatusEnum.DOING.getType()); + log.info("车机上报不允许接任务 :{}", robot.getRobotNo()); + continue; + } + + Object cargoDetected = redisUtil.get(cargoDetectedKey); + if (ObjectUtil.isEmpty(cargoDetected) || RobotStatusCodeConstant.CARGO_DETECTED.equals(Boolean.parseBoolean(String.valueOf(cargoDetected)))) { + robot.setRobotStatus(RobotStatusEnum.DOING.getType()); + log.info("车机上报传感器被按下--不允许接任务 :{}", robot.getRobotNo()); + continue; + } + + Boolean adequateBatteryCapacity = remainingElectricityBigger(chargeConfig, robot); + if (adequateBatteryCapacity) { + robot.setRobotStatus(RobotStatusEnum.STAND_BY.getType()); + String socKey = RobotTaskChcheConstant.ROBOT_INFORMATION_SOC + robot.getMacAddress(); + Object o = redisUtil.get(socKey); + Integer soc = ObjectUtil.isEmpty(o) ? 0 : Integer.parseInt(o.toString()); + map.put(robot.getRobotNo(), soc); + robotMap.put(robot.getRobotNo(),robot); + } + } + + if (ObjectUtil.isEmpty(map)) { + return needChargeRobots; + } + + map = map.entrySet().stream() + .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x1, x2) -> x2, LinkedHashMap::new)); + + log.info("排序后的集合 :{}",JSON.toJSONString(map)); + for (Map.Entry item : map.entrySet()) { + if (needChargeRobots.size() > sum) { + break; + } + needChargeRobots.add(robotMap.get(item.getKey())); + } + log.info("充电达到阀值,可以移动到等待点的车辆 :{}",JSON.toJSONString(needChargeRobots)); + return needChargeRobots; + } + + /** + * 查询需要充电的车辆 + * + * @param robots + * @return + */ + private List getNeedChargeRobot(List robots, CommonConfigVO chargeConfig) { + List needChargeRobots = new ArrayList<>(); + for (RobotInformationDO robot : robots) { + String taskStatusKey = RobotTaskChcheConstant.ROBOT_TASK_STATUS + robot.getMacAddress(); + String cargoDetectedKey = RobotTaskChcheConstant.ROBOT_CARGO_DETECTED + robot.getMacAddress(); + Object taskStatus = redisUtil.get(taskStatusKey); + if (ObjectUtil.isEmpty(taskStatus) || !RobotStatusCodeConstant.CAN_DO_TASK.equals(Boolean.parseBoolean(String.valueOf(taskStatus)))) { + robot.setRobotStatus(RobotStatusEnum.DOING.getType()); + log.info("车机上报不允许接任务 :{}", robot.getRobotNo()); + continue; + } + + Object cargoDetected = redisUtil.get(cargoDetectedKey); + if (ObjectUtil.isEmpty(cargoDetected) || RobotStatusCodeConstant.CARGO_DETECTED.equals(Boolean.parseBoolean(String.valueOf(cargoDetected)))) { + robot.setRobotStatus(RobotStatusEnum.DOING.getType()); + log.info("车机上报传感器被按下--不允许接任务 :{}", robot.getRobotNo()); + continue; + } + + Boolean adequateBatteryCapacity = remainingElectricityBigger(chargeConfig, robot); + if (!adequateBatteryCapacity) { + needChargeRobots.add(robot); + + } + } + return needChargeRobots; + } + + /** + * 剩余电量是否大于设置的充电阀值 + * + * @param chargeConfig + * @param robot + */ + private Boolean remainingElectricityBigger(CommonConfigVO chargeConfig, RobotInformationDO robot) { + String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT + robot.getMacAddress(); + String chargeModelKey = RobotTaskChcheConstant.ROBOT_CHARGE_MODEL + robot.getRobotNo(); + Object chargeModelCache = redisUtil.get(chargeModelKey); + Object poseCache = redisUtil.get(pose2dKey); +// RobotStatusDataPoseDTO dataPoseDTO = JSON.parseObject((String) poseCache, RobotStatusDataPoseDTO.class); +// log.info("充电机器人编号:{} ,信息: {}", robot.getRobotNo(), JSON.toJSONString(dataPoseDTO)); + + String socKey = RobotTaskChcheConstant.ROBOT_INFORMATION_SOC + robot.getMacAddress(); + Object o = redisUtil.get(socKey); + String soc = ObjectUtil.isEmpty(o) ? "0" : o.toString(); + + if (ObjectUtil.isEmpty(poseCache) || ObjectUtil.isEmpty(o)) { + log.info("没有点位信息/或者没有电量信息 :{}", robot.getRobotNo()); + return false; + } + + //车子剩余电量 + BigDecimal robotRemainingElectricity = new BigDecimal(soc); + //设置离开的电量 + BigDecimal robotEndElectricity = new BigDecimal("30"); + + if (ObjectUtil.isNotEmpty(robot.getAutoCharge()) && ObjectUtil.isNotEmpty(chargeModelCache) + && !ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) { + robotEndElectricity = new BigDecimal(String.valueOf(robot.getAutoCharge())); + } else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) { + robotEndElectricity = new BigDecimal(fullElectricity); + } else if (ObjectUtil.isNotEmpty(chargeModelCache) && ChargeModelEnum.CHANCE.getType().equals((Integer) chargeModelCache) + && ObjectUtil.isNotEmpty(chargeConfig.getEndAutoCharge())) { + robotEndElectricity = new BigDecimal(String.valueOf(chargeConfig.getChanceChargeEnd())); + } else if (ObjectUtil.isNotEmpty(chargeConfig.getEndAutoCharge())) { + robotEndElectricity = new BigDecimal(String.valueOf(chargeConfig.getEndAutoCharge())); + } + + if (robotRemainingElectricity.compareTo(robotEndElectricity) >= 0) { + return true; + } else { + log.info("机器人正在充电,还没达到充电设置的电量,暂不能接任务:{} ", robot.getRobotNo()); + } + return false; + } + + public Integer getSocByMac(RobotInformationDO robot) { + String socKey = RobotTaskChcheConstant.ROBOT_INFORMATION_SOC + robot.getMacAddress(); + Object socObject = redisUtil.get(socKey); + + if (ObjectUtil.isEmpty(socObject)) { + log.info("当前机器人查不到电量信息,所以不执行充电 :{}", robot.getRobotNo()); + return null; + } + String[] split = socObject.toString().split("\\."); + return Integer.valueOf(split[0]); + } + /** * 组装充电任务 + * * @param robots * @param deviceInformationDOS * @param chargeConfig @@ -157,29 +347,34 @@ public class AutoChargeServiceImpl implements AutoChargeService { */ public void assembleChargeTask(List robots, List deviceInformationDOS, CommonConfigVO chargeConfig, List chargeFullNos, - List logs, Map> detailMap) { + List logs, Map> detailMap, + List tasks, List taskDetails) { //判断机器人身上的电量少于设定的电量 for (RobotInformationDO robot : robots) { - String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC +robot.getMacAddress(); + String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT + robot.getMacAddress(); Object poseCache = redisUtil.get(pose2dKey); - RobotStatusDataPoseDTO dataPoseDTO= JSON.parseObject((String)poseCache, RobotStatusDataPoseDTO.class); - if (ObjectUtil.isEmpty(dataPoseDTO) || ObjectUtil.isEmpty(dataPoseDTO.getBatSoc())) { - log.info("当前机器人查不到电量信息,所以不执行充电 :{}",robot.getRobotNo()); + if (ObjectUtil.isEmpty(poseCache)) { + log.info("查不到车辆的点位信息 :{}", robot.getRobotNo()); + continue; + } + + Integer electricity = getSocByMac(robot); + if (ObjectUtil.isEmpty(electricity)) { continue; } if (ObjectUtil.isEmpty(deviceInformationDOS)) { - log.info("充电桩分配完成 :{}",robot.getRobotNo()); + log.info("充电桩分配完成 :{}", robot.getRobotNo()); break; } DeviceInformationDO deviceInformationDO = deviceInformationDOS.stream() .filter(v -> v.getDeviceAttribute().equals(robot.getChargeType()) - && robot.getFloorAreaJson().contains(v.getPositionMapId())) + && robot.getFloorAreaJson().contains(v.getPositionMapId())) .findFirst() .orElse(new DeviceInformationDO()); if (ObjectUtil.isEmpty(deviceInformationDO.getDeviceNo())) { - log.info("当前机器人查不到对应的充电桩类型、或者机器人不能在此区域充电 :{}",robot.getRobotNo()); + log.info("当前机器人查不到对应的充电桩类型、或者机器人不能在此区域充电 :{}", robot.getRobotNo()); continue; } @@ -187,19 +382,23 @@ public class AutoChargeServiceImpl implements AutoChargeService { logDo.setRobotNo(robot.getRobotNo()); logDo.setDeviceNo(deviceInformationDO.getDeviceNo()); logDo.setPositionMapItemId(deviceInformationDO.getPositionMapItemId()); - String[] split = dataPoseDTO.getBatSoc().split("\\."); - logDo.setStartElectricity(Integer.valueOf(split[0])); + + + logDo.setStartElectricity(electricity); //配置的充满电电量 BigDecimal robotFullElectricity = new BigDecimal(fullElectricity); //车子剩余电量 - BigDecimal robotRemainingElectricity = new BigDecimal(split[0]); + BigDecimal robotRemainingElectricity = new BigDecimal(electricity + ""); if (ObjectUtil.isNotEmpty(chargeConfig.getChanceCycle()) && !chargeFullNos.contains(robot.getRobotNo()) && robotRemainingElectricity.compareTo(robotFullElectricity) < 0) { //充满电 logDo.setChargeModel(ChargeModelEnum.FULL.getType()); + Long taskDetailId = createChargeTask(robot.getRobotNo(), tasks, taskDetails, deviceInformationDO.getPositionMapItemId(), deviceInformationDO.getDeviceNo()); + logDo.setTaskDetailId(taskDetailId); + logDo.setId(logDo.getTaskDetailId()); logs.add(logDo); deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo())); - log.info("分配到充满电充电任务 :{} ,充电设备编号是 :{}, 任务id :{}",logDo.getRobotNo(),logDo.getDeviceNo(),logDo.getTaskDetailId()); + log.info("分配到充满电充电任务 :{} ,充电设备编号是 :{}, 任务id :{}", logDo.getRobotNo(), logDo.getDeviceNo(), logDo.getTaskDetailId()); continue; } @@ -212,8 +411,9 @@ public class AutoChargeServiceImpl implements AutoChargeService { deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo())); logDo.setChargeModel(ChargeModelEnum.TASK.getType()); logDo.setTaskDetailId(robotTaskDetailDO.getId()); + logDo.setId(logDo.getTaskDetailId()); logs.add(logDo); - log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}",logDo.getRobotNo(),logDo.getDeviceNo(),logDo.getTaskDetailId()); + log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}", logDo.getRobotNo(), logDo.getDeviceNo(), logDo.getTaskDetailId()); continue; } } @@ -227,8 +427,9 @@ public class AutoChargeServiceImpl implements AutoChargeService { deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo())); logDo.setChargeModel(ChargeModelEnum.TASK.getType()); logDo.setTaskDetailId(robotTaskDetailDO.getId()); + logDo.setId(logDo.getTaskDetailId()); logs.add(logDo); - log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}",logDo.getRobotNo(),logDo.getDeviceNo(),logDo.getTaskDetailId()); + log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}", logDo.getRobotNo(), logDo.getDeviceNo(), logDo.getTaskDetailId()); continue; } } @@ -242,8 +443,9 @@ public class AutoChargeServiceImpl implements AutoChargeService { deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo())); logDo.setChargeModel(ChargeModelEnum.TASK.getType()); logDo.setTaskDetailId(robotTaskDetailDO.getId()); + logDo.setId(logDo.getTaskDetailId()); logs.add(logDo); - log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}",logDo.getRobotNo(),logDo.getDeviceNo(),logDo.getTaskDetailId()); + log.info("分配到任务充电任务 :{} ,充电设备编号是 :{}, 任务id :{}", logDo.getRobotNo(), logDo.getDeviceNo(), logDo.getTaskDetailId()); continue; } } @@ -253,9 +455,12 @@ public class AutoChargeServiceImpl implements AutoChargeService { BigDecimal robotConfigElectricity = new BigDecimal(String.valueOf(robot.getAutoCharge())); if (robotRemainingElectricity.compareTo(robotConfigElectricity) < 0) { logDo.setChargeModel(ChargeModelEnum.AUTO.getType()); + Long taskDetailId = createChargeTask(robot.getRobotNo(), tasks, taskDetails, deviceInformationDO.getPositionMapItemId(), deviceInformationDO.getDeviceNo()); + logDo.setTaskDetailId(taskDetailId); + logDo.setId(logDo.getTaskDetailId()); logs.add(logDo); deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo())); - log.info("分配到自动充电任务 :{} ,充电设备编号是 :{}",logDo.getRobotNo(),logDo.getDeviceNo()); + log.info("分配到自动充电任务 :{} ,充电设备编号是 :{}", logDo.getRobotNo(), logDo.getDeviceNo()); continue; } } @@ -265,9 +470,12 @@ public class AutoChargeServiceImpl implements AutoChargeService { BigDecimal robotConfigElectricity = new BigDecimal(String.valueOf(chargeConfig.getStartAutoCharge())); if (robotRemainingElectricity.compareTo(robotConfigElectricity) < 0) { logDo.setChargeModel(ChargeModelEnum.AUTO.getType()); + Long taskDetailId = createChargeTask(robot.getRobotNo(), tasks, taskDetails, deviceInformationDO.getPositionMapItemId(), deviceInformationDO.getDeviceNo()); + logDo.setTaskDetailId(taskDetailId); + logDo.setId(logDo.getTaskDetailId()); logs.add(logDo); deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo())); - log.info("分配到自动充电任务 :{} ,充电设备编号是 :{}",logDo.getRobotNo(),logDo.getDeviceNo()); + log.info("分配到自动充电任务 :{} ,充电设备编号是 :{}", logDo.getRobotNo(), logDo.getDeviceNo()); continue; } } @@ -277,12 +485,40 @@ public class AutoChargeServiceImpl implements AutoChargeService { BigDecimal robotConfigElectricity = new BigDecimal(String.valueOf(chargeConfig.getChanceChargeStart())); if (robotRemainingElectricity.compareTo(robotConfigElectricity) < 0) { logDo.setChargeModel(ChargeModelEnum.CHANCE.getType()); + Long taskDetailId = createChargeTask(robot.getRobotNo(), tasks, taskDetails, deviceInformationDO.getPositionMapItemId(), deviceInformationDO.getDeviceNo()); + logDo.setTaskDetailId(taskDetailId); + logDo.setId(logDo.getTaskDetailId()); logs.add(logDo); deviceInformationDOS.removeIf(v -> logDo.getDeviceNo().equals(v.getDeviceNo())); - log.info("分配到机会充电任务 :{} ,充电设备编号是 :{}",logDo.getRobotNo(),logDo.getDeviceNo()); + log.info("分配到机会充电任务 :{} ,充电设备编号是 :{}", logDo.getRobotNo(), logDo.getDeviceNo()); } } } } + /** + * 自动充电 + */ + public Long createChargeTask(String robotNo, List tasks, List taskDetails, Long positionMapItemId, String deviceNo) { + RobotTaskDO task = new RobotTaskDO(); + String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.CHARGE_TASK_NO.getKey()); + task.setTaskNo(chargeNo + DateUtils.getYearMonthDay() + incrementByKey); + task.setId(IdUtil.getSnowflakeNextId()); + task.setCycleNumber(0L); + task.setRemainingCycleNumber(0L); + task.setStartTime(LocalDateTime.now()); + + RobotTaskDetailAddVO detailAddVO = new RobotTaskDetailAddVO(); + detailAddVO.setId(IdUtil.getSnowflakeNextId()); + detailAddVO.setRobotTaskId(task.getId()); + detailAddVO.setTaskType(RobotTaskTypeEnum.CHARGE.getType()); + detailAddVO.setReleaseType(ReleaseTakeEnum.TO_LOCATION.getType()); + detailAddVO.setReleaseId(positionMapItemId); + detailAddVO.setToLocationNo(deviceNo); + detailAddVO.setRobotNo(robotNo); + tasks.add(task); + taskDetails.add(detailAddVO); + return detailAddVO.getId(); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/CycleServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/CycleServiceImpl.java index db3f67618..819f01c83 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/CycleServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/CycleServiceImpl.java @@ -1,16 +1,12 @@ package cn.iocoder.yudao.module.system.service.robot.job; import cn.hutool.core.util.ObjectUtil; -import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailAddVO; -import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskRespVO; -import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; 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.RobotWarnCodeMappingDO; import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskDetailMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskMapper; @@ -18,7 +14,7 @@ import cn.iocoder.yudao.module.system.enums.redis.RobotCacheLockEnum; import cn.iocoder.yudao.module.system.enums.robot.LocationLockEnum; import cn.iocoder.yudao.module.system.enums.robot.RobotTaskDetailStatusEnum; import cn.iocoder.yudao.module.system.enums.robot.RobotTaskStatusEnum; -import cn.iocoder.yudao.module.system.service.robot.RobotTaskDetailService; +import cn.iocoder.yudao.module.system.enums.robot.RobotTaskTypeEnum; import cn.iocoder.yudao.module.system.service.robot.RobotTaskService; import cn.iocoder.yudao.module.system.util.redis.RedisUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -35,7 +31,6 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static com.baomidou.mybatisplus.core.toolkit.IdWorker.getId; @Service @@ -136,6 +131,7 @@ public class CycleServiceImpl implements CycleService { .takeType(v.getReleaseType()) .releaseId(v.getTakeId()) .takeId(v.getReleaseId()) + .robotNo(v.getRobotNo()) .fromLocationNo(v.getToLocationNo()) .fromLocationId(v.getToLocationId()) .fromLaneId(v.getToLaneId()) @@ -155,6 +151,16 @@ public class CycleServiceImpl implements CycleService { .fromMapItemId(v.getToMapItemId()) .toMapItemId(v.getFromMapItemId()) .build(); + + if (RobotTaskTypeEnum.MOVE_TO_POINT.getType().equals(build.getTaskType())) { + build.setToLocationNo(v.getToLocationNo()); + build.setToLocationId(v.getToLocationId()); + build.setReleaseId(v.getReleaseId()); + build.setFromLocationNo(null); + build.setFromLocationId(null); + build.setTakeId(null); + } + taskDetailDOList.add(build); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/DistributeTasksServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/DistributeTasksServiceImpl.java index 8c86f2a38..7ddcb96a6 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/DistributeTasksServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/DistributeTasksServiceImpl.java @@ -4,7 +4,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.json.JSONUtil; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; +import cn.iocoder.yudao.module.system.api.robot.websocket.RobotStatusDataPoseDTO; import cn.iocoder.yudao.module.system.constant.robot.RobotStatusCodeConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.controller.admin.config.vo.CommonConfigVO; @@ -98,11 +98,11 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { } //机器人最后做的任务 - List lastTaskDetails = robotTaskDetailMapper.getLastTaskGroupByRobotNo(); + /*List lastTaskDetails = robotTaskDetailMapper.getLastTaskGroupByRobotNo(); Map lastTaskDetailMap = null; if (ObjectUtil.isNotEmpty(lastTaskDetails)) { lastTaskDetailMap = lastTaskDetails.stream().collect(Collectors.toMap(v -> v.getRobotNo(), Function.identity())); - } + }*/ CommonConfigVO chargeConfig = JSONUtil.toBean(commonConfigDO.getConfigStr(), CommonConfigVO.class); @@ -113,7 +113,7 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { } String taskStatusKey = RobotTaskChcheConstant.ROBOT_TASK_STATUS + robot.getMacAddress(); - String cargoDetectedKey = RobotTaskChcheConstant.ROBOT_CARGO_DETECTED + robot.getMacAddress(); + Object taskStatus = redisUtil.get(taskStatusKey); if (ObjectUtil.isEmpty(taskStatus) || !RobotStatusCodeConstant.CAN_DO_TASK.equals(Boolean.parseBoolean(String.valueOf(taskStatus)))) { robot.setRobotStatus(RobotStatusEnum.DOING.getType()); @@ -121,23 +121,23 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { continue; } - Object cargoDetected = redisUtil.get(cargoDetectedKey); + //取货的,先执行放货再去充电 - if (ObjectUtil.isNotEmpty(lastTaskDetailMap) && ObjectUtil.isNotEmpty(lastTaskDetailMap.get(robot.getRobotNo()))) { + /*if (ObjectUtil.isNotEmpty(lastTaskDetailMap) && ObjectUtil.isNotEmpty(lastTaskDetailMap.get(robot.getRobotNo()))) { robot.setRobotStatus(RobotStatusEnum.LAST_TASK_IS_TAKE.getType()); continue; - } + }*/ if (ObjectUtil.isNotEmpty(chargeConfig) && ObjectUtil.isNotEmpty(chargeConfig.getStartAutoCharge())) { - String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + robot.getMacAddress(); - Object poseCache = redisUtil.get(pose2dKey); - RobotStatusDataPoseDTO dataPoseDTO = JSON.parseObject((String) poseCache, RobotStatusDataPoseDTO.class); - if (ObjectUtil.isEmpty(dataPoseDTO.getBatSoc())) { + String socKey = RobotTaskChcheConstant.ROBOT_INFORMATION_SOC +robot.getMacAddress(); + Object socObject = redisUtil.get(socKey); + + if (ObjectUtil.isEmpty(socObject)) { robot.setRobotStatus(RobotStatusEnum.DOING.getType()); log.info("车机没有电量信息 :{}",robot.getRobotNo()); continue; } - BigDecimal robotRemainingElectricity = new BigDecimal(dataPoseDTO.getBatSoc()); + BigDecimal robotRemainingElectricity = new BigDecimal(socObject.toString()); BigDecimal robotEndElectricity = new BigDecimal(chargeConfig.getStartAutoCharge()+""); if (robotRemainingElectricity.compareTo(robotEndElectricity) < 0) { robot.setRobotStatus(RobotStatusEnum.DOING.getType()); @@ -146,28 +146,27 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { } } - if (ObjectUtil.isEmpty(cargoDetected) || RobotStatusCodeConstant.CARGO_DETECTED.equals(Boolean.parseBoolean(String.valueOf(cargoDetected)))) { - robot.setRobotStatus(RobotStatusEnum.DOING.getType()); - log.info("车机上报传感器被按下--不允许接任务 :{}",robot.getRobotNo()); - continue; - } + //自动充电的车子,电量到达设定的阀值,也能执行任务 /*if (ChargeTypeEnum.AUTOMATIC.getType().equals(robot.getChargeType()) && RobotStatusEnum.CHARGE.getType().equals(robot.getRobotStatus())) { setRobotStatus(commonConfigDO, robot); }*/ - setRobotStatus(commonConfigDO, robot); + Boolean b = remainingElectricityBigger(chargeConfig, robot); + if (b) { + robot.setRobotStatus(RobotStatusEnum.STAND_BY.getType()); + } } - robots = robots.stream() + /*robots = robots.stream() .filter(v -> (RobotStatusEnum.STAND_BY.getType().equals(v.getRobotStatus()) || RobotStatusEnum.LAST_TASK_IS_TAKE.getType().equals(v.getRobotStatus()))) - .collect(Collectors.toList()); + .collect(Collectors.toList());*/ - if (robots.isEmpty()) { + /*if (robots.isEmpty()) { log.info("暂无可用的机器人,可能正在充电,可能车机上报不允许接任务"); return pair; - } + }*/ log.info("完成查找车子"); @@ -190,14 +189,14 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { if (ObjectUtil.isEmpty(montageTaskIds) && ObjectUtil.isEmpty(singleTaskIds)) { log.info("暂无需要处理的主任务"); - return pair; + return ImmutablePair.of(robots, null); } List taskDetails = getTaskDetail(montageTaskIds, singleTaskIds); if (taskDetails.isEmpty()) { log.info("暂无需要处理的明细任务"); - return pair; + return ImmutablePair.of(robots, null); } return ImmutablePair.of(robots, taskDetails); } @@ -229,29 +228,31 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { } /** - * 设置机器人的状态 + * 剩余电量是否大于设置的充电阀值 * - * @param commonConfigDO + * @param chargeConfig * @param robot */ - private void setRobotStatus(CommonConfigDO commonConfigDO, RobotInformationDO robot) { - String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + robot.getMacAddress(); + private Boolean remainingElectricityBigger(CommonConfigVO chargeConfig, RobotInformationDO robot) { + String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT + robot.getMacAddress(); String chargeModelKey = RobotTaskChcheConstant.ROBOT_CHARGE_MODEL + robot.getRobotNo(); Object chargeModelCache = redisUtil.get(chargeModelKey); Object poseCache = redisUtil.get(pose2dKey); RobotStatusDataPoseDTO dataPoseDTO = JSON.parseObject((String) poseCache, RobotStatusDataPoseDTO.class); log.info("充电机器人编号:{} ,信息: {}", robot.getRobotNo(), JSON.toJSONString(dataPoseDTO)); - if (ObjectUtil.isEmpty(commonConfigDO) || ObjectUtil.isEmpty(poseCache) || ObjectUtil.isEmpty(dataPoseDTO.getBatSoc())) { - return; + String socKey = RobotTaskChcheConstant.ROBOT_INFORMATION_SOC +robot.getMacAddress(); + Object o = redisUtil.get(socKey); + String soc = ObjectUtil.isEmpty(o) ? "0": o.toString(); + + if ( ObjectUtil.isEmpty(poseCache) || ObjectUtil.isEmpty(o)) { + return false; } - CommonConfigVO chargeConfig = JSONUtil.toBean(commonConfigDO.getConfigStr(), CommonConfigVO.class); - //车子剩余电量 - BigDecimal robotRemainingElectricity = new BigDecimal(dataPoseDTO.getBatSoc()); + BigDecimal robotRemainingElectricity = new BigDecimal(soc); //设置离开的电量 - BigDecimal robotEndElectricity = new BigDecimal("10"); + BigDecimal robotEndElectricity = new BigDecimal("30"); if (ObjectUtil.isNotEmpty(robot.getAutoCharge()) && ObjectUtil.isNotEmpty(chargeModelCache) && !ChargeModelEnum.FULL.getType().equals((Integer) chargeModelCache)) { @@ -266,10 +267,11 @@ public class DistributeTasksServiceImpl implements DistributeTasksService { } if (robotRemainingElectricity.compareTo(robotEndElectricity) >= 0) { - robot.setRobotStatus(RobotStatusEnum.STAND_BY.getType()); + return true; }else { log.info("机器人正在充电,还没达到充电设置的电量,暂不能接任务:{} ", robot.getRobotNo()); } + return false; } /** diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/RobotTaskAutoMoveServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/RobotTaskAutoMoveServiceImpl.java index 75375bb46..7f6a94d96 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/RobotTaskAutoMoveServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/job/RobotTaskAutoMoveServiceImpl.java @@ -54,26 +54,12 @@ public class RobotTaskAutoMoveServiceImpl implements RobotTaskAutoMoveService { @Resource private RobotTaskAutoMoveMapper taskAutoMoveMapper; - @Autowired - private RobotInformationMapper robotInformationMapper; - - @Autowired - private RobotTaskMapper robotTaskMapper; - @Autowired private RobotTaskDetailMapper robotTaskDetailMapper; - @Resource - private RobotTaskApi robotTaskApi; - - @Resource - private PositionMapItemMapper positionMapItemMapper; - @Resource private WareHouseLocationMapper locationMapper; - @Autowired - private DistributeTasksService distributeTasksService; @Value("${zn.lane_auto_move:true}") private Boolean laneAutoMove; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/pathplanning/RobotPathPlanningService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/pathplanning/RobotPathPlanningService.java index abad18799..937890492 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/pathplanning/RobotPathPlanningService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/pathplanning/RobotPathPlanningService.java @@ -17,4 +17,6 @@ public interface RobotPathPlanningService { List robots); List getRobotNoLimitationArea(List robots); + + void moveRobotToWait(List robots); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/pathplanning/RobotPathPlanningServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/pathplanning/RobotPathPlanningServiceImpl.java index 6529adb05..14e07d975 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/pathplanning/RobotPathPlanningServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/robot/pathplanning/RobotPathPlanningServiceImpl.java @@ -1,39 +1,43 @@ package cn.iocoder.yudao.module.system.service.robot.pathplanning; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.json.JSONUtil; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; -import cn.iocoder.yudao.module.mqtt.api.path.PathPlanningApi; +import cn.iocoder.yudao.module.mqtt.api.common.CommonApi; import cn.iocoder.yudao.module.mqtt.api.path.task.TaskLimitationAreaDTO; 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.RobotStatusCodeConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; -import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.RobotPositionMapDTO; +import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskDetailAddVO; import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; 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.RobotChargeLogDO; 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.wait.MoveToWaitDO; import cn.iocoder.yudao.module.system.dal.mysql.houselocation.WareHouseLocationMapper; 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.RobotTaskDetailMapper; import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotTaskMapper; -import cn.iocoder.yudao.module.system.dal.mysql.wait.MoveToWaitMapper; import cn.iocoder.yudao.module.system.enums.common.ZeroOneEnum; import cn.iocoder.yudao.module.system.enums.item.PositionMapItemEnum; +import cn.iocoder.yudao.module.system.enums.item.UseStatusEnum; 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.*; import cn.iocoder.yudao.module.system.enums.robot.charge.ChargeModelEnum; import cn.iocoder.yudao.module.system.enums.robot.information.ChargeTypeEnum; +import cn.iocoder.yudao.module.system.service.robot.RobotInformationService; +import cn.iocoder.yudao.module.system.service.robot.RobotTaskService; import cn.iocoder.yudao.module.system.service.robot.job.DistributeTasksService; import cn.iocoder.yudao.module.system.util.redis.RedisUtil; import com.alibaba.fastjson.JSON; @@ -42,6 +46,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; @@ -81,9 +86,6 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { @Resource private PositionMapMapper positionMapMapper; - @Resource - private PathPlanningApi pathPlanningApi; - @Value("${zn.robot_chearg.release_location_number_config:50}") private Long releaseLocationNumberConfig; @@ -96,12 +98,26 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { @Value("${zn.path_planning.task_chche_time:604800}") private Long taskChcheTime; - @Resource - private MoveToWaitMapper moveToWaitMapper; + @Value("${zn.move-no:MOVE}") + private String moveTaskNo; + + @Value("${zn.robot_config.default_tray_height:0.82}") + private Double defaultTrayHeight; @Autowired private RobotTaskMapper robotTaskMapper; + @Resource + private CommonApi commonApi; + + @Resource + @Lazy + private RobotTaskService taskService; + + @Resource + @Lazy + private RobotInformationService informationService; + /** * 下发任务给PP */ @@ -110,7 +126,6 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { public void sendTaskToPP() { TenantContextHolder.setTenantId(1L); - log.info("-------开始查找车子和任务------"); Pair, List> robotAndTaskDetails = distributeTasksService.getRobotAndTaskDetails(); @@ -172,10 +187,18 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { * * @param robots */ - private void moveRobotToWait(List robots) { + @Override + public void moveRobotToWait(List robots) { + + List detailDOS = robotTaskDetailMapper.selectAutoCreateCycleTask(); + + if (ObjectUtil.isNotEmpty(detailDOS)) { + log.info("---存在需要自动创建循环的任务,不移动到等待点--"); + return; + } robots = robots.stream() - .filter(v -> !v.getRobotStatus().equals(RobotStatusEnum.STAND_BY.getType())) + .filter(v -> v.getRobotStatus().equals(RobotStatusEnum.STAND_BY.getType())) .collect(Collectors.toList()); if (ObjectUtil.isEmpty(robots)) { log.info("------没有空闲的机器人可以去等待点-----"); @@ -183,135 +206,121 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { } List positionMapItems = positionMapItemMapper.selectList(new LambdaQueryWrapperX() - .eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType()) - .eq(PositionMapItemDO::getUseStatus, ZeroOneEnum.ZERO.getType())); + .eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType())); + if (ObjectUtil.isEmpty(positionMapItems)) { - log.info("------没有空闲的停车点-----"); + log.info("------没有设置停车点,无法派发空闲的车辆去停车-----"); return; } - List positionMaps = positionMapMapper.selectList(new LambdaQueryWrapperX()); - Map positionMap = - positionMaps.stream().collect(Collectors.toMap(v -> v.getFloor() + "_" + v.getArea(), Function.identity())); + List robotNos = robots.stream().map(RobotInformationDO::getRobotNo).collect(Collectors.toList()); - List list = new ArrayList<>(); - for (RobotInformationDO robot : robots) { - String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + robot.getMacAddress(); - Object object = redisUtil.get(pose2dKey); - RobotStatusDataPoseDTO robotStatusDataPoseDTO = JSONUtil.toBean((String) object, RobotStatusDataPoseDTO.class); - if (ObjectUtil.isEmpty(object) || ObjectUtil.isEmpty(robotStatusDataPoseDTO)) { - log.info("------此机器人没有点位信息------ :{}", robot.getRobotNo()); - continue; - } - String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + robot.getMacAddress(); - Object floorAreaObject = redisUtil.get(floorAreaKey); - FloorZoneDTO floorZoneDTO = JSONUtil.toBean((String) floorAreaObject, FloorZoneDTO.class); - - String mapKey = floorZoneDTO.getFloor() + "_" + floorZoneDTO.getArea(); - PositionMapDO positionMapDO = positionMap.get(mapKey); - if (ObjectUtil.isEmpty(positionMapDO)) { - log.info("------此机器人没有匹配到楼层和区域------ :{}", robot.getRobotNo()); - } - RobotPositionMapDTO build = RobotPositionMapDTO.builder() - .actualLocationX(robotStatusDataPoseDTO.getX()) - .actualLocationY(robotStatusDataPoseDTO.getY()) - .robotNo(robot.getRobotNo()) - .positionMapId(positionMapDO.getId()) - .type(PositionMapItemEnum.STOP.getType()) - .build(); - list.add(build); - } - - if (ObjectUtil.isEmpty(list)) { - log.info("------没有需要移动到等待点的机器人------"); - return; - } - - //在等待点的车 - List existItems = positionMapItemMapper.selectInWaitList(list); - if (ObjectUtil.isEmpty(existItems)) { - robotToWait(list, positionMapItems); - } else { - robotToWaitFilterWait(list, positionMapItems, existItems); - } - } - - /** - * 派部分车去停车点 - * - * @param list 车辆 - * @param freePositionMapItems 空闲点位 - * @param existItems 已经有车的点位 - */ - private void robotToWaitFilterWait(List list, List freePositionMapItems, - List existItems) { - Map robotNoPositionMap = - list.stream().collect(Collectors.toMap(v -> v.getActualLocationX() + "_" - + v.getActualLocationY() + "_" + v.getPositionMapId(), Function.identity())); - - Map existItemsMap = - existItems.stream().collect(Collectors.toMap(v -> v.getActualLocationX() + "_" - + v.getActualLocationY() + "_" + v.getPositionMapId(), Function.identity())); - - List needMoveToWaitList = new ArrayList<>(); - robotNoPositionMap.forEach((key, value) -> { - PositionMapItemDO positionMapItemDO = existItemsMap.get(key); - if (ObjectUtil.isEmpty(positionMapItemDO)) { - needMoveToWaitList.add(value); - } - }); - - if (ObjectUtil.isEmpty(needMoveToWaitList)) { - log.info("没有需要移动到等待点的车辆"); - return; - } - robotToWait(needMoveToWaitList, freePositionMapItems); - } - - /** - * 派车去停车点 - * - * @param list - * @param positionMapItems - */ - private void robotToWait(List list, List positionMapItems) { - if (positionMapItems.size() < list.size()) { - log.info("空闲停车点少于车辆数量"); - list = list.subList(0, positionMapItems.size()); - } - - List waitIds = positionMapItems - .stream() - .map(u -> u.getId() + "") + List existMapItems = positionMapItems.stream() + .filter(v -> ObjectUtil.isNotEmpty(v.getRobotNo()) && robotNos.contains(v.getRobotNo())) .collect(Collectors.toList()); - List waits = list.stream() - .map(v -> { - MoveToWaitDO build = MoveToWaitDO.builder().robotNo(v.getRobotNo()).build(); - return build; - }) - .collect(Collectors.toList()); - moveToWaitMapper.insertBatch(waits); + + //车辆直接分配的停车点集合 + List robotMapItems = new ArrayList<>(); + if (ObjectUtil.isNotEmpty(existMapItems)) { + + for (PositionMapItemDO positionMapItem : existMapItems) { + if (ObjectUtil.isEmpty(robots)) { + break; + } + robotNos.removeIf(v -> v.equals(positionMapItem.getRobotNo())); + positionMapItem.setUseStatus(UseStatusEnum.PRE_OCCUPANCY.getType()); + robotMapItems.add(positionMapItem); + positionMapItems.removeIf(v -> v.getId().equals(positionMapItem.getId())); + } + } + + if (ObjectUtil.isNotEmpty(robotNos)) { + List emptyMapItems = positionMapItems.stream() + .filter(v -> UseStatusEnum.FREE.getType().equals(v.getUseStatus())) + .collect(Collectors.toList()); + if (ObjectUtil.isNotEmpty(emptyMapItems)) { + for (PositionMapItemDO positionMapItem : emptyMapItems) { + if (ObjectUtil.isEmpty(robotNos)) { + break; + } + positionMapItem.setRobotNo(robotNos.get(0)); + robotNos.removeIf(v -> v.equals(positionMapItem.getRobotNo())); + positionMapItem.setUseStatus(UseStatusEnum.PRE_OCCUPANCY.getType()); + robotMapItems.add(positionMapItem); + } + } + } + + if (ObjectUtil.isEmpty(robotMapItems)) { + log.info("车辆找不到合适的停车点,或者车辆都在停车点了,或者停车点不够用"); + return; + } + + Map sortMap = positionMapItems.stream().collect(Collectors.toMap(PositionMapItemDO::getId, PositionMapItemDO::getSortNum)); + + //机器人不能行走的区域 + List robotNoLimitationArea = getRobotNoLimitationArea(robots); + Map robotNoLimittationAreaDTOMap = + robotNoLimitationArea.stream().collect(Collectors.toMap(v -> v.getRobotNo(), Function.identity())); List pathPlanningList = new ArrayList<>(); - for (MoveToWaitDO wait : waits) { + List taskDetails = new ArrayList<>(); + List tasks = new ArrayList<>(); + for (PositionMapItemDO v : robotMapItems) { + + taskService.chargeDone(v.getRobotNo()); + + RobotTaskDO task = new RobotTaskDO(); + String incrementByKey = redisUtil.getIncrementByKey(RobotCacheLockEnum.MOVE_TASK_NO.getKey()); + task.setTaskNo(moveTaskNo + DateUtils.getYearMonthDay() + incrementByKey); + task.setId(IdUtil.getSnowflakeNextId()); + task.setCycleNumber(0L); + task.setRemainingCycleNumber(0L); + task.setStartTime(LocalDateTime.now()); + tasks.add(task); + + RobotTaskDetailAddVO detailAddVO = new RobotTaskDetailAddVO(); + detailAddVO.setId(IdUtil.getSnowflakeNextId()); + detailAddVO.setRobotTaskId(task.getId()); + detailAddVO.setTaskType(RobotTaskTypeEnum.MOVE_TO_POINT.getType()); + detailAddVO.setReleaseType(ReleaseTakeEnum.TO_LOCATION.getType()); + detailAddVO.setReleaseId(v.getId()); + detailAddVO.setToLocationNo(sortMap.get(v.getId()) + ""); + detailAddVO.setRobotNo(v.getRobotNo()); + taskDetails.add(detailAddVO); + TaskToPathPlanningDTO pathPlanning = TaskToPathPlanningDTO.builder() - .orderId(String.valueOf(wait.getId())) + .orderId(detailAddVO.getId() + "") .orderType(PathTaskTypeEnum.MOVE_TO_WAIT.getType()) .priority(1l) .createTime(LocalDateTime.now()) .taskType(PathTaskTypeToRobotEnum.MOVE.getType()) - .waitIds(waitIds) + .waitIds(Collections.singletonList(v.getId() + "")) .build(); + + TaskRobotNoLimittationAreaDTO taskRobotNoLimittationAreaDTO = robotNoLimittationAreaDTOMap.get(v.getRobotNo()); + List robotNoLimitions = Collections.singletonList(taskRobotNoLimittationAreaDTO); + pathPlanning.setRobotNoLimitationAreaDTOS(robotNoLimitions); + String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId(); redisUtil.set(key, JSON.toJSONString(pathPlanning), taskChcheTime); pathPlanningList.add(pathPlanning); } + robotTaskMapper.insertBatch(tasks); + + List bean = BeanUtils.toBean(taskDetails, RobotTaskDetailDO.class); + robotTaskDetailMapper.insertBatch(bean); + + positionMapItemMapper.updateById(robotMapItems); + log.info("派车去停车点--任务下发给PP :{}", JSON.toJSONString(pathPlanningList)); - pathPlanningApi.synchronousLineObject(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST); + commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST); + } + @Override public void sendChargeTaskToPP(List logs, List taskDetailDOS, List robots) { @@ -360,7 +369,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { pathPlanning.setReleaseGroupId("POINT_" + v.getPositionMapItemId()); pathPlanning.setReleaseLocationNumber(releaseLocationNumberConfig); - pathPlanning.setReleasePointId(v.getPositionMapItemId()); + pathPlanning.setWaitIds(Collections.singletonList(v.getPositionMapItemId() + "")); String key = PathPlanningChcheConstant.PATH_PLANNING_TASK + pathPlanning.getOrderId(); redisUtil.set(key, JSON.toJSONString(pathPlanning), taskChcheTime); @@ -369,7 +378,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { } log.info("充电任务下发给PP :{}", JSON.toJSONString(pathPlanningList)); - pathPlanningApi.synchronousLineObject(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST); + commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST); } @Transactional(rollbackFor = Exception.class) @@ -402,11 +411,15 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { List robotNoLimitationArea = pair.getLeft(); //前一个任务是仅取货 - List robotDoTake = getRobotDoTake(robots); +// List robotDoTake = getRobotDoTake(robots); + + for (RobotInformationDO robot : robots) { + taskService.chargeDone(robot.getRobotNo()); + } List positionMapItems = positionMapItemMapper.selectList(new LambdaQueryWrapperX() .eq(PositionMapItemDO::getType, PositionMapItemEnum.STOP.getType()) - .eq(PositionMapItemDO::getUseStatus, ZeroOneEnum.ZERO.getType())); + .eq(PositionMapItemDO::getUseStatus, UseStatusEnum.FREE.getType())); List waitIds = null; if (ObjectUtil.isNotEmpty(positionMapItems)) { waitIds = positionMapItems @@ -436,13 +449,20 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { pathPlanning.setWaitIds(waitIds); i++; } else if (RobotTaskTypeEnum.MOVE_TO_POINT.getType().equals(taskDetailDO.getTaskType())) { - moveToPoint(pathPlanning,taskDetailDO); + moveToPoint(pathPlanning, taskDetailDO); } - if (ObjectUtil.isNotEmpty(robotDoTake) && ObjectUtil.isNotEmpty(taskDetailDO.getRobotNo()) - && robotDoTake.contains(taskDetailDO.getRobotNo()) - && !RobotTaskTypeEnum.RELEASE.getType().equals(taskDetailDO.getTaskType())) { - log.info("机器人前一个任务是仅取货,当前任务非仅放货,所以当前任务不执行 :{}", taskDetailDO.getId()); + String mac = informationService.getMacByRobotNo(taskDetailDO.getRobotNo()); + String cargoDetectedKey = RobotTaskChcheConstant.ROBOT_CARGO_DETECTED + mac; + Object cargoDetected = redisUtil.get(cargoDetectedKey); + log.info("传感器是否按下 :{}", cargoDetected); + if (ObjectUtil.isEmpty(cargoDetected) || (RobotStatusCodeConstant.CARGO_DETECTED.equals(Boolean.parseBoolean(String.valueOf(cargoDetected))) + && !RobotTaskTypeEnum.RELEASE.getType().equals(taskDetailDO.getTaskType()))) { + log.info("车机上报传感器为空, 或者 被按下且任务非仅放货任务 :{} ,任务id :{}", taskDetailDO.getRobotNo(), taskDetailDO.getId()); + continue; + } else if (!RobotStatusCodeConstant.CARGO_DETECTED.equals(Boolean.parseBoolean(String.valueOf(cargoDetected))) + && RobotTaskTypeEnum.RELEASE.getType().equals(taskDetailDO.getTaskType())) { + log.info("仅放货任务,传感器未被按下,所以不执行任务 :{}, 任务id :{}", taskDetailDO.getRobotNo(), taskDetailDO.getId()); continue; } @@ -451,7 +471,11 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { robotNoLimitions = robotNoLimitationArea; } else { TaskRobotNoLimittationAreaDTO taskRobotNoLimittationAreaDTO = robotDoReleaseMap.get(taskDetailDO.getRobotNo()); - robotNoLimitions = Arrays.asList(taskRobotNoLimittationAreaDTO); + if (ObjectUtil.isEmpty(taskRobotNoLimittationAreaDTO)) { + log.info("车辆没有能行走的区域 :{}", taskDetailDO.getRobotNo()); + continue; + } + robotNoLimitions = Collections.singletonList(taskRobotNoLimittationAreaDTO); } if (ObjectUtil.isEmpty(robotNoLimitions)) { @@ -466,9 +490,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { if (ObjectUtil.isNotEmpty(taskDetailDO.getFromLocationId())) { pathPlanning.setTakeLocationNumber(Math.abs(locationNumberReduce - taskDetailDO.getFromLocationNumber())); pathPlanning.setTakePointId(fromLocation.getMapItemId()); - if (ObjectUtil.isNotEmpty(fromLocation.getLocationTotalHeight())) { - pathPlanning.setTakeHeight(Double.valueOf(fromLocation.getLocationTotalHeight() + "")); - } + + pathPlanningSetTakeHeight(pathPlanning, fromLocation); pathPlanning.setTakeLevel(fromLocation.getLocationStorey()); pathPlanning.setTakeOffsetHeight(offsetHeight); if (ObjectUtil.isNotEmpty(taskDetailDO.getFromLaneId())) { @@ -481,11 +504,8 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { if (ObjectUtil.isNotEmpty(taskDetailDO.getToLocationId())) { pathPlanning.setReleaseLocationNumber(taskDetailDO.getToLocationNumber()); pathPlanning.setReleasePointId(toLocation.getMapItemId()); - if (ObjectUtil.isNotEmpty(toLocation.getLocationStorey()) && ZeroOneEnum.ONE.getType().equals(toLocation.getLocationStorey())) { - pathPlanning.setReleaseHeight(0.0); - }else if (ObjectUtil.isNotEmpty(toLocation.getLocationTrayHeight())) { - pathPlanning.setReleaseHeight(Double.valueOf(toLocation.getLocationTrayHeight() + "")); - } + + pathPlanningSetReleaseHeight(pathPlanning, toLocation); pathPlanning.setReleaseLevel(toLocation.getLocationStorey()); pathPlanning.setReleaseOffsetHeight(offsetHeight); if (ObjectUtil.isNotEmpty(taskDetailDO.getToLaneId())) { @@ -503,12 +523,57 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { if (ObjectUtil.isNotEmpty(pathPlanningList)) { log.info("作业任务下发给PP :{}", JSON.toJSONString(pathPlanningList)); - pathPlanningApi.synchronousLineObject(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST); + commonApi.commonMethod(pathPlanningList, PathPlanningTopicConstant.TASK_ASSIGNMENT_REQUEST); } } + /** + * 设置放货高度 + * + * @param pathPlanning + * @param toLocation + */ + private void pathPlanningSetReleaseHeight(TaskToPathPlanningDTO pathPlanning, WareHouseLocationDO toLocation) { + if (ZeroOneEnum.ONE.getType().equals(toLocation.getLocationStorey())) { + pathPlanning.setReleaseHeight(0.0); + return; + } + + WareHouseLocationDO nextLocation = locationMapper.selectOne(new LambdaQueryWrapperX() + .eq(WareHouseLocationDO::getId, toLocation.getMapItemId()) + .eq(WareHouseLocationDO::getLocationStorey, toLocation.getLocationStorey() - 1) + .last("limit 1")); + if (ObjectUtil.isNotEmpty(nextLocation) && ObjectUtil.isNotEmpty(nextLocation.getLocationTotalHeight())) { + pathPlanning.setReleaseHeight(Double.valueOf(nextLocation.getLocationTotalHeight() + "")); + return; + } + + Integer locationStorey = toLocation.getLocationStorey() - 1; + double height = locationStorey * defaultTrayHeight; + log.info("放货设置默认高度 :{}", pathPlanning.getReleaseHeight()); + pathPlanning.setReleaseHeight(height); + } + + /** + * 设置取货高度 + * + * @param pathPlanning + * @param fromLocation + */ + private void pathPlanningSetTakeHeight(TaskToPathPlanningDTO pathPlanning, WareHouseLocationDO fromLocation) { + if (ObjectUtil.isNotEmpty(fromLocation.getLocationTotalHeight())) { + pathPlanning.setTakeHeight(Double.valueOf(fromLocation.getLocationTotalHeight() + "")); + return; + } + Integer locationStorey = fromLocation.getLocationStorey(); + double height = locationStorey * defaultTrayHeight; + log.info("取货设置默认取货高度 :{}", height); + pathPlanning.setTakeHeight(height); + } + /** * 移动到路径点 + * * @param pathPlanning * @param taskDetailDO */ @@ -540,14 +605,14 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { } } + if (positionMapDOS.size() == limitationAreaList.size()) { + log.info("车辆不能行走所有的区域所以不下发任务 :{}", robot.getRobotNo()); + continue; + } robotNoLimitationAreaDTO.setLimitationAreaList(limitationAreaList); - if (RobotStatusEnum.LAST_TASK_IS_TAKE.getType().equals(robot.getRobotStatus())) { - map.put(robot.getRobotNo(), robotNoLimitationAreaDTO); - } else { - robotNoLimitationAreaDTOS.add(robotNoLimitationAreaDTO); - map.put(robot.getRobotNo(), robotNoLimitationAreaDTO); - } + robotNoLimitationAreaDTOS.add(robotNoLimitationAreaDTO); + map.put(robot.getRobotNo(), robotNoLimitationAreaDTO); } return ImmutablePair.of(robotNoLimitationAreaDTOS, map); @@ -704,7 +769,7 @@ public class RobotPathPlanningServiceImpl implements RobotPathPlanningService { //仅取货 takeSetTask(list, v, fromLane, toLane, fromLocation, toLocation, toHaveFrom, fromHaveTo); } else if (RobotTaskTypeEnum.PARK.getType().equals(v.getTaskType()) - || RobotTaskTypeEnum.MOVE_TO_POINT.getType().equals(v.getTaskType())) { + || RobotTaskTypeEnum.MOVE_TO_POINT.getType().equals(v.getTaskType())) { list.add(v); } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/statistics/RobotWorkingHoursStatisticsService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/statistics/RobotWorkingHoursStatisticsService.java new file mode 100644 index 000000000..accbbd33c --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/statistics/RobotWorkingHoursStatisticsService.java @@ -0,0 +1,72 @@ +package cn.iocoder.yudao.module.system.service.statistics; + +import java.util.*; +import javax.validation.*; + +import cn.iocoder.yudao.module.system.controller.admin.statistics.dto.RobotWorkHourStatisticsDTO; +import cn.iocoder.yudao.module.system.controller.admin.statistics.vo.RobotWorkingHoursStatisticsPageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.statistics.vo.RobotWorkingHoursStatisticsSaveReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.statistics.RobotWorkingHoursStatisticsDO; +import com.baomidou.mybatisplus.extension.service.IService; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; + +/** + * 车辆工作时长统计 Service 接口 + * + * @author 陈宾顺 + */ +public interface RobotWorkingHoursStatisticsService extends IService { + + /** + * 创建车辆工作时长统计 + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createRobotWorkingHoursStatistics(@Valid RobotWorkingHoursStatisticsSaveReqVO createReqVO); + + /** + * 更新车辆工作时长统计 + * + * @param updateReqVO 更新信息 + */ + void updateRobotWorkingHoursStatistics(@Valid RobotWorkingHoursStatisticsSaveReqVO updateReqVO); + + /** + * 删除车辆工作时长统计 + * + * @param id 编号 + */ + void deleteRobotWorkingHoursStatistics(Long id); + + /** + * 获得车辆工作时长统计 + * + * @param id 编号 + * @return 车辆工作时长统计 + */ + RobotWorkingHoursStatisticsDO getRobotWorkingHoursStatistics(Long id); + + /** + * 获得车辆工作时长统计分页 + * + * @param pageReqVO 分页查询 + * @return 车辆工作时长统计分页 + */ + PageResult getRobotWorkingHoursStatisticsPage(RobotWorkingHoursStatisticsPageReqVO pageReqVO); + + //统计车辆工作时长 + void statisticsRobotDuration(); + + //创建空闲时间 + void createFreeTime(String robotNo); + + /** + * 统计车辆时长 + * @param type + * @param positionMapId + * @return + */ + List robotWorkHourStatistics(String type, String positionMapId); +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/statistics/RobotWorkingHoursStatisticsServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/statistics/RobotWorkingHoursStatisticsServiceImpl.java new file mode 100644 index 000000000..f84ce4326 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/statistics/RobotWorkingHoursStatisticsServiceImpl.java @@ -0,0 +1,266 @@ +package cn.iocoder.yudao.module.system.service.statistics; + +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.util.date.DateUtils; +import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; +import cn.iocoder.yudao.module.system.controller.admin.statistics.dto.RobotWorkHourStatisticsDTO; +import cn.iocoder.yudao.module.system.controller.admin.statistics.vo.RobotWorkingHoursStatisticsPageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.statistics.vo.RobotWorkingHoursStatisticsSaveReqVO; +import cn.iocoder.yudao.module.system.dal.dataobject.log.RobotTaskDetailActionLogDO; +import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO; +import cn.iocoder.yudao.module.system.dal.dataobject.statistics.RobotWorkingHoursStatisticsDO; +import cn.iocoder.yudao.module.system.dal.mysql.statistics.RobotWorkingHoursStatisticsMapper; +import cn.iocoder.yudao.module.system.enums.robot.RobotStatusEnum; +import cn.iocoder.yudao.module.system.enums.robot.statistics.DurationTypeEnum; +import cn.iocoder.yudao.module.system.service.log.RobotTaskDetailActionLogService; +import cn.iocoder.yudao.module.system.service.robot.RobotInformationService; +import cn.iocoder.yudao.module.system.util.redis.RedisUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +import org.springframework.transaction.annotation.Propagation; +import org.springframework.validation.annotation.Validated; +import org.springframework.transaction.annotation.Transactional; + +import java.text.SimpleDateFormat; +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.stream.Collectors; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.ROBOT_WORKING_HOURS_STATISTICS_NOT_EXISTS; + +/** + * 车辆工作时长统计 Service 实现类 + * + * @author 陈宾顺 + */ +@Service +@Validated +@Slf4j +public class RobotWorkingHoursStatisticsServiceImpl extends ServiceImpl implements RobotWorkingHoursStatisticsService { + + @Resource + private RobotWorkingHoursStatisticsMapper robotWorkingHoursStatisticsMapper; + + @Resource + private RobotTaskDetailActionLogService taskDetailActionLogService; + + @Resource + private RobotInformationService informationService; + + @Resource + private RedisUtil redisUtil; + + /** + * 统计工作时长 + */ + @Override + public void statisticsRobotDuration() { + List robots = informationService.getAllRobot(); + if (ObjectUtil.isEmpty(robots)) { + log.info("统计工作时长--暂无车辆"); + return; + } + + List statisticss = new ArrayList<>(); + for (RobotInformationDO robot : robots) { + String freeTimeKey = RobotTaskChcheConstant.ROBOT_LAST_FREE_TIME + robot.getRobotNo(); + Object freeTimeObject = redisUtil.get(freeTimeKey); + + if (ObjectUtil.isNotEmpty(freeTimeObject) + && RobotStatusEnum.STAND_BY.getType().equals(robot.getRobotStatus())) { + RobotWorkingHoursStatisticsDO statisticsDO = new RobotWorkingHoursStatisticsDO(); + statisticsDO.setDuration(getMinutes(freeTimeObject)); + statisticsDO.setRobotNo(robot.getRobotNo()); + Long mapId = informationService.getRobotMapIdByRobotNo(robot.getRobotNo()); + if (ObjectUtil.isNotEmpty(mapId)) { + statisticsDO.setPositionMapId(mapId); + } + statisticsDO.setDurationType(DurationTypeEnum.FREE_TIME.getType()); + statisticss.add(statisticsDO); + } + + if (RobotStatusEnum.STAND_BY.getType().equals(robot.getRobotStatus())) { + String timeStr = DateUtils.getYearMonthDayHourMinuteSecon(); + redisUtil.set(freeTimeKey, timeStr); + } + } + + if (ObjectUtil.isNotEmpty(statisticss)) { + robotWorkingHoursStatisticsMapper.insertBatch(statisticss); + } + + List actionLogList = taskDetailActionLogService.getUnStatisticsDurationLog(); + if (ObjectUtil.isEmpty(actionLogList)) { + log.info("统计工作时长--没有需要统计的任务信息"); + return; + } + + List statisticsDOS = getWorkingHoursStatisticsByActionLog(actionLogList); + if (ObjectUtil.isNotEmpty(statisticsDOS)) { + robotWorkingHoursStatisticsMapper.insertBatch(statisticsDOS); + } + } + + /** + * 创建这台车的空闲时间 + * 别改事务传播 + * @param robotNo + */ + @Override + @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) + public void createFreeTime(String robotNo) { + String freeTimeKey = RobotTaskChcheConstant.ROBOT_LAST_FREE_TIME + robotNo; + Object freeTimeObject = redisUtil.get(freeTimeKey); + if (ObjectUtil.isEmpty(freeTimeObject)) { + log.info("统计车辆空闲时间,没有车辆的初始空闲时间"); + return; + } + RobotWorkingHoursStatisticsDO statisticsDO = new RobotWorkingHoursStatisticsDO(); + statisticsDO.setDuration(getMinutes(freeTimeObject)); + statisticsDO.setRobotNo(robotNo); + Long mapId = informationService.getRobotMapIdByRobotNo(robotNo); + if (ObjectUtil.isNotEmpty(mapId)) { + statisticsDO.setPositionMapId(mapId); + } + statisticsDO.setDurationType(DurationTypeEnum.FREE_TIME.getType()); + robotWorkingHoursStatisticsMapper.insert(statisticsDO); + redisUtil.del(freeTimeKey); + } + + /** + * 统计时长 + * + * @param type + * @param positionMapId + * @return + */ + @Override + public List robotWorkHourStatistics(String type, String positionMapId) { + List data = robotWorkingHoursStatisticsMapper.getRobotWorkHourStatistics(type, positionMapId); + if (ObjectUtil.isEmpty(data)) { + return null; + } + + Map> robotMap = data.stream() + .collect(Collectors.groupingBy( + RobotWorkingHoursStatisticsDO::getRobotNo, + Collectors.groupingBy( + RobotWorkingHoursStatisticsDO::getDurationType, Collectors.summingLong(RobotWorkingHoursStatisticsDO::getDuration) + ) + )); + + List list = new ArrayList<>(); + + robotMap.forEach((k,v) ->{ + RobotWorkHourStatisticsDTO statisticsDTO = new RobotWorkHourStatisticsDTO(); + statisticsDTO.setRobotNo(k); + Long freeTime = v.get(DurationTypeEnum.FREE_TIME.getType()); + String freeTimeStr = ObjectUtil.isNotEmpty(freeTime) ? String.format("%.1f",(freeTime.doubleValue() / 60)) : "0"; + Long taskTime = v.get(DurationTypeEnum.TASK_TIME.getType()); + String taskTimeStr = ObjectUtil.isNotEmpty(taskTime) ? String.format("%.1f",(taskTime.doubleValue() / 60)) : "0"; + Long chargeTime = v.get(DurationTypeEnum.CHARGE_TIME.getType()); + String chargeTimeStr = ObjectUtil.isNotEmpty(chargeTime) ? String.format("%.1f",(chargeTime.doubleValue() / 60)) : "0"; + + statisticsDTO.setFreeTimeNum(freeTimeStr); + statisticsDTO.setTaskTimeNum(taskTimeStr); + statisticsDTO.setChargeTimeNum(chargeTimeStr); + + list.add(statisticsDTO); + }); + + return list; + } + + /** + * 获取这个时间距离当前时间的分钟 + * + * @param freeTimeObject + * @return + */ + public Long getMinutes(Object freeTimeObject) { + String freeTimeStr = freeTimeObject.toString(); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern(FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND); + LocalDateTime formattedDateTime = LocalDateTime.parse(freeTimeStr, formatter); + Duration duration = Duration.between(formattedDateTime, LocalDateTime.now()); + return duration.toMinutes(); + } + + private List getWorkingHoursStatisticsByActionLog(List actionLogList) { + List statisticsDOList = new ArrayList<>(); + + for (RobotTaskDetailActionLogDO v : actionLogList) { + RobotWorkingHoursStatisticsDO statisticsDO = new RobotWorkingHoursStatisticsDO(); + if (ObjectUtil.isNotEmpty(v.getDuration())) { + statisticsDO.setDuration(v.getDuration()); + } else if (ObjectUtil.isNotEmpty(v.getStartTime()) && ObjectUtil.isNotEmpty(v.getEndTime())) { + Duration duration = Duration.between(v.getStartTime(), v.getEndTime()); + statisticsDO.setDuration(duration.toMinutes()); + } else if (ObjectUtil.isEmpty(v.getStartTime()) || ObjectUtil.isEmpty(v.getEndTime())) { + continue; + } + statisticsDO.setRobotNo(v.getRobotNo()); + statisticsDO.setPositionMapId(v.getPositionMapId()); + Integer durationTypeByTaskType = DurationTypeEnum.getDurationTypeByTaskType(v.getCommandType()); + statisticsDO.setDurationType(durationTypeByTaskType); + statisticsDOList.add(statisticsDO); + } + + return statisticsDOList; + } + + @Override + public Long createRobotWorkingHoursStatistics(RobotWorkingHoursStatisticsSaveReqVO createReqVO) { + // 插入 + RobotWorkingHoursStatisticsDO robotWorkingHoursStatistics = BeanUtils.toBean(createReqVO, RobotWorkingHoursStatisticsDO.class); + robotWorkingHoursStatisticsMapper.insert(robotWorkingHoursStatistics); + // 返回 + return robotWorkingHoursStatistics.getId(); + } + + @Override + public void updateRobotWorkingHoursStatistics(RobotWorkingHoursStatisticsSaveReqVO updateReqVO) { + // 校验存在 + validateRobotWorkingHoursStatisticsExists(updateReqVO.getId()); + // 更新 + RobotWorkingHoursStatisticsDO updateObj = BeanUtils.toBean(updateReqVO, RobotWorkingHoursStatisticsDO.class); + robotWorkingHoursStatisticsMapper.updateById(updateObj); + } + + @Override + public void deleteRobotWorkingHoursStatistics(Long id) { + // 校验存在 + validateRobotWorkingHoursStatisticsExists(id); + // 删除 + robotWorkingHoursStatisticsMapper.deleteById(id); + } + + private void validateRobotWorkingHoursStatisticsExists(Long id) { + if (robotWorkingHoursStatisticsMapper.selectById(id) == null) { + throw exception(ROBOT_WORKING_HOURS_STATISTICS_NOT_EXISTS); + } + } + + @Override + public RobotWorkingHoursStatisticsDO getRobotWorkingHoursStatistics(Long id) { + return robotWorkingHoursStatisticsMapper.selectById(id); + } + + @Override + public PageResult getRobotWorkingHoursStatisticsPage(RobotWorkingHoursStatisticsPageReqVO pageReqVO) { + return robotWorkingHoursStatisticsMapper.selectPage(pageReqVO); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tool/ToolsService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tool/ToolsService.java index 90ca55065..dce8c1816 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tool/ToolsService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tool/ToolsService.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.system.service.tool; +import cn.iocoder.yudao.module.system.controller.admin.tool.dto.SendMsgToMqttDTO; + import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import javax.validation.constraints.NotBlank; @@ -14,4 +16,10 @@ public interface ToolsService { String updateWarnCode(); void simulationPose(); + + /** + * 发送消息给MQTT + * @param dto + */ + void sendMsgToMQTT(SendMsgToMqttDTO dto); } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tool/ToolsServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tool/ToolsServiceImpl.java index 7fcfa8979..e640be08c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tool/ToolsServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/tool/ToolsServiceImpl.java @@ -14,6 +14,7 @@ import cn.iocoder.yudao.module.system.constant.robot.RobotTopicConstant; import cn.iocoder.yudao.module.system.controller.admin.config.dto.TaskOrderConfigDTO; import cn.iocoder.yudao.module.system.controller.admin.config.vo.CommonConfigVO; import cn.iocoder.yudao.module.system.controller.admin.tool.dto.CleanAgvDTO; +import cn.iocoder.yudao.module.system.controller.admin.tool.dto.SendMsgToMqttDTO; import cn.iocoder.yudao.module.system.dal.dataobject.config.CommonConfigDO; import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO; import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO; @@ -244,6 +245,11 @@ public class ToolsServiceImpl implements ToolsService { } } + @Override + public void sendMsgToMQTT(SendMsgToMqttDTO dto) { + commonApi.commonMethodStr(dto.getMsg(),dto.getTopic()); + } + public void addWarnMsg() { RobotWarnMsgDO warnMsg = RobotWarnMsgDO.builder().warnLevel(4) diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/wait/MoveToWaitService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/wait/MoveToWaitService.java index caa451047..627af4aa8 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/wait/MoveToWaitService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/wait/MoveToWaitService.java @@ -50,7 +50,6 @@ public interface MoveToWaitService { */ PageResult getMoveToWaitPage(MoveToWaitPageReqVO pageReqVO); - void updateWaitStatus(Long orderId, Integer status); - void updateWaitStatusAndItrmId(Long orderId, Integer type, String waitId); + } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/wait/MoveToWaitServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/wait/MoveToWaitServiceImpl.java index d872863dd..b5e8c6f52 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/wait/MoveToWaitServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/wait/MoveToWaitServiceImpl.java @@ -71,21 +71,6 @@ public class MoveToWaitServiceImpl implements MoveToWaitService { return moveToWaitMapper.selectPage(pageReqVO); } - @Override - public void updateWaitStatus(Long orderId, Integer status) { - MoveToWaitDO updateObj = new MoveToWaitDO(); - updateObj.setId(orderId); - updateObj.setWaitStatus(status); - 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); - } } \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/aes/AESEncryptionUtil.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/aes/AESEncryptionUtil.java index acd4c0485..9730e6065 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/aes/AESEncryptionUtil.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/util/aes/AESEncryptionUtil.java @@ -8,6 +8,13 @@ import java.util.Base64; public class AESEncryptionUtil { private static final String AES_ALGORITHM = "AES"; + /** + * 加密 + * @param plaintext + * @param key + * @return + * @throws Exception + */ public static String encrypt(String plaintext, String key) throws Exception { SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES_ALGORITHM); Cipher cipher = Cipher.getInstance(AES_ALGORITHM); @@ -16,6 +23,13 @@ public class AESEncryptionUtil { return Base64.getEncoder().encodeToString(encryptedBytes); } + /** + * 解密 + * @param ciphertext + * @param key + * @return + * @throws Exception + */ public static String decrypt(String ciphertext, String key) throws Exception { SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES_ALGORITHM); Cipher cipher = Cipher.getInstance(AES_ALGORITHM); @@ -34,4 +48,25 @@ public class AESEncryptionUtil { String decryptedText = decrypt(encryptedText, key); System.out.println("Decrypted Text: " + decryptedText); } + + /** + * 获取解密后数据 + * @param str + * @param cameraSecretKey + * @return + */ + public static String getEncrypt(String str, String cameraSecretKey){ + try { + AESEncryptionUtil.decrypt(str, cameraSecretKey); + return str; + } catch (Exception ignored) { + + } + + try { + return AESEncryptionUtil.encrypt(str, cameraSecretKey); + } catch (Exception e) { + throw new RuntimeException(e); + } + } } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-dev.yaml b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-dev.yaml index 0cf18163a..05a901949 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-dev.yaml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-dev.yaml @@ -185,7 +185,9 @@ justauth: timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟 zn: - task-no: ZN #任务号开头 + task-no: TASK #任务号开头 + move-no: MOVE #自动移动任务号开头 + charge-no: CHARGE #自动充电任务号开头 camera_secret_key: A2C4rv7DY012c9ef #摄像头秘钥 do_cycle: true #是否开启循环 lane_auto_move: true #线库是否自动移库 true:线库执行自动移库 、false:线库关闭执行自动移库 @@ -195,7 +197,6 @@ zn: task_need_single: true #机器人对同一线库/点位是不是只能有一台机器人做任务 (true:一个点位/线库,只有一台机器人) location_number_reduce: 100000000 #库位排序的差值(下发取货任务,将库位排序减去此值,然后取绝对值) robot_doing_action: # 机器人正在做的动作 - action_entity_cache_time: 172800 #机器人所有动作缓存时间 8小时 doing_action_cache_time: 172800 #单个动作缓存时间 8小时 robot_chearg: #机器人充电的配置 release_location_number_config: 50 #同一组序号,越大越先执行 @@ -203,10 +204,11 @@ zn: task: #任务相关的配置 check_sku_info: true #校验物料信息 robot_config: #机器人取放货默认配置 - offset_height: 0.2 #叉起货需要在原来高度基础上偏移的高度 + offset_height: 0.1 #叉起货需要在原来高度基础上偏移的高度 default_tray_height: 1.1 #默认每层高度 open_rate_limiter: true #是否开启限流 path_planning: task_chche_time: 1209600 #任务缓存的时间, 默认一星期 is_simulation: false # 是否为仿真环境 + send_robot_init_pose: true # 是否为发送默认的车辆所在地图和点位 restore_task_restart: false # 恢复任务是否全部重新执行 true:全部重新开始 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml index ae92c18de..9c8ca5b2e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-local.yaml @@ -81,7 +81,7 @@ spring: host: 127.0.0.1 # 地址 port: 6379 # 端口 database: 0 # 数据库索引 -# password: 123456 # 密码,建议生产环境开启 + password: yhtkj@2024! # 密码,建议生产环境开启 --- #################### MQ 消息队列相关配置 #################### @@ -216,21 +216,22 @@ justauth: timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟 map: file: - upload-path: /Users/aikai/Documents/map/ # 地图文件上传路径 - warn-path: /Users/aikai/Documents/json/ # 告警码值上传路径 + upload-path: C:\system\config\map\map\map\2 # 地图文件上传路径 + warn-path: C:\system\config\map\map\map\2 # 告警码值上传路径 zn: - task-no: ZN #任务号开头 + task-no: TASK #任务号开头 + move-no: MOVE #自动移动任务号开头 + charge-no: CHARGE #自动充电任务号开头 camera_secret_key: A2C4rv7DY012c9ef #摄像头秘钥 do_cycle: true #是否开启循环 lane_auto_move: true #线库是否自动移库 true:线库执行自动移库 、false:线库关闭执行自动移库 - robot_position_cache_time: 10 #机器人上报点位存储时间(秒) + robot_position_cache_time: 10000000 #机器人上报点位存储时间(秒) cycle_do_auto_move: true #存在循环的任务,是否开启自动移库. true:存在循环任务,开启自动移库; false:有循环任务不自动移库 full_electricity: 100 #机器人充满电的电量 task_need_single: true #机器人对同一线库/点位是不是只能有一台机器人做任务 (true:一个点位/线库,只有一台机器人) location_number_reduce: 100000000 #库位排序的差值(下发取货任务,将库位排序减去此值,然后取绝对值) robot_doing_action: # 机器人正在做的动作 - action_entity_cache_time: 172800 #机器人所有动作缓存时间 8小时 doing_action_cache_time: 172800 #单个动作缓存时间 8小时 robot_chearg: #机器人充电的配置 release_location_number_config: 50 #同一组序号,越大越先执行 @@ -238,14 +239,15 @@ zn: task: #任务相关的配置 check_sku_info: true #校验物料信息 robot_config: #机器人取放货默认配置 - offset_height: 0.2 #叉起货需要在原来高度基础上偏移的高度 - default_tray_height: 1.1 #默认每层高度 + offset_height: 0.1 #叉起货需要在原来高度基础上偏移的高度 + default_tray_height: 0.82 #默认每层高度 open_rate_limiter: true #是否开启限流 path_planning: task_chche_time: 1209600 #任务缓存的时间, 默认一星期 is_simulation: true # 是否为仿真环境 + send_robot_init_pose: true # 是否为发送默认的车辆所在地图和点位 restore_task_restart: true # 恢复任务是否全部重新执行 true:全部重新开始 logging: file: - name: D:/project/rcs/logs/${spring.application.name}.log \ No newline at end of file + name: C:\system\install\log/${spring.application.name}.log \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-test.yaml b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-test.yaml index 7b91cd701..91a5abe2d 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/application-test.yaml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/application-test.yaml @@ -213,7 +213,10 @@ map: warn-path: D:\project\rcs\json\ # 告警码值上传路径 zn: - task-no: ZN #任务号开头 + task-no: TASK #任务号开头 + move-no: MOVE #自动移动任务号开头 + charge-no: CHARGE #自动充电任务号开头 + camera_secret_key: A2C4rv7DY012c9ef #摄像头秘钥 do_cycle: true #是否开启循环 lane_auto_move: true #线库是否自动移库 true:线库执行自动移库 、false:线库关闭执行自动移库 robot_position_cache_time: 10 #机器人上报点位存储时间(秒) @@ -222,7 +225,6 @@ zn: task_need_single: true #机器人对同一线库/点位是不是只能有一台机器人做任务 (true:一个点位/线库,只有一台机器人) location_number_reduce: 100000000 #库位排序的差值(下发取货任务,将库位排序减去此值,然后取绝对值) robot_doing_action: # 机器人正在做的动作 - action_entity_cache_time: 172800 #机器人所有动作缓存时间 8小时 doing_action_cache_time: 172800 #单个动作缓存时间 8小时 robot_chearg: #机器人充电的配置 release_location_number_config: 50 #同一组序号,越大越先执行 @@ -230,10 +232,12 @@ zn: task: #任务相关的配置 check_sku_info: true #校验物料信息 robot_config: #机器人取放货默认配置 - offset_height: 0.2 #叉起货需要在原来高度基础上偏移的高度 + offset_height: 0.1 #叉起货需要在原来高度基础上偏移的高度 default_tray_height: 1.1 #默认每层高度 open_rate_limiter: true #是否开启限流 path_planning: task_chche_time: 1209600 #任务缓存的时间, 默认一星期 - is_simulation: true # 是否为仿真环境 + is_simulation: false # 是否为仿真环境 + send_robot_init_pose: true # 是否为发送默认的车辆所在地图和点位 + restore_task_restart: false # 恢复任务是否全部重新执行 true:全部重新开始 diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/housearea/HouseAreaMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/housearea/HouseAreaMapper.xml index bcdc2bfb3..e4bebaeb0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/housearea/HouseAreaMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/housearea/HouseAreaMapper.xml @@ -9,4 +9,9 @@ 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ --> + + update ware_house_area + set deleted = 1 + where position_map_id = #{mapId} + \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/houselane/WareHouseLaneMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/houselane/WareHouseLaneMapper.xml index 88b5ca8ff..591bbe13e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/houselane/WareHouseLaneMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/houselane/WareHouseLaneMapper.xml @@ -9,4 +9,9 @@ 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ --> + + update ware_house_lane + set deleted = 1 + where position_map_id = #{mapId} + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/houselocation/WareHouseLocationMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/houselocation/WareHouseLocationMapper.xml index 5867a4eb2..f41b00a35 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/houselocation/WareHouseLocationMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/houselocation/WareHouseLocationMapper.xml @@ -77,6 +77,14 @@ update_time, deleted + + update + ware_house_location + set + deleted = 1 + where + map_id = #{mapId} + + + + diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/information/DeviceInformationMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/information/DeviceInformationMapper.xml index e29083cf7..ddcbc80bc 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/information/DeviceInformationMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/information/DeviceInformationMapper.xml @@ -28,4 +28,34 @@ where last_user = #{lastUser} + + update + device_information + set + deleted = 1 + where + position_map_id = #{mapId} + + + + update + device_information + set + last_user = #{newRobotNo} + where + last_user = #{oldRobotNo} + and deleted = '0' + and device_type = '1' + + + update + device_information + set + last_user = '', + device_use_status = '0' + where + last_user = #{robotNo} + and deleted = '0' + and device_type = '1' + \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/parkingspot/ParkingSpotMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/parkingspot/ParkingSpotMapper.xml index 01e8db785..0790321ac 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/parkingspot/ParkingSpotMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/parkingspot/ParkingSpotMapper.xml @@ -9,4 +9,9 @@ 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ --> + + update ware_parking_spot + set deleted = 1 + where position_map_id = #{mapId} + \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/positionmap/PositionChangePointBindingMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/positionmap/PositionChangePointBindingMapper.xml index 2081c5288..9584bc91a 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/positionmap/PositionChangePointBindingMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/positionmap/PositionChangePointBindingMapper.xml @@ -2,6 +2,13 @@ + + + update ware_position_change_point_binding + set deleted = 1 + where position_map_id = #{mapId} + + SELECT - t1.* + t1.* FROM - robot_warn_msg t1 + robot_warn_msg t1 WHERE - ( robot_no, create_time ) IN ( SELECT robot_no, MAX( create_time ) - FROM - robot_warn_msg - where - deleted = '0' - and warn_level = '4' - and task_detail_id - in - - #{taskDetailId} - - GROUP BY robot_no ) + ( robot_no, create_time ) IN ( SELECT robot_no, MAX( create_time ) + FROM + robot_warn_msg + where + deleted = '0' + and warn_level = '4' + and task_detail_id + in + + #{taskDetailId} + + GROUP BY robot_no ) + + + + \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/statistics/RobotWorkingHoursStatisticsMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/statistics/RobotWorkingHoursStatisticsMapper.xml new file mode 100644 index 000000000..fdde61fc3 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/statistics/RobotWorkingHoursStatisticsMapper.xml @@ -0,0 +1,36 @@ + + + + + + + + \ No newline at end of file diff --git a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/wait/MoveToWaitMapper.xml b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/wait/MoveToWaitMapper.xml index c2d16c898..8feec6e35 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/wait/MoveToWaitMapper.xml +++ b/yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/wait/MoveToWaitMapper.xml @@ -9,4 +9,13 @@ 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/ --> + + update + robot_move_to_wait + set + robot_no = #{newRobotNo} + where + robot_no = #{oldRobotNo} + and deleted = '0' + \ No newline at end of file