WritePictruePreview.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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. :class="[active_index !== index ? 'not-active' : '']"
  23. @click="active_index = index"
  24. />
  25. <h3 class="pic-title rich-text" v-html="sanitizeHTML(item.picture_title)"></h3>
  26. <p class="pic-info rich-text" v-html="sanitizeHTML(item.picture_info)"></p>
  27. </div>
  28. </div>
  29. <div v-if="answer.answer_list[active_index]" class="content-right">
  30. <el-input
  31. class="write-input"
  32. v-model="answer.answer_list[active_index].text"
  33. rows="12"
  34. resize="none"
  35. type="textarea"
  36. placeholder="请输入"
  37. :maxlength="data.property.word_num"
  38. show-word-limit
  39. :readonly="disabled"
  40. @input="handleInput"
  41. />
  42. </div>
  43. <template v-if="isEnable(data.property.is_enable_upload_accessory)">
  44. <!-- 上传附件 -->
  45. <UploadFiles
  46. v-if="answer.answer_list[active_index]"
  47. :disabled="disabled"
  48. :fille-number="999"
  49. file-type-name="文件"
  50. :upload-type="'*'"
  51. :file-id-list="answer.answer_list[active_index].accessory_file_id"
  52. @upload="handleUpload"
  53. @deleteFile="handleDelete"
  54. />
  55. </template>
  56. <template v-if="isEnable(data.property.is_enable_sample_text) && isShowRightAnswer">
  57. <el-divider content-position="center"
  58. ><span
  59. :class="['sample-text', show_sample_text ? 'sample-show' : 'sample-hide']"
  60. @click="show_sample_text = !show_sample_text"
  61. >{{ show_sample_text ? '隐藏范文' : '查看范文' }}</span
  62. ></el-divider
  63. >
  64. <div v-if="show_sample_text" class="article-content rich-text" v-html="sanitizeHTML(data.sample_text)"></div>
  65. </template>
  66. </div>
  67. </template>
  68. <script>
  69. import PreviewMixin from './components/PreviewMixin';
  70. import { GetFileStoreInfo } from '@/api/app';
  71. import UploadFiles from './components/common/UploadFiles.vue';
  72. export default {
  73. name: 'WritePicturePreview',
  74. components: {
  75. UploadFiles,
  76. },
  77. mixins: [PreviewMixin],
  78. data() {
  79. return {
  80. show_sample_text: false,
  81. pic_list: {},
  82. active_index: 0,
  83. show_preview: false,
  84. };
  85. },
  86. watch: {
  87. data: {
  88. handler(val) {
  89. if (!val || this.data.type !== 'write_picture') return;
  90. this.handleData();
  91. },
  92. deep: true,
  93. immediate: true,
  94. },
  95. },
  96. created() {
  97. // this.handleData();
  98. },
  99. methods: {
  100. // 初始化数据
  101. handleData() {
  102. this.show_preview = true;
  103. this.pic_list = {};
  104. this.active_index = 0;
  105. this.data.file_id_list.forEach((item) => {
  106. GetFileStoreInfo({ file_id: item }).then(({ file_id, file_url }) => {
  107. this.$set(this.pic_list, file_id, file_url);
  108. });
  109. });
  110. if (!this.isJudgingRightWrong) {
  111. this.data.option_list.forEach((item) => {
  112. let obj = {
  113. mark: item.mark,
  114. text: '',
  115. accessory_file_id: [], // 上传文件列表
  116. };
  117. this.answer.answer_list.push(obj);
  118. });
  119. }
  120. },
  121. changeImg(index) {
  122. this.active_index = index;
  123. },
  124. // 文件上传成功
  125. handleUpload(fileId) {
  126. this.answer.answer_list[this.active_index].accessory_file_id.push(fileId);
  127. },
  128. // 删除文件
  129. handleDelete(fileId) {
  130. this.answer.answer_list[this.active_index].accessory_file_id.splice(
  131. this.answer.answer_list[this.active_index].accessory_file_id.indexOf(fileId),
  132. 1,
  133. );
  134. },
  135. handleInput(value) {
  136. if (value.length >= this.data.property.word_num) {
  137. this.$message.warning(`字数达到${value.length}字!`);
  138. }
  139. },
  140. },
  141. };
  142. </script>
  143. <style lang="scss" scoped>
  144. @use '@/styles/mixin.scss' as *;
  145. .writepicture-preview {
  146. @include preview;
  147. :deep p {
  148. margin: 0;
  149. }
  150. .content {
  151. display: flex;
  152. column-gap: 8px;
  153. width: 100%;
  154. overflow: auto;
  155. .el-image {
  156. cursor: pointer;
  157. &.not-active {
  158. opacity: 0.2;
  159. }
  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-input__count {
  212. bottom: 5px;
  213. font-size: 14px;
  214. background-color: #f2f3f5;
  215. }
  216. }
  217. </style>