<template>
  <el-upload
    class="upload-demo"
    v-loading="fileUploadLoading"
    ref="FileUpload"
    drag
    :file-list="fileList"
    action="#"
    :http-request="doUpload"
    :headers="myHeaders"
    :limit="2"
    :on-remove="onRemove"
  >
    <i class="el-icon-upload"></i>
    <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
    <div
      class="el-upload__tip"
      slot="tip"
      style="color: #f56c6c; font-weight: 600"
    >
      {{ placeholder }}
    </div>
  </el-upload>
</template>

<script>
import { getToken } from "@/utils/auth";
import SparkMD5 from "spark-md5";

export default {
  name: "FileUpload",
  props: {
    fileUrl: {
      type: String,
      default: "",
    },
    placeholder: {
      type: String,
      default: "请上传 文件，建议大小在2M以内",
    },
  },
  data() {
    return {
      baseImgUrl: process.env.VUE_APP_BASE_IMG_URL,
      uploadUrl: process.env.VUE_APP_BASE_UPLOAD_API,
      myHeaders: {
        token: getToken(),
      },
      fileList: [],
      fileUploadLoading: false,
      tempUrl: "",
    };
  },
  computed: {},
  watch: {
    fileUrl: {
      handler(newVal, oldVal) {
        if (newVal) {
          this.fileList = [
            {
              name: newVal,
              url: this.baseImgUrl + newVal,
            },
          ];
          this.tempUrl = newVal;
        }
      },
      deep: true,
    },
  },
  created() {
    if (this.fileUrl) {
      this.fileList = [
        {
          name: this.fileUrl,
          url: this.baseImgUrl + this.fileUrl,
        },
      ];
      this.tempUrl = this.fileUrl;
    }
  },
  methods: {
    doUpload(fileData) {
      this.fileUploadLoading = true;
      // 1. 获取文件MD5值，判断md5是否已上传
      // 2. 若文件未上传，则执行上传
      // 3. 若文件已上传，则直接返回服务器文件路径
      var file = fileData.file;
      let md5;
      let fileSize = file.size;
      let fileReader = new FileReader();
      if (fileSize < 2 * 1024 * 1024) {
        fileReader.onload = (event) => {
          md5 = SparkMD5.hashBinary(event.target.result);
          // 从服务器获取 md5 对应文件信息
          this.getFileByMD5FromServer(md5, fileData);
        };
        fileReader.onerror = function () {
          this.onError();
          return;
        };
        fileReader.readAsBinaryString(file);
      } else {
        // 大于 2M 切片计算
        let spark = new SparkMD5();
        var chunkSize = 1 * 1024 * 1024;
        var maxChunks = Math.ceil(fileSize / chunkSize);
        var currChunk = 0;

        const loadFile = () => {
          var start = currChunk * chunkSize;
          const slice = file.slice(start, start + chunkSize);
          fileReader.readAsBinaryString(slice);
        };
        loadFile();

        fileReader.onload = (event) => {
          spark.appendBinary(event.target.result);

          if (currChunk < maxChunks) {
            currChunk++;
            loadFile();
            console.log("load finish", currChunk);
          } else {
            console.log("load finish");
            md5 = spark.end();
            // 从服务器获取 md5 对应文件信息
            this.getFileByMD5FromServer(md5, fileData);
          }
        };

        fileReader.onerror = function () {
          this.onError();
        };
      }
    },
    onRemove(file, fileList) {
      console.log(11122222, "onRemove");
      this.$refs.FileUpload.uploadFiles = [];
      this.tempUrl = "";
    },
    onError(message = "") {
      this.$message({
        message: message ? message : "文件上传出现异常",
        type: "error",
      });
      this.fileUploadLoading = false;
      this.tempUrl = "";
      this.fileList = [];
    },
    /**
     * 从服务器获取 md5 对应文件信息
     */
    getFileByMD5FromServer(md5, fileData) {
      $.ajax({
        type: "POST",
        data: { md5: md5 },
        url: this.uploadUrl + "getFileByMD5",
        dataType: "json",
        success: (res) => {
          if (res.code != 900) {
            this.onError(res.message);
          } else if (res.data && res.data.local) {
            this.tempUrl = res.data.local;
            this.fileList = [
              {
                name: this.tempUrl,
                url: this.baseImgUrl + this.tempUrl,
              },
            ];
            this.fileUploadLoading = false;
          } else {
            this.uploadFileToServer(fileData);
          }
        },
      });
    },
    /**
     * 上传文件至服务器
     */
    uploadFileToServer(fileData) {
      var formData = new FormData();
      formData.append("type", "local");
      formData.append("pid", process.env.VUE_APP_PID);
      formData.append("file", fileData.file);

      $.ajax({
        type: "POST",
        data: formData,
        url: this.uploadUrl + "upload",
        dataType: "json",
        async: true,
        cache: false,
        contentType: false,
        processData: false,
        success: (res) => {
          if (res.code != 900) {
            this.onError(res.message);
          } else if (res.data && res.data.local) {
            this.tempUrl = res.data.local;
            this.fileList = [
              {
                name: this.tempUrl,
                url: this.baseImgUrl + this.tempUrl,
              },
            ];
          } else {
            this.tempUrl = "";
            this.fileList = [];
          }

          this.fileUploadLoading = false;
        },
      });
    },
  },
};
</script>

<style lang="scss" scoped>
@import "~@/styles/mixin.scss";

.upload-demo {
  .el-upload-list {
    width: 360px !important;
  }
}
</style>
