From 64d998c7b33cddb0d330afe44f3b6eda173a3a1d Mon Sep 17 00:00:00 2001 From: hailin Date: Sat, 31 Jan 2026 22:29:33 -0800 Subject: [PATCH] =?UTF-8?q?fix(trading):=20=E5=8D=96=E5=87=BA=E9=87=91?= =?UTF-8?q?=E9=A2=9D=E8=B6=85=E8=BF=87=E5=8F=AF=E7=94=A8=E7=A7=AF=E5=88=86?= =?UTF-8?q?=E8=82=A1=E6=97=B6=E6=8F=90=E7=A4=BA=E5=B9=B6=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 _getSellValidationError 校验方法 - 输入金额反算的积分股数量 > 可用余额时显示红色提示 - 校验失败时禁用"确认交易"按钮(灰色) Co-Authored-By: Claude Opus 4.5 --- .../pages/trading/trading_page.dart | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/frontend/mining-app/lib/presentation/pages/trading/trading_page.dart b/frontend/mining-app/lib/presentation/pages/trading/trading_page.dart index 7f42e065..e301640f 100644 --- a/frontend/mining-app/lib/presentation/pages/trading/trading_page.dart +++ b/frontend/mining-app/lib/presentation/pages/trading/trading_page.dart @@ -645,10 +645,19 @@ class _TradingPageState extends ConsumerState { _selectedTab == 0 ? availableCash : null, currentPrice, ), - // 卖出时显示金额输入框(双向联动) + // 卖出时显示金额输入框(双向联动)+ 余额校验 if (_selectedTab == 1) ...[ const SizedBox(height: 16), _buildAmountInput(tradingShareBalance, currentPrice), + // 积分股不足提示 + if (_getSellValidationError(tradingShareBalance) != null) + Padding( + padding: const EdgeInsets.only(top: 8), + child: Text( + _getSellValidationError(tradingShareBalance)!, + style: const TextStyle(fontSize: 12, color: _red), + ), + ), ], const SizedBox(height: 16), // 买入时显示预计支出(卖出时金额输入框已替代预计获得) @@ -701,14 +710,17 @@ class _TradingPageState extends ConsumerState { ), ), const SizedBox(height: 24), - // 提交按钮 - SizedBox( + // 提交按钮(卖出时校验积分股余额) + Builder(builder: (context) { + final sellError = _selectedTab == 1 ? _getSellValidationError(tradingShareBalance) : null; + final isDisabled = sellError != null; + return SizedBox( width: double.infinity, height: 48, child: ElevatedButton( - onPressed: _handleTrade, + onPressed: isDisabled ? null : _handleTrade, style: ElevatedButton.styleFrom( - backgroundColor: _orange, + backgroundColor: isDisabled ? Colors.grey : _orange, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), @@ -722,7 +734,8 @@ class _TradingPageState extends ConsumerState { ), ), ), - ), + ); + }), ], ], ), @@ -957,6 +970,17 @@ class _TradingPageState extends ConsumerState { ); } + /// 卖出校验:返回错误信息,null 表示通过 + String? _getSellValidationError(String tradingShareBalance) { + final quantity = double.tryParse(_quantityController.text) ?? 0; + final available = double.tryParse(tradingShareBalance) ?? 0; + if (quantity <= 0) return null; // 空输入不提示 + if (quantity > available) { + return '交易账户积分股不足,需要 ${quantity.toStringAsFixed(4)},可用 ${formatAmount(tradingShareBalance)}'; + } + return null; + } + /// 获取卖出系数:(1 + burnMultiplier) × price × 0.9 double _getSellFactor() { final price = double.tryParse(_priceController.text) ?? 0;