ImportFileDialog.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <template>
  2. <el-dialog
  3. custom-class="side-dialog"
  4. :visible.sync="modalIsShow"
  5. :title="dialogTitle"
  6. width="520px"
  7. :modal="false"
  8. append-to-body
  9. @open="visibleChange"
  10. >
  11. <el-upload
  12. ref="UploadComp"
  13. :action="uploadUrl"
  14. :headers="headers"
  15. :max-size="maxSize"
  16. :accept="accept"
  17. :format="format"
  18. :data="uploadDataDict"
  19. :on-error="handleError"
  20. :on-success="handleSuccess"
  21. :on-change="fileChange"
  22. :http-request="upload"
  23. :show-file-list="false"
  24. :disabled="loading"
  25. :auto-upload="false"
  26. >
  27. <el-button
  28. slot="trigger"
  29. size="small"
  30. type="primary"
  31. icon="icon icon-search-white"
  32. :disabled="loading"
  33. >
  34. 选择文件
  35. </el-button>
  36. <el-button
  37. size="small"
  38. type="primary"
  39. icon="icon icon-save-white"
  40. :loading="loading"
  41. :disabled="!fileValid"
  42. @click="submitUpload"
  43. >
  44. 确认上传
  45. </el-button>
  46. <el-button
  47. size="small"
  48. type="primary"
  49. icon="icon icon-delete-white"
  50. :disabled="loading"
  51. @click="removeFile"
  52. >
  53. 清空文件
  54. </el-button>
  55. <el-button
  56. v-if="templateUrl"
  57. size="small"
  58. type="primary"
  59. icon="icon icon-export-white"
  60. @click="exportFile"
  61. >
  62. 下载模板
  63. </el-button>
  64. </el-upload>
  65. <p v-if="filename" class="tips-info">{{ filename }}</p>
  66. <p v-if="!res.success" class="tips-info tips-error">{{ res.message }}</p>
  67. </el-dialog>
  68. </template>
  69. <script>
  70. import { fileMD5 } from "@/plugins/md5";
  71. import { $httpWithMsg } from "@/plugins/axios";
  72. export default {
  73. name: "ImportFileDialog",
  74. props: {
  75. dialogTitle: {
  76. type: String,
  77. default: "导入文件",
  78. },
  79. format: {
  80. type: Array,
  81. default() {
  82. return ["xlsx", "xls"];
  83. },
  84. },
  85. accept: {
  86. type: String,
  87. default: null,
  88. },
  89. uploadUrl: {
  90. type: String,
  91. required: true,
  92. },
  93. uploadData: {
  94. type: Object,
  95. default() {
  96. return {};
  97. },
  98. },
  99. maxSize: {
  100. type: Number,
  101. default: 20 * 1024 * 1024,
  102. },
  103. addFilenameParam: {
  104. type: String,
  105. default: "filename",
  106. },
  107. templateUrl: {
  108. type: String,
  109. default: "",
  110. },
  111. },
  112. data() {
  113. return {
  114. modalIsShow: false,
  115. headers: {
  116. md5: "",
  117. },
  118. res: {},
  119. loading: false,
  120. uploadDataDict: {},
  121. filename: "",
  122. fileValid: false,
  123. };
  124. },
  125. methods: {
  126. visibleChange() {
  127. this.res = {};
  128. this.loading = false;
  129. this.uploadDataDict = {};
  130. this.filename = "";
  131. this.fileValid = false;
  132. },
  133. cancel() {
  134. this.modalIsShow = false;
  135. },
  136. open() {
  137. this.modalIsShow = true;
  138. },
  139. checkFileFormat(fileType) {
  140. const _file_format = fileType.split(".").pop().toLowerCase();
  141. return this.format.length
  142. ? this.format.some((item) => item.toLowerCase() === _file_format)
  143. : true;
  144. },
  145. fileChange(fileObj) {
  146. if (fileObj.status === "ready") {
  147. this.handleBeforeUpload(fileObj.raw).catch(() => {});
  148. }
  149. },
  150. async handleBeforeUpload(file) {
  151. this.res = {};
  152. this.filename = file.name;
  153. this.uploadDataDict = {
  154. ...this.uploadData,
  155. };
  156. this.uploadDataDict[this.addFilenameParam] = file.name;
  157. if (!this.checkFileFormat(file.name)) {
  158. this.handleFormatError();
  159. this.fileValid = false;
  160. return Promise.reject();
  161. }
  162. if (file.size > this.maxSize) {
  163. this.handleExceededSize();
  164. this.fileValid = false;
  165. return Promise.reject();
  166. }
  167. const md5 = await fileMD5(file);
  168. this.headers["md5"] = md5;
  169. this.fileValid = true;
  170. return true;
  171. },
  172. upload(options) {
  173. if (!options.file) return Promise.reject("文件丢失");
  174. let formData = new FormData();
  175. Object.entries(options.data).forEach(([k, v]) => {
  176. formData.append(k, v);
  177. });
  178. formData.append("file", options.file);
  179. return $httpWithMsg.post(options.action, formData, {
  180. headers: options.headers,
  181. });
  182. },
  183. handleError(error) {
  184. this.loading = false;
  185. this.res = {
  186. success: false,
  187. message: error.response.data.desc,
  188. };
  189. this.uploadDataDict = {};
  190. this.filename = "";
  191. this.fileValid = false;
  192. this.$refs.UploadComp.clearFiles();
  193. },
  194. handleSuccess(res) {
  195. this.loading = false;
  196. this.res = {
  197. success: true,
  198. message: "导入成功!",
  199. };
  200. this.cancel();
  201. this.$emit("uploaded", res);
  202. },
  203. handleFormatError() {
  204. const content = "只支持文件格式为" + this.format.join("/");
  205. this.res = {
  206. success: false,
  207. message: content,
  208. };
  209. },
  210. handleExceededSize() {
  211. const content =
  212. "文件大小不能超过" + Math.floor(this.maxSize / (1024 * 1024)) + "M";
  213. this.res = {
  214. success: false,
  215. message: content,
  216. };
  217. },
  218. // action
  219. submitUpload() {
  220. if (this.loading) return;
  221. this.$refs.UploadComp.submit();
  222. this.loading = true;
  223. },
  224. removeFile() {
  225. if (this.loading) return;
  226. this.uploadDataDict = {};
  227. this.filename = "";
  228. this.fileValid = false;
  229. this.res = {};
  230. this.$refs.UploadComp.clearFiles();
  231. },
  232. exportFile() {
  233. window.location.href = this.templateUrl;
  234. },
  235. },
  236. };
  237. </script>