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:
parent
e02bcf418c
commit
825c8a32e4
|
|
@ -32,7 +32,10 @@ class _AccountSwitchPageState extends ConsumerState<AccountSwitchPage> {
|
||||||
_loadAccounts();
|
_loadAccounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const String _tag = '[AccountSwitchPage]';
|
||||||
|
|
||||||
Future<void> _loadAccounts() async {
|
Future<void> _loadAccounts() async {
|
||||||
|
debugPrint('$_tag _loadAccounts() - 开始加载账号列表');
|
||||||
setState(() => _isLoading = true);
|
setState(() => _isLoading = true);
|
||||||
|
|
||||||
final multiAccountService = ref.read(multiAccountServiceProvider);
|
final multiAccountService = ref.read(multiAccountServiceProvider);
|
||||||
|
|
@ -43,6 +46,8 @@ class _AccountSwitchPageState extends ConsumerState<AccountSwitchPage> {
|
||||||
final accounts = await multiAccountService.getAccountList();
|
final accounts = await multiAccountService.getAccountList();
|
||||||
final currentId = await multiAccountService.getCurrentAccountId();
|
final currentId = await multiAccountService.getCurrentAccountId();
|
||||||
|
|
||||||
|
debugPrint('$_tag _loadAccounts() - 加载完成: ${accounts.length} 个账号, 当前=$currentId');
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_accounts = accounts;
|
_accounts = accounts;
|
||||||
|
|
@ -54,55 +59,74 @@ class _AccountSwitchPageState extends ConsumerState<AccountSwitchPage> {
|
||||||
|
|
||||||
Future<void> _switchToAccount(AccountSummary account) async {
|
Future<void> _switchToAccount(AccountSummary account) async {
|
||||||
if (account.userSerialNum == _currentAccountId) {
|
if (account.userSerialNum == _currentAccountId) {
|
||||||
// 已是当前账号,直接返回
|
debugPrint('$_tag _switchToAccount() - 已是当前账号 ${account.userSerialNum},直接返回');
|
||||||
context.pop();
|
context.pop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debugPrint('$_tag ========== 开始切换账号 ==========');
|
||||||
|
debugPrint('$_tag 当前账号: $_currentAccountId');
|
||||||
|
debugPrint('$_tag 目标账号: ${account.userSerialNum} (${account.username})');
|
||||||
setState(() => _isSwitching = true);
|
setState(() => _isSwitching = true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final multiAccountService = ref.read(multiAccountServiceProvider);
|
final multiAccountService = ref.read(multiAccountServiceProvider);
|
||||||
|
|
||||||
// 保存当前账号数据
|
// 保存当前账号数据
|
||||||
|
debugPrint('$_tag [1/6] 保存当前账号数据...');
|
||||||
await multiAccountService.saveCurrentAccountData();
|
await multiAccountService.saveCurrentAccountData();
|
||||||
|
|
||||||
// 切换到新账号
|
// 切换到新账号
|
||||||
// onBeforeRestore: storage 已清空、新数据尚未恢复 → 只停定时器
|
// onBeforeRestore: storage 已清空、新数据尚未恢复 → 只停定时器
|
||||||
// Provider invalidate 必须在 switchToAccount 返回后做(此时 storage 已恢复新账号数据)
|
// Provider invalidate 必须在 switchToAccount 返回后做(此时 storage 已恢复新账号数据)
|
||||||
|
debugPrint('$_tag [2/6] 调用 switchToAccount()...');
|
||||||
final success = await multiAccountService.switchToAccount(
|
final success = await multiAccountService.switchToAccount(
|
||||||
account.userSerialNum,
|
account.userSerialNum,
|
||||||
onBeforeRestore: () async {
|
onBeforeRestore: () async {
|
||||||
// ===== 1. 停止所有用户相关的定时任务 =====
|
// ===== 1. 停止所有用户相关的定时任务 =====
|
||||||
|
debugPrint('$_tag [3/6] onBeforeRestore - 停止定时器...');
|
||||||
ref.read(walletStatusProvider.notifier).stopPolling();
|
ref.read(walletStatusProvider.notifier).stopPolling();
|
||||||
|
debugPrint('$_tag ✓ walletStatusProvider 轮询已停止');
|
||||||
ref.read(pendingActionPollingServiceProvider).stop();
|
ref.read(pendingActionPollingServiceProvider).stop();
|
||||||
|
debugPrint('$_tag ✓ pendingActionPollingService 已停止');
|
||||||
// 遥测:清空旧账号事件队列、停止上传
|
// 遥测:清空旧账号事件队列、停止上传
|
||||||
if (TelemetryService().isInitialized) {
|
if (TelemetryService().isInitialized) {
|
||||||
await TelemetryService().pauseForLogout();
|
await TelemetryService().pauseForLogout();
|
||||||
|
debugPrint('$_tag ✓ TelemetryService 已暂停');
|
||||||
}
|
}
|
||||||
|
debugPrint('$_tag [3/6] onBeforeRestore - 定时器全部停止');
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (success && mounted) {
|
if (success && mounted) {
|
||||||
// ===== 2. invalidate 所有账号相关 Provider(此时 storage 已是新账号数据)=====
|
// ===== 2. invalidate 所有账号相关 Provider(此时 storage 已是新账号数据)=====
|
||||||
|
debugPrint('$_tag [4/6] switchToAccount 成功,invalidate Provider...');
|
||||||
ref.invalidate(authProvider);
|
ref.invalidate(authProvider);
|
||||||
|
debugPrint('$_tag ✓ authProvider invalidated');
|
||||||
ref.invalidate(walletStatusProvider);
|
ref.invalidate(walletStatusProvider);
|
||||||
|
debugPrint('$_tag ✓ walletStatusProvider invalidated');
|
||||||
ref.invalidate(notificationBadgeProvider);
|
ref.invalidate(notificationBadgeProvider);
|
||||||
|
debugPrint('$_tag ✓ notificationBadgeProvider invalidated');
|
||||||
|
|
||||||
// ===== 3. 恢复遥测上传(新账号上下文)=====
|
// ===== 3. 恢复遥测上传(新账号上下文)=====
|
||||||
|
debugPrint('$_tag [5/6] 恢复遥测上传...');
|
||||||
if (TelemetryService().isInitialized) {
|
if (TelemetryService().isInitialized) {
|
||||||
TelemetryService().resumeAfterLogin();
|
TelemetryService().resumeAfterLogin();
|
||||||
|
debugPrint('$_tag ✓ TelemetryService 已恢复');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 切换成功,跳转到主页刷新状态
|
// 切换成功,跳转到主页刷新状态
|
||||||
|
debugPrint('$_tag [6/6] 导航到 ranking 页面');
|
||||||
|
debugPrint('$_tag ========== 切换账号完成 ==========');
|
||||||
context.go(RoutePaths.ranking);
|
context.go(RoutePaths.ranking);
|
||||||
} else if (mounted) {
|
} else if (mounted) {
|
||||||
|
debugPrint('$_tag switchToAccount 返回 false,切换失败');
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('切换账号失败')),
|
const SnackBar(content: Text('切换账号失败')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('[AccountSwitchPage] 切换账号失败: $e');
|
debugPrint('$_tag 切换账号异常: $e');
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('切换账号失败: $e')),
|
SnackBar(content: Text('切换账号失败: $e')),
|
||||||
|
|
@ -118,32 +142,45 @@ class _AccountSwitchPageState extends ConsumerState<AccountSwitchPage> {
|
||||||
Future<void> _addNewAccount() async {
|
Future<void> _addNewAccount() async {
|
||||||
if (_isAddingAccount) return;
|
if (_isAddingAccount) return;
|
||||||
|
|
||||||
|
debugPrint('$_tag ========== 开始添加新账号 ==========');
|
||||||
|
debugPrint('$_tag 当前账号: $_currentAccountId');
|
||||||
setState(() => _isAddingAccount = true);
|
setState(() => _isAddingAccount = true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final multiAccountService = ref.read(multiAccountServiceProvider);
|
final multiAccountService = ref.read(multiAccountServiceProvider);
|
||||||
|
|
||||||
// 保存当前账号数据
|
// 保存当前账号数据
|
||||||
|
debugPrint('$_tag [1/5] 保存当前账号数据...');
|
||||||
await multiAccountService.saveCurrentAccountData();
|
await multiAccountService.saveCurrentAccountData();
|
||||||
|
|
||||||
// ===== 1. 停止所有用户相关的定时任务 =====
|
// ===== 1. 停止所有用户相关的定时任务 =====
|
||||||
|
debugPrint('$_tag [2/5] 停止定时器...');
|
||||||
ref.read(walletStatusProvider.notifier).stopPolling();
|
ref.read(walletStatusProvider.notifier).stopPolling();
|
||||||
|
debugPrint('$_tag ✓ walletStatusProvider 轮询已停止');
|
||||||
ref.read(pendingActionPollingServiceProvider).stop();
|
ref.read(pendingActionPollingServiceProvider).stop();
|
||||||
|
debugPrint('$_tag ✓ pendingActionPollingService 已停止');
|
||||||
|
|
||||||
// 退出当前账号但保留数据
|
// 退出当前账号但保留数据
|
||||||
|
debugPrint('$_tag [3/5] 调用 logoutCurrentAccount()...');
|
||||||
await multiAccountService.logoutCurrentAccount();
|
await multiAccountService.logoutCurrentAccount();
|
||||||
|
|
||||||
// ===== 2. invalidate 所有账号相关 Provider =====
|
// ===== 2. invalidate 所有账号相关 Provider =====
|
||||||
|
debugPrint('$_tag [4/5] invalidate Provider...');
|
||||||
ref.invalidate(authProvider);
|
ref.invalidate(authProvider);
|
||||||
|
debugPrint('$_tag ✓ authProvider invalidated');
|
||||||
ref.invalidate(walletStatusProvider);
|
ref.invalidate(walletStatusProvider);
|
||||||
|
debugPrint('$_tag ✓ walletStatusProvider invalidated');
|
||||||
ref.invalidate(notificationBadgeProvider);
|
ref.invalidate(notificationBadgeProvider);
|
||||||
|
debugPrint('$_tag ✓ notificationBadgeProvider invalidated');
|
||||||
|
|
||||||
// 跳转到向导页创建新账号
|
// 跳转到向导页创建新账号
|
||||||
|
debugPrint('$_tag [5/5] 导航到 guide 页面');
|
||||||
|
debugPrint('$_tag ========== 添加新账号准备完成 ==========');
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
context.go(RoutePaths.guide);
|
context.go(RoutePaths.guide);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('[AccountSwitchPage] 添加新账号失败: $e');
|
debugPrint('$_tag 添加新账号异常: $e');
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('添加新账号失败: $e')),
|
SnackBar(content: Text('添加新账号失败: $e')),
|
||||||
|
|
@ -181,19 +218,26 @@ class _AccountSwitchPageState extends ConsumerState<AccountSwitchPage> {
|
||||||
|
|
||||||
if (confirmed != true) return;
|
if (confirmed != true) return;
|
||||||
|
|
||||||
|
debugPrint('$_tag ========== 开始删除账号 ==========');
|
||||||
|
debugPrint('$_tag 删除目标: ${account.userSerialNum} (${account.username})');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final multiAccountService = ref.read(multiAccountServiceProvider);
|
final multiAccountService = ref.read(multiAccountServiceProvider);
|
||||||
await multiAccountService.deleteAccount(account.userSerialNum);
|
await multiAccountService.deleteAccount(account.userSerialNum);
|
||||||
|
debugPrint('$_tag 账号已从存储中删除');
|
||||||
|
|
||||||
// 重新加载账号列表
|
// 重新加载账号列表
|
||||||
await _loadAccounts();
|
await _loadAccounts();
|
||||||
|
debugPrint('$_tag 账号列表已刷新,剩余 ${_accounts.length} 个账号');
|
||||||
|
|
||||||
// 如果没有账号了,跳转到向导页
|
// 如果没有账号了,跳转到向导页
|
||||||
if (_accounts.isEmpty && mounted) {
|
if (_accounts.isEmpty && mounted) {
|
||||||
|
debugPrint('$_tag 无剩余账号,导航到 guide 页面');
|
||||||
context.go(RoutePaths.guide);
|
context.go(RoutePaths.guide);
|
||||||
}
|
}
|
||||||
|
debugPrint('$_tag ========== 删除账号完成 ==========');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('[AccountSwitchPage] 删除账号失败: $e');
|
debugPrint('$_tag 删除账号异常: $e');
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('删除账号失败: $e')),
|
SnackBar(content: Text('删除账号失败: $e')),
|
||||||
|
|
|
||||||
|
|
@ -4793,26 +4793,37 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
|
||||||
|
|
||||||
/// 执行退出登录
|
/// 执行退出登录
|
||||||
Future<void> _performLogout() async {
|
Future<void> _performLogout() async {
|
||||||
|
debugPrint('[ProfilePage] ========== 开始退出登录 ==========');
|
||||||
try {
|
try {
|
||||||
// ===== 1. 停止所有用户相关的定时任务 =====
|
// ===== 1. 停止所有用户相关的定时任务 =====
|
||||||
|
debugPrint('[ProfilePage] [1/4] 停止定时器...');
|
||||||
ref.read(walletStatusProvider.notifier).stopPolling();
|
ref.read(walletStatusProvider.notifier).stopPolling();
|
||||||
|
debugPrint('[ProfilePage] ✓ walletStatusProvider 轮询已停止');
|
||||||
ref.read(pendingActionPollingServiceProvider).stop();
|
ref.read(pendingActionPollingServiceProvider).stop();
|
||||||
|
debugPrint('[ProfilePage] ✓ pendingActionPollingService 已停止');
|
||||||
|
|
||||||
final multiAccountService = ref.read(multiAccountServiceProvider);
|
final multiAccountService = ref.read(multiAccountServiceProvider);
|
||||||
// 退出当前账号(保留账号数据)
|
// 退出当前账号(保留账号数据,清除 storage + 暂停遥测)
|
||||||
|
debugPrint('[ProfilePage] [2/4] 调用 logoutCurrentAccount()...');
|
||||||
await multiAccountService.logoutCurrentAccount();
|
await multiAccountService.logoutCurrentAccount();
|
||||||
|
|
||||||
// ===== 2. invalidate 所有账号相关 Provider =====
|
// ===== 2. invalidate 所有账号相关 Provider =====
|
||||||
|
debugPrint('[ProfilePage] [3/4] invalidate Provider...');
|
||||||
ref.invalidate(authProvider);
|
ref.invalidate(authProvider);
|
||||||
|
debugPrint('[ProfilePage] ✓ authProvider invalidated');
|
||||||
ref.invalidate(walletStatusProvider);
|
ref.invalidate(walletStatusProvider);
|
||||||
|
debugPrint('[ProfilePage] ✓ walletStatusProvider invalidated');
|
||||||
ref.invalidate(notificationBadgeProvider);
|
ref.invalidate(notificationBadgeProvider);
|
||||||
|
debugPrint('[ProfilePage] ✓ notificationBadgeProvider invalidated');
|
||||||
|
|
||||||
// 导航到向导页
|
// 导航到向导页
|
||||||
|
debugPrint('[ProfilePage] [4/4] 导航到 guide 页面');
|
||||||
|
debugPrint('[ProfilePage] ========== 退出登录完成 ==========');
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
context.go(RoutePaths.guide);
|
context.go(RoutePaths.guide);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('[ProfilePage] 退出登录失败: $e');
|
debugPrint('[ProfilePage] 退出登录异常: $e');
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
SnackBar(content: Text('退出登录失败: $e')),
|
SnackBar(content: Text('退出登录失败: $e')),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue