添加动态权限控制
This commit is contained in:
@@ -15,6 +15,7 @@ import { initComponentAdapter } from './adapter/component';
|
||||
import { initSetupVbenForm } from './adapter/form';
|
||||
import App from './app.vue';
|
||||
import { router } from './router';
|
||||
import { registerPermissionDirective } from './utils/permission';
|
||||
|
||||
async function bootstrap(namespace: string) {
|
||||
// 初始化组件适配器
|
||||
@@ -48,6 +49,8 @@ async function bootstrap(namespace: string) {
|
||||
|
||||
// 安装权限指令
|
||||
registerAccessDirective(app);
|
||||
// 注册自定义v-permission指令
|
||||
registerPermissionDirective(app);
|
||||
|
||||
// 初始化 tippy
|
||||
const { initTippy } = await import('@vben/common-ui/es/tippy');
|
||||
|
||||
@@ -13,9 +13,12 @@ import { defineStore } from 'pinia';
|
||||
import { getAccessCodesApi, getUserInfoApi, loginApi, logoutApi } from '#/api';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
import { usePermissionStore } from './permission';
|
||||
|
||||
export const useAuthStore = defineStore('auth', () => {
|
||||
const accessStore = useAccessStore();
|
||||
const userStore = useUserStore();
|
||||
const permissionStore = usePermissionStore();
|
||||
const router = useRouter();
|
||||
|
||||
const loginLoading = ref(false);
|
||||
@@ -62,7 +65,7 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
|
||||
if (userInfo?.realName) {
|
||||
notification.success({
|
||||
description: `${$t('authentication.loginSuccessDesc')}:${userInfo?.realName}`,
|
||||
description: `${$t('authentication.loginSuccessDesc')}:${userInfo?.username}`,
|
||||
duration: 3,
|
||||
message: $t('authentication.loginSuccess'),
|
||||
});
|
||||
@@ -101,6 +104,11 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
let userInfo: null | UserInfo = null;
|
||||
userInfo = await getUserInfoApi();
|
||||
userStore.setUserInfo(userInfo);
|
||||
// 设置权限
|
||||
if (userInfo && Array.isArray(userInfo.permissions)) {
|
||||
permissionStore.setPermissions(userInfo.permissions);
|
||||
}
|
||||
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
|
||||
30
web/apps/web-antd/src/store/permission.ts
Normal file
30
web/apps/web-antd/src/store/permission.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { ref } from 'vue';
|
||||
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
export const usePermissionStore = defineStore('permission', () => {
|
||||
// 权限码列表
|
||||
const permissions = ref<string[]>([]);
|
||||
|
||||
// 设置权限码
|
||||
function setPermissions(perms: string[]) {
|
||||
permissions.value = perms || [];
|
||||
}
|
||||
|
||||
// 判断是否有某个权限
|
||||
function hasPermission(code: string): boolean {
|
||||
return permissions.value.includes(code);
|
||||
}
|
||||
|
||||
// 重置
|
||||
function $reset() {
|
||||
permissions.value = [];
|
||||
}
|
||||
|
||||
return {
|
||||
permissions,
|
||||
setPermissions,
|
||||
hasPermission,
|
||||
$reset,
|
||||
};
|
||||
})
|
||||
48
web/apps/web-antd/src/utils/permission.ts
Normal file
48
web/apps/web-antd/src/utils/permission.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { App, DirectiveBinding } from 'vue';
|
||||
|
||||
import { usePermissionStore } from '#/store/permission';
|
||||
|
||||
/**
|
||||
* 权限按钮option生成工具
|
||||
* @param code 权限码
|
||||
* @param option 按钮option或字符串
|
||||
* @returns 有权限返回option,无权限返回false
|
||||
*/
|
||||
export function op(code: string, option: any) {
|
||||
const permissionStore = usePermissionStore();
|
||||
return permissionStore.hasPermission(code) ? option : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局权限判断函数,适用于模板v-if
|
||||
*/
|
||||
export function hasPermission(code: string): boolean {
|
||||
const permissionStore = usePermissionStore();
|
||||
return permissionStore.hasPermission(code);
|
||||
}
|
||||
|
||||
/**
|
||||
* v-permission 自定义指令
|
||||
* 用法:v-permission="'system:user:create'"
|
||||
* 或 v-permission="['system:user:create', 'system:user:update']"
|
||||
*/
|
||||
const permissionDirective = {
|
||||
mounted(el: HTMLElement, binding: DirectiveBinding<string | string[]>) {
|
||||
const codes = Array.isArray(binding.value)
|
||||
? binding.value
|
||||
: [binding.value];
|
||||
const permissionStore = usePermissionStore();
|
||||
const has = codes.some((code) => permissionStore.hasPermission(code));
|
||||
if (!has) {
|
||||
el.parentNode && el.remove();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 注册全局权限指令
|
||||
* @param app Vue App 实例
|
||||
*/
|
||||
export function registerPermissionDirective(app: App) {
|
||||
app.directive('permission', permissionDirective);
|
||||
}
|
||||
@@ -8,6 +8,8 @@ import { z } from '#/adapter/form';
|
||||
import { getDeptList } from '#/api/system/dept';
|
||||
import { $t } from '#/locales';
|
||||
import { format_datetime } from '#/utils/date';
|
||||
import { op } from '#/utils/permission';
|
||||
|
||||
/**
|
||||
* 获取编辑表单的字段配置。如果没有使用多语言,可以直接export一个数组常量
|
||||
*/
|
||||
@@ -137,18 +139,15 @@ export function useColumns(
|
||||
},
|
||||
name: 'CellOperation',
|
||||
options: [
|
||||
{
|
||||
code: 'append',
|
||||
text: '新增下级',
|
||||
},
|
||||
'edit', // 默认的编辑按钮
|
||||
{
|
||||
code: 'delete', // 默认的删除按钮
|
||||
op('system:dept:create', { code: 'append', text: '新增下级' }),
|
||||
op('system:dept:edit', 'edit'),
|
||||
op('system:dept:delete', {
|
||||
code: 'delete',
|
||||
disabled: (row: SystemDeptApi.SystemDept) => {
|
||||
return !!(row.children && row.children.length > 0);
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
].filter(Boolean),
|
||||
},
|
||||
field: 'operation',
|
||||
fixed: 'right',
|
||||
|
||||
@@ -133,7 +133,11 @@ function refreshGrid() {
|
||||
<FormModal @success="refreshGrid" />
|
||||
<Grid table-title="部门列表">
|
||||
<template #toolbar-tools>
|
||||
<Button type="primary" @click="onCreate">
|
||||
<Button
|
||||
type="primary"
|
||||
@click="onCreate"
|
||||
v-permission="'system:dept:create'"
|
||||
>
|
||||
<Plus class="size-5" />
|
||||
{{ $t('ui.actionTitle.create', [$t('system.dept.name')]) }}
|
||||
</Button>
|
||||
|
||||
@@ -15,7 +15,8 @@ interface UserInfo extends BasicUserInfo {
|
||||
* accessToken
|
||||
*/
|
||||
token: string;
|
||||
roles: [];
|
||||
roles?: string[];
|
||||
permissions?: string[];
|
||||
}
|
||||
|
||||
export type { UserInfo };
|
||||
|
||||
Reference in New Issue
Block a user