Browse Source

docs: add traffic ops admin page design

Spec for admin TrafficOpsView with package CRUD, purchase intake, and read-only ledger tabs.
main
xiaosi 3 weeks ago
parent
commit
657ac4b64a
  1. 177
      docs/superpowers/specs/2026-09-01-traffic-ops-admin-design.md

177
docs/superpowers/specs/2026-09-01-traffic-ops-admin-design.md

@ -0,0 +1,177 @@
# 流量运营管理页设计
日期:2026-09-01
状态:已确认(待实现计划)
## 背景
用户账户中心已能购买云媒体流量套餐并拉起微信支付二维码,但套餐数据目前只能通过 Admin API / 数据库维护,前端没有管理入口。运营还需要查看平台资源池、录入采购批次、核对账务流水。
后端 `/v1/admin/traffic/*` 已具备:
- 套餐分页 / 创建 / 更新 / 下架(DELETE → `inactive`
- 资源池查询、采购批次创建与分页
- 账务流水分页(只读)
## 目标
为管理员新增独立页面「流量运营」,页内三个 Tab:
1. **套餐管理**:完整 CRUD(删除语义=下架)
2. **采购入池**:展示资源池 + 录入采购批次
3. **账务流水**:只读筛选与分页
用户侧账户购买流程不变;仅 `status=active` 的套餐对用户可见。
## 非目标
- 不改后端 API 契约
- 不做采购批次编辑/删除(后端无接口)
- 不做流水写入/冲正
- 不把该能力塞进「系统管理」或「账户中心」
- 本轮不做通信卡套餐管理
## 方案
采用独立页面 `TrafficOpsView`
- 路由:`/traffic-ops`,`meta: { admin: true }`
- 侧栏:管理员菜单新增「流量运营」,与「固件管理」同级
- 顶栏标题:流量运营
- UI 模式对齐 `FirmwaresView`:`operation-page` + 工具栏 + `t-table` + `t-dialog` + `ui.confirm`
## 信息架构
```text
侧栏(管理员)
└─ 流量运营 /traffic-ops
├─ Tab 套餐管理
├─ Tab 采购入池
└─ Tab 账务流水
```
## Tab 1:套餐管理
### 列表
- 筛选:`status` = 全部 / `active` / `inactive`
- 操作:刷新、新建套餐
- 列:编码、名称、额度(GB)、价格、有效期、状态、排序、更新时间、操作
### 表单(新建/编辑同一弹窗)
| 字段 | 新建 | 编辑 | 说明 |
|---|---|---|---|
| code | 必填 | 只读展示 | 唯一;后端不可改 |
| name | 必填 | 可改 | |
| amountGb | 必填 | 可改 | UI 用 GB,提交转 `amountBytes = GB * 1024^3` |
| price | 必填,≥0 | 可改,但避免改成 0 | 后端 Update 仅在 `price > 0` 时写入 |
| validityDays | ≥0 | 可改,但避免把已有值改成 0 | `0` 表示长期有效;Update 仅在 `>0` 时写入 |
| sort | 可选 | 可改 | |
| status | 默认 active | 可改 active/inactive | |
### 操作语义
- **下架**:调用 `DELETE /v1/admin/traffic/packages/:id`,confirm 文案明确「下架后用户侧不可见,之后可再上架」
- **重新上架**:编辑弹窗把 `status` 改回 `active`,或等价更新
- 创建成功 / 更新成功 / 下架成功后刷新当前列表
## Tab 2:采购入池
### 资源池卡片
展示:`totalBytes`、`availableBytes`、`status`(同时换算 GB)。
`GET /v1/admin/traffic/pool` 返回 404 / 资源不存在:
- 不视为页面失败
- 展示空态:「尚未建立资源池」
- 提示:首次成功录入采购后自动建池
### 采购列表
- 筛选:provider、status(对接现有 query)
- 操作:刷新、录入采购
- 列:批次号、供应商、总量、成本、到期、状态、备注、创建时间
### 新建采购弹窗
对齐 `PlatformPurchaseCreateReq`
- 必填:`batchNo`、`provider`、`totalBytes`(UI 可用 GB 输入)
- 选填:`unitCost`、`totalCost`、`expiresAt`、`remark`
仅支持创建,不提供编辑/删除。创建成功后刷新 pool + purchases。
## Tab 3:账务流水(只读)
### 筛选
- `accountType`:全部 / user / platform
- `accountId`:可选
- 分页、刷新
### 列
时间、账户类型、账户 ID、方向(credit/debit)、金额(GB + 原始字节)、变动前/后余额、来源类型、来源 ID、幂等键。
无写操作。空态:「暂无流水」。
## 权限与错误处理
- 路由 `meta.admin` + 侧栏 `isAdmin` 双控;非管理员不可见、不可进入
- API 401/403:沿用全局拦截 toast
- 套餐 code 冲突:展示后端「套餐编码已存在」
- 下架必须二次确认
- pool 404:引导录入采购,不弹致命错误
## 前端改动面
1. `src/views/TrafficOpsView/TrafficOpsView.vue`(新)
2. `src/router/index.js`:注册 `/traffic-ops`
3. `src/layout/components/SideMenu.vue`:管理员菜单项
4. `src/layout/components/TopBar.vue`:标题映射
5. `src/config/urls.js`:补充
- `ADMIN_TRAFFIC_POOL`
- `ADMIN_TRAFFIC_PURCHASES`
- `ADMIN_TRAFFIC_PACKAGES`
- `ADMIN_TRAFFIC_PACKAGE(id)`
- `ADMIN_TRAFFIC_LEDGER`
## 数据流
```text
管理员打开 /traffic-ops
├─ 套餐 Tab → GET /v1/admin/traffic/packages
│ ├─ 新建 → POST /packages
│ ├─ 编辑 → PUT /packages/:id
│ └─ 下架 → DELETE /packages/:id
├─ 采购 Tab → GET /pool + GET /purchases
│ └─ 录入 → POST /purchases → 刷新 pool/purchases
└─ 流水 Tab → GET /ledger
用户账户页仍只读 GET /v1/account/traffic-packages(active)
```
## 验收标准
1. 管理员侧栏可见「流量运营」,普通用户不可见
2. 可新建套餐;账户中心购买区立即出现(active)
3. 可下架套餐;账户中心不再展示
4. 可编辑名称/价格/额度/排序/状态
5. 采购录入成功后,资源池从 404 变为有余额,或可用字节增加
6. 流水 Tab 可按账户类型筛选并分页
7. 非管理员访问 `/traffic-ops` 被重定向到 `/monitor`
## 风险与约束
- 后端 Update 对 `price`、`validityDays` 使用 `>0` 判断,UI 需避免误把有效值写成 0 导致“看似提交成功但未变更”
- 当前生产 pool 可能尚未初始化;采购 Tab 必须兼容 404
- 本页不处理微信支付回调;入账仍走既有 `/pay/wx/callback`
## 实现顺序建议
1. urls + 路由 + 菜单骨架
2. 套餐 Tab CRUD
3. 采购入池 Tab
4. 流水 Tab
5. 管理员权限冒烟 + 用户侧套餐可见性回归
Loading…
Cancel
Save