forked from wangziqi/gongxue-base
feat: import scorelines and videos
This commit is contained in:
@@ -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,处理大批量导入、重试和导入后校验。
|
||||
|
||||
Reference in New Issue
Block a user