feat: C3 客户端埋点 SDK(EventTracker 批量上报 + 核心事件)
This commit is contained in:
1 parent
1dbc3acd80
commit
92bfc76e50
2 files changed
+66
No files matched your search
@@ -41,6 +41,7 @@ import 'core/data/services/download_controller.dart';
|
|||||||
import 'core/data/services/favorite_controller.dart';
|
import 'core/data/services/favorite_controller.dart';
|
||||||
import 'core/data/services/interaction_controller.dart';
|
import 'core/data/services/interaction_controller.dart';
|
||||||
import 'core/data/services/locale_controller.dart';
|
import 'core/data/services/locale_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/video_player_port.dart';
|
import 'core/data/services/video_player_port.dart';
|
||||||
import 'core/data/services/wallet_controller.dart';
|
import 'core/data/services/wallet_controller.dart';
|
||||||
@@ -235,6 +236,7 @@ class _LumaDramaAppState extends State<LumaDramaApp> {
|
|||||||
return MultiProvider(
|
return MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
Provider(create: (_) => PlaybackCoordinator()),
|
Provider(create: (_) => PlaybackCoordinator()),
|
||||||
|
Provider<EventTracker>(create: (_) => EventTracker(_apiClient)),
|
||||||
Provider<PlayerFactory>(create: (_) => widget.playerFactory),
|
Provider<PlayerFactory>(create: (_) => widget.playerFactory),
|
||||||
Provider<CatalogRepository>.value(value: _catalogRepository),
|
Provider<CatalogRepository>.value(value: _catalogRepository),
|
||||||
Provider<PlaybackRepository>.value(value: _playback),
|
Provider<PlaybackRepository>.value(value: _playback),
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
// Author: fruit.com.cn
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import '../remote/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', body: {
|
||||||
|
'deviceId': 'device-0001',
|
||||||
|
'sessionId': 'session-0001',
|
||||||
|
'events': events,
|
||||||
|
});
|
||||||
|
} catch (_) {
|
||||||
|
// 埋点失败不影响主流程,静默丢弃。
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user