feat(ai-studio): streamline project workspace

This commit is contained in:
chengma
2026-07-11 16:23:22 +08:00
parent f28d197c58
commit 82e7e1bf14
3 changed files with 219 additions and 68 deletions
+94 -8
View File
@@ -494,7 +494,7 @@ class GuiTests(TempDirMixin, unittest.TestCase):
with self.make_temp_dir() as temp_dir:
cfg = self.make_config(temp_dir)
prompts_dir = os.path.join(temp_dir, "prompts", "image_studio")
accounts.create_account("主店", "alias-a", debug_port=9222, config=cfg)
account = accounts.create_account("主店", "alias-a", debug_port=9222, config=cfg)
prompts.save_image_studio_template("工场模板", "完整提示词", prompts_dir)
tab = ImageStudioTab(
@@ -512,19 +512,25 @@ class GuiTests(TempDirMixin, unittest.TestCase):
"导入本地图片",
" ".join(button.text() for button in tab.findChildren(gui.QPushButton)),
)
self.assertEqual("打开商品项目", tab.open_project_button.text())
self.assertNotIn(
"打开商品项目",
" ".join(button.text() for button in tab.findChildren(gui.QPushButton)),
)
self.assertEqual("拉取蝦皮主图", tab.pull_images_button.text())
self.assertEqual("删除项目", tab.delete_project_button.text())
self.assertEqual("导出到文件夹", tab.export_button.text())
self.assertIn("可部分导出", tab.export_hint_label.text())
self.assertIn("文件名按终选顺序连续", tab.export_hint_label.text())
self.assertEqual("未打开商品项目", tab.current_project_label.text())
self.assertIn("打开商品项目", tab.workspace_empty_label.text())
self.assertEqual("未选择商品", tab.current_project_label.text())
self.assertIn("拉取蝦皮主图", tab.workspace_empty_label.text())
self.assertFalse(tab.open_folder_button.isEnabled())
self.assertFalse(tab.delete_project_button.isEnabled())
self.assertEqual("生成 4 张主图", tab.start_button.text())
tab.count_spin.setValue(3)
tab.job_type_combo.setCurrentIndex(tab.job_type_combo.findData("detail"))
self.assertEqual("生成 3 张详情图", tab.start_button.text())
label_texts = "\n".join(label.text() for label in tab.findChildren(gui.QLabel))
self.assertIn("商品项目", label_texts)
self.assertIn("商品列表", label_texts)
self.assertIn("蝦皮原主图", label_texts)
self.assertIn("照片池", label_texts)
self.assertIn("生成设置", label_texts)
@@ -536,15 +542,26 @@ class GuiTests(TempDirMixin, unittest.TestCase):
tab.load_selected_template()
self.assertEqual("完整提示词", tab.prompt_edit.toPlainText())
tab.item_id_edit.setText("51100639510")
tab.open_project()
project = image_studio.create_or_get_project(
account,
item_id="51100639510",
path=cfg["db_path"],
)
tab.refresh_projects()
self.assertIsNotNone(tab.current_project)
self.assertEqual("alias-a", tab.current_project.account_alias)
self.assertEqual("51100639510", tab.current_project.item_id)
self.assertIn("alias-a", tab.current_project_label.text())
self.assertEqual(project.id, tab.current_project.id)
self.assertIn("主店", tab.current_project_label.text())
self.assertIn("51100639510", tab.current_project_label.text())
self.assertEqual("项目已自动保存", tab.autosave_label.text())
self.assertEqual(1, tab.project_table.rowCount())
self.assertEqual(["店铺", "商品ID", "更新时间"], [
tab.project_table.horizontalHeaderItem(column).text()
for column in range(tab.project_table.columnCount())
])
self.assertTrue(tab.open_folder_button.isEnabled())
self.assertTrue(tab.delete_project_button.isEnabled())
original = image_studio.sync_original_asset_urls(
tab.current_project.id,
@@ -565,6 +582,75 @@ class GuiTests(TempDirMixin, unittest.TestCase):
self.assert_removed(temp_dir)
def test_image_studio_deletes_selected_project_only_after_safe_confirmation(self):
with self.make_temp_dir() as temp_dir:
cfg = self.make_config(temp_dir)
db.init_db(cfg["db_path"])
first = image_studio.create_or_get_project(
account_alias="alias-a",
account_name="主店",
account_slug="alias_a",
item_id="51100639510",
path=cfg["db_path"],
)
second = image_studio.create_or_get_project(
account_alias="alias-a",
account_name="主店",
account_slug="alias_a",
item_id="51100639511",
path=cfg["db_path"],
)
tab = ImageStudioTab(config=cfg, db_path=cfg["db_path"])
self.addCleanup(tab.close)
tab._select_project(first.id)
confirmations = []
tab._confirm = lambda title, text: confirmations.append((title, text)) or False
tab.delete_current_project()
self.assertIsNotNone(image_studio.get_project(first.id, path=cfg["db_path"]))
self.assertEqual(first.id, tab.current_project.id)
self.assertIn("不会删除蝦皮商品", confirmations[0][1])
self.assertIn("不会删除本地图片", confirmations[0][1])
tab._confirm = lambda title, text: True
tab.delete_current_project()
self.assertIsNone(image_studio.get_project(first.id, path=cfg["db_path"]))
deleted = image_studio.get_project(first.id, path=cfg["db_path"], include_deleted=True)
self.assertIsNotNone(deleted)
self.assertEqual("用户从AI工场商品列表删除", deleted.deleted_reason)
self.assertIsNotNone(tab.current_project)
self.assertEqual(second.id, tab.current_project.id)
self.assertEqual(1, tab.project_table.rowCount())
self.assert_removed(temp_dir)
def test_image_studio_blocks_deletion_with_active_remote_job(self):
with self.make_temp_dir() as temp_dir:
cfg = self.make_config(temp_dir)
db.init_db(cfg["db_path"])
project = image_studio.create_or_get_project(
account_alias="alias-a",
account_name="主店",
account_slug="alias_a",
item_id="51100639510",
path=cfg["db_path"],
)
image_studio.create_job(project.id, path=cfg["db_path"])
tab = ImageStudioTab(config=cfg, db_path=cfg["db_path"])
self.addCleanup(tab.close)
tab._select_project(project.id)
messages = []
tab._message = lambda title, text: messages.append((title, text))
tab._confirm = lambda title, text: self.fail("有未完成任务时不应出现删除确认")
tab.delete_current_project()
self.assertIsNotNone(image_studio.get_project(project.id, path=cfg["db_path"]))
self.assertEqual("暂不能删除项目", messages[0][0])
self.assertIn("未完成的图片任务", messages[0][1])
self.assert_removed(temp_dir)
def test_image_studio_final_selection_order_and_guards(self):
with self.make_temp_dir() as temp_dir:
cfg = self.make_config(temp_dir)