<template>
  <div class="aos-upload">
    <el-upload
      ref="aosUpload"
      v-if="edit"
      :action="action"
      :multiple="multiple"
      :data="data"
      :name="name"
      :limit="limit"
      :on-exceed="onExceed"
      :show-file-list="showFileList"
      :file-list="fileList"
      :auto-upload="autoUpload"
      :http-request="httpRequest"
      drag
      :before-upload="beforeUpload"
      :before-remove="beforeRemove"
      :on-success="onSuccess"
      :on-remove="onRemove"
      :on-error="onError"
      :on-progress="onProgress"
      :on-change="onChange"
      :disabled="disabled"
      :on-preview="handlePreviewClick"
    >
      <div>
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
      </div>
    </el-upload>
    <div style="padding: 10px 5px" v-if="!edit">
      <div
        class="aos-upload__view"
        v-for="(ele, index) in fileList"
        :key="index"
        @click.stop="handlePreviewClick(ele)"
      >
        <i class="el-icon-document"> </i>
        <span style="margin-left: 10px">{{ ele.name }}</span>
      </div>
    </div>
    <el-dialog
      title="播放器"
      :visible.sync="showVideDialog"
      append-to-body
      destroy-on-close
      width="30%"
      @close="handleVideoClose"
    >
      <div class="aos-upload__video">
        <aos-video ref="aos-upload__video" :options="videoOptions"> </aos-video>
      </div>
    </el-dialog>
  </div>
</template>

<script >
import Viewer from "viewerjs-optimize";
import { PopupManager } from "aos-element/src/utils/popup";
export default {
  name: "AosUpload",
  data() {
    return {
      copyData: {},
      showVideDialog: false,
      videoOptions: {},
      videoFileTypeList: ["mp4", "webm", "mov", "flv", "mp3", "wav", "ogg"],
      imgFileTypeList: [
        "png",
        "jpg",
        "jpeg",
        "gif",
        "tif",
        "tiff",
        "bmp",
        "svg",
        "webp",
        "ico",
      ],
      viewer: "",
      currentContainer: "",
      currentContainerId: "",
    };
  },
  watch: {
    data: {
      handler: function (val) {
        if (val) {
          this.copyData = this.$_.cloneDeep(val);
        } else {
          this.copyData = {};
        }
      },
      immediate: true,
      deep: true,
    },
  },
  props: {
    //必选参数，上传的地址
    action: {
      type: String,
      require: true,
    },
    //是否支持多选文件
    multiple: {
      type: Boolean,
      default: false,
    },
    //是否编辑状态
    edit: {
      type: Boolean,
      default: true,
    },
    //上传时附带的额外参数
    data: {
      type: Object,
    },
    //上传的文件字段名
    name: {
      type: String,
      default: "file",
    },
    //最大允许上传个数
    limit: {
      type: Number,
    },
    //文件超出个数限制时的钩子
    onExceed: {
      type: Function,
    },
    //是否显示已上传文件列表
    showFileList: {
      type: Boolean,
      default: true,
    },
    //是否在选取文件后立即进行上传
    autoUpload: {
      type: Boolean,
      default: true,
    },
    //覆盖默认的上传行为，可以自定义上传的实现
    httpRequest: {
      type: Function,
    },
    //上传文件之前的钩子，参数为上传的文件，若返回 false 或者返回 Promise 且被 reject，则停止上传。
    beforeUpload: {
      type: Function,
    },
    //删除文件之前的钩子，参数为上传的文件和文件列表，若返回 false 或者返回 Promise 且被 reject，则停止删除。
    beforeRemove: {
      type: Function,
    },
    //文件上传成功时的钩子
    onSuccess: {
      type: Function,
    },
    //文件列表移除文件时的钩子
    onRemove: {
      type: Function,
    },
    //文件上传失败时的钩子
    onError: {
      type: Function,
    },
    //文件上传时的钩子
    onProgress: {
      type: Function,
    },
    //文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
    onChange: {
      type: Function,
    },
    //是否禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    fileList: {
      type: Array,
      default: [],
    },
    //是否展示上传框
    edit: {
      type: Boolean,
      default: true,
    },
  },
  beforeDestroy() {
    if (this.viewer) {
      this.viewer = null;
    }
    this.removeContainer();
  },
  components: {},
  methods: {
    handlePreviewClick(file) {
      if (file) {
        const fileSuffix = file.name.split(".")[1].toLowerCase();
        if (this.videoFileTypeList.indexOf(fileSuffix) > -1) {
          this.handleViewVideo(file, fileSuffix);
        } else if (fileSuffix.indexOf(".pdf") > -1) {
          this.handleViewPdf(file);
        } else if (this.imgFileTypeList.indexOf(fileSuffix) > -1) {
          this.handleViewerImg(file);
        } else {
          this.handleDownloadFile(file);
        }
      }
    },
    handleViewVideo(item, data) {
      this.showVideDialog = true;
      this.videoOptions = {
        width: 400,
        sources: [
          {
            src: item.url,
            type: `video/${data}`,
          },
        ],
      };
    },
    handleVideoClose() {
      this.$refs["aos-upload__video"].destory();
    },
    handleViewPdf(item) {
      this.$openPdfViewer(item.url);
    },
    handleDownloadFile(item) {
      const fileName = item.name;
      this.$http({
        url: item.url,
        responseType: "blob",
      }).then((res) => {
        this.download(res.data, fileName);
      });
    },
    download(blob, name) {
      const a = document.createElement("a");
      const url = window.URL.createObjectURL(blob);
      a.href = url;
      a.download = name;
      document.body.appendChild(a);
      a.click();
      window.URL.revokeObjectURL(url);
      document.body.removeChild(a);
    },
    handleViewerImg(item) {
      console.log("item", item);
      this.removeContainer(item.uid);
      let container = this.currentContainer;
      if (this.viewer) {
        this.viewer.destroy();
        this.viewer = null;
      }
      if (
        !this.currentContainerId ||
        (this.currentContainer && this.currentContainer !== item.id)
      ) {
        container = this.createImgList(item, item.uid);
      }
      this.currentContainerId = item.uid;
      this.currentContainer = container;
      this.viewer = new Viewer(
        document.getElementById("aos-upload-" + this.currentContainerId),
        {
          className:
            "aos-img-viewer-container " +
            ("aos-upload-" + this.currentContainerId),
          zIndex: PopupManager.nextZIndex() + 101,
        }
      );
      container.children[0].click();
    },
    createImgList(item, id) {
      const container = document.createElement("div");
      container.id = "aos-upload-" + id;
      container.style.position = "absolute";
      container.style.top = "-10000px";
      container.style.left = "-10000px";
      if (item) {
        const imgItem = document.createElement("img");
        imgItem.src = item.url;
        imgItem.alt = item.name;
        imgItem.title = item.name;
        container.appendChild(imgItem);
      }
      document.body.appendChild(container);
      return container;
    },
    removeContainer(id) {
      const dom = document.getElementById(
        "aos-upload-" + this.currentContainerId
      );
      if (!id) {
        if (dom) {
          document.body.removeChild(dom);
        }
      } else if (this.currentContainerId && this.currentContainerId !== id) {
        if (dom) {
          document.body.removeChild(dom);
        }
      }
    },
  },
};
</script>

