feat:更新考试记录功能

This commit is contained in:
2026-08-03 22:43:32 +08:00
parent 7ae51438f4
commit 69a5ab4851
8 changed files with 75 additions and 22 deletions

9
src/apis/exam.ts Normal file
View File

@@ -0,0 +1,9 @@
import { cloudService } from './index'
import type { IExamRecord } from '@/types/exam.ts'
export const addExamRecordApi = (data: IExamRecord): Promise<boolean> =>
cloudService({
url: '/study-api/exam/record',
method: 'post',
data
})

View File

@@ -30,7 +30,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { Delete, Edit, Picture, Document, Aim } from '@element-plus/icons-vue' import { Delete, Edit, Picture, Document, Aim } from '@element-plus/icons-vue'
import { useLibraryStore } from '@/stores/library.ts' import { useLibraryStore } from '@/stores/library.ts'
import { usePracticeStore } from '@/stores/practice.ts'
import { useQuestionStore } from '@/stores/question.ts' import { useQuestionStore } from '@/stores/question.ts'
import { useAppStore } from '@/stores/app.ts' import { useAppStore } from '@/stores/app.ts'
import type { ILibraryFile } from '@/types/library.ts' import type { ILibraryFile } from '@/types/library.ts'
@@ -41,7 +40,6 @@ import { filesize } from 'filesize'
import { ElLoading, ElMessage } from 'element-plus' import { ElLoading, ElMessage } from 'element-plus'
const libraryStore = useLibraryStore() const libraryStore = useLibraryStore()
const practiceStore = usePracticeStore()
const questionStore = useQuestionStore() const questionStore = useQuestionStore()
const appStore = useAppStore() const appStore = useAppStore()
@@ -66,8 +64,9 @@ const editClick = async (file: ILibraryFile) => {
const trainClick = async (file: ILibraryFile) => { const trainClick = async (file: ILibraryFile) => {
await libraryStore.queryFileById(file.id) await libraryStore.queryFileById(file.id)
await generateQuestion() await generateQuestion()
practiceStore.hasStart = true questionStore.type = 'Practice'
practiceStore.hasSubmit = false questionStore.hasStart = true
questionStore.hasSubmit = false
questionStore.checkList = [] questionStore.checkList = []
} }

View File

@@ -1,5 +1,6 @@
<template> <template>
<el-dialog v-model="examStore.dialogVisible" title="考试配置" width="30%" center destroy-on-close> <el-dialog v-model="examStore.dialogVisible" title="考试配置"
:width="appStore.isMobile ? '80%' : '30%'" center destroy-on-close>
<el-form ref="examFormRef" :model="examStore.config" :rules="rules" label-width="auto"> <el-form ref="examFormRef" :model="examStore.config" :rules="rules" label-width="auto">
<el-form-item label="考试学科" prop="subject"> <el-form-item label="考试学科" prop="subject">
<el-select <el-select
@@ -34,11 +35,13 @@ import { ElInputNumber, ElLoading, ElMessage, ElOption, ElSelect, type FormInsta
import { useExamStore } from '@/stores/exam.ts' import { useExamStore } from '@/stores/exam.ts'
import { useLibraryStore } from '@/stores/library.ts' import { useLibraryStore } from '@/stores/library.ts'
import { useQuestionStore } from '@/stores/question.ts' import { useQuestionStore } from '@/stores/question.ts'
import { useAppStore } from '@/stores/app.ts'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
const examStore = useExamStore() const examStore = useExamStore()
const libraryStore = useLibraryStore() const libraryStore = useLibraryStore()
const questionStore = useQuestionStore() const questionStore = useQuestionStore()
const appStore = useAppStore()
const examFormRef = ref<FormInstance>() const examFormRef = ref<FormInstance>()
@@ -59,6 +62,7 @@ const confirmClick = async (formEl: FormInstance | undefined) => {
if (!formEl) return if (!formEl) return
await formEl.validate(async (valid, fields) => { await formEl.validate(async (valid, fields) => {
if (valid) { if (valid) {
questionStore.type = 'Exam'
await generateExam() await generateExam()
} else { } else {
ElMessage.error('请先输入信息') ElMessage.error('请先输入信息')

View File

@@ -46,6 +46,7 @@ import { usePracticeStore } from '@/stores/practice.ts'
import { useLibraryStore } from '@/stores/library.ts' import { useLibraryStore } from '@/stores/library.ts'
import { useMistakeStore } from '@/stores/mistake.ts' import { useMistakeStore } from '@/stores/mistake.ts'
import { useQuestionStore } from '@/stores/question.ts' import { useQuestionStore } from '@/stores/question.ts'
import { useExamStore } from '@/stores/exam.ts'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { getMistakeList, isAnswerCorrect, optLetter } from '@/utils/practiceUtil.ts' import { getMistakeList, isAnswerCorrect, optLetter } from '@/utils/practiceUtil.ts'
import type { IMistake } from '@/types/mistake.ts' import type { IMistake } from '@/types/mistake.ts'
@@ -54,29 +55,43 @@ const practiceStore = usePracticeStore()
const libraryStore = useLibraryStore() const libraryStore = useLibraryStore()
const mistakeStore = useMistakeStore() const mistakeStore = useMistakeStore()
const questionStore = useQuestionStore() const questionStore = useQuestionStore()
const examStore = useExamStore()
const submitAnswerClick = async () => { const submitAnswerClick = async () => {
if (questionStore.questionList.find((item) => item.select.length === 0)) { if (questionStore.questionList.find((item) => item.select.length === 0)) {
ElMessage.error('还有未完成的题目') ElMessage.error('还有未完成的题目')
} else { } else {
practiceStore.hasSubmit = true questionStore.hasSubmit = true
questionStore.checkList = questionStore.questionList.map((q) => ({ questionStore.checkList = questionStore.questionList.map((q) => ({
id: q.id, id: q.id,
answer: q.answer, answer: q.answer,
select: q.select, select: q.select,
isCorrect: isAnswerCorrect(q.answer, q.select) isCorrect: isAnswerCorrect(q.answer, q.select)
})) }))
await addPracticeRecord()
await addMistakeList() await addMistakeList()
const { totalCount, correctCount, wrongCount } = practiceStore.currentRecord if (questionStore.type === 'Practice') {
await ElMessageBox.alert( await addPracticeRecord()
`${totalCount} 题 · 正确 ${correctCount} · 错误 ${wrongCount}`, const { totalCount, correctCount, wrongCount } = practiceStore.currentRecord
'训练结果', await ElMessageBox.alert(
{ `${totalCount} 题 · 正确 ${correctCount} · 错误 ${wrongCount}`,
confirmButtonText: '确认' '训练结果',
} {
) confirmButtonText: '确认'
}
)
} else {
await addExamRecord()
const { totalCount, correctCount, wrongCount } = examStore.currentRecord
await ElMessageBox.alert(
`${totalCount} 题 · 正确 ${correctCount} · 错误 ${wrongCount}`,
'考试结果',
{
confirmButtonText: '确认'
}
)
}
} }
} }
@@ -93,9 +108,24 @@ const addPracticeRecord = async () => {
await practiceStore.addRecord() await practiceStore.addRecord()
} }
const addExamRecord = async () => {
const totalCount = questionStore.checkList.length
const correctCount = questionStore.checkList.filter((c) => c.isCorrect).length
examStore.currentRecord = {
subject: examStore.config.subject,
totalCount,
correctCount,
wrongCount: totalCount - correctCount
}
await examStore.addRecord()
}
const addMistakeList = async () => { const addMistakeList = async () => {
const mistakeList = getMistakeList(questionStore.questionList, questionStore.checkList) const mistakeList = getMistakeList(questionStore.questionList, questionStore.checkList)
mistakeStore.currentMistakes = [] mistakeStore.currentMistakes = []
const subject = questionStore.type === 'Practice' ? libraryStore.currentFile.subject : examStore.config.subject
mistakeList.forEach((item) => { mistakeList.forEach((item) => {
const mistake:IMistake = { const mistake:IMistake = {
answer: item.answer, answer: item.answer,
@@ -103,7 +133,7 @@ const addMistakeList = async () => {
name: libraryStore.currentFile.name, name: libraryStore.currentFile.name,
options: item.options, options: item.options,
question: item.question, question: item.question,
subject: libraryStore.currentFile.subject, subject,
type: item.type type: item.type
} }
mistakeStore.currentMistakes.push(mistake) mistakeStore.currentMistakes.push(mistake)

View File

@@ -1,12 +1,12 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import type { IExamConfig } from '@/types/exam.ts' import type { IExamConfig, IExamRecord } from '@/types/exam.ts'
import { addExamRecordApi } from '@/apis/exam.ts'
export const useExamStore = defineStore('exam', { export const useExamStore = defineStore('exam', {
state: () => ({ state: () => ({
hasStart: false,
hasSubmit: false,
dialogVisible: false, dialogVisible: false,
config: {} as IExamConfig config: {} as IExamConfig,
currentRecord: {} as IExamRecord
}), }),
actions: { actions: {
getEmptyConfig(): IExamConfig { getEmptyConfig(): IExamConfig {
@@ -14,6 +14,9 @@ export const useExamStore = defineStore('exam', {
subject: '', subject: '',
total: 50 total: 50
} }
},
async addRecord() {
await addExamRecordApi(this.currentRecord)
} }
} }
}) })

View File

@@ -4,8 +4,6 @@ import type { IPracticeRecord } from '@/types/practice.ts'
export const usePracticeStore = defineStore('practice', { export const usePracticeStore = defineStore('practice', {
state: () => ({ state: () => ({
hasStart: false,
hasSubmit: false,
libraryFileId: 0, libraryFileId: 0,
recordList: [] as IPracticeRecord[], recordList: [] as IPracticeRecord[],
currentRecord: {} as IPracticeRecord currentRecord: {} as IPracticeRecord

View File

@@ -7,6 +7,7 @@ export const useQuestionStore = defineStore('question', {
hasStart: false, hasStart: false,
hasSubmit: false, hasSubmit: false,
hasGenerateQuestion: false, hasGenerateQuestion: false,
type: 'Practice' as 'Practice' | 'Exam',
questionContent: '', questionContent: '',
questionList: [] as IQuestion[], questionList: [] as IQuestion[],
recordList: [] as IPracticeRecord[], recordList: [] as IPracticeRecord[],

View File

@@ -2,3 +2,12 @@ export interface IExamConfig {
subject: string; subject: string;
total: number; total: number;
} }
export interface IExamRecord {
id?: number;
subject: string;
totalCount: number;
correctCount: number;
wrongCount: number;
createTime?: string;
}