From da68733cb37f46b5a682b4719141ee07e8145192 Mon Sep 17 00:00:00 2001 From: rd <1344903914@qq.com> Date: Tue, 5 Aug 2025 15:24:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20files=E6=8E=A5=E5=8F=A3=E7=BB=93?= =?UTF-8?q?=E6=9E=84=E8=B0=83=E6=95=B4=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manuscript/components/edit-form/index.vue | 110 ++++++++---------- .../manuscript/detail/index.vue | 8 +- .../manuscript/edit/index.vue | 25 ++-- 3 files changed, 60 insertions(+), 83 deletions(-) diff --git a/src/views/creative-generation-workshop/manuscript/components/edit-form/index.vue b/src/views/creative-generation-workshop/manuscript/components/edit-form/index.vue index be164a3..da6a2fd 100644 --- a/src/views/creative-generation-workshop/manuscript/components/edit-form/index.vue +++ b/src/views/creative-generation-workshop/manuscript/components/edit-form/index.vue @@ -26,6 +26,7 @@ export const INITIAL_VIDEO_INFO = { name: '', size: '', percent: 0, + duration: 0, time: '', uploadSpeed: '0 KB/s', startTime: 0, @@ -76,6 +77,7 @@ export default { getVideoInfo(file) .then(({ duration, firstFrame }) => { formData.value.videoInfo.poster = firstFrame; + formData.value.videoInfo.duration = Math.floor(duration); formData.value.videoInfo.time = formatDuration(duration); emit('updateVideoInfo', formData.value.videoInfo); }) @@ -83,6 +85,42 @@ export default { console.error('获取视频时长失败:', error); }); }; + const handleUploadProgress = (progressEvent) => { + const percentCompleted = Math.round(progressEvent.progress * 100); + formData.value.videoInfo.percent = percentCompleted; + + const currentTime = Date.now(); + const currentLoaded = progressEvent.loaded; + const totalSize = progressEvent.total; + + if (formData.value.videoInfo.lastLoaded === 0) { + formData.value.videoInfo.lastLoaded = currentLoaded; + formData.value.videoInfo.lastTime = currentTime; + return; + } + + const timeDiff = (currentTime - formData.value.videoInfo.lastTime) / 1000; + const bytesDiff = currentLoaded - formData.value.videoInfo.lastLoaded; + + // 避免频繁更新,至少间隔200ms计算一次速率 + if (timeDiff >= 0.2) { + const bytesPerSecond = bytesDiff / timeDiff; + formData.value.videoInfo.uploadSpeed = formatUploadSpeed(bytesPerSecond); + formData.value.videoInfo.lastLoaded = currentLoaded; + formData.value.videoInfo.lastTime = currentTime; + + // 计算预估剩余时间 + if (totalSize && bytesPerSecond > 0) { + const remainingBytes = totalSize - currentLoaded; + const remainingSeconds = remainingBytes / bytesPerSecond; + formData.value.videoInfo.estimatedTime = formatDuration(remainingSeconds); + } else { + formData.value.videoInfo.estimatedTime = 0; + } + } + + emit('updateVideoInfo', formData.value.videoInfo); + }; const uploadVideo = async (option) => { try { @@ -104,44 +142,12 @@ export default { await axios.put(upload_url, blob, { headers: { 'Content-Type': file.type }, onUploadProgress: (progressEvent) => { - const percentCompleted = Math.round(progressEvent.progress * 100); - formData.value.videoInfo.percent = percentCompleted; - - const currentTime = Date.now(); - const currentLoaded = progressEvent.loaded; - const totalSize = progressEvent.total; - - if (formData.value.videoInfo.lastLoaded === 0) { - formData.value.videoInfo.lastLoaded = currentLoaded; - formData.value.videoInfo.lastTime = currentTime; - return; - } - - const timeDiff = (currentTime - formData.value.videoInfo.lastTime) / 1000; - const bytesDiff = currentLoaded - formData.value.videoInfo.lastLoaded; - - // 避免频繁更新,至少间隔200ms计算一次速率 - if (timeDiff >= 0.2) { - const bytesPerSecond = bytesDiff / timeDiff; - formData.value.videoInfo.uploadSpeed = formatUploadSpeed(bytesPerSecond); - formData.value.videoInfo.lastLoaded = currentLoaded; - formData.value.videoInfo.lastTime = currentTime; - - // 计算预估剩余时间 - if (totalSize && bytesPerSecond > 0) { - const remainingBytes = totalSize - currentLoaded; - const remainingSeconds = remainingBytes / bytesPerSecond; - formData.value.videoInfo.estimatedTime = formatDuration(remainingSeconds); - } else { - formData.value.videoInfo.estimatedTime = 0; - } - } - - emit('updateVideoInfo', formData.value.videoInfo); + handleUploadProgress(progressEvent); }, }); - formData.value.files.push(file_url); + const { name, duration, size } = formData.value.videoInfo; + formData.value.files.push({ url: file_url, name, duration, size }); onChange(); } finally { formData.value.videoInfo.uploadStatus = ENUM_UPLOAD_STATUS.END; @@ -158,50 +164,29 @@ export default { fileItem: { file }, } = option; - // 验证文件大小 (5MB) - // const maxSize = 5 * 1024 * 1024; - // if (file.size > maxSize) { - // AMessage.error('图片大小不能超过5MB!'); - // return; - // } - // 验证文件数量 if (formData.value.files?.length >= 18) { AMessage.error('最多只能上传18张图片!'); return; } - - const response = await getImagePreSignedUrl({ suffix: getFileExtension(file.name) }); + const { name, size, type } = file; + const response = await getImagePreSignedUrl({ suffix: getFileExtension(name) }); const { file_name, upload_url, file_url } = response?.data; - const blob = new Blob([file], { type: file.type }); + const blob = new Blob([file], { type }); await axios.put(upload_url, blob, { - headers: { 'Content-Type': file.type }, + headers: { 'Content-Type': type }, }); - formData.value.files.push(file_url); + formData.value.files.push({ url: file_url, name, size }); onChange(); }; - // 删除文件 const handleDeleteFile = (index) => { formData.value.files.splice(index, 1); onChange(); }; - // // 获取项目列表 - // const getProjects = async () => { - // try { - // const { code, data } = await getProjectList(); - // if (code === 200) { - // projects.value = data; - // } - // } catch (error) { - // console.error('获取项目列表失败:', error); - // } - // }; - - // 表单验证 const validate = () => { return new Promise((resolve, reject) => { formRef.value?.validate((errors) => { @@ -214,7 +199,6 @@ export default { }); }; - // 重置表单 const resetForm = () => { formData.value = {}; formRef.value?.resetFields?.(); @@ -329,7 +313,7 @@ export default { {formData.value.files?.map((file, index) => (
- +