FilesUpload.vue 3.8 KB

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