完成数据权限重构

This commit is contained in:
dataprince 2023-11-21 21:17:21 +08:00
parent 61af7b3106
commit 57c7b3aaeb
10 changed files with 234 additions and 112 deletions

View File

@ -275,7 +275,7 @@ public class SysUserController extends BaseController {
List<SysRoleVo> roles = roleService.selectRolesByUserId(userId);
SysUserInfoVo userInfoVo = new SysUserInfoVo();
userInfoVo.setUser(user);
userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin()));
userInfoVo.setRoles(LoginHelper.isSuperAdmin(userId) ? roles : StreamUtils.filter(roles, r -> !r.isSuperAdmin()));//超级管理员角色只能id=1的admin用户才能拥有
return R.ok(userInfoVo);
}

View File

@ -1,16 +1,54 @@
package com.ruoyi.system.mapper;
import com.mybatisflex.core.BaseMapper;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper;
import com.ruoyi.system.domain.SysRole;
import com.ruoyi.system.domain.vo.SysRoleVo;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
import static com.ruoyi.system.domain.table.SysDeptTableDef.SYS_DEPT;
import static com.ruoyi.system.domain.table.SysRoleTableDef.SYS_ROLE;
import static com.ruoyi.system.domain.table.SysUserRoleTableDef.SYS_USER_ROLE;
import static com.ruoyi.system.domain.table.SysUserTableDef.SYS_USER;
/**
* 角色表 数据层
*
* @author ruoyi
* @author 数据小王子
*/
@Mapper
public interface SysRoleMapper extends BaseMapper<SysRole>
{
/**
* 根据用户ID查询其拥有的角色列表
*
* 为了避免在数据权限SysDataScopeServiceImpl引用产生循环引用问题将该方法的实现由service转到mapper中2023.11.21
*
* @param userId 用户ID
* @return 拥有的角色列表
*/
default List<SysRoleVo> selectUserRolesByUserId(Long userId) {
/*select distinct r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.menu_check_strictly, r.dept_check_strictly,
r.status, r.del_flag, r.create_time, r.remark
from sys_role r
left join sys_user_role ur on ur.role_id = r.role_id
left join sys_user u on u.user_id = ur.user_id
where r.del_flag = '0' and ur.user_id = #{userId}*/
QueryWrapper queryWrapper = QueryWrapper.create()
.select(QueryMethods.distinct(SYS_ROLE.ALL_COLUMNS))
.from(SYS_ROLE.as("r"))
.leftJoin(SYS_USER_ROLE).as("ur").on(SYS_USER_ROLE.ROLE_ID.eq(SYS_ROLE.ROLE_ID))
.leftJoin(SYS_USER).as("u").on(SYS_USER.USER_ID.eq(SYS_USER_ROLE.USER_ID))
.leftJoin(SYS_DEPT).as("d").on(SYS_DEPT.DEPT_ID.eq(SYS_USER.DEPT_ID));
queryWrapper.where(SYS_ROLE.DEL_FLAG.eq("0"))
.and(SYS_USER_ROLE.USER_ID.eq(userId));
List<SysRoleVo> userRoles = selectListByQueryAs(queryWrapper, SysRoleVo.class);
return userRoles;
}
}

View File

@ -16,27 +16,5 @@ import org.apache.ibatis.annotations.Param;
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser>
{
// /**
// * 根据条件分页查询用户列表
// *
// * @param sysUser 用户信息
// * @return 用户信息集合信息
// */
// List<SysUser> selectUserList(SysUser sysUser);
// /**
// * 根据条件分页查询已配用户角色列表
// *
// * @param user 用户信息
// * @return 用户信息集合信息
// */
// List<SysUser> selectAllocatedList(SysUser user);
//
// /**
// * 根据条件分页查询未分配用户角色列表
// *
// * @param user 用户信息
// * @return 用户信息集合信息
// */
// List<SysUser> selectUnallocatedList(SysUser user);
}

View File

@ -0,0 +1,17 @@
package com.ruoyi.system.service;
import com.mybatisflex.core.query.QueryWrapper;
/**
* 通用"数据权限过滤“服务
*
* @author dataprince数据小王子
*/
public interface ISysDataScopeService {
/**
* 添加数据查询过滤条件
* @param queryWrapper
* @return 添加了过滤条件后的queryWrapper
*/
QueryWrapper addCondition(QueryWrapper queryWrapper);
}

View File

@ -73,6 +73,15 @@ public interface ISysUserService extends IBaseService<SysUser>
*/
SysUserVo selectUserById(Long userId);
/**
* 个人中心模块通过用户ID查询用户
*
* @param userId 用户ID
* @return 用户对象信息
*/
SysUserVo selectProfileUserById(Long userId);
/**
* 根据用户ID查询用户所属角色组
*

View File

@ -0,0 +1,137 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryMethods;
import com.mybatisflex.core.query.QueryWrapper;
import com.ruoyi.common.core.core.domain.model.LoginUser;
import com.ruoyi.common.security.utils.LoginHelper;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.domain.vo.SysRoleVo;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysDataScopeService;
import com.ruoyi.system.service.ISysRoleService;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import static com.mybatisflex.core.query.QueryMethods.bracket;
import static com.mybatisflex.core.query.QueryMethods.select;
import static com.ruoyi.system.domain.table.SysDeptTableDef.SYS_DEPT;
import static com.ruoyi.system.domain.table.SysRoleDeptTableDef.SYS_ROLE_DEPT;
import static com.ruoyi.system.domain.table.SysUserTableDef.SYS_USER;
/**
* 通用"数据权限过滤“服务
*
* @author dataprince数据小王子
*/
@RequiredArgsConstructor
@Service
public class SysDataScopeServiceImpl implements ISysDataScopeService {
/**
* 全部数据权限
*/
public static final String DATA_SCOPE_ALL = "1";
/**
* 自定数据权限
*/
public static final String DATA_SCOPE_CUSTOM = "2";
/**
* 部门数据权限
*/
public static final String DATA_SCOPE_DEPT = "3";
/**
* 部门及以下数据权限
*/
public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";
/**
* 仅本人数据权限
*/
public static final String DATA_SCOPE_SELF = "5";
@Resource
private SysUserMapper userMapper;
@Resource
private SysRoleMapper roleMapper;
/**
* 添加数据查询过滤条件
*
* @param queryWrapper
* @return 添加了过滤条件后的queryWrapper
*/
@Override
public QueryWrapper addCondition(QueryWrapper queryWrapper) {
QueryCondition queryCondition = QueryCondition.createEmpty();
// 获取当前的用户
LoginUser loginUser = LoginHelper.getLoginUser();
if (ObjectUtil.isNotNull(loginUser)) {
Long userId = loginUser.getUserId();
if (userId > 0) {
//SysUserVo currentUser = userService.selectUserById(userId);
SysUser currentUser = userMapper.selectOneById(userId);
List<SysRoleVo> roleList = roleMapper.selectUserRolesByUserId(userId);
// 如果是超级管理员则不过滤数据
if (ObjectUtil.isNotNull(currentUser) && !LoginHelper.isSuperAdmin(userId)) {
List<String> dataScopeList = new ArrayList<>();
//除了2自定义数据权限其它值去重存入dataScopeList列表
for (SysRoleVo role : roleList) {
String dataScope = role.getDataScope();//数据范围1全部数据权限2自定义数据权限3本部门数据权限4本部门及以下数据权限5仅本人数据权限
if (!DATA_SCOPE_CUSTOM.equals(dataScope) && dataScopeList.contains(dataScope)) {
continue;
}
dataScopeList.add(dataScope);
}
//如果数据范围是1全部数据权限则不再添加过滤条件直接返回queryWrapper原值
if (dataScopeList.contains(DATA_SCOPE_ALL)) {
return queryWrapper;
}
//单独处理数据范围是2自定义数据权限
for (SysRoleVo role : roleList) {
String dataScope = role.getDataScope();//数据范围
if (DATA_SCOPE_CUSTOM.equals(dataScope)) {
//OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} )
queryCondition.or(SYS_DEPT.DEPT_ID.in(select(SYS_ROLE_DEPT.DEPT_ID).from(SYS_ROLE_DEPT).where(SYS_ROLE_DEPT.ROLE_ID.eq(role.getRoleId()))));
}
}
//单独处理数据范围是" 3本部门数据权限"
if (dataScopeList.contains(DATA_SCOPE_DEPT)) {
//OR {}.dept_id = {}
queryCondition.or(SYS_DEPT.DEPT_ID.eq(currentUser.getDeptId()));
}
//单独处理数据范围是" 4本部门及以下数据权限"
if (dataScopeList.contains(DATA_SCOPE_DEPT_AND_CHILD)) {
//OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors )
queryCondition.or(SYS_DEPT.DEPT_ID.in(select(SYS_DEPT.DEPT_ID).from(SYS_DEPT).where(SYS_DEPT.DEPT_ID.eq(currentUser.getDeptId())).or(QueryMethods.findInSet(QueryMethods.number(currentUser.getDeptId()),SYS_DEPT.ANCESTORS).gt(0))));
}
//单独处理数据范围是" 5仅本人数据权限"
if (dataScopeList.contains(DATA_SCOPE_SELF)) {
//OR {}.user_id = {}
queryCondition.or(SYS_USER.USER_ID.eq(currentUser.getUserId()));
}
}
}
}
queryWrapper.and(bracket(queryCondition));//所有新增的插叙条件外边用圆括号包括起来
//System.out.println("*******************:SysDataScopeServiceImpl.filter:queryWrapper.tosql="+queryWrapper.toSQL());
return queryWrapper;
}
}

View File

@ -76,6 +76,9 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
@Resource
protected Validator validator;
@Resource
private ISysDataScopeService dataScopeService;
@Override
public QueryWrapper query() {
return super.query().from(SYS_USER);
@ -110,8 +113,6 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
if (ObjectUtil.isNotNull(userBo.getDeptId())) {
queryWrapper.and(SYS_USER.DEPT_ID.eq(userBo.getDeptId()).or(SYS_USER.DEPT_ID.in(select(SYS_DEPT.DEPT_ID).from(SYS_DEPT.as("t")).where(findInSet(number(userBo.getDeptId()),SYS_DEPT.ANCESTORS).gt(0)))));
}
// addDataScope()
//TODO:数据范围过滤
return queryWrapper;
}
@ -137,7 +138,8 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
SYS_DEPT.DEPT_ID,SYS_DEPT.PARENT_ID,SYS_DEPT.ANCESTORS,SYS_DEPT.DEPT_NAME,SYS_DEPT.ORDER_NUM,SYS_DEPT.LEADER,SYS_DEPT.STATUS.as("dept_status")
))
.from(SYS_USER.as("u"))
.leftJoin(SYS_DEPT).as("d").on(SYS_DEPT.DEPT_ID.eq(SYS_USER.DEPT_ID));
.leftJoin(SYS_DEPT).as("d").on(SYS_DEPT.DEPT_ID.eq(SYS_USER.DEPT_ID))
.where(SYS_USER.DEL_FLAG.eq("0"));
//.leftJoin(SYS_USER_ROLE).as("ur").on(SYS_USER_ROLE.USER_ID.eq(SYS_USER.USER_ID))
//.leftJoin(SYS_ROLE).as("r").on(SYS_ROLE.ROLE_ID.eq(SYS_USER_ROLE.ROLE_ID));
}
@ -150,10 +152,8 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
* @return 用户信息集合信息
*/
@Override
//@DataScope(deptAlias = "d", userAlias = "u")
public List<SysUserVo> selectUserList(SysUserBo userBo) {
QueryWrapper queryWrapper = buildListQueryWrapper(userBo);
//TODO:数据范围过滤
QueryWrapper queryWrapper = dataScopeService.addCondition(buildListQueryWrapper(userBo));
return this.listAs(queryWrapper, SysUserVo.class);
}
@ -165,8 +165,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
*/
@Override
public TableDataInfo<SysUserVo> selectPage(SysUserBo userBo) {
QueryWrapper queryWrapper = buildListQueryWrapper(userBo);
//TODO:数据范围过滤
QueryWrapper queryWrapper = dataScopeService.addCondition(buildListQueryWrapper(userBo));
Page<SysUserVo> page = this.pageAs(PageQuery.build(), queryWrapper, SysUserVo.class);
return TableDataInfo.build(page);
}
@ -178,7 +177,6 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
* @return 用户信息集合信息
*/
@Override
//@DataScope(deptAlias = "d", userAlias = "u")
public TableDataInfo<SysUserVo> selectAllocatedPage(SysUserBo userBo) {
/* select distinct u.user_id, u.tenant_id, u.dept_id, u.user_name, u.nick_name, u.user_type, u.email, u.phonenumber, u.status, u.create_time
from sys_user u
@ -221,7 +219,6 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
* @return 用户信息集合信息
*/
@Override
//@DataScope(deptAlias = "d", userAlias = "u")
public TableDataInfo<SysUserVo> selectUnallocatedPage(SysUserBo userBo) {
/*select distinct u.user_id, u.tenant_id, u.dept_id, u.user_name, u.nick_name, u.user_type, u.email, u.phonenumber, u.status, u.create_time
from sys_user u
@ -245,6 +242,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
.leftJoin(SYS_USER_ROLE).as("ur").on(SYS_USER_ROLE.USER_ID.eq(SYS_USER.USER_ID))
.leftJoin(SYS_ROLE).as("r").on(SYS_ROLE.ROLE_ID.eq(SYS_USER_ROLE.ROLE_ID))
.where(SYS_USER.DEL_FLAG.eq("0"))
.and(SYS_USER.STATUS.eq("0"))
.and(SYS_ROLE.ROLE_ID.ne(userBo.getRoleId()).or(SYS_ROLE.ROLE_ID.isNull()))
.and(SYS_USER.USER_ID.notIn(select(SYS_USER.USER_ID).from(SYS_USER.as("u")).innerJoin(SYS_USER_ROLE).as("ur").on(SYS_USER_ROLE.USER_ID.eq(SYS_USER.USER_ID).and(SYS_USER_ROLE.ROLE_ID.eq(userBo.getRoleId())))));
if (StringUtils.isNotEmpty(userBo.getUserName())) {
@ -253,9 +251,8 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
if (StringUtils.isNotEmpty(userBo.getPhonenumber())) {
queryWrapper.and(SYS_USER.PHONENUMBER.like(userBo.getPhonenumber()));
}
//TODO:数据范围过滤
Page<SysUserVo> page = this.pageAs(PageQuery.build(), queryWrapper, SysUserVo.class);
Page<SysUserVo> page = this.pageAs(PageQuery.build(), dataScopeService.addCondition(queryWrapper), SysUserVo.class);
return TableDataInfo.build(page);
}
@ -307,6 +304,28 @@ public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser>
return this.getOneAs(queryWrapper,SysUserVo.class);
}
/**
* 个人中心模块通过用户ID查询用户
*
* @param userId 用户ID
* @return 用户对象信息
*/
@Override
public SysUserVo selectProfileUserById(Long userId) {
//使用leftjoin取得部门名称
QueryWrapper queryWrapper = QueryWrapper.create()
.select(QueryMethods.distinct(SYS_USER.USER_ID,SYS_USER.TENANT_ID,SYS_USER.DEPT_ID,SYS_USER.NICK_NAME,SYS_USER.USER_NAME,SYS_USER.USER_TYPE,SYS_USER.EMAIL,SYS_USER.AVATAR,SYS_USER.PHONENUMBER,SYS_USER.PASSWORD,SYS_USER.GENDER,SYS_USER.STATUS,SYS_USER.DEL_FLAG,SYS_USER.LOGIN_IP,SYS_USER.LOGIN_DATE,SYS_USER.CREATE_BY,SYS_USER.CREATE_TIME,SYS_USER.REMARK,
SYS_DEPT.DEPT_ID,SYS_DEPT.PARENT_ID,SYS_DEPT.ANCESTORS,SYS_DEPT.DEPT_NAME,SYS_DEPT.ORDER_NUM,SYS_DEPT.LEADER,SYS_DEPT.STATUS.as("dept_status")
))
.from(SYS_USER.as("u"))
.leftJoin(SYS_DEPT).as("d").on(SYS_DEPT.DEPT_ID.eq(SYS_USER.DEPT_ID))
.where(SYS_USER.DEL_FLAG.eq("0"));
if (ObjectUtil.isNotNull(userId)) {
queryWrapper.and(SYS_USER.USER_ID.eq(userId));
}
return this.getOneAs(queryWrapper,SysUserVo.class);
}
/**
* 查询用户所属角色组
*

View File

@ -58,70 +58,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
left join sys_role r on r.role_id = ur.role_id
</sql>
<!-- <select id="selectUserList" parameterType="SysUser" resultMap="SysUserResult">-->
<!-- select u.user_id, u.tenant_id, u.dept_id, u.nick_name, u.user_name, u.user_type, u.email, u.avatar, u.phonenumber, u.gender, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from sys_user u-->
<!-- left join sys_dept d on u.dept_id = d.dept_id-->
<!-- where u.del_flag = '0'-->
<!-- <if test="userId != null and userId != 0">-->
<!-- AND u.user_id = #{userId}-->
<!-- </if>-->
<!-- <if test="userName != null and userName != ''">-->
<!-- AND u.user_name like concat('%', #{userName}, '%')-->
<!-- </if>-->
<!-- <if test="status != null and status != ''">-->
<!-- AND u.status = #{status}-->
<!-- </if>-->
<!-- <if test="phonenumber != null and phonenumber != ''">-->
<!-- AND u.phonenumber like concat('%', #{phonenumber}, '%')-->
<!-- </if>-->
<!-- <if test="params.beginTime != null and params.beginTime != ''">&lt;!&ndash; 开始时间检索 &ndash;&gt;-->
<!-- AND date_format(u.create_time,'%y%m%d') &gt;= date_format(#{params.beginTime},'%y%m%d')-->
<!-- </if>-->
<!-- <if test="params.endTime != null and params.endTime != ''">&lt;!&ndash; 结束时间检索 &ndash;&gt;-->
<!-- AND date_format(u.create_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')-->
<!-- </if>-->
<!-- <if test="deptId != null and deptId != 0">-->
<!-- AND (u.dept_id = #{deptId} OR u.dept_id IN ( SELECT t.dept_id FROM sys_dept t WHERE find_in_set(#{deptId}, ancestors) ))-->
<!-- </if>-->
<!-- &lt;!&ndash; 数据范围过滤 &ndash;&gt;-->
<!-- ${params.dataScope}-->
<!-- </select>-->
<!-- <select id="selectAllocatedList" parameterType="SysUser" resultMap="SysUserResult">-->
<!-- select distinct u.user_id, u.tenant_id, u.dept_id, u.user_name, u.nick_name, u.user_type, u.email, u.phonenumber, u.status, u.create_time-->
<!-- from sys_user u-->
<!-- left join sys_dept d on u.dept_id = d.dept_id-->
<!-- left join sys_user_role ur on u.user_id = ur.user_id-->
<!-- left join sys_role r on r.role_id = ur.role_id-->
<!-- where u.del_flag = '0' and r.role_id = #{roleId}-->
<!-- <if test="userName != null and userName != ''">-->
<!-- AND u.user_name like concat('%', #{userName}, '%')-->
<!-- </if>-->
<!-- <if test="phonenumber != null and phonenumber != ''">-->
<!-- AND u.phonenumber like concat('%', #{phonenumber}, '%')-->
<!-- </if>-->
<!-- &lt;!&ndash; 数据范围过滤 &ndash;&gt;-->
<!-- ${params.dataScope}-->
<!-- </select>-->
<!-- <select id="selectUnallocatedList" parameterType="SysUser" resultMap="SysUserResult">-->
<!-- select distinct u.user_id, u.tenant_id, u.dept_id, u.user_name, u.nick_name, u.user_type, u.email, u.phonenumber, u.status, u.create_time-->
<!-- from sys_user u-->
<!-- left join sys_dept d on u.dept_id = d.dept_id-->
<!-- left join sys_user_role ur on u.user_id = ur.user_id-->
<!-- left join sys_role r on r.role_id = ur.role_id-->
<!-- where u.del_flag = '0' and (r.role_id != #{roleId} or r.role_id IS NULL)-->
<!-- and u.user_id not in (select u.user_id from sys_user u inner join sys_user_role ur on u.user_id = ur.user_id and ur.role_id = #{roleId})-->
<!-- <if test="userName != null and userName != ''">-->
<!-- AND u.user_name like concat('%', #{userName}, '%')-->
<!-- </if>-->
<!-- <if test="phonenumber != null and phonenumber != ''">-->
<!-- AND u.phonenumber like concat('%', #{phonenumber}, '%')-->
<!-- </if>-->
<!-- &lt;!&ndash; 数据范围过滤 &ndash;&gt;-->
<!-- ${params.dataScope}-->
<!-- </select>-->
</mapper>

View File

@ -4,9 +4,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysUserPostMapper">
<resultMap type="SysUserPost" id="SysUserPostResult">
<result property="userId" column="user_id" />
<result property="postId" column="post_id" />
</resultMap>
</mapper>

View File

@ -4,9 +4,4 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.SysUserRoleMapper">
<resultMap type="SysUserRole" id="SysUserRoleResult">
<result property="userId" column="user_id" />
<result property="roleId" column="role_id" />
</resultMap>
</mapper>