diff --git a/frontend/mining-app/lib/core/telemetry/telemetry_service.dart b/frontend/mining-app/lib/core/telemetry/telemetry_service.dart index 36d4c96b..d9b924bf 100644 --- a/frontend/mining-app/lib/core/telemetry/telemetry_service.dart +++ b/frontend/mining-app/lib/core/telemetry/telemetry_service.dart @@ -61,6 +61,8 @@ class TelemetryService { String? _userId; String? get userId => _userId; + String? _accessToken; + bool _isInitialized = false; bool get isInitialized => _isInitialized; @@ -148,7 +150,12 @@ class TelemetryService { } Map _getAuthHeaders() { - return {}; + if (_accessToken == null) return {}; + return {'Authorization': 'Bearer $_accessToken'}; + } + + void setAccessToken(String? token) { + _accessToken = token; } void logEvent( diff --git a/frontend/mining-app/lib/presentation/pages/splash/splash_page.dart b/frontend/mining-app/lib/presentation/pages/splash/splash_page.dart index c61dc553..135b8a54 100644 --- a/frontend/mining-app/lib/presentation/pages/splash/splash_page.dart +++ b/frontend/mining-app/lib/presentation/pages/splash/splash_page.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../core/router/routes.dart'; +import '../../../core/config/environment.dart'; +import '../../../core/telemetry/telemetry_service.dart'; import '../../providers/user_providers.dart'; class SplashPage extends ConsumerStatefulWidget { @@ -32,6 +34,19 @@ class _SplashPageState extends ConsumerState { final userState = ref.read(userNotifierProvider); + // 初始化遥测服务(非阻塞,异常不影响主流程) + TelemetryService().initialize( + apiBaseUrl: EnvironmentConfig.baseUrl, + context: context, + userId: userState.isLoggedIn ? userState.accountSequence : null, + ).then((_) { + if (userState.isLoggedIn && userState.accessToken != null) { + TelemetryService().setAccessToken(userState.accessToken); + } + }).catchError((e) { + debugPrint('[Telemetry] Initialize failed (non-blocking): $e'); + }); + if (userState.isLoggedIn) { // 已登录,直接跳转,不需要主动刷新 token // token 刷新只在 API 返回 401 时才触发 @@ -39,7 +54,7 @@ class _SplashPageState extends ConsumerState { context.go(Routes.trading); } } else { - context.go(Routes.login); + if (mounted) context.go(Routes.login); } } diff --git a/frontend/mining-app/lib/presentation/providers/user_providers.dart b/frontend/mining-app/lib/presentation/providers/user_providers.dart index 29d36238..842fe962 100644 --- a/frontend/mining-app/lib/presentation/providers/user_providers.dart +++ b/frontend/mining-app/lib/presentation/providers/user_providers.dart @@ -3,6 +3,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import '../../data/datasources/remote/auth_remote_datasource.dart'; import '../../data/models/capability_model.dart'; import '../../core/di/injection.dart'; +import '../../core/telemetry/telemetry_service.dart'; class UserState { final String? accountSequence; @@ -174,6 +175,9 @@ class UserNotifier extends StateNotifier { isLoggedIn: true, isLoading: false, ); + TelemetryService().setUserId(result.user.accountSequence); + TelemetryService().setAccessToken(result.accessToken); + TelemetryService().resumeAfterLogin(); // 登录后获取详细信息 await fetchProfile(); } catch (e) { @@ -197,6 +201,9 @@ class UserNotifier extends StateNotifier { isLoggedIn: true, isLoading: false, ); + TelemetryService().setUserId(result.user.accountSequence); + TelemetryService().setAccessToken(result.accessToken); + TelemetryService().resumeAfterLogin(); // 登录后获取详细信息 await fetchProfile(); } catch (e) { @@ -211,6 +218,8 @@ class UserNotifier extends StateNotifier { await _authDataSource.logout(state.refreshToken!); } catch (_) {} } + await TelemetryService().pauseForLogout(); + TelemetryService().setAccessToken(null); await _clearStorage(); state = UserState(); } @@ -224,6 +233,7 @@ class UserNotifier extends StateNotifier { final prefs = await SharedPreferences.getInstance(); await prefs.setString('access_token', newAccessToken); state = state.copyWith(accessToken: newAccessToken); + TelemetryService().setAccessToken(newAccessToken); } catch (e) { // 清除本地存储,不调用远程logout API(可能网络不可用) await _clearStorage();