import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/constants/app_colors.dart'; import '../../../core/utils/format_utils.dart'; import '../../providers/mining_providers.dart'; import '../../providers/user_providers.dart'; import '../../providers/trading_providers.dart'; class TradingPage extends ConsumerWidget { const TradingPage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final globalState = ref.watch(globalStateProvider); final user = ref.watch(userNotifierProvider); final accountSequence = user.accountSequence ?? ''; final accountAsync = ref.watch(shareAccountProvider(accountSequence)); return Scaffold( appBar: AppBar( title: const Text('兑换'), backgroundColor: AppColors.primary, foregroundColor: Colors.white, ), body: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 价格卡片 globalState.when( data: (state) { if (state == null) return const SizedBox.shrink(); return _buildPriceCard(state); }, loading: () => const Card( child: Padding( padding: EdgeInsets.all(32), child: Center(child: CircularProgressIndicator()), ), ), error: (_, __) => const Card( child: Padding( padding: EdgeInsets.all(32), child: Center(child: Text('加载失败')), ), ), ), const SizedBox(height: 24), // 账户余额 const Text( '账户余额', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), const SizedBox(height: 12), accountAsync.when( data: (account) { if (account == null) return const SizedBox.shrink(); return _buildBalanceCard(account); }, loading: () => const Card( child: Padding( padding: EdgeInsets.all(32), child: Center(child: CircularProgressIndicator()), ), ), error: (_, __) => const Card( child: Padding( padding: EdgeInsets.all(32), child: Center(child: Text('加载失败')), ), ), ), const SizedBox(height: 24), // 买卖按钮 Row( children: [ Expanded( child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: AppColors.up, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), onPressed: () => _showBuyDialog(context, ref, accountSequence), child: const Text( '买入', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ), ), const SizedBox(width: 16), Expanded( child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: AppColors.down, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), onPressed: () => _showSellDialog(context, ref, accountSequence), child: const Text( '卖出', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), ), ), ], ), const SizedBox(height: 24), // 交易说明 Card( child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '交易说明', style: TextStyle(fontWeight: FontWeight.bold), ), const SizedBox(height: 12), _buildInfoRow('买入', '使用绿积分购买积分股'), _buildInfoRow('卖出', '出售积分股获得绿积分'), _buildInfoRow('划转', '需先将挖矿账户余额划转到交易账户'), ], ), ), ), ], ), ), ); } Widget _buildPriceCard(state) { final isPriceUp = state.isPriceUp; return Card( child: Padding( padding: const EdgeInsets.all(20), child: Column( children: [ const Text( '当前价格', style: TextStyle(color: AppColors.textSecondary, fontSize: 14), ), const SizedBox(height: 8), Text( formatPrice(state.currentPrice), style: TextStyle( fontSize: 32, fontWeight: FontWeight.bold, color: isPriceUp ? AppColors.up : AppColors.down, ), ), const SizedBox(height: 4), Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), decoration: BoxDecoration( color: (isPriceUp ? AppColors.up : AppColors.down).withOpacity(0.1), borderRadius: BorderRadius.circular(20), ), child: Text( '${isPriceUp ? '+' : ''}${formatPercent(state.priceChange24h)} 24h', style: TextStyle( color: isPriceUp ? AppColors.up : AppColors.down, fontSize: 12, ), ), ), ], ), ), ); } Widget _buildBalanceCard(account) { return Card( child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '挖矿账户', style: TextStyle(color: AppColors.textSecondary, fontSize: 12), ), const SizedBox(height: 4), Text( formatAmount(account.miningBalance), style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ], ), ), Container( width: 1, height: 40, color: AppColors.border, ), Expanded( child: Padding( padding: const EdgeInsets.only(left: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( '交易账户', style: TextStyle(color: AppColors.textSecondary, fontSize: 12), ), const SizedBox(height: 4), Text( formatAmount(account.tradingBalance), style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ], ), ), ), ], ), ), ); } Widget _buildInfoRow(String title, String description) { return Padding( padding: const EdgeInsets.only(bottom: 8), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 6, height: 6, margin: const EdgeInsets.only(top: 6), decoration: const BoxDecoration( color: AppColors.primary, shape: BoxShape.circle, ), ), const SizedBox(width: 8), Expanded( child: RichText( text: TextSpan( style: const TextStyle(color: AppColors.textSecondary, fontSize: 13), children: [ TextSpan( text: '$title: ', style: const TextStyle(fontWeight: FontWeight.w500), ), TextSpan(text: description), ], ), ), ), ], ), ); } void _showBuyDialog(BuildContext context, WidgetRef ref, String accountSequence) { final controller = TextEditingController(); showDialog( context: context, builder: (context) => AlertDialog( title: const Text('买入积分股'), content: TextField( controller: controller, keyboardType: const TextInputType.numberWithOptions(decimal: true), decoration: const InputDecoration( labelText: '买入数量', hintText: '请输入买入数量', suffixText: '股', ), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('取消'), ), ElevatedButton( onPressed: () async { if (controller.text.isNotEmpty) { final success = await ref .read(tradingNotifierProvider.notifier) .buyShares(accountSequence, controller.text); if (context.mounted) { Navigator.pop(context); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(success ? '买入订单已提交' : '买入失败'), backgroundColor: success ? AppColors.up : AppColors.error, ), ); if (success) { ref.invalidate(shareAccountProvider(accountSequence)); } } } }, style: ElevatedButton.styleFrom(backgroundColor: AppColors.up), child: const Text('确认买入'), ), ], ), ); } void _showSellDialog(BuildContext context, WidgetRef ref, String accountSequence) { final controller = TextEditingController(); showDialog( context: context, builder: (context) => AlertDialog( title: const Text('卖出积分股'), content: TextField( controller: controller, keyboardType: const TextInputType.numberWithOptions(decimal: true), decoration: const InputDecoration( labelText: '卖出数量', hintText: '请输入卖出数量', suffixText: '股', ), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('取消'), ), ElevatedButton( onPressed: () async { if (controller.text.isNotEmpty) { final success = await ref .read(tradingNotifierProvider.notifier) .sellShares(accountSequence, controller.text); if (context.mounted) { Navigator.pop(context); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(success ? '卖出订单已提交' : '卖出失败'), backgroundColor: success ? AppColors.down : AppColors.error, ), ); if (success) { ref.invalidate(shareAccountProvider(accountSequence)); } } } }, style: ElevatedButton.styleFrom(backgroundColor: AppColors.down), child: const Text('确认卖出'), ), ], ), ); } }