From 8dc3501990c961dc63de791cf419ac5a28c92902 Mon Sep 17 00:00:00 2001
From: sion123 <450702724@qq.com>
Date: Wed, 4 Mar 2026 03:49:03 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../app/web-gold/src/views/material/Mix.vue | 7 +-
.../composables/useTaskOperations.js | 48 ++++--
.../system/task-management/mix-task/index.vue | 162 ++++++++++++++++--
3 files changed, 186 insertions(+), 31 deletions(-)
diff --git a/frontend/app/web-gold/src/views/material/Mix.vue b/frontend/app/web-gold/src/views/material/Mix.vue
index 699aa426ac..e04ed81878 100644
--- a/frontend/app/web-gold/src/views/material/Mix.vue
+++ b/frontend/app/web-gold/src/views/material/Mix.vue
@@ -323,7 +323,7 @@ const formData = ref({
produceCount: Number(localStorage.getItem('mix-produce-count')) || 3,
totalDuration: 15,
clipDuration: 5,
- cropMode: 'center'
+ cropMode: localStorage.getItem('mix-crop-mode') || 'center'
})
const uiState = ref({
@@ -377,6 +377,11 @@ const saveProduceCount = () => {
localStorage.setItem('mix-produce-count', formData.value.produceCount.toString())
}
+// 监听裁剪模式变化,保存到 localStorage
+watch(() => formData.value.cropMode, (newVal) => {
+ localStorage.setItem('mix-crop-mode', newVal)
+})
+
const getFileById = (fileId) => {
let file = dataState.value.groupFiles.find(f => f.id === fileId)
if (file) return file
diff --git a/frontend/app/web-gold/src/views/system/task-management/composables/useTaskOperations.js b/frontend/app/web-gold/src/views/system/task-management/composables/useTaskOperations.js
index c9dcecd590..485dbe1d42 100644
--- a/frontend/app/web-gold/src/views/system/task-management/composables/useTaskOperations.js
+++ b/frontend/app/web-gold/src/views/system/task-management/composables/useTaskOperations.js
@@ -118,15 +118,25 @@ export function useTaskOperations(apiHandlers, onSuccess) {
})
}
- // 下载单个文件
- function downloadFile(url, filename = 'download') {
- const link = document.createElement('a')
- link.href = url
- link.download = filename
- link.target = '_blank'
- document.body.appendChild(link)
- link.click()
- document.body.removeChild(link)
+ // 下载单个文件(使用 fetch + blob 强制下载)
+ async function downloadFile(url, filename = 'download') {
+ try {
+ const response = await fetch(url)
+ if (!response.ok) throw new Error('下载失败')
+ const blob = await response.blob()
+ const blobUrl = URL.createObjectURL(blob)
+ const link = document.createElement('a')
+ link.href = blobUrl
+ link.download = filename
+ document.body.appendChild(link)
+ link.click()
+ document.body.removeChild(link)
+ URL.revokeObjectURL(blobUrl)
+ } catch (error) {
+ console.error('下载失败:', error)
+ // 降级:直接打开让浏览器处理
+ window.open(url, '_blank')
+ }
}
// 获取签名URL
@@ -156,17 +166,21 @@ export function useTaskOperations(apiHandlers, onSuccess) {
}
message.destroy()
- message.loading('正在下载文件...', 0)
+ message.loading(`正在下载 ${downloadUrls.length} 个文件...`, 0)
- // 逐个触发下载,避免浏览器阻止多个弹窗
- downloadUrls.forEach((url, index) => {
- setTimeout(() => {
- downloadFile(url)
- }, index * DOWNLOAD_INTERVAL)
- })
+ // 逐个下载文件
+ for (let i = 0; i < downloadUrls.length; i++) {
+ const url = downloadUrls[i]
+ const filename = `video_${taskId}_${i + 1}.mp4`
+ await downloadFile(url, filename)
+ // 短暂延迟避免浏览器阻止
+ if (i < downloadUrls.length - 1) {
+ await new Promise(resolve => setTimeout(resolve, DOWNLOAD_INTERVAL))
+ }
+ }
message.destroy()
- message.success(`已触发 ${downloadUrls.length} 个文件的下载`)
+ message.success(`成功下载 ${downloadUrls.length} 个文件`)
} catch (error) {
message.destroy()
message.error('下载失败,请稍后重试')
diff --git a/frontend/app/web-gold/src/views/system/task-management/mix-task/index.vue b/frontend/app/web-gold/src/views/system/task-management/mix-task/index.vue
index 7af45028a0..a47c3e057e 100644
--- a/frontend/app/web-gold/src/views/system/task-management/mix-task/index.vue
+++ b/frontend/app/web-gold/src/views/system/task-management/mix-task/index.vue
@@ -50,10 +50,37 @@
:row-key="record => record.id"
:pagination="paginationConfig"
:expanded-row-keys="expandedRowKeys"
+ :row-selection="rowSelection"
:scroll="{ x: 'max-content' }"
@change="handleTableChange"
@expandedRowsChange="handleExpandedRowsChange"
>
+
+
+
+
+
@@ -187,9 +214,9 @@