feat: 优化任务状态与进度体验

This commit is contained in:
meijiali
2026-07-03 14:32:46 +08:00
parent 6a2ced0a07
commit 82d103757b
7 changed files with 203 additions and 5 deletions
+108
View File
@@ -30,6 +30,12 @@ def test_index_page_lists_existing_tasks():
hotspot_limit=3,
item_limit_per_hotspot=4,
comment_limit_per_item=50,
total_items_count=4,
processed_items_count=2,
successful_items_count=1,
failed_items_count=1,
analysis_success_rate=0.75,
analysis_status="insufficient",
)
)
session.commit()
@@ -40,6 +46,40 @@ def test_index_page_lists_existing_tasks():
assert "task-visible" in response.text
assert "抖音" in response.text
assert "运行中" in response.text
assert "已处理 2 / 共 4 条内容" in response.text
assert "成功 1 / 失败 1" in response.text
assert 'style="width: 50%"' in response.text
assert "AI 成功率 75%" in response.text
assert "AI 样本不足" in response.text
assert 'data-task-list-auto-poll="true"' in response.text
assert "pollTaskListStatus" in response.text
assert "DOMContentLoaded" in response.text
def test_index_page_does_not_auto_poll_without_running_tasks():
with make_test_client() as (client, engine):
from sqlalchemy.orm import Session
with Session(engine) as session:
session.add(
Task(
id="task-done",
platform="xiaohongshu",
status="success",
total_items_count=1,
processed_items_count=1,
successful_items_count=1,
analysis_success_rate=1.0,
)
)
session.commit()
response = client.get("/")
assert response.status_code == 200
assert "task-done" in response.text
assert 'data-task-list-auto-poll="true"' not in response.text
assert "pollTaskListStatus" not in response.text
def test_running_task_detail_page_auto_polls_current_task():
@@ -55,6 +95,11 @@ def test_running_task_detail_page_auto_polls_current_task():
hotspot_limit=1,
item_limit_per_hotspot=1,
comment_limit_per_item=10,
total_items_count=2,
processed_items_count=1,
successful_items_count=1,
failed_items_count=0,
analysis_success_rate=1.0,
)
)
session.commit()
@@ -65,6 +110,69 @@ def test_running_task_detail_page_auto_polls_current_task():
assert 'data-task-id="task-running"' in response.text
assert "pollTaskDetailStatus" in response.text
assert 'onclick="window.location.reload()"' in response.text
assert "已处理 1 / 共 2 条内容" in response.text
assert "AI 成功率 100%" in response.text
def test_running_task_detail_page_keeps_polling_after_hotspots_exist():
with make_test_client() as (client, engine):
from sqlalchemy.orm import Session
with Session(engine) as session:
task = Task(
id="task-running-with-hotspot",
platform="xiaohongshu",
status="running",
total_items_count=2,
processed_items_count=1,
successful_items_count=1,
analysis_success_rate=1.0,
)
session.add(task)
session.add(
Hotspot(
id="hot-running",
task_id=task.id,
platform="xiaohongshu",
title="运行中的热点",
rank=1,
raw_data="{}",
)
)
session.commit()
response = client.get("/tasks/task-running-with-hotspot")
assert response.status_code == 200
assert "运行中的热点" in response.text
assert "正在抓取热点数据" not in response.text
assert "pollTaskDetailStatus" 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
with Session(engine) as session:
session.add(
Task(
id="task-failed",
platform="douyin",
status="failed",
error_stage="recover",
error_type="interrupted",
error_message="系统重启,任务被中断",
)
)
session.commit()
response = client.get("/tasks/task-failed")
assert response.status_code == 200
assert "失败" in response.text
assert "recover / interrupted:系统重启,任务被中断" in response.text
assert "正在抓取热点数据" not in response.text
assert "pollTaskDetailStatus" not in response.text
def seed_result_data(engine):
+13 -1
View File
@@ -1,4 +1,4 @@
from app.templating import from_json_filter, status_badge_config
from app.templating import from_json_filter, progress_percent, rate_percent, status_badge_config
def test_status_badge_config_centralizes_task_status_copy():
@@ -11,3 +11,15 @@ def test_status_badge_config_centralizes_task_status_copy():
def test_from_json_filter_returns_empty_list_for_invalid_json():
assert from_json_filter('["认可"]') == ["认可"]
assert from_json_filter("bad-json") == []
def test_progress_percent_clamps_invalid_and_overflow_values():
assert progress_percent(0, 0) == 0
assert progress_percent(1, 2) == 50
assert progress_percent(5, 2) == 100
def test_rate_percent_formats_ai_success_rate():
assert rate_percent(None) == 0
assert rate_percent(0.754) == 75
assert rate_percent(2.0) == 100