前言:
在使用如若依、Jeecg等后台管理系统进行二次开发的时候,我们总会涉及到数据隔离相关的内容,如每个非管理员用户应该都只能看到自己创建的数据,而不是所有的数据,本文将以jeecg为例像大家介绍如何每个用户之间的数据隔离的效果。
先从功能需求说起,当查询房屋列表的时候,每个房东(用户)应该只能看到自己的房屋(house)表数据,而房屋和房东的关系存放于房东(house_holder)表中,所以我们需要通过两个表的关联来实现数据隔离的查询。而jeecg中要如何实现呢?我们一起啦看看吧
基于Jeecg实现:
先放出官方文档中跟数据隔离有关的内容:http://doc.jeecg.com/2044046
- 进入菜单管理页面,找到想要进行数据隔离的菜单,点击添加一个下级并进行配置
选择按钮/权限并配置菜单路径(笔者能力有限暂时无法弄清菜单路径和授权表示的作用在哪)
然后对添加的这个按钮/权限进行数据规则的配置,
由于我们需要要从另外一张表中去查出跟user_id
有关的house_id
所以要使用自定义SQL的方式
- 在角色管理中对用角色进行数据权限的授权
给需求中的房东用户配置上数据权限
- 在后端对应的controller中的list方法中加上
@PermissionData
注解,该注解有一个pageComponent参数为数据隔离的菜单的前端组件路径,如果配置了只有该前端组件路径会被拦截,不配置的话就拦截全部请求。
大家可能注意到了,官方文档中给出了系统上下文变量有sys_user_code
, 有sys_user_name
,有sys_org_code
但就是没有SQL表达式中的#{sys_user_id}
,而我们想要实现的效果只能给予user_id来实现,那么我们要怎么实现呢?
修改底层源码
笔者先给出如何修改,实现将当前登录用户的id存入数据权限的系统上下文变量中,来探讨其源码是如何进行修改的。
以下文件直接通过idea的search every where 的功能即可找到对应类
3.1. SysUserCacheInfo中添加一个String类型的sysUserId和其对应的setter/getter
...
private String sysUserId;
// 用idea生成setter/getter,如果懒的话直接用@Data然后删除其他的setter/getter也成
public String getSysUserId() {
return sysUserId;
}
public void setSysUserId(String sysUserId) {
this.sysUserId = sysUserId;
}
...
3.2. SysBaseApiImpl中的getCachUser为3.1的CacheInfo的新增的属性赋值
public SysUserCacheInfo getCacheUser(String username) {
SysUserCacheInfo info = new SysUserCacheInfo();
info.setOneDepart(true);
LoginUser user = this.getUserByName(username);
if(user!=null) {
//加上下面一行代码
info.setSysUserId(use