QuestionAnswerShow.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <template>
  2. <a-spin :spinning="qLoading" style="line-height: 1.8">
  3. <div v-if="[1, 2, 3, 4, 5].includes(qType)">
  4. <!-- 单选题 -->
  5. <div v-if="qType === 1">
  6. <!-- eslint-disable-next-line vue/no-v-html -->
  7. <div class="q-title" v-html="question.title" />
  8. <div class="q-content">
  9. <a-radio-group v-model:value="answer.content">
  10. <a-radio v-for="item in question.items" :key="item.prefix" :value="item.prefix" :class="askType==1?'read-only':''">
  11. <span class="question-prefix">{{ item.prefix }}.</span>
  12. <!-- eslint-disable-next-line vue/no-v-html -->
  13. <span v-html="item.content" class="q-item-span-content"></span>
  14. </a-radio>
  15. </a-radio-group>
  16. </div>
  17. </div>
  18. <!-- 多选题 -->
  19. <div v-else-if="qType === 2">
  20. <!-- eslint-disable-next-line vue/no-v-html -->
  21. <div class="q-title" v-html="question.title" />
  22. <div class="q-content">
  23. <a-checkbox-group v-model:value="answer.contentArray" :class="askType==1?'read-only':''">
  24. <a-checkbox v-for="item in question.items" :key="item.prefix" :value="item.prefix">
  25. <span class="question-prefix">{{ item.prefix }}.</span>
  26. <!-- eslint-disable-next-line vue/no-v-html -->
  27. <span v-html="item.content" class="q-item-span-content"></span>
  28. </a-checkbox>
  29. </a-checkbox-group>
  30. </div>
  31. </div>
  32. <!-- 判断题 -->
  33. <div v-else-if="qType === 3">
  34. <!-- eslint-disable-next-line vue/no-v-html -->
  35. <div class="q-title" v-html="question.title" style="display: inline; margin-right: 10px" />
  36. <span style="padding-right: 10px">(</span>
  37. <a-radio-group v-model:value="answer.content" :class="askType==1?'read-only':''">
  38. <a-radio v-for="item in question.items" :key="item.prefix" :value="item.prefix">
  39. <!-- eslint-disable-next-line vue/no-v-html -->
  40. <span v-html="item.content" class="q-item-span-content"></span>
  41. </a-radio>
  42. </a-radio-group>
  43. <span style="padding-left: 10px">)</span>
  44. </div>
  45. <!-- 填空题 -->
  46. <div v-else-if="qType === 4">
  47. <!-- eslint-disable-next-line vue/no-v-html -->
  48. <div class="q-title" v-html="question.title" />
  49. <div v-if="answer.contentArray !== null">
  50. <a-form layout="vertical">
  51. <a-form-item
  52. v-for="item in question.items"
  53. :label="item.prefix"
  54. :key="item.prefix"
  55. style="margin-top: 10px; margin-bottom: 10px"
  56. >
  57. <a-input :class="askType==1?'read-only':''" v-model:value="answer.contentArray[item.prefix - 1]" />
  58. </a-form-item>
  59. </a-form>
  60. </div>
  61. </div>
  62. <!-- 简答题 -->
  63. <div v-else-if="qType === 5">
  64. <!-- eslint-disable-next-line vue/no-v-html -->
  65. <div class="q-title" v-html="question.title" />
  66. <div>
  67. <a-textarea :class="askType==1?'read-only':''" v-model:value="answer.content" :rows="5" />
  68. </div>
  69. </div>
  70. <!-- 结果、分数、难度、解析、正确答案 -->
  71. <div class="question-answer-show-item" style="margin-top: 15px" v-if="paperType!=5">
  72. <span class="question-show-item">结果:</span>
  73. <a-tag :color="doRightTagFormatter(answer.doRight)">
  74. {{ doRightTextFormatter(answer.doRight) }}
  75. </a-tag>
  76. </div>
  77. <div class="question-answer-show-item" v-if="paperType!=5">
  78. <span class="question-show-item">分数:</span>
  79. <span>{{ question.score }}</span>
  80. </div>
  81. <div class="question-answer-show-item" v-if="paperType!=5">
  82. <span class="question-show-item">难度:</span>
  83. <a-rate :value="question.difficult" disabled class="question-show-item" />
  84. </div>
  85. <br />
  86. <div class="question-answer-show-item" style="line-height: 1.8">
  87. <span class="question-show-item">解析:</span>
  88. <span v-html="question.analyze" class="q-item-span-content" />
  89. </div>
  90. <div class="question-answer-show-item">
  91. <span class="question-show-item">正确答案:</span>
  92. <!-- eslint-disable-next-line vue/no-v-html -->
  93. <span v-if="[1, 2, 5].includes(qType)" v-html="question.correct" class="q-item-span-content" />
  94. <!-- eslint-disable-next-line vue/no-v-html -->
  95. <span v-if="qType === 3" v-html="trueFalseFormatter(question)" class="q-item-span-content" />
  96. <span v-if="qType === 4">{{ question.correctArray }}</span>
  97. </div>
  98. </div>
  99. <div v-else></div>
  100. </a-spin>
  101. </template>
  102. <script setup>
  103. import { computed, toRefs } from 'vue'
  104. import { useExamStore } from '@/store/exam'
  105. const props = defineProps({
  106. question: {
  107. type: Object,
  108. default: () => ({})
  109. },
  110. answer: {
  111. type: Object,
  112. default: () => ({ id: null, content: '', contentArray: [], doRight: false })
  113. },
  114. qLoading: {
  115. type: Boolean,
  116. default: false
  117. },
  118. qType: {
  119. type: Number,
  120. default: 0
  121. },
  122. paperType: {
  123. type: [String,Number],
  124. default: ''
  125. },
  126. askType:{
  127. type: String,
  128. default: ''
  129. }
  130. })
  131. const { question, answer, qLoading, qType, paperType, askType } = toRefs(props)
  132. const examStore = useExamStore()
  133. const doRightEnum = computed(() => examStore.exam.question.answer.doRightEnum)
  134. const doRightTag = computed(() => examStore.exam.question.answer.doRightTag)
  135. const enumFormat = examStore.enumFormat
  136. function trueFalseFormatter(question) {
  137. const item = question.items?.find((d) => d.prefix === question.correct)
  138. return item ? item.content : ''
  139. }
  140. function doRightTagFormatter(status) {
  141. // ant-design-vue 的 a-tag 颜色映射
  142. const tag = enumFormat(doRightTag.value, status)
  143. if (tag === 'success') return 'green'
  144. if (tag === 'danger') return 'red'
  145. if (tag === 'warning') return 'orange'
  146. return 'default'
  147. }
  148. function doRightTextFormatter(status) {
  149. return enumFormat(doRightEnum.value, status)
  150. }
  151. </script>
  152. <style lang="less" scoped>
  153. .q-title {
  154. font-weight: bold;
  155. margin-bottom: 8px;
  156. }
  157. .q-content {
  158. margin-bottom: 12px;
  159. }
  160. .question-prefix {
  161. font-weight: bold;
  162. margin-right: 4px;
  163. }
  164. .question-answer-show-item {
  165. margin-bottom: 8px;
  166. }
  167. .question-show-item {
  168. font-weight: 500;
  169. margin-right: 8px;
  170. }
  171. .q-item-span-content {
  172. display: inline-block;
  173. vertical-align: middle;
  174. }
  175. .read-only {
  176. pointer-events: none;
  177. }
  178. </style>