feat: UI permission instruction (#3010)
This commit is contained in:
parent
c79479d80b
commit
99fd32897c
27
ui/src/directives/hasPermission.ts
Normal file
27
ui/src/directives/hasPermission.ts
Normal 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)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
14
ui/src/directives/index.ts
Normal file
14
ui/src/directives/index.ts
Normal 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 }
|
||||||
@ -10,6 +10,7 @@ import App from './App.vue'
|
|||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import i18n from '@/locales'
|
import i18n from '@/locales'
|
||||||
import Components from '@/components'
|
import Components from '@/components'
|
||||||
|
import directives from '@/directives'
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
app.use(createPinia())
|
app.use(createPinia())
|
||||||
for (const [key, component] of Object.entries(ElementPlusIcons)) {
|
for (const [key, component] of Object.entries(ElementPlusIcons)) {
|
||||||
@ -18,11 +19,12 @@ for (const [key, component] of Object.entries(ElementPlusIcons)) {
|
|||||||
const locale_map: any = {
|
const locale_map: any = {
|
||||||
'zh-CN': zhCn,
|
'zh-CN': zhCn,
|
||||||
'zh-Hant': zhTW,
|
'zh-Hant': zhTW,
|
||||||
'en-US': enUs
|
'en-US': enUs,
|
||||||
}
|
}
|
||||||
app.use(ElementPlus, {
|
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(router)
|
||||||
app.use(i18n)
|
app.use(i18n)
|
||||||
app.use(Components)
|
app.use(Components)
|
||||||
|
|||||||
@ -36,8 +36,8 @@ const useLoginStore = defineStore('user', {
|
|||||||
return !this.themeInfo?.theme || this.themeInfo?.theme === '#3370FF'
|
return !this.themeInfo?.theme || this.themeInfo?.theme === '#3370FF'
|
||||||
},
|
},
|
||||||
async profile() {
|
async profile() {
|
||||||
return UserApi.getUserProfile().then((ok: { data: User }) => {
|
return UserApi.getUserProfile().then((ok) => {
|
||||||
this.userInfo = ok.data
|
this.userInfo = ok
|
||||||
useLocalStorage<string>(localeConfigKey, 'en-US').value =
|
useLocalStorage<string>(localeConfigKey, 'en-US').value =
|
||||||
ok.data?.language || this.getLanguage()
|
ok.data?.language || this.getLanguage()
|
||||||
// return this.asyncGetProfile()
|
// return this.asyncGetProfile()
|
||||||
@ -72,7 +72,7 @@ const useLoginStore = defineStore('user', {
|
|||||||
? [...this.userInfo?.permissions, 'x-pack']
|
? [...this.userInfo?.permissions, 'x-pack']
|
||||||
: this.userInfo?.permissions
|
: this.userInfo?.permissions
|
||||||
} else {
|
} else {
|
||||||
return []
|
return this.userInfo?.permissions
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getRole() {
|
getRole() {
|
||||||
|
|||||||
7
ui/src/utils/permission/data.ts
Normal file
7
ui/src/utils/permission/data.ts
Normal 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
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import useStore from '@/stores';
|
import useStore from '@/stores'
|
||||||
import { Role, Permission, ComplexPermission } from '@/utils/permission/type'
|
import { Role, Permission, ComplexPermission } from '@/utils/permission/type'
|
||||||
/**
|
/**
|
||||||
* 是否包含当前权限
|
* 是否包含当前权限
|
||||||
@ -6,7 +6,7 @@ import { Role, Permission, ComplexPermission } from '@/utils/permission/type'
|
|||||||
* @returns True 包含 false 不包含
|
* @returns True 包含 false 不包含
|
||||||
*/
|
*/
|
||||||
const hasPermissionChild = (permission: Role | string | Permission | ComplexPermission) => {
|
const hasPermissionChild = (permission: Role | string | Permission | ComplexPermission) => {
|
||||||
const { user } = useStore();
|
const { user } = useStore()
|
||||||
const permissions = user.getPermissions()
|
const permissions = user.getPermissions()
|
||||||
const role = user.getRole()
|
const role = user.getRole()
|
||||||
if (!permission) {
|
if (!permission) {
|
||||||
@ -43,7 +43,7 @@ export const hasPermission = (
|
|||||||
| string
|
| string
|
||||||
| Permission
|
| Permission
|
||||||
| ComplexPermission,
|
| ComplexPermission,
|
||||||
compare: 'OR' | 'AND'
|
compare: 'OR' | 'AND',
|
||||||
): boolean => {
|
): boolean => {
|
||||||
if (permission instanceof Array) {
|
if (permission instanceof Array) {
|
||||||
return compare === 'OR'
|
return compare === 'OR'
|
||||||
|
|||||||
@ -17,6 +17,24 @@ export class Permission {
|
|||||||
constructor(permission: string) {
|
constructor(permission: string) {
|
||||||
this.permission = permission
|
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}`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 复杂权限对象
|
* 复杂权限对象
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user