update 优化 多次处理性能问题增加缓存

This commit is contained in:
疯狂的狮子Li
2026-03-12 15:14:56 +08:00
parent 4db032e190
commit 08ec5b3f49
3 changed files with 73 additions and 33 deletions

View File

@@ -0,0 +1,24 @@
package org.dromara.common.mybatis.core.domain;
import cn.hutool.core.collection.CollUtil;
import java.io.Serial;
import java.io.Serializable;
import java.util.Set;
/**
* 当前请求的数据权限访问上下文
*
* @author Lion Li
*/
public record DataPermissionAccess(Set<String> perms, Set<String> roleKeys) implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
public static final DataPermissionAccess EMPTY = new DataPermissionAccess(Set.of(), Set.of());
public boolean constrained() {
return CollUtil.isNotEmpty(perms) || CollUtil.isNotEmpty(roleKeys);
}
}

View File

@@ -22,6 +22,7 @@ import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.annotation.DataColumn;
import org.dromara.common.mybatis.annotation.DataPermission;
import org.dromara.common.mybatis.core.domain.DataPermissionAccess;
import org.dromara.common.mybatis.enums.DataScopeType;
import org.dromara.common.mybatis.helper.DataPermissionHelper;
import org.dromara.common.satoken.utils.LoginHelper;
@@ -110,7 +111,7 @@ public class PlusDataPermissionHandler {
context.setBeanResolver(beanResolver);
DataPermissionHelper.getContext().forEach(context::setVariable);
Set<String> conditions = new HashSet<>();
RequestAccess access = currentAccess();
DataPermissionAccess access = currentAccess();
List<RoleDTO> scopeRoles = scopeRoles(user, access);
if (CollUtil.isEmpty(scopeRoles)) {
if (access.constrained()) {
@@ -182,29 +183,17 @@ public class PlusDataPermissionHandler {
return currentUser;
}
private RequestAccess currentAccess() {
HttpServletRequest request = ServletUtils.getRequest();
if (request == null) {
return RequestAccess.EMPTY;
private DataPermissionAccess currentAccess() {
DataPermissionAccess access = DataPermissionHelper.getAccess();
if (access != null) {
return access;
}
Object handler = request.getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE);
if (!(handler instanceof HandlerMethod handlerMethod)) {
return RequestAccess.EMPTY;
}
SaCheckPermission saCheckPermission = findAnnotation(handlerMethod, SaCheckPermission.class);
SaCheckRole saCheckRole = findAnnotation(handlerMethod, SaCheckRole.class);
Set<String> perms = saCheckPermission == null ? Set.of() : toSet(saCheckPermission.value());
Set<String> roleKeys = new LinkedHashSet<>();
if (saCheckPermission != null) {
roleKeys.addAll(toSet(saCheckPermission.orRole()));
}
if (saCheckRole != null) {
roleKeys.addAll(toSet(saCheckRole.value()));
}
return new RequestAccess(perms, roleKeys);
DataPermissionAccess resolvedAccess = resolveAccess();
DataPermissionHelper.setAccess(resolvedAccess);
return resolvedAccess;
}
private List<RoleDTO> scopeRoles(LoginUser user, RequestAccess access) {
private List<RoleDTO> scopeRoles(LoginUser user, DataPermissionAccess access) {
List<RoleDTO> roles = user.getRoles();
if (!access.constrained()) {
return roles;
@@ -212,22 +201,48 @@ public class PlusDataPermissionHandler {
Map<Long, RoleDTO> roleMap = new LinkedHashMap<>();
Map<String, List<RoleDTO>> dataScopeRoleMap = user.getDataScopeRoleMap();
if (CollUtil.isNotEmpty(dataScopeRoleMap)) {
access.perms.forEach(perm -> {
access.perms().forEach(perm -> {
List<RoleDTO> roleList = dataScopeRoleMap.get(perm);
if (CollUtil.isNotEmpty(roleList)) {
roleList.forEach(role -> roleMap.putIfAbsent(role.getRoleId(), role));
}
});
}
if (CollUtil.isNotEmpty(roles) && CollUtil.isNotEmpty(access.roleKeys)) {
if (CollUtil.isNotEmpty(roles) && CollUtil.isNotEmpty(access.roleKeys())) {
roles.stream()
.filter(role -> StringUtils.isNotBlank(role.getRoleKey()))
.filter(role -> StringUtils.splitList(role.getRoleKey()).stream().anyMatch(access.roleKeys::contains))
.filter(role -> StringUtils.splitList(role.getRoleKey()).stream().anyMatch(access.roleKeys()::contains))
.forEach(role -> roleMap.putIfAbsent(role.getRoleId(), role));
}
return new ArrayList<>(roleMap.values());
}
private DataPermissionAccess resolveAccess() {
HttpServletRequest request = ServletUtils.getRequest();
if (request == null) {
return DataPermissionAccess.EMPTY;
}
Object handler = request.getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE);
if (!(handler instanceof HandlerMethod handlerMethod)) {
return DataPermissionAccess.EMPTY;
}
Set<String> perms = new LinkedHashSet<>();
Set<String> roleKeys = new LinkedHashSet<>();
SaCheckPermission saCheckPermission = findAnnotation(handlerMethod, SaCheckPermission.class);
if (saCheckPermission != null) {
perms.addAll(toSet(saCheckPermission.value()));
roleKeys.addAll(toSet(saCheckPermission.orRole()));
}
SaCheckRole saCheckRole = findAnnotation(handlerMethod, SaCheckRole.class);
if (saCheckRole != null) {
roleKeys.addAll(toSet(saCheckRole.value()));
}
if (perms.isEmpty() && roleKeys.isEmpty()) {
return DataPermissionAccess.EMPTY;
}
return new DataPermissionAccess(Set.copyOf(perms), Set.copyOf(roleKeys));
}
private <A extends Annotation> A findAnnotation(HandlerMethod handlerMethod, Class<A> annotationType) {
A annotation = AnnotationUtil.getAnnotation(handlerMethod.getMethod(), annotationType);
if (annotation != null) {
@@ -323,13 +338,4 @@ public class PlusDataPermissionHandler {
}
}
private record RequestAccess(Set<String> perms, Set<String> roleKeys) {
private static final RequestAccess EMPTY = new RequestAccess(Set.of(), Set.of());
private boolean constrained() {
return CollUtil.isNotEmpty(perms) || CollUtil.isNotEmpty(roleKeys);
}
}
}

View File

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.dromara.common.mybatis.core.domain.DataPermissionAccess;
import org.dromara.common.core.utils.reflect.ReflectUtils;
import org.dromara.common.mybatis.annotation.DataPermission;
@@ -27,6 +28,7 @@ import java.util.function.Supplier;
public class DataPermissionHelper {
private static final String DATA_PERMISSION_KEY = "data:permission";
private static final String ACCESS_KEY = "data:permission:access";
private static final ThreadLocal<Stack<Integer>> REENTRANT_IGNORE = ThreadLocal.withInitial(Stack::new);
@@ -80,6 +82,14 @@ public class DataPermissionHelper {
context.put(key, value);
}
public static DataPermissionAccess getAccess() {
return getVariable(ACCESS_KEY);
}
public static void setAccess(DataPermissionAccess access) {
setVariable(ACCESS_KEY, access);
}
/**
* 获取数据权限上下文
*