Files
mp-pilates/packages/app/src/pages/profile/index.vue
2026-04-06 21:22:18 +08:00

144 lines
3.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="profile-page">
<!-- Custom nav bar (transparent, blends with UserCard gradient) -->
<CustomNavBar title="我的" transparent />
<!-- User card -->
<UserCard :logged-in="loggedIn" :has-profile="hasProfile" :user="user" :stats="stats" :memberships="memberships"
:loading="loginLoading" :nav-bar-height="navBarHeight" @login="handleLogin" />
<!-- Menu section: always visible -->
<ProfileMenu :is-admin="isAdmin" :require-auth="loggedIn" @clear-cache="handleClearCache" @about="handleAbout"
@require-login="handleLogin" />
<!-- 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, onMounted } from 'vue'
import { onShow, onShareAppMessage, onShareTimeline } from '@dcloudio/uni-app'
import { storeToRefs } from 'pinia'
import { useUserStore } from '../../stores/user'
import { getSystemLayout } from '../../utils/system'
import UserCard from '../../components/UserCard.vue'
import ProfileMenu from '../../components/ProfileMenu.vue'
import CustomNavBar from '../../components/CustomNavBar.vue'
const userStore = useUserStore()
const { loggedIn, hasProfile, user, stats, memberships, isAdmin } = storeToRefs(userStore)
const loginLoading = ref(false)
const navBarHeight = ref(64)
// ─── 微信分享 ───────────────────────────────────────────────
onShareAppMessage(() => {
return {
title: '我的普拉提会所,记录每一次进步',
path: '/pages/profile/index',
imageUrl: '',
}
})
onShareTimeline(() => {
return {
title: '我的普拉提会所,记录每一次进步',
query: '',
}
})
onMounted(() => {
navBarHeight.value = getSystemLayout().navBarHeight
})
onShow(async () => {
if (loggedIn.value) {
await Promise.all([
userStore.fetchProfile(),
userStore.fetchStats(),
userStore.fetchMemberships(),
])
}
})
async function handleLogin() {
if (loginLoading.value) return
loginLoading.value = true
try {
const { isNewUser } = await userStore.loginWithSetup()
if (!isNewUser) {
await userStore.fetchStats()
}
} catch {
uni.showToast({ title: '登录失败,请重试', icon: 'none' })
} finally {
loginLoading.value = false
}
}
function handleLogout() {
uni.showModal({
title: '退出登录',
content: '确定要退出登录吗?',
confirmText: '退出',
confirmColor: '#ff4d4f',
success(res) {
if (res.confirm) {
userStore.logout()
}
},
})
}
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>
.profile-page {
min-height: 100vh;
&__logout-wrap {
margin: $spacing-xl $spacing-lg $spacing-xl;
}
&__logout-btn {
width: 100%;
height: 88rpx;
line-height: 88rpx;
background: $bg-card;
color: $error-color;
font-size: 30rpx;
font-weight: 500;
border: none;
border-radius: $radius-lg;
text-align: center;
&::after {
border: none;
}
}
}
</style>