feat: 增强任务进度透明化

This commit is contained in:
meijiali
2026-07-03 18:14:58 +08:00
parent 61bcb2ef86
commit 9244f360be
5 changed files with 191 additions and 3 deletions
+103
View File
@@ -1,3 +1,5 @@
from datetime import UTC, datetime, timedelta
from app.models import Comment, ContentItem, Hotspot, Report, Task
from tests.helpers import make_test_client
from sqlalchemy.exc import OperationalError
@@ -150,6 +152,74 @@ def test_running_task_detail_page_keeps_polling_after_hotspots_exist():
assert "pollTaskDetailStatus" in response.text
def test_running_task_detail_page_shows_stage_runtime_and_stale_progress_warning(monkeypatch):
now = datetime(2026, 7, 3, 10, 30, tzinfo=UTC)
monkeypatch.setattr("app.services.task_service.utc_now", lambda: now)
with make_test_client() as (client, engine):
from sqlalchemy.orm import Session
with Session(engine) as session:
task = Task(
id="task-stale",
platform="xiaohongshu",
status="running",
current_stage="ai_analysis",
created_at=now - timedelta(hours=2, minutes=5),
last_progress_at=now - timedelta(minutes=12),
hotspot_limit=5,
item_limit_per_hotspot=5,
comment_limit_per_item=50,
total_items_count=10,
processed_items_count=6,
successful_items_count=6,
failed_items_count=0,
analysis_success_rate=0.6,
analysis_status="insufficient",
)
session.add(task)
hotspot = Hotspot(id="hot-stale", task_id=task.id, platform="xiaohongshu", title="运行热点", rank=1, raw_data="{}")
session.add(hotspot)
item = ContentItem(
id="item-stale",
task_id=task.id,
hotspot_id=hotspot.id,
platform="xiaohongshu",
source_item_id="note-stale",
item_type="note",
title="运行内容",
status="pending",
raw_data="{}",
)
session.add(item)
for index in range(3):
session.add(
Comment(
task_id=task.id,
hotspot_id=hotspot.id,
content_item_id=item.id,
platform="xiaohongshu",
source_comment_id=f"c{index}",
content=f"评论 {index}",
raw_data="{}",
)
)
session.commit()
response = client.get("/tasks/task-stale")
assert response.status_code == 200
assert "阶段:AI 分析中" in response.text
assert "运行时长" in response.text
assert "2小时5分钟" in response.text
assert "最近进度" in response.text
assert "12分钟前" in response.text
assert "已获取热点 1 / 目标 5" in response.text
assert "评论 3" in response.text
assert "超过 10 分钟没有进度更新" in response.text
assert "可能仍在等待外部接口或 AI 响应" in response.text
def test_failed_task_detail_page_shows_failure_reason_without_loading_copy():
with make_test_client() as (client, engine):
from sqlalchemy.orm import Session
@@ -511,3 +581,36 @@ def test_task_detail_page_explains_target_and_actual_counts():
assert "实际结果" in response.text
assert "实际评论 1" in response.text
assert "少于理论上限通常是内容本身评论不足或平台返回不足" in response.text
def test_task_api_includes_runtime_and_stale_progress_fields(monkeypatch):
now = datetime(2026, 7, 3, 10, 30, tzinfo=UTC)
monkeypatch.setattr("app.services.task_service.utc_now", lambda: now)
with make_test_client() as (client, engine):
from sqlalchemy.orm import Session
with Session(engine) as session:
session.add(
Task(
id="task-api-stale",
platform="douyin",
status="running",
current_stage="crawl_comments",
created_at=now - timedelta(minutes=45),
last_progress_at=now - timedelta(minutes=11),
)
)
session.commit()
response = client.get("/api/tasks/task-api-stale")
assert response.status_code == 200
data = response.json()
assert data["current_stage_label"] == "抓取评论中"
assert data["running_seconds"] == 2700
assert data["seconds_since_last_progress"] == 660
assert data["running_duration_label"] == "45分钟"
assert data["last_progress_ago_label"] == "11分钟前"
assert data["is_progress_stale"] is True
assert data["stale_threshold_minutes"] == 10