feat(ai-outfit): 话术按钮行微调 + 保留插入标题 + 最终提示词预览改弹窗 (§19.20)
话术组小改版(保留 {title} 占位符、不自动前置):
- 「保存话术」→「保存」,从编辑框下方上移到模板按钮行「重命名」之后
(行变 新建/另存为/重命名/保存/删除)
- 保留「插入标题」按钮 + {title} 占位符(用户自定标题位置,不与旧话术重复)
- 最终提示词预览改按需弹窗:编辑框下方「预览最终提示词」按钮 → 非模态
_OutfitPreviewDialog,含数据行下拉(read_all_rows,状态无关)+ 只读替换后
提示词(含 §7.1 输出要求);话术/分辨率/数据行变化时实时刷新
- 左栏空间理由:标题生成组 + 话术组并存,常驻预览会逼出滚动;弹窗零常驻高度
render_prompt 与 DEFAULT_OUTFIT_PROMPT 不改(纯面板改动)。
测试:面板断言按钮行含「保存」、保留「插入标题」+「预览最终提示词」、
预览弹窗按选中行替换 {title} 并附输出要求。全套 py37 通过
(test_config_service 的 ai_models.json 顺序失败属并行 §19.13,与本改动无关)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -97,6 +97,47 @@ class TestAiOutfitPanelDefaults(unittest.TestCase):
|
||||
|
||||
self.assertEqual(panel._title_prompt_edit.toPlainText(), DEFAULT_TITLE_PROMPT)
|
||||
|
||||
def test_prompt_buttons_save_row_insert_title_and_preview(self):
|
||||
"""§19.20: 按钮行含「保存」;编辑框下方保留「插入标题」+「预览最终提示词」。"""
|
||||
from PySide6.QtWidgets import QPushButton
|
||||
|
||||
panel = self._panel()
|
||||
panel.apply_config(dict(DEFAULT_CONFIG))
|
||||
|
||||
texts = [b.text() for b in panel.findChildren(QPushButton)]
|
||||
self.assertIn("保存", texts)
|
||||
self.assertIn("插入标题", texts)
|
||||
self.assertIn("预览最终提示词", texts)
|
||||
self.assertNotIn("保存话术", texts) # 旧按钮已改名上移
|
||||
|
||||
def test_preview_dialog_renders_selected_row(self):
|
||||
"""§7.3: 预览弹窗按选中数据行替换 {title} 并附加输出要求。"""
|
||||
from openpyxl import Workbook
|
||||
from app.widgets.ai_outfit_panel import _OutfitPreviewDialog
|
||||
|
||||
xlsx = self.tmp / "rows.xlsx"
|
||||
wb = Workbook(); ws = wb.active
|
||||
ws.append(["标题", "货号", "原始图片路径", "结果", "状态", "原因"])
|
||||
ws.append(["纯棉短袖", "TY001", r"D:\img\a.png", "", "", ""])
|
||||
wb.save(str(xlsx)); wb.close()
|
||||
|
||||
panel = self._panel()
|
||||
panel.apply_config(dict(DEFAULT_CONFIG))
|
||||
panel._excel_edit.setText(str(xlsx))
|
||||
panel._prompt_edit.setPlainText("为 {title} 生成")
|
||||
panel._set_combo(panel._resolution, "1K")
|
||||
|
||||
dialog = _OutfitPreviewDialog(panel) # __init__ fills rows + refresh
|
||||
# Row dropdown picked up the valid row; pick it.
|
||||
self.assertEqual(dialog._combo.count(), 1)
|
||||
dialog._combo.setCurrentIndex(0)
|
||||
|
||||
text = dialog._view.toPlainText()
|
||||
self.assertTrue(text.startswith("为 纯棉短袖 生成"))
|
||||
self.assertIn("批量生成输出要求", text)
|
||||
self.assertIn("参考解析度:1K", text)
|
||||
dialog.deleteLater()
|
||||
|
||||
def test_find_title_model_resolves_by_config_name(self):
|
||||
"""title_model 名字命中 ai_models.json → 返回 AiModelConfig。"""
|
||||
from services.ai_image_service import AiModelConfig
|
||||
|
||||
Reference in New Issue
Block a user