feat: 优化页面信息展示
This commit is contained in:
@@ -34,6 +34,11 @@ class TaskResponse(BaseModel):
|
||||
current_stage: str | None = None
|
||||
current_stage_label: str | None = None
|
||||
last_progress_at: datetime | None = None
|
||||
display_number: int = 0
|
||||
display_id: str = ""
|
||||
created_at_label: str = ""
|
||||
scale_label: str = ""
|
||||
error_summary: str | None = None
|
||||
running_seconds: int = 0
|
||||
seconds_since_last_progress: int | None = None
|
||||
running_duration_label: str = "刚刚"
|
||||
|
||||
@@ -34,6 +34,10 @@ STAGE_LABELS = {
|
||||
"success": "已完成",
|
||||
"failed": "失败",
|
||||
}
|
||||
PLATFORM_LABELS = {
|
||||
"xiaohongshu": "小红书",
|
||||
"douyin": "抖音",
|
||||
}
|
||||
|
||||
|
||||
def has_running_task(session: Session) -> bool:
|
||||
@@ -150,6 +154,15 @@ def get_task(session: Session, task_id: str) -> Task | None:
|
||||
|
||||
|
||||
def hydrate_task_progress(session: Session, task: Task) -> Task:
|
||||
display_number = calculate_task_display_number(session, task)
|
||||
task.display_number = display_number
|
||||
task.display_id = f"#{display_number}"
|
||||
task.created_at_label = format_datetime_minute(task.created_at)
|
||||
task.scale_label = (
|
||||
f"{PLATFORM_LABELS.get(task.platform, task.platform)} · "
|
||||
f"{task.hotspot_limit}热点 × {task.item_limit_per_hotspot}内容 × {task.comment_limit_per_item}评论"
|
||||
)
|
||||
task.error_summary = build_task_error_summary(task)
|
||||
task.hotspots_count = session.scalar(select(func.count(Hotspot.id)).where(Hotspot.task_id == task.id)) or 0
|
||||
task.comments_count = session.scalar(select(func.count(Comment.id)).where(Comment.task_id == task.id)) or 0
|
||||
task.reports_count = session.scalar(select(func.count(Report.id)).where(Report.task_id == task.id)) or 0
|
||||
@@ -182,6 +195,29 @@ def hydrate_task_progress(session: Session, task: Task) -> Task:
|
||||
return task
|
||||
|
||||
|
||||
def calculate_task_display_number(session: Session, task: Task) -> int:
|
||||
task_ids = list(session.scalars(select(Task.id).order_by(Task.created_at, Task.id)))
|
||||
try:
|
||||
return task_ids.index(task.id) + 1
|
||||
except ValueError:
|
||||
return len(task_ids) + 1
|
||||
|
||||
|
||||
def format_datetime_minute(value: datetime | None) -> str:
|
||||
value = ensure_utc_datetime(value)
|
||||
return value.strftime("%Y-%m-%d %H:%M") if value else ""
|
||||
|
||||
|
||||
def build_task_error_summary(task: Task) -> str | None:
|
||||
if task.error_message:
|
||||
return task.error_message
|
||||
if task.error_stage == "system" and task.error_type == "unexpected_restart":
|
||||
return RESTART_ERROR_MESSAGE
|
||||
if task.error_stage or task.error_type:
|
||||
return "任务失败,请查看后端日志"
|
||||
return None
|
||||
|
||||
|
||||
def format_duration_zh(total_seconds: int | None) -> str:
|
||||
if total_seconds is None:
|
||||
return "暂无记录"
|
||||
|
||||
@@ -28,8 +28,5 @@
|
||||
{% endblock %}
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
<footer class="border-top py-3">
|
||||
<div class="container text-muted small">内部演示工具 | 仅供学习参考</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{% block breadcrumbs %}
|
||||
<nav aria-label="breadcrumb"><ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/">首页</a></li>
|
||||
<li class="breadcrumb-item"><a href="/tasks/{{ task.id }}">任务 #{{ task.id }}</a></li>
|
||||
<li class="breadcrumb-item"><a href="/tasks/{{ task.id }}">任务 {{ task.display_id }}</a></li>
|
||||
<li class="breadcrumb-item active">汇总报告</li>
|
||||
</ol></nav>
|
||||
{% endblock %}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{% block breadcrumbs %}
|
||||
<nav aria-label="breadcrumb"><ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="/">首页</a></li>
|
||||
<li class="breadcrumb-item"><a href="/tasks/{{ task.id }}">任务 #{{ task.id }}</a></li>
|
||||
<li class="breadcrumb-item"><a href="/tasks/{{ task.id }}">任务 {{ task.display_id }}</a></li>
|
||||
<li class="breadcrumb-item"><a href="/hotspots/{{ hotspot.id }}/report">热点 #{{ hotspot.rank }}:{{ hotspot.title }}</a></li>
|
||||
<li class="breadcrumb-item active">{{ item.title or item.source_item_id }}</li>
|
||||
</ol></nav>
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
{% set ai_percent = rate_percent(task.analysis_success_rate) %}
|
||||
<tr>
|
||||
<td>
|
||||
<code>{{ task.id }}</code>
|
||||
<strong>{{ task.display_id or ("#" ~ loop.index) }}</strong>
|
||||
{% if task.is_demo %}
|
||||
<br><span class="badge text-bg-info">Demo 数据</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ task.platform | platform_label }}</td>
|
||||
<td>{{ task.created_at }}</td>
|
||||
<td><small class="text-muted">热点 {{ task.hotspot_limit }} / 内容 {{ task.item_limit_per_hotspot }} / 评论 {{ task.comment_limit_per_item }}</small></td>
|
||||
<td>{{ task.created_at_label }}</td>
|
||||
<td><small class="text-muted">{{ task.scale_label }}</small></td>
|
||||
<td class="task-progress-cell">
|
||||
<div class="d-flex justify-content-between align-items-center gap-2">
|
||||
<span class="small">已处理 {{ task.processed_items_count }} / 共 {{ task.total_items_count }} 条内容</span>
|
||||
@@ -32,11 +32,8 @@
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge {{ status_class }}">{{ status_label }}</span>
|
||||
{% if task.error_stage or task.error_type %}
|
||||
<br><small class="text-muted">{{ task.error_stage }} / {{ task.error_type }}</small>
|
||||
{% endif %}
|
||||
{% if task.error_message %}
|
||||
<br><small class="text-danger">{{ task.error_message }}</small>
|
||||
{% if task.error_summary %}
|
||||
<br><small class="text-danger">{{ task.error_summary }}</small>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td><a class="btn btn-sm btn-outline-primary" href="/tasks/{{ task.id }}">查看</a></td>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}任务 #{{ task.id }} - 热榜评论分析工具{% endblock %}
|
||||
{% 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.id }}</li>
|
||||
<li class="breadcrumb-item active">任务 {{ task.display_id }}</li>
|
||||
</ol></nav>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h1 class="h3 mb-0">任务 #{{ task.id }}</h1>
|
||||
<h1 class="h3 mb-0">任务 {{ task.display_id }}</h1>
|
||||
<button class="btn btn-outline-secondary btn-sm" onclick="window.location.reload()">手动刷新</button>
|
||||
</div>
|
||||
<section class="card mb-4" {% if task.status == "running" %}data-task-id="{{ task.id }}" data-auto-poll="true"{% endif %}><div class="card-body">
|
||||
@@ -20,6 +20,7 @@
|
||||
<p class="mb-0">平台:{{ task.platform | platform_label }} <span class="badge {{ cls }}">{{ label }}</span>{% if task.is_demo %}<span class="badge text-bg-info ms-1">Demo 数据</span>{% endif %}</p>
|
||||
<p class="mb-0 text-muted">阶段:{{ task.current_stage_label or "等待启动" }}</p>
|
||||
</div>
|
||||
<div class="small text-muted mb-3">创建时间 {{ task.created_at_label }} · 完整 ID {{ task.id }}</div>
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between align-items-center gap-2">
|
||||
<span>已处理 {{ task.processed_items_count }} / 共 {{ task.total_items_count }} 条内容</span>
|
||||
@@ -72,7 +73,7 @@
|
||||
<span class="badge text-bg-warning ms-1">AI 样本不足</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if task.error_message %}<div class="alert alert-danger">{{ task.error_stage }} / {{ task.error_type }}:{{ task.error_message }}</div>{% endif %}
|
||||
{% if task.error_summary %}<div class="alert alert-danger">{{ task.error_summary }}</div>{% endif %}
|
||||
</div></section>
|
||||
{% if task.status == "running" and not hotspots %}
|
||||
<div class="text-center text-muted py-5"><div class="spinner-border text-warning mb-3"></div><p>正在抓取热点数据,请稍候...</p></div>
|
||||
|
||||
Reference in New Issue
Block a user