ReplaceAnswerPreview.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <!-- eslint-disable vue/no-v-html -->
  2. <template>
  3. <div class="replace-preview">
  4. <div class="stem">
  5. <span class="question-number">{{ data.property.question_number }}.</span>
  6. <span v-html="sanitizeHTML(data.stem)"></span>
  7. </div>
  8. <div v-if="isEnable(data.property.is_enable_description)" class="description">{{ data.description }}</div>
  9. <div class="option-list">
  10. <div v-for="(item, i) in option_list" :key="i" :class="['option-item']">
  11. <template v-if="item.length > 1">
  12. <!-- <el-select v-model="answer.answer_list[0].mark_list[i]" placeholder="请选择">
  13. <el-option v-for="items in item" :key="items.content" :label="items.content" :value="items.content">
  14. </el-option>
  15. </el-select> -->
  16. <span class="select-item select-active">{{ active_content[i] }}</span>
  17. <ul :ref="'ui' + i" class="replace-ul" @scroll="handleScroll($event, i)">
  18. <li
  19. :class="[answer.answer_list[0].select_mark[i] === items.mark ? 'active' : '']"
  20. v-for="(items, indexs) in item"
  21. :key="indexs"
  22. @click="handleClickItem(i, indexs)"
  23. >
  24. {{ items.content }}
  25. </li>
  26. </ul>
  27. </template>
  28. <span v-else class="select-item">{{ item[0].content }}</span>
  29. </div>
  30. <SoundRecordPreview :wav-blob.sync="answer.answer_list[0].audio_file_id" />
  31. </div>
  32. </div>
  33. </template>
  34. <script>
  35. import PreviewMixin from './components/PreviewMixin';
  36. import { computeOptionMethods } from '@/views/exercise_questions/data/common';
  37. import SoundRecordPreview from './components/common/SoundRecordPreview.vue';
  38. export default {
  39. name: 'ReplaceAnswerPreview',
  40. components: {
  41. SoundRecordPreview,
  42. },
  43. mixins: [PreviewMixin],
  44. data() {
  45. return {
  46. computeOptionMethods,
  47. // answer: {
  48. // answer_list: [
  49. // {
  50. // audio_file_id: '',
  51. // mark_list: [],
  52. // },
  53. // ],
  54. // },
  55. option_list: [],
  56. active_content: [],
  57. };
  58. },
  59. created() {
  60. this.handleData();
  61. },
  62. mounted() {},
  63. methods: {
  64. // 初始化数据
  65. handleData() {
  66. this.option_list = [];
  67. this.active_content = [];
  68. this.answer.answer_list = [
  69. {
  70. audio_file_id: '',
  71. mark_list: [],
  72. },
  73. ];
  74. let option_lists = [[], [], [], []];
  75. this.data.option_list.forEach((item) => {
  76. item.forEach((items, indexs) => {
  77. if (items.content) {
  78. option_lists[indexs].push(items);
  79. }
  80. });
  81. });
  82. option_lists.forEach((option_item) => {
  83. if (option_item.length > 0) {
  84. this.option_list.push(option_item);
  85. this.answer.answer_list[0].mark_list.push(option_item.length > 1 ? option_item[0].mark : '');
  86. this.active_content.push(option_item.length > 1 ? option_item[0].content : '');
  87. }
  88. });
  89. },
  90. // 处理滚动
  91. handleScroll(event, i) {
  92. let scrollTop = event.target.scrollTop;
  93. let scrollIndex = Math.round(scrollTop / 48);
  94. this.active_content[i] = this.option_list[i][scrollIndex].content;
  95. this.answer.answer_list[0].mark_list[i] = this.option_list[i][scrollIndex].mark;
  96. this.$forceUpdate();
  97. },
  98. handleClickItem(i, indexs) {
  99. this.$refs['ui' + i][0].scrollTop = indexs * 48;
  100. this.active_content[i] = this.option_list[i][indexs].content;
  101. this.answer.answer_list[0].mark_list[i] = this.option_list[i][indexs].mark;
  102. this.$forceUpdate();
  103. },
  104. },
  105. };
  106. </script>
  107. <style lang="scss" scoped>
  108. @use '@/styles/mixin.scss' as *;
  109. .replace-preview {
  110. @include preview;
  111. .option-list {
  112. display: flex;
  113. justify-content: center;
  114. width: max-content;
  115. margin: 0 auto;
  116. border-left: 1px solid rgba(0, 0, 0, 8%);
  117. .option-item {
  118. position: relative;
  119. display: flex;
  120. align-items: center;
  121. height: 356px;
  122. border-right: 1px solid rgba(0, 0, 0, 8%);
  123. }
  124. .select-item {
  125. padding: 6px 8px;
  126. font-size: 20px;
  127. line-height: 28px;
  128. color: #1d2129;
  129. background-color: rgba(239, 239, 239, 100%);
  130. }
  131. .select-active {
  132. position: absolute;
  133. top: 50%;
  134. left: 0;
  135. z-index: 1;
  136. display: block;
  137. width: 100%;
  138. height: 40px;
  139. margin-top: -20px;
  140. color: rgba(29, 33, 41, 100%);
  141. background-color: rgba(239, 239, 239, 100%);
  142. }
  143. ul {
  144. height: 356px;
  145. padding: 158px 0 150px;
  146. overflow-y: scroll;
  147. &::-webkit-scrollbar {
  148. display: none;
  149. }
  150. li {
  151. padding: 6px 8px;
  152. margin-bottom: 8px;
  153. font-size: 20px;
  154. line-height: 28px;
  155. color: rgba(29, 33, 41, 100%);
  156. opacity: 0.4;
  157. }
  158. }
  159. }
  160. .sound-record-wrapper {
  161. margin-left: 80px;
  162. }
  163. }
  164. </style>