vue后台管理系统——权限管理模块

电商后台管理系统的功能——权限管理模块

1. 权限管理业务分析

通过权限管理模块控制不同的用户可以进行哪些操作,具体可以通过角色的方式进行控制,即每个用户分配一个特定的角色,角色包括不同的功能权限。 

2. 权限列表展示

<template slot-scope="scope">
    <el-tag size="small" v-if="scope.row.level == 0">一级</el-tag>
    <el-tag type="success" size="small" v-else-if="scope.row.level == 1">二级</el-tag>
    <el-tag type="warning" size="small" v-else>三级</el-tag>
</template>
// 获取权限列表数据
async getRightsList() {
    const { data: res } = await this.$http.get('rights/list')
    if (res.meta.status !== 200) {
        return this.$message.error('获取权限列表失败! ')
    }
    this.rightsList = res.data
}

创建权限管理组件:components目录下创建power文件夹,再创建Rights.vue

3. 角色列表展示

创建角色管理组件:components目录下创建power文件夹,再创建Roles.vue

  • 调用后台接口获取角色列表数据
  • 角色列表展示
// 获取所有角色列表
async getRolesList() {
    const { data: res } = await this.$http.get('roles')
    if (res.meta.status !== 200) {
        return this.$message.error('获取角色列表失败! ')
    }
    this.rolesList = res.data
},

4. 用户角色分配 

① 展示角色对话框

  • 实现用户角色对话框布局
  • 控制角色对话框显示和隐藏
  • 角色对话框显示时,加载角色列表数据
async showSetRoleDialog(userInfo) {
    this.userInfo = userInfo
    // 发起请求,获取所有角色的列表
    const { data: res } = await this.$http.get('roles')
    if (res.meta.status !== 200) {
        return this.$message.error('获取角色列表失败! ')
    }
    this.rolesList = res.data
    this.setRoleDialogVidible = true
}

② 完成角色分配功能 

点击编辑按钮分配角色

async saveNewRole() {
    if (this.selectedRoleId === '') {
        return this.$message.error('请选择新角色后再保存! ')
    }
    const { data: res } = await this.$http.put(`users/${this.userInfo.id}/role`, {
        rid: this.selectedRoleId
    })
    if (res.meta.status !== 200) {
        return this.$message.error('分配角色失败! ')
    }
    this.$message.success('分配角色成功! ')
    this.getUserList()
    this.setRoleDialogVidible = false
}

5. 角色权限分配 

① 表格行展开效果

通过 el-table-column 组件的 type =“expand” 方式实现表格行展开效果。 首先要通过scope.row拿到对应的角色信息,然后通过三层for循环把权限以对应的形式渲染出来。

<el-table :data="rolesList" border stripe>
    <!-- 展开行的列 -->
    <el-table-column type="expand">
        <template slot-scope="scope">
            <!-- 展开行内容填充 -->
        </template>
    </el-table-column>
</el-table>

② 渲染一级权限菜单

在表格展开行中渲染一级菜单

<el-row v-for="(item1, i1) in scope.row.children" :key="item1.id" class="centerRow">
    <!-- 这一列,专门渲染 一级权限 -->
    <el-col :span="5">
        <el-tag closable>{{item1.authName}}</el-tag>
        <i class="el-icon-caret-right"></i>
    </el-col>
    <!-- 还剩余 19 列,分配给二三级权限 -->
    <el-col :span="19">
        <!-- 这里显示二三级权限 -->
    </el-col>
</el-row>

③ 渲染二、三级权限菜单

在表格展开行中渲染二、 三级菜单

<el-row v-for="(item2, i2) in item1.children" :key="item2.id" class="centerRow">
    <!-- 放二级权限 -->
    <el-col :span="6">
        <el-tag closable type="success">{{item2.authName}}</el-tag>
        <i class="el-icon-caret-right"></i>
    </el-col>
    <!-- 放三级权限 -->
    <el-col :span="18">
        <el-tag closable type="warning" v-for="item3 in item2.children" :key="item3.id">
      {{item3.authName}}
     </el-tag> </el-col> </el-row>

出现一个bug:当页面宽度比较小时,小图标就被挤下来了,页面样式就很难看,如何解决呢?

解决方法:设置一个最小屏幕宽度,当屏幕宽度不够时,会出现滚动条

第二个问题:如何使一级权限和二级权限处于纵向居中的效果?

④ 删除角色下的权限

删除角色下指定权限的需求:给每个三级权限添加一个删除的功能。

点击权限菜单的删除按钮后,调用后台接口删除对应权限和其下的子权限。

<el-col :span="5">
    <el-tag closable @close="removeRight(scope.row, item1.id)">
        {{item1.authName}}
    </el-tag>
    <i class="el-icon-caret-right"></i>
</el-col>
const { data: res } = await this.$http.delete(`roles/${role.id}/rights/${rightId}`)
if (res.meta.status !== 200) {
    return this.$message.error('删除权限失败! ')
}
this.$message.success('删除权限成功! ')

出现一个bug:当删除权限之后,展开列表就自动关上了。这是因为我们删除权限之后,就重新渲染了整个角色列表,页面上的table表格会被重新渲染一次,所以展开状态就会被立即取消了。

解决方案:所以不建议调用重新渲染列表的函数,而是为当前的角色信息重新赋值下权限

⑤ 给角色分配权限流程

  • 实现角色分配权限对话框布局
  • 控制对话框的显示和隐藏
  • 对话框显示时调用后台接口加载权限列表数据
  • 完成树形权限菜单的展示
  • 选中默认的权限
  • 保存选中的权限,调用后台接口完成角色权限的分配

⑥ 实现权限分配对话框布局

  • 实现对话框布局效果
  • 控制对话框显示和隐藏

<!-- 分配权限的对话框 -->
<el-dialog title="分配权限" :visible.sync="setRightDialogVisible" width="50%"
  @close="resetSetRightDialog">
    <!-- 权限菜单 -->
    <span slot="footer" class="dialog-footer">
        <el-button @click="setRightDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveRight">确 定</el-button>
    </span>
</el-dialog>

 

⑦ 渲染权限的树形结构

  • 树形组件 el-tree 的基本使用
  • 权限数据的加载与填充

data绑定的是数据源,有了数据源,这棵树还不能正常的展示,还需要:props为整棵树指定数据绑定字段整棵树中看到的那些文本需要通过props来指定。

树添加一个复选框:show-checkbox

如果我们选中一项,对应选中的值肯定不能是文本,而是希望选中的是这项对应的id值。给这棵树添加node-key属性,值为每一项的id

优化:默认树形节点都是折叠起来的,而我们希望,只要一打开分配权限的对话框,就展开所有的节点

将角色身上已有的权限都加载到这棵树上:默认勾选上已有的权限

在点击分配权限按钮的同时,将当前角色身上所有三级权限的id获取出来,放到一个数组中,并且把这个数组通过属性绑定到default-checked-keys上即可。

<el-tree ref="tree" 
  :data
="rightTree"
  :props
="treeProps"
  show-checkbox
  nodekey
="id"
  default-expand-all
  :default-checked-keys
="defaultCheckedKeys"> </el-tree>

children代表的是实现父子嵌套用的是什么属性,label表示我们看到的文本是哪一个数据字段

// 在展示对话框之前,先获取到权限的树形结构数据
const { data: res } = await this.$http.get('rights/tree')
if (res.meta.status !== 200) return this.$message.error('初始化权限失败! ')
// 把权限的树形结构数据,保存到data中,供页面渲染使用
this.rightTree = res.data

⑧ 设置默认权限菜单选中

  • 获取所有叶子节点的 id
  • 设置权限节点选中
// 根据指定的节点和keys数组,递归获取所有三级节点的Id
getLeafIds(node, keys) {
    if (!node.children) {
        keys.push(node.id)
    } else {
        node.children.forEach(item => this.getLeafIds(item, keys))
    }
}
const keys = [] // 专门存放所有三级节点的Id
this.getLeafIds(role, keys)
this.defaultCheckedKeys = keys

通过一个递归函数来获取所有三级权限的id:

有一个小bug:当点击主管的分配权限按钮之后,可以看到主管对应的权限。然后再点开一个没有权限的角色,却发现里面勾选了很多权限。

这是为什么呢?因为我们每次点击按钮之后,都会把当前角色已有的三级权限id保存到数组中,但是在关系对话框的时候,并没有清空这个数组,所有数组的id值会越来越多

解决方案:每次关闭对话框的时候,都应该清空一下数组的内容

⑨ 完成角色授权

  • 获取所有选中的权限节点 id
  • 调用接口完成角色权限的分配

// 获取树形控件中,所有半选和全选节点的Id数组
const arr1 = this.$refs.tree.getCheckedKeys()
const arr2 = this.$refs.tree.getHalfCheckedKeys()
const rids = [...arr1, ...arr2].join(',')
const { data: res } = await this.$http.post(`roles/${this.selectedRoleId}/rights`, { rids })
if (res.meta.status !== 200) {
    return this.$message.error('分配权限失败! ')
}
this.$message.success('分配权限成功! ')

点击确定按钮分配权限

完成用户列表中的分配角色的功能:

6. 将权限管理功能上传到码云

  • 使用git checkout -b rights创建一个新分支并切换到该分支上
  • 使用git branch查看当前所处的分支,所有代码的修改也一起被切换到了rights子分支中
  • 使用git status命令检查当前分支的代码状态
  • 使用git add .命令统一增加到暂存区
  • 使用git commit -m "完成权限列表功能的开发"命令把rights分支提交到本地仓库中

本地rights的代码就是最新的了

使用git push -u origin rights命令把本地的rights分支推送到云端中

master是主分支,但是它的代码还是旧的,应该立即把所有的代码合并到主分支上

  • 使用git checkout master命令切换到主分支
  • 使用git merge rights命令从主分支上把rights分支上的代码合并过来
  • 使用git push命令将本地的master分支的代码推送到云端,这样master分支上的代码也是最新的了

代码地址:https://github.com/Emily-zcy/Backstage-Management-System-Based-on-vue

posted @ 2020-08-05 13:23  浮华夕颜  Views(4062)  Comments(3Edit  收藏  举报