From bcae0edf12369115d9cf34ef4b510266f3a3b99e Mon Sep 17 00:00:00 2001 From: colin Date: Fri, 6 Dec 2024 09:31:13 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat(organization):=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E7=BB=84=E7=BB=87=E6=9C=BA=E6=9E=84=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OrganizationUnitModal.vue | 115 +++++++++++++++++- .../OrganizationUnitTree.vue | 18 ++- 2 files changed, 128 insertions(+), 5 deletions(-) diff --git a/apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitModal.vue b/apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitModal.vue index 76711ad74..e9e25200e 100644 --- a/apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitModal.vue +++ b/apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitModal.vue @@ -1,11 +1,124 @@ diff --git a/apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitTree.vue b/apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitTree.vue index 9dd8a554c..151077d48 100644 --- a/apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitTree.vue +++ b/apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitTree.vue @@ -6,8 +6,9 @@ import type { } from 'ant-design-vue/es/tree'; import type { Key } from 'ant-design-vue/es/vc-table/interface'; -import { h, onMounted, ref, watchEffect } from 'vue'; +import { defineAsyncComponent, h, onMounted, ref, watchEffect } from 'vue'; +import { useVbenModal } from '@vben/common-ui'; import { createIconifyIcon } from '@vben/icons'; import { $t } from '@vben/locales'; @@ -36,6 +37,9 @@ const emits = defineEmits<{ const MenuItem = Menu.Item; const PermissionsOutlined = createIconifyIcon('icon-park-outline:permissions'); +const OrganizationUnitModal = defineAsyncComponent( + () => import('./OrganizationUnitModal.vue'), +); interface ContextMenuActionMap { [key: string]: (id: string) => Promise | void; @@ -52,6 +56,10 @@ const organizationUnits = ref([]); const loadedKeys = ref([]); const selectedKey = ref(); +const [OrganizationUnitEditModal, editModalApi] = useVbenModal({ + connectedComponent: OrganizationUnitModal, +}); + /** 刷新组织机构树 */ async function onRefresh() { loadedKeys.value = []; @@ -90,13 +98,14 @@ function onRightClick() { /** 创建组织机构树 */ function onCreate(parentId?: string) { - !parentId && console.warn('create root method not implemented!'); - parentId && console.warn('create children method not implemented!'); + editModalApi.setData({ parentId }); + editModalApi.open(); } /** 编辑组织机构树 */ function onUpdate(id: string) { - console.warn('update method not implemented!', id); + editModalApi.setData({ id }); + editModalApi.open(); } /** 编辑组织机构树权限 */ @@ -194,6 +203,7 @@ watchEffect(() => { + From 2d585e9e3f67dbdaf4d00c90dd3c8d982db019b1 Mon Sep 17 00:00:00 2001 From: colin Date: Fri, 6 Dec 2024 14:49:28 +0800 Subject: [PATCH 2/6] =?UTF-8?q?feat(permissions):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=9D=83=E9=99=90=E7=AE=A1=E7=90=86=E6=A8=A1=E6=80=81=E6=A1=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../packages/@abp/permission/package.json | 36 +++ .../@abp/permission/src/api/permissions.ts | 37 +++ .../groups/PermissionGroupDefinitionModal.vue | 7 + .../groups/PermissionGroupDefinitionTable.vue | 7 + .../permissions/PermissionDefinitionModal.vue | 7 + .../permissions/PermissionDefinitionTable.vue | 7 + .../@abp/permission/src/components/index.ts | 3 + .../permissions/PermissionModal.vue | 301 ++++++++++++++++++ .../packages/@abp/permission/src/index.ts | 2 + .../@abp/permission/src/types/index.ts | 1 + .../@abp/permission/src/types/permissions.ts | 60 ++++ .../@abp/permission/src/utils/index.ts | 143 +++++++++ .../packages/@abp/permission/tsconfig.json | 6 + apps/vben5/vben-admin.code-workspace | 4 + 14 files changed, 621 insertions(+) create mode 100644 apps/vben5/packages/@abp/permission/package.json create mode 100644 apps/vben5/packages/@abp/permission/src/api/permissions.ts create mode 100644 apps/vben5/packages/@abp/permission/src/components/definitions/groups/PermissionGroupDefinitionModal.vue create mode 100644 apps/vben5/packages/@abp/permission/src/components/definitions/groups/PermissionGroupDefinitionTable.vue create mode 100644 apps/vben5/packages/@abp/permission/src/components/definitions/permissions/PermissionDefinitionModal.vue create mode 100644 apps/vben5/packages/@abp/permission/src/components/definitions/permissions/PermissionDefinitionTable.vue create mode 100644 apps/vben5/packages/@abp/permission/src/components/index.ts create mode 100644 apps/vben5/packages/@abp/permission/src/components/permissions/PermissionModal.vue create mode 100644 apps/vben5/packages/@abp/permission/src/index.ts create mode 100644 apps/vben5/packages/@abp/permission/src/types/index.ts create mode 100644 apps/vben5/packages/@abp/permission/src/types/permissions.ts create mode 100644 apps/vben5/packages/@abp/permission/src/utils/index.ts create mode 100644 apps/vben5/packages/@abp/permission/tsconfig.json diff --git a/apps/vben5/packages/@abp/permission/package.json b/apps/vben5/packages/@abp/permission/package.json new file mode 100644 index 000000000..b5adfecf3 --- /dev/null +++ b/apps/vben5/packages/@abp/permission/package.json @@ -0,0 +1,36 @@ +{ + "name": "@abp/permission", + "version": "8.3.2", + "homepage": "https://github.com/colinin/abp-next-admin", + "bugs": "https://github.com/colinin/abp-next-admin/issues", + "repository": { + "type": "git", + "url": "git+https://github.com/colinin/abp-next-admin.git", + "directory": "packages/@abp/permission" + }, + "license": "MIT", + "type": "module", + "sideEffects": [ + "**/*.css" + ], + "exports": { + ".": { + "types": "./src/index.ts", + "default": "./src/index.ts" + } + }, + "dependencies": { + "@abp/core": "workspace:*", + "@abp/request": "workspace:*", + "@abp/ui": "workspace:*", + "@ant-design/icons-vue": "catalog:", + "@vben/access": "workspace:*", + "@vben/common-ui": "workspace:*", + "@vben/hooks": "workspace:*", + "@vben/icons": "workspace:*", + "@vben/layouts": "workspace:*", + "@vben/locales": "workspace:*", + "ant-design-vue": "catalog:", + "vue": "catalog:*" + } +} diff --git a/apps/vben5/packages/@abp/permission/src/api/permissions.ts b/apps/vben5/packages/@abp/permission/src/api/permissions.ts new file mode 100644 index 000000000..d4ad87c78 --- /dev/null +++ b/apps/vben5/packages/@abp/permission/src/api/permissions.ts @@ -0,0 +1,37 @@ +import type { + PermissionProvider, + PermissionResultDto, + PermissionsUpdateDto, +} from '../types/permissions'; + +import { requestClient } from '@abp/request'; + +/** + * 查询权限 + * @param provider + * @returns 权限实体数据传输对象 + */ +export function getApi( + provider: PermissionProvider, +): Promise { + return requestClient.get( + `/api/permission-management/permissions`, + { + params: provider, + }, + ); +} + +/** + * 更新权限 + * @param provider + * @param input + */ +export function updateApi( + provider: PermissionProvider, + input: PermissionsUpdateDto, +): Promise { + return requestClient.put(`/api/permission-management/permissions`, input, { + params: provider, + }); +} diff --git a/apps/vben5/packages/@abp/permission/src/components/definitions/groups/PermissionGroupDefinitionModal.vue b/apps/vben5/packages/@abp/permission/src/components/definitions/groups/PermissionGroupDefinitionModal.vue new file mode 100644 index 000000000..1017376d1 --- /dev/null +++ b/apps/vben5/packages/@abp/permission/src/components/definitions/groups/PermissionGroupDefinitionModal.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/apps/vben5/packages/@abp/permission/src/components/definitions/groups/PermissionGroupDefinitionTable.vue b/apps/vben5/packages/@abp/permission/src/components/definitions/groups/PermissionGroupDefinitionTable.vue new file mode 100644 index 000000000..1017376d1 --- /dev/null +++ b/apps/vben5/packages/@abp/permission/src/components/definitions/groups/PermissionGroupDefinitionTable.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/apps/vben5/packages/@abp/permission/src/components/definitions/permissions/PermissionDefinitionModal.vue b/apps/vben5/packages/@abp/permission/src/components/definitions/permissions/PermissionDefinitionModal.vue new file mode 100644 index 000000000..1017376d1 --- /dev/null +++ b/apps/vben5/packages/@abp/permission/src/components/definitions/permissions/PermissionDefinitionModal.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/apps/vben5/packages/@abp/permission/src/components/definitions/permissions/PermissionDefinitionTable.vue b/apps/vben5/packages/@abp/permission/src/components/definitions/permissions/PermissionDefinitionTable.vue new file mode 100644 index 000000000..1017376d1 --- /dev/null +++ b/apps/vben5/packages/@abp/permission/src/components/definitions/permissions/PermissionDefinitionTable.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/apps/vben5/packages/@abp/permission/src/components/index.ts b/apps/vben5/packages/@abp/permission/src/components/index.ts new file mode 100644 index 000000000..8187ea421 --- /dev/null +++ b/apps/vben5/packages/@abp/permission/src/components/index.ts @@ -0,0 +1,3 @@ +export { default as PermissionGroupDefinitionTable } from './definitions/groups/PermissionGroupDefinitionTable.vue'; +export { default as PermissionDefinitionTable } from './definitions/permissions/PermissionDefinitionTable.vue'; +export { default as PermissionModal } from './permissions/PermissionModal.vue'; diff --git a/apps/vben5/packages/@abp/permission/src/components/permissions/PermissionModal.vue b/apps/vben5/packages/@abp/permission/src/components/permissions/PermissionModal.vue new file mode 100644 index 000000000..f6c969593 --- /dev/null +++ b/apps/vben5/packages/@abp/permission/src/components/permissions/PermissionModal.vue @@ -0,0 +1,301 @@ + + + + + diff --git a/apps/vben5/packages/@abp/permission/src/index.ts b/apps/vben5/packages/@abp/permission/src/index.ts new file mode 100644 index 000000000..195d95f59 --- /dev/null +++ b/apps/vben5/packages/@abp/permission/src/index.ts @@ -0,0 +1,2 @@ +export * from './components'; +export * from './types'; diff --git a/apps/vben5/packages/@abp/permission/src/types/index.ts b/apps/vben5/packages/@abp/permission/src/types/index.ts new file mode 100644 index 000000000..c85954d3e --- /dev/null +++ b/apps/vben5/packages/@abp/permission/src/types/index.ts @@ -0,0 +1 @@ +export * from './permissions'; diff --git a/apps/vben5/packages/@abp/permission/src/types/permissions.ts b/apps/vben5/packages/@abp/permission/src/types/permissions.ts new file mode 100644 index 000000000..d90634a90 --- /dev/null +++ b/apps/vben5/packages/@abp/permission/src/types/permissions.ts @@ -0,0 +1,60 @@ +interface PermissionProvider { + providerKey?: string; + providerName: string; +} + +interface PermissionDto { + allowedProviders: string[]; + displayName: string; + grantedProviders: PermissionProvider[]; + isGranted: boolean; + name: string; + parentName?: string; +} + +interface PermissionGroupDto { + displayName: string; + name: string; + permissions: PermissionDto[]; +} + +interface PermissionUpdateDto { + /** 是否授权 */ + isGranted: boolean; + /** 权限名称 */ + name: string; +} + +interface PermissionsUpdateDto { + permissions: PermissionUpdateDto[]; +} + +interface PermissionResultDto { + entityDisplayName: string; + groups: PermissionGroupDto[]; +} + +interface PermissionTree { + /** 子节点 */ + children: PermissionTree[]; + /** 是否禁用 */ + disabled: boolean; + /** 显示名称 */ + displayName: string; + /** 是否授权 */ + isGranted?: boolean; + isRoot: boolean; + /** 权限标识 */ + name: string; + /** 父节点 */ + parentName?: string; +} + +export type { + PermissionDto, + PermissionGroupDto, + PermissionProvider, + PermissionResultDto, + PermissionsUpdateDto, + PermissionTree, +}; diff --git a/apps/vben5/packages/@abp/permission/src/utils/index.ts b/apps/vben5/packages/@abp/permission/src/utils/index.ts new file mode 100644 index 000000000..7e30e0aab --- /dev/null +++ b/apps/vben5/packages/@abp/permission/src/utils/index.ts @@ -0,0 +1,143 @@ +import type { + PermissionDto, + PermissionGroupDto, + PermissionTree, +} from '../types/permissions'; + +import { listToTree } from '@abp/core'; + +export function generatePermissionTree( + permissionGroups: PermissionGroupDto[], +): PermissionTree[] { + const trees: PermissionTree[] = []; + permissionGroups.forEach((g) => { + const tree: PermissionTree = { + disabled: false, + displayName: g.displayName, + isRoot: true, + name: g.name, + parentName: g.name, + children: [], + }; + tree.children = listToTree(g.permissions, { + id: 'name', + pid: 'parentName', + }); + trees.push(tree); + }); + return trees; +} + +export function findNode( + children: PermissionTree[], + key: string, +): PermissionTree | undefined { + let findC: PermissionTree | undefined; + for (const child of children) { + if (child.name === key) { + findC = child; + return findC; + } + findC = findNode(child.children, key); + if (findC) { + return findC; + } + } + return findC; +} + +export function getPermissionsCount(children: PermissionTree[]): number { + let count = 0; + children.forEach((c) => { + count += getPermissionCount(c); + }); + return count; +} + +export function getPermissionCount(tree: PermissionTree): number { + let count = tree.children.length; + tree.children.forEach((c) => { + count += getPermissionCount(c); + }); + return count; +} + +export function getGrantPermissionsCount(children: PermissionTree[]): number { + let count = 0; + children.forEach((c) => { + count += getGrantPermissionCount(c); + }); + return count; +} + +export function getGrantPermissionCount(tree: PermissionTree): number { + return getGrantedPermissionKeys(tree.children).length; +} + +export function getGrantedPermissionKeys(children: PermissionTree[]): string[] { + const keys: string[] = []; + children.forEach((c) => { + if (c.isGranted === true) { + keys.push(c.name); + } + keys.push(...getGrantedPermissionKeys(c.children)); + }); + return keys; +} + +export function getParentList( + children: PermissionTree[], + name: string, +): PermissionTree[] | undefined { + for (const child of children) { + if (child.name === name) { + return [child]; + } + if (child.children) { + const node = getParentList(child.children, name); + if (node) { + return [...node, child]; + } + } + } +} + +export function toPermissionList(treeList: PermissionTree[]) { + const permissions: PermissionDto[] = []; + for (const element of treeList) { + if (!element.isRoot && element.isGranted !== undefined) { + permissions.push({ + allowedProviders: [], + displayName: element.displayName, + grantedProviders: [], + isGranted: element.isGranted, + name: element.name, + }); + } + permissions.push(...toPermissionList(element.children)); + } + return permissions; +} + +export function updateParentGrant( + tree: PermissionTree, + name: string, + grant: boolean, +) { + const parentList = getParentList(tree.children, name); + if (parentList && Array.isArray(parentList)) { + for (const element of parentList) { + element.isGranted = grant; + } + } +} + +export function updateChildrenGrant( + children: PermissionTree[], + grant: boolean, +) { + for (const child of children) { + child.isGranted = grant; + updateChildrenGrant(child.children, grant); + } +} diff --git a/apps/vben5/packages/@abp/permission/tsconfig.json b/apps/vben5/packages/@abp/permission/tsconfig.json new file mode 100644 index 000000000..ce1a891fb --- /dev/null +++ b/apps/vben5/packages/@abp/permission/tsconfig.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig", + "extends": "@vben/tsconfig/web.json", + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/apps/vben5/vben-admin.code-workspace b/apps/vben5/vben-admin.code-workspace index 9b7519c1a..9bc930a45 100644 --- a/apps/vben5/vben-admin.code-workspace +++ b/apps/vben5/vben-admin.code-workspace @@ -192,5 +192,9 @@ "name": "@abp/account", "path": "packages/@abp/account", }, + { + "name": "@abp/permission", + "path": "packages/@abp/permission", + }, ], } From f7109b3de21fdfec9f8cb413dd55dd0386cfa7d9 Mon Sep 17 00:00:00 2001 From: colin Date: Fri, 6 Dec 2024 14:53:33 +0800 Subject: [PATCH 3/6] =?UTF-8?q?feat(organizations):=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=BB=84=E7=BB=87=E6=9C=BA=E6=9E=84=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../organization-units/OrganizationUnitTree.vue | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitTree.vue b/apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitTree.vue index 151077d48..2ca63969c 100644 --- a/apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitTree.vue +++ b/apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitTree.vue @@ -12,6 +12,7 @@ import { useVbenModal } from '@vben/common-ui'; import { createIconifyIcon } from '@vben/icons'; import { $t } from '@vben/locales'; +import { PermissionModal } from '@abp/permission'; import { DeleteOutlined, EditOutlined, @@ -22,6 +23,7 @@ import { Button, Card, Dropdown, Menu, Modal, Tree } from 'ant-design-vue'; import { deleteApi, + getApi, getChildrenApi, getRootListApi, moveTo, @@ -59,6 +61,9 @@ const selectedKey = ref(); const [OrganizationUnitEditModal, editModalApi] = useVbenModal({ connectedComponent: OrganizationUnitModal, }); +const [OrganizationUnitPermissionModal, permissionModalApi] = useVbenModal({ + connectedComponent: PermissionModal, +}); /** 刷新组织机构树 */ async function onRefresh() { @@ -109,8 +114,14 @@ function onUpdate(id: string) { } /** 编辑组织机构树权限 */ -function onPermissions(id: string) { - console.warn('permissions method not implemented!', id); +async function onPermissions(id: string) { + const dto = await getApi(id); + permissionModalApi.setData({ + displayName: dto.displayName, + providerKey: id, + providerName: 'O', + }); + permissionModalApi.open(); } /** 删除组织机构 */ @@ -204,6 +215,7 @@ watchEffect(() => { + From 779518ee7d658c01f04689575afb526a4db109ca Mon Sep 17 00:00:00 2001 From: colin Date: Fri, 6 Dec 2024 15:25:25 +0800 Subject: [PATCH 4/6] =?UTF-8?q?feat(roles):=20=E5=A2=9E=E5=8A=A0=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vben5/packages/@abp/identity/package.json | 1 + .../src/components/roles/RoleTable.vue | 78 +++++++++++++++++-- .../permissions/PermissionModal.vue | 33 ++++++-- 3 files changed, 100 insertions(+), 12 deletions(-) diff --git a/apps/vben5/packages/@abp/identity/package.json b/apps/vben5/packages/@abp/identity/package.json index 237482ec3..0a1fad4a5 100644 --- a/apps/vben5/packages/@abp/identity/package.json +++ b/apps/vben5/packages/@abp/identity/package.json @@ -21,6 +21,7 @@ }, "dependencies": { "@abp/core": "workspace:*", + "@abp/permission": "workspace:*", "@abp/request": "workspace:*", "@abp/ui": "workspace:*", "@ant-design/icons-vue": "catalog:", diff --git a/apps/vben5/packages/@abp/identity/src/components/roles/RoleTable.vue b/apps/vben5/packages/@abp/identity/src/components/roles/RoleTable.vue index 6be353eb4..5c8eb2a96 100644 --- a/apps/vben5/packages/@abp/identity/src/components/roles/RoleTable.vue +++ b/apps/vben5/packages/@abp/identity/src/components/roles/RoleTable.vue @@ -1,16 +1,25 @@ + + diff --git a/apps/vben5/packages/@abp/identity/src/components/users/UserTable.vue b/apps/vben5/packages/@abp/identity/src/components/users/UserTable.vue index 0de52b423..2dba33458 100644 --- a/apps/vben5/packages/@abp/identity/src/components/users/UserTable.vue +++ b/apps/vben5/packages/@abp/identity/src/components/users/UserTable.vue @@ -1,18 +1,25 @@ + - + diff --git a/apps/vben5/packages/@abp/permission/src/components/permissions/PermissionModal.vue b/apps/vben5/packages/@abp/permission/src/components/permissions/PermissionModal.vue index 014d2cbae..7fe29479b 100644 --- a/apps/vben5/packages/@abp/permission/src/components/permissions/PermissionModal.vue +++ b/apps/vben5/packages/@abp/permission/src/components/permissions/PermissionModal.vue @@ -74,6 +74,7 @@ const getPermissionNodeState = computed(() => { }); const [Modal, modalApi] = useVbenModal({ + centered: true, class: 'w-1/2', closeOnClickModal: false, closeOnPressEscape: false, @@ -307,10 +308,10 @@ function getChildren(permissions: PermissionTree[]): PermissionTree[] {