82 lines
3.1 KiB
HTML
82 lines
3.1 KiB
HTML
{% extends "base.html" %}
|
|
{% set active = 'dashboard' %}
|
|
{% block title %}仪表盘 - 新闻智能跟踪{% endblock %}
|
|
{% block content %}
|
|
<div class="page-head">
|
|
<h1>📊 仪表盘</h1>
|
|
<div class="actions">
|
|
<button class="btn" onclick="doAct('collect')">🔁 立即采集</button>
|
|
<button class="btn" onclick="doAct('llm')">🧠 LLM深度分析</button>
|
|
<button class="btn accent" onclick="doAct('summary')">📰 立即发汇总</button>
|
|
<button class="btn" onclick="doAct('reanalyze')">♻️ 重新打分</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="stat-grid">
|
|
<div class="stat"><div class="stat-num">{{ stats.total }}</div><div class="stat-label">资讯总数</div></div>
|
|
<div class="stat hot"><div class="stat-num">{{ stats.important }}</div><div class="stat-label">重要资讯</div></div>
|
|
<div class="stat"><div class="stat-num">{{ stats.notified }}</div><div class="stat-label">已通知</div></div>
|
|
<div class="stat warn"><div class="stat-num">{{ stats.pending_llm }}</div><div class="stat-label">待深度分析</div></div>
|
|
</div>
|
|
|
|
<div class="two-col">
|
|
<section class="card">
|
|
<h3>🔥 重要资讯 TOP</h3>
|
|
{% for a in important %}
|
|
<div class="item">
|
|
<a class="item-title" href="/news/{{ a.id }}">{{ a.title }}</a>
|
|
<div class="item-meta">
|
|
<span class="score s{{ a.total_score }}">{{ a.total_score }}</span>
|
|
<span>{{ a.domain }}</span>
|
|
<span>{{ a.published_at }}</span>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="empty">暂无重要资讯</div>
|
|
{% endfor %}
|
|
</section>
|
|
<section class="card">
|
|
<h3>🗂️ 领域分布</h3>
|
|
<div class="bars">
|
|
{% for d in domain_stats %}
|
|
<div class="bar-row">
|
|
<span class="bar-label">{{ d.name }}</span>
|
|
<div class="bar-track"><div class="bar-fill" style="width:{{ (d.count / domain_stats[0].count * 100)|int if domain_stats and domain_stats[0].count else 0 }}%"></div></div>
|
|
<span class="bar-val">{{ d.count }}</span>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</section>
|
|
</div>
|
|
|
|
<section class="card">
|
|
<h3>🕒 最新收录</h3>
|
|
{% for a in latest %}
|
|
<div class="item">
|
|
<a class="item-title" href="/news/{{ a.id }}">{{ a.title }}</a>
|
|
<div class="item-meta">
|
|
<span class="score s{{ a.total_score }}">{{ a.total_score }}</span>
|
|
<span>{{ a.source_name }}</span>
|
|
<span>{{ a.collected_at }}</span>
|
|
</div>
|
|
</div>
|
|
{% else %}
|
|
<div class="empty">尚未收录资讯,点击「立即采集」</div>
|
|
{% endfor %}
|
|
</section>
|
|
{% endblock %}
|
|
{% block script %}
|
|
<script>
|
|
async function doAct(action) {
|
|
const btn = event.target; btn.disabled = true;
|
|
const r = await API.json('/api/actions', {action});
|
|
btn.disabled = false;
|
|
if (action === 'summary') toast(r.sent ? `✅ 汇总邮件已发送 ${r.sent} 条` : '✅ 无可汇总资讯');
|
|
else if (action === 'llm') toast(`✅ 深度分析完成 ${r.done} 条` + (r.error ? `,失败 ${r.error}` : ''));
|
|
else if (action === 'collect') toast(r.added ? `✅ 采集到 ${r.added} 条新资讯` : '✅ 暂无新资讯');
|
|
else toast('✅ 已重新打分');
|
|
setTimeout(() => location.reload(), 800);
|
|
}
|
|
</script>
|
|
{% endblock %}
|