Compare commits

..

No commits in common. "22f58ed6b0393eda1dc8e08eed78f1d0fb801d54" and "a9bc6fdbba35d382301e25c96cade8f247ff46b0" have entirely different histories.

362 changed files with 1563 additions and 14799 deletions

View File

@ -16,7 +16,6 @@
<module>yudao-module-infra</module>
<module>yudao-module-grpc</module>
<module>yudao-module-mqtt</module>
<module>yudao-module-remote</module>
<!-- <module>yudao-module-member</module>-->
<!-- <module>yudao-module-bpm</module>-->
<!-- <module>yudao-module-pay</module>-->

View File

@ -1,9 +1,7 @@
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;
@ -35,21 +33,6 @@ 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
*

View File

@ -14,7 +14,6 @@ import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -34,8 +33,6 @@ public class ApiAccessLogInterceptor implements HandlerInterceptor {
private static final String ATTRIBUTE_STOP_WATCH = "ApiAccessLogInterceptor.StopWatch";
private static final List<String> ignoreInterfaceUrls = Arrays.asList("/rpc-api/system/task/robotStatusUpdate","/rpc-api/system/task/updateRobotCommonStatus");
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 记录 HandlerMethod提供给 ApiAccessLogFilter 使用
@ -48,9 +45,9 @@ public class ApiAccessLogInterceptor implements HandlerInterceptor {
if (!SpringUtils.isProd()) {
Map<String, String> queryString = ServletUtils.getParamMap(request);
String requestBody = ServletUtils.isJsonRequest(request) ? ServletUtils.getBody(request) : null;
if (CollUtil.isEmpty(queryString) && StrUtil.isEmpty(requestBody) && !ignoreInterfaceUrls.contains(request.getRequestURI())) {
if (CollUtil.isEmpty(queryString) && StrUtil.isEmpty(requestBody)) {
log.info("[preHandle][开始请求 URL({}) 无参数]", request.getRequestURI());
} else if( !ignoreInterfaceUrls.contains(request.getRequestURI())) {
} else {
log.info("[preHandle][开始请求 URL({}) 参数({})]", request.getRequestURI(),
StrUtil.blankToDefault(requestBody, queryString.toString()));
}
@ -70,10 +67,8 @@ public class ApiAccessLogInterceptor implements HandlerInterceptor {
if (!SpringUtils.isProd()) {
StopWatch stopWatch = (StopWatch) request.getAttribute(ATTRIBUTE_STOP_WATCH);
stopWatch.stop();
if( !ignoreInterfaceUrls.contains(request.getRequestURI())) {
log.info("[afterCompletion][完成请求 URL({}) 耗时({} ms)]",
request.getRequestURI(), stopWatch.getTotalTimeMillis());
}
log.info("[afterCompletion][完成请求 URL({}) 耗时({} ms)]",
request.getRequestURI(), stopWatch.getTotalTimeMillis());
}
}
@ -99,7 +94,7 @@ public class ApiAccessLogInterceptor implements HandlerInterceptor {
return;
}
// 打印结果
// System.out.printf("\tController 方法路径:%s(%s.java:%d)\n", clazz.getName(), clazz.getSimpleName(), lineNumber.get());
System.out.printf("\tController 方法路径:%s(%s.java:%d)\n", clazz.getName(), clazz.getSimpleName(), lineNumber.get());
} catch (Exception ignore) {
// 忽略异常原因仅仅打印非重要逻辑
}

View File

@ -251,7 +251,6 @@ 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;
}
}

View File

@ -31,19 +31,6 @@ spring:
- Path=/app-api/system/**
filters:
- RewritePath=/app-api/system/v3/api-docs, /v3/api-docs
## remote-server 服务
- id: remote-admin-api # 路由的编号
uri: grayLb://remote-server
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
- Path=/admin-api/remote/**
filters:
- RewritePath=/admin-api/remote/v3/api-docs, /v3/api-docs # 配置,保证转发到 /v3/api-docs
- id: remote-app-api # 路由的编号
uri: grayLb://remote-server
predicates: # 断言,作为路由的匹配条件,对应 RouteDefinition 数组
- Path=/app-api/remote/**
filters:
- RewritePath=/app-api/remote/v3/api-docs, /v3/api-docs
## infra-server 服务
- id: infra-admin-api # 路由的编号
uri: grayLb://infra-server
@ -201,9 +188,6 @@ knife4j:
- name: system-server
service-name: system-server
url: /admin-api/system/v3/api-docs
- name: remote-server
service-name: remote-server
url: /admin-api/remote/v3/api-docs
- name: infra-server
service-name: infra-server
url: /admin-api/infra/v3/api-docs

View File

@ -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);
}

View File

@ -15,7 +15,5 @@ public class PathPosedsDTO {
private String orderId;
private String orderType;
private String robotNo;
private String commandType;
private List<PathPosedsDataDTO> data;
private PathSwitchMapDTO arg;
}

View File

@ -1,9 +0,0 @@
package cn.iocoder.yudao.module.mqtt.api.path.dto;
import lombok.Data;
@Data
public class PathSwitchMapDTO {
private String floor;
private String areaId;
}

View File

@ -1,13 +0,0 @@
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;
}

View File

@ -1,12 +0,0 @@
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;
}

View File

@ -1,25 +0,0 @@
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;
}

View File

@ -1,15 +0,0 @@
package cn.iocoder.yudao.module.mqtt.api.path.dto;
import lombok.Data;
@Data
public class PositionAllChangePointBindingDTO {
/**
* 点位1的id
*/
private Long startingPointId;
/**
* 点位2的id
*/
private Long endPointId;
}

View File

@ -15,7 +15,7 @@ import java.util.List;
public class PositionMapItemSynDTO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "31007")
private String id;
private Long id;
@Schema(description = "坐标x轴")
private Double x;

View File

@ -28,7 +28,4 @@ public class RobotDimensionsDTO {
@Schema(description = "mac地址")
private String macAddress;
@Schema(description = "转弯半径(单位米)")
private Double robotTurningRadius;
}

View File

@ -1,14 +0,0 @@
package cn.iocoder.yudao.module.mqtt.api.path.dto.remote;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class RemotePathPlanningDTO {
@Schema(description = "车辆编号")
private String robotNo;
@Schema(description = "AUTO自动、 MAN手动")
private String operationMode;
}

View File

@ -1,16 +0,0 @@
package cn.iocoder.yudao.module.mqtt.api.path.dto.remote;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.bouncycastle.cms.PasswordRecipientId;
@Data
public class RobotModeDTO {
private String commandType;
@Schema(description = "AUTO自动、 MAN手动")
private String operationMode;
private Double maxSpeed;
}

View File

@ -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<RobotAcceptTaskDTO> robotTaskDOS );*/
void sendTaskToRobot(@Valid @RequestBody List<RobotAcceptTaskDTO> robotTaskDOS );
}

View File

@ -32,12 +32,6 @@
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-remote-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-mqtt-api</artifactId>

View File

@ -1,7 +1,6 @@
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;

View File

@ -26,21 +26,21 @@ 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));
log.info("同步给路径规划完成 :{}, topic:{}", JSON.toJSONString(relatedPathNode), topic);
log.info("同步给路径规划完成 :{}", JSON.toJSONString(relatedPathNode));
} catch (MqttException e) {
log.info("同步点位信息给路径规划异常 :{}",e);
}
}
*//**
/**
* 同步ware_position_map_item的点位信息
* @param positionMapItemSynDTOS
* @param topic
*//*
*/
@Override
public void synchronousAllItemToPP(List<PositionMapItemSynDTO> positionMapItemSynDTOS, String topic) {
try {
@ -59,5 +59,5 @@ public class PathPlanningApiImpl implements PathPlanningApi {
} catch (MqttException e) {
log.info("同步信息给PP--完成--异常 :{}",e);
}
}*/
}
}

View File

@ -23,7 +23,7 @@ public class RobotTaskApiImpl implements RobotTaskApi {
@Autowired
private MqttUtils mqttUtils;
/*@Override
@Override
public void sendTaskToRobot(List<RobotAcceptTaskDTO> robotTaskDOS) {
for (RobotAcceptTaskDTO robotTaskDO : robotTaskDOS) {
log.info("发送MQTT消息 :{}",JSON.toJSONString(robotTaskDO));
@ -33,5 +33,5 @@ public class RobotTaskApiImpl implements RobotTaskApi {
log.info("消息发送异常 :{}",e.getMessage());
}
}
}*/
}
}

View File

@ -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(), StandardCharsets.UTF_8);
String msg = new String(mqttMessage.getPayload());
// log.info("[MQTT]接收当前消息为 :{}", msg);
try {

View File

@ -98,7 +98,7 @@ public class MqttFactory {
MqttConnectOptions options = new MqttConnectOptions();
// 是否清空session设置false表示服务器会保留客户端的连接记录订阅主题qos,客户端重连之后能获取到服务器在客户端断开连接期间推送的消息
// 设置为true表示每次连接服务器都是以新的身份
options.setCleanSession(false);
options.setCleanSession(true);
// 设置连接用户名
options.setUserName(factory.config.getUsername());
// 设置连接密码
@ -147,8 +147,6 @@ 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:
@ -161,10 +159,6 @@ public class MqttFactory {
return BeanUtils.getBean(PathPlanningMoveServiceImpl.class);
case PLANNING_ROUTE_DISPLAY:
return BeanUtils.getBean(PathRouteDisplayPlanningServiceImpl.class);
case PLANNING_GRAPH_MATCH_DATA:
return BeanUtils.getBean(PlanningGraphMatchDataServiceImpl.class);
case PLANNING_REMOTE_ROBOT_MOVE_POSE_PLANNING:
return BeanUtils.getBean(PlanningRemoteRobotMovePosePlanningImpl.class);
default :
return BeanUtils.getBean(RobotTaskStatusServiceImpl.class);
}

View File

@ -22,15 +22,12 @@ 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,"路径规划失败上报"),
PLANNING_SIMULATION_ROBOT_POSE_REQUEST("SIMULATION_ROBOT_POSE_REQUEST", 2,"仿真初始化点位信息"),
PLANNING_MOVE("UPDATE_ROUTE_DISPLAY_PLANNING", 2,"车辆即将走的点位"),
PLANNING_ROUTE_DISPLAY("ROBOT_MOVE_POSE_PLANNING", 2,"路径规划上报实时路径"),
PLANNING_GRAPH_MATCH_DATA("GRAPH_MATCH_DATA", 2,"路网匹配实时数据"),
PLANNING_REMOTE_ROBOT_MOVE_POSE_PLANNING("REMOTE_ROBOT_MOVE_POSE_PLANNING", 2,"远遥车辆行走导航");
PLANNING_ROUTE_DISPLAY("ROBOT_MOVE_POSE_PLANNING", 2,"路径规划上报实时路径");
private final String topic;

View File

@ -1,10 +0,0 @@
package cn.iododer.yudao.module.mqtt.framework.remote;
import cn.iocoder.yudao.module.remote.api.path.RemotePathApi;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = {RemotePathApi.class})
public class RemoteConfiguration {
}

View File

@ -1,25 +0,0 @@
package cn.iododer.yudao.module.mqtt.service;
import cn.iocoder.yudao.module.system.api.path.PathApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* 路网匹配实时数据
*/
@Slf4j
@Service
public class PlanningGraphMatchDataServiceImpl implements MqttService{
@Resource
private PathApi pathApi;
@Override
public void analysisMessage(String message) {
log.info("匹配路网实时数据 :{}",message);
pathApi.graphMatchData(message);
}
}

View File

@ -1,22 +0,0 @@
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;
@Service
@Slf4j
public class PlanningRemoteRobotMovePosePlanningImpl implements MqttService{
@Resource
private RemotePathApi remotePathApi;
@Override
public void analysisMessage(String message) {
log.info("处理远遥导航的消息 :{}",message);
remotePathApi.remoteDistanceInformation(message);
}
}

View File

@ -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);
}

View File

@ -1,22 +0,0 @@
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);
}
}

View File

@ -12,8 +12,6 @@ spring:
config: # 【注册中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
mqtt:
charset: UTF-8
# Lock4j 配置项
lock4j:

View File

@ -12,8 +12,6 @@ spring:
config: # 【注册中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
mqtt:
charset: UTF-8
# Lock4j 配置项
lock4j:
@ -33,9 +31,8 @@ management:
# MQTT
mqtt:
# host: tcp://123.57.12.40:1883
# host: tcp://192.168.0.54:1883
host: tcp://127.0.0.1:1883
# host: tcp://10.10.7.195:1883
username: adminuser
password: adminuser
qos: 2

View File

@ -12,8 +12,6 @@ spring:
config: # 【注册中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
mqtt:
charset: UTF-8
# Lock4j 配置项
lock4j:
@ -33,7 +31,7 @@ management:
# MQTT
mqtt:
# host: tcp://123.57.12.40:1883
# host: tcp://192.168.0.54:1883
host: tcp://127.0.0.1:1883
username: adminuser
password: adminuser

View File

@ -31,7 +31,7 @@
<!-- 启动服务时,是否清理历史日志,一般不建议清理 -->
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<!-- 日志文件,到达多少容量,进行滚动 -->
<maxFileSize>50MB</maxFileSize>
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
<!-- 日志文件的总大小0 表示不限制 -->
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
<!-- 日志文件的保留天数 -->

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<modules>
<module>yudao-module-remote-api</module>
<module>yudao-module-remote-biz</module>
</modules>
<artifactId>yudao-module-remote</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>
system 模块下,我们放通用业务,支撑上层的核心业务。
例如说:用户、部门、权限、数据字典等等
</description>
</project>

View File

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-remote</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-remote-api</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
remote 模块 API暴露给其它模块调用
</description>
<dependencies>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-common</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<scope>provided</scope> <!-- 设置为 provided主要是 PageParam 使用到 -->
</dependency>
<!-- 参数校验 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<optional>true</optional>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -1,22 +0,0 @@
package cn.iocoder.yudao.module.remote.api.path;
import cn.iocoder.yudao.module.remote.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "远遥服务 - 路径规划常规信息上报")
public interface RemotePathApi {
String PREFIX = ApiConstants.PREFIX + "/path";
@PostMapping(PREFIX + "/remoteDistanceInformation")
@Operation(summary = "远遥同步车辆导航行走路程信息")
void remoteDistanceInformation(@RequestParam("message") String message);
@PostMapping(PREFIX + "/wirelessSignalStatus")
@Operation(summary = "车辆信号信息")
void wirelessSignalStatus(@RequestParam("message") String message);
}

View File

@ -1,21 +0,0 @@
package cn.iocoder.yudao.module.remote.api.path.dto;
import lombok.Data;
@Data
public class RemoteRobotDistanceInformationDTO {
//距离终点的距离
private String endDistance;
//车辆编号
private String robotNo;
//当前行走距离
private String nextDistance;
//下个状态 左前:1 右前:2 正前:3 左后4 右后:5 正后:6 终点:7
private String nextDirection;
//弧度
private String nextRadian;
//当前状态 参数含义同下个状态 左前:1 右前:2 正前:3 左后4 右后:5 正后:6 终点:7
private String currentDirection;
}

View File

@ -1,15 +0,0 @@
package cn.iocoder.yudao.module.remote.api.path.dto;
import lombok.Data;
@Data
public class RemoteRobotWirelessSignalDTO {
private String mac;
/**
* 整型单位dBm
*/
private String wirelessSignal;
}

View File

@ -1,23 +0,0 @@
package cn.iocoder.yudao.module.remote.enums;
import cn.iocoder.yudao.framework.common.enums.RpcConstants;
/**
* API 相关的枚举
*
* @author 芋道源码
*/
public class ApiConstants {
/**
* 服务名
*
* 注意需要保证和 spring.application.name 保持一致
*/
public static final String NAME = "remote-server";
public static final String PREFIX = RpcConstants.RPC_API_PREFIX + "/remote";
public static final String VERSION = "1.0.0";
}

View File

@ -1,170 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-remote</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-remote-biz</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
remote 模块,主要提供能力:
1. 与设备通信
</description>
<dependencies>
<!-- Spring Cloud 基础 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-env</artifactId>
</dependency>
<!-- 依赖服务 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-system-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-remote-api</artifactId>
<version>${revision}</version>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-websocket</artifactId>
</dependency>
<!-- DB 相关 -->
<!--<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-mybatis</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId> &lt;!&ndash; 代码生成器,使用它解析表结构 &ndash;&gt;
</dependency>-->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-redis</artifactId>
</dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-rpc</artifactId>
</dependency>
<!-- Registry 注册中心相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Config 配置中心相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- Job 定时任务相关 -->
<!--<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-job</artifactId>
</dependency>-->
<!-- 消息队列相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-mq</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId> <!-- 实现代码生成 -->
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-monitor</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId> <!-- 实现 Spring Boot Admin Server 服务端 -->
</dependency>
<!-- 三方云服务相关 -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId> <!-- 文件客户端:解决 ftp 连接 -->
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId> <!-- 文件客户端:解决 sftp 连接 -->
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId> <!-- 文件客户端解决阿里云、腾讯云、minio 等 S3 连接 -->
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId> <!-- 文件客户端:文件类型的识别 -->
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<!-- 设置构建的 jar 包名 -->
<finalName>${project.artifactId}</finalName>
<plugins>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal> <!-- 将引入的 jar 打入其中 -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,23 +0,0 @@
package cn.iocoder.yudao.module.remote;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableCaching
@EnableAsync
public class RemoteServerApplication {
public static void main(String[] args) {
// 如果你碰到启动的问题请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
// 如果你碰到 启动的问题请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
// 如果你碰到启动的问题请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
SpringApplication.run(RemoteServerApplication.class, args);
// 如果你碰到启动的问题请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
// 如果你碰到启动的问题请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
// 如果你碰到启动的问题请认真阅读 https://cloud.iocoder.cn/quick-start/ 文章
}
}

View File

@ -1,46 +0,0 @@
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;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Slf4j
@RestController // 提供 RESTful API 接口 Feign 调用
@Validated
public class RemotePathApiImpl implements RemotePathApi{
@Autowired
private RemoteRobotService remoteRobotService;
/**
* 远遥推送车辆将要行走的路径
* @param message
*/
@Override
public void remoteDistanceInformation(String message) {
RemoteRobotDistanceInformationDTO data = JSON.parseObject(message, RemoteRobotDistanceInformationDTO.class);
remoteRobotService.remoteDistanceInformation(data);
}
/**
* 车辆信号信息
* @param message
*/
@Override
public void wirelessSignalStatus(String message) {
RemoteRobotWirelessSignalDTO data = JSON.parseObject(message, RemoteRobotWirelessSignalDTO.class);
remoteRobotService.sendRobotWirelessSignalStatus(data);
}
}

View File

@ -1,241 +0,0 @@
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 lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.REMOTE_ROBOT_CONNECT_FAIL;
@Component
@Slf4j
public class RemoteControllerProcessor {
public final ConcurrentHashMap<String, RemoteControllerSocketDTO> cache = new ConcurrentHashMap<>();
public final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
@Value("${remote.msg}")
private String defaultMsg;
@Value("${remote.cockpit-time-out}")
private int cockpitTimeOut;
@Value("${remote.industrial-control-time-out}")
private int industrialControlTimeOut;
@Value("${remote.robot-communication-time-out}")
private int robotCommunicationTimeOut;
private final String ONE = "01";
private final String TWO = "02";
@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 :{}", cockpitIp);
} catch (IOException e) {
log.error("关闭socket出现异常 :{}", cockpitIp);
throw new RuntimeException(e);
}
} else {
remoteControllerSocketDTO = new RemoteControllerSocketDTO();
}
remoteControllerSocketDTO.setControllerIp(cockpitIp);
remoteControllerSocketDTO.setControllerPort(cockpitPort);
Socket socket = new Socket();
try {
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(cockpitIp, remoteControllerSocketDTO);
}
/**
* 设置
*
* @param remoteControllerSocket
* @param type
*/
public void setMsg(RemoteControllerSocketDTO remoteControllerSocket, Integer type, RemoteRobotTransferDTO dto) {
String msg = defaultMsg;
if (RemoteIpTypeEnum.ONE.getType().equals(type)) {
msg = msg + " " + ONE;
} else {
msg = msg + " " + TWO;
}
String[] split = dto.getRobotIp().split("\\.");
for (String ipItem : split) {
String hex = Integer.toHexString(Integer.valueOf(ipItem));
msg = msg + " " + hex;
log.info("组装 :{}", hex);
}
String portHex = Integer.toHexString(dto.getRobotPort().intValue());
String portHexOne = portHex.substring(0, 2);
String portHexTwo = portHex.substring(2);
msg = msg + " " + portHexTwo + " " + portHexOne;
if (cockpitTimeOut > 0) {
msg = msg + " " + ONE + " " + Integer.toHexString(cockpitTimeOut);
} else {
msg = msg + " " + TWO + " " + Integer.toHexString(cockpitTimeOut);
}
if (industrialControlTimeOut > 0) {
msg = msg + " " + ONE + " " + Integer.toHexString(industrialControlTimeOut);
} else {
msg = msg + " " + TWO + " " + Integer.toHexString(industrialControlTimeOut);
}
if (robotCommunicationTimeOut > 0) {
msg = msg + " " + ONE + " " + Integer.toHexString(robotCommunicationTimeOut);
} else {
msg = msg + " " + TWO + " " + Integer.toHexString(robotCommunicationTimeOut);
}
String crc = CRCUtil.getCRC(msg);
String crcOne = crc.substring(0, 2);
String crcTwo = crc.substring(2);
msg = msg + " " + crcOne + " " + crcTwo;
remoteControllerSocket.setMsg(msg);
}
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(cockpitIp);
Socket socket = remoteControllerSocketDTO.getSocket();
if (socket == null || socket.isClosed()) {
try {
socket = new Socket();
log.info("连接新的的socket");
socket.setKeepAlive(true);
socket.connect(new InetSocketAddress(cockpitIp, cockpit.getControllerPort()), 1000);
} catch (IOException e) {
log.error("连接socket出现异常 :{}", cockpitIp);
}
}
OutputStream os = null;
try {
os = socket.getOutputStream();
log.info("断开连接 :{} ,对应的IP :{}", remoteControllerSocketDTO.getMsg(), remoteControllerSocketDTO.getControllerIp());
os.write(remoteControllerSocketDTO.getMsg().getBytes());
socket.shutdownInput();
socket.close();
log.info("关闭socket :{}", cockpitIp);
} catch (IOException e) {
log.error("关闭socket出现异常 :{}", cockpitIp);
} finally {
if (ObjectUtil.isNotEmpty(os)) {
try {
os.close();
} catch (IOException e) {
}
}
}
remoteCache(dto,ip);
}
/*public RemoteControllerProcessor() {
// 每秒执行一次 - 处理并发送数据 - 避免数据丢失
scheduler.scheduleAtFixedRate(this::processAndSend, 150, 150, TimeUnit.MILLISECONDS);
}*/
public void processAndSend() {
if (ObjectUtil.isEmpty(cache)) {
return;
}
// log.info("socket发送数据开始");
for (Map.Entry<String, RemoteControllerSocketDTO> v : cache.entrySet()) {
RemoteControllerSocketDTO remoteControllerSocketDTO = v.getValue();
Socket socket = remoteControllerSocketDTO.getSocket();
if (socket == null || socket.isClosed()) {
socket = new Socket();
try {
socket.connect(new InetSocketAddress(v.getKey(), remoteControllerSocketDTO.getControllerPort()), 1000);
remoteControllerSocketDTO.setSocket(socket);
} catch (IOException e) {
log.error("socket重连异常 :{}", e);
}
}
OutputStream os = null;
try {
os = socket.getOutputStream();
String str = remoteControllerSocketDTO.getMsg();
os.write(remoteControllerSocketDTO.getMsg().getBytes());
log.info("socket推送的数据 :{}", str);
} catch (IOException e) {
log.error("socket发送异常 :{}", e);
} finally {
if (ObjectUtil.isNotEmpty(os)) {
try {
os.close();
} catch (IOException e) {
}
}
}
}
}
public void shutdown() {
scheduler.shutdown();
}
@PreDestroy
public void destroy() {
// 在Bean销毁前关闭去啊
shutdown();
}
}

View File

@ -1,36 +0,0 @@
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();
}
});
}
}

View File

@ -1,60 +0,0 @@
package cn.iocoder.yudao.module.remote.api.webSocket;
import cn.hutool.core.map.MapUtil;
import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Component
@Slf4j
public class RequestProcessor {
private final ConcurrentHashMap<String, ConcurrentHashMap<String, String>> cache = new ConcurrentHashMap<>();
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
@Resource
public WebSocketSenderApi webSocketSenderApi;
public RequestProcessor() {
// 每秒执行一次 - 处理并发送数据 - 避免数据丢失
scheduler.scheduleAtFixedRate(this::processAndSend, 100, 100, TimeUnit.MILLISECONDS);
}
public void handleRequest(String map, String mac, String data) {
cache.computeIfAbsent(map, k -> new ConcurrentHashMap<>()).put(mac, data);
}
private void processAndSend() {
// 创建快照
Map<String, ConcurrentHashMap<String, String>> snapshot = new ConcurrentHashMap<>(cache);
cache.clear(); // 先清理缓存
for (Map.Entry<String, ConcurrentHashMap<String, String>> entry : snapshot.entrySet()) {
if (!MapUtil.isEmpty(entry.getValue())) {
sendData(entry.getKey(), entry.getValue());
}
}
}
private void sendData(String map, Map<String, String> data) {
log.info("远遥 key:" + map + "发送数据:" + data);
webSocketSenderApi.sendObject(map, "remote_map_push", data);
}
public void shutdown() {
scheduler.shutdown();
}
@PreDestroy
public void destroy() {
// 在Bean销毁前关闭去啊
shutdown();
}
}

View File

@ -1,31 +0,0 @@
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> 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;
}
}

View File

@ -1,62 +0,0 @@
package cn.iocoder.yudao.module.remote.config.server;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
@Slf4j
@Component
public class TCPServerApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
new Thread(new Runnable() {
@Override
public void run() {
initServer();
}
}).start();
}
public void initServer() {
try {
log.info("开始初始化socket服务");
ServerSocket server=new ServerSocket(9000);
while (true){
// 监听客户端的请求,没有的话就会进行阻塞
Socket socket=server.accept();
//开启一个线程进行处理客户端的请求
new Thread(new Runnable() {
@Override
public void run() {
try {
InputStream is=socket.getInputStream();
byte[] bytes=new byte[1024];
int len=is.read(bytes);
System.out.println(new String(bytes,0,len));
OutputStream os= socket.getOutputStream();
//响应给客户端
os.write("收到谢谢".getBytes());
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
log.info("初始化socket服务完成");
}
} catch (Exception e) {
}
}
}

View File

@ -1,13 +0,0 @@
package cn.iocoder.yudao.module.remote.constant.robot;
public class RobotTaskChcheConstant {
//机器人楼层和区域 (拼接的是mac地址)
public static String ROBOT_FLOOR_AREA = "robot:floor:area";
//机器人编号和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";
}

View File

@ -1,51 +0,0 @@
package cn.iocoder.yudao.module.remote.controller.admin.login;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.remote.service.login.LoginService;
import cn.iocoder.yudao.module.system.api.remote.dto.LoginCheckDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 远遥登录")
@RestController
@RequestMapping("/remote/login")
@Validated
public class LoginController {
@Resource
private LoginService loginService;
@PostMapping("/check")
@Operation(summary = "测试通讯")
@PermitAll
public CommonResult<Boolean> checkCommunication(@Valid @RequestBody LoginCheckDTO loginCheckDTO) {
return success(loginService.checkCommunication(loginCheckDTO));
}
@PostMapping("/saveIpAndPort")
@Operation(summary = "保存IP和端口")
@PermitAll
public CommonResult<Boolean> saveIpAndPort(@Valid @RequestBody LoginCheckDTO loginCheckDTO,
HttpServletRequest request) {
loginService.saveIpAndPort(loginCheckDTO,request);
return success(true);
}
@PostMapping("/getIpAndPort")
@Operation(summary = "查询IP和端口")
@PermitAll
public CommonResult<LoginCheckDTO> getIpAndPort(HttpServletRequest request) {
return success(loginService.getIpAndPort(request));
}
}

View File

@ -1,109 +0,0 @@
package cn.iocoder.yudao.module.remote.controller.admin.robot;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
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;
import cn.iocoder.yudao.module.remote.service.robot.RemoteRobotService;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotStatusDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 远遥车辆")
@RestController
@RequestMapping("/remote/robot")
@Validated
public class RemoteRobotController {
@Autowired
private RemoteRobotService remoteRobotService;
@PostMapping("/getAreaRobot")
@Operation(summary = "获取地图区域对应的机器人信息")
public CommonResult<List<RemoteRobotDTO>> getAreaRobot(@Valid @RequestBody PositionMapRespDTO positionMapRespDTO) {
List<RemoteRobotDTO> list = remoteRobotService.remoteGetAreaRobot(positionMapRespDTO);
return success(list);
}
@GetMapping("/emergencyStopOrRecovery")
@Operation(summary = "一键急停or一键恢复地图上所有AGV")
@Parameter(name = "type", description = "类型(1:停止, 0:恢复)", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('remote:robot:emergencyStopOrRecovery')")
public CommonResult<Boolean> remoteEmergencyStopOrRecovery(@RequestParam("id") Long id, @RequestParam("type") Integer type) {
remoteRobotService.remoteEmergencyStopOrRecovery(id,type);
return success(true);
}
@PostMapping("/getRobotRemoteStatus")
@Operation(summary = "获取机器人远遥模式/急停/协控状态")
@PreAuthorize("@ss.hasPermission('remote:robot:getRobotRemoteStatus')")
public CommonResult<RemoteRobotStatusDTO> getRobotRemoteStatus(HttpServletRequest request) {
return success(remoteRobotService.getRemoteRobotStatus(request));
}
@GetMapping("/stop")
@Operation(summary = "暂停车辆")
@PreAuthorize("@ss.hasPermission('remote:robot:stop')")
public CommonResult<Boolean> robotStop(@RequestParam("robotNo") String robotNo) {
remoteRobotService.robotStop(robotNo);
return success(true);
}
@GetMapping("/recovery")
@Operation(summary = "恢复车辆")
@PreAuthorize("@ss.hasPermission('remote:robot:recovery')")
public CommonResult<Boolean> recovery(@RequestParam("robotNo") String robotNo) {
remoteRobotService.recovery(robotNo);
return success(true);
}
@PostMapping("/robotChangeMode")
@Operation(summary = "修改模式")
@PreAuthorize("@ss.hasPermission('remote:robot:robotChangeMode')")
public CommonResult<Boolean> robotChangeMode(@Valid @RequestBody RemoteRobotChangeModeDTO data,HttpServletRequest request) {
remoteRobotService.robotChangeMode(data,request);
return success(true);
}
@GetMapping("/getMap")
@Operation(summary = "获得仓库点位地图Map")
@PreAuthorize("@ss.hasPermission('remote:robot:getMap')")
public CommonResult<Object> getPositionMapList() {
Object result = remoteRobotService.getPositionMapList();
return success(result);
}
@PostMapping("/disconnect")
@Operation(summary = "断开连接")
@PreAuthorize("@ss.hasPermission('remote:robot:disconnect')")
public CommonResult<Boolean> remoteDisconnect(HttpServletRequest request) {
remoteRobotService.remoteDisconnect(request);
return success(true);
}
@PostMapping("/taskDone")
@Operation(summary = "任务完成/取货完成")
@PreAuthorize("@ss.hasPermission('remote:robot:taskDone')")
public CommonResult<Boolean> remoteTaskDone(@Valid @RequestBody RemoteRobotTaskDoneDTO remoteRobotTaskDoneDTO,
HttpServletRequest request) {
remoteRobotService.remoteTaskDone(remoteRobotTaskDoneDTO,request);
return success(true);
}
}

View File

@ -1,14 +0,0 @@
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;
}

View File

@ -1,13 +0,0 @@
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.NotNull;
@Data
public class PositionMapRespDTO {
@Schema(description = "地图id")
@NotNull(message = "请输入地图id")
private Long id;
}

View File

@ -1,16 +0,0 @@
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 {
@Schema(description = "驾舱IP")
private String controllerIp;
@Schema(description = "驾舱端口")
private int controllerPort;
private Socket socket;
private String msg;
}

View File

@ -1,22 +0,0 @@
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;
@Data
public class RemoteRobotChangeModeDTO {
@Schema(description = "远遥模式(0:自动模式, 1:手动模式, 2:自由模式)")
@NotNull(message = "请选择远遥模式")
@Max(value = 2,message = "请选择远遥模式")
@Min(value = 0,message = "请选择远遥模式")
private Integer remoteMode = 0;
@Schema(description = "车辆编号")
@NotEmpty(message = "请选择车辆编号")
private String robotNo ;
}

View File

@ -1,14 +0,0 @@
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.NotNull;
@Data
public class RemoteRobotTaskDoneDTO {
@Schema(description = "取货完成: 0, 任务完成: 1")
@NotNull(message = "请选择是取货完成还是任务完成")
private Integer mode = 0;
}

View File

@ -1,25 +0,0 @@
package cn.iocoder.yudao.module.remote.controller.admin.robot.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
@Builder
@Data
public class RobotDistanceInformationDTO {
@Schema(description = "车辆编号", example = "28234")
private String robotNo;
@Schema(description = "速度", example = "28234")
public String linearSpeed;
@Schema(description = "信息", example = "28234")
public String message;
@Schema(description = "距离终点的距离", example = "28234")
private String endDistance;
@Schema(description = "弧度", example = "28234")
private String nextRadian;
}

View File

@ -1,44 +0,0 @@
package cn.iocoder.yudao.module.remote.controller.admin.speed;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.remote.service.speed.RemoteRobotMaxSpeedService;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotMaxSpeedDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 远遥车辆速度")
@RestController
@RequestMapping("/remote/robotMaxSpeed")
@Validated
public class RemoteRobotMaxSpeedController {
@Autowired
private RemoteRobotMaxSpeedService remoteRobotMaxSpeedService;
@GetMapping("/list")
@Operation(summary = "获得远遥车辆最大速度集合")
@PreAuthorize("@ss.hasPermission('remote:robotMaxSpeed:list')")
public CommonResult<List<RemoteRobotMaxSpeedDTO>> getRobotMaxSpeedPage() {
List<RemoteRobotMaxSpeedDTO> list = remoteRobotMaxSpeedService.getRobotMaxSpeedPage();
return success(list);
}
@PostMapping("/update")
@Operation(summary = "更新远遥车辆最大速度")
@PreAuthorize("@ss.hasPermission('remote:robotMaxSpeed:update')")
public CommonResult<Boolean> updateRobotMaxSpeedPage(@RequestBody List<RemoteRobotMaxSpeedDTO> list) {
remoteRobotMaxSpeedService.updateRobotMaxSpeedPage(list);
return success(true);
}
}

View File

@ -1,68 +0,0 @@
package cn.iocoder.yudao.module.remote.controller.admin.task;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.remote.service.task.RemoteTaskService;
import cn.iocoder.yudao.module.remote.util.IpUtils;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteExceptionTaskDetailDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotCameraDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteTaskQueryDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteTaskTransferDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 异常车辆列表")
@RestController
@RequestMapping("/remote/task")
@Validated
public class RemoteTaskController {
@Autowired
private RemoteTaskService remoteTaskService;
@PostMapping("/getExceptionTaskDetail")
@Operation(summary = "获取异常车辆任务列表")
@PreAuthorize("@ss.hasPermission('remote:task:getExceptionTaskDetail')")
public CommonResult<PageResult<RemoteExceptionTaskDetailDTO>> getExceptionTaskDetail(@RequestBody RemoteTaskQueryDTO remoteTaskQuery) {
PageResult<RemoteExceptionTaskDetailDTO> list = remoteTaskService.getExceptionTaskDetail(remoteTaskQuery);
return success(list);
}
@GetMapping("/getCarmeraByRobotNo")
@Operation(summary = "查看环境--获取摄像头IP和账号")
@PreAuthorize("@ss.hasPermission('remote:task:getExceptionTaskDetail')")
public CommonResult<List<RemoteRobotCameraDTO>> getCarmeraByRobotNo(@RequestParam("robotNo") String robotNo) {
List<RemoteRobotCameraDTO> list = remoteTaskService.getCarmeraByRobotNo(robotNo);
return success(list);
}
@PostMapping("/transferTask")
@Operation(summary = "任务转移")
@PreAuthorize("@ss.hasPermission('remote:task:transferTask')")
public CommonResult<Boolean> remoteTransferTask(@RequestBody RemoteTaskTransferDTO remoteTaskTransfer, HttpServletRequest request) {
String remoteIp = IpUtils.getIp(request);
remoteTaskTransfer.setRemoteIp(remoteIp);
remoteTaskService.remoteTransferTask(remoteTaskTransfer);
return success(true);
}
}

View File

@ -1,42 +0,0 @@
package cn.iocoder.yudao.module.remote.enums.robot;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Iterator;
@Getter
@AllArgsConstructor
public enum DirectionEnum {
LEFT_FRONT("1", "左转"),
RIGHT_FRONT("2", "右转"),
RIGHT_IN_FRONT("3", "直走"),
LEFT_REAR("4", "左后方方向转弯"),
RIGHT_REAR("5", "右后方方向转弯"),
RIGHT_BEHIND("6", "正后方方向"),
END_POINT("7", "到达终点");
/**
* 类型
*/
private final String type;
/**
* 说明
*/
private final String msg;
public static String getMsgByType(String code){
Iterator<DirectionEnum> iterator = Arrays.stream(DirectionEnum.values()).iterator();
while (iterator.hasNext()){
DirectionEnum next = iterator.next();
if(next.type.equals(code)){
return next.getMsg() ;
}
}
return null;
}
}

View File

@ -1,23 +0,0 @@
package cn.iocoder.yudao.module.remote.enums.robot;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum RemoteIpTypeEnum {
ONE(1, "有效设置车辆IP信息"),
TWO(2, "有效设置工控主机IP信息"),
THREE(3, "有效断开当前车辆IP"),
FOUR(4, "无效IP信息直接舍弃");
/**
* 类型
*/
private final Integer type;
/**
* 说明
*/
private final String msg;
}

View File

@ -1,40 +0,0 @@
package cn.iocoder.yudao.module.remote.framework.security.config;
import cn.iocoder.yudao.module.remote.enums.ApiConstants;
import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
/**
* remote 模块的 Security 配置
*/
@Configuration(proxyBeanMethods = false, value = "remoteSecurityConfiguration")
public class SecurityConfiguration {
@Bean("RemoteAuthorizeRequestsCustomizer")
public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
return new AuthorizeRequestsCustomizer() {
@Override
public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
// TODO 芋艿这个每个项目都需要重复配置得捉摸有没通用的方案
// Swagger 接口文档
registry.requestMatchers("/v3/api-docs/**").permitAll()
.requestMatchers("/webjars/**").permitAll()
.requestMatchers("/swagger-ui").permitAll()
.requestMatchers("/swagger-ui/**").permitAll();
// Druid 监控
registry.requestMatchers("/druid/**").permitAll();
// Spring Boot Actuator 的安全配置
registry.requestMatchers("/actuator").permitAll()
.requestMatchers("/actuator/**").permitAll();
// RPC 服务的安全配置
registry.requestMatchers(ApiConstants.PREFIX + "/**").permitAll();
}
};
}
}

View File

@ -1,14 +0,0 @@
package cn.iocoder.yudao.module.remote.framework.system;
import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi;
import cn.iocoder.yudao.module.system.api.remote.RemoteExceptionTaskApi;
import cn.iocoder.yudao.module.system.api.remote.RemoteLoginApi;
import cn.iocoder.yudao.module.system.api.remote.RemoteRobotApi;
import cn.iocoder.yudao.module.system.api.remote.RemoteRobotMaxSpeedApi;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = {RemoteLoginApi.class, RemoteRobotApi.class, RemoteExceptionTaskApi.class, RemoteRobotMaxSpeedApi.class, WebSocketSenderApi.class})
public class SystemConfiguration {
}

View File

@ -1,21 +0,0 @@
package cn.iocoder.yudao.module.remote.service.login;
import cn.iocoder.yudao.module.system.api.remote.dto.LoginCheckDTO;
import javax.servlet.http.HttpServletRequest;
public interface LoginService {
Boolean checkCommunication(LoginCheckDTO loginCheckDTO);
/**
* 保存IP和端口
* @param loginCheckDTO
*/
void saveIpAndPort(LoginCheckDTO loginCheckDTO, HttpServletRequest request);
/**
* 查询默认IP和端口
* @return
*/
LoginCheckDTO getIpAndPort(HttpServletRequest request);
}

View File

@ -1,76 +0,0 @@
package cn.iocoder.yudao.module.remote.service.login;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.module.remote.util.IpUtils;
import cn.iocoder.yudao.module.system.api.remote.RemoteLoginApi;
import cn.iocoder.yudao.module.system.api.remote.dto.LoginCheckDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
public class LoginServiceImpl implements LoginService {
private String checkUrl = "/admin-api/system/remote/controller-information/checkAddress";
@Resource
private RemoteLoginApi remoteLoginApi;
/**
* 测试通讯
*
* @param loginCheckDTO
* @return
*/
@Override
public Boolean checkCommunication(LoginCheckDTO loginCheckDTO) {
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
factory.setConnectTimeout(2 * 1000);
RestTemplate restTemplate = new RestTemplate(factory);
String url = "http://" + loginCheckDTO.getSystemIp() + ":" + loginCheckDTO.getSystemPort() + checkUrl;
LinkedMultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
headers.add("Tenant-Id", "1");
headers.add("Content-Type", "application/json");
Map<String, String> map = new HashMap<>();
map.put("systemIp", loginCheckDTO.getSystemIp());
HttpEntity<String> request = new HttpEntity<String>(JSONUtil.toJsonStr(map), headers);
ResponseEntity<String> response = null;
try {
response = restTemplate.postForEntity(url, request, String.class);
} catch (Exception e) {
}
return ObjectUtil.isNotEmpty(response) && loginCheckDTO.getSystemIp().equals(response.getBody());
}
/**
* 保存IP和端口
*
* @param loginCheckDTO
*/
@Override
public void saveIpAndPort(LoginCheckDTO loginCheckDTO, HttpServletRequest request) {
String ip = IpUtils.getIp(request);
loginCheckDTO.setRemoteIp(ip);
remoteLoginApi.saveIpAndPort(loginCheckDTO);
}
@Override
public LoginCheckDTO getIpAndPort(HttpServletRequest request) {
String ip = IpUtils.getIp(request);
return remoteLoginApi.getIpAndPort(ip);
}
}

View File

@ -1,86 +0,0 @@
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;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotStatusDTO;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
public interface RemoteRobotService {
/**
* 获取地图区域对应的机器人信息
* @param positionMapRespDTO
* @return
*/
List<RemoteRobotDTO> remoteGetAreaRobot(PositionMapRespDTO positionMapRespDTO);
/**
* 键急停or一键恢复地图上所有AGV
* @param id
* @param type
*/
void remoteEmergencyStopOrRecovery(Long id, Integer type);
/**
* 获取机器人远遥模式/急停/协控状态
* @param request
* @return
*/
RemoteRobotStatusDTO getRemoteRobotStatus(HttpServletRequest request);
/**
* 暂停车辆
* @param robotNo
* @return
*/
void robotStop(String robotNo);
/**
* 恢复车辆
* @param robotNo
*/
void recovery(String robotNo);
/**
* 切换远遥模式
* @param data
* @return
*/
void robotChangeMode( RemoteRobotChangeModeDTO data,HttpServletRequest request);
/**
* 查询地图
* @return
*/
Object getPositionMapList();
/**
* 断开连接
* @param request
*/
void remoteDisconnect(HttpServletRequest request);
/**
* 任务完成/取货完成
* @param remoteRobotTaskDoneDTO
* @param request
*/
void remoteTaskDone( RemoteRobotTaskDoneDTO remoteRobotTaskDoneDTO, HttpServletRequest request);
/**
* 推送导航信息给前端
* @param data
*/
void remoteDistanceInformation(RemoteRobotDistanceInformationDTO data);
/**
* 上报车辆信号信息
* @param data
*/
void sendRobotWirelessSignalStatus(RemoteRobotWirelessSignalDTO data);
}

View File

@ -1,247 +0,0 @@
package cn.iocoder.yudao.module.remote.service.robot;
import cn.hutool.core.util.ObjectUtil;
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;
import cn.iocoder.yudao.module.remote.controller.admin.robot.dto.RobotDistanceInformationDTO;
import cn.iocoder.yudao.module.remote.enums.robot.DirectionEnum;
import cn.iocoder.yudao.module.remote.util.IpUtils;
import cn.iocoder.yudao.module.remote.util.redis.RedisUtil;
import cn.iocoder.yudao.module.system.api.remote.RemoteRobotApi;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotStatusDTO;
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;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TASK_COMMONG_FAIL;
@Slf4j
@Service
public class RemoteRobotServiceImpl implements RemoteRobotService {
@Resource
private RemoteRobotApi remoteRobotApi;
@Resource
private RedisUtil redisUtil;
@Resource
private RemoteControllerProcessor remoteControllerProcessor;
@Autowired
private IpProperties ipProperties;
/**
* 获取地图区域对应的机器人信息
*
* @param positionMapRespDTO
* @return
*/
@Override
public List<RemoteRobotDTO> remoteGetAreaRobot(PositionMapRespDTO positionMapRespDTO) {
return remoteRobotApi.remoteGetAreaRobot(positionMapRespDTO.getId());
}
/**
* 一键急停or一键恢复地图上所有AGV
*
* @param id
* @param type
*/
@Override
public void remoteEmergencyStopOrRecovery(Long id, Integer type) {
CommonResult<Boolean> result = remoteRobotApi.remoteEmergencyStopOrRecovery(id, type);
if (!result.isSuccess()) {
throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
}
}
/**
* 获取机器人远遥模式/急停/协控状态
*
* @param request
* @return
*/
@Override
public RemoteRobotStatusDTO getRemoteRobotStatus(HttpServletRequest request) {
String ip = IpUtils.getIp(request);
return remoteRobotApi.getRemoteRobotStatus(ip);
}
/**
* 暂停机器人
*
* @param robotNo
* @return
*/
@Override
public void robotStop(String robotNo) {
CommonResult<Boolean> result = remoteRobotApi.robotStop(robotNo);
if (!result.isSuccess()) {
throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
}
}
/**
* 恢复车辆
*
* @param robotNo
*/
@Override
public void recovery(String robotNo) {
CommonResult<Boolean> result = remoteRobotApi.recovery(robotNo);
if (!result.isSuccess()) {
throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
}
}
/**
* 切换远遥模式
*
* @param data
* @return
*/
@Override
public void robotChangeMode(RemoteRobotChangeModeDTO data, HttpServletRequest request) {
String ip = IpUtils.getIp(request);
Cockpit cockpit = ipProperties.getCockpitByIp(ip);
CommonResult<RemoteRobotTransferDTO> 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(),ip);
}else {
remoteControllerProcessor.remoteCache(result.getData(),ip);
}
}
@Override
public Object getPositionMapList() {
return remoteRobotApi.getRemotePositionMapList();
}
/**
* 断开连接
*
* @param request
*/
@Override
public void remoteDisconnect(HttpServletRequest request) {
String ip = IpUtils.getIp(request);
CommonResult<RemoteRobotTransferDTO> result = remoteRobotApi.remoteDisconnect(ip);
if (!result.isSuccess()) {
throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
}
if (ObjectUtil.isEmpty(result.getData())) {
log.info("断开连接, 未查到远遥绑定的信息 :{}",ip);
return;
}
remoteControllerProcessor.remoteCache(result.getData(),ip);
}
/**
* 任务完成/取货完成
*
* @param remoteRobotTaskDoneDTO
* @param request
*/
@Override
public void remoteTaskDone(RemoteRobotTaskDoneDTO remoteRobotTaskDoneDTO, HttpServletRequest request) {
String ip = IpUtils.getIp(request);
CommonResult<Boolean> result = remoteRobotApi.remoteTaskDone(ip, remoteRobotTaskDoneDTO.getMode());
if (!result.isSuccess()) {
throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
}
}
/**
* 推送导航信息给前端
*
* @param data
*/
@Override
public void remoteDistanceInformation(RemoteRobotDistanceInformationDTO data) {
TenantContextHolder.setTenantId(1L);
String mac = (String) redisUtil.get(RobotTaskChcheConstant.ROBOT_GET_MAC_BY_NO + data.getRobotNo());
if (ObjectUtil.isEmpty(mac)) {
mac = remoteRobotApi.getMacByRobotNo(data.getRobotNo());
}
String floorAreaKey = RobotTaskChcheConstant.ROBOT_FLOOR_AREA + mac;
Object o = redisUtil.get(floorAreaKey);
if (ObjectUtil.isEmpty(o)) {
log.info("找不到对应的车辆位置信息 :{}, 车辆编号:{}", floorAreaKey, data.getRobotNo());
return;
}
FloorZoneDTO floorZone = JSON.parseObject((String) o, FloorZoneDTO.class);
String msg = getDistanceInformationMsg(data);
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));*/
}
/**
* 上报车辆信息信息
* @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);
}
/**
* 组装
*
* @param data
* @return
*/
public String getDistanceInformationMsg(RemoteRobotDistanceInformationDTO data) {
if (DirectionEnum.LEFT_FRONT.getType().equals(data.getCurrentDirection())) {
return DirectionEnum.LEFT_FRONT.getMsg();
} else if (DirectionEnum.RIGHT_FRONT.getType().equals(data.getCurrentDirection())) {
return DirectionEnum.RIGHT_FRONT.getMsg();
} else if (DirectionEnum.RIGHT_IN_FRONT.getType().equals(data.getCurrentDirection()) && DirectionEnum.END_POINT.getType().equals(data.getNextDirection())) {
//直走到终点
return DirectionEnum.RIGHT_IN_FRONT.getMsg() + data.getEndDistance() + "米到达终点";
} else if (DirectionEnum.RIGHT_IN_FRONT.getType().equals(data.getCurrentDirection())) {
//直走后拐弯
return DirectionEnum.RIGHT_IN_FRONT.getMsg() + data.getNextDistance() + "米后 " + DirectionEnum.getMsgByType(data.getNextDirection());
} else {
return DirectionEnum.getMsgByType(data.getNextDirection());
}
}
}

View File

@ -1,11 +0,0 @@
package cn.iocoder.yudao.module.remote.service.speed;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotMaxSpeedDTO;
import java.util.List;
public interface RemoteRobotMaxSpeedService {
List<RemoteRobotMaxSpeedDTO> getRobotMaxSpeedPage();
void updateRobotMaxSpeedPage(List<RemoteRobotMaxSpeedDTO> list);
}

View File

@ -1,47 +0,0 @@
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{
@Resource
private RemoteRobotMaxSpeedApi remoteRobotMaxSpeedApi;
@Value("${remote.robot-max-speed:5}")
private int robotMaxSpeed;
@Override
public List<RemoteRobotMaxSpeedDTO> getRobotMaxSpeedPage() {
return remoteRobotMaxSpeedApi.getRobotMaxSpeedPage();
}
@Override
public void updateRobotMaxSpeedPage(List<RemoteRobotMaxSpeedDTO> 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);
}
}

View File

@ -1,15 +0,0 @@
package cn.iocoder.yudao.module.remote.service.task;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.api.remote.dto.*;
import java.util.List;
public interface RemoteTaskService {
PageResult<RemoteExceptionTaskDetailDTO> getExceptionTaskDetail(RemoteTaskQueryDTO remoteTaskQuery);
List<RemoteRobotCameraDTO> getCarmeraByRobotNo(String robotNo);
void remoteTransferTask(RemoteTaskTransferDTO remoteTaskTransfer);
}

View File

@ -1,60 +0,0 @@
package cn.iocoder.yudao.module.remote.service.task;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.api.remote.RemoteExceptionTaskApi;
import cn.iocoder.yudao.module.system.api.remote.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.TASK_COMMONG_FAIL;
@Slf4j
@Service
public class RemoteTaskServiceImpl implements RemoteTaskService {
@Resource
private RemoteExceptionTaskApi remoteExceptionTaskApi;
/**
* 远遥查询异常的车辆
* @param remoteTaskQuery
* @return
*/
@Override
public PageResult<RemoteExceptionTaskDetailDTO> getExceptionTaskDetail(RemoteTaskQueryDTO remoteTaskQuery) {
return remoteExceptionTaskApi.getExceptionTaskDetail(remoteTaskQuery);
}
/**
* 查摄像头信息
* @param robotNo
* @return
*/
@Override
public List<RemoteRobotCameraDTO> getCarmeraByRobotNo(String robotNo) {
CommonResult<List<RemoteRobotCameraDTO>> result = remoteExceptionTaskApi.getCarmeraByRobotNo(robotNo);
if (!result.isSuccess()){
throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
}
return result.getData();
}
/**
* 任务转移
* @param remoteTaskTransfer
*/
@Override
public void remoteTransferTask(RemoteTaskTransferDTO remoteTaskTransfer) {
CommonResult<Boolean> result = remoteExceptionTaskApi.remoteTransferTask(remoteTaskTransfer);
if (!result.isSuccess()){
throw exception0(TASK_COMMONG_FAIL.getCode(), result.getMsg());
}
}
}

View File

@ -1,39 +0,0 @@
package cn.iocoder.yudao.module.remote.util;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest;
/**
* 获取IP方法
*
*
*/
public class IpUtils
{
public static String getIp(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if (ip.equals("0:0:0:0:0:0:0:1")) {
ip = "127.0.0.1";
}
return ip;
}
}

View File

@ -1,91 +0,0 @@
package cn.iocoder.yudao.module.remote.util.crc;
/**
* @author lwt
* @date 2018-06-26
*
* CRC16校验码计算
* <p>
* (1)预置1个16位的寄存器为十六进制FFFF即全为1称此寄存器为CRC寄存器
* (2)把第一个8位二进制数据既通讯信息帧的第一个字节与16位的CRC寄存器的低
* 8位相异或把结果放于CRC寄存器
* (3)把CRC寄存器的内容右移一位朝低位用0填补最高位并检查右移后的移出位
* (4)如果移出位为0重复第3步再次右移一位如果移出位为1CRC寄存器与多项式A0011010 0000 0000 0001进行异或
* (5)重复步骤3和4直到右移8次这样整个8位数据全部进行了处理
* (6)重复步骤2到步骤5进行通讯信息帧下一个字节的处理
* (7)将该通讯信息帧所有字节按上述步骤计算完成后得到的16位CRC寄存器的高
* 字节进行交换
* (8)最后得到的CRC寄存器内容即为CRC16码(注意得到的CRC码即为低前高后顺序)
*/
public class CRCUtil {
/**
* 计算CRC16校验码
*
* @param data 需要校验的字符串
* @return 校验码
*/
public static String getCRC(String data) {
data = data.replace(" ", "");
int len = data.length();
if (!(len % 2 == 0)) {
return "0000";
}
int num = len / 2;
byte[] para = new byte[num];
for (int i = 0; i < num; i++) {
int value = Integer.valueOf(data.substring(i * 2, 2 * (i + 1)), 16);
para[i] = (byte) value;
}
return getCRC(para);
}
/**
* 计算CRC16校验码
*
* @param bytes 字节数组
* @return {@link String} 校验码
* @since 1.0
*/
public static String getCRC(byte[] bytes) {
//CRC寄存器全为1
int CRC = 0x0000ffff;
//多项式校验值
int POLYNOMIAL = 0x0000a001;
int i, j;
for (i = 0; i < bytes.length; i++) {
CRC ^= ((int) bytes[i] & 0x000000ff);
for (j = 0; j < 8; j++) {
if ((CRC & 0x00000001) != 0) {
CRC >>= 1;
CRC ^= POLYNOMIAL;
} else {
CRC >>= 1;
}
}
}
//结果转换为16进制
String result = Integer.toHexString(CRC).toUpperCase();
if (result.length() != 4) {
StringBuffer sb = new StringBuffer("0000");
result = sb.replace(4 - result.length(), 4, result).toString();
}
//交换高低位
return result.substring(2, 4) + result.substring(0, 2);
}
public static void main(String[] args) {
//01 03 20 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 8C 45
//01 03 00 00 00 08 44 0C
//01 03 10 00 8F 02 4E 00 91 02 44 00 92 02 5A 00 8B 02 47 40 D8
System.out.println(getCRC("01 03 20 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF 7F FF"));
System.out.println(getCRC("01 03 00 00 00 08"));
System.out.println(getCRC("01 03 10 00 8F 02 4E 00 91 02 44 00 92 02 5A 00 8B 02 47"));
}
}

View File

@ -1,568 +0,0 @@
package cn.iocoder.yudao.module.remote.util.redis;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public final class RedisUtil {
@Resource
private RedisTemplate<String, Object> redisTemplate;
/**
* 获取自增
* @param key
* @return
*/
public String getIncrementByKey( String key) {
Long autoID = redisTemplate.opsForValue().increment(key, 1);
// 设置key过期时间, 保证每天的流水号从1开始
if (autoID == 1) {
// 获取当前时间
DateTime now = DateUtil.date();
// 获取明天的时间
String tomorrowZero = DateUtil.format(DateUtil.tomorrow(), DatePattern.NORM_DATE_PATTERN);
DateTime tomorrowZeroDate = DateUtil.parse(tomorrowZero);
// 计算两个时间的秒数作为当天的key的失效时间
long timeOut = DateUtil.between(now, tomorrowZeroDate, DateUnit.SECOND);
// 设置过期时间
redisTemplate.expire(key, timeOut, TimeUnit.SECONDS);
}
return String.format("%06d", autoID);
}
public Set<String> keys(String keys){
try {
return redisTemplate.keys(keys);
}catch (Exception e){
e.printStackTrace();
return null;
}
}
/**
* 指定缓存失效时间
* @param key
* @param time 时间()
* @return
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key 获取过期时间
* @param key 不能为null
* @return 时间() 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判断key是否存在
* @param key
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
}
}
}
/**
* 普通缓存获取
* @param key
* @return
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
* @param key
* @param value
* @return true成功 false失败
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入, 不存在放入存在返回
* @param key
* @param value
* @return true成功 false失败
*/
public boolean setnx(String key, Object value) {
try {
redisTemplate.opsForValue().setIfAbsent(key,value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
* @param key
* @param value
* @param time 时间() time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间,不存在放入存在返回
* @param key
* @param value
* @param time 时间() time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean setnx(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 递增
* @param key
* @param delta 要增加几(大于0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
* @param key
* @param delta 要减少几(小于0)
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
/**
* HashGet
* @param key 不能为null
* @param item 不能为null
* @return
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
* @param key
* @return 对应的多个键值
*/
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
* @param key
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 并设置时间
* @param key
* @param map 对应多个键值
* @param time 时间()
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
* @param key
* @param item
* @param value
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
* @param key
* @param item
* @param value
* @param time 时间() 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除hash表中的值
* @param key 不能为null
* @param item 可以使多个 不能为null
*/
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否有该项的值
* @param key 不能为null
* @param item 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
* @param key
* @param item
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
* @param key
* @param item
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
/**
* 根据key获取Set中的所有值
* @param key
* @return
*/
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
* @param key
* @param value
* @return true 存在 false不存在
*/
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将数据放入set缓存
* @param key
* @param values 可以是多个
* @return 成功个数
*/
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 将set数据放入缓存
* @param key
* @param time 时间()
* @param values 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0){
expire(key, time);
}
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 获取set缓存的长度
* @param key
* @return
*/
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 移除值为value的
* @param key
* @param values 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// ===============================list=================================
/**
* 获取list缓存的内容
* @param key
* @param start 开始
* @param end 结束 0 -1代表所有值
* @return
*/
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取list缓存的长度
* @param key
* @return
*/
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 通过索引 获取list中的值
* @param key
* @param index 索引 index>=0时 0 表头1 第二个元素依次类推index<0时-1表尾-2倒数第二个元素依次类推
* @return
*/
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
* @param key
* @param value
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
* @param key
* @param value
* @param time 时间()
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0){
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
* @param key
* @param value
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
*
* @param key
* @param value
* @param time 时间()
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0){
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据索引修改list中的某条数据
* @param key
* @param index 索引
* @param value
* @return
*/
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N个值为value
* @param key
* @param count 移除多少个
* @param value
* @return 移除的个数
*/
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}

View File

@ -1,67 +0,0 @@
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
username: # Nacos 账号
password: # Nacos 密码
discovery: # 【配置中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
config: # 【注册中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
# Lock4j 配置项
lock4j:
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
--- #################### 监控相关配置 ####################
# Actuator 监控端点的配置项
management:
endpoints:
web:
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
spring:
redis:
host: 127.0.0.1 # 地址
port: 6379 # 端口
database: 0 # 数据库索引
# password: 123456 # 密码,建议生产环境开启
boot:
admin:
# Spring Boot Admin Client 客户端的相关配置
client:
instance:
service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
# 日志文件配置
logging:
level:
# 配置自己写的 MyBatis Mapper 打印日志
cn.iocoder.yudao.module.system.dal.mysql: debug
cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper: INFO # 配置 SmsChannelMapper 的日志级别为 info
org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿先禁用Spring Boot 3.X 存在部分错误的 WARN 提示
file:
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
remote:
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

View File

@ -1,68 +0,0 @@
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
username: # Nacos 账号
password: # Nacos 密码
discovery: # 【配置中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
config: # 【注册中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
# Lock4j 配置项
lock4j:
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
--- #################### 监控相关配置 ####################
# Actuator 监控端点的配置项
management:
endpoints:
web:
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
spring:
redis:
host: 127.0.0.1 # 地址
port: 6379 # 端口
database: 0 # 数据库索引
# password: 123456 # 密码,建议生产环境开启
boot:
admin:
# Spring Boot Admin Client 客户端的相关配置
client:
instance:
service-host-type: IP # 注册实例时,优先使用 IP [IP, HOST_NAME, CANONICAL_HOST_NAME]
# 日志文件配置
logging:
level:
# 配置自己写的 MyBatis Mapper 打印日志
cn.iocoder.yudao.module.system.dal.mysql: debug
cn.iocoder.yudao.module.system.dal.mysql.sms.SmsChannelMapper: INFO # 配置 SmsChannelMapper 的日志级别为 info
org.springframework.context.support.PostProcessorRegistrationDelegate: ERROR # TODO 芋艿先禁用Spring Boot 3.X 存在部分错误的 WARN 提示
file:
name: C:\system\install\log/${spring.application.name}.log
remote:
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

View File

@ -1,48 +0,0 @@
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
username: # Nacos 账号
password: # Nacos 密码
discovery: # 【配置中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
config: # 【注册中心】配置项
namespace: dev # 命名空间。这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
# Lock4j 配置项
lock4j:
acquire-timeout: 3000 # 获取分布式锁超时时间,默认为 3000 毫秒
expire: 30000 # 分布式锁的超时时间,默认为 30 毫秒
--- #################### 监控相关配置 ####################
# Actuator 监控端点的配置项
management:
endpoints:
web:
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
logging:
file:
name: D:/project/rcs/logs/${spring.application.name}.log
remote:
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

View File

@ -1,105 +0,0 @@
spring:
application:
name: remote-server
main:
allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。
allow-bean-definition-overriding: true # 允许 Bean 覆盖,例如说 Feign 等会存在重复定义的服务
profiles:
active: local
mvc:
pathmatch:
matching-strategy: ANT_PATH_MATCHER # 解决 SpringFox 与 SpringBoot 2.6.x 不兼容的问题,参见 SpringFoxHandlerProviderBeanPostProcessor 类
# Jackson 配置项
jackson:
serialization:
write-dates-as-timestamps: true # 设置 LocalDateTime 的格式,使用时间戳
write-date-timestamps-as-nanoseconds: false # 设置不使用 nanoseconds 的格式。例如说 1611460870.401,而是直接 1611460870401
write-durations-as-timestamps: true # 设置 Duration 的格式,使用时间戳
fail-on-empty-beans: false # 允许序列化无属性的 Bean
server:
port: 48084
logging:
file:
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径
springdoc:
api-docs:
enabled: true # 1. 是否开启 Swagger 接文档的元数据
path: /v3/api-docs
swagger-ui:
enabled: true # 2.1 是否开启 Swagger 文档的官方 UI 界面
path: /swagger-ui
default-flat-param-object: true # 参见 https://doc.xiaominfo.com/docs/faq/v4/knife4j-parameterobject-flat-param 文档
knife4j:
enable: true # 2.2 是否开启 Swagger 文档的 Knife4j UI 界面
setting:
language: zh_cn
yudao:
info:
version: 1.0.0
base-package: cn.iocoder.yudao.module.remote
web:
admin-ui:
url: http://dashboard.yudao.iocoder.cn # Admin 管理后台 UI 的地址
xss:
enable: false
exclude-urls: # 如下 url仅仅是为了演示去掉配置也没关系
- ${management.endpoints.web.base-path}/** # 不处理 Actuator 的请求
swagger:
title: 管理后台
description: 提供管理员管理的所有功能
version: ${yudao.info.version}
tenant: # 多租户相关配置项
enable: true
ignore-urls:
- /admin-api/system/tenant/get-id-by-name # 基于名字获取租户,不许带租户编号
- /admin-api/system/tenant/get-by-website # 基于域名获取租户,不许带租户编号
- /admin-api/system/captcha/get-image # 获取图片验证码,和租户无关
- /admin-api/system/captcha/get # 获取图片验证码,和租户无关
- /admin-api/system/captcha/check # 校验图片验证码,和租户无关
- /admin-api/system/sms/callback/* # 短信回调接口,无法带上租户编号
- /rpc-api/system/tenant/valid # 防止递归。避免调用 /rpc-api/system/tenant/valid 接口时,又去触发 /rpc-api/system/tenant/valid 去校验
- /rpc-api/system/tenant/id-list # 获得租户列表的时候,无需传递租户编号
- /rpc-api/system/oauth2/token/check # 访问令牌校验时,无需传递租户编号;主要解决上传文件的场景,前端不会传递 tenant-id
ignore-tables:
- system_tenant
- system_tenant_package
- system_dict_data
- system_dict_type
- system_error_code
- system_menu
- system_sms_channel
- system_sms_template
- system_sms_log
- system_sensitive_word
- system_oauth2_client
- system_mail_account
- system_mail_template
- system_mail_log
- system_notify_template
ignore-caches:
- user_role_ids
- permission_menu_ids
- oauth_client
- notify_template
- mail_account
- mail_template
- sms_template
sms-code: # 短信验证码相关的配置项
expire-times: 10m
send-frequency: 1m
send-maximum-quantity-per-day: 10
begin-code: 9999 # 这里配置 9999 的原因是,测试方便。
end-code: 9999 # 这里配置 9999 的原因是,测试方便。
debug: false

View File

@ -1,23 +0,0 @@
--- #################### 注册中心相关配置 ####################
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
namespace: dev # 命名空间。这里使用 dev 开发环境
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
--- #################### 配置中心相关配置 ####################
spring:
cloud:
nacos:
# Nacos Config 配置项,对应 NacosConfigProperties 配置属性类
config:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
namespace: dev # 命名空间 dev 的ID不能直接使用 dev 名称。创建命名空间的时候需要指定ID为 dev这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
name: ${spring.application.name} # 使用的 Nacos 配置集的 dataId默认为 spring.application.name
file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties

View File

@ -1,23 +0,0 @@
--- #################### 注册中心相关配置 ####################
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
namespace: dev # 命名空间。这里使用 dev 开发环境
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
--- #################### 配置中心相关配置 ####################
spring:
cloud:
nacos:
# Nacos Config 配置项,对应 NacosConfigProperties 配置属性类
config:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
namespace: dev # 命名空间 dev 的ID不能直接使用 dev 名称。创建命名空间的时候需要指定ID为 dev这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
name: ${spring.application.name} # 使用的 Nacos 配置集的 dataId默认为 spring.application.name
file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties

View File

@ -1,23 +0,0 @@
--- #################### 注册中心相关配置 ####################
spring:
cloud:
nacos:
server-addr: 127.0.0.1:8848
discovery:
namespace: prod # 命名空间。这里使用 dev 开发环境
metadata:
version: 1.0.0 # 服务实例的版本号,可用于灰度发布
--- #################### 配置中心相关配置 ####################
spring:
cloud:
nacos:
# Nacos Config 配置项,对应 NacosConfigProperties 配置属性类
config:
server-addr: 127.0.0.1:8848 # Nacos 服务器地址
namespace: prod # 命名空间 dev 的ID不能直接使用 dev 名称。创建命名空间的时候需要指定ID为 dev这里使用 dev 开发环境
group: DEFAULT_GROUP # 使用的 Nacos 配置分组,默认为 DEFAULT_GROUP
name: ${spring.application.name} # 使用的 Nacos 配置集的 dataId默认为 spring.application.name
file-extension: yaml # 使用的 Nacos 配置集的 dataId 的文件拓展名,同时也是 Nacos 配置集的配置格式,默认为 properties

View File

@ -1,15 +0,0 @@
spring:
application:
name: remote-server
profiles:
active: local #local
# active: prod
server:
port: 48084
# 日志文件配置。注意,如果 logging.file.name 不放在 bootstrap.yaml 配置文件,而是放在 application.yaml 中,会导致出现 LOG_FILE_IS_UNDEFINED 文件
logging:
file:
name: ${user.home}/logs/${spring.application.name}.log # 日志文件名,全路径

View File

@ -1,76 +0,0 @@
<configuration>
<!-- 引用 Spring Boot 的 logback 基础配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<!-- 变量 yudao.info.base-package基础业务包 -->
<springProperty scope="context" name="yudao.info.base-package" source="yudao.info.base-package"/>
<!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level级别从左显示 5 个字符宽度,%msg日志消息%n是换行符 -->
<property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} | %X{requestId} | %highlight(${LOG_LEVEL_PATTERN:-%5p} ${PID:- }) | %boldYellow(%thread [%tid]) %boldGreen(%-40.40logger{39}) | %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!-- 控制台 Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">     
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
</appender>
<!-- 文件 Appender -->
<!-- 参考 Spring Boot 的 file-appender.xml 编写 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
<!-- 日志文件名 -->
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 滚动后的日志文件名 -->
<fileNamePattern>${LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN:-${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz}</fileNamePattern>
<!-- 启动服务时,是否清理历史日志,一般不建议清理 -->
<cleanHistoryOnStart>${LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START:-false}</cleanHistoryOnStart>
<!-- 日志文件,到达多少容量,进行滚动 -->
<maxFileSize>${LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE:-10MB}</maxFileSize>
<!-- 日志文件的总大小0 表示不限制 -->
<totalSizeCap>${LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP:-0}</totalSizeCap>
<!-- 日志文件的保留天数 -->
<maxHistory>${LOGBACK_ROLLINGPOLICY_MAX_HISTORY:-30}</maxHistory>
</rollingPolicy>
</appender>
<!-- 异步写入日志,提升性能 -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志。默认的,如果队列的 80% 已满,则会丢弃 TRACT、DEBUG、INFO 级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能。默认值为 256 -->
<queueSize>256</queueSize>
<appender-ref ref="FILE"/>
</appender>
<!-- SkyWalking GRPC 日志收集实现日志中心。注意SkyWalking 8.4.0 版本开始支持 -->
<appender name="GRPC" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
<pattern>${PATTERN_DEFAULT}</pattern>
</layout>
</encoder>
</appender>
<!-- 本地环境 -->
<springProfile name="local">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="GRPC"/> <!-- 本地环境下,如果不想接入 SkyWalking 日志服务,可以注释掉本行 -->
<appender-ref ref="ASYNC"/> <!-- 本地环境下,如果不想打印日志,可以注释掉本行 -->
</root>
</springProfile>
<!-- 其它环境 -->
<springProfile name="dev,test,stage,prod,default">
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="ASYNC"/>
<appender-ref ref="GRPC"/>
</root>
</springProfile>
</configuration>

View File

@ -36,8 +36,4 @@ public interface PathApi {
@PostMapping(PREFIX + "/simulationRobotPose")
@Operation(summary = "仿真初始化点位信息")
void simulationRobotPoseRequest(@RequestParam("message") String message);
@PostMapping(PREFIX + "/graphMatchData")
@Operation(summary = "路网匹配实时数据")
void graphMatchData(@RequestParam("message") String message);
}

View File

@ -1,33 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.system.api.remote.dto.*;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 远遥任务相关")
public interface RemoteExceptionTaskApi {
String PREFIX = ApiConstants.PREFIX + "/remote";
@PostMapping(PREFIX + "/getExceptionTaskDetail")
@Operation(summary = "远遥查询异常的车辆")
PageResult<RemoteExceptionTaskDetailDTO> getExceptionTaskDetail(@RequestBody RemoteTaskQueryDTO remoteTaskQuery);
@PostMapping(PREFIX + "/getCarmeraByRobotNo")
@Operation(summary = "查摄像头信息")
CommonResult<List<RemoteRobotCameraDTO>> getCarmeraByRobotNo(@RequestParam("robotNo") String robotNo);
@PostMapping(PREFIX + "/remoteTransferTask")
@Operation(summary = "查摄像头信息")
CommonResult<Boolean> remoteTransferTask(@RequestBody RemoteTaskTransferDTO remoteTaskTransfer);
}

View File

@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote;
import cn.iocoder.yudao.module.system.api.remote.dto.LoginCheckDTO;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 远遥登录相关的服务调用")
public interface RemoteLoginApi {
String PREFIX = ApiConstants.PREFIX + "/remote";
@PostMapping(PREFIX + "/saveIpAndPort")
@Operation(summary = "保存IP和端口")
void saveIpAndPort(@RequestBody LoginCheckDTO loginCheckDTO);
@PostMapping(PREFIX + "/getIpAndPort")
@Operation(summary = "查询默认IP和端口")
LoginCheckDTO getIpAndPort(@RequestParam("ip") String ip);
}

View File

@ -1,69 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotStatusDTO;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotTransferDTO;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 远遥车辆相关")
public interface RemoteRobotApi {
String PREFIX = ApiConstants.PREFIX + "/remote";
@PostMapping(PREFIX + "/remoteGetAreaRobot")
@Operation(summary = "获取地图区域对应的机器人信息")
List<RemoteRobotDTO> remoteGetAreaRobot(@RequestParam(value = "mapId") Long mapId);
@PostMapping(PREFIX + "/remoteEmergencyStopOrRecovery")
@Operation(summary = "一键急停or一键恢复地图上所有AGV")
CommonResult<Boolean> remoteEmergencyStopOrRecovery(@RequestParam(value = "mapId") Long mapId, @RequestParam(value = "type") Integer type);
@PostMapping(PREFIX + "/getRemoteRobotStatus")
@Operation(summary = "获取机器人远遥模式/急停/协控状态")
RemoteRobotStatusDTO getRemoteRobotStatus(@RequestParam(value = "ip") String ip);
@PostMapping(PREFIX + "/robotStop")
@Operation(summary = "暂停机器人")
CommonResult<Boolean> robotStop(@RequestParam(value = "robotNo") String robotNo);
@PostMapping(PREFIX + "/recovery")
@Operation(summary = "恢复机器人")
CommonResult<Boolean> recovery(@RequestParam(value = "robotNo") String robotNo);
@PostMapping(PREFIX + "/robotChangeMode")
@Operation(summary = "切换模式")
CommonResult<RemoteRobotTransferDTO> robotChangeMode(@RequestParam(value = "remoteMode") Integer remoteMode,
@RequestParam(value = "ip") String ip,
@RequestParam(value = "robotNo") String robotNo,
@RequestParam(value = "remoteControllerPort") int remoteControllerPort,
@RequestParam(value = "remoteControllerIp") String remoteControllerIp);
@PostMapping(PREFIX + "/getRemotePositionMapList")
@Operation(summary = "远遥查询地图")
Object getRemotePositionMapList();
@PostMapping(PREFIX + "/remoteDisconnect")
@Operation(summary = "断开连接")
CommonResult<RemoteRobotTransferDTO> remoteDisconnect(@RequestParam(value = "remoteIp") String remoteIp);
@PostMapping(PREFIX + "/remoteTaskDone")
@Operation(summary = "任务完成/取货完成")
CommonResult<Boolean> remoteTaskDone(@RequestParam(value = "remoteIp") String remoteIp, @RequestParam(value = "mode") Integer mode);
@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);
}

View File

@ -1,26 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote;
import cn.iocoder.yudao.module.system.api.remote.dto.RemoteRobotMaxSpeedDTO;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "RPC 服务 - 远遥车辆相关速度")
public interface RemoteRobotMaxSpeedApi {
String PREFIX = ApiConstants.PREFIX + "/remote";
@PostMapping(PREFIX + "/getRobotMaxSpeedPage")
@Operation(summary = "获取远遥车辆速度")
List<RemoteRobotMaxSpeedDTO> getRobotMaxSpeedPage();
@PostMapping(PREFIX + "/updateRobotMaxSpeed")
@Operation(summary = "更新远遥车辆速度")
void updateRobotMaxSpeedPage(@RequestBody List<RemoteRobotMaxSpeedDTO> list);
}

View File

@ -1,23 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
@Data
public class LoginCheckDTO {
@Schema(description = "通讯地址")
@NotEmpty(message = "通讯地址不能为空")
@Size(max = 20, message = "通讯地址长度不符合要求")
private String systemIp;
@Schema(description = "通讯端口")
@NotEmpty(message = "端口不能为空")
@Size(max = 10, message = "端口长度不符合要求")
private String systemPort;
@Schema(description = "远遥IP")
private String remoteIp;
}

View File

@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class RemoteExceptionTaskDetailDTO {
@Schema(description = "任务主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26224")
private Long id;
@Schema(description = "车辆编号")
private String robotNo ;
@Schema(description = "图片附件RUL", example = "https://www.iocoder.cn")
private String url;
@Schema(description = "任务号")
private String taskNo;
@Schema(description = "异常信息")
private String warnMsg;
}

View File

@ -1,27 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class RemoteExceptionTaskListDTO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26224")
private Long id;
@Schema(description = "车辆编号")
private String robotNo ;
@Schema(description = "任务号")
private String taskNo;
@Schema(description = "取货库位编号")
private String fromLocationNo;
@Schema(description = "放货库位编号")
private String toLocationNo;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3前往放货、4放货中、5结束、6移动中、7:正在充电、8:取消、9:人工完成、10:异常)")
private Long taskStage;
}

View File

@ -1,23 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class RemoteRobotCameraDTO {
@Schema(description = "摄像头位置(0:上, 1:左, 2:右, 3:下, 4:后)")
private Integer cameraPosition;
@Schema(description = "摄像头IP--长度20")
private String cameraIp;
@Schema(description = "摄像头端口--长度10")
private String cameraPort;
@Schema(description = "摄像头账号--长度30", example = "24863")
private String cameraAccount;
@Schema(description = "摄像头密码--长度40")
private String cameraPassword;
}

View File

@ -1,21 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
public class RemoteRobotDTO {
@Schema(description = "远遥模式(0:自动模式, 1:手动模式, 2:自由模式)")
private Integer remoteMode = 0;
@Schema(description = "车辆数量")
private Integer robotQuantity = 0;
@Schema(description = "车辆明细")
private List<RemoteRobotDetailDTO> robotList;
}

View File

@ -1,26 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class RemoteRobotDetailDTO {
@Schema(description = "AGV编号")
private String robotNo;
@Schema(description = "上传图片附件", example = "https://www.iocoder.cn")
private String url;
@Schema(description = "任务模式0锁定、1正常", requiredMode = Schema.RequiredMode.REQUIRED)
private Integer robotTaskModel;
@Schema(description = "车辆状态(2任务中、3待命、4:充电中)")
private Integer robotStatus;
@Schema(description = "任务号")
private String taskNo;
@Schema(description = "车辆模式(0:自动模式, 1:手动模式, 2:自由模式)")
private Integer remoteMode = 0;
}

View File

@ -1,24 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class RemoteRobotMaxSpeedDTO {
@Schema(description = "速度表id")
private Long id;
@Schema(description = "仓库点位地图表id")
private Long positionMapId;
@Schema(description = "楼层")
private Integer floor;
@Schema(description = "区域")
private String area;
@Schema(description = "远遥最大速度, 最大5米每秒")
private String maxSpeed;
}

View File

@ -1,34 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class RemoteRobotStatusDTO {
@Schema(description = "AGV编号")
private String robotNo;
@Schema(description = "车辆是否暂停(0:已经暂停, 1:没暂停)")
private Integer isStop = 1;
@Schema(description = "远遥模式(0:自动模式, 1:手动模式, 2:自由模式)")
private Integer remoteMode = 0;
@Schema(description = "协控(0:关闭协控, 1:开启协控, 2:不显示协控)")
private Integer collaborativeControl = 2;
@Schema(description = "车辆任务状态(3待命 , 其他都是任务中)")
private Integer robotStatus = 2;
@Schema(description = "任务模式0锁定、1正常")
private Integer robotTaskModel;
@Schema(description = "是否可以点击: 异常处理(0:显示异常处理, 1:不显示异常处理)")
private Integer clickException = 1;
@Schema(description = "是否可以点击( 0: 显示取货完成按钮, 1:显示任务完成按钮 , 2: 不显示任务完成按钮)")
private Integer clickTaskDone = 2;
}

View File

@ -1,22 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RemoteRobotTransferDTO {
@Schema(description = "车辆IP")
private String robotIp;
@Schema(description = "车辆端口")
private Long robotPort;
@Schema(description = "AGV编号")
private String robotNo;
}

View File

@ -1,14 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote.dto;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class RemoteTaskDTO extends PageParam {
@Schema(description = "车辆编号")
private String robotNo ;
@Schema(description = "任务阶段(0:待执行、1前往取货、2取货中、3前往放货、4放货中、5结束、6移动中、7:正在充电、8:取消、9:人工完成、10:异常)")
private Long taskStage;
}

View File

@ -1,15 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote.dto;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class RemoteTaskQueryDTO extends PageParam {
@Schema(description = "车辆编号")
private String robotNo ;
@Schema(description = "任务号")
private String taskNo;
}

View File

@ -1,19 +0,0 @@
package cn.iocoder.yudao.module.system.api.remote.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
@Data
public class RemoteTaskTransferDTO implements Serializable {
@Schema(description = "任务ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "26224")
private Long id;
@Schema(description = "远遥模式(0:自动模式, 1:手动模式, 2:自由模式)")
private Integer remoteMode = 0;
@Schema(description = "远遥IP---前端不用传")
private String remoteIp;
}

View File

@ -11,7 +11,4 @@ public class FloorZoneDTO {
public String floor;
//地图所在区
public String area;
//线速度 float 单位m/s
public String linearSpeed;
}

Some files were not shown because too many files have changed in this diff Show More