style: 调整练习考试页面

This commit is contained in:
QDKF 2025-08-29 22:54:05 +08:00
parent 39fff08a0d
commit 8000bde1b9
7 changed files with 1539 additions and 4210 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1,52 @@
<template>
<div class="custom-checkbox" :class="{ checked: modelValue }" @click="toggle">
<span v-if="modelValue" class="checkmark"></span>
</div>
</template>
<script setup lang="ts">
interface Props {
modelValue: boolean
}
interface Emits {
(e: 'update:modelValue', value: boolean): void
}
const props = defineProps<Props>()
const emit = defineEmits<Emits>()
const toggle = () => {
emit('update:modelValue', !props.modelValue)
}
</script>
<style scoped>
.custom-checkbox {
width: 20px;
height: 20px;
border: 1px solid #0088D1;
border-radius: 3px;
display: flex;
align-items: center;
justify-content: center;
background-color: transparent;
flex-shrink: 0;
cursor: pointer;
transition: all 0.2s ease;
}
.custom-checkbox.checked {
background-color: #0088D1;
border-color: #0088D1;
}
.checkmark {
width: 10px;
height: 5px;
border: solid white;
border-width: 0 0 1.5px 1.5px;
transform: rotate(-45deg);
margin-top: -1px;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -270,7 +270,7 @@ watch(() => props.show, (newVal) => {
}
.modal-title {
font-size: 8px;
font-size: 18px;
padding-bottom: 10px;
font-weight: 500;
color: #000;

1141
src/views/ExamDetail.vue Normal file

File diff suppressed because it is too large Load Diff

View File

@ -972,9 +972,7 @@
<div class="search-input-container">
<input v-model="downloadFilter.keyword" type="text" class="search-input" placeholder="请输入文件名称" />
<button class="search-btn">
<img
src="/images/profile/search.png"
alt="搜索图标" class="search-icon" />
<img src="/images/profile/search.png" alt="搜索图标" class="search-icon" />
</button>
</div>
</div>
@ -1064,8 +1062,7 @@
</div>
<!-- 考试详情页面 -->
<ExamDetail v-if="showExamDetail && currentExamDetail" :currentExamDetail="currentExamDetail"
:currentDetailType="currentDetailType" @close="closeExamDetail" />
</template>
@ -1074,12 +1071,13 @@
import { ref, computed, onMounted, onActivated, reactive } from 'vue'
import { useMessage, NInput, NForm, NFormItem } from 'naive-ui'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import { useUserStore } from '@/stores/user'
import SafeAvatar from '@/components/common/SafeAvatar.vue'
import ExamDetail from '../components/ExamDetail.vue';
import QuillEditor from '@/components/common/QuillEditor.vue'
const { t, locale } = useI18n()
const router = useRouter()
//
const bannerImage = computed(() => {
@ -1135,36 +1133,36 @@ interface Exam {
}
//
interface ExamOption {
id: string
text: string
image?: string
}
// interface ExamOption {
// id: string
// text: string
// image?: string
// }
//
interface ExamQuestion {
id: number
type: 'single' | 'multiple'
title: string
content: string
options: ExamOption[]
correctAnswers: string[]
userAnswers: string[]
isCorrect: boolean
}
// interface ExamQuestion {
// id: number
// type: 'single' | 'multiple'
// title: string
// content: string
// options: ExamOption[]
// correctAnswers: string[]
// userAnswers: string[]
// isCorrect: boolean
// }
//
interface ExamDetail {
id: number
title: string
examDate: string
duration: number
totalQuestions: number
correctCount: number
wrongCount: number
score: number
questions: ExamQuestion[]
}
// interface ExamDetail {
// id: number
// title: string
// examDate: string
// duration: number
// totalQuestions: number
// correctCount: number
// wrongCount: number
// score: number
// questions: ExamQuestion[]
// }
//
interface Practice {
@ -1181,17 +1179,17 @@ interface Practice {
}
//
interface PracticeDetail {
id: number
title: string
practiceDate: string
duration: number
totalQuestions: number
correctCount: number
wrongCount: number
score: number
questions: ExamQuestion[]
}
// interface PracticeDetail {
// id: number
// title: string
// practiceDate: string
// duration: number
// totalQuestions: number
// correctCount: number
// wrongCount: number
// score: number
// questions: ExamQuestion[]
// }
//
interface Activity {
@ -1604,180 +1602,180 @@ const mockExams: Exam[] = [
]
//
const mockExamDetails: { [key: number]: ExamDetail } = {
3: {
id: 3,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-30 12:00',
duration: 100,
totalQuestions: 120,
correctCount: 90,
wrongCount: 10,
score: 98,
questions: [
{
id: 1,
type: 'single',
title: '[单选题]',
content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
options: [
{ id: 'A', text: 'A.操作规范说明书' },
{ id: 'B', text: 'B.应急处理措施' },
{ id: 'C', text: 'C.安全标签' },
{ id: 'D', text: 'D.产品合格证' }
],
correctAnswers: ['B'],
userAnswers: ['B'],
isCorrect: true
},
{
id: 2,
type: 'multiple',
title: '[多选题]',
content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
options: [
{ id: 'A', text: 'A.操作规范说明书', image: '/images/exam/option-a.png' },
{ id: 'B', text: 'B.应急处理措施', image: '/images/exam/option-b.png' },
{ id: 'C', text: 'C.安全标签' },
{ id: 'D', text: 'D.产品合格证', image: '/images/exam/option-d.png' },
{ id: 'E', text: 'E.产品标签' }
],
correctAnswers: ['A', 'B'],
userAnswers: ['A', 'B'],
isCorrect: true
}
]
},
6: {
id: 6,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-30 12:00',
duration: 100,
totalQuestions: 120,
correctCount: 90,
wrongCount: 10,
score: 98,
questions: [
{
id: 1,
type: 'single',
title: '[单选题]',
content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
options: [
{ id: 'A', text: 'A.操作规范说明书' },
{ id: 'B', text: 'B.应急处理措施' },
{ id: 'C', text: 'C.安全标签' },
{ id: 'D', text: 'D.产品合格证' }
],
correctAnswers: ['B'],
userAnswers: ['B'],
isCorrect: true
},
{
id: 2,
type: 'multiple',
title: '[多选题]',
content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
options: [
{ id: 'A', text: 'A.操作规范说明书', image: '/images/exam/option-a.png' },
{ id: 'B', text: 'B.应急处理措施', image: '/images/exam/option-b.png' },
{ id: 'C', text: 'C.安全标签' },
{ id: 'D', text: 'D.产品合格证', image: '/images/exam/option-d.png' },
{ id: 'E', text: 'E.产品标签' }
],
correctAnswers: ['A', 'B'],
userAnswers: ['A', 'B'],
isCorrect: true
}
]
},
8: {
id: 8,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-30 12:00',
duration: 100,
totalQuestions: 120,
correctCount: 90,
wrongCount: 10,
score: 98,
questions: [
{
id: 1,
type: 'single',
title: '[单选题]',
content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
options: [
{ id: 'A', text: 'A.操作规范说明书' },
{ id: 'B', text: 'B.应急处理措施' },
{ id: 'C', text: 'C.安全标签' },
{ id: 'D', text: 'D.产品合格证' }
],
correctAnswers: ['B'],
userAnswers: ['B'],
isCorrect: true
},
{
id: 2,
type: 'multiple',
title: '[多选题]',
content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
options: [
{ id: 'A', text: 'A.操作规范说明书', image: '/images/exam/option-a.png' },
{ id: 'B', text: 'B.应急处理措施', image: '/images/exam/option-b.png' },
{ id: 'C', text: 'C.安全标签' },
{ id: 'D', text: 'D.产品合格证', image: '/images/exam/option-d.png' },
{ id: 'E', text: 'E.产品标签' }
],
correctAnswers: ['A', 'B'],
userAnswers: ['A', 'B'],
isCorrect: true
}
]
},
9: {
id: 9,
title: 'C++语言程序设计基础考试',
examDate: '2025-07-30 12:00',
duration: 100,
totalQuestions: 120,
correctCount: 90,
wrongCount: 10,
score: 98,
questions: [
{
id: 1,
type: 'single',
title: '[单选题]',
content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
options: [
{ id: 'A', text: 'A.操作规范说明书' },
{ id: 'B', text: 'B.应急处理措施' },
{ id: 'C', text: 'C.安全标签' },
{ id: 'D', text: 'D.产品合格证' }
],
correctAnswers: ['B'],
userAnswers: ['B'],
isCorrect: true
},
{
id: 2,
type: 'multiple',
title: '[多选题]',
content: '危险化学品生产企业应当提供危险化学品安全技术说明书,并在包装(包括外包装)上标识,或者将技术与包装内危险化学品相符的化学品()和安全技术说明书。',
options: [
{ id: 'A', text: 'A.操作规范说明书', image: '/images/exam/option-a.png' },
{ id: 'B', text: 'B.应急处理措施', image: '/images/exam/option-b.png' },
{ id: 'C', text: 'C.安全标签' },
{ id: 'D', text: 'D.产品合格证', image: '/images/exam/option-d.png' },
{ id: 'E', text: 'E.产品标签' }
],
correctAnswers: ['A', 'B'],
userAnswers: ['A', 'B'],
isCorrect: true
}
]
}
}
// const mockExamDetails: { [key: number]: ExamDetail } = {
// 3: {
// id: 3,
// title: 'C++',
// examDate: '2025-07-30 12:00',
// duration: 100,
// totalQuestions: 120,
// correctCount: 90,
// wrongCount: 10,
// score: 98,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[]',
// content: '',
// options: [
// { id: 'A', text: 'A.' },
// { id: 'B', text: 'B.' },
// { id: 'C', text: 'C.' },
// { id: 'D', text: 'D.' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// },
// {
// id: 2,
// type: 'multiple',
// title: '[]',
// content: '',
// options: [
// { id: 'A', text: 'A.', image: '/images/exam/option-a.png' },
// { id: 'B', text: 'B.', image: '/images/exam/option-b.png' },
// { id: 'C', text: 'C.' },
// { id: 'D', text: 'D.', image: '/images/exam/option-d.png' },
// { id: 'E', text: 'E.' }
// ],
// correctAnswers: ['A', 'B'],
// userAnswers: ['A', 'B'],
// isCorrect: true
// }
// ]
// },
// 6: {
// id: 6,
// title: 'C++',
// examDate: '2025-07-30 12:00',
// duration: 100,
// totalQuestions: 120,
// correctCount: 90,
// wrongCount: 10,
// score: 98,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[]',
// content: '',
// options: [
// { id: 'A', text: 'A.' },
// { id: 'B', text: 'B.' },
// { id: 'C', text: 'C.' },
// { id: 'D', text: 'D.' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// },
// {
// id: 2,
// type: 'multiple',
// title: '[]',
// content: '',
// options: [
// { id: 'A', text: 'A.', image: '/images/exam/option-a.png' },
// { id: 'B', text: 'B.', image: '/images/exam/option-b.png' },
// { id: 'C', text: 'C.' },
// { id: 'D', text: 'D.', image: '/images/exam/option-d.png' },
// { id: 'E', text: 'E.' }
// ],
// correctAnswers: ['A', 'B'],
// userAnswers: ['A', 'B'],
// isCorrect: true
// }
// ]
// },
// 8: {
// id: 8,
// title: 'C++',
// examDate: '2025-07-30 12:00',
// duration: 100,
// totalQuestions: 120,
// correctCount: 90,
// wrongCount: 10,
// score: 98,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[]',
// content: '',
// options: [
// { id: 'A', text: 'A.' },
// { id: 'B', text: 'B.' },
// { id: 'C', text: 'C.' },
// { id: 'D', text: 'D.' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// },
// {
// id: 2,
// type: 'multiple',
// title: '[]',
// content: '',
// options: [
// { id: 'A', text: 'A.', image: '/images/exam/option-a.png' },
// { id: 'B', text: 'B.', image: '/images/exam/option-b.png' },
// { id: 'C', text: 'C.' },
// { id: 'D', text: 'D.', image: '/images/exam/option-d.png' },
// { id: 'E', text: 'E.' }
// ],
// correctAnswers: ['A', 'B'],
// userAnswers: ['A', 'B'],
// isCorrect: true
// }
// ]
// },
// 9: {
// id: 9,
// title: 'C++',
// examDate: '2025-07-30 12:00',
// duration: 100,
// totalQuestions: 120,
// correctCount: 90,
// wrongCount: 10,
// score: 98,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[]',
// content: '',
// options: [
// { id: 'A', text: 'A.' },
// { id: 'B', text: 'B.' },
// { id: 'C', text: 'C.' },
// { id: 'D', text: 'D.' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// },
// {
// id: 2,
// type: 'multiple',
// title: '[]',
// content: '',
// options: [
// { id: 'A', text: 'A.', image: '/images/exam/option-a.png' },
// { id: 'B', text: 'B.', image: '/images/exam/option-b.png' },
// { id: 'C', text: 'C.' },
// { id: 'D', text: 'D.', image: '/images/exam/option-d.png' },
// { id: 'E', text: 'E.' }
// ],
// correctAnswers: ['A', 'B'],
// userAnswers: ['A', 'B'],
// isCorrect: true
// }
// ]
// }
// }
//
const mockPractices: Practice[] = [
@ -2077,132 +2075,132 @@ const mockSystemMessages: SystemMessage[] = [
]
//
const mockPracticeDetails: { [key: number]: PracticeDetail } = {
2: {
id: 2,
title: 'C++语言程序设计基础练习题',
practiceDate: '2025-07-30 14:00',
duration: 88,
totalQuestions: 100,
correctCount: 18,
wrongCount: 15,
score: 90,
questions: [
{
id: 1,
type: 'single',
title: '[单选题]',
content: 'C++中,下列哪个关键字用于定义类?',
options: [
{ id: 'A', text: 'A.struct' },
{ id: 'B', text: 'B.class' },
{ id: 'C', text: 'C.union' },
{ id: 'D', text: 'D.enum' }
],
correctAnswers: ['B'],
userAnswers: ['B'],
isCorrect: true
},
{
id: 2,
type: 'multiple',
title: '[多选题]',
content: 'C++中,下列哪些是面向对象编程的特性?',
options: [
{ id: 'A', text: 'A.封装' },
{ id: 'B', text: 'B.继承' },
{ id: 'C', text: 'C.多态' },
{ id: 'D', text: 'D.递归' },
{ id: 'E', text: 'E.抽象' }
],
correctAnswers: ['A', 'B', 'C', 'E'],
userAnswers: ['A', 'B', 'C'],
isCorrect: false
}
]
},
3: {
id: 3,
title: 'C++语言程序设计基础练习题',
practiceDate: '2025-07-30 14:00',
duration: 88,
totalQuestions: 100,
correctCount: 18,
wrongCount: 15,
score: 90,
questions: [
{
id: 1,
type: 'single',
title: '[单选题]',
content: 'C++中,下列哪个关键字用于定义类?',
options: [
{ id: 'A', text: 'A.struct' },
{ id: 'B', text: 'B.class' },
{ id: 'C', text: 'C.union' },
{ id: 'D', text: 'D.enum' }
],
correctAnswers: ['B'],
userAnswers: ['B'],
isCorrect: true
}
]
},
5: {
id: 5,
title: 'C++语言程序设计基础练习题',
practiceDate: '2025-07-30 14:00',
duration: 88,
totalQuestions: 100,
correctCount: 18,
wrongCount: 15,
score: 90,
questions: [
{
id: 1,
type: 'single',
title: '[单选题]',
content: 'C++中,下列哪个关键字用于定义类?',
options: [
{ id: 'A', text: 'A.struct' },
{ id: 'B', text: 'B.class' },
{ id: 'C', text: 'C.union' },
{ id: 'D', text: 'D.enum' }
],
correctAnswers: ['B'],
userAnswers: ['B'],
isCorrect: true
}
]
},
6: {
id: 6,
title: 'C++语言程序设计基础练习题',
practiceDate: '2025-07-30 14:00',
duration: 88,
totalQuestions: 100,
correctCount: 18,
wrongCount: 15,
score: 90,
questions: [
{
id: 1,
type: 'single',
title: '[单选题]',
content: 'C++中,下列哪个关键字用于定义类?',
options: [
{ id: 'A', text: 'A.struct' },
{ id: 'B', text: 'B.class' },
{ id: 'C', text: 'C.union' },
{ id: 'D', text: 'D.enum' }
],
correctAnswers: ['B'],
userAnswers: ['B'],
isCorrect: true
}
]
}
}
// const mockPracticeDetails: { [key: number]: PracticeDetail } = {
// 2: {
// id: 2,
// title: 'C++',
// practiceDate: '2025-07-30 14:00',
// duration: 88,
// totalQuestions: 100,
// correctCount: 18,
// wrongCount: 15,
// score: 90,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[]',
// content: 'C++',
// options: [
// { id: 'A', text: 'A.struct' },
// { id: 'B', text: 'B.class' },
// { id: 'C', text: 'C.union' },
// { id: 'D', text: 'D.enum' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// },
// {
// id: 2,
// type: 'multiple',
// title: '[]',
// content: 'C++',
// options: [
// { id: 'A', text: 'A.' },
// { id: 'B', text: 'B.' },
// { id: 'C', text: 'C.' },
// { id: 'D', text: 'D.' },
// { id: 'E', text: 'E.' }
// ],
// correctAnswers: ['A', 'B', 'C', 'E'],
// userAnswers: ['A', 'B', 'C'],
// isCorrect: false
// }
// ]
// },
// 3: {
// id: 3,
// title: 'C++',
// practiceDate: '2025-07-30 14:00',
// duration: 88,
// totalQuestions: 100,
// correctCount: 18,
// wrongCount: 15,
// score: 90,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[]',
// content: 'C++',
// options: [
// { id: 'A', text: 'A.struct' },
// { id: 'B', text: 'B.class' },
// { id: 'C', text: 'C.union' },
// { id: 'D', text: 'D.enum' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// }
// ]
// },
// 5: {
// id: 5,
// title: 'C++',
// practiceDate: '2025-07-30 14:00',
// duration: 88,
// totalQuestions: 100,
// correctCount: 18,
// wrongCount: 15,
// score: 90,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[]',
// content: 'C++',
// options: [
// { id: 'A', text: 'A.struct' },
// { id: 'B', text: 'B.class' },
// { id: 'C', text: 'C.union' },
// { id: 'D', text: 'D.enum' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// }
// ]
// },
// 6: {
// id: 6,
// title: 'C++',
// practiceDate: '2025-07-30 14:00',
// duration: 88,
// totalQuestions: 100,
// correctCount: 18,
// wrongCount: 15,
// score: 90,
// questions: [
// {
// id: 1,
// type: 'single',
// title: '[]',
// content: 'C++',
// options: [
// { id: 'A', text: 'A.struct' },
// { id: 'B', text: 'B.class' },
// { id: 'C', text: 'C.union' },
// { id: 'D', text: 'D.enum' }
// ],
// correctAnswers: ['B'],
// userAnswers: ['B'],
// isCorrect: true
// }
// ]
// }
// }
//
const allFilteredCourses = computed(() => {
@ -2399,9 +2397,7 @@ const continueExam = (examId: number) => {
//
const viewExamResult = (examId: number) => {
currentExamId.value = examId
currentDetailType.value = 'exam'
showExamDetail.value = true
router.push(`/exam-detail/${examId}?source=exam`)
}
//
@ -2411,9 +2407,7 @@ const continuePractice = (practiceId: number) => {
//
const viewPracticeDetail = (practiceId: number) => {
currentExamId.value = practiceId
currentDetailType.value = 'practice'
showExamDetail.value = true
router.push(`/exam-detail/${practiceId}?source=practice`)
}
//
@ -2424,8 +2418,7 @@ const continueActivity = (id: number) => {
//
const viewActivityDetail = (id: number) => {
console.log('查看活动详情:', id)
message.info(`查看活动详情 ${id}`)
router.push(`/activity/${id}`)
}
//
@ -2652,28 +2645,7 @@ const showDraftBoxView = ref(false)
const draftAssignment = ref<Assignment | null>(null)
//
const showExamDetail = ref(false)
const currentExamId = ref<number | null>(null)
const currentDetailType = ref<'exam' | 'practice'>('exam')
//
const currentExamDetail = computed(() => {
if (currentExamId.value) {
if (currentDetailType.value === 'exam') {
return mockExamDetails[currentExamId.value]
} else if (currentDetailType.value === 'practice') {
return mockPracticeDetails[currentExamId.value]
}
}
return null
})
//
const closeExamDetail = () => {
showExamDetail.value = false
currentExamId.value = null
currentDetailType.value = 'exam'
}
// //
// const getAnswerItemClass = (index: number) => {