zhengyiming
3 天以前 5664a1a616df498cba58b9a8e63a91ac0ba96bab
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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'));
  }
}