FilesUpload.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <template>
  2. <el-upload
  3. v-model:file-list="fileList"
  4. class="upload-demo"
  5. :on-change="handleChange"
  6. :limit="limit"
  7. :auto-upload="false"
  8. :show-file-list="false"
  9. >
  10. <el-button
  11. type="primary"
  12. :loading="loading"
  13. :disabled="fileList.length >= limit"
  14. >点击上传文件</el-button
  15. >
  16. <template #tip>
  17. <div class="tip">
  18. 文件类型限制为.jpg,.jpeg,.png,word文档,pdf,大小不超过{{ size }}M
  19. </div>
  20. </template>
  21. <div>
  22. <el-tag
  23. class="file-item"
  24. v-for="(file, index) in fileList"
  25. :key="file.name"
  26. closable
  27. type="success"
  28. @close="deleteFile(index)"
  29. @click.stop.prevent="handlePreview(index)"
  30. >
  31. {{ file.name }}
  32. </el-tag>
  33. </div>
  34. </el-upload>
  35. <el-drawer
  36. v-model="PDFVisible"
  37. :footer="false"
  38. :header="false"
  39. :show-close="false"
  40. destroy-on-close
  41. direction="rtl"
  42. :append-to-body="true"
  43. size="972px"
  44. >
  45. <VuePdfEmbed :source="pdfSource" annotation-layer text-layer />
  46. </el-drawer>
  47. </template>
  48. <script lang="ts" setup>
  49. import { ref } from "vue";
  50. import { UploadFile, UploadFiles, UploadUserFile } from "element-plus";
  51. import { uploadFileApi } from "@/api/file";
  52. import PDFView from "@/components/PDFView/index.vue";
  53. import VuePdfEmbed from "vue-pdf-embed";
  54. const props = defineProps({
  55. size: {
  56. type: Number,
  57. default: 4,
  58. },
  59. limit: {
  60. type: Number,
  61. default: 1,
  62. },
  63. src: {
  64. type: String,
  65. default: "",
  66. },
  67. srcList: {
  68. type: Array<string>,
  69. default: () => [],
  70. },
  71. pdfList: {
  72. type: Array<string>,
  73. default: () => [],
  74. },
  75. generatePdf: {
  76. type: Boolean,
  77. default: false,
  78. },
  79. });
  80. const loading = ref(false);
  81. const emit = defineEmits([
  82. "update:src",
  83. "update:srcList",
  84. "update:pdfList",
  85. "finished",
  86. ]);
  87. // 上传文件成功返回的值
  88. const src = useVModel(props, "src", emit); //单文件用这个
  89. const srcList = useVModel(props, "srcList", emit); //多文件用这个
  90. const pdfList = useVModel(props, "pdfList", emit); //转换成pdf后的多文件用这个
  91. // el-upload 绑定的值
  92. const fileList = ref<UploadUserFile[]>([]);
  93. const handleChange = async (uploadFile: UploadFile) => {
  94. if (uploadFile.size! > props.size * 1048 * 1048) {
  95. ElMessage.warning(`上传文件不能大于${props.size}M`);
  96. return;
  97. }
  98. loading.value = true;
  99. uploadFileApi(uploadFile.raw as File, props.generatePdf)
  100. .then((res: any) => {
  101. loading.value = false;
  102. let url = props.generatePdf ? res.data.pdfUrl : res.data.fileUrl;
  103. src.value = url;
  104. pdfList.value.push(url);
  105. srcList.value.push(res.data.fileUrl);
  106. emit("finished");
  107. })
  108. .catch((err) => {
  109. ElMessage.error(err.message);
  110. loading.value = false;
  111. });
  112. };
  113. const deleteFile = (index: number) => {
  114. src.value = ""; //删除直接清空src即可,不用考虑是哪个,因为单文件不会有多个
  115. fileList.value.splice(index, 1);
  116. srcList.value.splice(index, 1);
  117. };
  118. const PDFVisible = ref(false);
  119. const pdfSource = ref("");
  120. const handlePreview = (index: number) => {
  121. if (srcList.value.length > index && props.generatePdf) {
  122. pdfSource.value =
  123. import.meta.env.VITE_APP_UPLOAD_URL + srcList.value[index];
  124. PDFVisible.value = true;
  125. }
  126. };
  127. </script>
  128. <style scoped lang="scss">
  129. .tip {
  130. font-size: 12px;
  131. color: #e6a23c;
  132. margin-top: 5px;
  133. }
  134. .file-item {
  135. margin-left: 10px;
  136. }
  137. </style>