index.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import { Tag, Image } from 'vant'
  2. import { computed, defineComponent, PropType, reactive } from 'vue'
  3. import { AnswerType, labelOptions } from '../../unit'
  4. import styles from './index.module.less'
  5. // 单选题 - 多选题
  6. export default defineComponent({
  7. name: 'choice-question',
  8. props: {
  9. value: {
  10. type: Array,
  11. default: () => []
  12. },
  13. type: {
  14. type: String as PropType<'radio' | 'checkbox'>,
  15. default: 'radio'
  16. },
  17. index: {
  18. // 题目是第几道
  19. type: Number,
  20. default: 1
  21. },
  22. data: {
  23. type: Object,
  24. default: () => ({})
  25. },
  26. readOnly: {
  27. type: Boolean,
  28. default: false
  29. }
  30. },
  31. emits: ['update:value'],
  32. setup(props, { emit }) {
  33. const onSelect = (item: any) => {
  34. if (props.readOnly) return
  35. const value: any = props.value || []
  36. const result = {
  37. answerId: item.examinationQuestionAnswerId,
  38. answer: item.questionAnswer,
  39. extra: item.questionExtra
  40. }
  41. if (props.type === 'checkbox') {
  42. const tempIndex = value.findIndex(
  43. (c: any) => c.answerId === item.examinationQuestionAnswerId
  44. )
  45. if (tempIndex >= 0) {
  46. value.splice(tempIndex, 1)
  47. emit('update:value', [...value])
  48. } else {
  49. emit('update:value', [...value, result])
  50. }
  51. } else {
  52. emit('update:value', [result])
  53. }
  54. }
  55. const answers = computed(() => {
  56. const list: any = props.data.answers || []
  57. const value: any = props.value || []
  58. list.forEach((item: any) => {
  59. const tempIndex = value.findIndex(
  60. (c: any) => c.answerId === item.examinationQuestionAnswerId
  61. )
  62. item.checked = tempIndex !== -1 ? true : false
  63. })
  64. return list
  65. })
  66. const mediaUrls = computed(() => (props.data.mediaUrls ? props.data.mediaUrls.split(',') : ''))
  67. return () => (
  68. <div class={styles.unitSubject}>
  69. <div class={styles.unitSubjectTitle}>
  70. {props.index}、{props.data.name}{' '}
  71. <span class={styles.unitScore}>({props.data.totalScore || 0}分)</span>
  72. <Tag type="primary">{props.type === 'radio' ? '单选题' : '多选题'}</Tag>
  73. </div>
  74. <div class={styles.unitDetail}>
  75. <div v-html={props.data.questionDetail}></div>
  76. {mediaUrls.value &&
  77. mediaUrls.value.map((url: any) => <Image class={styles.unitTitleImg} src={url} />)}
  78. </div>
  79. <div class={styles.unitAnswers}>
  80. {/* styles.active */}
  81. {answers.value.map((item: any, index: number) => (
  82. <div
  83. class={[styles.unitAnswer, item.checked && styles.active]}
  84. onClick={() => onSelect(item)}
  85. >
  86. <span class={styles.option}>{labelOptions[index + 1]}.</span>
  87. {item.questionAnswerTypeCode === AnswerType.IMAGE && (
  88. <div class={styles.value}>
  89. <Image src={item.questionAnswer} />
  90. </div>
  91. )}
  92. {item.questionAnswerTypeCode === AnswerType.TXT && (
  93. <div class={styles.value}>{item.questionAnswer}</div>
  94. )}
  95. </div>
  96. ))}
  97. </div>
  98. </div>
  99. )
  100. }
  101. })