import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import '../../../core/l10n/app_localizations.dart'; import '../../../core/theme/app_colors.dart'; import '../../../data/repositories/broker_repository.dart'; // ── State ───────────────────────────────────────────────── class _TeamDetailState { final DateTime month; final String filter; // 'all' | 'month' | 'week' | 'day' _TeamDetailState({required this.month, required this.filter}); _TeamDetailState copyWith({DateTime? month, String? filter}) => _TeamDetailState(month: month ?? this.month, filter: filter ?? this.filter); } // ── Screen ─────────────────────────────────────────────── class TeamDetailScreen extends ConsumerStatefulWidget { const TeamDetailScreen({super.key}); @override ConsumerState createState() => _TeamDetailScreenState(); } class _TeamDetailScreenState extends ConsumerState { _TeamDetailState _state = _TeamDetailState(month: DateTime.now(), filter: 'all'); Map _data = {}; bool _loading = false; String? _error; @override void initState() { super.initState(); _load(); } /// 对应安卓 requestAgentAwards(endDate) → GET agent/stat?endDate= Future _load() async { setState(() { _loading = true; _error = null; }); try { final endDate = _buildEndDate(); final data = await ref.read(brokerRepositoryProvider).getTotalAward(endDate: endDate); if (mounted) setState(() { _data = data; _loading = false; }); } catch (e) { if (mounted) setState(() { _error = e.toString(); _loading = false; }); } } /// 对应安卓各个 load 方法传递的 endDate String? _buildEndDate() { final fmt = DateFormat('yyyy-MM-dd'); final now = DateTime.now(); switch (_state.filter) { case 'day': // loadToday return fmt.format(now); case 'week': // loadWeekBefore return fmt.format(now.subtract(const Duration(days: 7))); case 'month': // loadCurrentMonth → "${month}-01" return '${_state.month.year}-${_state.month.month.toString().padLeft(2, '0')}-01'; default: // loadAllDate → null return null; } } Future _pickMonth() async { final now = DateTime.now(); final picked = await showDatePicker( context: context, initialDate: _state.month, firstDate: DateTime(now.year - 2), lastDate: now, initialDatePickerMode: DatePickerMode.year, ); if (picked != null && mounted) { setState(() => _state = _state.copyWith( month: DateTime(picked.year, picked.month), filter: 'month', )); _load(); } } void _setFilter(String f) { setState(() => _state = _state.copyWith(filter: f)); _load(); } @override Widget build(BuildContext context) { final cs = Theme.of(context).colorScheme; return Scaffold( backgroundColor: cs.surface, appBar: AppBar( backgroundColor: cs.surface, elevation: 0, leading: IconButton( icon: const Icon(Icons.arrow_back_ios, size: 18), onPressed: () => context.pop(), ), title: Text(AppLocalizations.of(context)!.teamDetail, style: TextStyle(color: cs.onSurface, fontSize: 17, fontWeight: FontWeight.w600)), centerTitle: true, ), body: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // ── 筛选栏:三个独立带边框按钮 ─────────────── Row(children: [ // 月份选择 Expanded( flex: 5, child: GestureDetector( onTap: _pickMonth, child: Container( height: 38, decoration: BoxDecoration( color: _state.filter == 'month' ? AppColors.brand : Colors.transparent, border: Border.all(color: AppColors.lightBorder, width: 1), borderRadius: BorderRadius.circular(6), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( '${_state.month.year}-${_state.month.month.toString().padLeft(2, '0')}', style: TextStyle( fontSize: 13, fontWeight: _state.filter == 'month' ? FontWeight.w600 : FontWeight.normal, color: _state.filter == 'month' ? Colors.black : cs.onSurface, ), ), const SizedBox(width: 2), Icon(Icons.arrow_drop_down, size: 18, color: _state.filter == 'month' ? Colors.black : cs.onSurface.withAlpha(160)), ], ), ), ), ), const SizedBox(width: 8), // 一周内 Expanded( flex: 3, child: GestureDetector( onTap: () => _setFilter('week'), child: Container( height: 38, alignment: Alignment.center, decoration: BoxDecoration( color: _state.filter == 'week' ? AppColors.brand : Colors.transparent, border: Border.all(color: AppColors.lightBorder, width: 1), borderRadius: BorderRadius.circular(6), ), child: Text( AppLocalizations.of(context)!.withinOneWeek, style: TextStyle( fontSize: 13, fontWeight: _state.filter == 'week' ? FontWeight.w600 : FontWeight.normal, color: _state.filter == 'week' ? Colors.black : cs.onSurface, ), ), ), ), ), const SizedBox(width: 8), // 当日 Expanded( flex: 3, child: GestureDetector( onTap: () => _setFilter('day'), child: Container( height: 38, alignment: Alignment.center, decoration: BoxDecoration( color: _state.filter == 'day' ? AppColors.brand : Colors.transparent, border: Border.all(color: AppColors.lightBorder, width: 1), borderRadius: BorderRadius.circular(6), ), child: Text( AppLocalizations.of(context)!.today, style: TextStyle( fontSize: 13, fontWeight: _state.filter == 'day' ? FontWeight.w600 : FontWeight.normal, color: _state.filter == 'day' ? Colors.black : cs.onSurface, ), ), ), ), ), ]), const SizedBox(height: 24), // ── 内容区 ──────────────────────────────── if (_loading) const Center(child: CircularProgressIndicator()) else if (_error != null) Center(child: Text('${AppLocalizations.of(context)!.loadFailed}: $_error', style: TextStyle(color: cs.error))) else ...[ Text(AppLocalizations.of(context)!.teamTotalAssets, style: TextStyle(fontSize: 13, color: cs.onSurface.withAlpha(120))), const SizedBox(height: 8), Row(crossAxisAlignment: CrossAxisAlignment.baseline, textBaseline: TextBaseline.alphabetic, children: [ Text( _formatAmount(_data['totalBalance']), style: TextStyle(fontSize: 28, fontWeight: FontWeight.w700, color: cs.onSurface), ), const SizedBox(width: 6), Text('USDT', style: TextStyle(fontSize: 14, color: cs.onSurface.withAlpha(160))), ]), ], ], ), ), ); } String _formatAmount(dynamic v) { if (v == null) return '0.00'; final d = double.tryParse(v.toString()) ?? 0.0; if (d >= 1000) { final intPart = d.truncate().toString(); final decPart = d.toStringAsFixed(2).split('.')[1]; final buf = StringBuffer(); for (int i = 0; i < intPart.length; i++) { if (i > 0 && (intPart.length - i) % 3 == 0) buf.write(','); buf.write(intPart[i]); } return '${buf.toString()}.$decPart'; } return d.toStringAsFixed(2); } }