From 0f5b969ddd52ca43ef003867b5a6749d74b7d71d Mon Sep 17 00:00:00 2001
From: zhaowenyu <35589726@qq.com>
Date: Wed, 12 Nov 2025 17:52:38 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev
---
ard-work/src/main/java/com/ard/work/aspect/UavControlAspect.java | 145 +++++++++++++++++++++++++++++++++---------------
1 files changed, 100 insertions(+), 45 deletions(-)
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("目标点在禁飞区内,无法执行操作!");
+ }
+ }
}
+
}
--
Gitblit v1.9.3