From 99fd32897cc6ba7e461d304c703bd8fa558471e6 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Mon, 28 Apr 2025 10:20:40 +0800 Subject: [PATCH] feat: UI permission instruction (#3010) --- ui/src/directives/hasPermission.ts | 27 +++++++++++++++++++++++++++ ui/src/directives/index.ts | 14 ++++++++++++++ ui/src/main.ts | 6 ++++-- ui/src/stores/modules/user.ts | 6 +++--- ui/src/utils/permission/data.ts | 7 +++++++ ui/src/utils/permission/index.ts | 6 +++--- ui/src/utils/permission/type.ts | 18 ++++++++++++++++++ ui/src/views/HomeView.vue | 22 ++++++++++++++++++++-- 8 files changed, 96 insertions(+), 10 deletions(-) create mode 100644 ui/src/directives/hasPermission.ts create mode 100644 ui/src/directives/index.ts create mode 100644 ui/src/utils/permission/data.ts diff --git a/ui/src/directives/hasPermission.ts b/ui/src/directives/hasPermission.ts new file mode 100644 index 000000000..5a71520e8 --- /dev/null +++ b/ui/src/directives/hasPermission.ts @@ -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) + }, + }) + }, +} diff --git a/ui/src/directives/index.ts b/ui/src/directives/index.ts new file mode 100644 index 000000000..de8ee8018 --- /dev/null +++ b/ui/src/directives/index.ts @@ -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 } diff --git a/ui/src/main.ts b/ui/src/main.ts index b47fbf0cf..c8e6c0329 100644 --- a/ui/src/main.ts +++ b/ui/src/main.ts @@ -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) diff --git a/ui/src/stores/modules/user.ts b/ui/src/stores/modules/user.ts index 0691a081e..528212b7d 100644 --- a/ui/src/stores/modules/user.ts +++ b/ui/src/stores/modules/user.ts @@ -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(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() { diff --git a/ui/src/utils/permission/data.ts b/ui/src/utils/permission/data.ts new file mode 100644 index 000000000..990e4eec7 --- /dev/null +++ b/ui/src/utils/permission/data.ts @@ -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 diff --git a/ui/src/utils/permission/index.ts b/ui/src/utils/permission/index.ts index 37313f90e..7e4c7e2ab 100644 --- a/ui/src/utils/permission/index.ts +++ b/ui/src/utils/permission/index.ts @@ -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' diff --git a/ui/src/utils/permission/type.ts b/ui/src/utils/permission/type.ts index 874fc830b..ec91e69aa 100644 --- a/ui/src/utils/permission/type.ts +++ b/ui/src/utils/permission/type.ts @@ -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}` + } } /** * 复杂权限对象 diff --git a/ui/src/views/HomeView.vue b/ui/src/views/HomeView.vue index 197bae0e3..1bdcee152 100644 --- a/ui/src/views/HomeView.vue +++ b/ui/src/views/HomeView.vue @@ -1,3 +1,21 @@ - + - +