Files
freeCell/lib/adjust/adjust_service.dart
2026-06-05 16:08:28 +08:00

184 lines
5.4 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:developer' as developer;
import 'package:flutter/foundation.dart';
import 'package:adjust_sdk/adjust.dart';
import 'package:adjust_sdk/adjust_attribution.dart';
import 'package:adjust_sdk/adjust_config.dart';
import 'package:adjust_sdk/adjust_event.dart';
import 'package:adjust_sdk/adjust_event_failure.dart';
import 'package:adjust_sdk/adjust_event_success.dart';
import 'package:adjust_sdk/adjust_session_failure.dart';
import 'package:adjust_sdk/adjust_session_success.dart';
import 'package:freecell/utils/report.dart';
typedef EventParams = Map<String, dynamic>;
class AdjustService {
Map<String, String> _eventNameToToken = {};
Map<String, String> get eventNameToToken => _eventNameToToken;
set eventNameToToken(Map<String, String> m) {
_eventNameToToken = Map<String, String>.from(m);
}
AdjustService._();
static final AdjustService instance = AdjustService._();
bool _inited = false;
String _toStr(dynamic v) => '$v';
double? _toNum(dynamic v) {
if (v == null) return null;
if (v is num) return v.toDouble();
return double.tryParse('$v');
}
Future<void> init(String appToken, [bool isProd = true]) async{
developer.log(appToken, name: 'Adjust');
if (_inited) {
developer.log('[Adjust] already inited', name: 'Adjust');
return;
}
if (appToken.isEmpty) return;
final environment = isProd
? AdjustEnvironment.production
: AdjustEnvironment.sandbox;
final config = AdjustConfig(appToken, environment);
config.isCostDataInAttributionEnabled = true;
config.attributionCallback = (AdjustAttribution a) async {
debugPrint('Adjust attribution: ${a.toString()}');
ReportService.I.attribution = a;
ReportService.I.reportAttribution();
};
config.eventSuccessCallback = (AdjustEventSuccess s) {
debugPrint('Adjust event success: ${s.toString()}');
};
config.eventFailureCallback = (AdjustEventFailure f) {
debugPrint('Adjust event failure: ${f.toString()}');
};
config.sessionSuccessCallback = (AdjustSessionSuccess s) {
debugPrint('Adjust session success: ${s.toString()}');
};
config.sessionFailureCallback = (AdjustSessionFailure f) {
debugPrint('Adjust session failure: ${f.toString()}');
};
// 可选:如果你希望缓存更多 deduplicationId可调大
config.eventDeduplicationIdsMaxSize = 20;
config.logLevel = isProd ? AdjustLogLevel.info : AdjustLogLevel.verbose;
Adjust.initSdk(config);
_inited = true;
}
Future<void> trackEventWithName(
String eventName, [
EventParams? params,
]) async {
debugPrint('call trackEventWithName eventName $eventName params $params');
// 你可以在这里做个映射eventName -> eventToken
// 也可以直接让外部传 eventToken 过来
final eventToken = _eventNameToToken[eventName];
if (eventToken == null) {
debugPrint('not find eventToken $eventName');
return;
}
ReportService.I.report(eventName, params);
await trackEvent(eventToken, params);
}
Future<void> trackEvent(String eventToken, [EventParams? params]) async {
try {
debugPrint("track event eventToken $eventToken params $params");
if (eventToken.isEmpty) return;
final event = AdjustEvent(eventToken);
if (params != null && params.isNotEmpty) {
double? revenue;
String? currency;
// 优先级deduplicationId > orderId > transactionId
String? dedupId;
for (final entry in params.entries) {
final key = entry.key;
final value = entry.value;
if (value == null) continue;
switch (key) {
case 'revenue':
case 'amount':
revenue = _toNum(value);
break;
case 'currency':
currency = _toStr(value);
break;
case 'deduplicationId':
case 'orderId':
dedupId ??= _toStr(value);
break;
case 'callbackId':
event.callbackId = _toStr(value);
break;
case 'transactionId':
final tid = _toStr(value);
event.transactionId = tid;
dedupId ??= tid;
break;
case 'productId':
event.productId = _toStr(value);
break;
case 'purchaseToken':
event.purchaseToken = _toStr(value);
break;
default:
final v = _toStr(value);
if (key.startsWith('partner:')) {
final realKey = key.substring('partner:'.length);
if (realKey.isNotEmpty) {
event.addPartnerParameter(realKey, v);
}
} else {
event.addCallbackParameter(key, v);
}
break;
}
}
if (dedupId != null && dedupId.isNotEmpty) {
event.deduplicationId = dedupId;
}
if (revenue != null && currency != null && currency.isNotEmpty) {
event.setRevenue(revenue, currency);
}
}
Adjust.trackEvent(event);
} catch (e, st) {
developer.log(
'[Adjust] trackEvent error: $e',
name: 'Adjust',
stackTrace: st,
);
}
}
}