From 11dfcd4d605781eb4f5a03bb3a309876436fd7f4 Mon Sep 17 00:00:00 2001 From: shaohuzhang1 <80892890+shaohuzhang1@users.noreply.github.com> Date: Mon, 16 Jun 2025 18:23:46 +0800 Subject: [PATCH] feat: ui hasPermission (#3270) --- ui/src/router/modules/application-detail.ts | 1 - ui/src/router/routes.ts | 5 ++ ui/src/stores/modules/user.ts | 16 ++++- ui/src/utils/permission/data.ts | 9 ++- ui/src/utils/permission/index.ts | 38 ++++++++--- ui/src/utils/permission/type.ts | 40 ++++++++++- ui/src/views/Permission.vue | 74 +++++++++++++++++++++ 7 files changed, 167 insertions(+), 16 deletions(-) create mode 100644 ui/src/views/Permission.vue diff --git a/ui/src/router/modules/application-detail.ts b/ui/src/router/modules/application-detail.ts index e32411492..47274f366 100644 --- a/ui/src/router/modules/application-detail.ts +++ b/ui/src/router/modules/application-detail.ts @@ -1,4 +1,3 @@ -import { ComplexPermission } from '@/utils/permission/type' import { PermissionConst, RoleConst } from '@/utils/permission/data' const ApplicationDetailRouter = { diff --git a/ui/src/router/routes.ts b/ui/src/router/routes.ts index c6e140d7a..46d6f7097 100644 --- a/ui/src/router/routes.ts +++ b/ui/src/router/routes.ts @@ -46,6 +46,11 @@ export const routes: Array = [ name: 'ResetPassword', component: () => import('@/views/login/ResetPassword.vue'), }, + { + path: '/permission', + name: 'permission', + component: () => import('@/views/Permission.vue'), + }, // { // path: '/:pathMatch(.*)', // name: '404', diff --git a/ui/src/stores/modules/user.ts b/ui/src/stores/modules/user.ts index 6630cf6a3..15ac59fd1 100644 --- a/ui/src/stores/modules/user.ts +++ b/ui/src/stores/modules/user.ts @@ -93,15 +93,27 @@ const useUserStore = defineStore('user', { getPermissions() { if (this.userInfo) { if (this.isEE()) { - return [...this.userInfo?.permissions, 'x-pack-ee'] + return [...this.userInfo?.permissions, 'X-PACK-EE'] } else if (this.isPE()) { - return [...this.userInfo?.permissions, 'x-pack-pe'] + return [...this.userInfo?.permissions, 'X-PACK-PE'] } return this.userInfo?.permissions } else { return [] } }, + getEdition() { + if (this.userInfo) { + if (this.isEE()) { + return 'X-PACK-EE' + } else if (this.isPE()) { + return 'X-PACK-PE' + } else { + return 'X-PACK-CE' + } + } + return 'X-PACK-CE' + }, getRole() { if (this.userInfo) { return this.userInfo?.role diff --git a/ui/src/utils/permission/data.ts b/ui/src/utils/permission/data.ts index 6fb5704ff..36838d334 100644 --- a/ui/src/utils/permission/data.ts +++ b/ui/src/utils/permission/data.ts @@ -1,4 +1,4 @@ -import { Permission, Role } from '@/utils/permission/type' +import { Permission, Role, Edition } from '@/utils/permission/type' const PermissionConst = { USER_READ: new Permission('USER:READ'), USER_CREATE: new Permission('USER:CREATE'), @@ -10,4 +10,9 @@ const RoleConst = { WORKSPACE_MANAGE: new Role('WORKSPACE_MANAGE'), USER: new Role('USER'), } -export { PermissionConst, RoleConst } +const EditionConst = { + IS_PE: new Edition('X-PACK-PE'), + IS_EE: new Edition('X-PACK-EE'), + IS_CE: new Edition('X-PACK-CE'), +} +export { PermissionConst, RoleConst, EditionConst } diff --git a/ui/src/utils/permission/index.ts b/ui/src/utils/permission/index.ts index 9169e6448..d6a56b049 100644 --- a/ui/src/utils/permission/index.ts +++ b/ui/src/utils/permission/index.ts @@ -1,21 +1,30 @@ import useStore from '@/stores' -import { Role, Permission, ComplexPermission } from '@/utils/permission/type' +import { + Role, + Permission, + ComplexPermission, + Edition, + type PF, + type CPF, + type CRF, +} from '@/utils/permission/type' import { isFunction } from '@/utils/common' -type PF = () => Role | string | Permission | ComplexPermission /** * 是否包含当前权限 * @param permission 当前权限 * @returns True 包含 false 不包含 */ -const hasPermissionChild = (permission: Role | string | Permission | ComplexPermission | PF) => { +const hasPermissionChild = ( + permission: Role | string | Permission | ComplexPermission | Edition | PF, +) => { const { user } = useStore() const permissions = user.getPermissions() const role: Array = user.getRole() + const edition = user.getEdition() if (!permission) { return true } - if (isFunction(permission)) { permission = (permission as PF)() } @@ -25,10 +34,22 @@ const hasPermissionChild = (permission: Role | string | Permission | ComplexPerm if (permission instanceof Permission) { return permissions.includes(permission.permission) } + if (permission instanceof Edition) { + return permission.edition === edition + } if (permission instanceof ComplexPermission) { - const permissionOk = permission.permissionList.some((p) => permissions.includes(p)) - const roleOk = role.some((r) => permission.roleList.includes(r)) - return permission.compare === 'AND' ? permissionOk && roleOk : permissionOk || roleOk + const permissionOk = permission.permissionList.some((p) => + permissions.includes(isFunction(p) ? (p as CPF)().toString() : p.toString()), + ) + const roleList = permission.roleList + const roleOk = roleList.some((r) => + role.includes(isFunction(r) ? (r as CRF)().toString() : r.toString()), + ) + const editionOK = permission.editionList.includes(edition.toString()) + + return permission.compare === 'AND' + ? permissionOk && roleOk && editionOK + : (permissionOk || roleOk) && editionOK } if (typeof permission === 'string') { return permissions.includes(permission) @@ -45,10 +66,11 @@ const hasPermissionChild = (permission: Role | string | Permission | ComplexPerm */ export const hasPermission = ( permission: - | Array + | Array | Role | string | Permission + | Edition | ComplexPermission | PF, compare: 'OR' | 'AND', diff --git a/ui/src/utils/permission/type.ts b/ui/src/utils/permission/type.ts index e9b6bcadf..70772deac 100644 --- a/ui/src/utils/permission/type.ts +++ b/ui/src/utils/permission/type.ts @@ -1,4 +1,7 @@ import useStore from '@/stores' +export type PF = () => Role | string | Permission | ComplexPermission +export type CRF = () => Role | string +export type CPF = () => Permission | string /** * 角色对象 */ @@ -13,6 +16,13 @@ export class Role { const { user } = useStore() return new Role(`${this.role}:/WORKSPACE/${user.getWorkspaceId()}`) } + getWorkspaceRoleString = () => { + const { user } = useStore() + return `${this.role}:/WORKSPACE/${user.getWorkspaceId()}` + } + toString() { + return this.role + } } /** * 权限对象 @@ -43,20 +53,44 @@ export class Permission { const { user } = useStore() return `${this.permission}:/WORKSPACE/${user.getWorkspaceId()}/${resource}/${resource_id}` } + toString() { + return this.permission + } } + /** * 复杂权限对象 */ export class ComplexPermission { - roleList: Array + roleList: Array - permissionList: Array + permissionList: Array + + editionList: Array compare: 'OR' | 'AND' - constructor(roleList: Array, permissionList: Array, compare: 'OR' | 'AND') { + constructor( + roleList: Array, + permissionList: Array, + editionList: Array, + compare: 'OR' | 'AND', + ) { this.roleList = roleList this.permissionList = permissionList + this.editionList = editionList this.compare = compare } } +/** + * 版本 + */ +export class Edition { + edition: string + constructor(edition: string) { + this.edition = edition + } + toString() { + return this.edition + } +} diff --git a/ui/src/views/Permission.vue b/ui/src/views/Permission.vue new file mode 100644 index 000000000..bf23ba8f6 --- /dev/null +++ b/ui/src/views/Permission.vue @@ -0,0 +1,74 @@ + + +