feat:增加个人中心:20% 支持左侧的个人信息

This commit is contained in:
YunaiV
2025-04-20 08:04:51 +08:00
parent 1662598488
commit 57c8d88bae
10 changed files with 260 additions and 12 deletions

View File

@@ -0,0 +1,58 @@
<script setup lang="ts">
import type { SystemUserProfileApi } from '#/api/system/user/profile';
import { onMounted, ref } from 'vue';
import { getUserProfile } from '#/api/system/user/profile';
import { useAuthStore } from '#/store';
import { Card, Tabs } from 'ant-design-vue';
import { Page } from '@vben/common-ui';
import ProfileUser from './modules/profile-user.vue';
const authStore = useAuthStore();
const activeName = ref('basicInfo');
/** 加载个人信息 */
const profile = ref<SystemUserProfileApi.UserProfileRespVO>();
async function loadProfile() {
profile.value = await getUserProfile();
}
/** 刷新个人信息 */
async function refreshProfile() {
// 加载个人信息
await loadProfile();
// 更新 store
await authStore.fetchUserInfo();
}
/** 初始化 */
onMounted(loadProfile);
</script>
<template>
<Page auto-content-height>
<div class="flex">
<!-- 左侧 个人信息 -->
<Card class="w-2/5" title="个人信息">
<ProfileUser :profile="profile" @success="refreshProfile" />
</Card>
<!-- 右侧 标签页 -->
<Card class="ml-3 w-3/5">
<Tabs v-model:active-key="activeName" class="-mt-4">
<Tabs.TabPane key="basicInfo" tab="基本信息">
<!-- <BaseSetting :profile="profile" /> -->
</Tabs.TabPane>
<Tabs.TabPane key="resetPwd" tab="修改密码">
<!-- <ResetPwd /> -->
</Tabs.TabPane>
<Tabs.TabPane key="userSocial" tab="社交信息">
<!-- <UserSocial :profile="profile" /> -->
</Tabs.TabPane>
</Tabs>
</Card>
</div>
</Page>
</template>

View File

@@ -0,0 +1,116 @@
<script setup lang="ts">
import type { SystemUserProfileApi } from '#/api/system/user/profile';
import { Descriptions, DescriptionsItem, Tooltip } from 'ant-design-vue';
import { IconifyIcon } from '@vben/icons';
import { computed } from 'vue';
import { preferences } from '@vben/preferences';
import { updateUserAvatar } from '#/api/system/user/profile';
import { formatDateTime } from '@vben/utils';
// import { CropperAvatar } from '#/components/cropper';
const props = defineProps<{ profile?: SystemUserProfileApi.UserProfileRespVO }>();
defineEmits<{
// 头像上传完毕
success: [];
}>();
const avatar = computed(
() => props.profile?.avatar || preferences.app.defaultAvatar,
);
</script>
<template>
<div v-if="profile">
<div class="flex flex-col items-center gap-[20px]">
<Tooltip title="点击上传头像">
<!-- TODO 芋艿待实现 -->
<CropperAvatar
:show-btn="false"
:upload-api="updateUserAvatar"
:value="avatar"
width="120"
@change=""
/>
</Tooltip>
</div>
<div>
<Descriptions :column="2">
<DescriptionsItem>
<template #label>
<div class="flex items-center">
<IconifyIcon icon="ant-design:user-outlined" class="mr-1" />
用户账号
</div>
</template>
{{ profile.username }}
</DescriptionsItem>
<DescriptionsItem>
<template #label>
<div class="flex items-center">
<IconifyIcon icon="ant-design:user-switch-outlined" class="mr-1" />
所属角色
</div>
</template>
{{ profile.roles.map(role => role.name).join(',') }}
</DescriptionsItem>
<DescriptionsItem>
<template #label>
<div class="flex items-center">
<IconifyIcon icon="ant-design:phone-outlined" class="mr-1" />
手机号码
</div>
</template>
{{ profile.mobile }}
</DescriptionsItem>
<DescriptionsItem>
<template #label>
<div class="flex items-center">
<IconifyIcon icon="ant-design:mail-outlined" class="mr-1" />
用户邮箱
</div>
</template>
{{ profile.email }}
</DescriptionsItem>
<DescriptionsItem>
<template #label>
<div class="flex items-center">
<IconifyIcon icon="ant-design:team-outlined" class="mr-1" />
所属部门
</div>
</template>
{{ profile.dept?.name }}
</DescriptionsItem>
<DescriptionsItem>
<template #label>
<div class="flex items-center">
<IconifyIcon icon="ant-design:usergroup-add-outlined" class="mr-1" />
所属岗位
</div>
</template>
{{ profile.posts.map(post => post.name).join(',') }}
</DescriptionsItem>
<DescriptionsItem>
<template #label>
<div class="flex items-center">
<IconifyIcon icon="ant-design:clock-circle-outlined" class="mr-1" />
创建时间
</div>
</template>
{{ formatDateTime(profile.createTime) }}
</DescriptionsItem>
<DescriptionsItem>
<template #label>
<div class="flex items-center">
<IconifyIcon icon="ant-design:login-outlined" class="mr-1" />
登录时间
</div>
</template>
{{ formatDateTime(profile.loginDate) }}
</DescriptionsItem>
</Descriptions>
</div>
</div>
</template>