UNPKG

@cherish8change/naviot-fillingpoint_sdk

Version:

naviot埋点SDK

145 lines (120 loc) 4.07 kB
import { v4 as uuidv4 } from 'uuid'; import * as turf from "@turf/turf"; interface ReporStruct { // 上报间隔超过一个小时后产生新的reporId,即使浏览器关闭再打开如果不超过一小时也是用旧的 reportId: string; // 用户唯一标识 userId: string; // 归类模块 tag: string; // 模块名称,对应页面路由 moduleName: string; // 用户操作 action: string; // 操作参数 params: any; // 纬度 latitude: number; // 经度 longitude: number; // 操作发生时间戳 timestamp: number; // 是否移动设备 mobile: boolean; userAgent: string; platform: string; } type CommStr = Pick<ReporStruct, 'reportId' | 'userId' | 'latitude' | 'longitude' | 'mobile' | 'userAgent' | 'platform'>; class FillingPointSDK { private data: CommStr private enable: boolean; // 启用/禁用 private STORAGE_KEY = 'FillingPoint_KEY'; private timeout = 1000 * 60 * 60; private url = ''; private headers: RequestInit['headers']; constructor(config: { url: string; userId: string; platform: string; mobile?: boolean, headers?: RequestInit['headers']; }) { this.enable = true; this.url = config.url; this.headers = config.headers ?? {}; this.data = { reportId: uuidv4(), userId: config.userId, latitude: -1, longitude: -1, mobile: config.mobile ?? false, userAgent: navigator.userAgent, platform: config.platform, }; this.listenerGeoChange(); if (typeof window !== 'undefined' && !window.FillingPointSDK) { // 挂载实例到 window window.FillingPointSDK = this; } } listenerGeoChange() { navigator.geolocation.watchPosition((succ) => { console.log('地理位置变化:', succ); const latitude = succ.coords.latitude; const longitude = succ.coords.longitude; const storage = JSON.parse(localStorage.getItem(this.STORAGE_KEY) ?? '{}'); const from = turf.point([storage.latitude ?? latitude, storage.longitude ?? longitude]); const to = turf.point([latitude, longitude]); const distance = turf.distance(from, to); // 千米 this.setData('latitude', latitude); this.setData('longitude', longitude); if (distance > 3) { const uuid = uuidv4(); this.setData('reportId', uuid); localStorage.setItem(this.STORAGE_KEY, JSON.stringify({ ...storage, reportId: uuid, latitude, longitude })); } else if (!storage.latitude && !storage.longitude) { localStorage.setItem(this.STORAGE_KEY, JSON.stringify({ ...storage, latitude, longitude })); } }, () => {}, {}); } getData<T extends keyof CommStr>(key: T): CommStr[T] { return this.data[key]; } setData<T extends keyof CommStr>(key: T, value: CommStr[T]) { this.data[key] = value; } setTime(time: number) { this.timeout = time; } disable() { this.enable = false; } repor(tag: string, moduleName: ReporStruct['moduleName'], action: ReporStruct['action'], params: ReporStruct['params'] = '') { if (!this.enable) return; const timestamp = new Date().getTime(); window.requestAnimationFrame(() => { const storage = JSON.parse(localStorage.getItem(this.STORAGE_KEY) ?? '{}'); if (timestamp - (storage.timestamp ?? 0) > this.timeout) { const uuid = uuidv4(); this.setData('reportId', uuid); localStorage.setItem(this.STORAGE_KEY, JSON.stringify({ ...storage, reportId: uuid, timestamp })); } else { localStorage.setItem(this.STORAGE_KEY, JSON.stringify({ ...storage, timestamp })); } const reporData: ReporStruct = { tag, moduleName, action, params, timestamp, ...this.data, }; if (!this.url) { return; } fetch(this.url, { method: 'post', headers: { "Content-Type": "application/json", ...this.headers }, body: JSON.stringify(reporData), }); }); } } export default FillingPointSDK;