混剪优化

This commit is contained in:
2025-12-07 00:10:22 +08:00
parent 0fffd787bb
commit 7f7551f74f
14 changed files with 479 additions and 113 deletions

View File

@@ -65,6 +65,13 @@ export const MixTaskService = {
*/
cancelTask(id) {
return http.post(`${BASE_URL}/cancel/${id}`)
},
/**
* 获取任务输出文件的签名URL
*/
getSignedUrls(id) {
return http.get(`${BASE_URL}/signed-url/${id}`)
}
}

View File

@@ -533,7 +533,6 @@ const loadLastTask = async () => {
if (task.status === 'SUCCESS' && task.resultVideoUrl) {
previewVideoUrl.value = task.resultVideoUrl
currentTaskStatus.value = 'SUCCESS'
message.success('已自动加载最近一次任务结果')
} else if (task.status === 'PROCESSING') {
// 如果任务还在处理中,继续轮询
currentTaskStatus.value = 'PROCESSING'

View File

@@ -877,7 +877,6 @@ const loadLastTask = async () => {
previewVideoUrl.value = task.resultVideoUrl
currentTaskStatus.value = 'SUCCESS'
currentTaskError.value = ''
message.success('已自动加载最近一次任务结果')
} else if (task.status === 'PROCESSING') {
// 如果任务还在处理中,继续轮询
currentTaskStatus.value = 'PROCESSING'

View File

@@ -119,23 +119,16 @@
<template v-else-if="column.key === 'actions'">
<a-space>
<a-button
v-if="record.outputUrls && record.outputUrls.length > 0"
v-if="record.status === 'success' && record.outputUrls && record.outputUrls.length > 0"
type="primary"
size="small"
@click="handleDownloadAll(record.outputUrls)"
@click="handleDownloadAll(record.id)"
>
<template #icon>
<DownloadOutlined />
</template>
<span>下载</span>
</a-button>
<a-button
v-if="record.status === 'failed'"
size="small"
@click="handleRetry(record.id)"
>
重新生成
</a-button>
<a-button
v-if="record.status === 'running'"
size="small"
@@ -171,17 +164,25 @@
:key="index"
class="result-item"
>
<a :href="url" target="_blank">
<a-button
v-if="record.status === 'success'"
type="link"
@click="handlePreviewSignedUrl(record.id, index)"
>
<PlayCircleOutlined />
视频 {{ index + 1 }}
</a>
</a-button>
<a-button
v-if="record.status === 'success'"
type="link"
size="small"
@click="handleDownload(url)"
@click="handleDownloadSignedUrl(record.id, index)"
>
<DownloadOutlined />
</a-button>
<span v-else class="processing-tip">
视频 {{ index + 1 }} (处理中...)
</span>
</div>
</div>
</div>
@@ -203,7 +204,7 @@
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ref, reactive, onMounted, onUnmounted } from 'vue'
import { message, Modal } from 'ant-design-vue'
import {
ReloadOutlined,
@@ -218,6 +219,7 @@ import { formatDate } from '@/utils/file'
const loading = ref(false)
const taskList = ref([])
const expandedRowKeys = ref([])
const refreshInterval = ref(null) // 定时刷新定时器
// 表格列定义
const columns = [
@@ -429,25 +431,73 @@ const handleDownload = (url) => {
document.body.removeChild(link)
}
// 批量下载所有视频
const handleDownloadAll = (urls) => {
if (!urls || urls.length === 0) {
message.warning('没有可下载的视频')
return
// 下载单个视频使用签名URL
const handlePreviewSignedUrl = async (taskId, index) => {
try {
message.loading('正在获取预览链接...', 0)
const res = await MixTaskService.getSignedUrls(taskId)
message.destroy()
if (res.code === 0 && res.data && res.data[index]) {
window.open(res.data[index], '_blank')
} else {
message.warning('获取预览链接失败')
}
} catch (error) {
console.error('获取预览链接失败:', error)
message.destroy()
message.error('获取预览链接失败')
}
}
message.loading('正在准备下载...', 0)
const handleDownloadSignedUrl = async (taskId, index) => {
try {
message.loading('正在获取下载链接...', 0)
const res = await MixTaskService.getSignedUrls(taskId)
message.destroy()
// 逐个触发下载,避免浏览器阻止多个弹窗
urls.forEach((url, index) => {
setTimeout(() => {
console.log('下载视频:', url)
handleDownload(url)
}, index * 500) // 每个下载间隔500ms
})
if (res.code === 0 && res.data && res.data[index]) {
handleDownload(res.data[index])
} else {
message.warning('获取下载链接失败')
}
} catch (error) {
console.error('获取下载链接失败:', error)
message.destroy()
message.error('获取下载链接失败')
}
}
message.destroy()
message.success(`已触发 ${urls.length} 个视频的下载`)
// 批量下载所有视频
const handleDownloadAll = async (taskId) => {
try {
message.loading('正在获取下载链接...', 0)
const res = await MixTaskService.getSignedUrls(taskId)
message.destroy()
if (res.code === 0 && res.data && res.data.length > 0) {
const urls = res.data
message.loading('正在准备下载...', 0)
// 逐个触发下载,避免浏览器阻止多个弹窗
urls.forEach((url, index) => {
setTimeout(() => {
console.log('下载视频:', url)
handleDownload(url)
}, index * 500) // 每个下载间隔500ms
})
message.destroy()
message.success(`已触发 ${urls.length} 个视频的下载`)
} else {
message.warning('没有可下载的视频')
}
} catch (error) {
console.error('获取下载链接失败:', error)
message.destroy()
message.error('获取下载链接失败')
}
}
// 获取状态文本
@@ -486,7 +536,35 @@ const getProgressStatus = (status) => {
// 初始化
onMounted(() => {
loadTaskList()
// 开启定时刷新每30秒检查一次running状态的任务
startAutoRefresh()
})
// 组件卸载时清理定时器
onUnmounted(() => {
stopAutoRefresh()
})
// 开启自动刷新
const startAutoRefresh = () => {
// 清除可能存在的旧定时器
stopAutoRefresh()
refreshInterval.value = setInterval(() => {
// 只在页面可见时刷新,避免后台浪费资源
if (document.visibilityState === 'visible') {
loadTaskList()
}
}, 30000) // 30秒刷新一次
}
// 停止自动刷新
const stopAutoRefresh = () => {
if (refreshInterval.value) {
clearInterval(refreshInterval.value)
refreshInterval.value = null
}
}
</script>
<style scoped>
@@ -578,6 +656,11 @@ onMounted(() => {
font-size: 13px;
}
.processing-tip {
color: var(--color-text-secondary);
font-size: 12px;
}
.task-error {
margin-bottom: 8px;
}