mirror of
https://github.com/chansee97/nova-admin.git
synced 2025-09-17 19:29:58 +08:00
feat: 完善权限
This commit is contained in:
parent
cf41abc5a5
commit
f9ef71f0c7
@ -1,21 +1,57 @@
|
||||
import type { App, Directive } from 'vue'
|
||||
import { usePermission } from '@/hooks'
|
||||
import { useMenuPermission, usePermission, useRolePermission } from '@/hooks'
|
||||
|
||||
export function install(app: App) {
|
||||
const { hasPermission } = usePermission()
|
||||
const { hasMenuPermission } = useMenuPermission()
|
||||
const { hasRolePermission } = useRolePermission()
|
||||
|
||||
function updatapermission(el: HTMLElement, permission: string | string[]) {
|
||||
function updatePermission(el: HTMLElement, permission: string | string[]) {
|
||||
if (!permission)
|
||||
throw new Error('v-permissson Directive with no explicit role attached')
|
||||
throw new Error('v-permission Directive with no explicit permission attached')
|
||||
|
||||
if (!hasPermission(permission))
|
||||
el.parentElement?.removeChild(el)
|
||||
}
|
||||
|
||||
function updateMenuPermission(el: HTMLElement, permission: string | string[]) {
|
||||
if (!permission)
|
||||
throw new Error('v-menu Directive with no explicit menu permission attached')
|
||||
|
||||
if (!hasMenuPermission(permission))
|
||||
el.parentElement?.removeChild(el)
|
||||
}
|
||||
|
||||
function updateRolePermission(el: HTMLElement, role: string | string[]) {
|
||||
if (!role)
|
||||
throw new Error('v-role Directive with no explicit role attached')
|
||||
|
||||
if (!hasRolePermission(role))
|
||||
el.parentElement?.removeChild(el)
|
||||
}
|
||||
|
||||
// 通用权限指令(兼容旧版本)
|
||||
const permissionDirective: Directive<HTMLElement, string | string[]> = {
|
||||
mounted(el, binding) {
|
||||
updatapermission(el, binding.value)
|
||||
updatePermission(el, binding.value)
|
||||
},
|
||||
}
|
||||
|
||||
// 菜单权限指令
|
||||
const menuPermissionDirective: Directive<HTMLElement, string | string[]> = {
|
||||
mounted(el, binding) {
|
||||
updateMenuPermission(el, binding.value)
|
||||
},
|
||||
}
|
||||
|
||||
// 角色权限指令
|
||||
const rolePermissionDirective: Directive<HTMLElement, string | string[]> = {
|
||||
mounted(el, binding) {
|
||||
updateRolePermission(el, binding.value)
|
||||
},
|
||||
}
|
||||
|
||||
app.directive('permission', permissionDirective)
|
||||
app.directive('menu', menuPermissionDirective)
|
||||
app.directive('role', rolePermissionDirective)
|
||||
}
|
||||
|
@ -1,6 +1,60 @@
|
||||
import { useAuthStore } from '@/store'
|
||||
|
||||
/** 权限判断 */
|
||||
/** 菜单权限判断 */
|
||||
export function useMenuPermission() {
|
||||
const authStore = useAuthStore()
|
||||
|
||||
function hasMenuPermission(
|
||||
permissions?: string | string[],
|
||||
) {
|
||||
if (!permissions)
|
||||
return true
|
||||
|
||||
// 确保 permissions 是数组
|
||||
const permissionArray = Array.isArray(permissions) ? permissions : [permissions]
|
||||
|
||||
// 全部权限
|
||||
if (permissionArray.includes('admin'))
|
||||
return true
|
||||
|
||||
const { permissions: userPermissions } = authStore
|
||||
|
||||
return permissionArray.some(i => userPermissions.includes(i))
|
||||
}
|
||||
|
||||
return {
|
||||
hasMenuPermission,
|
||||
}
|
||||
}
|
||||
|
||||
/** 角色权限判断 */
|
||||
export function useRolePermission() {
|
||||
const authStore = useAuthStore()
|
||||
|
||||
function hasRolePermission(
|
||||
roles?: string | string[],
|
||||
) {
|
||||
if (!roles)
|
||||
return true
|
||||
|
||||
// 确保 roles 是数组
|
||||
const roleArray = Array.isArray(roles) ? roles : [roles]
|
||||
|
||||
// 全部权限
|
||||
if (roleArray.includes('admin'))
|
||||
return true
|
||||
|
||||
const { roles: userRoles } = authStore
|
||||
|
||||
return roleArray.some(i => userRoles.includes(i))
|
||||
}
|
||||
|
||||
return {
|
||||
hasRolePermission,
|
||||
}
|
||||
}
|
||||
|
||||
/** 合并权限判断 */
|
||||
export function usePermission() {
|
||||
const authStore = useAuthStore()
|
||||
|
||||
@ -10,16 +64,20 @@ export function usePermission() {
|
||||
if (!permissions)
|
||||
return true
|
||||
|
||||
// 全部权限
|
||||
if (permissions === '*:*:*')
|
||||
return true
|
||||
|
||||
const { permissions: userPermissions } = authStore
|
||||
|
||||
// 确保 permissions 是数组
|
||||
const permissionArray = Array.isArray(permissions) ? permissions : [permissions]
|
||||
|
||||
return permissionArray.some(i => userPermissions.includes(i))
|
||||
// 全部权限
|
||||
if (permissionArray.includes('admin'))
|
||||
return true
|
||||
|
||||
const { permissions: userPermissions, roles: userRoles } = authStore
|
||||
|
||||
const hasPermission = permissionArray.some(i => userPermissions.includes(i))
|
||||
if (hasPermission)
|
||||
return true
|
||||
|
||||
return permissionArray.some(i => userRoles.includes(i))
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -6,12 +6,14 @@ import { useTabStore } from './tab'
|
||||
|
||||
interface AuthStatus {
|
||||
userInfo: Entity.User | Record<string, any>
|
||||
roles: string[]
|
||||
permissions: string[]
|
||||
}
|
||||
export const useAuthStore = defineStore('auth-store', {
|
||||
state: (): AuthStatus => {
|
||||
return {
|
||||
userInfo: {},
|
||||
roles: [],
|
||||
permissions: [],
|
||||
}
|
||||
},
|
||||
@ -71,6 +73,8 @@ export const useAuthStore = defineStore('auth-store', {
|
||||
async updataUserInfo() {
|
||||
const { data } = await fetchUserInfo()
|
||||
this.userInfo = data
|
||||
this.roles = data.roles.map((role: Entity.Role) => role.roleKey)
|
||||
this.permissions = data.permissions
|
||||
},
|
||||
/* 处理登录返回的数据 */
|
||||
async handleLoginInfo(data: any) {
|
||||
|
2
src/typings/entities/user.d.ts
vendored
2
src/typings/entities/user.d.ts
vendored
@ -33,5 +33,7 @@ namespace Entity {
|
||||
roles: Entity.Role[]
|
||||
/** 所属部门 */
|
||||
dept: Entity.Dept
|
||||
/** 用户权限, 登陆时返回该字段 */
|
||||
permissions: string[]
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ const settings = ref({
|
||||
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<n-alert type="warning" style="margin-bottom: 16px;">
|
||||
示例组件,实际功能未实现
|
||||
</n-alert>
|
||||
<!-- 邮件通知 -->
|
||||
<n-card title="邮件通知" size="small">
|
||||
<n-list>
|
||||
|
@ -8,12 +8,11 @@ const preferences = ref({
|
||||
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<n-alert type="warning" style="margin-bottom: 16px;">
|
||||
示例组件,实际功能未实现
|
||||
</n-alert>
|
||||
<!-- 实验性功能 -->
|
||||
<n-card title="实验性功能" size="small">
|
||||
<n-alert type="warning" style="margin-bottom: 16px;">
|
||||
以下功能仍在测试阶段,可能会影响系统稳定性
|
||||
</n-alert>
|
||||
|
||||
<n-list>
|
||||
<n-list-item>
|
||||
<n-thing>
|
||||
|
@ -86,7 +86,7 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-card>
|
||||
<n-card class="max-w-1024px m-auto">
|
||||
<n-flex :wrap="false" style="height: 100%;">
|
||||
<!-- 左侧区域 -->
|
||||
<div class="w-[220px] border-r border-[var(--n-border-color)] flex flex-col">
|
||||
|
@ -46,7 +46,7 @@
|
||||
/>
|
||||
<pro-input
|
||||
title="权限标识"
|
||||
tooltip="页面访问权限标识"
|
||||
tooltip="后端装饰器一致,如@RequirePermissions('system:user:list')"
|
||||
path="perms"
|
||||
placeholder="Eg: system:user:list"
|
||||
/>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<pro-input
|
||||
required
|
||||
title="权限标识"
|
||||
tooltip="按钮权限唯一标识符"
|
||||
tooltip="后端装饰器一致,如@RequirePermissions('system:user:add')"
|
||||
path="perms"
|
||||
placeholder="Eg: system:user:add"
|
||||
/>
|
||||
|
@ -46,9 +46,6 @@ async function getAllRoutes(params?: MenuSearchQuery) {
|
||||
parentProperty: 'parentId',
|
||||
})
|
||||
}
|
||||
catch {
|
||||
window.$message.error('获取菜单列表失败')
|
||||
}
|
||||
finally {
|
||||
endLoading()
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ export function createRoleColumns(actions: RoleColumnActions): DataTableColumns<
|
||||
width: 100,
|
||||
render: (row) => {
|
||||
return (
|
||||
row.roleKey !== 'admin' && (
|
||||
<NSwitch
|
||||
value={row.status}
|
||||
checked-value={0}
|
||||
@ -87,6 +88,7 @@ export function createRoleColumns(actions: RoleColumnActions): DataTableColumns<
|
||||
{{ checked: () => '启用', unchecked: () => '禁用' }}
|
||||
</NSwitch>
|
||||
)
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -102,6 +104,7 @@ export function createRoleColumns(actions: RoleColumnActions): DataTableColumns<
|
||||
width: 200,
|
||||
render: (row) => {
|
||||
return (
|
||||
row.roleKey !== 'admin' && (
|
||||
<NSpace justify="center">
|
||||
<NButton
|
||||
text
|
||||
@ -124,6 +127,7 @@ export function createRoleColumns(actions: RoleColumnActions): DataTableColumns<
|
||||
</NPopconfirm>
|
||||
</NSpace>
|
||||
)
|
||||
)
|
||||
},
|
||||
},
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user