Prechádzať zdrojové kódy

完成判断题、多选题、填空题的部分答题逻辑

Michael Wang 6 rokov pred
rodič
commit
b1a8d04c51

+ 71 - 0
src/features/OnlineExam/Examing/BooleanQuestionView.vue

@@ -0,0 +1,71 @@
+<template>
+  <div class="question-view">
+    <div class="question-body" v-html="question.body"></div>
+    <div class="ops">
+      <div class="stu-answer"> {{stuAnswer}}</div>
+      <i-button @click="resetQuestion(examQuestion.id)">重置</i-button>
+      <div class="score">({{question.questionScore}}分)</div>
+    </div>
+    <div @click="answerQuestion(examQuestion.id, '正确')">
+      <input type="radio" name="question" value="正确" :checked="stuAnswer === '正确'" />
+      <span class="question-options">正确</span>
+    </div>
+    <div @click="answerQuestion(examQuestion.id, '错误')">
+      <input type="radio" name="question" value="错误" :checked="stuAnswer === '错误'" />
+      <span class="question-options">错误</span>
+    </div>
+
+  </div>
+</template>
+
+<script>
+export default {
+  name: "BooleanQuestionView",
+  data() {
+    return {
+      stuAnswer: this.examQuestion.stuAnswer
+    };
+  },
+  props: {
+    question: Object,
+    examQuestion: Object
+  },
+  methods: {
+    answerQuestion: function(examQuestionId, stuAnswer) {
+      this.stuAnswer = stuAnswer;
+      this.$http.put("/api/exam_question/" + examQuestionId, { stuAnswer });
+    },
+    resetQuestion: function(examQuestionId) {
+      this.stuAnswer = null;
+      this.$http.put("/api/exam_question/" + examQuestionId, {
+        stuAnswer: null
+      });
+    }
+  },
+  watch: {}
+};
+</script>
+
+<style scoped>
+.question-view {
+  display: block;
+}
+
+.ops {
+  display: flex;
+  align-items: flex-end;
+}
+
+.stu-answer {
+  width: 100px;
+  border-bottom: 1px solid black;
+}
+
+.option {
+  display: flex;
+}
+.question-options {
+  text-align: left;
+  padding-left: 10px;
+}
+</style>

+ 10 - 1
src/features/OnlineExam/Examing/ExamingHome.vue

@@ -53,7 +53,16 @@ export default {
         this.$route.query.examRecordId
     );
     this.examQuestionList = examQuestionList.data;
-    this.examQuestion = this.examQuestionList[0];
+
+    if (!this.$route.query.examQuestionId) {
+      this.$router.push(
+        this.$route.fullPath + "&examQuestionId=" + this.examQuestionList[0].id
+      );
+      return;
+    }
+    this.examQuestion = this.examQuestionList.find(
+      eq => eq.id == this.$route.query.examQuestionId // number == string
+    );
   },
   components: {
     RemainTime,

+ 103 - 0
src/features/OnlineExam/Examing/FillBlankQuestionView.vue

@@ -0,0 +1,103 @@
+<template>
+  <div class="question-view">
+    <div class="question-body" v-html="questionBody"></div>
+    <div class="ops">
+      <i-button @click="resetQuestion(examQuestion.id)">重置</i-button>
+      <div class="score">({{question.questionScore}}分)</div>
+    </div>
+    <div v-for="(option, index) in stuAnswer.split('##')" :key="index" class="option">
+      <span class="question-options">{{index+1}}. </span>
+      <input type="text" name="question" :value="option" @input="inputAnswer" />
+    </div>
+
+  </div>
+</template>
+
+<script>
+const optionName = ["A", "B", "C", "D", "E", "F"];
+export default {
+  name: "FillBlankQuestionView",
+  data() {
+    const questionNumber = this.question.body.split(/_{5,}/).length - 1;
+
+    const answers = this.examQuestion.stuAnswer
+      ? this.examQuestion.stuAnswer.split("##")
+      : "##".repeat(questionNumber - 1).split("##");
+    let questionBody = this.question.body.replace(
+      /_{5,}/g,
+      () =>
+        "<span style='display: inline-block; min-width: 80px; border-bottom: 1px solid black'>" +
+        (answers.shift() || questionNumber - answers.length) +
+        "</span>"
+    );
+    return {
+      questionNumber,
+      questionBody,
+      stuAnswer: this.examQuestion.stuAnswer || "##".repeat(questionNumber - 1)
+    };
+  },
+  props: {
+    question: Object,
+    examQuestion: Object
+  },
+  methods: {
+    answerQuestion: function(examQuestionId, stuAnswer) {
+      this.stuAnswer = stuAnswer;
+      this.$http.put("/api/exam_question/" + examQuestionId, { stuAnswer });
+    },
+    resetQuestion: function(examQuestionId) {
+      this.stuAnswer = "##".repeat(this.questionNumber - 1);
+      setTimeout(this.inputAnswer, 100);
+      this.$http.put("/api/exam_question/" + examQuestionId, {
+        stuAnswer: null
+      });
+    },
+    inputAnswer: function(e) {
+      const questionNumber = this.question.body.split(/_{5,}/).length - 1;
+      let ans = "";
+      document
+        .querySelectorAll(".option input")
+        .forEach(e => (ans += e.value + "##"));
+      console.log(ans);
+      this.stuAnswer = ans.slice(0, -2);
+      const answers = this.stuAnswer.split("##");
+      this.questionBody = this.question.body.replace(
+        /_{5,}/g,
+        () =>
+          "<span style='display: inline-block; min-width: 80px; border-bottom: 1px solid black'>" +
+          (answers.shift() || questionNumber - answers.length) +
+          "</span>"
+      );
+    }
+  },
+  watch: {
+    stuAnswer: function() {
+      // question.body =
+    }
+  }
+};
+</script>
+
+<style scoped>
+.question-view {
+  display: block;
+}
+
+.ops {
+  display: flex;
+  align-items: flex-end;
+}
+
+.stu-answer {
+  width: 100px;
+  border-bottom: 1px solid black;
+}
+
+.option {
+  /* display: flex; */
+}
+.question-options {
+  text-align: left;
+  padding-left: 10px;
+}
+</style>

+ 84 - 0
src/features/OnlineExam/Examing/MultipleQuestionView.vue

@@ -0,0 +1,84 @@
+<template>
+  <div class="question-view">
+    <div class="question-body" v-html="question.body"></div>
+    <div class="ops">
+      <div class="stu-answer"> {{stuAnswer}}</div>
+      <i-button @click="resetQuestion(examQuestion.id)">重置</i-button>
+      <div class="score">({{question.questionScore}}分)</div>
+    </div>
+    <div v-for="(option, index) in question.options" :key="option.id" class="option" @click="toggleAnswer(index)">
+      <input type="checkbox" name="question" value="optionName[index]" :checked="stuAnswer.includes(optionName[index])" />
+      <span>{{optionName[index]}}: </span>
+      <span class="question-options" v-html="option.content"></span>
+    </div>
+
+  </div>
+</template>
+
+<script>
+const optionName = ["A", "B", "C", "D", "E", "F"];
+export default {
+  name: "MultipleQuestionView",
+  data() {
+    return {
+      // question: null
+      optionName,
+      stuAnswer: this.examQuestion.stuAnswer || ""
+    };
+  },
+  props: {
+    question: Object,
+    examQuestion: Object
+  },
+  methods: {
+    toggleAnswer: function(index) {
+      if (this.stuAnswer.includes(optionName[index])) {
+        this.stuAnswer.replace(optionName[index], "");
+      } else {
+        this.stuAnswer = this.stuAnswer
+          .concat(optionName[index])
+          .split("")
+          .sort()
+          .join("");
+      }
+      this.answerQuestion();
+    },
+    answerQuestion: function() {
+      this.$http.put("/api/exam_question/" + this.examQuestion.id, {
+        stuAnswer: this.stuAnswer
+      });
+    },
+    resetQuestion: function(examQuestionId) {
+      this.stuAnswer = "";
+      this.$http.put("/api/exam_question/" + examQuestionId, {
+        stuAnswer: null
+      });
+    }
+  },
+  watch: {}
+};
+</script>
+
+<style scoped>
+.question-view {
+  display: block;
+}
+
+.ops {
+  display: flex;
+  align-items: flex-end;
+}
+
+.stu-answer {
+  width: 100px;
+  border-bottom: 1px solid black;
+}
+
+.option {
+  display: flex;
+}
+.question-options {
+  text-align: left;
+  padding-left: 10px;
+}
+</style>

+ 19 - 2
src/features/OnlineExam/Examing/QuestionView.vue

@@ -2,12 +2,26 @@
   <div v-if="question && examQuestion" class="question-view">
     <div class="question-group">{{"大题占位"}}</div>
     <div class="question-group-progress">{{"大题进度占位"}}</div>
-    <single-question-view :question="question" :examQuestion="examQuestion" />
+    <template v-if="question.questionType === 'SINGLE_ANSWER_QUESTION'">
+      <single-question-view :question="question" :examQuestion="examQuestion" />
+    </template>
+    <template v-if="question.questionType === 'MULTIPLE_ANSWER_QUESTION'">
+      <multiple-question-view :question="question" :examQuestion="examQuestion" />
+    </template>
+    <template v-if="question.questionType === 'BOOL_ANSWER_QUESTION'">
+      <boolean-question-view :question="question" :examQuestion="examQuestion" />
+    </template>
+    <template v-if="question.questionType === 'FILL_BLANK_QUESTION'">
+      <fill-blank-question-view :question="question" :examQuestion="examQuestion" />
+    </template>
   </div>
 </template>
 
 <script>
 import SingleQuestionView from "./SingleQuestionView";
+import MultipleQuestionView from "./MultipleQuestionView";
+import BooleanQuestionView from "./BooleanQuestionView";
+import FillBlankQuestionView from "./FillBlankQuestionView";
 
 export default {
   name: "QuestionView",
@@ -105,7 +119,10 @@ export default {
     }
   },
   components: {
-    SingleQuestionView
+    SingleQuestionView,
+    MultipleQuestionView,
+    BooleanQuestionView,
+    FillBlankQuestionView
   }
 };
 </script>