Files
cmbuyer/docs/routes.md
T

161 lines
8.7 KiB
Markdown
Raw Normal View History

# 路由与页面结构
> 采购服务使用服务端渲染;采购工具使用固定 tab 的 Windows 桌面外壳。交互细节以
> [08-interaction-checklist.md](08-interaction-checklist.md) 为准。
## 一、采购服务页面路由
| 方法 | 路径 | 页面 / 动作 | 身份 |
| --- | --- | --- | --- |
| `GET` | `/login` | 登录页 | 匿名 |
| `POST` | `/login` | 建立会话 | 匿名 + CSRF |
| `POST` | `/logout` | 退出 | 管理员 + CSRF |
| `GET` | `/tasks` | 采购任务表格、筛选、批量选择和创建入口 | 管理员 |
| `GET` | `/tasks/new` | 无 JS 时的创建表单;有 JS 时装入对话框 | 管理员 |
| `POST` | `/tasks` | 创建 `DRAFT` | 管理员 + CSRF |
| `POST` | `/tasks/start-purchases` | 批量开始采购并签发一次性授权 | 管理员 + CSRF |
| `GET` | `/tasks/{id}` | 完整任务详情;也作为列表抽屉的可复制 URL | 管理员 |
| `POST` | `/tasks/{id}/reset-to-draft` | 围栏前人工处理后回待开始 | 管理员 + CSRF |
| `POST` | `/tasks/{id}/cancel` | 围栏前取消 | 管理员 + CSRF |
| `POST` | `/tasks/{id}/mark-paid` | 记录人工已付款并完成 | 管理员 + CSRF |
| `POST` | `/order-submissions/{sid}/reconcile` | 围栏后调和同一提交 | 管理员 + CSRF |
| `GET` | `/evidence/{asset_id}` | 受保护内部截图 | 管理员;不缓存 |
设备 JSON API 不属于页面路由,见 [api.md](api.md)。
## 二、采购任务工作台 `/tasks`
页面标题:**采购服务**。
表格上方两行:
1. 第一行:导入(disabled 占位)、创建按钮;存在选择时显示上下文批量操作条。
2. 第二行:标题关键词输入框(默认筛选)、其他可选筛选,右侧“筛选”“清除”。
表格字段:
| 字段 | 行为 |
| --- | --- |
| checkbox | 只允许选择 `DRAFT`;表头全选当前筛选结果中的可选行 |
| 标题 | `<a>` 指向 canonical 拼多多商品页;点击链接不触发行详情 |
| 颜色 | 任务目标颜色 |
| 尺码 | 任务目标尺码 |
| 价格 | 任务最高总价;执行后详情另列实际闸门金额 |
| 数量 | 正整数 |
| 采购结果 | 用 `颜色|尺码|价格|数量` 展示已执行摘要;无结果显示 `—` |
| 状态 | 中文状态徽标,不只靠颜色 |
| 创建时间 | 本地时区显示,数据按 UTC 保存 |
没有操作列。双击非控件区域或键盘 Enter 打开 `/tasks/{id}` 路由化详情抽屉;新 tab 直接访问同 URL
则显示完整详情页。标题下方同时提供可见“查看详情”按钮,双击不是唯一入口。商品外链、checkbox、
输入和按钮本身不触发行双击。抽屉成功加载后才把 URL 推进 `/tasks/{id}`;关闭、Esc 或浏览器返回
恢复筛选、滚动和触发行焦点,浏览器前进重新打开同一详情且不重复写 history。
### 批量开始采购
选择 `DRAFT` 后,表格前的上下文操作条显示:
- 已选条数;
- 所选最高总价合计;
- “将授权采购工具逐条创建待付款订单,系统不会付款”;
- 主按钮“开始采购(只创建待付款订单)”。
点击即为最终授权,不另弹“机器选对了吗”的同义确认框。整批全有或全无;成功更新 `PENDING`,
冲突时保持页面现场并要求刷新重选。
### 创建任务
字段:标题、拼多多商品链接、颜色分类、尺码、最高总价、数量。保存成功后关闭对话框,新任务插到
首行且状态为待开始;创建本身不授权、不领取、不执行。
## 三、任务详情 `/tasks/{id}`
详情按状态展示同一条单趟采购的事实,而不是审批流程:
1. 任务要求:商品链接 / goods_id、颜色、尺码、数量、最高总价、版本。
2. 开始采购授权:授权 id、授权人、锁定任务版本、创建/有效期、当前状态。
3. 设备执行:attempt、设备、App 版本、步骤时间线和失败 code。
4. 三道闸门:两次规格面板单价、规格/数量读回、确认页总额与判定。
2026-08-04 23:20:28 +08:00
5. 内部截图:三道闸门已批准的规格面板/确认页证据;只经受保护端点读取。MVP 不存在提交后结果
截图类型,不展示外部支付页,也不把 Gate3 图片冒充结果图。
6. 提交围栏:submission id、是否首次明确许可、唯一点击和调和记录。
7. 待付款收口:明确写系统尚未付款;人工核对后记录完成。
状态动作:
| 状态 | 页面动作 |
| --- | --- |
| `DRAFT` | 返回列表勾选并开始采购;可编辑/取消(按任务版本) |
| `PENDING` / `CLAIMED` / `ORDERING` | 只读进度;围栏前异常由人工处理,不中途确认规格 |
| `NEEDS_MANUAL` | 查看原因;确认没有围栏后重置为 DRAFT 或取消 |
| `RECONCILIATION_REQUIRED` | 只调和同一 submission;无重试、释放或重新授权 |
| `WAITING_PAYMENT` | 查看证据、人工付款、标记完成或转人工 |
| 终态 | 只读审计 |
详情中不出现 `WAITING_CONFIRMATION`、“确认机器选对了吗”、“签发第二趟授权”或“重新试选”。
完整页与抽屉执行同一 `task-detail-content` 模板和只读查询。直接导航返回完整 SSR 文档;列表 JS 对
同一 URL 发出同源 `X-CMBuyer-View: drawer` 请求,只取得 HTML fragment。加载失败时抽屉提供重试和
“在完整页打开”,不会把失败请求伪装成已打开详情。
T-204 只显示数据库中当前实际存在的任务、授权、attempt、submission 和内部截图,缺少事实就显示
明确空态;它不创建 attempt/event,不计算闸门,也不提供重置、调和、标记付款或任何设备动作。
截图以服务端记录的宽高预留布局并延迟加载,alt 只描述证据种类和采集时间,不转录截图中的地址或手机号。
## 四、采购工具界面结构
应用名:**采购工具**。顶部固定 tab:
1. **采购执行**(默认)
2. **配置**
### 采购执行 tab
- 顶部第一行:采购服务、ADB、拼多多版本、会话状态;其右侧是“开始轮询 / 停止轮询”。
- 左上“当前任务”:左侧文字约 2/3,右侧商品图片约 1/3;空闲显示占位。
- 左下“滚动日志”:占满剩余高度,显示阶段、固定 reason 和安全下一步。
- 右侧“采购记录”:时间倒序表格,MVP 只显示标题和状态。
- 双击或 Enter 记录:左侧原位切换到记录详情,不弹窗;上方文字/图片,下方执行结果。
- Esc 或“返回当前任务”:恢复当前任务视图;不暂停执行、不释放围栏。
单趟状态:待领取、已领取、打开商品、选择规格、闸门一、数量复核、闸门二、确认页/闸门三、
申请围栏、已发出唯一提交、待付款或待调和。桌面端没有让用户手工点击“提交订单”的按钮。
### 配置 tab
2026-08-04 23:20:28 +08:00
- 采购服务 URL、设备 token(密码框,不回显完整值;首次必填,已有凭据时留空表示保留,非空表示替换);
- ADB 路径、设备 serial、USB/WiFi 通道选择;
- 轮询间隔与连续失败停止阈值;
2026-08-04 23:20:28 +08:00
- 只做本地字段与路径格式检查,并提示服务身份、设备连接、拼多多安装和已取证版本将在首次真实领取/
后续已批准真机流程中验证。配置页不调用 `claim-next`、renew、evidence 等业务 API,也不运行 ADB/PDD
作为“连接检查”;MVP 不提供清除已保存设备凭据的命令。
配置凭据进入系统安全存储;日志和界面不显示完整 token。
## 五、导航和焦点规则
- Web 主导航 MVP 只有“采购任务”;logo 文案为“采购服务”。
- 商品标题链接是外部导航;行详情是内部导航,两者事件相互隔离。
- Web 路由抽屉与完整页共享数据和 URL;关闭恢复触发行焦点。
- Desk tab 使用标准键盘关系;历史详情 Esc 返回当前任务,不关闭应用。
- 真机执行、围栏和提交不受页面/视图切换影响;关闭窗口时若有活跃任务,提示只影响 UI/轮询,
不把它解释为撤销服务端授权。
## 六、组件归属
| 组件 | 归属 |
| --- | --- |
| 会话 / CSRF / SSR 模板 | `admin/internal/transport/webui` |
| 任务 / 授权 / attempt / submission 用例 | `admin/internal/usecase` |
| SQLite / 证据存储 | `admin/internal/storage` |
| 设备 API | `admin/internal/transport/httpapi` |
| ADB / PDD 页面能力 | `client/src/cmbuyer_client/device`、`pdd` |
| 任务来源与结果 sink | `client/src/cmbuyer_client/core`、`remote` |
| PySide6 UI | `client/src/cmbuyer_client/app` |
## 七、原型
- Web:`docs/design/web-task-create.html`、`web-task-workbench.html`、`web-task-detail.html`。
- Desk:`docs/design/desk-execution.html`;配置结构见 `desk-device-settings.html`。
- 原型只使用假数据、无网络和生产副作用;显著流程变更先更新原型再实现。