feat: verify content asset uploads

This commit is contained in:
Codex
2026-06-29 03:30:06 +08:00
parent 7c41bf525f
commit 21c0634020
13 changed files with 988 additions and 35 deletions

View File

@@ -167,7 +167,7 @@ tenant:<tenantId>:theme
| 单词收藏 | `/api/learning/vocabulary/favorites` |
| 知识手册 | `/api/catalog/handbook-subjects``handbook-chapters``handbook-entries` |
| 分数线 | `/api/scoreline/fields``schools``majors``records``trend``years` |
| 资料下载 | `/api/catalog/assets``/api/catalog/assets/download` |
| 资料下载/预览 | `/api/catalog/assets``/api/catalog/assets/preview``/api/catalog/assets/download` |
| 商城 | `/api/catalog/svip-plans``POST /api/commerce/coupons/claim``POST /api/commerce/orders``POST /api/commerce/payments/create` |
| 订单/权益 | `/api/commerce/orders``/api/commerce/orders/detail``/api/commerce/orders/status``/api/commerce/entitlements` |
| 激活码 | `POST /api/commerce/activation-codes/check``POST /api/commerce/activation-codes/redeem` |
@@ -438,6 +438,57 @@ GET /api/learning/vocabulary/review-plan?unitId=<unitId>&reviewLimit=30&newLimit
- 签名 URL 过期后必须重新调用 `/api/videos/play`,不要重试旧 URL。
- 小程序/H5 不保存对象存储真实 key不把播放 URL 写入本地持久缓存。
## 资料上传、预览和下载契约
学生端资料只读取目录、预览和下载签名,不接触对象存储真实密钥,也不自行拼接私有 bucket 地址。
学生端展示资料列表:
```http
GET /api/catalog/assets?assetType=pdf&regionId=<regionId>&includeLocked=true
```
学生端 PDF/图片预览:
```http
GET /api/catalog/assets/preview?assetId=<assetId>
```
学生端下载:
```http
GET /api/catalog/assets/download?assetId=<assetId>
```
前端处理规则:
- `preview.url` 是短期 inline URL只给预览组件使用不持久化。
- `download.url` 是短期 attachment URL只给下载动作使用。
- `ASSET_SVIP_REQUIRED`:提示开通对应地区/科目权益。
- `ASSET_UPLOAD_NOT_VERIFIED`:展示“资料正在处理中”,并上报前端日志。
- `ASSET_PREVIEW_NOT_SUPPORTED`:隐藏预览按钮,仅保留下载或提示不支持预览。
- `previewUrl` 字段只作为公开/托管预览提示,不代表可以绕过接口直接访问。
租户后台上传资料必须走五步:
```text
sign-upload -> 直传对象存储 -> PUT assets 登记草稿 -> confirm-upload -> sign-preview 验收
```
后台上传确认:
```json
{
"assetId": "<assetId>",
"fileSizeBytes": 4096,
"mimeType": "application/pdf",
"checksumSha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"publish": true
}
```
托管对象在确认前会保持 `status=draft``uploadStatus=pending`,学生端不会看到。确认失败时后端返回 `UPLOAD_VERIFICATION_FAILED`,后台必须展示失败原因并允许重新上传,不能前端强行改为已发布。
## 考试倒计时、签到积分和反馈
首页可用 `GET /api/catalog/exam-dates?regionId=<regionId>` 展示地区公开考试日期;个人中心优先用 `GET /api/profile/exam-countdowns`,后端会按学生当前 `regionId/selectedSchoolId` 返回匹配倒计时。