feat: add generate progress and readable logs

This commit is contained in:
chengma
2026-07-02 14:02:53 +08:00
parent 4c7d4fc624
commit f9c6dd3331
7 changed files with 337 additions and 34 deletions
+38 -4
View File
@@ -17,7 +17,7 @@ if gui.QT_IMPORT_ERROR is not None:
raise unittest.SkipTest("PySide6 未安装")
from PySide6.QtGui import QTextCursor
from PySide6.QtWidgets import QApplication, QLineEdit, QPlainTextEdit, QTableView
from PySide6.QtWidgets import QApplication, QLineEdit, QPlainTextEdit, QProgressBar, QTableView
from app.gui import (
AccountDialog,
@@ -696,6 +696,15 @@ class GuiTests(TempDirMixin, unittest.TestCase):
self.assertEqual("重置生成结果", tab.reset_generate_button.text())
self.assertFalse(tab.stop_generate_button.isEnabled())
self.assertEqual("进度:标题0/0 · 封面0/0 · 失败0", tab.progress_label.text())
self.assertIsInstance(tab.title_progress_bar, QProgressBar)
self.assertIsInstance(tab.cover_progress_bar, QProgressBar)
self.assertEqual("标题 0/0", tab.title_progress_label.text())
self.assertEqual("图片 0/0", tab.cover_progress_label.text())
self.assertEqual("失败 0", tab.failed_progress_label.text())
self.assertEqual(0, tab.title_progress_bar.value())
self.assertEqual(0, tab.cover_progress_bar.value())
self.assertEqual(1, tab.title_progress_bar.maximum())
self.assertEqual(1, tab.cover_progress_bar.maximum())
self.assertEqual("默认", tab.cover_template_combo.currentText())
self.assertEqual("模板操作", tab.cover_template_actions_button.text())
self.assertIs(tab.cover_template_actions_menu, tab.cover_template_actions_button.menu())
@@ -905,6 +914,7 @@ class GuiTests(TempDirMixin, unittest.TestCase):
tasks = db.list_tasks(batch_id=batch_id, path=cfg["db_path"])
progress = []
rows = []
logs = []
def fake_generate_batch(tasks_arg, prompt_values, ai_cfg=None, on_progress=None, should_stop=None):
self.assertEqual(tasks, tasks_arg)
@@ -919,10 +929,22 @@ class GuiTests(TempDirMixin, unittest.TestCase):
{
"task": tasks[0],
"phase": "cover",
"step": "cover_request",
"step": "cover_submit",
"result": "start",
}
)
ai_cfg["on_event"](
{
"task": tasks[0],
"phase": "cover",
"step": "cover_request",
"result": "retry",
"attempt": 1,
"attempts": 3,
"detail": "timeout token=SECRET-TOKEN",
"level": "warning",
}
)
ai_cfg["on_task_update"](tasks[0].id, {"stage": "generated"})
return {"ok": True, "total": 1, "title_done": 1, "cover_done": 1, "failed": 0}
@@ -934,6 +956,7 @@ class GuiTests(TempDirMixin, unittest.TestCase):
)
worker.progress.connect(progress.append)
worker.row_updated.connect(lambda task_id, fields: rows.append((task_id, fields)))
worker.log.connect(logs.append)
with mock.patch("app.gui.ai.generate_batch", side_effect=fake_generate_batch):
summary = worker.execute()
@@ -945,8 +968,17 @@ class GuiTests(TempDirMixin, unittest.TestCase):
self.assertEqual([(tasks[0].id, {"stage": "generated"})], rows)
run_log = db.list_run_logs(limit=1, run_type="generate", path=cfg["db_path"])[0]
self.assertEqual(summary["run_id"], run_log.id)
joined_logs = "\n".join(logs)
self.assertIn("[开始] 本轮生成 1 条", joined_logs)
self.assertIn("[图片] 1/1 商品 51100639510", joined_logs)
self.assertIn("准备重试 1/2", joined_logs)
self.assertIn("token=***", joined_logs)
self.assertNotIn("SECRET-TOKEN", joined_logs)
self.assertIn("[完成] AI 生成完成:标题1/1,图片1/1,失败0", joined_logs)
events = db.list_run_log_events(summary["run_id"], path=cfg["db_path"])
self.assertTrue(any("phase=cover step=cover_request result=start" in event.message for event in events))
event_messages = "\n".join(event.message for event in events)
self.assertIn("[图片] 1/1 商品 51100639510", event_messages)
self.assertIn("准备重试 1/2", event_messages)
self.assert_removed(temp_dir)
@@ -1010,7 +1042,8 @@ class GuiTests(TempDirMixin, unittest.TestCase):
events = db.list_run_log_events(summary["run_id"], path=cfg["db_path"])
messages = "\n".join(event.message for event in events)
self.assertIn("phase=cover step=cover_request result=failed", messages)
self.assertIn("[失败] 商品 51100639510", messages)
self.assertIn("图片生成失败", messages)
self.assertIn("token=***", messages)
self.assertNotIn("SECRET-TOKEN", messages)
@@ -1596,6 +1629,7 @@ class GuiTests(TempDirMixin, unittest.TestCase):
close_flags = []
progress = []
rows = []
logs = []
def fake_apply(account, task, close_success_tab=False, on_step=None):
applied_aliases.append(account.alias)