From 5b16fc5be6857018ea93199869e11c48958604de Mon Sep 17 00:00:00 2001 From: chenyuan Date: Fri, 9 Oct 2026 12:42:13 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E7=AE=80=E7=AD=94=E9=A2=98?= =?UTF-8?q?=E8=B5=84=E6=96=99=E6=94=AF=E6=8C=81=E4=B8=8A=E4=BC=A0Excel?= =?UTF-8?q?=EF=BC=9B=E6=9C=AA=E5=8F=91=E5=B8=83=E8=80=83=E8=AF=95=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=88=A0=E9=99=A4=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 教师端/平台管理端题目资料上传的 accept 增加 .xls/.xlsx - 考试列表"未发布"状态增加删除按钮,确认文案区分未发布与已结束 --- src/views/platformAdmin/questionBank/index.vue | 2 +- src/views/teacherEnd/exam/index.vue | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/views/platformAdmin/questionBank/index.vue b/src/views/platformAdmin/questionBank/index.vue index 85b966a..b36e882 100644 --- a/src/views/platformAdmin/questionBank/index.vue +++ b/src/views/platformAdmin/questionBank/index.vue @@ -11,7 +11,7 @@
- + diff --git a/src/views/teacherEnd/exam/index.vue b/src/views/teacherEnd/exam/index.vue index adc0c63..605eefb 100644 --- a/src/views/teacherEnd/exam/index.vue +++ b/src/views/teacherEnd/exam/index.vue @@ -15,6 +15,7 @@
撤回 编辑 + 删除 指定人回退
@@ -112,7 +113,7 @@ 正确错误 - 上传资料 + 上传资料 {{ questionForm.attachmentName }} @@ -175,7 +176,7 @@ async function doImport({ file }) { importing.value = true; try { const form = n async function downloadTemplate(format) { const extension = format === "excel" ? "xlsx" : "docx"; saveAs(await examApi.downloadQuestionTemplate(format), `考试题库${format === "excel" ? "Excel" : "Word"}导入模板.${extension}`); } async function publish(row) { await ElMessageBox.confirm(`确认发布“${row.name}”?发布后将在设定时间自动开始。`, "发布考试", { type: "warning" }); await examApi.publishExam(row.id); ElMessage.success("已发布"); loadExams(); } async function withdraw(row) { await examApi.withdrawExam(row.id); ElMessage.success("已撤回"); loadExams(); } -async function removeExam(row) { await ElMessageBox.confirm(`确认永久删除“${row.name}”?仅在已导出全部答卷后允许删除。`, "删除考试", { type: "warning", confirmButtonText: "确认删除" }); await examApi.deleteExam(row.id); ElMessage.success("已删除"); loadExams(); } +async function removeExam(row) { const message = row.status === "DRAFT" ? `确认删除未发布的考试“${row.name}”?删除后无法恢复。` : `确认永久删除“${row.name}”?仅在已导出全部答卷后允许删除。`; await ElMessageBox.confirm(message, "删除考试", { type: "warning", confirmButtonText: "确认删除" }); await examApi.deleteExam(row.id); ElMessage.success("已删除"); loadExams(); } async function handleExport(command, row) { const actions = { paper: [examApi.exportExamPaper, `${row.name}试卷.docx`], scores: [examApi.exportExamScores, `${row.name}班级成绩.xlsx`], submissions: [examApi.exportExamSubmissions, `${row.name}全部试卷.zip`] }; const [action, filename] = actions[command]; saveAs(await action(row.id), filename); if (command === "submissions") loadExams(); } function displayAnswer(value) { if (Array.isArray(value)) return value.join("、"); if (value === true) return "正确"; if (value === false) return "错误"; return value || "-"; } function formatTime(value) { return value ? new Date(value).toLocaleString("zh-CN", { hour12: false }).replaceAll("/", "-") : "-"; } From 2b640c32f50f0d9f6a0e3b09f26520db881b06d4 Mon Sep 17 00:00:00 2001 From: qinzhenpen Date: Fri, 9 Oct 2026 14:39:38 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(=E8=80=83=E8=AF=95=E7=B3=BB=E7=BB=9F):?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E9=A2=98=E7=9B=AE=E6=9D=A5=E6=BA=90?= =?UTF-8?q?=E7=AD=9B=E9=80=89=E3=80=81=E4=BE=A7=E8=BE=B9=E6=A0=8F=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E3=80=81=E9=A2=98=E7=9B=AE=E6=8E=92=E5=BA=8F=E5=8F=8A?= =?UTF-8?q?=E5=88=86=E9=A1=B5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/styles/sidebar.scss | 5 +++-- src/views/exam/index.vue | 4 ++-- src/views/exam/take.vue | 2 +- .../platformAdmin/questionBank/index.vue | 13 +++++++------ src/views/teacherEnd/exam/editor.vue | 4 ++-- src/views/teacherEnd/exam/index.vue | 19 +++++++++++++++---- 6 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss index 57435f0..788f1d7 100644 --- a/src/assets/styles/sidebar.scss +++ b/src/assets/styles/sidebar.scss @@ -1013,8 +1013,9 @@ * 同时隐藏教师端唯一的分组标题"教学管理"(标识),仅保留菜单项 */ #app .teacherLayout { + --teacher-sidebar-width: 180px; .main-container { - margin-left: 180px !important; + margin-left: var(--teacher-sidebar-width) !important; } // 收起后侧边栏仅保留 64px 图标轨道,主内容同步释放展开态的空间。 @@ -1023,7 +1024,7 @@ } .sidebar-container { - width: 180px !important; + width: var(--teacher-sidebar-width) !important; } // 隐藏教师端顶部分组标题("教学管理"标识),不影响学生端多分组标题 .student-course-nav > .student-course-heading { diff --git a/src/views/exam/index.vue b/src/views/exam/index.vue index 99c2ad7..0c978af 100644 --- a/src/views/exam/index.vue +++ b/src/views/exam/index.vue @@ -6,8 +6,8 @@ diff --git a/src/views/teacherEnd/exam/editor.vue b/src/views/teacherEnd/exam/editor.vue index d409a3f..3f76792 100644 --- a/src/views/teacherEnd/exam/editor.vue +++ b/src/views/teacherEnd/exam/editor.vue @@ -193,7 +193,7 @@ -
取消保存考试立即发布
+
取消保存考试立即发布
@@ -1048,7 +1048,7 @@ function toBoolean(value, fallback) { if (value === undefined || value === null diff --git a/src/views/teacherEnd/exam/index.vue b/src/views/teacherEnd/exam/index.vue index adc0c63..16542d5 100644 --- a/src/views/teacherEnd/exam/index.vue +++ b/src/views/teacherEnd/exam/index.vue @@ -28,6 +28,10 @@ + + + + @@ -79,10 +83,10 @@ -
+
正确错误 - 上传资料 + 上传资料 {{ questionForm.attachmentName }} @@ -141,11 +145,17 @@ const typeName = Object.fromEntries(typeOptions.map((item) => [item.value, item. const typeTone = { SINGLE: "", MULTIPLE: "success", TRUE_FALSE: "warning", SHORT_ANSWER: "info" }; const statusMeta = { DRAFT: { label: "未发布", tone: "info" }, NOT_STARTED: { label: "未开始", tone: "" }, IN_PROGRESS: { label: "进行中", tone: "success" }, ENDED: { label: "已结束", tone: "warning" } }; const questionQuery = reactive({ type: "", taskKey: "", keyword: "" }); +const sourceFilter = ref(""); // 题目来源前端筛选:PLATFORM=平台题库 / CUSTOM=教师自建(非 PLATFORM) // 题库列表使用前端分页:后端一次返回全部,前端按页切片 const questionPager = reactive({ page: 1, pageSize: 10 }); +const filteredQuestions = computed(() => { + const st = sourceFilter.value; + if (!st) return questions.value; + return questions.value.filter(q => st === "PLATFORM" ? q.sourceType === "PLATFORM" : q.sourceType !== "PLATFORM"); +}); const pagedQuestions = computed(() => { const start = (questionPager.page - 1) * questionPager.pageSize; - return questions.value.slice(start, start + questionPager.pageSize); + return filteredQuestions.value.slice(start, start + questionPager.pageSize); }); const emptyQuestion = () => ({ id: null, taskKey: "", type: "SINGLE", stem: "", options: [{ label: "A", content: "" }, { label: "B", content: "" }, { label: "C", content: "" }, { label: "D", content: "" }], answer: [], analysis: "", attachmentName: "", attachmentUrl: "" }); const questionForm = reactive(emptyQuestion()); @@ -158,6 +168,7 @@ let examsMounted = false; // KeepAlive 缓存页面:再次进入时刷新考 onActivated(() => { if (examsMounted) loadExams(); examsMounted = true; }); async function loadProjects() { try { projectOptions.value = (await examApi.getQuestionProjects()).data || []; } catch (e) { projectOptions.value = []; } } async function loadQuestions() { loading.value = true; try { questionPager.page = 1; questions.value = (await examApi.getQuestions(questionQuery)).data || []; } finally { loading.value = false; } } +function resetQuestionPager() { questionPager.page = 1; } async function loadExams() { loading.value = true; try { exams.value = (await examApi.getTeacherExams({ keyword: examKeyword.value })).data || []; } finally { loading.value = false; } } function openQuestion(row) { questionReadonly.value = row?.sourceType === 'PLATFORM'; Object.assign(questionForm, row ? JSON.parse(JSON.stringify(row)) : emptyQuestion()); if (!Array.isArray(questionForm.answer) && isChoice.value) questionForm.answer = []; questionDialog.value = true; } function openAi() { router.push('/exam/ai-generate'); }