index.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <template>
  2. <el-dialog class="show-file" :visible="dialogVisibleShowFile" width="900px" @close="dialogShowFileClose">
  3. <div slot="title">查看文件【{{ fileName }}】</div>
  4. <template v-if="fileType === 'pdf'">
  5. <pdf v-for="i in numPages" :key="i" :src="pdfSrc" :page="i" />
  6. </template>
  7. <template v-else-if="isImage(fileType)">
  8. <div class="image-parent">
  9. <el-image fit="contain" :src="fileUrl" />
  10. </div>
  11. </template>
  12. <div v-else-if="fileType === 'mp3'" class="audio-file">
  13. <audio :src="fileUrl" controls></audio>
  14. </div>
  15. <div v-else-if="fileType === 'mp4'" class="video-file">
  16. <video :src="fileUrl" controls></video>
  17. </div>
  18. <div v-else-if="fileType === 'txt'" class="text-file">
  19. <el-input v-model="text" type="textarea" :readonly="true" resize="none" />
  20. </div>
  21. <template v-else>
  22. <iframe
  23. :src="'https://view.officeapps.live.com/op/view.aspx?src=' + `${fileUrl}`"
  24. width="100%"
  25. height="490px"
  26. scrolling="no"
  27. />
  28. </template>
  29. <div slot="footer">
  30. <el-button @click="dialogShowFileClose">关闭</el-button>
  31. </div>
  32. </el-dialog>
  33. </template>
  34. <script>
  35. import pdf from 'vue-pdf';
  36. import { GetFileStoreInfo } from '@/api/app';
  37. import { getFileType } from '@/utils/filter';
  38. export default {
  39. components: { pdf },
  40. props: {
  41. fileName: {
  42. default: '',
  43. type: String
  44. },
  45. fileId: {
  46. default: '',
  47. type: String
  48. }
  49. },
  50. data() {
  51. return {
  52. dialogVisibleShowFile: false,
  53. pdfSrc: '',
  54. numPages: 1,
  55. fileUrl: '',
  56. text: ''
  57. };
  58. },
  59. computed: {
  60. fileType() {
  61. return getFileType(this.fileName);
  62. }
  63. },
  64. watch: {
  65. fileId(newVal) {
  66. if (newVal.length > 0) {
  67. this.getFileStoreInfo();
  68. }
  69. },
  70. dialogVisibleShowFile(newVal) {
  71. if (!newVal) {
  72. this.pdfSrc = '';
  73. this.numPages = 0;
  74. this.fileUrl = '';
  75. this.text = '';
  76. }
  77. }
  78. },
  79. methods: {
  80. getFileStoreInfo() {
  81. GetFileStoreInfo({ file_id: this.fileId }).then(({ file_url_https, file_relative_path }) => {
  82. this.fileUrl = file_url_https;
  83. if (this.fileType === 'pdf') {
  84. this.getNumPages(file_relative_path);
  85. }
  86. if (this.fileType === 'txt') {
  87. fetch(`${process.env.VUE_APP_PDF}${file_relative_path}`).then(async res => {
  88. if (!res.ok) return;
  89. this.text = await res.text();
  90. });
  91. }
  92. });
  93. },
  94. getNumPages(url) {
  95. let loadingTask = pdf.createLoadingTask(`${process.env.VUE_APP_PDF}${url}`);
  96. loadingTask.promise
  97. .then(pdf => {
  98. this.pdfSrc = loadingTask;
  99. this.numPages = pdf.numPages;
  100. })
  101. .catch(err => {
  102. console.error('pdf加载失败', err);
  103. this.$message.error('pdf加载失败');
  104. });
  105. },
  106. showDialog() {
  107. this.dialogVisibleShowFile = true;
  108. },
  109. dialogShowFileClose() {
  110. this.dialogVisibleShowFile = false;
  111. this.$emit('dialogShowFileClose');
  112. },
  113. isImage(type) {
  114. return ['jpeg', 'gif', 'jpg', 'png', 'bmp', 'pic', 'svg'].includes(type);
  115. }
  116. }
  117. };
  118. </script>
  119. <style lang="scss">
  120. @import '~@/styles/mixin';
  121. .show-file {
  122. @include dialog;
  123. .el-dialog__header {
  124. font-weight: bold;
  125. }
  126. %image-parent,
  127. .image-parent {
  128. display: flex;
  129. justify-content: center;
  130. }
  131. .audio-file {
  132. @extend %image-parent;
  133. }
  134. .video-file {
  135. @extend %image-parent;
  136. }
  137. .text-file {
  138. height: 60vh;
  139. .el-textarea,
  140. textarea {
  141. height: 100%;
  142. }
  143. }
  144. }
  145. </style>