feat: import scorelines and videos

This commit is contained in:
Codex
2026-06-29 06:40:42 +08:00
parent fc289f7b42
commit 4954ad3ca9
16 changed files with 1397 additions and 64 deletions

View File

@@ -1,6 +1,6 @@
# 内容导入契约
更新时间2026-06-21
更新时间2026-06-29
## 结论
@@ -33,6 +33,12 @@ POST /api/tenant-content/imports/vocabulary
POST /api/tenant-content/imports/preview/handbook
POST /api/tenant-content/imports/handbook
POST /api/tenant-content/imports/preview/scoreline
POST /api/tenant-content/imports/scoreline
POST /api/tenant-content/imports/preview/videos
POST /api/tenant-content/imports/videos
GET /api/tenant-content/imports
GET /api/tenant-content/imports/issues
```
@@ -144,6 +150,109 @@ GET /api/tenant-content/imports/issues
这样题目会同时落到旧兼容表和新内容导航/题目集合。
## 分数线导入
分数线导入支持字段、院校、专业、年份记录一起提交,适合把旧题库地区分数线 JSON 转成新结构后统一 preview/import。
推荐格式:
```json
{
"regionId": "uuid",
"sourceName": "scoreline-tianjin-2025.json",
"fields": [
{
"legacyId": "tj-min-score",
"fieldKey": "minScore",
"fieldName": "最低分",
"fieldType": "number",
"unit": "分",
"isFilter": true,
"isTrend": true,
"order": 1
}
],
"schools": [
{
"legacyId": "school-a",
"name": "天津测试学院",
"shortName": "测试学院",
"schoolType": "public",
"isHot": true
}
],
"majors": [
{
"legacyId": "major-a",
"schoolLegacyId": "school-a",
"name": "软件工程"
}
],
"records": [
{
"legacyId": "record-a-2025",
"schoolLegacyId": "school-a",
"majorLegacyId": "major-a",
"year": 2025,
"fieldValues": {
"minScore": 188,
"planCount": 60
}
}
]
}
```
校验规则:
- `kind` 可为 `field/school/major/record`;使用 `fields/schools/majors/records` 分桶时后端会自动补。
- `record` 必须能通过 `schoolId``schoolLegacyId``schoolName` 定位院校。
- `major` 必须能通过 `schoolId``schoolLegacyId``schoolName` 定位院校。
- `fieldValues` 保存动态字段值,前端筛选和趋势图应先读取 `/api/scoreline/fields`
- 相同 `legacyId` 再导入会幂等更新;内容 hash 未变化时计入 `skipped`
## 视频导入
视频导入支持视频基础信息和题目绑定一起提交。付费视频不要在列表页暴露可播放 URL播放仍走 `POST /api/videos/play` 做权益和签名校验。
推荐格式:
```json
{
"sourceName": "question-videos.json",
"videos": [
{
"legacyId": "video-001",
"title": "函数极限精讲",
"description": "题目解析视频",
"videoUrl": "https://example.com/private/video-001.mp4",
"thumbnailUrl": "https://example.com/thumb/video-001.jpg",
"durationSeconds": 120,
"knowledgeTags": ["高数", "极限"],
"subjectId": "uuid",
"accessMode": "svip",
"freePreviewSeconds": 15,
"bindings": [
{
"legacyId": "video-001-question-001",
"questionId": "uuid",
"videoType": "specific",
"order": 1
}
]
}
]
}
```
校验规则:
- `title` 必填。
- `accessMode` 可为 `free``svip``video_quota`
- 绑定题目必须提供 `questionId``legacyQuestionId`,且题目必须属于当前租户。
- `assetId` 可以绑定 `content_assets` 台账资源;生产建议优先用资源台账和签名播放,不让前端长期持有私有视频 URL。
- 导入成功会写 `question_videos`,并把题目 `has_video_explanation` 标记为 true。
## 幂等规则
- 优先使用 `legacyId` 作为跨迁移稳定标识。
@@ -154,5 +263,4 @@ GET /api/tenant-content/imports/issues
## 下一步
- 增加 Excel/CSV 解析入口,但解析后仍进入同一套 preview/import 管线。
- 增加分数线、视频导入。
- 增加异步 worker处理大批量导入、重试和导入后校验。