feat: UI permission instruction (#3010)

This commit is contained in:
shaohuzhang1 2025-04-28 10:20:40 +08:00 committed by GitHub
parent c79479d80b
commit 99fd32897c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 96 additions and 10 deletions

View File

@ -0,0 +1,27 @@
import type { App } from 'vue'
import { hasPermission } from '@/utils/permission'
const display = async (el: any, binding: any) => {
const has = hasPermission(
binding.value?.permission || binding.value,
binding.value?.compare || 'OR',
)
if (!has) {
el.style.display = 'none'
} else {
delete el.style.display
}
}
export default {
install: (app: App) => {
app.directive('hasPermission', {
async created(el: any, binding: any) {
display(el, binding)
},
async beforeUpdate(el: any, binding: any) {
display(el, binding)
},
})
},
}

View File

@ -0,0 +1,14 @@
import type { App } from 'vue'
const directives = import.meta.glob('./*.ts', { eager: true })
const install = (app: App) => {
Object.keys(directives)
.filter((key: string) => {
return !key.endsWith('index.ts')
})
.forEach((key: string) => {
const directive: any = directives[key]
app.use(directive.default)
})
}
export default { install }

View File

@ -10,6 +10,7 @@ import App from './App.vue'
import router from '@/router'
import i18n from '@/locales'
import Components from '@/components'
import directives from '@/directives'
const app = createApp(App)
app.use(createPinia())
for (const [key, component] of Object.entries(ElementPlusIcons)) {
@ -18,11 +19,12 @@ for (const [key, component] of Object.entries(ElementPlusIcons)) {
const locale_map: any = {
'zh-CN': zhCn,
'zh-Hant': zhTW,
'en-US': enUs
'en-US': enUs,
}
app.use(ElementPlus, {
locale: locale_map[localStorage.getItem('MaxKB-locale') || navigator.language || 'en-US']
locale: locale_map[localStorage.getItem('MaxKB-locale') || navigator.language || 'en-US'],
})
app.use(directives)
app.use(router)
app.use(i18n)
app.use(Components)

View File

@ -36,8 +36,8 @@ const useLoginStore = defineStore('user', {
return !this.themeInfo?.theme || this.themeInfo?.theme === '#3370FF'
},
async profile() {
return UserApi.getUserProfile().then((ok: { data: User }) => {
this.userInfo = ok.data
return UserApi.getUserProfile().then((ok) => {
this.userInfo = ok
useLocalStorage<string>(localeConfigKey, 'en-US').value =
ok.data?.language || this.getLanguage()
// return this.asyncGetProfile()
@ -72,7 +72,7 @@ const useLoginStore = defineStore('user', {
? [...this.userInfo?.permissions, 'x-pack']
: this.userInfo?.permissions
} else {
return []
return this.userInfo?.permissions
}
},
getRole() {

View File

@ -0,0 +1,7 @@
import { Permission } from '@/utils/permission/type'
const PermissionConst = {
USER_READ: new Permission('USER:READ'),
USER_CREATE: new Permission('USER:CREATE'),
KNOWLEDGE_READ: new Permission('KNOWLEDGE:READ'),
}
export default PermissionConst

View File

@ -1,4 +1,4 @@
import useStore from '@/stores';
import useStore from '@/stores'
import { Role, Permission, ComplexPermission } from '@/utils/permission/type'
/**
*
@ -6,7 +6,7 @@ import { Role, Permission, ComplexPermission } from '@/utils/permission/type'
* @returns True false
*/
const hasPermissionChild = (permission: Role | string | Permission | ComplexPermission) => {
const { user } = useStore();
const { user } = useStore()
const permissions = user.getPermissions()
const role = user.getRole()
if (!permission) {
@ -43,7 +43,7 @@ export const hasPermission = (
| string
| Permission
| ComplexPermission,
compare: 'OR' | 'AND'
compare: 'OR' | 'AND',
): boolean => {
if (permission instanceof Array) {
return compare === 'OR'

View File

@ -17,6 +17,24 @@ export class Permission {
constructor(permission: string) {
this.permission = permission
}
/**
*
* @param workspace_id id
* @returns
*/
getWorkspacePermission(workspace_id: string) {
return `${this.permission}:/WORKSPACE/${workspace_id}`
}
/**
*
* @param workspace_id id
* @param resource
* @param resource_id id
* @returns
*/
getWorkspaceResourcePermission(workspace_id: string, resource: string, resource_id: string) {
return `${this.permission}:/WORKSPACE/${workspace_id}/${resource}/${resource_id}`
}
}
/**
*

View File

@ -1,3 +1,21 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import PermissionConst from '@/utils/permission/data'
</script>
<template>首页</template>
<template>
首页
<div v-hasPermission="PermissionConst.USER_READ.getWorkspacePermission('default')">
default工作空间用户只读
</div>
<div v-hasPermission="PermissionConst.USER_READ.getWorkspacePermission('default1')">
default1工作空间用户只读
</div>
<div v-hasPermission="PermissionConst.USER_READ">用户只读</div>
<div
v-hasPermission="
PermissionConst.KNOWLEDGE_READ.getWorkspaceResourcePermission('default', 'KNOWLEDGE', 'xxx')
"
>
default工作空间的知识库xxx权限
</div>
</template>