hookehuyr

feat(profile): 重构个人中心页面布局和功能

- 简化用户信息展示,移除冗余字段
- 重新设计统计数据和快捷操作区域
- 优化菜单项结构和导航功能
- 更新页面样式和交互体验
/*
* @Date: 2025-07-01 17:55:08
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-07-02 14:44:50
* @FilePath: /jgdl/src/pages/profile/index.config.js
* @Description: 文件描述
*/
export default {
navigationBarTitleText: '首页'
navigationBarTitleText: '我的'
}
......
<template>
<view class="profile-page">
<!-- 用户信息卡片 -->
<view class="user-card">
<view class="user-info">
<image :src="userInfo.avatar" class="user-avatar" mode="aspectFill" />
<view class="user-details">
<text class="user-name">{{ userInfo.name }}</text>
<text class="user-school">{{ userInfo.school }}</text>
<view class="user-stats">
<text class="stat-item">信用分: {{ userInfo.creditScore }}</text>
<text class="stat-item">成交: {{ userInfo.dealCount }}笔</text>
</view>
<!-- User Profile Section -->
<view class="user-profile-section">
<image :src="userInfo.avatar" class="user-avatar" mode="aspectFill" />
<text class="user-name">{{ userInfo.name }}</text>
<text class="user-phone">{{ userInfo.phone }}</text>
<nut-button class="edit-profile-btn" @click="onEditProfile">
编辑资料
</nut-button>
<!-- Stats Row -->
<view class="stats-row">
<view class="stat-item">
<text class="stat-number">{{ userStats.following }}</text>
<text class="stat-label">关注</text>
</view>
</view>
<view class="edit-btn" @click="onEditProfile">
<Edit size="20" color="#f97316" />
</view>
</view>
<!-- 我的车辆 -->
<view class="section">
<view class="section-header">
<text class="section-title">我的车辆</text>
</view>
<view class="vehicle-stats">
<view class="stat-card" @click="onMyVehicles('selling')">
<text class="stat-number">{{ vehicleStats.selling }}</text>
<text class="stat-label">在售</text>
</view>
<view class="stat-card" @click="onMyVehicles('sold')">
<text class="stat-number">{{ vehicleStats.sold }}</text>
<text class="stat-label">已售</text>
<view class="stat-item" @click="onOrderManagement">
<text class="stat-number">{{ userStats.orders }}</text>
<text class="stat-label">订单</text>
</view>
<view class="stat-card" @click="onMyFavorites">
<text class="stat-number">{{ vehicleStats.favorites }}</text>
<text class="stat-label">收藏</text>
<view class="stat-item">
<text class="stat-number">{{ userStats.followers }}</text>
<text class="stat-label">被关注</text>
</view>
</view>
</view>
<!-- 功能菜单 -->
<view class="menu-section">
<view class="menu-item" @click="onOrderManagement">
<view class="menu-icon">
<Cart size="20" color="#f97316" />
</view>
<text class="menu-text">订单管理</text>
<Right size="16" color="#9ca3af" />
<!-- Quick Actions -->
<view class="quick-actions">
<view class="action-item" @click="onMyFavorites">
<Heart size="22" color="#6b7280" />
<text class="action-text">我的关注</text>
</view>
<view class="menu-item" @click="onCertification">
<view class="menu-icon">
<Service size="20" color="#f97316" />
</view>
<text class="menu-text">车辆认证</text>
<view class="certification-badge">
<text class="badge-text">{{ userInfo.isCertified ? '已认证' : '未认证' }}</text>
</view>
<Right size="16" color="#9ca3af" />
</view>
<view class="menu-item" @click="onWallet">
<view class="menu-icon">
<Shop size="20" color="#f97316" />
</view>
<text class="menu-text">我的钱包</text>
<text class="wallet-balance">¥{{ userInfo.balance }}</text>
<Right size="16" color="#9ca3af" />
</view>
<view class="menu-item" @click="onAddress">
<view class="menu-icon">
<Location size="20" color="#f97316" />
</view>
<text class="menu-text">收货地址</text>
<Right size="16" color="#9ca3af" />
<view class="action-item" @click="onOrderManagement">
<Clock size="22" color="#6b7280" />
<text class="action-text">我的订单</text>
</view>
</view>
<!-- 服务菜单 -->
<!-- Menu Items -->
<view class="menu-section">
<view class="menu-item" @click="onCustomerService">
<view class="menu-icon">
<Voice size="20" color="#f97316" />
</view>
<text class="menu-text">客服中心</text>
<Right size="16" color="#9ca3af" />
<view class="menu-item" @click="onMessages">
<Notice size="20" color="#6b7280" />
<text class="menu-text">我的消息</text>
<Right size="18" color="#9ca3af" />
</view>
<view class="menu-item" @click="onMySoldVehicles">
<Cart size="20" color="#6b7280" />
<text class="menu-text">我卖的车</text>
<Right size="18" color="#9ca3af" />
</view>
<view class="menu-item" @click="onFeedback">
<view class="menu-icon">
<Message size="20" color="#f97316" />
</view>
<Message size="20" color="#6b7280" />
<text class="menu-text">意见反馈</text>
<Right size="16" color="#9ca3af" />
<Right size="18" color="#9ca3af" />
</view>
<view class="menu-item" @click="onAbout">
<view class="menu-icon">
<Tips size="20" color="#f97316" />
</view>
<text class="menu-text">关于我们</text>
<Right size="16" color="#9ca3af" />
<view class="menu-item" @click="onHelpCenter">
<Tips size="20" color="#6b7280" />
<text class="menu-text">帮助中心</text>
<Right size="18" color="#9ca3af" />
</view>
</view>
<!-- 设置菜单 -->
<view class="menu-section">
<view class="menu-item" @click="onSettings">
<view class="menu-icon">
<Setting size="20" color="#f97316" />
</view>
<Setting size="20" color="#6b7280" />
<text class="menu-text">设置</text>
<Right size="16" color="#9ca3af" />
<Right size="18" color="#9ca3af" />
</view>
</view>
<!-- 退出登录 -->
<view class="logout-section">
<button class="logout-btn" @click="onLogout">退出登录</button>
</view>
<!-- 自定义TabBar -->
<TabBar />
</view>
......@@ -128,9 +78,8 @@
<script setup>
import { ref } from 'vue'
import {
Edit, Right, Cart, Service, Shop, Location,
Voice, Message, Tips, Setting
import {
Heart, Clock, Notice, Cart, Message, Tips, Setting, Right
} from '@nutui/icons-vue-taro'
import Taro from '@tarojs/taro'
import TabBar from '@/components/TabBar.vue'
......@@ -138,19 +87,15 @@ import TabBar from '@/components/TabBar.vue'
// 用户信息
const userInfo = ref({
name: '张同学',
school: '清华大学',
avatar: 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=100&h=100&fit=crop&crop=face',
creditScore: 95,
dealCount: 12,
isCertified: true,
balance: 1580.50
phone: '138****8888',
avatar: 'https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=100&h=100&fit=crop&crop=face'
})
// 车辆统计
const vehicleStats = ref({
selling: 3,
sold: 8,
favorites: 15
// 用户统计
const userStats = ref({
following: 12,
orders: 8,
followers: 24
})
/**
......@@ -163,17 +108,7 @@ const onEditProfile = () => {
}
/**
* 我的车辆
* @param {string} type - 车辆类型
*/
const onMyVehicles = (type) => {
Taro.navigateTo({
url: `/pages/my-vehicles/index?type=${type}`
})
}
/**
* 我的收藏
* 我的关注
*/
const onMyFavorites = () => {
Taro.navigateTo({
......@@ -191,62 +126,29 @@ const onOrderManagement = () => {
}
/**
* 车辆认证
*/
const onCertification = () => {
if (userInfo.value.isCertified) {
Taro.navigateTo({
url: '/pages/certification-status/index'
})
} else {
Taro.navigateTo({
url: '/pages/certification-apply/index'
})
}
}
/**
* 我的钱包
* 我的消息
*/
const onWallet = () => {
const onMessages = () => {
Taro.navigateTo({
url: '/pages/wallet/index'
url: '/pages/messages/index'
})
}
/**
* 收货地址
* 我卖的车
*/
const onAddress = () => {
const onMySoldVehicles = () => {
Taro.navigateTo({
url: '/pages/address/index'
url: '/pages/my-sold-vehicles/index'
})
}
/**
* 客服中心
* 帮助中心
*/
const onCustomerService = () => {
Taro.showActionSheet({
itemList: ['在线客服', '电话客服', '常见问题'],
success: (res) => {
if (res.tapIndex === 0) {
// 在线客服
Taro.navigateTo({
url: '/pages/online-service/index'
})
} else if (res.tapIndex === 1) {
// 电话客服
Taro.makePhoneCall({
phoneNumber: '400-123-4567'
})
} else if (res.tapIndex === 2) {
// 常见问题
Taro.navigateTo({
url: '/pages/faq/index'
})
}
}
const onHelpCenter = () => {
Taro.navigateTo({
url: '/pages/help-center/index'
})
}
......@@ -260,15 +162,6 @@ const onFeedback = () => {
}
/**
* 关于我们
*/
const onAbout = () => {
Taro.navigateTo({
url: '/pages/about/index'
})
}
/**
* 设置
*/
const onSettings = () => {
......@@ -276,241 +169,134 @@ const onSettings = () => {
url: '/pages/settings/index'
})
}
/**
* 退出登录
*/
const onLogout = () => {
Taro.showModal({
title: '确认退出',
content: '确定要退出登录吗?',
success: (res) => {
if (res.confirm) {
// 清除用户数据
Taro.clearStorageSync()
// 跳转到登录页
Taro.redirectTo({
url: '/pages/auth/index'
})
Taro.showToast({
title: '已退出登录',
icon: 'success'
})
}
}
})
}
</script>
<style lang="less">
.profile-page {
min-height: 100vh;
background-color: #f9fafb;
padding-bottom: 100px;
background-color: #f8fafc;
padding-bottom: 240rpx;
}
.user-card {
background: linear-gradient(135deg, #f97316 0%, #ea580c 100%);
padding: 24px 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.header {
background: #fb923c;
padding: 64rpx 0 32rpx;
position: relative;
.user-info {
display: flex;
align-items: center;
flex: 1;
}
.header-content {
padding: 0 48rpx;
display: flex;
justify-content: space-between;
align-items: center;
.user-avatar {
width: 64px;
height: 64px;
border-radius: 50%;
object-fit: cover;
border: 3px solid rgba(255, 255, 255, 0.3);
margin-right: 16px;
}
.user-details {
flex: 1;
}
.user-name {
font-size: 20px;
font-weight: 600;
color: #ffffff;
display: block;
margin-bottom: 4px;
}
.user-school {
font-size: 14px;
color: rgba(255, 255, 255, 0.8);
display: block;
margin-bottom: 8px;
}
.user-stats {
display: flex;
gap: 16px;
}
.stat-item {
font-size: 12px;
color: rgba(255, 255, 255, 0.9);
background-color: rgba(255, 255, 255, 0.2);
padding: 4px 8px;
border-radius: 12px;
}
.edit-btn {
width: 40px;
height: 40px;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
}
.edit-btn:active {
transform: scale(0.95);
background-color: rgba(255, 255, 255, 0.3);
}
.section {
background-color: #ffffff;
margin: 12px 16px;
border-radius: 12px;
padding: 20px;
}
.section-header {
margin-bottom: 16px;
}
.section-title {
font-size: 18px;
font-weight: 600;
color: #111827;
display: block;
}
.vehicle-stats {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
.header-title {
font-size: 40rpx;
font-weight: 700;
color: white;
}
}
}
.stat-card {
.user-profile-section {
background: white;
padding: 64rpx 48rpx;
margin-bottom: 32rpx;
text-align: center;
padding: 16px 8px;
background-color: #fef7ed;
border-radius: 8px;
border: 1px solid #fed7aa;
transition: all 0.2s;
}
.stat-card:active {
transform: scale(0.95);
background-color: #fef3e2;
}
.user-avatar {
width: 160rpx;
height: 160rpx;
border-radius: 80rpx;
margin-bottom: 32rpx;
}
.stat-number {
font-size: 24px;
font-weight: 700;
color: #f97316;
display: block;
margin-bottom: 4px;
}
.user-name {
font-size: 40rpx;
font-weight: 600;
color: #1e293b;
margin-bottom: 8rpx;
display: block;
}
.stat-label {
font-size: 14px;
color: #6b7280;
display: block;
}
.user-phone {
font-size: 28rpx;
color: #64748b;
margin-bottom: 40rpx;
display: block;
}
.menu-section {
background-color: #ffffff;
margin: 12px 16px;
border-radius: 12px;
overflow: hidden;
}
.edit-profile-btn {
background-color: #f1f5f9;
color: #475569;
border: none;
border-radius: 40rpx;
padding: 16rpx 48rpx;
font-size: 28rpx;
margin-bottom: 48rpx;
}
.menu-item {
display: flex;
align-items: center;
padding: 16px 20px;
border-bottom: 1px solid #f3f4f6;
transition: background-color 0.2s;
}
.stats-row {
display: flex;
justify-content: space-around;
.menu-item:last-child {
border-bottom: none;
}
.stat-item {
text-align: center;
.menu-item:active {
background-color: #f9fafb;
}
.stat-number {
font-size: 36rpx;
font-weight: 600;
color: #1e293b;
display: block;
margin-bottom: 8rpx;
}
.menu-icon {
width: 40px;
height: 40px;
background-color: #fef7ed;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 12px;
.stat-label {
font-size: 24rpx;
color: #64748b;
}
}
}
}
.menu-text {
flex: 1;
font-size: 16px;
color: #374151;
}
.quick-actions {
background: white;
padding: 40rpx 48rpx;
margin-bottom: 32rpx;
display: flex;
justify-content: space-around;
.certification-badge {
margin-right: 8px;
}
.action-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 16rpx;
.badge-text {
font-size: 12px;
color: #059669;
background-color: #d1fae5;
padding: 4px 8px;
border-radius: 12px;
.action-text {
font-size: 24rpx;
color: #64748b;
}
}
}
.wallet-balance {
font-size: 16px;
font-weight: 600;
color: #f97316;
margin-right: 8px;
}
.menu-section {
background: white;
.logout-section {
margin: 24px 16px;
}
.menu-item {
display: flex;
align-items: center;
padding: 32rpx 48rpx;
border-bottom: 1px solid #f1f5f9;
gap: 32rpx;
.logout-btn {
width: 100%;
padding: 16px;
background-color: #ffffff;
border: 1px solid #f87171;
border-radius: 12px;
color: #ef4444;
font-size: 16px;
font-weight: 500;
transition: all 0.2s;
}
&:last-child {
border-bottom: none;
}
.logout-btn:active {
background-color: #fef2f2;
transform: scale(0.98);
.menu-text {
flex: 1;
font-size: 32rpx;
color: #1e293b;
}
}
}
</style>
\ No newline at end of file
</style>
......