Files
hot_comment_radar/app/templates/tasks/detail.html
T

113 lines
6.4 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}任务 {{ task.display_id }} - 热榜评论分析工具{% endblock %}
{% block breadcrumbs %}
<nav aria-label="breadcrumb"><ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/">首页</a></li>
<li class="breadcrumb-item active">任务 {{ task.display_id }}</li>
</ol></nav>
{% endblock %}
{% block content %}
{% set label, cls = status_badge_config(task.status) %}
{% set percent = progress_percent(task.processed_items_count, task.total_items_count) %}
{% set ai_percent = rate_percent(task.analysis_success_rate) %}
{% set target_comments = task.hotspot_limit * task.item_limit_per_hotspot * task.comment_limit_per_item %}
<section class="task-detail-hero" {% if task.status == "running" %}data-task-id="{{ task.id }}" data-auto-poll="true"{% endif %}>
<div class="task-detail-copy">
<p class="section-kicker">TASK DETAIL</p>
<h1>{{ task.platform | platform_label }}热点评论采集任务 {{ task.display_id }}</h1>
<p>创建时间 {{ task.created_at_label }},当前阶段 {{ task.current_stage_label or "等待启动" }}。任务执行过程会隔离单条内容失败,并保留失败原因用于复查。</p>
</div>
<aside class="task-state-card">
<span>当前状态</span>
<strong>{{ label }}</strong>
<p>已处理 {{ task.processed_items_count }} / 共 {{ task.total_items_count }} 条内容 · AI 成功率 {{ ai_percent }}% · 报告 {{ task.reports_count or 0 }} 份 · 失败内容 {{ task.failed_items_count }}</p>
</aside>
</section>
<section class="execution-timeline" aria-label="执行阶段">
{% for stage, desc, state in [
("创建任务", "参数校验完成", "done"),
("热点抓取", (task.hotspots_count or 0) ~ " 个热点入库", "done" if (task.hotspots_count or 0) > 0 or task.status == "success" else "pending"),
("内容采集", task.processed_items_count ~ " / " ~ task.total_items_count ~ " 条内容", "done" if task.processed_items_count >= task.total_items_count and task.total_items_count > 0 else "active"),
("评论分页", (task.comments_count or 0) ~ " 条评论", "done" if (task.comments_count or 0) > 0 else "pending"),
("AI 分析", "成功率 " ~ ai_percent ~ "%", "done" if ai_percent >= 80 else "active"),
("报告生成", (task.reports_count or 0) ~ " 份报告", "done" if (task.reports_count or 0) > 0 else "pending")
] %}
<div class="execution-step execution-step-{{ state }}">
<span class="execution-step-icon">{% if state == "done" %}✓{% elif state == "active" %}•{% else %}○{% endif %}</span>
<strong>{{ stage }}</strong>
<small>{{ desc }}</small>
</div>
{% endfor %}
</section>
{% if task.status == "running" and not hotspots %}
<div class="empty-state text-muted py-5"><div class="spinner-border text-warning mb-3"></div><p class="mb-0">正在抓取热点数据,请稍候...</p></div>
{% endif %}
<div class="detail-workspace">
<section class="hotspot-card-list">
<div class="panel-title-row">
<div>
<p class="section-kicker">执行阶段</p>
<h2>热点结果</h2>
</div>
<span class="panel-note">按热度与评论完成度查看</span>
</div>
{% for hotspot in hotspots %}
<article class="hotspot-result-card">
<div class="hotspot-rank">{{ "%02d"|format(hotspot.rank or loop.index) }}</div>
<div class="hotspot-result-body">
<h3>热点 {{ hotspot.rank or loop.index }}{{ hotspot.title }}</h3>
<div class="hotspot-chip-row">
<span>{{ hotspot.content_items | length }} 内容</span>
<span>{{ hotspot.comments | length }} 评论</span>
<span>{{ task.platform | platform_label }}</span>
</div>
</div>
<a class="btn btn-sm btn-primary" href="/hotspots/{{ hotspot.id }}/report">查看报告</a>
</article>
{% else %}
<div class="empty-state text-muted py-5">暂无热点结果</div>
{% endfor %}
</section>
<aside class="detail-sidepanel">
<section class="sidepanel-card">
<h2>采集规模</h2>
<div class="stat-line"><span>目标上限</span><strong>{{ task.hotspot_limit }} 热点 × {{ task.item_limit_per_hotspot }} 内容 × {{ task.comment_limit_per_item }} 评论</strong></div>
<div class="stat-line"><span>实际结果</span><strong>实际评论 {{ task.comments_count or 0 }}</strong></div>
<div class="stat-line"><span>热点完成度</span><strong>已获取热点 {{ task.hotspots_count or 0 }} / 目标 {{ task.hotspot_limit }}</strong></div>
<div class="stat-line"><span>热点数</span><strong>{{ task.hotspot_limit }}</strong></div>
<div class="stat-line"><span>内容数</span><strong>{{ task.total_items_count }}</strong></div>
<div class="stat-line"><span>评论数</span><strong>{{ task.comments_count or 0 }}</strong></div>
<div class="stat-line"><span>报告数</span><strong>{{ task.reports_count or 0 }}</strong></div>
<div class="stat-line"><span>运行时长</span><strong>{{ task.running_duration_label or "刚刚" }}</strong></div>
<div class="stat-line"><span>最近进度</span><strong>{{ task.last_progress_ago_label or "暂无记录" }}</strong></div>
</section>
<section class="sidepanel-card sidepanel-card-danger">
<h2>错误会被隔离</h2>
<p>单条内容或评论失败不会让整个任务崩溃,失败原因会保留在对应结果和报告数据中。</p>
{% if task.error_summary %}<p class="task-card-error">{{ task.error_summary }}</p>{% endif %}
</section>
</aside>
</div>
{% if task.is_progress_stale %}
<div class="alert alert-warning mt-3">
超过 {{ task.stale_threshold_minutes }} 分钟没有进度更新,可能仍在等待外部接口或 AI 响应;如果长时间不恢复,请刷新状态或查看后端日志。
</div>
{% endif %}
{% if task.status == "success" and (task.comments_count or 0) < target_comments %}
<div class="alert alert-info mt-3">少于理论上限通常是内容本身评论不足或平台返回不足,不直接代表任务失败。若失败内容数大于 0,请结合失败原因判断。</div>
{% endif %}
{% if task.analysis_status == "insufficient" %}
<div class="alert alert-warning mt-3">AI 成功率 {{ ai_percent }}%,当前样本可能不足,报告结论请结合评论明细判断。</div>
{% endif %}
{% if task.status == "running" %}
<script>document.addEventListener("DOMContentLoaded", () => pollTaskDetailStatus("{{ task.id }}"));</script>
{% endif %}
{% endblock %}