Files
cmbuyer/docs/routes.md
T

161 lines
8.8 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.
# 路由与页面结构
> 采购服务使用服务端渲染;采购工具使用固定 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. 三道闸门:闸门一规格面板单价、规格/数量读回、闸门二顶部总额、闸门三最终控件金额同额校验。
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
- 采购服务 URL、设备 token(密码框,不回显完整值;首次必填,已有凭据时留空表示保留,非空表示替换);
- ADB 路径、设备 serial、USB/WiFi 通道选择;
- 轮询间隔与连续失败停止阈值;
- 只做本地字段与路径格式检查,并提示服务身份、设备连接、拼多多安装和已取证版本将在首次真实领取/
后续已批准真机流程中验证。配置页不调用 `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`。
- 原型只使用假数据、无网络和生产副作用;显著流程变更先更新原型再实现。