From 9685de3762d0ceea938b5c195638103f8d8de969 Mon Sep 17 00:00:00 2001
From: luohairen <3399054449@qq.com>
Date: 星期二, 12 十一月 2024 16:06:05 +0800
Subject: [PATCH] 优化错题查询
---
src/views/exam/index.vue | 249 ++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 193 insertions(+), 56 deletions(-)
diff --git a/src/views/exam/index.vue b/src/views/exam/index.vue
index 733daf1..29ad708 100644
--- a/src/views/exam/index.vue
+++ b/src/views/exam/index.vue
@@ -1,13 +1,15 @@
<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></AnswerTime>
+ <AnswerTime @timeOut="timeOut" ref="answerTime"></AnswerTime>
<div class="return-container grow flex justify-end">
<el-button type="danger" size="large" circle @click="closeClick">
@@ -24,8 +26,10 @@
<!-- 绛旈鍗″尯 -->
<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>
@@ -40,9 +44,13 @@
</div>
<div class="submit-wrapper">
- <el-button type="primary" class="submit-button" @click="submitExam">鎻愪氦璇曞嵎</el-button>
+ <el-button
+ type="primary"
+ class="submit-button"
+ @click="submitExamHandle"
+ >鎻愪氦璇曞嵎</el-button
+ >
</div>
-
</div>
</div>
@@ -50,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 ">{{ examType[currentType] }} ({{ examStore.getActiveQuestion.score}}鍒�)</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="currentIndex"></component>
+ <component
+ :is="typeComponent[currentType]"
+ :key="currentIndex"
+ ></component>
</Transition>
</div>
</div>
@@ -64,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>
@@ -76,7 +98,6 @@
</div>
</div>
</div>
-
<!-- 閫�鍑鸿�冭瘯鎻愮ず寮圭獥 -->
<el-dialog v-model="quitDialog" title="娉ㄦ剰" width="500">
@@ -87,9 +108,7 @@
<template #footer>
<div class="dialog-footer">
<el-button @click="quitDialog = false">缁х画浣滅瓟</el-button>
- <el-button type="danger" @click="confirmQuit">
- 纭畾閫�鍑�
- </el-button>
+ <el-button type="danger" @click="confirmQuit"> 纭畾閫�鍑� </el-button>
</div>
</template>
</el-dialog>
@@ -109,49 +128,101 @@
</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, watchEffect } 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';
-import AnswerSheet from './components/answer-sheet/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 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 } from '@/store/index.js';
-import { useRouter } from 'vue-router';
+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 { currentType, currentIndex, examDetail, examType } = storeToRefs(examStore);
+const userStore = useUserStore();
+
+const { userInfo } = storeToRefs(userStore);
+const { currentType, currentIndex, examDetail, examType, examInfo } =
+ storeToRefs(examStore);
const typeComponent = {
1: AnswerSingle,
2: AnswerMultiple,
- 3: AnswerAudio,
+ 3: AnswerDetermine,
+ 4: AnswerFill,
+ 5: AnswerShort,
+ 6: AnswerAudio,
+ 7: AnswerCount,
+ 8: AnswerShort,
};
const quitDialog = ref(false);
const submitDialog = ref(false);
+const timeDialog = ref(false);
+const { status, message, error, connect, disconnect, sendMessage } = useWebScoket({
+ url: 'wss://www.kgmeet.com:18443/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 = () => {
currentIndex.value--;
checkList();
};
+// 涓嬩竴棰�
const nextQuestion = () => {
currentIndex.value++;
checkList();
};
+// 鏌ヨ棰樼洰
const checkList = () => {
let tempIndex = 0;
const typeQuestion = examDetail.value.find((typeItem, index) => {
@@ -172,28 +243,16 @@
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;
+ 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);
}
}
};
@@ -204,33 +263,100 @@
};
const confirmQuit = () => {
- quitDialog.value = false;
- router.back();
+ timeOut();
};
// 浜ゅ嵎
-const submitExam = () => {
+const submitExamHandle = () => {
submitDialog.value = true;
-}
-
-const confirmSubmit = () => {
- submitDialog.value = false;
- router.back();
};
+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.correct) {
+ 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>
@@ -270,7 +396,7 @@
}
.answer-left {
- width: 340px;
+ width: 370px;
}
.submit-button,
@@ -282,4 +408,15 @@
.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