变基一下home.html

This commit is contained in:
2025-11-15 09:46:25 +08:00
parent 62ee8399e8
commit ca9da9f7aa

View File

@@ -78,6 +78,60 @@
margin-top: 10px;
text-align: center;
}
.card {
background: #fff;
border-radius: 14px;
box-shadow: 0 10px 24px rgba(31,35,40,0.08);
padding: 20px;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
}
.grid-3 {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 16px;
}
.header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
}
.badge {
background: #eef2ff;
color: #3730a3;
border-radius: 999px;
padding: 4px 10px;
font-size: 12px;
}
.legend {
display: flex;
gap: 12px;
align-items: center;
}
.legend .dot {
width: 8px;
height: 8px;
border-radius: 50%;
display: inline-block;
}
.muted {
color: #6b7280;
font-size: 12px;
}
.btn {
padding: 8px 12px;
border: none;
border-radius: 8px;
cursor: pointer;
}
.btn-primary {
background: #4f46e5;
color: #fff;
}
</style>
</head>
<body>
@@ -98,9 +152,41 @@
<!-- 主内容区域 -->
<div class="main-content">
<h1>欢迎来到系统</h1>
<p>这里是一大堆内容……</p>
<p style="height: 200vh;">滚动试试看,左边菜单不会消失哦!✨</p>
<div class="card">
<div class="header">
<h2>数据概览</h2>
<div style="display:flex; gap:8px; align-items:center;">
<span class="badge">用户:{{ user_id }}</span>
{% if is_admin %}
<button id="triggerAnalyze" class="btn btn-primary">手动开始分析</button>
{% endif %}
</div>
</div>
<div class="grid-3">
<div>
<div class="legend"><span class="dot" style="background:#4f46e5;"></span><span class="muted">最近十天录入</span></div>
<canvas id="chartDays" height="140"></canvas>
</div>
<div>
<div class="legend"><span class="dot" style="background:#16a34a;"></span><span class="muted">最近十周录入</span></div>
<canvas id="chartWeeks" height="140"></canvas>
</div>
<div>
<div class="legend"><span class="dot" style="background:#ea580c;"></span><span class="muted">最近十个月录入</span></div>
<canvas id="chartMonths" height="140"></canvas>
</div>
</div>
</div>
<div class="grid" style="margin-top:16px;">
<div class="card">
<div class="header"><h2>近1个月成果类型</h2></div>
<canvas id="pie1m" height="200"></canvas>
</div>
<div class="card">
<div class="header"><h2>近12个月成果类型</h2></div>
<canvas id="pie12m" height="200"></canvas>
</div>
</div>
</div>
<!-- 登出脚本(保持不变) -->
@@ -136,5 +222,90 @@
}
});
</script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
async function loadAnalytics() {
const resp = await fetch('/elastic/analytics/overview/');
const d = await resp.json();
if (!resp.ok || d.status !== 'success') return;
const data = d.data || {};
renderLine('chartDays', data.last_10_days || [], '#4f46e5');
renderLine('chartWeeks', data.last_10_weeks || [], '#16a34a');
renderLine('chartMonths', data.last_10_months || [], '#ea580c');
renderPie('pie1m', data.type_pie_1m || []);
renderPie('pie12m', data.type_pie_12m || []);
}
const btn = document.getElementById('triggerAnalyze');
if (btn) {
btn.addEventListener('click', async () => {
btn.disabled = true;
btn.textContent = '分析中…';
try {
const resp = await fetch('/elastic/analytics/overview/?force=1');
const d = await resp.json();
if (!resp.ok || d.status !== 'success') throw new Error('分析失败');
window.location.reload();
} catch (e) {
btn.textContent = '重试';
btn.disabled = false;
}
});
}
function hexWithAlpha(hex, alphaHex) {
if (!hex || !hex.startsWith('#')) return hex;
if (hex.length === 7) return hex + alphaHex;
return hex;
}
function renderLine(id, items, color) {
const ctx = document.getElementById(id);
const labels = items.map(x => x.label);
const values = items.map(x => x.count);
new Chart(ctx, {
type: 'line',
data: {
labels,
datasets: [{
data: values,
borderColor: color,
backgroundColor: hexWithAlpha(color, '26'),
tension: 0.25,
fill: true,
pointRadius: 3,
}]
},
options: {
responsive: true,
plugins: { legend: { display: false } },
animation: { duration: 800, easing: 'easeOutQuart' },
scales: {
x: { grid: { display: false } },
y: { grid: { color: 'rgba(31,35,40,0.06)' }, beginAtZero: true }
}
}
});
}
function renderPie(id, items) {
const ctx = document.getElementById(id);
const labels = items.map(x => x.type);
const values = items.map(x => x.count);
const colors = ['#2563eb','#22c55e','#f59e0b','#ef4444','#a855f7','#06b6d4','#84cc16','#ec4899','#475569','#d946ef'];
new Chart(ctx, {
type: 'doughnut',
data: {
labels,
datasets: [{ data: values, backgroundColor: colors.slice(0, labels.length) }]
},
options: {
responsive: true,
animation: { duration: 900, easing: 'easeOutQuart' },
plugins: { legend: { position: 'bottom' } }
}
});
}
loadAnalytics();
</script>
</body>
</html>