WritePictruePreview.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. <!-- eslint-disable vue/no-v-html -->
  2. <template>
  3. <div v-if="show_preview" class="writepicture-preview">
  4. <div class="stem">
  5. <span class="question-number" :style="{ fontSize: data.property.stem_question_number_font_size }">
  6. {{ questionNumberEndIsBracket(data.property.question_number) }}
  7. </span>
  8. <span v-html="sanitizeHTML(data.stem)"></span>
  9. </div>
  10. <div
  11. v-if="isEnable(data.property.is_enable_description)"
  12. class="description rich-text"
  13. v-html="sanitizeHTML(data.description)"
  14. ></div>
  15. <div class="content">
  16. <div v-for="(item, index) in data.option_list" :key="index" class="content-item">
  17. <!-- <el-image
  18. v-if="pic_list[item.picture_file_id]"
  19. style="width: 370px; height: 238px"
  20. :src="pic_list[item.picture_file_id]"
  21. fit="contain"
  22. /> -->
  23. <div class="img-box">
  24. <img
  25. v-if="pic_list[item.picture_file_id]"
  26. :src="pic_list[item.picture_file_id]"
  27. style="max-width: 370px; max-height: 238px"
  28. />
  29. </div>
  30. <p class="pic-info rich-text" v-html="sanitizeHTML(item.picture_info)"></p>
  31. </div>
  32. </div>
  33. <div v-if="answer.answer_list[active_index]" class="content-right">
  34. <el-input
  35. v-model="answer.answer_list[active_index].text"
  36. class="write-input"
  37. rows="12"
  38. resize="none"
  39. type="textarea"
  40. placeholder="请输入"
  41. :maxlength="data.property.word_num"
  42. show-word-limit
  43. :readonly="disabled"
  44. :autosize="{ minRows: 5 }"
  45. @input="handleInput"
  46. />
  47. </div>
  48. <template v-if="isEnable(data.property.is_enable_upload_accessory)">
  49. <!-- 上传附件 -->
  50. <UploadFiles
  51. v-if="answer.answer_list[active_index]"
  52. :disabled="disabled"
  53. :fille-number="999"
  54. file-type-name="文件"
  55. :upload-type="'*'"
  56. :file-id-list="answer.answer_list[active_index].accessory_file_id"
  57. @upload="handleUpload"
  58. @deleteFile="handleDelete"
  59. />
  60. </template>
  61. <template v-if="isEnable(data.property.is_enable_sample_text) && isShowRightAnswer">
  62. <el-divider content-position="center"
  63. ><span
  64. :class="['sample-text', show_sample_text ? 'sample-show' : 'sample-hide']"
  65. @click="show_sample_text = !show_sample_text"
  66. >{{ show_sample_text ? '隐藏范文' : '查看范文' }}</span
  67. ></el-divider
  68. >
  69. <div v-if="show_sample_text" class="article-content rich-text" v-html="sanitizeHTML(data.sample_text)"></div>
  70. </template>
  71. </div>
  72. </template>
  73. <script>
  74. import PreviewMixin from './components/PreviewMixin';
  75. import { GetFileStoreInfo } from '@/api/app';
  76. import UploadFiles from './components/common/UploadFiles.vue';
  77. export default {
  78. name: 'WritePicturePreview',
  79. components: {
  80. UploadFiles,
  81. },
  82. mixins: [PreviewMixin],
  83. data() {
  84. return {
  85. show_sample_text: false,
  86. pic_list: {},
  87. active_index: 0,
  88. show_preview: false,
  89. };
  90. },
  91. watch: {
  92. data: {
  93. handler(val) {
  94. if (!val || this.data.type !== 'write_picture') return;
  95. this.handleData();
  96. },
  97. deep: true,
  98. immediate: true,
  99. },
  100. },
  101. methods: {
  102. // 初始化数据
  103. handleData() {
  104. this.show_preview = true;
  105. this.pic_list = {};
  106. this.active_index = 0;
  107. this.data.file_id_list.forEach((item) => {
  108. GetFileStoreInfo({ file_id: item }).then(({ file_id, file_url }) => {
  109. this.$set(this.pic_list, file_id, file_url);
  110. });
  111. });
  112. if (!this.isJudgingRightWrong) {
  113. let obj = {
  114. text: '',
  115. accessory_file_id: [], // 上传文件列表
  116. };
  117. this.answer.answer_list.push(obj);
  118. }
  119. },
  120. changeImg(index) {
  121. this.active_index = index;
  122. },
  123. // 文件上传成功
  124. handleUpload(fileId) {
  125. this.answer.answer_list[this.active_index].accessory_file_id.push(fileId);
  126. },
  127. // 删除文件
  128. handleDelete(fileId) {
  129. this.answer.answer_list[this.active_index].accessory_file_id.splice(
  130. this.answer.answer_list[this.active_index].accessory_file_id.indexOf(fileId),
  131. 1,
  132. );
  133. },
  134. handleInput(value) {
  135. if (value.length >= this.data.property.word_num) {
  136. this.$message.warning(`字数达到${value.length}字!`);
  137. }
  138. },
  139. },
  140. };
  141. </script>
  142. <style lang="scss" scoped>
  143. @use '@/styles/mixin.scss' as *;
  144. .writepicture-preview {
  145. @include preview;
  146. :deep p {
  147. margin: 0;
  148. }
  149. .content {
  150. display: flex;
  151. column-gap: 8px;
  152. width: 100%;
  153. padding-bottom: 24px;
  154. overflow: auto;
  155. .img-box {
  156. display: flex;
  157. align-items: center;
  158. justify-content: center;
  159. height: 238px;
  160. }
  161. .pic-title {
  162. margin: 8px 0 4px;
  163. font-size: 12px;
  164. font-weight: 600;
  165. line-height: 20px;
  166. color: #000;
  167. word-break: break-word;
  168. }
  169. .pic-info {
  170. margin: 0;
  171. font-size: 12px;
  172. font-weight: 400;
  173. line-height: 20px;
  174. color: #000;
  175. word-break: break-word;
  176. }
  177. }
  178. .reference-box {
  179. padding: 12px;
  180. background: #f9f8f9;
  181. .reference-title {
  182. margin: 0 0 10px;
  183. font-size: 14px;
  184. font-weight: 400;
  185. line-height: 32px;
  186. color: #4e5969;
  187. }
  188. }
  189. .el-divider--horizontal {
  190. margin: 12px 0;
  191. }
  192. .sample-text {
  193. font-size: 14px;
  194. font-weight: 400;
  195. line-height: 30px;
  196. color: #000;
  197. cursor: pointer;
  198. &.sample-show {
  199. color: $light-main-color;
  200. }
  201. }
  202. .article-content,
  203. .description {
  204. :deep p {
  205. margin: 0;
  206. }
  207. }
  208. .write-input {
  209. font-size: 16px;
  210. }
  211. :deep .el-textarea .el-textarea__inner {
  212. padding-bottom: 25px;
  213. }
  214. :deep .el-textarea .el-input__count {
  215. bottom: 5px;
  216. font-size: 14px;
  217. background-color: #f2f3f5;
  218. }
  219. }
  220. /* 横向滚动条 */
  221. ::-webkit-scrollbar {
  222. height: 5px;
  223. background-color: #f5f5f5;
  224. }
  225. /* 横向滚动条滑块 */
  226. ::-webkit-scrollbar-thumb {
  227. background-color: #ccc;
  228. border-radius: 2px;
  229. }
  230. /* 鼠标悬停在滚动条上的滑块 */
  231. ::-webkit-scrollbar-thumb:hover {
  232. background-color: #555;
  233. }
  234. </style>