| import * as rrweb from 'rrweb'; | 
| import { guid } from './common'; | 
| import { eventWithTime, listenerHandler } from '@rrweb/types'; | 
| import { storageLocal } from './storage'; | 
|   | 
| export class Recorder { | 
|   // 生成会话ID(用于标识一次投保流程) | 
|   sessionId = guid(); | 
|   // 存储录制事件的数组 | 
|   events = []; | 
|   | 
|   stopFn: () => void; | 
|   | 
|   // 初始化录制器 | 
|   init() { | 
|     this.stopFn = rrweb.record({ | 
|       emit: (event) => { | 
|         // 收集事件(可选择实时发送到后端) | 
|         this.events.push(event); | 
|   | 
|         // 定期发送事件到后端(避免内存占用过大) | 
|         if (this.events.length % 100 === 0) { | 
|           this.sendEventsToBackend(this.events.splice(0, 100), this.sessionId); | 
|         } | 
|       }, | 
|       // 可选配置:忽略敏感元素 | 
|       blockClass: 'rr-block', // 为敏感元素添加此class | 
|       ignoreClass: 'rr-ignore', // 完全忽略的元素 | 
|     }); | 
|   } | 
|   | 
|   // 结束录制(例如提交投保表单时) | 
|   stopRecordingAndSave() { | 
|     this.stopFn?.(); | 
|     // 发送剩余事件到后端 | 
|     if (this.events.length > 0) { | 
|       this.sendEventsToBackend(this.events, this.sessionId); | 
|     } | 
|     // 存储会话ID(关联到用户投保记录) | 
|     this.saveSessionIdToUserRecord(this.sessionId); | 
|   } | 
|   | 
|   saveSessionIdToUserRecord(sessionId: string) {} | 
|   | 
|   async sendEventsToBackend(events: eventWithTime[], sessionId: string) { | 
|     try { | 
|       const body = JSON.stringify({ | 
|         sessionId, | 
|         events, | 
|         timestamp: new Date().toISOString(), | 
|       }); | 
|       console.log('body: ', body); | 
|       const storageEvents = storageLocal.getItem(`events`) || {}; | 
|       storageEvents[sessionId] = events; | 
|       storageLocal.setItem(`events`, storageEvents); | 
|       // await fetch('/api/recordings', { | 
|       //   method: 'POST', | 
|       //   headers: { | 
|       //     'Content-Type': 'application/json', | 
|       //   }, | 
|       //   body: , | 
|       // }); | 
|     } catch (error) { | 
|       console.error('Failed to send recording events:', error); | 
|       // 可实现本地存储作为降级方案 | 
|     } | 
|   } | 
|   | 
|   async replaySession(sessionId: string) { | 
|     // 从后端获取录制事件 | 
|     // const response = await fetch(`/api/recordings/${sessionId}`); | 
|     // const { events } = await response.json(); | 
|     const storageEvents = storageLocal.getItem(`events`) || {}; | 
|     if (!storageEvents[sessionId]) { | 
|       return; | 
|     } | 
|   | 
|     // 初始化回放器 | 
|     const player = new rrweb.Replayer(storageEvents[sessionId], { | 
|       root: document.getElementById('replay-container'), | 
|     }); | 
|   | 
|     // 可选:控制回放速度 | 
|     player.play(1.0); // 1倍速 | 
|   | 
|     // 可选:监听回放事件 | 
|     player.on('play', () => console.log('Replay started')); | 
|     player.on('pause', () => console.log('Replay paused')); | 
|     player.on('finish', () => console.log('Replay finished')); | 
|   } | 
| } |