feat(mining-app): 集成 telemetry 遥测功能

- TelemetryService 添加 _accessToken 字段和 setAccessToken() 方法
- _getAuthHeaders() 现在返回 Bearer token 供心跳上报使用
- splash_page.dart: 启动时初始化 TelemetryService,已登录用户自动注入 userId 和 token
- user_providers.dart: 登录成功后注入 userId/token 并恢复上报;退出时暂停上报并清除 token;token 刷新时同步更新 telemetry token

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-03-05 09:29:06 -08:00
parent 34603aac8e
commit a2a318e24c
3 changed files with 34 additions and 2 deletions

View File

@ -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<String, String> _getAuthHeaders() {
return {};
if (_accessToken == null) return {};
return {'Authorization': 'Bearer $_accessToken'};
}
void setAccessToken(String? token) {
_accessToken = token;
}
void logEvent(

View File

@ -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<SplashPage> {
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<SplashPage> {
context.go(Routes.trading);
}
} else {
context.go(Routes.login);
if (mounted) context.go(Routes.login);
}
}

View File

@ -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<UserState> {
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<UserState> {
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<UserState> {
await _authDataSource.logout(state.refreshToken!);
} catch (_) {}
}
await TelemetryService().pauseForLogout();
TelemetryService().setAccessToken(null);
await _clearStorage();
state = UserState();
}
@ -224,6 +233,7 @@ class UserNotifier extends StateNotifier<UserState> {
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();