From 9c2eb9ed6da32c1830b02431875dacaa7f904b1f Mon Sep 17 00:00:00 2001
From: 黄何裕 <1053952480@qq.com>
Date: 星期五, 12 七月 2024 18:16:56 +0800
Subject: [PATCH] 修改资料校验

---
 src/views/exam/index.vue |  330 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 302 insertions(+), 28 deletions(-)

diff --git a/src/views/exam/index.vue b/src/views/exam/index.vue
index aaf82e4..dbbf30c 100644
--- a/src/views/exam/index.vue
+++ b/src/views/exam/index.vue
@@ -1,23 +1,35 @@
 <template>
-  <div class="exam-container w-screen h-screen bg-slate-50 relative overflow-hidden">
+  <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>
+          <AnswerTime @timeOut="timeOut" ref="answerTime"></AnswerTime>
 
-          <AnswerTime></AnswerTime>
-
+          <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>
+              <div
+                class="title-wrapper w-full flex justify-between items-center mb-5"
+              >
+                <div class="title text-xl font-semibold">绛旈鍗�</div>
                 <AnswerTag></AnswerTag>
               </div>
 
@@ -32,9 +44,13 @@
               </div>
 
               <div class="submit-wrapper">
-                <el-button type="primary" class="submit-button">鎻愪氦璇曞嵎</el-button>
+                <el-button
+                  type="primary"
+                  class="submit-button"
+                  @click="submitExamHandle"
+                  >鎻愪氦璇曞嵎</el-button
+                >
               </div>
-
             </div>
           </div>
 
@@ -42,13 +58,20 @@
           <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 ">鍗曢�夐 (3鍒�)</div>
+                <div class="title text-xl font-semibold">
+                  {{ examType[currentType] }} ({{
+                    examStore.getActiveQuestion.questionScore
+                  }}鍒�)
+                </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">
-                    <component :is="typeComponent[currentType]" :key="questionIndex"></component>
+                    <component
+                      :is="typeComponent[currentType]"
+                      :key="currentIndex"
+                    ></component>
                   </Transition>
                 </div>
               </div>
@@ -56,10 +79,17 @@
               <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>
+                    <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>
+                    <el-button
+                      class="tool-button"
+                      type="primary"
+                      @click="nextQuestion"
+                      >涓嬩竴棰�</el-button
+                    >
                   </div>
                 </div>
               </div>
@@ -68,33 +98,265 @@
         </div>
       </div>
     </div>
+
+    <!-- 閫�鍑鸿�冭瘯鎻愮ず寮圭獥 -->
+    <el-dialog v-model="quitDialog" title="娉ㄦ剰" width="500">
+      <div class="dialog-container">
+        <p>璇风‘璁ゆ槸鍚﹂��鍑哄綋鍓嶈�冭瘯</p>
+        <p>褰撳墠璇曞嵎浼氳嚜鍔ㄦ彁浜�,鍚庣画灏嗘棤娉曠户缁綔绛�</p>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="quitDialog = false">缁х画浣滅瓟</el-button>
+          <el-button type="danger" @click="confirmQuit"> 纭畾閫�鍑� </el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 浜ゅ嵎鎻愮ず寮圭獥 -->
+    <el-dialog v-model="submitDialog" title="纭浜ゅ嵎?" width="500">
+      <div class="dialog-container">
+        <p>璇风‘璁ゆ槸鍚︽彁浜よ瘯鍗�</p>
+        <p>涓�鏃︿氦鍗峰皢鏃犳硶缁х画浣滅瓟鎴栦慨鏀圭瓟妗�</p>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="submitDialog = false">缁х画浣滅瓟</el-button>
+          <el-button type="primary" @click="confirmSubmit">
+            纭鎻愪氦
+          </el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 鑰冭瘯鏃堕棿寮圭獥 -->
+    <el-dialog
+      v-model="timeDialog"
+      align-center
+      width="500"
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      :show-close="false"
+    >
+      <div class="dialog-container flex flex-col items-center">
+        <div class="icon-container">
+          <el-icon :size="50" color="#3680fa">
+            <Timer />
+          </el-icon>
+        </div>
+        <div class="dialog-info">鑰冭瘯缁撴潫锛岀郴缁熻嚜鍔ㄦ敹鍗蜂腑.......</div>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script setup>
-import {ref} from 'vue';
-import AnswerTag from './components/answer-tag/index.vue';
-import AnswerProgress from './components/answer-progress/index.vue';
-import AnswerSheet from './components/answer-sheet/index.vue';
-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 { ref, watchEffect, watch, onMounted ,onUnmounted} from "vue";
+import { storeToRefs } from "pinia";
+import { Close, Timer } from "@element-plus/icons-vue";
+import AnswerTag from "./components/answer-tag/index.vue";
+import AnswerProgress from "./components/answer-progress/index.vue";
+import AnswerSheet from "./components/answer-sheet/index.vue";
+import AnswerTime from "./components/answer-time/index.vue";
+
+import AnswerSingle from "./components/answer-main/answer-single/index.vue";
+import AnswerMultiple from "./components/answer-main/answer-multiple/index.vue";
+import AnswerAudio from "./components/answer-main/answer-audio/index.vue";
+import AnswerFill from "./components/answer-main/answer-fill/index.vue";
+import AnswerDetermine from "./components/answer-main/answer-determine/index.vue";
+import AnswerShort from "./components/answer-main/answer-short/index.vue";
+import AnswerCount from "./components/answer-main/answer-count/index.vue";
+
+import { useExamStore, useUserStore } from "@/store/index.js";
+import { useRouter } from "vue-router";
+
+import { submitExam } from "@/api/modules/exam.js";
+import useWebScoket from "@/hooks/useWebScoket.js";
+
+import { ElMessage, ElMessageBox } from "element-plus";
+
+const router = useRouter();
+
+const examStore = useExamStore();
+const userStore = useUserStore();
+
+const { userInfo } = storeToRefs(userStore);
+const { currentType, currentIndex, examDetail, examType, examInfo } =
+  storeToRefs(examStore);
 
 const typeComponent = {
   1: AnswerSingle,
   2: AnswerMultiple,
-}
+  3: AnswerDetermine,
+  4: AnswerFill,
+  5: AnswerShort,
+  6: AnswerAudio,
+  7: AnswerCount,
+  8: AnswerShort,
+};
 
-const currentType = ref(1);
-const questionIndex = ref(0);
+const quitDialog = ref(false);
+const submitDialog = ref(false);
+const timeDialog = ref(false);
 
+// const { status, message, error, connect, disconnect, sendMessage } = useWebScoket({
+//   url: 'wss://42.193.1.25:8000/websocket/' + userInfo.value.id,
+//   heartBeatData: 'ping'
+// });
+
+const { status, message, error, connect, disconnect, sendMessage } =
+  useWebScoket({
+    url: "//192.168.3.64:8000/websocket/" + userInfo.value.id,
+    heartBeatData: "ping",
+  });
+
+// 涓婁竴棰�
 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;
+      }
+    }
+  }
+};
+
+// 閫�鍑鸿�冭瘯
+const closeClick = () => {
+  quitDialog.value = true;
+};
+
+const confirmQuit = () => {
+  timeOut();
+};
+
+// 浜ゅ嵎
+const submitExamHandle = () => {
+  submitDialog.value = true;
+};
+
+const confirmSubmit = () => {
+  timeOut();
+};
+
+const resetAllDialog = () => {
+  quitDialog.value = false;
+  submitDialog.value = false;
+};
+
+// 鏃堕棿缁撴潫
+const timeOut = () => {
+  const temp = {
+    ...examInfo.value,
+    titleList: examDetail.value,
+  };
+  timeDialog.value = true;
+  resetAllDialog();
+
+  disconnect();
+
+  submitExam(temp)
+    .then((res) => {
+      returnBack();
+    })
+    .catch(() => {
+      returnBack();
+    });
+};
+
+const returnBack = () => {
+  setTimeout(() => {
+    router.back();
+  }, 2000);
+};
+
+watchEffect(() => {
+  let progress = 0;
+  examDetail.value.forEach((item) => {
+    item.questionList.forEach((question) => {
+      if (
+        question.answer ||
+        (Array.isArray(question.answerList) && question.answerList.length)
+      ) {
+        progress += 1;
+      }
+    });
+  });
+  examStore.setProgress(progress);
+});
+const answerTime = ref();
+watch(
+  () => message.value,
+  (msg) => {
+    if (msg.commend == "delayed") {
+      answerTime.value.addTime(msg.data.addTimeM);
+    } else if (msg.commend == "forceSubmit") {
+      confirmSubmit();
+    }
+  }
+);
+// document.addEventListener('blur', function() {
+//     console.log('椤甸潰澶卞幓鐒︾偣');
+// });
+const warningNum = ref(0)
+const handleBlur = () => {
+  if (document.visibilityState === "visible") {
+  } else if (document.visibilityState === "hidden") {
+    ElMessageBox.alert("鑰冭瘯杩囩▼涓鍕跨寮�鑰冭瘯椤甸潰锛佽鍛婁笁娆″皢寮哄埗鏀跺嵎", "璀﹀憡", {
+      confirmButtonText: "纭畾",
+    });
+    warningNum.value++
+    if (warningNum.value==3) {
+      timeOut();
+    }
+  }
+};
+
+// -----------------------------------鐢熷懡鍛ㄦ湡
+onMounted(() => {
+  // 杩炴帴webscoket
+  connect();
+  document.addEventListener("visibilitychange", handleBlur);
+});
+onUnmounted(()=>{
+  document.removeEventListener("visibilitychange", handleBlur);
+})
 </script>
 
 <style lang="scss" scoped>
@@ -134,7 +396,7 @@
 }
 
 .answer-left {
-  width: 340px;
+  width: 370px;
 }
 
 .submit-button,
@@ -142,7 +404,19 @@
   width: 160px;
   height: 40px;
 }
+
 .tool-button {
   margin: 0 20px;
 }
-</style>
\ No newline at end of file
+
+.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>

--
Gitblit v1.8.0