package com.ruoyi.common.aop; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.framework.security.LoginUser; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.util.Collection; import java.util.Map; @Aspect @Component public class DataScopeAop { private static final String DATA_SCOPE_ALL = "1"; private static final String DATA_SCOPE_CUSTOM = "2"; private static final String DATA_SCOPE_DEPT = "3"; private static final String DATA_SCOPE_DEPT_AND_CHILD = "4"; private static final String DATA_SCOPE_SELF = "5"; @Before("@within(restController)") public void fillDataScopeCondition(JoinPoint joinPoint, RestController restController) { System.out.println("[DataScopeAop] enter: " + joinPoint.getSignature().toShortString()); fillDataScopeCondition(joinPoint); } public void fillDataScopeCondition(JoinPoint joinPoint) { LoginUser loginUser; try { loginUser = SecurityUtils.getLoginUser(); } catch (Exception ignored) { System.out.println("[DataScopeAop] skip: loginUser unavailable"); return; } if (loginUser == null || loginUser.getUser() == null || loginUser.getUser().isAdmin()) { System.out.println("[DataScopeAop] skip: loginUser null or admin"); return; } String dataScope = loginUser.getDataScope(); if (dataScope == null || DATA_SCOPE_ALL.equals(dataScope)) { System.out.println("[DataScopeAop] skip: dataScope=" + dataScope); return; } for (Object arg : joinPoint.getArgs()) { bindScope(arg, loginUser, dataScope); } } private void bindScope(Object arg, LoginUser loginUser, String dataScope) { if (arg == null || isIgnoredType(arg.getClass())) { return; } if (arg instanceof Collection) { for (Object item : (Collection) arg) { bindScope(item, loginUser, dataScope); } return; } if (arg instanceof Map) { for (Object value : ((Map) arg).values()) { bindScope(value, loginUser, dataScope); } return; } if (arg.getClass().isArray()) { int length = Array.getLength(arg); for (int i = 0; i < length; i++) { bindScope(Array.get(arg, i), loginUser, dataScope); } return; } if (DATA_SCOPE_SELF.equals(dataScope)) { setFieldValue(arg, "createUser", Integer.class, loginUser.getUserId() == null ? null : loginUser.getUserId().intValue()); return; } if (DATA_SCOPE_DEPT.equals(dataScope)) { setFieldValue(arg, "deptId", Long.class, resolveDeptId(loginUser)); return; } if (DATA_SCOPE_CUSTOM.equals(dataScope) || DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) { Long[] deptIds = loginUser.getDeptIds(); setFieldValue(arg, "deptIds", Long[].class, deptIds); if (deptIds != null && deptIds.length == 1) { setFieldValue(arg, "deptId", Long.class, deptIds[0]); } } } private Long resolveDeptId(LoginUser loginUser) { if (loginUser.getCurrentDeptId() != null) { return loginUser.getCurrentDeptId(); } Long[] deptIds = loginUser.getDeptIds(); return deptIds != null && deptIds.length > 0 ? deptIds[0] : null; } private void setFieldValue(Object target, String fieldName, Class fieldType, Object value) { if (value == null) { return; } Field field = findField(target.getClass(), fieldName); if (field == null || !fieldType.isAssignableFrom(field.getType())) { return; } try { field.setAccessible(true); field.set(target, value); System.out.println("[DataScopeAop] inject: class=" + target.getClass().getSimpleName() + ", field=" + fieldName + ", value=" + value); } catch (IllegalAccessException ignored) { } } private Field findField(Class type, String fieldName) { Class current = type; while (current != null && current != Object.class) { try { return current.getDeclaredField(fieldName); } catch (NoSuchFieldException ignored) { current = current.getSuperclass(); } } return null; } private boolean isIgnoredType(Class type) { Package targetPackage = type.getPackage(); String packageName = targetPackage == null ? "" : targetPackage.getName(); return type.isPrimitive() || Number.class.isAssignableFrom(type) || CharSequence.class.isAssignableFrom(type) || Boolean.class == type || Character.class == type || type.isEnum() || Page.class.isAssignableFrom(type) || MultipartFile.class.isAssignableFrom(type) || ServletRequest.class.isAssignableFrom(type) || ServletResponse.class.isAssignableFrom(type) || packageName.startsWith("java.") || packageName.startsWith("jakarta.") || packageName.startsWith("jakarta.") || packageName.startsWith("org.springframework.") || packageName.startsWith("com.baomidou."); } }