WritePictruePreview.vue 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <!-- eslint-disable vue/no-v-html -->
  2. <template>
  3. <div 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" v-html="sanitizeHTML(data.article)"></div>
  9. <div v-if="isEnable(data.property.is_enable_description)" class="description">
  10. {{ data.description }}
  11. </div>
  12. <div class="content">
  13. <div class="content-left">
  14. <el-carousel
  15. type="card"
  16. height="276px"
  17. :autoplay="false"
  18. indicator-position="none"
  19. arrow="always"
  20. @change="changeImg"
  21. >
  22. <el-carousel-item v-for="(item, index) in data.option_list" :key="index">
  23. <el-image
  24. v-if="pic_list[item.picture_file_id]"
  25. style="width: 370px; height: 276px"
  26. :src="pic_list[item.picture_file_id]"
  27. fit="contain"
  28. />
  29. </el-carousel-item>
  30. </el-carousel>
  31. <h3 class="pic-title" v-html="sanitizeHTML(data.option_list[active_index].picture_title)"></h3>
  32. <p class="pic-info" v-html="sanitizeHTML(data.option_list[active_index].picture_info)"></p>
  33. </div>
  34. <div class="content-right">
  35. <el-input
  36. v-model="answer_list[active_index].value"
  37. rows="12"
  38. resize="none"
  39. type="textarea"
  40. placeholder="请输入"
  41. :maxlength="data.property.word_num"
  42. show-word-limit
  43. @input="handleInput"
  44. />
  45. </div>
  46. </div>
  47. <template v-if="isEnable(data.property.is_enable_upload_accessory)">
  48. <!-- 上传附件 -->
  49. <UploadFiles
  50. :fille-number="999"
  51. file-type-name="文件"
  52. :upload-type="'*'"
  53. :file-id-list="answer_list[active_index].accessory_file_id"
  54. upload-title="上传附件:"
  55. @upload="handleUpload"
  56. @deleteFile="handleDelete"
  57. />
  58. </template>
  59. <template v-if="isEnable(data.property.is_enable_sample_text)">
  60. <el-divider content-position="center"
  61. ><span
  62. :class="['sample-text', show_sample_text ? 'sample-show' : 'sample-hide']"
  63. @click="show_sample_text = !show_sample_text"
  64. >{{ show_sample_text ? '隐藏范文' : '查看范文' }}</span
  65. ></el-divider
  66. >
  67. <div v-if="show_sample_text" class="article-content" v-html="sanitizeHTML(data.sample_text)"></div>
  68. </template>
  69. </div>
  70. </template>
  71. <script>
  72. import PreviewMixin from './components/PreviewMixin';
  73. import { GetFileStoreInfo } from '@/api/app';
  74. import UploadFiles from './components/common/UploadFiles.vue';
  75. export default {
  76. name: 'WritePicturePreview',
  77. components: {
  78. UploadFiles,
  79. },
  80. mixins: [PreviewMixin],
  81. data() {
  82. return {
  83. show_sample_text: false,
  84. pic_list: {},
  85. active_index: 0,
  86. answer_list: [],
  87. };
  88. },
  89. created() {
  90. this.handleData();
  91. },
  92. methods: {
  93. // 初始化数据
  94. handleData() {
  95. this.answer_list = [];
  96. this.pic_list = {};
  97. this.active_index = 0;
  98. this.data.file_id_list.forEach((item) => {
  99. GetFileStoreInfo({ file_id: item }).then(({ file_id, file_url }) => {
  100. this.$set(this.pic_list, file_id, file_url);
  101. });
  102. });
  103. this.data.option_list.forEach((item) => {
  104. let obj = {
  105. mark: item.mark,
  106. value: '',
  107. accessory_file_id: [], // 上传文件列表
  108. };
  109. this.answer_list.push(obj);
  110. });
  111. },
  112. changeImg(index) {
  113. this.active_index = index;
  114. },
  115. // 文件上传成功
  116. handleUpload(fileId) {
  117. this.user_answer[this.active_index].accessory_file_id.push(fileId);
  118. },
  119. // 删除文件
  120. handleDelete(fileId) {
  121. this.user_answer[this.active_index].accessory_file_id.splice(
  122. this.user_answer.accessory_file_id.indexOf(fileId),
  123. 1,
  124. );
  125. },
  126. handleInput(value) {
  127. if (value.length >= this.data.property.word_num) {
  128. this.$message.warning(`字数达到${value.length}字!`);
  129. }
  130. },
  131. },
  132. };
  133. </script>
  134. <style lang="scss" scoped>
  135. @use '@/styles/mixin.scss' as *;
  136. .writepicture-preview {
  137. @include preview;
  138. :deep p {
  139. margin: 0;
  140. }
  141. .content {
  142. display: flex;
  143. column-gap: 24px;
  144. &-left {
  145. flex-shrink: 0;
  146. width: 478px;
  147. :deep .el-carousel__item--card {
  148. width: 77%;
  149. margin-left: -13.5%;
  150. }
  151. .el-image {
  152. opacity: 0.2;
  153. }
  154. .el-carousel__item--card.is-active {
  155. .el-image {
  156. background: #fff;
  157. opacity: 1;
  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. :deep .el-carousel__arrow:focus {
  178. outline: none;
  179. }
  180. &-right {
  181. flex: 1;
  182. .el-textarea {
  183. height: 276px;
  184. margin-bottom: 16px;
  185. }
  186. }
  187. }
  188. .reference-box {
  189. padding: 12px;
  190. background: #f9f8f9;
  191. .reference-title {
  192. margin: 0 0 10px;
  193. font-size: 14px;
  194. font-weight: 400;
  195. line-height: 32px;
  196. color: #4e5969;
  197. }
  198. }
  199. .el-divider--horizontal {
  200. margin: 12px 0;
  201. }
  202. .sample-text {
  203. font-size: 14px;
  204. font-weight: 400;
  205. line-height: 30px;
  206. color: #000;
  207. cursor: pointer;
  208. &.sample-show {
  209. color: $light-main-color;
  210. }
  211. }
  212. .article-content {
  213. :deep p {
  214. margin: 0;
  215. }
  216. }
  217. :deep .el-textarea .el-input__count {
  218. bottom: 15px;
  219. background-color: #f2f3f5;
  220. }
  221. }
  222. </style>