/** * 小程序生命周期管理器 * 负责监听小程序的显示、隐藏等生命周期事件,并触发相应的埋点 */ import { Analytics } from './AnalyticsManager'; export class MPLifecycleManager { private static instance: MPLifecycleManager; private isInitialized: boolean = false; private showTime: number = 0; private hideTime: number = 0; private constructor() {} /** * 获取单例实例 */ public static getInstance(): MPLifecycleManager { if (!MPLifecycleManager.instance) { MPLifecycleManager.instance = new MPLifecycleManager(); } return MPLifecycleManager.instance; } /** * 初始化小程序生命周期监听 */ public init(): void { if (this.isInitialized) { return; } console.log('[MPLifecycleManager] 初始化小程序生命周期监听'); // 如果是微信小游戏环境,注册生命周期监听 if (typeof wx !== 'undefined') { this.setupWechatListeners(); } else { // Web环境下监听页面可见性变化 this.setupWebListeners(); } this.isInitialized = true; } /** * 设置微信小游戏生命周期监听 */ private setupWechatListeners(): void { // 监听小程序显示事件 if (wx.onShow) { wx.onShow((options: any) => { console.log('[MPLifecycleManager] 小程序显示', options); this.showTime = Date.now(); // 计算后台时长 const backgroundTime = this.hideTime > 0 ? this.showTime - this.hideTime : 0; // 追踪显示事件 Analytics.trackMPShow({ scene: options.scene || 0, query: JSON.stringify(options.query || {}), shareTicket: options.shareTicket || '', referrerInfo: options.referrerInfo || {} }); // 检测是否通过分享进入,如果是则追踪分享事件 if (options.shareTicket) { this.trackMPShareFromShow(options); } // 单独记录后台时长 if (backgroundTime > 0) { Analytics.track('$MPBackgroundTime', { background_time: backgroundTime }); } }); } // 监听小程序隐藏事件 if (wx.onHide) { wx.onHide(() => { console.log('[MPLifecycleManager] 小程序隐藏'); this.hideTime = Date.now(); // 计算前台时长 const foregroundTime = this.showTime > 0 ? this.hideTime - this.showTime : 0; Analytics.trackMPHide(); // 可以添加额外的隐藏事件属性 Analytics.track('$MPHide', { hide_time: this.hideTime, foreground_time: foregroundTime }); }); } } /** * 追踪通过分享进入的事件 */ private trackMPShareFromShow(options: any): void { try { Analytics.trackMPShare({ share_type: 'show_from_share', // 分享类型:从分享显示 share_target: 'unknown', // 分享目标:未知(显示时无法确定) share_content: options.shareTicket || '', // 分享内容:shareTicket share_time: Date.now(), // 分享时间戳 scene: options.scene || 0, // 显示场景 query: JSON.stringify(options.query || {}) // 显示参数 }); console.log('[MPLifecycleManager] $MPShare 事件已上报(从分享显示):', options); } catch (error) { console.error('[MPLifecycleManager] 追踪分享显示事件时出错:', error); } } /** * 设置Web环境生命周期监听 */ private setupWebListeners(): void { // 监听页面可见性变化 document.addEventListener('visibilitychange', () => { if (document.hidden) { // 页面隐藏 console.log('[MPLifecycleManager] 页面隐藏'); this.hideTime = Date.now(); const foregroundTime = this.showTime > 0 ? this.hideTime - this.showTime : 0; Analytics.track('$MPHide', { hide_time: this.hideTime, foreground_time: foregroundTime, platform: 'web' }); } else { // 页面显示 console.log('[MPLifecycleManager] 页面显示'); this.showTime = Date.now(); const backgroundTime = this.hideTime > 0 ? this.showTime - this.hideTime : 0; Analytics.track('$MPShow', { show_time: this.showTime, background_time: backgroundTime, platform: 'web' }); } }); // 监听页面加载完成 window.addEventListener('load', () => { console.log('[MPLifecycleManager] 页面加载完成'); this.showTime = Date.now(); Analytics.track('$MPShow', { show_time: this.showTime, platform: 'web', event_type: 'page_load' }); }); // 监听页面卸载 window.addEventListener('beforeunload', () => { console.log('[MPLifecycleManager] 页面即将卸载'); this.hideTime = Date.now(); const foregroundTime = this.showTime > 0 ? this.hideTime - this.showTime : 0; Analytics.track('$MPHide', { hide_time: this.hideTime, foreground_time: foregroundTime, platform: 'web', event_type: 'page_unload' }); }); } /** * 获取当前会话时长 */ public getSessionDuration(): number { if (this.showTime === 0) { return 0; } const currentTime = Date.now(); return currentTime - this.showTime; } /** * 手动触发显示事件(用于特殊场景) */ public triggerShow(options: any = {}): void { this.showTime = Date.now(); Analytics.trackMPShow(options); } /** * 手动触发隐藏事件(用于特殊场景) */ public triggerHide(): void { this.hideTime = Date.now(); Analytics.trackMPHide(); } } // 导出单例实例 export const MPLifecycle = MPLifecycleManager.getInstance();