index.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import { Tag, Image } from 'vant'
  2. import { computed, defineComponent, PropType, reactive } from 'vue'
  3. import { AnswerType, labelOptions, QuestionType } from '../../unit'
  4. import AnserTitle from '../anser-title'
  5. import AnswerAnalysis from '../answer-analysis'
  6. import UnitAudio from '../unit-audio'
  7. import styles from './index.module.less'
  8. // 单选题 - 多选题
  9. export default defineComponent({
  10. name: 'choice-question',
  11. props: {
  12. value: {
  13. type: Array,
  14. default: () => []
  15. },
  16. type: {
  17. type: String as PropType<'radio' | 'checkbox'>,
  18. default: 'radio'
  19. },
  20. index: {
  21. // 题目是第几道
  22. type: Number,
  23. default: 1
  24. },
  25. data: {
  26. type: Object,
  27. default: () => ({})
  28. },
  29. readOnly: {
  30. type: Boolean,
  31. default: false
  32. },
  33. showRate: {
  34. tyep: Boolean,
  35. default: false
  36. },
  37. showAnalysis: {
  38. // 是否显示解析
  39. type: Boolean,
  40. default: false
  41. },
  42. analysis: {
  43. type: Object,
  44. default: () => ({
  45. message: '',
  46. topic: false, // 是否显示结果
  47. userResult: true // 用户答题对错
  48. })
  49. }
  50. },
  51. emits: ['update:value'],
  52. setup(props, { emit }) {
  53. const onSelect = (item: any) => {
  54. console.log(item, 'onSelect')
  55. if (props.readOnly) return
  56. const value: any = props.value || []
  57. const result = {
  58. answerId: item.examinationQuestionAnswerId,
  59. answer: item.questionAnswer,
  60. answerExtra: item.questionExtra
  61. }
  62. console.log(result, 'onSelect')
  63. if (props.type === 'checkbox') {
  64. const tempIndex = value.findIndex(
  65. (c: any) => c.answerId === item.examinationQuestionAnswerId
  66. )
  67. if (tempIndex >= 0) {
  68. value.splice(tempIndex, 1)
  69. emit('update:value', [...value])
  70. } else {
  71. emit('update:value', [...value, result])
  72. }
  73. } else {
  74. emit('update:value', [result])
  75. }
  76. }
  77. const answers = computed(() => {
  78. const list: any = props.data.answers || []
  79. const value: any = props.value || []
  80. list.forEach((item: any) => {
  81. const tempIndex = value.findIndex(
  82. (c: any) => c.answerId === item.examinationQuestionAnswerId
  83. )
  84. item.checked = tempIndex !== -1 ? true : false
  85. })
  86. return list
  87. })
  88. return () => (
  89. <>
  90. <div class={styles.unitSubject}>
  91. {/* 标题 */}
  92. <AnserTitle
  93. index={props.index}
  94. name={props.data.name}
  95. showRate={props.showRate}
  96. score={props.data.totalScore}
  97. answerType={props.type === 'radio' ? QuestionType.RADIO : QuestionType.CHECKBOX}
  98. extra={{
  99. questionDetail: props.data.questionDetail,
  100. mediaUrls: props.data.mediaUrls,
  101. rightRate: props.data.rightRate
  102. }}
  103. />
  104. <div class={styles.unitAnswers}>
  105. {answers.value.map((item: any, index: number) => (
  106. <div
  107. class={[styles.unitAnswer, item.checked && styles.active]}
  108. onClick={() => onSelect(item)}
  109. >
  110. <div class={styles.answerContent}>
  111. <span class={styles.option}>{labelOptions[index + 1]}.</span>
  112. {item.questionAnswerTypeCode === AnswerType.IMAGE && (
  113. <div class={styles.value}>
  114. <Image src={item.questionAnswer} fit="contain" class={'answerTitleImg'} />
  115. </div>
  116. )}
  117. {item.questionAnswerTypeCode === AnswerType.TXT && (
  118. <div class={styles.value}>{item.questionAnswer}</div>
  119. )}
  120. {item.questionAnswerTypeCode === AnswerType.AUDIO && (
  121. <div class={styles.value}>
  122. <UnitAudio src={item.questionAnswer} class={styles.valueAudio} />
  123. </div>
  124. )}
  125. </div>
  126. {props.showRate && (
  127. <div class={styles.answerChoice}>{item.selectRate || 0}%人选择</div>
  128. )}
  129. </div>
  130. ))}
  131. </div>
  132. </div>
  133. {props.showAnalysis && (
  134. <div class={styles.unitSubject}>
  135. <AnswerAnalysis
  136. answerAnalysis={props.analysis.message}
  137. topic={props.analysis.topic}
  138. userResult={props.analysis.userResult}
  139. />
  140. </div>
  141. )}
  142. </>
  143. )
  144. }
  145. })