TimeOnPage.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. //计算账号累计活跃时长
  2. import setting from '@/mixins/theme.js'
  3. import {timeOnPage , recordActiveLogin} from '@/api/api.js';
  4. //活跃时间间隔 (s)
  5. const TimeInterval = 60*10
  6. //页面停留时间 (s)
  7. let stayTime = 0
  8. //活跃时间记录计时器 1分钟记录一次
  9. let intervalTimer=null
  10. export const openLoginTimer=()=>{
  11. clearInterval(intervalTimer)
  12. intervalTimer = setInterval(()=>{
  13. let ActiveTime=0
  14. if(localStorage.getItem('loginTime')){
  15. ActiveTime = (new Date()-new Date(localStorage.getItem('loginTime')))/1000
  16. console.log("间隔记录时长",ActiveTime+'s');
  17. recordActiveLogin({ActiveTime:Math.round(ActiveTime)}).then(res=>{
  18. if(res.Ret!==200) return
  19. })
  20. }
  21. },1000*60)
  22. }
  23. export const recordActiveLoginFun=(time)=>{
  24. let inactiveTime = time || new Date()
  25. let ActiveTime=0
  26. if(localStorage.getItem('loginTime')){
  27. ActiveTime = (inactiveTime-new Date(localStorage.getItem('loginTime')))/1000
  28. console.log("结束计算时长",ActiveTime+'s');
  29. recordActiveLogin({ActiveTime:Math.round(ActiveTime)}).then(res=>{
  30. if(res.Ret!==200) return
  31. }).finally(()=>{
  32. // 清除工作
  33. clearInterval(intervalTimer)
  34. // localStorage.removeItem('loginTime')
  35. })
  36. }
  37. }
  38. let timer = null
  39. //打开计时器
  40. export const optionTimeCalc = ()=>{
  41. const IsActive = sessionStorage.getItem('IsActive')
  42. // console.log(IsActive,'IsActive');
  43. if(Number(IsActive)===0){
  44. //console.log('打开计时器')
  45. sessionStorage.setItem('IsActive',1)
  46. timeStr = new Date().getTime()
  47. startCalc()
  48. }
  49. }
  50. //开始计时
  51. export const startCalc = ()=>{
  52. sessionStorage.setItem('preTitle',document.title)
  53. timer = setInterval(()=>{
  54. stayTime++
  55. if(stayTime>=TimeInterval){
  56. endCalc('timeup',0)
  57. }
  58. },1000)
  59. }
  60. //结束计时
  61. export const endCalc = (type,intervalT)=>{
  62. //console.log('关闭计时器')
  63. clearInterval(timer)
  64. const IsActive = sessionStorage.getItem('IsActive')
  65. if(Number(IsActive) && localStorage.getItem('auth')){
  66. sendTOPInfo(type,intervalT)
  67. }
  68. stayTime = 0
  69. /* if(type==='timeup'){
  70. sessionStorage.setItem('IsActive',0)
  71. } */
  72. timeStr = new Date().getTime()
  73. sessionStorage.setItem('IsActive',0)
  74. }
  75. // 退出登录时的结算
  76. export const loginEndCalc=()=>{
  77. let t = new Date().getTime() - timeStr
  78. //console.log('待了时长replacestate:'+ t)
  79. const IsActive = sessionStorage.getItem('IsActive')
  80. if(Number(IsActive)){
  81. endCalc('logout',t)
  82. }
  83. }
  84. //发送活跃时长数据
  85. export const sendTOPInfo = (type,intervalT)=>{
  86. //获取上一个页面标题
  87. const Title = sessionStorage.getItem('preTitle')
  88. //console.log('发送活跃时长数据 ↓↓↓')
  89. //获取计时间隔时间和页面名称
  90. if(type==='timeup'){
  91. console.table([{'停留时间(timeup)':stayTime+' s','停留页面':Title}])
  92. }else{
  93. console.table([{'停留时间(other)':Number(intervalT)/1000+' s','停留页面':Title,'触发类型':type}])
  94. }
  95. const Part = Title.split('-').length>1?Title.split('-')[1]:Title
  96. const ActiveTime = type==='timeup'?stayTime:Number(intervalT)/1000
  97. //发送数据
  98. if(!Part.length||Part==setting.name) return
  99. if(ActiveTime>TimeInterval*12) return
  100. console.log("ActiveTime:",ActiveTime,"Part:",Part)
  101. timeOnPage({
  102. ActiveTime:Math.round(ActiveTime),
  103. Part:Part
  104. }).then(res=>{
  105. if(res.Ret!==200) return
  106. })
  107. }
  108. //路由监听部分
  109. //source https://juejin.cn/post/6905913200060366862#heading-2
  110. let timeStr=null
  111. let rewriteHis = function(type){
  112. let origin = window.history[type]
  113. return function(){
  114. let rs = origin.apply(this, arguments)
  115. let e = new Event(type.toLocaleLowerCase())
  116. e.arguments = arguments
  117. window.dispatchEvent(e)
  118. return rs
  119. }
  120. }
  121. export function init(){
  122. // const unloadT = sessionStorage.getItem('unloadT')
  123. // console.log("init",unloadT,IsActive);
  124. // if(unloadT){
  125. // //console.log('刷新该页呆了时长',unloadT)
  126. // sessionStorage.removeItem('unloadT')
  127. // sessionStorage.setItem('preTitle',document.title)
  128. // if(Number(IsActive)){
  129. // endCalc('unload',unloadT)
  130. // }
  131. // }
  132. // timeStr = new Date().getTime()
  133. sessionStorage.setItem('IsActive',0)
  134. optionTimeCalc()
  135. // const IsActive = sessionStorage.getItem('IsActive')
  136. // if(Number(IsActive)){
  137. // sessionStorage.setItem('unloadT',t)
  138. // }
  139. if(localStorage.getItem("loginTime") && localStorage.getItem('auth')){
  140. openLoginTimer()
  141. }
  142. }
  143. export const doPageEventListener=function(){
  144. // init() 放在router.afterEach中,不然一开始拿不到正确的页面标题
  145. window.history.pushState = rewriteHis('pushState')
  146. window.history.replaceState = rewriteHis('replaceState')
  147. //刷新加载完成
  148. // 因为监听改位置了,每次路由刷新时,由于需要等待接口返回,需要先判断是否有 权限才能监听,这时候onload已经执行了,根本监听不到
  149. // window.addEventListener('load',(e)=>{
  150. // const unloadT = sessionStorage.getItem('unloadT')
  151. // const IsActive = sessionStorage.getItem('IsActive')
  152. // if(unloadT){
  153. // //console.log('刷新该页呆了时长',unloadT)
  154. // sessionStorage.removeItem('unloadT')
  155. // sessionStorage.setItem('preTitle',document.title)
  156. // if(Number(IsActive)){
  157. // endCalc('unload',unloadT)
  158. // }
  159. // }
  160. // timeStr = new Date().getTime()
  161. // optionTimeCalc()
  162. // if((!localStorage.getItem("loginTime")) && localStorage.getItem('auth')){
  163. // // 初始化的时候 先重置最近登录时长
  164. // recordActiveLogin({ActiveTime:0}).then(res=>{
  165. // if(res.Ret!==200) return
  166. // })
  167. // openLoginTimer()
  168. // }
  169. // })
  170. //刷新离开页面
  171. window.addEventListener('beforeunload',(e)=>{
  172. console.log('beforeunload')
  173. let t = new Date().getTime() - timeStr
  174. // const unloadT = sessionStorage.getItem('unloadT')
  175. const IsActive = sessionStorage.getItem('IsActive')
  176. console.log("init",IsActive);
  177. // if(unloadT){
  178. //console.log('刷新该页呆了时长',unloadT)
  179. // sessionStorage.removeItem('unloadT')
  180. // sessionStorage.setItem('preTitle',document.title)
  181. if(Number(IsActive)){
  182. endCalc('unload',t)
  183. }
  184. // }
  185. // timeStr = new Date().getTime()
  186. // optionTimeCalc()
  187. // const IsActive = sessionStorage.getItem('IsActive')
  188. // if(Number(IsActive)){
  189. // sessionStorage.setItem('unloadT',t)
  190. // }
  191. })
  192. //刷新离开页面
  193. window.addEventListener('unload',(e)=>{
  194. console.log('unload')
  195. recordActiveLoginFun()
  196. // 猜测在unload这里 浏览器不会等待异步返回 清除工作在这进行
  197. clearInterval(intervalTimer)
  198. // localStorage.removeItem('loginTime')
  199. })
  200. //popstate会在router.before/afterEach 之前触发,所以这里不对计时操作,操作放到before/afterEach
  201. window.addEventListener('popstate',(e)=>{
  202. //console.log('popState',e)
  203. let t = new Date().getTime() - timeStr
  204. timeStr = new Date().getTime()
  205. //console.log('待了时长popstate:'+ t)
  206. sessionStorage.setItem('routerChangeType','popstate')
  207. sessionStorage.setItem('popStayTime',t)
  208. })
  209. window.addEventListener('pushstate',()=>{
  210. let t = new Date().getTime() - timeStr
  211. timeStr = new Date().getTime()
  212. //console.log('待了时长pushstate:'+ t)
  213. const IsActive = sessionStorage.getItem('IsActive')
  214. if(Number(IsActive)){
  215. endCalc('pushstate',t)
  216. }
  217. optionTimeCalc()
  218. })
  219. window.addEventListener('replacestate',()=>{
  220. let t = new Date().getTime() - timeStr
  221. timeStr = new Date().getTime()
  222. //console.log('待了时长replacestate:'+ t)
  223. const IsActive = sessionStorage.getItem('IsActive')
  224. if(Number(IsActive)){
  225. endCalc('replacestate',t)
  226. }
  227. optionTimeCalc()
  228. })
  229. document.addEventListener('click',(e)=>{
  230. //console.log('click',e,e.composedPath())
  231. //只计算displayMain 的click
  232. const path = e.composedPath()
  233. const contentIndex = path.findIndex((item)=>{return item.className==="content-container"})
  234. if(contentIndex===-1) return
  235. //console.log('合法的click')
  236. const IsActive = sessionStorage.getItem('IsActive')
  237. console.log(IsActive,'IsActive');
  238. if(Number(IsActive)===0){
  239. optionTimeCalc()
  240. }else{
  241. //console.log('重置活跃计时')
  242. //重置活跃时间
  243. stayTime = 0
  244. }
  245. })
  246. }