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

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

最新文章

  1. pm剩余要看的内容
  2. 几点基于Web日志的Webshell检测思路
  3. DP 子序列问题
  4. Watch​Kit Learning Resources
  5. CSS伪类对象before和after的用法
  6. dubbo简述
  7. HTML5画布(阴影)
  8. hdu5001(概率dp)
  9. 并发编程实践三:Condition
  10. C# 获取磁盘容量
  11. 简易RPC框架-上下文
  12. BOM(浏览器对象模型)的一些操作
  13. Linux CenterOS安装mysql-5.6.12-linux-glibc2.5-x86_64.tar.gz步骤
  14. Java基础_0303:封装性初步
  15. java I/O系统 LineNumberReader类
  16. 【Java】 剑指offer(52) 两个链表的第一个公共结点
  17. Linux内核设计(第二周)——操作系统工作原理
  18. 在EditText里输入小写字母时,将小写字母转化为大写显示
  19. Java基础-IO流对象之内存操作流(ByteArrayOutputStream与ByteArrayInputStream)
  20. 教你破解MyEclipse到2016年【图文详解】

热门文章

  1. IEEE 802.66( WiMax)的衰亡
  2. 网络协议及osi模型
  3. vue3 门户网站搭建6-wangeditor
  4. async/await和promise的执行顺序
  5. Python矩阵作图库matplotlib的初级使用(2)
  6. 转载-Shell脚本中字符串截取功能
  7. 尝试window10系统下使用appuim获取ios元素
  8. 大道至简读后感以及JAVA伪代码
  9. kmp失效函数(测试博客的编辑器)
  10. 面试官:来说说 https 和 http 区别?