import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../core/router/routes.dart'; import '../../providers/user_providers.dart'; import '../../providers/profile_providers.dart'; import '../../widgets/shimmer_loading.dart'; class ProfilePage extends ConsumerWidget { const ProfilePage({super.key}); // 设计色彩 static const Color _orange = Color(0xFFFF6B00); static const Color _green = Color(0xFF10B981); static const Color _darkText = Color(0xFF1F2937); static const Color _grayText = Color(0xFF6B7280); static const Color _lightGray = Color(0xFF9CA3AF); static const Color _bgGray = Color(0xFFF3F4F6); static const Color _red = Color(0xFFEF4444); @override Widget build(BuildContext context, WidgetRef ref) { final user = ref.watch(userNotifierProvider); final statsAsync = ref.watch(userStatsProvider); final invitationCode = ref.watch(invitationCodeProvider); final isStatsLoading = statsAsync.isLoading; final stats = statsAsync.valueOrNull; return Scaffold( backgroundColor: _bgGray, body: SafeArea( bottom: false, child: RefreshIndicator( onRefresh: () async { ref.invalidate(userStatsProvider); await ref.read(userNotifierProvider.notifier).fetchProfile(); }, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), child: Column( children: [ // 用户头部信息 _buildUserHeader(context, user), const SizedBox(height: 16), // 统计数据行 _buildStatsRow(stats, isStatsLoading), const SizedBox(height: 16), // 邀请码卡片 _buildInvitationCard(context, invitationCode), const SizedBox(height: 16), // 账户设置 _buildAccountSettings(context, user), const SizedBox(height: 16), // 记录入口 _buildRecordsSection(context), const SizedBox(height: 16), // 团队与收益 _buildTeamEarningsSection(context), const SizedBox(height: 16), // 其他设置 _buildOtherSettings(context), const SizedBox(height: 24), // 退出登录 _buildLogoutButton(context, ref), const SizedBox(height: 16), // 版本信息 const Text( 'Version 1.0.0', style: TextStyle( fontSize: 12, color: _lightGray, ), ), const SizedBox(height: 100), ], ), ), ), ), ); } Widget _buildUserHeader(BuildContext context, UserState user) { return Container( padding: const EdgeInsets.all(20), color: Colors.white, child: Row( children: [ // 头像 Container( width: 80, height: 80, decoration: BoxDecoration( shape: BoxShape.circle, gradient: LinearGradient( colors: [_orange.withValues(alpha: 0.8), _orange], begin: Alignment.topLeft, end: Alignment.bottomRight, ), ), child: Center( child: Text( user.nickname?.isNotEmpty == true ? user.nickname!.substring(0, 1).toUpperCase() : (user.realName?.isNotEmpty == true ? user.realName!.substring(0, 1).toUpperCase() : 'U'), style: const TextStyle( fontSize: 36, fontWeight: FontWeight.bold, color: Colors.white, ), ), ), ), const SizedBox(width: 16), // 用户信息 Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( user.realName ?? user.nickname ?? '榴莲用户', style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: _darkText, ), ), const SizedBox(width: 8), // 实名认证徽章 if (user.isKycVerified) Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 2, ), decoration: BoxDecoration( color: _green.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(10), ), child: const Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.verified, size: 12, color: _green), SizedBox(width: 2), Text( '已实名', style: TextStyle( fontSize: 10, fontWeight: FontWeight.w500, color: _green, ), ), ], ), ), ], ), const SizedBox(height: 8), Row( children: [ Text( 'ID: ${user.accountSequence ?? '--------'}', style: const TextStyle( fontSize: 14, color: _grayText, ), ), const SizedBox(width: 8), GestureDetector( onTap: () { if (user.accountSequence != null) { Clipboard.setData( ClipboardData(text: user.accountSequence!), ); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('ID已复制'), duration: Duration(seconds: 1), ), ); } }, child: const Icon( Icons.copy, size: 16, color: _grayText, ), ), ], ), // 手机号 if (user.phone != null) Padding( padding: const EdgeInsets.only(top: 4), child: Text( '手机: ${user.phone}', style: const TextStyle( fontSize: 12, color: _lightGray, ), ), ), ], ), ), // 编辑按钮 IconButton( onPressed: () { // TODO: 编辑个人资料 }, icon: const Icon( Icons.edit_outlined, color: _grayText, ), ), ], ), ); } Widget _buildStatsRow(UserStats? stats, bool isLoading) { return Container( padding: const EdgeInsets.symmetric(vertical: 16), color: Colors.white, child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildStatItem( '认种状态', stats?.hasAdopted == true ? '已认种' : '未认种', isLoading, ), _buildDivider(), _buildStatItem( '直推人数', stats?.directReferralAdoptedCount.toString() ?? '0', isLoading, ), _buildDivider(), _buildStatItem( '团队层级', stats?.unlockedLevelDepth.toString() ?? '0', isLoading, ), _buildDivider(), _buildStatItem( 'VIP等级', stats?.vipLevel ?? '-', isLoading, ), ], ), ); } Widget _buildStatItem(String label, String value, bool isLoading) { return Column( children: [ DataText( data: isLoading ? null : value, isLoading: isLoading, placeholder: '--', style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: _darkText, ), ), const SizedBox(height: 4), Text( label, style: const TextStyle( fontSize: 12, color: _grayText, ), ), ], ); } Widget _buildDivider() { return Container( width: 1, height: 30, color: _bgGray, ); } Widget _buildInvitationCard(BuildContext context, String invitationCode) { return Container( margin: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '我的邀请码', style: TextStyle( fontSize: 14, color: _grayText, ), ), const SizedBox(height: 12), Row( children: [ Expanded( child: Container( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 12, ), decoration: BoxDecoration( color: _bgGray, borderRadius: BorderRadius.circular(8), ), child: Text( invitationCode, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: _darkText, letterSpacing: 2, ), ), ), ), const SizedBox(width: 12), _buildActionButton( icon: Icons.copy, label: '复制', onTap: () { Clipboard.setData(ClipboardData(text: invitationCode)); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('邀请码已复制'), duration: Duration(seconds: 1), ), ); }, ), const SizedBox(width: 8), _buildActionButton( icon: Icons.share, label: '分享', onTap: () { // TODO: 分享功能 }, ), ], ), ], ), ); } Widget _buildActionButton({ required IconData icon, required String label, required VoidCallback onTap, }) { return GestureDetector( onTap: onTap, child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( color: _orange, borderRadius: BorderRadius.circular(8), ), child: Row( children: [ Icon(icon, size: 16, color: Colors.white), const SizedBox(width: 4), Text( label, style: const TextStyle( fontSize: 12, color: Colors.white, fontWeight: FontWeight.w500, ), ), ], ), ), ); } Widget _buildAccountSettings(BuildContext context, UserState user) { return Container( margin: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Padding( padding: EdgeInsets.fromLTRB(16, 16, 16, 8), child: Text( '账户设置', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: _darkText, ), ), ), _buildSettingItem( icon: Icons.security, label: '账户安全', onTap: () => context.push(Routes.changePassword), ), _buildSettingItem( icon: Icons.verified_user, label: '实名认证', trailing: Text( user.isKycVerified ? '已认证' : '未认证', style: TextStyle( fontSize: 14, color: user.isKycVerified ? _green : _lightGray, ), ), onTap: () {}, ), _buildSettingItem( icon: Icons.lock_outline, label: '支付密码', trailing: const Text( '已设置', style: TextStyle( fontSize: 14, color: _green, ), ), onTap: () {}, showDivider: false, ), ], ), ); } Widget _buildSettingItem({ required IconData icon, required String label, Widget? trailing, required VoidCallback onTap, bool showDivider = true, }) { return Column( children: [ ListTile( leading: Icon(icon, color: _grayText, size: 22), title: Text( label, style: const TextStyle( fontSize: 14, color: _darkText, ), ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ if (trailing != null) trailing, if (trailing != null) const SizedBox(width: 8), const Icon(Icons.chevron_right, color: _lightGray, size: 20), ], ), onTap: onTap, ), if (showDivider) const Divider(height: 1, indent: 56, endIndent: 16), ], ); } Widget _buildRecordsSection(BuildContext context) { return Container( margin: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '我的记录', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: _darkText, ), ), const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _buildRecordIcon( icon: Icons.eco, label: '认种记录', onTap: () {}, ), _buildRecordIcon( icon: Icons.assignment, label: '分配记录', onTap: () {}, ), _buildRecordIcon( icon: Icons.receipt_long, label: '交易记录', onTap: () {}, ), _buildRecordIcon( icon: Icons.account_balance_wallet, label: '提现记录', onTap: () {}, ), ], ), ], ), ); } Widget _buildRecordIcon({ required IconData icon, required String label, required VoidCallback onTap, }) { return GestureDetector( onTap: onTap, behavior: HitTestBehavior.opaque, child: Column( children: [ Container( width: 48, height: 48, decoration: BoxDecoration( color: _orange.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(12), ), child: Icon(icon, color: _orange, size: 24), ), const SizedBox(height: 8), Text( label, style: const TextStyle( fontSize: 12, color: _grayText, ), ), ], ), ); } Widget _buildTeamEarningsSection(BuildContext context) { return Container( margin: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Padding( padding: EdgeInsets.fromLTRB(16, 16, 16, 8), child: Text( '团队与收益', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: _darkText, ), ), ), _buildSettingItem( icon: Icons.people, label: '我的团队', onTap: () {}, ), _buildSettingItem( icon: Icons.trending_up, label: '收益明细', onTap: () {}, ), _buildSettingItem( icon: Icons.card_giftcard, label: '推广奖励', onTap: () {}, showDivider: false, ), ], ), ); } Widget _buildOtherSettings(BuildContext context) { return Container( margin: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Padding( padding: EdgeInsets.fromLTRB(16, 16, 16, 8), child: Text( '其他设置', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: _darkText, ), ), ), _buildSwitchItem( icon: Icons.notifications_outlined, label: '消息通知', value: true, onChanged: (value) {}, ), _buildSwitchItem( icon: Icons.dark_mode_outlined, label: '深色模式', value: false, onChanged: (value) {}, ), _buildSettingItem( icon: Icons.help_outline, label: '帮助中心', onTap: () {}, ), _buildSettingItem( icon: Icons.info_outline, label: '关于我们', onTap: () {}, showDivider: false, ), ], ), ); } Widget _buildSwitchItem({ required IconData icon, required String label, required bool value, required ValueChanged onChanged, }) { return Column( children: [ ListTile( leading: Icon(icon, color: _grayText, size: 22), title: Text( label, style: const TextStyle( fontSize: 14, color: _darkText, ), ), trailing: Switch( value: value, onChanged: onChanged, activeTrackColor: _orange, activeThumbColor: Colors.white, ), ), const Divider(height: 1, indent: 56, endIndent: 16), ], ); } Widget _buildLogoutButton(BuildContext context, WidgetRef ref) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: SizedBox( width: double.infinity, child: TextButton( onPressed: () { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('退出登录'), content: const Text('确定要退出登录吗?'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('取消'), ), TextButton( onPressed: () { Navigator.pop(context); ref.read(userNotifierProvider.notifier).logout(); }, child: const Text( '确定', style: TextStyle(color: _red), ), ), ], ), ); }, style: TextButton.styleFrom( backgroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), child: const Text( '退出登录', style: TextStyle( fontSize: 16, color: _red, fontWeight: FontWeight.w500, ), ), ), ), ); } }