feat: skip incomplete apply tasks before update
This commit is contained in:
+81
-12
@@ -253,8 +253,10 @@ class ApplyTab(QWidget):
|
||||
return
|
||||
update_cfg = self._shopee_update_config()
|
||||
update_mode = self._current_update_mode()
|
||||
content_error = self._update_content_error(tasks, update_mode)
|
||||
if content_error:
|
||||
content_plan = self._partition_update_content_tasks(tasks, update_mode)
|
||||
executable_tasks = content_plan["executable"]
|
||||
if not executable_tasks:
|
||||
content_error = self._update_content_error(content_plan, update_mode)
|
||||
QMessageBox.warning(self, "更新内容未生成", content_error)
|
||||
self._set_status(content_error.replace("\n", " "))
|
||||
return
|
||||
@@ -262,7 +264,11 @@ class ApplyTab(QWidget):
|
||||
answer = QMessageBox.question(
|
||||
self,
|
||||
"确认检查本轮更新" if dry_run else "确认开始更新",
|
||||
self._confirmation_message(tasks, dry_run=dry_run),
|
||||
self._confirmation_message(
|
||||
executable_tasks,
|
||||
dry_run=dry_run,
|
||||
content_plan=content_plan,
|
||||
),
|
||||
QMessageBox.Yes | QMessageBox.No,
|
||||
QMessageBox.No,
|
||||
)
|
||||
@@ -271,7 +277,7 @@ class ApplyTab(QWidget):
|
||||
return
|
||||
batch_size = max(1, int(update_cfg.get("max_items_per_run", 1) or 1))
|
||||
worker = ApplyWorker(
|
||||
tasks,
|
||||
executable_tasks,
|
||||
db_path=self.db_path,
|
||||
config=self.config,
|
||||
dry_run=dry_run,
|
||||
@@ -294,11 +300,19 @@ class ApplyTab(QWidget):
|
||||
self.apply_worker = worker
|
||||
self.apply_thread = thread
|
||||
self._set_apply_running(True)
|
||||
self._reset_run_log(tasks, dry_run=dry_run, batch_size=batch_size)
|
||||
self._reset_run_log(
|
||||
executable_tasks,
|
||||
dry_run=dry_run,
|
||||
batch_size=batch_size,
|
||||
content_plan=content_plan,
|
||||
)
|
||||
skip_status = self._content_skip_status(content_plan)
|
||||
if dry_run:
|
||||
self._set_status(f"开始检查本轮更新:{len(tasks)} 条")
|
||||
self._set_status(f"开始检查本轮更新:{len(executable_tasks)} 条{skip_status}")
|
||||
else:
|
||||
self._set_status(f"开始更新:{len(tasks)} 条,按每批最多 {batch_size} 条执行")
|
||||
self._set_status(
|
||||
f"开始更新:{len(executable_tasks)} 条,按每批最多 {batch_size} 条执行{skip_status}"
|
||||
)
|
||||
thread.start()
|
||||
|
||||
def stop_update(self, checked=False):
|
||||
@@ -480,7 +494,7 @@ class ApplyTab(QWidget):
|
||||
return task.status == "skipped"
|
||||
return True
|
||||
|
||||
def _confirmation_message(self, tasks, dry_run=False):
|
||||
def _confirmation_message(self, tasks, dry_run=False, content_plan=None):
|
||||
update_cfg = self._shopee_update_config()
|
||||
update_mode = self._current_update_mode()
|
||||
update_mode_text = self._update_mode_label(update_mode)
|
||||
@@ -501,6 +515,8 @@ class ApplyTab(QWidget):
|
||||
if dry_run
|
||||
else "即将按当前筛选结果分批更新蝦皮线上商品。\n\n"
|
||||
)
|
||||
skipped_text = self._content_skip_text(content_plan)
|
||||
skipped_block = f"\n{skipped_text}\n" if skipped_text else ""
|
||||
return (
|
||||
intro
|
||||
+ f"批次:{self._batch_filter_label()}\n"
|
||||
@@ -509,7 +525,9 @@ class ApplyTab(QWidget):
|
||||
+ f"状态:{self._status_label()}\n"
|
||||
+ f"更新内容:{update_mode_text}\n"
|
||||
+ f"任务数:{len(tasks)}\n"
|
||||
+ f"预计批次:{batch_count}\n\n"
|
||||
+ f"预计批次:{batch_count}\n"
|
||||
+ skipped_block
|
||||
+ "\n"
|
||||
+ "执行设置:"
|
||||
+ f"每批最大更新条数={batch_size},"
|
||||
+ "成功后自动关闭程序新开编辑页,"
|
||||
@@ -581,7 +599,7 @@ class ApplyTab(QWidget):
|
||||
self._set_status(f"更新内容已设置为:{self._update_mode_label(update_mode)}")
|
||||
return True
|
||||
|
||||
def _update_content_error(self, tasks, update_mode):
|
||||
def _partition_update_content_tasks(self, tasks, update_mode):
|
||||
missing_title = [
|
||||
task for task in tasks
|
||||
if appconfig.update_mode_includes_title(update_mode)
|
||||
@@ -592,10 +610,24 @@ class ApplyTab(QWidget):
|
||||
if appconfig.update_mode_includes_cover(update_mode)
|
||||
and not str(getattr(task, "new_cover_path", "") or "").strip()
|
||||
]
|
||||
if not missing_title and not missing_cover:
|
||||
skipped = {id(task) for task in missing_title + missing_cover}
|
||||
return {
|
||||
"executable": [task for task in tasks if id(task) not in skipped],
|
||||
"missing_title": missing_title,
|
||||
"missing_cover": missing_cover,
|
||||
}
|
||||
|
||||
def _update_content_error(self, tasks_or_plan, update_mode):
|
||||
if isinstance(tasks_or_plan, dict):
|
||||
content_plan = tasks_or_plan
|
||||
else:
|
||||
content_plan = self._partition_update_content_tasks(tasks_or_plan, update_mode)
|
||||
if content_plan["executable"]:
|
||||
return None
|
||||
lines = []
|
||||
mode_text = self._update_mode_label(update_mode)
|
||||
missing_title = content_plan["missing_title"]
|
||||
missing_cover = content_plan["missing_cover"]
|
||||
if missing_title:
|
||||
lines.append(f"当前筛选结果中有 {len(missing_title)} 条缺少新标题,不能执行“{mode_text}”。")
|
||||
lines.append("请先回到②AI生成选择“只生成标题”或“生成标题和封面”。")
|
||||
@@ -608,6 +640,38 @@ class ApplyTab(QWidget):
|
||||
lines.append(f"示例商品ID:{self._sample_item_ids(missing_cover)}")
|
||||
return "\n".join(lines)
|
||||
|
||||
def _content_skip_text(self, content_plan):
|
||||
if not content_plan:
|
||||
return ""
|
||||
missing_title = content_plan.get("missing_title", [])
|
||||
missing_cover = content_plan.get("missing_cover", [])
|
||||
skipped_count = len({id(task) for task in missing_title + missing_cover})
|
||||
if not skipped_count:
|
||||
return ""
|
||||
lines = [f"本轮将跳过 {skipped_count} 条缺少所选更新内容的记录:"]
|
||||
if missing_title:
|
||||
lines.append(
|
||||
f"缺少新标题:{len(missing_title)} 条(示例商品ID:{self._sample_item_ids(missing_title)})"
|
||||
)
|
||||
if missing_cover:
|
||||
lines.append(
|
||||
f"缺少新封面:{len(missing_cover)} 条(示例商品ID:{self._sample_item_ids(missing_cover)})"
|
||||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
def _content_skip_status(self, content_plan):
|
||||
if not content_plan:
|
||||
return ""
|
||||
missing_title = content_plan.get("missing_title", [])
|
||||
missing_cover = content_plan.get("missing_cover", [])
|
||||
skipped_count = len({id(task) for task in missing_title + missing_cover})
|
||||
if not skipped_count:
|
||||
return ""
|
||||
return (
|
||||
f",跳过 {skipped_count} 条(缺标题 {len(missing_title)} / "
|
||||
f"缺封面 {len(missing_cover)})"
|
||||
)
|
||||
|
||||
def _sample_item_ids(self, tasks):
|
||||
values = [
|
||||
str(getattr(task, "item_id", "") or "").strip()
|
||||
@@ -711,13 +775,18 @@ class ApplyTab(QWidget):
|
||||
def _show_current_run_log_empty(self):
|
||||
self.run_log_view.setPlainText("本轮日志会在开始运行后显示")
|
||||
|
||||
def _reset_run_log(self, tasks, dry_run=False, batch_size=1):
|
||||
def _reset_run_log(self, tasks, dry_run=False, batch_size=1, content_plan=None):
|
||||
self.run_log_view.clear()
|
||||
action = "检查" if dry_run else "更新"
|
||||
mode_text = self._update_mode_label(self._current_update_mode())
|
||||
self._append_run_log(
|
||||
f"本轮{action}开始:任务 {len(tasks)} 条,更新内容:{mode_text},每批 {batch_size} 条"
|
||||
)
|
||||
skip_status = self._content_skip_status(content_plan)
|
||||
if skip_status:
|
||||
self._append_run_log(
|
||||
f"本轮预检:可执行 {len(tasks)} 条{skip_status};缺失记录未进入本轮执行。"
|
||||
)
|
||||
|
||||
def _load_latest_run_log(self):
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user