Files
JiaZhiQianYan/utils/posthog.js
2025-11-26 17:19:38 +08:00

151 lines
3.9 KiB
JavaScript
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 posthog from 'posthog-js'
class PostHogTracker {
constructor(config) {
// US Cloud 或 EU Cloud 或自托管地址
this.apiHost = config.apiHost || 'https://us.i.posthog.com';
this.apiKey = config.apiKey; // 项目 API Key
this.distinctId = null;
}
// 初始化并获取用户唯一标识
init() {
// 优先使用 openid如果没有则生成随机 ID
const storedId = uni.getStorageSync('posthog_distinct_id');
if (storedId) {
this.distinctId = storedId;
} else {
this.distinctId = this._generateUUID();
uni.setStorageSync('posthog_distinct_id', this.distinctId);
}
return this;
}
// 设置用户 ID登录后调用
identify(userId, userProperties = {}) {
this.distinctId = userId;
uni.setStorageSync('posthog_distinct_id', userId);
// 发送 $identify 事件
this._capture('$identify', {
$set: userProperties
});
}
// 捕获事件
capture(eventName, properties = {}) {
this._capture(eventName, properties);
}
// 页面浏览事件
pageView(pagePath, pageTitle) {
this._capture('$pageview', {
$current_url: pagePath,
$title: pageTitle
});
}
// 内部发送方法
_capture(event, properties = {}) {
const payload = {
api_key: this.apiKey,
event: event,
distinct_id: this.distinctId,
timestamp: new Date().toISOString(),
properties: {
...properties,
$lib: 'uniapp-miniprogram',
$lib_version: '1.0.0',
...this._getDefaultProperties()
}
};
uni.request({
url: `${this.apiHost}/i/v0/e/`,
method: 'POST',
header: {
'Content-Type': 'application/json'
},
data: payload,
success: (res) => {
console.log('PostHog event captured:', event);
},
fail: (err) => {
console.error('PostHog capture failed:', err);
// 可以考虑将失败的事件存储到本地,稍后重试
this._saveFailedEvent(payload);
}
});
}
// 批量发送事件(性能优化)
captureBatch(events) {
const payload = events.map(e => ({
api_key: this.apiKey,
event: e.event,
distinct_id: this.distinctId,
timestamp: e.timestamp || new Date().toISOString(),
properties: {
...e.properties,
...this._getDefaultProperties()
}
}));
uni.request({
url: `${this.apiHost}/batch/`,
method: 'POST',
header: {
'Content-Type': 'application/json'
},
data: payload,
success: (res) => {
console.log('PostHog batch captured:', events.length, 'events');
}
});
}
// 获取默认属性
_getDefaultProperties() {
const systemInfo = uni.getSystemInfoSync();
return {
$os: systemInfo.platform,
$os_version: systemInfo.system,
$device: systemInfo.model,
$screen_height: systemInfo.screenHeight,
$screen_width: systemInfo.screenWidth,
mp_platform: 'uniapp'
};
}
// 生成 UUID
_generateUUID() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = Math.random() * 16 | 0;
const v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
// 保存失败事件(离线支持)
_saveFailedEvent(payload) {
const failedEvents = uni.getStorageSync('posthog_failed_events') || [];
failedEvents.push(payload);
uni.setStorageSync('posthog_failed_events', failedEvents);
}
// 重试发送失败的事件
retryFailedEvents() {
const failedEvents = uni.getStorageSync('posthog_failed_events') || [];
if (failedEvents.length > 0) {
this.captureBatch(failedEvents);
uni.removeStorageSync('posthog_failed_events');
}
}
}
// 导出单例
export default new PostHogTracker({
apiHost: 'https://us.i.posthog.com', // 或 eu.i.posthog.com
apiKey: 'YOUR_PROJECT_API_KEY' // 在 PostHog 项目设置中获取
}).init();