feat: 完成T-204旧字段回写

实现 Excel 旧标题与旧封面路径回写原文件,按 source_file_abs/source_sheet/source_row 定位行,支持输出列自动追加、xlsm 保留 VBA、文件占用中文错误提示与 export_copy 另存副本。

Tab① 增加回写旧数据按钮与 WriteBackWorker,后台调用 excel.write_back,锁文件时提示关闭后重试;补充 Excel 与 GUI 单测覆盖回写、锁文件、另存副本和 worker 调用。

同步 harness 文档:T-204 标记完成,新增 T-204b 记录采集完成自动回写缺口,扩展 T-205 覆盖 Chrome 未启动/未登录引导保护,并更新 current-state、routes、api、architecture、requirements 与 progress。
This commit is contained in:
chengma
2026-06-27 14:37:58 +08:00
parent 8fe979942c
commit b9d84e71ec
11 changed files with 503 additions and 29 deletions
+1 -1
View File
@@ -48,7 +48,7 @@
| 更新 shopee(③) | 按批次/店铺/状态筛选;点击「开始更新」后弹窗确认,确认后对当前筛选出的已生成任务打开编辑页换标题+封面,并逐条点「更新」提交线上;可按状态=失败重试 | P0 |
| 结果存储与回写 | 各阶段结果实时存 SQLite;该文件全部完成后把旧/新数据+状态批量回写原 Excel | P0 |
| 设置(⑤) | AI 模型管理(下拉+新增/删除/详情/测试连接,至少各一个文本+图像模型);标题/图片大模型角色选择;分辨率(512/1k/2k/4k,返回超时随分辨率自动);并发/重试/jpg质量;图片目录/Chrome 路径/端口 | P0 |
| 首次引导保护 | 未配账号/未登录时,① ③ 执行按钮禁用并提示去④ | P0 |
| 首次引导保护 | 未配账号、对应账号 Chrome 未启动或未登录时,① ③ 执行按钮禁用/执行前拦截并提示去④ | P0 |
### 后续迭代
+2 -1
View File
@@ -59,7 +59,7 @@ imported → collected → generated → applied
## 三、职责划分
**GUI(5 Tab)**:见 [routes.md](routes.md)。只做交互与预览,不写业务逻辑;耗时操作走 PySide6 `QObject` worker + `QThread`,用 signal 回主线程刷新 UI。**首次未配账号/未登录时,① ③ 执行按钮禁用并提示去 ④。**
**GUI(5 Tab)**:见 [routes.md](routes.md)。只做交互与预览,不写业务逻辑;耗时操作走 PySide6 `QObject` worker + `QThread`,用 signal 回主线程刷新 UI。**首次未配账号、对应账号 Chrome 未启动或未登录时,① ③ 执行按钮禁用或执行前拦截,并提示去 ④。**
**核心模块**
@@ -288,6 +288,7 @@ images/<slug>/<item_id>_new.<ext> # AI 生成的新封面
- 用账号 Chrome 打开商品页,等就绪,读旧标题(标题输入框 value)。
- 旧封面:取第一张 itembox 的 `img.src`(CDN 链接),下载到 `images/<slug>/<item_id>_old`。
- 写 `old_title/old_cover_path`、stage=collected;批量回写 Excel 旧字段。
- T-204b 目标:采集任务结束后自动触发当前批次旧字段回写;原 Excel 被锁时不影响 SQLite 结果,提示关闭后重试,并保留手动「回写旧数据到 Excel」入口。
### 6.2 AI 生成(② Tab)
+3 -2
View File
@@ -51,8 +51,9 @@
| T-202 | Tab① 任务列表 + 导入按钮 + 别名匹配标记 | T-201, T-105 | `QTableView` 显示账号/别名/商品id/阶段;未匹配标“略过” | DONE |
| T-202b | Tab① 导入汇总栏 | T-202 | 导入后显示 文件数/解析行数/有效/无效/匹配(按账号)/未匹配;未匹配可点击筛出 | DONE |
| T-203 | 采集旧标题+旧封面(只读),下载图片,立即写库 | T-202, T-001, T-104b | 通过 worker 执行;逐条 set_collected;旧封面下载到 `images/<slug>/`;未登录/未匹配略过记原因 | DONE |
| T-204 | 回写旧字段到原 Excel(含文件锁处理) | T-203, T-201 | 旧标题/旧封面回写原文件;被锁提示重试或 export_copy | TODO |
| T-205 | 首次未配账号/未登录的引导保护 | T-105, T-203 | 无账号/未登录时 ① 执行按钮禁用并提示去④ | TODO |
| T-204 | 回写旧字段到原 Excel(含文件锁处理) | T-203, T-201 | `excel.write_back()` 按源文件/工作表/行号回写旧标题、旧封面;`export_copy()` 另存副本;Tab① 用 `WriteBackWorker` 后台回写,文件被占用时提示关闭后重试 | DONE |
| T-204b | 采集完成后自动回写旧字段到 Excel | T-204 | `CollectWorker` 完成后自动触发 `excel.write_back()` 回写当前批次旧字段;成功时状态栏/日志提示“已回写”;原文件被锁时不影响 SQLite,提示关闭后点「回写旧数据到 Excel」手动重试或另存副本 | TODO |
| T-205 | 首次未配账号 / Chrome 未启动 / 未登录的引导保护 | T-105, T-203 | 无账号、匹配账号未启动 CDP 端口或未登录时,① 执行按钮禁用或采集前汇总提示,并引导去④;可提供“打开账号管理/启动登录”入口,但不无提示批量启动所有账号 Chrome | TODO |
## Phase 3 · AI 生成(②)
+11 -6
View File
@@ -88,7 +88,7 @@ SQLite 连接规则:
- `connect()` 必须设置 `PRAGMA foreign_keys=ON`、`journal_mode=WAL`、`busy_timeout=5000`、`synchronous=NORMAL`。
- DB 写入短事务、单条提交;Excel 回写失败不回滚 DB。
## excel 模块(`app/excel.py`,导入已建;回写待 T-204/T-403,依赖 openpyxl)
## excel 模块(`app/excel.py`,导入与旧字段回写已建;结果回写待 T-403,依赖 openpyxl)
```python
class ExcelError(RuntimeError): ...
@@ -116,12 +116,14 @@ match_summary(rows: list[dict], accounts: list) -> dict
# -> {"matched": int, "unmatched": int, "by_account": {别名: 行数}, "unmatched_aliases": [..]}
write_back(batch_id, excel_path=None, path=None) -> dict
# 把【旧标题/旧封面/新标题/新封面/更新状态】批量回写到【原 Excel】
# 把【旧标题/旧封面图片路径】批量回写到【原 Excel】
# excel_path 为空则按 source_file_abs 分组回写本批次涉及的所有原文件
# 原文件被占用(锁) → 抛错,调用方提示“请关闭后重试”,或改用 export_copy
# 只写 stage 已到 collected/generated/applied 或已有旧字段值的任务;无可写任务时返回 rows=0
# 原文件被占用(锁) → 抛 ExcelError,调用方提示“请关闭后重试”,或改用 export_copy
# -> {"ok": True, "batch_id": str, "files": int, "rows": int, "written_files": [abs_path, ...]}
export_copy(batch_id, out_dir_or_path, path=None) -> dict
# 退路:另存新结果文件,不动原文件
# T-201 仅保证函数存在;实际回写/另存实现留给 T-204/T-403。
# 退路:另存带旧字段的副本,不动原文件;目录输出时生成 *_cmshopee回写.xlsx
# T-403 会在此基础上扩展新标题/新封面/更新状态回写。
```
列模板见 [架构 5.3](04-architecture.md);别名以“别名”列为权威,必须与 ④ 账号管理中的账号别名一致。`shopee待处理任务模板.xlsx` 是可提交的标准空模板;运营填写后的 Excel 副本属于业务数据,不提交。
@@ -273,6 +275,7 @@ main() -> int # 创建 QApplication + MainWindow
class MainWindow(QMainWindow) # QTabWidget: ①②③④⑤;支持注入 db_path/config 便于测试
class CollectTab(QWidget) # ① 导入采集:导入 Excel + 汇总栏 + QTableView 任务列表 + 未匹配略过标记
class CollectWorker(BaseWorker) # ① 后台采集:登录检测 -> editor.collect -> db.set_collected/mark_skipped/mark_failed
class WriteBackWorker(BaseWorker) # ① 后台回写:excel.write_back(batch_id) 写旧标题/旧封面到原 Excel
class TaskTableModel(QAbstractTableModel) # 任务表格模型:账号/别名/商品ID/阶段;未匹配别名显示“略过”
class AccountsTab(QWidget) # ④ 账号管理:表格 + 增删改 + 启动登录 + 检测登录 + 快捷方式
class AccountDialog(QDialog) # 账号编辑弹窗;密码 QLineEdit.Password
@@ -298,8 +301,10 @@ TAB_STYLE: str # 顶层 Tab 栏防误点样式:
- 任务列表使用 `QTableView + TaskTableModel`,列为:账号、别名、商品ID、阶段。
- 账号列优先显示匹配到的 `accounts.account_name`;未匹配账号时保留 Excel 输入账号名。
- 别名未匹配 `accounts.alias` 时列表阶段列显示“略过”;点击「采集旧标题/旧封面」后由 `CollectWorker` 写库为 `skipped`,原因 `别名未匹配账号`。
- 「采集旧标题/旧封面」通过 `CollectWorker` 后台执行,只处理 `stage=imported` 的任务;每条先检测登录,未登录写 `mark_skipped`,已登录则下载旧封面到 `image_dir/<slug>/<item_id>_old.jpg` 并 `db.set_collected()`;单条失败 `mark_failed(..., "collect", error)` 后继续。
- 「采集旧标题/旧封面」通过 `CollectWorker` 后台执行,只处理 `stage=imported` 的任务;每条先检测登录,未登录写 `mark_skipped`,已登录则下载旧封面到 `image_dir/<slug>/<item_id>_old.jpg` 并 `db.set_collected()`;单条失败 `mark_failed(..., "collect", error)` 后继续。T-204b 后采集完成应自动触发当前批次旧字段回写,锁文件失败时只提示,不回滚 SQLite。
- 「停止」调用 worker 的协作式 `cancel()`,已开始的单条跑到安全边界后结束。
- 「回写旧数据到 Excel」通过 `WriteBackWorker` 后台调用 `excel.write_back()`,把已采集旧标题/旧封面路径按原 Excel 行定位写回;T-204b 后该按钮主要作为自动回写失败后的手动重试入口。原文件被占用时弹窗提示关闭后重试,SQLite 采集结果不回滚。
- T-205 后,若无账号、当前批次匹配账号未启动 CDP 端口或未登录,① 的采集执行应禁用或在执行前汇总拦截并提示去④账号管理;可以提供跳转/启动登录入口,但不无提示批量启动所有账号 Chrome。
## workers 模块(`app/workers.py`,已建,PySide6)
+13 -8
View File
@@ -6,9 +6,9 @@
## 当前快照
- 日期:2026-06-27
- 阶段:V0 单账号 CDP 流程已验证;V1 已完成 T-000 正式代码包结构、T-001 `app/editor.py` 模块化、T-002 `app/appconfig.py` 应用配置、T-003 SQLite 持久化地基、T-004 本地数据忽略规则、T-005 AI 模型清单后端、T-006 单元测试基座、T-101 账号 user-data-dir 工具、T-102 Chrome 启动器、T-103 登录保活与检测、T-104 PySide6 主窗口骨架、T-104b PySide6 worker 基座、T-105 Tab④ 账号管理、T-106 账号快捷方式、T-201 Excel 导入入库、T-202 Tab① 任务列表与导入按钮、T-202b Tab① 导入汇总栏、T-203 采集旧标题旧封面。
- 阶段:V0 单账号 CDP 流程已验证;V1 已完成 T-000 正式代码包结构、T-001 `app/editor.py` 模块化、T-002 `app/appconfig.py` 应用配置、T-003 SQLite 持久化地基、T-004 本地数据忽略规则、T-005 AI 模型清单后端、T-006 单元测试基座、T-101 账号 user-data-dir 工具、T-102 Chrome 启动器、T-103 登录保活与检测、T-104 PySide6 主窗口骨架、T-104b PySide6 worker 基座、T-105 Tab④ 账号管理、T-106 账号快捷方式、T-201 Excel 导入入库、T-202 Tab① 任务列表与导入按钮、T-202b Tab① 导入汇总栏、T-203 采集旧标题旧封面、T-204 回写旧字段到原 Excel。
- 技术栈:Python 3.10+,自研 CDP(websocket-client + requests),SQLite(sqlite3)+ `config.json` + openpyxl + AI(服务商待定),GUI PySide6 5 Tab(已定)。
- 生产代码:已建立 `app/` 包 + 根入口 `main.py`;`app/cdp.py` 为已验证 CDP 底座;`app/editor.py` 已封装登录状态检测、标题/封面/采集/更新按钮能力;`app/appconfig.py` 已实现 `config.json` 默认值/读写/更新、AI 参数与端口读取,以及 `config/ai_models.json` 模型清单 CRUD/过滤/打码/测试连接;`app/db.py` 已实现 SQLite schema、连接 PRAGMA、批次/账号/任务与阶段写库函数;`app/excel.py` 已实现多 Excel 输入列解析、整文件列校验、脏行统计跳过、导入批次与任务入库、别名匹配统计;`app/config.py` 已实现账号 slug 与 user-data-dir 创建;`app/accounts.py` 已实现账号 CRUD 服务、端口默认分配、启动登录、检测登录、生成快捷方式;`app/chrome.py` 已实现 Chrome 参数拼装、启动、CDP 端口探测、PowerShell `.lnk` 快捷方式生成;`app/gui.py` 已实现 PySide6 `MainWindow`、五 Tab、顶部 Tab 栏防误点样式、① 导入采集的 Excel 导入按钮/导入汇总栏/QTableView 任务列表/未匹配筛选与略过标记/采集旧标题旧封面 worker、④ 账号管理表格/弹窗/按钮/快捷方式与状态栏;`app/workers.py` 已实现 `BaseWorker`、通用 signals、取消标记和 `QThread` 启动包装。
- 生产代码:已建立 `app/` 包 + 根入口 `main.py`;`app/cdp.py` 为已验证 CDP 底座;`app/editor.py` 已封装登录状态检测、标题/封面/采集/更新按钮能力;`app/appconfig.py` 已实现 `config.json` 默认值/读写/更新、AI 参数与端口读取,以及 `config/ai_models.json` 模型清单 CRUD/过滤/打码/测试连接;`app/db.py` 已实现 SQLite schema、连接 PRAGMA、批次/账号/任务与阶段写库函数;`app/excel.py` 已实现多 Excel 输入列解析、整文件列校验、脏行统计跳过、导入批次与任务入库、别名匹配统计、旧标题/旧封面路径回写原 Excel 与另存副本;`app/config.py` 已实现账号 slug 与 user-data-dir 创建;`app/accounts.py` 已实现账号 CRUD 服务、端口默认分配、启动登录、检测登录、生成快捷方式;`app/chrome.py` 已实现 Chrome 参数拼装、启动、CDP 端口探测、PowerShell `.lnk` 快捷方式生成;`app/gui.py` 已实现 PySide6 `MainWindow`、五 Tab、顶部 Tab 栏防误点样式、① 导入采集的 Excel 导入按钮/导入汇总栏/QTableView 任务列表/未匹配筛选与略过标记/采集旧标题旧封面 worker/旧数据回写按钮与 worker、④ 账号管理表格/弹窗/按钮/快捷方式与状态栏;`app/workers.py` 已实现 `BaseWorker`、通用 signals、取消标记和 `QThread` 启动包装。
- 测试:`tests/` 已建立;T-006 后纯逻辑改动必须运行 `python -m unittest discover -s tests`,当前覆盖 appconfig/db/config/accounts/chrome 启动与快捷方式/editor 登录检测/excel 导入/gui ① 导入采集/gui ④ 账号管理/worker signal 与线程包装,并对尚未实现的 app.prompts 做契约占位 skip;CDP/Shopee 改动仍需测试商品手动验证。
- 数据:`config.json`、`config/ai_models.json`、`cmshopee.db`、`chrome_user_data_dir/`、`images/` 已由 `.gitignore` 排除;运营填写后的 Excel 业务文件默认忽略,标准空模板 `shopee待处理任务模板.xlsx` 可提交;`app/appconfig.py` 首次读取缺失的 `config.json` 时会在本地写默认配置,`app/db.py` 调用 `init_db()` 时会在本地创建 SQLite DB。
@@ -21,7 +21,7 @@
- 账号↔任务绑定:以 Excel“别名”列为权威;未匹配略过,结束弹窗汇总。
- 执行:多账号串行、单条失败继续;③ 点击「开始更新」后弹窗确认当前筛选范围和任务数量,确认后逐条点「更新」提交线上。
- AI:服务商待定;生成内容直接用于更新,本地留档+回写 Excel 供追溯。
- 登录:人工登录 + 程序检测,不自动登录;无 Shopee tab 时检测入口为 `https://<region_host>/`(默认 `https://seller.shopee.tw/`);首次未配账号/未登录时 ① ③ 禁用并引导去④。
- 登录:人工登录 + 程序检测,不自动登录;无 Shopee tab 时检测入口为 `https://<region_host>/`(默认 `https://seller.shopee.tw/`);首次未配账号、对应账号 Chrome 未启动或未登录时,① ③ 应禁用/提示并引导去④。
## 当前目录要点
@@ -32,7 +32,7 @@
| `prototypes/` | 已有 | 已验证原型/探查脚本(demo/set_title/set_cover/get_title/cookies/inspect_images/grab/1.py),保留作人工回归与探查参考;见 `prototypes/README.md` |
| `chrome-remote-debug-lan.md` | 已有 | WSL→Windows CDP 转发排查记录 |
| `app/__init__.py` / `app/__main__.py` / `main.py` | 已有 | 正式包与启动入口;`python main.py` / `python -m app` 可运行占位入口 |
| `app/gui.py` | 已有 | T-104/T-105/T-106/T-202/T-202b/T-203 产出:PySide6 `QMainWindow` + 五 Tab;顶部 Tab 栏防误点样式;① 导入采集导入按钮、导入汇总栏、`QTableView` 任务列表、未匹配筛选与略过标记、采集旧标题旧封面 worker;④ 账号管理表格、账号弹窗、启动登录、检测登录、快捷方式 |
| `app/gui.py` | 已有 | T-104/T-105/T-106/T-202/T-202b/T-203/T-204 产出:PySide6 `QMainWindow` + 五 Tab;顶部 Tab 栏防误点样式;① 导入采集导入按钮、导入汇总栏、`QTableView` 任务列表、未匹配筛选与略过标记、采集旧标题旧封面 worker、旧数据回写 worker;④ 账号管理表格、账号弹窗、启动登录、检测登录、快捷方式 |
| `app/workers.py` | 已有 | T-104b 产出:`BaseWorker` + 通用 signals + 取消标记 + `run_worker()` QThread 包装 |
| `app/accounts.py` | 已有 | T-105/T-106 产出:账号 CRUD 服务、目录创建、端口分配、启动登录、检测登录、快捷方式 |
| `app/editor.py` | 已有 | T-001/T-103 产出:登录状态检测、打开商品页、读/写标题、读/下载封面、上传拖封面、更新按钮、apply_task |
@@ -40,8 +40,8 @@
| `app/db.py` | 已有 | T-003 产出:batches/accounts/tasks schema;WAL/busy_timeout/foreign_keys;账号/批次/任务与 set_* 阶段写库 |
| `app/config.py` | 已有 | T-101 产出:别名→稳定 slug;创建并返回绝对 user-data-dir |
| `app/chrome.py` | 已有 | T-102/T-106 产出:Chrome 启动参数、`subprocess.Popen` 启动、`/json/version` 端口探测、PowerShell `.lnk` 快捷方式 |
| `tests/` | 已有 | T-006/T-201/T-202/T-202b/T-203 产出:stdlib unittest 基座;覆盖 appconfig/db/config/accounts/chrome/editor/excel/gui/workers;prompts 模块契约占位测试 |
| `app/excel.py` | 已有 | T-201 产出:多文件 Excel 输入列解析、必需列整文件拒绝、脏行逐行跳过、批次/任务入库、匹配统计;回写留给 T-204/T-403 |
| `tests/` | 已有 | T-006/T-201/T-202/T-202b/T-203/T-204 产出:stdlib unittest 基座;覆盖 appconfig/db/config/accounts/chrome/editor/excel/gui/workers;prompts 模块契约占位测试 |
| `app/excel.py` | 已有 | T-201/T-204 产出:多文件 Excel 输入列解析、必需列整文件拒绝、脏行逐行跳过、批次/任务入库、匹配统计;按源文件/工作表/行号回写旧标题与旧封面路径;支持原文件被占用时另存副本 |
| `shopee待处理任务模板.xlsx` | 已有,待提交 | 标准空 Excel 模板;单工作表 `待处理任务`,表头 `账号名 | 别名 | 商品id | 旧标题 | 旧封面图片路径 | 新标题 | 新封面图片路径 | 更新状态`;运营复制后填写,填写副本不提交 |
| `config.json` / `config/ai_models.json` / `cmshopee.db` / `chrome_user_data_dir/` / `images/` | 本地待建,已忽略 | 含配置、密钥、业务、登录态、图片,不提交版本库 |
@@ -57,9 +57,14 @@
任务状态以 [`06-tasks.md`](06-tasks.md) 为准,历史记录见 [`../progress.md`](../progress.md)。
- 已完成:T-000(正式代码包结构)、T-001(`app/editor.py` 模块化)、T-002(`app/appconfig.py` + `config.json`)、T-003(`app/db.py` + SQLite 建表)、T-004(本地数据 gitignore)、T-005(AI 模型清单后端)、T-006(单元测试基座)、T-101(账号 slug/user-data-dir)、T-102(Chrome 启动器)、T-103(登录保活与检测)、T-104(PySide6 五 Tab 主窗口骨架)、T-104b(PySide6 worker 基座)、T-105(Tab④ 账号管理)、T-106(账号快捷方式)、T-201(Excel 导入:解析多文件输入列入库)、T-202(Tab① 任务列表 + 导入按钮 + 别名匹配标记)、T-202b(Tab① 导入汇总栏)、T-203(采集旧标题+旧封面)。
- 已完成:T-000(正式代码包结构)、T-001(`app/editor.py` 模块化)、T-002(`app/appconfig.py` + `config.json`)、T-003(SQLite 建表)、T-004(本地数据 gitignore)、T-005(AI 模型清单后端)、T-006(单元测试基座)、T-101(账号 slug/user-data-dir)、T-102(Chrome 启动器)、T-103(登录保活与检测)、T-104(PySide6 五 Tab 主窗口骨架)、T-104b(PySide6 worker 基座)、T-105(Tab④ 账号管理)、T-106(账号快捷方式)、T-201(Excel 导入:解析多文件输入列入库)、T-202(Tab① 任务列表 + 导入按钮 + 别名匹配标记)、T-202b(Tab① 导入汇总栏)、T-203(采集旧标题+旧封面)、T-204(回写旧字段到原 Excel)。
- 正在进行:无。
- 下一个可领取任务:**T-204(回写旧字段到原 Excel,含文件锁处理)**。
- 下一个可领取任务:**T-204b(采集完成后自动回写旧字段到 Excel)**。
## 当前已发现待修体验问题
- T-204 已提供手动「回写旧数据到 Excel」,但当前采集完成后不会自动写回原 Excel;已拆为 T-204b 修复,目标是采集完成自动回写,失败时保留手动重试。
- ① 采集依赖对应账号 Chrome 已用专属 user-data-dir 和 CDP 端口启动并登录;若未启动或未登录,当前会采集失败/略过。已在 T-205 明确处理:禁用或提示,并引导去④账号管理启动登录,不无提示批量启动所有账号 Chrome。
## 当前可运行内容
+6 -5
View File
@@ -30,7 +30,8 @@
## 首次使用引导保护
- ① 导入采集 与 ③ 更新shopee 都依赖**账号已配置且已登录**(在 ④ 账号管理)。
- 当无账号 / 账号未登录时:相关执行按钮**禁用**,并提示「请先到『账号管理』配置账号并登录」。
- 当无账号 / 对应账号 Chrome 未启动 / 账号未登录时:相关执行按钮**禁用或在执行前汇总拦截**,并提示「请先到『账号管理』配置账号并登录」。
- 可以提供「打开账号管理」或「启动登录」入口辅助用户处理当前账号;不要无提示批量启动所有账号 Chrome,避免开错账号或启动过多浏览器进程。
- 老用户账号已就绪则无感。
## ① 导入采集
@@ -51,8 +52,8 @@
- 导入:openpyxl 解析**输入列**(账号名/别名/商品id)入 SQLite。
- **导入汇总栏**(导入后即时刷新,跑采集前的校验关口):显示 文件数、解析行数(原始数据量)、有效/无效行、匹配账号行数(按账号细分)、未匹配行数。未匹配/无效数字标红可点,点击在列表筛出便于定位纠错。
- 采集:用该账号 Chrome 只读打开商品页,读旧标题、下载旧封面到本地图片目录,写 `old_title/old_cover_path`,stage=collected。
- 回写:采集完把旧标题/旧封面路径批量回写原 Excel(原文件被锁→提示重试/另存)。
- 采集:用该账号已启动并登录的 Chrome 只读打开商品页,读旧标题、下载旧封面到本地图片目录,写 `old_title/old_cover_path`,stage=collected。
- 回写:采集完成后自动把旧标题/旧封面路径批量回写原 Excel;保留「回写旧数据到 Excel」作为手动重试入口(原文件被锁→提示关闭后重试/另存)。
- 别名未匹配账号 / 账号未登录 → 该行 skipped 并记原因。
## ② AI生成
@@ -130,14 +131,14 @@
```text
④ 账号管理:配账号 + 启动登录(首次必做)
│
① 导入采集:导入 Excel → 采集旧标题/旧封面 → 回写旧字段
① 导入采集:导入 Excel → 采集旧标题/旧封面 → 自动回写旧字段(失败可手动重试)
│
② AI生成:提示词 → 生成新标题/新封面(无逐条审核)
│
③ 更新shopee:对已生成任务点击开始更新 → 弹窗确认 → 换标题+封面 → 点「更新」提交 → 回写结果
```
- 未配账号/未登录:① ③ 的执行按钮禁用并提示去 ④。
- 未配账号 / Chrome 未启动 / 未登录:① ③ 的执行按钮禁用或执行前提示去 ④。
- 已生成的任务即可进 ③;③ 用户确认批量弹窗后提交线上,无常驻提交开关。
- 任意步骤失败:记入该任务、日志标明,不影响其他任务。