822 lines
25 KiB
HTML
822 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: 1600px;
|
||
margin: 0 auto;
|
||
padding: 20px;
|
||
}
|
||
|
||
.page-header {
|
||
background: white;
|
||
padding: 16px 24px;
|
||
margin-bottom: 16px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.page-title {
|
||
font-size: 24px;
|
||
font-weight: 600;
|
||
color: #262626;
|
||
}
|
||
|
||
/* 筛选区域 */
|
||
.filter-section {
|
||
background: #fff;
|
||
padding: 24px;
|
||
border-radius: 8px;
|
||
margin-bottom: 16px;
|
||
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: 16px;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.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: 16px;
|
||
}
|
||
|
||
.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="page-header">
|
||
<h1 class="page-title">客户分析</h1>
|
||
</div>
|
||
|
||
<!-- 筛选区域 -->
|
||
<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> |