| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 | import UAParser from 'ua-parser-js'import moment, { Moment } from 'moment'import request from 'utils/request'import api from 'utils/api'export interface IUserData {  user_id?: number  email?: string}export interface IVizData {  org_id: number  project_id: number  project_name: string  viz_type: 'dashboard' | 'display'  viz_id: number  viz_name: string  sub_viz_id: number  sub_viz_name: string}export interface IOperation extends IUserData, IVizData {  id?: number  action:    | 'login'    | 'visit'    | 'initial'    | 'sync'    | 'search'    | 'linkage'    | 'drill'    | 'download'    | 'print'  create_time: string}export interface IDuration extends IUserData, IVizData {  id?: number  start_time: string  end_time: string}export interface ITerminal extends IUserData {  id?: number  browser_name: string  browser_version: string  engine_name: string  engine_version: string  os_name: string  os_version: string  device_model: string  device_type: string  device_vendor: string  cpu_architecture: string  create_time: string}class Statistic {  public constructor() {    const uaParser = new UAParser().getResult()    const { browser, cpu, device, engine, os, ua } = uaParser    const loginUser = this.parse(this.getItemByLocalStorage('loginUser'))    this.setUserDate({      user_id: loginUser ? loginUser.id : void 0,      email: loginUser ? loginUser.email : ''    })    this.setTerminal({      browser_name: browser.name,      browser_version: browser.version,      engine_name: engine.name,      engine_version: engine.version,      os_name: os.name,      os_version: os.version,      device_model: device.model,      device_type: device.type,      device_vendor: device.vendor,      cpu_architecture: cpu.architecture,      create_time: this.getCurrentDateTime()    })    this.setDuration({      start_time: '',      end_time: '',      org_id: void 0,      project_id: void 0,      project_name: '',      viz_type: 'dashboard',      viz_id: void 0,      viz_name: '',      sub_viz_id: void 0,      sub_viz_name: ''    })    this.setOperation({      action: 'initial',      org_id: void 0,      project_id: void 0,      project_name: '',      viz_type: 'dashboard',      viz_id: void 0,      viz_name: '',      sub_viz_id: void 0,      sub_viz_name: '',      create_time: ''    })    const that = this    Reflect.defineProperty(that.clock, 'checkTime', {      configurable: true,      set(value) {        const time = that.getClock()        if (time >= 30) {          that.onceSetDurations(            {              end_time: that.getCurrentDateTime()            },            (data) => {              that.sendDuration([that.durationRecord])            }          )        }      }    })    this.onceSendTerminal = this.__once__(this.whenSendTerminal)  }  public onceSendTerminal: any  private onceSetDurations: any  private clock: { time: number } = { time: 0 }  private clocker: any  private startTime: Date  private endTimd: Date  public userData: IUserData  public terminalRecord: ITerminal  public durationRecord: IDuration  public operationRecord: IOperation  private prevDurationRecord: string = 'PREVDURATIONRECORD'  private setUserDate = (options?: IUserData) => {    const { user_id, email } = options    this.userData = {      user_id: user_id || void 0,      email: email || ''    }  }  public __once__(fn) {    let tag = true    return (...args) => {      if (tag) {        tag = !tag        return fn.apply(this, args)      } else {        return void 0      }    }  }  public startClock = () => {    this.resetClock()    this.clocker = setInterval(() => {      this.clock['time'] += 1      this.clock['checkTime'] = this.clock['time']    }, 1000)    this.onceSetDurations = this.__once__(this.setDurations)  }  public resetClock = () => {    if (this.clocker) {      clearTimeout(this.clocker)    }    this.clock['time'] = 0  }  public sendPrevDurationRecord = () => {    // 从localstorege拿上一次时长数据 send server    const record = this.getPrevDurationRecord()    if (record && record.length) {      this.sendDuration(record).then((data) => {        this.clearPrevDurationRecord()      })    }  }  public whenSendTerminal = () => {    this.sendPrevDurationRecord()    const loginUser = this.parse(this.getItemByLocalStorage('loginUser'))    this.setUserDate({      user_id: loginUser ? loginUser.id : void 0,      email: loginUser ? loginUser.email : ''    })    this.setTerminals({}, (data) => {      this.sendTerminal(data)    })  }  public isTimeout = (callback?: (data: IDuration) => any) => {    const time = this.getClock()    if (time > 30) {      this.setDurations({        start_time: this.getCurrentDateTime()      })    }    this.startClock()    if (typeof callback === 'function') {      callback(this.durationRecord)    }  }  public isResetTime = () => {    const time = this.getClock()    if (time && this.clocker) {      this.isTimeout()    }    return  }  public sendDuration = (body) => {    const url = `${api.buriedPoints}/duration`    return request(url, {      method: 'post',      data: body    })  }  public sendTerminal = (body) => {    const url = `${api.buriedPoints}/terminal`    return request(url, {      method: 'post',      data: [body]    })  }  public sendOperation = (body) => {    const url = `${api.buriedPoints}/visitoroperation`    return request(url, {      method: 'post',      data: Array.isArray(body) ? body : [body]    })  }  public getClock = () => this.clock['time']  private setTerminal = (options?: ITerminal) => {    const {      browser_name,      browser_version,      engine_name,      engine_version,      os_name,      os_version,      device_model,      device_type,      device_vendor,      cpu_architecture,      create_time    } = options as ITerminal    this.terminalRecord = {      browser_name: browser_name || '',      browser_version: browser_version || '',      engine_name: engine_name || '',      engine_version: engine_version || '',      os_name: os_name || '',      os_version: os_version || '',      device_model: device_model || '',      device_type: device_type || '',      device_vendor: device_vendor || '',      cpu_architecture: cpu_architecture || '',      create_time: create_time || '',      ...this.userData    }  }  public updateSingleFleld = <T>(    flag: 'terminal' | 'duration' | 'operation',    fleld: keyof T,    value,    callback?: (data: T) => any  ) => {    this[`${flag}Record`] = {      ...this[`${flag}Record`],      [fleld]: value    }    if (typeof callback === 'function') {      callback(this[`${flag}Record`])    }  }  public getPrevDurationRecord = () => {    const pr = this.parse(localStorage.getItem(this.prevDurationRecord))    if (pr && pr.length) {      return pr    }    return []  }  public setPrevDurationRecord = (    record: IDuration,    callback?: (data: IDuration) => any  ) => {    record = {      ...record,      ...this.userData    }    let prevDRecord = this.parse(localStorage.getItem(this.prevDurationRecord))    prevDRecord =      prevDRecord && Array.isArray(prevDRecord)        ? prevDRecord.concat(record)        : [record]    localStorage.setItem(this.prevDurationRecord, this.stringify(prevDRecord))    if (typeof callback === 'function') {      callback(this.durationRecord)    }  }  public clearPrevDurationRecord = () => {    localStorage.setItem(this.prevDurationRecord, this.stringify([]))  }  public getRecord = (flag: 'terminal' | 'duration' | 'operation') => {    return this[`${flag}Record`]  }  private setDuration = (options?: IDuration) => {    const {      org_id,      viz_id,      viz_type,      viz_name,      sub_viz_id,      project_id,      project_name,      sub_viz_name,      start_time,      end_time    } = options as IDuration    this.durationRecord = {      start_time: start_time || '',      end_time: end_time || '',      org_id: org_id || void 0,      project_id: project_id || void 0,      project_name: project_name || '',      viz_type: viz_type || 'dashboard',      viz_id: viz_id || void 0,      viz_name: viz_name || '',      sub_viz_id: sub_viz_id || void 0,      sub_viz_name: sub_viz_name || ''    }  }  public getCurrentDateTime = () => moment().format('YYYY-MM-DD HH:mm:ss')  private setOperation = (options?: IOperation) => {    const {      action,      org_id,      viz_id,      viz_type,      viz_name,      sub_viz_id,      project_id,      project_name,      sub_viz_name,      create_time    } = options as IOperation    this.operationRecord = {      action: action || 'initial',      org_id: org_id || void 0,      project_id: project_id || void 0,      project_name: project_name || '',      viz_type: viz_type || 'dashboard',      viz_id: viz_id || void 0,      viz_name: viz_name || '',      sub_viz_id: sub_viz_id || void 0,      sub_viz_name: sub_viz_name || '',      create_time: create_time || ''    }  }  public setOperations = (    options?: Partial<IOperation>,    callback?: (data: IOperation) => any  ) => {    this.operationRecord = {      ...this.operationRecord,      ...options,      ...this.userData    }    if (typeof callback === 'function') {      callback(this.operationRecord)    }  }  public setTerminals = (    options?: Partial<ITerminal>,    callback?: (data: ITerminal) => any  ) => {    this.terminalRecord = {      ...this.terminalRecord,      ...options,      ...this.userData    }    if (typeof callback === 'function') {      callback(this.terminalRecord)    }  }  public setDurations = (    options?: Partial<IDuration>,    callback?: (data: IDuration) => any  ) => {    this.durationRecord = {      ...this.durationRecord,      ...options,      ...this.userData    }    if (typeof callback === 'function') {      callback(this.durationRecord)    }  }  private obj2url = (obj) => {    return Object.keys(obj).reduce((a, b, currentIndex, array) => {      a = a + `${b}=${obj[b]}` + (currentIndex + 1 === array.length ? '' : '&')      return a    }, '?')  }  private getItemByLocalStorage = (item: string) => {    try {      if (item) {        return localStorage.getItem(item)      }    } catch (err) {      throw new Error(err)    }  }  private parse(str: string) {    try {      if (str) {        return JSON.parse(str)      }    } catch (err) {      throw new Error(err)    }  }  private stringify(data) {    try {      if (data) {        return JSON.stringify(data)      }    } catch (err) {      throw new Error(err)    }  }}export const statistic = new Statistic()
 |