/** * 分析仪表板 * 显示用户行为统计和分析数据 */ class AnalyticsDashboard { constructor() { this.analytics = window.analytics; this.container = null; } /** * 初始化仪表板 */ init(containerSelector = '.analytics-dashboard') { this.container = document.querySelector(containerSelector); if (!this.container) { console.log('未找到分析仪表板容器'); return; } this.render(); } /** * 渲染仪表板 */ render() { const stats = this.analytics.getStats(); this.container.innerHTML = `

用户行为统计

${this.renderOverviewCards(stats)}

热门页面

${this.renderTopPages(stats.topPages)}

搜索关键词

${this.renderTopSearchTerms(stats.topSearchTerms)}

访问信息

${this.renderVisitInfo(stats)}

会话信息

${this.renderSessionInfo()}
`; } /** * 渲染概览卡片 */ renderOverviewCards(stats) { const cards = [ { icon: 'fa-eye', title: '总浏览量', value: stats.totalViews, color: '#3498db' }, { icon: 'fa-file-o', title: '页面数', value: stats.totalPages, color: '#2ecc71' }, { icon: 'fa-search', title: '搜索次数', value: stats.totalSearches, color: '#f39c12' }, { icon: 'fa-mouse-pointer', title: '点击次数', value: stats.totalClicks, color: '#e74c3c' }, { icon: 'fa-users', title: '会话数', value: stats.sessions, color: '#9b59b6' } ]; return cards.map(card => `
${this.formatNumber(card.value)}
${card.title}
`).join(''); } /** * 渲染热门页面 */ renderTopPages(topPages) { if (!topPages || topPages.length === 0) { return '
暂无数据
'; } const maxViews = Math.max(...topPages.map(([, page]) => page.count)); return `
${topPages.map(([path, page], index) => `
${index + 1}
${path}
${page.count}
`).join('')}
`; } /** * 渲染热门搜索词 */ renderTopSearchTerms(topSearchTerms) { if (!topSearchTerms || topSearchTerms.length === 0) { return '
暂无数据
'; } const maxCount = Math.max(...topSearchTerms.map(([, count]) => count)); return `
${topSearchTerms.slice(0, 10).map(([term, count], index) => `
${index + 1}
${term}
${count}
`).join('')}
`; } /** * 渲染访问信息 */ renderVisitInfo(stats) { const firstVisit = new Date(stats.firstVisit); const lastVisit = new Date(stats.lastVisit); const now = new Date(); return `
首次访问
${this.formatDate(firstVisit)}
最近访问
${this.formatDate(lastVisit)}
访问时长
${this.calculateDuration(firstVisit, now)}
当前日期
${now.toLocaleDateString('zh-CN')}
`; } /** * 渲染会话信息 */ renderSessionInfo() { const session = this.analytics.getCurrentSession(); if (!session) { return '
无活跃会话
'; } return `
会话 ID
${session.id}
开始时间
${this.formatDate(new Date(session.startTime))}
浏览页面
${session.pageViews}
会话时长
${this.formatDuration(session.duration)}
来源
${session.referrer || '直接访问'}
屏幕分辨率
${session.screen.width} × ${session.screen.height}
`; } /** * 格式化数字 */ formatNumber(num) { if (num >= 1000000) return (num / 1000000).toFixed(1) + 'M'; if (num >= 1000) return (num / 1000).toFixed(1) + 'K'; return num.toString(); } /** * 格式化日期 */ formatDate(date) { return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); } /** * 计算时长 */ calculateDuration(start, end) { const diff = end - start; const days = Math.floor(diff / (1000 * 60 * 60 * 24)); const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); if (days > 0) return `${days}天${hours}小时`; if (hours > 0) return `${hours}小时${minutes}分钟`; return `${minutes}分钟`; } /** * 格式化时长 */ formatDuration(ms) { const seconds = Math.floor(ms / 1000); const minutes = Math.floor(seconds / 60); const hours = Math.floor(minutes / 60); if (hours > 0) return `${hours}小时${minutes % 60}分钟`; if (minutes > 0) return `${minutes}分钟${seconds % 60}秒`; return `${seconds}秒`; } /** * 导出数据 */ exportData() { if (confirm('确定要导出分析数据吗?')) { this.analytics.exportData(); } } /** * 清除数据 */ clearData() { if (confirm('确定要清除所有分析数据吗?此操作不可恢复!')) { this.analytics.clearAllData(); this.render(); } } /** * 刷新数据 */ refresh() { this.render(); } } // 创建全局实例 const analyticsDashboard = new AnalyticsDashboard(); // 导出供其他模块使用 if (typeof module !== 'undefined' && module.exports) { module.exports = AnalyticsDashboard; }