TalkPictureQuestion.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <template>
  2. <QuestionBase>
  3. <template #content>
  4. <div class="stem">
  5. <RichText v-model="data.stem" placeholder="输入题干" />
  6. <el-input
  7. v-show="isEnable(data.property.is_enable_description)"
  8. v-model="data.description"
  9. rows="3"
  10. resize="none"
  11. type="textarea"
  12. placeholder="输入描述"
  13. />
  14. </div>
  15. <div class="content">
  16. <div v-for="(item, index) in data.option_list" :key="index" class="content-item">
  17. <template v-if="pic_list[item.picture_file_id]">
  18. <div class="item-left">
  19. <el-image
  20. style="width: 72px; height: 72px"
  21. :src="pic_list[item.picture_file_id]"
  22. :preview-src-list="[pic_list[item.picture_file_id]]"
  23. fit="contain"
  24. />
  25. <button class="delete-btn" @click="delectOptions(index, item.picture_file_id)">
  26. <i class="el-icon-delete"></i>删除
  27. </button>
  28. </div>
  29. <div class="item-right">
  30. <div class="item-rich">
  31. <label class="">图片标题</label>
  32. <RichText v-model="item.picture_title" placeholder="输入图片标题" />
  33. </div>
  34. <div class="item-rich">
  35. <label class="">图片信息</label>
  36. <RichText v-model="item.picture_info" placeholder="输入图片信息" />
  37. </div>
  38. <div v-if="isEnable(data.property.is_enable_reference_answer)" class="item-rich">
  39. <label class="">参考答案</label>
  40. <RichText v-model="item.reference_answer" placeholder="输入参考答案" />
  41. </div>
  42. </div>
  43. </template>
  44. </div>
  45. <UploadDrag ref="uploadDrag" :limit="999" @fileUploadSuccess="fileUploadSuccess" />
  46. </div>
  47. </template>
  48. <template #property>
  49. <el-form :model="data.property">
  50. <el-form-item label="题号">
  51. <el-input v-model="data.property.question_number" />
  52. </el-form-item>
  53. <el-form-item label-width="45px">
  54. <el-radio
  55. v-for="{ value, label } in questionNumberTypeList"
  56. :key="value"
  57. v-model="data.other.question_number_type"
  58. :label="value"
  59. >
  60. {{ label }}
  61. </el-radio>
  62. </el-form-item>
  63. <el-form-item label="描述">
  64. <el-radio
  65. v-for="{ value, label } in switchOption"
  66. :key="value"
  67. v-model="data.property.is_enable_description"
  68. :label="value"
  69. >
  70. {{ label }}
  71. </el-radio>
  72. </el-form-item>
  73. <el-form-item label="分值">
  74. <el-radio
  75. v-for="{ value, label } in scoreTypeList"
  76. :key="value"
  77. v-model="data.property.score_type"
  78. :label="value"
  79. >
  80. {{ label }}
  81. </el-radio>
  82. </el-form-item>
  83. <el-form-item label-width="45px">
  84. <el-input-number
  85. v-model="data.property.score"
  86. :min="0"
  87. :step="data.property.score_type === scoreTypeList[0].value ? 1 : 0.1"
  88. />
  89. </el-form-item>
  90. <el-form-item label="语音作答">
  91. <el-radio
  92. v-for="{ value, label } in switchOption"
  93. :key="value"
  94. v-model="data.property.is_enable_voice_answer"
  95. :label="value"
  96. >
  97. {{ label }}
  98. </el-radio>
  99. </el-form-item>
  100. <el-form-item label="参考答案">
  101. <el-radio
  102. v-for="{ value, label } in switchOption"
  103. :key="value"
  104. v-model="data.property.is_enable_reference_answer"
  105. :label="value"
  106. >
  107. {{ label }}
  108. </el-radio>
  109. </el-form-item>
  110. </el-form>
  111. </template>
  112. </QuestionBase>
  113. </template>
  114. <script>
  115. import QuestionMixin from '../common/QuestionMixin.js';
  116. import { talkPictrueData, getOption } from '@/views/exercise_questions/data/talkPicture';
  117. import { GetFileStoreInfo } from '@/api/app';
  118. import UploadDrag from '../common/UploadDrag.vue';
  119. export default {
  120. name: 'TalkPicture',
  121. components: { UploadDrag },
  122. mixins: [QuestionMixin],
  123. data() {
  124. return {
  125. data: JSON.parse(JSON.stringify(talkPictrueData)),
  126. pic_list: {},
  127. is_first: true,
  128. };
  129. },
  130. watch: {
  131. 'data.file_id_list': {
  132. handler() {
  133. if (this.is_first) {
  134. this.handleData();
  135. }
  136. },
  137. deep: true,
  138. },
  139. },
  140. created() {},
  141. mounted() {},
  142. methods: {
  143. // 初始化数据
  144. handleData() {
  145. this.data.file_id_list.forEach((item) => {
  146. GetFileStoreInfo({ file_id: item }).then(({ file_id, file_url }) => {
  147. this.$set(this.pic_list, file_id, file_url);
  148. });
  149. });
  150. this.is_first = false;
  151. },
  152. // 删除
  153. delectOptions(i, id) {
  154. this.$confirm('是否删除该条全部信息?', '提示', {
  155. confirmButtonText: '确定',
  156. cancelButtonText: '取消',
  157. type: 'warning',
  158. })
  159. .then(() => {
  160. delete this.pic_list[id];
  161. this.data.file_id_list.splice(this.data.file_id_list.indexOf(id), 1);
  162. this.data.option_list.splice(i, 1);
  163. this.$refs.uploadDrag.clearFiles();
  164. })
  165. .catch(() => {});
  166. },
  167. fileUploadSuccess(file_id, file_url) {
  168. this.data.file_id_list.push(file_id);
  169. this.data.option_list.push(getOption());
  170. this.data.option_list[this.data.option_list.length - 1].picture_file_id = file_id;
  171. this.$set(this.pic_list, file_id, file_url);
  172. },
  173. },
  174. };
  175. </script>
  176. <style lang="scss" scoped>
  177. .content {
  178. :deep .el-upload {
  179. width: 100%;
  180. &-dragger {
  181. display: flex;
  182. flex-direction: column;
  183. align-items: center;
  184. justify-content: center;
  185. width: 100%;
  186. height: 90px;
  187. font-size: 14px;
  188. :first-child {
  189. color: #000;
  190. }
  191. :last-child {
  192. color: $text-color;
  193. }
  194. }
  195. }
  196. .content-item {
  197. display: flex;
  198. column-gap: 8px;
  199. margin-bottom: 24px;
  200. }
  201. .delete-btn {
  202. width: 100%;
  203. padding: 5px 8px;
  204. font-size: 14px;
  205. line-height: 22px;
  206. color: #f53f3f;
  207. background: #fff4f4;
  208. border: none;
  209. border-radius: 4px;
  210. .el-icon-delete {
  211. margin-right: 8px;
  212. }
  213. &:hover {
  214. color: #f53f3f;
  215. }
  216. &:focus {
  217. outline: none;
  218. }
  219. }
  220. .item-left {
  221. width: 72px;
  222. }
  223. .item-right {
  224. flex: 1;
  225. .item-rich {
  226. display: flex;
  227. > label {
  228. flex-shrink: 0;
  229. width: 64px;
  230. font-size: 14px;
  231. line-height: 32px;
  232. color: #4e5969;
  233. }
  234. }
  235. }
  236. }
  237. </style>