docs: 规划正式代码包结构
将正式代码目标结构统一为 app/ 包和根目录 main.py,区分 app/ 正式代码与 prototypes/ 原型参照。 新增 T-000 作为首个实现任务:创建 app 包、迁移 cdp.py、补 app/__main__.py 与 main.py、修正 prototypes/demo.py 导入。 更新模块合约、技术栈、编码规则和 current-state:后续模块路径改为 app/editor.py、app/appconfig.py、app/db.py 等,启动方式为 python main.py 或 python -m app。
This commit is contained in:
@@ -25,7 +25,7 @@ cmshopee 是一个 **Windows 本地桌面自动化工具**:管理多个 Shopee
|
|||||||
|
|
||||||
## 工作规则
|
## 工作规则
|
||||||
|
|
||||||
- 复用已有 `cdp.py`,遵守架构第七节的选择器、就绪判断、上传/拖拽方式,不另起一套 CDP 交互。
|
- 正式代码统一放入 `app/` 包;迁移完成后复用 `app/cdp.py`,遵守架构第七节的选择器、就绪判断、上传/拖拽方式,不另起一套 CDP 交互。
|
||||||
- 只做当前任务范围内的事;V2(多账号并行、dry-run、运行日志)只记录不实现。
|
- 只做当前任务范围内的事;V2(多账号并行、dry-run、运行日志)只记录不实现。
|
||||||
- CDP 选择器 / 流程 / 配置 schema 变化,必须同步更新 `docs/04-architecture.md` 与相关任务。
|
- CDP 选择器 / 流程 / 配置 schema 变化,必须同步更新 `docs/04-architecture.md` 与相关任务。
|
||||||
- 改完后更新任务状态、追加 `progress.md`、覆盖 `docs/current-state.md`。
|
- 改完后更新任务状态、追加 `progress.md`、覆盖 `docs/current-state.md`。
|
||||||
@@ -40,7 +40,7 @@ cmshopee 是一个 **Windows 本地桌面自动化工具**:管理多个 Shopee
|
|||||||
## 验证
|
## 验证
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m py_compile *.py # 语法检查
|
python -m compileall app main.py # 语法检查(T-000 后)
|
||||||
python -m unittest discover -s tests # 纯逻辑单元测试(T-006 完成且 tests/ 存在后)
|
python -m unittest discover -s tests # 纯逻辑单元测试(T-006 完成且 tests/ 存在后)
|
||||||
python prototypes/demo.py # 单账号闭环(不提交)
|
python prototypes/demo.py # 单账号闭环(不提交)
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ cmshopee 是一个 Windows 本地桌面自动化工具(PySide6,5 Tab),
|
|||||||
|
|
||||||
优先路径:
|
优先路径:
|
||||||
|
|
||||||
1. Phase 0:把已验证流程模块化(`editor.py`),建立 `config.json` 与 SQLite。
|
1. Phase 0:先建立正式代码包 `app/` 与根入口 `main.py`,再把已验证流程模块化到 `app/editor.py`,建立 `config.json` 与 SQLite。
|
||||||
2. Phase 1:账号绑定 user-data-dir、Chrome 启动、登录保活、PySide6 主窗口骨架。
|
2. Phase 1:账号绑定 user-data-dir、Chrome 启动、登录保活、PySide6 主窗口骨架。
|
||||||
3. Phase 2:导入 Excel、采集旧标题/旧封面并回写。
|
3. Phase 2:导入 Excel、采集旧标题/旧封面并回写。
|
||||||
4. Phase 3:AI 生成新标题/新封面。
|
4. Phase 3:AI 生成新标题/新封面。
|
||||||
@@ -61,7 +61,7 @@ cmshopee 是一个 Windows 本地桌面自动化工具(PySide6,5 Tab),
|
|||||||
|
|
||||||
- 单账号已登录 Chrome,通过 CDP 打开商品页、改标题、换封面。
|
- 单账号已登录 Chrome,通过 CDP 打开商品页、改标题、换封面。
|
||||||
- 原型脚本默认不提交线上,`UPDATE=1` 才点击「更新」。
|
- 原型脚本默认不提交线上,`UPDATE=1` 才点击「更新」。
|
||||||
- 作为 `editor.py` 的已验证参照,不再代表当前完整产品范围。
|
- 作为 `app/editor.py` 的已验证参照,不再代表当前完整产品范围。
|
||||||
|
|
||||||
**V1 当前 coding 目标**:
|
**V1 当前 coding 目标**:
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ cmshopee 是一个 Windows 本地桌面自动化工具(PySide6,5 Tab),
|
|||||||
- [`04-architecture.md`](04-architecture.md) 第七节:CDP 交互已验证结论(选择器、就绪判断、上传/拖拽方式)。
|
- [`04-architecture.md`](04-architecture.md) 第七节:CDP 交互已验证结论(选择器、就绪判断、上传/拖拽方式)。
|
||||||
- [`04-architecture.md`](04-architecture.md) 5.1/5.1b/5.2/5.3:`config.json`、`config/ai_models.json`、SQLite schema、Excel 模板。
|
- [`04-architecture.md`](04-architecture.md) 5.1/5.1b/5.2/5.3:`config.json`、`config/ai_models.json`、SQLite schema、Excel 模板。
|
||||||
- 真实页面探查结果(用 `prototypes/inspect_images.py` / `prototypes/cookies.py` 实地确认)。
|
- 真实页面探查结果(用 `prototypes/inspect_images.py` / `prototypes/cookies.py` 实地确认)。
|
||||||
- 已验证脚本 `cdp.py`、`prototypes/demo.py`、`prototypes/set_title.py`、`prototypes/set_cover.py` 中跑通的逻辑。
|
- 已验证脚本 `cdp.py`(T-000 后迁入 `app/cdp.py`)、`prototypes/demo.py`、`prototypes/set_title.py`、`prototypes/set_cover.py` 中跑通的逻辑。
|
||||||
|
|
||||||
不要把以下当事实来源:
|
不要把以下当事实来源:
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ cmshopee 是一个 Windows 本地桌面自动化工具(PySide6,5 Tab),
|
|||||||
|
|
||||||
- 先看 `04-architecture.md` 第七节已验证事实。
|
- 先看 `04-architecture.md` 第七节已验证事实。
|
||||||
- 再看 `api.md` 的 `cdp` / `editor` 模块合约。
|
- 再看 `api.md` 的 `cdp` / `editor` 模块合约。
|
||||||
- 复用 `cdp.py`,不重写一套。
|
- 复用 `app/cdp.py`(迁移前参考根目录 `cdp.py`),不重写一套。
|
||||||
|
|
||||||
做账号配置 / Chrome 启动:
|
做账号配置 / Chrome 启动:
|
||||||
|
|
||||||
@@ -116,7 +116,7 @@ cmshopee 是一个 Windows 本地桌面自动化工具(PySide6,5 Tab),
|
|||||||
## 验证命令
|
## 验证命令
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m py_compile *.py # 语法检查
|
python -m compileall app main.py # 语法检查(T-000 后)
|
||||||
python -m unittest discover -s tests # 纯逻辑单元测试(T-006 完成且 tests/ 存在后)
|
python -m unittest discover -s tests # 纯逻辑单元测试(T-006 完成且 tests/ 存在后)
|
||||||
python prototypes/demo.py # 单账号闭环验证(分步,不提交)
|
python prototypes/demo.py # 单账号闭环验证(分步,不提交)
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| 语言 | Python 3.10+ | 已定 | 已有脚本均为 Python;标准库够用 |
|
| 语言 | Python 3.10+ | 已定 | 已有脚本均为 Python;标准库够用 |
|
||||||
| 运行平台 | Windows(生产);WSL 可用于开发 | 已定 | Chrome 与各 user-data-dir 在 Windows;GUI 与 Chrome 同机,CDP 走 `localhost` |
|
| 运行平台 | Windows(生产);WSL 可用于开发 | 已定 | Chrome 与各 user-data-dir 在 Windows;GUI 与 Chrome 同机,CDP 走 `localhost` |
|
||||||
| 浏览器自动化 | 自研 CDP 客户端 `cdp.py` | 已定 | 基于 websocket-client + requests 手写;不引入 playwright/selenium,规避代理与 Origin 坑 |
|
| 浏览器自动化 | 自研 CDP 客户端 `app/cdp.py` | 已定 | 基于 websocket-client + requests 手写;不引入 playwright/selenium,规避代理与 Origin 坑 |
|
||||||
| WebSocket | `websocket-client`(import `websocket`) | 已定 | 讲 CDP 协议;用 `suppress_origin=True` 绕过 403 |
|
| WebSocket | `websocket-client`(import `websocket`) | 已定 | 讲 CDP 协议;用 `suppress_origin=True` 绕过 403 |
|
||||||
| HTTP | `requests` | 已定 | 读 `/json` 拿 tab 列表;`trust_env=False` 忽略代理 |
|
| HTTP | `requests` | 已定 | 读 `/json` 拿 tab 列表;`trust_env=False` 忽略代理 |
|
||||||
| 浏览器 | Google Chrome(已安装) | 已定 | 带 `--remote-debugging-port` 启动 |
|
| 浏览器 | Google Chrome(已安装) | 已定 | 带 `--remote-debugging-port` 启动 |
|
||||||
@@ -22,17 +22,17 @@
|
|||||||
| AI 图像生成 | 选 `default_image_model`(category=image,image-to-image) | 选型在配置 | 提示词+旧封面→新封面;分辨率 512/1k/2k/4k,返回超时随分辨率 |
|
| AI 图像生成 | 选 `default_image_model`(category=image,image-to-image) | 选型在配置 | 提示词+旧封面→新封面;分辨率 512/1k/2k/4k,返回超时随分辨率 |
|
||||||
| 并发 | 标准库 `concurrent.futures.ThreadPoolExecutor` | 已定 | 标题/图片分别按并发数并行;可停止、可重试 |
|
| 并发 | 标准库 `concurrent.futures.ThreadPoolExecutor` | 已定 | 标题/图片分别按并发数并行;可停止、可重试 |
|
||||||
| 图片处理 | `requests`(下载)+ `Pillow`(按分辨率/jpg质量存盘) | 部分待定 | 下载旧封面;新封面按 resolution 生成、jpg_quality 存盘 |
|
| 图片处理 | `requests`(下载)+ `Pillow`(按分辨率/jpg质量存盘) | 部分待定 | 下载旧封面;新封面按 resolution 生成、jpg_quality 存盘 |
|
||||||
| 测试 | `python -m py_compile` + `unittest` + 手动 CDP/AI 验证 | 已定(分层) | 配置/DB/Excel/prompts 用单测;CDP/Shopee 与真实 AI 属集成验证或 mock |
|
| 测试 | `python -m compileall app main.py` + `unittest` + 手动 CDP/AI 验证 | 已定(分层) | 配置/DB/Excel/prompts 用单测;CDP/Shopee 与真实 AI 属集成验证或 mock |
|
||||||
|
|
||||||
## 二、决策记录与演进
|
## 二、决策记录与演进
|
||||||
|
|
||||||
- **CDP 自研而非 playwright**:当前手写 `cdp.py`,因为它零重依赖、完全可控,并已在开发环境绕开了代理(`*_proxy` 指向本地 :1080)和 Chrome 的 Origin 403 两个坑。未来若交互复杂度大幅上升,再评估 playwright。
|
- **CDP 自研而非 playwright**:当前已验证根目录 `cdp.py`,正式代码迁入 `app/cdp.py`;它零重依赖、完全可控,并已在开发环境绕开了代理(`*_proxy` 指向本地 :1080)和 Chrome 的 Origin 403 两个坑。未来若交互复杂度大幅上升,再评估 playwright。
|
||||||
- **GUI 选 PySide6**:V1 是 5 Tab 运营工作台,包含任务表格、筛选、图片预览、后台采集/生成/更新、进度与停止。当前环境已安装 PySide6,且 Tkinter 不可用;Qt 的 `QThread`/signal-slot 比 Tkinter 手动 queue/after 更适合长任务回传 UI。
|
- **GUI 选 PySide6**:V1 是 5 Tab 运营工作台,包含任务表格、筛选、图片预览、后台采集/生成/更新、进度与停止。当前环境已安装 PySide6,且 Tkinter 不可用;Qt 的 `QThread`/signal-slot 比 Tkinter 手动 queue/after 更适合长任务回传 UI。
|
||||||
- **存储拆两层**:应用设置进 `config.json`,账号/任务/结果进 SQLite。判据:少量人改无需查询 → 配置文件;成行增长要查询/导出 → DB。同一事实只存一处,不重复。取代早期的 `accounts.json` 方案。
|
- **存储拆两层**:应用设置进 `config.json`,账号/任务/结果进 SQLite。判据:少量人改无需查询 → 配置文件;成行增长要查询/导出 → DB。同一事实只存一处,不重复。取代早期的 `accounts.json` 方案。
|
||||||
- **Excel 用 openpyxl**:运营用真实 .xlsx;stdlib 无法读写 xlsx,引入一个轻依赖比改用 CSV 更贴合用户习惯。
|
- **Excel 用 openpyxl**:运营用真实 .xlsx;stdlib 无法读写 xlsx,引入一个轻依赖比改用 CSV 更贴合用户习惯。
|
||||||
- **多账号隔离用独立 user-data-dir,不用 Chrome profile**:profile 共享同一 user-data-dir/进程/调试端口,无法每账号独立 CDP 与并行;独立 user-data-dir 才契合自动化。详见 [架构 3.0](04-architecture.md)。
|
- **多账号隔离用独立 user-data-dir,不用 Chrome profile**:profile 共享同一 user-data-dir/进程/调试端口,无法每账号独立 CDP 与并行;独立 user-data-dir 才契合自动化。详见 [架构 3.0](04-architecture.md)。
|
||||||
- **快捷方式生成用 PowerShell(无额外依赖)**:用 `WScript.Shell.CreateShortcut` 生成 `.lnk`,不引入 `pywin32` 等依赖。
|
- **快捷方式生成用 PowerShell(无额外依赖)**:用 `WScript.Shell.CreateShortcut` 生成 `.lnk`,不引入 `pywin32` 等依赖。
|
||||||
- **AI 服务商待定**:需选支持文本生成 + 图像 image-to-image 的服务;选型要权衡能力、合规(电商主图)、计费、Key 管理。**未确认前不在代码里写死某家 SDK**,先在 `ai.py` 留稳定接口(`gen_title`/`gen_cover`)。
|
- **AI 服务商待定**:需选支持文本生成 + 图像 image-to-image 的服务;选型要权衡能力、合规(电商主图)、计费、Key 管理。**未确认前不在代码里写死某家 SDK**,先在 `app/ai.py` 留稳定接口(`gen_title`/`gen_cover`)。
|
||||||
- **AI 产出无逐条审核**:生成的新标题/新封面经 ③ 批量确认后提交线上;无常驻提交开关,本地留档 + 回写 Excel 供追溯。
|
- **AI 产出无逐条审核**:生成的新标题/新封面经 ③ 批量确认后提交线上;无常驻提交开关,本地留档 + 回写 Excel 供追溯。
|
||||||
- **不引入数据库(指外部 DB)**:用 stdlib SQLite 足够;不引入 Postgres/MySQL 等。
|
- **不引入数据库(指外部 DB)**:用 stdlib SQLite 足够;不引入 Postgres/MySQL 等。
|
||||||
- **生产在 Windows 直跑**:开发期我们用过 WSL→Windows 的 `netsh portproxy`(9333→9222)连 CDP;但 GUI 与 Chrome 都在 Windows 时,直接连 `127.0.0.1:9222`,无需 portproxy。
|
- **生产在 Windows 直跑**:开发期我们用过 WSL→Windows 的 `netsh portproxy`(9333→9222)连 CDP;但 GUI 与 Chrome 都在 Windows 时,直接连 `127.0.0.1:9222`,无需 portproxy。
|
||||||
@@ -43,7 +43,8 @@
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| 安装依赖 | `pip install websocket-client requests openpyxl pillow PySide6` |
|
| 安装依赖 | `pip install websocket-client requests openpyxl pillow PySide6` |
|
||||||
| 检查 PySide6 | `python -c "import PySide6; print(PySide6.__version__)"` |
|
| 检查 PySide6 | `python -c "import PySide6; print(PySide6.__version__)"` |
|
||||||
| 语法检查 | `python -m py_compile *.py` |
|
| 语法检查 | `python -m compileall app main.py` |
|
||||||
|
| 启动 GUI | `python main.py` / `python -m app` |
|
||||||
| 单元测试(T-006 后) | `python -m unittest discover -s tests` |
|
| 单元测试(T-006 后) | `python -m unittest discover -s tests` |
|
||||||
| 跑单账号演示 | `python prototypes/demo.py`(分步)/ `set AUTO=1 && python prototypes/demo.py`(自动) |
|
| 跑单账号演示 | `python prototypes/demo.py`(分步)/ `set AUTO=1 && python prototypes/demo.py`(自动) |
|
||||||
| 提交更新(真改线上) | `set UPDATE=1 && python prototypes/demo.py` |
|
| 提交更新(真改线上) | `set UPDATE=1 && python prototypes/demo.py` |
|
||||||
@@ -66,14 +67,14 @@ set AUTO=1 && python prototypes/demo.py
|
|||||||
|
|
||||||
- 新增第三方依赖前,先在本文说明用途、替代方案和维护成本。
|
- 新增第三方依赖前,先在本文说明用途、替代方案和维护成本。
|
||||||
- GUI 框架固定为 PySide6,不允许混入 Tkinter/PyQt/Web 形成两套 UI。
|
- GUI 框架固定为 PySide6,不允许混入 Tkinter/PyQt/Web 形成两套 UI。
|
||||||
- 不引入第二套浏览器自动化方案(不要 cdp.py 之外再混入 selenium/playwright)。
|
- 不引入第二套浏览器自动化方案(不要 `app/cdp.py` 之外再混入 selenium/playwright)。
|
||||||
- 不确定的技术选型先更新本文,再进入代码。
|
- 不确定的技术选型先更新本文,再进入代码。
|
||||||
|
|
||||||
## 五、测试分层
|
## 五、测试分层
|
||||||
|
|
||||||
| 层级 | 覆盖对象 | 验证方式 |
|
| 层级 | 覆盖对象 | 验证方式 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| 语法 | 所有 `.py` | `python -m py_compile *.py`,后续可扩展 `compileall` |
|
| 语法 | 正式代码包与入口 | `python -m compileall app main.py` |
|
||||||
| 单元 | `appconfig/db/excel/prompts/config/chrome` 的纯逻辑 | T-006 建立 `tests/` 后运行 `python -m unittest discover -s tests`,使用临时目录/临时 SQLite/样例 Excel |
|
| 单元 | `appconfig/db/excel/prompts/config/chrome` 的纯逻辑 | T-006 建立 `tests/` 后运行 `python -m unittest discover -s tests`,使用临时目录/临时 SQLite/样例 Excel |
|
||||||
| GUI 轻测 | PySide6 主窗口可创建、Tab 数量、worker signal 基本行为 | 可用 unittest 构造 `QApplication`,不连真实 Shopee |
|
| GUI 轻测 | PySide6 主窗口可创建、Tab 数量、worker signal 基本行为 | 可用 unittest 构造 `QApplication`,不连真实 Shopee |
|
||||||
| 集成 | CDP/editor 操作 Shopee 测试商品 | 手动跑 `prototypes/demo.py` 或后续专用集成脚本 |
|
| 集成 | CDP/editor 操作 Shopee 测试商品 | 手动跑 `prototypes/demo.py` 或后续专用集成脚本 |
|
||||||
|
|||||||
+13
-7
@@ -34,8 +34,8 @@ Shopee 卖家中心页面 / 本地图片目录
|
|||||||
|
|
||||||
真实组件:
|
真实组件:
|
||||||
|
|
||||||
- GUI 入口:`gui.py`(待建,PySide6 + `QMainWindow` + `QTabWidget`,5 Tab)。
|
- GUI 入口:根目录 `main.py` 调用 `app/gui.py`(待建,PySide6 + `QMainWindow` + `QTabWidget`,5 Tab);也支持 `python -m app`。
|
||||||
- 核心模块:`appconfig.py`、`db.py`、`excel.py`、`config.py`、`chrome.py`、`editor.py`、`ai.py`(待建);CDP 底座 `cdp.py`(已有)。
|
- 核心模块统一放在正式代码包 `app/`:`appconfig.py`、`db.py`、`excel.py`、`config.py`、`chrome.py`、`editor.py`、`ai.py`、`prompts.py`、`workers.py`(待建);CDP 底座迁入 `app/cdp.py`(当前根目录 `cdp.py` 为已验证来源)。
|
||||||
- 已验证脚本(重构进模块):`prototypes/demo.py`、`prototypes/set_title.py`、`prototypes/set_cover.py`、`prototypes/get_title.py`、`prototypes/cookies.py`、`prototypes/inspect_images.py`、`prototypes/grab.py`。
|
- 已验证脚本(重构进模块):`prototypes/demo.py`、`prototypes/set_title.py`、`prototypes/set_cover.py`、`prototypes/get_title.py`、`prototypes/cookies.py`、`prototypes/inspect_images.py`、`prototypes/grab.py`。
|
||||||
- 外部依赖:本机 Google Chrome;Shopee;AI 服务(文本+图像,服务商待定);`openpyxl`。
|
- 外部依赖:本机 Google Chrome;Shopee;AI 服务(文本+图像,服务商待定);`openpyxl`。
|
||||||
|
|
||||||
@@ -338,7 +338,7 @@ images/<slug>/<item_id>_new.<ext> # AI 生成的新封面
|
|||||||
|
|
||||||
## 八、推荐开发顺序
|
## 八、推荐开发顺序
|
||||||
|
|
||||||
1. **地基**:`editor.py`(含采集)、`appconfig.py`+`config.json`、`db.py`、`.gitignore`。
|
1. **地基**:先建 `app/` 包、`app/cdp.py`、`app/__main__.py`、根目录 `main.py`;再做 `app/editor.py`(含采集)、`app/appconfig.py`+`config.json`、`app/db.py`、`.gitignore`。
|
||||||
2. **账号与启动**(④):`config` 建目录、`chrome` 启动器/快捷方式、登录保活与检测、账号 CRUD。
|
2. **账号与启动**(④):`config` 建目录、`chrome` 启动器/快捷方式、登录保活与检测、账号 CRUD。
|
||||||
3. **导入采集**(①):`excel` 导入、采集旧标题/旧封面、回写。
|
3. **导入采集**(①):`excel` 导入、采集旧标题/旧封面、回写。
|
||||||
4. **AI 生成**(②):`ai` 模块、提示词、对照预览。
|
4. **AI 生成**(②):`ai` 模块、提示词、对照预览。
|
||||||
@@ -350,6 +350,13 @@ images/<slug>/<item_id>_new.<ext> # AI 生成的新封面
|
|||||||
```text
|
```text
|
||||||
cmshopee/
|
cmshopee/
|
||||||
├── docs/
|
├── docs/
|
||||||
|
├── app/
|
||||||
|
│ ├── __init__.py
|
||||||
|
│ ├── __main__.py # 支持 python -m app
|
||||||
|
│ ├── cdp.py # CDP 底座(由根目录 cdp.py 迁入)
|
||||||
|
│ ├── appconfig.py / db.py / excel.py / config.py / chrome.py
|
||||||
|
│ ├── editor.py / ai.py / prompts.py / gui.py / workers.py
|
||||||
|
├── main.py # GUI 启动入口:from app.gui import main
|
||||||
├── config.json # 应用配置(模型选择/生成参数/路径,gitignore)
|
├── config.json # 应用配置(模型选择/生成参数/路径,gitignore)
|
||||||
├── config/ai_models.json # AI 模型清单(含密钥,必须 gitignore)
|
├── config/ai_models.json # AI 模型清单(含密钥,必须 gitignore)
|
||||||
├── cmshopee.db # SQLite(账号/任务/结果,gitignore)
|
├── cmshopee.db # SQLite(账号/任务/结果,gitignore)
|
||||||
@@ -357,11 +364,8 @@ cmshopee/
|
|||||||
├── images/ # 旧封面/新封面本地图片(gitignore)
|
├── images/ # 旧封面/新封面本地图片(gitignore)
|
||||||
├── title_prompt.txt # 标题提示词(单文件,启动回显)
|
├── title_prompt.txt # 标题提示词(单文件,启动回显)
|
||||||
├── prompts/cover/<名称>.txt # 封面提示词模板(多个)
|
├── prompts/cover/<名称>.txt # 封面提示词模板(多个)
|
||||||
├── appconfig.py / db.py / excel.py / config.py / chrome.py / editor.py / ai.py / prompts.py / gui.py # 待建
|
|
||||||
├── workers.py # PySide6 worker/QThread 编排(可选拆分)
|
|
||||||
├── cdp.py # CDP 底座(正式模块,已有)
|
|
||||||
└── prototypes/ # 已验证原型/探查脚本(demo/set_*/get_title/cookies/inspect_images/grab/1.py)
|
└── prototypes/ # 已验证原型/探查脚本(demo/set_*/get_title/cookies/inspect_images/grab/1.py)
|
||||||
# 逻辑待并入 editor.py 后清理;见 prototypes/README.md
|
# 逻辑待并入 app/editor.py 后清理;见 prototypes/README.md
|
||||||
```
|
```
|
||||||
|
|
||||||
> `config.json`、`config/ai_models.json`、`cmshopee.db`、`chrome_user_data_dir/`、`images/` 含密钥/凭证/业务数据,必须 gitignore。
|
> `config.json`、`config/ai_models.json`、`cmshopee.db`、`chrome_user_data_dir/`、`images/` 含密钥/凭证/业务数据,必须 gitignore。
|
||||||
@@ -369,6 +373,8 @@ cmshopee/
|
|||||||
## 十、架构纪律
|
## 十、架构纪律
|
||||||
|
|
||||||
- CDP 交互事实变化同步第七节。
|
- CDP 交互事实变化同步第七节。
|
||||||
|
- 正式代码只放 `app/` 包;根目录只保留 `main.py`、配置/数据目录、文档和原型目录,不新增正式业务模块。
|
||||||
|
- `app` 包内模块优先用相对导入(如 `from .cdp import CDP`);根入口 `main.py` 用 `from app.gui import main`。
|
||||||
- 存储边界:应用设置→config.json,账号/任务/结果→SQLite,图片→本地目录并记路径于 DB,登录态→user-data-dir;同一事实只存一处。
|
- 存储边界:应用设置→config.json,账号/任务/结果→SQLite,图片→本地目录并记路径于 DB,登录态→user-data-dir;同一事实只存一处。
|
||||||
- 别名是账号↔任务唯一关联键。
|
- 别名是账号↔任务唯一关联键。
|
||||||
- 密码与 AI Key 本地明文保存、UI 打码、不外传、不写日志;不自动登录。
|
- 密码与 AI Key 本地明文保存、UI 打码、不外传、不写日志;不自动登录。
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
1. **不臆造**:选择器、字段、文件、接口不确定就查证或先用 `prototypes/inspect_images.py` 探查页面,不要猜 class 名。
|
1. **不臆造**:选择器、字段、文件、接口不确定就查证或先用 `prototypes/inspect_images.py` 探查页面,不要猜 class 名。
|
||||||
2. **守范围**:只做当前任务要求的事,不顺手加批量/并行等后续功能。
|
2. **守范围**:只做当前任务要求的事,不顺手加批量/并行等后续功能。
|
||||||
3. **照架构**:复用 `cdp.py`,遵守 `04-architecture.md` 第七节“已验证结论”,不另起一套 CDP 交互。
|
3. **照架构**:复用 `app/cdp.py`(迁移前参考根目录 `cdp.py`),遵守 `04-architecture.md` 第七节“已验证结论”,不另起一套 CDP 交互。
|
||||||
4. **小步改**:一次只解决一个问题,不夹带无关重构。
|
4. **小步改**:一次只解决一个问题,不夹带无关重构。
|
||||||
5. **可验证**:改完必须能 `py_compile`,关键路径能在测试商品上跑通,对得上验收标准。
|
5. **可验证**:改完必须能 `py_compile`,关键路径能在测试商品上跑通,对得上验收标准。
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
- 按链路确认:`vision` -> `requirements` -> `tech-stack` -> `architecture` -> `tasks`。
|
- 按链路确认:`vision` -> `requirements` -> `tech-stack` -> `architecture` -> `tasks`。
|
||||||
- 找到本任务对应的验收标准,写之前就知道“怎么算做对”。
|
- 找到本任务对应的验收标准,写之前就知道“怎么算做对”。
|
||||||
- 复用优先:已有 `cdp.py` 的 `CDP`、`find_product_tab`、`create_tab`、`drag`;已有 `prototypes/demo.py`/`prototypes/set_*.py` 中验证过的 JS 片段。
|
- 复用优先:已有 CDP 底座(T-000 后为 `app/cdp.py`,当前来源为根目录 `cdp.py`)的 `CDP`、`find_product_tab`、`create_tab`、`drag`;已有 `prototypes/demo.py`/`prototypes/set_*.py` 中验证过的 JS 片段。
|
||||||
- 需求含糊或改动会偏离已验证事实时,先问。
|
- 需求含糊或改动会偏离已验证事实时,先问。
|
||||||
|
|
||||||
## 2. 事实来源纪律
|
## 2. 事实来源纪律
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
完成前至少检查:
|
完成前至少检查:
|
||||||
|
|
||||||
- [ ] `python -m py_compile` 通过。
|
- [ ] `python -m compileall app main.py` 通过(T-000 前仅文档改动不要求)。
|
||||||
- [ ] T-006 完成后,纯逻辑改动有对应 `unittest`,至少覆盖正常路径和一个失败路径。
|
- [ ] T-006 完成后,纯逻辑改动有对应 `unittest`,至少覆盖正常路径和一个失败路径。
|
||||||
- [ ] 涉及 CDP 的改动,在测试商品(ITEM_ID 51100639510)上实跑验证。
|
- [ ] 涉及 CDP 的改动,在测试商品(ITEM_ID 51100639510)上实跑验证。
|
||||||
- [ ] 涉及 DB 的改动,覆盖 schema 初始化、重复初始化、短事务写入、失败状态写入。
|
- [ ] 涉及 DB 的改动,覆盖 schema 初始化、重复初始化、短事务写入、失败状态写入。
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
- [ ] 回复里如实说明跑了什么命令、结果如何。
|
- [ ] 回复里如实说明跑了什么命令、结果如何。
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
python -m py_compile *.py
|
python -m compileall app main.py
|
||||||
python -m unittest discover -s tests # T-006 完成且 tests/ 存在后
|
python -m unittest discover -s tests # T-006 完成且 tests/ 存在后
|
||||||
python prototypes/demo.py # 单账号闭环验证(不提交)
|
python prototypes/demo.py # 单账号闭环验证(不提交)
|
||||||
```
|
```
|
||||||
|
|||||||
+8
-7
@@ -23,9 +23,10 @@
|
|||||||
|
|
||||||
| ID | 任务 | 依赖 | 验收要点 | 状态 |
|
| ID | 任务 | 依赖 | 验收要点 | 状态 |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| T-001 | `editor.py`:改标题/换封面/点更新/登录检测/**采集(读旧标题+旧封面下载)**/apply_task,复用 `cdp.py` | - | 函数可调用,在测试商品跑通;与 `prototypes/demo.py` 行为一致 | TODO |
|
| T-000 | 正式代码包结构:创建 `app/`、迁入 `cdp.py` 为 `app/cdp.py`、新增 `app/__init__.py`、`app/__main__.py`、根入口 `main.py`、最小 `app/gui.py` 占位入口,并修正 prototypes 导入 | - | `python -m compileall app main.py` 通过;`python -m app`/`python main.py` 可进入入口(GUI 未完成时给明确提示并退出);`prototypes/demo.py` 可从项目根导入 `app.cdp` | TODO |
|
||||||
| T-002 | `appconfig.py` + `config.json`(含 image_dir、ai 选择/参数段、端口等默认值;不含 AI Key) | - | 读写正常;不存在则写默认;AI Key 留给 `config/ai_models.json`/T-501 | TODO |
|
| T-001 | `app/editor.py`:改标题/换封面/点更新/登录检测/**采集(读旧标题+旧封面下载)**/apply_task,复用 `app/cdp.py` | T-000 | 函数可调用,在测试商品跑通;与 `prototypes/demo.py` 行为一致 | TODO |
|
||||||
| T-003 | `db.py` + SQLite 建表(batches/accounts/tasks,含 Excel 行定位、状态、时间戳、重试字段) | - | `init_db` 幂等;`connect` 设置 WAL/busy_timeout/foreign_keys;账号/批次/任务/各 set_* 可用;schema 同架构 5.2 | TODO |
|
| T-002 | `app/appconfig.py` + `config.json`(含 image_dir、ai 选择/参数段、端口等默认值;不含 AI Key) | T-000 | 读写正常;不存在则写默认;AI Key 留给 `config/ai_models.json`/T-501 | TODO |
|
||||||
|
| T-003 | `app/db.py` + SQLite 建表(batches/accounts/tasks,含 Excel 行定位、状态、时间戳、重试字段) | T-000 | `init_db` 幂等;`connect` 设置 WAL/busy_timeout/foreign_keys;账号/批次/任务/各 set_* 可用;schema 同架构 5.2 | TODO |
|
||||||
| T-004 | `.gitignore`:排除 `config.json`、`config/ai_models.json`、`cmshopee.db`、`chrome_user_data_dir/`、`images/` | T-002, T-003 | 配置、密钥、凭证、业务数据、图片不被提交 | TODO |
|
| T-004 | `.gitignore`:排除 `config.json`、`config/ai_models.json`、`cmshopee.db`、`chrome_user_data_dir/`、`images/` | T-002, T-003 | 配置、密钥、凭证、业务数据、图片不被提交 | TODO |
|
||||||
| T-005 | AI 模型清单后端:`config/ai_models.json` 读写 + category 过滤 + 测试连接 | T-002 | 本地明文 api_key;UI/API 打码显示;日志脱敏;至少 text/image 各一个;`get_model` 返回调用所需字段 | TODO |
|
| T-005 | AI 模型清单后端:`config/ai_models.json` 读写 + category 过滤 + 测试连接 | T-002 | 本地明文 api_key;UI/API 打码显示;日志脱敏;至少 text/image 各一个;`get_model` 返回调用所需字段 | TODO |
|
||||||
| T-006 | 单元测试基座:`tests/` + appconfig/db/excel/prompts 最小测试 | T-002, T-003 | `python -m unittest discover -s tests` 可跑;不依赖真实 Shopee/AI;临时文件在测试目录清理 | TODO |
|
| T-006 | 单元测试基座:`tests/` + appconfig/db/excel/prompts 最小测试 | T-002, T-003 | `python -m unittest discover -s tests` 可跑;不依赖真实 Shopee/AI;临时文件在测试目录清理 | TODO |
|
||||||
@@ -35,7 +36,7 @@
|
|||||||
| ID | 任务 | 依赖 | 验收要点 | 状态 |
|
| ID | 任务 | 依赖 | 验收要点 | 状态 |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| T-101 | `config` 生成 slug + 创建 `chrome_user_data_dir/<slug>` | T-003 | 别名→唯一 slug;目录按需建;路径绝对化 | TODO |
|
| T-101 | `config` 生成 slug + 创建 `chrome_user_data_dir/<slug>` | T-003 | 别名→唯一 slug;目录按需建;路径绝对化 | TODO |
|
||||||
| T-102 | `chrome.py` 启动器:拼参数并启动、探测端口 | T-101, T-002 | 含三参数;端口就绪可探测 | TODO |
|
| T-102 | `app/chrome.py` 启动器:拼参数并启动、探测端口 | T-101, T-002 | 含三参数;端口就绪可探测 | TODO |
|
||||||
| T-103 | 首次登录保活 + 登录检测 `is_logged_in` | T-102, T-001 | 关闭再启动免重登;登录/未登录判断准确 | TODO |
|
| T-103 | 首次登录保活 + 登录检测 `is_logged_in` | T-102, T-001 | 关闭再启动免重登;登录/未登录判断准确 | TODO |
|
||||||
| T-104 | PySide6 五 Tab 主窗口骨架(`QMainWindow` + `QTabWidget`,5 Tab 空壳) | T-002 | 五个 Tab 按顺序可切换;启动不阻塞;基础状态栏可用 | TODO |
|
| T-104 | PySide6 五 Tab 主窗口骨架(`QMainWindow` + `QTabWidget`,5 Tab 空壳) | T-002 | 五个 Tab 按顺序可切换;启动不阻塞;基础状态栏可用 | TODO |
|
||||||
| T-104b | PySide6 worker 基类与线程启动工具(`BaseWorker` + `QThread` 包装) | T-104 | signals: progress/log/row_updated/failed/finished/cancelled;取消标记可用;worker 不直接操作 QWidget | TODO |
|
| T-104b | PySide6 worker 基类与线程启动工具(`BaseWorker` + `QThread` 包装) | T-104 | signals: progress/log/row_updated/failed/finished/cancelled;取消标记可用;worker 不直接操作 QWidget | TODO |
|
||||||
@@ -46,7 +47,7 @@
|
|||||||
|
|
||||||
| ID | 任务 | 依赖 | 验收要点 | 状态 |
|
| ID | 任务 | 依赖 | 验收要点 | 状态 |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| T-201 | `excel.py` 导入:解析多文件输入列入库 | T-003 | 按模板解析账号名/别名/商品id;记录 source_file_abs/source_sheet/source_row/row_key;缺必需列则拒绝整文件并记 file_errors;脏行逐行跳过计 invalid;写 batches/tasks | TODO |
|
| T-201 | `app/excel.py` 导入:解析多文件输入列入库 | T-003 | 按模板解析账号名/别名/商品id;记录 source_file_abs/source_sheet/source_row/row_key;缺必需列则拒绝整文件并记 file_errors;脏行逐行跳过计 invalid;写 batches/tasks | TODO |
|
||||||
| T-202 | Tab① 任务列表 + 导入按钮 + 别名匹配标记 | T-201, T-105 | `QTableView` 显示账号/别名/商品id/阶段;未匹配标“略过” | TODO |
|
| T-202 | Tab① 任务列表 + 导入按钮 + 别名匹配标记 | T-201, T-105 | `QTableView` 显示账号/别名/商品id/阶段;未匹配标“略过” | TODO |
|
||||||
| T-202b | Tab① 导入汇总栏 | T-202 | 导入后显示 文件数/解析行数/有效/无效/匹配(按账号)/未匹配;未匹配可点击筛出 | TODO |
|
| T-202b | Tab① 导入汇总栏 | T-202 | 导入后显示 文件数/解析行数/有效/无效/匹配(按账号)/未匹配;未匹配可点击筛出 | TODO |
|
||||||
| T-203 | 采集旧标题+旧封面(只读),下载图片,立即写库 | T-202, T-001, T-104b | 通过 worker 执行;逐条 set_collected;旧封面下载到 `images/<slug>/`;未登录/未匹配略过记原因 | TODO |
|
| T-203 | 采集旧标题+旧封面(只读),下载图片,立即写库 | T-202, T-001, T-104b | 通过 worker 执行;逐条 set_collected;旧封面下载到 `images/<slug>/`;未登录/未匹配略过记原因 | TODO |
|
||||||
@@ -57,9 +58,9 @@
|
|||||||
|
|
||||||
| ID | 任务 | 依赖 | 验收要点 | 状态 |
|
| ID | 任务 | 依赖 | 验收要点 | 状态 |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| T-301 | 确定 AI 服务商/模型并接入 `ai.py`(`gen_title`/`gen_cover`,带重试/分辨率/jpg质量) | T-005 | 从 `config/ai_models.json` 读取模型与本地明文 Key;`gen_cover` 支持 resolution+jpg_quality;失败按 retry 重试;错误明确;日志脱敏 | TODO |
|
| T-301 | 确定 AI 服务商/模型并接入 `app/ai.py`(`gen_title`/`gen_cover`,带重试/分辨率/jpg质量) | T-005 | 从 `config/ai_models.json` 读取模型与本地明文 Key;`gen_cover` 支持 resolution+jpg_quality;失败按 retry 重试;错误明确;日志脱敏 | TODO |
|
||||||
| T-302 | Tab② 左右布局:左提示词(标题/封面),右按批次/店铺/状态筛选 + 任务列表 | T-301, T-203 | 左 ~1/4 提示词多行;右筛选+列表(店铺/商品id/旧标题/新标题/状态) | TODO |
|
| T-302 | Tab② 左右布局:左提示词(标题/封面),右按批次/店铺/状态筛选 + 任务列表 | T-301, T-203 | 左 ~1/4 提示词多行;右筛选+列表(店铺/商品id/旧标题/新标题/状态) | TODO |
|
||||||
| T-302p | `prompts.py` + Tab② 提示词管理 | T-302 | 标题保存/启动回显 title_prompt.txt;封面多模板(下拉+新建/保存/另存为/重命名/删除,存 prompts/cover/);插入 `{新标题}`;预览变量替换;render_prompt 接入生成 | TODO |
|
| T-302p | `app/prompts.py` + Tab② 提示词管理 | T-302 | 标题保存/启动回显 title_prompt.txt;封面多模板(下拉+新建/保存/另存为/重命名/删除,存 prompts/cover/);插入 `{新标题}`;预览变量替换;render_prompt 接入生成 | TODO |
|
||||||
| T-303 | Tab② 开始生成(单按钮)+ 停止 + 进度:**先并发标题再并发图片** | T-302, T-104b | `generate_batch` 先 title_concurrency 并发标题、再 image_concurrency 并发图片;worker/signal 回传进度;每条 set_generated 立即写库;停止可取消未开始项;进度 标题/封面/失败 计数;双击弹窗看新旧封面 | TODO |
|
| T-303 | Tab② 开始生成(单按钮)+ 停止 + 进度:**先并发标题再并发图片** | T-302, T-104b | `generate_batch` 先 title_concurrency 并发标题、再 image_concurrency 并发图片;worker/signal 回传进度;每条 set_generated 立即写库;停止可取消未开始项;进度 标题/封面/失败 计数;双击弹窗看新旧封面 | TODO |
|
||||||
|
|
||||||
## Phase 4 · 更新 shopee(③)
|
## Phase 4 · 更新 shopee(③)
|
||||||
|
|||||||
+26
-10
@@ -9,7 +9,7 @@
|
|||||||
- 凭证:登录态在 user-data-dir;密码、AI Key 本地明文存于 config/DB;`config.json`、`config/ai_models.json`、`cmshopee.db`、`chrome_user_data_dir/`、`images/` 必须 gitignore;UI 打码显示,不出现在日志/导出。
|
- 凭证:登录态在 user-data-dir;密码、AI Key 本地明文存于 config/DB;`config.json`、`config/ai_models.json`、`cmshopee.db`、`chrome_user_data_dir/`、`images/` 必须 gitignore;UI 打码显示,不出现在日志/导出。
|
||||||
- 失败处理:抛带中文说明的异常或返回状态字段;GUI 负责提示,不静默吞错。
|
- 失败处理:抛带中文说明的异常或返回状态字段;GUI 负责提示,不静默吞错。
|
||||||
|
|
||||||
## appconfig 模块(`appconfig.py`,待建)
|
## appconfig 模块(`app/appconfig.py`,待建)
|
||||||
|
|
||||||
读写 `config.json`(schema 见 [架构 5.1](04-architecture.md))。
|
读写 `config.json`(schema 见 [架构 5.1](04-architecture.md))。
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ test_ai_model(name) -> dict # 「测试连接」:用 key/url
|
|||||||
get_model(name) -> dict # 返回模型定义,含 api_key(调用方不得写日志)
|
get_model(name) -> dict # 返回模型定义,含 api_key(调用方不得写日志)
|
||||||
```
|
```
|
||||||
|
|
||||||
## db 模块(`db.py`,待建)
|
## db 模块(`app/db.py`,待建)
|
||||||
|
|
||||||
SQLite 读写,表见 [架构 5.2](04-architecture.md)。
|
SQLite 读写,表见 [架构 5.2](04-architecture.md)。
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ SQLite 连接规则:
|
|||||||
- `connect()` 必须设置 `PRAGMA foreign_keys=ON`、`journal_mode=WAL`、`busy_timeout=5000`、`synchronous=NORMAL`。
|
- `connect()` 必须设置 `PRAGMA foreign_keys=ON`、`journal_mode=WAL`、`busy_timeout=5000`、`synchronous=NORMAL`。
|
||||||
- DB 写入短事务、单条提交;Excel 回写失败不回滚 DB。
|
- DB 写入短事务、单条提交;Excel 回写失败不回滚 DB。
|
||||||
|
|
||||||
## excel 模块(`excel.py`,待建,依赖 openpyxl)
|
## excel 模块(`app/excel.py`,待建,依赖 openpyxl)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import_tasks(file_paths: list[str]) -> dict
|
import_tasks(file_paths: list[str]) -> dict
|
||||||
@@ -91,14 +91,14 @@ export_copy(batch_id, out_dir_or_path) -> dict # 退路:另存新结果
|
|||||||
|
|
||||||
列模板见 [架构 5.3](04-architecture.md);别名以“别名”列为权威。
|
列模板见 [架构 5.3](04-architecture.md);别名以“别名”列为权威。
|
||||||
|
|
||||||
## config 模块(`config.py`,待建)
|
## config 模块(`app/config.py`,待建)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
make_slug(alias) -> str # 别名→唯一 slug [a-z0-9_]
|
make_slug(alias) -> str # 别名→唯一 slug [a-z0-9_]
|
||||||
ensure_user_data_dir(slug) -> str # chrome_user_data_dir/<slug> 绝对路径,按需创建
|
ensure_user_data_dir(slug) -> str # chrome_user_data_dir/<slug> 绝对路径,按需创建
|
||||||
```
|
```
|
||||||
|
|
||||||
## chrome 模块(`chrome.py`,待建)
|
## chrome 模块(`app/chrome.py`,待建)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
build_launch_args(account) -> list[str] # chrome + --remote-debugging-port + --remote-allow-origins=* + --user-data-dir
|
build_launch_args(account) -> list[str] # chrome + --remote-debugging-port + --remote-allow-origins=* + --user-data-dir
|
||||||
@@ -108,7 +108,7 @@ is_running(port) -> bool
|
|||||||
create_shortcut(account, dest_dir=None) -> str # 可选 .lnk,PowerShell WScript.Shell
|
create_shortcut(account, dest_dir=None) -> str # 可选 .lnk,PowerShell WScript.Shell
|
||||||
```
|
```
|
||||||
|
|
||||||
## cdp 模块(`cdp.py`,已实现)
|
## cdp 模块(`app/cdp.py`,T-000 由根目录 `cdp.py` 迁入)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
CDP_HOST: str
|
CDP_HOST: str
|
||||||
@@ -116,7 +116,7 @@ http_get(path); find_product_tab(item_id); create_tab(url)
|
|||||||
class CDP: send/ev/val/object_id/drag/close # suppress_origin、trust_env=False
|
class CDP: send/ev/val/object_id/drag/close # suppress_origin、trust_env=False
|
||||||
```
|
```
|
||||||
|
|
||||||
## editor 模块(`editor.py`,待建,重构自现有脚本)
|
## editor 模块(`app/editor.py`,待建,重构自现有脚本)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
is_logged_in(account) -> bool # 重定向登录页或缺 SPC_ST → False
|
is_logged_in(account) -> bool # 重定向登录页或缺 SPC_ST → False
|
||||||
@@ -136,7 +136,7 @@ apply_task(account, task) -> dict # 对已生成任务:换标题+
|
|||||||
# -> {committed, error}
|
# -> {committed, error}
|
||||||
```
|
```
|
||||||
|
|
||||||
## ai 模块(`ai.py`,待建,外部 AI,服务商待定)
|
## ai 模块(`app/ai.py`,待建,外部 AI,服务商待定)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
gen_title(title_prompt, old_title, retry=2) -> str
|
gen_title(title_prompt, old_title, retry=2) -> str
|
||||||
@@ -160,7 +160,7 @@ generate_batch(tasks, prompts, ai_cfg, on_progress, should_stop) -> None
|
|||||||
- 调用有成本与失败可能:超时、限流、内容安全拒绝都要返回明确错误。
|
- 调用有成本与失败可能:超时、限流、内容安全拒绝都要返回明确错误。
|
||||||
- 生成结果**直接进入 ③ 更新候选**;③ 点击「开始更新」后弹窗批量确认,确认后提交线上。本地留档 + 回写 Excel 供追溯。
|
- 生成结果**直接进入 ③ 更新候选**;③ 点击「开始更新」后弹窗批量确认,确认后提交线上。本地留档 + 回写 Excel 供追溯。
|
||||||
|
|
||||||
## prompts 模块(`prompts.py`,待建)
|
## prompts 模块(`app/prompts.py`,待建)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# 标题提示词:单文件
|
# 标题提示词:单文件
|
||||||
@@ -185,7 +185,7 @@ render_prompt(template_text, task) -> str
|
|||||||
- 生成封面时 `gen_cover` 的 prompt = `render_prompt(当前封面模板, task)`。
|
- 生成封面时 `gen_cover` 的 prompt = `render_prompt(当前封面模板, task)`。
|
||||||
- 模板与 `title_prompt.txt` 均为可手改的纯文本文件。
|
- 模板与 `title_prompt.txt` 均为可手改的纯文本文件。
|
||||||
|
|
||||||
## gui / workers 模块(`gui.py` / `workers.py`,待建,PySide6)
|
## gui / workers 模块(`app/gui.py` / `app/workers.py`,待建,PySide6)
|
||||||
|
|
||||||
```python
|
```python
|
||||||
# GUI 入口
|
# GUI 入口
|
||||||
@@ -212,6 +212,22 @@ run_worker(worker: BaseWorker) -> QThread # 绑定 signals、启动、收尾 d
|
|||||||
- 每个 worker/线程按需创建自己的 SQLite connection,不跨线程共享连接。
|
- 每个 worker/线程按需创建自己的 SQLite connection,不跨线程共享连接。
|
||||||
- ③ 的批量确认弹窗在 GUI 主线程完成;用户确认后才创建 `ApplyWorker`。
|
- ③ 的批量确认弹窗在 GUI 主线程完成;用户确认后才创建 `ApplyWorker`。
|
||||||
|
|
||||||
|
## 启动入口
|
||||||
|
|
||||||
|
```python
|
||||||
|
# main.py
|
||||||
|
from app.gui import main
|
||||||
|
|
||||||
|
raise SystemExit(main())
|
||||||
|
|
||||||
|
# app/__main__.py
|
||||||
|
from .gui import main
|
||||||
|
|
||||||
|
raise SystemExit(main())
|
||||||
|
```
|
||||||
|
|
||||||
|
正式运行入口:`python main.py`;开发/包入口:`python -m app`。
|
||||||
|
|
||||||
## CLI / 触发合约(现有脚本,过渡期保留)
|
## CLI / 触发合约(现有脚本,过渡期保留)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
- 日期:2026-06-26
|
- 日期:2026-06-26
|
||||||
- 阶段:V0 单账号 CDP 流程已验证;V1 多账号管理 + 5 Tab GUI + Excel/AI 流水线为既定设计,尚未开始编码。
|
- 阶段:V0 单账号 CDP 流程已验证;V1 多账号管理 + 5 Tab GUI + Excel/AI 流水线为既定设计,尚未开始编码。
|
||||||
- 技术栈:Python 3.10+,自研 CDP(websocket-client + requests),SQLite(sqlite3)+ `config.json` + openpyxl + AI(服务商待定),GUI PySide6 5 Tab(已定)。
|
- 技术栈:Python 3.10+,自研 CDP(websocket-client + requests),SQLite(sqlite3)+ `config.json` + openpyxl + AI(服务商待定),GUI PySide6 5 Tab(已定)。
|
||||||
- 生产代码:尚无 `appconfig/db/excel/config/chrome/editor/gui/workers`;现有为验证脚本 + `cdp.py`。
|
- 生产代码:正式目标为 `app/` 包 + 根入口 `main.py`,尚未创建;现有根目录 `cdp.py` 是已验证 CDP 底座,待 T-000 迁入 `app/cdp.py`。
|
||||||
- 测试:当前以 `py_compile` + 在测试商品上手动跑 `prototypes/demo.py` 为主;`tests/` 与 `python -m unittest discover -s tests` 由 T-006 建立,T-006 完成前不把缺少 `tests/` 视为验证失败。
|
- 测试:当前以 `py_compile` + 在测试商品上手动跑 `prototypes/demo.py` 为主;`tests/` 与 `python -m unittest discover -s tests` 由 T-006 建立,T-006 完成前不把缺少 `tests/` 视为验证失败。
|
||||||
- 数据:无 `config.json`、`config/ai_models.json`、`cmshopee.db`、`chrome_user_data_dir/`、`images/`(待 Phase 0/1 建立,均须 gitignore)。
|
- 数据:无 `config.json`、`config/ai_models.json`、`cmshopee.db`、`chrome_user_data_dir/`、`images/`(待 Phase 0/1 建立,均须 gitignore)。
|
||||||
|
|
||||||
@@ -28,10 +28,11 @@
|
|||||||
| 路径 | 状态 | 说明 |
|
| 路径 | 状态 | 说明 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `docs/` | 已有 | 本 harness coding 文档集合 |
|
| `docs/` | 已有 | 本 harness coding 文档集合 |
|
||||||
| `cdp.py` | 已有 | CDP 底座:连接/找 tab/开 tab/执行 JS/拖拽(正式模块,留根目录) |
|
| `cdp.py` | 已有 | 已验证 CDP 底座来源;T-000 迁入 `app/cdp.py` 后根目录不再放正式业务模块 |
|
||||||
| `prototypes/` | 已有 | 已验证原型/探查脚本(demo/set_title/set_cover/get_title/cookies/inspect_images/grab/1.py),逻辑待并入 `editor.py` 后清理;见 `prototypes/README.md` |
|
| `prototypes/` | 已有 | 已验证原型/探查脚本(demo/set_title/set_cover/get_title/cookies/inspect_images/grab/1.py),逻辑待并入 `app/editor.py` 后清理;见 `prototypes/README.md` |
|
||||||
| `chrome-remote-debug-lan.md` | 已有 | WSL→Windows CDP 转发排查记录 |
|
| `chrome-remote-debug-lan.md` | 已有 | WSL→Windows CDP 转发排查记录 |
|
||||||
| `appconfig.py` / `db.py` / `excel.py` / `config.py` / `chrome.py` / `editor.py` / `gui.py` / `workers.py` | 待建 | Phase 0-3 产出 |
|
| `app/` / `main.py` | 待建 | 正式代码包与启动入口;T-000 产出 |
|
||||||
|
| `app/appconfig.py` / `app/db.py` / `app/excel.py` / `app/config.py` / `app/chrome.py` / `app/editor.py` / `app/gui.py` / `app/workers.py` | 待建 | Phase 0-3 产出 |
|
||||||
| `config.json` / `config/ai_models.json` / `cmshopee.db` / `chrome_user_data_dir/` / `images/` | 待建 | 含配置、密钥、业务、登录态、图片,须 gitignore |
|
| `config.json` / `config/ai_models.json` / `cmshopee.db` / `chrome_user_data_dir/` / `images/` | 待建 | 含配置、密钥、业务、登录态、图片,须 gitignore |
|
||||||
|
|
||||||
## 已验证能力(单账号)
|
## 已验证能力(单账号)
|
||||||
@@ -48,19 +49,19 @@
|
|||||||
|
|
||||||
- 已完成:无(任务均为 TODO;单账号能力以脚本形式存在,待 T-001 模块化)。
|
- 已完成:无(任务均为 TODO;单账号能力以脚本形式存在,待 T-001 模块化)。
|
||||||
- 正在进行:无。
|
- 正在进行:无。
|
||||||
- 下一个可领取任务:**T-001(`editor.py`:改标题/换封面/点更新/登录检测/采集/apply_task)**。虽然 T-002/T-003 也无依赖,但任务领取规则固定为“取 `06-tasks.md` 中第一个 TODO 且依赖均 DONE 的任务”,因此当前不能任选。
|
- 下一个可领取任务:**T-000(正式代码包结构)**。先创建 `app/`、迁入 `cdp.py`、新增 `main.py`/`app/__main__.py`,再开始 T-001/T-002/T-003。
|
||||||
|
|
||||||
## 当前可运行内容
|
## 当前可运行内容
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 语法检查
|
# 语法检查(T-000 后)
|
||||||
python -m py_compile *.py
|
python -m compileall app main.py
|
||||||
|
|
||||||
# 单元测试(T-006 完成且 tests/ 存在后)
|
# 单元测试(T-006 完成且 tests/ 存在后)
|
||||||
python -m unittest discover -s tests
|
python -m unittest discover -s tests
|
||||||
|
|
||||||
# 单账号闭环(不提交线上)
|
# 单账号闭环(不提交线上)
|
||||||
python prototypes/demo.py # 分步(需根目录 cdp.py 可导入)
|
python prototypes/demo.py # 分步(T-000 后从项目根导入 app.cdp)
|
||||||
set AUTO=1 && python prototypes/demo.py # 自动(cmd)
|
set AUTO=1 && python prototypes/demo.py # 自动(cmd)
|
||||||
|
|
||||||
# 真实提交(谨慎)
|
# 真实提交(谨慎)
|
||||||
|
|||||||
+11
@@ -213,4 +213,15 @@
|
|||||||
- Excel 导入容错定稿:必需列缺失(别名/商品id)时拒绝整个文件;单行缺值或商品id格式错误等脏数据逐行跳过,计入 invalid,不阻塞同文件其他有效行。
|
- Excel 导入容错定稿:必需列缺失(别名/商品id)时拒绝整个文件;单行缺值或商品id格式错误等脏数据逐行跳过,计入 invalid,不阻塞同文件其他有效行。
|
||||||
- 下一步:按任务看板领取 T-001。
|
- 下一步:按任务看板领取 T-001。
|
||||||
|
|
||||||
|
## 【2026-06-26】决策 · 正式代码迁入 app 包
|
||||||
|
|
||||||
|
- 状态:DONE(仅文档)
|
||||||
|
- 变更:更新 `AGENTS.md`、`docs/00-ai-start-here.md`、`docs/03-tech-stack.md`、`docs/04-architecture.md`、`docs/05-coding-rules.md`、`docs/06-tasks.md`、`docs/current-state.md`、`docs/api.md`、`prototypes/README.md`。
|
||||||
|
- 决策:
|
||||||
|
- 正式代码统一放入 `app/` 包,根目录只保留 `main.py`、配置/数据目录、文档和原型目录。
|
||||||
|
- `cdp.py` 由根目录迁入 `app/cdp.py`;包内模块优先使用相对导入,根入口使用 `from app.gui import main`。
|
||||||
|
- 新增 T-000 作为首个任务:创建 `app/`、迁移 CDP、补 `app/__main__.py` 和 `main.py`,并修正 `prototypes/demo.py` 导入。
|
||||||
|
- 正式启动入口为 `python main.py`,开发/包入口为 `python -m app`。
|
||||||
|
- 下一步:按任务看板领取 T-000。
|
||||||
|
|
||||||
<!-- 新一轮从这里向下追加记录。 -->
|
<!-- 新一轮从这里向下追加记录。 -->
|
||||||
|
|||||||
@@ -1,25 +1,24 @@
|
|||||||
# prototypes —— 已验证原型 / 探查脚本
|
# prototypes —— 已验证原型 / 探查脚本
|
||||||
|
|
||||||
这些是单账号阶段写的**已验证脚本**,逻辑与关键事实将被正式模块(尤其 `editor.py`,见任务 T-001)移植。
|
这些是单账号阶段写的**已验证脚本**,逻辑与关键事实将被正式模块(尤其 `app/editor.py`,见任务 T-001)移植。
|
||||||
**待 `editor.py` 完成并实测通过后,本目录可清理删除。** 在此之前保留它们作为"唯一已验证参照"。
|
**待 `app/editor.py` 完成并实测通过后,本目录可清理删除。** 在此之前保留它们作为"唯一已验证参照"。
|
||||||
|
|
||||||
## 文件
|
## 文件
|
||||||
|
|
||||||
| 文件 | 用途 | 移植去向 |
|
| 文件 | 用途 | 移植去向 |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `demo.py` | 单账号端到端:改标题 + 换封面(UPDATE=1 提交) | `editor.py` 编排 |
|
| `demo.py` | 单账号端到端:改标题 + 换封面(UPDATE=1 提交) | `app/editor.py` 编排 |
|
||||||
| `set_title.py` | 改标题(原生 setter + 事件,value/modelvalue 验证) | `editor.change_title` |
|
| `set_title.py` | 改标题(原生 setter + 事件,value/modelvalue 验证) | `editor.change_title` |
|
||||||
| `set_cover.py` | 上传图片 + 拖到第一位设封面(含选择器、拖拽落点) | `editor.replace_cover` |
|
| `set_cover.py` | 上传图片 + 拖到第一位设封面(含选择器、拖拽落点) | `editor.replace_cover` |
|
||||||
| `get_title.py` | 找/开商品 tab 并读取标题 | `editor.open_product` / `read_title` |
|
| `get_title.py` | 找/开商品 tab 并读取标题 | `editor.open_product` / `read_title` |
|
||||||
| `cookies.py` | 读 shopee.tw 标签页 Cookie/会话 | `editor.is_logged_in` 的依据 |
|
| `cookies.py` | 读 shopee.tw 标签页 Cookie/会话 | `editor.is_logged_in` 的依据 |
|
||||||
| `inspect_images.py` | 只读探查图片管理器 DOM(**Shopee 改版时重新探查可复用**) | 工具,保留参考 |
|
| `inspect_images.py` | 只读探查图片管理器 DOM(**Shopee 改版时重新探查可复用**) | 工具,保留参考 |
|
||||||
| `grab.py` | 抓商品页 HTML + 列表接口 JSON(早期探查) | 参考 |
|
| `grab.py` | 抓商品页 HTML + 列表接口 JSON(早期探查) | 参考 |
|
||||||
| `1.py` | OpenAI SDK 最小调用测试 | `ai.py` 调用方式参考 |
|
| `1.py` | OpenAI SDK 最小调用测试 | `app/ai.py` 调用方式参考 |
|
||||||
|
|
||||||
## 运行注意
|
## 运行注意
|
||||||
|
|
||||||
- **`cdp.py` 在项目根目录**(正式模块),不在本目录。
|
- T-000 后正式 CDP 底座在 `app/cdp.py`;`demo.py` 从项目根运行并导入 `app.cdp`。
|
||||||
- 仅 `demo.py` `import cdp`;其余脚本各自内置了 CDP 类,可独立运行。
|
- 其余脚本各自内置了 CDP 类,可独立运行。
|
||||||
- 跑 `demo.py` 需让根目录的 `cdp.py` 可被导入(从项目根运行,或设 `PYTHONPATH=项目根`)。
|
|
||||||
- 这些脚本默认连开发期的 WSL 转发地址 `192.168.0.224:9333`;正式模块用 `127.0.0.1:9222`(可用 `CDP_HOST` 覆盖)。
|
- 这些脚本默认连开发期的 WSL 转发地址 `192.168.0.224:9333`;正式模块用 `127.0.0.1:9222`(可用 `CDP_HOST` 覆盖)。
|
||||||
- 已验证的关键事实(选择器、SPA 就绪判断、上传/拖拽方式)权威记录见 [`../docs/04-architecture.md`](../docs/04-architecture.md) 第七节。
|
- 已验证的关键事实(选择器、SPA 就绪判断、上传/拖拽方式)权威记录见 [`../docs/04-architecture.md`](../docs/04-architecture.md) 第七节。
|
||||||
|
|||||||
Reference in New Issue
Block a user