<template>
  <div>
    <el-upload
      class="upload-demo"
      :action="action"
      :headers="headers"
      :accept="accept"
      :drag="drag"
      :name="name"
      :file-list="fileList"
      :auto-upload="autoUpload"
      :multiple="multiple"
      :limit="limit"
      ref="upload"
      :class="isVideo ? 'video' : ''"
      :list-type="listType"
      :on-preview="previewFile"
      :on-remove="removeFile"
      :on-success="uploadSuccess"
      :on-error="uploadFailure"
      :on-exceed="uploadExceed"
      :before-upload="beforeUpload"
      :readonly="readonly"
      :disabled="readonly"
      :filesize="filesize"
      :http-request="httpRequest"
    >
      <el-button v-show="!drag && !readonly" size="small" type="primary">点击上传</el-button>
      <div v-show="!drag && !readonly && showTips" slot="tip" class="el-upload__tip">
        {{ tips }}
      </div>
      <i v-show="drag" class="el-icon-upload"></i>
      <div v-show="drag" class="el-upload__text">
        将文件拖到此处，或<em>点击上传</em>
      </div>
      <div v-show="drag" class="el-upload__tip" slot="tip">{{ tips }}</div>
    </el-upload>
  </div>
</template>
<script>
import { setUploadParam } from "./ossUpload";
import axios from "axios";
//图片压缩库
import Compressor from "compressorjs";
export default {
  methods: {
    removeFile(file, fileList) {
      console.log(file);
      //上传文件删除方法
      this.$emit("update:fileList", fileList);
      this.$emit("removeFileList", fileList);
    },
    previewFile(file) {
      //上传文件预览方法
      window.open(file.url);
    },
    beforeUpload(file) {
      const size = file.size / 1024 / 1024;
      if (this.filesize < size) {
        this.commonUtil.showMessage({
          message: this.commonUtil.getMessageFromList("error.upload.size", [
            this.filesize,
          ]),
          type: this.commonConstants.messageType.error,
        });
        return false;
      }
      if (
        this.accept == "" ||
        this.accept == "*" ||
        this.accept == "*.*" ||
        this.accept == "image/*"
      ) {
        return true;
      } else {
        let fileSuffix = file.name.substring(file.name.lastIndexOf("."));
        if (this.accept.toUpperCase().indexOf(fileSuffix.toUpperCase()) >= 0) {
          return true;
        } else {
          this.commonUtil.showMessage({
            message: this.commonUtil.getMessageFromList("error.upload.type", [
              file.name,
              this.accept,
            ]),
            type: this.commonConstants.messageType.error,
          });
          return false;
        }
      }
    },
    uploadSuccess(response, file, fileList) {
      //上传文件预览方法
      console.log("res", response, file, fileList);
      if (response.code == "200") {
        this.$emit("update:fileUrl", response.url);
        //jsx中使用
        this.$emit("updateFileUrl", response.url);
        file.url = response.url;
        delete file["response"];
        this.$emit("update:fileList", fileList);
        this.$emit("updateFileList", fileList);
        this.$parent.clearValidate(); //清空父组件的错误信息
      } else {
        if (fileList.length > 0) {
          for (let index = 0; index < fileList.length; index++) {
            const element = fileList[index];
            if ((element.uid = file.uid)) {
              fileList.splice(index, 1);
              break;
            }
          }
        }
        this.$emit("update:fileList", fileList);
        this.commonUtil.showMessage({
          message: this.commonUtil.getMessageFromList("error.upload", null),
          type: this.commonConstants.messageType.error,
        });
      }
      //  获取视频url对应的切图
      if (fileList[0] && this.isVideo) {
        let item = this.$refs["upload"].$el.children[3].children[0];

        item.style.background = `url(${
          fileList[0].url + "?x-oss-process=video/snapshot,t_10000,m_fast"
        })`;

        //    item.children[2].addEventListener()
      }
    },
    uploadFailure(
      err,
      file,
      fileList //文件上传失败
    ) {
      this.commonUtil.showMessage({
        message: this.commonUtil.getMessageFromList("error.upload", null),
        type: this.commonConstants.messageType.error,
      });
    },
    uploadExceed(files, fileList) {
      //文件超出个数限制
      this.commonUtil.showMessage({
        message: this.commonUtil.getMessageFromList("error.upload.exceed", [
          this.limit,
        ]),
        type: this.commonConstants.messageType.error,
      });
    },
    compressed(blob,quality=0.6){
      return new Promise((resolve,reject)=>{
        new Compressor(blob, {
          quality,
          success(result) {
            resolve(result);
          },
        });
      })
    },
    httpRequest(item) {
      const formData = new FormData();
      let CancelToken = axios.CancelToken;
      let cancel = null;
      let obj = {
        headers: {
          "Content-Type": "multipart/form-data",
        },
        method: "post",
        data: formData,
        cancelToken: new CancelToken(function executor(c) {
          cancel = c;
        }),
        onUploadProgress: (progressEvent) => {
          const complete = parseInt(
            ((progressEvent.loaded / progressEvent.total) * 100) | 0,
            10
          );
          // 重点二：onProgress()方法需要以上方接收的形参来调用
          // 这个方法有一个参数"percent"，给他进度值 complete 即可
          try {
            item.onProgress({ percent: complete });
          } catch (err) {
            cancel();
          }
        },
      };


      //如果启用压缩，返回一个压缩地址
      if(this.enableImageCompressor==true){
        this.compressed(item.file)
        .then((result)=>{
          setUploadParam(obj, item.file.name);
          formData.append("file", result);
          axios(obj)
          .then((res) => {
            console.log("请求结束");
            item.onSuccess({ url: obj.resUrl, code: "200" });
          })
          .catch((err) => {
            console.log(err);
          });
        })
      }else{
        setUploadParam(obj, item.file.name);
        formData.append("file", item.file);
        axios(obj)
        .then((res) => {
          console.log("请求结束");
          item.onSuccess({ url: obj.resUrl, code: "200" });
        })
        .catch((err) => {
          console.log(err);
        });
      }

    },
  },
  props: {
    // action:{
    //    type: String,
    //     default: this.action
    // },
    accept: {
      type: String,
      default: "*",
    },
    isVideo: {
      type: Boolean,
      default: false,
    },
    drag: {
      type: Boolean,
      default: false,
    },
    multiple: {
      type: Boolean,
      default: true,
    },
    limit: {
      type: Number,
      default: 1,
    },
    filesize: {
      type: Number,
      default: 1000,
    },
    name: {
      type: String,
      default: "file",
    },
    fileUrl: {
      //单张图片图片地址
      type: String,
    },
    fileList: {
      type: Array,
      default() {
        return [];
      },
    },
    listType: {
      type: String,
      default: "picture",
    },
    formitemRef: {
      type: String,
      default: "upload",
    },
    autoUpload: {
      type: Boolean,
      default: true,
    },
    tips: {
      type: String,
      default: "请上传图片文件。",
    },
    readonly: {
      type: Boolean,
      default: false,
    },
    showTips:{
      type:Boolean,
      default:true
    },
    //启用图片压缩,启用后返回一个压缩地址
    enableImageCompressor:{
      type:Boolean,
      default:false
    }
  },
  data() {
    return {
      action: this.$uploadUrl,
      headers: {
        Authorization: localStorage.getItem(
          this.commonConstants.sessionItem.authorization
        ),
      },
    };
  },
  mounted() {
    //  获取视频url对应的切图
    if (this.fileList[0] && this.isVideo) {
      let item = this.$refs["upload"].$el.children[3].children[0];

      item.style.background = `url(${
        this.fileList[0].url + "?x-oss-process=video/snapshot,t_10000,m_fast"
      })`;

      //    item.children[2].addEventListener()
    }
  },
};
</script>
<style scoped lang="scss">
// 通过video样式仅修改对应的上传组件
.video {
  >>> .el-upload-list__item {
    background-size: cover !important;
    height: 200px;
  }
  >>> .el-upload-list__item-name {
    .el-icon-document::before {
      content: "";
    }
    background: url(~@/assets/img/play.svg);
    background-size: 100% 100%;
    height: 50px;
    margin: auto;
    width: 50px;
    padding-top: 200px;
    background-repeat: no-repeat;
  }
  >>> .el-upload-list__item-name:hover {
    background: url(~@/assets/img/play1.svg);
    background-size: 100% 100%;
  }
}
.upload-demo ::v-deep {
  .el-upload-list__item {
    transition: none !important;
  }
}
</style>