| 对比新文件 |
| | |
| | | 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."); |
| | | } |
| | | } |