package com.iailab.framework.datapermission.core.db; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.extension.plugins.handler.MultiDataPermissionHandler; import com.iailab.framework.datapermission.core.rule.DataPermissionRule; import com.iailab.framework.datapermission.core.rule.DataPermissionRuleFactory; import com.iailab.framework.mybatis.core.util.MyBatisUtils; import lombok.RequiredArgsConstructor; import net.sf.jsqlparser.expression.Expression; import net.sf.jsqlparser.expression.operators.conditional.AndExpression; import net.sf.jsqlparser.schema.Table; import java.util.List; /** * 基于 {@link DataPermissionRule} 的数据权限处理器 * * 它的底层,是基于 MyBatis Plus 的 数据权限插件 * 核心原理:它会在 SQL 执行前拦截 SQL 语句,并根据用户权限动态添加权限相关的 SQL 片段。这样,只有用户有权限访问的数据才会被查询出来 * * @author 芋道源码 */ @RequiredArgsConstructor public class DataPermissionRuleHandler implements MultiDataPermissionHandler { private final DataPermissionRuleFactory ruleFactory; @Override public Expression getSqlSegment(Table table, Expression where, String mappedStatementId) { // 获得 Mapper 对应的数据权限的规则 List rules = ruleFactory.getDataPermissionRule(mappedStatementId); if (CollUtil.isEmpty(rules)) { return null; } // 生成条件 Expression allExpression = null; for (DataPermissionRule rule : rules) { // 判断表名是否匹配 String tableName = MyBatisUtils.getTableName(table); if (!rule.getTableNames().contains(tableName)) { continue; } // 单条规则的条件 Expression oneExpress = rule.getExpression(tableName, table.getAlias()); if (oneExpress == null) { continue; } // 拼接到 allExpression 中 allExpression = allExpression == null ? oneExpress : new AndExpression(allExpression, oneExpress); } return allExpression; } }