前端權限流程(基于rbac實現思想)

1. 權限控制

1.1. 實現思想

基于rbac權限控制思想實現,給用戶分配角色,給角色分配權限

給用戶分配角色業務

注意:上方圖片是個示例圖,代表給用戶分配職位(角色),頁面中使用了Element-plus的el-? ? ? ? ?checkbox組件和el-checkbox-group組件

靜態結構(不完整)

          <el-form-item label="用戶姓名"><el-input v-model="userParams.username" :disabled="true"></el-input></el-form-item><el-form-item label="職位列表"><el-checkbox>全選</el-checkbox><!-- 顯示職位的的復選框 --><el-checkbox-group><el-checkboxv-for="(role, index) in 10":key="index":label="index">{{ index }}</el-checkbox></el-checkbox-group></el-form-item>

獲取&&存儲數據

首先先獲取全部的職位(角色)的數據與當前用戶已有的職位(角色)的數據,分別進行保存

//收集頂部復選框全選數據
let checkAll = ref<boolean>(false)
//控制頂部全選復選框不確定的樣式
let isIndeterminate = ref<boolean>(true)
//存儲全部職位的數據
let allRole = ref<AllRole>([])
//當前用戶已有的職位
let userRole = ref<AllRole>([])
//分配角色按鈕的回調
const setRole = async (row: User) => {//存儲已有的用戶信息Object.assign(userParams, row)//獲取全部的職位的數據與當前用戶已有的職位的數據let result: AllRoleResponseData = await reqAllRole(userParams.id as number)if (result.code == 200) {//存儲全部的職位allRole.value = result.data.allRolesList//存儲當前用戶已有的職位userRole.value = result.data.assignRoles//抽屜顯示出來drawer1.value = true}
}

展示數據

<!-- 抽屜結構:用戶某一個已有的賬號進行職位分配 --><el-drawer v-model="drawer1"><template #header><h4>分配角色(職位)</h4></template><template #default><el-form><el-form-item label="用戶姓名"><el-input v-model="userParams.username" :disabled="true"></el-input></el-form-item><el-form-item label="職位列表"><el-checkbox@change="handleCheckAllChange"v-model="checkAll":indeterminate="isIndeterminate">全選</el-checkbox><!-- 顯示職位的的復選框 --><el-checkbox-groupv-model="userRole"@change="handleCheckedCitiesChange"><el-checkboxv-for="(role, index) in allRole":key="index":label="role">{{ role.roleName }}</el-checkbox></el-checkbox-group></el-form-item></el-form></template></el-drawer>

詳細解釋

全選部分:

@change:全選框點擊時的回調

v-model:綁定的數據,根據這個值決定是否全選(是一個布爾值)

:indeterminate:不確定狀態,既沒有全選也沒有全不選

?


復選框部分:

v-for="(role, index) in allRole":遍歷allRole。

:label="role":收集的數據(勾上的數據)

v-model="userRole":綁定收集的數據,也就是收集的數據存儲到userRole中。

@change:勾選變化時的回調(點擊每個復選框都會執行的回調)

?


全選框勾選的回調:

實現原理:函數會將勾選與否注入到val中,如果是,就將全部數據(allRole)賦值給選中的數據(userRole),選中的數據通過v-model實現頁面的同步變化

該函數會接收到一個布爾值,如果為真代表全選按鈕被勾選,在回調中需要將全部角色(職位)數據賦值給在el-checkbox-group使用v-model綁定的變量中(該變量表示被選中的數據)

//頂部的全部復選框的change事件
const handleCheckAllChange = (val: boolean) => {//val:true(全選)|false(沒有全選)userRole.value = val ? allRole.value : []//不確定的樣式(確定樣式)isIndeterminate.value = false
}

復選框

每勾選一個復選框就會執行該函數,并收集勾選的數據到數組中傳遞進該函數

在函數內部判斷數組的長度是否等于全部角色數據,如果等于需要將上方的權限按鈕勾上,因為已經使用v-model綁定了,所以直接給checkAll.value賦一個布爾值即可

//頂部全部的復選框的change事件
const handleCheckedCitiesChange = (value: string[]) => {//頂部復選框的勾選數據//代表:勾選上的項目個數與全部的職位個數相等,頂部的復選框勾選上checkAll.value = value.length === allRole.value.length//不確定的樣式isIndeterminate.value = value.length !== allRole.value.length
}

當點擊確定按鈕的回調

需要收集兩個參數:第一個:當前用戶的id標識,第二個:從收集好的userRole中使用map過濾出選中的角色的id標識(數組)

然后發起分配用戶角色的請求,請求成功,重新獲取更新完畢用戶的信息。

//確定按鈕的回調(分配職位)
const confirmClick = async () => {//收集參數let data: SetRoleData = {userId: userParams.id as number,roleIdList: userRole.value.map((item) => {return item.id as number}),}//分配用戶的職位let result: any = await reqSetUserRole(data)if (result.code == 200) {//提示信息ElMessage({ type: 'success', message: '分配職務成功' })//關閉抽屜drawer1.value = false//獲取更新完畢用戶的信息,更新完畢留在當前頁getHasUser(pageNo.value)}
}

?看到這里,相信你一定有收獲!!!

給角色分配權限業務

靜態結構

當點擊上圖中的分配權限按鈕時,會彈出一個抽屜組件(el-drawer),利用樹組件展示所有權限數據,并可以看到點擊的角色已有的權限數據(勾選的)

注意:上方圖片是個示例圖,代表給角色分配權限,頁面中使用了Element-plus的el-table和el-drawer,el-tree組件。

注意:因為這是在vue3和typescript項目中,所以進行了類型限制。

type這里MenuData與MenuList互相調用,適合這種樹狀的數據結構(type還可以定義多個復雜類型)

//菜單與按鈕數據的ts類型
export interface MenuData {id: numbercreateTime: stringupdateTime: stringpid: numbername: stringcode: stringtoCode: stringtype: numberstatus: nulllevel: numberchildren?: MenuListselect: boolean
}
export type MenuList = MenuData[]

分配權限按鈕

獲取&&存儲數據

根據角色id發送請求獲取全部角色權限數據(包含該角色已有的職位)

//準備一個數組:數組用于存儲勾選的節點的ID(四級的)
let selectArr = ref<number[]>([])
//已有的職位的數據
const setPermisstion = async (row: RoleData) => {//抽屜顯示出來drawer.value = true//收集當前要分類權限的職位的數據Object.assign(RoleParams, row)//根據職位獲取權限的數據let result: MenuResponseData = await reqAllMenuList(RoleParams.id as number)if (result.code == 200) {menuArr.value = result.data//下面這行代碼下面會具體講解,可以先往下看selectArr.value = filterSelectArr(menuArr.value, [])}
}

?使用樹組件展示全部權限數據(樹組件詳細使用說明)

我們重點關注el-tree組件,先介紹一些常用屬性和方法

const defaultProps = {//子樹為節點對象的childrenchildren: 'children',//節點標簽為節點對象的name屬性label: 'name',
}

常用屬性:?

1. data:展示的數據(數據源)

2. show-checkbox:節點是否可被選擇(點擊可以選中)

3. node-key:每個樹節點用來作為唯一標識的屬性,整棵樹應該是唯一的(如果樹中包含children子數據,該屬性不能省略)

4. default-expand-all:默認展開所有節點

5. default-checked-keys:默認勾選的節點的 key 的數組(是一個數組,數組中存放的就是上面node-key存放的唯一標識)

6. default-expanded-keys:默認展開的節點的 key 的數組(是一個數組,數組中存放的就是上面node-key存放的唯一標識)

7. current-node-key:當前選中的節點(可以是number或string類型)

8. props:接收一個對象,對象中可以包含以下兩個屬性(還可以包含其他屬性,這里只列舉了以下兩個)

label:指定節點標簽為節點對象的某個屬性值(就是代表了要在頁面中展示的節點名稱) ,children:指定子樹為節點對象的某個屬性值(就是代表去哪個字段下讀取數據當作子節點的數據)(注意:label和children這兩個屬性名是不變的,屬性值需要根據項目需要進行修改)


常用方法:

使用el-tree樹組件提供的方法時,需要先在el-tree組件標簽上利用ref打上標識(<el-tree ref="xxx"> </el-tree>),然后通過ref得到el-tree組件實例才能調用對應方法!

1. getCheckedKeys:如果在el-tree標簽上設置了show-checkbox屬性且被選中,通過樹組件實例.getCheckedKeys進行調用,它將返回當前選中節點key的數組(該數組由所有被選中的節點的id屬性組成【為什么是id屬性呢? ? ? ? ?因為:在el-tree標簽上設置了node-key="id"屬性。所以該方法會收集所有選中的節點對象的id屬性】)


?2. getHalfCheckedKeys:如果在el-tree標簽上設置了show-checkbox屬性且被選中,通過樹組件實例.getHalfCheckedKeys進行調用,它將返回當前半選中的節點的id屬性組成的數組
如遇這種情況該方法一般會和上面的getCheckedKeys配合使用


在樹組件中展示已分配的權限

為什么要使用遞歸函數?
因為不能直接根據1級,2級,3級的select屬性進行判斷,要判斷最內層的職位對象的select屬性是真是假,因為層級較深要判斷最內層的職位對象的select屬性,所以使用了遞歸函數

具體實現思路:
? ? 目的:要先對返回的全部權限數據進行過濾,找到最內層的職位對象,根據其select屬性判斷!
?? ?封裝一個遞歸函數,接收兩個參數,一個全部權限數據,一個空數組(用于存放滿足level為4級職位對象中的select屬性為真的職位的id),在遞歸函數?? ?中使用for Each遍歷全部權限數據,判斷item.select && item.level === 4如果滿足說明到最內層了,將當前這個對象的id屬性(item.id)push到空數組中,否則代表沒有到最內層,繼續判斷item.children && item.children.length > 0 滿足該條件遞歸調用?? ?filterSelectArr(item.children,initArr),最后返回這個過濾好的數組,交給el-tree組件的default-checked-keys屬性,那么就可以找出該角色已有的權限就可以在樹組件選中了

//分配權限按鈕的回調
//已有的職位的數據
const setPermisstion = async (row: RoleData) => {//抽屜顯示出來drawer.value = true//收集當前要分類權限的職位的數據Object.assign(RoleParams, row)//根據職位獲取權限的數據let result: MenuResponseData = await reqAllMenuList(RoleParams.id as number)if (result.code == 200) {menuArr.value = result.data/*最后返回這個過濾好的數組,交給el-tree組件的default-checked-keys屬性,那么就可以找出該角色已有的權限就可以在樹組件選中了*/selectArr.value = filterSelectArr(menuArr.value, [])}
}
// 遞歸函數
const filterSelectArr = (allData: any, initArr: any) => {allData.forEach((item: any) => {if (item.select && item.level == 4) {initArr.push(item.id)}if (item.children && item.children.length > 0) {//層層遞進,直到最內層的職位對象的level屬性===4filterSelectArr(item.children, initArr)}})//返回這個過濾好的數組return initArr
} 

收集用戶分配的權限

我們這里收集主要用到了2個方法:getCheckedKeys、getHalfCheckedKeys。它們會返回已選擇以及半選擇用戶的id數組(這兩個方法上方都有詳細解釋)

//抽屜確定按鈕的回調
const handler = async () => {//職位(角色)的IDconst roleId = RoleParams.id as number//選中節點的ID		getCheckedKeys方法會得到show-checkbox為true選中的全部節點對象的id組成的數組//為什么是能收集到id 		因為el-tree配置了node-key="id"屬性let arr = tree.value.getCheckedKeys()//半選的IDlet arr1 = tree.value.getHalfCheckedKeys()let permissionId = arr.concat(arr1)//下發權限let result: any = await reqSetPermisstion(roleId, permissionId)if (result.code == 200) {//抽屜關閉drawer.value = false//提示信息ElMessage({ type: 'success', message: '分配權限成功' })//頁面刷新window.location.reload()}
}

繼續加油!


1.2. 實現深度

3級權限:模塊權限、頁面權限、按鈕權限

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/72570.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/72570.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/72570.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

軟件高級架構師 - 軟件工程

補充中 測試 測試類型 靜態測試 動態測試 測試階段 單元測試中&#xff0c;包含性能測試&#xff0c;如下&#xff1a; 集成測試中&#xff0c;包含以下&#xff1a; 維護 遺留系統處置 高水平低價值&#xff1a;采取集成 對于這類系統&#xff0c;采取 集成 的方式&…

python3.13安裝教程【2025】python3.13超詳細圖文教程(包含安裝包)

文章目錄 前言一、python3.13安裝包下載二、Python 3.13安裝步驟三、Python3.13驗證 前言 本教程將為你詳細介紹 Python 3.13 python3.13安裝教程&#xff0c;幫助你順利搭建起 Python 3.13 開發環境&#xff0c;快速投身于 Python 編程的精彩實踐中。 一、python3.13安裝包下…

【極客時間】瀏覽器工作原理與實踐-2 宏觀視角下的瀏覽器 (6講) - 2.5 渲染流程(上):HTML、CSS和JavaScript,是如何變成頁面的?

https://time.geekbang.org/column/article/118205 2.5 渲染流程&#xff08;上&#xff09;&#xff1a;HTML、CSS和JavaScript&#xff0c;是如何變成頁面的&#xff1f; 2.4講了導航相關的流程&#xff0c;那導航被提交后又會怎么樣呢&#xff1f; 就進入了渲染階段。 這…

小模型和小數據可以實現AGI嗎

小模型和小數據很難實現真正的 通用人工智能&#xff08;AGI, Artificial General Intelligence&#xff09;&#xff0c;但在特定任務或受限環境下&#xff0c;可以通過高效的算法和優化方法實現“近似 AGI” 的能力。 1. 為什么小模型小數據難以實現 AGI&#xff1f; AGI 需…

Android14 OTA差分包升級報kPayloadTimestampError (51)

由于VF 架構&#xff0c; 所以鏡像的打包時間可能存在偏差&#xff0c; 如 boot.img 和 客制化的一些鏡像打包 可能會在 vendor 側進行打包。 而 與system 側進行merge 時&#xff0c;時間戳比較亂&#xff0c;為了解決這個問題&#xff0c;讓時間戳進行統一。 使用adb方式驗證…

CMake學習筆記(一):工程的新建和如何將源文件生成二進制文件

cmake是我們在工作過程中比較常見的一個工具&#xff0c;該系列文章是自己用來學習的筆記。目前只是記錄下自己學習cmake的過程中的一些重要的知識點&#xff0c;其是以項目需求為導向并非完整的cmake的學習路線和系統&#xff0c;同樣也并非適合所有的人。 1.生成一個可執行文…

重定位(1)

一、重定位 1、對于有強大ROM的板子&#xff0c;他們會將上電后的程序放到指定RAM內存 2、無強大片內ROM的板子&#xff0c;自己編程序讓他知道RAM內存指定位置 指定位置&#xff1a;就是鏈接地址&#xff0c;指定哪里&#xff0c;哪里就被編譯好一塊內存用來存放上電的程序 …

自由學習記錄(41)

代理服務器的核心功能是在客戶端&#xff08;用戶設備&#xff09;和目標服務器&#xff08;網站/資源服務器&#xff09;之間充當“中介”&#xff0c;具體過程如下&#xff1a; 代理服務器的工作流程 當客戶端希望訪問某個網站&#xff08;比如 example.com&#xff09;時&…

Jadx Gui 的詳細介紹、安裝指南、使用方法及配置說明

Jadx Gui&#xff1a;安卓應用逆向分析神器 一、Jadx Gui 簡介 Jadx 是一款開源的 Android 反編譯工具&#xff0c;支持將 .apk、.aab、.dex 等文件反編譯為可讀的 Java/Kotlin 源代碼和資源文件&#xff08;如 XML、PNG&#xff09;。其特點包括&#xff1a; 圖形化界面&am…

Linux+apache之 瀏覽器訪問云服務器磁盤的圖片,通過tomcat

https://javab.blog.csdn.net/article/details/80580520 安裝tomcact 修改添加 <Context docBase"/home/wyp/images" path"/img" debug"0" reloadable"true" />修改完成后保存重啟tomcat服務。 測試訪問方式&#xff1a;http…

軟件工程與實踐(第4版 新形態) 練習與實踐1

軟件工程與實踐&#xff08;第4版 新形態&#xff09; 練習與實踐1 1.填空題 (1)程序&#xff0c;文檔 (2)系統軟件&#xff0c;支撐軟件&#xff0c;應用軟件 (3)系統方法 (4)軟件開發和維護 (5)工程的概念、原理、技術和方法 (6)實現軟件的優質高產 (7)軟件開發技術和…

基于遺傳算法的無人機三維路徑規劃仿真步驟詳解

基于遺傳算法的無人機三維路徑規劃仿真步驟詳解 一、問題定義 目標:在三維空間內,尋找從起點到終點的最優路徑,需滿足: 避障:避開所有障礙物。路徑最短:總飛行距離盡可能短。平滑性:轉折角度不宜過大,降低機動能耗。輸入: 三維地圖(含障礙物,如立方體、圓柱體)。起…

LIUNX學習-線程

線程概念 一個進程需要訪的大部分資源&#xff0c;諸如自身的代碼、數據、new\malloc的空間數據、命令行參數和環境變量、動態庫、甚至是系統調用訪問內核代碼…都是通過虛擬地址空間來訪問的。換而言之&#xff0c;進程地址空間是進程的資源窗口&#xff01;&#xff01; ? …

1.Big-endian/ little endian大端對齊、小端對齊

一、大端模式、小端模式的介紹 Little endian&#xff1a;是低位字節排放在內存的低地址端、高位字節排放在內存的高地址端。 Big-endian&#xff1a;是高位字節排放在內存的低地址端、低位字節排放在內存的高地址端。 西門子是大端模式&#xff0c;因為比如 MW100 MB100(高位…

[mybatis]resultMap詳解

resultMap Mybatis中提供了resultMap功能&#xff0c;可以將數據庫查詢結果映射到Java對象&#xff0c;用于解決 字段名與屬性名不一致 或 復雜關系&#xff08;如一對多&#xff09;的映射問題。 比如一個User類&#xff0c;在它的屬性里還有另一個子對象&#xff08;或者多…

SpringBoot Actuator

SpringBoot Actuator 一、簡介二、入門1、依賴2、默認監控指標3、查詢監控指標4、全量監控指標 三、Spring Boot Admin1、主要功能2、Admin3、Client4、應用墻5、其他 四、定制化1、定制Health端點2、定制Info端點3、定制Metrics端點4、定制Endpoint端點 一、簡介 SpringBoot自…

python標識符

在 Python 中&#xff0c;標識符&#xff08;Identifier&#xff09;是指用來標識變量、函數、類、模塊等的名稱。標識符的命名規則如下&#xff1a; 1. 標識符的命名規則 字母、數字和下劃線&#xff1a;標識符可以由字母&#xff08;a-z, A-Z&#xff09;、數字&#xff08;…

06 HarmonyOS Next性能優化之LazyForEach 列表渲染基礎與實現詳解 (一)

溫馨提示&#xff1a;本篇博客的詳細代碼已發布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下載運行哦&#xff01; 目錄 一、代碼結構概覽二、詳細代碼解析1. 數據源管理實現2. 數據結構定義3. 優化的列表項組件4. 主列表組件實現 一、代碼結構概覽 本文將詳細解…

vscode 查看3d

目錄 1. vscode-3d-preview obj查看ok 2. vscode-obj-viewer 沒找到這個插件&#xff1a; 3. 3D Viewer for Vscode 查看obj失敗 1. vscode-3d-preview obj查看ok 可以查看obj 顯示過程&#xff1a;開始是綠屏&#xff0c;過了1到2秒&#xff0c;后來就正常看了。 2. vsc…

excel 斜向拆分單元格

右鍵-合并單元格 右鍵-設置單元格格式-邊框 在設置好分割線后&#xff0c;你可以開始輸入文字。 需要注意的是&#xff0c;文字并不會自動分成上下兩行。 為了達到你期望的效果&#xff0c;你可以通過 同過左對齊、上對齊 空格鍵或使用【AltEnter】組合鍵來調整單元格中內容的…