|
@@ -0,0 +1,426 @@
|
|
|
+<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:'UniqueCode',label:'ChartClassifyName',children:'Children',checkStrictly:true}"
|
|
|
+ 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="size" width="120">
|
|
|
+ <template slot-scope="{row}" >
|
|
|
+ <span class="table-span">{{ row.size }}</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"
|
|
|
+ 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 {
|
|
|
+ last:0,
|
|
|
+ current:0,
|
|
|
+ diaTitle:'上传本地音视频文件',
|
|
|
+ formData:{
|
|
|
+ catalogue:''
|
|
|
+ },
|
|
|
+ fileLimit:50,
|
|
|
+ fileExp:new RegExp(/\.(mp3|wav|m4a|amr|wma|aac|opus|ogg|flac|mp4|flv|3gp)$/,'i'),
|
|
|
+ fileList:[
|
|
|
+ {name:"fdsfsa.mp4",size:"1021.26M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ ],
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.26M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.26M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.26M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},
|
|
|
+ // {name:"fdsfsa.mp4",size:"1021.2M",type:"音频"},{name:"fdsfsa.mp4",size:"1021.2M",type:"音频"}
|
|
|
+ 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);
|
|
|
+ if(this.uploadingFileNames.some(item=> item.split('.')[0] == file.name.split('.')[0])){
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!( (this.fileList.length+this.uploadingFileNames.length) < this.fileLimit)){
|
|
|
+ return this.$message.error(`上传文件已超过${this.fileLimit}个,${file.name}上传失败`)
|
|
|
+ }
|
|
|
+ // TODO: 调用接口判断是否与数据库的文件重复
|
|
|
+
|
|
|
+ if(!this.uploadHint){
|
|
|
+ this.uploadHint = this.$message({
|
|
|
+ type:"info",
|
|
|
+ message:'上传中,请勿关闭弹窗',
|
|
|
+ duration:0,
|
|
|
+ iconClass:'el-icon-loading'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ // 上传
|
|
|
+ let fileFront=file.name.split('.')[0]
|
|
|
+ this.uploadingFileNames.push(fileFront)
|
|
|
+
|
|
|
+ let temName = `asr/media/${new Date().getTime()}`
|
|
|
+ let clientType = this.$setting.dynamicOutLinks.ObjectStorageClient ||
|
|
|
+ this.$store.state.dynamicOutLinks.ObjectStorageClient ||
|
|
|
+ JSON.parse(localStorage.getItem('dynamicOutLinks')).ObjectStorageClient
|
|
|
+ let options={}
|
|
|
+ if((file.size/1024/1024 > 200)){
|
|
|
+ // 大于200MB,分片上传
|
|
|
+ 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。
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // uploadFileDirect(clientType,file.raw,temName,options).then(res=>{
|
|
|
+ setTimeout(()=>{
|
|
|
+ console.log(this.current,this.last,'current','last');
|
|
|
+ if(!this.diaShow || (this.current!=this.last)) return
|
|
|
+ this.fileList.push({name:fileFront,fileUrl:'res',size:this.sizeFormat(file.size),type:"音频"})
|
|
|
+ this.deleteUploadItem(fileFront)
|
|
|
+ },10000)
|
|
|
+ // }).finally(()=>{
|
|
|
+
|
|
|
+ // })
|
|
|
+ },
|
|
|
+ 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+'时长已超限'})
|
|
|
+ }else{
|
|
|
+ resolve({flag:true,msg:''})
|
|
|
+ }
|
|
|
+ });
|
|
|
+ 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("还有音/视频未上传完成,请等待上传成功后再转写!")
|
|
|
+ }
|
|
|
+ this.$refs.diaForm.validate(valid=>{
|
|
|
+ if(valid){
|
|
|
+ //TODO: 转写接口调用
|
|
|
+ this.$message.success("提交转写成功")
|
|
|
+ this.$emit("uploadSuccess")
|
|
|
+ this.$emit("update:diaShow",false)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ closeHandle(){
|
|
|
+ this.formData={}
|
|
|
+ this.closeDia=true
|
|
|
+ this.uploadingFileNames=[]
|
|
|
+ this.fileList=[]
|
|
|
+ this.last++
|
|
|
+ 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>
|