fix(mobile-app): 完善退出登录时的数据清理逻辑
遵循大厂最佳实践,确保退出登录后下次登录是干净的环境: SecureStorage 新增清除项: - inviterReferralCode (临时邀请码) - biometricEnabled (生物识别设置) LocalStorage 新增清除项: - lastSyncTime (最后同步时间) - cachedRankingData (排行榜缓存) - cachedMiningStatus (矿机状态缓存) 遥测数据: - 清除用户相关的事件队列 重构: - MultiAccountService 增加 LocalStorage 和 TelemetryStorage 依赖 - 更新依赖注入容器 - TelemetryStorage 新增 clearUserData 方法 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
e742a360ec
commit
4de96dac9d
|
|
@ -7,7 +7,6 @@ import 'package:go_router/go_router.dart';
|
|||
import 'core/di/injection_container.dart';
|
||||
import 'core/theme/app_theme.dart';
|
||||
import 'core/services/auth_event_service.dart';
|
||||
import 'core/services/multi_account_service.dart';
|
||||
import 'routes/app_router.dart';
|
||||
import 'routes/route_paths.dart';
|
||||
|
||||
|
|
@ -48,8 +47,7 @@ class _AppState extends ConsumerState<App> {
|
|||
debugPrint('[App] Token expired, navigating to login page');
|
||||
|
||||
// 清除当前账号状态(但保留账号列表和向导页标识)
|
||||
final secureStorage = ref.read(secureStorageProvider);
|
||||
final multiAccountService = MultiAccountService(secureStorage);
|
||||
final multiAccountService = ref.read(multiAccountServiceProvider);
|
||||
await multiAccountService.logoutCurrentAccount();
|
||||
|
||||
// 使用全局 Navigator Key 跳转到登录页面
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import '../services/notification_service.dart';
|
|||
import '../services/system_config_service.dart';
|
||||
import '../services/contract_signing_service.dart';
|
||||
import '../services/contract_check_service.dart';
|
||||
import '../telemetry/storage/telemetry_storage.dart';
|
||||
import '../../features/kyc/data/kyc_service.dart';
|
||||
|
||||
// Storage Providers
|
||||
|
|
@ -41,10 +42,17 @@ final accountServiceProvider = Provider<AccountService>((ref) {
|
|||
);
|
||||
});
|
||||
|
||||
// Telemetry Storage Provider
|
||||
final telemetryStorageProvider = Provider<TelemetryStorage>((ref) {
|
||||
return TelemetryStorage();
|
||||
});
|
||||
|
||||
// Multi Account Service Provider
|
||||
final multiAccountServiceProvider = Provider<MultiAccountService>((ref) {
|
||||
final secureStorage = ref.watch(secureStorageProvider);
|
||||
return MultiAccountService(secureStorage);
|
||||
final localStorage = ref.watch(localStorageProvider);
|
||||
final telemetryStorage = ref.watch(telemetryStorageProvider);
|
||||
return MultiAccountService(secureStorage, localStorage, telemetryStorage);
|
||||
});
|
||||
|
||||
// Referral Service Provider
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import 'dart:convert';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import '../storage/secure_storage.dart';
|
||||
import '../storage/local_storage.dart';
|
||||
import '../storage/storage_keys.dart';
|
||||
import '../telemetry/telemetry_service.dart';
|
||||
import '../telemetry/storage/telemetry_storage.dart';
|
||||
import '../sentry/sentry_service.dart';
|
||||
|
||||
/// 账号信息摘要(用于账号列表显示)
|
||||
|
|
@ -49,8 +51,14 @@ class MultiAccountService {
|
|||
static const String _tag = '[MultiAccountService]';
|
||||
|
||||
final SecureStorage _secureStorage;
|
||||
final LocalStorage _localStorage;
|
||||
final TelemetryStorage _telemetryStorage;
|
||||
|
||||
MultiAccountService(this._secureStorage);
|
||||
MultiAccountService(
|
||||
this._secureStorage,
|
||||
this._localStorage,
|
||||
this._telemetryStorage,
|
||||
);
|
||||
|
||||
/// 获取账号列表
|
||||
Future<List<AccountSummary>> getAccountList() async {
|
||||
|
|
@ -241,6 +249,7 @@ class MultiAccountService {
|
|||
|
||||
/// 退出当前账号(不删除账号数据)
|
||||
/// 清除当前会话状态,但保留账号在列表中
|
||||
/// 遵循大厂最佳实践,确保下次登录是干净的环境
|
||||
Future<void> logoutCurrentAccount() async {
|
||||
debugPrint('$_tag logoutCurrentAccount() - 退出当前账号');
|
||||
|
||||
|
|
@ -250,48 +259,67 @@ class MultiAccountService {
|
|||
// 清除当前账号标记
|
||||
await setCurrentAccountId(null);
|
||||
|
||||
// 清除所有当前账号相关的状态(但不删除账号列表)
|
||||
// 这样新账号创建/导入时不会受到旧状态影响
|
||||
final keysToClear = [
|
||||
// Token
|
||||
// ===== 1. 清除 SecureStorage 中的敏感数据 =====
|
||||
final secureKeysToClear = [
|
||||
// Token(必须清除)
|
||||
StorageKeys.accessToken,
|
||||
StorageKeys.refreshToken,
|
||||
// 账号信息
|
||||
// 账号信息(必须清除)
|
||||
StorageKeys.userSerialNum,
|
||||
StorageKeys.username,
|
||||
StorageKeys.avatarSvg,
|
||||
StorageKeys.avatarUrl,
|
||||
StorageKeys.referralCode,
|
||||
StorageKeys.inviterSequence,
|
||||
StorageKeys.inviterReferralCode, // 临时邀请码
|
||||
StorageKeys.isAccountCreated,
|
||||
StorageKeys.phoneNumber,
|
||||
StorageKeys.isPasswordSet,
|
||||
// 钱包信息
|
||||
// 钱包信息(必须清除)
|
||||
StorageKeys.walletAddressBsc,
|
||||
StorageKeys.walletAddressKava,
|
||||
StorageKeys.walletAddressDst,
|
||||
StorageKeys.mnemonic,
|
||||
StorageKeys.isWalletReady,
|
||||
StorageKeys.isMnemonicBackedUp,
|
||||
// 安全设置(与账号绑定,需清除)
|
||||
StorageKeys.biometricEnabled,
|
||||
];
|
||||
|
||||
for (final key in keysToClear) {
|
||||
for (final key in secureKeysToClear) {
|
||||
await _secureStorage.delete(key: key);
|
||||
}
|
||||
debugPrint('$_tag logoutCurrentAccount() - 已清除 ${secureKeysToClear.length} 个 SecureStorage 键');
|
||||
|
||||
// 清除遥测服务的用户ID
|
||||
// ===== 2. 清除 LocalStorage 中的缓存数据 =====
|
||||
final localKeysToClear = [
|
||||
StorageKeys.lastSyncTime,
|
||||
StorageKeys.cachedRankingData,
|
||||
StorageKeys.cachedMiningStatus,
|
||||
];
|
||||
|
||||
for (final key in localKeysToClear) {
|
||||
await _localStorage.remove(key);
|
||||
}
|
||||
debugPrint('$_tag logoutCurrentAccount() - 已清除 ${localKeysToClear.length} 个 LocalStorage 缓存');
|
||||
|
||||
// ===== 3. 清除遥测事件队列(用户相关数据) =====
|
||||
await _telemetryStorage.clearUserData();
|
||||
|
||||
// ===== 4. 清除遥测服务的用户ID =====
|
||||
if (TelemetryService().isInitialized) {
|
||||
TelemetryService().clearUserId();
|
||||
debugPrint('$_tag logoutCurrentAccount() - 清除TelemetryService userId');
|
||||
debugPrint('$_tag logoutCurrentAccount() - 清除 TelemetryService userId');
|
||||
}
|
||||
|
||||
// 清除 Sentry 用户信息
|
||||
// ===== 5. 清除 Sentry 用户信息 =====
|
||||
if (SentryService().isInitialized) {
|
||||
SentryService().clearUser();
|
||||
debugPrint('$_tag logoutCurrentAccount() - 清除SentryService userId');
|
||||
debugPrint('$_tag logoutCurrentAccount() - 清除 SentryService userId');
|
||||
}
|
||||
|
||||
debugPrint('$_tag logoutCurrentAccount() - 退出完成,已清除 ${keysToClear.length} 个状态');
|
||||
final totalCleared = secureKeysToClear.length + localKeysToClear.length;
|
||||
debugPrint('$_tag logoutCurrentAccount() - 退出完成,共清除 $totalCleared 个存储键 + 遥测数据');
|
||||
}
|
||||
|
||||
/// 完全删除账号(包括所有数据)
|
||||
|
|
|
|||
|
|
@ -103,6 +103,13 @@ class TelemetryStorage {
|
|||
await _prefs.remove(_keyEventQueue);
|
||||
}
|
||||
|
||||
/// 清空所有遥测数据(退出登录时调用)
|
||||
/// 保留 installId 和 deviceContext(设备级别数据)
|
||||
Future<void> clearUserData() async {
|
||||
await _prefs.remove(_keyEventQueue);
|
||||
debugPrint('📊 TelemetryStorage: 已清除用户相关遥测数据');
|
||||
}
|
||||
|
||||
// 私有方法
|
||||
List<Map<String, dynamic>> _getEventQueue() {
|
||||
final str = _prefs.getString(_keyEventQueue);
|
||||
|
|
|
|||
Loading…
Reference in New Issue