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.");
|
}
|
}
|