diff --git a/com.actionsoft.apps.coe.pal/template/page/pal.pl.repository.designer.htm b/com.actionsoft.apps.coe.pal/template/page/pal.pl.repository.designer.htm index 1106370c..74215d67 100755 --- a/com.actionsoft.apps.coe.pal/template/page/pal.pl.repository.designer.htm +++ b/com.actionsoft.apps.coe.pal/template/page/pal.pl.repository.designer.htm @@ -647,130 +647,150 @@ }); - - - // 用户停留时间追踪器 - const stayTimeTracker = { - totalStayTime: 0, // 总有效停留时间(秒) - intervalStartTime: 0, // 当前间隔开始时间戳 - isActive: true, // 是否处于活跃状态 - checkInterval: 5000, // 活动检查间隔(毫秒) - - // 初始化 - init() { - this.intervalStartTime = Date.now(); - - // 页面可见性变化监听 - document.addEventListener('visibilitychange', () => { - if (document.hidden) { - this.pauseTracking(); - } else { - this.resumeTracking(); - } - }); - - // 用户活动监听(鼠标移动、点击、滚动、键盘等) - const activityEvents = ['mousemove', 'click', 'scroll', 'keydown', 'touchstart']; - activityEvents.forEach(event => { - window.addEventListener(event, this.resetTimer.bind(this), { passive: true }); - }); - - // 开始检查 - this.startChecking(); - - // 页面卸载前保存数据 - window.addEventListener('beforeunload', this.handleUnload.bind(this)); - }, - - // 开始检查活动状态 - startChecking() { - setInterval(() => { - if (!this.isActive) return; - - const currentTime = Date.now(); - const elapsedSeconds = Math.floor((currentTime - this.intervalStartTime) / 1000); - - // 达到60秒有效间隔 - if (elapsedSeconds >= 10) { - this.totalStayTime += 10; - //this.intervalStartTime = currentTime; - this.reportStayTime(10,this.intervalStartTime,currentTime,this.isActive); - } - }, this.checkInterval); - }, - - // 重置计时器(用户有活动时调用) - resetTimer() { - if (!this.isActive) { - this.resumeTracking(); - } - this.intervalStartTime = Date.now(); - }, - - // 暂停追踪 - pauseTracking() { + // 页面停留时间统计 + class PageStayTimeTracker { + constructor() { + this.startTime = null; + this.lastReportTime = null; + this.reportInterval = 10000; // 60秒报告一次 this.isActive = false; - console.log('停留追踪已暂停'); - }, + this.isPageVisible = true; // 默认页面是可见的 + this.visibilityBound = false; // 是否已绑定可见性事件 + } - // 恢复追踪 - resumeTracking() { - this.isActive = true; - this.intervalStartTime = Date.now(); - console.log('停留追踪已恢复'); - }, - // 报告停留时间 - reportStayTime(duration,intervalStartTime,currentTime,isActive) { - console.log(`有效停留时间: ${duration}秒 | 总计: ${this.totalStayTime}秒 ${currentTime} ${intervalStartTime}`); + // 延迟绑定可见性事件 + bindVisibilityEvents() { + if (this.visibilityBound) return; - // 实际应用中这里发送数据到服务器 - $.ajax({ - type : "POST", - url : "./w?sid=" + encodeURIComponent($('#sid').val()) + "&cmd=com.awspaas.user.apps.browsing_data.service.insertReadingLog", - data : "userId="+userId+"&userName="+userName+"&ruuid="+ruuid+"&fileName="+fileName+"&intervalStartTime="+intervalStartTime+"¤tTime="+currentTime+"&browserId="+browserId+"&isActive="+isActive, - success : function(msg) { - if (msg.result == "error") { - $.simpleAlert("删除失败", "error"); - } - } - }); + document.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this)); + this.visibilityBound = true; - }, - - // 发送数据到服务器(使用sendBeacon确保页面关闭时也能发送) - sendToServer(duration,intervalStartTime,currentTime,isActive) { - // 实际应用中这里发送数据到服务器 - $.ajax({ - type : "POST", - url : "./w?sid=" + encodeURIComponent($('#sid').val()) + "&cmd=com.awspaas.user.apps.browsing_data.service.insertReadingLog", - data : "userId="+userId+"&userName="+userName+"&ruuid="+ruuid+"&fileName="+fileName+"&intervalStartTime="+intervalStartTime+"¤tTime="+currentTime+"&browserId="+browserId+"&isActive="+isActive, - success : function(msg) { - if (msg.result == "error") { - $.simpleAlert("删除失败", "error"); - } - } - }); - - }, - - // 页面卸载处理 - handleUnload() { - // 如果有部分停留时间但不足60秒 - const partialTime = Math.floor((Date.now() - this.intervalStartTime) / 1000); - if (partialTime > 0) { - console.log(`未完成间隔的停留时间: ${partialTime}秒`); - } - const currentTime = Date.now(); - // 发送总停留时间 - if (this.totalStayTime > 0) { - this.sendToServer(this.totalStayTime,this.intervalStartTime,currentTime,false); + // 初始检查页面可见状态 + this.isPageVisible = !document.hidden; + if (!this.isPageVisible) { + this.lastReportTime = new Date(); // 更新最后记录时间 } } - }; - // 启动追踪器 - stayTimeTracker.init(); + + + // 开始跟踪 + startTracking() { + if (this.isActive) return; + + this.startTime = new Date(); + this.lastReportTime = this.startTime; + this.isActive = true; + + + + // 设置定时器 + this.intervalId = setInterval(() => { + if (this.isPageVisible) { + this.reportStayTime(); + } + }, this.reportInterval); + + + + // 页面卸载前发送剩余时间 + window.addEventListener('beforeunload', this.finalReport.bind(this)); + + + // 延迟绑定可见性事件(在用户首次交互后) + const bindOnInteraction = () => { + this.bindVisibilityEvents(); + // 移除所有交互监听器 + ['click', 'scroll', 'keydown', 'mousemove', 'touchstart'].forEach(event => { + window.removeEventListener(event, bindOnInteraction); + }); + }; + + // 添加多种交互监听 + ['click', 'scroll', 'keydown', 'mousemove', 'touchstart'].forEach(event => { + window.addEventListener(event, bindOnInteraction, { once: true }); + }); + + + } + + // 报告停留时间 + reportStayTime() { + const now = new Date(); + const elapsed = now - this.lastReportTime; + this.totalStayTime += elapsed; + this.lastReportTime = now; + + this.sendStayTimeToServer(elapsed, true); + } + + // 最终报告 + finalReport() { + if (!this.isActive) return; + if (this.isPageVisible) { + const now = new Date(); + const elapsed = now - this.lastReportTime; + } + + + this.sendStayTimeToServer(elapsed, false); + this.cleanUp(); + } + + // 处理页面可见性变化 + handleVisibilityChange() { + var now = new Date(); + if (document.hidden) { + if (this.isPageVisible) { + this.isPageVisible = false; + // 页面不可见,暂停计时 + const now = new Date(); + const elapsed = now - this.lastReportTime; + this.totalStayTime += elapsed; + this.sendStayTimeToServer(elapsed, false); + clearInterval(this.intervalId); + } + + } else { + // 页面恢复可见 + if (!this.isPageVisible) { + this.lastReportTime = now; // 重置最后记录时间 + } + this.isPageVisible = true; + + } + } + + // 发送数据到服务器 + sendStayTimeToServer(elapsedMs,isActive) { + $.ajax({ + type : "POST", + url : "./w?sid=" + encodeURIComponent($('#sid').val()) + "&cmd=com.awspaas.user.apps.browsing_data.service.insertReadingLog", + data : "userId="+userId+"&userName="+userName+"&ruuid="+ruuid+"&fileName="+fileName+"&startTime="+new Date(this.startTime).getTime()+"¤tTime="+new Date().getTime()+"&browserId="+browserId+"&isActive="+isActive, + success : function(msg) { + if (msg.result == "error") { + $.simpleAlert("新增失败", "error"); + } + } + }); + + } + + // 清理资源 + cleanUp() { + clearInterval(this.intervalId); + document.removeEventListener('visibilitychange', this.handleVisibilityChange); + window.removeEventListener('beforeunload', this.finalReport); + this.isActive = false; + } + } + + // 使用示例 + const tracker = new PageStayTimeTracker(); + tracker.startTracking(); + + //初始化封面模板 function initCoverTpl(){