import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../../core/constants/app_colors.dart'; import '../../../data/models/coin.dart'; import '../../../providers/market_provider.dart'; import '../../../providers/asset_provider.dart'; /// 交易页面 class TradePage extends StatefulWidget { const TradePage({super.key}); @override State createState() => _TradePageState(); } class _TradePageState extends State with AutomaticKeepAliveClientMixin { @override bool get wantKeepAlive => true; int _tradeType = 0; // 0=买入, 1=卖出 Coin? _selectedCoin; final _priceController = TextEditingController(); final _quantityController = TextEditingController(); @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { _loadData(); }); } void _loadData() { context.read().loadCoins(); context.read().loadOverview(); } @override void dispose() { _priceController.dispose(); _quantityController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { super.build(context); return Scaffold( backgroundColor: AppColors.background, body: Consumer2( builder: (context, market, asset, _) { return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( children: [ _buildCoinSelector(market), const SizedBox(height: 16), _buildPriceCard(), const SizedBox(height: 16), _buildTradeForm(asset), const SizedBox(height: 16), _buildTradeButton(), ], ), ); }, ), ); } Widget _buildCoinSelector(MarketProvider market) { final coins = market.allCoins; if (_selectedCoin == null && coins.isNotEmpty) { _selectedCoin = coins.first; _priceController.text = _selectedCoin!.formattedPrice; } return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.cardBackground, borderRadius: BorderRadius.circular(16), ), child: Row( children: [ Container( width: 44, height: 44, decoration: BoxDecoration( color: AppColors.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(22), ), child: Center( child: Text( _selectedCoin?.displayIcon ?? '?', style: const TextStyle(fontSize: 20, color: AppColors.primary), ), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _selectedCoin != null ? '${_selectedCoin!.code}/USDT' : '选择币种', style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: AppColors.textPrimary, ), ), const SizedBox(height: 4), Text( _selectedCoin != null ? _selectedCoin!.name : '点击选择交易对', style: const TextStyle(fontSize: 12, color: AppColors.textSecondary), ), ], ), ), const Icon(Icons.chevron_right, color: AppColors.textSecondary), ], ), ); } Widget _buildPriceCard() { if (_selectedCoin == null) { return const SizedBox.shrink(); } final coin = _selectedCoin!; return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.cardBackground, borderRadius: BorderRadius.circular(16), ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text('最新价', style: TextStyle(fontSize: 12, color: AppColors.textSecondary)), const SizedBox(height: 4), Text( '\$${coin.formattedPrice}', style: const TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: AppColors.textPrimary, ), ), ], ), Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: coin.isUp ? AppColors.up.withOpacity(0.2) : AppColors.down.withOpacity(0.2), borderRadius: BorderRadius.circular(8), ), child: Text( coin.formattedChange, style: TextStyle( fontSize: 16, color: coin.isUp ? AppColors.up : AppColors.down, fontWeight: FontWeight.w600, ), ), ), ], ), ], ), ); } Widget _buildTradeForm(AssetProvider asset) { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.cardBackground, borderRadius: BorderRadius.circular(16), ), child: Column( children: [ // 买入/卖出切换 Row( children: [ Expanded( child: GestureDetector( onTap: () => setState(() => _tradeType = 0), child: Container( padding: const EdgeInsets.symmetric(vertical: 12), decoration: BoxDecoration( color: _tradeType == 0 ? AppColors.up : Colors.transparent, borderRadius: BorderRadius.circular(8), ), child: Center( child: Text( '买入', style: TextStyle( color: _tradeType == 0 ? Colors.white : AppColors.up, fontWeight: FontWeight.w600, ), ), ), ), ), ), const SizedBox(width: 16), Expanded( child: GestureDetector( onTap: () => setState(() => _tradeType = 1), child: Container( padding: const EdgeInsets.symmetric(vertical: 12), decoration: BoxDecoration( color: _tradeType == 1 ? AppColors.down : Colors.transparent, borderRadius: BorderRadius.circular(8), ), child: Center( child: Text( '卖出', style: TextStyle( color: _tradeType == 1 ? Colors.white : AppColors.down, fontWeight: FontWeight.w600, ), ), ), ), ), ), ], ), const SizedBox(height: 20), // 价格输入 TextField( controller: _priceController, keyboardType: const TextInputType.numberWithOptions(decimal: true), style: const TextStyle(color: AppColors.textPrimary), decoration: const InputDecoration( labelText: '价格(USDT)', suffixText: 'USDT', ), ), const SizedBox(height: 12), // 数量输入 TextField( controller: _quantityController, keyboardType: const TextInputType.numberWithOptions(decimal: true), style: const TextStyle(color: AppColors.textPrimary), decoration: const InputDecoration( labelText: '数量', suffixText: _selectedCoin?.code ?? '', ), ), const SizedBox(height: 12), // 交易金额 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text('交易金额', style: TextStyle(color: AppColors.textSecondary)), Text( '${_calculateAmount()} USDT', style: const TextStyle(color: AppColors.textPrimary, fontWeight: FontWeight.w600), ), ], ), const SizedBox(height: 8), // 可用余额 Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text('可用', style: TextStyle(color: AppColors.textSecondary)), Text( '${asset.overview?.tradeBalance ?? '0.00'} USDT', style: const TextStyle(color: AppColors.textSecondary), ), ], ), ], ), ); } String _calculateAmount() { final price = double.tryParse(_priceController.text) ?? 0; final quantity = double.tryParse(_quantityController.text) ?? 0; return (price * quantity).toStringAsFixed(2); } Widget _buildTradeButton() { final isBuy = _tradeType == 0; return Container( width: double.infinity, height: 48, decoration: BoxDecoration( gradient: isBuy ? AppColors.buyGradient : AppColors.sellGradient, borderRadius: BorderRadius.circular(12), ), child: Center( child: Text( isBuy ? '买入 ${_selectedCoin?.code ?? ''}' : '卖出 ${_selectedCoin?.code ?? ''}', style: const TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.w600, ), ), ), ); } }