TrainQuItem.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <template>
  2. <view v-if="quData" class="qu-box" :class="{'sub-box': sub}">
  3. <view class="qu-item">
  4. <view>
  5. <text class="num">{{ quData.sort || card.sort }}</text>
  6. <text >【{{ quData.quType_dictText }}】</text>
  7. </view>
  8. <view class="content">
  9. <rich-text :nodes="quData.content | formatRichText"></rich-text>
  10. </view>
  11. </view>
  12. <view v-if="quData.quType==='1' || quData.quType==='2' || quData.quType==='3' " class="qu-answer">
  13. <view v-for="item in quData.answerList" class="item" :class="{'active':item.checked}"
  14. @click="handleCheck(item)">
  15. <view class="tag">{{ item.abc }}</view>
  16. <view class="content">
  17. <view>{{ item.content }}</view>
  18. <view v-if="item.image">
  19. <img :src="item.image" style="width: 60vw" mode="widthFix">
  20. </view>
  21. </view>
  22. <view class="right-box" v-if="item.isRight && (cardItem.answered || mode==='13')">
  23. <icon type="success" size="16" />
  24. <text>答案</text>
  25. </view>
  26. </view>
  27. </view>
  28. <view v-if="quData.quType === '4'" class="as-box">
  29. <view>
  30. <rich-text v-if="quData.analysis" :nodes="quData.analysis | formatRichText"></rich-text>
  31. <view v-else>暂无试题解析!</view>
  32. </view>
  33. <view v-if="mode!=='13'" style="font-size: 22rpx; color: #FF0000;">请您详细阅读解析并点击下方的`确认答案`即可完成训练</view>
  34. </view>
  35. <!-- 填空题 -->
  36. <view v-if="quData.quType==='5' && mode!=='13'" class="qu-answer">
  37. <view v-for="item in quData.answerList" :key="item.id" class="item">
  38. <input v-model="item.answer" :disabled="cardItem.answered" />
  39. </view>
  40. </view>
  41. <!-- 组合题显示子级 -->
  42. <view v-if="quData.quType=== '99' && quData.subList.length > 0">
  43. <view v-for="(sub,index) in quData.subList" :key="sub.id">
  44. <train-qu-item v-model="quData.subList[index]" :sub="true" :card="cardItem" :mode="mode"></train-qu-item>
  45. </view>
  46. </view>
  47. <!-- 背题模式或已答都显示答案 -->
  48. <view v-if="(cardItem.answered || mode==='13') && quData.quType!=='4'" class="as-box">
  49. <view v-if="quData.quType==='5'">
  50. <view>试题解析:</view>
  51. <view v-for="item in quData.answerList">
  52. <view>{{ item.content }}</view>
  53. </view>
  54. </view>
  55. <view v-else>
  56. <view>试题解析:</view>
  57. <rich-text v-if="quData.analysis" :nodes="quData.analysis"></rich-text>
  58. <view v-else>此题暂无解析内容!</view>
  59. </view>
  60. </view>
  61. <view
  62. v-if="mode!=='13' && !cardItem.answered && !sub && (quData.quType==='2' || quData.quType==='4' || quData.quType==='5' || quData.quType==='99') ">
  63. <button type="warn" @click="checkAnswer">确认答案</button>
  64. </view>
  65. </view>
  66. </template>
  67. <script>
  68. import { fillResult } from '@/api/repo/train'
  69. import TrainQuItem from './TrainQuItem.vue'
  70. export default {
  71. name: 'TrainQuItem',
  72. components: {
  73. TrainQuItem
  74. },
  75. props: {
  76. value: {
  77. type: Object,
  78. default: () => ({})
  79. },
  80. card: {
  81. type: Object,
  82. default: () => ({})
  83. },
  84. mode: String,
  85. sub: {
  86. type: Boolean,
  87. default: false
  88. }
  89. },
  90. data() {
  91. return {
  92. // 是否已答
  93. tags: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
  94. 'U', 'V', 'W', 'X', 'Y', 'Z'
  95. ],
  96. cardItem: {},
  97. // 当前题目内容
  98. quData: {
  99. quType: '',
  100. answerList: []
  101. }
  102. }
  103. },
  104. watch: {
  105. card: {
  106. handler() {
  107. this.cardItem = this.card
  108. }
  109. },
  110. value: {
  111. handler() {
  112. this.quData = this.value
  113. this.initValues()
  114. }
  115. },
  116. quData: {
  117. handler(val) {
  118. this.$emit('input', val)
  119. },
  120. deep: true
  121. }
  122. },
  123. created() {
  124. this.cardItem = this.card
  125. this.quData = this.value
  126. this.initValues()
  127. },
  128. methods: {
  129. // 检查答案是否正确
  130. checkAnswer() {
  131. // 不提交子题目
  132. if (this.sub) {
  133. return
  134. }
  135. console.log('提交数据', this.quData)
  136. // 保存答案
  137. fillResult(this.quData).then(res => {
  138. // 回调
  139. this.$emit('rest', res)
  140. })
  141. },
  142. // 初始化填入值
  143. initValues() {
  144. const answers = this.quData.answerList
  145. for (let i = 0; i < answers.length; i++) {
  146. // 动态添加属性
  147. this.$set(answers[i], 'abc', this.tags[i])
  148. }
  149. // 无答案不填充
  150. if (!this.cardItem.answers) {
  151. return
  152. }
  153. },
  154. // 选定值
  155. handleCheck(item) {
  156. // 不允许重复回答
  157. if (this.cardItem.answered) {
  158. return
  159. }
  160. let auto = false
  161. // 单选题直接保答案
  162. if (this.quData.quType === '1' || this.quData.quType === '3') {
  163. // 自动提交
  164. auto = true
  165. // 互斥答案
  166. const answers = this.quData.answerList
  167. for (let i = 0; i < answers.length; i++) {
  168. answers[i].checked = false
  169. }
  170. }
  171. // 选中或取消
  172. item.checked = !item.checked
  173. if (auto) {
  174. this.checkAnswer()
  175. }
  176. }
  177. }
  178. }
  179. </script>