<template>
  <div class="component-upload-image img-accessory-1">
    <div class="img-box-1" :class="low && 'low'">

      <ul class="el-upload-list el-upload-list--picture-card">
        <li v-for="(item, index) in previewList" class="el-upload-list__item is-ready" style="float: left;">
          <auth-img v-if="!isPublic" :auth-src="item.thumbUrl" image-width="80px" image-height="78px"></auth-img>
          <el-image v-if="isPublic" :src="item.thumbUrl" fit="contain" style="width: 80px;height: 78px;border-radius: 4px;"></el-image>
          <label class="el-upload-list__item-status-label"><i class="el-icon-upload-success el-icon-check"></i></label>
          <span class="el-upload-list__item-actions">
            <span class="el-upload-list__item-preview"><i class="el-icon-zoom-in" @click="handlePreview(item)"></i></span>
            <span class="el-upload-list__item-delete"><i class="el-icon-delete" @click="handleDelete(item)"></i></span>
          </span>
        </li>
      </ul>
      <el-upload
        :action="fileSaveUrl"
        list-type="picture-card"
        :data="reqData"
        :on-success="fileUploadSuccess"
        :before-upload="handleBeforeUpload"
        :limit="limit"
        :on-error="handleUploadError"
        :on-exceed="handleExceed"
        name="file"
        multiple
        :on-remove="handleRemove"
        :show-file-list="false"
        :headers="headers"
        :http-request="reqUploadImage"
        :file-list="previewList"
        :on-preview="handlePictureCardPreview"
        :auto-upload="true"
        :class="{hide: this.fileList.length >= this.limit}">
        <i class="el-icon-plus"></i>

      </el-upload>

    </div>
    <!-- 上传提示 -->
    <!-- <div class="el-upload__tip" slot="tip" v-if="showTip">
      请上传
      <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
      <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
      的文件
    </div> -->
    <el-dialog :visible.sync="dialogVisible" title="预览" width="800" append-to-body>
      <div style="display: block; max-width: 100%; margin: 0 auto;text-align: center;max-height: 435px;overflow: auto;">
        <auth-img v-if="!isPublic && dialogVisible" :auth-src="dialogImageUrl" image-width="435px" ></auth-img>
        <img v-if="isPublic" :src="dialogImageUrl" style="display: block; max-width: 100%; margin: 0 auto" />
      </div>

    </el-dialog>
  </div>
</template>

<script>
  import {
    getToken,
    getSign
  } from "@/utils/auth";
  import {
    randomStr20
  } from '@/utils/util'
  import {
    privateFileSaveUrl,
    publicFileSaveUrl,
    publicFileSaveAPI,
    privateFileSaveAPI,
    publicFileGetUrl,
    privateFileGetUrl
  } from '@/api/common'

  import AuthImg from "@/components/AuthImg/index.vue"
  import UploadImg from "@/components/UploadImg/index.vue"


  export default {
    components: {
      AuthImg,
      UploadImg
    },
    props: {
      // 已经上传的文件url列表
      value: [String, Object, Array],
      // 图片数量限制
      limit: {
        type: Number,
        default: 5,
      },
      // 大小限制(MB)
      fileSize: {
        type: Number,
        default: 5,
      },
      // 文件类型, 例如['png', 'jpg', 'jpeg']
      fileType: {
        type: Array,
        default: () => ["png", "jpg", "jpeg"],
      },
      // 是否显示提示
      isShowTip: {
        type: Boolean,
        default: true
      },
      // 是否显示提示
      isPublic: {
        type: Boolean,
        default: true
      },
      // 半高显示
      low: {
        type: Boolean,
        default: false
      }
    },
    data() {
      return {
        dialogImageUrl: "",
        dialogVisible: false,
        hideUpload: false,
        baseUrl: process.env.VUE_APP_BASE_API,
        uploadImgUrl: this.isPublic ? publicFileSaveUrl : privateFileSaveUrl, // 上传的图片服务器地址
        fileSaveUrl: '',
        headers: {
          Authorization: "Bearer " + getToken(),
        },
        fileList: [],
        previewList: [],
        reqData: {}
      };
    },
    watch: {
      value(val) {
        if (val) {
          this.initHandle()
        }
      }
    },
    computed: {
      // 是否显示提示
      showTip() {
        return this.isShowTip && (this.fileType || this.fileSize);
      }
    },
    created() {
      this.initHandle()
    },
    methods: {

      initHandle() {
        if (this.value) {
          // 首先将值转为数组
          const list = Array.isArray(this.value) ? this.value : this.value.split(',')
          // 然后将数组转为对象数组
          this.previewList = []
          this.fileList = list.map(item => {
            var pitem = {
              name: item.fileName,
              url:  (this.isPublic ? publicFileGetUrl : (this.baseUrl + privateFileGetUrl)) + item.fileName,
              thumbUrl:  (this.isPublic ? publicFileGetUrl : (this.baseUrl + privateFileGetUrl)) + item.fileName + "?imageView2/2/w/375"
            };
            this.previewList.push(pitem)
            return item;
          });
        } else {
          this.previewList = []
          this.fileList = []
        }
      },


      handlePreview(item){
        this.dialogVisible = true;
        this.dialogImageUrl = item.url

      },

      handleDelete(item){
        const findex = this.fileList.map(f => f.fileName).indexOf(item.name);
        this.fileList.splice(findex, 1);
        this.previewList.splice(findex, 1);
        this.$emit("input", this.fileList);
        this.$emit('change')
      },

      // 删除图片
      handleRemove(file, fileList) {
        const findex = this.fileList.map(f => f.name).indexOf(file.name);
        this.fileList.splice(findex, 1);
        this.previewList.splice(findex, 1);
        this.$emit("input", this.fileList);
        this.$emit('change')
      },

      /**
       * 上传图片
       */
      fileUploadSuccess(response, file, fileList) {
        this.fileList.push({
          fileName: response.fileName,
          fileType: response.fileType
        });
        this.previewList.push({
          name: response.fileName,
          url:  (this.isPublic ? publicFileGetUrl : (this.baseUrl + privateFileGetUrl)) + response.fileName,
          fileType: response.fileType
        });
        this.$emit("input", this.fileList);
        this.$emit('change')
        this.loading.close();

      },

      // 上传前loading加载
      handleBeforeUpload(file) {
        let isImg = false;
        if (this.fileType.length) {
          let fileExtension = "";
          if (file.name.lastIndexOf(".") > -1) {
            fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
          }
          isImg = this.fileType.some(type => {
            if (file.type.indexOf(type) > -1) return true;
            if (fileExtension && fileExtension.indexOf(type) > -1) return true;
            return false;
          });
        } else {
          isImg = file.type.indexOf("image") > -1;
        }

        if (!isImg) {
          this.$message.error(
            `文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`
          );
          return false;
        }
        if (this.fileSize) {
          const isLt = file.size / 1024 / 1024 < this.fileSize;
          if (!isLt) {
            this.$message.error(`上传图片大小不能超过 ${this.fileSize} MB!`);
            return false;
          }
        }
        this.getHttpHeader()
        this.loading = this.$loading({
          lock: true,
          text: "上传中",
          background: "rgba(0, 0, 0, 0.7)",
        });
      },

      // 自定义文件上传的实现
      reqUploadImage(param) {
        var data = this.reqData || {}
        var params = {
          file: param.file,
          ...data
        }
        const request = this.isPublic ? publicFileSaveAPI : privateFileSaveAPI
        request(params, this.headers).then(response => {
          var res = {
            fileName: response.data.fileName,
            fileType: response.data.fileType
          }
          this.fileList.push({
            fileName: response.data.fileName,
            fileType: response.data.fileType
          });
          this.previewList.push({
            name: response.data.fileName,
            url:  (this.isPublic ? publicFileGetUrl : (this.baseUrl + privateFileGetUrl)) + response.data.fileName,
            fileType: response.fileType
          });
          this.$emit("input", this.fileList);
          this.$emit('change')
          this.loading.close();


          // 但是我们上传成功了图片， fileList 里面的值却没有改变，还好有on-change指令可以使用
        }).catch(response => {
          param.onError()
        })
      },

      // 请求头
      getHttpHeader() {
        let timestamp = parseInt(new Date().getTime()),
          nonce = randomStr20();
        var sign = getSign(this.reqData || {}, timestamp)
        let url = this.uploadImgUrl + '?sign=' + sign + '&nonce=' + nonce;
        this.fileSaveUrl = url
        var headers = {
          "Authorization": "Bearer " + getToken(),
          "x-zz-timestamp": timestamp
        }
        this.headers = headers
      },

      // 文件个数超出
      handleExceed() {
        this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
      },
      // 上传失败
      handleUploadError() {
        // this.$message({
        //   type: "error",
        //   message: "上传失败",
        // });
        this.loading.close();
      },
      // 预览
      handlePictureCardPreview(file) {
        this.dialogImageUrl = file.url;
        this.dialogVisible = true;
      },
      // 对象转成指定字符串分隔
      listToString(list, separator) {
        let strs = "";
        separator = separator || ",";
        for (let i in list) {
          strs += list[i].url.replace(this.baseUrl, "") + separator;
        }
        return strs != '' ? strs.substr(0, strs.length - 1) : '';
      }
    }
  };
</script>
<style scoped lang="scss">
  // .el-upload--picture-card 控制加号部分
  ::v-deep.hide .el-upload--picture-card {
    display: none;
  }

  // 去掉动画效果
  ::v-deep .el-list-enter-active,
  ::v-deep .el-list-leave-active {
    transition: all 0s;
  }

  ::v-deep .el-list-enter,
  .el-list-leave-active {
    opacity: 0;
    transform: translateY(0);
  }


  .img-accessory-1 {
    padding: 0 1px;
    font-size: 12px;

    img {
      width: 16px;
      vertical-align: middle;
    }

    .img-box-1 ::v-deep .el-upload {
      width: 80px;
      height: 80px;
      line-height: 90px;
    }

    .img-box-1 ::v-deep .el-upload-list {
      .el-upload-list__item {
        width: 80px;
        height: 80px;
      }
    }

    .img-box-1 {
      position: relative;
      margin-top: 0px;

      .add-img {
        position: absolute;
        left: 0;
        top: -30px;
        height: 20px;
        line-height: 20px;
        margin-bottom: 10px;
        color: #2362FB;
      }
    }

    .add-accessory-1 {
      margin-top: 25px;
      margin-bottom: 20px;
      color: #2362FB;

      .wukong-file {
        font-size: 13px;
      }
    }
  }

  .el-upload-litem-actions{
        position: absolute;
        width: 80px;
        height: 78px;
        left: 0;
        top: 0;
        cursor: default;
        text-align: center;
        color: #fff;
        opacity: 0;
        font-size: 20px;
        background-color: rgba(0,0,0,.5);
        -webkit-transition: opacity .3s;
        transition: opacity .3s;
        border-radius: 4px;
  }

  .el-upload-item-actions span {
      display: none;
      cursor: pointer;
  }

  [class^=el-icon-], [class*=" el-icon-"] {
      font-family: "element-icons" !important;
      speak: none;
      font-style: normal;
      font-weight: normal;
      font-variant: normal;
      text-transform: none;
      line-height: 1;
      vertical-align: baseline;
      display: inline-block;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
  }

  .el-upload-litem-actions .el-upload-item-delete {
      position: static;
      font-size: inherit;
      color: inherit;
  }

  .el-upload-litem-actions .el-upload-item-preview {
      position: static;
      font-size: inherit;
      color: inherit;
  }


  .el-upload-litem-actions:hover {
      opacity: 1;
  }

  .el-icon-zoom-in:before {
      content: "\E777";
  }

  .el-icon-delete:before {
      content: "\E6D7";
  }



  .el-upload-item-actions:hover span {
      display: inline-block;
  }

  .el-upload-item-actions:hover .el-upload-item-preview {
      position: absolute!important;
      left: 10px!important;
      top: 0!important;
      color: #666;
      display: block;
  }

  .el-upload-item-actions:hover .el-upload-item-delete {
      position: absolute!important;
      right: 10px!important;
      top: 0!important;
      color: #666;
      display: block;
  }
</style>
<style lang="scss">
.component-upload-image {
  .low {
    height: 40px;
    .el-upload--picture-card {
      height: 40px !important;
      line-height: 50px !important;
    }
    .el-upload-list__item {
      margin: 0 !important;
      height: 40px !important;
    }
    .el-image {
      height: 38px !important;
    }
    .el-upload-list__item-actions {
      height: 38px !important;
    }
  }
}
</style>