import 'package:flutter/material.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 '../../providers/settings_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); // 预设头像颜色列表(与编辑页面保持一致) static const List _avatarColors = [ Color(0xFFFF6B00), // 橙色 Color(0xFF10B981), // 绿色 Color(0xFF3B82F6), // 蓝色 Color(0xFFEF4444), // 红色 Color(0xFF8B5CF6), // 紫色 Color(0xFFF59E0B), // 琥珀色 Color(0xFFEC4899), // 粉色 Color(0xFF06B6D4), // 青色 ]; @override Widget build(BuildContext context, WidgetRef ref) { final user = ref.watch(userNotifierProvider); final statsAsync = ref.watch(userStatsProvider); 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), // 账户设置 _buildAccountSettings(context, user), const SizedBox(height: 16), // 记录入口 _buildRecordsSection(context), const SizedBox(height: 16), // 团队与收益 _buildTeamEarningsSection(context), const SizedBox(height: 16), // 其他设置 _buildOtherSettings(context, ref), 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: 24), ], ), ), ), ), ); } Widget _buildUserHeader(BuildContext context, UserState user) { final avatarColor = _avatarColors[user.avatarIndex % _avatarColors.length]; return Container( padding: const EdgeInsets.all(20), color: Colors.white, child: Row( children: [ // 头像(可点击) GestureDetector( onTap: () => context.push(Routes.editProfile), child: Container( width: 80, height: 80, decoration: BoxDecoration( shape: BoxShape.circle, gradient: LinearGradient( colors: [avatarColor.withValues(alpha: 0.8), avatarColor], 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.nickname?.isNotEmpty == true ? user.nickname! : (user.realName ?? '榴莲用户'), 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), // 手机号显示为ID if (user.phone != null) Text( 'ID: ${user.phone}', style: const TextStyle( fontSize: 14, color: _grayText, ), ), ], ), ), // 编辑按钮 IconButton( onPressed: () => context.push(Routes.editProfile), 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( '团队上级', '15', 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 _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), 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: () => context.push(Routes.plantingRecords), ), _buildRecordIcon( icon: Icons.assignment, label: '分配记录', onTap: () => context.push(Routes.miningRecords), ), _buildRecordIcon( icon: Icons.receipt_long, label: '交易记录', onTap: () => context.push(Routes.tradingRecords), ), ], ), ], ), ); } 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: () => context.push(Routes.myTeam), showDivider: false, ), ], ), ); } Widget _buildOtherSettings(BuildContext context, WidgetRef ref) { final notificationsEnabled = ref.watch(notificationsEnabledProvider); final darkModeEnabled = ref.watch(darkModeEnabledProvider); 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: notificationsEnabled, onChanged: (value) { ref.read(notificationsEnabledProvider.notifier).setEnabled(value); }, ), _buildSwitchItem( icon: Icons.dark_mode_outlined, label: '深色模式', value: darkModeEnabled, onChanged: (value) { ref.read(darkModeEnabledProvider.notifier).setEnabled(value); }, ), _buildSettingItem( icon: Icons.help_outline, label: '帮助中心', onTap: () => context.push(Routes.helpCenter), ), _buildSettingItem( icon: Icons.info_outline, label: '关于我们', onTap: () => context.push(Routes.about), 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, ), ), ), ), ); } }