diff --git a/frontend/mobile-app/lib/features/auth/presentation/pages/splash_page.dart b/frontend/mobile-app/lib/features/auth/presentation/pages/splash_page.dart index fa6cdbb6..5fbfb918 100644 --- a/frontend/mobile-app/lib/features/auth/presentation/pages/splash_page.dart +++ b/frontend/mobile-app/lib/features/auth/presentation/pages/splash_page.dart @@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../../core/constants/app_constants.dart'; import '../../../../routes/route_paths.dart'; +import '../../../../routes/app_router.dart'; import '../../../../bootstrap.dart'; import '../providers/auth_provider.dart'; @@ -38,20 +39,38 @@ class _SplashPageState extends ConsumerState { final authState = ref.read(authProvider); // 根据认证状态决定跳转目标 - String targetRoute; + // 优先级: + // 1. 钱包已创建且已备份 → 主页面 + // 2. 账号已创建但钱包未完成 → 备份助记词页面 + // 3. 首次打开或未看过向导 → 向导页 + // 4. 其他情况 → 创建账户页面 if (authState.isWalletCreated) { - // 已创建钱包,进入主页面(龙虎榜) - targetRoute = RoutePaths.ranking; + // 已创建钱包且已备份,进入主页面(龙虎榜) + debugPrint('[SplashPage] 钱包已创建且已备份 → 跳转到龙虎榜'); + context.go(RoutePaths.ranking); + } else if (authState.isAccountCreated && authState.userSerialNum != null) { + // 账号已创建但钱包未完成(可能正在生成或未备份),直接进入备份助记词页面 + debugPrint('[SplashPage] 账号已创建但钱包未完成 → 跳转到备份助记词页面'); + debugPrint('[SplashPage] userSerialNum: ${authState.userSerialNum}, isWalletReady: ${authState.isWalletReady}'); + context.go( + RoutePaths.backupMnemonic, + extra: BackupMnemonicParams( + userSerialNum: authState.userSerialNum!, + referralCode: authState.referralCode, + ), + ); } else if (authState.isFirstLaunch || !authState.hasSeenGuide) { // 首次打开或未看过向导,进入向导页 - targetRoute = RoutePaths.guide; + debugPrint('[SplashPage] 首次打开或未看过向导 → 跳转到向导页'); + context.go(RoutePaths.guide); } else { // 已看过向导但未创建钱包,直接进入创建账户页面 - targetRoute = RoutePaths.onboarding; + debugPrint('[SplashPage] 已看过向导但未创建钱包 → 跳转到创建账户页面'); + context.go(RoutePaths.onboarding); } - // 跳转到目标页面 - context.go(targetRoute); + // 获取目标路由用于后续检查 + final targetRoute = authState.isWalletCreated ? RoutePaths.ranking : null; // 延迟检查应用更新(跳转后执行,避免阻塞启动) if (targetRoute == RoutePaths.ranking) { diff --git a/frontend/mobile-app/lib/features/auth/presentation/providers/auth_provider.dart b/frontend/mobile-app/lib/features/auth/presentation/providers/auth_provider.dart index 9dda7896..434a99f9 100644 --- a/frontend/mobile-app/lib/features/auth/presentation/providers/auth_provider.dart +++ b/frontend/mobile-app/lib/features/auth/presentation/providers/auth_provider.dart @@ -17,6 +17,14 @@ class AuthState { final bool isFirstLaunch; final bool hasSeenGuide; final String? errorMessage; + // 新增:账号是否已创建(但钱包可能还未就绪) + final bool isAccountCreated; + // 新增:钱包是否已就绪 + final bool isWalletReady; + // 新增:用户序列号(用于跳转到备份助记词页面) + final int? userSerialNum; + // 新增:推荐码 + final String? referralCode; const AuthState({ this.status = AuthStatus.initial, @@ -25,6 +33,10 @@ class AuthState { this.isFirstLaunch = true, this.hasSeenGuide = false, this.errorMessage, + this.isAccountCreated = false, + this.isWalletReady = false, + this.userSerialNum, + this.referralCode, }); AuthState copyWith({ @@ -34,6 +46,10 @@ class AuthState { bool? isFirstLaunch, bool? hasSeenGuide, String? errorMessage, + bool? isAccountCreated, + bool? isWalletReady, + int? userSerialNum, + String? referralCode, }) { return AuthState( status: status ?? this.status, @@ -42,6 +58,10 @@ class AuthState { isFirstLaunch: isFirstLaunch ?? this.isFirstLaunch, hasSeenGuide: hasSeenGuide ?? this.hasSeenGuide, errorMessage: errorMessage, + isAccountCreated: isAccountCreated ?? this.isAccountCreated, + isWalletReady: isWalletReady ?? this.isWalletReady, + userSerialNum: userSerialNum ?? this.userSerialNum, + referralCode: referralCode ?? this.referralCode, ); } } @@ -59,22 +79,64 @@ class AuthNotifier extends StateNotifier { final isFirstLaunchStr = await _secureStorage.read(key: StorageKeys.isFirstLaunch); final isFirstLaunch = isFirstLaunchStr == null || isFirstLaunchStr != 'false'; - // 检查钱包状态 + // 检查账号是否已创建 + final isAccountCreatedStr = await _secureStorage.read(key: StorageKeys.isAccountCreated); + final isAccountCreated = isAccountCreatedStr == 'true'; + + // 检查钱包是否已就绪 + final isWalletReadyStr = await _secureStorage.read(key: StorageKeys.isWalletReady); + final isWalletReady = isWalletReadyStr == 'true'; + + // 检查助记词是否已备份 + final isMnemonicBackedUpStr = await _secureStorage.read(key: StorageKeys.isMnemonicBackedUp); + final isMnemonicBackedUp = isMnemonicBackedUpStr == 'true'; + + // 获取用户序列号和推荐码(用于跳转到备份页面) + final userSerialNumStr = await _secureStorage.read(key: StorageKeys.userSerialNum); + final userSerialNum = userSerialNumStr != null ? int.tryParse(userSerialNumStr) : null; + final referralCode = await _secureStorage.read(key: StorageKeys.referralCode); + + // 旧版兼容:检查旧的 walletAddress 字段 final walletAddress = await _secureStorage.read(key: StorageKeys.walletAddress); - final isWalletCreated = walletAddress != null && walletAddress.isNotEmpty; + final hasLegacyWallet = walletAddress != null && walletAddress.isNotEmpty; + + // 综合判断钱包是否已创建完成 + // 1. 新版:isWalletReady == true 且 isMnemonicBackedUp == true + // 2. 旧版兼容:有 walletAddress + final isWalletCreated = (isWalletReady && isMnemonicBackedUp) || hasLegacyWallet; if (isWalletCreated) { + // 钱包已创建且备份完成,进入主页面 state = state.copyWith( status: AuthStatus.authenticated, walletAddress: walletAddress, isWalletCreated: true, + isAccountCreated: true, + isWalletReady: true, isFirstLaunch: false, hasSeenGuide: true, + userSerialNum: userSerialNum, + referralCode: referralCode, ); - } else { + } else if (isAccountCreated) { + // 账号已创建但钱包未完成(可能正在生成或未备份) state = state.copyWith( status: AuthStatus.unauthenticated, isWalletCreated: false, + isAccountCreated: true, + isWalletReady: isWalletReady, + isFirstLaunch: false, + hasSeenGuide: true, + userSerialNum: userSerialNum, + referralCode: referralCode, + ); + } else { + // 账号未创建 + state = state.copyWith( + status: AuthStatus.unauthenticated, + isWalletCreated: false, + isAccountCreated: false, + isWalletReady: false, isFirstLaunch: isFirstLaunch, hasSeenGuide: !isFirstLaunch, );