diff --git a/frontend/src/api/modules/video.js b/frontend/src/api/modules/video.js index a686971..1fc72f0 100644 --- a/frontend/src/api/modules/video.js +++ b/frontend/src/api/modules/video.js @@ -14,6 +14,11 @@ export function getVideoDetail(id) { return http.get(`/video/${id}`) } +/** 根据知识图谱关联关系推荐相关视频。 */ +export function getRecommendedVideos(id) { + return http.get(`/video/${id}/recommendations`) +} + /** 查询当前用户在某个视频上的观看记录。 */ export function getWatchRecord(videoId) { return http.get(`/video/watch-record/${videoId}`, { diff --git a/frontend/src/components/KnowledgeGraph/NodeDetail.vue b/frontend/src/components/KnowledgeGraph/NodeDetail.vue index 226ee08..942bf4d 100644 --- a/frontend/src/components/KnowledgeGraph/NodeDetail.vue +++ b/frontend/src/components/KnowledgeGraph/NodeDetail.vue @@ -59,6 +59,36 @@ + +
+
相关视频
+
+ +
+
+ +
+
配套习题
+
+ +
+
@@ -176,6 +206,33 @@ const corePointList = computed(() => { if (!props.node?.corePoints) return [] return props.node.corePoints.split(/[、,,]/).map((s) => s.trim()).filter(Boolean) }) + +const openVideo = (id) => { + router.push({ name: 'VideoPlayer', query: { videoId: id } }) +} + +const openExercise = (exercise) => { + if (!exercise?.id) return + if (['SINGLE_CHOICE', 'MULTIPLE_CHOICE'].includes(exercise.type)) { + router.push({ path: `/exercise/choice/${exercise.id}` }) + return + } + if (exercise.type === 'FILL_BLANK') { + router.push({ path: `/exercise/fill/${exercise.id}` }) + return + } + router.push({ path: `/exercise/${exercise.id}` }) +} + +const exerciseTypeLabel = (type) => { + const map = { + SINGLE_CHOICE: '单选', + MULTIPLE_CHOICE: '多选', + FILL_BLANK: '填空', + PROGRAMMING: '编程', + } + return map[type] || '习题' +}