148 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// app/static/js/user_activity.js
 | 
						||
document.addEventListener('DOMContentLoaded', function() {
 | 
						||
    let activityChart = null;
 | 
						||
 | 
						||
    // 初始加载
 | 
						||
    loadUserActivity();
 | 
						||
 | 
						||
    function loadUserActivity() {
 | 
						||
        // 显示加载状态
 | 
						||
        document.getElementById('user-table-body').innerHTML = `
 | 
						||
            <tr class="loading-row">
 | 
						||
                <td colspan="4">加载中...</td>
 | 
						||
            </tr>
 | 
						||
        `;
 | 
						||
 | 
						||
        // 调用API获取数据
 | 
						||
        fetch('/statistics/api/user-activity')
 | 
						||
            .then(response => {
 | 
						||
                if (!response.ok) {
 | 
						||
                    throw new Error(`HTTP error! status: ${response.status}`);
 | 
						||
                }
 | 
						||
                return response.json();
 | 
						||
            })
 | 
						||
            .then(data => {
 | 
						||
                updateUserTable(data);
 | 
						||
                updateUserChart(data);
 | 
						||
            })
 | 
						||
            .catch(error => {
 | 
						||
                console.error('加载用户活跃度数据失败:', error);
 | 
						||
                document.getElementById('user-table-body').innerHTML = `
 | 
						||
                    <tr class="error-row">
 | 
						||
                        <td colspan="4">加载数据失败,请稍后重试</td>
 | 
						||
                    </tr>
 | 
						||
                `;
 | 
						||
                // 也可以考虑清除或提示图表加载失败
 | 
						||
                if (activityChart) {
 | 
						||
                    activityChart.destroy();
 | 
						||
                    activityChart = null;
 | 
						||
                }
 | 
						||
                const canvas = document.getElementById('user-activity-chart');
 | 
						||
                const ctx = canvas.getContext('2d');
 | 
						||
                ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除画布
 | 
						||
                // 可以在画布上显示错误信息,但这比较复杂,通常表格的错误提示已足够
 | 
						||
            });
 | 
						||
    }
 | 
						||
 | 
						||
    function updateUserTable(data) {
 | 
						||
        const tableBody = document.getElementById('user-table-body');
 | 
						||
 | 
						||
        if (!data || data.length === 0) { // 增加了对 data 本身的检查
 | 
						||
            tableBody.innerHTML = `
 | 
						||
                <tr class="no-data-row">
 | 
						||
                    <td colspan="4">暂无数据</td>
 | 
						||
                </tr>
 | 
						||
            `;
 | 
						||
            return;
 | 
						||
        }
 | 
						||
 | 
						||
        let tableHtml = '';
 | 
						||
 | 
						||
        data.forEach((user, index) => {
 | 
						||
            tableHtml += `
 | 
						||
                <tr>
 | 
						||
                    <td class="rank">${index + 1}</td>
 | 
						||
                    <td>${user.username || 'N/A'}</td>
 | 
						||
                    <td>${user.nickname || 'N/A'}</td>
 | 
						||
                    <td class="borrow-count">${user.borrow_count}</td>
 | 
						||
                </tr>
 | 
						||
            `;
 | 
						||
        });
 | 
						||
 | 
						||
        tableBody.innerHTML = tableHtml;
 | 
						||
    }
 | 
						||
 | 
						||
    function updateUserChart(data) {
 | 
						||
        // 销毁旧图表
 | 
						||
        if (activityChart) {
 | 
						||
            activityChart.destroy();
 | 
						||
            activityChart = null; // 确保旧实例被完全清除
 | 
						||
        }
 | 
						||
 | 
						||
        const canvas = document.getElementById('user-activity-chart');
 | 
						||
        const ctx = canvas.getContext('2d');
 | 
						||
 | 
						||
        if (!data || data.length === 0) {
 | 
						||
            // 如果没有数据,清除画布,避免显示旧图表或空白图表框架
 | 
						||
            ctx.clearRect(0, 0, canvas.width, canvas.height);
 | 
						||
            // 也可以在这里显示 "暂无数据" 的文本到 canvas 上,如果需要
 | 
						||
            // 例如:
 | 
						||
            // ctx.textAlign = 'center';
 | 
						||
            // ctx.fillText('暂无图表数据', canvas.width / 2, canvas.height / 2);
 | 
						||
            return;
 | 
						||
        }
 | 
						||
 | 
						||
        // 准备图表数据
 | 
						||
        const labels = data.map(user => user.nickname || user.username || '未知用户');
 | 
						||
        const borrowCounts = data.map(user => user.borrow_count);
 | 
						||
 | 
						||
        // 创建图表
 | 
						||
        activityChart = new Chart(ctx, {
 | 
						||
            type: 'bar',
 | 
						||
            data: {
 | 
						||
                labels: labels,
 | 
						||
                datasets: [{
 | 
						||
                    label: '借阅次数',
 | 
						||
                    data: borrowCounts,
 | 
						||
                    backgroundColor: 'rgba(153, 102, 255, 0.6)',
 | 
						||
                    borderColor: 'rgba(153, 102, 255, 1)',
 | 
						||
                    borderWidth: 1
 | 
						||
                }]
 | 
						||
            },
 | 
						||
            options: {
 | 
						||
                responsive: true,
 | 
						||
                maintainAspectRatio: false,
 | 
						||
                scales: {
 | 
						||
                    y: {
 | 
						||
                        beginAtZero: true,
 | 
						||
                        title: {
 | 
						||
                            display: true,
 | 
						||
                            text: '借阅次数'
 | 
						||
                        }
 | 
						||
                    },
 | 
						||
                    x: {
 | 
						||
                        title: {
 | 
						||
                            display: true,
 | 
						||
                            text: '用户' // 这个标题现在应该有空间显示了
 | 
						||
                        }
 | 
						||
                    }
 | 
						||
                },
 | 
						||
                plugins: {
 | 
						||
                    legend: {
 | 
						||
                        display: false // 保持不显示图例
 | 
						||
                    },
 | 
						||
                    title: {
 | 
						||
                        display: true, // 如果HTML中已有h3标题,这里可以设为 false
 | 
						||
                        text: '最活跃用户排行' // 这个是图表内部的标题
 | 
						||
                    }
 | 
						||
                },
 | 
						||
                layout: { // <--- 这是添加的部分
 | 
						||
                    padding: {
 | 
						||
                        bottom: 30 // 为X轴标题和标签留出足够的底部空间,可以根据实际显示效果调整此数值
 | 
						||
                    }
 | 
						||
                }
 | 
						||
            }
 | 
						||
        });
 | 
						||
    }
 | 
						||
});
 |