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 _red = Color(0xFFEF4444); // 浅色模式色彩 static const Color _lightDarkText = Color(0xFF1F2937); static const Color _lightGrayText = Color(0xFF6B7280); static const Color _lightLightGray = Color(0xFF9CA3AF); static const Color _lightBgGray = Color(0xFFF3F4F6); static const Color _lightCardBg = Colors.white; // 深色模式色彩 static const Color _darkDarkText = Color(0xFFE5E7EB); static const Color _darkGrayText = Color(0xFF9CA3AF); static const Color _darkLightGray = Color(0xFF6B7280); static const Color _darkBgGray = Color(0xFF111827); static const Color _darkCardBg = Color(0xFF1F2937); /// 根据当前主题获取颜色 static Color _darkText(BuildContext context) => Theme.of(context).brightness == Brightness.dark ? _darkDarkText : _lightDarkText; static Color _grayText(BuildContext context) => Theme.of(context).brightness == Brightness.dark ? _darkGrayText : _lightGrayText; static Color _lightGray(BuildContext context) => Theme.of(context).brightness == Brightness.dark ? _darkLightGray : _lightLightGray; static Color _bgGray(BuildContext context) => Theme.of(context).brightness == Brightness.dark ? _darkBgGray : _lightBgGray; static Color _cardBg(BuildContext context) => Theme.of(context).brightness == Brightness.dark ? _darkCardBg : _lightCardBg; // 预设头像颜色列表(与编辑页面保持一致) 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(context), 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(context, 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), // 版本信息 Text( 'Version 1.0.0', style: TextStyle( fontSize: 12, color: _lightGray(context), ), ), 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: _cardBg(context), 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: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: _darkText(context), ), ), 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: TextStyle( fontSize: 14, color: _grayText(context), ), ), ], ), ), // 编辑按钮 IconButton( onPressed: () => context.push(Routes.editProfile), icon: Icon( Icons.edit_outlined, color: _grayText(context), ), ), ], ), ); } Widget _buildStatsRow(BuildContext context, UserStats? stats, bool isLoading) { return Container( padding: const EdgeInsets.symmetric(vertical: 16), color: _cardBg(context), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildStatItem( context, '参与状态', stats?.hasAdopted == true ? '已参与' : '未参与', isLoading, ), _buildDivider(context), _buildStatItem( context, '引荐人数', stats?.directReferralAdoptedCount.toString() ?? '0', isLoading, ), _buildDivider(context), _buildStatItem( context, '团队下贡献值', stats?.unlockedLevelDepth.toString() ?? '0', isLoading, ), _buildDivider(context), _buildStatItem( context, '团队上贡献值', '15', isLoading, ), ], ), ); } Widget _buildStatItem(BuildContext context, String label, String value, bool isLoading) { return Column( children: [ DataText( data: isLoading ? null : value, isLoading: isLoading, placeholder: '--', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: _darkText(context), ), ), const SizedBox(height: 4), Text( label, style: TextStyle( fontSize: 12, color: _grayText(context), ), ), ], ); } Widget _buildDivider(BuildContext context) { return Container( width: 1, height: 30, color: _bgGray(context), ); } Widget _buildAccountSettings(BuildContext context, UserState user) { return Container( margin: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: _cardBg(context), borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), child: Text( '账户设置', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: _darkText(context), ), ), ), _buildSettingItem( context: context, icon: Icons.security, label: '账户安全', onTap: () => context.push(Routes.changePassword), showDivider: false, ), ], ), ); } Widget _buildSettingItem({ required BuildContext context, required IconData icon, required String label, Widget? trailing, required VoidCallback onTap, bool showDivider = true, }) { return Column( children: [ ListTile( leading: Icon(icon, color: _grayText(context), size: 22), title: Text( label, style: TextStyle( fontSize: 14, color: _darkText(context), ), ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ if (trailing != null) trailing, if (trailing != null) const SizedBox(width: 8), Icon(Icons.chevron_right, color: _lightGray(context), 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: _cardBg(context), borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '我的记录', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: _darkText(context), ), ), const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _buildRecordIcon( context: context, icon: Icons.eco, label: '参与记录', onTap: () => context.push(Routes.plantingRecords), ), _buildRecordIcon( context: context, icon: Icons.assignment, label: '分配记录', onTap: () => context.push(Routes.miningRecords), ), _buildRecordIcon( context: context, icon: Icons.receipt_long, label: '交易记录', onTap: () => context.push(Routes.tradingRecords), ), ], ), ], ), ); } Widget _buildRecordIcon({ required BuildContext context, 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: TextStyle( fontSize: 12, color: _grayText(context), ), ), ], ), ); } Widget _buildTeamEarningsSection(BuildContext context) { return Container( margin: const EdgeInsets.symmetric(horizontal: 16), decoration: BoxDecoration( color: _cardBg(context), borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), child: Text( '团队与收益', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: _darkText(context), ), ), ), _buildSettingItem( context: context, 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: _cardBg(context), borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.fromLTRB(16, 16, 16, 8), child: Text( '其他设置', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: _darkText(context), ), ), ), _buildSwitchItem( context: context, icon: Icons.notifications_outlined, label: '消息通知', value: notificationsEnabled, onChanged: (value) { ref.read(notificationsEnabledProvider.notifier).setEnabled(value); }, ), _buildSwitchItem( context: context, icon: Icons.dark_mode_outlined, label: '深色模式', value: darkModeEnabled, onChanged: (value) { ref.read(darkModeEnabledProvider.notifier).setEnabled(value); }, ), _buildSettingItem( context: context, icon: Icons.help_outline, label: '帮助中心', onTap: () => context.push(Routes.helpCenter), ), _buildSettingItem( context: context, icon: Icons.info_outline, label: '关于我们', onTap: () => context.push(Routes.about), showDivider: false, ), ], ), ); } Widget _buildSwitchItem({ required BuildContext context, required IconData icon, required String label, required bool value, required ValueChanged onChanged, }) { return Column( children: [ ListTile( leading: Icon(icon, color: _grayText(context), size: 22), title: Text( label, style: TextStyle( fontSize: 14, color: _darkText(context), ), ), 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: (dialogContext) => AlertDialog( title: const Text('退出登录'), content: const Text('确定要退出登录吗?'), actions: [ TextButton( onPressed: () => Navigator.pop(dialogContext), child: const Text('取消'), ), TextButton( onPressed: () { Navigator.pop(dialogContext); ref.read(userNotifierProvider.notifier).logout(); }, child: const Text( '确定', style: TextStyle(color: _red), ), ), ], ), ); }, style: TextButton.styleFrom( backgroundColor: _cardBg(context), padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), child: const Text( '退出登录', style: TextStyle( fontSize: 16, color: _red, fontWeight: FontWeight.w500, ), ), ), ), ); } }