Files
smt/pages/profile/index.vue
T

284 lines
6.0 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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="page">
<view class="user-section">
<view class="avatar-wrapper">
<image class="avatar" :src="userAvatar" mode="aspectFill"></image>
<view class="avatar-edit">📷</view>
</view>
<text class="user-name">{{ userName }}</text>
<view class="goal-badge">
<text>目标{{ goalDate }} 戒烟</text>
<text class="goal-icon">🎯</text>
</view>
<text class="streak-text">已连续戒烟 {{ streakDays }} 🔥</text>
</view>
<view class="section">
<text class="section-title">我的进程</text>
<view class="menu-list">
<view class="menu-item" @tap="goPage('goal')">
<view class="menu-icon menu-icon-green">🎯</view>
<view class="menu-content">
<text class="menu-label">目标设定</text>
<text class="menu-desc">调整每日限额与戒烟日期</text>
</view>
<text class="menu-arrow"></text>
</view>
<view class="menu-item" @tap="goPage('ai-plan')">
<view class="menu-icon menu-icon-blue">🤖</view>
<view class="menu-content">
<text class="menu-label">AI 计划调整</text>
<text class="menu-desc">个性化辅导风格</text>
</view>
<text class="menu-arrow"></text>
</view>
</view>
</view>
<view class="section">
<text class="section-title">偏好设置</text>
<view class="menu-list">
<view class="menu-item" @tap="goPage('notification')">
<view class="menu-icon menu-icon-orange">🔔</view>
<view class="menu-content">
<text class="menu-label">通知设置</text>
</view>
<text class="menu-arrow"></text>
</view>
<view class="menu-item" @tap="goPage('vip')">
<view class="menu-icon menu-icon-yellow">💎</view>
<view class="menu-content">
<text class="menu-label">解锁会员</text>
<view class="pro-badge">PRO</view>
</view>
<text class="menu-arrow"></text>
</view>
</view>
</view>
<view class="section">
<text class="section-title">通用</text>
<view class="menu-list">
<view class="menu-item" @tap="goPage('settings')">
<view class="menu-icon menu-icon-gray"></view>
<view class="menu-content">
<text class="menu-label">基础设置</text>
</view>
<text class="menu-arrow"></text>
</view>
<view class="menu-item" @tap="goPage('privacy')">
<view class="menu-icon menu-icon-gray">🔒</view>
<view class="menu-content">
<text class="menu-label">隐私与数据</text>
</view>
<text class="menu-arrow"></text>
</view>
</view>
</view>
<view class="logout-btn" @tap="logout">
<text class="logout-text">退出登录</text>
</view>
<text class="version">版本 1.0.0</text>
</view>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue'
import { useUserStore } from '@/stores/user'
import { useLogin } from '@/hooks/useLogin'
const userStore = useUserStore()
const { waitForLogin } = useLogin()
const userName = computed(() => userStore.user?.nickname || 'Alex Doe')
const userAvatar = computed(() => userStore.user?.avatar_url || '/static/images/default-avatar.png')
const goalDate = ref('12月1日')
const streakDays = ref(12)
function goPage(page) {
uni.showToast({ title: '功能开发中', icon: 'none' })
}
function logout() {
uni.showModal({
title: '确认退出',
content: '确定要退出登录吗?',
success: (res) => {
if (res.confirm) {
userStore.logout()
uni.reLaunch({ url: '/pages/index/index' })
}
}
})
}
onMounted(async () => {
await waitForLogin()
})
</script>
<style scoped>
.page {
min-height: 100vh;
background-color: #0D1F17;
padding: 32rpx;
padding-bottom: 120rpx;
box-sizing: border-box;
}
.user-section {
display: flex;
flex-direction: column;
align-items: center;
padding: 48rpx 0;
}
.avatar-wrapper {
position: relative;
margin-bottom: 24rpx;
}
.avatar {
width: 160rpx;
height: 160rpx;
border-radius: 50%;
border: 6rpx solid #4ADE80;
background-color: #1A3325;
}
.avatar-edit {
position: absolute;
right: 0;
bottom: 0;
width: 48rpx;
height: 48rpx;
background-color: #4ADE80;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 24rpx;
}
.user-name {
font-size: 40rpx;
font-weight: 700;
color: #FFFFFF;
margin-bottom: 16rpx;
}
.goal-badge {
display: flex;
align-items: center;
gap: 8rpx;
background-color: #EF4444;
color: #FFFFFF;
padding: 12rpx 24rpx;
border-radius: 32rpx;
font-size: 24rpx;
margin-bottom: 12rpx;
}
.goal-icon { font-size: 24rpx; }
.streak-text {
font-size: 26rpx;
color: #9CA3AF;
}
.section { margin-bottom: 32rpx; }
.section-title {
font-size: 26rpx;
color: #6B7280;
margin-bottom: 16rpx;
display: block;
}
.menu-list {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.menu-item {
display: flex;
align-items: center;
gap: 24rpx;
background-color: #1A3325;
border-radius: 24rpx;
padding: 24rpx;
}
.menu-icon {
width: 64rpx;
height: 64rpx;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
}
.menu-icon-green { background-color: rgba(74, 222, 128, 0.2); }
.menu-icon-blue { background-color: rgba(96, 165, 250, 0.2); }
.menu-icon-orange { background-color: rgba(251, 146, 60, 0.2); }
.menu-icon-yellow { background-color: rgba(251, 191, 36, 0.2); }
.menu-icon-gray { background-color: rgba(107, 114, 128, 0.2); }
.menu-content {
flex: 1;
display: flex;
flex-direction: column;
gap: 4rpx;
}
.menu-label {
font-size: 30rpx;
color: #FFFFFF;
}
.menu-desc {
font-size: 24rpx;
color: #6B7280;
}
.pro-badge {
display: inline-block;
background-color: #4ADE80;
color: #0D1F17;
font-size: 20rpx;
padding: 4rpx 12rpx;
border-radius: 8rpx;
font-weight: 600;
margin-top: 4rpx;
width: fit-content;
}
.menu-arrow {
font-size: 36rpx;
color: #6B7280;
}
.logout-btn {
text-align: center;
padding: 24rpx;
margin-top: 32rpx;
}
.logout-text {
color: #EF4444;
font-size: 30rpx;
}
.version {
display: block;
text-align: center;
font-size: 24rpx;
color: #6B7280;
margin-top: 24rpx;
}
</style>