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;