package com.ard.work.aspect; import com.ard.common.exception.ControlException; import com.ard.common.utils.SecurityUtils; 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.service.control.UavControlService; import com.ard.work.domain.message.UavControlType; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.lang.reflect.Field; /** * AOP 切面:拦截 @RequireUavControl,检查用户是否拥有 UAV 控制权限 * * 注意切面顺序:同类方法注解按字母ABCD顺序,不同类注解按order(1)顺序 越小优先级越高 */ @Aspect @Component public class UavControlAspect { @Resource private UavControlService uavControlService; /** * 前置通知:控制权检测 */ @Before("@annotation(checkControlRight)") public void checkUavControl(JoinPoint joinPoint, CheckControlRight checkControlRight) { // 获取当前用户 ID Long userId = SecurityUtils.getUserId(); // 获取控制类型 UavControlType controlType = checkControlRight.value(); // 获取方法参数 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 + " 控制权限"); } } } } /** * 前置通知:高度检查 */ @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.get(boxSn); if (uavTelemetryData == null) { throw new ControlException("遥测数据异常,无法执行!"); } // 检查高度 if (uavTelemetryData.getAltitude() < minAltitude) { throw new ControlException("高度太低,无法执行!最低高度: " + minAltitude); } } } } /** * 通过反射获取对象中的 boxSn 字段 * * @param dto 要反射的对象 * @return boxSn 字段的值,如果没有找到则返回 null */ public static String getBoxSn(Object dto) { if (dto == null) { return null; // 如果对象为空,直接返回 null } 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; } } } } catch (IllegalAccessException e) { // 捕获异常并打印日志 System.err.println("反射访问失败: " + e.getMessage()); e.printStackTrace(); } return null; // 如果没有找到 boxSn 字段,返回 null } }