<template>
  <div id="upload-component"
       class="uploadComponent">
    <template v-if="!readonly">
      <el-upload :class="style"
                 :action="actionUrl"
                 multiple
                 :accept="accept"
                 :data="data"
                 :headers="headers"
                 :on-exceed="handleExceed"
                 :on-progress="handleProgress"
                 :on-success="handleSuccess"
                 :on-error="handleError"
                 :before-upload="handleBeforeUpload"
                 :show-file-list="!!uploadFileList.length&&showFileList"
                 :file-list="uploadFileList">
        <el-button :size="buttonSize"
                   type="primary">{{buttonText}}</el-button>
      </el-upload>
    </template>
  </div>
</template>

<script>
import { reqDeleteFile } from './api'

export default {
  name: 'UploadImport',

  props: {
    showFileList: {
      type: Boolean,
      default: function () {
        return true
      }
    },
    // 文件list
    uploadFileList: {
      type: Array,
      default: function () {
        return []
      }
    },

    uploadObject: {
      type: Object,
      default: function () {
        return {}
      }
    },

    // 单个文件的key
    fileKey: {
      type: String,
      default: function () {
        return ''
      }
    },

    // 单个文件的链接
    coverUrl: {
      type: String,
      default: function () {
        return ''
      }
    },

    // 文件类型
    fileType: {
      type: String,
      default: function () {
        return 'text'
      }
    },

    // 按钮size
    buttonSize: {
      type: String,
      default: 'small'
    },

    // 按钮文本
    buttonText: {
      type: String,
      default: '本地上传'
    },

    // 详情
    readonly: {
      type: Boolean,
      default: function () {
        return false
      }
    },

    // 文件夹key
    folderKey: {
      type: String,
      default: function () {
        return ''
      }
    },

    // 上传单个文件不得超过2G
    maxFileSize: {
      type: Number,
      default: function () {
        return 2000
      }
    },
    action: {
      type: String,
      default: ''
    },
  },

  data () {
    return {
      limit: 1, // 最大允许上传个数
      headers: {
        token: localStorage.getItem('token') // 获取token
      },
      data: {
        folderKey: this.folderKey
      },
      imageUrl: '',
      fileList: []
    }
  },

  created () {
    // 如果是封面上传对象 添加时候修改
  },

  computed: {
    accept () {
      if (this.fileType === 'picture-card' || this.fileType === 'avatar') {
        return '.jpg,.jpeg,.png,.gif,.bmp,.JPG,.JPEG,.PBG,.GIF,.BMP'
      }else if(this.fileType === 'excel'){
        return '.xlsx,.xls'
      }
      return ''
    },
    style () {
      if (this.fileType === 'avatar') {
        return 'avatar-uploader'
      } else if (this.readonly) {
        return 'readonly'
      }
      return 'upload-demo'
    },
    actionUrl() {
      let url = this.action || window.ajaxBase.uploadFileUrl;
      return url
    },
  },

  components: {},

  methods: {
    handleProgress (event, file, fileList) {
      
      let tempArr = this.uploadFileList
      this.uploadFileList.forEach((element, index) => {
        if (element.uid === file.uid) {
          // 更新这个uid下的进度
          const progress = Math.floor(event.percent)
          const loaded = event.loaded
          const timeStamp = event.timeStamp
          let mark = false
          let speed = element.speed
          let diffTime = 0
          if (element.timeStamp > 0) {
            diffTime = timeStamp - element.timeStamp
            if (diffTime >= 1000) {
              mark = true
              speed = Math.floor(
                (1000 * (loaded - element.loaded)) /
                  (timeStamp - element.timeStamp)
              )
            }
          } else {
            mark = true
          }
          // 防止上传完接口还没有返回成功值，所以此处给定progress的最大值为99，成功的钩子中再置为100
          element.progress = progress === 100 ? 99 : progress
          element.speed = speed
          if (mark) {
            element.loaded = loaded
            element.timeStamp = timeStamp
          }
          this.$set(tempArr, index, element)
          this.$emit('changeFileList', tempArr)
        }
      })
    },

    /***
     * 添加数据
     */
    objAddItem (tempArr, file) {
      const tempObj = {
        uid: file.uid, // uid用于辨别文件
        originalName: file.name, // 列表显示的文件名
        progress: 0, // 进度条
        speed: 0, // 上传速度
        timeStamp: 0, // 时间戳
        loaded: 0 // 已上传
      }
      tempArr.push(tempObj)
      this.$emit('changeFileList', tempArr)
    },

    /**
     * 文件超出个数限制时的钩子
     */
    handleExceed (files, fileList) {
      if (files.length > this.limit) {
        this.$message.error(`最多允许上传${this.limit}个文件`)
        return false
      }
    },

    handleBeforeUpload (file) {
      // 文件大小限制
      const result = file.size / 1024 / 1024 < this.maxFileSize
      if (!result) {
        this.$message.warning(`上传文件大小不得超过${this.maxFileSize}M`)
        return result
      }
      this.$emit('onUploadBefore', file)
      // 验证都通过后，给自定义的列表中添加需要的数据
      this.objAddItem(this.uploadFileList, file)
    },

    handleSuccess (response, file, fileList) {
      let tempArr = this.uploadFileList
      this.uploadFileList.forEach((element, index) => {
        if (element.uid === file.uid) {
          if (response.success) {
            const { key, url, sourceUrl, name } = response.data.rows[0]
            element.progress = 100
            element.key = key
            element.url = url
            element.sourceUrl = sourceUrl
            element.name = name
            this.$set(tempArr, index, element)

            // 封面
            if (
              this.fileType === 'avatar' ||
              this.fileType === 'oneFile' ||
              this.fileType === 'img-article'
            ) {
              this.$emit('update:fileKey', element.key)
              this.$emit('update:coverUrl', element.url)
              if (tempArr.length > 1) {
                // 判断是一张图片时候删除
                tempArr.splice(0, 1)
              }
            }
            this.$emit('onUploadSuccess', file, tempArr)
          } else {
            tempArr.splice(index, 1) // 上传失败删除该记录
            this.$message.error(
              `"${element.originalName}"上传失败,${response.message}`
            )
            this.$emit('onUploadFailed', file, tempArr)
          }
        }
      })
    },
    handleError (errorObj, file, fileList) {
      if (errorObj.message.indexOf('666') > 0) {
        this.$router.replace({
          name: 'login'
        })
        this.$message.warning('登录超时，请重新登录')
      }
      let tempArr = this.fileList
      this.fileList.forEach((element, index) => {
        if (element.uid === file.uid) {
          tempArr.splice(index, 1) // 上传失败删除该记录
          this.$message.error(`文件上传失败:${element.originalName}`)
          this.$emit('onUploadFailed', file, fileList)
        }
      })
    },

    async handleBeforeRemove (file, fileList) {
      if (this.fileType === 'avatar') {
        await reqDeleteFile(this.fileKey)
      } else {
        await reqDeleteFile(file.key)
      }
    },

    handleRemove (file, fileList) {
      this.fileList = fileList
    },
  }
}
</script>
<style lang="scss" scoped>
.uploadComponent {
  display: inline-block;
  .el-upload {
    .picture-card-box {
      width: 150px;
      height: 150px;
      border: 1px dashed #d9d9d9;
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
      i {
        font-size: 28px;
        color: #8c939d;
        width: 148px;
        height: 148px;
        line-height: 148px;
        text-align: center;
      }
    }
    .avatar-box {
      border: 1px dashed #d9d9d9;
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
      :hover {
        border-color: #409eff;
      }
      .avatar-uploader-icon {
        font-size: 28px;
        color: #8c939d;
        width: 148px;
        height: 148px;
        line-height: 148px;
        text-align: center;
      }
      .avatar {
        width: 148px;
        height: 148px;
        display: block;
      }
    }
  }
}

.readonyImg {
  width: 150px;
  height: 150px;
  .avatar-box {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    overflow: hidden;
    .avatar {
      width: 148px;
      height: 148px;
      display: block;
    }
  }
}

.uploadArticle {
  display: block;
  .article-box {
    width: 100%;
    position: relative;

    .progress-bxo {
      z-index: 200;
      width: 100%;
      position: absolute;
      top: 50%;
      left: 0px;
      z-index: 99;
      transform: translateY(-50%);
      -ms-transform: translateY(-50%);
      /* IE 9 */
      -moz-transform: translateY(-50%);
      /* Firefox */
      -webkit-transform: translateY(-50%);
      /* Safari 和 Chrome */
      -o-transform: translateY(-50%);
      /* Opera */
    }
    .progess-bxo-bg {
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      left: 0;
      z-index: 88;
      background: rgba(0, 0, 0, 0.3);
    }
  }
  img {
    width: 100%;
  }
}
</style>

<style lang="scss">
.readonly {
  .el-upload.el-upload--picture-card {
    display: none;
  }
}
.uploadArticle {
  .el-progress--circle {
    display: inline-block;
  }
  .el-progress-circle {
    margin-left: 12px;
    margin-top: 12px;
  }
  .el-progress__text {
    color: #ffffff;
    padding-left: 5px;
  }
}

.uploadComponent {
  .progress-bxo {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0px;
    left: 0px;
    z-index: 99;
    background: rgba(0, 0, 0, 0.3);
    .el-progress--circle {
      display: block;
    }
    .el-progress-circle {
      margin-left: 12px;
      margin-top: 12px;
    }
    .el-progress__text {
      color: #ffffff;
      padding-left: 5px;
    }
  }
}
</style>
