feat(miniprogram): 埋点事件追踪服务
- 新增 analytics.ts:trackEvent/trackPageView/flushEvents - 事件队列本地缓存,批量上报到 /analytics/batch - 首页 page_view、预约创建、随访提交、健康数据录入四个关键埋点
This commit is contained in:
82
apps/miniprogram/src/services/analytics.ts
Normal file
82
apps/miniprogram/src/services/analytics.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import Taro from '@tarojs/taro';
|
||||
|
||||
type EventName =
|
||||
| 'page_view'
|
||||
| 'login'
|
||||
| 'bind_phone'
|
||||
| 'health_data_input'
|
||||
| 'health_trend_view'
|
||||
| 'appointment_create'
|
||||
| 'appointment_detail'
|
||||
| 'followup_submit'
|
||||
| 'report_view'
|
||||
| 'article_view'
|
||||
| 'article_share'
|
||||
| 'medication_add'
|
||||
| 'family_add'
|
||||
| 'profile_edit';
|
||||
|
||||
interface AnalyticsEvent {
|
||||
event: EventName | string;
|
||||
properties?: Record<string, unknown>;
|
||||
timestamp: number;
|
||||
userId?: string;
|
||||
patientId?: string;
|
||||
}
|
||||
|
||||
const QUEUE_KEY = 'analytics_queue';
|
||||
const MAX_QUEUE_SIZE = 50;
|
||||
|
||||
function getQueue(): AnalyticsEvent[] {
|
||||
return Taro.getStorageSync(QUEUE_KEY) || [];
|
||||
}
|
||||
|
||||
function setQueue(queue: AnalyticsEvent[]): void {
|
||||
Taro.setStorageSync(QUEUE_KEY, queue.slice(-MAX_QUEUE_SIZE));
|
||||
}
|
||||
|
||||
export function trackEvent(event: EventName | string, properties?: Record<string, unknown>): void {
|
||||
const userId = Taro.getStorageSync('user')?.id;
|
||||
const patientId = Taro.getStorageSync('current_patient_id');
|
||||
|
||||
const evt: AnalyticsEvent = {
|
||||
event,
|
||||
properties,
|
||||
timestamp: Date.now(),
|
||||
userId,
|
||||
patientId,
|
||||
};
|
||||
|
||||
const queue = getQueue();
|
||||
queue.push(evt);
|
||||
setQueue(queue);
|
||||
}
|
||||
|
||||
export function trackPageView(pageName: string, properties?: Record<string, unknown>): void {
|
||||
trackEvent('page_view', { page: pageName, ...properties });
|
||||
}
|
||||
|
||||
export async function flushEvents(): Promise<void> {
|
||||
const queue = getQueue();
|
||||
if (queue.length === 0) return;
|
||||
|
||||
const batch = queue.slice();
|
||||
setQueue([]);
|
||||
|
||||
try {
|
||||
const BASE_URL = process.env.TARO_APP_API_URL || 'http://localhost:3000/api/v1';
|
||||
await Taro.request({
|
||||
url: `${BASE_URL}/analytics/batch`,
|
||||
method: 'POST',
|
||||
data: { events: batch },
|
||||
});
|
||||
} catch {
|
||||
// 发送失败,回填队列
|
||||
const current = getQueue();
|
||||
setQueue([...batch.slice(-MAX_QUEUE_SIZE + current.length), ...current]);
|
||||
}
|
||||
}
|
||||
|
||||
export function getQueueSize(): number {
|
||||
return getQueue().length;
|
||||
}
|
||||
Reference in New Issue
Block a user