liusuyi
2025-03-17 a82c9a2633c519d5d7d868d3ec89832f77849700
ard-work/src/main/java/com/ard/tianyu/aspect/UavControlAspect.java
@@ -1,8 +1,11 @@
package com.ard.tianyu.aspect;
import com.ard.common.exception.NoPermissionException;
import com.ard.common.exception.ControlException;
import com.ard.common.utils.SecurityUtils;
import com.ard.tianyu.aspect.annotation.RequireUavControl;
import com.ard.tianyu.aspect.annotation.CheckTakeoffAltitude;
import com.ard.tianyu.aspect.annotation.CheckControlRight;
import com.ard.tianyu.domain.cache.UavTelemetryDataCache;
import com.ard.tianyu.domain.dto.telemetry.TelemetryData;
import com.ard.tianyu.service.control.UavControlService;
import com.ard.tianyu.websocket.domain.UavControlType;
import org.aspectj.lang.JoinPoint;
@@ -15,6 +18,8 @@
/**
 * AOP 切面:拦截 @RequireUavControl,检查用户是否拥有 UAV 控制权限
 *
 * 注意切面顺序:同类方法注解按字母ABCD顺序,不同类注解按order(1)顺序 越小优先级越高
 */
@Aspect
@Component
@@ -24,15 +29,15 @@
    private UavControlService uavControlService;
    /**
     * 拦截 @RequireUavControl 注解的方法
     * 前置通知:控制权检测
     */
    @Before("@annotation(requireUavControl)")
    public void checkUavControl(JoinPoint joinPoint, RequireUavControl requireUavControl) {
    @Before("@annotation(checkControlRight)")
    public void checkUavControl(JoinPoint joinPoint, CheckControlRight checkControlRight) {
        // 获取当前用户 ID
        Long userId = SecurityUtils.getUserId();
        // 获取控制类型
        UavControlType controlType = requireUavControl.value();
        UavControlType controlType = checkControlRight.value();
        // 获取方法参数
        Object[] args = joinPoint.getArgs();
@@ -45,12 +50,37 @@
                Long currentController = uavControlService.getCurrentController(boxSn,
                        controlType.name().toLowerCase());
                if (currentController == null || !currentController.equals(userId)) {
                    throw new NoPermissionException("无权执行该操作,需要 " + controlType + " 控制权限");
                    throw new ControlException("无权执行该操作,需要 " + controlType + " 控制权限");
                }
            }
        }
    }
    /**
     * 前置通知:高度检查
     */
    @Before("@annotation(checkTakeoffAltitude)")
    public void takeoffAltitudeCheck(JoinPoint joinPoint, CheckTakeoffAltitude checkTakeoffAltitude) {
        // 获取最小高度
        double minAltitude = checkTakeoffAltitude.minAltitude();
        // 获取方法参数
        Object[] args = joinPoint.getArgs();
        // 遍历参数,使用反射获取每个参数中的 boxSn
        for (Object arg : args) {
            String boxSn = getBoxSn(arg);  // 调用之前实现的 getBoxSn 方法
            if (boxSn != null) {
                TelemetryData uavTelemetryData = UavTelemetryDataCache.getUavTelemetryData(boxSn);
                if (uavTelemetryData == null) {
                    throw new ControlException("遥测数据异常,无法执行!");
                }
                // 检查高度
                if (uavTelemetryData.getAltitude() < minAltitude) {
                    throw new ControlException("高度太低,无法执行!最低高度: " + minAltitude);
                }
            }
        }
    }
    /**
     * 通过反射获取对象中的 boxSn 字段