refactor(用户管理): 优化用户信息展示和操作菜单逻辑

重构用户信息模态框中的登录时间显示,移除重复代码并优化标签渲染
将用户列表中的操作菜单改为计算属性方式,简化模板代码
This commit is contained in:
dap
2026-01-13 19:58:30 +08:00
parent 0626b65c74
commit efe744cfdd
2 changed files with 37 additions and 35 deletions

View File

@@ -1,26 +1,19 @@
<script setup lang="ts"> <script setup lang="ts">
import type { MenuProps } from 'antdv-next';
import type { VbenFormProps } from '@vben/common-ui'; import type { VbenFormProps } from '@vben/common-ui';
import type { VxeGridProps } from '#/adapter/vxe-table'; import type { VxeGridProps } from '#/adapter/vxe-table';
import type { User } from '#/api/system/user/model'; import type { User } from '#/api/system/user/model';
import { ref } from 'vue'; import { computed, ref } from 'vue';
import { useAccess } from '@vben/access'; import { useAccess } from '@vben/access';
import { Page, useVbenDrawer, useVbenModal } from '@vben/common-ui'; import { Page, useVbenDrawer, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
import { preferences } from '@vben/preferences'; import { preferences } from '@vben/preferences';
import { getVxePopupContainer } from '@vben/utils';
import { import { Avatar, Dropdown, Modal, Popconfirm, Space } from 'antdv-next';
Avatar,
Dropdown,
Menu,
MenuItem,
Modal,
Popconfirm,
Space,
} from 'antdv-next';
import { useVbenVxeGrid, vxeCheckboxChecked } from '#/adapter/vxe-table'; import { useVbenVxeGrid, vxeCheckboxChecked } from '#/adapter/vxe-table';
import { import {
@@ -61,7 +54,7 @@ const formOptions: VbenFormProps = {
allowClear: true, allowClear: true,
}, },
}, },
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4', wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
handleReset: async () => { handleReset: async () => {
selectDeptId.value = []; selectDeptId.value = [];
@@ -186,6 +179,26 @@ function handleResetPwd(record: User) {
} }
const { hasAccessByCodes } = useAccess(); const { hasAccessByCodes } = useAccess();
const menuItems = computed(() => {
const items: MenuProps['items'] = [{ key: 'info', label: '用户信息' }];
if (hasAccessByCodes(['system:user:resetPwd'])) {
items.push({ key: 'resetPwd', label: '重置密码' });
}
return items;
});
function handleMenuClick(key: string, row: any) {
switch (key) {
case 'info': {
handleUserInfo(row);
break;
}
case 'resetPwd': {
handleResetPwd(row);
break;
}
}
}
</script> </script>
<template> <template>
@@ -254,7 +267,6 @@ const { hasAccessByCodes } = useAccess();
{{ $t('pages.common.edit') }} {{ $t('pages.common.edit') }}
</ghost-button> </ghost-button>
<Popconfirm <Popconfirm
:get-popup-container="getVxePopupContainer"
placement="left" placement="left"
title="确认删除?" title="确认删除?"
@confirm="handleDelete(row)" @confirm="handleDelete(row)"
@@ -268,19 +280,13 @@ const { hasAccessByCodes } = useAccess();
</ghost-button> </ghost-button>
</Popconfirm> </Popconfirm>
</Space> </Space>
<Dropdown placement="bottomRight"> <Dropdown
<template #overlay> placement="bottomRight"
<Menu> :menu="{
<MenuItem key="1" @click="handleUserInfo(row)"> items: menuItems,
用户信息 onClick: (info) => handleMenuClick(info.key, row),
</MenuItem> }"
<span v-access:code="['system:user:resetPwd']"> >
<MenuItem key="2" @click="handleResetPwd(row)">
重置密码
</MenuItem>
</span>
</Menu>
</template>
<a-button size="small" type="link"> <a-button size="small" type="link">
{{ $t('pages.common.more') }} {{ $t('pages.common.more') }}
</a-button> </a-button>

View File

@@ -124,20 +124,16 @@ const items = computed<DescriptionsProps['items']>(() => {
}, },
{ label: '创建时间', content: currentUser.value.createTime }, { label: '创建时间', content: currentUser.value.createTime },
{ label: '上次登录IP', content: currentUser.value.loginIp || '-' }, { label: '上次登录IP', content: currentUser.value.loginIp || '-' },
{ label: '上次登录时间', content: currentUser.value.loginDate || '-' },
{ {
label: '上次登录时间', label: '上次登录时间',
content: ( content: (
<> <>
<span>{currentUser.value.loginDate ?? '-'}</span> <span>{currentUser.value.loginDate ?? '-'}</span>
<Tag {diffLoginTime.value && (
bordered={false} <Tag class="ml-2" color="processing">
class="ml-2" {diffLoginTime.value}
color="processing" </Tag>
v-if="diffLoginTime" )}
>
{diffLoginTime}
</Tag>
</> </>
), ),
}, },