feat(mobile-app): add detailed debug logging for account creation flow

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 <noreply@anthropic.com>
This commit is contained in:
hailin 2025-12-06 20:03:36 -08:00
parent 6150617c14
commit 37aab77e7a
3 changed files with 268 additions and 39 deletions

View File

@ -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<String, dynamic> 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<String, dynamic> 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<String, dynamic> 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<String> 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<DeviceHardwareInfo> 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<CreateAccountResponse> 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<String, dynamic>,
);
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<WalletInfoResponse> 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<String, dynamic>,
);
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<void> _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<bool> 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<bool> 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<int?> 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<String?> 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<String?> 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<String?> 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<WalletAddresses?> 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<String?> 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<void> markMnemonicBackedUp() async {
debugPrint('$_tag markMnemonicBackedUp() - 标记助记词已备份');
await _secureStorage.write(
key: StorageKeys.isMnemonicBackedUp,
value: 'true',
);
debugPrint('$_tag markMnemonicBackedUp() - 完成');
}
///
Future<bool> 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<void> logout() async {
debugPrint('$_tag logout() - 开始登出,清除所有数据');
await _secureStorage.deleteAll();
debugPrint('$_tag logout() - 登出完成');
}
}

View File

@ -54,27 +54,41 @@ class _BackupMnemonicPageState extends ConsumerState<BackupMnemonicPage> {
@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<void> _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<BackupMnemonicPage> {
});
} else if (response.isGenerating) {
//
debugPrint('[BackupMnemonicPage] _loadWalletInfo - 钱包生成中,开始轮询...');
setState(() {
_isLoading = true;
_errorMessage = null;
@ -93,13 +108,15 @@ class _BackupMnemonicPageState extends ConsumerState<BackupMnemonicPage> {
_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<BackupMnemonicPage> {
}
}
/// ()
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<BackupMnemonicPage> {
_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<BackupMnemonicPage> {
///
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<BackupMnemonicPage> {
///
Future<void> _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();
}

View File

@ -33,24 +33,30 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
@override
void initState() {
super.initState();
debugPrint('[OnboardingPage] initState - 检查账号状态');
_checkAccountStatus();
}
///
Future<void> _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<OnboardingPage> {
});
}
} else {
debugPrint('[OnboardingPage] _checkAccountStatus - 账号未创建');
if (mounted) {
setState(() {
_isAccountCreated = false;
@ -71,8 +78,9 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
});
}
}
} 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<OnboardingPage> {
///
/// API
Future<void> _createAccount() async {
debugPrint('[OnboardingPage] _createAccount - 用户点击创建账号');
if (!_isAgreed) {
debugPrint('[OnboardingPage] _createAccount - 未同意协议,显示提示');
_showAgreementTip();
return;
}
@ -100,13 +110,17 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
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<OnboardingPage> {
});
//
debugPrint('[OnboardingPage] _createAccount - 跳转到备份助记词页面');
context.push(
RoutePaths.backupMnemonic,
extra: BackupMnemonicParams(
@ -123,8 +138,9 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
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<OnboardingPage> {
///
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<OnboardingPage> {
return;
}
debugPrint('[OnboardingPage] _goToBackupMnemonic - userSerialNum: $_userSerialNum');
context.push(
RoutePaths.backupMnemonic,
extra: BackupMnemonicParams(
@ -192,6 +211,7 @@ class _OnboardingPageState extends ConsumerState<OnboardingPage> {
///
void _handleButtonTap() {
debugPrint('[OnboardingPage] _handleButtonTap - isAccountCreated: $_isAccountCreated');
if (_isAccountCreated) {
//
_goToBackupMnemonic();