From d5fee8d8c6b3fd47a2b15435c9450f2fdceed00d Mon Sep 17 00:00:00 2001 From: hailin Date: Sat, 3 Jan 2026 07:38:57 -0800 Subject: [PATCH] feat(trading): enable one-click settlement button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 开放兑换页面的"一键结算"功能: - 有可结算收益时:显示"一键结算",按钮可点击(金色) - 无可结算收益时:显示"暂无可结算收益",按钮禁用(半透明) - 结算中:显示加载动画,防止重复点击 - 使用 rewardService.settleToBalance() API 执行结算 - 结算成功后自动刷新页面数据 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../presentation/pages/trading_page.dart | 82 +++++++++++-------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/frontend/mobile-app/lib/features/trading/presentation/pages/trading_page.dart b/frontend/mobile-app/lib/features/trading/presentation/pages/trading_page.dart index d89c1488..111ed8c5 100644 --- a/frontend/mobile-app/lib/features/trading/presentation/pages/trading_page.dart +++ b/frontend/mobile-app/lib/features/trading/presentation/pages/trading_page.dart @@ -93,7 +93,7 @@ class _TradingPageState extends ConsumerState { builder: (context) => AlertDialog( title: const Text('确认结算'), content: Text( - '确定将 ${_formatNumber(_settleableAmount)} 绿积分 结算为 ${_getCurrencyName(_selectedCurrency)} 吗?', + '确定将 ${_formatNumber(_settleableAmount)} 绿积分 结算到钱包余额吗?', ), actions: [ TextButton( @@ -122,26 +122,27 @@ class _TradingPageState extends ConsumerState { try { debugPrint('[TradingPage] 开始结算...'); - debugPrint('[TradingPage] 金额: $_settleableAmount USDT'); - debugPrint('[TradingPage] 币种: ${_getCurrencyName(_selectedCurrency)}'); + debugPrint('[TradingPage] 金额: $_settleableAmount 绿积分'); - final walletService = ref.read(walletServiceProvider); - final orderId = await walletService.settleRewards( - usdtAmount: _settleableAmount, - settleCurrency: _getCurrencyName(_selectedCurrency), - ); + // 使用 reward-service 的 settleToBalance API + final rewardService = ref.read(rewardServiceProvider); + final result = await rewardService.settleToBalance(); - debugPrint('[TradingPage] 结算成功: orderId=$orderId'); + if (result.success) { + debugPrint('[TradingPage] 结算成功: settlementId=${result.settlementId}, amount=${result.settledUsdtAmount}'); - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('结算成功'), - backgroundColor: Color(0xFFD4AF37), - ), - ); - // 刷新钱包数据 - _loadWalletData(); + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('结算成功,${result.settledUsdtAmount.toStringAsFixed(2)} 绿积分已转入钱包余额'), + backgroundColor: const Color(0xFFD4AF37), + ), + ); + // 刷新钱包数据 + _loadWalletData(); + } + } else { + throw Exception(result.error ?? '结算失败'); } } catch (e) { debugPrint('[TradingPage] 结算失败: $e'); @@ -371,33 +372,44 @@ class _TradingPageState extends ConsumerState { } /// 构建一键结算按钮 - /// 注意:一键结算功能暂时禁用 Widget _buildSettlementButton() { - // 功能暂时禁用,始终不可点击 - const bool canSettle = false; + // 根据可结算金额判断是否可点击 + final bool canSettle = _settleableAmount > 0 && !_isSettling; + return Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: GestureDetector( - onTap: null, // 功能暂时禁用 + onTap: canSettle ? _onSettlement : null, child: Container( width: double.infinity, height: 56, decoration: BoxDecoration( - color: const Color(0x80D4AF37), // 禁用状态颜色 + color: canSettle + ? const Color(0xFFD4AF37) // 启用状态:金色 + : const Color(0x80D4AF37), // 禁用状态:半透明金色 borderRadius: BorderRadius.circular(12), ), - child: const Center( - child: Text( - '一键结算(暂未开放)', - style: TextStyle( - fontSize: 16, - fontFamily: 'Inter', - fontWeight: FontWeight.w700, - height: 1.5, - letterSpacing: 0.24, - color: Colors.white, - ), - ), + child: Center( + child: _isSettling + ? const SizedBox( + width: 24, + height: 24, + child: CircularProgressIndicator( + strokeWidth: 2, + color: Colors.white, + ), + ) + : Text( + canSettle ? '一键结算' : '暂无可结算收益', + style: const TextStyle( + fontSize: 16, + fontFamily: 'Inter', + fontWeight: FontWeight.w700, + height: 1.5, + letterSpacing: 0.24, + color: Colors.white, + ), + ), ), ), ),