RepeatQuestion.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <!-- 听读训练 -->
  2. <template>
  3. <QuestionBase>
  4. <template #content>
  5. <div class="stem">
  6. <el-input
  7. v-if="data.property.stem_type === stemTypeList[0].value"
  8. v-model="data.stem"
  9. rows="3"
  10. resize="none"
  11. type="textarea"
  12. placeholder="输入题干"
  13. />
  14. <RichText v-if="data.property.stem_type === stemTypeList[1].value" v-model="data.stem" placeholder="输入题干" />
  15. <el-input
  16. v-show="isEnable(data.property.is_enable_description)"
  17. v-model="data.description"
  18. rows="3"
  19. resize="none"
  20. type="textarea"
  21. placeholder="输入描述"
  22. />
  23. </div>
  24. <div class="content">
  25. <label class="title-little">内容</label>
  26. <ul>
  27. <li v-for="(item, i) in data.option_list" :key="i" class="content-item repeat-option">
  28. <span class="question-number" @dblclick="changeOptionType(data)">
  29. {{ computedQuestionNumber(i, data.option_number_show_mode) }}.
  30. </span>
  31. <div class="option-content">
  32. <RichText v-model="item.content" placeholder="输入内容" :inline="true" />
  33. </div>
  34. <UploadAudio
  35. :key="item.audio_file_id || i"
  36. :file-id="item.audio_file_id"
  37. :item-index="i"
  38. @upload="uploads"
  39. @deleteFile="deleteFiles"
  40. />
  41. <SvgIcon icon-class="delete" class="delete pointer" @click="deleteOption(i, item.audio_file_id)" />
  42. </li>
  43. </ul>
  44. </div>
  45. <div class="footer">
  46. <span class="add-option" @click="addOption">
  47. <SvgIcon icon-class="add-circle" size="14" /> <span>增加选项</span>
  48. </span>
  49. </div>
  50. </template>
  51. <template #property>
  52. <el-form :model="data.property">
  53. <el-form-item label="题干">
  54. <el-radio
  55. v-for="{ value, label } in stemTypeList"
  56. :key="value"
  57. v-model="data.property.stem_type"
  58. :label="value"
  59. >
  60. {{ label }}
  61. </el-radio>
  62. </el-form-item>
  63. <el-form-item label="题号">
  64. <el-input v-model="data.property.question_number" />
  65. </el-form-item>
  66. <el-form-item label-width="45px">
  67. <el-radio
  68. v-for="{ value, label } in questionNumberTypeList"
  69. :key="value"
  70. v-model="data.other.question_number_type"
  71. :label="value"
  72. >
  73. {{ label }}
  74. </el-radio>
  75. </el-form-item>
  76. <el-form-item label="描述">
  77. <el-radio
  78. v-for="{ value, label } in switchOption"
  79. :key="value"
  80. v-model="data.property.is_enable_description"
  81. :label="value"
  82. >
  83. {{ label }}
  84. </el-radio>
  85. </el-form-item>
  86. <el-form-item label="分值">
  87. <el-radio
  88. v-for="{ value, label } in scoreTypeList"
  89. :key="value"
  90. v-model="data.property.score_type"
  91. :label="value"
  92. >
  93. {{ label }}
  94. </el-radio>
  95. </el-form-item>
  96. <el-form-item label-width="45px">
  97. <el-input v-model="data.property.score" type="number" />
  98. </el-form-item>
  99. </el-form>
  100. </template>
  101. </QuestionBase>
  102. </template>
  103. <script>
  104. import UploadAudio from '../common/UploadAudio.vue';
  105. import QuestionMixin from '../common/QuestionMixin.js';
  106. import { selectTypeList, changeOptionType } from '@/views/exercise_questions/data/common';
  107. import { repeatData, getOption } from '@/views/exercise_questions/data/repeat';
  108. export default {
  109. name: 'RepeatQuestion',
  110. components: {
  111. UploadAudio,
  112. },
  113. mixins: [QuestionMixin],
  114. data() {
  115. return {
  116. selectTypeList,
  117. changeOptionType,
  118. data: JSON.parse(JSON.stringify(repeatData)),
  119. };
  120. },
  121. methods: {
  122. /**
  123. * 智能识别
  124. * @param {String} text 识别数据
  125. */
  126. recognition(text) {
  127. let arr = text
  128. .split(/[\r\n]/)
  129. .map((item) => item.trim())
  130. .filter((item) => item);
  131. if (arr.length > 0) {
  132. this.data.stem = arr[0];
  133. this.data.option_list = arr.slice(1).map((content) => getOption(content));
  134. }
  135. },
  136. addOption() {
  137. this.data.option_list.push(getOption());
  138. },
  139. uploads(file_id, index) {
  140. this.data.option_list[index].audio_file_id = file_id;
  141. this.data.file_id_list.push(file_id);
  142. },
  143. deleteFiles(file_id, itemIndex) {
  144. this.data.option_list[itemIndex].audio_file_id = '';
  145. this.data.file_id_list.splice(this.data.file_id_list.indexOf(file_id), 1);
  146. },
  147. // 删除小题
  148. deleteOption(i, file_id) {
  149. this.data.option_list.splice(i, 1);
  150. this.data.file_id_list.splice(this.data.file_id_list.indexOf(file_id), 1);
  151. },
  152. },
  153. };
  154. </script>
  155. <style lang="scss" scoped>
  156. .repeat-option {
  157. :deep .upload-wrapper {
  158. margin-top: 0;
  159. }
  160. :deep .file-name {
  161. width: 140px;
  162. overflow: hidden;
  163. text-overflow: ellipsis;
  164. white-space: nowrap;
  165. }
  166. }
  167. </style>