<template>
  <div>
	<el-dialog
		:visible.sync="diaShow"
		:close-on-click-modal="false"
		:modal-append-to-body='false'
    :title="diaTitle"
		@close="closeHandle"
		center top="10vh"
		width="800px">
			<div class="dialog-main">
				<el-form
				ref="diaForm"
				label-position="left"
				hide-required-asterisk
				:model="formData">
          <el-form-item label="所属目录" :rules="{required:true,message:'所属目录必填',trigger:'change'}" 
          prop="catalogue" label-width="76px">
            <el-cascader v-model="formData.catalogue" placeholder="请选择所属目录" clearable id="media-upload-cascader"
              :options="articleCatalogue" :props="{value:'MenuId',label:'MenuName',children:'Children',checkStrictly:true,emitPath:false}"
              style="width: 604px;"></el-cascader>
          </el-form-item>
				</el-form>
        <div class="file-upload-zone">
          <div class="file-upload-title">
            <span>文件数量：{{ fileList.length }} / {{ this.fileLimit }}</span>
            <span v-if="fileList.length>0" class="file-readdition" 
              :class="{'disable-readdition':!( (this.fileList.length+this.uploadingFileNames.length) <fileLimit)}" @click="uploadClick">继续添加</span>
          </div>
          <div class="file-upload-main" id="drop-upload-zone" @dragover="uploadDragover" @drop="uploadDrop">
            <el-table :data="fileList" id="file-list-table">
              <el-table-column label="文件名" prop="name" show-overflow-tooltip >
                <template slot-scope="{row}">
                  <span class="table-span">{{ row.name }}</span>
                </template>
              </el-table-column>
              <el-table-column label="大小" prop="sizeText" width="120">
                <template slot-scope="{row}" >
                  <span class="table-span">{{ row.sizeText }}</span>
                </template>
              </el-table-column>
              <el-table-column label="音/视频" prop="type" width="100">
                <template slot-scope="{row}">
                  <span class="table-span">{{ row.type }}</span>
                </template>
              </el-table-column>
              <el-table-column label="操作" prop="operation" width="60">
                <template slot-scope="{row,$index}">
                  <span class="table-button" @click="deleteFile($index)">删除</span>
                </template>
              </el-table-column>
                  <div slot="empty" class="no-file-show" @click="uploadClick">
                    <div class="upload-text"><span style="color:#0052D9 ;">点击/拖拽</span>本地音视频文件</div>
                    <div class="upload-message-box">
                      <div class="upload-message-row">支持音频格式：mp3、wav、m4a、amr、wma、aac、ogg-opus、flac</div>
                      <div class="upload-message-row">支持视频格式：mp4、flv、3gp</div>
                      <div class="upload-message-row">单个文件最长5小时、最大1GB,单次支持上传50个</div>
                    </div>
                  </div>
            </el-table>
          </div>
        </div>
        <div class="dia-bot">
          <el-button type="primary" plain style="margin-right:20px;min-width:120px ;" @click="cancelHandle">取消</el-button>
          <el-button type="primary" @click="saveHandle" style="min-width:120px;" :disabled="fileList.length==0">开始转写</el-button>
        </div>
        <!-- :http-request="handleUpload"
          :before-upload="handleBeforeUpload" -->
        <el-upload 
          ref="uploadRef" id="upload-media" style="display: none;"
          accept=".mp3,.wav,.m4a,.amr,.wma,.aac,.opus,.ogg,.flac,.mp4,.flv,.3gp"
          action="#" multiple :limit="fileLimit"
          :on-change="uploadMedia"
          :show-file-list="false"
          :auto-upload="false"
          :disabled="!((this.fileList.length+this.uploadingFileNames.length)<fileLimit)">
        </el-upload>
			</div>
		</el-dialog>
</div>
</template>

<script>
import {uploadFileDirect} from "@/utils/common.js"
import {asrInterface} from '@/api/modules/semanticsApi.js';
import MD5 from "js-md5";
  export default {
    name:"editTag",
    props:{
      diaShow:{
        type:Boolean,
        default:false
      },
      articleCatalogue:{
        type:Array,
        required:true
      }
    },
    watch:{
      uploadingFileNames(value){
        if(!(value && value.length>0)){
          if(this.uploadHint){
            this.uploadHint.close()
            this.uploadHint=null
          }
          if(this.closeDia) return 
          this.$message.success("上传完成，请检查转写列表")
        }
      },
      diaShow(value){
        if(value){
          this.current++
        }
      }
    },
    data() {
      return {
        current:0,
        diaTitle:'上传本地音视频文件',
        formData:{
          catalogue:''
        },
        fileLimit:50,
        fileExp:new RegExp(/\.(mp3|wav|m4a|amr|wma|aac|opus|ogg|flac|mp4|flv|3gp)$/,'i'),
        videoExp:new RegExp(/\.(mp4|flv|3gp)$/,'i'),
        fileList:[],
        uploadingFileNames:[],
        uploadHint:null,
        closeDia:false
      }
    },
    methods: {
      uploadClick(){
        if(!( (this.fileList.length+this.uploadingFileNames.length) < this.fileLimit)) return 
        $('#upload-media input').trigger('click')
      },
      uploadDragover(event){
        event.preventDefault(); //阻止默认行为，允许放置
      },
      uploadDrop(event){
        event.preventDefault(); //阻止浏览器默认行为
        // 获取文件的数据
        const DataTransferItemList = event.dataTransfer.files
        DataTransferItemList.forEach(file =>{
          file.raw=file
          setTimeout(()=>{
            this.uploadMedia(file)
          })
        })
      },
      async uploadMedia(file){
        // console.log(file,this.uploadingFileNames,'this.uploadingFileNames');
        let fileFront=file.name.split('.')[0]
  
        if(this.uploadingFileNames.some(item=> item == fileFront)){
          return this.$message.error(file.name+'同名文件正在上传，请稍后重试')
        }
        if(!(this.fileExp.test(file.name))){
          return this.$message.error(file.name+'格式不受支持')
        }
        if(!(file.size/1024/1024 < 1024.1)){
          return this.$message.error(file.name+'大小已超限')
        }

        let res = await this.checkDuration(file)
        if(!res.flag){
          return this.$message.error(res.msg);
        }
        
        let audioDuration = res.duration

        if(!( (this.fileList.length+this.uploadingFileNames.length) < this.fileLimit)){
          return this.$message.error(`上传文件已超过${this.fileLimit}个,${file.name}上传失败`)
        } 
        // 判断于 在库的文件名是否重名
        let flag=true
        let checkRes = await asrInterface.speechFlieRepetitionCheck({FileName:fileFront})
        if(checkRes.Ret == 200) flag=false
        if(flag) return 

        if(!this.uploadHint){
          this.uploadHint = this.$message({
            type:"info",
            message:'上传中，请勿关闭弹窗',
            duration:0,
            iconClass:'el-icon-loading'
          })
        }
        // 上传
        this.uploadingFileNames.push(fileFront)

        const t = new Date().getTime().toString();
        const temName = `asr/media/${process.env.NODE_ENV}/${MD5(t)}.${
          file.raw.type.split("/")[1]
        }`;
        let clientType = this.$setting.dynamicOutLinks.ObjectStorageClient ||
                  this.$store.state.dynamicOutLinks.ObjectStorageClient ||
                  JSON.parse(localStorage.getItem('dynamicOutLinks')).ObjectStorageClient
        let options={}
        if((file.size/1024/1024 > 100)){
          // 大于100MB，分片上传
          console.log("切片上传");
          // 上传的配置
          options={
            // 阿里云
            OSS:{
              // 设置并发上传的分片数量。
              parallel: 10,
              // 设置分片大小。默认值为1 MB，最小值为100 KB。
              partSize: 1024 * 1024 * 10, // 10MB
            },
            /**
             * minIO的上传方法自动将较大的文件进行分片，不需要特殊配置
             * 官网文档翻译文：单个对象的最大大小限制为5TB。putObject透明地将大于64MiB的对象分成多个部分上传。使用MD5SUM签名仔细验证上传的数据。
             */
            //S3
            S3:{
              partSize: 10 * 1024 * 1024, // 设置每个分片大小为10MB，默认为8MB。
              queueSize: 10, // 并发数，默认为4。
            }
          }
        }
        let windowNum=this.current
        uploadFileDirect(clientType,file.raw,temName,options).then(res=>{
          if(!this.diaShow || (this.current!=windowNum)) return 
          let item = {
            name:fileFront,
            fileUrl:res,
            sizeText:this.sizeFormat(file.size),
            size:file.size,
            type:this.videoExp.test(res)?"视频":"音频",
            duration:audioDuration || 0
          }
          this.fileList.push(item)
        }).finally(()=>{
          this.deleteUploadItem(fileFront)
        })
      },
      sizeFormat(s){
        let size = Number(s)
        if(size<1024){
          return size+'B'
        }else if(size<(1024*1024)){
          return Math.floor((size/1024)*100)/100 +'KB'
        }else{
          return Math.floor((size/1024/1024)*100)/100 +'MB'
        }
      },
      deleteUploadItem(name){
        let index = this.uploadingFileNames.findIndex(fileName=> fileName==name)
        if(index!=-1){
          this.uploadingFileNames.splice(index,1)
        }
      },
      checkDuration(file){
        return new Promise((resolve,reject)=>{
          try {
            let url = URL.createObjectURL(file.raw);
            
            let audioElement = new Audio(url);
            audioElement.addEventListener('loadeddata', () => {
              if(audioElement.duration>(60*60*5+1)){
                resolve({flag:false,msg:file.name+'时长已超限',duration:audioElement.duration})
              }else{
                resolve({flag:true,msg:'',duration:audioElement.duration})
              }
              URL.revokeObjectURL(url);
            });
            setTimeout(()=>{
              resolve({flag:false,msg:file.name+"获取不到时长，请重试"})
            },5000)
          } catch (error) {
            this.$message.error(error.msg)
            console.error(error.msg);
            reject(error)
          }
        })
      },
      deleteFile(index){
        this.fileList.splice(index,1)
      },
      cancelHandle(){
        this.$emit("update:diaShow",false)
      },
      saveHandle(){
        if(this.uploadingFileNames && this.uploadingFileNames.length>0){
          return this.$message.error("还有音/视频未上传完成，请等待上传成功后再转写！") 
        } 
        let params={
          MenuId:this.formData.catalogue,
          Files:this.fileList.map(f =>{
            return {
              FileName:f.name,
              ResourceUrl:f.fileUrl,
              FileSecond:Math.round(f.duration),
              FileSize:f.size
            }
          })
        }
        this.$refs.diaForm.validate(valid=>{
          if(valid){
            asrInterface.speechTransfer(params).then(res=>{
              if(res.Ret == 200){
                this.$message.success("提交转写成功")
                this.$emit("uploadSuccess")
                this.$emit("update:diaShow",false)
              }
            })
          }
        })
      },
      closeHandle(){
        this.formData={}
        this.closeDia=true
        this.uploadingFileNames=[]
        this.fileList=[]
        this.$emit("update:diaShow",false)
        this.$nextTick(()=>{
          this.$refs.diaForm.clearValidate()
          this.closeDia=false
        })
      }
    },
  }
</script>

<style lang="scss" scoped>
  @mixin font-type {
    font-size: 14px;
    line-height: 22px;
    font-weight: 400;
    color: #333333;
  }
.dialog-main{
  padding: 5px 35px 35px;
  .file-upload-zone{
    .file-upload-title{
      display: flex;
      align-items: center;
      justify-content: space-between;
      span{
        @include font-type
      }
      .file-readdition{
        color: #0052D9;
        cursor: pointer;
      }
      .disable-readdition{
        color: #999999;
        cursor:not-allowed;
      }
    }
    .file-upload-main{
      width: 100%;
      height: 380px;
      box-sizing: border-box;
      // border: 1px solid #C8CDD9;
      background-color: #ECF2FE;
      border-radius: 4px;
      margin-top: 10px;
      .table-span{
        @include font-type;
      }
      .table-button{
        @include font-type;
        color: #C54322;
        cursor: pointer;
      }
      .no-file-show{
        height: 332px;
        width: 100%;
        box-sizing: border-box;
        padding: 130px 0 30px;
        cursor: pointer;
        .upload-text{
          margin-bottom:80px;
          @include font-type
        }
        .upload-message-box{
          text-align: left;
          padding-left: 30px;
          .upload-message-row{
            @include font-type;
            color: #666666;
          }
        }
      }
    }
  }
  .dia-bot{
    text-align: center;
    margin-top: 60px;
  }
}
</style>
<style lang="scss">
  @mixin font-type {
    font-size: 14px;
    line-height: 22px;
    font-weight: 400;
    color: #333333;
  }
.el-cascader-node{
  max-width: 200px;
}
#media-upload-cascader{
  .el-input{
    width: 100%;
  }
}
#file-list-table{
  background-color: #ECF2FE;
  border: 1px solid #C8CDD9;
  border-radius: 4px;
  th{
    background-color: #ECF2FE!important;
    border-color: #C8CDD9!important;
    @include font-type;
    color: #999999;
  }
  td{
    border: none;
    background-color: #ECF2FE!important;
    padding: 10px 0;
  }
  .el-table__body-wrapper{
    height: 332px;
    overflow-y: auto;
  }
  .el-table__empty-block{
    .el-table__empty-text{
      width: 100%;
      color: unset;
      line-height: unset;
    }
  }
}
</style>