petsHero-AI/lib/core/adjust/adjust_events.dart

144 lines
4.3 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:async';
import 'package:adjust_sdk/adjust.dart';
import 'package:adjust_sdk/adjust_event.dart';
import 'package:facebook_app_events/facebook_app_events.dart';
import 'package:logger/logger.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../config/facebook_config.dart';
/// 事件埋点Adjust + Facebook App Events 双通道上报
/// Adjust 识别码见 docs/adjuest.md
abstract final class AdjustEvents {
static final _fb = FacebookAppEvents();
static final _fbLog = Logger(
printer: PrettyPrinter(methodCount: 0, lineLength: 120),
level: FacebookConfig.debugLogs ? Level.trace : Level.off,
);
// 购买档位(充值页选择档位时上报)
static const String tier1999 = 'm0r9u9'; // 19.99
static const String tier4999 = 'aht1ve'; // 49.99
static const String tier599 = '47hhx9'; // 5.99
static const String tier999 = 'w775gd'; // 9.99
static const String tier9999 = 'y7994m'; // 99.99
// 首日充值
static const String firstPurchase = 'r6w4bi';
// 支付失败
static const String orderAbnormal = '4txlo1';
// 支付成功
static const String purchase = 'ek780r';
// 注册(首次调用 fast_login 成功时)
static const String register = '2z3dm4';
// 其他
static const String monthlyVip = '96o5ez'; // PetsHero AI Monthly VIP
static const String weeklyVip = '95yg4o'; // PetsHero AI Weekly VIP
/// 根据金额(如 19.99, 9.99)返回档位事件 token无法匹配时返回 purchase
static String? tierTokenFromPrice(num price) {
final p = price.toStringAsFixed(2);
switch (p) {
case '5.99':
return tier599;
case '9.99':
return tier999;
case '19.99':
return tier1999;
case '49.99':
return tier4999;
case '99.99':
return tier9999;
default:
return purchase;
}
}
/// 从金额字符串解析数字(如 "¥19.99" / "\$19.99"
static num? parsePrice(String amount) {
final match = RegExp(r'[\d.]+').firstMatch(amount);
if (match == null) return null;
return num.tryParse(match.group(0)!);
}
static void _track(String eventToken) {
Adjust.trackEvent(AdjustEvent(eventToken));
}
/// 上报 Facebookfire-and-forget不阻塞主流程
static void _trackFb(String eventDesc, Future<void> Function() fn) {
if (FacebookConfig.debugLogs) _fbLog.w('FB ↑ $eventDesc');
unawaited(fn());
}
/// 购买档位(用户点击某档位购买时)
static void trackTier(String eventToken) {
_track(eventToken);
}
/// 首日充值
static void trackFirstPurchase(double amount) {
_track(firstPurchase);
_trackFb(
'FirstRecharge amount=$amount',
() => _fb
.logEvent(name: 'FirstRecharge', parameters: {'amount': amount}));
}
/// 支付失败
static void trackOrderAbnormal() {
_track(orderAbnormal);
_trackFb('payment_failed', () => _fb.logEvent(name: 'payment_failed'));
}
/// 注册(首次 fast_login 成功)
static void trackRegister() {
_track(register);
_trackFb('CompletedRegistration',
() => _fb.logCompletedRegistration(registrationMethod: 'device'));
}
/// PetsHero AI Monthly VIP
static void trackMonthlyVip() {
_track(monthlyVip);
_trackFb('Subscribe monthly_vip',
() => _fb.logSubscribe(orderId: 'monthly_vip'));
}
/// PetsHero AI Weekly VIP
static void trackWeeklyVip() {
_track(weeklyVip);
_trackFb(
'Subscribe weekly_vip', () => _fb.logSubscribe(orderId: 'weekly_vip'));
}
static const String _keyRegisterDate = 'adjust_register_date';
/// 支付成功时调用:上报 Purchase若为首日充值则同时上报 first purchase
static Future<void> trackPurchaseSuccess(double amount) async {
_track(purchase);
final prefs = await SharedPreferences.getInstance();
final registerDate = prefs.getString(_keyRegisterDate);
final isFirstPurchase = registerDate != null &&
registerDate == DateTime.now().toIso8601String().substring(0, 10);
if (isFirstPurchase) {
trackFirstPurchase(amount);
}
_trackFb(
'Purchase',
() => _fb.logPurchase(
amount: amount,
currency: 'USD',
));
}
/// 支付失败时调用
static void trackPaymentFailed() {
trackOrderAbnormal();
}
}