🎈 perf: 更新用户主页

This commit is contained in:
Litrix2 2024-12-21 23:22:02 +08:00
parent 91e6327760
commit 47952a774e

View File

@ -1,100 +1,66 @@
<template>
<el-main>
<template v-if="userInfo !== undefined">
<div class="banner">
<div class="banner-inner">
<el-avatar :size="60"></el-avatar>
<div>
<div class="username">{{ userInfo.name }}</div>
<el-main
v-loading="loading"
element-loading-text="正在加载"
class="page-main !flex flex-col items-center gap-10px"
:class="{ 'justify-center': !loading && !userInfo }"
>
<template v-if="!loading">
<template v-if="userInfo">
<el-card class="banner outer">
<el-avatar :size="80"></el-avatar>
<div class="flex flex-col gap-10px">
<h4>{{ userInfo.name }}</h4>
</div>
</el-card>
<div class="outer flex gap-10px">
<el-card class="w-200px">ss</el-card>
<el-card class="flex-1">ss</el-card>
</div>
</div>
</template>
<template v-else>
<div class="font-bold text-30px">无法获取用户信息</div>
<el-button type="primary" @click="loadUserInfo">刷新</el-button>
</template>
</template>
<template v-else></template>
</el-main>
</template>
<style lang="scss" scoped>
.loading-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
.page-main {
--el-main-padding: 30px 0;
}
.banner {
position: relative;
height: 190px;
// background-image: url('@/assets/banner.jpg');
background-size: cover;
.el-card {
transition: none;
}
.banner-inner {
position: absolute;
bottom: 10px;
padding: 0 20px;
box-sizing: border-box;
display: flex;
width: 100%;
.outer {
@apply h-120px max-lg-w-700px lg-w-950px;
}
.el-avatar {
margin-right: 10px;
}
.username {
font-size: 30px;
line-height: 60px;
font-weight: bold;
color: white;
:deep(.banner) {
.el-card__body {
@apply flex gap-20px;
}
}
</style>
<script lang="ts" setup>
import axiosInstance from '@/api';
import { type UserInfo, userInfoResponseSchema } from '@/schemas';
import { getUserInfo } from '@/api';
import { type UserInfo } from '@/schemas';
import { useMediaStore } from '@/stores/media';
import { useUserStore } from '@/stores/user';
import { computed, onBeforeMount, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import { storeToRefs } from 'pinia';
import { onMounted, ref } from 'vue';
const { lgLess, lgOnly } = storeToRefs(useMediaStore());
const userStore = useUserStore();
const initialized = ref(false);
const loading = ref(true);
const userInfo = ref<UserInfo>();
const isSelf = computed(() =>
userStore.userInfo === null ? false : userStore.userInfo.id === userInfo.value?.id,
);
const route = useRoute();
const id = route.params.id as string | undefined;
const avatar = ref<string>();
async function getAvatar(sha1: string) {
const avatarResp = await axiosInstance.get(`/api/user/avatar${sha1}`);
}
watch(
() => userStore.userInfo,
(info) => {
userInfo.value = info ?? undefined;
},
);
onBeforeMount(async () => {
if (id == undefined) {
userInfo.value = userStore.userInfo!;
initialized.value = true;
} else {
try {
const userInfoResponse = userInfoResponseSchema.parse(
(await axiosInstance.get(`/api/user/info/${id}`)).data,
);
if (userInfoResponse.type === 'error') {
return;
}
userInfo.value = userInfoResponse.data;
if (!userInfo.value.avatar) {
/* empty */
}
} catch (e) {
/* empty */
} finally {
initialized.value = true;
}
async function loadUserInfo() {
loading.value = true;
try {
const resp = await getUserInfo(true);
if (!resp) return;
userInfo.value = resp.data;
} finally {
loading.value = false;
}
});
}
onMounted(loadUserInfo);
</script>