新代码

This commit is contained in:
zhangyu 2025-09-22 10:42:01 +08:00
parent c420ff3bea
commit cabc747f2c
155 changed files with 2617 additions and 795 deletions

View File

@ -4,17 +4,17 @@ import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.domain.model.LoginUser;
import org.zxwl.common.core.exception.BusinessException;
import org.zxwl.common.core.exception.SystemErrorCode;
import org.zxwl.common.core.service.PermissionService;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
@ -38,56 +38,18 @@ public class AuthController {
private final HttpSession session;
private final UserInfoService userInfoService;
private final RoleInfoService roleInfoService;
private final PermissionService permissionService;
@PostMapping("/login")
@Log(module = ModuleType.USER, operateType = OperateType.LOGIN, operateExplain = "登录认证模块")
public Result<String> login(@RequestBody UserLogin userLogin) {
@Log(module = ModuleType.SYSTEM, operateType = OperateType.LOGIN, operateExplain = "登录认证")
public Result<String> login(@RequestBody @Validated UserLogin userLogin) {
UserInfo userInfo = userInfoService.login(userLogin);
if (userInfo != null) {
if (CharSequenceUtil.isEmpty(userLogin.getDevice())) {
return Result.failure("登录失败");
}
RoleInfo roleInfo = roleInfoService.getById(userInfo.getRoleId());
if (userLogin.getDevice().equalsIgnoreCase("pc")) {
if (!roleInfo.getRoleKey().equals("system")) {
return Result.failure("登录失败");
}
}
StpUtil.login(userInfo.getId());
StpUtil.login(userInfo.getId(), userLogin.getDevice());
LoginUser loginUser = BeanUtil.copyProperties(userInfo, LoginUser.class);
StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
log.info("token值{}", StpUtil.getTokenValue());
return Result.success("登录成功", StpUtil.getTokenValue());
}
return Result.failure("登录失败");
}
//车端应用登录
@PostMapping("/vehicle/login")
public Result<String> vehicleLogin(@RequestBody UserLogin userLogin) {
UserInfo userInfo = userInfoService.login(userLogin);
if (userInfo != null) {
if (CharSequenceUtil.isEmpty(userLogin.getDevice())) {
return Result.failure("登录失败");
}
RoleInfo roleInfo = roleInfoService.getById(userInfo.getRoleId());
if (userLogin.getDevice().equalsIgnoreCase("pc")) {
if (!roleInfo.getRoleKey().equals("system")) {
return Result.failure("登录失败");
}
}
StpUtil.login(userInfo.getId());
LoginUser loginUser = BeanUtil.copyProperties(userInfo, LoginUser.class);
StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
log.info("token值{}", StpUtil.getTokenValue());
return Result.success("登录成功", StpUtil.getTokenValue());
}
return Result.failure("登录失败");
}
@RequestMapping("/getCaptcha")
public void test(HttpServletResponse response) throws IOException {
@ -104,30 +66,27 @@ public class AuthController {
System.out.println("session 里的验证码:" + sessionCode);
String receivedCode = code.toLowerCase();
System.out.println("用户的验证码:" + receivedCode);
return !"".equals(sessionCode) && !"".equals(receivedCode) && sessionCode.equals(receivedCode) ?
return StrUtil.isBlank(sessionCode) && StrUtil.isBlank(receivedCode) && sessionCode.equals(receivedCode) ?
Result.success() : Result.failure(7777, "验证码错误");
}
@GetMapping("/user")
public Result<UserInfoVO> getUser() {
Object loginId = StpUtil.getLoginId();
if (loginId == null) {
throw new BusinessException(SystemErrorCode.USER_NOT_LOGIN);
}
LoginUser loginUser = (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY);
System.out.println("o = " + loginUser.getUserName());
Long userId = (Long) StpUtil.getLoginId();
UserInfo userInfo = userInfoService.getById((String) loginId);
UserInfo userInfo = userInfoService.getById(userId);
RoleInfo roleInfo = roleInfoService.getById(userInfo.getRoleId());
UserInfoVO userInfoVO = new UserInfoVO(userInfo);
userInfoVO.setRoleName(roleInfo.getRoleName());
userInfoVO.setMenuPermission(permissionService.getMenuPermission(userId));
userInfoVO.setRolePermission(permissionService.getRolePermission(userId));
return Result.success(userInfoVO);
}
@PostMapping("/logout")
@Log(module = ModuleType.SYSTEM, operateType = OperateType.LOGOUT, operateExplain = "登出账号")
public Result<Void> logout() {
log.info("[/sso/logout]");
// System.out.println("StpUtil.getLoginId() = " + StpUtil.getLoginId());
// 如果未登录则无需注销
if (!StpUtil.isLogin()) {
return Result.success();

View File

@ -100,12 +100,14 @@ spring:
timeout: 30 # 超时时间
keepalive: 60 # 保持连接
clearSession: true # 清除会话(设置为false,断开连接,重连后使用原来的会话 保留订阅的主题,能接收离线期间的消息)
topics:
- /zxwl/vehicle/+/info
- /zxwl/vehicle/+/gps
- /zxwl/vehicle/+/fault
- /zxwl/vehicle/+/task
- /zxwl/cockpit/+/heartbeat
topics: # 订阅主题
- /zxwl/vehicle/+/info # 清扫车信息上报
- /zxwl/vehicle/+/gps # 定位信息上报
- /zxwl/vehicle/+/fault # 故障信息上报
- /zxwl/vehicle/+/task # 清扫任务推送、任务停止
- /zxwl/vehicle/+/task/status # 清扫任务状态上报
- /zxwl/vehicle/+/ctrl # 驾驶舱远程控制、路径采集
- /zxwl/cockpit/+/heartbeat # 网关心跳
--- # redis配置
spring:

View File

@ -1,6 +0,0 @@
package org.zxwl.common.core.constant;
public class DefaultConstant {
public static final String NULL = "null";
public static final String EMPTY = "";
}

View File

@ -0,0 +1,15 @@
package org.zxwl.common.core.constant;
public interface SystemConstants {
/**
* 管理员角色 roleKey
*/
String ADMIN_ROLE_KEY = "admin";
/**
* 超级管理员ID
*/
Long SUPER_ADMIN_ID = 1L;
}

View File

@ -26,6 +26,11 @@ public class LoginUser {
*/
private String avatar;
/**
* 用户类型是否系统用户 0- 1-
*/
private Integer userType;
/**
* 用户性别 0 未知 1 2
*/

View File

@ -57,11 +57,6 @@ public enum SystemErrorCode {
DELETE_FAILURE_EXIST_BINDING_GATEWAY(11018, "操作失败,车辆存在绑定的网关"),
DELETE_FAILURE_EXIST_UNDO_RECORD(11019, "操作失败,存在未完成的调度记录"),
CLASSROOM_NUMBER_EXIST(12001, "该教室编号已被使用"),
DELETE_DAILY_INVALID(12002, "存在被绑定的作息,无法删除"),
DAILY_OCCUPY(12003, "作息时间存在冲突"),
CLASS_INFO_EXIST(12004, "班级已存在"),
FILE_CHECK_ERROR(20000, "文件校验异常"),
FILE_NOT_EXIST(20001, "文件不存在"),
FILE_EXTENSION_INVALID(20002, "非法的文件扩展名"),
@ -74,7 +69,6 @@ public enum SystemErrorCode {
VEHICLE_DISPATCH_DUPLICATE(30002, "存在重复的调度记录"),
VEHICLE_DISPATCH_STARTING(30003, "当前驾驶舱正在执行任务,请先结束当前任务"),
FTP_CLIENT_ERROR(15000, "ftp客户端异常"),
FTP_FILE_WRITE_ERROR(15001, "ftp文件写入异常"),
FTP_FILE_NOT_FOUND(15002, "当前文件不存在"),
@ -83,14 +77,15 @@ public enum SystemErrorCode {
VEHICLE_OFFLINE(15005, "当前车辆不在线"),
CAMERA_URL_NOT_FOUND(15006, "未配置摄像头地址"),
VEHICLE_NOT_FOUND(16000, "车辆不存在"),
PICKUP_CODE_NOT_FOUND(16001, "取货码无效或已过期"),
TASK_NOT_EXIST(50001, "任务不存在"),
TASK_EXECUTING(50002, "存在进行中的任务"),
TASK_NAME_EXIST(50003, "任务名称已存在"),
VEHICLE_NOT_EXIST(50013, "车辆不存在"),
VEHICLE_STATUS_EXIST(50014, "车辆存在启用状态"),
ROUTE_STATUS_EXIST(50015, "路径信息存在已启用状态"),
ROUTE_TASK_EXIST(50016, "该路径所属的任务正在进行中"),
COCKPIT_STATUS_EXIST(50017, "驾驶舱存在已启用状态"),
;
private final int code;

View File

@ -0,0 +1,93 @@
package org.zxwl.common.core.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import io.github.linpeilie.Converter;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Map;
/**
* Mapstruct 工具类
* <p>参考文档<a href="https://mapstruct.plus/introduction/quick-start.html">mapstruct-plus</a></p>
*
*
* @author Michelle.Chung
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class MapstructUtil {
private final static Converter CONVERTER = SpringUtil.getBean(Converter.class);
/**
* T 类型对象转换为 desc 类型的对象并返回
*
* @param source 数据来源实体
* @param desc 描述对象 转换后的对象
* @return desc
*/
public static <T, V> V convert(T source, Class<V> desc) {
if (ObjectUtil.isNull(source)) {
return null;
}
if (ObjectUtil.isNull(desc)) {
return null;
}
return CONVERTER.convert(source, desc);
}
/**
* T 类型对象按照配置的映射字段规则 desc 类型的对象赋值并返回 desc 对象
*
* @param source 数据来源实体
* @param desc 转换后的对象
* @return desc
*/
public static <T, V> V convert(T source, V desc) {
if (ObjectUtil.isNull(source)) {
return null;
}
if (ObjectUtil.isNull(desc)) {
return null;
}
return CONVERTER.convert(source, desc);
}
/**
* T 类型的集合转换为 desc 类型的集合并返回
*
* @param sourceList 数据来源实体列表
* @param desc 描述对象 转换后的对象
* @return desc
*/
public static <T, V> List<V> convert(List<T> sourceList, Class<V> desc) {
if (ObjectUtil.isNull(sourceList)) {
return null;
}
if (CollUtil.isEmpty(sourceList)) {
return CollUtil.newArrayList();
}
return CONVERTER.convert(sourceList, desc);
}
/**
* Map 转换为 beanClass 类型的集合并返回
*
* @param map 数据来源
* @param beanClass bean类
* @return bean对象
*/
public static <T> T convert(Map<String, Object> map, Class<T> beanClass) {
if (MapUtil.isEmpty(map)) {
return null;
}
if (ObjectUtil.isNull(beanClass)) {
return null;
}
return CONVERTER.convert(map, beanClass);
}
}

View File

@ -15,7 +15,6 @@ import org.zxwl.common.core.utils.IpUtils;
import org.zxwl.common.core.utils.SpringUtil;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.event.OperLogEvent;
import org.zxwl.common.satoken.utils.LoginHelper;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
@ -85,18 +84,19 @@ public class LogAspect {
systemLog.setOperateExplain(log.operateExplain());
}
}
String ipAddr = IpUtils.getIpAddr(request);
String className = joinPoint.getTarget().getClass().getName();
String methodName = method.getName();
systemLog.setClassMethod(className + "." + methodName + "()");
systemLog.setClassMethod(className + "." + methodName + "()");
systemLog.setRequestUrl(request.getRequestURL().toString());
String ipAddr = IpUtils.getIpAddr(request);
systemLog.setOperator(LoginHelper.getRealName());
// TODO 暂时测试
//systemLog.setOperator(LoginHelper.getRealName());
systemLog.setOperator("admin");
systemLog.setRemoteAddress(ipAddr);
systemLog.setCreated(LocalDateTime.now());
// 发布事件保存数据库
SpringUtil.context().publishEvent(systemLog);
}

View File

@ -7,23 +7,44 @@ public enum ModuleType {
*/
OTHER,
/**
* 控制模块
*/
CONTROL,
/**
* 系统模块
*/
SYSTEM,
/**
* 用户模块
* 清洁车模块
*/
USER,
VEHICLE,
/**
* 角色模块
* 驾驶舱模块
*/
ROLE;
COCKPIT,
/**
* 任务模块
*/
TASK,
/**
* 安全员模块
*/
SAFETY,
/**
* 路径模块
*/
ROUTE,
/**
* 远控模块
*/
CONTROL,
/**
* 报修模块
*/
REPAIR
}

View File

@ -17,11 +17,6 @@ public enum OperateType {
*/
LOGOUT,
/**
* 查询
*/
SEARCH,
/**
* 新增
*/
@ -50,5 +45,5 @@ public enum OperateType {
/**
* 命令
*/
COMMAND;
COMMAND,
}

View File

@ -41,10 +41,12 @@ public class MqttMessageReceiver implements MessageHandler {
if (Boolean.TRUE.equals(retained)) {
return;
}
Integer qos = (Integer) headers.get(MqttHeaders.RECEIVED_QOS);
// 获取消息体
String payload = (String) message.getPayload();
log.info("MQTT获取到的消息-topic{}, qos: {}, payload: {}", topic, qos, payload);
String payload = message.getPayload().toString();
log.info("\n--------------------START-------------------\n" +
"接收到订阅消息:\ntopic:" + topic + "\nmessage:" + payload +
"\n---------------------END--------------------");
// 去掉第一个字符/
String replace = topic.replaceFirst("^/", "").replace('/', '.');
// 根据主题分别进行消息处理

View File

@ -116,9 +116,9 @@ public class MinioUtil {
return "/" + bucketName + "/" + objectName;
}
public void download(String fileName, String bucketName, HttpServletResponse res) {
public void download(String fileName, String url, String bucketName, HttpServletResponse res) {
GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(bucketName)
.object(fileName).build();
.object(url).build();
try (GetObjectResponse response = minioClient.getObject(objectArgs)) {
byte[] buf = new byte[1024];
int len;

View File

@ -3,13 +3,18 @@ package org.zxwl.common.utils;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
@RequiredArgsConstructor
public class RedisUtil {
@ -29,7 +34,7 @@ public class RedisUtil {
try {
return Optional.ofNullable(redisTemplate.opsForValue().get(key));
} catch (Exception e) {
e.printStackTrace();
log.error("Error getting value: {}", e.getMessage(), e);
return Optional.empty();
}
}
@ -38,7 +43,7 @@ public class RedisUtil {
try {
redisTemplate.opsForValue().set(key, value);
} catch (Exception e) {
e.printStackTrace();
log.error("Error putting value: {}", e.getMessage(), e);
}
}
@ -46,16 +51,16 @@ public class RedisUtil {
try {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
log.error("Error putting value and expire: {}", e.getMessage(), e);
}
}
public static Boolean exist(String key) {
System.out.println("key = " + key);
try {
return redisTemplate.hasKey(key);
return Objects.equals(redisTemplate.hasKey(key), Boolean.TRUE);
} catch (Exception e) {
e.printStackTrace();
log.error("Error hasKey: {}", e.getMessage(), e);
return false;
}
}
@ -65,7 +70,7 @@ public class RedisUtil {
redisTemplate.delete(key);
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("Error delete key: {}", e.getMessage(), e);
return false;
}
}
@ -74,7 +79,7 @@ public class RedisUtil {
try {
return redisTemplate.keys(key);
} catch (Exception e) {
e.printStackTrace();
log.error("Error getting keys: {}", e.getMessage(), e);
return null;
}
}
@ -82,12 +87,9 @@ public class RedisUtil {
public static boolean setIfAbsent(String key, Object value) {
try {
Boolean bool = redisTemplate.opsForValue().setIfAbsent(key, value);
if (bool != null) {
return bool;
}
return false;
return Objects.equals(bool, Boolean.TRUE);
} catch (Exception e) {
e.printStackTrace();
log.error("Error setIfAbsent value: {}", e.getMessage(), e);
return false;
}
}
@ -96,7 +98,7 @@ public class RedisUtil {
try {
return Optional.ofNullable(redisTemplate.opsForHash().get(key, hashKey));
} catch (Exception e) {
e.printStackTrace();
log.error("Error getting hashValue: {}", e.getMessage(), e);
return Optional.empty();
}
}
@ -105,7 +107,7 @@ public class RedisUtil {
try {
return redisTemplate.opsForHash().entries(key);
} catch (Exception e) {
e.printStackTrace();
log.error("Error getting all hashMap: {}", e.getMessage(), e);
return new HashMap<>();
}
}
@ -114,16 +116,33 @@ public class RedisUtil {
try {
return redisTemplate.opsForHash().values(key);
} catch (Exception e) {
e.printStackTrace();
log.error("Error getting all hash values: {}", e.getMessage(), e);
return new ArrayList<>();
}
}
public static void putHashAll(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
} catch (Exception e) {
log.error("Error putting hashMap: {}", e.getMessage(), e);
}
}
public static void putHashAll(String key, Map<String, Object> map, long time, TimeUnit timeUnit) {
try {
redisTemplate.opsForHash().putAll(key, map);
redisTemplate.expire(key, time, timeUnit);
} catch (Exception e) {
log.error("Error putting hashMap: {}", e.getMessage(), e);
}
}
public static void putHashValue(String key, String hashKey, Object value) {
try {
redisTemplate.opsForHash().put(key, hashKey, value);
} catch (Exception e) {
e.printStackTrace();
log.error("Error putting hash key value: {}", e.getMessage(), e);
}
}
@ -132,7 +151,7 @@ public class RedisUtil {
redisTemplate.opsForHash().delete(key, hashKey);
return true;
} catch (Exception e) {
e.printStackTrace();
log.error("Error delete hash key Value: {}", e.getMessage(), e);
return false;
}
}
@ -141,7 +160,7 @@ public class RedisUtil {
try {
return redisTemplate.opsForHash().entries(key);
} catch (Exception e) {
e.printStackTrace();
log.error("Error delete hash entries: {}", e.getMessage(), e);
return MapUtil.empty();
}
}
@ -150,7 +169,7 @@ public class RedisUtil {
try {
return redisTemplate.opsForHash().values(key);
} catch (Exception e) {
e.printStackTrace();
log.error("Error getting hash values: {}", e.getMessage(), e);
return ListUtil.empty();
}
}
@ -159,7 +178,7 @@ public class RedisUtil {
try {
return redisTemplate.opsForHash().hasKey(key, hashKey);
} catch (Exception e) {
e.printStackTrace();
log.error("Error boolean hash key: {}", e.getMessage(), e);
return false;
}
}
@ -172,8 +191,8 @@ public class RedisUtil {
return redisTemplate.opsForList().range(key, 0, -1);
}
public static boolean addZSet(String key, Object value, double score) {
return Boolean.TRUE.equals(redisTemplate.opsForZSet().add(key, value, score));
public static void addZSet(String key, Object value, double score) {
redisTemplate.opsForZSet().add(key, value, score);
}
public static long getZSetSize(String key) {
@ -185,7 +204,32 @@ public class RedisUtil {
return redisTemplate.opsForZSet().range(key, start, end);
}
public static Long removeRangeByScore(String key, long min, long max) {
return redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
public static void removeRangeByScore(String key, long min, long max) {
redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
}
/**
* 统计指定前缀的 key 数量
*
* @param keyPrefix key 前缀 "user:profile:"
* @return 未过期的 key 数量
*/
public static Long countKeysByPrefix(String keyPrefix) {
return redisTemplate.execute((RedisCallback<Long>) connection -> {
long count = 0;
ScanOptions options = ScanOptions.scanOptions()
.match(keyPrefix + "*")
.count(1000)
.build();
try (Cursor<byte[]> cursor = connection.scan(options)) {
while (cursor.hasNext()) {
cursor.next();
count++;
}
} catch (Exception e) {
log.error("统计前缀为{}的key数量时发生异常", keyPrefix, e);
}
return count;
});
}
}

View File

@ -1,12 +1,12 @@
package org.zxwl.common.satoken.utils;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.context.model.SaStorage;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.zxwl.common.core.constant.SystemConstants;
import org.zxwl.common.core.domain.model.LoginUser;
/**
@ -20,20 +20,6 @@ public class LoginHelper {
public static final String LOGIN_USER_KEY = "loginUser";
public static final String USER_KEY = "userId";
/**
* 登录系统 基于 设备类型
* 针对相同用户体系不同设备
*
* @param loginUser 登录用户信息
*/
public static void loginByDevice(LoginUser loginUser) {
SaStorage storage = SaHolder.getStorage();
storage.set(LOGIN_USER_KEY, loginUser);
storage.set(USER_KEY, loginUser.getId());
StpUtil.login(loginUser.getId());
StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);
}
/**
* 获取用户(多级缓存)
*/
@ -86,18 +72,35 @@ public class LoginHelper {
}
/**
* 是否为管理员
* 是否为超级管理员
*
* @param userId 用户ID
* @return 结果
*/
public static boolean isAdmin(Long userId) {
// return UserConstants.ADMIN_ID.equals(userId);
public static boolean isSuperAdmin(Long userId) {
return SystemConstants.SUPER_ADMIN_ID.equals(userId);
}
/**
* 是否为超级管理员
*
* @return 结果
*/
public static boolean isSuperAdmin() {
return isSuperAdmin(getUserId());
}
/**
* 检查当前用户是否已登录
*
* @return 结果
*/
public static boolean isLogin() {
try {
return getLoginUser() != null;
} catch (Exception e) {
return false;
}
public static boolean isAdmin() {
return isAdmin(getUserId());
}
}

View File

@ -19,5 +19,6 @@ public class ScheduleConfig {
public void checkCockpitStatus() {
long threshold = Instant.now().minus(30, ChronoUnit.SECONDS).getEpochSecond();
RedisUtil.removeRangeByScore(RedisKeyConst.COCKPIT_ONLINE_KEY, 0, threshold);
}
}

View File

@ -3,7 +3,23 @@ package org.zxwl.sweeper.constant;
public interface KafkaTopicConst {
String GATEWAY_HEARTBEAT_TOPIC = "^dcpcmcc\\.v1\\.vehmedia\\.[a-zA-Z0-9_]+\\.heartbeat.up$"; //网关的心跳
String GATEWAY_PUSH_VIDEO_TOPIC = "adcpcmcc.v1.vehmedia.*.video.down"; //网关的视频拉流
String GATEWAY_SAVE_VIDEO_TOPIC = "adcpcmcc.v1.vehmedia.*.video.save.down"; //网关的视频存储
String VEHICLE_INFO = "zxwl.vehicle.*.info";
String VEHICLE_FAULT = "zxwl.vehicle.*.fault";
String VEHICLE_GPS = "zxwl.vehicle.*.gps";
String VEHICLE_CTRL = "zxwl.vehicle.*.ctrl";
String VEHICLE_TASK = "zxwl.vehicle.*.task";
String VEHICLE_TASK_STATUS = "zxwl.vehicle.*.task.status";
String COCKPIT_HEARTBEAT = "zxwl.cockpit.*.heartbeat";
}

View File

@ -1,34 +1,12 @@
package org.zxwl.sweeper.constant;
public interface MqttTopicConst {
static String generateVehicleCtrlTopic(String vid) { //控制命令主题
return "/zxwl/vehicle/" + vid + "/ctrl";
static String VehicleCtrl(String vid) {
return "/zxwl/vehicle/" + vid + "/ctrl"; //车辆控制
}
// String CTRL_COMMAND_TOPIC = "/ntvu/vehicle/ctrl/+"; //控制命令主题的前缀
//
// String INFO_COMMAND_PREFIX = "/ntvu/vehicle/info/"; //车辆信息上报主题的前缀
// String INFO_COMMAND_TOPIC = "/ntvu/vehicle/info/+"; //车辆信息上报主题的前缀
//
// String WARNING_COMMAND_PREFIX = "/ntvu/vehicle/warning/"; //车辆状态上报主题的前缀
// String WARNING_COMMAND_TOPIC = "/ntvu/vehicle/warning/+"; //车辆状态上报主题的前缀
//
// String GATEWAY_HEARTBEAT_TOPIC = "adcpcmcc/v1/vehmedia/+/heartbeat/up"; //网关的心跳
// String GATEWAY_PUSH_VIDEO_TOPIC = "adcpcmcc/v1/vehmedia/+/video/down"; //网关的视频拉流
// String GATEWAY_SAVE_VIDEO_TOPIC = "adcpcmcc/v1/vehmedia/+/video/save/down"; //网关的视频存储
//网关推流主题
static String getPushVideoTopic(String vid) {
return "adcpcmcc/v1/vehmedia/" + vid + "/video/down";
}
//网关保存视频
static String getVideoSaveDownTopic(String vid) {
return "adcpcmcc/v1/vehmedia/" + vid + "/video/save/down";
}
//网关心跳
static String getHeartbeatTopic(String vid) {
return "adcpcmcc/v1/vehmedia/" + vid + "/heartbeat/up";
static String TaskCtrl(String vid) {
return "/zxwl/vehicle/" + vid + "/task"; //任务控制
}
}

View File

@ -8,16 +8,23 @@ public interface RedisKeyConst {
String GATEWAY_INFO_IP = "ZXWL:GATEWAY:INFO:IP"; //记录网关IP信息
String GATEWAY_INFO_URL = "ZXWL:GATEWAY:INFO:URL"; //记录网关摄像头地址信息
// vehicle车俩
String VEHICLE_CTRL_RESPONSE = "ZXWL:VEHICLE:CTRL:RESPONSE:"; //车辆控制响应
String TASK_RESPONSE = "ZXWL:VEHICLE:TASK:RESPONSE:"; //任务响应
String VEHICLE_STATUS = "ZXWL:VEHICLE:ONLINE:"; //车辆在线状态
String VEHICLE_FAULT_STATUS = "ZXWL:VEHICLE:FAULT:"; //车辆故障状态
String VEHICLE_POWER = "ZXWL:VEHICLE:POWER:"; //车辆电量
String VEHICLE_STATUS_INFO = "ZXWL:VEHICLE:STATUS:INFO:"; //车俩状态
// route路径
String ROUTE_KEY_PREFIX = "routeName:";
String DEVICE_STATUS_KEY_PREFIX = "ZXWL:DEVICE_STATUS:";
// cockpit
// task任务
String TASK_RESPONSE = "ZXWL:VEHICLE:TASK:RESPONSE:"; //任务响应
// cockpit驾驶舱
String COCKPIT_ONLINE_PREFIX = "ZXWL:COCKPIT:ONLINE:";
String COCKPIT_ONLINE_KEY = "ZXWL:COCKPIT:ONLINE";
String DEVICE_STATUS_KEY_PREFIX = "ZXWL:DEVICE_STATUS:";
}

View File

@ -1,24 +0,0 @@
package org.zxwl.sweeper.constant;
public interface TopicNameConst {
static String TrainBoxIMU(String deviceId) {
return "/zxwl/training_box/" + deviceId + "/imu_setting"; //车辆信息上报
}
static String TrainBoxRTK(String deviceId) {
return "/zxwl/training_box/" + deviceId + "/rtk_setting"; //车辆信息上报
}
static String VehicleCtrl(String deviceId) {
return "/zxwl/vehicle/" + deviceId + "/ctrl"; //车辆控制
}
static String TaskCtrl(String vid) {
return "/zxwl/vehicle/" + vid + "/task"; //任务控制
}
static String AdasFunctionCtrl(String deviceId) {
return "/zxwl/adas/" + deviceId + "/function"; //adas功能开关控制
}
}

View File

@ -8,6 +8,9 @@ import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.utils.ValidatorUtil;
import org.zxwl.common.core.validate.UpdateGroup;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.model.cockpitInfo.CockpitDropVO;
import org.zxwl.sweeper.model.cockpitInfo.CockpitInfoDTO;
@ -48,37 +51,36 @@ public class CockpitInfoController extends BaseController {
}
@PostMapping
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.INSERT, operateExplain = "驾驶舱新增")
//@SaCheckPermission("cockpit:info:add")
@Log(module = ModuleType.COCKPIT, operateType = OperateType.INSERT, operateExplain = "驾驶舱信息新增")
public Result<Void> add(@RequestBody @Validated CockpitInfoDTO dto) {
return toResult(cockpitInfoService.add(dto));
}
@PutMapping
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.UPDATE, operateExplain = "驾驶舱修改")
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class,
Default.class}) CockpitInfoDTO dto) {
//@SaCheckPermission("cockpit:info:update")
@Log(module = ModuleType.COCKPIT, operateType = OperateType.UPDATE, operateExplain = "驾驶舱信息修改")
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class, Default.class}) CockpitInfoDTO dto) {
return toResult(cockpitInfoService.update(dto));
}
@DeleteMapping("{ids}")
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.DELETE, operateExplain = "驾驶舱删除")
//@SaCheckPermission("cockpit:info:delete")
@Log(module = ModuleType.COCKPIT, operateType = OperateType.DELETE, operateExplain = "驾驶舱信息删除")
public Result<Void> delete(@PathVariable("ids") List<Long> ids) {
return toResult(cockpitInfoService.delete(ValidatorUtil.checkIds(ids)));
}
@PutMapping("enable")
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.OTHER, operateExplain = "驾驶舱启用")
//@SaCheckPermission("cockpit:info:enable")
@Log(module = ModuleType.COCKPIT, operateType = OperateType.OTHER, operateExplain = "驾驶舱启用")
public Result<Void> enable(@RequestParam Long id) {
return toResult(cockpitInfoService.enable(id));
}
@PutMapping("disable")
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.OTHER, operateExplain = "驾驶舱停用")
//@SaCheckPermission("cockpit:info:disable")
@Log(module = ModuleType.COCKPIT, operateType = OperateType.OTHER, operateExplain = "驾驶舱停用")
public Result<Void> disable(@RequestParam Long id) {
return toResult(cockpitInfoService.disable(id));
}

View File

@ -9,6 +9,9 @@ import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.utils.ValidatorUtil;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.model.dispatchRecord.DispatchRecordExcelQuery;
import org.zxwl.sweeper.model.dispatchRecord.DispatchRecordQuery;
@ -44,15 +47,15 @@ public class DispatchRecordController extends BaseController {
}
@DeleteMapping("{ids}")
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.DELETE, operateExplain = "调度记录删除")
//@SaCheckPermission("cockpit:dispatch:delete")
@Log(module = ModuleType.COCKPIT, operateType = OperateType.DELETE, operateExplain = "远程调度记录删除")
public Result<Void> delete(@PathVariable("ids") List<Long> ids) {
return toResult(dispatchRecordService.delete(ValidatorUtil.checkIds(ids)));
}
@PostMapping("export")
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.EXPORT, operateExplain = "调度记录导出")
//@SaCheckPermission("cockpit:dispatch:export")
@Log(module = ModuleType.COCKPIT, operateType = OperateType.EXPORT, operateExplain = "远程调度记录导出")
public void downloadExcel(@RequestBody DispatchRecordExcelQuery query, HttpServletResponse response) {
dispatchRecordService.downloadExcel(query, response);
}

View File

@ -22,16 +22,32 @@ public class DpHomeController {
private final DpHomeService dpService;
/**
* 驾驶舱状态列表
*
* @param query 查询
* @return Result
*/
@GetMapping("/listCockpitStatus")
public Result<Page<CockpitStatusInfoVO>> listDevice(CockpitSimpleInfoQuery query) {
return Result.success(dpService.listCockpitStatus(query));
}
/**
* 车辆状态列表
* @param query 查询
* @return Result
*/
@GetMapping("/listVehicleStatus")
public Result<Page<VehicleStatusInfoVO>> listDevice(VehicleSimpleInfoQuery query) {
return Result.success(dpService.listVehicleStatus(query));
}
/**
* 远控记录列表
*
* @return Result
*/
@GetMapping("/listDispatchRecord")
public Result<List<DispatchRecordVO>> listDispatchRecord() {
return Result.success(dpService.listDispatchRecord());

View File

@ -7,6 +7,9 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.validate.UpdateGroup;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.model.electricFence.ElectricFenceDTO;
import org.zxwl.sweeper.model.electricFence.ElectricFenceQuery;
@ -36,17 +39,22 @@ public class ElectricFenceController extends BaseController {
}
@PostMapping
//@SaCheckPermission("electric:info:add")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.INSERT, operateExplain = "围栏信息新增")
public Result<Void> add(@RequestBody @Validated ElectricFenceDTO electricFenceDTO) {
return toResult(electricFenceService.add(electricFenceDTO));
}
@PutMapping
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class,
Default.class}) ElectricFenceDTO electricFenceDTO) {
//@SaCheckPermission("electric:info:update")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.UPDATE, operateExplain = "围栏信息修改")
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class, Default.class}) ElectricFenceDTO electricFenceDTO) {
return toResult(electricFenceService.update(electricFenceDTO));
}
@DeleteMapping("{ids}")
//@SaCheckPermission("electric:info:delete")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.DELETE, operateExplain = "围栏信息删除")
public Result<Void> delete(@PathVariable("ids") List<Long> ids) {
return toResult(electricFenceService.delete(ids));
}

View File

@ -0,0 +1,93 @@
package org.zxwl.sweeper.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.validation.groups.Default;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.validate.UpdateGroup;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.enums.RepairStatusEnum;
import org.zxwl.sweeper.model.faultRepair.*;
import org.zxwl.sweeper.service.FaultRepairService;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author zy
* @since 2025-09-19
*/
@RestController
@RequestMapping("/fault/repair")
@RequiredArgsConstructor
public class FaultRepairController extends BaseController {
private final FaultRepairService faultRepairService;
@GetMapping
public Result<Page<FaultRepairVo>> queryPage(FaultRepairQuery query) {
return Result.success(faultRepairService.queryPage(query));
}
@GetMapping
public Result<FaultRepairDataVo> data() {
return Result.success(faultRepairService.data());
}
@PostMapping
//@SaCheckPermission("fault:repair:add")
@Log(module = ModuleType.REPAIR, operateType = OperateType.INSERT, operateExplain = "故障报修新增")
public Result<Void> add(@RequestBody @Validated FaultRepairDTO faultRepairDTO) {
return toResult(faultRepairService.add(faultRepairDTO));
}
@PutMapping
//@SaCheckPermission("fault:repair:update")
@Log(module = ModuleType.REPAIR, operateType = OperateType.UPDATE, operateExplain = "故障报修修改")
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class, Default.class}) FaultRepairDTO faultRepairDTO) {
return toResult(faultRepairService.edit(faultRepairDTO));
}
@DeleteMapping("{ids}")
//@SaCheckPermission("fault:repair:delete")
@Log(module = ModuleType.REPAIR, operateType = OperateType.DELETE, operateExplain = "故障报修删除")
public Result<Void> delete(@PathVariable("ids") List<Long> ids) {
return toResult(faultRepairService.removeByIds(ids));
}
@PostMapping("/allocate")
//@SaCheckPermission("fault:repair:allocate")
@Log(module = ModuleType.REPAIR, operateType = OperateType.OTHER, operateExplain = "指派给维修人员")
public Result<Void> allocate(@RequestBody FaultRepairAllocateDTO faultRepairAllocateDTO) {
return toResult(faultRepairService.assign(faultRepairAllocateDTO));
}
@PostMapping("/complete/{id}")
//@SaCheckPermission("fault:repair:complete")
@Log(module = ModuleType.REPAIR, operateType = OperateType.OTHER, operateExplain = "维修人员完成报修单")
public Result<Void> complete(@PathVariable("id") Long id) {
return toResult(faultRepairService.updateByStatus(id, RepairStatusEnum.SOLVE.getValue()));
}
@PostMapping("/close/{id}")
//@SaCheckPermission("fault:repair:close")
@Log(module = ModuleType.REPAIR, operateType = OperateType.OTHER, operateExplain = "维修人员关闭报修单")
public Result<Void> close(@PathVariable("id") Long id) {
return toResult(faultRepairService.updateByStatus(id, RepairStatusEnum.CLOSE.getValue()));
}
@PostMapping("/cancel/{id}")
//@SaCheckPermission("fault:repair:cancel")
@Log(module = ModuleType.REPAIR, operateType = OperateType.OTHER, operateExplain = "维修人员取消报修单")
public Result<Void> cancel(@PathVariable("id") Long id) {
return toResult(faultRepairService.updateByStatus(id, RepairStatusEnum.CANCEL.getValue()));
}
}

View File

@ -8,6 +8,9 @@ import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.utils.ValidatorUtil;
import org.zxwl.common.core.validate.UpdateGroup;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.model.gatewayInfo.GatewayInfoDTO;
import org.zxwl.sweeper.model.gatewayInfo.GatewayInfoQuery;
@ -37,32 +40,30 @@ public class GatewayInfoController extends BaseController {
}
@PostMapping
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.INSERT, operateExplain = "网关信息新增")
//@SaCheckPermission("gateway:info:add")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.INSERT, operateExplain = "网关信息新增")
public Result<Void> add(@RequestBody @Validated GatewayInfoDTO dto) {
return toResult(gatewayInfoService.add(dto));
}
@PutMapping
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.UPDATE, operateExplain = "网关信息修改")
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class,
Default.class}) GatewayInfoDTO dto) {
//@SaCheckPermission("gateway:info:update")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.UPDATE, operateExplain = "网关信息修改")
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class, Default.class}) GatewayInfoDTO dto) {
return toResult(gatewayInfoService.update(dto));
}
@DeleteMapping("{ids}")
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.DELETE, operateExplain = "网关信息删除")
//@SaCheckPermission("gateway:info:delete")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.DELETE, operateExplain = "网关信息删除")
public Result<Void> delete(@PathVariable("ids") List<Long> ids) {
return toResult(gatewayInfoService.delete(ValidatorUtil.checkIds(ids)));
}
@PutMapping("binding")
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.OTHER, operateExplain = "网关设备绑定")
public Result<Void> bindVehicle(@RequestParam("id") Long id,
@RequestParam("vid") String vid) {
//@SaCheckPermission("gateway:info:bind")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.OTHER, operateExplain = "网关设备绑定")
public Result<Void> bindVehicle(@RequestParam("id") Long id, @RequestParam("vid") String vid) {
return toResult(gatewayInfoService.bindVehicle(id, vid));
}

View File

@ -1,37 +0,0 @@
package org.zxwl.sweeper.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.zxwl.common.core.domain.Result;
import org.zxwl.sweeper.model.app.ctrl.CtrlCommand;
import org.zxwl.sweeper.service.CtrlCommandService;
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/ctrl")
public class RemoteController {
private final CtrlCommandService ctrlCommandService;
// private void sendCommand(String id, String command, String value) {
// CtrlCommand ctrlCommand = new CtrlCommand(command, value);
// String jsonStr = JSONUtil.toJsonStr(ctrlCommand);
// log.info("发送命令 ==> {}", jsonStr);
// mqttGateway.sendToMqtt(getTopicById(id), jsonStr);
// }
@PostMapping
// @Log(module = ModuleType.CONTROL, operateType = OperateType.COMMAND, operateExplain = "指令下发")
public Result<Void> ctrlCommand(@RequestBody @Validated CtrlCommand command) {
ctrlCommandService.sendCommand(command);
return Result.success();
}
}

View File

@ -6,6 +6,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.service.DispatchRecordService;
@ -17,9 +20,8 @@ public class RemoteTakeOverController extends BaseController {
private final DispatchRecordService dispatchRecordService;
@GetMapping("confirm")
// @Log(module = ModuleType.CONTROL, operateType = OperateType.COMMAND, operateExplain = "远程接管")
public Result<Void> takeOver(@RequestParam("cid") String cid,
@RequestParam("vid") String vid) {
@Log(module = ModuleType.CONTROL, operateType = OperateType.COMMAND, operateExplain = "开始远程接管车辆")
public Result<Void> takeOver(@RequestParam("cid") String cid, @RequestParam("vid") String vid) {
return toResult(dispatchRecordService.takeOver(cid, vid));
}
}

View File

@ -8,6 +8,9 @@ import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.validate.AddGroup;
import org.zxwl.common.core.validate.UpdateGroup;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.model.routeInfo.*;
import org.zxwl.sweeper.model.routeInfo.app.RouteInfoDetailVO;
@ -38,16 +41,22 @@ public class RouteInfoController extends BaseController {
}
@PostMapping("/ctrl")
//@SaCheckPermission("route:info:ctrl")
@Log(module = ModuleType.ROUTE, operateType = OperateType.COMMAND, operateExplain = "路径采集开始")
public Result<Void> route(@RequestBody @Validated RouteCommandDTO routeCommandDTO) {
return toResult(routeInfoService.sendRouteCommand(routeCommandDTO));
}
@PostMapping("/upload")
//@SaCheckPermission("route:info:upload")
@Log(module = ModuleType.ROUTE, operateType = OperateType.OTHER, operateExplain = "路径文件上传")
public Result<Void> upload(@ModelAttribute @Validated RouteUploadDTO routeUploadDTO) {
return toResult(routeInfoService.uploadFile(routeUploadDTO));
}
@GetMapping("/download/{id}")
//@SaCheckPermission("route:info:download")
@Log(module = ModuleType.ROUTE, operateType = OperateType.OTHER, operateExplain = "路径信息下发")
public Result<Void> download(@PathVariable("id") Long id) {
routeInfoService.downloadFile(id);
return Result.success();
@ -59,22 +68,30 @@ public class RouteInfoController extends BaseController {
}
@PostMapping
//@SaCheckPermission("route:info:add")
@Log(module = ModuleType.ROUTE, operateType = OperateType.INSERT, operateExplain = "路径信息新增")
public Result<Void> add(@ModelAttribute @Validated({AddGroup.class,
Default.class}) RouteInfoDTO dto) {
return toResult(routeInfoService.add(dto));
}
@PutMapping("enable")
//@SaCheckPermission("route:info:enable")
@Log(module = ModuleType.ROUTE, operateType = OperateType.OTHER, operateExplain = "路径信息启用")
public Result<Void> enable(@RequestParam Long id) {
return toResult(routeInfoService.enable(id));
}
@PutMapping("disable")
//@SaCheckPermission("route:info:disable")
@Log(module = ModuleType.ROUTE, operateType = OperateType.OTHER, operateExplain = "路径信息禁用")
public Result<Void> disable(@RequestParam Long id) {
return toResult(routeInfoService.disable(id));
}
@PutMapping
//@SaCheckPermission("route:info:update")
@Log(module = ModuleType.ROUTE, operateType = OperateType.OTHER, operateExplain = "路径信息修改")
public Result<Void> update(@ModelAttribute @Validated({UpdateGroup.class,
Default.class}) RouteInfoDTO dto) {
return toResult(routeInfoService.update(dto));

View File

@ -8,6 +8,9 @@ import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.utils.ValidatorUtil;
import org.zxwl.common.core.validate.UpdateGroup;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.model.safetyOfficer.SafetyOfficerDTO;
import org.zxwl.sweeper.model.safetyOfficer.SafetyOfficerQuery;
@ -37,17 +40,23 @@ public class SafetyOfficerController extends BaseController {
}
@PostMapping
//@SaCheckPermission("safety:info:add")
@Log(module = ModuleType.SAFETY, operateType = OperateType.INSERT, operateExplain = "安全员信息新增")
public Result<Void> add(@RequestBody @Validated SafetyOfficerDTO dto) {
return toResult(safetyOfficerService.add(dto));
}
@PutMapping
//@SaCheckPermission("safety:info:update")
@Log(module = ModuleType.SAFETY, operateType = OperateType.UPDATE, operateExplain = "安全员信息修改")
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class,
Default.class}) SafetyOfficerDTO dto) {
return toResult(safetyOfficerService.update(dto));
}
@DeleteMapping("{ids}")
//@SaCheckPermission("safety:info:delete")
@Log(module = ModuleType.SAFETY, operateType = OperateType.DELETE, operateExplain = "安全员信息删除")
public Result<Void> delete(@PathVariable("ids") List<Long> ids) {
return toResult(safetyOfficerService.delete(ValidatorUtil.checkIds(ids)));
}

View File

@ -8,6 +8,9 @@ import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.utils.ValidatorUtil;
import org.zxwl.common.core.validate.UpdateGroup;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.model.taskInfo.TaskInfoDTO;
import org.zxwl.sweeper.model.taskInfo.TaskInfoQuery;
@ -42,27 +45,37 @@ public class TaskInfoController extends BaseController {
}
@PostMapping
//@SaCheckPermission("task:info:add")
@Log(module = ModuleType.TASK, operateType = OperateType.INSERT, operateExplain = "任务信息新增")
public Result<Void> add(@RequestBody @Validated TaskInfoDTO dto) {
return toResult(taskInfoService.add(dto));
}
@PutMapping
//@SaCheckPermission("task:info:update")
@Log(module = ModuleType.TASK, operateType = OperateType.UPDATE, operateExplain = "任务信息修改")
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class,
Default.class}) TaskInfoDTO dto) {
return toResult(taskInfoService.update(dto));
}
@DeleteMapping("{ids}")
//@SaCheckPermission("task:info:delete")
@Log(module = ModuleType.TASK, operateType = OperateType.DELETE, operateExplain = "任务信息删除")
public Result<Void> delete(@PathVariable("ids") List<Long> ids) {
return toResult(taskInfoService.delete(ValidatorUtil.checkIds(ids)));
}
@GetMapping("/start/{id}")
//@SaCheckPermission("task:info:start")
@Log(module = ModuleType.TASK, operateType = OperateType.DELETE, operateExplain = "任务调度开始")
public Result<Void> start(@PathVariable("id") Long id) {
return toResult(taskInfoService.start(id));
}
@GetMapping("/stop/{id}")
//@SaCheckPermission("task:info:stop")
@Log(module = ModuleType.TASK, operateType = OperateType.DELETE, operateExplain = "任务调度停止")
public Result<Void> stop(@PathVariable("id") Long id) {
return toResult(taskInfoService.stop(id));
}

View File

@ -5,6 +5,9 @@ import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.utils.ValidatorUtil;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.model.taskRecord.TaskRecordQuery;
import org.zxwl.sweeper.model.taskRecord.TaskRecordVO;
@ -33,6 +36,8 @@ public class TaskRecordController extends BaseController {
}
@DeleteMapping("{ids}")
//@SaCheckPermission("task:record:delete")
@Log(module = ModuleType.TASK, operateType = OperateType.DELETE, operateExplain = "任务调度记录删除")
public Result<Void> delete(@PathVariable("ids") List<Long> ids) {
return toResult(taskRecordService.delete(ValidatorUtil.checkIds(ids)));
}

View File

@ -3,6 +3,9 @@ package org.zxwl.sweeper.controller;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.model.app.ctrl.RemoteCommand;
import org.zxwl.sweeper.model.app.vehicleCard.VehicleCard;
@ -23,13 +26,13 @@ public class VehicleCardController extends BaseController {
}
@PostMapping("confirmCtrl")
// @Log(module = ModuleType.CONTROL, operateType = OperateType.COMMAND, operateExplain = "远程控制")
@Log(module = ModuleType.CONTROL, operateType = OperateType.COMMAND, operateExplain = "确认远程控制车辆")
public Result<List<String>> confirmRemote(@RequestBody RemoteCommand remoteCommand) {
return Result.success(vehicleCardService.submitRemoteControl(remoteCommand));
}
@PostMapping("confirmAutoCtrl")
// @Log(module = ModuleType.CONTROL, operateType = OperateType.COMMAND, operateExplain = "远程控制")
@Log(module = ModuleType.CONTROL, operateType = OperateType.COMMAND, operateExplain = "开启自动驾驶模式")
public Result<Void> confirmAutoControl(@RequestBody RemoteCommand remoteCommand) {
return toResult(vehicleCardService.submitAutoControl(remoteCommand));
}

View File

@ -7,6 +7,9 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.model.app.ctrl.CtrlCommand;
import org.zxwl.sweeper.model.app.ctrl.RemoteCommand;
@ -22,13 +25,13 @@ public class VehicleCtrlController extends BaseController {
private final DispatchRecordService dispatchRecordService;
@PostMapping
// @Log(module = ModuleType.CONTROL, operateType = OperateType.COMMAND, operateExplain = "远控指令")
@Log(module = ModuleType.CONTROL, operateType = OperateType.COMMAND, operateExplain = "下发指令")
public Result<Void> vehicleCtrl(@RequestBody @Validated CtrlCommand command) {
return toResult(vehicleCtrlService.sendCommand(command));
}
@PostMapping("/endCtrl")
// @Log(module = ModuleType.CONTROL, operateType = OperateType.COMMAND, operateExplain = "结束远")
@Log(module = ModuleType.CONTROL, operateType = OperateType.COMMAND, operateExplain = "结束远程接管车辆")
public Result<Void> endVehicleCtrl(@RequestBody RemoteCommand remoteCommand) {
return toResult(dispatchRecordService.endRemote(remoteCommand));
}

View File

@ -6,6 +6,9 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.utils.ValidatorUtil;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.model.vehicleFault.VehicleFaultDTO;
import org.zxwl.sweeper.model.vehicleFault.VehicleFaultQuery;
@ -40,6 +43,8 @@ public class VehicleFaultController extends BaseController {
}
@DeleteMapping("{ids}")
//@SaCheckPermission("vehicle:fault:delete")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.DELETE, operateExplain = "车辆故障信息删除")
public Result<Void> delete(@PathVariable("ids") List<Long> ids) {
return toResult(vehicleFaultService.delete(ValidatorUtil.checkIds(ids)));
}

View File

@ -1,34 +0,0 @@
package org.zxwl.sweeper.controller;
import org.zxwl.sweeper.service.VehicleGridService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.zxwl.common.core.domain.Result;
import org.zxwl.sweeper.model.vehicleGrid.VehicleGridInfoVO;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author Ben
* @since 2025-06-20
*/
@RestController
@RequestMapping("/vehicleGrid")
@RequiredArgsConstructor
public class VehicleGridController {
private final VehicleGridService vehicleGridService;
@GetMapping
public Result<List<VehicleGridInfoVO>> vehicleGrid(@RequestParam String vid) {
return Result.success(vehicleGridService.listGridByVehicle(vid));
}
}

View File

@ -6,10 +6,13 @@ import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.sweeper.model.VehicleInfoAPPVO;
import org.zxwl.common.core.utils.ValidatorUtil;
import org.zxwl.common.core.validate.UpdateGroup;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.sweeper.model.VehicleInfoAPPVO;
import org.zxwl.sweeper.model.app.vehicleCard.VehicleCard;
import org.zxwl.sweeper.model.vehicleInfo.*;
import org.zxwl.sweeper.service.VehicleInfoService;
@ -62,46 +65,45 @@ public class VehicleInfoController extends BaseController {
}
@PostMapping
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.INSERT, operateExplain = "车辆信息新增")
//@SaCheckPermission("vehicle:info:add")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.INSERT, operateExplain = "车辆信息新增")
public Result<Void> add(@RequestBody @Validated VehicleInfoDTO dto) {
return toResult(vehicleInfoService.add(dto));
}
@PutMapping
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.UPDATE, operateExplain = "车辆信息修改")
//@SaCheckPermission("vehicle:info:update")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.UPDATE, operateExplain = "车辆信息修改")
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class,
Default.class}) VehicleInfoDTO dto) {
return toResult(vehicleInfoService.update(dto));
}
@DeleteMapping("{ids}")
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.DELETE, operateExplain = "车辆信息删除")
//@SaCheckPermission("vehicle:info:delete")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.DELETE, operateExplain = "车辆信息删除")
public Result<Void> delete(@PathVariable("ids") List<Long> ids) {
return toResult(vehicleInfoService.delete(ValidatorUtil.checkIds(ids)));
}
@PutMapping("enable")
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.OTHER, operateExplain = "车辆信息启用")
//@SaCheckPermission("vehicle:info:enable")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.OTHER, operateExplain = "车辆启用")
public Result<Void> enable(@RequestParam Long id) {
return toResult(vehicleInfoService.enable(id));
}
@PutMapping("disable")
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.OTHER, operateExplain = "车辆信息禁用")
//@SaCheckPermission("vehicle:info:disable")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.OTHER, operateExplain = "车辆禁用")
public Result<Void> disable(@RequestParam Long id) {
return toResult(vehicleInfoService.disable(id));
}
@PutMapping("binding")
// @SaCheckRole(value = {"admin", "system"}, mode = SaMode.OR)
// @Log(module = ModuleType.SYSTEM, operateType = OperateType.OTHER, operateExplain = "车辆绑定")
public Result<Void> bindCockpit(@RequestParam("id") Long id,
@RequestParam("cid") String cid) {
//@SaCheckPermission("vehicle:info:bind")
@Log(module = ModuleType.VEHICLE, operateType = OperateType.OTHER, operateExplain = "车辆绑定")
public Result<Void> bindCockpit(@RequestParam("id") Long id, @RequestParam("cid") String cid) {
return toResult(vehicleInfoService.bindCockpit(id, cid));
}

View File

@ -0,0 +1,96 @@
package org.zxwl.sweeper.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
/**
* <p>
* 故障报修表
* </p>
*
* @author zy
* @since 2025-09-19
*/
@Getter
@Setter
@TableName("info_fault_repair")
public class FaultRepair {
/**
* ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 标题
*/
@TableField("title")
private String title;
/**
* 故障详细描述
*/
@TableField("description")
private String description;
/**
* 报修人id
*/
@TableField("report_user_id")
private Long reportUserId;
/**
* 优先级
*/
@TableField("priority")
private Integer priority;
/**
* 状态
*/
@TableField("status")
private Integer status;
/**
* 指派给维修人员ID
*/
@TableField("assign_to_user_id")
private Long assignToUserId;
/**
* 维修结果描述
*/
@TableField("repair_result")
private String repairResult;
/**
* 备注
*/
@TableField("remark")
private String remark;
/**
* 创建时间
*/
@TableField(value = "created", fill = FieldFill.INSERT)
private LocalDateTime created;
/**
* 修改时间
*/
@TableField(value = "last", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime last;
/**
* 是否删除 0 未删除 1 已删除
*/
@TableField("deleted")
@TableLogic
private Integer deleted;
}

View File

@ -0,0 +1,19 @@
package org.zxwl.sweeper.enums;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum RepairStatusEnum {
PEND("待处理", 0),
PROCESS("处理中", 1),
SOLVE("已解决", 2),
CLOSE("已关闭", 3),
CANCEL("已取消", 4);
private final String label;
private final Integer value;
}

View File

@ -11,8 +11,7 @@ public enum TaskStatusEnum {
UN_EXECUTED("待执行", 0),
EXECUTING("执行中", 1),
COMPLETED("已完成", 2),
EXCEPTION("运行异常", 3),
;
EXCEPTION("运行异常", 3);
private final String label;
private final Integer value;

View File

@ -10,6 +10,7 @@ import org.springframework.kafka.support.KafkaHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import org.zxwl.common.utils.RedisUtil;
import org.zxwl.sweeper.constant.KafkaTopicConst;
import org.zxwl.sweeper.constant.RedisKeyConst;
import org.zxwl.sweeper.utils.KafkaUtil;
@ -21,15 +22,13 @@ import java.util.Optional;
@RequiredArgsConstructor
public class CockpitKafkaConsumer {
@KafkaListener(id = "device_heartbeat_info", topicPattern = "zxwl.cockpit.*.heartbeat")
@KafkaListener(id = "device_heartbeat_info", topicPattern = KafkaTopicConst.COCKPIT_HEARTBEAT)
public void handleDeviceHeartbeatInfo(ConsumerRecord<String, String> record, Acknowledgment ack,
@Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
Optional<String> message = Optional.ofNullable(record.value());
if (message.isPresent()) {
String msg = message.get();
String cid = KafkaUtil.getVIdByTopic(topic, 3);
if (CharSequenceUtil.isEmpty(cid)) return;
// log.info("[kafka] ==> Topic: {}, Message: {}", topic, msg);
// RedisUtil.setValueWithExpire(RedisKeyConst.COCKPIT_ONLINE_PREFIX + cid, LocalDateTimeUtil.now(), 30);
RedisUtil.addZSet(RedisKeyConst.COCKPIT_ONLINE_KEY, cid, Instant.now().getEpochSecond());
ack.acknowledge();

View File

@ -11,6 +11,7 @@ import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import org.zxwl.common.json.utils.JacksonUtil;
import org.zxwl.common.utils.RedisUtil;
import org.zxwl.sweeper.constant.KafkaTopicConst;
import org.zxwl.sweeper.constant.RedisKeyConst;
import org.zxwl.sweeper.model.reply.ReplyHeader;
@ -21,7 +22,7 @@ import java.util.Optional;
@RequiredArgsConstructor
public class TaskKafkaConsumer {
@KafkaListener(id = "task_push", topicPattern = "zxwl.vehicle.*.task")
@KafkaListener(id = "task_push", topicPattern = KafkaTopicConst.VEHICLE_TASK)
public void handleVehicleTask(ConsumerRecord<String, String> consumerRecord, Acknowledgment ack,
@Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
Optional<String> message = Optional.ofNullable(consumerRecord.value());
@ -37,4 +38,15 @@ public class TaskKafkaConsumer {
ack.acknowledge();
}
}
@KafkaListener(id = "task_status_push", topicPattern = KafkaTopicConst.VEHICLE_TASK_STATUS)
public void handleVehicleStatusTask(ConsumerRecord<String, String> consumerRecord, Acknowledgment ack,
@Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
Optional<String> message = Optional.ofNullable(consumerRecord.value());
if (message.isPresent()) {
String msg = message.get();
log.info("task_status_push <==> {}", msg);
ack.acknowledge();
}
}
}

View File

@ -1,5 +1,6 @@
package org.zxwl.sweeper.listener;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
@ -12,18 +13,23 @@ import org.springframework.kafka.support.Acknowledgment;
import org.springframework.kafka.support.KafkaHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import org.zxwl.common.json.utils.JacksonUtil;
import org.zxwl.common.utils.RedisUtil;
import org.zxwl.sweeper.constant.KafkaTopicConst;
import org.zxwl.sweeper.constant.RedisKeyConst;
import org.zxwl.sweeper.model.app.info.VehicleFaultInfo;
import org.zxwl.sweeper.model.app.info.VehicleInfoReport;
import org.zxwl.sweeper.model.app.sensor.GPSInfo;
import org.zxwl.sweeper.model.reply.ReplyHeader;
import org.zxwl.sweeper.utils.KafkaUtil;
import org.zxwl.sweeper.ws.VehicleGpsWebSocket;
import org.zxwl.sweeper.ws.VehicleInfoWebSocket;
import org.zxwl.sweeper.ws.VehicleWarningWebSocket;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
@ -32,7 +38,24 @@ public class VehicleKafkaConsumer {
private final MongoTemplate mongoTemplate;
@KafkaListener(id = "vehicle_base_info", topicPattern = "zxwl.vehicle.*.info")
@KafkaListener(id = "vehicle_ctrl_info", topicPattern = KafkaTopicConst.VEHICLE_CTRL)
public void handleVehicleTask(ConsumerRecord<String, String> consumerRecord, Acknowledgment ack,
@Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
Optional<String> message = Optional.ofNullable(consumerRecord.value());
if (message.isPresent()) {
String msg = message.get();
log.info("ctrl_push <==> {}", msg);
ReplyHeader<?> replyHeader = JSONUtil.toBean(msg, ReplyHeader.class);
if ("response".equals(replyHeader.getType())) {
Long seqNo = replyHeader.getSeqNo();
RedisUtil.setValueWithExpire(RedisKeyConst.VEHICLE_CTRL_RESPONSE + seqNo,
JacksonUtil.toJsonStr(replyHeader.getData()), 10);
}
ack.acknowledge();
}
}
@KafkaListener(id = "vehicle_base_info", topicPattern = KafkaTopicConst.VEHICLE_INFO)
public void handleVehicleInfo(ConsumerRecord<String, String> consumerRecord, Acknowledgment ack,
@Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
Optional<String> message = Optional.ofNullable(consumerRecord.value());
@ -41,6 +64,7 @@ public class VehicleKafkaConsumer {
String vid = KafkaUtil.getVIdByTopic(topic, 3);
if (CharSequenceUtil.isEmpty(vid)) return;
// 车俩在线状态
RedisUtil.setValueWithExpire(RedisKeyConst.VEHICLE_STATUS + vid,
System.currentTimeMillis(), 30);
@ -54,17 +78,21 @@ public class VehicleKafkaConsumer {
// log.info("[kafka] ==> Topic: {}, Message: {}", topic, jsonObject);
VehicleInfoWebSocket.sendBroadcast(vid, 1, jsonObject.toString());
Map<String, Object> map = BeanUtil.beanToMap(jsonObject);
VehicleInfoReport vehicleInfoReport = JSONUtil.toBean(msg, VehicleInfoReport.class);
vehicleInfoReport.setVid(vid);
vehicleInfoReport.setCreatedAt(LocalDateTime.now());
// 车俩电池容量
RedisUtil.setValue(RedisKeyConst.VEHICLE_POWER + vid ,vehicleInfoReport.getPower());
// 车俩实时状态信息(档位水位充电状态速度电机温度垃圾豆容量等)
RedisUtil.putHashAll(RedisKeyConst.VEHICLE_STATUS_INFO + vid, map, 30, TimeUnit.SECONDS);
mongoTemplate.save(vehicleInfoReport, "v_vehicle_info");
ack.acknowledge();
}
}
@KafkaListener(id = "vehicle_gps_info", topicPattern = "zxwl.vehicle.*.gps")
@KafkaListener(id = "vehicle_gps_info", topicPattern = KafkaTopicConst.VEHICLE_GPS)
public void handleGPSInfo(ConsumerRecord<String, String> consumerRecord, Acknowledgment ack,
@Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
Optional<String> message = Optional.ofNullable(consumerRecord.value());
@ -93,7 +121,7 @@ public class VehicleKafkaConsumer {
}
}
@KafkaListener(id = "vehicle_fault_info", topicPattern = "zxwl.vehicle.*.fault")
@KafkaListener(id = "vehicle_fault_info", topicPattern = KafkaTopicConst.VEHICLE_FAULT)
public void handleVehicleWarningInfo(ConsumerRecord<String, String> record, Acknowledgment ack,
@Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
Optional<String> message = Optional.ofNullable(record.value());
@ -101,7 +129,6 @@ public class VehicleKafkaConsumer {
String msg = message.get();
String vid = KafkaUtil.getVIdByTopic(topic, 3);
if (CharSequenceUtil.isEmpty(vid)) return;
// log.info("[kafka] ==> Topic: {}, Message: {}", topic, msg);
VehicleWarningWebSocket.sendBroadcast(vid, 1, msg);
VehicleFaultInfo vehicleFaultInfo = JSONUtil.toBean(msg, VehicleFaultInfo.class);
vehicleFaultInfo.setVin(vid);
@ -113,11 +140,11 @@ public class VehicleKafkaConsumer {
}
}
@KafkaListener(id = "test", topicPattern = "zxwl.vehicle.*.test")
public void listener(ConsumerRecord<String, String> record, Acknowledgment ack,
@Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
log.info("kafka收到的消息-topic{}, data{}", topic, record.value());
ack.acknowledge();
}
// @KafkaListener(id = "test", topicPattern = "zxwl.vehicle.*.test")
// public void listener(ConsumerRecord<String, String> record, Acknowledgment ack,
// @Header(KafkaHeaders.RECEIVED_TOPIC) String topic) {
// log.info("kafka收到的消息-topic{}, data{}", topic, record.value());
// ack.acknowledge();
// }
}

View File

@ -0,0 +1,29 @@
package org.zxwl.sweeper.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.zxwl.sweeper.entity.FaultRepair;
import org.zxwl.sweeper.model.faultRepair.FaultRepairQuery;
import org.zxwl.sweeper.model.faultRepair.FaultRepairStatus;
import org.zxwl.sweeper.model.faultRepair.FaultRepairVo;
import java.util.List;
@Mapper
public interface FaultRepairMapper extends BaseMapper<FaultRepair> {
/**
* 分页查询
*
* @param page 分页参数
* @param query 查询参数
* @return Page
*/
Page<FaultRepairVo> queryPage(@Param("page") Page<FaultRepair> page, @Param("query") FaultRepairQuery query);
@Select("select status, count(*) count from info_fault_repair where deleted = 0 group by status")
List<FaultRepairStatus> selectData();
}

View File

@ -5,9 +5,13 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.zxwl.sweeper.entity.TaskRecord;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.zxwl.sweeper.entity.TaskRecord;
import org.zxwl.sweeper.model.taskRecord.TaskStatusDataVo;
import java.time.LocalDateTime;
import java.util.List;
/**
* <p>
@ -22,4 +26,6 @@ public interface TaskRecordMapper extends BaseMapper<TaskRecord> {
Page<TaskRecord> selectAllByPage(@Param("page") IPage<TaskRecord> page,
@Param(Constants.WRAPPER) Wrapper<TaskRecord> wrapper);
List<TaskStatusDataVo> getDataList(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end);
}

View File

@ -1,20 +0,0 @@
package org.zxwl.sweeper.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.zxwl.sweeper.entity.VehicleGrid;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author Ben
* @since 2025-06-20
*/
@Mapper
public interface VehicleGridMapper extends BaseMapper<VehicleGrid> {
}

View File

@ -18,6 +18,10 @@ public class VehicleInfoAPPVO {
* ID
*/
private Long id;
/**
* 车俩vin
*/
private String vid;
/**
@ -39,6 +43,7 @@ public class VehicleInfoAPPVO {
* 状态 0 离线 1 在线
*/
private Integer status;
/**
* 故障状态
*/
@ -50,20 +55,19 @@ public class VehicleInfoAPPVO {
if (CharSequenceUtil.isNotEmpty(vehicleInfo.getPicture())) {
this.picture = EnvUtil.getProperty("minio.pathPrefix") + vehicleInfo.getPicture();
}
if(Boolean.TRUE.equals(RedisUtil.exist(RedisKeyConst.VEHICLE_STATUS + vehicleInfo.getVid()))) {
if (RedisUtil.exist(RedisKeyConst.VEHICLE_STATUS + vehicleInfo.getVid())) {
this.status = OnlineEnum.ONLINE.getValue();
} else {
this.status = OnlineEnum.OFFLINE.getValue();
}
if(Boolean.TRUE.equals(RedisUtil.exist(RedisKeyConst.VEHICLE_FAULT_STATUS + vehicleInfo.getVid()))) {
if (RedisUtil.exist(RedisKeyConst.VEHICLE_FAULT_STATUS + vehicleInfo.getVid())) {
this.faultStatus = OnlineEnum.ONLINE.getValue();
} else {
this.faultStatus = OnlineEnum.OFFLINE.getValue();
}
this.power = String.valueOf(RedisUtil.getValue(RedisKeyConst.VEHICLE_POWER + vehicleInfo.getVid()).orElse(""));
}
}
}

View File

@ -38,11 +38,15 @@ public class CockpitInfoVO {
* 异常状态 0 正常 1 异常
*/
private Integer faultStatus;
private Integer enableStatus;
/**
* 启用状态 0 停用 1 启用
*/
private Integer enableStatus;
/**
* 在线状态 0 离线 1 在线
*/
private Integer status;
/**
@ -68,7 +72,8 @@ public class CockpitInfoVO {
if (CharSequenceUtil.isNotEmpty(cockpitInfo.getPicture())) {
this.picture = EnvUtil.getProperty("minio.pathPrefix") + cockpitInfo.getPicture();
}
if(Boolean.TRUE.equals(RedisUtil.exist(RedisKeyConst.COCKPIT_ONLINE_PREFIX + cockpitInfo.getCid()))) {
if (RedisUtil.exist(RedisKeyConst.COCKPIT_ONLINE_PREFIX + cockpitInfo.getCid())) {
this.status = OnlineEnum.ONLINE.getValue();
} else {
this.status = OnlineEnum.OFFLINE.getValue();

View File

@ -0,0 +1,12 @@
package org.zxwl.sweeper.model.cockpitInfo;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class CockpitStatisticsVO {
private long onlineCount; // 驾驶舱在线数量
private long remoteCtrlCount; // 远控数量
private long idleCount; // 空闲数量
}

View File

@ -30,7 +30,7 @@ public class CockpitStatusInfoVO {
if (cockpitInfo != null) {
this.name = cockpitInfo.getName();
this.faultStatus = cockpitInfo.getFaultStatus();
if(Boolean.TRUE.equals(RedisUtil.exist(RedisKeyConst.COCKPIT_ONLINE_PREFIX + cockpitInfo.getCid()))) {
if (RedisUtil.exist(RedisKeyConst.COCKPIT_ONLINE_PREFIX + cockpitInfo.getCid())) {
this.status = OnlineEnum.ONLINE.getValue();
} else {
this.status = OnlineEnum.OFFLINE.getValue();

View File

@ -29,7 +29,8 @@ public class ElectricFenceQuery extends BaseQuery<ElectricFence> {
return new LambdaQueryWrapper<ElectricFence>()
.like(CharSequenceUtil.isNotEmpty(name), ElectricFence::getName, name)
.eq(Objects.nonNull(vehicleId), ElectricFence::getVehicleId, vehicleId)
.eq(Objects.nonNull(type), ElectricFence::getType, type);
.eq(Objects.nonNull(type), ElectricFence::getType, type)
.orderByDesc(ElectricFence::getCreated);
}
}

View File

@ -0,0 +1,31 @@
package org.zxwl.sweeper.model.faultRepair;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 故障报修表
* </p>
*
* @author zy
* @since 2025-09-19
*/
@Getter
@Setter
public class FaultRepairAllocateDTO {
/**
* 主键id
*/
@NotNull(message = "主键id不能为空")
private Long id;
/**
* 维修人员id
*/
@NotNull(message = "维修人员id")
private Long assignToUserId;
}

View File

@ -0,0 +1,67 @@
package org.zxwl.sweeper.model.faultRepair;
import cn.hutool.core.bean.BeanUtil;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.Getter;
import lombok.Setter;
import org.zxwl.common.core.validate.UpdateGroup;
import org.zxwl.sweeper.entity.FaultRepair;
import java.util.List;
/**
* <p>
* 故障报修表
* </p>
*
* @author zy
* @since 2025-09-19
*/
@Getter
@Setter
public class FaultRepairDTO {
/**
* ID
*/
@NotNull(groups = UpdateGroup.class)
@PositiveOrZero(groups = UpdateGroup.class)
private Long id;
/**
* 标题
*/
@NotBlank(message = "标题不能为空")
private String title;
/**
* 故障详细描述
*/
@NotBlank(message = "故障详细描述不能为空")
private String description;
/**
* 优先级
*/
@NotNull(message = "优先级不能为空")
private Integer priority;
/**
* 故障图片或者视频集合
*/
private List<Long> fileIds;
/**
* 备注
*/
private String remark;
public FaultRepair toFaultRepair() {
FaultRepair faultRepair = new FaultRepair();
BeanUtil.copyProperties(this, faultRepair);
return faultRepair;
}
}

View File

@ -0,0 +1,27 @@
package org.zxwl.sweeper.model.faultRepair;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 故障报修表
* </p>
*
* @author zy
* @since 2025-09-19
*/
@Getter
@Setter
public class FaultRepairDataVo {
/**
* 代办数量
*/
private Long pendCount;
/**
* 处理中数量
*/
private Long processCount;
}

View File

@ -0,0 +1,26 @@
package org.zxwl.sweeper.model.faultRepair;
import lombok.Getter;
import lombok.Setter;
import org.zxwl.common.mybatis.page.BaseQuery;
import org.zxwl.sweeper.entity.FaultRepair;
/**
* <p>
* 故障报修表
* </p>
*
* @author zy
* @since 2025-09-19
*/
@Getter
@Setter
public class FaultRepairQuery extends BaseQuery<FaultRepair> {
private String title;
private Integer status;
private Integer priority;
}

View File

@ -0,0 +1,28 @@
package org.zxwl.sweeper.model.faultRepair;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 故障报修表
* </p>
*
* @author zy
* @since 2025-09-19
*/
@Getter
@Setter
public class FaultRepairStatus {
/**
* 状态
*/
private Integer status;
/**
* 状态统计
*/
private Long count;
}

View File

@ -0,0 +1,109 @@
package org.zxwl.sweeper.model.faultRepair;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
/**
* <p>
* 故障报修表
* </p>
*
* @author zy
* @since 2025-09-19
*/
@Getter
@Setter
public class FaultRepairVo {
/**
* ID
*/
private Long id;
/**
* 标题
*/
private String title;
/**
* 故障详细描述
*/
private String description;
/**
* 报修人id
*/
private Long reportUserId;
/**
* 报修人姓名
*/
private String reportName;
/**
* 报修人手机号
*/
private String reportPhone;
/**
* 优先级
*/
private Integer priority;
/**
* 优先级中文
*/
private String priorityCn;
/**
* 状态
*/
private Integer status;
/**
* 状态中文
*/
private String statusCn;
/**
* 指派给维修人员ID
*/
private Long assignToUserId;
/**
* 指派给维修人员姓名
*/
private String assignName;
/**
* 维修人员手机号
*/
private String assignPhone;
/**
* 维修结果描述
*/
private String repairResult;
/**
* 备注
*/
private String remark;
/**
* 创建时间
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime created;
/**
* 修改时间
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime last;
}

View File

@ -41,7 +41,7 @@ public class SafetyOfficerQuery extends BaseQuery<SafetyOfficer> {
.like(CharSequenceUtil.isNotEmpty(key), SafetyOfficer::getPhone, key).or()
.like(CharSequenceUtil.isNotEmpty(key), SafetyOfficer::getDriverCardNo, key).or()
.like(CharSequenceUtil.isNotEmpty(key), SafetyOfficer::getLoginName, key).or()
.orderByDesc(SafetyOfficer::getCreated)
;
}
}

View File

@ -23,6 +23,10 @@ public class TaskInfoVO {
* 任务路径
*/
private Long routeId;
/**
* 路径名称
*/
private String routeName;
/**
@ -39,6 +43,10 @@ public class TaskInfoVO {
* 任务车辆
*/
private Long vehicleId;
/**
* 车俩名称
*/
private String vehicleName;
/**

View File

@ -0,0 +1,15 @@
package org.zxwl.sweeper.model.taskRecord;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class TaskStatisticsVo {
private long count; // 当日任务总数
private long unExecutedCount; // 当日待执行任务总数
private long pendingCount; // 当日执行中任务总数
private long abnormalCount; // 当日异常任务总数
private long completionCount; // 当日任务完成总数
private long completionRate; // 任务完成率当日完成数/总数
}

View File

@ -0,0 +1,11 @@
package org.zxwl.sweeper.model.taskRecord;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class TaskStatusDataVo {
private int status;
private long count;
}

View File

@ -1,12 +0,0 @@
package org.zxwl.sweeper.model.vehicleGrid;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class VehicleGridInfoVO {
private String label; //格口标签
private String value; //锁编号
}

View File

@ -94,7 +94,7 @@ public class VehicleInfoVO {
if (CharSequenceUtil.isNotEmpty(vehicleInfo.getPicture())) {
this.picture = EnvUtil.getProperty("minio.pathPrefix") + vehicleInfo.getPicture();
}
if(Boolean.TRUE.equals(RedisUtil.exist(RedisKeyConst.VEHICLE_STATUS + vehicleInfo.getVid()))) {
if (RedisUtil.exist(RedisKeyConst.VEHICLE_STATUS + vehicleInfo.getVid())) {
this.status = OnlineEnum.ONLINE.getValue();
} else {
this.status = OnlineEnum.OFFLINE.getValue();

View File

@ -0,0 +1,13 @@
package org.zxwl.sweeper.model.vehicleInfo;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class VehicleStatisticsVo {
private long count; // 车辆总数
private long onlineCount; // 在线数
private long offlineCount; // 离线数
private long faultCount; // 故障数
}

View File

@ -37,9 +37,13 @@ public class VehicleSimpleInfoVO {
private String picture;
/**
* 状态 0 离线 1 在线
* 在线状态 0 离线 1 在线
*/
private Integer status;
/**
* 故障状态
*/
private Integer faultStatus;
public VehicleSimpleInfoVO(VehicleInfo vehicleInfo) {
@ -48,12 +52,12 @@ public class VehicleSimpleInfoVO {
if (CharSequenceUtil.isNotEmpty(vehicleInfo.getPicture())) {
this.picture = EnvUtil.getProperty("minio.pathPrefix") + vehicleInfo.getPicture();
}
if(Boolean.TRUE.equals(RedisUtil.exist(RedisKeyConst.VEHICLE_STATUS + vehicleInfo.getVid()))) {
if (RedisUtil.exist(RedisKeyConst.VEHICLE_STATUS + vehicleInfo.getVid())) {
this.status = OnlineEnum.ONLINE.getValue();
} else {
this.status = OnlineEnum.OFFLINE.getValue();
}
if(Boolean.TRUE.equals(RedisUtil.exist(RedisKeyConst.VEHICLE_FAULT_STATUS + vehicleInfo.getVid()))) {
if (RedisUtil.exist(RedisKeyConst.VEHICLE_FAULT_STATUS + vehicleInfo.getVid())) {
this.faultStatus = OnlineEnum.ONLINE.getValue();
} else {
this.faultStatus = OnlineEnum.OFFLINE.getValue();

View File

@ -29,12 +29,18 @@ public class VehicleStatusInfoVO {
public VehicleStatusInfoVO(VehicleInfo vehicleInfo) {
if (vehicleInfo != null) {
this.name = vehicleInfo.getName();
// this.faultStatus = vehicleInfo.getFaultStatus();
if(Boolean.TRUE.equals(RedisUtil.exist(RedisKeyConst.VEHICLE_STATUS + vehicleInfo.getVid()))) {
if (RedisUtil.exist(RedisKeyConst.VEHICLE_STATUS + vehicleInfo.getVid())) {
this.status = OnlineEnum.ONLINE.getValue();
} else {
this.status = OnlineEnum.OFFLINE.getValue();
}
if (RedisUtil.exist(RedisKeyConst.VEHICLE_FAULT_STATUS + vehicleInfo.getVid())) {
this.faultStatus = OnlineEnum.ONLINE.getValue();
} else {
this.faultStatus = OnlineEnum.OFFLINE.getValue();
}
}
}
}

View File

@ -3,10 +3,7 @@ package org.zxwl.sweeper.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.zxwl.sweeper.entity.CockpitInfo;
import org.zxwl.sweeper.model.cockpitInfo.CockpitDropVO;
import org.zxwl.sweeper.model.cockpitInfo.CockpitInfoDTO;
import org.zxwl.sweeper.model.cockpitInfo.CockpitInfoQuery;
import org.zxwl.sweeper.model.cockpitInfo.CockpitInfoVO;
import org.zxwl.sweeper.model.cockpitInfo.*;
import org.zxwl.sweeper.model.cockpitInfo.dp.CockpitSimpleInfoQuery;
import org.zxwl.sweeper.model.cockpitInfo.dp.CockpitStatusInfoVO;
@ -24,15 +21,24 @@ import java.util.Set;
public interface CockpitInfoService extends IService<CockpitInfo> {
Page<CockpitInfoVO> list(CockpitInfoQuery query); //列表
boolean add(CockpitInfoDTO dto); //新增
boolean update(CockpitInfoDTO dto); //编辑
boolean delete(Set<Long> ids); //删除
boolean enable(Long id); //启用
boolean disable(Long id); //停用
List<CockpitDropVO> bindingList(); //驾驶舱绑定下拉列表
List<CockpitDropVO> dropList(); //驾驶舱下拉列表
Long onlineCount(); //在线数
Page<CockpitStatusInfoVO> listStatusInfo(CockpitSimpleInfoQuery query); //列表
CockpitStatisticsVO getData();
}

View File

@ -1,8 +0,0 @@
package org.zxwl.sweeper.service;
import org.zxwl.sweeper.model.app.ctrl.CtrlCommand;
public interface CtrlCommandService {
void sendCommand(CtrlCommand command); //发送控制命令
}

View File

@ -25,15 +25,21 @@ import java.util.Set;
public interface DispatchRecordService extends IService<DispatchRecord> {
Page<DispatchRecordVO> list(DispatchRecordQuery query); //列表
boolean add(DispatchRecordDTO dto); //新增
boolean update(DispatchRecordDTO dto); //编辑
boolean delete(Set<Long> ids); //删除
VehicleIdVO getVehicleIdByCid(String cid); //根据座舱ID获取车辆ID
DispatchRecordVO getDispatchRecordByCid(String cid); //根据cid获取调度信息
List<String> confirmRemote(RemoteCommand remoteCommand); //确认远控
boolean endRemote(RemoteCommand remoteCommand); //结束远控
boolean confirmAutoDrive(RemoteCommand remoteCommand); //确认自动驾驶
boolean takeOver(String cid, String vid); //远程接管

View File

@ -12,7 +12,9 @@ import java.util.List;
public interface DpHomeService {
Page<CockpitStatusInfoVO> listCockpitStatus(CockpitSimpleInfoQuery query);
Page<VehicleStatusInfoVO> listVehicleStatus(VehicleSimpleInfoQuery query);
List<DispatchRecordVO> listDispatchRecord();
// List<VehicleWarningVO> listVehicleWarning();
}

View File

@ -20,8 +20,11 @@ import java.util.List;
public interface ElectricFenceService extends IService<ElectricFence> {
Page<ElectricFenceVO> list(ElectricFenceQuery query); //列表
boolean add(ElectricFenceDTO dto); //新增
boolean update(ElectricFenceDTO dto); //编辑
boolean delete(List<Long> ids); //删除
// List<ElectricFenceVO> listElectricFenceByCid(); //查询电子围栏

View File

@ -0,0 +1,28 @@
package org.zxwl.sweeper.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.zxwl.sweeper.entity.FaultRepair;
import org.zxwl.sweeper.model.faultRepair.*;
/**
* <p>
* 接口
* </p>
*
* @author zy
* @since 2025-09-19
*/
public interface FaultRepairService extends IService<FaultRepair> {
Page<FaultRepairVo> queryPage(FaultRepairQuery query); // 分页查询
FaultRepairDataVo data(); // 统计代办和处理中总数量
boolean add(FaultRepairDTO faultRepairDTO);
boolean edit(FaultRepairDTO faultRepairDTO);
boolean assign(FaultRepairAllocateDTO faultRepairAllocateDTO);
boolean updateByStatus(Long id, Integer status);
}

View File

@ -20,9 +20,13 @@ import java.util.Set;
*/
public interface GatewayInfoService extends IService<GatewayInfo> {
Page<GatewayInfoVO> list(GatewayInfoQuery query); //列表
List<String> listCameraUrls(String vid); //根据vid查询摄像头地址
boolean add(GatewayInfoDTO dto); //新增
boolean update(GatewayInfoDTO dto); //编辑
boolean delete(Set<Long> ids); //删除
boolean bindVehicle(Long id, String vid); //绑定车辆

View File

@ -11,24 +11,32 @@ import java.util.List;
public interface RouteInfoService extends IService<RouteInfo> {
Page<RouteInfoAPPVO> listRouteInfo(RouteInfoAPPQuery routeInfoAPPQuery); //根据VID获取车辆的路径信息
List<RouteInfoAPPVO> routeDropList(String vid); //根据VID获取车辆的路径下拉列表
RouteInfoDetailVO routeInfoDetail(Long id); //路径详情
List<RoutePosition> listRoutePosition(String rid); //根据路径ID获取路径点的信息
List<RoutePosition> listRoutePositionByVid(String vid); //根据vid获取路径点的信息
boolean uploadFile(RouteUploadDTO routeUploadDTO); //上传路径文件
void downloadFile(Long id); //根据路径ID下载路径文件
RoutePath getRoutePath(Long id); //根据路径ID获取路径文件
boolean sendRouteCommand(RouteCommandDTO routeCommandDTO); //发送路径命令
Page<RouteInfoVO> list(RouteInfoQuery query); //列表
boolean add(RouteInfoDTO dto); //路径新增
boolean update(RouteInfoDTO dto); //路径编辑
boolean delete(List<Long> ids); //路径删除
boolean enable(Long id); //路径启用
boolean disable(Long id); //路径停用
}

View File

@ -20,7 +20,10 @@ import java.util.Set;
public interface SafetyOfficerService extends IService<SafetyOfficer> {
Page<SafetyOfficerVO> list(SafetyOfficerQuery query); //列表
boolean add(SafetyOfficerDTO dto); //新增
boolean update(SafetyOfficerDTO dto); //编辑
boolean delete(Set<Long> ids); //删除
}

View File

@ -21,9 +21,13 @@ import java.util.Set;
public interface TaskInfoService extends IService<TaskInfo> {
Page<TaskInfoVO> list(TaskInfoQuery query); //列表
TaskInfoVO detail(Long id); //详情
boolean add(TaskInfoDTO dto); //新增
boolean update(TaskInfoDTO dto); //编辑
boolean delete(Set<Long> ids); //删除
TaskInfoAPPVO currentTaskInfo(Long vehicleId); //当前任务

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import org.zxwl.sweeper.entity.TaskRecord;
import org.zxwl.sweeper.model.taskRecord.TaskRecordQuery;
import org.zxwl.sweeper.model.taskRecord.TaskRecordVO;
import org.zxwl.sweeper.model.taskRecord.TaskStatisticsVo;
import java.util.Set;
@ -19,9 +20,15 @@ import java.util.Set;
public interface TaskRecordService extends IService<TaskRecord> {
Page<TaskRecordVO> list(TaskRecordQuery query); //列表
// TaskInfoVO detail(Long id); //详情
boolean add(Long taskId, Long vehicleId); //新增
boolean updateRecordCompleted(Long taskId, Long vehicleId); //更新完成记录
boolean updateRecordException(Long taskId, Long vehicleId); //更新失败记录
boolean delete(Set<Long> ids); //删除
TaskStatisticsVo getData();
}

View File

@ -9,6 +9,7 @@ public interface VehicleCardService {
List<VehicleCard> listVehicleCard(String cid); //车辆卡片列表
List<String> submitRemoteControl(RemoteCommand remoteCommand);
boolean submitAutoControl(RemoteCommand remoteCommand);
List<String> submitRemoteControl(RemoteCommand remoteCommand); //确认远程
boolean submitAutoControl(RemoteCommand remoteCommand); //确认自动驾驶
}

View File

@ -21,7 +21,9 @@ import java.util.Set;
public interface VehicleFaultService extends IService<VehicleFault> {
Page<VehicleFaultVO> list(VehicleFaultQuery query); //列表
boolean add(VehicleFaultDTO dto); //新增
boolean delete(Set<Long> ids); //删除
List<VehicleFaultVO> listByVid(String vid); //根据vid查询故障信息

View File

@ -1,21 +0,0 @@
package org.zxwl.sweeper.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.zxwl.sweeper.entity.VehicleGrid;
import org.zxwl.sweeper.model.vehicleGrid.VehicleGridInfoVO;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author Ben
* @since 2025-06-20
*/
public interface VehicleGridService extends IService<VehicleGrid> {
List<VehicleGridInfoVO> listGridByVehicle(String vid);
}

View File

@ -28,15 +28,25 @@ public interface VehicleInfoService extends IService<VehicleInfo> {
VehicleSimpleInfoVO getVehicleSimpleInfo(Long id); //车辆详情简化
Page<VehicleInfoVO> list(VehicleInfoQuery query); //列表
List<VehicleDropVO> listDrop(); //下拉菜单
List<VehicleStatusVO> sidebar(); //侧边栏
List<VehicleDropVO> bindingList(); //下拉菜单
boolean add(VehicleInfoDTO dto); //新增
boolean update(VehicleInfoDTO dto); //编辑
boolean delete(Set<Long> ids); //删除
boolean enable(Long id); //启用
boolean disable(Long id); //停用
boolean bindCockpit(Long id, String cid); //绑定驾驶舱
boolean hasGateway(String vid); //判断是否具有网关
Long onlineCount(); //在线数
@ -46,4 +56,6 @@ public interface VehicleInfoService extends IService<VehicleInfo> {
Page<VehicleStatusInfoVO> listStatusInfo(VehicleSimpleInfoQuery query); //车辆状态列表
boolean exitVehicleInfo(String vid); //是否存在车辆信息
VehicleStatisticsVo getData();
}

View File

@ -15,16 +15,16 @@ import org.zxwl.common.core.exception.SystemErrorCode;
import org.zxwl.common.utils.RedisUtil;
import org.zxwl.sweeper.constant.RedisKeyConst;
import org.zxwl.sweeper.entity.CockpitInfo;
import org.zxwl.sweeper.entity.DispatchRecord;
import org.zxwl.sweeper.entity.VehicleInfo;
import org.zxwl.sweeper.enums.DispatchStatusEnum;
import org.zxwl.sweeper.enums.EnableEnum;
import org.zxwl.sweeper.enums.OnlineEnum;
import org.zxwl.sweeper.mapper.CockpitInfoMapper;
import org.zxwl.sweeper.mapper.DispatchRecordMapper;
import org.zxwl.sweeper.mapper.VehicleInfoMapper;
import org.zxwl.sweeper.model.cache.DeviceStatusCache;
import org.zxwl.sweeper.model.cockpitInfo.CockpitDropVO;
import org.zxwl.sweeper.model.cockpitInfo.CockpitInfoDTO;
import org.zxwl.sweeper.model.cockpitInfo.CockpitInfoQuery;
import org.zxwl.sweeper.model.cockpitInfo.CockpitInfoVO;
import org.zxwl.sweeper.model.cockpitInfo.*;
import org.zxwl.sweeper.model.cockpitInfo.dp.CockpitSimpleInfoQuery;
import org.zxwl.sweeper.model.cockpitInfo.dp.CockpitStatusInfoVO;
import org.zxwl.sweeper.service.CockpitInfoService;
@ -49,6 +49,7 @@ public class CockpitInfoServiceImpl extends ServiceImpl<CockpitInfoMapper, Cockp
private final CockpitInfoMapper cockpitInfoMapper;
private final VehicleInfoMapper vehicleInfoMapper;
private final DispatchRecordMapper dispatchRecordMapper;
@PostConstruct
private void init() {
@ -94,34 +95,15 @@ public class CockpitInfoServiceImpl extends ServiceImpl<CockpitInfoMapper, Cockp
@Override
public boolean delete(Set<Long> ids) {
if (exitsBindingVehicle(ids)) {
throw new BusinessException(SystemErrorCode.ELETE_FAILURE_EXIST_BINDING_VEHICLE);
LambdaUpdateWrapper<CockpitInfo> wrapper = new LambdaUpdateWrapper<>();
wrapper.in(CockpitInfo::getId, ids);
wrapper.eq(CockpitInfo::getEnableStatus, EnableEnum.ENABLE.getValue());
if (exists(wrapper)) {
throw new BusinessException(SystemErrorCode.COCKPIT_STATUS_EXIST);
}
return cockpitInfoMapper.deleteByIds(ids) > 0;
}
private boolean exitsBindingVehicle(Set<Long> ids) {
List<String> cidList = cockpitInfoMapper.selectBatchIds(ids).stream().map(CockpitInfo::getCid).toList();
for (String cid : cidList) {
LambdaQueryWrapper<VehicleInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(VehicleInfo::getCid, cid);
if (vehicleInfoMapper.exists(queryWrapper)) {
return true;
}
}
return false;
}
private boolean exitsBindingVehicle(Long id) {
CockpitInfo cockpitInfo = cockpitInfoMapper.selectById(id);
if (cockpitInfo == null) {
return false;
}
LambdaQueryWrapper<VehicleInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(VehicleInfo::getCid, cockpitInfo.getCid());
return vehicleInfoMapper.exists(queryWrapper);
}
@Override
public boolean enable(Long id) {
LambdaUpdateWrapper<CockpitInfo> updateWrapper = new LambdaUpdateWrapper<>();
@ -132,9 +114,24 @@ public class CockpitInfoServiceImpl extends ServiceImpl<CockpitInfoMapper, Cockp
@Override
public boolean disable(Long id) {
if (exitsBindingVehicle(id)) {
throw new BusinessException(SystemErrorCode.DELETE_FAILURE_EXIST_BINDING_GATEWAY);
// 判断该驾驶舱是否存在已绑定的车辆
CockpitInfo cockpitInfo = cockpitInfoMapper.selectById(id);
LambdaQueryWrapper<VehicleInfo> vehicleWrapper = new LambdaQueryWrapper<>();
vehicleWrapper.eq(VehicleInfo::getCid, cockpitInfo.getCid());
vehicleWrapper.eq(VehicleInfo::getEnableStatus, EnableEnum.ENABLE.getValue());
if (vehicleInfoMapper.exists(vehicleWrapper)) {
throw new BusinessException(SystemErrorCode.ELETE_FAILURE_EXIST_BINDING_VEHICLE);
}
// 判断该驾驶舱是否存在远程控制车辆
LambdaQueryWrapper<DispatchRecord> dispatchRecordWrapper = new LambdaQueryWrapper<>();
dispatchRecordWrapper.eq(DispatchRecord::getCid, cockpitInfo.getCid());
dispatchRecordWrapper.ne(DispatchRecord::getStatus, DispatchStatusEnum.DISPATCH_END.getValue());
if (dispatchRecordMapper.exists(dispatchRecordWrapper)) {
throw new BusinessException(SystemErrorCode.VEHICLE_DISPATCH_STARTING);
}
LambdaUpdateWrapper<CockpitInfo> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Objects.nonNull(id), CockpitInfo::getId, id);
updateWrapper.set(CockpitInfo::getEnableStatus, EnableEnum.DISABLE.getValue());
@ -170,4 +167,21 @@ public class CockpitInfoServiceImpl extends ServiceImpl<CockpitInfoMapper, Cockp
return new Page<CockpitStatusInfoVO>(page.getCurrent(), page.getSize(), page.getTotal()).setRecords(list);
}
@Override
public CockpitStatisticsVO getData() {
long count = cockpitInfoMapper.selectCount(Wrappers.query(CockpitInfo.class).lambda()
.eq(CockpitInfo::getEnableStatus, EnableEnum.ENABLE.getValue()));
long remoteCtrlCount = dispatchRecordMapper.selectCount(Wrappers.query(DispatchRecord.class).lambda()
.ne(DispatchRecord::getStatus, DispatchStatusEnum.DISPATCH_END.getValue()));
long onlineCount = RedisUtil.countKeysByPrefix(RedisKeyConst.COCKPIT_ONLINE_PREFIX);
CockpitStatisticsVO statisticsVO = new CockpitStatisticsVO();
statisticsVO.setOnlineCount(onlineCount);
statisticsVO.setRemoteCtrlCount(remoteCtrlCount);
statisticsVO.setIdleCount(count - onlineCount);
return statisticsVO;
}
}

View File

@ -1,28 +0,0 @@
package org.zxwl.sweeper.service.impl;
import cn.hutool.json.JSONUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.zxwl.common.mqtt.handler.MqttMessageSender;
import org.zxwl.sweeper.constant.MqttTopicConst;
import org.zxwl.sweeper.model.app.ctrl.CtrlCommand;
import org.zxwl.sweeper.service.CtrlCommandService;
@Slf4j
@Service
@RequiredArgsConstructor
public class CtrlCommandServiceImpl implements CtrlCommandService {
//private final MqttInfoService mqttInfoService;
private final MqttMessageSender mqttMessageSender;
@Override
public void sendCommand(CtrlCommand command) {
String jsonStr = JSONUtil.toJsonStr(command);
String topic = MqttTopicConst.generateVehicleCtrlTopic(command.getVid());
log.info("发送命令 ==> {} : {}", topic, jsonStr);
//mqttInfoService.publishMessage(topic, jsonStr);
mqttMessageSender.send(topic, jsonStr);
}
}

View File

@ -15,6 +15,7 @@ import org.zxwl.common.core.exception.BusinessException;
import org.zxwl.common.core.exception.SystemErrorCode;
import org.zxwl.common.excel.utils.ExcelUtil;
import org.zxwl.common.mqtt.handler.MqttMessageSender;
import org.zxwl.common.satoken.utils.LoginHelper;
import org.zxwl.common.utils.RedisUtil;
import org.zxwl.sweeper.constant.MqttTopicConst;
import org.zxwl.sweeper.constant.RedisKeyConst;
@ -128,9 +129,9 @@ public class DispatchRecordServiceImpl extends ServiceImpl<DispatchRecordMapper,
DispatchRecord undoRecord = getUndoDispatchRecord(cid, vid);
//通知车辆准备远控
//mqttInfoService.publishMessage(MqttTopicConst.generateVehicleCtrlTopic(vid),
//mqttInfoService.publishMessage(MqttTopicConst.VehicleCtrl(vid),
// JSONUtil.toJsonStr(BaseCommand.startRemoteCommand(remoteCommand.getValue())));
mqttMessageSender.send(MqttTopicConst.generateVehicleCtrlTopic(vid),
mqttMessageSender.send(MqttTopicConst.VehicleCtrl(vid),
JSONUtil.toJsonStr(BaseCommand.startRemoteCommand(remoteCommand.getValue())));
boolean hasGateWay = vehicleInfoService.hasGateway(vid);
@ -156,9 +157,9 @@ public class DispatchRecordServiceImpl extends ServiceImpl<DispatchRecordMapper,
@Override
public boolean confirmAutoDrive(RemoteCommand remoteCommand) {
//mqttInfoService.publishMessage(MqttTopicConst.generateVehicleCtrlTopic(remoteCommand.getVid()),
// mqttInfoService.publishMessage(MqttTopicConst.VehicleCtrl(remoteCommand.getVid()),
// JSONUtil.toJsonStr(BaseCommand.startRemoteCommand(remoteCommand.getValue())));
mqttMessageSender.send(MqttTopicConst.generateVehicleCtrlTopic(remoteCommand.getVid()),
mqttMessageSender.send(MqttTopicConst.VehicleCtrl(remoteCommand.getVid()),
JSONUtil.toJsonStr(BaseCommand.startRemoteCommand(remoteCommand.getValue())));
return true;
}
@ -174,9 +175,9 @@ public class DispatchRecordServiceImpl extends ServiceImpl<DispatchRecordMapper,
String cid = remoteCommand.getCid();
String vid = remoteCommand.getVid();
//mqttInfoService.publishMessage(MqttTopicConst.generateVehicleCtrlTopic(vid),
//mqttInfoService.publishMessage(MqttTopicConst.VehicleCtrl(vid),
// JSONUtil.toJsonStr(BaseCommand.endRemoteCommand(remoteCommand.getValue())));
mqttMessageSender.send(MqttTopicConst.generateVehicleCtrlTopic(vid),
mqttMessageSender.send(MqttTopicConst.VehicleCtrl(vid),
JSONUtil.toJsonStr(BaseCommand.endRemoteCommand(remoteCommand.getValue())));
// gatewayVideoService.closeRemoteCtrlWindows();
// gatewayVideoService.stopSaveVideo(vid);
@ -210,9 +211,9 @@ public class DispatchRecordServiceImpl extends ServiceImpl<DispatchRecordMapper,
throw new BusinessException(SystemErrorCode.VEHICLE_DISPATCH_STARTING);
}
//mqttInfoService.publishMessage(MqttTopicConst.generateVehicleCtrlTopic(vid),
//mqttInfoService.publishMessage(MqttTopicConst.VehicleCtrl(vid),
// JSONUtil.toJsonStr(BaseCommand.startRemoteCommand(1)), 2);
mqttMessageSender.send(MqttTopicConst.generateVehicleCtrlTopic(vid), 2,
mqttMessageSender.send(MqttTopicConst.VehicleCtrl(vid), 2,
JSONUtil.toJsonStr(BaseCommand.startRemoteCommand(1)));
// gatewayVideoService.startSaveVideo(vid);
// gatewayVideoService.openRemoteCtrl(vid, vehicleInfoService.hasGateway(vid));
@ -329,9 +330,7 @@ public class DispatchRecordServiceImpl extends ServiceImpl<DispatchRecordMapper,
DispatchRecord dispatchRecord = new DispatchRecord();
dispatchRecord.setCid(cid);
dispatchRecord.setVid(vid);
// dispatchRecord.setDispatcher(LoginHelper.getRealName());
// TODO: 2025/01/03 临时
dispatchRecord.setDispatcher("admin");
dispatchRecord.setDispatcher(LoginHelper.getRealName());
return flashCache(dispatchRecordMapper.insert(dispatchRecord));
}

View File

@ -0,0 +1,71 @@
package org.zxwl.sweeper.service.impl;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.zxwl.sweeper.entity.FaultRepair;
import org.zxwl.sweeper.enums.RepairStatusEnum;
import org.zxwl.sweeper.mapper.FaultRepairMapper;
import org.zxwl.sweeper.model.faultRepair.*;
import org.zxwl.sweeper.service.FaultRepairService;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* </p>
*
* @author zy
* @since 2025-09-19
*/
@RequiredArgsConstructor
@Service
public class FaultRepairServiceImpl extends ServiceImpl<FaultRepairMapper, FaultRepair> implements FaultRepairService {
private final FaultRepairMapper faultRepairMapper;
@Override
public Page<FaultRepairVo> queryPage(FaultRepairQuery query) {
return faultRepairMapper.queryPage(query.toPage(), query);
}
@Override
public FaultRepairDataVo data() {
List<FaultRepairStatus> list = faultRepairMapper.selectData();
Map<Integer, Long> map = list.stream().collect(Collectors.groupingBy(FaultRepairStatus::getStatus, Collectors.counting()));
FaultRepairDataVo vo = new FaultRepairDataVo();;
vo.setPendCount(map.getOrDefault(RepairStatusEnum.PEND.getValue(), 0L));
vo.setProcessCount(map.getOrDefault(RepairStatusEnum.PROCESS.getValue(), 0L));
return vo;
}
@Override
public boolean add(FaultRepairDTO faultRepairDTO) {
return save(faultRepairDTO.toFaultRepair());
}
@Override
public boolean edit(FaultRepairDTO faultRepairDTO) {
return updateById(faultRepairDTO.toFaultRepair());
}
@Override
public boolean assign(FaultRepairAllocateDTO dto) {
return update(new LambdaUpdateWrapper<FaultRepair>()
.eq(FaultRepair::getId, dto.getId())
.set(FaultRepair::getAssignToUserId, dto.getAssignToUserId()));
}
@Override
public boolean updateByStatus(Long id, Integer status) {
return update(new LambdaUpdateWrapper<FaultRepair>()
.eq(FaultRepair::getId, id)
.set(FaultRepair::getStatus, status));
}
}

View File

@ -24,9 +24,11 @@ import org.zxwl.common.mqtt.handler.MqttMessageSender;
import org.zxwl.common.utils.RedisUtil;
import org.zxwl.sweeper.constant.MqttTopicConst;
import org.zxwl.sweeper.constant.RedisKeyConst;
import org.zxwl.sweeper.constant.TopicNameConst;
import org.zxwl.sweeper.entity.RouteInfo;
import org.zxwl.sweeper.entity.TaskInfo;
import org.zxwl.sweeper.enums.TaskStatusEnum;
import org.zxwl.sweeper.mapper.RouteInfoMapper;
import org.zxwl.sweeper.mapper.TaskInfoMapper;
import org.zxwl.sweeper.model.app.ctrl.BaseCommand;
import org.zxwl.sweeper.model.reply.ReplyHeader;
import org.zxwl.sweeper.model.reply.ResponseMessage;
@ -51,6 +53,7 @@ import java.util.concurrent.TimeUnit;
public class RouteInfoServiceImpl extends ServiceImpl<RouteInfoMapper, RouteInfo> implements RouteInfoService {
private final RouteInfoMapper routeInfoMapper;
private final TaskInfoMapper taskInfoMapper;
// private final MqttInfoService mqttInfoService;
private final MqttMessageSender mqttMessageSender;
private final CurrentRouteService currentRouteService;
@ -155,8 +158,8 @@ public class RouteInfoServiceImpl extends ServiceImpl<RouteInfoMapper, RouteInfo
BaseCommand baseCommand = new BaseCommand();
baseCommand.setCommand("distribute");
baseCommand.setValue(baseWebPath + routeInfo.getFileName() + "," + routeInfo.getMd5());
//mqttInfoService.publishMessage(MqttTopicConst.generateVehicleCtrlTopic(routeInfo.getVid()), JSONUtil.toJsonStr(baseCommand));
mqttMessageSender.send(MqttTopicConst.generateVehicleCtrlTopic(routeInfo.getVid()), JSONUtil.toJsonStr(baseCommand));
//mqttInfoService.publishMessage(MqttTopicConst.VehicleCtrl(routeInfo.getVid()), JSONUtil.toJsonStr(baseCommand));
mqttMessageSender.send(MqttTopicConst.VehicleCtrl(routeInfo.getVid()), JSONUtil.toJsonStr(baseCommand));
}
@Override
@ -183,13 +186,13 @@ public class RouteInfoServiceImpl extends ServiceImpl<RouteInfoMapper, RouteInfo
// mqttInfoService.publishMessage(topic, jsonStr);
ReplyHeader<BaseCommand> replyHeader = new ReplyHeader<>();
long seqNo = generateSeqNo();
long seqNo = RandomUtil.randomLong(1, Integer.MAX_VALUE);
replyHeader.requestInfo(seqNo, routeCommandDTO.toBaseCommand());
String topic = MqttTopicConst.generateVehicleCtrlTopic(routeCommandDTO.getVid());
String topic = MqttTopicConst.VehicleCtrl(routeCommandDTO.getVid());
String jsonStr = JacksonUtil.toJsonStr(replyHeader);
log.info("发送命令 ==> {} : {}", topic, jsonStr);
//mqttInfoService.publishMessage(TopicNameConst.VehicleCtrl(routeCommandDTO.getVid()), jsonStr, 2);
mqttMessageSender.send(TopicNameConst.VehicleCtrl(routeCommandDTO.getVid()), 2, jsonStr);
//mqttInfoService.publishMessage(MqttTopicConst.VehicleCtrl(routeCommandDTO.getVid()), jsonStr, 2);
mqttMessageSender.send(MqttTopicConst.VehicleCtrl(routeCommandDTO.getVid()), 2, jsonStr);
RedisUtil.setValueWithExpire(RedisKeyConst.ROUTE_KEY_PREFIX + routeCommandDTO.getVid(),
routeCommandDTO.getRouteName(), 5 * 60 * 60L);
@ -203,10 +206,6 @@ public class RouteInfoServiceImpl extends ServiceImpl<RouteInfoMapper, RouteInfo
return false;
}
private static long generateSeqNo() {
return RandomUtil.randomLong(1, Integer.MAX_VALUE);
}
private static Object tryGetObject(String key, int initDelay, int count) {
if (count == 0) {
return null;
@ -282,6 +281,13 @@ public class RouteInfoServiceImpl extends ServiceImpl<RouteInfoMapper, RouteInfo
@Override
public boolean delete(List<Long> ids) {
// 判断路径信息是否存在已启用
LambdaQueryWrapper<RouteInfo> wrapper = new LambdaQueryWrapper<>();
wrapper.in(RouteInfo::getId, ids);
wrapper.eq(RouteInfo::getStatus, 1);
if (exists(wrapper)) {
throw new BusinessException(SystemErrorCode.ROUTE_STATUS_EXIST);
}
return routeInfoMapper.deleteByIds(ids) > 0;
}
@ -295,13 +301,17 @@ public class RouteInfoServiceImpl extends ServiceImpl<RouteInfoMapper, RouteInfo
@Override
public boolean disable(Long id) {
// 路径是否存在未完成的任务调用
LambdaUpdateWrapper<TaskInfo> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(TaskInfo::getRouteId, id);
wrapper.eq(TaskInfo::getStatus, TaskStatusEnum.EXECUTING.getValue());
if (taskInfoMapper.exists(wrapper)) {
throw new BusinessException(SystemErrorCode.ROUTE_TASK_EXIST);
}
LambdaUpdateWrapper<RouteInfo> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Objects.nonNull(id), RouteInfo::getId, id);
updateWrapper.set(RouteInfo::getStatus, 0);
return routeInfoMapper.update(updateWrapper) > 0;
}
public boolean saveRoute(RouteInfo routeInfo) {
return routeInfoMapper.insert(routeInfo) > 0;
}
}

View File

@ -37,9 +37,6 @@ public class SafetyOfficerServiceImpl extends ServiceImpl<SafetyOfficerMapper, S
@Override
public boolean add(SafetyOfficerDTO dto) {
// if (existCockpitInfo(dto.getId(), dto.getCid())) {
// throw new BusinessException(SystemErrorCode.COCKPIT_EXIST);
// }
return safetyOfficerMapper.insert(dto.toSafetyOfficer()) > 0;
}

View File

@ -13,9 +13,10 @@ import org.zxwl.common.core.exception.SystemErrorCode;
import org.zxwl.common.core.utils.TimeUtil;
import org.zxwl.common.json.utils.JacksonUtil;
import org.zxwl.common.mqtt.handler.MqttMessageSender;
import org.zxwl.common.satoken.utils.LoginHelper;
import org.zxwl.common.utils.RedisUtil;
import org.zxwl.sweeper.constant.RedisKeyConst;
import org.zxwl.sweeper.constant.TopicNameConst;
import org.zxwl.sweeper.constant.MqttTopicConst;
import org.zxwl.sweeper.entity.RouteInfo;
import org.zxwl.sweeper.entity.TaskInfo;
import org.zxwl.sweeper.entity.VehicleInfo;
@ -90,8 +91,7 @@ public class TaskInfoServiceImpl extends ServiceImpl<TaskInfoMapper, TaskInfo> i
throw new BusinessException(SystemErrorCode.TASK_NAME_EXIST);
}
TaskInfo taskInfo = dto.toTaskInfo();
//todo 临时
taskInfo.setOperator("admin");
taskInfo.setOperator(LoginHelper.getRealName());
return taskInfoMapper.insert(taskInfo) > 0;
}
@ -117,10 +117,10 @@ public class TaskInfoServiceImpl extends ServiceImpl<TaskInfoMapper, TaskInfo> i
if (existExecutingTask(ids)) {
throw new BusinessException(SystemErrorCode.TASK_EXECUTING);
}
return taskInfoMapper.deleteByIds(ids) > 0;
}
//是否有正在执行中的任务
private boolean existExecutingTask(Set<Long> ids) {
LambdaQueryWrapper<TaskInfo> queryWrapper = new LambdaQueryWrapper<>();
@ -165,11 +165,11 @@ public class TaskInfoServiceImpl extends ServiceImpl<TaskInfoMapper, TaskInfo> i
ReplyHeader<RequestMessage> replyHeader = new ReplyHeader<>();
RequestMessage requestMessage = new RequestMessage("start", taskPushInfo);
long seqNo = generateSeqNo();
long seqNo = RandomUtil.randomLong(1, Integer.MAX_VALUE);
replyHeader.requestInfo(seqNo, requestMessage);
//mqttInfoService.publishMessage(TopicNameConst.TaskCtrl(vid), JacksonUtil.toJsonStr(replyHeader));
mqttMessageSender.send(TopicNameConst.TaskCtrl(vid), JacksonUtil.toJsonStr(replyHeader));
//mqttInfoService.publishMessage(MqttTopicConst.TaskCtrl(vid), JacksonUtil.toJsonStr(replyHeader));
mqttMessageSender.send(MqttTopicConst.TaskCtrl(vid), JacksonUtil.toJsonStr(replyHeader));
Object o = tryGetObject(RedisKeyConst.TASK_RESPONSE + seqNo, 200, 25);
if (o != null) {
@ -196,11 +196,11 @@ public class TaskInfoServiceImpl extends ServiceImpl<TaskInfoMapper, TaskInfo> i
ReplyHeader<RequestMessage> replyHeader = new ReplyHeader<>();
RequestMessage requestMessage = new RequestMessage("stop", id);
long seqNo = generateSeqNo();
long seqNo = RandomUtil.randomLong(1, Integer.MAX_VALUE);
replyHeader.requestInfo(seqNo, requestMessage);
//mqttInfoService.publishMessage(TopicNameConst.TaskCtrl(vid), JacksonUtil.toJsonStr(replyHeader));
mqttMessageSender.send(TopicNameConst.TaskCtrl(vid), JacksonUtil.toJsonStr(replyHeader));
//mqttInfoService.publishMessage(MqttTopicConst.TaskCtrl(vid), JacksonUtil.toJsonStr(replyHeader));
mqttMessageSender.send(MqttTopicConst.TaskCtrl(vid), JacksonUtil.toJsonStr(replyHeader));
Object o = tryGetObject(RedisKeyConst.TASK_RESPONSE + seqNo, 200, 25);
if (o != null) {
@ -231,10 +231,6 @@ public class TaskInfoServiceImpl extends ServiceImpl<TaskInfoMapper, TaskInfo> i
return vehicleInfo.getVid();
}
private static long generateSeqNo() {
return RandomUtil.randomLong(1, Integer.MAX_VALUE);
}
private static Object tryGetObject(String key, int initDelay, int count) {
if (count == 0) {
return null;

View File

@ -10,11 +10,18 @@ import org.zxwl.sweeper.enums.TaskStatusEnum;
import org.zxwl.sweeper.mapper.TaskRecordMapper;
import org.zxwl.sweeper.model.taskRecord.TaskRecordQuery;
import org.zxwl.sweeper.model.taskRecord.TaskRecordVO;
import org.zxwl.sweeper.model.taskRecord.TaskStatisticsVo;
import org.zxwl.sweeper.model.taskRecord.TaskStatusDataVo;
import org.zxwl.sweeper.service.TaskRecordService;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* <p>
@ -49,11 +56,6 @@ public class TaskRecordServiceImpl extends ServiceImpl<TaskRecordMapper, TaskRec
@Override
public boolean updateRecordCompleted(Long taskId, Long vehicleId) {
// TaskRecord taskRecord = new TaskRecord();
// taskRecord.setTaskId(taskId);
// taskRecord.setVehicleId(vehicleId);
// taskRecord.setStartTime(LocalDateTime.now());
// taskRecord.setStatus(TaskStatusEnum.COMPLETED.getValue());
LambdaUpdateWrapper<TaskRecord> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(TaskRecord::getEndTime, LocalDateTime.now());
updateWrapper.set(TaskRecord::getStatus, TaskStatusEnum.COMPLETED.getValue());
@ -78,4 +80,36 @@ public class TaskRecordServiceImpl extends ServiceImpl<TaskRecordMapper, TaskRec
public boolean delete(Set<Long> ids) {
return taskRecordMapper.deleteByIds(ids) > 0;
}
@Override
public TaskStatisticsVo getData() {
LocalDate today = LocalDate.now();
List<TaskStatusDataVo> list = taskRecordMapper.getDataList(today.atStartOfDay(), today.plusDays(1).atStartOfDay());
Map<Integer, Long> map = list.stream().collect(Collectors.toMap(TaskStatusDataVo::getStatus, TaskStatusDataVo::getCount));
long count = list.stream().mapToLong(TaskStatusDataVo::getCount).sum();
long unExecutedCount = map.getOrDefault(TaskStatusEnum.UN_EXECUTED.getValue(), 0L);
long pendingCount = map.getOrDefault(TaskStatusEnum.EXECUTING.getValue(), 0L);
long completionCount = map.getOrDefault(TaskStatusEnum.COMPLETED.getValue(), 0L);
long abnormalCount = map.getOrDefault(TaskStatusEnum.EXCEPTION.getValue(), 0L);
TaskStatisticsVo vo = new TaskStatisticsVo();
vo.setCount(count);
vo.setCompletionRate(unExecutedCount);
vo.setPendingCount(pendingCount);
vo.setCompletionCount(completionCount);
vo.setAbnormalCount(abnormalCount);
vo.setCompletionRate(calculateRate(completionCount, count));
return vo;
}
private long calculateRate(long completionCount, long totalCount) {
if (totalCount == 0) {
return 0;
}
BigDecimal d1 = new BigDecimal(completionCount);
BigDecimal d2 = new BigDecimal(totalCount);
return d1.divide(d2, 2, RoundingMode.DOWN).multiply(new BigDecimal("100")).longValue();
}
}

View File

@ -30,8 +30,7 @@ public class VehicleCardServiceImpl implements VehicleCardService {
LambdaQueryWrapper<VehicleInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(VehicleInfo::getCid, cid);
queryWrapper.eq(VehicleInfo::getEnableStatus, EnableEnum.ENABLE.getValue());
List<VehicleCard> records = vehicleInfoMapper.selectList(queryWrapper).stream().map(VehicleCard::new).toList();
return records;
return vehicleInfoMapper.selectList(queryWrapper).stream().map(VehicleCard::new).toList();
}
@Override

View File

@ -13,7 +13,7 @@ import org.zxwl.common.json.utils.JacksonUtil;
import org.zxwl.common.mqtt.handler.MqttMessageSender;
import org.zxwl.common.utils.RedisUtil;
import org.zxwl.sweeper.constant.RedisKeyConst;
import org.zxwl.sweeper.constant.TopicNameConst;
import org.zxwl.sweeper.constant.MqttTopicConst;
import org.zxwl.sweeper.model.app.baseInfo.VehicleReportInfo;
import org.zxwl.sweeper.model.app.ctrl.BaseCommand;
import org.zxwl.sweeper.model.app.ctrl.CtrlCommand;
@ -36,16 +36,14 @@ public class VehicleCtrlServiceImpl implements VehicleCtrlService {
@Override
public boolean sendCommand(CtrlCommand command) {
log.info("***********command************");
// sendTestInfo(command);
ReplyHeader<BaseCommand> replyHeader = new ReplyHeader<>();
long seqNo = generateSeqNo();
long seqNo = RandomUtil.randomLong(1, Integer.MAX_VALUE);
replyHeader.requestInfo(seqNo, new BaseCommand(command));
//mqttInfoService.publishMessage(TopicNameConst.VehicleCtrl(command.getVid()),
// JacksonUtil.toJsonStr(replyHeader), 2);
mqttMessageSender.send(TopicNameConst.VehicleCtrl(command.getVid()), 2, JacksonUtil.toJsonStr(replyHeader));
// mqttInfoService.publishMessage(MqttTopicConst.VehicleCtrl(command.getVid()), JacksonUtil.toJsonStr(replyHeader), 2);
mqttMessageSender.send(MqttTopicConst.VehicleCtrl(command.getVid()), 2, JacksonUtil.toJsonStr(replyHeader));
Object o = tryGetObject(RedisKeyConst.VEHICLE_CTRL_RESPONSE + seqNo, 200, 25);
if (o != null) {
@ -56,10 +54,6 @@ public class VehicleCtrlServiceImpl implements VehicleCtrlService {
return false;
}
private static long generateSeqNo() {
return RandomUtil.randomLong(1, Integer.MAX_VALUE);
}
private static Object tryGetObject(String key, int initDelay, int count) {
if (count == 0) {
return null;

View File

@ -56,11 +56,8 @@ public class VehicleFaultServiceImpl extends ServiceImpl<VehicleFaultMapper, Veh
@Override
public List<VehicleFaultVO> listByVid(String vid) {
// TODO: 2025/06/04 minusDays临时
LocalDateTime todayStart = LocalDate.now().atStartOfDay();
LocalDateTime todayEnd = todayStart.plusDays(1).minusNanos(1);
// Date startDate = Date.from(todayStart.atZone(ZoneId.systemDefault()).toInstant());
// Date endDate = Date.from(todayEnd.atZone(ZoneId.systemDefault()).toInstant());
Query query = Query.query(Criteria.where("createdAt")
.gte(todayStart)

View File

@ -1,59 +0,0 @@
package org.zxwl.sweeper.service.impl;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.zxwl.sweeper.entity.VehicleGrid;
import org.zxwl.sweeper.entity.VehicleInfo;
import org.zxwl.sweeper.mapper.VehicleGridMapper;
import org.zxwl.sweeper.model.vehicleGrid.VehicleGridInfoVO;
import org.zxwl.sweeper.service.VehicleGridService;
import org.zxwl.sweeper.service.VehicleInfoService;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* <p>
* 服务实现类
* </p>
*
* @author Ben
* @since 2025-06-20
*/
@Service
@RequiredArgsConstructor
public class VehicleGridServiceImpl extends ServiceImpl<VehicleGridMapper, VehicleGrid> implements VehicleGridService {
private final VehicleGridMapper vehicleGridMapper;
private final VehicleInfoService vehicleInfoService;
@Override
public List<VehicleGridInfoVO> listGridByVehicle(String vid) {
VehicleInfo vehicleInfo = vehicleInfoService.getOne(Wrappers.lambdaQuery(VehicleInfo.class).eq(VehicleInfo::getVid, vid));
Long id = vehicleInfo.getId();
VehicleGrid vehicleGrid = vehicleGridMapper.selectOne(Wrappers.lambdaQuery(VehicleGrid.class).eq(VehicleGrid::getVehicleId, id));
String gridNum = vehicleGrid.getGridNum();
if (CharSequenceUtil.isEmpty(gridNum)) {
return Collections.emptyList();
}
List<VehicleGridInfoVO> list = new ArrayList<>();
String[] gridNumSplit = gridNum.split(",");
int sum = 0;
for (int i = 0; i < gridNumSplit.length; i++) {
int num = Integer.parseInt(gridNumSplit[i]);
for (int j = 0; j < num; j++) {
VehicleGridInfoVO vehicleGridInfoVO = new VehicleGridInfoVO();
sum++;
vehicleGridInfoVO.setLabel(String.valueOf(sum));
vehicleGridInfoVO.setValue(String.valueOf(i + 1) + String.valueOf(j + 1));
list.add(vehicleGridInfoVO);
}
}
return list;
}
}

View File

@ -1,5 +1,6 @@
package org.zxwl.sweeper.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@ -16,9 +17,14 @@ import org.zxwl.common.core.exception.BusinessException;
import org.zxwl.common.core.exception.SystemErrorCode;
import org.zxwl.common.utils.RedisUtil;
import org.zxwl.sweeper.constant.RedisKeyConst;
import org.zxwl.sweeper.entity.VehicleInfo;
import org.zxwl.sweeper.entity.*;
import org.zxwl.sweeper.enums.DispatchStatusEnum;
import org.zxwl.sweeper.enums.EnableEnum;
import org.zxwl.sweeper.enums.OnlineEnum;
import org.zxwl.sweeper.enums.TaskStatusEnum;
import org.zxwl.sweeper.mapper.DispatchRecordMapper;
import org.zxwl.sweeper.mapper.RouteInfoMapper;
import org.zxwl.sweeper.mapper.TaskInfoMapper;
import org.zxwl.sweeper.mapper.VehicleInfoMapper;
import org.zxwl.sweeper.model.VehicleInfoAPPVO;
import org.zxwl.sweeper.model.app.vehicleCard.VehicleCard;
@ -49,6 +55,9 @@ import java.util.Set;
public class VehicleInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, VehicleInfo> implements VehicleInfoService {
private final VehicleInfoMapper vehicleInfoMapper;
private final RouteInfoMapper routeInfoMapper;
private final DispatchRecordMapper dispatchRecordMapper;
private final TaskInfoMapper taskInfoMapper;
private final CurrentRouteService currentRouteService;
@PostConstruct
@ -69,9 +78,6 @@ public class VehicleInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, Vehic
public Page<VehicleInfoAPPVO> listVehicleInfo(VehicleInfoQuery query) {
Page<VehicleInfo> page = vehicleInfoMapper.selectPage(query.toPage(), query.toWrapper());
List<VehicleInfoAPPVO> list = page.getRecords().stream().map(VehicleInfoAPPVO::new).toList();
// LambdaQueryWrapper<VehicleInfo> queryWrapper = new LambdaQueryWrapper<>();
// queryWrapper.eq(VehicleInfo::getEnableStatus, 1);
// System.out.println("list.size() = " + list.size());
return new Page<VehicleInfoAPPVO>(page.getCurrent(), page.getSize(), page.getTotal())
.setRecords(list);
}
@ -84,9 +90,6 @@ public class VehicleInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, Vehic
@Override
public Page<VehicleInfoVO> list(VehicleInfoQuery query) {
// UserInfo userInfo = LoginHelper.getLoginUser();
// System.out.println("organizeId = " + userInfo.getOrganizeId());
Page<VehicleInfo> page = vehicleInfoMapper.selectPage(query.toPage(), query.toWrapper());
List<VehicleInfoVO> list = page.getRecords().stream().map(VehicleInfoVO::new).toList();
return new Page<VehicleInfoVO>(page.getCurrent(), page.getSize(), page.getTotal()).setRecords(list);
@ -121,7 +124,7 @@ public class VehicleInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, Vehic
}
@Override
@Transactional
@Transactional(rollbackFor = Exception.class)
public boolean add(VehicleInfoDTO dto) {
if (existVehicleInfo(dto.getId(), dto.getVid())) {
throw new BusinessException(SystemErrorCode.VID_EXIST);
@ -131,7 +134,7 @@ public class VehicleInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, Vehic
}
@Override
@Transactional
@Transactional(rollbackFor = Exception.class)
public boolean update(VehicleInfoDTO dto) {
if (existVehicleInfo(dto.getId(), dto.getVid())) {
throw new BusinessException(SystemErrorCode.VID_EXIST);
@ -147,8 +150,23 @@ public class VehicleInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, Vehic
}
@Override
@Transactional
@Transactional(rollbackFor = Exception.class)
public boolean delete(Set<Long> ids) {
// 判断车辆状态是否启用
LambdaQueryWrapper<VehicleInfo> wrapper = new LambdaQueryWrapper<>();
wrapper.in(VehicleInfo::getId, ids);
wrapper.eq(VehicleInfo::getEnableStatus, EnableEnum.ENABLE.getValue());
List<VehicleInfo> list = vehicleInfoMapper.selectList(wrapper);
if (CollUtil.isEmpty(list)) {
throw new BusinessException(SystemErrorCode.VEHICLE_STATUS_EXIST);
}
List<String> vids = list.stream().map(VehicleInfo::getVid).toList();
// 解除关联信息
taskInfoMapper.delete(Wrappers.lambdaQuery(TaskInfo.class).in(TaskInfo::getVehicleId, ids));
routeInfoMapper.delete(Wrappers.lambdaQuery(RouteInfo.class).in(RouteInfo::getVid, vids));
currentRouteService.remove(Wrappers.lambdaQuery(CurrentRoute.class).in(CurrentRoute::getVid, vids));
return vehicleInfoMapper.deleteByIds(ids) > 0;
}
@ -162,6 +180,25 @@ public class VehicleInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, Vehic
@Override
public boolean disable(Long id) {
VehicleInfo vehicleInfo = vehicleInfoMapper.selectById(id);
// 判断车辆是否存在未完成任务调度
LambdaQueryWrapper<TaskInfo> taskWrapper = new LambdaQueryWrapper<>();
taskWrapper.eq(TaskInfo::getVehicleId, id);
taskWrapper.eq(TaskInfo::getStatus, TaskStatusEnum.EXECUTING.getValue());
if (taskInfoMapper.exists(taskWrapper)) {
throw new BusinessException(SystemErrorCode.DELETE_FAILURE_EXIST_UNDO_RECORD);
}
// 判断车辆是否存在被驾驶舱远程控制
LambdaUpdateWrapper<DispatchRecord> dispatchWrapper = new LambdaUpdateWrapper<>();
dispatchWrapper.eq(DispatchRecord::getVid, vehicleInfo.getVid());
dispatchWrapper.eq(DispatchRecord::getStatus, DispatchStatusEnum.DISPATCH_BEGIN.getValue());
if (dispatchRecordMapper.exists(dispatchWrapper)) {
throw new BusinessException(SystemErrorCode.VEHICLE_DISPATCH_BEGIN);
}
// 车辆停用
LambdaUpdateWrapper<VehicleInfo> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(Objects.nonNull(id), VehicleInfo::getId, id);
updateWrapper.set(VehicleInfo::getEnableStatus, EnableEnum.DISABLE.getValue());
@ -170,6 +207,7 @@ public class VehicleInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, Vehic
/**
* 检查绑定上限一台驾驶舱最多绑定10台车
*
* @param cid
* @return
*/
@ -240,4 +278,21 @@ public class VehicleInfoServiceImpl extends ServiceImpl<VehicleInfoMapper, Vehic
queryWrapper.eq(VehicleInfo::getVid, vid);
return vehicleInfoMapper.exists(queryWrapper);
}
@Override
public VehicleStatisticsVo getData() {
long count = vehicleInfoMapper.selectCount(Wrappers.query(VehicleInfo.class).lambda()
.eq(VehicleInfo::getEnableStatus, EnableEnum.ENABLE.getValue()));
long onlineCount = RedisUtil.countKeysByPrefix(RedisKeyConst.VEHICLE_STATUS);
long faultCount = RedisUtil.countKeysByPrefix(RedisKeyConst.VEHICLE_FAULT_STATUS);
VehicleStatisticsVo statisticsVo = new VehicleStatisticsVo();
statisticsVo.setCount(count);
statisticsVo.setOnlineCount(onlineCount);
statisticsVo.setFaultCount(faultCount);
statisticsVo.setOfflineCount(count - onlineCount);
return statisticsVo;
}
}

View File

@ -0,0 +1,67 @@
package org.zxwl.sweeper.ws;
import cn.hutool.json.JSONUtil;
import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.zxwl.sweeper.service.CockpitInfoService;
import org.zxwl.sweeper.service.TaskRecordService;
import org.zxwl.sweeper.service.VehicleInfoService;
import java.util.Arrays;
/**
* 云控大屏(统计驾驶舱车辆任务作业)
*/
@Slf4j
@Component
@ServerEndpoint(value = "/zxwl/cloud/ctrl/web")
public class CloudCtrlWebSocket {
private static VehicleInfoService vehicleInfoService;
private static CockpitInfoService cockpitInfoService;
private static TaskRecordService taskRecordService;
@Autowired
public void setVehicleInfoService(VehicleInfoService vehicleInfoService,
CockpitInfoService cockpitInfoService,
TaskRecordService taskRecordService) {
CloudCtrlWebSocket.vehicleInfoService = vehicleInfoService;
CloudCtrlWebSocket.cockpitInfoService = cockpitInfoService;
CloudCtrlWebSocket.taskRecordService = taskRecordService;
}
@OnOpen
public void onOpen(Session session) {
log.info("云控大屏与WebSocket已连接...");
}
@OnClose
public void onClose(Session session) {
log.warn("云控大屏与WebSocket连接关闭...");
}
@OnMessage
public void onMessage(Session session, String message) {
// 根据前台请求类型返回对应的响应数据
Object result = switch (message) {
case "cockpit" -> cockpitInfoService.getData();
case "vehicle" -> vehicleInfoService.getData();
case "task" -> taskRecordService.getData();
default -> null;
};
if (result != null) {
session.getAsyncRemote().sendText(JSONUtil.toJsonStr(result));
}
}
@OnError
public void onError(Session session, Throwable throwable) {
log.error("云控大屏WebSocket异常错误{}", Arrays.toString(throwable.getStackTrace()));
}
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zxwl.sweeper.mapper.FaultRepairMapper">
<select id="queryPage" resultType="org.zxwl.sweeper.model.faultRepair.FaultRepairVo">
select
a.id,
a.title,
a.description,
a.report_user_id,
d.real_name reportName,
d.phone reportPhone,
a.priority,
b.dict_label priorityCn,
a.status,
c.dict_label statusCn,
a.assign_to_user_id,
e.real_name assignName,
e.phone assignPhone,
a.repair_result,
a.remark,
a.created,
a.last
from info_fault_repair a
left join sys_dict_item b on b.dict_code = 'priority' and b.dict_value = a.priority
left join sys_dict_item c on c.dict_code = 'fault_repair_status' and c.dict_value = a.status
left join sys_user_info d on d.id = a.report_user_id
left join sys_user_info e on e.id = a.assign_to_user_id
where a.deleted = 0
<if test="query.title != null and query.title != ''">
AND a.title LIKE CONCAT('%', #{query.title}, '%')
</if>
<if test="query.status != null">
and a.title = #{query.status}
</if>
<if test="query.priority != null">
and a.priority = #{query.priority}
</if>
order by a.created desc
</select>
</mapper>

View File

@ -33,4 +33,13 @@
</if>
order by tr.created desc
</select>
<select id="getDataList" resultType="org.zxwl.sweeper.model.taskRecord.TaskStatusDataVo">
SELECT
status,
COUNT(*) AS count
FROM info_task_record
WHERE deleted = 0 and created >= #{start} AND created &lt; #{end}
GROUP BY status
</select>
</mapper>

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.zxwl.sweeper.mapper.VehicleGridMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="org.zxwl.sweeper.entity.VehicleGrid">
<id column="id" property="id" />
<result column="vehicle_id" property="vehicleId" />
<result column="grid_num" property="gridNum" />
<result column="status" property="status" />
<result column="created" property="created" />
<result column="last" property="last" />
<result column="deleted" property="deleted" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id, vehicle_id, grid_num, status, created, last, deleted
</sql>
</mapper>

View File

@ -24,6 +24,11 @@
<artifactId>zxwl-common-doc</artifactId>
</dependency>
<dependency>
<groupId>org.zxwl</groupId>
<artifactId>zxwl-common-excel</artifactId>
</dependency>
<dependency>
<groupId>org.zxwl</groupId>
<artifactId>zxwl-common-log</artifactId>

View File

@ -8,6 +8,9 @@ import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.utils.ValidatorUtil;
import org.zxwl.common.core.validate.UpdateGroup;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.system.model.companyInfo.CompanyInfoDTO;
import org.zxwl.system.model.companyInfo.CompanyInfoQuery;
@ -32,22 +35,28 @@ public class CompanyInfoController extends BaseController {
private final CompanyInfoService companyInfoService;
@GetMapping
//@SaCheckPermission("sys:company:list")
public Result<Page<CompanyInfoVO>> list(CompanyInfoQuery query) {
return Result.success(companyInfoService.list(query));
}
@PostMapping
//@SaCheckPermission("sys:company:add")
@Log(module = ModuleType.SYSTEM, operateType = OperateType.INSERT, operateExplain = "企业信息新增")
public Result<Void> add(@RequestBody @Validated CompanyInfoDTO dto) {
return toResult(companyInfoService.add(dto));
}
@PutMapping
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class,
Default.class}) CompanyInfoDTO dto) {
//@SaCheckPermission("sys:company:update")
@Log(module = ModuleType.SYSTEM, operateType = OperateType.UPDATE, operateExplain = "企业信息修改")
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class, Default.class}) CompanyInfoDTO dto) {
return toResult(companyInfoService.update(dto));
}
@DeleteMapping("{ids}")
//@SaCheckPermission("sys:company:delete")
@Log(module = ModuleType.SYSTEM, operateType = OperateType.DELETE, operateExplain = "企业信息删除")
public Result<Void> delete(@PathVariable("ids") List<Long> ids) {
return toResult(companyInfoService.delete(ValidatorUtil.checkIds(ids)));
}

View File

@ -0,0 +1,63 @@
package org.zxwl.system.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.validation.groups.Default;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.zxwl.common.core.domain.Result;
import org.zxwl.common.core.utils.ValidatorUtil;
import org.zxwl.common.core.validate.UpdateGroup;
import org.zxwl.common.log.annotation.Log;
import org.zxwl.common.log.enums.ModuleType;
import org.zxwl.common.log.enums.OperateType;
import org.zxwl.common.web.base.BaseController;
import org.zxwl.system.model.config.ConfigInfoDTO;
import org.zxwl.system.model.config.ConfigInfoQuery;
import org.zxwl.system.model.config.ConfigInfoVO;
import org.zxwl.system.service.ConfigService;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author zy
* @since 2025-09-19
*/
@RestController
@RequestMapping("/config")
@RequiredArgsConstructor
public class ConfigInfoController extends BaseController {
private final ConfigService configService;
@GetMapping
//@SaCheckPermission("sys:config:list")
public Result<Page<ConfigInfoVO>> queryPageList(ConfigInfoQuery query) {
return Result.success(configService.queryPageList(query));
}
@PostMapping
//@SaCheckPermission("sys:config:add")
@Log(module = ModuleType.SYSTEM, operateType = OperateType.INSERT, operateExplain = "配置信息新增")
public Result<Void> add(@RequestBody @Validated ConfigInfoDTO dto) {
return toResult(configService.add(dto));
}
@PutMapping
//@SaCheckPermission("sys:config:update")
@Log(module = ModuleType.SYSTEM, operateType = OperateType.UPDATE, operateExplain = "配置信息修改")
public Result<Void> update(@RequestBody @Validated({UpdateGroup.class, Default.class}) ConfigInfoDTO dto) {
return toResult(configService.edit(dto));
}
@DeleteMapping("{ids}")
//@SaCheckPermission("sys:config:delete")
@Log(module = ModuleType.SYSTEM, operateType = OperateType.DELETE, operateExplain = "配置信息删除")
public Result<Void> delete(@PathVariable("ids") List<Long> ids) {
return toResult(configService.removeByIds(ValidatorUtil.checkIds(ids)));
}
}

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