statistic.dv.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. import UAParser from 'ua-parser-js'
  2. import moment, { Moment } from 'moment'
  3. import request from 'utils/request'
  4. import api from 'utils/api'
  5. export interface IUserData {
  6. user_id?: number
  7. email?: string
  8. }
  9. export interface IVizData {
  10. org_id: number
  11. project_id: number
  12. project_name: string
  13. viz_type: 'dashboard' | 'display'
  14. viz_id: number
  15. viz_name: string
  16. sub_viz_id: number
  17. sub_viz_name: string
  18. }
  19. export interface IOperation extends IUserData, IVizData {
  20. id?: number
  21. action:
  22. | 'login'
  23. | 'visit'
  24. | 'initial'
  25. | 'sync'
  26. | 'search'
  27. | 'linkage'
  28. | 'drill'
  29. | 'download'
  30. | 'print'
  31. create_time: string
  32. }
  33. export interface IDuration extends IUserData, IVizData {
  34. id?: number
  35. start_time: string
  36. end_time: string
  37. }
  38. export interface ITerminal extends IUserData {
  39. id?: number
  40. browser_name: string
  41. browser_version: string
  42. engine_name: string
  43. engine_version: string
  44. os_name: string
  45. os_version: string
  46. device_model: string
  47. device_type: string
  48. device_vendor: string
  49. cpu_architecture: string
  50. create_time: string
  51. }
  52. class Statistic {
  53. public constructor() {
  54. const uaParser = new UAParser().getResult()
  55. const { browser, cpu, device, engine, os, ua } = uaParser
  56. const loginUser = this.parse(this.getItemByLocalStorage('loginUser'))
  57. this.setUserDate({
  58. user_id: loginUser ? loginUser.id : void 0,
  59. email: loginUser ? loginUser.email : ''
  60. })
  61. this.setTerminal({
  62. browser_name: browser.name,
  63. browser_version: browser.version,
  64. engine_name: engine.name,
  65. engine_version: engine.version,
  66. os_name: os.name,
  67. os_version: os.version,
  68. device_model: device.model,
  69. device_type: device.type,
  70. device_vendor: device.vendor,
  71. cpu_architecture: cpu.architecture,
  72. create_time: this.getCurrentDateTime()
  73. })
  74. this.setDuration({
  75. start_time: '',
  76. end_time: '',
  77. org_id: void 0,
  78. project_id: void 0,
  79. project_name: '',
  80. viz_type: 'dashboard',
  81. viz_id: void 0,
  82. viz_name: '',
  83. sub_viz_id: void 0,
  84. sub_viz_name: ''
  85. })
  86. this.setOperation({
  87. action: 'initial',
  88. org_id: void 0,
  89. project_id: void 0,
  90. project_name: '',
  91. viz_type: 'dashboard',
  92. viz_id: void 0,
  93. viz_name: '',
  94. sub_viz_id: void 0,
  95. sub_viz_name: '',
  96. create_time: ''
  97. })
  98. const that = this
  99. Reflect.defineProperty(that.clock, 'checkTime', {
  100. configurable: true,
  101. set(value) {
  102. const time = that.getClock()
  103. if (time >= 30) {
  104. that.onceSetDurations(
  105. {
  106. end_time: that.getCurrentDateTime()
  107. },
  108. (data) => {
  109. that.sendDuration([that.durationRecord])
  110. }
  111. )
  112. }
  113. }
  114. })
  115. this.onceSendTerminal = this.__once__(this.whenSendTerminal)
  116. }
  117. public onceSendTerminal: any
  118. private onceSetDurations: any
  119. private clock: { time: number } = { time: 0 }
  120. private clocker: any
  121. private startTime: Date
  122. private endTimd: Date
  123. public userData: IUserData
  124. public terminalRecord: ITerminal
  125. public durationRecord: IDuration
  126. public operationRecord: IOperation
  127. private prevDurationRecord: string = 'PREVDURATIONRECORD'
  128. private setUserDate = (options?: IUserData) => {
  129. const { user_id, email } = options
  130. this.userData = {
  131. user_id: user_id || void 0,
  132. email: email || ''
  133. }
  134. }
  135. public __once__(fn) {
  136. let tag = true
  137. return (...args) => {
  138. if (tag) {
  139. tag = !tag
  140. return fn.apply(this, args)
  141. } else {
  142. return void 0
  143. }
  144. }
  145. }
  146. public startClock = () => {
  147. this.resetClock()
  148. this.clocker = setInterval(() => {
  149. this.clock['time'] += 1
  150. this.clock['checkTime'] = this.clock['time']
  151. }, 1000)
  152. this.onceSetDurations = this.__once__(this.setDurations)
  153. }
  154. public resetClock = () => {
  155. if (this.clocker) {
  156. clearTimeout(this.clocker)
  157. }
  158. this.clock['time'] = 0
  159. }
  160. public sendPrevDurationRecord = () => {
  161. // 从localstorege拿上一次时长数据 send server
  162. const record = this.getPrevDurationRecord()
  163. if (record && record.length) {
  164. this.sendDuration(record).then((data) => {
  165. this.clearPrevDurationRecord()
  166. })
  167. }
  168. }
  169. public whenSendTerminal = () => {
  170. this.sendPrevDurationRecord()
  171. const loginUser = this.parse(this.getItemByLocalStorage('loginUser'))
  172. this.setUserDate({
  173. user_id: loginUser ? loginUser.id : void 0,
  174. email: loginUser ? loginUser.email : ''
  175. })
  176. this.setTerminals({}, (data) => {
  177. this.sendTerminal(data)
  178. })
  179. }
  180. public isTimeout = (callback?: (data: IDuration) => any) => {
  181. const time = this.getClock()
  182. if (time > 30) {
  183. this.setDurations({
  184. start_time: this.getCurrentDateTime()
  185. })
  186. }
  187. this.startClock()
  188. if (typeof callback === 'function') {
  189. callback(this.durationRecord)
  190. }
  191. }
  192. public isResetTime = () => {
  193. const time = this.getClock()
  194. if (time && this.clocker) {
  195. this.isTimeout()
  196. }
  197. return
  198. }
  199. public sendDuration = (body) => {
  200. const url = `${api.buriedPoints}/duration`
  201. return request(url, {
  202. method: 'post',
  203. data: body
  204. })
  205. }
  206. public sendTerminal = (body) => {
  207. const url = `${api.buriedPoints}/terminal`
  208. return request(url, {
  209. method: 'post',
  210. data: [body]
  211. })
  212. }
  213. public sendOperation = (body) => {
  214. const url = `${api.buriedPoints}/visitoroperation`
  215. return request(url, {
  216. method: 'post',
  217. data: Array.isArray(body) ? body : [body]
  218. })
  219. }
  220. public getClock = () => this.clock['time']
  221. private setTerminal = (options?: ITerminal) => {
  222. const {
  223. browser_name,
  224. browser_version,
  225. engine_name,
  226. engine_version,
  227. os_name,
  228. os_version,
  229. device_model,
  230. device_type,
  231. device_vendor,
  232. cpu_architecture,
  233. create_time
  234. } = options as ITerminal
  235. this.terminalRecord = {
  236. browser_name: browser_name || '',
  237. browser_version: browser_version || '',
  238. engine_name: engine_name || '',
  239. engine_version: engine_version || '',
  240. os_name: os_name || '',
  241. os_version: os_version || '',
  242. device_model: device_model || '',
  243. device_type: device_type || '',
  244. device_vendor: device_vendor || '',
  245. cpu_architecture: cpu_architecture || '',
  246. create_time: create_time || '',
  247. ...this.userData
  248. }
  249. }
  250. public updateSingleFleld = <T>(
  251. flag: 'terminal' | 'duration' | 'operation',
  252. fleld: keyof T,
  253. value,
  254. callback?: (data: T) => any
  255. ) => {
  256. this[`${flag}Record`] = {
  257. ...this[`${flag}Record`],
  258. [fleld]: value
  259. }
  260. if (typeof callback === 'function') {
  261. callback(this[`${flag}Record`])
  262. }
  263. }
  264. public getPrevDurationRecord = () => {
  265. const pr = this.parse(localStorage.getItem(this.prevDurationRecord))
  266. if (pr && pr.length) {
  267. return pr
  268. }
  269. return []
  270. }
  271. public setPrevDurationRecord = (
  272. record: IDuration,
  273. callback?: (data: IDuration) => any
  274. ) => {
  275. record = {
  276. ...record,
  277. ...this.userData
  278. }
  279. let prevDRecord = this.parse(localStorage.getItem(this.prevDurationRecord))
  280. prevDRecord =
  281. prevDRecord && Array.isArray(prevDRecord)
  282. ? prevDRecord.concat(record)
  283. : [record]
  284. localStorage.setItem(this.prevDurationRecord, this.stringify(prevDRecord))
  285. if (typeof callback === 'function') {
  286. callback(this.durationRecord)
  287. }
  288. }
  289. public clearPrevDurationRecord = () => {
  290. localStorage.setItem(this.prevDurationRecord, this.stringify([]))
  291. }
  292. public getRecord = (flag: 'terminal' | 'duration' | 'operation') => {
  293. return this[`${flag}Record`]
  294. }
  295. private setDuration = (options?: IDuration) => {
  296. const {
  297. org_id,
  298. viz_id,
  299. viz_type,
  300. viz_name,
  301. sub_viz_id,
  302. project_id,
  303. project_name,
  304. sub_viz_name,
  305. start_time,
  306. end_time
  307. } = options as IDuration
  308. this.durationRecord = {
  309. start_time: start_time || '',
  310. end_time: end_time || '',
  311. org_id: org_id || void 0,
  312. project_id: project_id || void 0,
  313. project_name: project_name || '',
  314. viz_type: viz_type || 'dashboard',
  315. viz_id: viz_id || void 0,
  316. viz_name: viz_name || '',
  317. sub_viz_id: sub_viz_id || void 0,
  318. sub_viz_name: sub_viz_name || ''
  319. }
  320. }
  321. public getCurrentDateTime = () => moment().format('YYYY-MM-DD HH:mm:ss')
  322. private setOperation = (options?: IOperation) => {
  323. const {
  324. action,
  325. org_id,
  326. viz_id,
  327. viz_type,
  328. viz_name,
  329. sub_viz_id,
  330. project_id,
  331. project_name,
  332. sub_viz_name,
  333. create_time
  334. } = options as IOperation
  335. this.operationRecord = {
  336. action: action || 'initial',
  337. org_id: org_id || void 0,
  338. project_id: project_id || void 0,
  339. project_name: project_name || '',
  340. viz_type: viz_type || 'dashboard',
  341. viz_id: viz_id || void 0,
  342. viz_name: viz_name || '',
  343. sub_viz_id: sub_viz_id || void 0,
  344. sub_viz_name: sub_viz_name || '',
  345. create_time: create_time || ''
  346. }
  347. }
  348. public setOperations = (
  349. options?: Partial<IOperation>,
  350. callback?: (data: IOperation) => any
  351. ) => {
  352. this.operationRecord = {
  353. ...this.operationRecord,
  354. ...options,
  355. ...this.userData
  356. }
  357. if (typeof callback === 'function') {
  358. callback(this.operationRecord)
  359. }
  360. }
  361. public setTerminals = (
  362. options?: Partial<ITerminal>,
  363. callback?: (data: ITerminal) => any
  364. ) => {
  365. this.terminalRecord = {
  366. ...this.terminalRecord,
  367. ...options,
  368. ...this.userData
  369. }
  370. if (typeof callback === 'function') {
  371. callback(this.terminalRecord)
  372. }
  373. }
  374. public setDurations = (
  375. options?: Partial<IDuration>,
  376. callback?: (data: IDuration) => any
  377. ) => {
  378. this.durationRecord = {
  379. ...this.durationRecord,
  380. ...options,
  381. ...this.userData
  382. }
  383. if (typeof callback === 'function') {
  384. callback(this.durationRecord)
  385. }
  386. }
  387. private obj2url = (obj) => {
  388. return Object.keys(obj).reduce((a, b, currentIndex, array) => {
  389. a = a + `${b}=${obj[b]}` + (currentIndex + 1 === array.length ? '' : '&')
  390. return a
  391. }, '?')
  392. }
  393. private getItemByLocalStorage = (item: string) => {
  394. try {
  395. if (item) {
  396. return localStorage.getItem(item)
  397. }
  398. } catch (err) {
  399. throw new Error(err)
  400. }
  401. }
  402. private parse(str: string) {
  403. try {
  404. if (str) {
  405. return JSON.parse(str)
  406. }
  407. } catch (err) {
  408. throw new Error(err)
  409. }
  410. }
  411. private stringify(data) {
  412. try {
  413. if (data) {
  414. return JSON.stringify(data)
  415. }
  416. } catch (err) {
  417. throw new Error(err)
  418. }
  419. }
  420. }
  421. export const statistic = new Statistic()