feat:更新记录模块

This commit is contained in:
2026-08-09 14:01:59 +08:00
parent 8f92c55852
commit 1a63e14e82
15 changed files with 94 additions and 143 deletions

View File

@@ -1,9 +0,0 @@
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

@@ -1,15 +1,15 @@
import { cloudService } from './index'
import type { IMistake } from '@/types/mistake.ts'
export const queryMistakeListApi = (): Promise<IMistake[]> =>
export const queryMistakeListApi = (subject: string): Promise<IMistake[]> =>
cloudService({
url: '/study-api/mistake',
url: `/study-api/mistake/${subject}`,
method: 'get'
})
export const addMistakeListApi = (data: IMistake[]): Promise<boolean> =>
export const addMistakeListApi = (subject: string, data: IMistake[]): Promise<boolean> =>
cloudService({
url: '/study-api/mistake',
url: `/study-api/mistake/${subject}`,
method: 'post',
data
})

View File

@@ -1,15 +0,0 @@
import { cloudService } from './index'
import type { IPracticeRecord } from '@/types/practice.ts'
export const queryPracticeRecordApi = (id: number): Promise<IPracticeRecord[]> =>
cloudService({
url: `/study-api/practice/record/${id}`,
method: 'get'
})
export const addPracticeRecordApi = (data: IPracticeRecord): Promise<boolean> =>
cloudService({
url: '/study-api/practice/record',
method: 'post',
data
})

15
src/apis/record.ts Normal file
View File

@@ -0,0 +1,15 @@
import { cloudService } from './index'
import type { IRecord } from '@/types/record.ts'
export const queryRecordApi = (subject: string): Promise<IRecord[]> =>
cloudService({
url: `/study-api/record/${subject}`,
method: 'get'
})
export const addRecordApi = (subject: string, data: IRecord): Promise<boolean> =>
cloudService({
url: `/study-api/record/${subject}`,
method: 'post',
data
})

View File

@@ -42,20 +42,18 @@
</template>
<script setup lang="ts">
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 { useRecordStore } from '@/stores/record.ts'
import { useLibraryStore } from '@/stores/library.ts'
import { ElMessage, ElMessageBox } from 'element-plus'
import { getMistakeList, isAnswerCorrect, optLetter } from '@/utils/practiceUtil.ts'
import type { IMistake } from '@/types/mistake.ts'
const practiceStore = usePracticeStore()
const libraryStore = useLibraryStore()
const mistakeStore = useMistakeStore()
const questionStore = useQuestionStore()
const examStore = useExamStore()
const recordStore = useRecordStore()
const libraryStore = useLibraryStore()
const submitAnswerClick = async () => {
if (questionStore.questionList.find((item) => item.select.length === 0)) {
@@ -70,77 +68,46 @@ const submitAnswerClick = async () => {
}))
await addMistakeList()
await addRecord()
}
}
const addRecord = async () => {
const totalCount = questionStore.checkList.length
const correctCount = questionStore.checkList.filter((c) => c.isCorrect).length
const wrongCount = totalCount - correctCount
recordStore.currentRecord = {
type: questionStore.type,
totalCount,
correctCount,
wrongCount
}
await recordStore.addRecord(libraryStore.currentFile.subject)
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: '确认'
}
)
}
}
}
const addPracticeRecord = async () => {
const totalCount = questionStore.checkList.length
const correctCount = questionStore.checkList.filter((c) => c.isCorrect).length
practiceStore.currentRecord = {
libraryFileId: libraryStore.currentFile.id,
totalCount,
correctCount,
wrongCount: totalCount - correctCount
}
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
const module = questionStore.type === 'Practice' ? libraryStore.currentFile.module : ''
const name = questionStore.type === 'Practice' ? libraryStore.currentFile.name : ''
mistakeList.forEach((item) => {
const mistake:IMistake = {
const mistake: IMistake = {
answer: item.answer,
module,
name,
options: item.options,
question: item.question,
subject,
type: item.type
}
mistakeStore.currentMistakes.push(mistake)
})
await mistakeStore.addMistakeList()
await mistakeStore.addMistakeList(libraryStore.currentFile.subject)
}
</script>

View File

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

View File

@@ -8,11 +8,11 @@ export const useMistakeStore = defineStore('mistake', {
currentMistakes: [] as IMistake[]
}),
actions: {
async queryMistakeList() {
this.mistakeList = await queryMistakeListApi()
async queryMistakeList(subject: string) {
this.mistakeList = await queryMistakeListApi(subject)
},
async addMistakeList() {
await addMistakeListApi(this.currentMistakes)
async addMistakeList(subject: string) {
await addMistakeListApi(subject, this.currentMistakes)
},
async deleteMistakeById(id: number) {
await deleteMistakeApi(id)

View File

@@ -1,19 +0,0 @@
import { defineStore } from 'pinia'
import { addPracticeRecordApi, queryPracticeRecordApi } from '@/apis/practice.ts'
import type { IPracticeRecord } from '@/types/practice.ts'
export const usePracticeStore = defineStore('practice', {
state: () => ({
libraryFileId: 0,
recordList: [] as IPracticeRecord[],
currentRecord: {} as IPracticeRecord
}),
actions: {
async queryRecord() {
this.recordList = await queryPracticeRecordApi(this.libraryFileId)
},
async addRecord() {
await addPracticeRecordApi(this.currentRecord)
}
}
})

View File

@@ -1,6 +1,6 @@
import { defineStore } from 'pinia'
import type { IPracticeCheck, IPracticeRecord } from '@/types/practice.ts'
import type { IQuestion } from '@/types/question.ts'
import type { IRecord, IRecordCheck } from '@/types/record.ts'
export const useQuestionStore = defineStore('question', {
state: () => ({
@@ -8,7 +8,7 @@ export const useQuestionStore = defineStore('question', {
type: 'Practice' as 'Practice' | 'Exam',
questionContent: '',
questionList: [] as IQuestion[],
recordList: [] as IPracticeRecord[],
checkList: [] as IPracticeCheck[]
recordList: [] as IRecord[],
checkList: [] as IRecordCheck[]
})
})

18
src/stores/record.ts Normal file
View File

@@ -0,0 +1,18 @@
import { defineStore } from 'pinia'
import { addRecordApi, queryRecordApi } from '@/apis/record.ts'
import type { IRecord } from '@/types/record.ts'
export const useRecordStore = defineStore('record', {
state: () => ({
recordList: [] as IRecord[],
currentRecord: {} as IRecord
}),
actions: {
async queryRecord(subject: string) {
this.recordList = await queryRecordApi(subject)
},
async addRecord(subject: string) {
await addRecordApi(subject, this.currentRecord)
}
}
})

View File

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

View File

@@ -1,8 +1,5 @@
export interface IMistake {
id?: number;
subject: string;
module: string;
name: string;
type: string;
question: string;
options: string[];

View File

@@ -1,13 +1,13 @@
export interface IPracticeCheck {
export interface IRecordCheck {
id: number;
answer: string[];
select: string[];
isCorrect: boolean;
}
export interface IPracticeRecord {
export interface IRecord {
id?: number;
libraryFileId:number;
type: string;
totalCount: number;
correctCount: number;
wrongCount: number;

View File

@@ -9,6 +9,7 @@
</div>
<question-list v-if="questionStore.questionList.length > 0"/>
<p v-else>请点击开始考试按钮进入考试</p>
<exam-dialog />
</div>

View File

@@ -7,13 +7,21 @@
</div>
</div>
<div class="filter-bar card-item">
<div class="filter-row">
<span class="filter-label">学科</span>
<el-segmented v-model="libraryStore.selectedSubject"
:options="libraryStore.subjectOptions"/>
</div>
</div>
<div class="mistake-record">
<div v-if="mistakeStore.mistakeList.length" class="mistake-list">
<el-card v-for="item in mistakeStore.mistakeList"
:key="item.id" class="mistake-card" shadow="never">
<div class="library">
<el-tag type="primary" effect="dark">{{ item.subject }} · {{ item.module }}</el-tag>
<el-button type="success" size="small" @click="deleteClick(item.id)">已掌握</el-button>
<el-tag type="primary" effect="dark">{{ libraryStore.selectedSubject }}</el-tag>
<el-button type="success" size="small" @click="deleteClick(item)">已掌握</el-button>
</div>
<div class="question">{{ item.question }}</div>
@@ -38,11 +46,13 @@ import { useMistakeStore } from '@/stores/mistake.ts'
import { optLetter } from '@/utils/practiceUtil.ts'
import type { IMistake } from '@/types/mistake.ts'
import { ElMessageBox } from 'element-plus'
import { useLibraryStore } from '@/stores/library.ts'
const mistakeStore = useMistakeStore()
const libraryStore = useLibraryStore()
onMounted(async () => {
await mistakeStore.queryMistakeList()
await mistakeStore.queryMistakeList(libraryStore.selectedSubject as string)
})
const optionClass = (item: IMistake, index: number) => {
@@ -53,14 +63,14 @@ const optionClass = (item: IMistake, index: number) => {
}
}
const deleteClick = (id: number) => {
const deleteClick = (mistake: IMistake) => {
ElMessageBox.confirm('确定已掌握该错题?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
await mistakeStore.deleteMistakeById(id)
await mistakeStore.queryMistakeList()
await mistakeStore.deleteMistakeById(mistake.id as number)
await mistakeStore.queryMistakeList(libraryStore.selectedSubject as string)
})
}
</script>