v 1.0
1. 新增用户与部门,一对多的关系; 2. 新增管理多部门用户,如果有为公司的多个部门可以进行选择登录(选择后,直到下次变更访问公司前,只能访问此次选择公的业务数据,使用 company_id 控制,后续补充此数据权限的实现); 3. sql 转化工具修复,现在可以正确的对 mysql 进行不同数据库实例的转化了; 4. 所有表格主键,修改为分布式 Id 实现; 5. 补全在初始版本中没有被纳入的其他预制功能模块
This commit is contained in:
@@ -13,7 +13,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
||||
import cn.iocoder.yudao.framework.security.core.LoginUser;
|
||||
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||
import cn.iocoder.yudao.framework.tenant.core.context.DeptContextHolder;
|
||||
import cn.iocoder.yudao.framework.tenant.core.context.CompanyContextHolder;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -21,17 +21,22 @@ import net.sf.jsqlparser.expression.Alias;
|
||||
import net.sf.jsqlparser.expression.Expression;
|
||||
import net.sf.jsqlparser.expression.LongValue;
|
||||
import net.sf.jsqlparser.expression.NullValue;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
|
||||
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
|
||||
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
|
||||
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
|
||||
import net.sf.jsqlparser.expression.operators.relational.InExpression;
|
||||
import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList;
|
||||
import net.sf.jsqlparser.expression.operators.relational.*;
|
||||
import net.sf.jsqlparser.schema.Column;
|
||||
import net.sf.jsqlparser.schema.Table;
|
||||
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
|
||||
import net.sf.jsqlparser.statement.select.PlainSelect;
|
||||
import net.sf.jsqlparser.statement.select.SelectItem;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
/**
|
||||
* 基于部门的 {@link DataPermissionRule} 数据权限规则实现
|
||||
*
|
||||
@@ -62,13 +67,13 @@ public class DeptDataPermissionRule implements DataPermissionRule {
|
||||
private static final String USER_COLUMN_NAME = "user_id";
|
||||
|
||||
static final Expression EXPRESSION_NULL = new NullValue();
|
||||
public static final String SYSTEM_USERS = "system_users";
|
||||
|
||||
private final PermissionCommonApi permissionApi;
|
||||
|
||||
/**
|
||||
* 基于部门的表字段配置
|
||||
* 一般情况下,每个表的部门编号字段是 dept_id,通过该配置自定义。
|
||||
*
|
||||
* key:表名
|
||||
* value:字段名
|
||||
*/
|
||||
@@ -76,7 +81,6 @@ public class DeptDataPermissionRule implements DataPermissionRule {
|
||||
/**
|
||||
* 基于用户的表字段配置
|
||||
* 一般情况下,每个表的部门编号字段是 dept_id,通过该配置自定义。
|
||||
*
|
||||
* key:表名
|
||||
* value:字段名
|
||||
*/
|
||||
@@ -85,6 +89,7 @@ public class DeptDataPermissionRule implements DataPermissionRule {
|
||||
* 所有表名,是 {@link #deptColumns} 和 {@link #userColumns} 的合集
|
||||
*/
|
||||
private final Set<String> TABLE_NAMES = new HashSet<>();
|
||||
private static final String SYSTEM_USER_DEPT = "system_user_dept";
|
||||
|
||||
@Override
|
||||
public Set<String> getTableNames() {
|
||||
@@ -116,11 +121,11 @@ public class DeptDataPermissionRule implements DataPermissionRule {
|
||||
// 添加到上下文中,避免重复计算
|
||||
loginUser.setContext(CONTEXT_KEY, deptDataPermission);
|
||||
}
|
||||
// 如果开启了部门上下文,且缓存的部门编号不等于 DeptContextHolder 的部门编号,则更新缓存
|
||||
if(!DeptContextHolder.isIgnore()) {
|
||||
Set<Long> deptIds = DeptContextHolder.getDeptIdList();
|
||||
if (CollUtil.isNotEmpty(deptIds) && !CollUtil.isEqualList(deptDataPermission.getDeptIds(), deptIds)) {
|
||||
deptDataPermission.setDeptIds(deptIds);
|
||||
// 如果开启了公司上下文,且缓存的公司编号不等于 CompanyContextHolder 的公司编号,则更新缓存
|
||||
if(!CompanyContextHolder.isIgnore()) {
|
||||
Long companyId = CompanyContextHolder.getCompanyId();
|
||||
if (companyId != null && !companyId.equals(deptDataPermission.getCompanyId())) {
|
||||
deptDataPermission.setCompanyId(companyId);
|
||||
// 更新到上下文中
|
||||
loginUser.setContext(CONTEXT_KEY, deptDataPermission);
|
||||
}
|
||||
@@ -137,8 +142,9 @@ public class DeptDataPermissionRule implements DataPermissionRule {
|
||||
return new EqualsTo(null, null); // WHERE null = null,可以保证返回的数据为空
|
||||
}
|
||||
|
||||
// 情况三,拼接 Dept 和 User 的条件,最后组合
|
||||
Expression deptExpression = buildDeptExpression(tableName,tableAlias, deptDataPermission.getDeptIds());
|
||||
// 情况三,拼接 Dept 和 Company User 的条件,最后组合
|
||||
Expression deptExpression = buildDeptExpression(tableName, tableAlias, deptDataPermission.getDeptIds());
|
||||
// Expression deptExpression = buildDeptExpression(tableName, tableAlias, deptDataPermission.getDeptIds());
|
||||
Expression userExpression = buildUserExpression(tableName, tableAlias, deptDataPermission.getSelf(), loginUser.getId());
|
||||
if (deptExpression == null && userExpression == null) {
|
||||
// TODO 芋艿:获得不到条件的时候,暂时不抛出异常,而是不返回数据
|
||||
@@ -161,6 +167,35 @@ public class DeptDataPermissionRule implements DataPermissionRule {
|
||||
private Expression buildDeptExpression(String tableName, Alias tableAlias, Set<Long> deptIds) {
|
||||
// 如果不存在配置,则无需作为条件
|
||||
String columnName = deptColumns.get(tableName);
|
||||
// 特殊处理:system_users 表没有 dept_id 字段,已经迁移到了 user_dept 表
|
||||
if (SYSTEM_USERS.equals(tableName)) {
|
||||
// system_users 走 exists 子查询 user_dept
|
||||
if (CollUtil.isEmpty(deptIds)) {
|
||||
return null;
|
||||
}
|
||||
// 构造 exists (select 1 from user_dept where user_dept.user_id = system_users.id and user_dept.dept_id in (...))
|
||||
PlainSelect plainSelect = new PlainSelect();
|
||||
plainSelect.setSelectItems(singletonList(new SelectItem<>(new LongValue(1))));
|
||||
Table userDept = new Table(SYSTEM_USER_DEPT);
|
||||
// 使用 user 表别名避免语法错误
|
||||
Table user = new Table(tableAlias == null ? tableName : tableAlias.getName());
|
||||
plainSelect.setFromItem(userDept);
|
||||
// where user_dept.user_id = system_users.id and user_dept.dept_id in (...)
|
||||
Column userDeptUserIdCol = new Column(userDept, USER_COLUMN_NAME);
|
||||
Column systemUsersIdCol = new Column(user, "id");
|
||||
EqualsTo userIdEquals = new EqualsTo(userDeptUserIdCol, systemUsersIdCol);
|
||||
Column userDeptDeptIdCol = new Column(userDept, DEPT_COLUMN_NAME);
|
||||
InExpression deptIn = new InExpression(userDeptDeptIdCol, new ParenthesedExpressionList<>(new ExpressionList<>(CollectionUtils.convertList(deptIds, LongValue::new))));
|
||||
Expression whereExp = new AndExpression(userIdEquals, deptIn);
|
||||
plainSelect.setWhere(whereExp);
|
||||
//
|
||||
ParenthesedSelect parenthesedSelect = new ParenthesedSelect();
|
||||
parenthesedSelect.setSelect(plainSelect);
|
||||
// 构建 exists 表达式
|
||||
ExistsExpression existsExpr = new ExistsExpression();
|
||||
existsExpr.setRightExpression(parenthesedSelect);
|
||||
return existsExpr;
|
||||
}
|
||||
if (StrUtil.isEmpty(columnName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user