mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 10:12:51 +00:00
feat: ui hasPermission (#3270)
This commit is contained in:
parent
3540ad8550
commit
11dfcd4d60
|
|
@ -1,4 +1,3 @@
|
|||
import { ComplexPermission } from '@/utils/permission/type'
|
||||
import { PermissionConst, RoleConst } from '@/utils/permission/data'
|
||||
|
||||
const ApplicationDetailRouter = {
|
||||
|
|
|
|||
|
|
@ -46,6 +46,11 @@ export const routes: Array<RouteRecordRaw> = [
|
|||
name: 'ResetPassword',
|
||||
component: () => import('@/views/login/ResetPassword.vue'),
|
||||
},
|
||||
{
|
||||
path: '/permission',
|
||||
name: 'permission',
|
||||
component: () => import('@/views/Permission.vue'),
|
||||
},
|
||||
// {
|
||||
// path: '/:pathMatch(.*)',
|
||||
// name: '404',
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -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<string> = 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<Role | string | Permission | ComplexPermission | PF>
|
||||
| Array<Role | string | Permission | ComplexPermission | Edition | PF>
|
||||
| Role
|
||||
| string
|
||||
| Permission
|
||||
| Edition
|
||||
| ComplexPermission
|
||||
| PF,
|
||||
compare: 'OR' | 'AND',
|
||||
|
|
|
|||
|
|
@ -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<string>
|
||||
roleList: Array<string | Role | CRF>
|
||||
|
||||
permissionList: Array<string>
|
||||
permissionList: Array<string | Permission | CPF>
|
||||
|
||||
editionList: Array<string | Edition>
|
||||
|
||||
compare: 'OR' | 'AND'
|
||||
|
||||
constructor(roleList: Array<string>, permissionList: Array<string>, compare: 'OR' | 'AND') {
|
||||
constructor(
|
||||
roleList: Array<string | Role | CRF>,
|
||||
permissionList: Array<string | Permission | CPF>,
|
||||
editionList: Array<string | Edition>,
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
<template>
|
||||
<div>说明: v-hasPermission 是使用v-show 本质上组件是渲染的 v-if="hasPermission('xxxx')"</div>
|
||||
<div>这种方式组件不会渲染(用于比如像组件挂载的时候需要调用接口,不想让组件渲染)</div>
|
||||
<div>比如工作空间的下拉列表组件使用v-if 示例: 企业版组件:</div>
|
||||
|
||||
<button v-if="hasPermission(EditionConst.IS_CE, 'OR')">我是社区版组件</button>
|
||||
|
||||
<button v-hasPermission="EditionConst.IS_CE">我是社区版组件</button>
|
||||
<!-- ================我是企业版组件================== -->
|
||||
<button v-if="hasPermission(EditionConst.IS_EE, 'OR')">我是企业版组件</button>
|
||||
<button v-hasPermission="EditionConst.IS_EE">我是企业版组件</button>
|
||||
|
||||
<!-- ================企业版组件 并且是ADMIN角色================== -->
|
||||
<button v-if="hasPermission([EditionConst.IS_EE, RoleConst.ADMIN], 'AND')">
|
||||
我是企业版并且是ADMIN角色
|
||||
</button>
|
||||
<button
|
||||
v-hasPermission="new ComplexPermission([RoleConst.ADMIN], [], [EditionConst.IS_EE], 'AND')"
|
||||
>
|
||||
我是企业版并且是ADMIN角色
|
||||
</button>
|
||||
<!-- ================企业版组件 并且是当前工作空间管理员================== -->
|
||||
<button
|
||||
v-if="hasPermission([EditionConst.IS_EE, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole], 'AND')"
|
||||
>
|
||||
我是企业版并且拥有当前工作空间管理员角色
|
||||
</button>
|
||||
<button
|
||||
v-hasPermission="
|
||||
new ComplexPermission(
|
||||
[RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
||||
[],
|
||||
[EditionConst.IS_EE],
|
||||
'OR',
|
||||
)
|
||||
"
|
||||
>
|
||||
我是企业版并且拥有当前工作空间管理员角色
|
||||
</button>
|
||||
<!-- ================企业版组件 (并且是当前工作空间管理员 或者有用户只读)================== -->
|
||||
<button
|
||||
v-if="
|
||||
hasPermission(
|
||||
new ComplexPermission(
|
||||
[RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
||||
[PermissionConst.USER_READ],
|
||||
[EditionConst.IS_EE],
|
||||
'OR',
|
||||
),
|
||||
'OR',
|
||||
)
|
||||
"
|
||||
>
|
||||
我是企业版 (并且是当前工作空间管理员 或者有用户只读)
|
||||
</button>
|
||||
<button
|
||||
v-hasPermission="
|
||||
new ComplexPermission(
|
||||
[RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
|
||||
[PermissionConst.USER_READ],
|
||||
[EditionConst.IS_EE],
|
||||
'OR',
|
||||
)
|
||||
"
|
||||
>
|
||||
我是企业版(并且是当前工作空间管理员 或者有用户只读)
|
||||
</button>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { PermissionConst, EditionConst, RoleConst } from '@/utils/permission/data'
|
||||
import { hasPermission } from '@/utils/permission/index'
|
||||
import { ComplexPermission } from '@/utils/permission/type'
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
Loading…
Reference in New Issue