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

View File

@@ -1,5 +1,6 @@
<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-item label="考试学科" prop="subject">
<el-select
@@ -34,11 +35,13 @@ import { ElInputNumber, ElLoading, ElMessage, ElOption, ElSelect, type FormInsta
import { useExamStore } from '@/stores/exam.ts'
import { useLibraryStore } from '@/stores/library.ts'
import { useQuestionStore } from '@/stores/question.ts'
import { useAppStore } from '@/stores/app.ts'
import { computed, ref } from 'vue'
const examStore = useExamStore()
const libraryStore = useLibraryStore()
const questionStore = useQuestionStore()
const appStore = useAppStore()
const examFormRef = ref<FormInstance>()
@@ -59,6 +62,7 @@ const confirmClick = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate(async (valid, fields) => {
if (valid) {
questionStore.type = 'Exam'
await generateExam()
} else {
ElMessage.error('请先输入信息')

View File

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

View File

@@ -1,12 +1,12 @@
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', {
state: () => ({
hasStart: false,
hasSubmit: false,
dialogVisible: false,
config: {} as IExamConfig
config: {} as IExamConfig,
currentRecord: {} as IExamRecord
}),
actions: {
getEmptyConfig(): IExamConfig {
@@ -14,6 +14,9 @@ export const useExamStore = defineStore('exam', {
subject: '',
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', {
state: () => ({
hasStart: false,
hasSubmit: false,
libraryFileId: 0,
recordList: [] as IPracticeRecord[],
currentRecord: {} as IPracticeRecord

View File

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

View File

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