727 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			727 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
{include file="public/header" /}
 | 
						|
<script src="__STATIC__/js/jquery.min.js"></script>
 | 
						|
<style>
 | 
						|
    .dashboard-container {
 | 
						|
        padding: 24px;
 | 
						|
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
 | 
						|
        /* background-color: #f5f7fa; */
 | 
						|
        /* min-height: calc(100vh - 60px); */
 | 
						|
    }
 | 
						|
    .welcome-header {
 | 
						|
        background: linear-gradient(135deg, #3881fd 0%, #2c5fd9 100%);
 | 
						|
        border-radius: 12px;
 | 
						|
        padding: 30px;
 | 
						|
        color: white;
 | 
						|
        margin-bottom: 24px;
 | 
						|
        box-shadow: 0 4px 20px rgba(56, 129, 253, 0.15);
 | 
						|
    }
 | 
						|
    .welcome-header h1 {
 | 
						|
        font-size: 28px;
 | 
						|
        font-weight: 600;
 | 
						|
        margin-bottom: 8px;
 | 
						|
    }
 | 
						|
    .welcome-header p {
 | 
						|
        font-size: 15px;
 | 
						|
        opacity: 0.9;
 | 
						|
        margin: 0;
 | 
						|
    }
 | 
						|
    .stats-container {
 | 
						|
        display: grid;
 | 
						|
        grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
 | 
						|
        gap: 24px;
 | 
						|
        margin-bottom: 24px;
 | 
						|
    }
 | 
						|
    .stat-card {
 | 
						|
        background: white;
 | 
						|
        border-radius: 12px;
 | 
						|
        padding: 24px;
 | 
						|
        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
 | 
						|
        transition: all 0.3s ease;
 | 
						|
        position: relative;
 | 
						|
        overflow: hidden;
 | 
						|
    }
 | 
						|
    .stat-card::before {
 | 
						|
        content: '';
 | 
						|
        position: absolute;
 | 
						|
        top: 0;
 | 
						|
        left: 0;
 | 
						|
        width: 4px;
 | 
						|
        height: 100%;
 | 
						|
        background: #3881fd;
 | 
						|
    }
 | 
						|
    .stat-card:hover {
 | 
						|
        transform: translateY(-5px);
 | 
						|
        box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
 | 
						|
    }
 | 
						|
    .stat-card .stat-value {
 | 
						|
        font-size: 32px;
 | 
						|
        font-weight: 600;
 | 
						|
        color: #2c3e50;
 | 
						|
        margin: 12px 0;
 | 
						|
        display: flex;
 | 
						|
        align-items: baseline;
 | 
						|
    }
 | 
						|
    .stat-card .stat-title {
 | 
						|
        color: #64748b;
 | 
						|
        font-size: 14px;
 | 
						|
        font-weight: 500;
 | 
						|
        text-transform: uppercase;
 | 
						|
        letter-spacing: 0.5px;
 | 
						|
    }
 | 
						|
    .stat-card .stat-icon {
 | 
						|
        position: absolute;
 | 
						|
        right: 20px;
 | 
						|
        top: 50%;
 | 
						|
        transform: translateY(-50%);
 | 
						|
        font-size: 48px;
 | 
						|
        opacity: 0.1;
 | 
						|
    }
 | 
						|
    .quick-actions {
 | 
						|
        background: white;
 | 
						|
        border-radius: 12px;
 | 
						|
        padding: 24px;
 | 
						|
        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
 | 
						|
    }
 | 
						|
    .quick-actions h2 {
 | 
						|
        color: #1e293b;
 | 
						|
        font-size: 18px;
 | 
						|
        font-weight: 600;
 | 
						|
        margin-bottom: 20px;
 | 
						|
        display: flex;
 | 
						|
        align-items: center;
 | 
						|
    }
 | 
						|
    .quick-actions h2::before {
 | 
						|
        content: '';
 | 
						|
        display: inline-block;
 | 
						|
        width: 4px;
 | 
						|
        height: 18px;
 | 
						|
        background: #3881fd;
 | 
						|
        margin-right: 8px;
 | 
						|
        border-radius: 2px;
 | 
						|
    }
 | 
						|
    .action-buttons {
 | 
						|
        display: grid;
 | 
						|
        grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
 | 
						|
        gap: 16px;
 | 
						|
    }
 | 
						|
    .action-button {
 | 
						|
        background: #f8fafc;
 | 
						|
        border: 1px solid #e2e8f0;
 | 
						|
        border-radius: 8px;
 | 
						|
        padding: 12px 16px;
 | 
						|
        color: #1e293b;
 | 
						|
        font-weight: 500;
 | 
						|
        cursor: pointer;
 | 
						|
        transition: all 0.2s ease;
 | 
						|
        display: flex;
 | 
						|
        align-items: center;
 | 
						|
        justify-content: center;
 | 
						|
        text-decoration: none;
 | 
						|
    }
 | 
						|
    .action-button:hover {
 | 
						|
        background: #3881fd;
 | 
						|
        color: white;
 | 
						|
        border-color: #3881fd;
 | 
						|
        transform: translateY(-2px);
 | 
						|
    }
 | 
						|
    .action-button i {
 | 
						|
        margin-right: 8px;
 | 
						|
    }
 | 
						|
    .recent-activity {
 | 
						|
        margin-top: 24px;
 | 
						|
        background: white;
 | 
						|
        border-radius: 12px;
 | 
						|
        padding: 24px;
 | 
						|
        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
 | 
						|
    }
 | 
						|
    .activity-list {
 | 
						|
        margin-top: 16px;
 | 
						|
    }
 | 
						|
    .activity-item {
 | 
						|
        display: flex;
 | 
						|
        align-items: center;
 | 
						|
        padding: 12px 0;
 | 
						|
        border-bottom: 1px solid #f1f5f9;
 | 
						|
    }
 | 
						|
    .activity-item:last-child {
 | 
						|
        border-bottom: none;
 | 
						|
    }
 | 
						|
    .activity-icon {
 | 
						|
        width: 36px;
 | 
						|
        height: 36px;
 | 
						|
        border-radius: 8px;
 | 
						|
        background: #f1f5f9;
 | 
						|
        display: flex;
 | 
						|
        align-items: center;
 | 
						|
        justify-content: center;
 | 
						|
        margin-right: 12px;
 | 
						|
    }
 | 
						|
    .activity-content {
 | 
						|
        flex: 1;
 | 
						|
    }
 | 
						|
    .activity-title {
 | 
						|
        font-weight: 500;
 | 
						|
        color: #9b9b9b;
 | 
						|
    }
 | 
						|
    .activity-time {
 | 
						|
        font-size: 12px;
 | 
						|
        color: #64748b;
 | 
						|
    }
 | 
						|
    .charts-container {
 | 
						|
        display: grid;
 | 
						|
        grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
 | 
						|
        gap: 24px;
 | 
						|
        margin-top: 24px;
 | 
						|
    }
 | 
						|
    .chart-card {
 | 
						|
        background: white;
 | 
						|
        border-radius: 12px;
 | 
						|
        padding: 24px;
 | 
						|
        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);
 | 
						|
    }
 | 
						|
    .chart-card h2 {
 | 
						|
        color: #1e293b;
 | 
						|
        font-size: 18px;
 | 
						|
        font-weight: 600;
 | 
						|
        margin-bottom: 20px;
 | 
						|
        display: flex;
 | 
						|
        align-items: center;
 | 
						|
    }
 | 
						|
    .chart-card h2::before {
 | 
						|
        content: '';
 | 
						|
        display: inline-block;
 | 
						|
        width: 4px;
 | 
						|
        height: 18px;
 | 
						|
        background: #3881fd;
 | 
						|
        margin-right: 8px;
 | 
						|
        border-radius: 2px;
 | 
						|
    }
 | 
						|
    .chart-container {
 | 
						|
        height: 300px;
 | 
						|
        width: 100%;
 | 
						|
    }
 | 
						|
</style>
 | 
						|
 | 
						|
<div class="dashboard-container">
 | 
						|
    <div class="welcome-header">
 | 
						|
        <h1>欢迎使用{$config['admin_name']}</h1>
 | 
						|
        <p>今天是 <span id="current-time"></span>,祝您工作愉快</p>
 | 
						|
    </div>
 | 
						|
    
 | 
						|
    <div class="stats-container">
 | 
						|
        <div class="stat-card">
 | 
						|
            <div class="stat-title">用户总数</div>
 | 
						|
            <div class="stat-value">{$todayStats.total_users|number_format}</div>
 | 
						|
            <div class="stat-icon">👥</div>
 | 
						|
        </div>
 | 
						|
        <div class="stat-card">
 | 
						|
            <div class="stat-title">今日访问</div>
 | 
						|
            <div class="stat-value">{$todayStats.daily_visits|number_format}</div>
 | 
						|
            <div class="stat-icon">📊</div>
 | 
						|
        </div>
 | 
						|
        <div class="stat-card">
 | 
						|
            <div class="stat-title">文章总数</div>
 | 
						|
            <div class="stat-value">{$todayStats.total_articles|number_format}</div>
 | 
						|
            <div class="stat-icon">📝</div>
 | 
						|
        </div>
 | 
						|
        <div class="stat-card">
 | 
						|
            <div class="stat-title">资源总数</div>
 | 
						|
            <div class="stat-value">{$todayStats.total_resources|number_format}</div>
 | 
						|
            <div class="stat-icon">📦</div>
 | 
						|
        </div>
 | 
						|
    </div>
 | 
						|
    
 | 
						|
    <div class="quick-actions">
 | 
						|
        <h2>快捷操作</h2>
 | 
						|
        <div class="action-buttons">
 | 
						|
            <a href="{:url('user/index')}" class="action-button">
 | 
						|
                <i class="fas fa-users"></i>用户管理
 | 
						|
            </a>
 | 
						|
            <a href="{:url('content/publish')}" class="action-button">
 | 
						|
                <i class="fas fa-edit"></i>内容发布
 | 
						|
            </a>
 | 
						|
            <a href="{:url('statistics/index')}" class="action-button">
 | 
						|
                <i class="fas fa-chart-bar"></i>数据统计
 | 
						|
            </a>
 | 
						|
            <a href="{:url('system/settings')}" class="action-button">
 | 
						|
                <i class="fas fa-cog"></i>系统设置
 | 
						|
            </a>
 | 
						|
            <a href="{:url('system/clear_cache')}" class="action-button">
 | 
						|
                <i class="fas fa-broom"></i>清除缓存
 | 
						|
            </a>
 | 
						|
        </div>
 | 
						|
    </div>
 | 
						|
 | 
						|
    <div class="recent-activity">
 | 
						|
        <h2>最近动态</h2>
 | 
						|
        <div class="activity-list">
 | 
						|
            {volist name="recentActivities" id="activity"}
 | 
						|
            <div class="activity-item">
 | 
						|
                <div class="activity-icon">{$activity.icon|default='📌'}</div>
 | 
						|
                <div class="activity-content">
 | 
						|
                    <div class="activity-title">{$activity.content}</div>
 | 
						|
                </div>
 | 
						|
            </div>
 | 
						|
            {/volist}
 | 
						|
        </div>
 | 
						|
    </div>
 | 
						|
    <div class="charts-container">
 | 
						|
    <div class="chart-card">
 | 
						|
        <h2>访问趋势</h2>
 | 
						|
        <div id="visitTrend" class="chart-container"></div>
 | 
						|
    </div>
 | 
						|
    <div class="chart-card">
 | 
						|
        <h2>用户增长</h2>
 | 
						|
        <div id="userGrowth" class="chart-container"></div>
 | 
						|
    </div>
 | 
						|
    <div class="chart-card">
 | 
						|
        <h2>资源统计</h2>
 | 
						|
        <div id="resourceStats" class="chart-container"></div>
 | 
						|
    </div>
 | 
						|
    <div class="chart-card">
 | 
						|
        <h2>文章统计</h2>
 | 
						|
        <div id="articleStats" class="chart-container"></div>
 | 
						|
    </div>
 | 
						|
</div>
 | 
						|
</div>
 | 
						|
 | 
						|
 | 
						|
 | 
						|
<script src="__JS__/echarts.min.js"></script>
 | 
						|
<script>
 | 
						|
function updateTime() {
 | 
						|
    var now = new Date();
 | 
						|
    var year = now.getFullYear();
 | 
						|
    var month = now.getMonth() + 1;
 | 
						|
    var date = now.getDate();
 | 
						|
    var hours = now.getHours();
 | 
						|
    var minutes = now.getMinutes();
 | 
						|
    var seconds = now.getSeconds();
 | 
						|
 | 
						|
    var padZero = function(num) {
 | 
						|
        return num < 10 ? '0' + num : num;
 | 
						|
    };
 | 
						|
 | 
						|
    var timeString = year + '年' + 
 | 
						|
                     padZero(month) + '月' + 
 | 
						|
                     padZero(date) + '日 ' + 
 | 
						|
                     padZero(hours) + ':' + 
 | 
						|
                     padZero(minutes) + ':' + 
 | 
						|
                     padZero(seconds);
 | 
						|
 | 
						|
    document.getElementById('current-time').innerHTML = timeString;
 | 
						|
}
 | 
						|
 | 
						|
// 获取用户统计数据
 | 
						|
function getUserCounts() {
 | 
						|
    fetch('{:url("users/counts")}')
 | 
						|
        .then(response => response.json())
 | 
						|
        .then(res => {
 | 
						|
            console.log('用户统计接口返回数据:', res);
 | 
						|
            if (res.code === 0 && res.data) {
 | 
						|
                // 更新用户总数
 | 
						|
                document.querySelector('.stat-card:nth-child(1) .stat-value').textContent = res.data.total.toLocaleString();
 | 
						|
                
 | 
						|
                // 更新用户增长图表
 | 
						|
                if (window.userChart) {
 | 
						|
                    window.userChart.setOption({
 | 
						|
                        xAxis: {
 | 
						|
                            data: res.data.dates
 | 
						|
                        },
 | 
						|
                        series: [{
 | 
						|
                            name: '新增用户',
 | 
						|
                            data: res.data.counts
 | 
						|
                        }, {
 | 
						|
                            name: '总用户数',
 | 
						|
                            data: res.data.totalCounts
 | 
						|
                        }]
 | 
						|
                    });
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                console.warn('用户统计接口返回异常:', res);
 | 
						|
                document.querySelector('.stat-card:nth-child(1) .stat-value').textContent = '0';
 | 
						|
            }
 | 
						|
        })
 | 
						|
        .catch(error => {
 | 
						|
            console.error('获取用户统计失败:', error);
 | 
						|
            document.querySelector('.stat-card:nth-child(1) .stat-value').textContent = '0';
 | 
						|
        });
 | 
						|
}
 | 
						|
 | 
						|
// 获取文章统计数据
 | 
						|
function getArticleCounts() {
 | 
						|
    fetch('{:url("articles/counts")}')
 | 
						|
        .then(response => response.json())
 | 
						|
        .then(res => {
 | 
						|
            console.log('文章统计接口返回数据:', res);
 | 
						|
            if (res.code === 0 && res.data) {
 | 
						|
                // 更新文章总数
 | 
						|
                document.querySelector('.stat-card:nth-child(3) .stat-value').textContent = res.data.total.toLocaleString();
 | 
						|
                
 | 
						|
                // 更新文章统计图表
 | 
						|
                if (window.articleChart) {
 | 
						|
                    window.articleChart.setOption({
 | 
						|
                        xAxis: {
 | 
						|
                            data: res.data.dates
 | 
						|
                        },
 | 
						|
                        series: [{
 | 
						|
                            name: '新增文章',
 | 
						|
                            data: res.data.counts
 | 
						|
                        }, {
 | 
						|
                            name: '总文章数',
 | 
						|
                            data: res.data.totalCounts
 | 
						|
                        }]
 | 
						|
                    });
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                console.warn('文章统计接口返回异常:', res);
 | 
						|
                document.querySelector('.stat-card:nth-child(3) .stat-value').textContent = '0';
 | 
						|
            }
 | 
						|
        })
 | 
						|
        .catch(error => {
 | 
						|
            console.error('获取文章统计失败:', error);
 | 
						|
            document.querySelector('.stat-card:nth-child(3) .stat-value').textContent = '0';
 | 
						|
        });
 | 
						|
}
 | 
						|
 | 
						|
// 获取资源统计数据
 | 
						|
function getResourcesCounts() {
 | 
						|
    fetch('{:url("resources/counts")}')
 | 
						|
        .then(response => response.json())
 | 
						|
        .then(res => {
 | 
						|
            console.log('资源统计接口返回数据:', res);
 | 
						|
            if (res.code === 0 && res.data) {
 | 
						|
                // 更新资源总数
 | 
						|
                document.querySelector('.stat-card:nth-child(4) .stat-value').textContent = res.data.total.toLocaleString();
 | 
						|
                
 | 
						|
                // 更新资源统计图表
 | 
						|
                if (window.resourceChart) {
 | 
						|
                    window.resourceChart.setOption({
 | 
						|
                        xAxis: {
 | 
						|
                            data: res.data.dates
 | 
						|
                        },
 | 
						|
                        series: [{
 | 
						|
                            name: '新增资源',
 | 
						|
                            data: res.data.counts
 | 
						|
                        }, {
 | 
						|
                            name: '总资源数',
 | 
						|
                            data: res.data.totalCounts
 | 
						|
                        }]
 | 
						|
                    });
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                console.warn('资源统计接口返回异常:', res);
 | 
						|
                document.querySelector('.stat-card:nth-child(4) .stat-value').textContent = '0';
 | 
						|
            }
 | 
						|
        })
 | 
						|
        .catch(error => {
 | 
						|
            console.error('获取资源统计失败:', error);
 | 
						|
            document.querySelector('.stat-card:nth-child(4) .stat-value').textContent = '0';
 | 
						|
        });
 | 
						|
}
 | 
						|
 | 
						|
updateTime();
 | 
						|
setInterval(updateTime, 1000);
 | 
						|
 | 
						|
// 页面加载完成后获取统计数据
 | 
						|
document.addEventListener('DOMContentLoaded', function() {
 | 
						|
    getUserCounts();
 | 
						|
    getArticleCounts();
 | 
						|
    getResourcesCounts();
 | 
						|
});
 | 
						|
 | 
						|
// 访问趋势图表
 | 
						|
function initVisitTrend() {
 | 
						|
    var chart = echarts.init(document.getElementById('visitTrend'));
 | 
						|
    var option = {
 | 
						|
        tooltip: {
 | 
						|
            trigger: 'axis',
 | 
						|
            axisPointer: {
 | 
						|
                type: 'shadow'
 | 
						|
            }
 | 
						|
        },
 | 
						|
        legend: {
 | 
						|
            data: ['访问量', '独立访客']
 | 
						|
        },
 | 
						|
        grid: {
 | 
						|
            left: '3%',
 | 
						|
            right: '4%',
 | 
						|
            bottom: '3%',
 | 
						|
            containLabel: true
 | 
						|
        },
 | 
						|
        xAxis: {
 | 
						|
            type: 'category',
 | 
						|
            data: {$chartData.visitTrend.dates|json_encode},
 | 
						|
            axisLine: {
 | 
						|
                lineStyle: {
 | 
						|
                    color: '#e2e8f0'
 | 
						|
                }
 | 
						|
            }
 | 
						|
        },
 | 
						|
        yAxis: {
 | 
						|
            type: 'value',
 | 
						|
            axisLine: {
 | 
						|
                lineStyle: {
 | 
						|
                    color: '#e2e8f0'
 | 
						|
                }
 | 
						|
            },
 | 
						|
            splitLine: {
 | 
						|
                lineStyle: {
 | 
						|
                    color: '#f1f5f9'
 | 
						|
                }
 | 
						|
            }
 | 
						|
        },
 | 
						|
        series: [{
 | 
						|
            name: '访问量',
 | 
						|
            data: {$chartData.visitTrend.visits|json_encode},
 | 
						|
            type: 'line',
 | 
						|
            smooth: true,
 | 
						|
            areaStyle: {
 | 
						|
                opacity: 0.1
 | 
						|
            },
 | 
						|
            itemStyle: {
 | 
						|
                color: '#3881fd'
 | 
						|
            },
 | 
						|
            lineStyle: {
 | 
						|
                width: 3
 | 
						|
            }
 | 
						|
        }, {
 | 
						|
            name: '独立访客',
 | 
						|
            data: {$chartData.visitTrend.uvs|json_encode},
 | 
						|
            type: 'line',
 | 
						|
            smooth: true,
 | 
						|
            itemStyle: {
 | 
						|
                color: '#10b981'
 | 
						|
            },
 | 
						|
            lineStyle: {
 | 
						|
                width: 3
 | 
						|
            }
 | 
						|
        }]
 | 
						|
    };
 | 
						|
    chart.setOption(option);
 | 
						|
}
 | 
						|
 | 
						|
// 用户增长图表
 | 
						|
function initUserGrowth() {
 | 
						|
    var chart = echarts.init(document.getElementById('userGrowth'));
 | 
						|
    var option = {
 | 
						|
        tooltip: {
 | 
						|
            trigger: 'axis',
 | 
						|
            axisPointer: {
 | 
						|
                type: 'cross',
 | 
						|
                label: {
 | 
						|
                    backgroundColor: '#6a7985'
 | 
						|
                }
 | 
						|
            }
 | 
						|
        },
 | 
						|
        legend: {
 | 
						|
            data: ['新增用户', '总用户数']
 | 
						|
        },
 | 
						|
        grid: {
 | 
						|
            left: '3%',
 | 
						|
            right: '4%',
 | 
						|
            bottom: '3%',
 | 
						|
            containLabel: true
 | 
						|
        },
 | 
						|
        xAxis: {
 | 
						|
            type: 'category',
 | 
						|
            boundaryGap: false,
 | 
						|
            data: {$chartData.userGrowth.dates|json_encode}
 | 
						|
        },
 | 
						|
        yAxis: {
 | 
						|
            type: 'value'
 | 
						|
        },
 | 
						|
        series: [
 | 
						|
            {
 | 
						|
                name: '新增用户',
 | 
						|
                type: 'bar',
 | 
						|
                data: {$chartData.userGrowth.newUsers|json_encode},
 | 
						|
                itemStyle: {
 | 
						|
                    color: '#3881fd'
 | 
						|
                }
 | 
						|
            },
 | 
						|
            {
 | 
						|
                name: '总用户数',
 | 
						|
                type: 'line',
 | 
						|
                smooth: true,
 | 
						|
                data: {$chartData.userGrowth.totalUsers|json_encode},
 | 
						|
                itemStyle: {
 | 
						|
                    color: '#10b981'
 | 
						|
                },
 | 
						|
                lineStyle: {
 | 
						|
                    width: 3
 | 
						|
                }
 | 
						|
            }
 | 
						|
        ]
 | 
						|
    };
 | 
						|
    chart.setOption(option);
 | 
						|
}
 | 
						|
 | 
						|
// 资源统计图表
 | 
						|
function initResourceStats() {
 | 
						|
    var chart = echarts.init(document.getElementById('resourceStats'));
 | 
						|
    var option = {
 | 
						|
        tooltip: {
 | 
						|
            trigger: 'axis',
 | 
						|
            axisPointer: {
 | 
						|
                type: 'cross',
 | 
						|
                label: {
 | 
						|
                    backgroundColor: '#6a7985'
 | 
						|
                }
 | 
						|
            }
 | 
						|
        },
 | 
						|
        legend: {
 | 
						|
            data: ['新增资源', '总资源数', '下载量']
 | 
						|
        },
 | 
						|
        grid: {
 | 
						|
            left: '3%',
 | 
						|
            right: '4%',
 | 
						|
            bottom: '3%',
 | 
						|
            containLabel: true
 | 
						|
        },
 | 
						|
        xAxis: {
 | 
						|
            type: 'category',
 | 
						|
            boundaryGap: false,
 | 
						|
            data: {$chartData.resourceStats.dates|json_encode}
 | 
						|
        },
 | 
						|
        yAxis: {
 | 
						|
            type: 'value'
 | 
						|
        },
 | 
						|
        series: [
 | 
						|
            {
 | 
						|
                name: '新增资源',
 | 
						|
                type: 'bar',
 | 
						|
                data: {$chartData.resourceStats.newResources|json_encode},
 | 
						|
                itemStyle: {
 | 
						|
                    color: '#3881fd'
 | 
						|
                }
 | 
						|
            },
 | 
						|
            {
 | 
						|
                name: '总资源数',
 | 
						|
                type: 'line',
 | 
						|
                smooth: true,
 | 
						|
                data: {$chartData.resourceStats.totalResources|json_encode},
 | 
						|
                itemStyle: {
 | 
						|
                    color: '#10b981'
 | 
						|
                },
 | 
						|
                lineStyle: {
 | 
						|
                    width: 3
 | 
						|
                }
 | 
						|
            },
 | 
						|
            {
 | 
						|
                name: '下载量',
 | 
						|
                type: 'line',
 | 
						|
                smooth: true,
 | 
						|
                data: {$chartData.resourceStats.downloads|json_encode},
 | 
						|
                itemStyle: {
 | 
						|
                    color: '#f59e0b'
 | 
						|
                },
 | 
						|
                lineStyle: {
 | 
						|
                    width: 3
 | 
						|
                }
 | 
						|
            }
 | 
						|
        ]
 | 
						|
    };
 | 
						|
    chart.setOption(option);
 | 
						|
}
 | 
						|
 | 
						|
// 文章统计图表
 | 
						|
function initArticleStats() {
 | 
						|
    var chart = echarts.init(document.getElementById('articleStats'));
 | 
						|
    var option = {
 | 
						|
        tooltip: {
 | 
						|
            trigger: 'axis',
 | 
						|
            axisPointer: {
 | 
						|
                type: 'cross',
 | 
						|
                label: {
 | 
						|
                    backgroundColor: '#6a7985'
 | 
						|
                }
 | 
						|
            }
 | 
						|
        },
 | 
						|
        legend: {
 | 
						|
            data: ['新增文章', '总文章数', '浏览量']
 | 
						|
        },
 | 
						|
        grid: {
 | 
						|
            left: '3%',
 | 
						|
            right: '4%',
 | 
						|
            bottom: '3%',
 | 
						|
            containLabel: true
 | 
						|
        },
 | 
						|
        xAxis: {
 | 
						|
            type: 'category',
 | 
						|
            boundaryGap: false,
 | 
						|
            data: {$chartData.articleStats.dates|json_encode}
 | 
						|
        },
 | 
						|
        yAxis: {
 | 
						|
            type: 'value'
 | 
						|
        },
 | 
						|
        series: [
 | 
						|
            {
 | 
						|
                name: '新增文章',
 | 
						|
                type: 'bar',
 | 
						|
                data: {$chartData.articleStats.newArticles|json_encode},
 | 
						|
                itemStyle: {
 | 
						|
                    color: '#3881fd'
 | 
						|
                }
 | 
						|
            },
 | 
						|
            {
 | 
						|
                name: '总文章数',
 | 
						|
                type: 'line',
 | 
						|
                smooth: true,
 | 
						|
                data: {$chartData.articleStats.totalArticles|json_encode},
 | 
						|
                itemStyle: {
 | 
						|
                    color: '#10b981'
 | 
						|
                },
 | 
						|
                lineStyle: {
 | 
						|
                    width: 3
 | 
						|
                }
 | 
						|
            },
 | 
						|
            {
 | 
						|
                name: '浏览量',
 | 
						|
                type: 'line',
 | 
						|
                smooth: true,
 | 
						|
                data: {$chartData.articleStats.views|json_encode},
 | 
						|
                itemStyle: {
 | 
						|
                    color: '#f59e0b'
 | 
						|
                },
 | 
						|
                lineStyle: {
 | 
						|
                    width: 3
 | 
						|
                }
 | 
						|
            }
 | 
						|
        ]
 | 
						|
    };
 | 
						|
    chart.setOption(option);
 | 
						|
}
 | 
						|
 | 
						|
// 初始化所有图表
 | 
						|
document.addEventListener('DOMContentLoaded', function() {
 | 
						|
    // 确保ECharts已加载
 | 
						|
    if (typeof echarts === 'undefined') {
 | 
						|
        console.error('ECharts未加载');
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    // 初始化图表
 | 
						|
    try {
 | 
						|
        initVisitTrend();
 | 
						|
        initUserGrowth();
 | 
						|
        initResourceStats();
 | 
						|
        initArticleStats();
 | 
						|
        
 | 
						|
        // 监听窗口大小变化,重绘图表
 | 
						|
        window.addEventListener('resize', function() {
 | 
						|
            var charts = document.querySelectorAll('.chart-container');
 | 
						|
            charts.forEach(function(chart) {
 | 
						|
                var instance = echarts.getInstanceByDom(chart);
 | 
						|
                if (instance) {
 | 
						|
                    instance.resize();
 | 
						|
                }
 | 
						|
            });
 | 
						|
        });
 | 
						|
    } catch (error) {
 | 
						|
        console.error('初始化图表失败:', error);
 | 
						|
    }
 | 
						|
});
 | 
						|
</script>
 | 
						|
 | 
						|
{include file="public/tail" /} |