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'
|
import { PermissionConst, RoleConst } from '@/utils/permission/data'
|
||||||
|
|
||||||
const ApplicationDetailRouter = {
|
const ApplicationDetailRouter = {
|
||||||
|
|||||||
@ -46,6 +46,11 @@ export const routes: Array<RouteRecordRaw> = [
|
|||||||
name: 'ResetPassword',
|
name: 'ResetPassword',
|
||||||
component: () => import('@/views/login/ResetPassword.vue'),
|
component: () => import('@/views/login/ResetPassword.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/permission',
|
||||||
|
name: 'permission',
|
||||||
|
component: () => import('@/views/Permission.vue'),
|
||||||
|
},
|
||||||
// {
|
// {
|
||||||
// path: '/:pathMatch(.*)',
|
// path: '/:pathMatch(.*)',
|
||||||
// name: '404',
|
// name: '404',
|
||||||
|
|||||||
@ -93,15 +93,27 @@ const useUserStore = defineStore('user', {
|
|||||||
getPermissions() {
|
getPermissions() {
|
||||||
if (this.userInfo) {
|
if (this.userInfo) {
|
||||||
if (this.isEE()) {
|
if (this.isEE()) {
|
||||||
return [...this.userInfo?.permissions, 'x-pack-ee']
|
return [...this.userInfo?.permissions, 'X-PACK-EE']
|
||||||
} else if (this.isPE()) {
|
} else if (this.isPE()) {
|
||||||
return [...this.userInfo?.permissions, 'x-pack-pe']
|
return [...this.userInfo?.permissions, 'X-PACK-PE']
|
||||||
}
|
}
|
||||||
return this.userInfo?.permissions
|
return this.userInfo?.permissions
|
||||||
} else {
|
} else {
|
||||||
return []
|
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() {
|
getRole() {
|
||||||
if (this.userInfo) {
|
if (this.userInfo) {
|
||||||
return this.userInfo?.role
|
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 = {
|
const PermissionConst = {
|
||||||
USER_READ: new Permission('USER:READ'),
|
USER_READ: new Permission('USER:READ'),
|
||||||
USER_CREATE: new Permission('USER:CREATE'),
|
USER_CREATE: new Permission('USER:CREATE'),
|
||||||
@ -10,4 +10,9 @@ const RoleConst = {
|
|||||||
WORKSPACE_MANAGE: new Role('WORKSPACE_MANAGE'),
|
WORKSPACE_MANAGE: new Role('WORKSPACE_MANAGE'),
|
||||||
USER: new Role('USER'),
|
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 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'
|
import { isFunction } from '@/utils/common'
|
||||||
|
|
||||||
type PF = () => Role | string | Permission | ComplexPermission
|
|
||||||
/**
|
/**
|
||||||
* 是否包含当前权限
|
* 是否包含当前权限
|
||||||
* @param permission 当前权限
|
* @param permission 当前权限
|
||||||
* @returns True 包含 false 不包含
|
* @returns True 包含 false 不包含
|
||||||
*/
|
*/
|
||||||
const hasPermissionChild = (permission: Role | string | Permission | ComplexPermission | PF) => {
|
const hasPermissionChild = (
|
||||||
|
permission: Role | string | Permission | ComplexPermission | Edition | PF,
|
||||||
|
) => {
|
||||||
const { user } = useStore()
|
const { user } = useStore()
|
||||||
const permissions = user.getPermissions()
|
const permissions = user.getPermissions()
|
||||||
const role: Array<string> = user.getRole()
|
const role: Array<string> = user.getRole()
|
||||||
|
const edition = user.getEdition()
|
||||||
if (!permission) {
|
if (!permission) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFunction(permission)) {
|
if (isFunction(permission)) {
|
||||||
permission = (permission as PF)()
|
permission = (permission as PF)()
|
||||||
}
|
}
|
||||||
@ -25,10 +34,22 @@ const hasPermissionChild = (permission: Role | string | Permission | ComplexPerm
|
|||||||
if (permission instanceof Permission) {
|
if (permission instanceof Permission) {
|
||||||
return permissions.includes(permission.permission)
|
return permissions.includes(permission.permission)
|
||||||
}
|
}
|
||||||
|
if (permission instanceof Edition) {
|
||||||
|
return permission.edition === edition
|
||||||
|
}
|
||||||
if (permission instanceof ComplexPermission) {
|
if (permission instanceof ComplexPermission) {
|
||||||
const permissionOk = permission.permissionList.some((p) => permissions.includes(p))
|
const permissionOk = permission.permissionList.some((p) =>
|
||||||
const roleOk = role.some((r) => permission.roleList.includes(r))
|
permissions.includes(isFunction(p) ? (p as CPF)().toString() : p.toString()),
|
||||||
return permission.compare === 'AND' ? permissionOk && roleOk : permissionOk || roleOk
|
)
|
||||||
|
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') {
|
if (typeof permission === 'string') {
|
||||||
return permissions.includes(permission)
|
return permissions.includes(permission)
|
||||||
@ -45,10 +66,11 @@ const hasPermissionChild = (permission: Role | string | Permission | ComplexPerm
|
|||||||
*/
|
*/
|
||||||
export const hasPermission = (
|
export const hasPermission = (
|
||||||
permission:
|
permission:
|
||||||
| Array<Role | string | Permission | ComplexPermission | PF>
|
| Array<Role | string | Permission | ComplexPermission | Edition | PF>
|
||||||
| Role
|
| Role
|
||||||
| string
|
| string
|
||||||
| Permission
|
| Permission
|
||||||
|
| Edition
|
||||||
| ComplexPermission
|
| ComplexPermission
|
||||||
| PF,
|
| PF,
|
||||||
compare: 'OR' | 'AND',
|
compare: 'OR' | 'AND',
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
import useStore from '@/stores'
|
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()
|
const { user } = useStore()
|
||||||
return new Role(`${this.role}:/WORKSPACE/${user.getWorkspaceId()}`)
|
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()
|
const { user } = useStore()
|
||||||
return `${this.permission}:/WORKSPACE/${user.getWorkspaceId()}/${resource}/${resource_id}`
|
return `${this.permission}:/WORKSPACE/${user.getWorkspaceId()}/${resource}/${resource_id}`
|
||||||
}
|
}
|
||||||
|
toString() {
|
||||||
|
return this.permission
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 复杂权限对象
|
* 复杂权限对象
|
||||||
*/
|
*/
|
||||||
export class ComplexPermission {
|
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'
|
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.roleList = roleList
|
||||||
this.permissionList = permissionList
|
this.permissionList = permissionList
|
||||||
|
this.editionList = editionList
|
||||||
this.compare = compare
|
this.compare = compare
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 版本
|
||||||
|
*/
|
||||||
|
export class Edition {
|
||||||
|
edition: string
|
||||||
|
constructor(edition: string) {
|
||||||
|
this.edition = edition
|
||||||
|
}
|
||||||
|
toString() {
|
||||||
|
return this.edition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
74
ui/src/views/Permission.vue
Normal file
74
ui/src/views/Permission.vue
Normal file
@ -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
Block a user