WritePictruePreview.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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">{{ data.property.question_number }}.</span>
  6. <span v-html="sanitizeHTML(data.stem)"></span>
  7. </div>
  8. <div class="article-content rich-text" v-html="sanitizeHTML(data.article)"></div>
  9. <div
  10. v-if="isEnable(data.property.is_enable_description)"
  11. class="description rich-text"
  12. v-html="sanitizeHTML(data.description)"
  13. ></div>
  14. <div class="content">
  15. <div v-for="(item, index) in data.option_list" :key="index" class="content-item">
  16. <el-image
  17. v-if="pic_list[item.picture_file_id]"
  18. style="width: 370px; height: 238px"
  19. :src="pic_list[item.picture_file_id]"
  20. fit="cover"
  21. :class="[active_index !== index ? 'not-active' : '']"
  22. @click="active_index = index"
  23. />
  24. <h3 class="pic-title rich-text" v-html="sanitizeHTML(item.picture_title)"></h3>
  25. <p class="pic-info rich-text" v-html="sanitizeHTML(item.picture_info)"></p>
  26. </div>
  27. </div>
  28. <div v-if="answer.answer_list[active_index]" class="content-right">
  29. <el-input
  30. v-model="answer.answer_list[active_index].text"
  31. rows="12"
  32. resize="none"
  33. type="textarea"
  34. placeholder="请输入"
  35. :maxlength="data.property.word_num"
  36. show-word-limit
  37. :readonly="disabled"
  38. @input="handleInput"
  39. />
  40. </div>
  41. <template v-if="isEnable(data.property.is_enable_upload_accessory)">
  42. <!-- 上传附件 -->
  43. <UploadFiles
  44. v-if="answer.answer_list[active_index]"
  45. :disabled="disabled"
  46. :fille-number="999"
  47. file-type-name="文件"
  48. :upload-type="'*'"
  49. :file-id-list="answer.answer_list[active_index].accessory_file_id"
  50. upload-title="上传附件:"
  51. @upload="handleUpload"
  52. @deleteFile="handleDelete"
  53. />
  54. </template>
  55. <template v-if="isEnable(data.property.is_enable_sample_text) && isShowRightAnswer">
  56. <el-divider content-position="center"
  57. ><span
  58. :class="['sample-text', show_sample_text ? 'sample-show' : 'sample-hide']"
  59. @click="show_sample_text = !show_sample_text"
  60. >{{ show_sample_text ? '隐藏范文' : '查看范文' }}</span
  61. ></el-divider
  62. >
  63. <div v-if="show_sample_text" class="article-content rich-text" v-html="sanitizeHTML(data.sample_text)"></div>
  64. </template>
  65. </div>
  66. </template>
  67. <script>
  68. import PreviewMixin from './components/PreviewMixin';
  69. import { GetFileStoreInfo } from '@/api/app';
  70. import UploadFiles from './components/common/UploadFiles.vue';
  71. export default {
  72. name: 'WritePicturePreview',
  73. components: {
  74. UploadFiles,
  75. },
  76. mixins: [PreviewMixin],
  77. data() {
  78. return {
  79. show_sample_text: false,
  80. pic_list: {},
  81. active_index: 0,
  82. show_preview: false,
  83. };
  84. },
  85. watch: {
  86. data: {
  87. handler(val) {
  88. if (!val || this.data.type !== 'write_picture') return;
  89. this.handleData();
  90. },
  91. deep: true,
  92. immediate: true,
  93. },
  94. },
  95. created() {
  96. // this.handleData();
  97. },
  98. methods: {
  99. // 初始化数据
  100. handleData() {
  101. this.show_preview = true;
  102. this.pic_list = {};
  103. this.active_index = 0;
  104. this.data.file_id_list.forEach((item) => {
  105. GetFileStoreInfo({ file_id: item }).then(({ file_id, file_url }) => {
  106. this.$set(this.pic_list, file_id, file_url);
  107. });
  108. });
  109. if (!this.isJudgingRightWrong) {
  110. this.data.option_list.forEach((item) => {
  111. let obj = {
  112. mark: item.mark,
  113. text: '',
  114. accessory_file_id: [], // 上传文件列表
  115. };
  116. this.answer.answer_list.push(obj);
  117. });
  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. overflow: auto;
  154. .el-image {
  155. cursor: pointer;
  156. &.not-active {
  157. opacity: 0.2;
  158. }
  159. }
  160. .pic-title {
  161. margin: 8px 0 4px;
  162. font-size: 12px;
  163. font-weight: 600;
  164. line-height: 20px;
  165. color: #000;
  166. word-break: break-word;
  167. }
  168. .pic-info {
  169. margin: 0;
  170. font-size: 12px;
  171. font-weight: 400;
  172. line-height: 20px;
  173. color: #000;
  174. word-break: break-word;
  175. }
  176. }
  177. .reference-box {
  178. padding: 12px;
  179. background: #f9f8f9;
  180. .reference-title {
  181. margin: 0 0 10px;
  182. font-size: 14px;
  183. font-weight: 400;
  184. line-height: 32px;
  185. color: #4e5969;
  186. }
  187. }
  188. .el-divider--horizontal {
  189. margin: 12px 0;
  190. }
  191. .sample-text {
  192. font-size: 14px;
  193. font-weight: 400;
  194. line-height: 30px;
  195. color: #000;
  196. cursor: pointer;
  197. &.sample-show {
  198. color: $light-main-color;
  199. }
  200. }
  201. .article-content,
  202. .description {
  203. :deep p {
  204. margin: 0;
  205. }
  206. }
  207. :deep .el-textarea .el-input__count {
  208. bottom: 15px;
  209. background-color: #f2f3f5;
  210. }
  211. }
  212. </style>