From 360f252566e55aae61f0bb17469cb28955dc32bc Mon Sep 17 00:00:00 2001
From: ZhangXianQiang <1135831638@qq.com>
Date: 星期二, 11 六月 2024 10:12:02 +0800
Subject: [PATCH] feat:答题切换

---
 src/components/ExamInfo/index.vue                             |   13 +
 src/store/modules/user.js                                     |    4 
 src/store/modules/exam.js                                     |  178 ++++++++++++++++++++++++++++-
 src/views/exam/components/answer-sheet/index.vue              |   49 ++-----
 src/views/exam/components/answer-main/answer-single/index.vue |   43 +-----
 src/router/index.js                                           |    2 
 src/views/exam/index.vue                                      |   67 +++++++++-
 7 files changed, 267 insertions(+), 89 deletions(-)

diff --git a/src/components/ExamInfo/index.vue b/src/components/ExamInfo/index.vue
index e776b51..8fd4032 100644
--- a/src/components/ExamInfo/index.vue
+++ b/src/components/ExamInfo/index.vue
@@ -1,7 +1,7 @@
 <template>
   <div class="info-container w-full">
     <div class="exam-title break-all mb-4 text-base text-gray-700">
-      1.娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯
+      {{ title }}
     </div>
     <div class="img-container flex">
       <div class="img-item">
@@ -12,7 +12,16 @@
 </template>
 
 <script setup>
-
+const props = defineProps({
+  questionIndex: {
+    type: Number,
+    required: true
+  },
+  title: {
+    type: String,
+    required: true
+  }
+})
 </script>
 
 <style lang="scss" scoped>
diff --git a/src/router/index.js b/src/router/index.js
index 726610c..91a47a3 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -5,7 +5,7 @@
 const routes = [
   {
     path: '/',
-    redirect: '/index'
+    redirect: '/exam'
   },
 
   {
diff --git a/src/store/modules/exam.js b/src/store/modules/exam.js
index 96a55e9..f436304 100644
--- a/src/store/modules/exam.js
+++ b/src/store/modules/exam.js
@@ -1,11 +1,175 @@
-import { ref } from 'vue';
+import { ref,computed } from 'vue';
 import { defineStore } from 'pinia';
-const useExamStore = defineStore('exam', () => {
-  const examInfo = ref(null);
+export const useExamStore = defineStore('exam', () => {
+  const examInfo = ref({
+    examId: 1,
+    examName: '鑰冭瘯鍚嶇О',
+    examType: '鑰冭瘯绫诲瀷',
+    examStatus: '鑰冭瘯鐘舵��',
+    examStartTime: '2021-01-01',
+    examEndTime: '2021-01-01',
+  });
+
+  const examType = ref({
+    1: '鍗曢�夐',
+    2: '澶氶�夐'
+  });
+
+  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=锛�123",
+          "items": [
+            {
+              "prefix": "A",
+              "content": "1"
+            },
+            {
+              "prefix": "B",
+              "content": "2"
+            },
+            {
+              "prefix": "C",
+              "content": "3"
+            },
+            {
+              "prefix": "D",
+              "content": "4"
+            }
+          ],
+          "analyze": "闂皬鏈嬪弸",
+          "correct": "B",
+          "score": "",
+          "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": "B",
+          "score": "",
+          "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": "B",
+          "score": "",
+          "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": "B",
+          "score": "",
+          "difficult": 5
+        }
+      ]
+    }
+  ]);
+
+  const activeQuestion = ref(null);
+
+  const setExamInfo = (info) => {
+    examInfo.value = info;
+  };
+
+  const setExamDetail = (detail) => {
+    examDetail.value = detail;
+  };
+
+  const setActiveQuestion = (detail) => {
+    activeQuestion.value = detail;
+  };
 
   return {
-    examInfo
-  }
+    examInfo,
+    examDetail,
+    examType,
+    activeQuestion,
+    currentType,
+    currentIndex,
+    setExamInfo,
+    setExamDetail,
+    setActiveQuestion
+  };
 });
-
-export default useExamStore;
\ No newline at end of file
diff --git a/src/store/modules/user.js b/src/store/modules/user.js
index 5663aa1..3641412 100644
--- a/src/store/modules/user.js
+++ b/src/store/modules/user.js
@@ -1,11 +1,9 @@
 import { ref } from 'vue';
 import { defineStore } from 'pinia';
-const useUserInfoStore = defineStore('userInfo', () => {
+export const useUserInfoStore = defineStore('userInfo', () => {
   const userInfo = ref('');
 
   return {
     userInfo
   }
 });
-
-export default useUserInfoStore;
\ No newline at end of file
diff --git a/src/views/exam/components/answer-main/answer-single/index.vue b/src/views/exam/components/answer-main/answer-single/index.vue
index c5316c2..140d1b7 100644
--- a/src/views/exam/components/answer-main/answer-single/index.vue
+++ b/src/views/exam/components/answer-main/answer-single/index.vue
@@ -1,13 +1,13 @@
 <template>
   <div class="answer-container w-full h-full">
     <el-scrollbar>
-      <ExamInfo class="mb-5"></ExamInfo>
+      <ExamInfo class="mb-5" :questionIndex="currentIndex" :title="activeQuestion.title"></ExamInfo>
 
       <div class="answer-content">
-        <div class="answer-item flex" v-for="item, index in examInfo.answerList" @click="answerClick(item)"
+        <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.type }}</div>
-          <div class="answer-text text-gray-700">{{ item.text }}</div>
+          <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>
 
@@ -17,36 +17,12 @@
 
 <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 examInfo = ref({
-  qId: 1,
-  answerList: [
-    {
-      type: 'A',
-      text: '娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯璇曟祴璇�',
-      isActive: false
-    },
-    {
-      type: 'B',
-      text: '娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯璇曟祴璇�',
-      isActive: false
-    },
-    {
-      type: 'C',
-      text: '娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯璇曟祴璇�',
-      isActive: false
-    },
-    {
-      type: 'D',
-      text: '娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯娴嬭瘯璇曟祴璇�',
-      isActive: false
-    },
-  ]
-});
-
-const activeIndex = ref(null);
-
+const {currentIndex,activeQuestion} = storeToRefs(examStore);
 const answerClick = (item) => {
   if(item) {
     resetAnswer();
@@ -61,9 +37,10 @@
 }
 
 const resetAnswer = () => {
-  examInfo.value.answerList.forEach(item => item.isActive = false);
+  activeQuestion.value.items.forEach(item => item.isActive = false);
 }
 
+
 </script>
 
 <style lang="scss" scoped>
diff --git a/src/views/exam/components/answer-sheet/index.vue b/src/views/exam/components/answer-sheet/index.vue
index eb8c60b..b25642b 100644
--- a/src/views/exam/components/answer-sheet/index.vue
+++ b/src/views/exam/components/answer-sheet/index.vue
@@ -1,12 +1,12 @@
 <template>
   <div class="sheet-container w-full h-full">
     <el-scrollbar>
-      <el-collapse v-model="activeNames" @change="handleChange">
-        <template v-for="item in sheetList">
-          <el-collapse-item :title="item.title" :name="item.type">
+      <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="index in item.total" @click="sheetClick(item,index)" :class="itemClass(item.type, index)">
-                {{ index }}
+              <div class="sheet-item cursor-pointer flex justify-center items-center" v-for="question,index in item.questionList" @click="sheetClick(question,index)" :class="itemClass(item.questionType, index)">
+                {{ index + 1 }}
               </div>
             </div>
           </el-collapse-item>
@@ -18,45 +18,24 @@
 
 <script setup>
 import { ref } from 'vue';
+import {storeToRefs} from 'pinia';
+import {useExamStore} from '@/store/index.js';
+const examStore = useExamStore();
 
-const categroy = ref(0);
-const sheetIndex = ref(0);
+const {examType, examDetail,currentType,currentIndex} = storeToRefs(examStore);
 
 const itemClass = (type,index) => {
   return {
-    active: categroy.value === type && sheetIndex.value === index
+    active: currentType.value === type && currentIndex.value === index
   }
 }
 
-
-const sheetList = ref([
-  {
-    title: '鍗曢�夐',
-    type: 1,
-    total: 20,
-  },
-  {
-    title: '澶氶�夐',
-    type: 2,
-    total: 20,
-  },
-  {
-    title: '鍒ゆ柇棰�',
-    type: 3,
-    total: 20,
-  },
-]);
-
-const activeNames = ref(sheetList.value.map(item => item.type));
-
-
-const handleChange = () => {
-
-};
+const activeNames = ref(examDetail.value.map(item => item.questionType));
 
 const sheetClick = (item, index) => {
-  categroy.value = item.type;
-  sheetIndex.value = index;
+  currentType.value = item.questionType;
+  currentIndex.value = index;
+  examStore.setActiveQuestion(item);
 }
 </script>
 
diff --git a/src/views/exam/index.vue b/src/views/exam/index.vue
index 8703f59..65c156c 100644
--- a/src/views/exam/index.vue
+++ b/src/views/exam/index.vue
@@ -56,7 +56,7 @@
               <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">
-                    <component :is="typeComponent[currentType]" :key="questionIndex"></component>
+                    <component :is="typeComponent[currentType]" :key="currentIndex"></component>
                   </Transition>
                 </div>
               </div>
@@ -97,7 +97,8 @@
 </template>
 
 <script setup>
-import { ref } from 'vue';
+import { ref, toRefs } from 'vue';
+import { storeToRefs } from 'pinia';
 import { Close } from '@element-plus/icons-vue';
 import AnswerTag from './components/answer-tag/index.vue';
 import AnswerProgress from './components/answer-progress/index.vue';
@@ -105,23 +106,73 @@
 import AnswerSingle from './components/answer-main/answer-single/index.vue';
 import AnswerMultiple from './components/answer-main/answer-multiple/index.vue';
 import AnswerTime from './components/answer-time/index.vue';
+import { useExamStore } from '@/store/index.js';
+
+const examStore = useExamStore();
+const { currentType, currentIndex, activeQuestion, examDetail } = storeToRefs(examStore);
 
 const typeComponent = {
   1: AnswerSingle,
   2: AnswerMultiple,
 };
-
-const currentType = ref(1);
-const questionIndex = ref(0);
+examStore.setActiveQuestion(examDetail.value[0].questionList[0]);
 
 const dialogVisible = ref(false);
 
 const prevQuestion = () => {
-  questionIndex.value--;
+  currentIndex.value--;
+  checkList();
 };
 
 const nextQuestion = () => {
-  questionIndex.value++;
+  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;
+      }
+    }
+    findQuestion(currentType.value, currentIndex.value);
+  }
+
+};
+
+const findQuestion = (type, index) => {
+  const typeQuestion = examDetail.value.find(typeItem => typeItem.questionType === type);
+  if (typeQuestion) {
+    const question = typeQuestion.questionList[index];
+    if (question) {
+      examStore.setActiveQuestion(question);
+    }
+  }
 };
 
 const closeClick = () => {
@@ -130,7 +181,7 @@
 
 const confirmCancel = () => {
   dialogVisible.value = false;
-}
+};
 </script>
 
 <style lang="scss" scoped>

--
Gitblit v1.8.0