Skip to content

Commit c1ad339

Browse files
committed
feat: ui hasPermission
1 parent baf1c2c commit c1ad339

File tree

7 files changed

+167
-16
lines changed

7 files changed

+167
-16
lines changed

ui/src/router/modules/application-detail.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { ComplexPermission } from '@/utils/permission/type'
21
import { PermissionConst, RoleConst } from '@/utils/permission/data'
32

43
const ApplicationDetailRouter = {

ui/src/router/routes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ export const routes: Array<RouteRecordRaw> = [
4646
name: 'ResetPassword',
4747
component: () => import('@/views/login/ResetPassword.vue'),
4848
},
49+
{
50+
path: '/permission',
51+
name: 'permission',
52+
component: () => import('@/views/Permission.vue'),
53+
},
4954
// {
5055
// path: '/:pathMatch(.*)',
5156
// name: '404',

ui/src/stores/modules/user.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,27 @@ const useUserStore = defineStore('user', {
9393
getPermissions() {
9494
if (this.userInfo) {
9595
if (this.isEE()) {
96-
return [...this.userInfo?.permissions, 'x-pack-ee']
96+
return [...this.userInfo?.permissions, 'X-PACK-EE']
9797
} else if (this.isPE()) {
98-
return [...this.userInfo?.permissions, 'x-pack-pe']
98+
return [...this.userInfo?.permissions, 'X-PACK-PE']
9999
}
100100
return this.userInfo?.permissions
101101
} else {
102102
return []
103103
}
104104
},
105+
getEdition() {
106+
if (this.userInfo) {
107+
if (this.isEE()) {
108+
return 'X-PACK-EE'
109+
} else if (this.isPE()) {
110+
return 'X-PACK-PE'
111+
} else {
112+
return 'X-PACK-CE'
113+
}
114+
}
115+
return 'X-PACK-CE'
116+
},
105117
getRole() {
106118
if (this.userInfo) {
107119
return this.userInfo?.role

ui/src/utils/permission/data.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Permission, Role } from '@/utils/permission/type'
1+
import { Permission, Role, Edition } from '@/utils/permission/type'
22
const PermissionConst = {
33
USER_READ: new Permission('USER:READ'),
44
USER_CREATE: new Permission('USER:CREATE'),
@@ -10,4 +10,9 @@ const RoleConst = {
1010
WORKSPACE_MANAGE: new Role('WORKSPACE_MANAGE'),
1111
USER: new Role('USER'),
1212
}
13-
export { PermissionConst, RoleConst }
13+
const EditionConst = {
14+
IS_PE: new Edition('X-PACK-PE'),
15+
IS_EE: new Edition('X-PACK-EE'),
16+
IS_CE: new Edition('X-PACK-CE'),
17+
}
18+
export { PermissionConst, RoleConst, EditionConst }

ui/src/utils/permission/index.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,30 @@
11
import useStore from '@/stores'
2-
import { Role, Permission, ComplexPermission } from '@/utils/permission/type'
2+
import {
3+
Role,
4+
Permission,
5+
ComplexPermission,
6+
Edition,
7+
type PF,
8+
type CPF,
9+
type CRF,
10+
} from '@/utils/permission/type'
311
import { isFunction } from '@/utils/common'
412

5-
type PF = () => Role | string | Permission | ComplexPermission
613
/**
714
* 是否包含当前权限
815
* @param permission 当前权限
916
* @returns True 包含 false 不包含
1017
*/
11-
const hasPermissionChild = (permission: Role | string | Permission | ComplexPermission | PF) => {
18+
const hasPermissionChild = (
19+
permission: Role | string | Permission | ComplexPermission | Edition | PF,
20+
) => {
1221
const { user } = useStore()
1322
const permissions = user.getPermissions()
1423
const role: Array<string> = user.getRole()
24+
const edition = user.getEdition()
1525
if (!permission) {
1626
return true
1727
}
18-
1928
if (isFunction(permission)) {
2029
permission = (permission as PF)()
2130
}
@@ -25,10 +34,22 @@ const hasPermissionChild = (permission: Role | string | Permission | ComplexPerm
2534
if (permission instanceof Permission) {
2635
return permissions.includes(permission.permission)
2736
}
37+
if (permission instanceof Edition) {
38+
return permission.edition === edition
39+
}
2840
if (permission instanceof ComplexPermission) {
29-
const permissionOk = permission.permissionList.some((p) => permissions.includes(p))
30-
const roleOk = role.some((r) => permission.roleList.includes(r))
31-
return permission.compare === 'AND' ? permissionOk && roleOk : permissionOk || roleOk
41+
const permissionOk = permission.permissionList.some((p) =>
42+
permissions.includes(isFunction(p) ? (p as CPF)().toString() : p.toString()),
43+
)
44+
const roleList = permission.roleList
45+
const roleOk = roleList.some((r) =>
46+
role.includes(isFunction(r) ? (r as CRF)().toString() : r.toString()),
47+
)
48+
const editionOK = permission.editionList.includes(edition.toString())
49+
50+
return permission.compare === 'AND'
51+
? permissionOk && roleOk && editionOK
52+
: (permissionOk || roleOk) && editionOK
3253
}
3354
if (typeof permission === 'string') {
3455
return permissions.includes(permission)
@@ -45,10 +66,11 @@ const hasPermissionChild = (permission: Role | string | Permission | ComplexPerm
4566
*/
4667
export const hasPermission = (
4768
permission:
48-
| Array<Role | string | Permission | ComplexPermission | PF>
69+
| Array<Role | string | Permission | ComplexPermission | Edition | PF>
4970
| Role
5071
| string
5172
| Permission
73+
| Edition
5274
| ComplexPermission
5375
| PF,
5476
compare: 'OR' | 'AND',

ui/src/utils/permission/type.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import useStore from '@/stores'
2+
export type PF = () => Role | string | Permission | ComplexPermission
3+
export type CRF = () => Role | string
4+
export type CPF = () => Permission | string
25
/**
36
* 角色对象
47
*/
@@ -13,6 +16,13 @@ export class Role {
1316
const { user } = useStore()
1417
return new Role(`${this.role}:/WORKSPACE/${user.getWorkspaceId()}`)
1518
}
19+
getWorkspaceRoleString = () => {
20+
const { user } = useStore()
21+
return `${this.role}:/WORKSPACE/${user.getWorkspaceId()}`
22+
}
23+
toString() {
24+
return this.role
25+
}
1626
}
1727
/**
1828
* 权限对象
@@ -43,20 +53,44 @@ export class Permission {
4353
const { user } = useStore()
4454
return `${this.permission}:/WORKSPACE/${user.getWorkspaceId()}/${resource}/${resource_id}`
4555
}
56+
toString() {
57+
return this.permission
58+
}
4659
}
60+
4761
/**
4862
* 复杂权限对象
4963
*/
5064
export class ComplexPermission {
51-
roleList: Array<string>
65+
roleList: Array<string | Role | CRF>
66+
67+
permissionList: Array<string | Permission | CPF>
5268

53-
permissionList: Array<string>
69+
editionList: Array<string | Edition>
5470

5571
compare: 'OR' | 'AND'
5672

57-
constructor(roleList: Array<string>, permissionList: Array<string>, compare: 'OR' | 'AND') {
73+
constructor(
74+
roleList: Array<string | Role | CRF>,
75+
permissionList: Array<string | Permission | CPF>,
76+
editionList: Array<string | Edition>,
77+
compare: 'OR' | 'AND',
78+
) {
5879
this.roleList = roleList
5980
this.permissionList = permissionList
81+
this.editionList = editionList
6082
this.compare = compare
6183
}
6284
}
85+
/**
86+
* 版本
87+
*/
88+
export class Edition {
89+
edition: string
90+
constructor(edition: string) {
91+
this.edition = edition
92+
}
93+
toString() {
94+
return this.edition
95+
}
96+
}

ui/src/views/Permission.vue

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<template>
2+
<div>说明: v-hasPermission 是使用v-show 本质上组件是渲染的 v-if="hasPermission('xxxx')"</div>
3+
<div>这种方式组件不会渲染(用于比如像组件挂载的时候需要调用接口,不想让组件渲染)</div>
4+
<div>比如工作空间的下拉列表组件使用v-if 示例: 企业版组件:</div>
5+
6+
<button v-if="hasPermission(EditionConst.IS_CE, 'OR')">我是社区版组件</button>
7+
8+
<button v-hasPermission="EditionConst.IS_CE">我是社区版组件</button>
9+
<!-- ================我是企业版组件================== -->
10+
<button v-if="hasPermission(EditionConst.IS_EE, 'OR')">我是企业版组件</button>
11+
<button v-hasPermission="EditionConst.IS_EE">我是企业版组件</button>
12+
13+
<!-- ================企业版组件 并且是ADMIN角色================== -->
14+
<button v-if="hasPermission([EditionConst.IS_EE, RoleConst.ADMIN], 'AND')">
15+
我是企业版并且是ADMIN角色
16+
</button>
17+
<button
18+
v-hasPermission="new ComplexPermission([RoleConst.ADMIN], [], [EditionConst.IS_EE], 'AND')"
19+
>
20+
我是企业版并且是ADMIN角色
21+
</button>
22+
<!-- ================企业版组件 并且是当前工作空间管理员================== -->
23+
<button
24+
v-if="hasPermission([EditionConst.IS_EE, RoleConst.WORKSPACE_MANAGE.getWorkspaceRole], 'AND')"
25+
>
26+
我是企业版并且拥有当前工作空间管理员角色
27+
</button>
28+
<button
29+
v-hasPermission="
30+
new ComplexPermission(
31+
[RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
32+
[],
33+
[EditionConst.IS_EE],
34+
'OR',
35+
)
36+
"
37+
>
38+
我是企业版并且拥有当前工作空间管理员角色
39+
</button>
40+
<!-- ================企业版组件 (并且是当前工作空间管理员 或者有用户只读)================== -->
41+
<button
42+
v-if="
43+
hasPermission(
44+
new ComplexPermission(
45+
[RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
46+
[PermissionConst.USER_READ],
47+
[EditionConst.IS_EE],
48+
'OR',
49+
),
50+
'OR',
51+
)
52+
"
53+
>
54+
我是企业版 (并且是当前工作空间管理员 或者有用户只读)
55+
</button>
56+
<button
57+
v-hasPermission="
58+
new ComplexPermission(
59+
[RoleConst.WORKSPACE_MANAGE.getWorkspaceRole],
60+
[PermissionConst.USER_READ],
61+
[EditionConst.IS_EE],
62+
'OR',
63+
)
64+
"
65+
>
66+
我是企业版(并且是当前工作空间管理员 或者有用户只读)
67+
</button>
68+
</template>
69+
<script setup lang="ts">
70+
import { PermissionConst, EditionConst, RoleConst } from '@/utils/permission/data'
71+
import { hasPermission } from '@/utils/permission/index'
72+
import { ComplexPermission } from '@/utils/permission/type'
73+
</script>
74+
<style lang="scss" scoped></style>

0 commit comments

Comments
 (0)