- 新增地址类型定义,增强前端地址数据结构 - 新增地址编辑页面,支持地址智能识别和定位选点功能 - 地址编辑支持省市区选择及默认地址设置 - 新增地址列表页面,支持地址展示、删除、编辑和选择功能 - 实现售后申请页面,支持选择售后类型和退款原因 - 售后申请支持商品选择、退款金额计算和凭证上传 - 新增售后详情页面,支持售后状态展示及申请取消 - 优化页面加载和用户交互体验,增加错误提示和权限处理
234 lines
9.3 KiB
TypeScript
234 lines
9.3 KiB
TypeScript
import React from 'react'
|
|
import { View, Text, Image, ScrollView } from '@tarojs/components'
|
|
import Taro from '@tarojs/taro'
|
|
import { useUser } from '@/hooks/useUser'
|
|
import MemberBadge from '@/components/business/MemberBadge'
|
|
|
|
const UserPage: React.FC = () => {
|
|
const { user, isLoggedIn } = useUser()
|
|
|
|
const menuItems = [
|
|
{ icon: '📦', label: '我的订单', url: '/pages/order/list' },
|
|
{ icon: '📅', label: '预约订单', url: '/pages/booking/list' },
|
|
{ icon: '🏆', label: '赛事活动', url: '/pages/event/my/index' },
|
|
{ icon: '🎫', label: '优惠券', url: '/pages/user/coupon-list' },
|
|
{ icon: '💰', label: '我的钱包', url: '/pages/user/wallet' },
|
|
{ icon: '📍', label: '收货地址', url: '/pages/user/address-list' },
|
|
{ icon: '⭐', label: '积分明细', url: '/pages/user/points-record' },
|
|
{ icon: '🔔', label: '消息通知', url: '/pages/index/notification' },
|
|
{ icon: '⚙️', label: '设置', url: '/pages/user/setting' },
|
|
]
|
|
|
|
const handleLogin = () => {
|
|
if (!isLoggedIn) {
|
|
Taro.navigateTo({ url: '/passport/login' })
|
|
}
|
|
}
|
|
|
|
return (
|
|
<View className='min-h-screen bg-gray-100 flex flex-col'>
|
|
<ScrollView scrollY className='flex-1'>
|
|
{/* 顶部渐变背景区域 */}
|
|
<View className='relative'>
|
|
{/* 渐变背景 — 绿色系 */}
|
|
<View
|
|
className='absolute inset-0'
|
|
style={{
|
|
background: 'linear-gradient(135deg, #0d9488 0%, #059669 50%, #10b981 100%)',
|
|
}}
|
|
/>
|
|
{/* 装饰圆形 */}
|
|
<View
|
|
className='absolute'
|
|
style={{
|
|
width: '240px',
|
|
height: '240px',
|
|
borderRadius: '120px',
|
|
background: 'rgba(255, 255, 255, 0.08)',
|
|
top: '-100px',
|
|
right: '-80px',
|
|
}}
|
|
/>
|
|
<View
|
|
className='absolute'
|
|
style={{
|
|
width: '180px',
|
|
height: '180px',
|
|
borderRadius: '90px',
|
|
background: 'rgba(255, 255, 255, 0.06)',
|
|
top: '-60px',
|
|
left: '-60px',
|
|
}}
|
|
/>
|
|
<View
|
|
className='absolute'
|
|
style={{
|
|
width: '120px',
|
|
height: '120px',
|
|
borderRadius: '60px',
|
|
background: 'rgba(255, 255, 255, 0.05)',
|
|
bottom: '20px',
|
|
right: '-30px',
|
|
}}
|
|
/>
|
|
|
|
{/* 用户信息卡片 */}
|
|
<View className='relative mx-3 mt-3 p-4 rounded-2xl' style={{
|
|
background: 'rgba(255, 255, 255, 0.15)',
|
|
backdropFilter: 'blur(10px)',
|
|
border: '1px solid rgba(255, 255, 255, 0.2)',
|
|
}}>
|
|
<View className='flex items-center gap-4' onClick={handleLogin}>
|
|
{/* 头像区域 */}
|
|
<View className='relative'>
|
|
{isLoggedIn && user?.avatar ? (
|
|
<Image
|
|
className='w-16 h-16 rounded-full border-3 border-white/30'
|
|
style={{ boxShadow: '0 4px 16px rgba(0, 0, 0, 0.2)' }}
|
|
src={user.avatar}
|
|
mode='aspectFill'
|
|
/>
|
|
) : (
|
|
<View
|
|
className='w-16 h-16 rounded-full border-3 border-white/30 flex items-center justify-center'
|
|
style={{ background: 'rgba(255, 255, 255, 0.25)', boxShadow: '0 4px 16px rgba(0, 0, 0, 0.2)' }}
|
|
>
|
|
<Text className='text-2xl text-white'>👤</Text>
|
|
</View>
|
|
)}
|
|
{/* VIP标识 */}
|
|
{isLoggedIn && user?.memberLevelName && (
|
|
<View
|
|
className='absolute -bottom-1 -right-1 px-1 py-1 rounded text-xs text-white'
|
|
style={{ background: 'linear-gradient(135deg, #fbbf24, #f59e0b)' }}
|
|
>
|
|
VIP
|
|
</View>
|
|
)}
|
|
</View>
|
|
|
|
{/* 用户信息 */}
|
|
<View className='flex-1'>
|
|
<View className='flex items-center gap-2'>
|
|
<Text className='text-lg font-bold text-white'>
|
|
{isLoggedIn ? (user?.nickname || user?.phone || '用户') : '点击登录'}
|
|
</Text>
|
|
{isLoggedIn && user?.memberLevelName && (
|
|
<MemberBadge levelName={user.memberLevelName} />
|
|
)}
|
|
</View>
|
|
{isLoggedIn ? (
|
|
<Text className='text-xs text-white/60 mt-1'>ID: {(user as any)?.id || '暂无'}</Text>
|
|
) : (
|
|
<Text className='text-xs text-white/60 mt-1'>登录后享受更多服务</Text>
|
|
)}
|
|
</View>
|
|
|
|
{/* 箭头 */}
|
|
<View className='w-6 h-6 rounded-full bg-white/20 flex items-center justify-center'>
|
|
<Text className='text-white/80 text-xs'>{'>'}</Text>
|
|
</View>
|
|
</View>
|
|
|
|
{/* 数据概览 — 4列白色文字 */}
|
|
{isLoggedIn && (
|
|
<View
|
|
className='grid grid-cols-4 gap-2 mt-4 pt-4'
|
|
style={{ borderTop: '1px solid rgba(255, 255, 255, 0.2)' }}
|
|
>
|
|
<View
|
|
className='text-center py-2'
|
|
onClick={() => Taro.navigateTo({ url: '/pages/user/wallet' })}
|
|
>
|
|
<Text className='text-xl font-bold text-white'>
|
|
¥{((user as any)?.balance || '0.00')}
|
|
</Text>
|
|
<Text className='text-xs text-white/70 mt-1 block'>余额</Text>
|
|
</View>
|
|
<View
|
|
className='text-center py-2'
|
|
onClick={() => Taro.navigateTo({ url: '/pages/points/index' })}
|
|
>
|
|
<Text className='text-xl font-bold text-white'>
|
|
{(user as any)?.points || 0}
|
|
</Text>
|
|
<Text className='text-xs text-white/70 mt-1 block'>积分</Text>
|
|
</View>
|
|
<View
|
|
className='text-center py-2'
|
|
onClick={() => Taro.navigateTo({ url: '/pages/user/coupon-list' })}
|
|
>
|
|
<Text className='text-xl font-bold text-white'>
|
|
0
|
|
</Text>
|
|
<Text className='text-xs text-white/70 mt-1 block'>优惠券</Text>
|
|
</View>
|
|
<View
|
|
className='text-center py-2'
|
|
onClick={() => Taro.navigateTo({ url: '/pages/order/list' })}
|
|
>
|
|
<Text className='text-xl font-bold text-white'>
|
|
0
|
|
</Text>
|
|
<Text className='text-xs text-white/70 mt-1 block'>订单</Text>
|
|
</View>
|
|
</View>
|
|
)}
|
|
</View>
|
|
|
|
</View>
|
|
|
|
{/* 我的订单快捷入口 */}
|
|
<View className='bg-white rounded-xl mx-3 mt-3 p-4' style={{ boxShadow: '0 2px 8px rgba(0, 0, 0, 0.05)' }}>
|
|
<View className='flex justify-between items-center mb-3'>
|
|
<Text className='text-base font-medium text-gray-800'>我的订单</Text>
|
|
<Text className='text-xs text-gray-400' onClick={() => Taro.navigateTo({ url: '/pages/order/list' })}>
|
|
全部订单 {'>'}
|
|
</Text>
|
|
</View>
|
|
<View className='grid grid-cols-4 gap-2'>
|
|
{[
|
|
{ icon: '💳', label: '待付款', status: 0, color: '#f093fb' },
|
|
{ icon: '📦', label: '待发货', status: 1, color: '#667eea' },
|
|
{ icon: '🚚', label: '待收货', status: 2, color: '#4facfe' },
|
|
{ icon: '✅', label: '已完成', status: 3, color: '#52c41a' },
|
|
].map(item => (
|
|
<View
|
|
key={item.status}
|
|
className='flex flex-col items-center py-2 rounded-lg'
|
|
style={{ background: `${item.color}10` }}
|
|
onClick={() => Taro.navigateTo({ url: `/pages/order/list?tab=${item.status}` })}
|
|
>
|
|
<Text className='text-xl mb-1'>{item.icon}</Text>
|
|
<Text className='text-xs text-gray-600'>{item.label}</Text>
|
|
</View>
|
|
))}
|
|
</View>
|
|
</View>
|
|
{/* 功能菜单 */}
|
|
<View className='bg-white rounded-xl mx-3 mt-3 overflow-hidden' style={{ boxShadow: '0 2px 8px rgba(0, 0, 0, 0.05)' }}>
|
|
{menuItems.map((item, idx) => (
|
|
<View
|
|
key={item.label}
|
|
className={`flex items-center justify-between px-4 py-3 ${
|
|
idx < menuItems.length - 1 ? 'border-b border-gray-50' : ''
|
|
}`}
|
|
onClick={() => Taro.navigateTo({ url: item.url })}
|
|
>
|
|
<View className='flex items-center gap-3'>
|
|
<Text className='text-base'>{item.icon}</Text>
|
|
<Text className='text-sm text-gray-700'>{item.label}</Text>
|
|
</View>
|
|
<Text className='text-gray-300 text-sm'>{'>'}</Text>
|
|
</View>
|
|
))}
|
|
</View>
|
|
{/* 底部安全区域 */}
|
|
<View className='h-20' />
|
|
</ScrollView>
|
|
</View>
|
|
)
|
|
}
|
|
|
|
export default UserPage
|