feat: C3 客户端埋点 SDK(EventTracker 批量上报 + 核心事件)
This commit is contained in:
1 parent
070ec78668
commit
faaf2f7283
2 files changed
+66
No files matched your search
@@ -13,6 +13,7 @@ import 'core/data/services/app_catalog_controller.dart';
|
|||||||
import 'core/data/services/auth_controller.dart';
|
import 'core/data/services/auth_controller.dart';
|
||||||
import 'core/data/services/catalog_controller.dart';
|
import 'core/data/services/catalog_controller.dart';
|
||||||
import 'core/data/services/engagement_controller.dart';
|
import 'core/data/services/engagement_controller.dart';
|
||||||
|
import 'core/data/services/event_tracker.dart';
|
||||||
import 'core/data/services/playback_session.dart';
|
import 'core/data/services/playback_session.dart';
|
||||||
import 'core/data/services/token_storage.dart';
|
import 'core/data/services/token_storage.dart';
|
||||||
import 'core/data/services/video_player_port.dart';
|
import 'core/data/services/video_player_port.dart';
|
||||||
@@ -31,6 +32,7 @@ class LumaDramaApp extends StatelessWidget {
|
|||||||
Provider(create: (_) => PlaybackCoordinator()),
|
Provider(create: (_) => PlaybackCoordinator()),
|
||||||
Provider<PlayerFactory>(create: (_) => playerFactory),
|
Provider<PlayerFactory>(create: (_) => playerFactory),
|
||||||
Provider(create: (_) => ApiClient()),
|
Provider(create: (_) => ApiClient()),
|
||||||
|
Provider(create: (ctx) => EventTracker(ctx.read<ApiClient>())),
|
||||||
Provider(create: (_) => TokenStorage()),
|
Provider(create: (_) => TokenStorage()),
|
||||||
Provider(
|
Provider(
|
||||||
create: (ctx) => AuthRepository(
|
create: (ctx) => AuthRepository(
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
// Author: fruit.com.cn
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'api_client.dart';
|
||||||
|
|
||||||
|
/// 核心埋点事件名(第一阶段口径,后续与运营对齐后可扩展)。
|
||||||
|
class AppEvents {
|
||||||
|
AppEvents._();
|
||||||
|
|
||||||
|
static const String playbackStart = 'playback_start';
|
||||||
|
static const String playbackEnd = 'playback_end';
|
||||||
|
static const String paySuccess = 'pay_success';
|
||||||
|
static const String register = 'register';
|
||||||
|
static const String click = 'click';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 埋点上报:本地缓冲、批量上报,失败静默丢弃不影响主流程。
|
||||||
|
class EventTracker {
|
||||||
|
EventTracker(this._api);
|
||||||
|
|
||||||
|
final ApiClient _api;
|
||||||
|
|
||||||
|
static const int _flushSize = 10;
|
||||||
|
static const Duration _flushInterval = Duration(seconds: 10);
|
||||||
|
|
||||||
|
final List<Map<String, Object?>> _buffer = [];
|
||||||
|
Timer? _timer;
|
||||||
|
|
||||||
|
void track(
|
||||||
|
String eventName, {
|
||||||
|
String? page,
|
||||||
|
Map<String, Object?>? properties,
|
||||||
|
}) {
|
||||||
|
_buffer.add({
|
||||||
|
'eventName': eventName,
|
||||||
|
'eventTime': DateTime.now().toIso8601String(),
|
||||||
|
'page': page,
|
||||||
|
'properties': properties,
|
||||||
|
});
|
||||||
|
if (_buffer.length >= _flushSize) {
|
||||||
|
flush();
|
||||||
|
} else {
|
||||||
|
_timer ??= Timer(_flushInterval, flush);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> flush() async {
|
||||||
|
if (_buffer.isEmpty) return;
|
||||||
|
final events = List<Map<String, Object?>>.from(_buffer);
|
||||||
|
_buffer.clear();
|
||||||
|
_timer?.cancel();
|
||||||
|
_timer = null;
|
||||||
|
try {
|
||||||
|
await _api.post('/app/events', data: {
|
||||||
|
'deviceId': 'device-0001',
|
||||||
|
'sessionId': 'session-0001',
|
||||||
|
'events': events,
|
||||||
|
});
|
||||||
|
} catch (_) {
|
||||||
|
// 埋点失败不影响主流程,静默丢弃。
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user