chore(mobile-app): 补全多账号切换流程的关键日志,便于验证与排查

切换流程中的每一步现在都有清晰的日志输出,方便通过 adb logcat
或 flutter logs 验证切换行为是否符合预期。

account_switch_page.dart - 三条路径全部覆盖:

_switchToAccount(切换账号):
  [1/6] 保存当前账号数据
  [2/6] 调用 switchToAccount()
  [3/6] onBeforeRestore - 停止 walletStatus/pendingAction 轮询、暂停遥测
  [4/6] invalidate authProvider / walletStatusProvider / notificationBadgeProvider
  [5/6] 恢复遥测上传
  [6/6] 导航到 ranking 页面

_addNewAccount(添加新账号):
  [1/5] 保存当前账号数据
  [2/5] 停止定时器
  [3/5] 调用 logoutCurrentAccount()
  [4/5] invalidate 三个 Provider
  [5/5] 导航到 guide 页面

_deleteAccount(删除账号):
  删除前打印目标账号,删除后打印剩余账号数

profile_page.dart - _performLogout(退出登录):
  [1/4] 停止 walletStatus/pendingAction 轮询
  [2/4] 调用 logoutCurrentAccount()
  [3/4] invalidate 三个 Provider
  [4/4] 导航到 guide 页面

每条关键操作完成后打印 ✓ 确认符号,便于逐步验证。
每条路径用 ========== 分隔符标识开始/完成,日志易于 grep 过滤。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-02-25 09:04:14 -08:00
parent e02bcf418c
commit 825c8a32e4
2 changed files with 61 additions and 6 deletions

View File

@ -32,7 +32,10 @@ class _AccountSwitchPageState extends ConsumerState<AccountSwitchPage> {
_loadAccounts();
}
static const String _tag = '[AccountSwitchPage]';
Future<void> _loadAccounts() async {
debugPrint('$_tag _loadAccounts() - 开始加载账号列表');
setState(() => _isLoading = true);
final multiAccountService = ref.read(multiAccountServiceProvider);
@ -43,6 +46,8 @@ class _AccountSwitchPageState extends ConsumerState<AccountSwitchPage> {
final accounts = await multiAccountService.getAccountList();
final currentId = await multiAccountService.getCurrentAccountId();
debugPrint('$_tag _loadAccounts() - 加载完成: ${accounts.length} 个账号, 当前=$currentId');
if (mounted) {
setState(() {
_accounts = accounts;
@ -54,55 +59,74 @@ class _AccountSwitchPageState extends ConsumerState<AccountSwitchPage> {
Future<void> _switchToAccount(AccountSummary account) async {
if (account.userSerialNum == _currentAccountId) {
//
debugPrint('$_tag _switchToAccount() - 已是当前账号 ${account.userSerialNum},直接返回');
context.pop();
return;
}
debugPrint('$_tag ========== 开始切换账号 ==========');
debugPrint('$_tag 当前账号: $_currentAccountId');
debugPrint('$_tag 目标账号: ${account.userSerialNum} (${account.username})');
setState(() => _isSwitching = true);
try {
final multiAccountService = ref.read(multiAccountServiceProvider);
//
debugPrint('$_tag [1/6] 保存当前账号数据...');
await multiAccountService.saveCurrentAccountData();
//
// onBeforeRestore: storage
// Provider invalidate switchToAccount storage
debugPrint('$_tag [2/6] 调用 switchToAccount()...');
final success = await multiAccountService.switchToAccount(
account.userSerialNum,
onBeforeRestore: () async {
// ===== 1. =====
debugPrint('$_tag [3/6] onBeforeRestore - 停止定时器...');
ref.read(walletStatusProvider.notifier).stopPolling();
debugPrint('$_tag ✓ walletStatusProvider 轮询已停止');
ref.read(pendingActionPollingServiceProvider).stop();
debugPrint('$_tag ✓ pendingActionPollingService 已停止');
//
if (TelemetryService().isInitialized) {
await TelemetryService().pauseForLogout();
debugPrint('$_tag ✓ TelemetryService 已暂停');
}
debugPrint('$_tag [3/6] onBeforeRestore - 定时器全部停止');
},
);
if (success && mounted) {
// ===== 2. invalidate Provider storage =====
debugPrint('$_tag [4/6] switchToAccount 成功invalidate Provider...');
ref.invalidate(authProvider);
debugPrint('$_tag ✓ authProvider invalidated');
ref.invalidate(walletStatusProvider);
debugPrint('$_tag ✓ walletStatusProvider invalidated');
ref.invalidate(notificationBadgeProvider);
debugPrint('$_tag ✓ notificationBadgeProvider invalidated');
// ===== 3. =====
debugPrint('$_tag [5/6] 恢复遥测上传...');
if (TelemetryService().isInitialized) {
TelemetryService().resumeAfterLogin();
debugPrint('$_tag ✓ TelemetryService 已恢复');
}
//
debugPrint('$_tag [6/6] 导航到 ranking 页面');
debugPrint('$_tag ========== 切换账号完成 ==========');
context.go(RoutePaths.ranking);
} else if (mounted) {
debugPrint('$_tag switchToAccount 返回 false切换失败');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('切换账号失败')),
);
}
} catch (e) {
debugPrint('[AccountSwitchPage] 切换账号失败: $e');
debugPrint('$_tag 切换账号异常: $e');
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('切换账号失败: $e')),
@ -118,32 +142,45 @@ class _AccountSwitchPageState extends ConsumerState<AccountSwitchPage> {
Future<void> _addNewAccount() async {
if (_isAddingAccount) return;
debugPrint('$_tag ========== 开始添加新账号 ==========');
debugPrint('$_tag 当前账号: $_currentAccountId');
setState(() => _isAddingAccount = true);
try {
final multiAccountService = ref.read(multiAccountServiceProvider);
//
debugPrint('$_tag [1/5] 保存当前账号数据...');
await multiAccountService.saveCurrentAccountData();
// ===== 1. =====
debugPrint('$_tag [2/5] 停止定时器...');
ref.read(walletStatusProvider.notifier).stopPolling();
debugPrint('$_tag ✓ walletStatusProvider 轮询已停止');
ref.read(pendingActionPollingServiceProvider).stop();
debugPrint('$_tag ✓ pendingActionPollingService 已停止');
// 退
debugPrint('$_tag [3/5] 调用 logoutCurrentAccount()...');
await multiAccountService.logoutCurrentAccount();
// ===== 2. invalidate Provider =====
debugPrint('$_tag [4/5] invalidate Provider...');
ref.invalidate(authProvider);
debugPrint('$_tag ✓ authProvider invalidated');
ref.invalidate(walletStatusProvider);
debugPrint('$_tag ✓ walletStatusProvider invalidated');
ref.invalidate(notificationBadgeProvider);
debugPrint('$_tag ✓ notificationBadgeProvider invalidated');
//
debugPrint('$_tag [5/5] 导航到 guide 页面');
debugPrint('$_tag ========== 添加新账号准备完成 ==========');
if (mounted) {
context.go(RoutePaths.guide);
}
} catch (e) {
debugPrint('[AccountSwitchPage] 添加新账号失败: $e');
debugPrint('$_tag 添加新账号异常: $e');
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('添加新账号失败: $e')),
@ -181,19 +218,26 @@ class _AccountSwitchPageState extends ConsumerState<AccountSwitchPage> {
if (confirmed != true) return;
debugPrint('$_tag ========== 开始删除账号 ==========');
debugPrint('$_tag 删除目标: ${account.userSerialNum} (${account.username})');
try {
final multiAccountService = ref.read(multiAccountServiceProvider);
await multiAccountService.deleteAccount(account.userSerialNum);
debugPrint('$_tag 账号已从存储中删除');
//
await _loadAccounts();
debugPrint('$_tag 账号列表已刷新,剩余 ${_accounts.length} 个账号');
//
if (_accounts.isEmpty && mounted) {
debugPrint('$_tag 无剩余账号,导航到 guide 页面');
context.go(RoutePaths.guide);
}
debugPrint('$_tag ========== 删除账号完成 ==========');
} catch (e) {
debugPrint('[AccountSwitchPage] 删除账号失败: $e');
debugPrint('$_tag 删除账号异常: $e');
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('删除账号失败: $e')),

View File

@ -4793,26 +4793,37 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
/// 退
Future<void> _performLogout() async {
debugPrint('[ProfilePage] ========== 开始退出登录 ==========');
try {
// ===== 1. =====
debugPrint('[ProfilePage] [1/4] 停止定时器...');
ref.read(walletStatusProvider.notifier).stopPolling();
debugPrint('[ProfilePage] ✓ walletStatusProvider 轮询已停止');
ref.read(pendingActionPollingServiceProvider).stop();
debugPrint('[ProfilePage] ✓ pendingActionPollingService 已停止');
final multiAccountService = ref.read(multiAccountServiceProvider);
// 退
// 退 storage +
debugPrint('[ProfilePage] [2/4] 调用 logoutCurrentAccount()...');
await multiAccountService.logoutCurrentAccount();
// ===== 2. invalidate Provider =====
debugPrint('[ProfilePage] [3/4] invalidate Provider...');
ref.invalidate(authProvider);
debugPrint('[ProfilePage] ✓ authProvider invalidated');
ref.invalidate(walletStatusProvider);
debugPrint('[ProfilePage] ✓ walletStatusProvider invalidated');
ref.invalidate(notificationBadgeProvider);
debugPrint('[ProfilePage] ✓ notificationBadgeProvider invalidated');
//
debugPrint('[ProfilePage] [4/4] 导航到 guide 页面');
debugPrint('[ProfilePage] ========== 退出登录完成 ==========');
if (mounted) {
context.go(RoutePaths.guide);
}
} catch (e) {
debugPrint('[ProfilePage] 退出登录失败: $e');
debugPrint('[ProfilePage] 退出登录异常: $e');
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('退出登录失败: $e')),