From e6ccd8b629598f9fa87331549fdd01c4f58bc346 Mon Sep 17 00:00:00 2001 From: colin Date: Thu, 19 Dec 2024 16:38:03 +0800 Subject: [PATCH] =?UTF-8?q?feat(users):=20=E5=A2=9E=E5=8A=A0=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=A3=B0=E6=98=8E=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../@abp/identity/src/api/claim-types.ts | 13 +- .../packages/@abp/identity/src/api/users.ts | 54 ++++++ .../components/claim-types/ClaimTypeModal.vue | 27 ++- .../components/claim-types/ClaimTypeTable.vue | 4 +- .../organization-units/SelectMemberModal.vue | 8 +- .../src/components/roles/RoleModal.vue | 29 ++-- .../src/components/roles/RoleTable.vue | 4 +- .../components/users/UserClaimEditModal.vue | 119 +++++++++++++ .../src/components/users/UserClaimModal.vue | 159 ++++++++++++++++++ .../src/components/users/UserModal.vue | 20 ++- .../src/components/users/UserTable.vue | 16 +- .../packages/@abp/identity/src/types/users.ts | 17 ++ .../permissions/PermissionModal.vue | 2 + 13 files changed, 421 insertions(+), 51 deletions(-) create mode 100644 apps/vben5/packages/@abp/identity/src/components/users/UserClaimEditModal.vue create mode 100644 apps/vben5/packages/@abp/identity/src/components/users/UserClaimModal.vue diff --git a/apps/vben5/packages/@abp/identity/src/api/claim-types.ts b/apps/vben5/packages/@abp/identity/src/api/claim-types.ts index dbbc8d603..b42816c5c 100644 --- a/apps/vben5/packages/@abp/identity/src/api/claim-types.ts +++ b/apps/vben5/packages/@abp/identity/src/api/claim-types.ts @@ -1,4 +1,4 @@ -import type { PagedResultDto } from '@abp/core'; +import type { ListResultDto, PagedResultDto } from '@abp/core'; import type { GetIdentityClaimTypePagedListInput, @@ -72,3 +72,14 @@ export function getPagedListApi( }, ); } + +/** + * 获取可用的声明类型列表 + */ +export function getAssignableClaimsApi(): Promise< + ListResultDto +> { + return requestClient.get>( + `/api/identity/claim-types/actived-list`, + ); +} diff --git a/apps/vben5/packages/@abp/identity/src/api/users.ts b/apps/vben5/packages/@abp/identity/src/api/users.ts index c4cea8535..f73e7a2dc 100644 --- a/apps/vben5/packages/@abp/identity/src/api/users.ts +++ b/apps/vben5/packages/@abp/identity/src/api/users.ts @@ -4,6 +4,10 @@ import type { IdentityRoleDto, OrganizationUnitDto } from '../types'; import type { ChangeUserPasswordInput, GetUserPagedListInput, + IdentityUserClaimCreateDto, + IdentityUserClaimDeleteDto, + IdentityUserClaimDto, + IdentityUserClaimUpdateDto, IdentityUserCreateDto, IdentityUserDto, IdentityUserUpdateDto, @@ -147,3 +151,53 @@ export function getRolesApi( `/api/identity/users/${id}/roles`, ); } + +/** + * 获取用户声明列表 + * @param id 用户id + */ +export function getClaimsApi( + id: string, +): Promise> { + return requestClient.get>( + `/api/identity/users/${id}/claims`, + ); +} + +/** + * 删除用户声明 + * @param id 用户id + * @param input 用户声明dto + */ +export function deleteClaimApi( + id: string, + input: IdentityUserClaimDeleteDto, +): Promise { + return requestClient.delete(`/api/identity/users/${id}/claims`, { + params: input, + }); +} + +/** + * 创建用户声明 + * @param id 用户id + * @param input 用户声明dto + */ +export function createClaimApi( + id: string, + input: IdentityUserClaimCreateDto, +): Promise { + return requestClient.post(`/api/identity/users/${id}/claims`, input); +} + +/** + * 更新用户声明 + * @param id 用户id + * @param input 用户声明dto + */ +export function updateClaimApi( + id: string, + input: IdentityUserClaimUpdateDto, +): Promise { + return requestClient.put(`/api/identity/users/${id}/claims`, input); +} diff --git a/apps/vben5/packages/@abp/identity/src/components/claim-types/ClaimTypeModal.vue b/apps/vben5/packages/@abp/identity/src/components/claim-types/ClaimTypeModal.vue index 911a35e38..754e08fe7 100644 --- a/apps/vben5/packages/@abp/identity/src/components/claim-types/ClaimTypeModal.vue +++ b/apps/vben5/packages/@abp/identity/src/components/claim-types/ClaimTypeModal.vue @@ -79,24 +79,23 @@ const [Modal, modalApi] = useVbenModal({ }, onOpenChange: async (isOpen: boolean) => { if (isOpen) { - const { values } = modalApi.getData>(); - if (values?.id) { - modalApi.setState({ loading: true }); - return getApi(values.id) - .then((dto) => { - formModel.value = dto; - modalApi.setState({ - title: `${$t('AbpIdentity.DisplayName:ClaimType')} - ${dto.name}`, - }); - }) - .finally(() => { - modalApi.setState({ loading: false }); - }); - } formModel.value = { ...defaultModel }; modalApi.setState({ title: $t('AbpIdentity.IdentityClaim:New'), }); + const claimTypeDto = modalApi.getData(); + if (claimTypeDto?.id) { + modalApi.setState({ loading: true }); + try { + const dto = await getApi(claimTypeDto.id); + formModel.value = dto; + modalApi.setState({ + title: `${$t('AbpIdentity.DisplayName:ClaimType')} - ${dto.name}`, + }); + } finally { + modalApi.setState({ loading: false }); + } + } } }, title: 'ClaimType', diff --git a/apps/vben5/packages/@abp/identity/src/components/claim-types/ClaimTypeTable.vue b/apps/vben5/packages/@abp/identity/src/components/claim-types/ClaimTypeTable.vue index 97d2d3689..2f088c700 100644 --- a/apps/vben5/packages/@abp/identity/src/components/claim-types/ClaimTypeTable.vue +++ b/apps/vben5/packages/@abp/identity/src/components/claim-types/ClaimTypeTable.vue @@ -157,9 +157,7 @@ const handleAdd = () => { }; const handleEdit = (row: IdentityClaimTypeDto) => { - roleModalApi.setData({ - values: row, - }); + roleModalApi.setData(row); roleModalApi.open(); }; diff --git a/apps/vben5/packages/@abp/identity/src/components/organization-units/SelectMemberModal.vue b/apps/vben5/packages/@abp/identity/src/components/organization-units/SelectMemberModal.vue index e01ee5d52..7980d2edf 100644 --- a/apps/vben5/packages/@abp/identity/src/components/organization-units/SelectMemberModal.vue +++ b/apps/vben5/packages/@abp/identity/src/components/organization-units/SelectMemberModal.vue @@ -1,4 +1,6 @@ + + + + diff --git a/apps/vben5/packages/@abp/identity/src/components/users/UserClaimModal.vue b/apps/vben5/packages/@abp/identity/src/components/users/UserClaimModal.vue new file mode 100644 index 000000000..c9223b9db --- /dev/null +++ b/apps/vben5/packages/@abp/identity/src/components/users/UserClaimModal.vue @@ -0,0 +1,159 @@ + + + + + diff --git a/apps/vben5/packages/@abp/identity/src/components/users/UserModal.vue b/apps/vben5/packages/@abp/identity/src/components/users/UserModal.vue index b57aab912..e0b7b3023 100644 --- a/apps/vben5/packages/@abp/identity/src/components/users/UserModal.vue +++ b/apps/vben5/packages/@abp/identity/src/components/users/UserModal.vue @@ -93,15 +93,18 @@ const [Modal, modalApi] = useVbenModal({ formModel.value = { ...defaultModel }; modalApi.setState({ loading: true, - title: $t('NewUser'), + title: $t('AbpIdentity.NewUser'), }); try { - const { values } = modalApi.getData>(); + const userDto = modalApi.getData(); const manageRolePolicy = checkManageRolePolicy(); - if (values?.id) { - await initUserInfo(values.id); - manageRolePolicy && (await initUserRoles(values.id)); - checkManageOuPolicy() && (await initOrganizationUnitTree(values.id)); + if (userDto?.id) { + await initUserInfo(userDto.id); + manageRolePolicy && (await initUserRoles(userDto.id)); + checkManageOuPolicy() && (await initOrganizationUnitTree(userDto.id)); + modalApi.setState({ + title: `${$t('AbpIdentity.Users')} - ${userDto.userName}`, + }); } manageRolePolicy && (await initAssignableRoles()); } finally { @@ -275,7 +278,10 @@ async function onLoadOuChildren(node: EventDataNode) { height: '338px', }" :render="(item) => item.title" - :titles="[$t('AbpIdentity.Assigned'), $t('AbpIdentity.Available')]" + :titles="[ + $t('AbpIdentityServer.Assigned'), + $t('AbpIdentityServer.Available'), + ]" class="tree-transfer" /> 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 8a60c6f46..758e31ebd 100644 --- a/apps/vben5/packages/@abp/identity/src/components/users/UserTable.vue +++ b/apps/vben5/packages/@abp/identity/src/components/users/UserTable.vue @@ -19,6 +19,7 @@ import { EditOutlined, EllipsisOutlined, LockOutlined, + PlusOutlined, UnlockOutlined, } from '@ant-design/icons-vue'; import { Button, Dropdown, Menu, Modal } from 'ant-design-vue'; @@ -32,6 +33,7 @@ defineOptions({ const UserModal = defineAsyncComponent(() => import('./UserModal.vue')); const LockModal = defineAsyncComponent(() => import('./UserLockModal.vue')); +const ClaimModal = defineAsyncComponent(() => import('./UserClaimModal.vue')); const PasswordModal = defineAsyncComponent( () => import('./UserPasswordModal.vue'), ); @@ -151,6 +153,9 @@ const [UserLockModal, lockModalApi] = useVbenModal({ const [UserPasswordModal, pwdModalApi] = useVbenModal({ connectedComponent: PasswordModal, }); +const [UserClaimModal, claimModalApi] = useVbenModal({ + connectedComponent: ClaimModal, +}); const [UserPermissionModal, permissionModalApi] = useVbenModal({ connectedComponent: PermissionModal, }); @@ -166,9 +171,7 @@ const handleAdd = () => { }; const handleEdit = (row: IdentityUserDto) => { - userModalApi.setData({ - values: row, - }); + userModalApi.setData(row); userModalApi.open(); }; @@ -190,6 +193,11 @@ const handleUnlock = async (row: IdentityUserDto) => { const handleMenuClick = async (row: IdentityUserDto, info: MenuInfo) => { switch (info.key) { + case 'claims': { + claimModalApi.setData(row); + claimModalApi.open(); + break; + } case 'lock': { lockModalApi.setData(row); lockModalApi.open(); @@ -223,6 +231,7 @@ const handleMenuClick = async (row: IdentityUserDto, info: MenuInfo) => { + diff --git a/apps/vben5/packages/@abp/identity/src/types/users.ts b/apps/vben5/packages/@abp/identity/src/types/users.ts index 9c718cd88..075564265 100644 --- a/apps/vben5/packages/@abp/identity/src/types/users.ts +++ b/apps/vben5/packages/@abp/identity/src/types/users.ts @@ -6,6 +6,8 @@ import type { PagedAndSortedResultRequestDto, } from '@abp/core'; +import type { IdentityClaimDto } from './claim-types'; + /** 用户对象接口 */ interface IUser { /** 邮件地址 */ @@ -90,10 +92,25 @@ interface GetUserPagedListInput extends PagedAndSortedResultRequestDto { type IdentityUserCreateDto = IdentityUserCreateOrUpdateDto; type IdentityUserUpdateDto = IdentityUserCreateOrUpdateDto; +interface IdentityUserClaimDto extends IdentityClaimDto { + id: string; +} + +interface IdentityUserClaimUpdateDto extends IdentityClaimDto { + newClaimValue: string; +} + +type IdentityUserClaimDeleteDto = IdentityClaimDto; +type IdentityUserClaimCreateDto = IdentityClaimDto; + export type { ChangeMyPasswordInput, ChangeUserPasswordInput, GetUserPagedListInput, + IdentityUserClaimCreateDto, + IdentityUserClaimDeleteDto, + IdentityUserClaimDto, + IdentityUserClaimUpdateDto, IdentityUserCreateDto, IdentityUserDto, IdentityUserOrganizationUnitUpdateDto, 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 fea114430..62cf75f3f 100644 --- a/apps/vben5/packages/@abp/permission/src/components/permissions/PermissionModal.vue +++ b/apps/vben5/packages/@abp/permission/src/components/permissions/PermissionModal.vue @@ -115,6 +115,7 @@ const [Modal, modalApi] = useVbenModal({ const state = modalApi.getData(); modelState.value = state; modalApi.setState({ + confirmLoading: true, loading: true, }); try { @@ -129,6 +130,7 @@ const [Modal, modalApi] = useVbenModal({ checkedNodeKeys.value = getGrantedPermissionKeys(permissionTree.value); } finally { modalApi.setState({ + confirmLoading: false, loading: false, }); }