UploadFileView.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. <template>
  2. <div class="upload-file-view">
  3. <el-input
  4. :style="{ width: inputWidth }"
  5. v-model.trim="attachmentName"
  6. placeholder="文件名称"
  7. readonly
  8. ></el-input>
  9. <el-upload
  10. :action="uploadUrl"
  11. :headers="headers"
  12. :max-size="maxSize"
  13. :format="format"
  14. :data="uploadDataDict"
  15. :on-change="handleFileChange"
  16. :before-upload="handleBeforeUpload"
  17. :on-error="handleError"
  18. :on-success="handleSuccess"
  19. :on-progress="handleProgress"
  20. :http-request="upload"
  21. :show-file-list="false"
  22. :disabled="disabled"
  23. style="display:inline-block;margin: 0 10px;"
  24. ref="UploadComp"
  25. >
  26. <el-button type="primary" :disabled="disabled" :loading="loading"
  27. >选择</el-button
  28. >
  29. </el-upload>
  30. <el-button
  31. type="primary"
  32. @click="startUpload"
  33. v-if="canUpload && !autoUpload"
  34. :loading="loading"
  35. style="margin-right: 10px;"
  36. >开始上传</el-button
  37. >
  38. </div>
  39. </template>
  40. <script>
  41. import { fileMD5 } from "@/plugins/md5";
  42. import { $post } from "@/plugins/axios";
  43. export default {
  44. name: "upload-file-view",
  45. props: {
  46. inputWidth: {
  47. type: String,
  48. default: "400px"
  49. },
  50. format: {
  51. type: Array,
  52. default() {
  53. return ["xls", "xlsx"];
  54. }
  55. },
  56. uploadUrl: {
  57. type: String,
  58. required: true
  59. },
  60. uploadData: {
  61. type: Object,
  62. default() {
  63. return {};
  64. }
  65. },
  66. maxSize: {
  67. type: Number,
  68. default: 20 * 1024 * 1024
  69. },
  70. addFilenameParam: {
  71. type: String,
  72. default: "filename"
  73. },
  74. autoUpload: {
  75. type: Boolean,
  76. default: true
  77. },
  78. disabled: {
  79. type: Boolean,
  80. default: false
  81. }
  82. },
  83. data() {
  84. return {
  85. attachmentName: "",
  86. canUpload: false,
  87. loading: false,
  88. uploadDataDict: {},
  89. headers: {
  90. md5: ""
  91. },
  92. res: {}
  93. };
  94. },
  95. methods: {
  96. startUpload() {
  97. this.loading = true;
  98. this.$refs.UploadComp.submit();
  99. },
  100. checkFileFormat(fileType) {
  101. const _file_format = fileType
  102. .split(".")
  103. .pop()
  104. .toLocaleLowerCase();
  105. return this.format.some(
  106. item => item.toLocaleLowerCase() === _file_format
  107. );
  108. },
  109. handleFileChange(file) {
  110. this.attachmentName = file.name;
  111. this.canUpload = file.status === "ready";
  112. },
  113. async handleBeforeUpload(file) {
  114. this.uploadDataDict = {
  115. ...this.uploadData
  116. };
  117. this.uploadDataDict[this.addFilenameParam] = file.name;
  118. if (file.size > this.maxSize) {
  119. this.handleExceededSize();
  120. return Promise.reject();
  121. }
  122. if (!this.checkFileFormat(file.name)) {
  123. this.handleFormatError();
  124. return Promise.reject();
  125. }
  126. const md5 = await fileMD5(file);
  127. this.headers["md5"] = md5;
  128. if (this.autoUpload) this.loading = true;
  129. return this.autoUpload;
  130. },
  131. upload(options) {
  132. let formData = new FormData();
  133. Object.entries(options.data).forEach(([k, v]) => {
  134. formData.append(k, v);
  135. });
  136. formData.append("file", options.file);
  137. return $post(options.action, formData, { headers: options.headers });
  138. },
  139. handleError(error) {
  140. this.canUpload = false;
  141. this.loading = false;
  142. this.res = {
  143. success: false,
  144. message: error.message
  145. };
  146. this.$emit("upload-error", error);
  147. },
  148. handleSuccess(responseData) {
  149. this.canUpload = false;
  150. this.loading = false;
  151. this.res = {
  152. success: true,
  153. message: "导入成功!"
  154. };
  155. this.$emit("upload-success", {
  156. ...responseData,
  157. filename: this.uploadDataDict[this.addFilenameParam]
  158. });
  159. },
  160. handleProgress() {
  161. this.loading = true;
  162. },
  163. handleFormatError() {
  164. const content = "只支持文件格式为" + this.format.join("/");
  165. this.res = {
  166. success: false,
  167. message: content
  168. };
  169. this.loading = false;
  170. this.$emit("upload-error", this.res);
  171. },
  172. handleExceededSize() {
  173. const content =
  174. "文件大小不能超过" + Math.floor(this.maxSize / 1024) + "M";
  175. this.res = {
  176. success: false,
  177. message: content
  178. };
  179. this.loading = false;
  180. this.$emit("upload-error", this.res);
  181. },
  182. setAttachmentName(name) {
  183. this.attachmentName = name;
  184. }
  185. }
  186. };
  187. </script>
  188. <style scoped>
  189. .upload-file-view {
  190. display: inline-block;
  191. }
  192. </style>