wz-uniapp/pages/my/my.vue

411 lines
9.1 KiB
Vue

<template>
<view class="profile-page">
<view class="safe-top"></view>
<view class="header">
<text class="header-title">个人中心</text>
<view class="header-actions">
<view class="action-item" @click="onAction('设置')">
<uni-icons type="settings-filled" :size="20" color="#6b7280" />
</view>
<view class="action-item" @click="onAction('通知')">
<uni-icons type="notification-filled" :size="20" color="#6b7280" />
</view>
</view>
</view>
<view class="user-card">
<view class="user-left">
<view class="avatar-wrap">
<view class="avatar">
<uni-icons type="person-filled" :size="44" color="#8ca0be" />
</view>
<view class="verified">
<uni-icons type="medal-filled" :size="12" color="#ffffff" />
</view>
</view>
<view class="user-info">
<text class="user-name">{{ user.name }}</text>
<view class="user-tags">
<text class="tag">{{ user.role }}</text>
<view class="vip-tag">
<uni-icons type="vip-filled" :size="12" color="#4a7c59" />
<text class="vip-text">{{ user.vipStatus }}</text>
</view>
</view>
</view>
</view>
<view class="primary-btn" @click="onAction('激活会员')">立即激活</view>
</view>
<view class="stats-card">
<view class="stat-item" v-for="stat in stats" :key="stat.label">
<text class="stat-value">{{ stat.value }}</text>
<text class="stat-label">{{ stat.label }}</text>
</view>
</view>
<view class="section" v-for="section in sections" :key="section.title">
<text class="section-title">{{ section.title }}</text>
<view class="section-body">
<view class="row" v-for="item in section.items" :key="item.title" @click="onMenuTap(item)">
<view class="row-left">
<view class="row-icon" :style="{ backgroundColor: item.bg }">
<uni-icons :type="item.icon" :size="16" color="#ffffff" />
</view>
<text class="row-title">{{ item.title }}</text>
</view>
<uni-icons type="arrow-right" :size="14" color="#c3cad6" />
</view>
</view>
</view>
<view class="logout-wrap">
<view class="logout-btn" @click="handleLogout">退出登录</view>
<text class="version">Version 2.4.1 (Build 20241021)</text>
</view>
</view>
</template>
<script>
import { STORAGE_KEYS } from '@/common/env';
export default {
data() {
return {
user: {
name: '领航学子',
role: '普通用户',
vipStatus: '未激活会员'
},
stats: [
{ label: '志愿数量', value: '12' },
{ label: '全省排名', value: '342' },
{ label: '录取概率', value: '85%' }
],
sections: [
{
title: '核心服务',
items: [
{ title: '我的志愿表', icon: 'folder-add-filled', bg: '#4a7c59' },
{ title: '我的订单/缴费记录', icon: 'wallet-filled', bg: '#3e8be4' },
{ title: '成绩/排名记录', icon: 'medal-filled', bg: '#f08a24' },
{ title: '打印设置', icon: 'compose', bg: '#7b6fe4' }
]
},
{
title: '更多功能',
items: [
{ title: '激活会员卡', icon: 'vip-filled', bg: '#ff8a33' },
{ title: '商务合作', icon: 'shop-filled', bg: '#4b9ce2' },
{ title: '填报指南/教程', icon: 'compose', bg: '#6e7a8c' },
{ title: '联系老师/客服', icon: 'chatbubble-filled', bg: '#8a5ae0' },
{ title: '关于我们', icon: 'info-filled', bg: '#6b7280', path: '/pages/about/about' }
]
}
]
};
},
onShow() {
const token = uni.getStorageSync(STORAGE_KEYS.TOKEN);
if (!token) {
uni.navigateTo({ url: '/pages/login/login' });
return;
}
const userInfo = uni.getStorageSync(STORAGE_KEYS.USER_INFO) || {};
this.user.name = userInfo.nickName || userInfo.name || this.user.name;
},
methods: {
onAction(label) {
uni.showToast({
title: `${label} 可点击`,
icon: 'none'
});
},
onMenuTap(item) {
if (item.path) {
// #ifdef H5 || APP-PLUS
uni.navigateTo({ url: item.path });
// #endif
// #ifndef H5 || APP-PLUS
uni.showToast({
title: '当前端暂不支持',
icon: 'none'
});
// #endif
return;
}
uni.showToast({
title: `${item.title} 可点击`,
icon: 'none'
});
},
handleLogout() {
uni.showModal({
title: '提示',
content: '确认退出登录吗?',
success: (res) => {
if (!res.confirm) return;
uni.removeStorageSync(STORAGE_KEYS.TOKEN);
uni.removeStorageSync(STORAGE_KEYS.USER_INFO);
uni.showToast({
title: '已退出登录',
icon: 'none'
});
setTimeout(() => {
uni.switchTab({ url: '/pages/index/index' });
}, 300);
}
});
}
}
};
</script>
<style scoped>
.profile-page {
min-height: 100vh;
padding: 0 24rpx 140rpx;
background-color: #fdfaf6;
background-image: radial-gradient(circle at 20% 30%, rgba(74, 124, 89, 0.08) 0%, transparent 55%),
radial-gradient(circle at 80% 70%, rgba(74, 124, 89, 0.05) 0%, transparent 45%);
}
.safe-top {
height: calc(var(--status-bar-height) + 12rpx);
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8rpx 0 16rpx;
}
.header-title {
font-size: 34rpx;
font-weight: 700;
color: #1f2d3d;
}
.header-actions {
display: flex;
align-items: center;
}
.action-item {
width: 56rpx;
height: 56rpx;
border-radius: 50%;
background: #ffffff;
margin-left: 16rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 18rpx rgba(74, 124, 89, 0.1);
}
.user-card {
background: #ffffff;
border-radius: 28rpx;
padding: 24rpx;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 16rpx 32rpx rgba(74, 124, 89, 0.1);
}
.user-left {
display: flex;
align-items: center;
}
.avatar-wrap {
position: relative;
}
.avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
background: #f2f5f1;
display: flex;
align-items: center;
justify-content: center;
border: 4rpx solid rgba(74, 124, 89, 0.12);
}
.verified {
position: absolute;
right: 0;
bottom: 4rpx;
width: 32rpx;
height: 32rpx;
border-radius: 50%;
background: #4a7c59;
display: flex;
align-items: center;
justify-content: center;
border: 3rpx solid #ffffff;
}
.user-info {
margin-left: 20rpx;
}
.user-name {
display: block;
font-size: 30rpx;
font-weight: 700;
color: #243244;
}
.user-tags {
margin-top: 10rpx;
display: flex;
align-items: center;
}
.tag {
padding: 4rpx 12rpx;
background: #f1f5f9;
border-radius: 999rpx;
font-size: 20rpx;
font-weight: 600;
color: #64748b;
margin-right: 12rpx;
}
.vip-tag {
display: flex;
align-items: center;
background: rgba(74, 124, 89, 0.12);
padding: 4rpx 12rpx;
border-radius: 999rpx;
}
.vip-text {
font-size: 20rpx;
color: #4a7c59;
font-weight: 600;
margin-left: 6rpx;
}
.primary-btn {
padding: 12rpx 24rpx;
border-radius: 999rpx;
background: #4a7c59;
color: #ffffff;
font-size: 22rpx;
font-weight: 600;
}
.stats-card {
margin-top: 20rpx;
background: rgba(255, 255, 255, 0.9);
border-radius: 24rpx;
display: flex;
justify-content: space-between;
padding: 20rpx 12rpx;
box-shadow: 0 12rpx 24rpx rgba(74, 124, 89, 0.08);
}
.stat-item {
flex: 1;
text-align: center;
border-right: 1px solid #eef2f7;
}
.stat-item:last-child {
border-right: none;
}
.stat-value {
display: block;
font-size: 30rpx;
font-weight: 700;
color: #4a7c59;
}
.stat-label {
display: block;
margin-top: 6rpx;
font-size: 20rpx;
color: #94a3b8;
}
.section {
margin-top: 28rpx;
}
.section-title {
display: block;
font-size: 22rpx;
font-weight: 700;
color: #94a3b8;
letter-spacing: 2rpx;
margin-bottom: 12rpx;
}
.section-body {
background: #ffffff;
border-radius: 24rpx;
overflow: hidden;
box-shadow: 0 12rpx 24rpx rgba(74, 124, 89, 0.08);
}
.row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 20rpx;
border-bottom: 1px solid #f1f5f9;
}
.row:last-child {
border-bottom: none;
}
.row-left {
display: flex;
align-items: center;
}
.row-icon {
width: 64rpx;
height: 64rpx;
border-radius: 18rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16rpx;
}
.row-title {
font-size: 26rpx;
color: #1f2d3d;
}
.logout-wrap {
margin-top: 24rpx;
text-align: center;
}
.logout-btn {
background: rgba(255, 255, 255, 0.8);
border-radius: 20rpx;
padding: 20rpx 0;
font-size: 26rpx;
font-weight: 700;
color: #f87171;
box-shadow: 0 12rpx 24rpx rgba(74, 124, 89, 0.08);
}
.version {
display: block;
margin-top: 16rpx;
font-size: 20rpx;
color: #94a3b8;
}
</style>