From 04de920362c9dcc1cc6077b54acba8eeff5090fd Mon Sep 17 00:00:00 2001
From: zhaowenyu <35589726@qq.com>
Date: Thu, 05 Feb 2026 14:09:03 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev
---
ard-inspection/src/main/java/com/ard/inspection/service/impl/BigFileUploadServiceImpl.java | 139 ++++++++++++
ard-admin/src/main/java/com/ard/web/controller/inspection/BigFileUploadController.java | 60 ++++
ard-route/src/main/java/com/ard/route/domain/route/ArdRouteMission.java | 29 ++
ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java | 3
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java | 2
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteMissionServiceImpl.java | 40 +++
ard-route/src/main/resources/mapper/ArdRouteMissionMapper.xml | 71 +++++-
ard-route/pom.xml | 5
ard-route/src/main/java/com/ard/route/websocket/handler/MiWebSocketHandler.java | 39 +++
ard-route/src/main/java/com/ard/route/websocket/utils/MiWebSocketUtils.java | 131 +++++++++++
ard-route/src/main/java/com/ard/route/websocket/interceptor/MiHandshakeInterceptor.java | 32 ++
ard-route/src/main/java/com/ard/route/mapper/ArdRouteMissionMapper.java | 11
ard-route/src/main/java/com/ard/route/service/IArdRouteMissionService.java | 9
ard-inspection/src/main/java/com/ard/inspection/service/IBigFileUploadService.java | 42 +++
ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteMissionController.java | 11 +
ard-route/src/main/java/com/ard/route/websocket/config/MiWebSocketConfig.java | 28 ++
16 files changed, 626 insertions(+), 26 deletions(-)
diff --git a/ard-admin/src/main/java/com/ard/web/controller/inspection/BigFileUploadController.java b/ard-admin/src/main/java/com/ard/web/controller/inspection/BigFileUploadController.java
index 9732383..d9ad474 100644
--- a/ard-admin/src/main/java/com/ard/web/controller/inspection/BigFileUploadController.java
+++ b/ard-admin/src/main/java/com/ard/web/controller/inspection/BigFileUploadController.java
@@ -1,18 +1,66 @@
package com.ard.web.controller.inspection;
+import com.ard.common.annotation.Log;
import com.ard.common.core.controller.BaseController;
-import io.lettuce.core.dynamic.annotation.Value;
+import com.ard.common.core.domain.AjaxResult;
+import com.ard.common.enums.BusinessType;
+import com.ard.inspection.service.IBigFileUploadService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import io.swagger.annotations.Api;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import java.util.*;
+
+/**
+ * @author xia
+ */
@Api(tags = "大文件上传")
@RestController
@RequestMapping("/inspection/bigfile")
+@Slf4j
public class BigFileUploadController extends BaseController {
- /** 若依文件上传根目录(从配置文件读取) */
- //@Value("${ruoyi.profile}")
- private String uploadRootDir;
+ @Autowired
+ private IBigFileUploadService bigFileUploadService;
+
+ @Value(value = "${inspection.profile}")
+ private String uploadPath;
+
+ @Value(value = "${inspection.chunk.path}")
+ private String chunkPath;
+
+ /**
+ * 检查分片是否存在
+ */
+ @GetMapping("/chunks/{fileMd5}")
+ public AjaxResult checkChunk(@PathVariable String fileMd5) {
+ Map<String, Object> result = bigFileUploadService.checkChunk(fileMd5,chunkPath);
+ return AjaxResult.success(result);
+ }
+
+ /**
+ * 上传分片
+ */
+ @PostMapping("/chunk")
+ public AjaxResult uploadChunk(@RequestParam("file") MultipartFile file,
+ @RequestParam("chunkNumber") Integer chunkNumber,
+ @RequestParam("fileMd5") String fileMd5) {
+ Map<String, Object> result = bigFileUploadService.uploadChunk(file, chunkNumber, fileMd5, chunkPath);
+ return AjaxResult.success(result);
+ }
+
+ /**
+ * 合并切片
+ */
+ @Log(title = "合并切片", businessType = BusinessType.IMPORT)
+ @PostMapping("/merge")
+ public AjaxResult mergeChunks(@RequestParam("md5") String md5,
+ @RequestParam("fileName") String fileName) {
+ Map<String, Object> result = bigFileUploadService.mergeChunks(md5, fileName, uploadPath);
+ return AjaxResult.success(result);
+ }
}
diff --git a/ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteMissionController.java b/ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteMissionController.java
index 4a85722..e999013 100644
--- a/ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteMissionController.java
+++ b/ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteMissionController.java
@@ -105,4 +105,15 @@
return toAjax(ardRouteMissionService.updateArdRouteMissionStatus(id,status));
}
+ /**
+ * 批量修改航线任务已读状态
+ */
+ @ApiOperation("批量修改航线任务已读状态")
+ @Log(title = "航线任务", businessType = BusinessType.UPDATE)
+ @PutMapping("editIsRead/{ids}/{isRead}")
+ public AjaxResult editIsRead(@PathVariable String[] ids,
+ @PathVariable String isRead) {
+ return toAjax(ardRouteMissionService.updateIsRead(ids,isRead));
+ }
+
}
diff --git a/ard-inspection/src/main/java/com/ard/inspection/service/IBigFileUploadService.java b/ard-inspection/src/main/java/com/ard/inspection/service/IBigFileUploadService.java
new file mode 100644
index 0000000..276ed75
--- /dev/null
+++ b/ard-inspection/src/main/java/com/ard/inspection/service/IBigFileUploadService.java
@@ -0,0 +1,42 @@
+package com.ard.inspection.service;
+
+
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Map;
+
+public interface IBigFileUploadService {
+
+ /**
+ * 检查分片是否存在
+ *
+ * @param fileMd5 fileMd5
+ * @param chunkPath 切片临时目录
+ */
+ public Map<String, Object> checkChunk(String fileMd5, String chunkPath);
+
+ /**
+ * 上传分片
+ *
+ * @param file 文件
+ * @param chunkNumber chunkNumber
+ * @param fileMd5 fileMd5
+ * @param chunkPath 切片临时目录
+ */
+ public Map<String, Object> uploadChunk(MultipartFile file,
+ Integer chunkNumber,
+ String fileMd5,
+ String chunkPath);
+
+ /**
+ * 合并切片
+ *
+ * @param md5 文件MD5
+ * @param fileName 原始文件名
+ * @param uploadPath 上传文件存储路径
+ */
+ public Map<String, Object> mergeChunks(String md5,
+ String fileName,
+ String uploadPath);
+
+}
diff --git a/ard-inspection/src/main/java/com/ard/inspection/service/impl/BigFileUploadServiceImpl.java b/ard-inspection/src/main/java/com/ard/inspection/service/impl/BigFileUploadServiceImpl.java
new file mode 100644
index 0000000..0daf7a3
--- /dev/null
+++ b/ard-inspection/src/main/java/com/ard/inspection/service/impl/BigFileUploadServiceImpl.java
@@ -0,0 +1,139 @@
+package com.ard.inspection.service.impl;
+
+import com.ard.inspection.service.IBigFileUploadService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * @author xia
+ */
+@Service
+@Slf4j
+public class BigFileUploadServiceImpl implements IBigFileUploadService {
+
+ @Override
+ public Map<String, Object> checkChunk(String fileMd5,String chunkPath) {
+ Map<String, Object> result = new HashMap<>();
+ try {
+ File chunkFolder = new File(chunkPath + File.separator + fileMd5);
+ if (!chunkFolder.exists()) {
+ result.put("exception", "分片不存在!!!");
+ return result;
+ }
+
+ File[] chunks = chunkFolder.listFiles();
+ if (chunks == null || chunks.length == 0) {
+ result.put("exception", "无分片!!!");
+ return result;
+ }
+
+ List<Integer> uploadedChunks = Arrays.stream(chunks)
+ .map(file -> Integer.parseInt(file.getName().split("\\.")[0]))
+ .collect(Collectors.toList());
+ result.put("message", uploadedChunks);
+ return result;
+ } catch (Exception e) {
+ log.error("检查分片失败", e);
+ result.put("exception", "检查分片失败!!!");
+ return result;
+ }
+ }
+
+ @Override
+ public Map<String, Object> uploadChunk(MultipartFile file,
+ Integer chunkNumber,
+ String fileMd5,
+ String chunkPath) {
+ Map<String, Object> result = new HashMap<>();
+ try {
+ // 验证参数
+ if (file.isEmpty()) {
+ result.put("exception", "文件不能为空!!!");
+ return result;
+ }
+
+ // 创建分片目录
+ String chunkDirPath = chunkPath + File.separator + fileMd5;
+ File chunkDir = new File(chunkDirPath);
+ if (!chunkDir.exists()) {
+ chunkDir.mkdirs();
+ }
+
+ // 保存分片
+ String chunkFileName = chunkNumber + ".part";
+ File chunkFile = new File(chunkDir, chunkFileName);
+ file.transferTo(chunkFile);
+
+ result.put("message", "分片上传成功!!!");
+ return result;
+ } catch (IOException e) {
+ log.error("分片上传失败", e);
+ result.put("exception", "分片上传失败!!!");
+ return result;
+ }
+ }
+
+ @Override
+ public Map<String, Object> mergeChunks(String md5,String fileName,String uploadPath) {
+ Map<String, Object> result = new HashMap<>();
+ // 临时目录
+ String chunkDir = uploadPath + File.separator + md5;
+ File dir = new File(chunkDir);
+ if (!dir.exists()) {
+ result.put("exception", "切片目录不存在");
+ return result;
+ }
+ // 获取所有切片文件
+ File[] chunks = dir.listFiles();
+ if (chunks == null || chunks.length == 0) {
+ result.put("exception", "没有切片文件");
+ return result;
+ }
+ // 按照切片索引排序
+ Arrays.sort(chunks, (a, b) -> {
+ int aIndex = Integer.parseInt(a.getName().split("\\.")[0]);
+ int bIndex = Integer.parseInt(b.getName().split("\\.")[0]);
+ return aIndex - bIndex;
+ });
+
+ // 合并后的文件,这里使用原始文件名,为了避免重名,可以加上时间戳或使用UUID
+ // 这里根据业务需求,可以保存到数据库,记录文件路径等信息
+ String ext = fileName.substring(fileName.lastIndexOf("."));
+ String newFileName = UUID.randomUUID().toString().replace("-", "") + ext; // 生成新文件名
+ File mergeFile = new File(uploadPath, newFileName);
+
+ try (RandomAccessFile randomAccessFile = new RandomAccessFile(mergeFile, "rw")) {
+ byte[] buffer = new byte[1024 * 1024]; // 1MB缓冲区
+ for (File chunk : chunks) {
+ try (RandomAccessFile chunkFile = new RandomAccessFile(chunk, "r")) {
+ int len;
+ while ((len = chunkFile.read(buffer)) != -1) {
+ randomAccessFile.write(buffer, 0, len);
+ }
+ }
+ // 删除切片文件
+ chunk.delete();
+ }
+ // 删除临时目录
+ dir.delete();
+ } catch (IOException e) {
+ log.error("合并文件失败", e);
+ result.put("exception", "合并文件失败");
+ return result;
+ }
+
+ // 这里可以保存文件信息到数据库,例如文件路径、文件名、md5等
+ // fileService.saveFileInfo(...);
+
+ result.put("message", "文件合并成功");
+ return result;
+ }
+
+}
diff --git a/ard-route/pom.xml b/ard-route/pom.xml
index 4bdfa32..fad44dd 100644
--- a/ard-route/pom.xml
+++ b/ard-route/pom.xml
@@ -59,6 +59,11 @@
<groupId>com.ard</groupId>
<artifactId>ard-work</artifactId>
</dependency>
+ <!--websocket依赖-->
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-websocket</artifactId>
+ </dependency>
</dependencies>
diff --git a/ard-route/src/main/java/com/ard/route/domain/route/ArdRouteMission.java b/ard-route/src/main/java/com/ard/route/domain/route/ArdRouteMission.java
index 8edb55d..77f6194 100644
--- a/ard-route/src/main/java/com/ard/route/domain/route/ArdRouteMission.java
+++ b/ard-route/src/main/java/com/ard/route/domain/route/ArdRouteMission.java
@@ -33,11 +33,23 @@
*/
private String executeStatus;
- /** 执行人 */
- private String executeBy;
+ /** 执行人ID */
+ private Long executeId;
+
+ /** 执行人姓名 */
+ private String executeName;
/** 执行时间 */
private Date executeTime;
+
+ /** 下发人ID */
+ private Long issuerId;
+
+ /** 下发人姓名 */
+ private String issuerName;
+
+ /** 下发时间 */
+ private Date issuerTime;
/**
* 任务类型
@@ -46,10 +58,17 @@
* */
private String taskType;
- /** 航线任务航点列表 */
- private List<ArdRoutePoint> missionDetailList;
-
/** 任务描述 */
private String taskDescription;
+ /**
+ * 是否已读
+ * 0:否
+ * 1:是
+ * */
+ private String isRead;
+
+ /** 航线任务航点列表 */
+ private List<ArdRoutePoint> missionDetailList;
+
}
diff --git a/ard-route/src/main/java/com/ard/route/mapper/ArdRouteMissionMapper.java b/ard-route/src/main/java/com/ard/route/mapper/ArdRouteMissionMapper.java
index 9d02438..2d55ae3 100644
--- a/ard-route/src/main/java/com/ard/route/mapper/ArdRouteMissionMapper.java
+++ b/ard-route/src/main/java/com/ard/route/mapper/ArdRouteMissionMapper.java
@@ -68,6 +68,15 @@
* @param executeStatus 状态类型
* @return 结果
*/
- public int updateArdRouteMissionStatus(@Param("id")String id, @Param("executeStatus")String executeStatus);
+ public int updateArdRouteMissionStatus(@Param("id")String id,@Param("executeStatus")String executeStatus);
+
+ /**
+ * 批量修改航线任务已读状态
+ *
+ * @param ids 主键集合
+ * @param isRead 已读状态
+ * @return 结果
+ */
+ public int updateIsRead(@Param("id")String[] ids,@Param("isRead")String isRead);
}
diff --git a/ard-route/src/main/java/com/ard/route/service/IArdRouteMissionService.java b/ard-route/src/main/java/com/ard/route/service/IArdRouteMissionService.java
index b41bdcb..e2e55d4 100644
--- a/ard-route/src/main/java/com/ard/route/service/IArdRouteMissionService.java
+++ b/ard-route/src/main/java/com/ard/route/service/IArdRouteMissionService.java
@@ -69,4 +69,13 @@
*/
public int updateArdRouteMissionStatus(String id,String status);
+ /**
+ * 批量修改航线任务已读状态
+ *
+ * @param ids 主键集合
+ * @param isRead 已读状态
+ * @return 结果
+ */
+ public int updateIsRead(String[] ids,String isRead);
+
}
diff --git a/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java b/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java
index 136018d..f6859f7 100644
--- a/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java
+++ b/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java
@@ -198,7 +198,7 @@
if ("0".equals(mission.getExecuteStatus())) {
mission.setRouteId(ardRouteInfo.getId());
mission.setExecuteStatus("1");
- mission.setExecuteBy(SecurityUtils.getUsername());
+ mission.setExecuteName(SecurityUtils.getUsername());
mission.setExecuteTime(DateUtils.getNowDate());
mission.setUpdateTime(DateUtils.getNowDate());
ardRouteMissionMapper.updateArdRouteMission(mission);
diff --git a/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteMissionServiceImpl.java b/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteMissionServiceImpl.java
index f3e54d2..e23626c 100644
--- a/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteMissionServiceImpl.java
+++ b/ard-route/src/main/java/com/ard/route/service/impl/ArdRouteMissionServiceImpl.java
@@ -1,18 +1,23 @@
package com.ard.route.service.impl;
import java.util.List;
+
+import com.alibaba.fastjson2.JSON;
+import com.ard.common.core.domain.entity.SysUser;
import com.ard.common.utils.DateUtils;
import com.ard.common.utils.SecurityUtils;
import com.ard.common.utils.uuid.IdUtils;
import com.ard.route.domain.route.ArdRouteMission;
import com.ard.route.domain.route.ArdRoutePoint;
import com.ard.route.mapper.ArdRoutePointMapper;
+import com.ard.route.websocket.utils.MiWebSocketUtils;
+import com.ard.system.mapper.SysUserMapper;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ard.route.mapper.ArdRouteMissionMapper;
import com.ard.route.service.IArdRouteMissionService;
-import static com.ard.common.utils.SecurityUtils.getUsername;
/**
* 航线任务Service业务层处理
@@ -21,6 +26,7 @@
* @date 2026-01-20
*/
@Service
+@Slf4j
public class ArdRouteMissionServiceImpl implements IArdRouteMissionService {
@Autowired
@@ -28,6 +34,9 @@
@Autowired
private ArdRoutePointMapper ardRoutePointMapper;
+
+ @Autowired
+ private SysUserMapper sysUserMapper;
/**
* 查询航线任务
@@ -71,8 +80,16 @@
public int insertArdRouteMission(ArdRouteMission ardRouteMission) {
ardRouteMission.setId(IdUtils.simpleUUID());
ardRouteMission.setExecuteStatus("0");
+ ardRouteMission.setIsRead("0");
ardRouteMission.setCreateTime(DateUtils.getNowDate());
+ ardRouteMission.setIssuerName(getUserName(ardRouteMission.getIssuerId()));
dataProcessingRoutePoint(ardRouteMission.getMissionDetailList(),ardRouteMission.getId());
+ try {
+ log.debug("给用户{}定时推送,航线任务信息", ardRouteMission.getIssuerName());
+ MiWebSocketUtils.sendMessage(ardRouteMission.getIssuerId(),JSON.toJSONString(ardRouteMission));
+ } catch (Exception e) {
+ log.error("Error sending message to session {}", ardRouteMission.getIssuerName(), e);
+ }
return ardRouteMissionMapper.insertArdRouteMission(ardRouteMission);
}
@@ -85,11 +102,18 @@
@Override
public int updateArdRouteMission(ArdRouteMission ardRouteMission) {
ardRouteMission.setUpdateTime(DateUtils.getNowDate());
+ ardRouteMission.setIssuerName(getUserName(ardRouteMission.getIssuerId()));
// 删除航线任务航点
ardRoutePointMapper.deleteArdRoutePointByMissionId(ardRouteMission.getId());
// 重新插入航线任务航点
dataProcessingRoutePoint(ardRouteMission.getMissionDetailList(),ardRouteMission.getId());
return ardRouteMissionMapper.updateArdRouteMission(ardRouteMission);
+ }
+
+ // 获取用户名称
+ private String getUserName(Long userId) {
+ SysUser sysUser = sysUserMapper.selectUserById(userId);
+ return sysUser.getUserName();
}
/**
@@ -139,10 +163,22 @@
ArdRouteMission ardRouteMission = new ArdRouteMission();
ardRouteMission.setId(id);
ardRouteMission.setExecuteStatus(status);
- ardRouteMission.setExecuteBy(SecurityUtils.getUsername());
+ ardRouteMission.setExecuteName(SecurityUtils.getUsername());
ardRouteMission.setExecuteTime(DateUtils.getNowDate());
ardRouteMission.setUpdateTime(DateUtils.getNowDate());
return ardRouteMissionMapper.updateArdRouteMission(ardRouteMission);
}
+ /**
+ * 批量修改航线任务已读状态
+ *
+ * @param ids 主键集合
+ * @param isRead 已读状态
+ * @return 结果
+ */
+ @Override
+ public int updateIsRead(String[] ids, String isRead) {
+ return ardRouteMissionMapper.updateIsRead(ids,isRead);
+ }
+
}
diff --git a/ard-route/src/main/java/com/ard/route/websocket/config/MiWebSocketConfig.java b/ard-route/src/main/java/com/ard/route/websocket/config/MiWebSocketConfig.java
new file mode 100644
index 0000000..d207936
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/websocket/config/MiWebSocketConfig.java
@@ -0,0 +1,28 @@
+package com.ard.route.websocket.config;
+
+import com.ard.route.websocket.handler.MiWebSocketHandler;
+import com.ard.route.websocket.interceptor.MiHandshakeInterceptor;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+
+import javax.annotation.Resource;
+
+@Configuration
+@EnableWebSocket
+public class MiWebSocketConfig implements WebSocketConfigurer {
+
+ @Resource
+ private MiWebSocketHandler miWebSocketHandler;
+
+ @Override
+ public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+ //添加myWebSocketHandler消息处理对象以及websocket连接地址
+ registry.addHandler(miWebSocketHandler, "/ws/mission/**")
+ //设置允许跨域访问
+ .setAllowedOrigins("*")
+ //添加拦截器可实现用户链接前进行权限校验等操作
+ .addInterceptors(new MiHandshakeInterceptor());
+ }
+}
diff --git a/ard-route/src/main/java/com/ard/route/websocket/handler/MiWebSocketHandler.java b/ard-route/src/main/java/com/ard/route/websocket/handler/MiWebSocketHandler.java
new file mode 100644
index 0000000..9228529
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/websocket/handler/MiWebSocketHandler.java
@@ -0,0 +1,39 @@
+package com.ard.route.websocket.handler;
+
+import com.ard.route.websocket.utils.MiWebSocketUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.web.socket.CloseStatus;
+import org.springframework.web.socket.TextMessage;
+import org.springframework.web.socket.WebSocketSession;
+import org.springframework.web.socket.handler.TextWebSocketHandler;
+
+@Component
+@Slf4j
+public class MiWebSocketHandler extends TextWebSocketHandler {
+
+ @Override
+ public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
+ // 处理接收到的消息
+ String payload = message.getPayload();
+ log.info("【mi_websocket】Received message: " + payload);
+ log.info("【mi_websocket】size: " + MiWebSocketUtils.ONLINE_USER_SESSIONS.size());
+ }
+
+ @Override
+ public void afterConnectionEstablished(WebSocketSession session) {
+ log.info("【mi_websocket】Connected: " + session.getId());
+ String userId = (String) session.getAttributes().get("userId");
+ MiWebSocketUtils.ONLINE_USER_SESSIONS.put(userId, session);
+ log.info("【mi_websocket】size: " + MiWebSocketUtils.ONLINE_USER_SESSIONS.size());
+ }
+
+ @Override
+ public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
+ log.info("【mi_websocket】Disconnected: " + session.getId());
+ String userId = (String) session.getAttributes().get("userId");
+ MiWebSocketUtils.ONLINE_USER_SESSIONS.remove(userId);
+ log.info("【mi_websocket】size: " + MiWebSocketUtils.ONLINE_USER_SESSIONS.size());
+ }
+
+}
diff --git a/ard-route/src/main/java/com/ard/route/websocket/interceptor/MiHandshakeInterceptor.java b/ard-route/src/main/java/com/ard/route/websocket/interceptor/MiHandshakeInterceptor.java
new file mode 100644
index 0000000..9d29610
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/websocket/interceptor/MiHandshakeInterceptor.java
@@ -0,0 +1,32 @@
+package com.ard.route.websocket.interceptor;
+
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.socket.WebSocketHandler;
+
+import java.util.Map;
+
+public class MiHandshakeInterceptor implements org.springframework.web.socket.server.HandshakeInterceptor {
+ @Override
+ public boolean beforeHandshake(ServerHttpRequest request,
+ ServerHttpResponse response,
+ WebSocketHandler wsHandler,
+ Map<String, Object> attributes) throws Exception {
+ //从路径中获取userId
+ String path = request.getURI().getPath();
+ String[] segments = path.split("/");
+ if (segments.length > 2) {
+ String userId = segments[segments.length - 1];
+ attributes.put("userId", userId);
+ }
+ return true;
+ }
+
+ @Override
+ public void afterHandshake(ServerHttpRequest request,
+ ServerHttpResponse response,
+ WebSocketHandler wsHandler,
+ Exception exception) {
+
+ }
+}
diff --git a/ard-route/src/main/java/com/ard/route/websocket/utils/MiWebSocketUtils.java b/ard-route/src/main/java/com/ard/route/websocket/utils/MiWebSocketUtils.java
new file mode 100644
index 0000000..eae6628
--- /dev/null
+++ b/ard-route/src/main/java/com/ard/route/websocket/utils/MiWebSocketUtils.java
@@ -0,0 +1,131 @@
+package com.ard.route.websocket.utils;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.ard.work.component.websocket.WebSocketSessionManager;
+import com.ard.work.component.websocket.utils.WebSocketUtil;
+import com.ard.work.domain.message.BaseMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.socket.TextMessage;
+import org.springframework.web.socket.WebSocketSession;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+@Slf4j
+public class MiWebSocketUtils {
+
+ // 用于存储所有打开的WebSocket会话
+ public static final ConcurrentMap<String, WebSocketSession> ONLINE_USER_SESSIONS = new ConcurrentHashMap<>();
+
+ /**
+ * @param session 用户 session
+ * @param message 发送内容
+ */
+ public static void sendMessage(WebSocketSession session, String message) {
+ if (session == null) {
+ return;
+ }
+ final InetSocketAddress remoteAddress = session.getRemoteAddress();
+ if (remoteAddress == null) {
+ return;
+ }
+ synchronized (session) {
+ try {
+ log.debug("发送消息:" + message);
+ session.sendMessage(new TextMessage(String.join(", ", message)));
+ } catch (IOException e) {
+ log.error("sendMessage IOException ", e);
+ }
+ }
+ }
+
+ public static void sendMessage(Long userId, String message) {
+ WebSocketSession session = WebSocketSessionManager.getSession(userId);
+ sendMessage(session, message);
+ }
+
+ /**
+ * @param session 用户 session
+ * @param message 发送内容
+ */
+ public static void sendMessage(WebSocketSession session, Map message) {
+ if (session == null) {
+ return;
+ }
+ final InetSocketAddress remoteAddress = session.getRemoteAddress();
+ if (remoteAddress == null) {
+ return;
+ }
+ synchronized (session) {
+ try {
+ session.sendMessage(new TextMessage(JSONObject.toJSONString(message)));
+ } catch (IOException e) {
+ log.error("sendMessage IOException ", e);
+ }
+ }
+ }
+
+ public static void sendMessage(WebSocketSession session, List message) {
+ if (session == null) {
+ return;
+ }
+ final InetSocketAddress remoteAddress = session.getRemoteAddress();
+ if (remoteAddress == null) {
+ return;
+ }
+ synchronized (session) {
+ try {
+ session.sendMessage(new TextMessage(JSONObject.toJSONString(message)));
+ } catch (IOException e) {
+ log.error("sendMessage IOException ", e);
+ }
+ }
+ }
+
+ /**
+ * 推送消息到其他客户端
+ *
+ * @param message
+ */
+ public static void sendMessageAll(String message) {
+ ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, message));
+ }
+
+ /**
+ * 推送消息到其他客户端
+ *
+ * @param message
+ */
+ public static void sendMessageAll(Map message) {
+ JSONObject jsonObject = new JSONObject(message);
+ ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, jsonObject.toString()));
+ }
+
+ /**
+ * 推送消息到其他客户端
+ *
+ * @param message
+ */
+ public static void sendMessageAll(List message) {
+ ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, JSON.toJSONString(message)));
+ }
+
+ // 发送消息到所有 WebSocket 客户端
+ public static <T> void sendToAll(BaseMessage<T> baseMessage) {
+ WebSocketUtil.sendMessageAll(baseMessage); // 你已有的 WebSocket 发送逻辑
+ }
+
+ // 根据消息类型和内容创建消息并发送
+ public static <T> void sendMessage(String type, T payload) {
+ BaseMessage<T> baseMessage = BaseMessage.<T>builder()
+ .type(type)
+ .payload(payload)
+ .build();
+ sendToAll(baseMessage);
+ }
+}
diff --git a/ard-route/src/main/resources/mapper/ArdRouteMissionMapper.xml b/ard-route/src/main/resources/mapper/ArdRouteMissionMapper.xml
index 895f203..b3c6aef 100644
--- a/ard-route/src/main/resources/mapper/ArdRouteMissionMapper.xml
+++ b/ard-route/src/main/resources/mapper/ArdRouteMissionMapper.xml
@@ -13,10 +13,15 @@
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
- <result property="executeBy" column="execute_by" />
+ <result property="executeId" column="execute_id" />
+ <result property="executeName" column="execute_name" />
<result property="executeTime" column="execute_time" />
+ <result property="issuerId" column="issuer_id" />
+ <result property="issuerName" column="issuer_name" />
+ <result property="issuerTime" column="issuer_time" />
<result property="taskType" column="task_type" />
<result property="taskDescription" column="task_description" />
+ <result property="isRead" column="is_read" />
</resultMap>
<sql id="selectArdRouteMissionVo">
@@ -28,22 +33,32 @@
create_time,
update_by,
update_time,
- execute_by,
+ execute_id,
+ execute_name,
execute_time,
task_type,
- task_description
+ task_description,
+ is_read,
+ issuer_id,
+ issuer_name,
+ issuer_time
from ard_route_mission
</sql>
<select id="selectArdRouteMissionList" parameterType="ArdRouteMission" resultMap="ArdRouteMissionResult">
<include refid="selectArdRouteMissionVo"/>
<where>
- <if test="routeId != null and routeId != ''"> and route_id = #{routeId}</if>
- <if test="missionName != null and missionName != ''"> and mission_name like concat('%', #{missionName}, '%')</if>
- <if test="executeStatus != null and executeStatus != ''"> and execute_status = #{executeStatus}</if>
- <if test="executeBy != null and executeBy != ''"> and execute_by = #{executeBy}</if>
+ <if test="routeId != null and routeId != ''"> and route_id = #{routeId}</if>
+ <if test="missionName != null and missionName != ''"> and mission_name like concat('%', #{missionName}, '%')</if>
+ <if test="executeStatus != null and executeStatus != ''"> and execute_status = #{executeStatus}</if>
+ <if test="executeId != null and executeId != ''"> and execute_id = #{executeId}</if>
+ <if test="executeName != null and executeName != ''"> and execute_name like concat('%', #{executeName}, '%')</if>
<if test="executeTime != null "> and execute_time = #{executeTime}</if>
- <if test="taskType != null and taskType != ''"> and task_type = #{taskType}</if>
+ <if test="issuerId != null and issuerId != ''"> and issuer_id = #{issuerId}</if>
+ <if test="issuerName != null and issuerName != ''"> and issuer_name like concat('%', #{issuerName}, '%')</if>
+ <if test="issuerTime != null "> and issuer_time = #{issuerTime}</if>
+ <if test="taskType != null and taskType != ''"> and task_type = #{taskType}</if>
+ <if test="isRead != null and isRead != ''"> and is_read = #{isRead}</if>
</where>
order by create_time DESC
</select>
@@ -65,10 +80,15 @@
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
- <if test="executeBy != null">execute_by,</if>
+ <if test="executeId != null">execute_id,</if>
+ <if test="executeName != null">execute_name,</if>
<if test="executeTime != null">execute_time,</if>
+ <if test="issuerId != null">issuer_id,</if>
+ <if test="issuerName != null">issuer_name,</if>
+ <if test="issuerTime != null">issuer_time,</if>
<if test="taskType != null">task_type,</if>
<if test="taskDescription != null">task_description,</if>
+ <if test="isRead != null">is_read,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if>
@@ -79,10 +99,15 @@
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
- <if test="executeBy != null">#{executeBy},</if>
+ <if test="executeId != null">#{executeId},</if>
+ <if test="executeName != null">#{executeName},</if>
<if test="executeTime != null">#{executeTime},</if>
+ <if test="issuerId != null">#{issuerId},</if>
+ <if test="issuerName != null">#{issuerName},</if>
+ <if test="issuerTime != null">#{issuerTime},</if>
<if test="taskType != null">#{taskType},</if>
<if test="taskDescription != null">#{taskDescription},</if>
+ <if test="isRead != null">#{isRead},</if>
</trim>
</insert>
@@ -96,10 +121,15 @@
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
- <if test="executeBy != null">execute_by = #{executeBy},</if>
+ <if test="executeId != null">execute_id = #{executeId},</if>
+ <if test="executeName != null">execute_name = #{executeName},</if>
<if test="executeTime != null">execute_time = #{executeTime},</if>
+ <if test="issuerId != null">issuer_id = #{issuerId},</if>
+ <if test="issuerName != null">issuer_name = #{issuerName},</if>
+ <if test="issuerTime != null">issuer_time = #{issuerTime},</if>
<if test="taskType != null">task_type = #{taskType},</if>
<if test="taskDescription != null">task_description = #{taskDescription},</if>
+ <if test="isRead != null">is_read = #{isRead},</if>
</trim>
where id = #{id}
</update>
@@ -123,4 +153,23 @@
where id = #{id}
</update>
+ <update id="updateArdRouteMissionStatus">
+ update ard_route_mission
+ <trim prefix="SET" suffixOverrides=",">
+ <if test="executeStatus != null">execute_status = #{executeStatus},</if>
+ </trim>
+ where id = #{id}
+ </update>
+
+ <update id="updateIsRead">
+ update ard_route_mission
+ <trim prefix="SET" suffixOverrides=",">
+ <if test="isRead != null">is_read = #{isRead},</if>
+ </trim>
+ where id in
+ <foreach item="id" collection="array" open="(" separator="," close=")">
+ #{id}
+ </foreach>
+ </update>
+
</mapper>
\ No newline at end of file
diff --git a/ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java b/ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java
index ed5d4bb..f03d7c3 100644
--- a/ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java
+++ b/ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java
@@ -637,6 +637,9 @@
/**
* 环绕飞行控制
*/
+// @CheckControlRight(UavControlType.FLY)
+// @CheckTakeoffAltitude
+// @CheckNoFlyZone
@Override
public Boolean FlyRoundControl(FlyRoundControlDTO flyRoundControlDTO) {
String boxSn = flyRoundControlDTO.getBoxSn();
--
Gitblit v1.9.3