《若依ruoyi》第三十八章:Ruoyi-数据权限使用拆解

在实际应用中,公司会有多个部门存在,每个部门的职能不一样,看到的数据不一样,每个部门也会分层级,例如普通员工职能看到自己创建的数据,部门领导可以看到该部门下的所有员工数据,系统需要实现这一逻辑,就是数据权限功能

1、功能实现操作界面

第一步:点击右侧菜单导航栏,点击角色管理

第二步:点击角色右侧的更多的数据权限

数据权限分为:全部数据、自定义数据、本部门数据、本部门以及一下数据、仅本人数据权限。

2、数据权限配置

1、如下是弹窗显示数据权限代码

<!-- 分配角色数据权限对话框 --><el-dialog :title="title" :visible.sync="openDataScope" width="500px" append-to-body>
  <el-form :model="form" label-width="80px">
    <el-form-item label="角色名称">
      <el-input v-model="form.roleName" :disabled="true" />
    </el-form-item>
    <el-form-item label="权限字符">
      <el-input v-model="form.roleKey" :disabled="true" />
    </el-form-item>
    <el-form-item label="权限范围">
      <el-select v-model="form.dataScope" @change="dataScopeSelectChange">
        <el-option
          v-for="item in dataScopeOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        ></el-option>
      </el-select>
    </el-form-item>
    <el-form-item label="数据权限" v-show="form.dataScope == 2">
      <el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">展开/折叠</el-checkbox>
      <el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">全选/全不选</el-checkbox>
      <el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">父子联动</el-checkbox>
      <el-tree
        class="tree-border"
        :data="deptOptions"
        show-checkbox
        default-expand-all
        ref="dept"
        node-key="id"
        :check-strictly="!form.deptCheckStrictly"
        empty-text="加载中,请稍候"
        :props="defaultProps"
      ></el-tree>
    </el-form-item>
  </el-form>
  <div slot="footer" class="dialog-footer">
    <el-button type="primary" @click="submitDataScope">确 定</el-button>
    <el-button @click="cancelDataScope">取 消</el-button>
  </div></el-dialog>

2、下面是提交数据权限代码

/** 提交按钮(数据权限) */submitDataScope: function() {  if (this.form.roleId != undefined) {    this.form.deptIds = this.getDeptAllCheckedKeys();
    dataScope(this.form).then(response => {      this.$modal.msgSuccess("修改成功");      this.openDataScope = false;      this.getList();
    });
  }
},

3、后台api接口处理修改数据权限

1、如下是接口代码

/**
 * 修改保存数据权限
 */@PreAuthorize("@ss.hasPermi('system:role:edit')")
 @Log(title = "角色管理", businessType = BusinessType.UPDATE)@PutMapping("/dataScope")
public AjaxResult dataScope(@RequestBody SysRole role)
{   
 
     roleService.checkRoleAllowed(role);    
     roleService.checkRoleDataScope(role.getRoleId());    
     return toAjax(roleService.authDataScope(role));
}

业务逻辑说明:

1)、检查角色是否允许操作,针对登录者操作,具体代码
roleService.checkRoleAllowed(role);

2)、校验角色是否有数据权限,
roleService.checkRoleDataScope(role.getRoleId());

3)、修改数据权限信息,就是将角色绑定到角色部门表,并保存数据权限

如下是角色数据库表:

CREATE TABLE `sys_role` (  `role_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '角色ID',  `role_name` varchar(30) NOT NULL COMMENT '角色名称',  `role_key` varchar(100) NOT NULL COMMENT '角色权限字符串',  `role_sort` int(4) NOT NULL COMMENT '显示顺序',  `data_scope` char(1) DEFAULT '1' COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)',  `menu_check_strictly` tinyint(1) DEFAULT '1' COMMENT '菜单树选择项是否关联显示',  `dept_check_strictly` tinyint(1) DEFAULT '1' COMMENT '部门树选择项是否关联显示',  `status` char(1) NOT NULL COMMENT '角色状态(0正常 1停用)',  `del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',  `create_by` varchar(64) DEFAULT '' COMMENT '创建者',  `create_time` datetime DEFAULT NULL COMMENT '创建时间',  `update_by` varchar(64) DEFAULT '' COMMENT '更新者',  `update_time` datetime DEFAULT NULL COMMENT '更新时间',  `remark` varchar(500) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='角色信息表';

data_scope:数据范围。

4、具体数据权限实现方式

在执行mysql到时候,通过spring 的aop切面,在执行sql前,追加数据过滤的sql语句。

具体代码如下

代码路径是在ruoyi-framewro模块下的

package com.ruoyi.framework.aspectj;DataScopeAspect

/**
 * 数据范围过滤
 *
 * @param joinPoint 切点
 * @param user 用户
 * @param deptAlias 部门别名
 * @param userAlias 用户别名
 * @param permission 权限字符
 */public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias, String permission){
    StringBuilder sqlString = new StringBuilder();
    List<String> conditions = new ArrayList<String>();    for (SysRole role : user.getRoles())
    {
        String dataScope = role.getDataScope();       
        if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope))
        {            
            continue;
        }        if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions())
                && !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
        {            
            continue;
        }        if (DATA_SCOPE_ALL.equals(dataScope))
        {
            sqlString = new StringBuilder();
            conditions.add(dataScope);            break;
        }        else if (DATA_SCOPE_CUSTOM.equals(dataScope))
        {
            sqlString.append(StringUtils.format(                    " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,
                    role.getRoleId()));
        }        else if (DATA_SCOPE_DEPT.equals(dataScope))
        {
            sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
        }        else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
        {
            sqlString.append(StringUtils.format(                    " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
                    deptAlias, user.getDeptId(), user.getDeptId()));
        }        else if (DATA_SCOPE_SELF.equals(dataScope))
        {            if (StringUtils.isNotBlank(userAlias))
            {
                sqlString.append(StringUtils.format(" OR {}.user_id = {} ", userAlias, user.getUserId()));
            }            else
            {                // 数据权限为仅本人且没有userAlias别名不查询任何数据
                sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
            }
        }
        conditions.add(dataScope);
    }    // 多角色情况下,所有角色都不包含传递过来的权限字符,这个时候sqlString也会为空,所以要限制一下,不查询任何数据
    if (StringUtils.isEmpty(conditions))
    {
        sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));
    }    if (StringUtils.isNotBlank(sqlString.toString()))
    {
        Object params = joinPoint.getArgs()[0];        if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
        {
            BaseEntity baseEntity = (BaseEntity) params;
            baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
        }
    }
}

如上述代码,根据数据库配置的data_scope字段,决定增加哪些sql语句。

来源: 互联网
本文观点不代表源码解析立场,不承担法律责任,文章及观点也不构成任何投资意见。

赞 ()

相关推荐

发表回复

评论列表

点击查看更多

    联系我们

    在线咨询: QQ交谈

    微信:13450247865

    邮件:451255340#qq.com

    工作时间:周一至周五,9:30-18:30,节假日休息

    微信