| | |
| | | const routes = [ |
| | | { |
| | | path: '/', |
| | | redirect: '/login' |
| | | redirect: '/grade-list' |
| | | }, |
| | | |
| | | { |
| | |
| | | path: '/grade-list', |
| | | component: () => import('@/views/grade-list/index.vue'), |
| | | }, |
| | | // 试卷 |
| | | { |
| | | path: '/grade', |
| | | component: () => import('@/views/grade/index.vue'), |
| | | }, |
| | | ]; |
| | | |
| | | const router = createRouter({ |
| | |
| | | |
| | | export * from './modules/user.js'; |
| | | export * from './modules/exam.js'; |
| | | export * from './modules/grade.js'; |
New file |
| | |
| | | import { ref, computed } from 'vue'; |
| | | import { defineStore } from 'pinia'; |
| | | export const useGradeStore = defineStore('exam', () => { |
| | | const examInfo = ref({ |
| | | examId: 1, |
| | | examName: '考试名称', |
| | | examType: '考试类型', |
| | | examStatus: '考试状态', |
| | | examStartTime: '2021-01-01', |
| | | examEndTime: '2021-01-01', |
| | | examTime: 5, |
| | | }); |
| | | |
| | | const examType = ref({ |
| | | 1: '单选题', |
| | | 2: '多选题', |
| | | 3: '音频题' |
| | | }); |
| | | |
| | | const currentType = ref(1); |
| | | const currentIndex = ref(0); |
| | | |
| | | |
| | | const examDetail = ref([ |
| | | { |
| | | questionType: 1, |
| | | questionList: [ |
| | | { |
| | | "id": null, |
| | | "questionType": 1, |
| | | "gradeLevel": null, |
| | | "subjectId": 2, |
| | | "title": "1+1=?", |
| | | "items": [ |
| | | { |
| | | "prefix": "A", |
| | | "content": "1" |
| | | }, |
| | | { |
| | | "prefix": "B", |
| | | "content": "2" |
| | | }, |
| | | { |
| | | "prefix": "C", |
| | | "content": "3" |
| | | }, |
| | | { |
| | | "prefix": "D", |
| | | "content": "4" |
| | | } |
| | | ], |
| | | "analyze": "问小朋友", |
| | | "correct": "A", |
| | | "right": "B", |
| | | "score": "3", |
| | | "difficult": 5 |
| | | }, |
| | | { |
| | | "id": null, |
| | | "questionType": 1, |
| | | "gradeLevel": null, |
| | | "subjectId": 2, |
| | | "title": "1+1=?", |
| | | "items": [ |
| | | { |
| | | "prefix": "A", |
| | | "content": "1" |
| | | }, |
| | | { |
| | | "prefix": "B", |
| | | "content": "2" |
| | | }, |
| | | { |
| | | "prefix": "C", |
| | | "content": "3" |
| | | }, |
| | | { |
| | | "prefix": "D", |
| | | "content": "4" |
| | | } |
| | | ], |
| | | "analyze": "问小朋友", |
| | | "correct": "A", |
| | | "right": "B", |
| | | "score": "3", |
| | | "difficult": 5 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | questionType: 2, |
| | | questionList: [ |
| | | { |
| | | "id": null, |
| | | "questionType": 1, |
| | | "gradeLevel": null, |
| | | "subjectId": 2, |
| | | "title": "1+1=?", |
| | | "items": [ |
| | | { |
| | | "prefix": "A", |
| | | "content": "1" |
| | | }, |
| | | { |
| | | "prefix": "B", |
| | | "content": "2" |
| | | }, |
| | | { |
| | | "prefix": "C", |
| | | "content": "3" |
| | | }, |
| | | { |
| | | "prefix": "D", |
| | | "content": "4" |
| | | } |
| | | ], |
| | | "analyze": "问小朋友", |
| | | "correct": "A,B", |
| | | "right": "A,B,C", |
| | | "score": "5", |
| | | "difficult": 5 |
| | | }, |
| | | { |
| | | "id": null, |
| | | "questionType": 1, |
| | | "gradeLevel": null, |
| | | "subjectId": 2, |
| | | "title": "1+1=?", |
| | | "items": [ |
| | | { |
| | | "prefix": "A", |
| | | "content": "1" |
| | | }, |
| | | { |
| | | "prefix": "B", |
| | | "content": "2" |
| | | }, |
| | | { |
| | | "prefix": "C", |
| | | "content": "3" |
| | | }, |
| | | { |
| | | "prefix": "D", |
| | | "content": "4" |
| | | } |
| | | ], |
| | | "analyze": "问小朋友", |
| | | "correct": "A,D", |
| | | "right": "B,C", |
| | | "score": "5", |
| | | "difficult": 5 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | questionType: 3, |
| | | questionList: [ |
| | | { |
| | | "id": null, |
| | | "questionType": 1, |
| | | "gradeLevel": null, |
| | | "subjectId": 2, |
| | | "title": "测试音频1", |
| | | "audioFile": '/test.mp3', |
| | | "items": [ |
| | | { |
| | | "prefix": "A", |
| | | "content": "1" |
| | | }, |
| | | { |
| | | "prefix": "B", |
| | | "content": "2" |
| | | }, |
| | | { |
| | | "prefix": "C", |
| | | "content": "3" |
| | | }, |
| | | { |
| | | "prefix": "D", |
| | | "content": "4" |
| | | } |
| | | ], |
| | | "analyze": "问小朋友", |
| | | "correct": "", |
| | | "right": "B", |
| | | "score": "3", |
| | | "difficult": 5 |
| | | }, |
| | | { |
| | | "id": null, |
| | | "questionType": 1, |
| | | "gradeLevel": null, |
| | | "subjectId": 2, |
| | | "title": "测试音频2", |
| | | "audioFile": '/test.mp3', |
| | | "items": [ |
| | | { |
| | | "prefix": "A", |
| | | "content": "1" |
| | | }, |
| | | { |
| | | "prefix": "B", |
| | | "content": "2" |
| | | }, |
| | | { |
| | | "prefix": "C", |
| | | "content": "3" |
| | | }, |
| | | { |
| | | "prefix": "D", |
| | | "content": "4" |
| | | } |
| | | ], |
| | | "analyze": "问小朋友", |
| | | "correct": "D", |
| | | "right": "A", |
| | | "score": "3", |
| | | "difficult": 5 |
| | | } |
| | | ] |
| | | }, |
| | | ]); |
| | | |
| | | const getActiveQuestion = computed(() => { |
| | | const temp = examDetail.value.find(item => item.questionType === currentType.value); |
| | | if (temp) { |
| | | return temp.questionList[currentIndex.value]; |
| | | } |
| | | }); |
| | | |
| | | const setExamInfo = (info) => { |
| | | examInfo.value = info; |
| | | }; |
| | | |
| | | const setExamDetail = (detail) => { |
| | | examDetail.value = detail; |
| | | }; |
| | | |
| | | return { |
| | | examInfo, |
| | | examDetail, |
| | | examType, |
| | | |
| | | currentType, |
| | | currentIndex, |
| | | |
| | | getActiveQuestion, |
| | | |
| | | setExamInfo, |
| | | setExamDetail, |
| | | }; |
| | | }); |
| | |
| | | </div> |
| | | <div class="right-container"> |
| | | <div class="button-container"> |
| | | <el-button type="primary" size="large">查看试卷</el-button> |
| | | <el-button type="primary" size="large" @click="checkExam">查看试卷</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | <script setup> |
| | | import {ref} from 'vue'; |
| | | import { Timer } from '@element-plus/icons-vue'; |
| | | import {useRouter} from 'vue-router'; |
| | | const router = useRouter(); |
| | | |
| | | const checkExam = () => { |
| | | router.push('/grade'); |
| | | } |
| | | |
| | | </script> |
| | | |
New file |
| | |
| | | <template> |
| | | <div class="answer-container w-full h-full"> |
| | | <el-scrollbar> |
| | | <ExamInfo class="mb-5" :questionIndex="currentIndex" :activeQuestion="activeQuestion"></ExamInfo> |
| | | |
| | | <div class="answer-content"> |
| | | <div class="answer-item flex" v-for="item, index in activeQuestion.items" @click="answerClick(item)" |
| | | :class="answerState(item)"> |
| | | <div class="answer-icon flex flex-col justify-center items-center flex-shrink-0">{{ item.prefix }}</div> |
| | | <div class="answer-text text-gray-700">{{ item.content }}</div> |
| | | </div> |
| | | </div> |
| | | |
| | | </el-scrollbar> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue'; |
| | | import { storeToRefs } from 'pinia'; |
| | | import ExamInfo from '@/components/ExamInfo/index.vue'; |
| | | import { useExamStore } from '@/store/index.js'; |
| | | const examStore = useExamStore(); |
| | | |
| | | const { currentType, currentIndex } = storeToRefs(examStore); |
| | | |
| | | const activeQuestion = ref(examStore.getActiveQuestion); |
| | | |
| | | const answerClick = (item) => { |
| | | if (item) { |
| | | if (item.isActive) { |
| | | item.isActive = !item.isActive; |
| | | } else { |
| | | resetAnswer(); |
| | | item.isActive = true; |
| | | } |
| | | const answerList = filterAnswer(); |
| | | examStore.setQuestionAnswer(currentType.value, currentIndex.value, answerList.join(',')); |
| | | } |
| | | }; |
| | | |
| | | const answerState = (item) => { |
| | | return { |
| | | active: item.isActive |
| | | }; |
| | | }; |
| | | |
| | | const resetAnswer = () => { |
| | | activeQuestion.value.items.forEach(item => item.isActive = false); |
| | | }; |
| | | |
| | | const filterAnswer = () => { |
| | | return activeQuestion.value.items.filter(item => item.isActive); |
| | | } |
| | | |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .answer-item { |
| | | max-width: 500px; |
| | | border-radius: 10px; |
| | | border: 1px solid #DCDFE6; |
| | | overflow: hidden; |
| | | margin-bottom: 20px; |
| | | cursor: pointer; |
| | | |
| | | &:last-of-type { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | &:hover { |
| | | border-color: #3680fa; |
| | | |
| | | .answer-icon { |
| | | color: #3680fa; |
| | | border-color: #3680fa; |
| | | } |
| | | } |
| | | |
| | | |
| | | .answer-icon { |
| | | width: 50px; |
| | | background-color: #F0F2F5; |
| | | border-right: 1px solid #ffffff; |
| | | } |
| | | |
| | | .answer-text { |
| | | min-height: 50px; |
| | | padding: 15px 0; |
| | | margin: 0 10px; |
| | | } |
| | | } |
| | | |
| | | .active { |
| | | border-color: #409EFF !important; |
| | | |
| | | .answer-icon { |
| | | color: #ffffff !important; |
| | | border-color: #409EFF !important; |
| | | background-color: #409EFF !important; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="answer-container w-full h-full"> |
| | | <el-scrollbar> |
| | | <ExamInfo class="mb-5" :questionIndex="currentIndex" :activeQuestion="activeQuestion"></ExamInfo> |
| | | |
| | | <div class="answer-content"> |
| | | <div class="answer-item flex" v-for="item, index in activeQuestion.items" @click="answerClick(item)" |
| | | :class="answerState(item)"> |
| | | <div class="answer-icon flex flex-col justify-center items-center flex-shrink-0">{{ item.prefix }}</div> |
| | | <div class="answer-text text-gray-700">{{ item.content }}</div> |
| | | </div> |
| | | </div> |
| | | |
| | | </el-scrollbar> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue'; |
| | | import { storeToRefs } from 'pinia'; |
| | | import ExamInfo from '@/components/ExamInfo/index.vue'; |
| | | import { useExamStore } from '@/store/index.js'; |
| | | |
| | | const examStore = useExamStore(); |
| | | |
| | | const { currentType, currentIndex } = storeToRefs(examStore); |
| | | |
| | | const activeQuestion = ref(examStore.getActiveQuestion); |
| | | |
| | | const answerClick = (item) => { |
| | | if (item) { |
| | | // resetAnswer(); |
| | | item.isActive = !item.isActive; |
| | | const answerList = filterAnswer(); |
| | | examStore.setQuestionAnswer(currentType.value, currentIndex.value, answerList.join(',')); |
| | | |
| | | } |
| | | }; |
| | | |
| | | const answerState = (item) => { |
| | | return { |
| | | active: item.isActive |
| | | }; |
| | | }; |
| | | |
| | | const filterAnswer = () => { |
| | | return activeQuestion.value.items.filter(item => item.isActive); |
| | | } |
| | | |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .answer-item { |
| | | max-width: 500px; |
| | | border-radius: 10px; |
| | | border: 1px solid #DCDFE6; |
| | | overflow: hidden; |
| | | margin-bottom: 20px; |
| | | cursor: pointer; |
| | | |
| | | &:last-of-type { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | &:hover { |
| | | border-color: #3680fa; |
| | | |
| | | .answer-icon { |
| | | color: #3680fa; |
| | | border-color: #3680fa; |
| | | } |
| | | } |
| | | |
| | | |
| | | .answer-icon { |
| | | width: 50px; |
| | | background-color: #F0F2F5; |
| | | border-right: 1px solid #ffffff; |
| | | } |
| | | |
| | | .answer-text { |
| | | min-height: 50px; |
| | | padding: 15px 0; |
| | | margin: 0 10px; |
| | | } |
| | | } |
| | | |
| | | .active { |
| | | border-color: #409EFF !important; |
| | | |
| | | .answer-icon { |
| | | color: #ffffff !important; |
| | | border-color: #409EFF !important; |
| | | background-color: #409EFF !important; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="answer-container w-full h-full"> |
| | | <el-scrollbar> |
| | | <ExamInfo class="mb-5" :questionIndex="currentIndex" :activeQuestion="activeQuestion"></ExamInfo> |
| | | |
| | | <div class="answer-content"> |
| | | <div class="answer-item flex" v-for="item, index in activeQuestion.items" @click="answerClick(item)" |
| | | :class="answerState(item)"> |
| | | <div class="answer-icon flex flex-col justify-center items-center flex-shrink-0">{{ item.prefix }}</div> |
| | | <div class="answer-text text-gray-700">{{ item.content }}</div> |
| | | </div> |
| | | </div> |
| | | |
| | | </el-scrollbar> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue'; |
| | | import { storeToRefs } from 'pinia'; |
| | | import ExamInfo from '@/components/ExamInfo/index.vue'; |
| | | import { useExamStore } from '@/store/index.js'; |
| | | const examStore = useExamStore(); |
| | | |
| | | const { currentType, currentIndex } = storeToRefs(examStore); |
| | | |
| | | const activeQuestion = ref(examStore.getActiveQuestion); |
| | | |
| | | const answerClick = (item) => { |
| | | if (item) { |
| | | if (item.isActive) { |
| | | item.isActive = !item.isActive; |
| | | } else { |
| | | resetAnswer(); |
| | | item.isActive = true; |
| | | } |
| | | const answerList = filterAnswer(); |
| | | examStore.setQuestionAnswer(currentType.value, currentIndex.value, answerList.join(',')); |
| | | } |
| | | }; |
| | | |
| | | const answerState = (item) => { |
| | | return { |
| | | active: item.isActive |
| | | }; |
| | | }; |
| | | |
| | | const resetAnswer = () => { |
| | | activeQuestion.value.items.forEach(item => item.isActive = false); |
| | | }; |
| | | |
| | | const filterAnswer = () => { |
| | | return activeQuestion.value.items.filter(item => item.isActive); |
| | | } |
| | | |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .answer-item { |
| | | max-width: 500px; |
| | | border-radius: 10px; |
| | | border: 1px solid #DCDFE6; |
| | | overflow: hidden; |
| | | margin-bottom: 20px; |
| | | cursor: pointer; |
| | | |
| | | &:last-of-type { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | &:hover { |
| | | border-color: #3680fa; |
| | | |
| | | .answer-icon { |
| | | color: #3680fa; |
| | | border-color: #3680fa; |
| | | } |
| | | } |
| | | |
| | | |
| | | .answer-icon { |
| | | width: 50px; |
| | | background-color: #F0F2F5; |
| | | border-right: 1px solid #ffffff; |
| | | } |
| | | |
| | | .answer-text { |
| | | min-height: 50px; |
| | | padding: 15px 0; |
| | | margin: 0 10px; |
| | | } |
| | | } |
| | | |
| | | .active { |
| | | border-color: #409EFF !important; |
| | | |
| | | .answer-icon { |
| | | color: #ffffff !important; |
| | | border-color: #409EFF !important; |
| | | background-color: #409EFF !important; |
| | | } |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="sheet-container w-full h-full"> |
| | | <el-scrollbar> |
| | | <el-collapse v-model="activeNames"> |
| | | <template v-for="item in examDetail"> |
| | | <el-collapse-item :title="examType[item.questionType]" :name="item.questionType"> |
| | | <div class="sheet-list grid grid-cols-5 gap-4 justify-items-center"> |
| | | <div class="sheet-item cursor-pointer flex justify-center items-center" v-for="question,index in item.questionList" @click="sheetClick(item.questionType,index)" :class="itemClass(question,item.questionType, index)"> |
| | | {{ index + 1 }} |
| | | </div> |
| | | </div> |
| | | </el-collapse-item> |
| | | </template> |
| | | </el-collapse> |
| | | </el-scrollbar> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue'; |
| | | import {storeToRefs} from 'pinia'; |
| | | import {useExamStore} from '@/store/index.js'; |
| | | const examStore = useExamStore(); |
| | | |
| | | const {examType, examDetail,currentType,currentIndex} = storeToRefs(examStore); |
| | | |
| | | const activeNames = ref(examDetail.value.map(item => item.questionType)); |
| | | |
| | | const itemClass = (question,type,index) => { |
| | | return { |
| | | answer: question.correct, |
| | | active: currentType.value === type && currentIndex.value === index |
| | | } |
| | | } |
| | | |
| | | const sheetClick = (type,index) => { |
| | | currentType.value = type; |
| | | currentIndex.value = index; |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .sheet-list { |
| | | width: 97%; |
| | | } |
| | | .sheet-item { |
| | | width: 35px; |
| | | height: 35px; |
| | | border: 1px solid #DCDFE6; |
| | | background-color: #fff; |
| | | color: #374151; |
| | | } |
| | | |
| | | .active { |
| | | border-color: #3680fa; |
| | | } |
| | | .answer { |
| | | border-color: #3680fa !important; |
| | | background-color: #3680fa !important; |
| | | color: #fff !important; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="tag-container flex flex-wrap"> |
| | | <div class="tag-item flex items-center" v-for="item in tagList"> |
| | | <div class="label text-xs text-gray-500 mr-2">{{ item.name }}</div> |
| | | <div class="tag flex-shrink-0" :style="{backgroundColor: item.bgColor, borderColor: item.borderColor}"></div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import {ref} from 'vue'; |
| | | |
| | | const tagList = ref([ |
| | | { |
| | | name: '已答', |
| | | bgColor: '#3680fa', |
| | | borderColor: '#3680fa', |
| | | }, |
| | | { |
| | | name: '当前', |
| | | bgColor: '#ffffff', |
| | | borderColor: '#3680fa', |
| | | }, |
| | | { |
| | | name: '未答', |
| | | bgColor: '#ffffff', |
| | | borderColor: '#DCDFE6', |
| | | }, |
| | | ]) |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .tag-item { |
| | | margin-right: 14px; |
| | | &:last-of-type { |
| | | margin: 0; |
| | | } |
| | | } |
| | | .tag { |
| | | width: 12px; |
| | | height: 12px; |
| | | border: 1px solid #fff; |
| | | background-color: #fff; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="exam-container w-screen h-screen bg-slate-50 relative overflow-hidden"> |
| | | <div class="top-bg bg-blue-500"></div> |
| | | <div class="exam-content"> |
| | | <div class="exam-wrapper container mx-auto h-full flex flex-col"> |
| | | <div class="exam-header flex items-center mt-12 mb-10"> |
| | | <div class="title-container text-3xl font-semibold text-white mr-8"> |
| | | {{ examInfo.examName }} |
| | | </div> |
| | | |
| | | <div class="return-container grow flex justify-end"> |
| | | <el-button type="danger" size="large" circle @click="closeClick"> |
| | | <template #icon> |
| | | <el-icon :size="20"> |
| | | <Close /> |
| | | </el-icon> |
| | | </template> |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="exam-main grow flex justify-between"> |
| | | <!-- 答题卡区 --> |
| | | <div class="answer-wrapper answer-left mr-8 shadow-xl p-4 box-border"> |
| | | <div class="wrapper h-full flex flex-col items-center"> |
| | | <div class="title-wrapper w-full flex justify-between items-center mb-5"> |
| | | <div class="title text-xl font-semibold ">答题卡</div> |
| | | <AnswerTag></AnswerTag> |
| | | </div> |
| | | |
| | | <div class="sheet-wrapper w-full grow relative my-5"> |
| | | <div class="sheet-content absolute top-0 bottom-0 w-full"> |
| | | <!-- <AnswerSheet></AnswerSheet> --> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 答题内容区 --> |
| | | <div class="answer-wrapper answer-right grow shadow-xl p-4"> |
| | | <div class="wrapper h-full flex flex-col"> |
| | | <div class="title-wrapper w-full flex mb-5"> |
| | | <div class="title text-xl font-semibold ">{{ examType[currentType] }} ({{ |
| | | gradeStore.getActiveQuestion.score }}分) |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="main-wrapper w-full grow relative my-5"> |
| | | <div class="main-content absolute top-0 bottom-0 w-full"> |
| | | <Transition appear name="fade-transform" mode="out-in"> |
| | | </Transition> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="tool-wrapper flex justify-end"> |
| | | <div class="button-container flex items-center"> |
| | | <div class="button-item"> |
| | | <el-button class="tool-button" @click="prevQuestion">上一题</el-button> |
| | | </div> |
| | | <div class="button-item"> |
| | | <el-button class="tool-button" type="primary" @click="nextQuestion">下一题</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, watchEffect } from 'vue'; |
| | | import { storeToRefs } from 'pinia'; |
| | | import { Close,Timer } from '@element-plus/icons-vue'; |
| | | |
| | | import AnswerTag from './components/answer-tag/index.vue'; |
| | | // import AnswerSheet from './components/answer-sheet/index.vue'; |
| | | |
| | | import { useGradeStore } from '@/store/index.js'; |
| | | import { useRouter } from 'vue-router'; |
| | | |
| | | const router = useRouter(); |
| | | |
| | | const gradeStore = useGradeStore(); |
| | | const { currentType, currentIndex, examDetail, examType, examInfo } = storeToRefs(gradeStore); |
| | | |
| | | // const typeComponent = { |
| | | // 1: AnswerSingle, |
| | | // 2: AnswerMultiple, |
| | | // 3: AnswerAudio, |
| | | // }; |
| | | |
| | | |
| | | const prevQuestion = () => { |
| | | currentIndex.value--; |
| | | checkList(); |
| | | }; |
| | | |
| | | const nextQuestion = () => { |
| | | currentIndex.value++; |
| | | checkList(); |
| | | }; |
| | | |
| | | const checkList = () => { |
| | | let tempIndex = 0; |
| | | const typeQuestion = examDetail.value.find((typeItem, index) => { |
| | | if (typeItem.questionType === currentType.value) { |
| | | tempIndex = index; |
| | | return typeItem; |
| | | } else { |
| | | return false; |
| | | } |
| | | }); |
| | | if (typeQuestion) { |
| | | if (currentIndex.value >= typeQuestion.questionList.length) { |
| | | tempIndex++; |
| | | if (examDetail.value[tempIndex]) { |
| | | currentType.value = examDetail.value[tempIndex].questionType; |
| | | currentIndex.value = 0; |
| | | } else { |
| | | currentType.value = typeQuestion.questionType; |
| | | currentIndex.value = typeQuestion.questionList.length - 1; |
| | | } |
| | | |
| | | } else if (currentIndex.value < 0) { |
| | | tempIndex--; |
| | | if (examDetail.value[tempIndex]) { |
| | | currentType.value = examDetail.value[tempIndex].questionType; |
| | | currentIndex.value = examDetail.value[tempIndex].questionList.length - 1; |
| | | } else { |
| | | currentType.value = typeQuestion.questionType; |
| | | currentIndex.value = 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | }; |
| | | |
| | | |
| | | const closeClick = () => { |
| | | router.back(); |
| | | }; |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | @media (min-width: 1836px) { |
| | | .container { |
| | | max-width: 1724px; |
| | | } |
| | | } |
| | | |
| | | .top-bg { |
| | | width: 130%; |
| | | height: 200px; |
| | | position: absolute; |
| | | border-bottom-left-radius: 50%; |
| | | border-bottom-right-radius: 50%; |
| | | left: 50%; |
| | | transform: translateX(-50%); |
| | | } |
| | | |
| | | .exam-content { |
| | | width: 100%; |
| | | height: 100%; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | z-index: 2; |
| | | } |
| | | |
| | | .exam-header { |
| | | width: 100%; |
| | | } |
| | | |
| | | .answer-wrapper { |
| | | background-color: #fff; |
| | | border-top-left-radius: 10px; |
| | | border-top-right-radius: 10px; |
| | | } |
| | | |
| | | .answer-left { |
| | | width: 340px; |
| | | } |
| | | |
| | | .submit-button, |
| | | .tool-button { |
| | | width: 160px; |
| | | height: 40px; |
| | | } |
| | | |
| | | .tool-button { |
| | | margin: 0 20px; |
| | | } |
| | | |
| | | .icon-container { |
| | | width: 70px; |
| | | height: 70px; |
| | | border-radius: 50%; |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | background-color: rgba($color: #3680fa, $alpha: 0.2); |
| | | margin-bottom: 20px; |
| | | } |
| | | </style> |