111
This commit is contained in:
@@ -15,14 +15,14 @@ import 'components/trade_form_card.dart';
|
||||
import 'components/trade_button.dart';
|
||||
import 'components/confirm_dialog.dart';
|
||||
|
||||
/// 交易页面
|
||||
/// 交易頁面
|
||||
///
|
||||
/// 设计稿 Trade 页面,布局结构:
|
||||
/// - 币种选择器卡片(Coin Selector Card)
|
||||
/// - 价格卡片(Price Card):大号价格 + 涨跌幅徽章 + 副标题
|
||||
/// - 买入/卖出切换(Buy/Sell Toggle)
|
||||
/// - 交易表单卡片(Trade Form Card):金额输入 + 快捷比例 + 计算数量
|
||||
/// - CTA 买入/卖出按钮(Buy/Sell Button)
|
||||
/// 設計稿 Trade 頁面,佈局結構:
|
||||
/// - 幣種選擇器卡片(Coin Selector Card)
|
||||
/// - 價格卡片(Price Card):大號價格 + 漲跌幅徽章 + 副標題
|
||||
/// - 買入/賣出切換(Buy/Sell Toggle)
|
||||
/// - 交易表單卡片(Trade Form Card):金額輸入 + 快捷比例 + 計算數量
|
||||
/// - CTA 買入/賣出按鈕(Buy/Sell Button)
|
||||
class TradePage extends StatefulWidget {
|
||||
final String? initialCoinCode;
|
||||
|
||||
@@ -34,7 +34,7 @@ class TradePage extends StatefulWidget {
|
||||
|
||||
class _TradePageState extends State<TradePage>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
int _tradeType = 0; // 0=买入, 1=卖出
|
||||
int _tradeType = 0; // 0=買入, 1=賣出
|
||||
Coin? _selectedCoin;
|
||||
final _amountController = TextEditingController();
|
||||
bool _isSubmitting = false;
|
||||
@@ -71,14 +71,14 @@ class _TradePageState extends State<TradePage>
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
/// 获取交易账户中 USDT 可用余额
|
||||
/// 獲取交易賬戶中 USDT 可用餘額
|
||||
String get _availableUsdt {
|
||||
final holdings = context.read<AssetProvider>().holdings;
|
||||
final usdt = holdings.where((h) => h.coinCode == 'USDT').firstOrNull;
|
||||
return usdt?.quantity ?? '0';
|
||||
}
|
||||
|
||||
/// 获取交易账户中当前币种的持仓数量
|
||||
/// 獲取交易賬戶中當前幣種的持倉數量
|
||||
String get _availableCoinQty {
|
||||
if (_selectedCoin == null) return '0';
|
||||
final holdings = context.read<AssetProvider>().holdings;
|
||||
@@ -88,7 +88,7 @@ class _TradePageState extends State<TradePage>
|
||||
return pos?.quantity ?? '0';
|
||||
}
|
||||
|
||||
/// 计算可买入/卖出的最大 USDT 金额
|
||||
/// 計算可買入/賣出的最大 USDT 金額
|
||||
String get _maxAmount {
|
||||
if (_selectedCoin == null) return '0';
|
||||
final price = _selectedCoin!.price;
|
||||
@@ -102,7 +102,7 @@ class _TradePageState extends State<TradePage>
|
||||
}
|
||||
}
|
||||
|
||||
/// 计算数量
|
||||
/// 計算數量
|
||||
String get _calculatedQuantity {
|
||||
final amount = double.tryParse(_amountController.text) ?? 0;
|
||||
final price = _selectedCoin?.price ?? 0;
|
||||
@@ -121,11 +121,11 @@ class _TradePageState extends State<TradePage>
|
||||
return SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.fromLTRB(
|
||||
AppSpacing.md, AppSpacing.md, AppSpacing.md, AppSpacing.xl + AppSpacing.sm, // 添加顶部间距
|
||||
AppSpacing.md, AppSpacing.md, AppSpacing.md, AppSpacing.xl + AppSpacing.sm, // 添加頂部間距
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
// 币种选择器卡片
|
||||
// 幣種選擇器卡片
|
||||
CoinSelector(
|
||||
selectedCoin: _selectedCoin,
|
||||
coins: market.allCoins
|
||||
@@ -143,16 +143,16 @@ class _TradePageState extends State<TradePage>
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
// 价格卡片
|
||||
// 價格卡片
|
||||
if (_selectedCoin != null)
|
||||
PriceCard(coin: _selectedCoin!)
|
||||
else
|
||||
PlaceholderCard(
|
||||
message: '请先选择交易币种',
|
||||
message: '請先選擇交易幣種',
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
// 交易表单卡片(内含买入/卖出切换 + 表单)
|
||||
// 交易表單卡片(內含買入/賣出切換 + 表單)
|
||||
TradeFormCard(
|
||||
tradeType: _tradeType,
|
||||
selectedCoin: _selectedCoin,
|
||||
@@ -170,7 +170,7 @@ class _TradePageState extends State<TradePage>
|
||||
),
|
||||
const SizedBox(height: AppSpacing.md),
|
||||
|
||||
// CTA 买入/卖出按钮
|
||||
// CTA 買入/賣出按鈕
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 48,
|
||||
@@ -195,7 +195,7 @@ class _TradePageState extends State<TradePage>
|
||||
if (_selectedCoin == null) return false;
|
||||
final amount = double.tryParse(_amountController.text) ?? 0;
|
||||
if (amount <= 0) return false;
|
||||
// 买入时校验不超过可用USDT
|
||||
// 買入時校驗不超過可用USDT
|
||||
if (_tradeType == 0) {
|
||||
final available = double.tryParse(_availableUsdt) ?? 0;
|
||||
if (amount > available) return false;
|
||||
@@ -243,16 +243,16 @@ class _TradePageState extends State<TradePage>
|
||||
|
||||
if (response.success) {
|
||||
_amountController.clear();
|
||||
// 刷新资产数据
|
||||
// 刷新資產數據
|
||||
context.read<AssetProvider>().refreshAll(force: true);
|
||||
_showResultDialog(true, '${isBuy ? '买入' : '卖出'}成功',
|
||||
_showResultDialog(true, '${isBuy ? '買入' : '賣出'}成功',
|
||||
'$quantity $coinCode @ $price USDT');
|
||||
} else {
|
||||
_showResultDialog(false, '交易失败', response.message ?? '请稍后重试');
|
||||
_showResultDialog(false, '交易失敗', response.message ?? '請稍後重試');
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
_showResultDialog(false, '交易失败', e.toString());
|
||||
_showResultDialog(false, '交易失敗', e.toString());
|
||||
}
|
||||
} finally {
|
||||
if (mounted) setState(() => _isSubmitting = false);
|
||||
@@ -279,7 +279,7 @@ class _TradePageState extends State<TradePage>
|
||||
description: Text(message),
|
||||
actions: [
|
||||
ShadButton(
|
||||
child: const Text('确定'),
|
||||
child: const Text('確定'),
|
||||
onPressed: () => Navigator.of(ctx).pop(),
|
||||
),
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user