forked from wangziqi/gongxue-base
feat: protect video playback access
This commit is contained in:
@@ -139,7 +139,7 @@ tenant:<tenantId>:theme
|
||||
| 提交答案 | `POST /api/learning/answers` |
|
||||
| 错题本 | `GET /api/learning/wrong-questions`、`POST /api/learning/wrong-questions/resolve` |
|
||||
| 收藏夹 | `GET/POST /api/learning/favorites/questions` |
|
||||
| 题目视频 | `GET /api/questions/{questionId}/videos`、`POST /api/questions/videos/batch` |
|
||||
| 题目视频 | `GET /api/questions/{questionId}/videos`、`POST /api/questions/videos/batch`、`POST /api/videos/play` |
|
||||
| 背单词 | `/api/catalog/vocabulary-units`、`/api/catalog/vocabulary-words` |
|
||||
| 单词进度 | `/api/learning/vocabulary/progress`、`/api/learning/vocabulary/stats` |
|
||||
| 单词收藏 | `/api/learning/vocabulary/favorites` |
|
||||
@@ -152,6 +152,60 @@ tenant:<tenantId>:theme
|
||||
| 个人中心 | `GET/PATCH /api/profile/me` |
|
||||
| 销售分享 | `/api/referral/resolve`、`track-event`、`bind` |
|
||||
|
||||
## 视频播放契约
|
||||
|
||||
题目视频分为 `free`、`svip`、`video_quota` 三种访问模式。列表接口只用于展示标题、封面、时长、访问模式和试看秒数;除免费公开视频外,列表和搜索接口不会返回可播放 URL。
|
||||
|
||||
播放步骤:
|
||||
|
||||
1. 进入题目页后调用 `GET /api/questions/{questionId}/videos` 或批量预加载 `POST /api/questions/videos/batch`。
|
||||
2. 用户点击播放时调用 `POST /api/videos/play`。
|
||||
3. 后端校验当前 session 用户、租户、题目绑定关系、SVIP 权益或视频次数权益。
|
||||
4. 后端返回短期签名 URL、播放 token、权益来源和过期时间。
|
||||
5. 前端播放器只使用本次返回的 `playback.url`,不要缓存为长期资源地址。
|
||||
|
||||
请求示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"videoId": "00000000-0000-0000-0000-000000000821",
|
||||
"questionId": "00000000-0000-0000-0000-000000000401"
|
||||
}
|
||||
```
|
||||
|
||||
响应关键字段:
|
||||
|
||||
```json
|
||||
{
|
||||
"item": {
|
||||
"id": "...",
|
||||
"title": "...",
|
||||
"accessMode": "svip",
|
||||
"freePreviewSeconds": 15
|
||||
},
|
||||
"playToken": "vp_...",
|
||||
"playback": {
|
||||
"url": "https://...",
|
||||
"expiresAt": "2026-06-28T12:00:00.000Z",
|
||||
"signatureMode": "signed"
|
||||
},
|
||||
"access": {
|
||||
"mode": "svip",
|
||||
"entitlementId": "...",
|
||||
"quotaAccountId": null,
|
||||
"consumedQuota": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
前端处理规则:
|
||||
|
||||
- `VIDEO_SVIP_REQUIRED`:弹出开通或升级会员。
|
||||
- `VIDEO_QUOTA_REQUIRED`:提示购买视频次数包或套餐。
|
||||
- `VIDEO_ASSET_REQUIRED`:展示“视频暂不可播放”,同时上报前端日志。
|
||||
- 签名 URL 过期后必须重新调用 `/api/videos/play`,不要重试旧 URL。
|
||||
- 小程序/H5 不保存对象存储真实 key,不把播放 URL 写入本地持久缓存。
|
||||
|
||||
## 题库新模型接入方式
|
||||
|
||||
旧项目常按“地区 -> 科目 -> 章节/试卷”固定层级处理。新项目不要写死层级,按下面模型渲染:
|
||||
|
||||
Reference in New Issue
Block a user