feat: 完善个人中心

This commit is contained in:
richarjiang
2026-04-04 10:46:20 +08:00
parent 817d5a85c5
commit 2b3b636c54
5 changed files with 258 additions and 176 deletions

View File

@@ -1,46 +1,51 @@
<template>
<view class="profile-page">
<!-- User card: always visible -->
<!-- User card -->
<UserCard
:logged-in="loggedIn"
:user="user"
:stats="stats"
:memberships="memberships"
:loading="loginLoading"
@login="handleLogin"
/>
<!-- Logged-in content -->
<template v-if="loggedIn">
<!-- Training stats: overlaps bottom of UserCard -->
<TrainingStats :stats="stats" />
<!-- Menu section: always visible -->
<ProfileMenu
:is-admin="isAdmin"
:require-auth="loggedIn"
@clear-cache="handleClearCache"
@about="handleAbout"
@require-login="handleLogin"
/>
<!-- Menu section -->
<ProfileMenu :is-admin="isAdmin" />
<!-- Logout button -->
<view class="profile-page__logout-wrap">
<button class="profile-page__logout-btn" @tap="handleLogout">退出登录</button>
</view>
</template>
<!-- Logout button: only when logged in -->
<view v-if="loggedIn" class="profile-page__logout-wrap">
<button class="profile-page__logout-btn" @tap="handleLogout">退出登录</button>
</view>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { storeToRefs } from 'pinia'
import { useUserStore } from '../../stores/user'
import UserCard from '../../components/UserCard.vue'
import TrainingStats from '../../components/TrainingStats.vue'
import ProfileMenu from '../../components/ProfileMenu.vue'
const userStore = useUserStore()
const { loggedIn, user, stats, isAdmin } = userStore
const { loggedIn, user, stats, memberships, isAdmin } = storeToRefs(userStore)
const loginLoading = ref(false)
onShow(async () => {
if (loggedIn) {
await Promise.all([userStore.fetchProfile(), userStore.fetchStats()])
if (loggedIn.value) {
await Promise.all([
userStore.fetchProfile(),
userStore.fetchStats(),
userStore.fetchMemberships(),
])
}
})
@@ -49,8 +54,11 @@ async function handleLogin() {
loginLoading.value = true
try {
await userStore.login()
// After login, fetch stats immediately
await Promise.all([userStore.fetchProfile(), userStore.fetchStats()])
await Promise.all([
userStore.fetchProfile(),
userStore.fetchStats(),
userStore.fetchMemberships(),
])
} catch {
uni.showToast({ title: '登录失败,请重试', icon: 'none' })
} finally {
@@ -71,6 +79,27 @@ function handleLogout() {
},
})
}
function handleClearCache() {
uni.showModal({
title: '清除缓存',
content: '确定要清除本地缓存数据吗?',
success(res) {
if (res.confirm) {
uni.clearStorageSync()
uni.showToast({ title: '缓存已清除', icon: 'success' })
}
},
})
}
function handleAbout() {
uni.showModal({
title: '关于我们',
content: 'Focus Core 普拉提工作室\n版本 1.0.0\n\n专注核心遇见更好的自己',
showCancel: false,
})
}
</script>
<style lang="scss" scoped>
@@ -78,11 +107,8 @@ function handleLogout() {
min-height: 100vh;
background: $bg-page;
// Content area below the dark header card
// UserCard has its own dark bg, content sits on $bg-page
&__logout-wrap {
margin: $spacing-xl $spacing-lg $spacing-lg;
margin: $spacing-xl $spacing-lg $spacing-xl;
}
&__logout-btn {