import 'package:flutter/material.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; import 'package:provider/provider.dart'; import '../../../providers/asset_provider.dart'; import '../../../providers/auth_provider.dart'; /// 首页 - 使用 shadcn_ui 现代化设计 class HomePage extends StatefulWidget { const HomePage({super.key}); @override State createState() => _HomePageState(); } class _HomePageState extends State with AutomaticKeepAliveClientMixin { @override bool get wantKeepAlive => true; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { _loadData(); }); } void _loadData() { final assetProvider = context.read(); assetProvider.loadOverview(); assetProvider.loadTradeAccount(); } @override Widget build(BuildContext context) { super.build(context); final theme = ShadTheme.of(context); return Scaffold( backgroundColor: theme.colorScheme.background, body: Consumer( builder: (context, provider, _) { return RefreshIndicator( onRefresh: () => provider.refreshAll(), color: theme.colorScheme.primary, child: SingleChildScrollView( physics: const AlwaysScrollableScrollPhysics(), padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 8), _buildHeader(), const SizedBox(height: 20), _buildAssetCard(provider), const SizedBox(height: 16), _buildQuickActions(), const SizedBox(height: 24), _buildHoldings(provider), ], ), ), ); }, ), ); } Widget _buildHeader() { final theme = ShadTheme.of(context); return Consumer( builder: (context, auth, _) { final user = auth.user; return Row( children: [ CircleAvatar( radius: 20, backgroundColor: theme.colorScheme.primary.withValues(alpha: 0.2), child: Text( user?.avatarText ?? 'U', style: TextStyle( color: theme.colorScheme.primary, fontWeight: FontWeight.bold, ), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '你好,${user?.username ?? '用户'}', style: theme.textTheme.large.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 2), Text( '欢迎来到模拟所', style: theme.textTheme.muted, ), ], ), ), ], ).animate().fadeIn(duration: 300.ms).slideX(begin: -0.1, end: 0); }, ); } Widget _buildAssetCard(AssetProvider provider) { final theme = ShadTheme.of(context); final overview = provider.overview; // 自定义渐变色 const gradientColors = [ Color(0xFF00D4AA), Color(0xFF00B894), ]; return Container( width: double.infinity, padding: const EdgeInsets.all(20), decoration: BoxDecoration( gradient: const LinearGradient( colors: gradientColors, begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '总资产(USDT)', style: theme.textTheme.small.copyWith(color: Colors.white70), ), const SizedBox(height: 8), Text( overview?.totalAsset ?? '0.00', style: theme.textTheme.h2.copyWith( color: Colors.white, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildAssetItem('资金账户', overview?.fundBalance ?? '0.00'), _buildAssetItem('交易账户', overview?.tradeBalance ?? '0.00'), ], ), ], ), ).animate().fadeIn(duration: 400.ms).slideY(begin: 0.1, end: 0); } Widget _buildAssetItem(String label, String value) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: const TextStyle(fontSize: 12, color: Colors.white70), ), const SizedBox(height: 4), Text( value, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.w600, color: Colors.white, ), ), ], ); } Widget _buildQuickActions() { final theme = ShadTheme.of(context); return ShadCard( padding: const EdgeInsets.all(16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _buildActionItem( icon: LucideIcons.arrowDownToLine, text: '充值', color: const Color(0xFF00C853), onTap: () => _showDeposit(), ), _buildActionItem( icon: LucideIcons.arrowUpFromLine, text: '提现', color: const Color(0xFFFF9800), onTap: () => _showWithdraw(), ), _buildActionItem( icon: LucideIcons.arrowRightLeft, text: '划转', color: theme.colorScheme.primary, onTap: () => _showTransfer(), ), _buildActionItem( icon: LucideIcons.trendingUp, text: '交易', color: const Color(0xFF2196F3), onTap: () => _navigateToTrade(), ), ], ), ).animate().fadeIn(duration: 500.ms, delay: 100.ms); } Widget _buildActionItem({ required IconData icon, required String text, required Color color, required VoidCallback onTap, }) { return GestureDetector( onTap: onTap, child: Column( children: [ Container( width: 48, height: 48, decoration: BoxDecoration( color: color.withOpacity(0.15), shape: BoxShape.circle, ), child: Icon(icon, color: color, size: 22), ), const SizedBox(height: 8), Text( text, style: TextStyle( fontSize: 12, color: ShadTheme.of(context).colorScheme.foreground, ), ), ], ), ); } Widget _buildHoldings(AssetProvider provider) { final theme = ShadTheme.of(context); final holdings = provider.holdings; return ShadCard( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '我的持仓', style: theme.textTheme.large.copyWith( fontWeight: FontWeight.bold, ), ), Icon( LucideIcons.chevronRight, color: theme.colorScheme.mutedForeground, size: 20, ), ], ), const SizedBox(height: 16), if (holdings.isEmpty) Center( child: Padding( padding: const EdgeInsets.all(32), child: Column( children: [ Icon( LucideIcons.wallet, size: 48, color: theme.colorScheme.mutedForeground, ), const SizedBox(height: 12), Text( '暂无持仓', style: theme.textTheme.muted, ), const SizedBox(height: 4), Text( '快去交易吧~', style: theme.textTheme.muted.copyWith(fontSize: 12), ), ], ), ), ) else ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: holdings.length > 5 ? 5 : holdings.length, separatorBuilder: (_, __) => Divider( color: theme.colorScheme.border, height: 1, ), itemBuilder: (context, index) { final holding = holdings[index]; return _buildHoldingItem(holding) .animate() .fadeIn(delay: Duration(milliseconds: 50 * index)); }, ), ], ), ).animate().fadeIn(duration: 500.ms, delay: 200.ms); } Widget _buildHoldingItem(holding) { final theme = ShadTheme.of(context); final upColor = const Color(0xFF00C853); final downColor = const Color(0xFFFF5252); return Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row( children: [ CircleAvatar( radius: 18, backgroundColor: theme.colorScheme.primary.withValues(alpha: 0.1), child: Text( holding.coinCode.substring(0, 1), style: TextStyle( color: theme.colorScheme.primary, fontWeight: FontWeight.bold, ), ), ), const SizedBox(width: 12), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( holding.coinCode, style: theme.textTheme.large.copyWith( fontWeight: FontWeight.bold, ), ), Text( holding.quantity, style: theme.textTheme.muted, ), ], ), ], ), Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( '${holding.currentValue} USDT', style: theme.textTheme.small.copyWith( fontWeight: FontWeight.w500, ), ), Text( holding.formattedProfitRate, style: TextStyle( color: holding.isProfit ? upColor : downColor, fontSize: 12, ), ), ], ), ], ), ); } void _showDeposit() { _showActionDialog('充值', '请输入充值金额(USDT)', (amount) { context.read().deposit(amount: amount); }); } void _showWithdraw() { _showActionDialog('提现', '请输入提现金额(USDT)', (amount) { context.read().withdraw(amount: amount); }); } void _showTransfer() { _showActionDialog('划转', '请输入划转金额(USDT)', (amount) { context.read().transfer(direction: 1, amount: amount); }); } void _showActionDialog(String title, String hint, Function(String) onSubmit) { final controller = TextEditingController(); final formKey = GlobalKey(); showShadDialog( context: context, builder: (context) => ShadDialog( title: Text(title), child: ShadForm( key: formKey, child: ShadInputFormField( id: 'amount', placeholder: Text(hint), controller: controller, keyboardType: const TextInputType.numberWithOptions(decimal: true), validator: (value) { if (value == null || value.isEmpty) { return '请输入金额'; } final amount = double.tryParse(value); if (amount == null || amount <= 0) { return '请输入有效金额'; } return null; }, ), ), actions: [ ShadButton.outline( child: const Text('取消'), onPressed: () => Navigator.of(context).pop(), ), ShadButton( child: const Text('确认'), onPressed: () { if (formKey.currentState!.saveAndValidate()) { onSubmit(controller.text); Navigator.of(context).pop(); } }, ), ], ), ); } void _navigateToTrade() { // 切换到交易页 - 通过 MainController } }