diff --git a/src/app/widgets/ai_outfit_panel.py b/src/app/widgets/ai_outfit_panel.py index 3760b70..ec45faa 100644 --- a/src/app/widgets/ai_outfit_panel.py +++ b/src/app/widgets/ai_outfit_panel.py @@ -806,7 +806,8 @@ class AiOutfitPanel(QWidget): self._set_cell(row, 5, "—") self._progress.setMaximum(max(1, len(tasks))) self._update_stats(0, 0, len(tasks)) - self._fill_sample_combo(tasks) + # Preview sample rows are owned by read_all_rows (§10.3/§10.4); don't reset + # them to the run's task list (which is empty when the sheet is all 完成). self._append_log("已加载 {} 行待处理任务".format(len(tasks))) def _on_progress(self, completed, total, result): @@ -831,12 +832,43 @@ class AiOutfitPanel(QWidget): def _on_finished(self, summary): self._set_running(False) + if getattr(summary, "total", 0) == 0: + self._append_log("没有待处理的行。") + self._show_no_pending_message() + return msg = "完成 {},失败 {}{}".format( summary.success_count, summary.failure_count, "(已停止)" if getattr(summary, "stopped", False) else "") self._append_log("批量结束:" + msg) QMessageBox.information(self, "AI 穿搭", "本次生成结束。\n" + msg) + def _show_no_pending_message(self): + """Explain why nothing ran: rows already 完成/失败, and how to redo (§10.4).""" + done = failed = 0 + excel = self._excel_edit.text().strip() + if excel: + try: + from services.excel_service import ( + STATUS_DONE, STATUS_FAILED, read_all_rows) + for r in read_all_rows(excel): + if r.status == STATUS_DONE: + done += 1 + elif r.status == STATUS_FAILED: + failed += 1 + except Exception: # noqa: BLE001 - best effort + pass + if done == 0 and failed == 0: + text = "该表没有可处理的行(标题/货号/衣服图为空的行会被跳过)。" + else: + parts = [] + if done: + parts.append("已完成 {} 行(已跳过)".format(done)) + if failed: + parts.append("失败 {} 行(勾选「重试上次失败的行」可重做)".format(failed)) + text = ("该表没有待处理的行:" + ";".join(parts) + + "。\n要重做已完成的行,请清空对应行的状态(E)列后重试。") + QMessageBox.information(self, "没有待处理的行", text) + def _on_failed(self, message): self._set_running(False) self._append_log("无法开始:" + message) diff --git a/tasks.md b/tasks.md index 0f8b993..d43bd93 100644 --- a/tasks.md +++ b/tasks.md @@ -1131,6 +1131,6 @@ 背景:整表都「完成」后点「开始生成」,当前只显示「已加载 0 行待处理任务 / 完成 0,失败 0」,看不懂;且 `_on_tasks_loaded([])` 会把预览样本下拉清空(破坏 §10.3)。 -- [ ] 改进 1:检测 0 行待处理时弹明确提示「该表没有待处理的行:已完成 N 行会跳过;失败 M 行可勾『重试失败行』;要重做已完成行请清空对应行状态(E)列」(N/M 由 `read_all_rows` 统计);在 `tasks_loaded` 为空或 `_on_finished(total==0)` 时弹 `QMessageBox.information` -- [ ] 改进 2:`_on_tasks_loaded` 去掉 `_fill_sample_combo(tasks)`,预览样本下拉只由 `read_all_rows`/`_reload_sample_rows` 维护,与运行解耦 -- [ ] 离屏验证:全表完成点生成 → 弹"无待处理行"提示、预览下拉仍有样本行;正常有待处理行时不弹该提示 +- [x] 改进 1:`_on_finished(total==0)` 弹 `_show_no_pending_message`——统计 `read_all_rows` 的「完成 N / 失败 M」,提示「已完成 N 跳过;失败 M 可勾『重试上次失败的行』;重做已完成请清空状态(E)列」(无有效行时另提示) +- [x] 改进 2:`_on_tasks_loaded` 去掉 `_fill_sample_combo(tasks)`,预览样本下拉只由 `read_all_rows`/`_reload_sample_rows` 维护,与运行解耦 +- [x] 离屏验证:全表完成 → `tasks_loaded([])` 后预览下拉仍 2 行、`_on_finished(total=0)` 弹"没有待处理的行"(含已完成1/失败1);`total>0` 仍弹常规"AI 穿搭"结束框;全套 12 文件绿