<template>
  <div class="largeFileUpload">
    <!-- <Upload
        ref="upload"
        :show-upload-list="false"
        :default-file-list="defaultList"
        :on-success="handleSuccess"
        :format="['jpg','jpeg','png']"
        :max-size="2048"
        :on-format-error="handleFormatError"
        :on-exceeded-size="handleMaxSize"
        :before-upload="handleBeforeUpload"
        :headers="headers"
        multiple
        type="drag"
        :action="action"
        class="uploadDiv"
        >
        <Button icon="ios-cloud-upload-outline">上传文件</Button>
    </Upload> -->
    <input 
      type="file" 
      class="fileInput"
      ref="largeFile"
      @change="handlerUpload"
    />
    <div class="filebutton">
      <Button icon="ios-cloud-upload-outline">上传文件</Button>
    </div>
    <div class="demo-upload-list" v-for="(item,index) in uploadList" :key="index">
        <template>
            <span>{{item.name +' -- '+ item.size}}</span>
            <Progress :percent="item.percentage"></Progress>
        </template>
    </div>
  </div>
</template>

<script>
import axios from '@/libs/api.request';

export default {
  name: 'largeFileUpload', // 组件名称
  data(){
    return {
      file: null,
      fileSuccess:{},
      data: [],
      filename: '',
      filesize: '',
      chunkSize:10 * 1024 * 1024, //切分文件片段大小
      fileindex:0,
      uploadList: [],
      uploadStates:[],
      headers: {
          token: localStorage.getItem('token'),
          timestamp: localStorage.getItem('timestamp'),
          nonce: localStorage.getItem('nonce'),
          sign: localStorage.getItem('sign')
      },
    }
  },
  props:[],
  methods: {
      //文件上传
      handlerUpload(){
        //单文件上传
        var _this = this;
        const file = this.$refs.largeFile.files[0];
        if(file){
          _this.file = file;
          _this.filename = _this.file.name + ' ';
          _this.filesize = _this.getFileSize(_this.file.size);//文件大小
          _this.file.filesize = _this.filesize;
          _this.uploadList = [];
          //判断文件是否已经上传
          var filetype = file.name.split('.')[1];
          var fileParaInfo = "totalSize="+file.size+"&fileName="+file.name+"&fileType=."+filetype+"&lastModified="+file.lastModified+"&fileChunkSize="+_this.chunkSize;
          var url = _this.axios.publicPath+"config/FileSystem/GetFileInfo?"+fileParaInfo;
          $.ajax({
              type: "get",
              url: url,
              dataType: "json",
              headers:_this.headers,
              async:true,
              contentType: false,//实体头部用于指示资源的MIME类型 media type 。这里要为false
              processData: false,//processData 默认为true，当设置为true的时候,jquery ajax 提交的时候不会序列化 data，而是直接使用data
              success: function (res) {
                  if(res.data.isHasUploaded){
                    _this.uploadList.push({
                      name:res.data.fileName,
                      size:_this.filesize,
                      percentage:100
                    })
                    _this.file.fileid = res.data.fileId;
                    _this.fileSuccess = _this.file;
                    _this.UpdateValue();
                    _this.$Message.success('文件上传成功')
                    return false;
                  }
                  else
                  {
                    _this.uploadStates = [];
                    _this.uploadList.push({
                      name:_this.filename,
                      size:_this.filesize,
                      percentage:0
                    })
                    //判断文件大小，小文件不切片,直接上传
                    if(_this.file.size <= _this.chunkSize)
                    {
                      var ckInfo = {
                          file:_this.file,
                          partName:_this.filename,
                          params:"total="+1+"&curIdx="+1+"&startSize="+0+"&endSize="+_this.file.size+"&totalSize="+_this.file.size+"&lastModified="+_this.file.lastModified
                      }
                      _this.doUploadFile(ckInfo,1);
                    }
                    else
                    {
                      //文件切片
                      const fileChunkList = _this.createFileChunk(_this.file);
                      var total = fileChunkList.length;
                      var index = 0;
                      this.fileindex = 0;
                      var ckInfo;
                      while (fileChunkList[index]) {
                        ckInfo = fileChunkList[index];
                        index++;
                        var partFileName = _this.filename + ".part-" + index;
                        ckInfo.partName = partFileName;
                        var params="total="+total+"&curIdx="+index+"&startSize="+ckInfo.start+"&endSize="+ckInfo.end+"&totalSize="+_this.file.size+"&lastModified="+_this.file.lastModified;
                        ckInfo.params = params;
                        _this.doUploadFile(ckInfo,total);
                      }
                    }
                  }
              },
              error: function (data) {
                  console.log("error:" + data);
              }
          });
        }
        else
        {
          this.$Message.error('请选择文件');
        }
      },
      //文件上传
      doUploadFile(chunkInfo,total){
        var formData = new FormData();
        formData.append("file", chunkInfo.file, chunkInfo.partName);
        var url = this.axios.publicPath+"config/FileSystem/Upload?" + chunkInfo.params;
        var _this = this;
        $.ajax({
            type: "post",
            url: url,
            dataType: "json",
            headers:this.headers,
            data: formData,
            async: true,
            contentType: false,//实体头部用于指示资源的MIME类型 media type 。这里要为false
            processData: false,//processData 默认为true，当设置为true的时候,jquery ajax 提交的时候不会序列化 data，而是直接使用data
            success: function (res) {
                _this.fileindex++;
                _this.uploadList[0].percentage = Math.floor(_this.fileindex/total*100) - 1;
                //当合并成功后显示上传成功
                //state 0待处理 1执行中 2数据合并成功 3失败 4异常报错
                _this.uploadStates.push(res.data.state)
                if(_this.uploadStates.indexOf(2)!=-1){
                  _this.uploadList[0].percentage = 100;
                  _this.file.fileid = res.data.fileId;
                  _this.fileSuccess = _this.file;
                  _this.UpdateValue();
                  _this.$Message.success('上传成功');
                }
                else
                {
                  if(_this.uploadStates.length === total){
                    _this.uploadList = [];
                    _this.$Message.error('上传失败，请重新上传');
                  }
                }
            },
            error: function (data) {
                console.log("error:" + data);
            }
        });
      },
      //文件切片
      createFileChunk(file){
        const fileChunkList = [];
        const chunkSize = this.chunkSize;
        let cur = 0;
        while (cur < file.size) {
            fileChunkList.push({
                file: file.slice(cur, cur + chunkSize),
                start: cur,
                end: cur + chunkSize < this.file.size ? cur + chunkSize : this.file.size
            })
            cur += chunkSize;
        }
        return fileChunkList;
      },
      //获取文件大小
      getFileSize(count){
        let str = '';
        if (count >= 1024 * 1024 * 1024) {
            str = Math.round(count / 1024 / 1024 / 1024 * 100) / 100 + 'G';
        } else if (count >= 1024 * 1024) {
            str = Math.round(count / 1024 / 1024 * 100) / 100 + 'MB';
        } else if (count >= 1024) {
            str = Math.round(count / 1024 * 100) / 100 + 'kb';
        } else {
            str = count + 'b';
        }
        return str;
      },
      UpdateValue(){
        this.$emit('getFileInfo',this.fileSuccess);
      }
  },
  mounted () {
      this.UpdateValue()
  }
}
</script>

<style lang="less">
  .largeFileUpload{
    margin-left:5px;
    .fileInput{
      width:100%;
      position:relative;
      opacity: 0;
      z-index: 100;
    }
    .filebutton{
      border:1px solid #dcdee2;
      border-radius: 3px;
      position: relative;
      top: -29px;
      margin-bottom:-20px;
      z-index: 99;
    }
    button{
      border:hidden;
      width:100%;
    }
    .demo-upload-list{
        // display: inline-block;
        display:block;
        margin-bottom:10px;
        width: 100%;
        height: 40px;
        text-align: left;
        line-height: 20px;
        // border: 1px solid transparent;
        border-radius: 4px;
        // overflow: hidden;
        overflow: inherit;
        background: #fff;
        position: relative;
        box-shadow:0px 0px 0px 0px rgba(0,0,0,0.2);
        margin-right: 4px;
    }
    .demo-upload-list img{
        width: 100%;
        height: 100%;
    }
    .demo-upload-list-cover{
        display: none;
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        background: rgba(0,0,0,.6);
    }
    .demo-upload-list:hover .demo-upload-list-cover{
        display: block;
    }
    .demo-upload-list-cover i{
        color: #fff;
        font-size: 20px;
        cursor: pointer;
        margin: 0 2px;
    }
  }

</style>