Files
cmshoppe/docs/routes.md
T
chengma 598df5f20b feat: 完成Tab④账号管理
- 新增 accounts 服务层,封装账号 CRUD、目录创建、端口分配与登录检测

- 接入 PySide6 账号管理 Tab:表格、账号弹窗、启动登录、后台检测登录

- 密码仅本地保存并在 UI 打码,表格不展示明文;不自动登录或填密码

- 增加顶部 Tab 栏防误点样式,扩大点击区域并高亮当前 Tab

- 补充账号服务和 GUI 单元测试,并同步架构、API、路由、任务和进度文档
2026-06-27 10:30:45 +08:00

158 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 界面与流程结构
> 桌面工具,无前端路由。用 **5 Tab GUI(PySide6 `QMainWindow` + `QTabWidget`)+ 流水线** 约定界面职责与导航。
## Tab 顺序与职责(工作流优先)
```
① 导入采集 │ ② AI生成 │ ③ 更新shopee │ ④ 账号管理 │ ⑤ 设置
```
| Tab | 职责 | 风险 |
| --- | --- | --- |
| ① 导入采集 | 导入多个 Excel;任务列表;**采集**商品当前的旧标题/旧封面(只读),封面图下载本地;回写 Excel 旧字段 | 只读,低 |
| ② AI生成 | 左侧标题/封面**提示词**;右侧按批次/店铺筛选任务列表;AI 生成新标题/新封面;双击看新旧封面 | 不触线上,中 |
| ③ 更新shopee | 对**已生成**任务点击「开始更新」后弹窗确认;确认后打开编辑页换标题+封面并逐条点「更新」提交;结果回写 Excel | **写线上,高** |
| ④ 账号管理 | Shopee 账号(账号名/别名/数据目录/端口/密码本地明文仅参考/登录状态);启动登录、检测登录、生成快捷方式 | 中 |
| ⑤ 设置 | AI 模型/API Key、本地图片目录、Chrome 路径、默认端口等 | — |
任务的**阶段状态**贯穿各 Tab:`imported → collected → generated → applied`(或 `failed/skipped`)。② 不设逐条人工确认阶段;③ 无常驻提交开关,但点击「开始更新」后必须弹窗确认当前筛选范围和任务数量。各 Tab 聚焦各自阶段的列与按钮,但操作同一批任务(同一 batch)。
## 全局 Tab 栏可用性
5 个主 Tab 是高频导航入口,不能使用 Qt 默认的紧凑宽度。`MainWindow` 必须为 `QTabWidget/QTabBar` 设置基础样式:
- 每个 Tab 设置稳定最小宽度和足够左右 padding,避免文字贴边或窄到误点。
- Tab 之间保留明显间距,当前 Tab 有清晰背景/边框高亮。
- 样式只影响顶层主 Tab,不改变各业务表格、弹窗和后续 Tab 内部布局。
- 新增业务 Tab 内容时不得缩小主 Tab 栏点击区域。
## 首次使用引导保护
- ① 导入采集 与 ③ 更新shopee 都依赖**账号已配置且已登录**(在 ④ 账号管理)。
- 当无账号 / 账号未登录时:相关执行按钮**禁用**,并提示「请先到『账号管理』配置账号并登录」。
- 老用户账号已就绪则无感。
## ① 导入采集
```
┌ 导入采集 ─────────────────────────────────────────────────────┐
│ [导入 Excel…] [移除] [清空] │
│ ▸ 3 文件 · 128 行 · 有效125/无效3 · 匹配123 · 未匹配5⚠ │ ← 导入汇总栏
│ 匹配明细:女装店60 · my主店40 · 饰品店23 │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 账号名 别名 商品ID 阶段 旧标题 旧封面 │ │
│ │ 主店A 女装店 51100639510 待采集 — — │ │
│ └───────────────────────────────────────────────────────────┘ │
│ [▶ 采集旧标题/旧封面] [■停止] [回写旧数据到 Excel] │
│ 日志:逐条 文件→匹配账号、采集结果 │
└───────────────────────────────────────────────────────────────┘
```
- 导入:openpyxl 解析**输入列**(账号名/别名/商品id)入 SQLite。
- **导入汇总栏**(导入后即时刷新,跑采集前的校验关口):显示 文件数、解析行数(原始数据量)、有效/无效行、匹配账号行数(按账号细分)、未匹配行数。未匹配/无效数字标红可点,点击在列表筛出便于定位纠错。
- 采集:用该账号 Chrome 只读打开商品页,读旧标题、下载旧封面到本地图片目录,写 `old_title/old_cover_path`,stage=collected。
- 回写:采集完把旧标题/旧封面路径批量回写原 Excel(原文件被锁→提示重试/另存)。
- 别名未匹配账号 / 账号未登录 → 该行 skipped 并记原因。
## ② AI生成
左右布局:左侧约 1/4 放提示词,右侧放筛选 + 任务列表。
```
┌ AI生成 ───────────────────────────────────────────────────────┐
│ ┌─左 ~1/4─┐ ┌──────────────── 右 3/4 ──────────────────────┐ │
│ │标题提示词│ │ 批次[本次▼] 店铺[全部▼] 状态[全部▼] [筛选] │ │
│ │[ ]│ │ ┌──────────────────────────────────────────┐ │ │
│ │[ ]│ │ │ 店铺名 商品id 旧标题 新标题 状态 │ │ │
│ │ │ │ │ 女装店 511..639 …T恤 …百搭 已生成 │ │ │
│ │封面提示词│ │ │ 女装店 511..640 … — 待生成 │ │ │
│ │[ ]│ │ └──────────────────────────────────────────┘ │ │
│ │[ ]│ │ (双击某行 → 弹窗看 旧封面 | 新封面) │ │
│ └──────────┘ └───────────────────────────────────────────────┘ │
│ 进度:标题30/30 · 封面12/30 · 失败1 [▶ 开始生成] [■停止] │
└───────────────────────────────────────────────────────────────┘
```
- 左侧(提示词管理,上下两块):
- **标题提示词**:多行输入 + 「保存」(写 `title_prompt.txt`);启动时自动加载回显。
- **封面提示词**:模板下拉(读 `prompts/cover/*.txt`)+ 图标工具栏(新建/保存/另存为/重命名/删除)+ 多行输入 + 「插入标题」(插 `{新标题}`)/「预览」(变量替换后查看)。
- 变量:`{旧标题}`/`{新标题}`/`{商品id}`/`{店铺}`,生成前按任务替换。
- 右上:按导入批次 / 店铺 / 状态筛选任务。
- 右下:任务列表(店铺名、商品id、旧标题、新标题、状态);**双击某条 → 弹窗展示旧封面 | 新封面**(纯查看)。
- 底部**单个「开始生成」+「停止」**:开始生成 = **先按 `title_concurrency` 并发生成标题,接着按 `image_concurrency` 并发生成封面**;进度实时显示 标题/封面/失败 计数。
- 生成参数(标题/图片并发数、失败重试、分辨率、jpg 质量、模型/Key)在 **⑤ 设置**,不在本 Tab 重复。
- 每条/每张完成即写库;「停止」取消未开始项,可再次「开始生成」对剩余继续。
- **无逐条人工审核环节**;新标题直接用 AI 输出(不可编辑);可选对单行 `重生成`。生成完即可进入 ③,③ 开始更新前会做批量确认。
## ③ 更新shopee
```
┌ 更新shopee ───────────────────────────────────────────────────┐
│ 批次[本次▼] 店铺[全部▼] 状态[已生成▼] [筛选] │
│ ⚠ 点击「开始更新」后确认【当前筛选结果】,确认后改标题+换封面并提交 │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 店铺 商品ID 新标题 新封面 阶段 结果 │ │
│ └───────────────────────────────────────────────────────────┘ │
│ [▶ 开始更新] [■停止] [回写结果到 Excel] │
└───────────────────────────────────────────────────────────────┘
```
- 顶部**按批次 / 店铺 / 状态筛选**(与 ①②一致);「开始更新」作用于**当前筛选结果**,是一道范围控制。
- 店铺筛选:建议**逐店铺更新**(每店铺需先启动其 Chrome 并登录)。
- 状态筛选:`已生成` 只跑未更新的;`失败` 用于**失败重试**;`已更新成功/略过` 仅查看。
- 点击「开始更新」后弹窗展示本次筛选条件、任务数量和“将提交线上”的风险提示;用户点「是/确认」才开始,点「否/取消」不执行。
- 对确认后的**已生成(generated)任务**执行:打开编辑页换标题+换封面 → 点「更新」提交。
- 串行、单条失败继续;每条立即写回 SQLite(committed/状态/error)。
- 全部完成 → 把新标题/新封面/更新状态批量回写原 Excel;弹窗汇总。
## ④ 账号管理
```
┌ 账号管理 ─────────────────────────────────────────────────────┐
│ 账号名 别名 地区 端口 登录状态 备注 │
│ 主店A 女装店 seller.shopee.tw 9222 ●已登录 │
│ [+新增][✎编辑][🗑删除] [▶启动并登录][🔄检测登录][⧉快捷方式] │
└───────────────────────────────────────────────────────────────┘
```
账号弹窗字段:账号名、别名(唯一,Excel 用它匹配)、地区域名、调试端口、密码(本地明文仅参考,UI 打码,不自动登录)、备注;配置目录按别名生成 slug 只读显示。
## ⑤ 设置
- AI:服务商 / 文本模型 / 图像模型 / API Key(本地明文存,UI 打码,不入日志)。
- AI 生成参数:**标题并发数、图片并发数、失败重试次数、分辨率、jpg 质量**。
- 本地图片目录(旧封面下载、新封面生成的存放根目录)。
- Chrome 路径、默认调试端口 / 端口范围、超时、DB 路径。
## 流程导航
```text
④ 账号管理:配账号 + 启动登录(首次必做)
│
① 导入采集:导入 Excel → 采集旧标题/旧封面 → 回写旧字段
│
② AI生成:提示词 → 生成新标题/新封面(无逐条审核)
│
③ 更新shopee:对已生成任务点击开始更新 → 弹窗确认 → 换标题+封面 → 点「更新」提交 → 回写结果
```
- 未配账号/未登录:① ③ 的执行按钮禁用并提示去 ④。
- 已生成的任务即可进 ③;③ 用户确认批量弹窗后提交线上,无常驻提交开关。
- 任意步骤失败:记入该任务、日志标明,不影响其他任务。
## 组件建议(PySide6)
| 组件 | 归属 | 说明 |
| --- | --- | --- |
| `MainWindow(QMainWindow)` | 根窗口 | 持有 `QTabWidget`、状态栏、全局消息 |
| `CollectTab(QWidget)` | ① | 导入、任务表、采集、回写 |
| `GenerateTab(QWidget)` | ② | 左提示词 + 右筛选/任务列表、双击看新旧封面、开始生成 |
| `ApplyTab(QWidget)` | ③ | 已生成任务、开始更新确认、换标题+封面+提交、回写 |
| `AccountsTab(QWidget)` | ④ | 账号增删改、启动登录 |
| `SettingsTab(QWidget)` | ⑤ | AI/目录/Chrome 配置 |
| `TaskTableModel(QAbstractTableModel)` | ①②③ | 任务表格数据模型,供 `QTableView` 使用 |
| `BaseWorker(QObject)` | 后台 | 定义 `progress/log/row_updated/failed/finished/cancelled` signals |
> 采集、生成、更新都是耗时操作,使用 `QObject` worker + `QThread`。Worker 不直接操作 QWidget,只通过 signal 通知主线程刷新 UI。