docs: add market batch submit design
This commit is contained in:
parent
12ff0b56fb
commit
58f5de03f2
305
docs/superpowers/specs/2026-04-22-market-batch-submit-design.md
Normal file
305
docs/superpowers/specs/2026-04-22-market-batch-submit-design.md
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
# 星图达人批次提交设计
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
当前插件已经具备以下能力:
|
||||||
|
|
||||||
|
- 使用 Logto 登录并获取访问 `https://talent-search.intelligrow.cn` 的 access token
|
||||||
|
- 读取星图市场页中的达人列表数据
|
||||||
|
- 支持按当前页、前 5 页、前 10 页、全部、自定义页数进行多页采集
|
||||||
|
- 支持导出 CSV
|
||||||
|
|
||||||
|
下一阶段需要把“当前采集范围内的一批达人”提交给其他同学维护的后端接口,而不是逐条发送。用户期望在现有导出范围逻辑基础上,新增一个独立的“提交批次”动作,用来测试整批提交流程。
|
||||||
|
|
||||||
|
## 目标
|
||||||
|
|
||||||
|
- 在现有工具栏中新增一个独立的 `提交批次` 按钮
|
||||||
|
- 提交动作复用当前导出范围逻辑,支持多页达人数据采集
|
||||||
|
- 提交前通过浏览器 `prompt()` 让用户输入批次名称
|
||||||
|
- 自动生成 `batchId = 批次名称 + 时间戳`
|
||||||
|
- 将以下信息整合为单个批次 payload 发送给后端:
|
||||||
|
- Logto 用户 ID
|
||||||
|
- 星图达人 ID 列表
|
||||||
|
- 用户输入的批次名称
|
||||||
|
- 自动生成的批次 ID
|
||||||
|
|
||||||
|
## 非目标
|
||||||
|
|
||||||
|
- 不改造为逐条提交达人
|
||||||
|
- 不移除或替代现有 `导出 CSV`
|
||||||
|
- 不在首版实现复杂弹窗或表单 UI
|
||||||
|
- 不在首版实现批次列表管理、重试历史、草稿保存
|
||||||
|
|
||||||
|
## 方案对比
|
||||||
|
|
||||||
|
### 方案 A:只提交当前页
|
||||||
|
|
||||||
|
- 新按钮只处理当前页达人
|
||||||
|
- 优点:实现最简单
|
||||||
|
- 缺点:与现有多页导出/采集使用方式不一致,不符合真实业务需求
|
||||||
|
|
||||||
|
### 方案 B:提交当前导出范围内的一整批达人
|
||||||
|
|
||||||
|
- 复用现有导出范围控制器,提交当前选择范围内的所有达人
|
||||||
|
- 优点:与用户当前使用习惯一致,便于从测试过渡到真实业务
|
||||||
|
- 缺点:比只提交当前页多一层批次组装逻辑
|
||||||
|
|
||||||
|
### 方案 C:先导出 CSV,再从 CSV 结果提交
|
||||||
|
|
||||||
|
- 先走导出逻辑,再把导出结果转换为提交 payload
|
||||||
|
- 优点:数据来源统一
|
||||||
|
- 缺点:流程绕、耦合高,不适合作为长期模式
|
||||||
|
|
||||||
|
推荐采用方案 B。
|
||||||
|
|
||||||
|
## 交互设计
|
||||||
|
|
||||||
|
### 工具栏按钮
|
||||||
|
|
||||||
|
在现有工具栏中保留 `导出 CSV`,并新增:
|
||||||
|
|
||||||
|
- `提交批次`
|
||||||
|
|
||||||
|
两个按钮共享现有导出范围控件:
|
||||||
|
|
||||||
|
- 当前页
|
||||||
|
- 前 5 页
|
||||||
|
- 前 10 页
|
||||||
|
- 全部
|
||||||
|
- 自定义
|
||||||
|
|
||||||
|
### 批次名称输入
|
||||||
|
|
||||||
|
用户点击 `提交批次` 时:
|
||||||
|
|
||||||
|
1. 弹出浏览器 `prompt()`
|
||||||
|
2. 提示文案建议为:`请输入批次名称`
|
||||||
|
3. 用户输入如:`618 达人筛选第一批`
|
||||||
|
|
||||||
|
处理规则:
|
||||||
|
|
||||||
|
- 用户取消:直接终止,不报错
|
||||||
|
- 输入为空或仅空格:提示 `请输入批次名称`
|
||||||
|
- 输入有效:继续批次提交流程
|
||||||
|
|
||||||
|
### 提交状态
|
||||||
|
|
||||||
|
批次提交过程中:
|
||||||
|
|
||||||
|
- `提交批次` 按钮禁用
|
||||||
|
- `导出 CSV` 按钮与范围选择器一并禁用
|
||||||
|
- 状态文案可复用现有导出状态区域
|
||||||
|
|
||||||
|
建议状态文案:
|
||||||
|
|
||||||
|
- 当前页:`提交中...`
|
||||||
|
- 前 N 页:`提交中 3/5 页...`
|
||||||
|
- 全部:`提交中 第 3 页...`
|
||||||
|
|
||||||
|
### 成功与失败反馈
|
||||||
|
|
||||||
|
成功:
|
||||||
|
|
||||||
|
- 提示 `批次提交成功`
|
||||||
|
|
||||||
|
失败:
|
||||||
|
|
||||||
|
- 未登录:`请先登录插件`
|
||||||
|
- 批次名为空:`请输入批次名称`
|
||||||
|
- 接口失败:`批次提交失败,请稍后重试`
|
||||||
|
|
||||||
|
## 批次数据模型
|
||||||
|
|
||||||
|
首版建议 payload 结构如下:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"logtoUserId": "p7pdhhtde8kj",
|
||||||
|
"creatorName": "王少卿",
|
||||||
|
"resource": "https://talent-search.intelligrow.cn",
|
||||||
|
"batchName": "618达人筛选第一批",
|
||||||
|
"batchId": "618达人筛选第一批-2026-04-22T12:30:00.000Z",
|
||||||
|
"createdAt": "2026-04-22T12:30:00.000Z",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"authorId": "111",
|
||||||
|
"authorName": "达人A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"authorId": "222",
|
||||||
|
"authorName": "达人B"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 字段来源
|
||||||
|
|
||||||
|
- `logtoUserId`
|
||||||
|
- 来源:当前登录用户的 Logto `sub`
|
||||||
|
- `creatorName`
|
||||||
|
- 来源:当前登录用户 `name` 或 `username`
|
||||||
|
- `resource`
|
||||||
|
- 来源:当前认证配置中的 API resource
|
||||||
|
- `batchName`
|
||||||
|
- 来源:用户在 `prompt()` 中输入
|
||||||
|
- `createdAt`
|
||||||
|
- 来源:当前时间的 ISO 字符串
|
||||||
|
- `batchId`
|
||||||
|
- 规则:`${batchName}-${createdAt}`
|
||||||
|
- `authors`
|
||||||
|
- 来源:当前导出范围内采集出的达人记录
|
||||||
|
|
||||||
|
### 达人字段
|
||||||
|
|
||||||
|
首版只要求最小字段:
|
||||||
|
|
||||||
|
- `authorId`
|
||||||
|
- `authorName`
|
||||||
|
|
||||||
|
后续如有需要,可增加:
|
||||||
|
|
||||||
|
- `price21To60s`
|
||||||
|
- 看后搜率字段
|
||||||
|
- 城市/地区等补充信息
|
||||||
|
|
||||||
|
## 数据流
|
||||||
|
|
||||||
|
完整流程如下:
|
||||||
|
|
||||||
|
1. 用户在工具栏选择导出范围
|
||||||
|
2. 用户点击 `提交批次`
|
||||||
|
3. 插件弹出 `prompt()` 请求输入批次名称
|
||||||
|
4. 插件检查登录状态与用户信息
|
||||||
|
5. 插件复用当前多页采集逻辑,获取当前范围内达人记录
|
||||||
|
6. 插件读取 Logto 用户 ID
|
||||||
|
7. 插件生成 `createdAt` 和 `batchId`
|
||||||
|
8. 插件组装整批 payload
|
||||||
|
9. 插件使用带 Bearer token 的客户端提交到后端
|
||||||
|
10. 插件显示成功或失败状态
|
||||||
|
|
||||||
|
## 模块边界
|
||||||
|
|
||||||
|
建议按以下边界实现:
|
||||||
|
|
||||||
|
### 工具栏层
|
||||||
|
|
||||||
|
职责:
|
||||||
|
|
||||||
|
- 渲染 `提交批次` 按钮
|
||||||
|
- 管理按钮禁用态
|
||||||
|
- 回传点击事件
|
||||||
|
|
||||||
|
### 市场控制器层
|
||||||
|
|
||||||
|
职责:
|
||||||
|
|
||||||
|
- 响应 `提交批次` 点击
|
||||||
|
- 调用 `prompt()` 获取批次名称
|
||||||
|
- 复用现有导出范围采集逻辑
|
||||||
|
- 调用批次 payload 组装器和提交客户端
|
||||||
|
|
||||||
|
### 批次 payload 组装层
|
||||||
|
|
||||||
|
职责:
|
||||||
|
|
||||||
|
- 接收用户信息、批次名、时间戳、达人记录
|
||||||
|
- 生成标准批次对象
|
||||||
|
|
||||||
|
该层不负责网络请求,方便后续根据后端要求调整结构。
|
||||||
|
|
||||||
|
### 批次提交客户端
|
||||||
|
|
||||||
|
职责:
|
||||||
|
|
||||||
|
- 获取 access token
|
||||||
|
- 附带 `Authorization: Bearer <token>` 请求头
|
||||||
|
- 向后端提交整批 JSON
|
||||||
|
|
||||||
|
后续从 mock 接口切到真实接口时,应主要修改这一层。
|
||||||
|
|
||||||
|
## 认证与授权
|
||||||
|
|
||||||
|
当前系统已具备:
|
||||||
|
|
||||||
|
- Logto 登录能力
|
||||||
|
- 请求 `https://talent-search.intelligrow.cn` resource 的 access token
|
||||||
|
- `talent-search:read` scope
|
||||||
|
|
||||||
|
首版批次提交如果是写操作,后端后续可能需要新增写权限,例如:
|
||||||
|
|
||||||
|
- `talent-search:write`
|
||||||
|
- 或 `talent-search:batch:submit`
|
||||||
|
|
||||||
|
如果后端要求新的写权限,则前端需要同步更新 `auth-config.ts` 中的 `scopes`。
|
||||||
|
|
||||||
|
## 错误处理
|
||||||
|
|
||||||
|
### 用户取消输入
|
||||||
|
|
||||||
|
- 直接停止,不提示错误
|
||||||
|
|
||||||
|
### 批次名为空
|
||||||
|
|
||||||
|
- 不发请求
|
||||||
|
- 直接提示 `请输入批次名称`
|
||||||
|
|
||||||
|
### 未登录或取不到用户信息
|
||||||
|
|
||||||
|
- 不发请求
|
||||||
|
- 提示 `请先登录插件`
|
||||||
|
|
||||||
|
### 采集失败
|
||||||
|
|
||||||
|
- 复用当前导出多页采集失败逻辑
|
||||||
|
- 不生成不完整 payload
|
||||||
|
|
||||||
|
### 接口失败
|
||||||
|
|
||||||
|
- 提示 `批次提交失败,请稍后重试`
|
||||||
|
|
||||||
|
## 测试策略
|
||||||
|
|
||||||
|
### 单元测试
|
||||||
|
|
||||||
|
- 点击 `提交批次` 时会弹出 `prompt()`
|
||||||
|
- 用户取消输入时不会继续提交
|
||||||
|
- 空白批次名会报错
|
||||||
|
- `batchId` 按 `批次名 + ISO 时间戳` 生成
|
||||||
|
- payload 中包含:
|
||||||
|
- `logtoUserId`
|
||||||
|
- `batchName`
|
||||||
|
- `batchId`
|
||||||
|
- `authors[]`
|
||||||
|
|
||||||
|
### 集成测试
|
||||||
|
|
||||||
|
- `提交批次` 复用当前导出范围采集逻辑
|
||||||
|
- 当前页模式只提交当前页达人
|
||||||
|
- 多页模式会合并多页达人
|
||||||
|
- 接口调用时带 Bearer token
|
||||||
|
- 成功时显示成功状态
|
||||||
|
- 失败时显示失败状态
|
||||||
|
|
||||||
|
## 手动验证
|
||||||
|
|
||||||
|
1. 登录插件
|
||||||
|
2. 选择导出范围
|
||||||
|
3. 点击 `提交批次`
|
||||||
|
4. 在 `prompt()` 中输入批次名
|
||||||
|
5. 确认请求 payload 中包含:
|
||||||
|
- Logto 用户 ID
|
||||||
|
- 多个达人 ID
|
||||||
|
- 批次名
|
||||||
|
- 批次 ID
|
||||||
|
6. 确认后端返回成功
|
||||||
|
|
||||||
|
## 后续扩展
|
||||||
|
|
||||||
|
当真实接口稳定后,可以继续扩展:
|
||||||
|
|
||||||
|
- 批次提交结果详情展示
|
||||||
|
- 最近提交批次列表
|
||||||
|
- 批次重试
|
||||||
|
- 批次备注、标签
|
||||||
|
- 写权限 scope 单独拆分
|
||||||
Loading…
x
Reference in New Issue
Block a user