From eb92bf8c9e0278655b058e31b15be278fddacc2c Mon Sep 17 00:00:00 2001
From: liusuyi <1951119284@qq.com>
Date: Tue, 11 Nov 2025 10:20:11 +0800
Subject: [PATCH] 增加无人机状态和禁飞区检查

---
 ard-work/src/main/java/com/ard/work/aspect/annotation/CheckDroneStatus.java               |   15 +
 ard-work/src/main/java/com/ard/work/aspect/annotation/CheckNoFlyZone.java                 |   14 +
 ard-work/src/main/java/com/ard/work/aspect/annotation/CheckControlRight.java              |    3 
 ard-work/src/main/java/com/ard/work/service/impl/TyServiceImpl.java                       |  298 +++++++-----------------------------
 ard-work/src/main/java/com/ard/work/aspect/UavControlAspect.java                          |  145 ++++++++++++-----
 ard-work/src/main/java/com/ard/work/aspect/annotation/CheckTakeoffAltitude.java           |    3 
 ard-system/src/main/java/com/ard/data/noflyzone/service/impl/ArdNoFlyZoneServiceImpl.java |    2 
 7 files changed, 196 insertions(+), 284 deletions(-)

diff --git a/ard-system/src/main/java/com/ard/data/noflyzone/service/impl/ArdNoFlyZoneServiceImpl.java b/ard-system/src/main/java/com/ard/data/noflyzone/service/impl/ArdNoFlyZoneServiceImpl.java
index 8f4c338..56e2c48 100644
--- a/ard-system/src/main/java/com/ard/data/noflyzone/service/impl/ArdNoFlyZoneServiceImpl.java
+++ b/ard-system/src/main/java/com/ard/data/noflyzone/service/impl/ArdNoFlyZoneServiceImpl.java
@@ -100,4 +100,6 @@
     {
         return ardNoFlyZoneMapper.deleteArdNoFlyZoneById(id);
     }
+
+
 }
diff --git a/ard-work/src/main/java/com/ard/work/aspect/UavControlAspect.java b/ard-work/src/main/java/com/ard/work/aspect/UavControlAspect.java
index f796aa1..06ee04a 100644
--- a/ard-work/src/main/java/com/ard/work/aspect/UavControlAspect.java
+++ b/ard-work/src/main/java/com/ard/work/aspect/UavControlAspect.java
@@ -1,11 +1,23 @@
 package com.ard.work.aspect;
 
+import com.ard.common.constant.CacheConstants;
+import com.ard.common.core.redis.RedisCache;
 import com.ard.common.exception.ControlException;
 import com.ard.common.utils.SecurityUtils;
+import com.ard.common.utils.StringUtils;
+import com.ard.common.utils.reflect.ReflectUtils;
+import com.ard.data.noflyzone.domain.ArdNoFlyZone;
+import com.ard.data.noflyzone.domain.Vertex;
+import com.ard.data.noflyzone.service.IArdNoFlyZoneService;
+import com.ard.data.noflyzone.utils.NoFlyZoneUtils;
+import com.ard.work.aspect.annotation.CheckDroneStatus;
+import com.ard.work.aspect.annotation.CheckNoFlyZone;
 import com.ard.work.aspect.annotation.CheckTakeoffAltitude;
 import com.ard.work.aspect.annotation.CheckControlRight;
 import com.ard.work.domain.cache.UavTelemetryDataCache;
 import com.ard.work.domain.dto.telemetry.TelemetryData;
+import com.ard.work.domain.entity.ArdDroneInfo;
+import com.ard.work.service.IArdDroneInfoService;
 import com.ard.work.service.control.UavControlService;
 import com.ard.work.domain.message.UavControlType;
 import org.aspectj.lang.JoinPoint;
@@ -14,11 +26,11 @@
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
-import java.lang.reflect.Field;
+import java.util.List;
 
 /**
- * AOP 切面:拦截 @RequireUavControl,检查用户是否拥有 UAV 控制权限
- *
+ * 无人机控制切面
+ * <p>
  * 注意切面顺序:同类方法注解按字母ABCD顺序,不同类注解按order(1)顺序 越小优先级越高
  */
 @Aspect
@@ -27,9 +39,13 @@
 
     @Resource
     private UavControlService uavControlService;
+    @Resource
+    private IArdNoFlyZoneService ardNoFlyZoneService;
+    @Resource
+    private RedisCache redisCache;
 
     /**
-     * 前置通知:控制权检测
+     * 控制权检查
      */
     @Before("@annotation(checkControlRight)")
     public void checkUavControl(JoinPoint joinPoint, CheckControlRight checkControlRight) {
@@ -42,22 +58,35 @@
         // 获取方法参数
         Object[] args = joinPoint.getArgs();
 
-        // 遍历参数,使用反射获取每个参数中的 boxSn
         for (Object arg : args) {
-            String boxSn = getBoxSn(arg);  // 调用之前实现的 getBoxSn 方法
-            if (boxSn != null) {
-                // 检查当前用户是否拥有该设备的控制权限
-                Long currentController = uavControlService.getCurrentController(boxSn,
-                        controlType.name().toLowerCase());
-                if (currentController == null || !currentController.equals(userId)) {
-                    throw new ControlException("无权执行该操作,需要 " + controlType + " 控制权限");
-                }
+            if (arg == null) {
+                continue;
             }
+
+            // 1️⃣ 获取 boxSn
+            String boxSn = ReflectUtils.getFieldValue(arg, "boxSn");
+            if (StringUtils.isBlank(boxSn)) {
+                continue;
+            }
+
+            // 2️⃣ 检查控制权
+            Long currentController = uavControlService.getCurrentController(boxSn,
+                    controlType.name().toLowerCase());
+            if (currentController == null || !currentController.equals(userId)) {
+                throw new ControlException("无权执行该操作,需要 " + controlType + " 控制权限");
+            }
+
+            // 3️⃣ 检查在线状态
+            Boolean online = redisCache.getCacheObject(CacheConstants.UAV_ONLINE_KEY + boxSn);
+            if (online == null || !online) {
+                throw new ControlException("无人机离线,无法执行操作!boxSn: " + boxSn);
+            }
+
         }
     }
 
     /**
-     * 前置通知:高度检查
+     * 高度检查
      */
     @Before("@annotation(checkTakeoffAltitude)")
     public void takeoffAltitudeCheck(JoinPoint joinPoint, CheckTakeoffAltitude checkTakeoffAltitude) {
@@ -68,7 +97,7 @@
 
         // 遍历参数,使用反射获取每个参数中的 boxSn
         for (Object arg : args) {
-            String boxSn = getBoxSn(arg);  // 调用之前实现的 getBoxSn 方法
+            String boxSn = ReflectUtils.getFieldValue(arg, "boxSn");  // 调用之前实现的 getBoxSn 方法
             if (boxSn != null) {
                 TelemetryData uavTelemetryData = UavTelemetryDataCache.get(boxSn);
                 if (uavTelemetryData == null) {
@@ -83,41 +112,67 @@
     }
 
     /**
-     * 通过反射获取对象中的 boxSn 字段
-     *
-     * @param dto 要反射的对象
-     * @return boxSn 字段的值,如果没有找到则返回 null
+     * 状态检查
      */
-    public static String getBoxSn(Object dto) {
-        if (dto == null) {
-            return null; // 如果对象为空,直接返回 null
-        }
+    @Before("@annotation(checkDroneStatus)")
+    public void checkDroneStatus(JoinPoint joinPoint, CheckDroneStatus checkDroneStatus) {
+        for (Object arg : joinPoint.getArgs()) {
+            if (arg == null) {
+                continue;
+            }
 
-        try {
-            // 获取类的所有字段
-            Field[] fields = dto.getClass().getDeclaredFields();
-            for (Field field : fields) {
-                // 设置字段可访问
-                field.setAccessible(true);
-
-                // 判断是否是 boxSn 字段
-                if ("boxSn".equals(field.getName())) {
-                    // 检查字段类型是否是 String 类型
-                    if (field.getType().equals(String.class)) {
-                        // 获取并返回 boxSn 字段的值
-                        return (String) field.get(dto);
-                    } else {
-                        // 如果字段类型不是 String,返回 null
-                        return null;
-                    }
+            String boxSn = ReflectUtils.getFieldValue(arg, "boxSn");
+            if (boxSn == null) {
+                continue;
+            }
+            // 检查在线状态
+            if (checkDroneStatus.checkOnline()) {
+                Boolean online = redisCache.getCacheObject(CacheConstants.UAV_ONLINE_KEY + boxSn);
+                if (online == null || !online) {
+                    throw new ControlException("无人机离线,无法执行操作!boxSn: " + boxSn);
                 }
             }
-        } catch (IllegalAccessException e) {
-            // 捕获异常并打印日志
-            System.err.println("反射访问失败: " + e.getMessage());
-            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 禁飞区检查
+     */
+    @Before("@annotation(checkNoFlyZone)")
+    public void checkNoFlyZone(JoinPoint joinPoint, CheckNoFlyZone checkNoFlyZone) {
+        Object[] args = joinPoint.getArgs();
+        if (args == null || args.length == 0) {
+            return;
         }
 
-        return null; // 如果没有找到 boxSn 字段,返回 null
+        Double longitude = null;
+        Double latitude = null;
+
+        for (Object arg : args) {
+            if (arg == null) {
+                continue;
+            }
+            Double lon = ReflectUtils.getFieldValue(arg, "longitude");
+            Double lat = ReflectUtils.getFieldValue(arg, "latitude");
+            if (lon != null && lat != null) {
+                longitude = lon;
+                latitude = lat;
+                break;
+            }
+        }
+
+        if (longitude == null || latitude == null) {
+            throw new ControlException("方法参数中未找到有效经纬度字段,无法判断禁飞区!");
+        }
+
+        List<ArdNoFlyZone> ardNoFlyZones = ardNoFlyZoneService.selectArdNoFlyZoneList(new ArdNoFlyZone());
+        if (!ardNoFlyZones.isEmpty()) {
+            Vertex vertex = new Vertex(longitude, latitude);
+            boolean inNoFlyZones = NoFlyZoneUtils.isInNoFlyZones(vertex, ardNoFlyZones);
+            if (inNoFlyZones) {
+                throw new ControlException("目标点在禁飞区内,无法执行操作!");
+            }
+        }
     }
+
 }
diff --git a/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckControlRight.java b/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckControlRight.java
index 55c3f34..f67e0c8 100644
--- a/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckControlRight.java
+++ b/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckControlRight.java
@@ -8,7 +8,8 @@
 import java.lang.annotation.Target;
 
 /**
- * 自定义注解:用于方法拦截,检查 UAV 控制权限
+ * 控制权限检查
+ * 包含无人机在线检查
  */
 @Target(ElementType.METHOD)   // 作用于方法
 @Retention(RetentionPolicy.RUNTIME) // 运行时生效
diff --git a/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckDroneStatus.java b/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckDroneStatus.java
new file mode 100644
index 0000000..e00f915
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckDroneStatus.java
@@ -0,0 +1,15 @@
+package com.ard.work.aspect.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 检查飞行器状态
+ *
+ */
+
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface CheckDroneStatus {
+    boolean checkOnline() default true;
+}
diff --git a/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckNoFlyZone.java b/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckNoFlyZone.java
new file mode 100644
index 0000000..0d7c228
--- /dev/null
+++ b/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckNoFlyZone.java
@@ -0,0 +1,14 @@
+package com.ard.work.aspect.annotation;
+
+import java.lang.annotation.*;
+
+
+/**
+ * 检查禁飞区
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface CheckNoFlyZone {
+    // 简化,不需要字段
+}
diff --git a/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckTakeoffAltitude.java b/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckTakeoffAltitude.java
index b765bc0..a9f3902 100644
--- a/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckTakeoffAltitude.java
+++ b/ard-work/src/main/java/com/ard/work/aspect/annotation/CheckTakeoffAltitude.java
@@ -5,6 +5,9 @@
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+/**
+ * 检查最低高度
+ */
 @Target(ElementType.METHOD)
 @Retention(RetentionPolicy.RUNTIME)
 public @interface CheckTakeoffAltitude {
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 311c6c8..7546230 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
@@ -1,14 +1,9 @@
 package com.ard.work.service.impl;
 
-import com.ard.common.constant.CacheConstants;
-import com.ard.common.core.redis.RedisCache;
-import com.ard.common.exception.ServiceException;
-import com.ard.common.utils.StringUtils;
-import com.ard.data.noflyzone.domain.ArdNoFlyZone;
-import com.ard.data.noflyzone.domain.Vertex;
-import com.ard.data.noflyzone.service.IArdNoFlyZoneService;
-import com.ard.data.noflyzone.utils.NoFlyZoneUtils;
+import com.ard.common.exception.ControlException;
 import com.ard.work.aspect.annotation.CheckControlRight;
+import com.ard.work.aspect.annotation.CheckDroneStatus;
+import com.ard.work.aspect.annotation.CheckNoFlyZone;
 import com.ard.work.aspect.annotation.CheckTakeoffAltitude;
 import com.ard.work.component.forest.TyClient;
 import com.ard.work.component.netty.TcpClientUtil;
@@ -60,7 +55,6 @@
 import com.ard.work.service.IArdServerInfoService;
 import com.ard.work.service.ITyService;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
@@ -82,11 +76,7 @@
     @Resource
     private IArdDroneInfoService ardDroneService;
     @Resource
-    private IArdNoFlyZoneService ardNoFlyZoneService;
-    @Resource
     private TyClient tyClient;
-    @Resource
-    private RedisCache redisCache;
 
     /**
      * 获取边缘服务器token信息
@@ -131,12 +121,10 @@
     public BoxStreamUrlReceiver getBoxLiveUrl(String boxSn) {
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
-        }
+        
+        
         TyHttpCommonReceiver<BoxStreamUrlReceiver> boxLiveUrl = tyClient.getBoxLiveUrl(ardDroneInfo.getServerId(),
                 boxSn);
         return boxLiveUrl == null ? null : boxLiveUrl.getContent();
@@ -152,11 +140,7 @@
         String boxSn = boxHistoryDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行起飞指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         TyHttpCommonReceiver<List<BoxHistoryReceiver>> boxHistory = tyClient.getBoxHistory(ardDroneInfo.getServerId(),
                 boxHistoryDTO);
@@ -173,11 +157,7 @@
         String boxSn = boxPhotosDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行起飞指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         TyHttpCommonReceiver<List<BoxPhotosReceiver>> boxPhotos = tyClient.getBoxPhotos(ardDroneInfo.getServerId(),
                 boxPhotosDTO);
@@ -192,11 +172,7 @@
         String boxSn = boxSettingsDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         TyHttpCommonReceiver<?> result = tyClient.updateBoxSettings(ardDroneInfo.getServerId(), boxSettingsDTO);
         return result.getState() == 1;
@@ -210,11 +186,7 @@
         String boxSn = returnHeightSettingDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         ReturnHeightSettingCmd returnHeightSettingCmd = new ReturnHeightSettingCmd(returnHeightSettingDTO);
         this.sendMessage(ardDroneInfo.getServerId(), returnHeightSettingCmd);
@@ -229,11 +201,7 @@
         String boxSn = returnPointSettingDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         ReturnPointSettingCmd returnPointSettingCmd = new ReturnPointSettingCmd(returnPointSettingDTO);
         this.sendMessage(ardDroneInfo.getServerId(), returnPointSettingCmd);
@@ -248,11 +216,7 @@
         String boxSn = videoStreamSettingDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         VideoStreamSettingCmd videoStreamSettingCmd = new VideoStreamSettingCmd(videoStreamSettingDTO);
         this.sendMessage(ardDroneInfo.getServerId(), videoStreamSettingCmd);
@@ -284,11 +248,7 @@
         String boxSn = angleControlDto.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         AngleControlCmd controlAngleCommand = new AngleControlCmd(angleControlDto);
         this.sendMessage(ardDroneInfo.getServerId(), controlAngleCommand);
@@ -304,11 +264,7 @@
         String boxSn = absAngleControlDto.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         AbsAngleControlCmd absAngleControlCommand = new AbsAngleControlCmd(absAngleControlDto);
         this.sendMessage(ardDroneInfo.getServerId(), absAngleControlCommand);
@@ -324,11 +280,7 @@
         String boxSn = speedControlDto.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         SpeedControlCmd speedControlCommand = new SpeedControlCmd(speedControlDto);
         this.sendMessage(ardDroneInfo.getServerId(), speedControlCommand);
@@ -338,16 +290,13 @@
     /**
      * 设置相机模式
      */
+    @CheckControlRight(UavControlType.PAYLOAD)
     @Override
     public Boolean updateCameraMode(CameraModeDTO cameraModeDTO) {
         String boxSn = cameraModeDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         CameraModeCmd cameraModeCommand = new CameraModeCmd(cameraModeDTO);
         this.sendMessage(ardDroneInfo.getServerId(), cameraModeCommand);
@@ -357,16 +306,13 @@
     /**
      * 拍照
      */
+    @CheckControlRight(UavControlType.PAYLOAD)
     @Override
     public Boolean capturePic(CapturePicDTO capturePicDto) {
         String boxSn = capturePicDto.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         //设置相机模式为拍照模式
         updateCameraMode(CameraModeDTO.builder().boxSn(capturePicDto.getBoxSn()).actionParam((byte) 0x01).build());
@@ -381,16 +327,13 @@
     /**
      * 录像
      */
+    @CheckControlRight(UavControlType.PAYLOAD)
     @Override
     public Boolean record(RecordDTO recordDto) {
         String boxSn = recordDto.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         BaseCmd baseCmd;
         if (recordDto.getIsRecord()) {
@@ -412,11 +355,7 @@
         String boxSn = zoomDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         ZoomCmd zoomCommand = new ZoomCmd(zoomDTO);
         this.sendMessage(ardDroneInfo.getServerId(), zoomCommand);
@@ -432,11 +371,7 @@
         String boxSn = zoomToLevelDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         ZoomToLevelCmd zoomToLevelCommand = new ZoomToLevelCmd(zoomToLevelDTO);
         this.sendMessage(ardDroneInfo.getServerId(), zoomToLevelCommand);
@@ -446,16 +381,13 @@
     /**
      * 切换摄像头
      */
+    @CheckControlRight(UavControlType.PAYLOAD)
     @Override
     public Boolean switchCamera(SwitchCameraDTO switchCameraDTO) {
         String boxSn = switchCameraDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         SwitchCameraCmd switchCameraCmd = new SwitchCameraCmd(switchCameraDTO);
         this.sendMessage(ardDroneInfo.getServerId(), switchCameraCmd);
@@ -465,16 +397,13 @@
     /**
      * 切换视频源
      */
+    @CheckControlRight(UavControlType.PAYLOAD)
     @Override
     public Boolean switchSource(SwitchSourceDTO switchSourceDTO) {
         String boxSn = switchSourceDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         SwitchSourceCmd switchSourceCmd = new SwitchSourceCmd(switchSourceDTO);
         this.sendMessage(ardDroneInfo.getServerId(), switchSourceCmd);
@@ -484,16 +413,13 @@
     /**
      * 打开或关闭照片回传
      */
+    @CheckControlRight(UavControlType.PAYLOAD)
     @Override
     public Boolean photoReturnToggle(PhotoReturnToggleDTO photoReturnToggleDTO) {
         String boxSn = photoReturnToggleDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         PhotoReturnToggleCmd photoReturnToggleCmd = new PhotoReturnToggleCmd(photoReturnToggleDTO);
         this.sendMessage(ardDroneInfo.getServerId(), photoReturnToggleCmd);
@@ -503,16 +429,13 @@
     /**
      * 切换无人机控制权
      */
+    @CheckDroneStatus
     @Override
     public Boolean switchUavControl(SwitchUavControlDTO switchUavControlDTO) {
         String boxSn = switchUavControlDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         SwitchUavControlCmd switchUavControlCmd = new SwitchUavControlCmd(switchUavControlDTO);
         this.sendMessage(ardDroneInfo.getServerId(), switchUavControlCmd);
@@ -528,11 +451,7 @@
         String boxSn = takeOffDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         TakeOffCmd takeOffCmd = new TakeOffCmd(takeOffDTO);
         this.sendMessage(ardDroneInfo.getServerId(), takeOffCmd);
@@ -548,11 +467,7 @@
         String boxSn = returnHomeDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         ReturnHomeCmd returnHomeCmd = new ReturnHomeCmd(returnHomeDTO);
         this.sendMessage(ardDroneInfo.getServerId(), returnHomeCmd);
@@ -568,11 +483,7 @@
         String boxSn = returnHomeCancelDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         ReturnHomeCancelCmd returnHomeCancelCmd = new ReturnHomeCancelCmd(returnHomeCancelDTO);
         this.sendMessage(ardDroneInfo.getServerId(), returnHomeCancelCmd);
@@ -588,11 +499,7 @@
         String boxSn = landDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         LandCmd landCmd = new LandCmd(landDTO);
         this.sendMessage(ardDroneInfo.getServerId(), landCmd);
@@ -608,11 +515,7 @@
         String boxSn = landCancelDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         LandCancelCmd landCancelCmd = new LandCancelCmd(landCancelDTO);
         this.sendMessage(ardDroneInfo.getServerId(), landCancelCmd);
@@ -628,11 +531,7 @@
         String boxSn = landForcedDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         LandForcedCmd landForcedCmd = new LandForcedCmd(landForcedDTO);
         this.sendMessage(ardDroneInfo.getServerId(), landForcedCmd);
@@ -644,16 +543,13 @@
      */
     @CheckControlRight(UavControlType.FLY)
     @CheckTakeoffAltitude(minAltitude = 30.0)
+    @CheckNoFlyZone
     @Override
     public Boolean flyControl(FlyControlDTO flyControlDTO) {
         String boxSn = flyControlDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         FlyControlCmd flyControlCmd = new FlyControlCmd(flyControlDTO);
         this.sendMessage(ardDroneInfo.getServerId(), flyControlCmd);
@@ -665,27 +561,14 @@
      */
     @CheckControlRight(UavControlType.FLY)
     @CheckTakeoffAltitude(minAltitude = 30.0)
+    @CheckNoFlyZone
     @Override
     public Boolean flyPointControl(FlyPointControlDTO flyPointControlDTO) {
         String boxSn = flyPointControlDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
-        }
-        // 判断目标点是否经过禁飞区
-        List<ArdNoFlyZone> ardNoFlyZones = ardNoFlyZoneService.selectArdNoFlyZoneList(new ArdNoFlyZone());
-        if (!ardNoFlyZones.isEmpty()) {
-            Vertex vertex = new Vertex(flyPointControlDTO.getLongitude(), flyPointControlDTO.getLatitude());
-            boolean inNoFlyZones = NoFlyZoneUtils.isInNoFlyZones(vertex, ardNoFlyZones);
-            if (inNoFlyZones) {
-                throw new ServiceException("目标点在禁飞区内,无法执行指令, boxSn: " + boxSn);
-            }
-        }
-
         FlyPointControlCmd flyPointControlCmd = new FlyPointControlCmd(flyPointControlDTO);
         this.sendMessage(ardDroneInfo.getServerId(), flyPointControlCmd);
         return true;
@@ -700,12 +583,10 @@
         String boxSn = flyPointControlCancelDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
-        }
+        
+        
         FlyPointControlCancelCmd flyPointControlCancelCmd = new FlyPointControlCancelCmd(flyPointControlCancelDTO);
         this.sendMessage(ardDroneInfo.getServerId(), flyPointControlCancelCmd);
         return true;
@@ -720,12 +601,10 @@
         String boxSn = emeragencyBrakeDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
-        }
+        
+        
         EmergencyBrakeCmd emergencyBrakeCmd = new EmergencyBrakeCmd(emeragencyBrakeDTO);
         this.sendMessage(ardDroneInfo.getServerId(), emergencyBrakeCmd);
         return true;
@@ -763,11 +642,7 @@
         String boxSn = speakModeSwitchDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         SpeakModeSwitchCmd speakModeSwitchCmd = new SpeakModeSwitchCmd(speakModeSwitchDTO);
         this.sendMessage(ardDroneInfo.getServerId(), speakModeSwitchCmd);
@@ -782,11 +657,7 @@
         String boxSn = textSpeakDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         TextSpeakCmd textSpeakCmd = new TextSpeakCmd(textSpeakDTO);
         this.sendMessage(ardDroneInfo.getServerId(), textSpeakCmd);
@@ -801,11 +672,7 @@
         String boxSn = realSpeakDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         RealSpeakCmd realSpeakCmd = new RealSpeakCmd(realSpeakDTO);
         this.sendMessage(ardDroneInfo.getServerId(), realSpeakCmd);
@@ -820,11 +687,7 @@
         String boxSn = recordSpeakDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         RecordSpeakCmd recordSpeakCmd = new RecordSpeakCmd(recordSpeakDTO);
         this.sendMessage(ardDroneInfo.getServerId(), recordSpeakCmd);
@@ -839,11 +702,7 @@
         String boxSn = volumeSettingDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         VolumeSettingCmd volumeSettingCmd = new VolumeSettingCmd(volumeSettingDTO);
         this.sendMessage(ardDroneInfo.getServerId(), volumeSettingCmd);
@@ -858,11 +717,7 @@
         String boxSn = loopSettingDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         LoopSettingCmd loopSettingCmd = new LoopSettingCmd(loopSettingDTO);
         this.sendMessage(ardDroneInfo.getServerId(), loopSettingCmd);
@@ -877,11 +732,7 @@
         String boxSn = stopSpeakDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         StopSpeakCmd stopSpeakCmd = new StopSpeakCmd(stopSpeakDTO);
         this.sendMessage(ardDroneInfo.getServerId(), stopSpeakCmd);
@@ -891,16 +742,13 @@
     /**
      * 航线上传
      */
+    @CheckControlRight(UavControlType.FLY)
     @Override
     public Boolean wayLineUpload(WayLineUploadDTO wayLineUploadDTO) {
         String boxSn = wayLineUploadDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         //wayLineUploadDTO.setWayLineData(this.CreatePlanLineData());//设置航线数据
         WayLineUploadCmd wayLineUploadCmd = new WayLineUploadCmd(wayLineUploadDTO);
@@ -951,11 +799,7 @@
         String boxSn = wayLineBeginDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         WayLineBeginCmd wayLineBeginCmd = new WayLineBeginCmd(wayLineBeginDTO);
         this.sendMessage(ardDroneInfo.getServerId(), wayLineBeginCmd);
@@ -971,11 +815,7 @@
         String boxSn = wayLinePauseDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         WayLinePauseCmd wayLinePauseCmd = new WayLinePauseCmd(wayLinePauseDTO);
         this.sendMessage(ardDroneInfo.getServerId(), wayLinePauseCmd);
@@ -991,11 +831,7 @@
         String boxSn = wayLineResumeDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         WayLineResumeCmd wayLineResumeCmd = new WayLineResumeCmd(wayLineResumeDTO);
         this.sendMessage(ardDroneInfo.getServerId(), wayLineResumeCmd);
@@ -1011,11 +847,7 @@
         String boxSn = wayLineEndDTO.getBoxSn();
         ArdDroneInfo ardDroneInfo = ardDroneService.selectArdDroneByboxSn(boxSn);
         if (ardDroneInfo == null) {
-            throw new ServiceException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
-        }
-        // ✅ 判断无人机是否在线
-        if (!isDroneOnline(boxSn)) {
-            throw new ServiceException("无人机离线,无法执行指令, boxSn: " + boxSn);
+            throw new ControlException("未找到对应的飞行器信息,boxSn:{}" + boxSn);
         }
         WayLineEndCmd wayLineEndCmd = new WayLineEndCmd(wayLineEndDTO);
         this.sendMessage(ardDroneInfo.getServerId(), wayLineEndCmd);
@@ -1291,14 +1123,4 @@
     private void sendMessage(String key, BaseCmd msg) {
         TcpClientUtil.sendMessage(key, msg);
     }
-
-    // 判断无人机是否在线
-    private boolean isDroneOnline(String boxSn) {
-        if (StringUtils.isBlank(boxSn)) {
-            return false;
-        }
-        Object obj = redisCache.getCacheObject(CacheConstants.UAV_ONLINE_KEY + boxSn);
-        return obj != null;
-    }
-
 }
\ No newline at end of file

--
Gitblit v1.9.3