From 254fb72d0da0ed75a645697bd6eceb25a5af4a05 Mon Sep 17 00:00:00 2001 From: yuk255 Date: Tue, 23 Sep 2025 16:47:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0=E5=B0=8F=E8=8A=82?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E5=8A=9F=E8=83=BD;=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E7=AB=A0=E8=8A=82=E7=BC=96=E8=BE=91=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/modules/teachCourse.ts | 41 +- src/components/common/PreviewModal.vue | 323 ++++++++++ .../common/preview/DiscussionPreview.vue | 401 +++++++++++++ .../common/preview/DocumentPreview.vue | 451 ++++++++++++++ src/components/common/preview/ExamPreview.vue | 424 ++++++++++++++ .../common/preview/HomeworkPreview.vue | 335 +++++++++++ .../common/preview/PracticePreview.vue | 506 ++++++++++++++++ .../common/preview/VideoPreview.vue | 550 ++++++++++++++++++ src/views/teacher/course/ChapterEditor.vue | 16 +- .../teacher/course/ChapterManagement.vue | 73 ++- src/views/teacher/course/HomeworkReview.vue | 274 +++++++-- .../teacher/course/HomeworkReviewDetail.vue | 225 ++++--- 12 files changed, 3440 insertions(+), 179 deletions(-) create mode 100644 src/components/common/PreviewModal.vue create mode 100644 src/components/common/preview/DiscussionPreview.vue create mode 100644 src/components/common/preview/DocumentPreview.vue create mode 100644 src/components/common/preview/ExamPreview.vue create mode 100644 src/components/common/preview/HomeworkPreview.vue create mode 100644 src/components/common/preview/PracticePreview.vue create mode 100644 src/components/common/preview/VideoPreview.vue diff --git a/src/api/modules/teachCourse.ts b/src/api/modules/teachCourse.ts index 2b9e716..035cbe2 100644 --- a/src/api/modules/teachCourse.ts +++ b/src/api/modules/teachCourse.ts @@ -562,6 +562,34 @@ export class TeachCourseApi { } } + /** + * 查询练习章节 + */ + static async getSectionExercise(sectionId: string): Promise> { + try { + const response = await ApiRequest.get<{ result: any }>(`/aiol/aiolExam/getExamQuestionsByChapter/${sectionId}`) + console.log('📑 查询小节绑定的练习响应:', response) + return response + } catch (error) { + console.error('❌ 查询小节绑定的练习失败:', error) + throw error + } + } + + /** + * 查询讨论章节 + */ + static async getSectionDiscussion(courseId:string,sectionId: string): Promise> { + try { + const response = await ApiRequest.get<{ result: any }>(`/aiol/aiolCourse/${courseId}/section_discussion/${sectionId}`) + console.log('📑 查询小节绑定的讨论响应:', response) + return response + } catch (error) { + console.error('❌ 查询小节绑定的讨论失败:', error) + throw error + } + } + } // 作业相关类型定义 @@ -726,15 +754,15 @@ export class HomeworkApi { /** * 查询作业提交情况 */ - static async getHomeworkSubmits(homeworkId: string): Promise> { + static async getHomeworkSubmits(homeworkId: string): Promise> { try { console.log('🚀 发送查询作业提交情况请求:', { url: `/aiol/aiolHomeworkSubmit/homework/${homeworkId}/submits`, homeworkId }) - - const response = await ApiRequest.get<{ result: HomeworkSubmit[] }>(`/aiol/aiolHomeworkSubmit/homework/${homeworkId}/submits`) - + + const response = await ApiRequest.get(`/aiol/aiolHomeworkSubmit/homework/${homeworkId}/submits`) + console.log('📊 作业提交情况响应:', response) return response } catch (error) { @@ -800,7 +828,10 @@ export class ClassApi { return ApiRequest.post('/aiol/aiolClass/add', data); } - static async queryClassList(params: { course_id: string|null }): Promise> { + /** + * 查询班级列表 + */ + static async queryClassList(params: { course_id: string|null }): Promise> { return ApiRequest.get('/aiol/aiolClass/query_list', params); } diff --git a/src/components/common/PreviewModal.vue b/src/components/common/PreviewModal.vue new file mode 100644 index 0000000..dedefb8 --- /dev/null +++ b/src/components/common/PreviewModal.vue @@ -0,0 +1,323 @@ + + + + + \ No newline at end of file diff --git a/src/components/common/preview/DiscussionPreview.vue b/src/components/common/preview/DiscussionPreview.vue new file mode 100644 index 0000000..4441ee7 --- /dev/null +++ b/src/components/common/preview/DiscussionPreview.vue @@ -0,0 +1,401 @@ + + + + + \ No newline at end of file diff --git a/src/components/common/preview/DocumentPreview.vue b/src/components/common/preview/DocumentPreview.vue new file mode 100644 index 0000000..f6e7f44 --- /dev/null +++ b/src/components/common/preview/DocumentPreview.vue @@ -0,0 +1,451 @@ + + + + + \ No newline at end of file diff --git a/src/components/common/preview/ExamPreview.vue b/src/components/common/preview/ExamPreview.vue new file mode 100644 index 0000000..f231acf --- /dev/null +++ b/src/components/common/preview/ExamPreview.vue @@ -0,0 +1,424 @@ + + + + + \ No newline at end of file diff --git a/src/components/common/preview/HomeworkPreview.vue b/src/components/common/preview/HomeworkPreview.vue new file mode 100644 index 0000000..55cb8ad --- /dev/null +++ b/src/components/common/preview/HomeworkPreview.vue @@ -0,0 +1,335 @@ + + + + + \ No newline at end of file diff --git a/src/components/common/preview/PracticePreview.vue b/src/components/common/preview/PracticePreview.vue new file mode 100644 index 0000000..c5a38d1 --- /dev/null +++ b/src/components/common/preview/PracticePreview.vue @@ -0,0 +1,506 @@ + + + + + \ No newline at end of file diff --git a/src/components/common/preview/VideoPreview.vue b/src/components/common/preview/VideoPreview.vue new file mode 100644 index 0000000..6503dd8 --- /dev/null +++ b/src/components/common/preview/VideoPreview.vue @@ -0,0 +1,550 @@ + + + + + \ No newline at end of file diff --git a/src/views/teacher/course/ChapterEditor.vue b/src/views/teacher/course/ChapterEditor.vue index 6b9c941..27d18c2 100644 --- a/src/views/teacher/course/ChapterEditor.vue +++ b/src/views/teacher/course/ChapterEditor.vue @@ -1915,7 +1915,6 @@ const getSelectedResources = async (sectionData: any) => { if (videoResult.data?.result) { console.log('📹 视频资源查询成功:', videoResult.data.result); - // TODO: 更新对应小节的视频资源显示 data = videoResult.data.result; } else { console.log('📹 视频资源查询无数据'); @@ -1929,7 +1928,6 @@ const getSelectedResources = async (sectionData: any) => { const documentResult = await TeachCourseApi.getSectionDocument(courseId.value, sectionId); if (documentResult.data?.result) { console.log('📄 文档资源查询成功:', documentResult.data.result); - // TODO: 更新对应小节的文档资源显示 data = documentResult.data.result; } else { @@ -1944,8 +1942,6 @@ const getSelectedResources = async (sectionData: any) => { const examResult = await TeachCourseApi.getSectionExam(courseId.value, sectionId); if (examResult.data?.result) { console.log('📝 考试资源查询成功:', examResult.data.result); - // TODO: 更新对应小节的考试资源显示 - data = examResult.data.result; } else { console.log('📝 考试资源查询无数据'); @@ -1959,7 +1955,6 @@ const getSelectedResources = async (sectionData: any) => { const homeworkResult = await TeachCourseApi.getSectionHomeWork(courseId.value, sectionId); if (homeworkResult.data?.result) { console.log('📋 作业资源查询成功:', homeworkResult.data.result); - // TODO: 更新对应小节的作业资源显示 data = homeworkResult.data.result } else { console.log('📋 作业资源查询无数据'); @@ -1970,16 +1965,17 @@ const getSelectedResources = async (sectionData: any) => { case 4: { // 练习类型 console.log('🏃 练习资源接口暂未实现'); - // TODO: 预留练习资源接口 - // const exerciseResult = await TeachCourseApi.getSectionExercise(courseId.value, sectionId); + const exerciseResult = await TeachCourseApi.getSectionExercise(sectionId); + console.log('🏃 练习资源查询结果:', exerciseResult); + data = exerciseResult.data.result break; } case 5: { - // 讨论类型 console.log('💬 讨论资源接口暂未实现'); - // TODO: 预留讨论资源接口 - // const discussionResult = await TeachCourseApi.getSectionDiscussion(courseId.value, sectionId); + const discussionResult = await TeachCourseApi.getSectionDiscussion(courseId.value, sectionId); + console.log('💬 讨论资源查询结果:', discussionResult); + data = discussionResult.data.result; break; } diff --git a/src/views/teacher/course/ChapterManagement.vue b/src/views/teacher/course/ChapterManagement.vue index 0b21a1e..531113f 100644 --- a/src/views/teacher/course/ChapterManagement.vue +++ b/src/views/teacher/course/ChapterManagement.vue @@ -41,9 +41,9 @@ ... - + @@ -59,6 +59,14 @@ + + + @@ -69,6 +77,7 @@ import type { DataTableColumns } from 'naive-ui' import { useRouter, useRoute } from 'vue-router' import { ChevronForwardOutline } from '@vicons/ionicons5' import ImportModal from '@/components/common/ImportModal.vue' +import PreviewModal from '@/components/common/PreviewModal.vue' import TeachCourseApi from '@/api/modules/teachCourse' const router = useRouter() @@ -97,6 +106,10 @@ interface Chapter { const showImportModal = ref(false) +// 预览弹窗相关状态 +const showPreviewModal = ref(false) +const previewSectionData = ref(null) + // 加载状态 const loading = ref(false) // const error = ref('') @@ -486,7 +499,27 @@ const columns: DataTableColumns = [ default: () => h(ChevronForwardOutline) }) : (isChapter ? h('span', {}) : null), h('span', { - style: { color: '#062333', fontSize: '13px', fontWeight: isChapter ? '600' : '400' } + style: { + color: '#062333', + fontSize: '13px', + fontWeight: isChapter ? '600' : '400', + cursor: !isChapter ? 'pointer' : 'default', + textDecoration: !isChapter ? 'none' : 'none' + }, + onClick: !isChapter ? (e: Event) => { + e.stopPropagation() + handleSectionPreview(row) + } : undefined, + onMouseenter: !isChapter ? (e: Event) => { + const target = e.target as HTMLElement + target.style.textDecoration = 'underline' + target.style.color = '#1890ff' + } : undefined, + onMouseleave: !isChapter ? (e: Event) => { + const target = e.target as HTMLElement + target.style.textDecoration = 'none' + target.style.color = '#062333' + } : undefined }, row.name) ]) } @@ -614,6 +647,40 @@ const getTypeText = (type: string) => { return typeMap[type] || '-' } +// 处理小节预览 +const handleSectionPreview = (section: Chapter) => { + console.log('预览小节:', section) + + // 检查小节是否有有效的类型 + if (!section.type || section.type === '-') { + message.warning('该小节暂未设置类型,无法预览') + return + } + + // 设置预览数据并显示弹窗 + previewSectionData.value = { + id: section.id, + name: section.name, + type: section.type, + courseId: courseId.value, + parentId: section.parentId, + level: section.level, + createTime: section.createTime + } + + showPreviewModal.value = true +} + +// 处理预览弹窗的编辑事件 +const handlePreviewEdit = (sectionData: any, detailData: any) => { + console.log('编辑小节:', sectionData, detailData) + showPreviewModal.value = false + + // 这里可以跳转到编辑页面或打开编辑弹窗 + message.info('跳转到小节编辑页面') + // 实际实现中可以使用 router.push() 跳转 +} + const fetchCourseChapters = () => { loading.value = true TeachCourseApi.getCourseSections(courseId.value).then(res => { diff --git a/src/views/teacher/course/HomeworkReview.vue b/src/views/teacher/course/HomeworkReview.vue index f155df4..2833c0c 100644 --- a/src/views/teacher/course/HomeworkReview.vue +++ b/src/views/teacher/course/HomeworkReview.vue @@ -22,6 +22,21 @@
+ +
+ + + + +
+
@@ -37,7 +52,7 @@
发布人 - 发布人:{{ homework.publisher }} + 班级:{{ homework.classNames?.join(', ') || '未绑定班级' }}
时间 @@ -68,11 +83,11 @@
-

{{ homework.content }}

+

发布人 - 发布人:{{ homework.publisher }} + 班级:{{ homework.classNames?.join(', ') || '未绑定班级' }}
时间 @@ -101,11 +116,12 @@ @@ -275,6 +400,27 @@ /* 作业列表 */ .homework-list { padding: 0; + min-height: 400px; + } + + /* 空状态样式 */ + .empty-state { + display: flex; + justify-content: center; + align-items: center; + min-height: 400px; + padding: 40px 20px; + } + + .empty-icon { + font-size: 48px; + margin-bottom: 16px; + } + + .empty-extra { + color: #999; + font-size: 14px; + margin-top: 8px; } .homework-card { diff --git a/src/views/teacher/course/HomeworkReviewDetail.vue b/src/views/teacher/course/HomeworkReviewDetail.vue index e2dbb4a..7154249 100644 --- a/src/views/teacher/course/HomeworkReviewDetail.vue +++ b/src/views/teacher/course/HomeworkReviewDetail.vue @@ -45,7 +45,7 @@