From 37aab77e7a6519692edc62400833c22e166304cb Mon Sep 17 00:00:00 2001 From: hailin Date: Sat, 6 Dec 2025 20:03:36 -0800 Subject: [PATCH] feat(mobile-app): add detailed debug logging for account creation flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add comprehensive debugPrint logging with [Tag] prefixes: - [AccountService]: API calls, storage operations, responses - [OnboardingPage]: account status check, creation flow - [BackupMnemonicPage]: wallet info loading, polling state Logging includes: - Request/response details with masked sensitive data - Stack traces for error handling - Polling count and timing for wallet generation - User interaction tracking 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../lib/core/services/account_service.dart | 200 +++++++++++++++--- .../pages/backup_mnemonic_page.dart | 73 ++++++- .../presentation/pages/onboarding_page.dart | 34 ++- 3 files changed, 268 insertions(+), 39 deletions(-) diff --git a/frontend/mobile-app/lib/core/services/account_service.dart b/frontend/mobile-app/lib/core/services/account_service.dart index 56e803c4..d8bb35f4 100644 --- a/frontend/mobile-app/lib/core/services/account_service.dart +++ b/frontend/mobile-app/lib/core/services/account_service.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'package:device_info_plus/device_info_plus.dart'; +import 'package:flutter/foundation.dart'; import 'package:uuid/uuid.dart'; import '../network/api_client.dart'; import '../storage/secure_storage.dart'; @@ -44,6 +45,10 @@ class DeviceHardwareInfo { if (sdkInt != null) 'sdkInt': sdkInt, if (isPhysicalDevice != null) 'isPhysicalDevice': isPhysicalDevice, }; + + @override + String toString() => + 'DeviceHardwareInfo(brand: $brand, model: $model, platform: $platform, osVersion: $osVersion)'; } /// 创建账号请求 @@ -64,6 +69,10 @@ class CreateAccountRequest { if (inviterReferralCode != null) 'inviterReferralCode': inviterReferralCode, }; + + @override + String toString() => + 'CreateAccountRequest(deviceId: $deviceId, inviterReferralCode: $inviterReferralCode)'; } /// 创建账号响应 (新版 - 不含钱包信息) @@ -85,6 +94,7 @@ class CreateAccountResponse { }); factory CreateAccountResponse.fromJson(Map json) { + debugPrint('[AccountService] 解析 CreateAccountResponse: ${json.keys.toList()}'); return CreateAccountResponse( userSerialNum: json['userSerialNum'] as int, referralCode: json['referralCode'] as String, @@ -94,6 +104,10 @@ class CreateAccountResponse { refreshToken: json['refreshToken'] as String, ); } + + @override + String toString() => + 'CreateAccountResponse(userSerialNum: $userSerialNum, username: $username, referralCode: $referralCode)'; } /// 钱包信息响应 @@ -109,6 +123,7 @@ class WalletInfoResponse { }); factory WalletInfoResponse.fromJson(Map json) { + debugPrint('[AccountService] 解析 WalletInfoResponse: status=${json['status']}'); return WalletInfoResponse( status: json['status'] as String, walletAddresses: json['walletAddresses'] != null @@ -122,6 +137,10 @@ class WalletInfoResponse { bool get isReady => status == 'ready'; bool get isGenerating => status == 'generating'; bool get isFailed => status == 'failed'; + + @override + String toString() => + 'WalletInfoResponse(status: $status, hasAddresses: ${walletAddresses != null}, hasMnemonic: ${mnemonic != null})'; } /// 钱包地址 @@ -137,12 +156,23 @@ class WalletAddresses { }); factory WalletAddresses.fromJson(Map json) { + debugPrint('[AccountService] 解析 WalletAddresses: kava=${_maskAddress(json['kava'])}, dst=${_maskAddress(json['dst'])}, bsc=${_maskAddress(json['bsc'])}'); return WalletAddresses( kava: json['kava'] as String, dst: json['dst'] as String, bsc: json['bsc'] as String, ); } + + @override + String toString() => + 'WalletAddresses(kava: ${_maskAddress(kava)}, dst: ${_maskAddress(dst)}, bsc: ${_maskAddress(bsc)})'; +} + +/// 遮蔽地址中间部分,用于日志输出 +String _maskAddress(String? address) { + if (address == null || address.length <= 10) return address ?? 'null'; + return '${address.substring(0, 6)}...${address.substring(address.length - 4)}'; } /// 账号服务 @@ -152,29 +182,40 @@ class AccountService { final ApiClient _apiClient; final SecureStorage _secureStorage; + static const String _tag = '[AccountService]'; + AccountService({ required ApiClient apiClient, required SecureStorage secureStorage, }) : _apiClient = apiClient, - _secureStorage = secureStorage; + _secureStorage = secureStorage { + debugPrint('$_tag 初始化完成'); + } /// 获取设备唯一标识符 /// /// Android: 使用 Android ID (64位十六进制字符串) /// iOS: 使用 identifierForVendor Future getDeviceId() async { + debugPrint('$_tag getDeviceId() - 开始获取设备ID'); final deviceInfoPlugin = DeviceInfoPlugin(); if (Platform.isAndroid) { final info = await deviceInfoPlugin.androidInfo; - return info.id; // Android ID + final deviceId = info.id; + debugPrint('$_tag getDeviceId() - Android ID: ${_maskAddress(deviceId)}'); + return deviceId; } else if (Platform.isIOS) { final info = await deviceInfoPlugin.iosInfo; - return info.identifierForVendor ?? const Uuid().v4(); + final deviceId = info.identifierForVendor ?? const Uuid().v4(); + debugPrint('$_tag getDeviceId() - iOS identifierForVendor: ${_maskAddress(deviceId)}'); + return deviceId; } // 其他平台回退到 UUID - return const Uuid().v4(); + final uuid = const Uuid().v4(); + debugPrint('$_tag getDeviceId() - 其他平台,使用 UUID: ${_maskAddress(uuid)}'); + return uuid; } /// 获取设备硬件信息 @@ -182,11 +223,12 @@ class AccountService { /// Android: 完整硬件信息 /// iOS: 基本信息 Future getDeviceHardwareInfo() async { + debugPrint('$_tag getDeviceHardwareInfo() - 开始获取设备硬件信息'); final deviceInfoPlugin = DeviceInfoPlugin(); if (Platform.isAndroid) { final info = await deviceInfoPlugin.androidInfo; - return DeviceHardwareInfo( + final hardwareInfo = DeviceHardwareInfo( brand: info.brand, manufacturer: info.manufacturer, model: info.model, @@ -198,9 +240,11 @@ class AccountService { sdkInt: info.version.sdkInt, isPhysicalDevice: info.isPhysicalDevice, ); + debugPrint('$_tag getDeviceHardwareInfo() - Android: $hardwareInfo'); + return hardwareInfo; } else if (Platform.isIOS) { final info = await deviceInfoPlugin.iosInfo; - return DeviceHardwareInfo( + final hardwareInfo = DeviceHardwareInfo( brand: 'Apple', manufacturer: 'Apple', model: info.model, @@ -209,9 +253,12 @@ class AccountService { platform: 'ios', isPhysicalDevice: info.isPhysicalDevice, ); + debugPrint('$_tag getDeviceHardwareInfo() - iOS: $hardwareInfo'); + return hardwareInfo; } // 其他平台返回空信息 + debugPrint('$_tag getDeviceHardwareInfo() - 其他平台,返回空信息'); return DeviceHardwareInfo(); } @@ -221,37 +268,57 @@ class AccountService { Future createAccount({ String? inviterReferralCode, }) async { + debugPrint('$_tag createAccount() - 开始创建账号'); + debugPrint('$_tag createAccount() - 邀请码: ${inviterReferralCode ?? "无"}'); + try { // 获取设备ID (必填) final deviceId = await getDeviceId(); + debugPrint('$_tag createAccount() - 获取设备ID成功'); + // 获取设备硬件信息 (可选) final deviceName = await getDeviceHardwareInfo(); + debugPrint('$_tag createAccount() - 获取设备硬件信息成功'); + + final request = CreateAccountRequest( + deviceId: deviceId, + deviceName: deviceName, + inviterReferralCode: inviterReferralCode, + ); + debugPrint('$_tag createAccount() - 请求参数: $request'); // 调用 API + debugPrint('$_tag createAccount() - 调用 POST /user/auto-create'); final response = await _apiClient.post( '/user/auto-create', - data: CreateAccountRequest( - deviceId: deviceId, - deviceName: deviceName, - inviterReferralCode: inviterReferralCode, - ).toJson(), + data: request.toJson(), ); + debugPrint('$_tag createAccount() - API 响应状态码: ${response.statusCode}'); if (response.data == null) { + debugPrint('$_tag createAccount() - 错误: API 返回空响应'); throw const ApiException('创建账号失败: 空响应'); } + debugPrint('$_tag createAccount() - 解析响应数据'); final result = CreateAccountResponse.fromJson( response.data as Map, ); + debugPrint('$_tag createAccount() - 解析成功: $result'); // 保存账号数据到安全存储 + debugPrint('$_tag createAccount() - 保存账号数据到安全存储'); await _saveAccountData(result, deviceId); + debugPrint('$_tag createAccount() - 账号数据保存成功'); + debugPrint('$_tag createAccount() - 账号创建完成'); return result; - } on ApiException { + } on ApiException catch (e) { + debugPrint('$_tag createAccount() - API 异常: $e'); rethrow; - } catch (e) { + } catch (e, stackTrace) { + debugPrint('$_tag createAccount() - 未知异常: $e'); + debugPrint('$_tag createAccount() - 堆栈: $stackTrace'); throw ApiException('创建账号失败: $e'); } } @@ -260,26 +327,43 @@ class AccountService { /// /// 用 userSerialNum 查询钱包生成状态和助记词 Future getWalletInfo(int userSerialNum) async { + debugPrint('$_tag getWalletInfo() - 开始获取钱包信息'); + debugPrint('$_tag getWalletInfo() - userSerialNum: $userSerialNum'); + try { + debugPrint('$_tag getWalletInfo() - 调用 GET /user/$userSerialNum/wallet'); final response = await _apiClient.get('/user/$userSerialNum/wallet'); + debugPrint('$_tag getWalletInfo() - API 响应状态码: ${response.statusCode}'); if (response.data == null) { + debugPrint('$_tag getWalletInfo() - 错误: API 返回空响应'); throw const ApiException('获取钱包信息失败: 空响应'); } + debugPrint('$_tag getWalletInfo() - 解析响应数据'); final result = WalletInfoResponse.fromJson( response.data as Map, ); + debugPrint('$_tag getWalletInfo() - 解析成功: $result'); // 如果钱包已就绪,保存钱包地址和助记词 if (result.isReady) { + debugPrint('$_tag getWalletInfo() - 钱包已就绪,保存钱包数据'); await _saveWalletData(result); + debugPrint('$_tag getWalletInfo() - 钱包数据保存成功'); + } else if (result.isGenerating) { + debugPrint('$_tag getWalletInfo() - 钱包生成中,需要继续轮询'); + } else if (result.isFailed) { + debugPrint('$_tag getWalletInfo() - 钱包生成失败'); } return result; - } on ApiException { + } on ApiException catch (e) { + debugPrint('$_tag getWalletInfo() - API 异常: $e'); rethrow; - } catch (e) { + } catch (e, stackTrace) { + debugPrint('$_tag getWalletInfo() - 未知异常: $e'); + debugPrint('$_tag getWalletInfo() - 堆栈: $stackTrace'); throw ApiException('获取钱包信息失败: $e'); } } @@ -289,150 +373,218 @@ class AccountService { CreateAccountResponse response, String deviceId, ) async { + debugPrint('$_tag _saveAccountData() - 开始保存账号数据'); + // 保存用户序列号 + debugPrint('$_tag _saveAccountData() - 保存 userSerialNum: ${response.userSerialNum}'); await _secureStorage.write( key: StorageKeys.userSerialNum, value: response.userSerialNum.toString(), ); + + debugPrint('$_tag _saveAccountData() - 保存 referralCode: ${response.referralCode}'); await _secureStorage.write( key: StorageKeys.referralCode, value: response.referralCode, ); // 保存用户信息 + debugPrint('$_tag _saveAccountData() - 保存 username: ${response.username}'); await _secureStorage.write( key: StorageKeys.username, value: response.username, ); + + debugPrint('$_tag _saveAccountData() - 保存 avatarSvg (长度: ${response.avatarSvg.length})'); await _secureStorage.write( key: StorageKeys.avatarSvg, value: response.avatarSvg, ); // 保存 Token + debugPrint('$_tag _saveAccountData() - 保存 accessToken (长度: ${response.accessToken.length})'); await _secureStorage.write( key: StorageKeys.accessToken, value: response.accessToken, ); + + debugPrint('$_tag _saveAccountData() - 保存 refreshToken (长度: ${response.refreshToken.length})'); await _secureStorage.write( key: StorageKeys.refreshToken, value: response.refreshToken, ); // 保存设备 ID + debugPrint('$_tag _saveAccountData() - 保存 deviceId: ${_maskAddress(deviceId)}'); await _secureStorage.write( key: StorageKeys.deviceId, value: deviceId, ); // 标记账号已创建 + debugPrint('$_tag _saveAccountData() - 标记账号已创建'); await _secureStorage.write( key: StorageKeys.isAccountCreated, value: 'true', ); + + debugPrint('$_tag _saveAccountData() - 账号数据保存完成'); } /// 保存钱包数据 Future _saveWalletData(WalletInfoResponse response) async { + debugPrint('$_tag _saveWalletData() - 开始保存钱包数据'); + if (response.walletAddresses != null) { + debugPrint('$_tag _saveWalletData() - 保存 BSC 地址: ${_maskAddress(response.walletAddresses!.bsc)}'); await _secureStorage.write( key: StorageKeys.walletAddressBsc, value: response.walletAddresses!.bsc, ); + + debugPrint('$_tag _saveWalletData() - 保存 KAVA 地址: ${_maskAddress(response.walletAddresses!.kava)}'); await _secureStorage.write( key: StorageKeys.walletAddressKava, value: response.walletAddresses!.kava, ); + + debugPrint('$_tag _saveWalletData() - 保存 DST 地址: ${_maskAddress(response.walletAddresses!.dst)}'); await _secureStorage.write( key: StorageKeys.walletAddressDst, value: response.walletAddresses!.dst, ); + } else { + debugPrint('$_tag _saveWalletData() - 警告: walletAddresses 为空'); } if (response.mnemonic != null && response.mnemonic!.isNotEmpty) { + final wordCount = response.mnemonic!.split(' ').length; + debugPrint('$_tag _saveWalletData() - 保存助记词 ($wordCount 个单词)'); await _secureStorage.write( key: StorageKeys.mnemonic, value: response.mnemonic!, ); + } else { + debugPrint('$_tag _saveWalletData() - 警告: mnemonic 为空'); } // 标记钱包已就绪 + debugPrint('$_tag _saveWalletData() - 标记钱包已就绪'); await _secureStorage.write( key: StorageKeys.isWalletReady, value: 'true', ); + + debugPrint('$_tag _saveWalletData() - 钱包数据保存完成'); } /// 检查是否已创建账号 Future hasAccount() async { + debugPrint('$_tag hasAccount() - 检查账号是否已创建'); final isCreated = await _secureStorage.read(key: StorageKeys.isAccountCreated); - return isCreated == 'true'; + final result = isCreated == 'true'; + debugPrint('$_tag hasAccount() - 结果: $result'); + return result; } /// 检查钱包是否已就绪 Future isWalletReady() async { + debugPrint('$_tag isWalletReady() - 检查钱包是否已就绪'); final isReady = await _secureStorage.read(key: StorageKeys.isWalletReady); - return isReady == 'true'; + final result = isReady == 'true'; + debugPrint('$_tag isWalletReady() - 结果: $result'); + return result; } /// 获取用户序列号 Future getUserSerialNum() async { + debugPrint('$_tag getUserSerialNum() - 获取用户序列号'); final serialNum = await _secureStorage.read(key: StorageKeys.userSerialNum); - return serialNum != null ? int.tryParse(serialNum) : null; + final result = serialNum != null ? int.tryParse(serialNum) : null; + debugPrint('$_tag getUserSerialNum() - 结果: $result'); + return result; } /// 获取用户名 Future getUsername() async { - return _secureStorage.read(key: StorageKeys.username); + debugPrint('$_tag getUsername() - 获取用户名'); + final result = await _secureStorage.read(key: StorageKeys.username); + debugPrint('$_tag getUsername() - 结果: $result'); + return result; } /// 获取头像 SVG Future getAvatarSvg() async { - return _secureStorage.read(key: StorageKeys.avatarSvg); + debugPrint('$_tag getAvatarSvg() - 获取头像 SVG'); + final result = await _secureStorage.read(key: StorageKeys.avatarSvg); + debugPrint('$_tag getAvatarSvg() - 结果长度: ${result?.length ?? 0}'); + return result; } /// 获取推荐码 Future getReferralCode() async { - return _secureStorage.read(key: StorageKeys.referralCode); + debugPrint('$_tag getReferralCode() - 获取推荐码'); + final result = await _secureStorage.read(key: StorageKeys.referralCode); + debugPrint('$_tag getReferralCode() - 结果: $result'); + return result; } /// 获取钱包地址 (从本地存储) Future getWalletAddresses() async { + debugPrint('$_tag getWalletAddresses() - 获取钱包地址'); final bsc = await _secureStorage.read(key: StorageKeys.walletAddressBsc); final kava = await _secureStorage.read(key: StorageKeys.walletAddressKava); final dst = await _secureStorage.read(key: StorageKeys.walletAddressDst); if (bsc == null || kava == null || dst == null) { + debugPrint('$_tag getWalletAddresses() - 钱包地址不完整'); return null; } - return WalletAddresses(kava: kava, dst: dst, bsc: bsc); + final result = WalletAddresses(kava: kava, dst: dst, bsc: bsc); + debugPrint('$_tag getWalletAddresses() - 结果: $result'); + return result; } /// 获取助记词 (从本地存储) Future getMnemonic() async { - return _secureStorage.read(key: StorageKeys.mnemonic); + debugPrint('$_tag getMnemonic() - 获取助记词'); + final result = await _secureStorage.read(key: StorageKeys.mnemonic); + if (result != null) { + final wordCount = result.split(' ').length; + debugPrint('$_tag getMnemonic() - 获取到 $wordCount 个单词'); + } else { + debugPrint('$_tag getMnemonic() - 未找到助记词'); + } + return result; } /// 标记助记词已备份 Future markMnemonicBackedUp() async { + debugPrint('$_tag markMnemonicBackedUp() - 标记助记词已备份'); await _secureStorage.write( key: StorageKeys.isMnemonicBackedUp, value: 'true', ); + debugPrint('$_tag markMnemonicBackedUp() - 完成'); } /// 检查助记词是否已备份 Future isMnemonicBackedUp() async { + debugPrint('$_tag isMnemonicBackedUp() - 检查助记词是否已备份'); final isBackedUp = await _secureStorage.read(key: StorageKeys.isMnemonicBackedUp); - return isBackedUp == 'true'; + final result = isBackedUp == 'true'; + debugPrint('$_tag isMnemonicBackedUp() - 结果: $result'); + return result; } /// 登出 Future logout() async { + debugPrint('$_tag logout() - 开始登出,清除所有数据'); await _secureStorage.deleteAll(); + debugPrint('$_tag logout() - 登出完成'); } } diff --git a/frontend/mobile-app/lib/features/auth/presentation/pages/backup_mnemonic_page.dart b/frontend/mobile-app/lib/features/auth/presentation/pages/backup_mnemonic_page.dart index 3b3d04c2..672f4a48 100644 --- a/frontend/mobile-app/lib/features/auth/presentation/pages/backup_mnemonic_page.dart +++ b/frontend/mobile-app/lib/features/auth/presentation/pages/backup_mnemonic_page.dart @@ -54,27 +54,41 @@ class _BackupMnemonicPageState extends ConsumerState { @override void initState() { super.initState(); + debugPrint('[BackupMnemonicPage] initState - userSerialNum: ${widget.userSerialNum}, referralCode: ${widget.referralCode}'); _loadWalletInfo(); } @override void dispose() { + debugPrint('[BackupMnemonicPage] dispose - 取消轮询定时器'); _pollTimer?.cancel(); super.dispose(); } /// 加载钱包信息 Future _loadWalletInfo() async { + debugPrint('[BackupMnemonicPage] _loadWalletInfo - 开始加载钱包信息, userSerialNum: ${widget.userSerialNum}'); try { final accountService = ref.read(accountServiceProvider); // 调用 API 获取钱包信息 + debugPrint('[BackupMnemonicPage] _loadWalletInfo - 调用 accountService.getWalletInfo()'); final response = await accountService.getWalletInfo(widget.userSerialNum); - if (!mounted) return; + if (!mounted) { + debugPrint('[BackupMnemonicPage] _loadWalletInfo - Widget已卸载,忽略响应'); + return; + } + + debugPrint('[BackupMnemonicPage] _loadWalletInfo - 响应状态: ${response.status}, isReady: ${response.isReady}, isGenerating: ${response.isGenerating}, isFailed: ${response.isFailed}'); if (response.isReady) { // 钱包已就绪 + final wordCount = response.mnemonic?.split(' ').length ?? 0; + debugPrint('[BackupMnemonicPage] _loadWalletInfo - 钱包就绪! 助记词数量: $wordCount'); + debugPrint('[BackupMnemonicPage] _loadWalletInfo - KAVA: ${_maskAddress(response.walletAddresses?.kava)}'); + debugPrint('[BackupMnemonicPage] _loadWalletInfo - DST: ${_maskAddress(response.walletAddresses?.dst)}'); + debugPrint('[BackupMnemonicPage] _loadWalletInfo - BSC: ${_maskAddress(response.walletAddresses?.bsc)}'); setState(() { _walletInfo = response; _mnemonicWords = response.mnemonic?.split(' ') ?? []; @@ -86,6 +100,7 @@ class _BackupMnemonicPageState extends ConsumerState { }); } else if (response.isGenerating) { // 钱包生成中,轮询等待 + debugPrint('[BackupMnemonicPage] _loadWalletInfo - 钱包生成中,开始轮询...'); setState(() { _isLoading = true; _errorMessage = null; @@ -93,13 +108,15 @@ class _BackupMnemonicPageState extends ConsumerState { _startPolling(); } else if (response.isFailed) { // 钱包生成失败 + debugPrint('[BackupMnemonicPage] _loadWalletInfo - 钱包生成失败'); setState(() { _isLoading = false; _errorMessage = '钱包生成失败,请稍后重试'; }); } - } catch (e) { - debugPrint('加载钱包信息失败: $e'); + } catch (e, stackTrace) { + debugPrint('[BackupMnemonicPage] _loadWalletInfo - 异常: $e'); + debugPrint('[BackupMnemonicPage] _loadWalletInfo - 堆栈: $stackTrace'); if (mounted) { setState(() { _isLoading = false; @@ -109,23 +126,44 @@ class _BackupMnemonicPageState extends ConsumerState { } } + /// 脱敏地址显示 (用于日志) + String _maskAddress(String? address) { + if (address == null || address.length < 10) return address ?? 'null'; + return '${address.substring(0, 6)}...${address.substring(address.length - 4)}'; + } + /// 开始轮询 + int _pollCount = 0; void _startPolling() { _pollTimer?.cancel(); + _pollCount = 0; + debugPrint('[BackupMnemonicPage] _startPolling - 启动轮询定时器 (每2秒)'); _pollTimer = Timer.periodic(const Duration(seconds: 2), (timer) async { + _pollCount++; if (!mounted) { + debugPrint('[BackupMnemonicPage] _startPolling - Widget已卸载,取消轮询'); timer.cancel(); return; } + debugPrint('[BackupMnemonicPage] _startPolling - 第 $_pollCount 次轮询...'); + try { final accountService = ref.read(accountServiceProvider); final response = await accountService.getWalletInfo(widget.userSerialNum); - if (!mounted) return; + if (!mounted) { + debugPrint('[BackupMnemonicPage] _startPolling - Widget已卸载,忽略响应'); + return; + } + + debugPrint('[BackupMnemonicPage] _startPolling - 轮询响应状态: ${response.status}'); if (response.isReady) { + debugPrint('[BackupMnemonicPage] _startPolling - 钱包就绪! 停止轮询 (共轮询 $_pollCount 次)'); timer.cancel(); + final wordCount = response.mnemonic?.split(' ').length ?? 0; + debugPrint('[BackupMnemonicPage] _startPolling - 助记词数量: $wordCount'); setState(() { _walletInfo = response; _mnemonicWords = response.mnemonic?.split(' ') ?? []; @@ -136,22 +174,25 @@ class _BackupMnemonicPageState extends ConsumerState { _errorMessage = null; }); } else if (response.isFailed) { + debugPrint('[BackupMnemonicPage] _startPolling - 钱包生成失败,停止轮询'); timer.cancel(); setState(() { _isLoading = false; _errorMessage = '钱包生成失败,请稍后重试'; }); + } else { + debugPrint('[BackupMnemonicPage] _startPolling - 仍在生成中,继续轮询...'); } - // 如果仍在生成中,继续轮询 } catch (e) { // 忽略轮询中的错误,继续尝试 - debugPrint('轮询钱包信息出错: $e'); + debugPrint('[BackupMnemonicPage] _startPolling - 轮询出错 (继续重试): $e'); } }); } /// 复制全部助记词 void _copyAllMnemonic() { + debugPrint('[BackupMnemonicPage] _copyAllMnemonic - 复制助记词到剪贴板'); final mnemonicText = _mnemonicWords.join(' '); Clipboard.setData(ClipboardData(text: mnemonicText)); _showCopySuccess('助记词已复制到剪贴板'); @@ -159,6 +200,7 @@ class _BackupMnemonicPageState extends ConsumerState { /// 复制地址 void _copyAddress(String address, String label) { + debugPrint('[BackupMnemonicPage] _copyAddress - 复制 $label: ${_maskAddress(address)}'); Clipboard.setData(ClipboardData(text: address)); _showCopySuccess('$label 已复制'); } @@ -183,12 +225,17 @@ class _BackupMnemonicPageState extends ConsumerState { /// 下载助记词备份文件 Future _downloadMnemonic() async { - if (_isDownloading || _mnemonicWords.isEmpty) return; + debugPrint('[BackupMnemonicPage] _downloadMnemonic - 开始下载备份文件'); + if (_isDownloading || _mnemonicWords.isEmpty) { + debugPrint('[BackupMnemonicPage] _downloadMnemonic - 跳过: isDownloading=$_isDownloading, wordsEmpty=${_mnemonicWords.isEmpty}'); + return; + } setState(() => _isDownloading = true); try { // 获取临时目录 + debugPrint('[BackupMnemonicPage] _downloadMnemonic - 获取临时目录'); final directory = await getTemporaryDirectory(); final timestamp = DateTime.now().millisecondsSinceEpoch; final file = File('${directory.path}/mnemonic_backup_$timestamp.txt'); @@ -229,11 +276,13 @@ ${DateTime.now().toString()} '''; // 写入文件 + debugPrint('[BackupMnemonicPage] _downloadMnemonic - 写入文件: ${file.path}'); await file.writeAsString(content); if (!mounted) return; // 分享文件 + debugPrint('[BackupMnemonicPage] _downloadMnemonic - 调用分享'); await Share.shareXFiles( [XFile(file.path)], subject: 'RWA 助记词备份', @@ -241,9 +290,13 @@ ${DateTime.now().toString()} // 删除临时文件 if (await file.exists()) { + debugPrint('[BackupMnemonicPage] _downloadMnemonic - 删除临时文件'); await file.delete(); } - } catch (e) { + debugPrint('[BackupMnemonicPage] _downloadMnemonic - 下载完成'); + } catch (e, stackTrace) { + debugPrint('[BackupMnemonicPage] _downloadMnemonic - 下载失败: $e'); + debugPrint('[BackupMnemonicPage] _downloadMnemonic - 堆栈: $stackTrace'); if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( @@ -260,7 +313,9 @@ ${DateTime.now().toString()} /// 确认已备份,跳转到确认备份页面进行验证 void _confirmBackup() { + debugPrint('[BackupMnemonicPage] _confirmBackup - 用户点击确认备份'); if (_mnemonicWords.isEmpty || _kavaAddress == null) { + debugPrint('[BackupMnemonicPage] _confirmBackup - 钱包信息不完整: words=${_mnemonicWords.length}, kavaAddress=${_kavaAddress != null}'); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('钱包信息不完整,请等待加载完成'), @@ -270,6 +325,7 @@ ${DateTime.now().toString()} return; } + debugPrint('[BackupMnemonicPage] _confirmBackup - 跳转到验证页面, userSerialNum: ${widget.userSerialNum}'); // 跳转到确认备份页面 context.push( RoutePaths.verifyMnemonic, @@ -286,6 +342,7 @@ ${DateTime.now().toString()} /// 返回上一步 void _goBack() { + debugPrint('[BackupMnemonicPage] _goBack - 用户返回上一步'); context.pop(); } diff --git a/frontend/mobile-app/lib/features/auth/presentation/pages/onboarding_page.dart b/frontend/mobile-app/lib/features/auth/presentation/pages/onboarding_page.dart index 6172369e..75a0e8af 100644 --- a/frontend/mobile-app/lib/features/auth/presentation/pages/onboarding_page.dart +++ b/frontend/mobile-app/lib/features/auth/presentation/pages/onboarding_page.dart @@ -33,24 +33,30 @@ class _OnboardingPageState extends ConsumerState { @override void initState() { super.initState(); + debugPrint('[OnboardingPage] initState - 检查账号状态'); _checkAccountStatus(); } /// 检查账号是否已创建 Future _checkAccountStatus() async { + debugPrint('[OnboardingPage] _checkAccountStatus - 开始检查'); try { final accountService = ref.read(accountServiceProvider); // 检查是否已创建账号 final hasAccount = await accountService.hasAccount(); + debugPrint('[OnboardingPage] _checkAccountStatus - hasAccount: $hasAccount'); if (hasAccount) { // 读取已保存的账号数据 + debugPrint('[OnboardingPage] _checkAccountStatus - 读取已保存账号数据'); final userSerialNum = await accountService.getUserSerialNum(); final username = await accountService.getUsername(); final avatarSvg = await accountService.getAvatarSvg(); final referralCode = await accountService.getReferralCode(); + debugPrint('[OnboardingPage] _checkAccountStatus - userSerialNum: $userSerialNum, username: $username'); + if (mounted) { setState(() { _isAccountCreated = true; @@ -64,6 +70,7 @@ class _OnboardingPageState extends ConsumerState { }); } } else { + debugPrint('[OnboardingPage] _checkAccountStatus - 账号未创建'); if (mounted) { setState(() { _isAccountCreated = false; @@ -71,8 +78,9 @@ class _OnboardingPageState extends ConsumerState { }); } } - } catch (e) { - debugPrint('检查账号状态失败: $e'); + } catch (e, stackTrace) { + debugPrint('[OnboardingPage] _checkAccountStatus - 异常: $e'); + debugPrint('[OnboardingPage] _checkAccountStatus - 堆栈: $stackTrace'); if (mounted) { setState(() { _isAccountCreated = false; @@ -86,7 +94,9 @@ class _OnboardingPageState extends ConsumerState { /// /// 调用后端 API 快速创建账号(不含钱包信息) Future _createAccount() async { + debugPrint('[OnboardingPage] _createAccount - 用户点击创建账号'); if (!_isAgreed) { + debugPrint('[OnboardingPage] _createAccount - 未同意协议,显示提示'); _showAgreementTip(); return; } @@ -100,13 +110,17 @@ class _OnboardingPageState extends ConsumerState { final accountService = ref.read(accountServiceProvider); // 调用后端 API 创建账号 - debugPrint('开始创建账号...'); + debugPrint('[OnboardingPage] _createAccount - 调用 accountService.createAccount()'); final response = await accountService.createAccount(); - debugPrint('账号创建成功: 序列号=${response.userSerialNum}, 用户名=${response.username}'); + debugPrint('[OnboardingPage] _createAccount - 成功! 序列号=${response.userSerialNum}, 用户名=${response.username}'); - if (!mounted) return; + if (!mounted) { + debugPrint('[OnboardingPage] _createAccount - Widget已卸载,忽略响应'); + return; + } // 更新状态 + debugPrint('[OnboardingPage] _createAccount - 更新本地状态'); setState(() { _isAccountCreated = true; _userSerialNum = response.userSerialNum; @@ -116,6 +130,7 @@ class _OnboardingPageState extends ConsumerState { }); // 跳转到备份助记词页面 + debugPrint('[OnboardingPage] _createAccount - 跳转到备份助记词页面'); context.push( RoutePaths.backupMnemonic, extra: BackupMnemonicParams( @@ -123,8 +138,9 @@ class _OnboardingPageState extends ConsumerState { referralCode: response.referralCode, ), ); - } catch (e) { - debugPrint('创建账号失败: $e'); + } catch (e, stackTrace) { + debugPrint('[OnboardingPage] _createAccount - 创建失败: $e'); + debugPrint('[OnboardingPage] _createAccount - 堆栈: $stackTrace'); if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( @@ -171,7 +187,9 @@ class _OnboardingPageState extends ConsumerState { /// 跳转到备份助记词页面(账号已创建的情况) void _goToBackupMnemonic() { + debugPrint('[OnboardingPage] _goToBackupMnemonic - 跳转到备份页面'); if (_userSerialNum == null) { + debugPrint('[OnboardingPage] _goToBackupMnemonic - userSerialNum为空,显示错误'); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('账号数据不完整,请重新创建'), @@ -181,6 +199,7 @@ class _OnboardingPageState extends ConsumerState { return; } + debugPrint('[OnboardingPage] _goToBackupMnemonic - userSerialNum: $_userSerialNum'); context.push( RoutePaths.backupMnemonic, extra: BackupMnemonicParams( @@ -192,6 +211,7 @@ class _OnboardingPageState extends ConsumerState { /// 处理按钮点击 void _handleButtonTap() { + debugPrint('[OnboardingPage] _handleButtonTap - isAccountCreated: $_isAccountCreated'); if (_isAccountCreated) { // 账号已创建,跳转到备份页面 _goToBackupMnemonic();