<template>
  <div class="uploader-tool">
    <input type="file"
           ref="uploadBtn"
           multiple="true"
           v-show="false"
           @change="handleFileChange" />
    <!-- 上传 -->
    <uploader ref="uploader"
              :options="options"
              :auto-start="autoStart"
              :file-status-text="fileStatusText"
              @file-added="handleFileAdded"
              @file-removed="handleFileRemoved"
              @file-progress="handleFileProgress"
              @file-error="onFileError"
              @file-success="handleFileSuccess"
              class="uploader-app">
      <uploader-unsupport></uploader-unsupport>

      <!--       <uploader-btn v-show="false"
                    :attrs="attrs"
                    ref="uploadBtn">选择文件</uploader-btn> -->

      <uploader-list v-show="panelShow">
        <div class="file-panel"
             slot-scope="props"
             :class="{'collapse': collapse}">
          <div class="file-title">
            <h3>上传文件列表</h3>
            <div class="operate">
              <Icon type="ios-cloud-upload"
                    size='18'
                    @click="startUpdate"
                    v-tip="`开始上传`" />
              <Button @click="close"
                      type="text"
                      title="关闭"
                      size="small">
                <Icon type="md-close"
                      size="20" />
              </Button>
            </div>
          </div>

          <ul ref="uploaderFileList"
              class="file-list">
            <li v-for="file in props.fileList"
                :key="file.id"
                :class="[`${file.errorMsg!==''?'uploader-file-error':''}`]">
              <uploader-file :class="[`file_${file.id}`]"
                             ref="files"
                             :file="file"
                             :list="true"></uploader-file>
              <span v-if="file.errorMsg!==''"
                    v-tip="file.error"
                    style="position:absolute;right:5px;">{{file.errorMsg}}</span>
            </li>
            <div class="no-file"
                 v-if="!props.fileList.length">
              <i class="iconfont icon-empty-file"></i> 暂无待上传文件
            </div>
          </ul>
        </div>
      </uploader-list>

    </uploader>

  </div>
</template>

<script>
import photoCompress from './photoCompress.js'
let FILE_ITEM = ''
const image = ['.png', '.jpg', '.jpeg', '.gif', '.bmp']
const video = ['.mp4', '.rmvb', '.mkv', '.wmv', '.flv']
const document = ['.cfg', '.doc', '.docx', '.xls', '.xlsx', '.et', '.wps', '.ppt', '.pptx', '.pdf', '.txt', '.tif', '.tiff', '.ceb']
export default {
  name: 'UploaderTool',
  props: {
    // 上传文件接收地址
    uploadPath: {
      type: String,
      default: ''
    },
    params: {
      type: Object,
      default: () => { }
    },
    headers: {
      type: Object,
      default: () => { }
    },
    autoZipImg: {
      type: Boolean,
      default: true
    }
  },
  data () {
    return {
      autoStart: true,
      options: {
        target: this.uploadPath,
        query: () => {
          const params = { ...this.params }
          this.params.fjxh = this.params.fjxh + 1
          return {
            ...params
          }
        },
        chunkSize: '20480000000',
        fileParameterName: 'upfile',
        maxChunkRetries: 3,
        testChunks: false, // 是否开启服务器分片校验
        parseTimeRemaining: function (timeRemaining, parsedTimeRemaining) {
          const info = parsedTimeRemaining
            .replace(/\syears?/, '年')
            .replace(/\days?/, '天')
            .replace(/\shours?/, '小时')
            .replace(/\sminutes?/, '分钟')
            .replace(/\sseconds?/, '秒')
          return info
        },
        headers: this.headers
      },
      attrs: {
        accept: [...image, ...video, ...document]
      },
      collapse: false,
      // 上传文件列表
      fileList: [],
      timeString: false
    }
  },
  computed: {
    // Uploader实例
    uploader () {
      return this.$refs.uploader.uploader
    },
    panelShow () {
      return this.fileList.length > 0
    }/* ,
    djid() {
      return this.params.djid
    } */
  },
  watch: {
    uploadPath () {
      this.options.target = this.uploadPath
    },
    headers: {
      deep: true,
      handler () {
        this.options.headers = this.headers
      }
    }/* ,
    djid() {
      this.options.query.djid = this.djid
    },
    params: {
      deep: true,
      handler(newVal, oldVal) {
        // this.options.query.djlxguid = this.params.djlxguid
        this.options.query = Object.assign(this.options.query, this.params)
      }
    } */
  },
  methods: {
    startUpdate () {
      this.fileList.forEach(file => file.resume())
    },
    getFileExt (fileName) {
      const nameSplit = fileName.split('.')
      return nameSplit[nameSplit.length - 1]
    },
    openUploader () {
      if (this.$refs.uploadBtn) {
        // token有时过期
        this.options.headers.Authorization = sessionStorage.getItem('Authorization')
        this.$refs.uploadBtn.click()
      }
    },
    async handleFileChange (evt) {
      /*
      let file = evt.target.files[0]
      const fileType = file.name.split('.')[1]
      if (this.autoZipImg && image.includes(`.${fileType}`)) {
        const compressFile = await photoCompress(file, { mimeType: file.type, width: 1500, height: 1500, quality: 0.7 })
        file = new File([compressFile], file.name, {
          type: file.type
        })
      }
      this.$refs.uploader.uploader.addFile(file)
      */
      const files = evt.target.files
      files.forEach(async (file) => {
        const fileType = file.name.split('.')[1]
        if (this.autoZipImg && image.includes(`.${fileType}`)) {
          // console.log('文件压缩')
          const compressFile = await photoCompress(file, {
            mimeType: file.type,
            width: 1500,
            height: 1500,
            quality: 0.7
          })
          file = new File([compressFile], file.name, {
            type: file.type
          })
        }
        await this.$refs.uploader.uploader.addFile(file)
        // this.options.query.fjxh = this.options.query.fjxh + 1
      })
      evt.target.value = ''
    },
    handleFileAdded (file) {
      file.uniqueIdentifier = this.$utils.guid()
      if (FILE_ITEM) {
        FILE_ITEM.uniqueIdentifier = file.uniqueIdentifier
        FILE_ITEM = null
      }
      file.gxGuid = file.uniqueIdentifier
      file.fileType = this.getFileExt(file.name)
      file.FILE_CLASS = this.params.fjlxguid
      // file.name = file.name.substring(0, file.name.length - file.fileType.length - 1)
      this.fileList.push(file)
      this.params['gxGuid'] = file.gxGuid
    },
    handleFileRemoved (file) {
      if (!this.timeString) {
        this.removeFile(file)
      }
    },
    removeFile (file) {
      this.timeString = true
      const idx = this.fileList.findIndex(f => f.uniqueIdentifier === file.uniqueIdentifier)
      const UploaderInatance = this.$refs.uploader.uploader
      // console.log(idx)
      if (idx >= 0) {
        UploaderInatance.removeFile(this.fileList[idx])
        this.fileList.splice(idx, 1)
      }
      this.timeString = false
    },
    handleFileProgress (rootFile, file, chunk) {

    },
    handleFileSuccess (rootFile, file, response, chunk) {
      let res = JSON.parse(response)
      // 服务器自定义的错误（即虽返回200，但是是错误的情况），这种错误是Uploader无法拦截的
      file.errorMsg = ''
      if (res.status === 500) {
        file.errorMsg = res.msg
        file.error = res.msg
        return false
      }
      file.fileType = this.getFileExt(file.name)

      this.$emit('on-success', file)
      this.removeFile(file)
    },
    onFileError (rootFile, file, response, chunk) {
      let res = JSON.parse(response)
      file.error = res.message
    },
    fileStatusText (status, response) {
      // console.log(status, response, '上传结果')
      const statusTextMap = {
        success: '成功',
        error: '失败',
        uploading: '上传中',
        paused: '等待中',
        waiting: '暂停'
      }
      if (response && response.status === 500) {
        status = 'error'
        return '上传失败'
      }
      if (response && (status === 'success' || status === 'error')) {
        return response.data
      } else {
        return statusTextMap[status]
      }
    },
    close () {
      this.uploader.cancel()
      this.fileList = []
    },
    addFile (fileList) {
      if (Array.isArray(fileList) && fileList.length === 1) {
        FILE_ITEM = fileList[0]
      }
      const UploaderInatance = this.$refs.uploader.uploader
      for (let i = 0, len = fileList.length; i < len; i++) {
        UploaderInatance.addFile(fileList[i])
      }
    }
  },
  mounted () {
    this.options.target = this.uploadPath
  }
}
</script>

<style scoped lang="less">
.uploader-tool {
  position: fixed;
  z-index: 20;
  right: 15px;
  bottom: 15px;
  .uploader-app {
    width: 520px;
  }
  .file-panel {
    background-color: #fff;
    border: 1px solid #e2e2e2;
    border-radius: 7px 7px 0 0;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
    .file-title {
      display: flex;
      height: 40px;
      line-height: 40px;
      padding: 0 5px 0 15px;
      border-bottom: 1px solid #ddd;
      .operate {
        flex: 1;
        text-align: right;
      }
    }
    .file-list {
      position: relative;
      height: 240px;
      overflow-x: hidden;
      overflow-y: auto;
      background-color: #fff;
      > li {
        background-color: #fff;
      }
    }
    &.collapse {
      .file-title {
        background-color: #e7ecf2;
      }
    }
  }
  .no-file {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 16px;
  }
  /*   /deep/.uploader-file-icon {
    &:before {
      content: '' !important;
    }
    &[icon='image'] {
      background: url(./images/image-icon.png);
    }
    &[icon='video'] {
      background: url(./images/video-icon.png);
    }
    &[icon='document'] {
      background: url(./images/text-icon.png);
    }
  } */
  /deep/.uploader-file-actions > span {
    margin-right: 6px;
  }
  .uploader-file-error .uploader-file-progress {
    background: rgba(240, 158, 158, 0.6);
  }
}
</style>
