手把手教你實現Java許可權管理系統 前端篇(十三):頁面許可權控制
許可權控制方案
既然是後臺許可權管理系統,當然少不了許可權控制啦,至於許可權控制,前端方面當然就是對頁面資源的訪問和操作控制啦。
前端資源許可權主要又分為兩個部分,即導航選單的檢視許可權和頁面增刪改操作按鈕的操作許可權。
我們的設計把頁面導航選單和頁面操作按鈕統一儲存在選單資料庫表中,選單表中包含以下許可權關注點。
選單型別
選單型別程式碼頁面資源的型別。型別包括,0:目錄 1:選單 2:按鈕'。
許可權標識
許可權標識即是代表此頁面資源,用來進行許可權控制的唯一標識,主要是進行增刪改查的許可權控制。
許可權標識包括,sys:user:add:新增 sys:user:edit:編輯 sys:user:delete:刪除 sys:user:view:檢視。
注:目前檢視都可以通過選單可見性進行控制,所以檢視許可權標識目前沒有用上,如果需要顯示無許可權頁面可以使用。
選單表結構
具體的選單表結構如下。
-- ------------------------------------------------ -- 選單 -- ------------------------------------------------ -- Table structure for `sys_menu` -- ------------------------------------------------ CREATE TABLE `sys_menu` ( `id`bigint NOT NULL AUTO_INCREMENT COMMENT '編號', `name` varchar(50) COMMENT '選單名稱', `parent_id` bigint COMMENT '父選單ID,一級選單為0', `url` varchar(200) COMMENT '選單URL', `perms` varchar(500) COMMENT '授權(多個用逗號分隔,如:sys:user:add,sys:user:edit)', `type` int COMMENT '型別 0:目錄 1:選單 2:按鈕', `icon` varchar(50) COMMENT '選單圖示', `order_num` int COMMENT '排序', `create_by` varchar(50) COMMENT '建立人', `create_time` datetime COMMENT '建立時間', `last_update_by` varchar(50) COMMENT '更新人', `last_update_time` datetime COMMENT '更新時間', `del_flag` tinyint DEFAULT 0 COMMENT '是否刪除 -1:已刪除 0:正常', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='選單管理';
導航選單實現思路
1.使用者登入系統
使用者登入系統之後,跳轉到首頁。
2.根據使用者載入導航選單
在路由導航守衛路由時載入使用者導航選單並存儲到store。
載入過程如下,返回結果排除按鈕型別。
user -> user_role -> role -> role_menu -> menu。
3.導航欄讀取選單樹
導航欄到sotre讀取導航樹並進行展示。
頁面按鈕實現思路
1.使用者登入系統
使用者登入系統之後,跳轉到首頁。
2.根據使用者載入許可權標識集合
在路由導航守衛路由時載入使用者許可權標識集合。
載入過程如下,返回結果是使用者許可權標識的集合。
user -> user_role -> role -> role_menu -> menu。
3.頁面按鈕控制
頁面操作按鈕提供許可權標識,查詢是否在使用者許可權標識集合中。
在:有許可權,可見或可用,不在:無許可權,不可見或禁用。
目前本系統採用的是狀態禁用。
許可權控制實現
導航選單許可權
載入導航選單
如下圖所示,在導航守衛路由時載入導航選單並儲存狀態。
router/index.js
頁面元件引用
導航欄頁面從共享狀態中讀取導航選單樹並展示。
views/NavBar/NavBar.vue
views/NavBar/NavBar.vue
頁面按鈕許可權
新增許可權獲取介面
http/modules/user.js
// 查詢使用者的選單許可權標識集合 export const findPermissions = (params) => { return axios({ url: '/user/findPermissions', method: 'get', params }) }
新增許可權獲取介面
store/modules/user.js
export default { state: { perms: [], // 使用者許可權標識集合 }, getters: { }, mutations: { setPerms(state, perms){ // 使用者許可權標識集合 state.perms = perms; } }, actions: { } }
載入許可權標識
如下圖所示,在導航守衛路由時載入許可權標識並儲存狀態。
router/index.js
許可權按鈕判斷
封裝了許可權操作按鈕元件,在元件中根據外部傳入的許可權標識進行許可權判斷。
views/Core/KtButton.vue
<template> <el-button :size="size" :type="type" :loading="loading" :disabled="!hasPerms(perms)" @click="handleClick"> {{label}} </el-button> </template> <script> import { hasPermission } from '@/permission/index.js' export default { name: 'KtButton', props: { label: { // 按鈕顯示文字 type: String, default: 'Button' }, size: { // 按鈕尺寸 type: String, default: 'mini' }, type: { // 按鈕型別 type: String, default: null }, loading: { // 按鈕載入標識 type: Boolean, default: false }, disabled: { // 按鈕是否禁用 type: Boolean, default: false }, perms: { // 按鈕許可權標識,外部使用者傳入 type: String, default: null } }, data() { return { } }, methods: { handleClick: function () { // 按鈕操作處理函式 this.$emit('click', {}) }, hasPerms: function (perms) { // 根據許可權標識和外部指示狀態進行許可權判斷 return hasPermission(perms) & !this.disabled } }, mounted() { } } </script> <style scoped> </style>
許可權判斷邏輯
src/permission/index.js
import store from '@/store' /** * 判斷使用者是否擁有操作許可權 * 根據傳入的許可權標識,檢視是否存在使用者許可權標識集合 * @param perms */ export function hasPermission (perms) { let hasPermission = false let permissions = store.state.user.perms for(let i=0, len=permissions.length; i<len; i++) { if(permissions[i] === perms) { hasPermission = true; break } } return hasPermission }
許可權按鈕引用
views/Sys/User.vue
測試效果
1.可用狀態,操作按鈕可用。
2.修改頁面的許可權標識,導致認證失敗。
如下圖所示,修改新增和刪除按鈕的許可權標識(加個2),導致許可權認證失敗。
3.無許可權,操作按鈕禁用。
新增和刪除按鈕因為修改了許可權標識,匹配失敗,變成了禁用狀態。