Xiajijian
2026-02-05 5ea2094378f25a3f98d8f370dafaf9367c05c2e5
1. 增加任务航线websocket。
2. 增加执行人id信息,下发人id信息。
6 files added
10 files modified
630 ■■■■■ changed files
ard-admin/src/main/java/com/ard/web/controller/inspection/BigFileUploadController.java 60 ●●●●● patch | view | raw | blame | history
ard-admin/src/main/java/com/ard/web/controller/route/ArdRouteMissionController.java 11 ●●●●● patch | view | raw | blame | history
ard-inspection/src/main/java/com/ard/inspection/service/IBigFileUploadService.java 42 ●●●●● patch | view | raw | blame | history
ard-inspection/src/main/java/com/ard/inspection/service/impl/BigFileUploadServiceImpl.java 139 ●●●●● patch | view | raw | blame | history
ard-route/pom.xml 5 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/domain/route/ArdRouteMission.java 29 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/mapper/ArdRouteMissionMapper.java 9 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/IArdRouteMissionService.java 9 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteInfoServiceImpl.java 2 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteMissionServiceImpl.java 28 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/websocket/config/MiWebSocketConfig.java 28 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/websocket/handler/MiWebSocketHandler.java 39 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/websocket/interceptor/MiHandshakeInterceptor.java 32 ●●●●● patch | view | raw | blame | history
ard-route/src/main/java/com/ard/route/websocket/utils/MiWebSocketUtils.java 131 ●●●●● patch | view | raw | blame | history
ard-route/src/main/resources/mapper/ArdRouteMissionMapper.xml 63 ●●●●● patch | view | raw | blame | history
ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java 3 ●●●●● patch | view | raw | blame | history
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);
    }
}
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));
    }
}
ard-inspection/src/main/java/com/ard/inspection/service/IBigFileUploadService.java
New file
@@ -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);
}
ard-inspection/src/main/java/com/ard/inspection/service/impl/BigFileUploadServiceImpl.java
New file
@@ -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;
    }
}
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>
ard-route/src/main/java/com/ard/route/domain/route/ArdRouteMission.java
@@ -33,11 +33,23 @@
     */
    private String executeStatus;
    /** 执行人 */
    private String executeBy;
    /** 执行人ID */
    private Integer executeId;
    /** 执行人ID */
    private String executeName;
    /** 执行时间 */
    private Date executeTime;
    /** 下发人ID */
    private Integer 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;
}
ard-route/src/main/java/com/ard/route/mapper/ArdRouteMissionMapper.java
@@ -69,5 +69,14 @@
     * @return 结果
     */
    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);
}
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);
}
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);
ard-route/src/main/java/com/ard/route/service/impl/ArdRouteMissionServiceImpl.java
@@ -1,18 +1,21 @@
package com.ard.route.service.impl;
import java.util.List;
import com.alibaba.fastjson2.JSON;
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 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 +24,7 @@
 * @date 2026-01-20
 */
@Service
@Slf4j
public class ArdRouteMissionServiceImpl implements IArdRouteMissionService {
    @Autowired
@@ -71,8 +75,16 @@
    public int insertArdRouteMission(ArdRouteMission ardRouteMission) {
        ardRouteMission.setId(IdUtils.simpleUUID());
        ardRouteMission.setExecuteStatus("0");
        ardRouteMission.setIsRead("0");
        ardRouteMission.setCreateTime(DateUtils.getNowDate());
        dataProcessingRoutePoint(ardRouteMission.getMissionDetailList(),ardRouteMission.getId());
        Long userId = ardRouteMission.getIssuerId().longValue();
        try {
            log.debug("给用户{}定时推送,航线任务信息", ardRouteMission.getIssuerName());
            MiWebSocketUtils.sendMessage(userId,JSON.toJSONString(ardRouteMission));
        } catch (Exception e) {
            log.error("Error sending message to session {}", ardRouteMission.getIssuerName(), e);
        }
        return ardRouteMissionMapper.insertArdRouteMission(ardRouteMission);
    }
@@ -139,10 +151,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);
    }
}
ard-route/src/main/java/com/ard/route/websocket/config/MiWebSocketConfig.java
New file
@@ -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());
    }
}
ard-route/src/main/java/com/ard/route/websocket/handler/MiWebSocketHandler.java
New file
@@ -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());
    }
}
ard-route/src/main/java/com/ard/route/websocket/interceptor/MiHandshakeInterceptor.java
New file
@@ -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) {
    }
}
ard-route/src/main/java/com/ard/route/websocket/utils/MiWebSocketUtils.java
New file
@@ -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);
    }
}
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,10 +33,15 @@
               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>
@@ -41,9 +51,14 @@
            <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="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="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>
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();