Book_system/app/static/js/user_activity.js
2025-05-12 19:44:22 +08:00

148 lines
5.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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轴标题和标签留出足够的底部空间可以根据实际显示效果调整此数值
}
}
}
});
}
});