From 3e352dbcfebf0974966effa8cc38b026401ad843 Mon Sep 17 00:00:00 2001 From: hailin Date: Sun, 21 Dec 2025 18:20:10 -0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=92=B1=E5=8C=85=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E8=BD=AE=E8=AF=A2=E8=87=AA=E5=8A=A8=E9=87=8D=E8=AF=95?= =?UTF-8?q?=EF=BC=8C=E7=A7=BB=E9=99=A4=E6=89=8B=E5=8A=A8=E9=87=8D=E8=AF=95?= =?UTF-8?q?=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 设计原则:只要钱包不是 ready 状态,就持续轮询并自动重试生成 - 移除 failed 状态和重试按钮(用户无需手动操作) - 非 ready 时自动调用 retryWalletGeneration API(幂等) - 轮询间隔改为60秒(API 1-10分钟幂等) - 只有 ready 时停止轮询 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../providers/wallet_status_provider.dart | 98 +++++++------------ .../presentation/pages/mining_page.dart | 79 +-------------- .../presentation/pages/profile_page.dart | 47 +-------- 3 files changed, 42 insertions(+), 182 deletions(-) diff --git a/frontend/mobile-app/lib/features/auth/presentation/providers/wallet_status_provider.dart b/frontend/mobile-app/lib/features/auth/presentation/providers/wallet_status_provider.dart index 98935333..2a5e54a2 100644 --- a/frontend/mobile-app/lib/features/auth/presentation/providers/wallet_status_provider.dart +++ b/frontend/mobile-app/lib/features/auth/presentation/providers/wallet_status_provider.dart @@ -11,32 +11,27 @@ enum WalletGenerationStatus { unknown, // 未知状态 generating, // 生成中 ready, // 已就绪 - failed, // 生成失败 } /// 钱包状态信息 class WalletStatusState { final WalletGenerationStatus status; - final String? errorMessage; final DateTime? lastChecked; final bool isPolling; const WalletStatusState({ this.status = WalletGenerationStatus.unknown, - this.errorMessage, this.lastChecked, this.isPolling = false, }); WalletStatusState copyWith({ WalletGenerationStatus? status, - String? errorMessage, DateTime? lastChecked, bool? isPolling, }) { return WalletStatusState( status: status ?? this.status, - errorMessage: errorMessage, lastChecked: lastChecked ?? this.lastChecked, isPolling: isPolling ?? this.isPolling, ); @@ -44,10 +39,14 @@ class WalletStatusState { bool get isGenerating => status == WalletGenerationStatus.generating; bool get isReady => status == WalletGenerationStatus.ready; - bool get isFailed => status == WalletGenerationStatus.failed; } /// 钱包状态管理器 +/// +/// 设计原则:只要钱包不是 ready 状态,就持续轮询并自动重试生成 +/// - 轮询间隔:1-10分钟(幂等) +/// - 只有 ready 时停止轮询 +/// - 非 ready 时自动调用 retryWalletGeneration API 触发新的生成过程 class WalletStatusNotifier extends StateNotifier { final AccountService _accountService; final SecureStorage _secureStorage; @@ -58,7 +57,7 @@ class WalletStatusNotifier extends StateNotifier { /// 开始轮询钱包状态 /// - /// 每5秒检查一次,直到钱包就绪或失败 + /// 每60秒检查一次,直到钱包就绪 Future startPolling() async { if (state.isPolling) { debugPrint('[WalletStatusProvider] Already polling, skipping'); @@ -69,17 +68,12 @@ class WalletStatusNotifier extends StateNotifier { state = state.copyWith(isPolling: true); // 立即检查一次 - await _checkWalletStatus(); + await _checkAndRetryIfNeeded(); - // 设置定时器,每5秒检查一次 + // 设置定时器,每60秒检查一次(幂等,1-10分钟间隔) _pollingTimer?.cancel(); - _pollingTimer = Timer.periodic(const Duration(seconds: 5), (_) async { - await _checkWalletStatus(); - - // 如果钱包已就绪或失败,停止轮询 - if (state.isReady || state.isFailed) { - stopPolling(); - } + _pollingTimer = Timer.periodic(const Duration(seconds: 60), (_) async { + await _checkAndRetryIfNeeded(); }); } @@ -91,8 +85,8 @@ class WalletStatusNotifier extends StateNotifier { state = state.copyWith(isPolling: false); } - /// 检查钱包状态 - Future _checkWalletStatus() async { + /// 检查钱包状态,非 ready 时自动重试 + Future _checkAndRetryIfNeeded() async { try { debugPrint('[WalletStatusProvider] Checking wallet status...'); @@ -112,62 +106,46 @@ class WalletStatusNotifier extends StateNotifier { debugPrint( '[WalletStatusProvider] Wallet status: ${walletInfo.status}'); - // 更新状态 - WalletGenerationStatus newStatus; if (walletInfo.isReady) { - newStatus = WalletGenerationStatus.ready; - - // 钱包已就绪,保存标记 + // 钱包已就绪,保存标记并停止轮询 await _secureStorage.write( key: StorageKeys.isWalletReady, value: 'true', ); - debugPrint('[WalletStatusProvider] Wallet is ready, marked in storage'); - } else if (walletInfo.isGenerating) { - newStatus = WalletGenerationStatus.generating; - } else if (walletInfo.isFailed) { - newStatus = WalletGenerationStatus.failed; - } else { - newStatus = WalletGenerationStatus.unknown; - } + debugPrint('[WalletStatusProvider] Wallet is ready, stopping polling'); - state = state.copyWith( - status: newStatus, - lastChecked: DateTime.now(), - errorMessage: null, - ); + state = state.copyWith( + status: WalletGenerationStatus.ready, + lastChecked: DateTime.now(), + ); + + stopPolling(); + } else { + // 非 ready 状态,自动触发重试生成(API 是幂等的) + debugPrint('[WalletStatusProvider] Wallet not ready, triggering retry...'); + + try { + await _accountService.retryWalletGeneration(); + debugPrint('[WalletStatusProvider] Retry triggered successfully'); + } catch (e) { + debugPrint('[WalletStatusProvider] Retry API call failed: $e'); + // 继续轮询,下次再试 + } + + state = state.copyWith( + status: WalletGenerationStatus.generating, + lastChecked: DateTime.now(), + ); + } } catch (e) { debugPrint('[WalletStatusProvider] Error checking wallet status: $e'); + // 出错不停止轮询,继续尝试 state = state.copyWith( - errorMessage: e.toString(), lastChecked: DateTime.now(), ); } } - /// 手动触发重试 - Future retryWalletGeneration() async { - try { - debugPrint('[WalletStatusProvider] Manually retrying wallet generation'); - - // 调用重试 API - await _accountService.retryWalletGeneration(); - - // 重新开始轮询 - state = state.copyWith( - status: WalletGenerationStatus.generating, - errorMessage: null, - ); - - if (!state.isPolling) { - await startPolling(); - } - } catch (e) { - debugPrint('[WalletStatusProvider] Error retrying wallet generation: $e'); - state = state.copyWith(errorMessage: e.toString()); - } - } - @override void dispose() { _pollingTimer?.cancel(); diff --git a/frontend/mobile-app/lib/features/mining/presentation/pages/mining_page.dart b/frontend/mobile-app/lib/features/mining/presentation/pages/mining_page.dart index ee4ed3f7..3edfaa4c 100644 --- a/frontend/mobile-app/lib/features/mining/presentation/pages/mining_page.dart +++ b/frontend/mobile-app/lib/features/mining/presentation/pages/mining_page.dart @@ -13,10 +13,9 @@ enum MonitorStatus { /// 钱包生成状态枚举 enum WalletCreationStatus { - unknown, // 未知 + unknown, // 未知(初始状态) creating, // 创建中(显示"创建账号审核中...") ready, // 已就绪 - failed, // 失败 } /// 监控页面 - 显示监控状态和控制 @@ -45,7 +44,6 @@ class _MiningPageState extends ConsumerState { // 钱包生成状态 WalletCreationStatus _walletStatus = WalletCreationStatus.unknown; - String? _walletError; Timer? _walletPollingTimer; @override @@ -170,19 +168,13 @@ class _MiningPageState extends ConsumerState { setState(() { if (walletInfo.isReady) { _walletStatus = WalletCreationStatus.ready; - _walletError = null; // 钱包已就绪,停止轮询 _walletPollingTimer?.cancel(); debugPrint('[MiningPage] 钱包已就绪,停止轮询'); - } else if (walletInfo.isFailed) { - _walletStatus = WalletCreationStatus.failed; - _walletError = '账号创建失败'; - _walletPollingTimer?.cancel(); - debugPrint('[MiningPage] 钱包创建失败'); } else { + // 非 ready 状态(包括 failed、creating)都继续轮询 _walletStatus = WalletCreationStatus.creating; - _walletError = null; - debugPrint('[MiningPage] 钱包创建中...'); + debugPrint('[MiningPage] 钱包创建中,继续轮询...'); } }); } catch (e) { @@ -191,34 +183,6 @@ class _MiningPageState extends ConsumerState { } } - /// 手动重试钱包生成 - Future _retryWalletGeneration() async { - try { - debugPrint('[MiningPage] 手动重试钱包生成...'); - final accountService = ref.read(accountServiceProvider); - await accountService.retryWalletGeneration(); - - if (!mounted) return; - - // 重置状态并重新开始轮询 - setState(() { - _walletStatus = WalletCreationStatus.creating; - _walletError = null; - }); - - // 重新开始轮询 - _walletPollingTimer?.cancel(); - _startWalletPolling(); - } catch (e) { - debugPrint('[MiningPage] 重试钱包生成失败: $e'); - if (mounted) { - setState(() { - _walletError = '重试失败: $e'; - }); - } - } - } - /// 显示帮助信息 void _showHelpInfo() { showDialog( @@ -433,43 +397,6 @@ class _MiningPageState extends ConsumerState { ), ], ) - else if (_walletStatus == WalletCreationStatus.failed) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - _walletError ?? '账号创建失败', - style: const TextStyle( - fontSize: 16, - fontFamily: 'Inter', - fontWeight: FontWeight.w600, - color: Colors.red, - ), - ), - const SizedBox(height: 4), - GestureDetector( - onTap: _retryWalletGeneration, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 6, - ), - decoration: BoxDecoration( - color: const Color(0xFF8B5A2B), - borderRadius: BorderRadius.circular(4), - ), - child: const Text( - '重试', - style: TextStyle( - fontSize: 14, - fontWeight: FontWeight.w600, - color: Colors.white, - ), - ), - ), - ), - ], - ) else if (_walletStatus == WalletCreationStatus.ready) Text( '序列号$_serialNumber', diff --git a/frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart b/frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart index a291c01c..566f56ae 100644 --- a/frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart +++ b/frontend/mobile-app/lib/features/profile/presentation/pages/profile_page.dart @@ -4079,52 +4079,7 @@ class _ProfilePageState extends ConsumerState { ); } - // 如果钱包生成失败,显示失败状态和重试按钮 - if (walletStatus.isFailed) { - return Row( - children: [ - const Icon( - Icons.error_outline, - size: 16, - color: Color(0xFFD32F2F), - ), - const SizedBox(width: 8), - Text( - '钱包生成失败', - style: const TextStyle( - fontSize: 14, - fontFamily: 'Inter', - height: 1.5, - color: Color(0xFFD32F2F), - ), - ), - const SizedBox(width: 8), - GestureDetector( - onTap: () async { - await ref.read(walletStatusProvider.notifier).retryWalletGeneration(); - }, - child: Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), - decoration: BoxDecoration( - color: const Color(0xFFD4AF37), - borderRadius: BorderRadius.circular(4), - ), - child: const Text( - '重试', - style: TextStyle( - fontSize: 12, - fontFamily: 'Inter', - color: Colors.white, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - ], - ); - } - - // 默认情况(unknown状态)显示"创建账号审核中..." + // 默认情况(unknown/generating状态)显示"创建账号审核中..." return Row( children: [ const SizedBox(