T-576 增加生成和更新内容模式
This commit is contained in:
+72
-38
@@ -751,6 +751,7 @@ def _cover_regenerate_config(config):
|
||||
runtime_config = dict(config or {})
|
||||
ai_settings = appconfig.ai_config(runtime_config)
|
||||
ai_settings["generate_cover"] = True
|
||||
ai_settings["generate_mode"] = "cover"
|
||||
runtime_config["ai"] = ai_settings
|
||||
return runtime_config
|
||||
|
||||
@@ -842,6 +843,11 @@ class GenerateTab(QWidget):
|
||||
"cover": "封面",
|
||||
"all": "标题和封面",
|
||||
}
|
||||
GENERATE_MODE_ITEMS = [
|
||||
("只生成标题", "title"),
|
||||
("只生成封面", "cover"),
|
||||
("生成标题和封面", "title_cover"),
|
||||
]
|
||||
TABLE_COLUMN_WEIGHTS = (1.0, 0.5, 1.8375, 1.8375, 0.4125, 0.4125)
|
||||
|
||||
def __init__(
|
||||
@@ -910,11 +916,12 @@ class GenerateTab(QWidget):
|
||||
self.reset_generate_button = QPushButton("重置生成结果")
|
||||
self.reset_generate_button.setObjectName("resetGenerateButton")
|
||||
self.stop_generate_button.setEnabled(False)
|
||||
ai_settings = appconfig.ai_config(self.config)
|
||||
self.generate_cover_checkbox = QCheckBox("生成封面图片(成本较高)")
|
||||
self.generate_cover_checkbox.setObjectName("generateCoverCheckbox")
|
||||
self.generate_cover_checkbox.setToolTip("关闭后只生成标题并保存为可更新,不调用图片模型")
|
||||
self.generate_cover_checkbox.setChecked(bool(ai_settings.get("generate_cover", False)))
|
||||
self.generate_mode_combo = QComboBox()
|
||||
self.generate_mode_combo.setObjectName("generateModeCombo")
|
||||
self.generate_mode_combo.setToolTip("选择本轮生成标题、封面,或同时生成标题和封面")
|
||||
for label, value in self.GENERATE_MODE_ITEMS:
|
||||
self.generate_mode_combo.addItem(label, value)
|
||||
self._set_combo_by_data(self.generate_mode_combo, appconfig.ai_generate_mode(self.config))
|
||||
self.progress_label = QLabel("进度:标题0/0 · 图片0/0 · 失败0")
|
||||
self.title_progress_label = QLabel("标题 0/0")
|
||||
self.title_progress_label.setObjectName("generateTitleProgressLabel")
|
||||
@@ -1007,7 +1014,7 @@ class GenerateTab(QWidget):
|
||||
self.empty_state_button.clicked.connect(self.open_accounts_callback)
|
||||
self.task_table = QTableView()
|
||||
self.model = GenerateTaskTableModel(self.task_table, db_path=self.db_path, status_callback=self._set_status)
|
||||
self.model.set_generate_cover_enabled(self.generate_cover_checkbox.isChecked())
|
||||
self.model.set_generate_cover_enabled(self._current_generate_mode_includes_cover())
|
||||
self.task_table.setModel(self.model)
|
||||
self.task_table.setSelectionBehavior(QAbstractItemView.SelectRows)
|
||||
self.task_table.setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||||
@@ -1060,7 +1067,8 @@ class GenerateTab(QWidget):
|
||||
button_layout.addWidget(self.reset_generate_button)
|
||||
|
||||
bottom_layout = QHBoxLayout()
|
||||
bottom_layout.addWidget(self.generate_cover_checkbox)
|
||||
bottom_layout.addWidget(QLabel("生成内容"))
|
||||
bottom_layout.addWidget(self.generate_mode_combo)
|
||||
bottom_layout.addLayout(progress_layout, 1)
|
||||
bottom_layout.addLayout(button_layout)
|
||||
|
||||
@@ -1084,7 +1092,7 @@ class GenerateTab(QWidget):
|
||||
self.delete_cover_template_action.triggered.connect(self.delete_cover_template)
|
||||
self.insert_title_button.clicked.connect(self.insert_title_placeholder)
|
||||
self.preview_prompt_button.clicked.connect(self.preview_cover_prompt)
|
||||
self.generate_cover_checkbox.toggled.connect(self._on_generate_cover_toggled)
|
||||
self.generate_mode_combo.currentIndexChanged.connect(self._on_generate_mode_changed)
|
||||
self.generate_button.clicked.connect(self.start_generate)
|
||||
self.stop_generate_button.clicked.connect(self.stop_generate)
|
||||
self.reset_generate_button.clicked.connect(self.reset_generated_result)
|
||||
@@ -1115,11 +1123,11 @@ class GenerateTab(QWidget):
|
||||
def _show_current_run_log_empty(self):
|
||||
self.run_log_view.setPlainText("本轮日志会在开始运行后显示")
|
||||
|
||||
def _reset_generate_run_log(self, tasks, generate_cover):
|
||||
def _reset_generate_run_log(self, tasks, generate_mode):
|
||||
self.run_log_view.clear()
|
||||
cover_text = "是" if generate_cover else "否"
|
||||
mode_text = self._generate_mode_label(generate_mode)
|
||||
self._append_generate_log(
|
||||
f"本轮AI生成开始:任务 {len(tasks)} 条,生成封面:{cover_text}"
|
||||
f"本轮AI生成开始:任务 {len(tasks)} 条,生成内容:{mode_text}"
|
||||
)
|
||||
|
||||
def _reset_generation_elapsed(self):
|
||||
@@ -1208,16 +1216,17 @@ class GenerateTab(QWidget):
|
||||
self._refresh_elapsed_labels()
|
||||
self._update_elapsed_timer_state()
|
||||
|
||||
def _on_generate_cover_toggled(self, checked):
|
||||
previous = bool(appconfig.ai_config(self.config).get("generate_cover", False))
|
||||
if self._save_generate_cover_setting(show_status=True):
|
||||
self.model.set_generate_cover_enabled(bool(checked))
|
||||
def _on_generate_mode_changed(self, index=None):
|
||||
previous = appconfig.ai_generate_mode(self.config)
|
||||
current = self._current_generate_mode()
|
||||
if self._save_generate_mode_setting(show_status=True):
|
||||
self.model.set_generate_cover_enabled(appconfig.generate_mode_includes_cover(current))
|
||||
self.refresh_tasks()
|
||||
return
|
||||
self.generate_cover_checkbox.blockSignals(True)
|
||||
self.generate_cover_checkbox.setChecked(previous)
|
||||
self.generate_cover_checkbox.blockSignals(False)
|
||||
self.model.set_generate_cover_enabled(previous)
|
||||
self.generate_mode_combo.blockSignals(True)
|
||||
self._set_combo_by_data(self.generate_mode_combo, previous)
|
||||
self.generate_mode_combo.blockSignals(False)
|
||||
self.model.set_generate_cover_enabled(appconfig.generate_mode_includes_cover(previous))
|
||||
|
||||
def _apply_task_table_column_widths(self):
|
||||
if self.model.columnCount() != len(self.TABLE_COLUMN_WEIGHTS):
|
||||
@@ -1237,9 +1246,11 @@ class GenerateTab(QWidget):
|
||||
used += section_width
|
||||
header.resizeSection(column, section_width)
|
||||
|
||||
def _save_generate_cover_setting(self, show_status=True):
|
||||
generate_cover = bool(self.generate_cover_checkbox.isChecked())
|
||||
def _save_generate_mode_setting(self, show_status=True):
|
||||
generate_mode = self._current_generate_mode()
|
||||
generate_cover = appconfig.generate_mode_includes_cover(generate_mode)
|
||||
ai_settings = appconfig.ai_config(self.config)
|
||||
ai_settings["generate_mode"] = generate_mode
|
||||
ai_settings["generate_cover"] = generate_cover
|
||||
payload = {
|
||||
key: value
|
||||
@@ -1250,7 +1261,7 @@ class GenerateTab(QWidget):
|
||||
try:
|
||||
saved = appconfig.save_config(payload, path=self.config_path)
|
||||
except Exception as exc:
|
||||
self._set_status(f"生成封面开关保存失败:{exc}")
|
||||
self._set_status(f"生成内容设置保存失败:{exc}")
|
||||
return False
|
||||
internal = {
|
||||
key: value
|
||||
@@ -1263,10 +1274,30 @@ class GenerateTab(QWidget):
|
||||
if self.config_path != appconfig.CONFIG_PATH:
|
||||
self.config["config_path"] = self.config_path
|
||||
if show_status:
|
||||
mode = "会同时生成封面图片" if generate_cover else "只生成标题,不生成图片"
|
||||
self._set_status(f"AI生成设置已保存:{mode}")
|
||||
self._set_status(f"AI生成设置已保存:{self._generate_mode_label(generate_mode)}")
|
||||
return True
|
||||
|
||||
def _current_generate_mode(self):
|
||||
return appconfig.normalize_generate_mode(
|
||||
self.generate_mode_combo.currentData(),
|
||||
generate_cover=False,
|
||||
)
|
||||
|
||||
def _current_generate_mode_includes_cover(self):
|
||||
return appconfig.generate_mode_includes_cover(self._current_generate_mode())
|
||||
|
||||
def _generate_mode_label(self, mode):
|
||||
mode = appconfig.normalize_generate_mode(mode)
|
||||
return {
|
||||
"title": "只生成标题",
|
||||
"cover": "只生成封面",
|
||||
"title_cover": "生成标题和封面",
|
||||
}.get(mode, "只生成标题")
|
||||
|
||||
def _set_combo_by_data(self, combo, value):
|
||||
index = combo.findData(value)
|
||||
combo.setCurrentIndex(index if index >= 0 else 0)
|
||||
|
||||
def _load_latest_generate_run_log(self):
|
||||
try:
|
||||
logs = db.list_run_logs(limit=1, run_type="generate", path=self.db_path)
|
||||
@@ -1433,21 +1464,23 @@ class GenerateTab(QWidget):
|
||||
if self.generate_thread is not None:
|
||||
self._set_status("AI 生成正在进行...")
|
||||
return
|
||||
if not self._save_generate_cover_setting(show_status=False):
|
||||
if not self._save_generate_mode_setting(show_status=False):
|
||||
return
|
||||
generate_cover = bool(self.generate_cover_checkbox.isChecked())
|
||||
generate_mode = self._current_generate_mode()
|
||||
generate_cover = appconfig.generate_mode_includes_cover(generate_mode)
|
||||
tasks = [
|
||||
task for task in self.model.tasks
|
||||
if ai.is_generatable_task(task, generate_cover=generate_cover)
|
||||
if ai.is_generatable_task(task, generate_mode=generate_mode)
|
||||
]
|
||||
if not tasks:
|
||||
self._set_status(
|
||||
"当前筛选结果没有可生成的缺失内容;请先在①导入采集完成采集,或勾选“生成封面图片(成本较高)”补封面"
|
||||
)
|
||||
if generate_mode == "cover":
|
||||
self._set_status("当前筛选结果没有可生成封面的任务,请先生成标题。")
|
||||
else:
|
||||
self._set_status("当前筛选结果没有可生成的缺失内容;请先在①导入采集完成采集,或调整生成内容")
|
||||
return
|
||||
component_totals = ai.generation_component_totals(
|
||||
tasks,
|
||||
generate_cover=generate_cover,
|
||||
generate_mode=generate_mode,
|
||||
)
|
||||
prompt_values = {
|
||||
"title": self.title_prompt_edit.toPlainText(),
|
||||
@@ -1466,11 +1499,11 @@ class GenerateTab(QWidget):
|
||||
worker.failed.connect(self._on_generate_failed)
|
||||
worker.finished.connect(self._on_generate_finished)
|
||||
worker.cancelled.connect(self._on_generate_cancelled)
|
||||
self._reset_generate_run_log(tasks, generate_cover)
|
||||
self._reset_generate_run_log(tasks, generate_mode)
|
||||
self._reset_cmhub_balance_label()
|
||||
self._start_generation_elapsed(
|
||||
component_totals["title_total"],
|
||||
component_totals["cover_total"] if generate_cover else 0,
|
||||
component_totals["cover_total"],
|
||||
)
|
||||
thread = run_worker(worker, thread_name="GenerateWorker", start=False)
|
||||
thread.finished.connect(lambda: self._forget_generate_thread(thread))
|
||||
@@ -1483,10 +1516,11 @@ class GenerateTab(QWidget):
|
||||
"title_total": component_totals["title_total"],
|
||||
"title_done": 0,
|
||||
"cover_done": 0,
|
||||
"cover_total": component_totals["cover_total"] if generate_cover else 0,
|
||||
"cover_total": component_totals["cover_total"],
|
||||
"generated_done": 0,
|
||||
"failed": 0,
|
||||
"generate_cover": generate_cover,
|
||||
"generate_mode": generate_mode,
|
||||
}
|
||||
)
|
||||
self._set_status(f"开始 AI 生成:{len(tasks)} 条")
|
||||
@@ -1739,7 +1773,7 @@ class GenerateTab(QWidget):
|
||||
self.save_cover_template_as_action.setEnabled(not running)
|
||||
self.rename_cover_template_action.setEnabled(not running)
|
||||
self.delete_cover_template_action.setEnabled(not running)
|
||||
self.generate_cover_checkbox.setEnabled(not running)
|
||||
self.generate_mode_combo.setEnabled(not running)
|
||||
self._sync_cover_gallery_regenerate_guard()
|
||||
|
||||
def _set_cover_gallery_regenerate_running(self, running):
|
||||
@@ -1984,7 +2018,7 @@ class GenerateTab(QWidget):
|
||||
_set_empty_state(self.empty_state_card, self.empty_state_label, self.empty_state_button)
|
||||
self._set_status(f"AI 生成任务读取失败:{exc}")
|
||||
return
|
||||
self.model.set_generate_cover_enabled(self.generate_cover_checkbox.isChecked())
|
||||
self.model.set_generate_cover_enabled(self._current_generate_mode_includes_cover())
|
||||
self.model.set_tasks(filtered_tasks, accounts_rows)
|
||||
self._apply_task_table_column_widths()
|
||||
self.summary_label.setText(
|
||||
@@ -2082,8 +2116,8 @@ class GenerateTab(QWidget):
|
||||
if selected_status in (None, "all"):
|
||||
return True
|
||||
if selected_status == "to_generate":
|
||||
generate_cover = bool(self.generate_cover_checkbox.isChecked())
|
||||
return ai.is_generatable_task(task, generate_cover=generate_cover) and task.status != "failed"
|
||||
generate_mode = self._current_generate_mode()
|
||||
return ai.is_generatable_task(task, generate_mode=generate_mode) and task.status != "failed"
|
||||
if selected_status == "generated":
|
||||
return task.stage == "generated"
|
||||
if selected_status == "applied":
|
||||
|
||||
Reference in New Issue
Block a user