電商后台管理系統的功能——權限管理模塊
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/Emliy-zcy/Backstage-Management-System-Based-on-vue