feat(course): 添加自定义考试功能并优化试卷组件

- 新增自定义考试试卷类型支持
- 实现试卷预览和编辑功能
- 添加试题管理组件,支持单选、多选、判断题
- 集成雪花ID生成器用于试题唯一标识
- 优化课程创建流程,支持考试内容配置
- 扩展SCSS样式库,增加flex布局和间距工具类
- 新增课程API模块,完善考试相关接口
- 实现试卷内容动态加载和保存逻辑
This commit is contained in:
陈昱达
2025-11-25 14:45:44 +08:00
parent f07582d5c1
commit 6c87968ab4
8 changed files with 1240 additions and 14 deletions

View File

@@ -2,7 +2,7 @@
import dragCollapse from "./dragCollapse.vue";
import { ElButton, ElCheckbox, ElDialog, ElMessageBox } from "element-plus";
import dragTable from "./dragTable.vue";
import { ref, reactive } from "vue";
import { ref, watch } from "vue";
defineOptions({
name: "CreateCourse",
});
@@ -14,6 +14,7 @@ import EditorComp from "@/components/CreatedCourse/preview/EditorComp.vue";
import DocComp from "@/components/CreatedCourse/preview/DocComp.vue";
import LinkComp from "@/components/CreatedCourse/preview/LinkComp.vue";
import ScormComp from "@/components/CreatedCourse/preview/ScormComp.vue";
import PaperComp from "@/components/CreatedCourse/preview/PaperComp.vue";
import { getType } from "@/hooks/useCreateCourseMaps";
const mapComponents = [
VideoComp,
@@ -22,6 +23,7 @@ const mapComponents = [
DocComp,
LinkComp,
ScormComp,
PaperComp,
];
// 使用课程数据hook
@@ -30,10 +32,24 @@ const { courseMetadata, courseList, courseActionButtons, addChapter } =
const isPreview = ref(false);
const chooseItemData = ref({});
const showSettingDialog = ref(false);
// 添加操作的时候 弹窗是否弹出对应类型表单
const isNext = ref(true);
const showTablePreview = ref(false);
// 定义表格列
const showDialog = ref(false);
const classId = ref("");
watch(
() => courseMetadata.chooseIndex,
(newVal) => {
console.log(newVal);
console.log(courseList.value[newVal]);
classId.value = courseList.value[newVal].id;
console.log(classId.value);
}
);
// 课程操作映射
const courseOperations = {
addVideo: () => {
@@ -67,6 +83,7 @@ const courseOperations = {
addExam: () => {
courseMetadata.resType = 61;
showDialog.value = true;
isNext.value = false;
},
addHomework: () => {
console.log("添加作业功能调用");
@@ -104,6 +121,8 @@ const choosePreviewItem = (data) => {
};
// 保存
const saveContent = () => {
console.log(chooseItemData.value);
if (courseMetadata.selectionIndex !== null) {
courseList.value[courseMetadata.chooseIndex].data[
courseMetadata.selectionIndex
@@ -116,6 +135,8 @@ const saveContent = () => {
}
showDialog.value = false;
showSettingDialog.value = false;
// 可以调用保存方法 保存考试
};
const deleteRow = (data) => {
courseMetadata.chooseIndex = data.index;
@@ -145,6 +166,12 @@ const previewRow = (data) => {
isPreview.value = true;
showSettingDialog.value = true;
};
// 自定义考试
const chooseCusExam = (data) => {
chooseItemData.value = data;
showSettingDialog.value = true;
};
</script>
<template>
@@ -201,6 +228,7 @@ const previewRow = (data) => {
@choosePreviewItem="choosePreviewItem"
:resType="courseMetadata.resType"
:showTablePreview="showTablePreview"
@chooseCusExam="chooseCusExam"
></chooseFileList>
</el-dialog>
@@ -209,15 +237,19 @@ const previewRow = (data) => {
v-model="showSettingDialog"
:title="isPreview ? '预览' : getType(chooseItemData.resType)"
>
<div v-for="item in mapComponents">
<component
v-if="
Number(chooseItemData.resType) === item.resType && showSettingDialog
"
:is="item"
v-model:dialogVideoForm="chooseItemData"
:isPreview="isPreview"
></component>
<div style="max-height: 600px; overflow: auto">
<template v-for="item in mapComponents">
<component
v-if="
Number(chooseItemData.resType) === item.resType &&
showSettingDialog
"
:is="item"
v-model:dialogVideoForm="chooseItemData"
:isPreview="isPreview"
:classId="classId"
></component>
</template>
</div>
<template #footer>