|
@@ -0,0 +1,244 @@
|
|
|
+<template>
|
|
|
+ <div class="import-file">
|
|
|
+ <el-upload
|
|
|
+ ref="UploadComp"
|
|
|
+ :action="uploadUrl"
|
|
|
+ :headers="headers"
|
|
|
+ :max-size="maxSize"
|
|
|
+ :accept="accept"
|
|
|
+ :format="format"
|
|
|
+ :data="uploadDataDict"
|
|
|
+ :on-error="handleError"
|
|
|
+ :on-success="handleSuccess"
|
|
|
+ :on-change="fileChange"
|
|
|
+ :http-request="upload"
|
|
|
+ :show-file-list="false"
|
|
|
+ :disabled="loading"
|
|
|
+ :auto-upload="false"
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ slot="trigger"
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ icon="icon icon-search-white"
|
|
|
+ :disabled="loading"
|
|
|
+ >
|
|
|
+ 选择文件
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ icon="icon icon-save-white"
|
|
|
+ :loading="loading"
|
|
|
+ :disabled="!fileValid"
|
|
|
+ @click="submitUpload"
|
|
|
+ >
|
|
|
+ 确认上传
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ icon="icon icon-delete-white"
|
|
|
+ :disabled="loading"
|
|
|
+ @click="removeFile"
|
|
|
+ >
|
|
|
+ 清空文件
|
|
|
+ </el-button>
|
|
|
+ <el-button
|
|
|
+ v-if="templateUrl"
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ icon="icon icon-export-white"
|
|
|
+ @click="exportFile"
|
|
|
+ >
|
|
|
+ 下载模板
|
|
|
+ </el-button>
|
|
|
+ </el-upload>
|
|
|
+ <p v-if="filename" class="tips-info">{{ filename }}</p>
|
|
|
+ <p v-if="!res.success" class="tips-info tips-error">{{ res.message }}</p>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { fileMD5 } from "@/plugins/md5";
|
|
|
+import { $httpWithMsg } from "@/plugins/axios";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "ImportFile",
|
|
|
+ props: {
|
|
|
+ format: {
|
|
|
+ type: Array,
|
|
|
+ default() {
|
|
|
+ return ["xlsx", "xls"];
|
|
|
+ },
|
|
|
+ },
|
|
|
+ accept: {
|
|
|
+ type: String,
|
|
|
+ default: null,
|
|
|
+ },
|
|
|
+ onlyFetchFile: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ uploadUrl: {
|
|
|
+ type: String,
|
|
|
+ default: "",
|
|
|
+ },
|
|
|
+ uploadData: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {};
|
|
|
+ },
|
|
|
+ },
|
|
|
+ maxSize: {
|
|
|
+ type: Number,
|
|
|
+ default: 20 * 1024 * 1024,
|
|
|
+ },
|
|
|
+ addFilenameParam: {
|
|
|
+ type: String,
|
|
|
+ default: "filename",
|
|
|
+ },
|
|
|
+ templateUrl: {
|
|
|
+ type: String,
|
|
|
+ default: "",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ headers: {
|
|
|
+ md5: "",
|
|
|
+ },
|
|
|
+ res: {},
|
|
|
+ loading: false,
|
|
|
+ uploadDataDict: {},
|
|
|
+ filename: "",
|
|
|
+ fileValid: false,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ initData() {
|
|
|
+ this.res = {};
|
|
|
+ this.loading = false;
|
|
|
+ this.uploadDataDict = {};
|
|
|
+ this.filename = "";
|
|
|
+ this.fileValid = false;
|
|
|
+ },
|
|
|
+ checkFileFormat(fileType) {
|
|
|
+ const _file_format = fileType.split(".").pop().toLowerCase();
|
|
|
+ return this.format.length
|
|
|
+ ? this.format.some((item) => item.toLowerCase() === _file_format)
|
|
|
+ : true;
|
|
|
+ },
|
|
|
+ fileChange(fileObj) {
|
|
|
+ if (fileObj.status === "ready") {
|
|
|
+ this.handleBeforeUpload(fileObj.raw).catch(() => {});
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async handleBeforeUpload(file) {
|
|
|
+ this.res = {};
|
|
|
+ this.filename = file.name;
|
|
|
+ this.uploadDataDict = {
|
|
|
+ ...this.uploadData,
|
|
|
+ };
|
|
|
+ this.uploadDataDict[this.addFilenameParam] = file.name;
|
|
|
+
|
|
|
+ if (!this.checkFileFormat(file.name)) {
|
|
|
+ this.handleFormatError();
|
|
|
+ this.fileValid = false;
|
|
|
+ return Promise.reject();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (file.size > this.maxSize) {
|
|
|
+ this.handleExceededSize();
|
|
|
+ this.fileValid = false;
|
|
|
+ return Promise.reject();
|
|
|
+ }
|
|
|
+
|
|
|
+ const md5 = await fileMD5(file);
|
|
|
+ this.headers["md5"] = md5;
|
|
|
+ this.fileValid = true;
|
|
|
+
|
|
|
+ if (this.onlyFetchFile) {
|
|
|
+ this.$emit("file-change", {
|
|
|
+ file,
|
|
|
+ md5,
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ },
|
|
|
+ upload(options) {
|
|
|
+ if (!options.file) return Promise.reject("文件丢失");
|
|
|
+
|
|
|
+ let formData = new FormData();
|
|
|
+ Object.entries(options.data).forEach(([k, v]) => {
|
|
|
+ formData.append(k, v);
|
|
|
+ });
|
|
|
+ formData.append("file", options.file);
|
|
|
+
|
|
|
+ return $httpWithMsg.post(options.action, formData, {
|
|
|
+ headers: options.headers,
|
|
|
+ });
|
|
|
+ },
|
|
|
+ handleError(error) {
|
|
|
+ this.loading = false;
|
|
|
+ this.res = {
|
|
|
+ success: false,
|
|
|
+ message: error.response.data.desc,
|
|
|
+ };
|
|
|
+ this.uploadDataDict = {};
|
|
|
+ this.filename = "";
|
|
|
+ this.fileValid = false;
|
|
|
+ this.$refs.UploadComp.clearFiles();
|
|
|
+ },
|
|
|
+ handleSuccess(res) {
|
|
|
+ this.loading = false;
|
|
|
+ this.res = {
|
|
|
+ success: true,
|
|
|
+ message: "导入成功!",
|
|
|
+ };
|
|
|
+ this.cancel();
|
|
|
+ this.$emit("uploaded", res);
|
|
|
+ },
|
|
|
+ handleFormatError() {
|
|
|
+ const content = "只支持文件格式为" + this.format.join("/");
|
|
|
+ this.res = {
|
|
|
+ success: false,
|
|
|
+ message: content,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ handleExceededSize() {
|
|
|
+ const content =
|
|
|
+ "文件大小不能超过" + Math.floor(this.maxSize / (1024 * 1024)) + "M";
|
|
|
+ this.res = {
|
|
|
+ success: false,
|
|
|
+ message: content,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ // action
|
|
|
+ submitUpload() {
|
|
|
+ if (this.onlyFetchFile) {
|
|
|
+ this.$emit("confirm");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (this.loading) return;
|
|
|
+ this.$refs.UploadComp.submit();
|
|
|
+ this.loading = true;
|
|
|
+ },
|
|
|
+ removeFile() {
|
|
|
+ if (this.loading) return;
|
|
|
+ this.uploadDataDict = {};
|
|
|
+ this.filename = "";
|
|
|
+ this.fileValid = false;
|
|
|
+ this.res = {};
|
|
|
+ this.$refs.UploadComp.clearFiles();
|
|
|
+ },
|
|
|
+ exportFile() {
|
|
|
+ window.location.href = this.templateUrl;
|
|
|
+ },
|
|
|
+ setLoading(loading) {
|
|
|
+ this.loading = loading;
|
|
|
+ },
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|