TalkPictureQuestion.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. <template>
  2. <QuestionBase>
  3. <template #content>
  4. <div class="stem">
  5. <el-input
  6. v-if="data.property.stem_type === stemTypeList[0].value"
  7. v-model="data.stem"
  8. rows="3"
  9. resize="none"
  10. type="textarea"
  11. placeholder="输入题干"
  12. />
  13. <RichText v-if="data.property.stem_type === stemTypeList[1].value" v-model="data.stem" placeholder="输入题干" />
  14. <el-input
  15. v-show="isEnable(data.property.is_enable_description)"
  16. v-model="data.description"
  17. rows="3"
  18. resize="none"
  19. type="textarea"
  20. placeholder="输入描述"
  21. />
  22. </div>
  23. <div class="content">
  24. <div v-for="(item, index) in data.option_list" :key="index" class="content-item">
  25. <template v-if="pic_list[item.picture_file_id]">
  26. <div class="item-left">
  27. <el-image
  28. style="width: 72px; height: 72px"
  29. :src="pic_list[item.picture_file_id]"
  30. :preview-src-list="[pic_list[item.picture_file_id]]"
  31. fit="contain"
  32. />
  33. <el-button type="danger" plain @click="delectOption(index, item.picture_file_id)"
  34. ><i class="el-icon-delete"></i>删除</el-button
  35. >
  36. </div>
  37. <div class="item-right">
  38. <div class="item-rich">
  39. <label class="">图片标题</label>
  40. <RichText v-model="item.picture_title" placeholder="输入图片标题" />
  41. </div>
  42. <div class="item-rich">
  43. <label class="">图片信息</label>
  44. <RichText v-model="item.picture_info" placeholder="输入图片信息" />
  45. </div>
  46. <div v-if="isEnable(data.property.is_enable_reference_answer)" class="item-rich">
  47. <label class="">参考答案</label>
  48. <RichText v-model="item.reference_answer" placeholder="输入参考答案" />
  49. </div>
  50. </div>
  51. </template>
  52. </div>
  53. <el-upload
  54. ref="upload"
  55. action="no"
  56. accept=".jpg,.png,.gif"
  57. drag
  58. :show-file-list="false"
  59. :before-upload="beforeUpload"
  60. :http-request="upload"
  61. :on-exceed="handleExceed"
  62. >
  63. <div>点击或拖拽图片到此上传</div>
  64. <div>只有 jpg, png, gif 等格式文件可以上传,文件大小不得超过 5MB</div>
  65. </el-upload>
  66. </div>
  67. </template>
  68. <template #property>
  69. <el-form :model="data.property">
  70. <el-form-item label="题干">
  71. <el-radio
  72. v-for="{ value, label } in stemTypeList"
  73. :key="value"
  74. v-model="data.property.stem_type"
  75. :label="value"
  76. >
  77. {{ label }}
  78. </el-radio>
  79. </el-form-item>
  80. <el-form-item label="题号">
  81. <el-input v-model="data.property.question_number" />
  82. </el-form-item>
  83. <el-form-item label-width="45px">
  84. <el-radio
  85. v-for="{ value, label } in questionNumberTypeList"
  86. :key="value"
  87. v-model="data.other.question_number_type"
  88. :label="value"
  89. >
  90. {{ label }}
  91. </el-radio>
  92. </el-form-item>
  93. <el-form-item label="描述">
  94. <el-radio
  95. v-for="{ value, label } in switchOption"
  96. :key="value"
  97. v-model="data.property.is_enable_description"
  98. :label="value"
  99. >
  100. {{ label }}
  101. </el-radio>
  102. </el-form-item>
  103. <el-form-item label="分值">
  104. <el-radio
  105. v-for="{ value, label } in scoreTypeList"
  106. :key="value"
  107. v-model="data.property.score_type"
  108. :label="value"
  109. >
  110. {{ label }}
  111. </el-radio>
  112. </el-form-item>
  113. <el-form-item label-width="45px">
  114. <el-input v-model="data.property.score" type="number" />
  115. </el-form-item>
  116. <el-form-item label="语音作答">
  117. <el-radio
  118. v-for="{ value, label } in switchOption"
  119. :key="value"
  120. v-model="data.property.is_enable_voice_answer"
  121. :label="value"
  122. >
  123. {{ label }}
  124. </el-radio>
  125. </el-form-item>
  126. <el-form-item label="参考答案">
  127. <el-radio
  128. v-for="{ value, label } in switchOption"
  129. :key="value"
  130. v-model="data.property.is_enable_reference_answer"
  131. :label="value"
  132. >
  133. {{ label }}
  134. </el-radio>
  135. </el-form-item>
  136. </el-form>
  137. </template>
  138. </QuestionBase>
  139. </template>
  140. <script>
  141. import QuestionMixin from '../common/QuestionMixin.js';
  142. import { talkPictrueData, getOption } from '@/views/exercise_questions/data/talkPicture';
  143. import { fileUpload, GetFileStoreInfo } from '@/api/app';
  144. export default {
  145. name: 'TalkPicture',
  146. mixins: [QuestionMixin],
  147. data() {
  148. return {
  149. data: JSON.parse(JSON.stringify(talkPictrueData)),
  150. pic_list: {},
  151. is_first: true,
  152. };
  153. },
  154. watch: {
  155. 'data.file_id_list': {
  156. handler() {
  157. if (this.is_first) {
  158. this.handleData();
  159. }
  160. },
  161. deep: true,
  162. },
  163. },
  164. created() {},
  165. mounted() {},
  166. methods: {
  167. // 初始化数据
  168. handleData() {
  169. this.data.file_id_list.forEach((item) => {
  170. GetFileStoreInfo({ file_id: item }).then(({ file_id, file_url }) => {
  171. this.$set(this.pic_list, file_id, file_url);
  172. });
  173. });
  174. this.is_first = false;
  175. },
  176. // 删除
  177. delectOption(i, id) {
  178. this.$confirm('是否删除该条全部信息?', '提示', {
  179. confirmButtonText: '确定',
  180. cancelButtonText: '取消',
  181. type: 'warning',
  182. })
  183. .then(() => {
  184. delete this.pic_list[id];
  185. this.data.file_id_list.splice(this.data.file_id_list.indexOf(id), 1);
  186. this.data.option_list.splice(i, 1);
  187. console.log(this.data);
  188. })
  189. .catch(() => {});
  190. },
  191. beforeUpload(file) {
  192. // 可以用来限制文件大小
  193. },
  194. upload(file) {
  195. fileUpload('Mid', file).then(({ file_info_list }) => {
  196. if (file_info_list.length > 0) {
  197. const { file_id, file_url } = file_info_list[0];
  198. this.data.file_id_list.push(file_id);
  199. this.data.option_list.push(getOption());
  200. this.data.option_list[this.data.option_list.length - 1].picture_file_id = file_id;
  201. this.$set(this.pic_list, file_id, file_url);
  202. }
  203. });
  204. },
  205. handleExceed(files, fileList) {
  206. this.$message.warning(
  207. `当前限制选择 ${this.filleNumber ? this.filleNumber : 1} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
  208. files.length + fileList.length
  209. } 个文件`,
  210. );
  211. },
  212. },
  213. };
  214. </script>
  215. <style lang="scss" scoped>
  216. .content {
  217. :deep .el-upload {
  218. width: 100%;
  219. &-dragger {
  220. display: flex;
  221. flex-direction: column;
  222. align-items: center;
  223. justify-content: center;
  224. width: 100%;
  225. height: 90px;
  226. font-size: 14px;
  227. :first-child {
  228. color: #000;
  229. }
  230. :last-child {
  231. color: $text-color;
  232. }
  233. }
  234. }
  235. .content-item {
  236. display: flex;
  237. column-gap: 8px;
  238. margin-bottom: 24px;
  239. }
  240. .item-left {
  241. width: 72px;
  242. }
  243. .item-right {
  244. flex: 1;
  245. .item-rich {
  246. display: flex;
  247. > label {
  248. flex-shrink: 0;
  249. width: 64px;
  250. font-size: 14px;
  251. line-height: 32px;
  252. color: #4e5969;
  253. }
  254. }
  255. }
  256. }
  257. </style>