BooleanQuestionView.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <template>
  2. <div v-if="isSyncState" class="question-view">
  3. <question-body
  4. :question-body="question.body"
  5. :exam-question="examQuestion"
  6. ></question-body>
  7. <div class="ops">
  8. <div class="stu-answer">
  9. {{ { true: "正确", false: "错误" }[studentAnswer] }}
  10. </div>
  11. <div class="score">({{ examQuestion.questionScore }}分)</div>
  12. </div>
  13. <div
  14. :class="[studentAnswer === 'true' && 'row-selected', 'option']"
  15. @click="() => answerQuestion('true')"
  16. >
  17. <input
  18. type="radio"
  19. name="question"
  20. value="true"
  21. :checked="studentAnswer === 'true'"
  22. style="margin-top:3px;display:block"
  23. />
  24. <span class="question-options">正确</span>
  25. </div>
  26. <div
  27. :class="[studentAnswer === 'false' && 'row-selected', 'option']"
  28. @click="() => answerQuestion('false')"
  29. >
  30. <input
  31. type="radio"
  32. name="question"
  33. value="false"
  34. :checked="studentAnswer === 'false'"
  35. style="margin-top:3px;display:block"
  36. />
  37. <span class="question-options">错误</span>
  38. </div>
  39. <div class="reset">
  40. <i-button type="warning" size="large" @click="() => answerQuestion(null)">
  41. 重置答案
  42. </i-button>
  43. <span v-if="examShouldShowAnswer()">
  44. &nbsp;&nbsp;&nbsp;<i-button
  45. type="info"
  46. size="large"
  47. @click="showAnswer"
  48. >
  49. 显示答案
  50. </i-button>
  51. </span>
  52. <div v-if="examShouldShowAnswer() && isShowAnswer">
  53. 正确答案:
  54. <div>{{ { true: "正确", false: "错误" }[question.rightAnswer] }}</div>
  55. </div>
  56. </div>
  57. </div>
  58. </template>
  59. <script>
  60. import QuestionBody from "./QuestionBody";
  61. import { createNamespacedHelpers } from "vuex";
  62. const { mapMutations, mapGetters } = createNamespacedHelpers(
  63. "examingHomeModule"
  64. );
  65. export default {
  66. name: "BooleanQuestionView",
  67. components: {
  68. QuestionBody,
  69. },
  70. props: {
  71. question: {
  72. type: Object,
  73. default() {
  74. return {};
  75. },
  76. },
  77. examQuestion: {
  78. type: Object,
  79. default() {
  80. return {};
  81. },
  82. },
  83. },
  84. data() {
  85. return {
  86. isShowAnswer: false,
  87. };
  88. },
  89. computed: {
  90. isSyncState() {
  91. return this.examQuestion.order == this.$route.params.order;
  92. },
  93. studentAnswer: vm => vm.examQuestion.studentAnswer,
  94. },
  95. watch: {
  96. // examQuestion: function() {
  97. // this.studentAnswer = this.examQuestion.studentAnswer;
  98. // },
  99. // question(question) {
  100. // this.questionBody = question.body;
  101. // }
  102. },
  103. created: function() {
  104. window.addEventListener("keyup", this.keyup);
  105. },
  106. beforeDestroy() {
  107. window.removeEventListener("keyup", this.keyup);
  108. },
  109. methods: {
  110. ...mapMutations(["updateExamQuestion"]),
  111. ...mapGetters(["examShouldShowAnswer"]),
  112. keyup(e) {
  113. // console.log(e);
  114. // console.log(document.activeElement.type);
  115. if (
  116. ["BODY", "A", "BUTTON", "DIV"].includes(
  117. document.activeElement.tagName
  118. ) ||
  119. (["INPUT"].includes(document.activeElement.tagName) &&
  120. ["checkbox", "radio"].includes(document.activeElement.type))
  121. ) {
  122. window._hmt.push(["_trackEvent", "正在考试页面", "快捷键", "YN"]);
  123. if ("KeyY" === e.code) {
  124. this.answerQuestion("true");
  125. }
  126. if ("KeyN" === e.code) {
  127. this.answerQuestion("false");
  128. }
  129. }
  130. },
  131. async answerQuestion(studentAnswer) {
  132. if (this.isSyncState === false) {
  133. console.log("更新答案时,问题与答案的号码不一致。");
  134. return;
  135. }
  136. if (studentAnswer !== this.examQuestion.studentAnswer) {
  137. this.updateExamQuestion({
  138. order: this.examQuestion.order,
  139. studentAnswer,
  140. });
  141. }
  142. },
  143. showAnswer() {
  144. this.isShowAnswer = !this.isShowAnswer;
  145. },
  146. },
  147. };
  148. </script>
  149. <style scoped>
  150. .question-view {
  151. display: grid;
  152. grid-row-gap: 10px;
  153. }
  154. .question-body {
  155. font-size: 18px;
  156. margin-bottom: 10px;
  157. }
  158. .ops {
  159. display: flex;
  160. align-items: flex-end;
  161. }
  162. .stu-answer {
  163. width: 100px;
  164. border-bottom: 1px solid black;
  165. text-align: center;
  166. height: 20px;
  167. }
  168. .option {
  169. display: flex;
  170. cursor: pointer;
  171. }
  172. .option:hover {
  173. background-color: aliceblue;
  174. }
  175. .row-selected {
  176. background-color: aliceblue;
  177. width: 100%;
  178. }
  179. .question-options {
  180. text-align: left;
  181. margin-left: 10px;
  182. }
  183. </style>