SelectQuestion.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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. <UploadAudio
  24. v-show="isEnable(data.property.is_enable_listening)"
  25. :file-id="data.file_id_list?.[0]"
  26. @upload="upload"
  27. @deleteFile="deleteFile"
  28. />
  29. </div>
  30. <div class="content">
  31. <ul>
  32. <li v-for="(item, i) in data.option_list" :key="i" class="content-item">
  33. <span class="question-number" @dblclick="changeOptionType(data)">
  34. {{ computedQuestionNumber(i, data.option_number_show_mode) }}.
  35. </span>
  36. <div class="option-content">
  37. <span :class="['checkbox', { active: isAnswer(item.mark) }]" @click="selectAnswer(item.mark)"></span>
  38. <RichText v-model="item.content" placeholder="输入内容" :inline="true" />
  39. </div>
  40. <SvgIcon icon-class="delete" class="delete pointer" @click="deleteOption(i)" />
  41. </li>
  42. </ul>
  43. </div>
  44. <div class="footer">
  45. <span class="add-option" @click="addOption">
  46. <SvgIcon icon-class="add-circle" size="14" /> <span>增加选项</span>
  47. </span>
  48. </div>
  49. </template>
  50. <template #property>
  51. <el-form :model="data.property">
  52. <el-form-item label="题干">
  53. <el-radio
  54. v-for="{ value, label } in stemTypeList"
  55. :key="value"
  56. v-model="data.property.stem_type"
  57. :label="value"
  58. >
  59. {{ label }}
  60. </el-radio>
  61. </el-form-item>
  62. <el-form-item label="题号">
  63. <el-input v-model="data.property.question_number" />
  64. </el-form-item>
  65. <el-form-item label-width="45px">
  66. <el-radio
  67. v-for="{ value, label } in questionNumberTypeList"
  68. :key="value"
  69. v-model="data.other.question_number_type"
  70. :label="value"
  71. >
  72. {{ label }}
  73. </el-radio>
  74. </el-form-item>
  75. <el-form-item label="描述">
  76. <el-radio
  77. v-for="{ value, label } in switchOption"
  78. :key="value"
  79. v-model="data.property.is_enable_description"
  80. :label="value"
  81. >
  82. {{ label }}
  83. </el-radio>
  84. </el-form-item>
  85. <el-form-item label="选项">
  86. <el-radio
  87. v-for="{ value, label } in selectTypeList"
  88. :key="value"
  89. v-model="data.property.select_type"
  90. :label="value"
  91. @input="changeSelectType"
  92. >
  93. {{ label }}
  94. </el-radio>
  95. </el-form-item>
  96. <el-form-item label="听力">
  97. <el-radio
  98. v-for="{ value, label } in switchOption"
  99. :key="value"
  100. v-model="data.property.is_enable_listening"
  101. :label="value"
  102. >
  103. {{ label }}
  104. </el-radio>
  105. </el-form-item>
  106. <el-form-item label="分值">
  107. <el-radio
  108. v-for="{ value, label } in scoreTypeList"
  109. :key="value"
  110. v-model="data.property.score_type"
  111. :label="value"
  112. :disabled="scoreTypeList[1].value === value && data.property.select_type === selectTypeList[0].value"
  113. >
  114. {{ label }}
  115. </el-radio>
  116. </el-form-item>
  117. <el-form-item label-width="45px">
  118. <el-input v-model="data.property.score" type="number" />
  119. </el-form-item>
  120. </el-form>
  121. </template>
  122. </QuestionBase>
  123. </template>
  124. <script>
  125. import UploadAudio from '../common/UploadAudio.vue';
  126. import QuestionMixin from '../common/QuestionMixin.js';
  127. import { selectTypeList, scoreTypeList, changeOptionType } from '@/views/exercise_questions/data/common';
  128. import { getSelectData, getOption } from '@/views/exercise_questions/data/select';
  129. export default {
  130. name: 'SelectQuestion',
  131. components: {
  132. UploadAudio,
  133. },
  134. mixins: [QuestionMixin],
  135. data() {
  136. return {
  137. selectTypeList,
  138. changeOptionType,
  139. data: getSelectData(),
  140. };
  141. },
  142. methods: {
  143. /**
  144. * 智能识别
  145. * @param {String} text 识别数据
  146. */
  147. recognition(text) {
  148. let arr = text
  149. .split(/[\r\n]/)
  150. .map((item) => item.trim())
  151. .filter((item) => item);
  152. if (arr.length > 0) {
  153. this.data.stem = arr[0];
  154. this.data.option_list = arr.slice(1).map((content) => getOption(content));
  155. }
  156. },
  157. changeSelectType(val) {
  158. if (val === selectTypeList[0].value && this.data.answer.answer_list.length > 1) {
  159. this.data.answer.answer_list = [this.data.answer.answer_list[0]];
  160. }
  161. // 当多选题切换到单选题时,分值类型切换为总分
  162. if (val === selectTypeList[0].value && this.data.property.score_type === scoreTypeList[1].value) {
  163. this.data.property.score_type = scoreTypeList[0].value;
  164. }
  165. },
  166. isAnswer(mark) {
  167. return this.data.answer.answer_list.indexOf(mark) !== -1;
  168. },
  169. selectAnswer(mark) {
  170. let index = this.data.answer.answer_list.indexOf(mark);
  171. if (this.data.property.select_type === selectTypeList[0].value) {
  172. this.data.answer.answer_list = [mark];
  173. }
  174. if (this.data.property.select_type === selectTypeList[1].value) {
  175. if (index === -1) {
  176. this.data.answer.answer_list.push(mark);
  177. } else {
  178. this.data.answer.answer_list.splice(index, 1);
  179. }
  180. }
  181. },
  182. addOption() {
  183. this.data.option_list.push(getOption());
  184. },
  185. },
  186. };
  187. </script>
  188. <style lang="scss" scoped>
  189. .content {
  190. .option-content {
  191. .checkbox {
  192. display: inline-flex;
  193. align-items: center;
  194. justify-content: center;
  195. width: 16px;
  196. height: 16px;
  197. margin-right: 8px;
  198. cursor: pointer;
  199. border: 1px solid #333;
  200. border-radius: 50%;
  201. &.active {
  202. &::before {
  203. display: inline-block;
  204. width: 6px;
  205. height: 6px;
  206. content: '';
  207. background-color: #333;
  208. border-radius: 50%;
  209. }
  210. }
  211. }
  212. }
  213. }
  214. </style>