import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; /// 排行榜类型枚举 enum RankingType { daily, weekly, monthly } /// 筛选类型枚举 enum FilterType { all, previousDay, previousWeek, previousMonth } /// 排行榜数据模型 class RankingItem { final int rank; final String name; final String province; final String city; final int teamPlantingAmount; final String? avatarUrl; RankingItem({ required this.rank, required this.name, required this.province, required this.city, required this.teamPlantingAmount, this.avatarUrl, }); } /// 龙虎榜页面 - 显示用户排行榜 /// 支持日榜、周榜、月榜切换,以及筛选功能 class RankingPage extends ConsumerStatefulWidget { const RankingPage({super.key}); @override ConsumerState createState() => _RankingPageState(); } class _RankingPageState extends ConsumerState { // 当前选中的排行榜类型 RankingType _selectedRankingType = RankingType.daily; // 当前选中的筛选类型 FilterType _selectedFilterType = FilterType.all; // 模拟排行榜数据 final List _mockRankingData = [ RankingItem( rank: 1, name: '环保先锋', province: '广东', city: '深圳', teamPlantingAmount: 1234567, ), RankingItem( rank: 2, name: '绿色卫士', province: '广东', city: '深圳', teamPlantingAmount: 1123456, ), RankingItem( rank: 3, name: '低碳达人', province: '广东', city: '深圳', teamPlantingAmount: 987654, ), RankingItem( rank: 4, name: '节能小能手', province: '广东', city: '深圳', teamPlantingAmount: 876543, ), RankingItem( rank: 5, name: '分类高手', province: '广东', city: '深圳', teamPlantingAmount: 765432, ), ]; /// 切换排行榜类型 void _selectRankingType(RankingType type) { setState(() { _selectedRankingType = type; }); } /// 切换筛选类型 void _selectFilterType(FilterType type) { setState(() { _selectedFilterType = type; }); } /// 格式化数字(添加千分位) String _formatNumber(int number) { return number.toString().replaceAllMapped( RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},', ); } @override Widget build(BuildContext context) { return Scaffold( body: Container( decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0xFFFFF5E6), // 浅米色 Color(0xFFEAE0C8), // 浅橙色 ], ), ), child: Column( children: [ // 顶部标题和Tab栏 _buildHeader(), // 筛选栏 _buildFilterBar(), // 排行榜列表 Expanded( child: _buildRankingList(), ), ], ), ), ); } /// 构建顶部标题和Tab栏 Widget _buildHeader() { return Container( color: const Color(0xCCFFF5E6), child: SafeArea( bottom: false, child: Column( children: [ // 标题 Container( height: 56, padding: const EdgeInsets.symmetric(horizontal: 16), child: const Center( child: Text( '龙虎榜', style: TextStyle( fontSize: 18, fontFamily: 'Inter', fontWeight: FontWeight.w700, height: 1.25, letterSpacing: -0.27, color: Color(0xFF5D4037), ), ), ), ), // Tab栏 _buildTabBar(), ], ), ), ); } /// 构建Tab栏 Widget _buildTabBar() { return Container( height: 45, padding: const EdgeInsets.symmetric(horizontal: 16), decoration: const BoxDecoration( border: Border( bottom: BorderSide( width: 1, color: Color(0x338B5A2B), ), ), ), child: Row( children: [ // 日榜 Expanded( child: _buildTabItem( title: '日榜', isSelected: _selectedRankingType == RankingType.daily, onTap: () => _selectRankingType(RankingType.daily), ), ), // 周榜 Expanded( child: _buildTabItem( title: '周榜', isSelected: _selectedRankingType == RankingType.weekly, onTap: () => _selectRankingType(RankingType.weekly), ), ), // 月榜 Expanded( child: _buildTabItem( title: '月榜', isSelected: _selectedRankingType == RankingType.monthly, onTap: () => _selectRankingType(RankingType.monthly), ), ), ], ), ); } /// 构建Tab项 Widget _buildTabItem({ required String title, required bool isSelected, required VoidCallback onTap, }) { return GestureDetector( onTap: onTap, child: Container( height: 44, decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 3, color: isSelected ? const Color(0xFFD4AF37) : Colors.transparent, ), ), ), child: Center( child: Text( title, style: TextStyle( fontSize: 14, fontFamily: 'Inter', fontWeight: FontWeight.w700, height: 1.5, letterSpacing: 0.21, color: isSelected ? const Color(0xFFD4AF37) : const Color(0xFF8B5A2B), ), ), ), ), ); } /// 构建筛选栏 Widget _buildFilterBar() { return Container( height: 56, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: [ _buildFilterChip( title: '全部', isSelected: _selectedFilterType == FilterType.all, onTap: () => _selectFilterType(FilterType.all), ), const SizedBox(width: 12), _buildFilterChip( title: '上一日榜', isSelected: _selectedFilterType == FilterType.previousDay, onTap: () => _selectFilterType(FilterType.previousDay), ), const SizedBox(width: 12), _buildFilterChip( title: '上一周榜', isSelected: _selectedFilterType == FilterType.previousWeek, onTap: () => _selectFilterType(FilterType.previousWeek), ), const SizedBox(width: 12), _buildFilterChip( title: '上一月榜', isSelected: _selectedFilterType == FilterType.previousMonth, onTap: () => _selectFilterType(FilterType.previousMonth), ), ], ), ), ); } /// 构建筛选标签 Widget _buildFilterChip({ required String title, required bool isSelected, required VoidCallback onTap, }) { return GestureDetector( onTap: onTap, child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6), decoration: BoxDecoration( color: isSelected ? const Color(0xFFD4AF37) : const Color(0x1A8B5A2B), borderRadius: BorderRadius.circular(9999), ), child: Text( title, style: TextStyle( fontSize: 14, fontFamily: 'Inter', fontWeight: FontWeight.w500, height: 1.5, color: isSelected ? Colors.white : const Color(0xFF8B5A2B), ), ), ), ); } /// 构建排行榜列表 Widget _buildRankingList() { return ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), itemCount: _mockRankingData.length, itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.only(bottom: 4), child: _buildRankingItem(_mockRankingData[index]), ); }, ); } /// 构建排行榜项 Widget _buildRankingItem(RankingItem item) { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: const Color(0xFFFFFDF8), // 浅白色背景,与页面背景区分 borderRadius: BorderRadius.circular(12), ), child: Row( children: [ // 排名 SizedBox( width: 32, child: _buildRankBadge(item.rank), ), const SizedBox(width: 16), // 头像 _buildAvatar(item), const SizedBox(width: 16), // 用户信息 Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( item.name, style: const TextStyle( fontSize: 16, fontFamily: 'Inter', fontWeight: FontWeight.w700, height: 1.5, color: Color(0xFF5D4037), ), ), Text( '省份: ${item.province}', style: const TextStyle( fontSize: 14, fontFamily: 'Inter', height: 1.5, color: Color(0xFF8B5A2B), ), ), Text( '城市: ${item.city}', style: const TextStyle( fontSize: 14, fontFamily: 'Inter', height: 1.5, color: Color(0xFF8B5A2B), ), ), ], ), ), // 团队认种量 Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( _formatNumber(item.teamPlantingAmount), style: const TextStyle( fontSize: 16, fontFamily: 'Inter', fontWeight: FontWeight.w700, height: 1.5, color: Color(0xFFD4AF37), ), ), const Text( '团队认种量', style: TextStyle( fontSize: 12, fontFamily: 'Inter', height: 1.5, color: Color(0xFF8B5A2B), ), ), ], ), ], ), ); } /// 构建排名徽章 Widget _buildRankBadge(int rank) { // 前三名使用皇冠图标 if (rank <= 3) { Color crownColor; switch (rank) { case 1: crownColor = const Color(0xFFFFD700); // 金色 break; case 2: crownColor = const Color(0xFFC0C0C0); // 银色 break; case 3: crownColor = const Color(0xFFCD7F32); // 铜色 break; default: crownColor = const Color(0xFF8B5A2B); } return Icon( Icons.workspace_premium, size: 32, color: crownColor, ); } // 其他排名显示数字 return Text( rank.toString(), style: const TextStyle( fontSize: 20, fontFamily: 'Inter', fontWeight: FontWeight.w700, height: 1.4, color: Color(0xFF8B5A2B), ), textAlign: TextAlign.center, ); } /// 构建头像 Widget _buildAvatar(RankingItem item) { return Container( width: 56, height: 56, decoration: BoxDecoration( color: const Color(0x33D4AF37), borderRadius: BorderRadius.circular(28), ), child: item.avatarUrl != null ? ClipRRect( borderRadius: BorderRadius.circular(28), child: Image.network( item.avatarUrl!, fit: BoxFit.cover, ), ) : const Icon( Icons.person, size: 32, color: Color(0xFF8B5A2B), ), ); } }