let myChart, trendChart; let isAdmin = false; $(document).ready(function() { // 设置默认日期范围(最近30天) applyQuickSelect('30days'); // 加载统计数据 loadStatistics(); }); // 快捷时间选择 function applyQuickSelect(value) { if (!value) { value = $('#quick-select').val(); } const today = new Date(); let dateFrom, dateTo; switch(value) { case 'today': dateFrom = dateTo = today; break; case 'week': dateFrom = new Date(today); dateFrom.setDate(today.getDate() - today.getDay()); dateTo = today; break; case 'month': dateFrom = new Date(today.getFullYear(), today.getMonth(), 1); dateTo = today; break; case '30days': dateFrom = new Date(today); dateFrom.setDate(today.getDate() - 30); dateTo = today; break; default: return; } $('#date-from').val(dateFrom.toISOString().split('T')[0]); $('#date-to').val(dateTo.toISOString().split('T')[0]); $('#quick-select').val(value); } // 加载统计数据 function loadStatistics() { loadOverview(); loadUserStatistics(); loadLeaderboard(); } // 加载概览数据 function loadOverview() { const dateFrom = $('#date-from').val(); const dateTo = $('#date-to').val(); $.ajax({ url: '/api/statistics/overview', method: 'GET', data: { group_id: 1, date_from: dateFrom, date_to: dateTo }, success: function(data) { isAdmin = data.is_admin; $('#today-count').text(data.today_completed); $('#month-count').text(data.month_completed); $('#pending-count').text(data.status_counts.pending || 0); $('#claimed-count').text(data.status_counts.claimed || 0); // 更新标题和统计数据 if (isAdmin) { $('#stats-title').text('全局完成统计'); $('#trend-title').text('全局完成趋势'); // 管理员使用全局数据 $('#my-total').text(data.total_completed); $('#my-pending').text(data.claimed_pending); // 渲染管理员图表 renderMyChart(data.total_completed, data.claimed_pending); } else { $('#stats-title').text('我的完成统计'); $('#trend-title').text('我的完成趋势'); } // 渲染趋势图 renderTrendChart(data.trend); }, error: handleAjaxError }); } // 加载个人统计 function loadUserStatistics() { const userStr = localStorage.getItem('current_user'); if (isAdmin) { return; } if (!userStr) { console.error('用户信息不存在'); $('#my-total').text('0'); $('#my-pending').text('0'); return; } let user; try { user = JSON.parse(userStr); } catch (e) { console.error('用户信息格式错误', e); $('#my-total').text('0'); $('#my-pending').text('0'); return; } if (!user || !user.id) { console.error('用户ID不存在'); $('#my-total').text('0'); $('#my-pending').text('0'); return; } const dateFrom = $('#date-from').val(); const dateTo = $('#date-to').val(); $.ajax({ url: `/api/statistics/user/${user.id}`, method: 'GET', data: { group_id: 1, date_from: dateFrom, date_to: dateTo }, success: function(data) { $('#my-total').text(data.total_completed); $('#my-pending').text(data.claimed_pending); // 渲染个人图表 renderMyChart(data.total_completed, data.claimed_pending); }, error: handleAjaxError }); } // 加载排行榜 function loadLeaderboard() { $.ajax({ url: '/api/statistics/leaderboard', method: 'GET', data: { group_id: 1, period: 'monthly' }, success: function(data) { renderLeaderboard(data.leaderboard); }, error: handleAjaxError }); } // 渲染个人图表 function renderMyChart(totalCompleted, claimedPending) { const ctx = document.getElementById('myChart'); if (myChart) { myChart.destroy(); } myChart = new Chart(ctx, { type: 'bar', data: { labels: ['总完成数', '待完成数'], datasets: [{ label: '任务数量', data: [totalCompleted, claimedPending], backgroundColor: [ 'rgba(75, 192, 192, 0.5)', 'rgba(255, 159, 64, 0.5)' ], borderColor: [ 'rgba(75, 192, 192, 1)', 'rgba(255, 159, 64, 1)' ], borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: true, scales: { y: { beginAtZero: true, ticks: { stepSize: 1 } } } } }); } // 渲染趋势图 function renderTrendChart(trend) { const ctx = document.getElementById('trendChart'); if (trendChart) { trendChart.destroy(); } const labels = trend.map(t => t.date); const data = trend.map(t => t.count); trendChart = new Chart(ctx, { type: 'line', data: { labels: labels, datasets: [{ label: '完成数', data: data, fill: true, backgroundColor: 'rgba(75, 192, 192, 0.2)', borderColor: 'rgba(75, 192, 192, 1)', tension: 0.4 }] }, options: { responsive: true, maintainAspectRatio: true, scales: { y: { beginAtZero: true, ticks: { stepSize: 1 } } } } }); } // 渲染排行榜 function renderLeaderboard(leaderboard) { const tbody = $('#leaderboard'); tbody.empty(); if (leaderboard.length === 0) { tbody.append('