<template>
  <div :class="prefixCls">
    <el-dialog
      class="modify-data"
      :visible.sync="modalIsShow"
      :title="title"
      top="10vh"
      width="500px"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      append-to-body
      @open="visibleChange"
    >
      <div style="footer"></div>
      <div :class="[`${prefixCls}-footer`]" v-if="downloadUrl">
        文件下载：
        <a :href="downloadUrl" :download="dfilename">{{ dfilename }}</a>
      </div>
      <div :class="[`${prefixCls}-footer`]" v-if="downloadHandle">
        文件下载：
        <el-button type="text" @click="downloadHandle">{{
          dfilename
        }}</el-button>
      </div>
      <div :class="[`${prefixCls}-body`]">
        <el-upload
          drag
          :action="uploadUrl"
          :headers="headers"
          :max-size="maxSize"
          :format="format"
          :accept="accept"
          :data="uploadDataDict"
          :before-upload="handleBeforeUpload"
          :on-error="handleError"
          :on-success="handleSuccess"
          :http-request="upload"
          :disabled="disabled || loading"
          :show-file-list="false"
          ref="UploadComp"
        >
          <i class="el-icon-upload"></i><br />
          <em class="el-upload__text">将文件拖到此处，或<em>点击上传</em></em>
          <p
            slot="tip"
            :class="[
              `${prefixCls}-tips`,
              {
                'cc-tips-success': res.success,
                'cc-tips-error': !res.success
              }
            ]"
            v-if="res.msg"
          >
            {{ res.msg }}
          </p>
        </el-upload>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { fileMD5 } from "@/plugins/md5";
import { $post } from "@/plugins/axios";

const prefixCls = "cc-import-file";

export default {
  name: "import-file",
  props: {
    title: {
      type: String,
      default: "文件上传"
    },
    downloadHandle: {
      type: Function
    },
    downloadUrl: {
      type: String,
      default: ""
    },
    downloadFilename: String,
    format: {
      type: Array,
      default() {
        return ["jpg", "jpeg", "png"];
      }
    },
    uploadUrl: {
      type: String,
      required: true
    },
    uploadData: {
      type: Object,
      default() {
        return {};
      }
    },
    maxSize: {
      type: Number,
      default: 20 * 1024 * 1024
    },
    addFilenameParam: {
      type: String,
      default: "filename"
    },
    disabled: { type: Boolean, default: false }
  },
  data() {
    return {
      prefixCls,
      modalIsShow: false,
      headers: {
        md5: ""
      },
      loading: false,
      uploadDataDict: {},
      res: {
        success: true,
        msg: ""
      }
    };
  },
  computed: {
    dfilename() {
      return this.downloadFilename || this.downloadUrl.split("/").pop();
    },
    accept() {
      return this.format.map(el => `.${el}`).join();
    }
  },
  methods: {
    visibleChange() {
      this.res = {
        success: true,
        msg: ""
      };
      this.headers = { md5: "" };
      this.loading = false;
      this.uploadDataDict = {};
    },
    checkFileFormat(fileType) {
      const _file_format = fileType
        .split(".")
        .pop()
        .toLowerCase();
      return this.format.length
        ? this.format.some(item => item.toLowerCase() === _file_format)
        : true;
    },
    async handleBeforeUpload(file) {
      this.uploadDataDict = {
        ...this.uploadData
      };
      this.uploadDataDict[this.addFilenameParam] = file.name;

      if (file.size > this.maxSize) {
        this.handleExceededSize();
        return Promise.reject();
      }
      if (!this.checkFileFormat(file.name)) {
        this.handleFormatError();
        return Promise.reject();
      }

      const md5 = await fileMD5(file);
      this.headers["md5"] = md5;
      this.loading = true;

      return true;
    },
    upload(options) {
      let formData = new FormData();
      Object.entries(options.data).forEach(([k, v]) => {
        formData.append(k, v);
      });
      formData.append("file", options.file);
      this.$emit("uploading");

      return $post(options.action, formData, { headers: options.headers });
    },
    handleError(error) {
      this.loading = false;
      this.res = {
        success: false,
        msg: error.message
      };
      this.$emit("upload-error", error);
    },
    handleSuccess(responseData) {
      this.loading = false;
      this.res = {
        success: true,
        msg: "导入成功！"
      };
      this.cancel();
      this.$emit("upload-success", responseData);
    },
    handleFormatError() {
      this.res = {
        success: false,
        msg: "只支持文件格式为" + this.format.join("/")
      };
      this.$refs.UploadComp.clearFiles();
    },
    handleExceededSize() {
      this.res = {
        success: false,
        msg: "文件大小不能超过" + Math.floor(this.maxSize / (1024 * 1024)) + "M"
      };
      this.$refs.UploadComp.clearFiles();
    },
    cancel() {
      this.modalIsShow = false;
    },
    open() {
      this.modalIsShow = true;
    }
  }
};
</script>
