803 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			803 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			HTML
		
	
	
	
| <!DOCTYPE html>
 | ||
| <html lang="zh-CN">
 | ||
| <head>
 | ||
|     <meta charset="UTF-8">
 | ||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | ||
|     <title>数据分析 - 商家端</title>
 | ||
|     <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
 | ||
|     <style>
 | ||
|         * {
 | ||
|             margin: 0;
 | ||
|             padding: 0;
 | ||
|             box-sizing: border-box;
 | ||
|         }
 | ||
| 
 | ||
|         body {
 | ||
|             font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", 微软雅黑, Arial, sans-serif;
 | ||
|             background-color: #f5f5f5;
 | ||
|             color: #333;
 | ||
|             overflow-x: hidden;
 | ||
|         }
 | ||
| 
 | ||
|         .container {
 | ||
|             max-width: 1400px;
 | ||
|             margin: 0 auto;
 | ||
|             padding: 30px;
 | ||
|         }
 | ||
| 
 | ||
|         /* 筛选区域 */
 | ||
|         .filter-section {
 | ||
|             background: #fff;
 | ||
|             padding: 20px;
 | ||
|             border-radius: 8px;
 | ||
|             margin-bottom: 30px;
 | ||
|             box-shadow: 0 2px 8px rgba(0,0,0,0.1);
 | ||
|         }
 | ||
| 
 | ||
|         .filter-row {
 | ||
|             display: flex;
 | ||
|             align-items: center;
 | ||
|             gap: 20px;
 | ||
|             flex-wrap: wrap;
 | ||
|         }
 | ||
| 
 | ||
|         .filter-item {
 | ||
|             display: flex;
 | ||
|             align-items: center;
 | ||
|             gap: 10px;
 | ||
|         }
 | ||
| 
 | ||
|         .filter-item label {
 | ||
|             font-weight: 500;
 | ||
|             color: #333;
 | ||
|             min-width: 70px;
 | ||
|         }
 | ||
| 
 | ||
|         .filter-item select,
 | ||
|         .filter-item input {
 | ||
|             padding: 8px 12px;
 | ||
|             border: 1px solid #d9d9d9;
 | ||
|             border-radius: 4px;
 | ||
|             min-width: 120px;
 | ||
|             font-size: 14px;
 | ||
|             transition: all 0.3s ease;
 | ||
|         }
 | ||
| 
 | ||
|         .filter-item select:focus,
 | ||
|         .filter-item input:focus {
 | ||
|             border-color: #1890ff;
 | ||
|             box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
 | ||
|             outline: none;
 | ||
|         }
 | ||
| 
 | ||
|         .btn {
 | ||
|             padding: 10px 20px;
 | ||
|             border-radius: 5px;
 | ||
|             font-size: 14px;
 | ||
|             font-weight: 500;
 | ||
|             transition: all 0.3s ease;
 | ||
|             display: inline-flex;
 | ||
|             align-items: center;
 | ||
|             gap: 5px;
 | ||
|             border: none;
 | ||
|             cursor: pointer;
 | ||
|         }
 | ||
| 
 | ||
|         .btn-primary {
 | ||
|             background-color: #1890ff;
 | ||
|             color: #fff;
 | ||
|         }
 | ||
| 
 | ||
|         .btn-primary:hover {
 | ||
|             background-color: #40a9ff;
 | ||
|             transform: translateY(-2px);
 | ||
|         }
 | ||
| 
 | ||
|         .btn-success {
 | ||
|             background-color: #52c41a;
 | ||
|             color: #fff;
 | ||
|         }
 | ||
| 
 | ||
|         .btn-success:hover {
 | ||
|             background-color: #73d13d;
 | ||
|             transform: translateY(-2px);
 | ||
|         }
 | ||
| 
 | ||
|         /* 数据卡片区域 */
 | ||
|         .stats-section {
 | ||
|             display: grid;
 | ||
|             grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
 | ||
|             gap: 20px;
 | ||
|             margin-bottom: 30px;
 | ||
|         }
 | ||
| 
 | ||
|         .stats-card {
 | ||
|             background: #fff;
 | ||
|             padding: 20px;
 | ||
|             border-radius: 8px;
 | ||
|             box-shadow: 0 2px 8px rgba(0,0,0,0.1);
 | ||
|             position: relative;
 | ||
|             overflow: hidden;
 | ||
|         }
 | ||
| 
 | ||
|         .stats-card::before {
 | ||
|             content: '';
 | ||
|             position: absolute;
 | ||
|             top: 0;
 | ||
|             left: 0;
 | ||
|             width: 4px;
 | ||
|             height: 100%;
 | ||
|             background: linear-gradient(45deg, #1890ff, #40a9ff);
 | ||
|         }
 | ||
| 
 | ||
|         .stats-item {
 | ||
|             display: flex;
 | ||
|             align-items: center;
 | ||
|             justify-content: space-between;
 | ||
|             margin-bottom: 15px;
 | ||
|         }
 | ||
| 
 | ||
|         .stats-item:last-child {
 | ||
|             margin-bottom: 0;
 | ||
|         }
 | ||
| 
 | ||
|         .stats-label {
 | ||
|             display: flex;
 | ||
|             align-items: center;
 | ||
|             gap: 8px;
 | ||
|             font-size: 14px;
 | ||
|             color: #666;
 | ||
|         }
 | ||
| 
 | ||
|         .stats-icon {
 | ||
|             width: 20px;
 | ||
|             height: 20px;
 | ||
|             border-radius: 50%;
 | ||
|             display: flex;
 | ||
|             align-items: center;
 | ||
|             justify-content: center;
 | ||
|             font-size: 12px;
 | ||
|             color: #fff;
 | ||
|         }
 | ||
| 
 | ||
|         .icon-view { background-color: #1890ff; }
 | ||
|         .icon-visitor { background-color: #52c41a; }
 | ||
|         .icon-new { background-color: #faad14; }
 | ||
|         .icon-order { background-color: #f5222d; }
 | ||
|         .icon-rate { background-color: #722ed1; }
 | ||
|         .icon-purchase { background-color: #13c2c2; }
 | ||
| 
 | ||
|         .stats-value {
 | ||
|             display: flex;
 | ||
|             flex-direction: column;
 | ||
|             align-items: flex-end;
 | ||
|         }
 | ||
| 
 | ||
|         .stats-number {
 | ||
|             font-size: 24px;
 | ||
|             font-weight: bold;
 | ||
|             color: #333;
 | ||
|             margin-bottom: 2px;
 | ||
|         }
 | ||
| 
 | ||
|         .stats-change {
 | ||
|             font-size: 12px;
 | ||
|             display: flex;
 | ||
|             align-items: center;
 | ||
|             gap: 2px;
 | ||
|         }
 | ||
| 
 | ||
|         .stats-change.positive {
 | ||
|             color: #52c41a;
 | ||
|         }
 | ||
| 
 | ||
|         .stats-change.negative {
 | ||
|             color: #f5222d;
 | ||
|         }
 | ||
| 
 | ||
|         .stats-change.neutral {
 | ||
|             color: #666;
 | ||
|         }
 | ||
| 
 | ||
|         /* 图表区域 */
 | ||
|         .charts-section {
 | ||
|             display: grid;
 | ||
|             grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
 | ||
|             gap: 20px;
 | ||
|         }
 | ||
| 
 | ||
|         .chart-section {
 | ||
|             background: #fff;
 | ||
|             padding: 20px;
 | ||
|             border-radius: 8px;
 | ||
|             box-shadow: 0 2px 8px rgba(0,0,0,0.1);
 | ||
|         }
 | ||
| 
 | ||
|         .chart-header {
 | ||
|             display: flex;
 | ||
|             justify-content: space-between;
 | ||
|             align-items: center;
 | ||
|             margin-bottom: 20px;
 | ||
|             padding-bottom: 15px;
 | ||
|             border-bottom: 1px solid #e8e8e8;
 | ||
|         }
 | ||
| 
 | ||
|         .chart-title {
 | ||
|             font-size: 16px;
 | ||
|             font-weight: 600;
 | ||
|             color: #333;
 | ||
|         }
 | ||
| 
 | ||
|         .chart-legend {
 | ||
|             display: flex;
 | ||
|             align-items: center;
 | ||
|             gap: 20px;
 | ||
|         }
 | ||
| 
 | ||
|         .legend-item {
 | ||
|             display: flex;
 | ||
|             align-items: center;
 | ||
|             gap: 8px;
 | ||
|             font-size: 14px;
 | ||
|             color: #666;
 | ||
|         }
 | ||
| 
 | ||
|         .legend-color {
 | ||
|             width: 12px;
 | ||
|             height: 12px;
 | ||
|             border-radius: 50%;
 | ||
|         }
 | ||
| 
 | ||
|         .chart-container {
 | ||
|             position: relative;
 | ||
|             height: 300px;
 | ||
|             width: 100%;
 | ||
|         }
 | ||
| 
 | ||
|         /* 响应式设计 */
 | ||
|         @media (max-width: 768px) {
 | ||
|             .container {
 | ||
|                 padding: 15px;
 | ||
|             }
 | ||
| 
 | ||
|             .filter-row {
 | ||
|                 flex-direction: column;
 | ||
|                 align-items: stretch;
 | ||
|             }
 | ||
| 
 | ||
|             .filter-item {
 | ||
|                 flex-direction: column;
 | ||
|                 align-items: stretch;
 | ||
|                 gap: 5px;
 | ||
|             }
 | ||
| 
 | ||
|             .filter-item label {
 | ||
|                 min-width: auto;
 | ||
|             }
 | ||
| 
 | ||
|             .stats-section {
 | ||
|                 grid-template-columns: 1fr;
 | ||
|             }
 | ||
| 
 | ||
|             .charts-section {
 | ||
|                 grid-template-columns: 1fr;
 | ||
|             }
 | ||
| 
 | ||
|             .chart-header {
 | ||
|                 flex-direction: column;
 | ||
|                 align-items: stretch;
 | ||
|                 gap: 15px;
 | ||
|             }
 | ||
| 
 | ||
|             .chart-legend {
 | ||
|                 justify-content: center;
 | ||
|                 flex-wrap: wrap;
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         /* 动画效果 */
 | ||
|         @keyframes fadeIn {
 | ||
|             from {
 | ||
|                 opacity: 0;
 | ||
|                 transform: translateY(20px);
 | ||
|             }
 | ||
|             to {
 | ||
|                 opacity: 1;
 | ||
|                 transform: translateY(0);
 | ||
|             }
 | ||
|         }
 | ||
| 
 | ||
|         .stats-card,
 | ||
|         .filter-section,
 | ||
|         .chart-section {
 | ||
|             animation: fadeIn 0.6s ease-out;
 | ||
|         }
 | ||
| 
 | ||
|         .stats-card:nth-child(2) { animation-delay: 0.1s; }
 | ||
|         .stats-card:nth-child(3) { animation-delay: 0.2s; }
 | ||
|     </style>
 | ||
| </head>
 | ||
| <body>
 | ||
|     <div class="container">
 | ||
|         <!-- 筛选区域 -->
 | ||
|         <div class="filter-section">
 | ||
|             <div class="filter-row">
 | ||
|                 <div class="filter-item">
 | ||
|                     <label for="dateRange">日期范围:</label>
 | ||
|                     <select id="dateRange">
 | ||
|                         <option value="today">近1天</option>
 | ||
|                         <option value="week" selected>近7天</option>
 | ||
|                         <option value="month">近30天</option>
 | ||
|                         <option value="custom">自定义</option>
 | ||
|                     </select>
 | ||
|                 </div>
 | ||
|                 <div class="filter-item" id="customDateRange" style="display: none;">
 | ||
|                     <label for="startDate">开始日期:</label>
 | ||
|                     <input type="date" id="startDate">
 | ||
|                     <label for="endDate">结束日期:</label>
 | ||
|                     <input type="date" id="endDate">
 | ||
|                 </div>
 | ||
|                 <button class="btn btn-primary" onclick="queryData()">
 | ||
|                     <span>查询</span>
 | ||
|                 </button>
 | ||
|                 <button class="btn btn-success" onclick="exportData()">
 | ||
|                     <span>导出</span>
 | ||
|                 </button>
 | ||
|             </div>
 | ||
|         </div>
 | ||
| 
 | ||
|         <!-- 数据卡片区域 -->
 | ||
|         <div class="stats-section">
 | ||
|             <div class="stats-card">
 | ||
|                 <div class="stats-item">
 | ||
|                     <div class="stats-label">
 | ||
|                         <div class="stats-icon icon-view">👁</div>
 | ||
|                         展现量(次)
 | ||
|                     </div>
 | ||
|                     <div class="stats-value">
 | ||
|                         <div class="stats-number">0</div>
 | ||
|                         <div class="stats-change neutral">↑ 0.00%</div>
 | ||
|                     </div>
 | ||
|                 </div>
 | ||
|                 <div class="stats-item">
 | ||
|                     <div class="stats-label">
 | ||
|                         <div class="stats-icon icon-order">👤</div>
 | ||
|                         支付订单人数(人)
 | ||
|                     </div>
 | ||
|                     <div class="stats-value">
 | ||
|                         <div class="stats-number">0</div>
 | ||
|                         <div class="stats-change neutral"></div>
 | ||
|                     </div>
 | ||
|                 </div>
 | ||
|             </div>
 | ||
| 
 | ||
|             <div class="stats-card">
 | ||
|                 <div class="stats-item">
 | ||
|                     <div class="stats-label">
 | ||
|                         <div class="stats-icon icon-visitor">👥</div>
 | ||
|                         浏览人数(人)
 | ||
|                     </div>
 | ||
|                     <div class="stats-value">
 | ||
|                         <div class="stats-number">0</div>
 | ||
|                         <div class="stats-change neutral">↑ 0.00%</div>
 | ||
|                     </div>
 | ||
|                 </div>
 | ||
|                 <div class="stats-item">
 | ||
|                     <div class="stats-label">
 | ||
|                         <div class="stats-icon icon-rate">📊</div>
 | ||
|                         支付订单转化率(%)
 | ||
|                     </div>
 | ||
|                     <div class="stats-value">
 | ||
|                         <div class="stats-number">0.00%</div>
 | ||
|                         <div class="stats-change neutral"></div>
 | ||
|                     </div>
 | ||
|                 </div>
 | ||
|             </div>
 | ||
| 
 | ||
|             <div class="stats-card">
 | ||
|                 <div class="stats-item">
 | ||
|                     <div class="stats-label">
 | ||
|                         <div class="stats-icon icon-new">⭐</div>
 | ||
|                         新客数量(人)
 | ||
|                     </div>
 | ||
|                     <div class="stats-value">
 | ||
|                         <div class="stats-number">0</div>
 | ||
|                         <div class="stats-change neutral">↑ 0.00%</div>
 | ||
|                     </div>
 | ||
|                 </div>
 | ||
|                 <div class="stats-item">
 | ||
|                     <div class="stats-label">
 | ||
|                         <div class="stats-icon icon-purchase">💰</div>
 | ||
|                         客户复购率(%)
 | ||
|                     </div>
 | ||
|                     <div class="stats-value">
 | ||
|                         <div class="stats-number">0.00%</div>
 | ||
|                         <div class="stats-change neutral"></div>
 | ||
|                     </div>
 | ||
|                 </div>
 | ||
|             </div>
 | ||
|         </div>
 | ||
| 
 | ||
|         <!-- 图表区域 -->
 | ||
|         <div class="charts-section">
 | ||
|             <div class="chart-section">
 | ||
|                 <div class="chart-header">
 | ||
|                     <div class="chart-title">浏览数量趋势</div>
 | ||
|                     <div class="chart-legend">
 | ||
|                         <div class="legend-item">
 | ||
|                             <div class="legend-color" style="background-color: #1890ff;"></div>
 | ||
|                             浏览数量
 | ||
|                         </div>
 | ||
|                     </div>
 | ||
|                 </div>
 | ||
|                 <div class="chart-container">
 | ||
|                     <canvas id="viewChart"></canvas>
 | ||
|                 </div>
 | ||
|             </div>
 | ||
| 
 | ||
|             <div class="chart-section">
 | ||
|                 <div class="chart-header">
 | ||
|                     <div class="chart-title">浏览人数趋势</div>
 | ||
|                     <div class="chart-legend">
 | ||
|                         <div class="legend-item">
 | ||
|                             <div class="legend-color" style="background-color: #52c41a;"></div>
 | ||
|                             浏览人数
 | ||
|                         </div>
 | ||
|                     </div>
 | ||
|                 </div>
 | ||
|                 <div class="chart-container">
 | ||
|                     <canvas id="visitorChart"></canvas>
 | ||
|                 </div>
 | ||
|             </div>
 | ||
| 
 | ||
|             <div class="chart-section">
 | ||
|                 <div class="chart-header">
 | ||
|                     <div class="chart-title">新客数量趋势</div>
 | ||
|                     <div class="chart-legend">
 | ||
|                         <div class="legend-item">
 | ||
|                             <div class="legend-color" style="background-color: #faad14;"></div>
 | ||
|                             新客数量
 | ||
|                         </div>
 | ||
|                     </div>
 | ||
|                 </div>
 | ||
|                 <div class="chart-container">
 | ||
|                     <canvas id="newCustomerChart"></canvas>
 | ||
|                 </div>
 | ||
|             </div>
 | ||
| 
 | ||
|             <div class="chart-section">
 | ||
|                 <div class="chart-header">
 | ||
|                     <div class="chart-title">支付订单人数趋势</div>
 | ||
|                     <div class="chart-legend">
 | ||
|                         <div class="legend-item">
 | ||
|                             <div class="legend-color" style="background-color: #f5222d;"></div>
 | ||
|                             支付订单人数
 | ||
|                         </div>
 | ||
|                     </div>
 | ||
|                 </div>
 | ||
|                 <div class="chart-container">
 | ||
|                     <canvas id="orderChart"></canvas>
 | ||
|                 </div>
 | ||
|             </div>
 | ||
|         </div>
 | ||
|     </div>
 | ||
| 
 | ||
|     <script>
 | ||
|         // 初始化图表数据
 | ||
|         const chartLabels = [];
 | ||
|         const chartData = [];
 | ||
| 
 | ||
|         // 生成最近30天的日期标签
 | ||
|         for (let i = 29; i >= 0; i--) {
 | ||
|             const date = new Date();
 | ||
|             date.setDate(date.getDate() - i);
 | ||
|             chartLabels.push(String(date.getMonth() + 1).padStart(2, '0') + '-' + String(date.getDate()).padStart(2, '0'));
 | ||
|             chartData.push(0);
 | ||
|         }
 | ||
| 
 | ||
| 
 | ||
|         // 图表配置
 | ||
|         const chartConfig = {
 | ||
|             responsive: true,
 | ||
|             maintainAspectRatio: false,
 | ||
|             plugins: {
 | ||
|                 legend: {
 | ||
|                     display: false
 | ||
|                 }
 | ||
|             },
 | ||
|             scales: {
 | ||
|                 y: {
 | ||
|                     beginAtZero: true,
 | ||
|                     grid: {
 | ||
|                         color: '#f0f0f0'
 | ||
|                     },
 | ||
|                     ticks: {
 | ||
|                         color: '#666',
 | ||
|                         font: {
 | ||
|                             size: 12
 | ||
|                         }
 | ||
|                     }
 | ||
|                 },
 | ||
|                 x: {
 | ||
|                     grid: {
 | ||
|                         color: '#f0f0f0'
 | ||
|                     },
 | ||
|                     ticks: {
 | ||
|                         color: '#666',
 | ||
|                         font: {
 | ||
|                             size: 12
 | ||
|                         },
 | ||
|                         maxRotation: 45
 | ||
|                     }
 | ||
|                 }
 | ||
|             },
 | ||
|             interaction: {
 | ||
|                 intersect: false,
 | ||
|                 mode: 'index'
 | ||
|             },
 | ||
|             elements: {
 | ||
|                 point: {
 | ||
|                     hoverRadius: 6
 | ||
|                 }
 | ||
|             }
 | ||
|         };
 | ||
| 
 | ||
|         // 初始化浏览数量图表
 | ||
|         const viewChart = new Chart(document.getElementById('viewChart').getContext('2d'), {
 | ||
|             type: 'line',
 | ||
|             data: {
 | ||
|                 labels: chartLabels,
 | ||
|                 datasets: [{
 | ||
|                     label: '浏览数量',
 | ||
|                     data: chartData,
 | ||
|                     borderColor: '#1890ff',
 | ||
|                     backgroundColor: 'rgba(24, 144, 255, 0.1)',
 | ||
|                     borderWidth: 2,
 | ||
|                     fill: true,
 | ||
|                     tension: 0.4,
 | ||
|                     pointRadius: 4,
 | ||
|                     pointBackgroundColor: '#1890ff',
 | ||
|                     pointBorderColor: '#fff',
 | ||
|                     pointBorderWidth: 2
 | ||
|                 }]
 | ||
|             },
 | ||
|             options: chartConfig
 | ||
|         });
 | ||
| 
 | ||
|         // 初始化浏览人数图表
 | ||
|         const visitorChart = new Chart(document.getElementById('visitorChart').getContext('2d'), {
 | ||
|             type: 'line',
 | ||
|             data: {
 | ||
|                 labels: chartLabels,
 | ||
|                 datasets: [{
 | ||
|                     label: '浏览人数',
 | ||
|                     data: chartData,
 | ||
|                     borderColor: '#52c41a',
 | ||
|                     backgroundColor: 'rgba(82, 196, 26, 0.1)',
 | ||
|                     borderWidth: 2,
 | ||
|                     fill: true,
 | ||
|                     tension: 0.4,
 | ||
|                     pointRadius: 4,
 | ||
|                     pointBackgroundColor: '#52c41a',
 | ||
|                     pointBorderColor: '#fff',
 | ||
|                     pointBorderWidth: 2
 | ||
|                 }]
 | ||
|             },
 | ||
|             options: chartConfig
 | ||
|         });
 | ||
| 
 | ||
|         // 初始化新客数量图表
 | ||
|         const newCustomerChart = new Chart(document.getElementById('newCustomerChart').getContext('2d'), {
 | ||
|             type: 'line',
 | ||
|             data: {
 | ||
|                 labels: chartLabels,
 | ||
|                 datasets: [{
 | ||
|                     label: '新客数量',
 | ||
|                     data: chartData,
 | ||
|                     borderColor: '#faad14',
 | ||
|                     backgroundColor: 'rgba(250, 173, 20, 0.1)',
 | ||
|                     borderWidth: 2,
 | ||
|                     fill: true,
 | ||
|                     tension: 0.4,
 | ||
|                     pointRadius: 4,
 | ||
|                     pointBackgroundColor: '#faad14',
 | ||
|                     pointBorderColor: '#fff',
 | ||
|                     pointBorderWidth: 2
 | ||
|                 }]
 | ||
|             },
 | ||
|             options: chartConfig
 | ||
|         });
 | ||
| 
 | ||
|         // 初始化支付订单人数图表
 | ||
|         const orderChart = new Chart(document.getElementById('orderChart').getContext('2d'), {
 | ||
|             type: 'line',
 | ||
|             data: {
 | ||
|                 labels: chartLabels,
 | ||
|                 datasets: [{
 | ||
|                     label: '支付订单人数',
 | ||
|                     data: chartData,
 | ||
|                     borderColor: '#f5222d',
 | ||
|                     backgroundColor: 'rgba(245, 34, 45, 0.1)',
 | ||
|                     borderWidth: 2,
 | ||
|                     fill: true,
 | ||
|                     tension: 0.4,
 | ||
|                     pointRadius: 4,
 | ||
|                     pointBackgroundColor: '#f5222d',
 | ||
|                     pointBorderColor: '#fff',
 | ||
|                     pointBorderWidth: 2
 | ||
|                 }]
 | ||
|             },
 | ||
|             options: chartConfig
 | ||
|         });
 | ||
| 
 | ||
|         // 日期范围选择
 | ||
|         document.getElementById('dateRange').addEventListener('change', function() {
 | ||
|             const customDateRange = document.getElementById('customDateRange');
 | ||
|             if (this.value === 'custom') {
 | ||
|                 customDateRange.style.display = 'flex';
 | ||
|             } else {
 | ||
|                 customDateRange.style.display = 'none';
 | ||
|             }
 | ||
|         });
 | ||
| 
 | ||
|         // 查询数据函数
 | ||
|         function queryData() {
 | ||
|             const dateRange = document.getElementById('dateRange').value;
 | ||
|             let startDate, endDate;
 | ||
| 
 | ||
|             if (dateRange === 'custom') {
 | ||
|                 startDate = document.getElementById('startDate').value;
 | ||
|                 endDate = document.getElementById('endDate').value;
 | ||
| 
 | ||
|                 if (!startDate || !endDate) {
 | ||
|                     showNotification('请选择时间范围', 'error');
 | ||
|                     return;
 | ||
|                 }
 | ||
| 
 | ||
|                 if (new Date(startDate) > new Date(endDate)) {
 | ||
|                     showNotification('开始时间不能大于结束时间', 'error');
 | ||
|                     return;
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             console.log('查询参数:', { dateRange, startDate, endDate });
 | ||
| 
 | ||
|             updateStatsCards();
 | ||
|             updateCharts();
 | ||
| 
 | ||
|             showNotification('数据查询成功', 'success');
 | ||
|         }
 | ||
| 
 | ||
|         // 导出数据函数
 | ||
|         function exportData() {
 | ||
|             const dateRange = document.getElementById('dateRange').value;
 | ||
| 
 | ||
|             if (dateRange === 'custom') {
 | ||
|                 const startDate = document.getElementById('startDate').value;
 | ||
|                 const endDate = document.getElementById('endDate').value;
 | ||
| 
 | ||
|                 if (!startDate || !endDate) {
 | ||
|                     showNotification('请选择时间范围', 'error');
 | ||
|                     return;
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             console.log('导出数据');
 | ||
|             showNotification('数据导出中...', 'info');
 | ||
| 
 | ||
|             setTimeout(() => {
 | ||
|                 showNotification('数据导出完成', 'success');
 | ||
|             }, 2000);
 | ||
|         }
 | ||
| 
 | ||
|         // 更新统计卡片数据
 | ||
|         function updateStatsCards() {
 | ||
|             const statsNumbers = document.querySelectorAll('.stats-number');
 | ||
|             statsNumbers.forEach((element, index) => {
 | ||
|                 if (element.textContent.includes('%')) {
 | ||
|                     element.textContent = (Math.random() * 10).toFixed(2) + '%';
 | ||
|                 } else {
 | ||
|                     element.textContent = Math.floor(Math.random() * 1000);
 | ||
|                 }
 | ||
|             });
 | ||
| 
 | ||
|             const statsChanges = document.querySelectorAll('.stats-change');
 | ||
|             statsChanges.forEach(element => {
 | ||
|                 const change = (Math.random() * 20 - 10).toFixed(2);
 | ||
|                 if (change > 0) {
 | ||
|                     element.className = 'stats-change positive';
 | ||
|                     element.textContent = `↑ ${change}%`;
 | ||
|                 } else if (change < 0) {
 | ||
|                     element.className = 'stats-change negative';
 | ||
|                     element.textContent = `↓ ${Math.abs(change)}%`;
 | ||
|                 } else {
 | ||
|                     element.className = 'stats-change neutral';
 | ||
|                     element.textContent = '0.00%';
 | ||
|                 }
 | ||
|             });
 | ||
|         }
 | ||
| 
 | ||
|         // 更新所有图表数据
 | ||
|         function updateCharts() {
 | ||
|             const newData1 = chartData.map(() => Math.floor(Math.random() * 100));
 | ||
|             const newData2 = chartData.map(() => Math.floor(Math.random() * 80));
 | ||
|             const newData3 = chartData.map(() => Math.floor(Math.random() * 50));
 | ||
|             const newData4 = chartData.map(() => Math.floor(Math.random() * 60));
 | ||
| 
 | ||
|             viewChart.data.datasets[0].data = newData1;
 | ||
|             visitorChart.data.datasets[0].data = newData2;
 | ||
|             newCustomerChart.data.datasets[0].data = newData3;
 | ||
|             orderChart.data.datasets[0].data = newData4;
 | ||
| 
 | ||
|             viewChart.update('active');
 | ||
|             visitorChart.update('active');
 | ||
|             newCustomerChart.update('active');
 | ||
|             orderChart.update('active');
 | ||
|         }
 | ||
| 
 | ||
|         // 显示通知函数
 | ||
|         function showNotification(message, type) {
 | ||
|             const notification = document.createElement('div');
 | ||
|             notification.textContent = message;
 | ||
|             notification.style.cssText = `
 | ||
|                 position: fixed;
 | ||
|                 top: 20px;
 | ||
|                 right: 20px;
 | ||
|                 padding: 12px 20px;
 | ||
|                 border-radius: 4px;
 | ||
|                 color: white;
 | ||
|                 font-weight: 500;
 | ||
|                 z-index: 9999;
 | ||
|                 animation: slideIn 0.3s ease-out;
 | ||
|                 background-color: ${type === 'success' ? '#52c41a' : type === 'error' ? '#f5222d' : '#1890ff'};
 | ||
|             `;
 | ||
| 
 | ||
|             document.body.appendChild(notification);
 | ||
| 
 | ||
|             setTimeout(() => {
 | ||
|                 notification.style.animation = 'slideOut 0.3s ease-in';
 | ||
|                 setTimeout(() => {
 | ||
|                     document.body.removeChild(notification);
 | ||
|                 }, 300);
 | ||
|             }, 3000);
 | ||
|         }
 | ||
| 
 | ||
|         // 添加动画样式
 | ||
|         const style = document.createElement('style');
 | ||
|         style.textContent = `
 | ||
|             @keyframes slideIn {
 | ||
|                 from {
 | ||
|                     transform: translateX(100%);
 | ||
|                     opacity: 0;
 | ||
|                 }
 | ||
|                 to {
 | ||
|                     transform: translateX(0);
 | ||
|                     opacity: 1;
 | ||
|                 }
 | ||
|             }
 | ||
| 
 | ||
|             @keyframes slideOut {
 | ||
|                 from {
 | ||
|                     transform: translateX(0);
 | ||
|                     opacity: 1;
 | ||
|                 }
 | ||
|                 to {
 | ||
|                     transform: translateX(100%);
 | ||
|                     opacity: 0;
 | ||
|                 }
 | ||
|             }
 | ||
|         `;
 | ||
|         document.head.appendChild(style);
 | ||
| 
 | ||
|         // 页面加载完成后的初始化
 | ||
|         document.addEventListener('DOMContentLoaded', function() {
 | ||
|             console.log('数据分析页面加载完成');
 | ||
| 
 | ||
|             setTimeout(() => {
 | ||
|                 updateStatsCards();
 | ||
|                 updateCharts();
 | ||
|             }, 1000);
 | ||
|         });
 | ||
|     </script>
 | ||
| </body>
 | ||
| </html> |