Browse Source
Specify a TrafficOps header dialog for admins to grant test traffic via POST /v1/admin/traffic/test-grants without payment.main
1 changed files with 119 additions and 0 deletions
@ -0,0 +1,119 @@ |
|||||
|
# 管理员测试流量发放小工具设计 |
||||
|
|
||||
|
日期:2026-09-02 |
||||
|
范围:只改前端;对接后端已约定的管理员测试发放接口,绕过「套餐下单 → 支付 → 回调入账」。 |
||||
|
|
||||
|
## 背景 |
||||
|
|
||||
|
测试阶段需要给普通用户快速加云媒体流量,不走完整购买链路。后端约定接口: |
||||
|
|
||||
|
- `POST /v1/admin/traffic/test-grants` |
||||
|
- Header:`Authorization: Bearer <admin_token>` |
||||
|
- Body:`{ "userId": number, "amountGb": number, "reason": string }` |
||||
|
- 成功后目标用户余额增加,并返回最新余额 |
||||
|
|
||||
|
线上此前探测该路径可能仍为 404;前端按约定接入,接口未就绪时由请求层 toast 错误信息。 |
||||
|
|
||||
|
## 目标 |
||||
|
|
||||
|
在管理员「流量运营」页提供最小可用发放入口: |
||||
|
|
||||
|
1. 选择/填写目标普通用户 |
||||
|
2. 填写发放额度(GB)与原因 |
||||
|
3. 一键调用测试发放接口 |
||||
|
4. 成功后 toast,并在对话框展示最新余额 |
||||
|
|
||||
|
## 非目标 |
||||
|
|
||||
|
- 不改后端、不部署后端 |
||||
|
- 不改普通用户账户购买/支付流程 |
||||
|
- 不在 Users 页挂入口(后续如需可复用同一对话框逻辑) |
||||
|
- 不做发放历史独立列表(可用现有「账务流水」Tab 核对) |
||||
|
|
||||
|
## 入口与权限 |
||||
|
|
||||
|
- 页面:`/traffic-ops`(已有 `meta.admin`) |
||||
|
- 位置:页头右侧新增主按钮「测试发放」 |
||||
|
- 权限:沿用现有 admin 路由守卫,不另加前端权限分支 |
||||
|
|
||||
|
## 交互 |
||||
|
|
||||
|
### 打开对话框 |
||||
|
|
||||
|
点击「测试发放」→ 打开 `t-dialog`: |
||||
|
|
||||
|
| 字段 | 控件 | 规则 | |
||||
|
|------|------|------| |
||||
|
| 用户 | 搜索下拉 + 可手填用户 ID | 必填;最终提交 `userId` | |
||||
|
| 额度(GB) | `t-input-number` | 必填,整数,`min=1`,默认 `10` | |
||||
|
| 原因 | `t-input` | 必填,默认 `live test` | |
||||
|
|
||||
|
用户选择支持两种方式(可并存): |
||||
|
|
||||
|
1. 输入关键字,调 `GET /v1/users?keyword=&pageNum=1&pageSize=20`(可带 `role=user`),下拉展示 `姓名 · 手机号 · ID`,选中后写入 `userId` |
||||
|
2. 直接在用户 ID 输入框填写数字 ID |
||||
|
|
||||
|
若先搜索选中再改 ID,以当前 ID 输入框值为准提交。 |
||||
|
|
||||
|
### 提交 |
||||
|
|
||||
|
1. 前端校验:`userId` 为正整数、`amountGb >= 1`、`reason` 非空 |
||||
|
2. `POST /v1/admin/traffic/test-grants`,body:`{ userId, amountGb, reason }` |
||||
|
3. 成功: |
||||
|
- `ui.toast('测试流量已发放')` |
||||
|
- 在对话框内展示返回的最新余额(优先读常见字段:`balance` / `trafficBalance` / `data.balance` 等实际返回;统一格式化为 `xx.xx GB`;若只有 bytes 则按 `1024**3` 换算) |
||||
|
- 对话框不强制关闭,便于连续发放或核对余额 |
||||
|
4. 失败:沿用 `http` 拦截器 / `ui.toast` 展示后端 `msg` |
||||
|
|
||||
|
### 取消 |
||||
|
|
||||
|
关闭对话框并重置表单(含搜索结果与余额展示)。 |
||||
|
|
||||
|
## API 约定(前端) |
||||
|
|
||||
|
`src/config/urls.js` 新增: |
||||
|
|
||||
|
```js |
||||
|
export const ADMIN_TRAFFIC_TEST_GRANTS = '/v1/admin/traffic/test-grants' |
||||
|
``` |
||||
|
|
||||
|
用户搜索复用: |
||||
|
|
||||
|
```js |
||||
|
export const USERS = '/v1/users' |
||||
|
``` |
||||
|
|
||||
|
余额展示兼容:后端文档未钉死返回结构。前端解析顺序: |
||||
|
|
||||
|
1. 若响应本身是 number → 视为 bytes 或 GB(优先:绝对值很大则当 bytes,否则当 GB;实现里以 `>= 1024**3` 判 bytes) |
||||
|
2. 若对象含 `trafficBalance` / `balance` / `balanceBytes` / `trafficBalanceBytes` → 按字段语义展示 |
||||
|
3. 都没有 → 只 toast 成功,余额区显示「已发放(未返回余额字段)」 |
||||
|
|
||||
|
## 代码改动面 |
||||
|
|
||||
|
- `src/config/urls.js`:新增常量 |
||||
|
- `src/views/TrafficOpsView/TrafficOpsView.vue`: |
||||
|
- 页头按钮 |
||||
|
- 发放对话框 + 表单状态 |
||||
|
- 用户搜索 / 提交逻辑 |
||||
|
- 不新增路由、不改侧栏 |
||||
|
|
||||
|
## 错误与边界 |
||||
|
|
||||
|
- 接口 404/未部署:toast 后端或网络错误,不假装成功 |
||||
|
- 非 admin token:现有 403 处理 |
||||
|
- 搜索无结果:下拉空态「无匹配用户」 |
||||
|
- 连续提交:提交中按钮 loading,防重复点击 |
||||
|
|
||||
|
## 验收 |
||||
|
|
||||
|
1. 管理员进入 `/traffic-ops`,可见「测试发放」 |
||||
|
2. 搜索普通用户并选中,或手填 `userId` |
||||
|
3. 填写额度与原因后提交;接口可用时余额增加且对话框展示最新余额 |
||||
|
4. 普通用户账户中心余额刷新后可见增量 |
||||
|
5. 非管理员无法进入该页(既有守卫) |
||||
|
|
||||
|
## 风险 |
||||
|
|
||||
|
- 后端 `test-grants` 若尚未上线,功能按钮可见但提交失败——可接受,文案不隐藏入口 |
||||
|
- 返回余额字段名不确定——用兼容解析,避免强耦合单一字段 |
||||
Loading…
Reference in new issue