feat(product-suite): add prompt template settings
This commit is contained in:
@@ -40,9 +40,18 @@ from PySide6.QtWidgets import (
|
||||
QWidget,
|
||||
)
|
||||
|
||||
from ... import accounts, appconfig, diagnostics, image_studio, image_studio_images, product_suite
|
||||
from ... import (
|
||||
accounts,
|
||||
appconfig,
|
||||
diagnostics,
|
||||
image_studio,
|
||||
image_studio_images,
|
||||
product_suite,
|
||||
prompts,
|
||||
)
|
||||
from .. import file_manager
|
||||
from ..image_preview import ImagePreviewDialog
|
||||
from ..product_suite_prompt_dialog import ProductSuitePromptDialog
|
||||
from ..widgets import _emit_status, run_worker
|
||||
from ..workers import (
|
||||
ImageStudioDownloadOriginalWorker,
|
||||
@@ -57,13 +66,6 @@ ORIGINAL_DOWNLOAD_CONCURRENCY = 2
|
||||
ORIGINAL_CHECK_STATE_ROLE = Qt.UserRole + 1
|
||||
_PRODUCT_SUITE_THREAD_REFS = {}
|
||||
_URL_RE = re.compile(r"https?://[^\s,,;;))\]]+", re.IGNORECASE)
|
||||
FIXED_CATEGORY_HELPERS = {
|
||||
"白底图": "白底主图,多角度呈现商品细节",
|
||||
"场景图": "生活化场景展示商品使用方式",
|
||||
"卖点图": "突出核心卖点和差异化优势",
|
||||
}
|
||||
|
||||
|
||||
def _asset_usable(asset):
|
||||
path = str(getattr(asset, "local_path", "") or "")
|
||||
return (
|
||||
@@ -663,6 +665,7 @@ class ProductSuiteTab(QWidget):
|
||||
self.db_path = db_path or appconfig.db_path(self.config)
|
||||
self.config_path = config_path or self.config.get("config_path") or appconfig.CONFIG_PATH
|
||||
self.cmhub_config_path = self.config.get("cmhub_config_path") or appconfig.cmhub_config_file_path(self.config)
|
||||
self.product_suite_prompt_path = appconfig.product_suite_prompt_path(self.config)
|
||||
self.status_callback = status_callback
|
||||
self.accounts = []
|
||||
self._states = {}
|
||||
@@ -673,6 +676,12 @@ class ProductSuiteTab(QWidget):
|
||||
self._original_list_context = None
|
||||
self._loading = False
|
||||
self._result_refresh_pending = False
|
||||
self._prompt_template_init_error = ""
|
||||
|
||||
try:
|
||||
prompts.ensure_default_product_suite_prompt(self.product_suite_prompt_path)
|
||||
except prompts.PromptError as exc:
|
||||
self._prompt_template_init_error = str(exc)
|
||||
|
||||
self._build_ui()
|
||||
self._connect_signals()
|
||||
@@ -684,6 +693,8 @@ class ProductSuiteTab(QWidget):
|
||||
self.elapsed_timer.setInterval(1000)
|
||||
self.elapsed_timer.timeout.connect(self._refresh_elapsed)
|
||||
self.elapsed_timer.start()
|
||||
if self._prompt_template_init_error:
|
||||
self._status(self._prompt_template_init_error, "danger")
|
||||
|
||||
def _build_ui(self):
|
||||
root = QVBoxLayout(self)
|
||||
@@ -956,17 +967,23 @@ class ProductSuiteTab(QWidget):
|
||||
layout = QVBoxLayout(frame)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
title_row = QHBoxLayout()
|
||||
self.prompt_title_layout = title_row
|
||||
title = QLabel("商品卖点与要求")
|
||||
self.prompt_title_label = title
|
||||
title.setStyleSheet("font-weight: 600;")
|
||||
title_row.addWidget(title)
|
||||
title_row.addStretch(1)
|
||||
self.ai_write_button = QPushButton("AI 帮写")
|
||||
self.ai_write_button.setObjectName("suiteAiWriteButton")
|
||||
title_row.addWidget(self.ai_write_button)
|
||||
self.ai_cancel_button = QPushButton("取消")
|
||||
self.ai_cancel_button.setObjectName("suiteAiCancelButton")
|
||||
self.ai_cancel_button.hide()
|
||||
title_row.addWidget(self.ai_cancel_button)
|
||||
self.ai_write_button = QPushButton("AI 帮写")
|
||||
self.ai_write_button.setObjectName("suiteAiWriteButton")
|
||||
title_row.addWidget(self.ai_write_button)
|
||||
title_row.addStretch(1)
|
||||
self.prompt_settings_button = QPushButton("提示词设置")
|
||||
self.prompt_settings_button.setObjectName("suitePromptSettingsButton")
|
||||
self.prompt_settings_button.setToolTip("编辑并预览套图最终提示词")
|
||||
title_row.addWidget(self.prompt_settings_button)
|
||||
layout.addLayout(title_row)
|
||||
self.prompt_edit = QPlainTextEdit()
|
||||
self.prompt_edit.setObjectName("suitePromptEdit")
|
||||
@@ -1098,6 +1115,7 @@ class ProductSuiteTab(QWidget):
|
||||
self.prompt_edit.textChanged.connect(self._on_prompt_changed)
|
||||
self.ai_write_button.clicked.connect(self.start_ai_write)
|
||||
self.ai_cancel_button.clicked.connect(self.cancel_ai_write)
|
||||
self.prompt_settings_button.clicked.connect(self.open_prompt_settings)
|
||||
self.add_category_button.clicked.connect(self.add_custom_category)
|
||||
self.custom_category_edit.returnPressed.connect(self._commit_custom_category)
|
||||
self.custom_category_edit.editingFinished.connect(self._finish_custom_category_edit)
|
||||
@@ -1638,6 +1656,27 @@ class ProductSuiteTab(QWidget):
|
||||
state = self._displayed_state
|
||||
state.prompt = self.prompt_edit.toPlainText()
|
||||
|
||||
def open_prompt_settings(self, checked=False):
|
||||
state = self._displayed_state
|
||||
if state is not None:
|
||||
self._save_controls_to_state(state)
|
||||
settings = state.settings
|
||||
base_prompt = state.prompt
|
||||
item_id = state.item_id or "未绑定商品"
|
||||
else:
|
||||
settings = product_suite.default_suite_settings()
|
||||
base_prompt = ""
|
||||
item_id = "未绑定商品"
|
||||
dialog = ProductSuitePromptDialog(
|
||||
prompt_path=self.product_suite_prompt_path,
|
||||
base_prompt=base_prompt,
|
||||
settings=settings,
|
||||
item_id=item_id,
|
||||
parent=self,
|
||||
)
|
||||
self.prompt_settings_dialog = dialog
|
||||
dialog.exec()
|
||||
|
||||
def _update_context_actions(self, state):
|
||||
is_draft = self._is_draft_state(state)
|
||||
self.pull_button.setEnabled(
|
||||
@@ -2093,7 +2132,7 @@ class ProductSuiteTab(QWidget):
|
||||
row = SuiteCategoryRow(
|
||||
name,
|
||||
categories.get(name, 0),
|
||||
helper=FIXED_CATEGORY_HELPERS.get(name, ""),
|
||||
helper=product_suite.category_helper(name),
|
||||
custom=custom,
|
||||
)
|
||||
row.countChangeRequested.connect(self.change_category_count)
|
||||
@@ -2327,6 +2366,18 @@ class ProductSuiteTab(QWidget):
|
||||
return False
|
||||
if state is self._displayed_state:
|
||||
self._save_controls_to_state(state)
|
||||
template_text = None
|
||||
if specs is None:
|
||||
try:
|
||||
template_text = prompts.load_product_suite_prompt(
|
||||
self.product_suite_prompt_path
|
||||
)
|
||||
except prompts.PromptError:
|
||||
self._message(
|
||||
"套图提示词模板无效",
|
||||
"套图提示词模板无效,请在提示词设置中修复或恢复默认。",
|
||||
)
|
||||
return False
|
||||
if self._ensure_project_for_local_work(state) is None:
|
||||
return False
|
||||
local_assets = [asset for asset in self._original_assets(state) if _asset_usable(asset)]
|
||||
@@ -2341,6 +2392,7 @@ class ProductSuiteTab(QWidget):
|
||||
state.prompt,
|
||||
state.settings,
|
||||
state.item_id or "未绑定商品",
|
||||
template_text=template_text,
|
||||
))
|
||||
if not specs:
|
||||
self._message("生成数量为0", "请至少把一个套图分类的数量设为1。")
|
||||
|
||||
Reference in New Issue
Block a user