提交 35439386 authored 作者: 王鹏飞's avatar 王鹏飞

chore: 优化视频下载

上级 ae3099bd
...@@ -93,3 +93,10 @@ export function getSignature() { ...@@ -93,3 +93,10 @@ export function getSignature() {
export function getMeetingCount(params) { export function getMeetingCount(params) {
return httpRequest.get('/api/live/admin/v3/tencent/meeting/count', { params }) return httpRequest.get('/api/live/admin/v3/tencent/meeting/count', { params })
} }
/**
* 获取会议回放详情列表
*/
export function getMeetingRecords(params) {
return httpRequest.get(`/api/live/admin/v3/tencent/meeting/${params.meeting_id}/records`, { params })
}
<template>
<el-dialog title="下载" v-bind="$attrs" v-on="$listeners">
<el-alert type="info" show-icon :closable="false">
<template #title>
已选择<span style="color:#409eff;padding:0 5px;">{{ multipleSelection.length }}</span
>
<el-button
type="text"
:disabled="!multipleSelection.length"
@click="handleBatchDownload"
style="margin-left: 10px;"
>批量下载</el-button
>
</template>
</el-alert>
<el-table :data="list" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" />
<el-table-column label="开始时间" prop="record_start_time"></el-table-column>
<el-table-column label="结束时间" prop="record_end_time"></el-table-column>
<el-table-column label="大小" prop="record_size"></el-table-column>
<el-table-column label="操作" width="100">
<template #default="{row}">
<el-button type="text" @click="handleDownload(row)">下载</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
</template>
<script>
import { getMeetingRecords, getMeetingRecordAddr } from '@/api/common'
export default {
props: { data: Object },
data() {
return {
list: [],
multipleSelection: []
}
},
methods: {
handleSelectionChange(val) {
this.multipleSelection = val
},
fetchList() {
getMeetingRecords({ meeting_id: this.data.meeting_id, sub_meeting_id: this.data.sub_meeting_id }).then(res => {
if (res.code === 0) {
this.list = res.data.items || []
} else {
this.$message.error(res.message)
}
})
},
// 下载
handleDownload(row) {
const params = {
meeting_id: this.data.meeting_id,
record_file_ids: [].concat(row.record_file_id)
}
this.fetchDownloadInfo(params)
},
// 批量下载
handleBatchDownload() {
const params = {
meeting_id: this.data.meeting_id,
record_file_ids: this.multipleSelection.map(item => item.record_file_id)
}
this.fetchDownloadInfo(params)
},
fetchDownloadInfo(params) {
getMeetingRecordAddr(params).then(res => {
const files = res.data.files || []
files.forEach((file, index) => {
setTimeout(() => {
this.funDownload(file.download_address, file.download_address)
}, index * 1000)
})
})
},
funDownload(fileUrl, fileName) {
const elink = document.createElement('a') // 创建一个a标签
elink.download = fileName // 设置a标签的下载属性
elink.style.display = 'none' // 将a标签设置为隐藏
elink.href = fileUrl // 把之前处理好的地址赋给a标签的href
document.body.appendChild(elink) // 将a标签添加到body中
elink.click() // 执行a标签的点击方法
// URL.revokeObjectURL(elink.href) // 下载完成释放URL 对象
document.body.removeChild(elink) // 移除a标签
}
},
mounted() {
this.fetchList()
}
}
</script>
...@@ -15,9 +15,15 @@ ...@@ -15,9 +15,15 @@
<el-button type="text" size="small" v-else @click="handleDetails">查看</el-button> <el-button type="text" size="small" v-else @click="handleDetails">查看</el-button>
</template> </template>
<template v-if="status === 2"> <template v-if="status === 2">
<el-button type="text" size="small" v-if="operatable && hasJoin && isFuture" @click="handleJoin">进入会议</el-button> <el-button type="text" size="small" v-if="operatable && hasJoin && isFuture" @click="handleJoin"
<el-button type="text" size="small" v-if="operatable && hasUpdate && isFuture" @click="handleUpdate">更新</el-button> >进入会议</el-button
<el-button type="text" size="small" v-if="(operatable && hasDownload) || hasManage" @click="handleRecord">下载回放</el-button> >
<el-button type="text" size="small" v-if="operatable && hasUpdate && isFuture" @click="handleUpdate"
>更新</el-button
>
<el-button type="text" size="small" v-if="(operatable && hasDownload) || hasManage" @click="handleRecord"
>下载回放</el-button
>
<el-button type="text" size="small" v-if="operatable && hasDelete" @click="handleDelete">删除</el-button> <el-button type="text" size="small" v-if="operatable && hasDelete" @click="handleDelete">删除</el-button>
<el-button type="text" size="small" @click="handleDetails">查看</el-button> <el-button type="text" size="small" @click="handleDetails">查看</el-button>
</template> </template>
...@@ -25,27 +31,36 @@ ...@@ -25,27 +31,36 @@
<el-button type="text" size="small" @click="handleDetails">查看</el-button> <el-button type="text" size="small" @click="handleDetails">查看</el-button>
<!-- <el-button type="text" size="small" v-if="operatable" @click="handleDelete">删除</el-button> --> <!-- <el-button type="text" size="small" v-if="operatable" @click="handleDelete">删除</el-button> -->
</template> </template>
<el-dialog :title="domicTitle" :visible.sync="dialogVisible" width="520px" center> <el-dialog :title="domicTitle" :visible.sync="dialogVisible" width="520px" center class="my-dialog">
<div slot="title" class="dialog-header"> <div slot="title" class="dialog-header">
<p class="meeting-status" v-show="dialogType === 'details'">会议{{rowData.status | statusFilter}}</p> <p class="meeting-status" v-show="dialogType === 'details'">会议{{ rowData.status | statusFilter }}</p>
<p class="title">{{domicTitle}}</p> <p class="title">{{ domicTitle }}</p>
</div> </div>
<dialog-details :rowData="rowData" :details="details" v-show="dialogType === 'details'" :operatable="operatable"/> <dialog-details
<dialog-copy-invite :rowData="rowData" :details="details" v-show="dialogType === 'copy'"/> :rowData="rowData"
:details="details"
v-show="dialogType === 'details'"
:operatable="operatable"
/>
<dialog-copy-invite :rowData="rowData" :details="details" v-show="dialogType === 'copy'" />
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" v-show="dialogType === 'copy'" @click="copyLink">复制</el-button> <el-button type="primary" size="mini" v-show="dialogType === 'copy'" @click="copyLink">复制</el-button>
<el-button @click="dialogVisible = false" size="mini">取 消</el-button> <el-button @click="dialogVisible = false" size="mini">取 消</el-button>
</div> </div>
</el-dialog> </el-dialog>
<!-- 下载 -->
<DownloadVideo :data="rowData" :visible.sync="downloadVisible" v-if="downloadVisible"></DownloadVideo>
</div> </div>
</template> </template>
<script> <script>
import DialogDetails from './DialogDetails.vue' import DialogDetails from './DialogDetails.vue'
import DialogCopyInvite from './DialogCopyInvite' import DialogCopyInvite from './DialogCopyInvite'
import DownloadVideo from './DownloadVideo'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { getMeetingDetails, stopMeeting, cancelMeeting, getMeetingRecordAddr } from '@api/common' import { getMeetingDetails, stopMeeting, cancelMeeting, getMeetingRecordAddr } from '@api/common'
import { timeTrans } from '@/utils/dateAlgs' import { timeTrans } from '@/utils/dateAlgs'
export default { export default {
components: { DialogDetails, DialogCopyInvite, DownloadVideo },
props: { props: {
rowData: {} rowData: {}
}, },
...@@ -53,7 +68,8 @@ export default { ...@@ -53,7 +68,8 @@ export default {
return { return {
dialogVisible: false, dialogVisible: false,
dialogType: 'copy', dialogType: 'copy',
details: '' details: '',
downloadVisible: false
} }
}, },
computed: { computed: {
...@@ -151,9 +167,6 @@ export default { ...@@ -151,9 +167,6 @@ export default {
return result return result
} }
}, },
components: { DialogDetails, DialogCopyInvite },
created() {
},
methods: { methods: {
handleCopy() { handleCopy() {
this.fetchMeetingDetails() this.fetchMeetingDetails()
...@@ -166,44 +179,53 @@ export default { ...@@ -166,44 +179,53 @@ export default {
this.fetchMeetingDetails() this.fetchMeetingDetails()
}, },
handleLive() { handleLive() {
window.open(this.rowData.live_config.live_addr, '_blank'); window.open(this.rowData.live_config.live_addr, '_blank')
}, },
handleUpdate() { handleUpdate() {
this.$router.push({ path: '/meeting-update', query: { meeting_id: this.rowData.meeting_id, sub_meeting_id: this.rowData.sub_meeting_id } }) this.$router.push({
path: '/meeting-update',
query: { meeting_id: this.rowData.meeting_id, sub_meeting_id: this.rowData.sub_meeting_id }
})
}, },
handleCancel() { handleCancel() {
this.$confirm('此操作将取消这场会议, 是否继续?', '提示', { this.$confirm('此操作将取消这场会议, 是否继续?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消' cancelButtonText: '取消'
}).then(() => { })
this.fetchCancelMeeting('cancel') .then(() => {
}).catch(() => {}) this.fetchCancelMeeting('cancel')
})
.catch(() => {})
}, },
handleStop() { handleStop() {
this.$confirm('此操作将终止正在进行中的会议, 是否继续?', '提示', { this.$confirm('此操作将终止正在进行中的会议, 是否继续?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消' cancelButtonText: '取消'
}).then(() => { })
this.fetchStopMeeting() .then(() => {
}).catch(() => {}) this.fetchStopMeeting()
})
.catch(() => {})
}, },
handleDelete() { handleDelete() {
this.$confirm('此操作将删除这场会议, 是否继续?', '提示', { this.$confirm('此操作将删除这场会议, 是否继续?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消' cancelButtonText: '取消'
}).then(() => { })
this.fetchCancelMeeting('delete') .then(() => {
}).catch(() => {}) this.fetchCancelMeeting('delete')
})
.catch(() => {})
}, },
handleJoin() { handleJoin() {
window.open(this.rowData.join_url, '_blank'); window.open(this.rowData.join_url, '_blank')
}, },
copyLink() { copyLink() {
const dom = document.createElement('input') const dom = document.createElement('input')
document.body.appendChild(dom) document.body.appendChild(dom)
dom.value = this.rowData.join_url dom.value = this.rowData.join_url
dom.select(); // 选择对象 dom.select() // 选择对象
document.execCommand('Copy'); document.execCommand('Copy')
this.$message({ this.$message({
message: '复制成功!', message: '复制成功!',
type: 'success' type: 'success'
...@@ -211,31 +233,32 @@ export default { ...@@ -211,31 +233,32 @@ export default {
document.body.removeChild(dom) document.body.removeChild(dom)
}, },
async handleRecord() { async handleRecord() {
if (this.rowData.record_file_ids.length === 0) { this.downloadVisible = true
this.$message.error('该会议没有回放') // if (this.rowData.record_file_ids.length === 0) {
} else { // this.$message.error('该会议没有回放')
const list = await this.fetchMeetingRecordAddr() // } else {
if (list && Array.isArray(list)) { // const list = await this.fetchMeetingRecordAddr()
list.forEach((it, index) => { // if (list && Array.isArray(list)) {
if (it.download_address) { // list.forEach((it, index) => {
// window.open(it.download_address, '_blank') // if (it.download_address) {
setTimeout(() => { // // window.open(it.download_address, '_blank')
this.funDownload(it.download_address, it.download_address) // setTimeout(() => {
}, index * 1000) // this.funDownload(it.download_address, it.download_address)
} // }, index * 1000)
}) // }
} // })
} // }
// }
}, },
funDownload(fileUrl, fileName) { funDownload(fileUrl, fileName) {
const elink = document.createElement('a')// 创建一个a标签 const elink = document.createElement('a') // 创建一个a标签
elink.download = fileName;// 设置a标签的下载属性 elink.download = fileName // 设置a标签的下载属性
elink.style.display = 'none';// 将a标签设置为隐藏 elink.style.display = 'none' // 将a标签设置为隐藏
elink.href = fileUrl;// 把之前处理好的地址赋给a标签的href elink.href = fileUrl // 把之前处理好的地址赋给a标签的href
document.body.appendChild(elink);// 将a标签添加到body中 document.body.appendChild(elink) // 将a标签添加到body中
elink.click();// 执行a标签的点击方法 elink.click() // 执行a标签的点击方法
// URL.revokeObjectURL(elink.href) // 下载完成释放URL 对象 // URL.revokeObjectURL(elink.href) // 下载完成释放URL 对象
document.body.removeChild(elink)// 移除a标签 document.body.removeChild(elink) // 移除a标签
}, },
fetchStopMeeting() { fetchStopMeeting() {
const params = { const params = {
...@@ -288,46 +311,50 @@ export default { ...@@ -288,46 +311,50 @@ export default {
record_file_ids: this.rowData.record_file_ids record_file_ids: this.rowData.record_file_ids
} }
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getMeetingRecordAddr(params).then(res => { getMeetingRecordAddr(params)
if (res.code === 0 && res.data.files) { .then(res => {
resolve(res.data.files) if (res.code === 0 && res.data.files) {
} else { resolve(res.data.files)
reject(res) } else {
} reject(res)
}).catch((err) => reject(err)) }
})
.catch(err => reject(err))
}) })
} }
} }
} }
</script> </script>
<style scoped> <style lang="scss" scoped>
.dropdown-link{ .dropdown-link {
cursor: pointer; cursor: pointer;
color: #409EFF; color: #409eff;
font-size:12px; font-size: 12px;
} }
::v-deep.el-icon-arrow-down { ::v-deep.el-icon-arrow-down {
font-size: 12px; font-size: 12px;
} }
.btns ::v-deep.el-dialog__header{ .my-dialog {
padding-top:14px; ::v-deep.el-dialog__header {
} padding-top: 14px;
.btns ::v-deep.el-dialog__headerbtn{ }
top:12px; ::v-deep.el-dialog__headerbtn {
right:12px; top: 12px;
} right: 12px;
.btns ::v-deep.el-dialog__body{ }
padding:10px 0; ::v-deep.el-dialog__body {
margin:0 20px; padding: 10px 0;
border: 1px solid #DBDBDB; margin: 0 20px;
} border: 1px solid #dbdbdb;
.btns ::v-deep.el-dialog__footer{ }
padding-bottom:16px; ::v-deep.el-dialog__footer {
} padding-bottom: 16px;
.dialog-header .meeting-status{ }
text-align:left; .dialog-header .meeting-status {
} text-align: left;
.dialog-header .title{ }
font-size:16px; .dialog-header .title {
font-size: 16px;
}
} }
</style> </style>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论