diff --git a/apps/vben5/packages/@abp/identity/src/api/users.ts b/apps/vben5/packages/@abp/identity/src/api/users.ts index 42745cd90..dd51b9028 100644 --- a/apps/vben5/packages/@abp/identity/src/api/users.ts +++ b/apps/vben5/packages/@abp/identity/src/api/users.ts @@ -78,3 +78,20 @@ export function removeOrganizationUnit( `/api/identity/users/${id}/organization-units/${ouId}`, ); } + +/** + * 锁定用户 + * @param id 用户id + * @param seconds 锁定时长(秒) + */ +export function lockApi(id: string, seconds: number): Promise { + return requestClient.put(`/api/identity/users/${id}/lock/${seconds}`); +} + +/** + * 解锁用户 + * @param id 用户id + */ +export function unLockApi(id: string): Promise { + return requestClient.put(`/api/identity/users/${id}/unlock`); +} diff --git a/apps/vben5/packages/@abp/identity/src/components/users/UserLockModal.vue b/apps/vben5/packages/@abp/identity/src/components/users/UserLockModal.vue new file mode 100644 index 000000000..235a7c03b --- /dev/null +++ b/apps/vben5/packages/@abp/identity/src/components/users/UserLockModal.vue @@ -0,0 +1,117 @@ + + + + + + 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 55939d133..a3eb444c6 100644 --- a/apps/vben5/packages/@abp/identity/src/components/users/UserTable.vue +++ b/apps/vben5/packages/@abp/identity/src/components/users/UserTable.vue @@ -4,7 +4,7 @@ import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import type { IdentityUserDto } from '../../types/users'; -import { defineAsyncComponent, h } from 'vue'; +import { computed, defineAsyncComponent, h } from 'vue'; import { useAccess } from '@vben/access'; import { useVbenModal } from '@vben/common-ui'; @@ -18,10 +18,12 @@ import { DeleteOutlined, EditOutlined, EllipsisOutlined, + LockOutlined, + UnlockOutlined, } from '@ant-design/icons-vue'; import { Button, Dropdown, Menu, Modal } from 'ant-design-vue'; -import { deleteApi, getPagedListApi } from '../../api/users'; +import { deleteApi, getPagedListApi, unLockApi } from '../../api/users'; import { IdentityUserPermissions } from '../../constants/permissions'; defineOptions({ @@ -29,6 +31,7 @@ defineOptions({ }); const UserModal = defineAsyncComponent(() => import('./UserModal.vue')); +const LockModal = defineAsyncComponent(() => import('./UserLockModal.vue')); const MenuItem = Menu.Item; const CheckIcon = createIconifyIcon('ant-design:check-outlined'); @@ -36,8 +39,19 @@ const CloseIcon = createIconifyIcon('ant-design:close-outlined'); const MenuOutlined = createIconifyIcon('heroicons-outline:menu-alt-3'); const ClaimOutlined = createIconifyIcon('la:id-card-solid'); const PermissionsOutlined = createIconifyIcon('icon-park-outline:permissions'); -const [UserPermissionModal, permissionModalApi] = useVbenModal({ - connectedComponent: PermissionModal, + +const getLockEnd = computed(() => { + return (row: IdentityUserDto) => { + if (row.lockoutEnd) { + const lockTime = new Date(row.lockoutEnd); + if (lockTime) { + // 锁定时间高于当前时间不显示 + const nowTime = new Date(); + return lockTime < nowTime; + } + } + return true; + }; }); const abpStore = useAbpStore(); @@ -127,6 +141,12 @@ const gridEvents: VxeGridListeners = { const [UserEditModal, userModalApi] = useVbenModal({ connectedComponent: UserModal, }); +const [UserLockModal, lockModalApi] = useVbenModal({ + connectedComponent: LockModal, +}); +const [UserPermissionModal, permissionModalApi] = useVbenModal({ + connectedComponent: PermissionModal, +}); const [Grid, { query }] = useVbenVxeGrid({ formOptions, gridEvents, @@ -156,8 +176,18 @@ const handleDelete = (row: IdentityUserDto) => { }); }; +const handleUnlock = async (row: IdentityUserDto) => { + await unLockApi(row.id); + await query(); +}; + const handleMenuClick = async (row: IdentityUserDto, info: MenuInfo) => { switch (info.key) { + case 'lock': { + lockModalApi.setData(row); + lockModalApi.open(); + break; + } case 'permissions': { const userId = abpStore.application?.currentUser.id; permissionModalApi.setData({ @@ -169,6 +199,10 @@ const handleMenuClick = async (row: IdentityUserDto, info: MenuInfo) => { permissionModalApi.open(); break; } + case 'unlock': { + handleUnlock(row); + break; + } } }; @@ -221,6 +255,28 @@ const handleMenuClick = async (row: IdentityUserDto, info: MenuInfo) => {