2026-06-26 20b96473f2520590a0dca6b775b81e3ea06a77a0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package cn.iocoder.yudao.framework.datapermission.core.rule;
 
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
import cn.iocoder.yudao.framework.datapermission.core.aop.DataPermissionContextHolder;
import org.dromara.trans.service.impl.SimpleTransService;
import lombok.RequiredArgsConstructor;
 
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
 
/**
 * 默认的 DataPermissionRuleFactoryImpl 实现类
 * 支持通过 {@link DataPermissionContextHolder} 过滤数据权限
 *
 * @author 芋道源码
 */
@RequiredArgsConstructor
public class DataPermissionRuleFactoryImpl implements DataPermissionRuleFactory {
 
    /**
     * 数据权限规则数组
     */
    private final List<DataPermissionRule> rules;
 
    @Override
    public List<DataPermissionRule> getDataPermissionRules() {
        return rules;
    }
 
    @Override // mappedStatementId 参数,暂时没有用。以后,可以基于 mappedStatementId + DataPermission 进行缓存
    public List<DataPermissionRule> getDataPermissionRule(String mappedStatementId) {
        // 1.1 无数据权限
        if (CollUtil.isEmpty(rules)) {
            return Collections.emptyList();
        }
        // 1.2 未配置,则默认开启
        DataPermission dataPermission = DataPermissionContextHolder.get();
        if (dataPermission == null) {
            return rules;
        }
        // 1.3 已配置,但禁用
        if (!dataPermission.enable()) {
            return Collections.emptyList();
        }
        // 1.4 特殊:数据翻译时,强制忽略数据权限 https://github.com/YunaiV/ruoyi-vue-pro/issues/1007
        if (isTranslateCall()) {
            return Collections.emptyList();
        }
 
        // 2.1 情况一:已配置,只选择部分规则
        if (ArrayUtil.isNotEmpty(dataPermission.includeRules())) {
            return rules.stream().filter(rule -> ArrayUtil.contains(dataPermission.includeRules(), rule.getClass()))
                    .collect(Collectors.toList()); // 一般规则不会太多,所以不采用 HashSet 查询
        }
        // 2.2 已配置,只排除部分规则
        if (ArrayUtil.isNotEmpty(dataPermission.excludeRules())) {
            return rules.stream().filter(rule -> !ArrayUtil.contains(dataPermission.excludeRules(), rule.getClass()))
                    .collect(Collectors.toList()); // 一般规则不会太多,所以不采用 HashSet 查询
        }
        // 2.3 已配置,全部规则
        return rules;
    }
 
    /**
     * 判断是否为数据翻译 {@link org.dromara.core.trans.anno.Trans} 的调用
     *
     * 目前暂时只有这个办法,已经和 easy-trans 做过沟通
     *
     * @return 是否
     */
    private boolean isTranslateCall() {
        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
        for (StackTraceElement e : stack) {
            if (SimpleTransService.class.getName().equals(e.getClassName())) {
                return true;
            }
        }
        return false;
    }
 
}