feat:更新考试记录功能
This commit is contained in:
9
src/apis/exam.ts
Normal file
9
src/apis/exam.ts
Normal 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
|
||||||
|
})
|
||||||
@@ -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 = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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('请先输入信息')
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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[],
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user