850 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			850 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php /*a:3:{s:51:"E:\Demo\PHP\yunzer\app\admin\view\index\welcome.php";i:1747665416;s:51:"E:\Demo\PHP\yunzer\app\admin\view\public\header.php";i:1746890051;s:49:"E:\Demo\PHP\yunzer\app\admin\view\public\tail.php";i:1745855804;}*/ ?>
 | |
| <!DOCTYPE html>
 | |
| <html>
 | |
| 	<head>
 | |
| 		<title><?php echo htmlentities((string) $config['admin_name']); ?></title>
 | |
| 		<meta name="renderer" content="webkit">
 | |
| 		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
 | |
| 		<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
 | |
| 		<link rel="stylesheet" type="text/css" href="/static/layui/css/layui.css" media="all"/>
 | |
| 		<link rel="stylesheet" type="text/css" href="/static/css/moban.css" media="all"/>
 | |
| 		<link rel="stylesheet" type="text/css" href="/static/css/wangeditor.css" media="all"/>
 | |
| 		<style type="text/css">
 | |
| 			.header span{background:#009688;margin-left:30px;padding:10px;color:#ffffff;}
 | |
| 			.header div{border-bottom:solid 2px #009688;margin-top: 8px;}
 | |
| 			.header button{float:right;margin-top:-5px;}
 | |
| 			.pagination {
 | |
| 				display: inline-block;
 | |
| 				padding-left: 0;
 | |
| 				margin: 20px 0;
 | |
| 				border-radius: 4px;
 | |
| 			}
 | |
| 			.pagination > li {
 | |
| 				display: inline;
 | |
| 			}
 | |
| 			.pagination > li > a,
 | |
| 			.pagination > li > span {
 | |
| 				position: relative;
 | |
| 				float: left;
 | |
| 				padding: 6px 12px;
 | |
| 				margin-left: -1px;
 | |
| 				line-height: 1.42857143;
 | |
| 				color: #337ab7;
 | |
| 				text-decoration: none;
 | |
| 				background-color: #fff;
 | |
| 				border: 1px solid #ddd;
 | |
| 			}
 | |
| 			.pagination > li:first-child > a,
 | |
| 			.pagination > li:first-child > span {
 | |
| 				margin-left: 0;
 | |
| 				border-top-left-radius: 4px;
 | |
| 				border-bottom-left-radius: 4px;
 | |
| 			}
 | |
| 			.pagination > li:last-child > a,
 | |
| 			.pagination > li:last-child > span {
 | |
| 				border-top-right-radius: 4px;
 | |
| 				border-bottom-right-radius: 4px;
 | |
| 			}
 | |
| 			.pagination > li > a:hover,
 | |
| 			.pagination > li > span:hover,
 | |
| 			.pagination > li > a:focus,
 | |
| 			.pagination > li > span:focus {
 | |
| 				z-index: 2;
 | |
| 				color: #23527c;
 | |
| 				background-color: #eee;
 | |
| 				border-color: #ddd;
 | |
| 			}
 | |
| 			.pagination > .active > a,
 | |
| 			.pagination > .active > span,
 | |
| 			.pagination > .active > a:hover,
 | |
| 			.pagination > .active > span:hover,
 | |
| 			.pagination > .active > a:focus,
 | |
| 			.pagination > .active > span:focus {
 | |
| 				z-index: 3;
 | |
| 				color: #fff;
 | |
| 				cursor: default;
 | |
| 				background-color: #337ab7;
 | |
| 				border-color: #337ab7;
 | |
| 			}
 | |
| 			.pagination > .disabled > span,
 | |
| 			.pagination > .disabled > span:hover,
 | |
| 			.pagination > .disabled > span:focus,
 | |
| 			.pagination > .disabled > a,
 | |
| 			.pagination > .disabled > a:hover,
 | |
| 			.pagination > .disabled > a:focus {
 | |
| 				color: #777;
 | |
| 				cursor: not-allowed;
 | |
| 				background-color: #fff;
 | |
| 				border-color: #ddd;
 | |
| 			}
 | |
| 			.close-img { background: url(/static/images/close_img.png); background-size: 20px 20px; width:20px; height: 20px; position: absolute; right: 5px; top: 5px; z-index: 2;}
 | |
| 		</style>
 | |
| 		<script type="text/javascript" src="/static/layui/layui.js"></script>
 | |
| 		<script type="text/javascript">
 | |
| 			layui.use(['layer','form','table','laydate','element','upload'],function(){
 | |
| 				layer = layui.layer;		// layui 弹框
 | |
| 				form = layui.form;			// layui form表单
 | |
| 				table = layui.table;		// layui 表格
 | |
| 				laydate = layui.laydate;	// layui 时间框
 | |
| 				element = layui.element;	// layui element
 | |
| 				upload = layui.upload;		// layui 上传
 | |
| 				$ = layui.jquery;			// layui jquery
 | |
| 			})
 | |
| 		</script>
 | |
| 	</head>
 | |
| 	<body style="padding:10px; box-sizing: border-box;">
 | |
| <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>欢迎使用<?php echo htmlentities((string) $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"><?php echo htmlentities((string) number_format($todayStats['total_users'])); ?></div>
 | |
|             <div class="stat-icon">👥</div>
 | |
|         </div>
 | |
|         <div class="stat-card">
 | |
|             <div class="stat-title">今日访问</div>
 | |
|             <div class="stat-value"><?php echo htmlentities((string) number_format($todayStats['daily_visits'])); ?></div>
 | |
|             <div class="stat-icon">📊</div>
 | |
|         </div>
 | |
|         <div class="stat-card">
 | |
|             <div class="stat-title">文章总数</div>
 | |
|             <div class="stat-value"><?php echo htmlentities((string) number_format($todayStats['total_articles'])); ?></div>
 | |
|             <div class="stat-icon">📝</div>
 | |
|         </div>
 | |
|         <div class="stat-card">
 | |
|             <div class="stat-title">资源总数</div>
 | |
|             <div class="stat-value"><?php echo htmlentities((string) number_format($todayStats['total_resources'])); ?></div>
 | |
|             <div class="stat-icon">📦</div>
 | |
|         </div>
 | |
|     </div>
 | |
|     
 | |
|     <div class="quick-actions">
 | |
|         <h2>快捷操作</h2>
 | |
|         <div class="action-buttons">
 | |
|             <a href="<?php echo url('user/index'); ?>" class="action-button">
 | |
|                 <i class="fas fa-users"></i>用户管理
 | |
|             </a>
 | |
|             <a href="<?php echo url('content/publish'); ?>" class="action-button">
 | |
|                 <i class="fas fa-edit"></i>内容发布
 | |
|             </a>
 | |
|             <a href="<?php echo url('statistics/index'); ?>" class="action-button">
 | |
|                 <i class="fas fa-chart-bar"></i>数据统计
 | |
|             </a>
 | |
|             <a href="<?php echo url('system/settings'); ?>" class="action-button">
 | |
|                 <i class="fas fa-cog"></i>系统设置
 | |
|             </a>
 | |
|             <a href="<?php echo 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">
 | |
|             <?php if(is_array($recentActivities) || $recentActivities instanceof \think\Collection || $recentActivities instanceof \think\Paginator): $i = 0; $__LIST__ = $recentActivities;if( count($__LIST__)==0 ) : echo "" ;else: foreach($__LIST__ as $key=>$activity): $mod = ($i % 2 );++$i;?>
 | |
|             <div class="activity-item">
 | |
|                 <div class="activity-icon"><?php echo htmlentities((string) (isset($activity['icon']) && ($activity['icon'] !== '')?$activity['icon']:'📌')); ?></div>
 | |
|                 <div class="activity-content">
 | |
|                     <div class="activity-title"><?php echo htmlentities((string) $activity['content']); ?></div>
 | |
|                 </div>
 | |
|             </div>
 | |
|             <?php endforeach; endif; else: echo "" ;endif; ?>
 | |
|         </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="/static/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('<?php echo 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('<?php echo 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('<?php echo 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: <?php echo htmlentities((string) json_encode($chartData['visitTrend']['dates'])); ?>,
 | |
|             axisLine: {
 | |
|                 lineStyle: {
 | |
|                     color: '#e2e8f0'
 | |
|                 }
 | |
|             }
 | |
|         },
 | |
|         yAxis: {
 | |
|             type: 'value',
 | |
|             axisLine: {
 | |
|                 lineStyle: {
 | |
|                     color: '#e2e8f0'
 | |
|                 }
 | |
|             },
 | |
|             splitLine: {
 | |
|                 lineStyle: {
 | |
|                     color: '#f1f5f9'
 | |
|                 }
 | |
|             }
 | |
|         },
 | |
|         series: [{
 | |
|             name: '访问量',
 | |
|             data: <?php echo htmlentities((string) json_encode($chartData['visitTrend']['visits'])); ?>,
 | |
|             type: 'line',
 | |
|             smooth: true,
 | |
|             areaStyle: {
 | |
|                 opacity: 0.1
 | |
|             },
 | |
|             itemStyle: {
 | |
|                 color: '#3881fd'
 | |
|             },
 | |
|             lineStyle: {
 | |
|                 width: 3
 | |
|             }
 | |
|         }, {
 | |
|             name: '独立访客',
 | |
|             data: <?php echo htmlentities((string) json_encode($chartData['visitTrend']['uvs'])); ?>,
 | |
|             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: <?php echo htmlentities((string) json_encode($chartData['userGrowth']['dates'])); ?>
 | |
|         },
 | |
|         yAxis: {
 | |
|             type: 'value'
 | |
|         },
 | |
|         series: [
 | |
|             {
 | |
|                 name: '新增用户',
 | |
|                 type: 'bar',
 | |
|                 data: <?php echo htmlentities((string) json_encode($chartData['userGrowth']['newUsers'])); ?>,
 | |
|                 itemStyle: {
 | |
|                     color: '#3881fd'
 | |
|                 }
 | |
|             },
 | |
|             {
 | |
|                 name: '总用户数',
 | |
|                 type: 'line',
 | |
|                 smooth: true,
 | |
|                 data: <?php echo htmlentities((string) json_encode($chartData['userGrowth']['totalUsers'])); ?>,
 | |
|                 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: <?php echo htmlentities((string) json_encode($chartData['resourceStats']['dates'])); ?>
 | |
|         },
 | |
|         yAxis: {
 | |
|             type: 'value'
 | |
|         },
 | |
|         series: [
 | |
|             {
 | |
|                 name: '新增资源',
 | |
|                 type: 'bar',
 | |
|                 data: <?php echo htmlentities((string) json_encode($chartData['resourceStats']['newResources'])); ?>,
 | |
|                 itemStyle: {
 | |
|                     color: '#3881fd'
 | |
|                 }
 | |
|             },
 | |
|             {
 | |
|                 name: '总资源数',
 | |
|                 type: 'line',
 | |
|                 smooth: true,
 | |
|                 data: <?php echo htmlentities((string) json_encode($chartData['resourceStats']['totalResources'])); ?>,
 | |
|                 itemStyle: {
 | |
|                     color: '#10b981'
 | |
|                 },
 | |
|                 lineStyle: {
 | |
|                     width: 3
 | |
|                 }
 | |
|             },
 | |
|             {
 | |
|                 name: '下载量',
 | |
|                 type: 'line',
 | |
|                 smooth: true,
 | |
|                 data: <?php echo htmlentities((string) json_encode($chartData['resourceStats']['downloads'])); ?>,
 | |
|                 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: <?php echo htmlentities((string) json_encode($chartData['articleStats']['dates'])); ?>
 | |
|         },
 | |
|         yAxis: {
 | |
|             type: 'value'
 | |
|         },
 | |
|         series: [
 | |
|             {
 | |
|                 name: '新增文章',
 | |
|                 type: 'bar',
 | |
|                 data: <?php echo htmlentities((string) json_encode($chartData['articleStats']['newArticles'])); ?>,
 | |
|                 itemStyle: {
 | |
|                     color: '#3881fd'
 | |
|                 }
 | |
|             },
 | |
|             {
 | |
|                 name: '总文章数',
 | |
|                 type: 'line',
 | |
|                 smooth: true,
 | |
|                 data: <?php echo htmlentities((string) json_encode($chartData['articleStats']['totalArticles'])); ?>,
 | |
|                 itemStyle: {
 | |
|                     color: '#10b981'
 | |
|                 },
 | |
|                 lineStyle: {
 | |
|                     width: 3
 | |
|                 }
 | |
|             },
 | |
|             {
 | |
|                 name: '浏览量',
 | |
|                 type: 'line',
 | |
|                 smooth: true,
 | |
|                 data: <?php echo htmlentities((string) json_encode($chartData['articleStats']['views'])); ?>,
 | |
|                 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>
 | |
| 
 | |
| 	</body>
 | |
| </html>
 | |
| <script type="text/javascript">
 | |
| 	// 显示图片
 | |
| 	function show_img(obj){
 | |
| 		var imgurl = $(obj).attr('src');
 | |
| 		var res = getMousePos();
 | |
| 		var html = '<div style="background:#fff;position:absolute;width:200px;border:solid 1px #cdcdcd;border-radius:6px;padding:2px;left:'+res.x+'px;top:'+res.y+'px;z-index:1000" id="preview">\
 | |
| 				<img style="width:100%;border-radius:6px;" src="'+imgurl+'">\
 | |
| 			</div>';
 | |
| 		$('body').append(html);
 | |
| 	}
 | |
| 	// 隐藏图片
 | |
| 	function hide_img(){
 | |
| 		$('#preview').remove();
 | |
| 	}
 | |
| 	// 图片位置计算
 | |
| 	function getMousePos(event) {
 | |
| 		var e = event || window.event;
 | |
| 		var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
 | |
| 		var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
 | |
| 		var x = e.pageX || e.clientX + scrollX;
 | |
| 		var y = e.pageY || e.clientY + scrollY;
 | |
| 		return { 'x': x, 'y': y };
 | |
| 	}
 | |
| 	// 删除图片
 | |
| 	function deleteImage(path,obj){
 | |
| 		$(obj).closest('.upload_pic_li').remove();
 | |
| 	}
 | |
| </script>
 | 
