feat: files接口结构调整对接

This commit is contained in:
rd
2025-08-05 15:24:46 +08:00
parent e8f2e561f5
commit da68733cb3
3 changed files with 60 additions and 83 deletions

View File

@ -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,27 +85,7 @@ export default {
console.error('获取视频时长失败:', error);
});
};
const uploadVideo = async (option) => {
try {
formData.value.videoInfo.uploadStatus = ENUM_UPLOAD_STATUS.UPLOADING;
emit('updateVideoInfo', formData.value.videoInfo);
const {
fileItem: { file },
} = option;
setVideoInfo(file);
const response = await getVideoPreSignedUrl({ suffix: getFileExtension(file.name) });
const { file_name, upload_url, file_url } = response?.data;
if (!upload_url) {
throw new Error('未能获取有效的预签名上传地址');
}
const blob = new Blob([file], { type: file.type });
await axios.put(upload_url, blob, {
headers: { 'Content-Type': file.type },
onUploadProgress: (progressEvent) => {
const handleUploadProgress = (progressEvent) => {
const percentCompleted = Math.round(progressEvent.progress * 100);
formData.value.videoInfo.percent = percentCompleted;
@ -138,10 +120,34 @@ export default {
}
emit('updateVideoInfo', formData.value.videoInfo);
};
const uploadVideo = async (option) => {
try {
formData.value.videoInfo.uploadStatus = ENUM_UPLOAD_STATUS.UPLOADING;
emit('updateVideoInfo', formData.value.videoInfo);
const {
fileItem: { file },
} = option;
setVideoInfo(file);
const response = await getVideoPreSignedUrl({ suffix: getFileExtension(file.name) });
const { file_name, upload_url, file_url } = response?.data;
if (!upload_url) {
throw new Error('未能获取有效的预签名上传地址');
}
const blob = new Blob([file], { type: file.type });
await axios.put(upload_url, blob, {
headers: { 'Content-Type': file.type },
onUploadProgress: (progressEvent) => {
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) => (
<div key={index} class="group relative cursor-move overflow-visible py-8px pr-8px">
<div class="group-container relative rounded-8px w-100px h-100px">
<img src={file} class=" object-cover w-full h-full border-1px border-#E6E6E8 rounded-8px" />
<img src={file.url} class=" object-cover w-full h-full border-1px border-#E6E6E8 rounded-8px" />
<icon-close-circle-fill
size={16}
class="absolute top--8px right--8px cursor-pointer hidden color-#939499 hidden group-hover:block z-50"

View File

@ -40,10 +40,10 @@ export default {
const initData = () => {
const [fileOne, ...fileOthers] = dataSource.value.files ?? [];
if (isVideo.value) {
videoUrl.value = fileOne;
coverImageUrl.value = convertVideoUrlToCoverUrl(fileOne);
videoUrl.value = fileOne.url;
coverImageUrl.value = convertVideoUrlToCoverUrl(fileOne.url);
} else {
coverImageUrl.value = fileOne;
coverImageUrl.value = fileOne.url;
images.value = fileOthers;
}
};
@ -172,7 +172,7 @@ export default {
<div class="desc-img-wrap mt-40px">
{images.value.map((item, index) => (
<div class="desc-img-box" key={index}>
<img src={item} class="w-100% h-100% object-contain" />
<img src={item.url} class="w-100% h-100% object-contain" />
</div>
))}
</div>

View File

@ -4,15 +4,7 @@ import EditForm, { ENUM_UPLOAD_STATUS, INITIAL_VIDEO_INFO } from '../components/
import CancelEditModal from './cancel-edit-modal.vue';
import { getWorksDetail, putWorksUpdate } from '@/api/all/generationWorkshop';
import { EnumManuscriptType } from '@/views/creative-generation-workshop/manuscript/list/constants.ts';
// const INITIAL_DATA = {
// title: '',
// content: '',
// type: EnumManuscriptType.Video,
// // project_ids: [],
// files: [],
// videoInfo: cloneDeep(INITIAL_VIDEO_INFO),
// };
import { formatDuration, formatFileSize, convertVideoUrlToCoverUrl } from '@/utils/tools';
export default {
components: {
@ -32,7 +24,7 @@ export default {
const onCancel = () => {
const isModified = !isEqual(dataSource.value, remoteDataSource.value);
if (isModified && isSaved.value) {
if (isModified && !isSaved.value) {
cancelEditModal.value?.open();
} else {
onBack();
@ -60,25 +52,27 @@ export default {
}
});
};
const init = () => {
dataSource.value = cloneDeep(INITIAL_DATA);
remoteDataSource.value = cloneDeep(INITIAL_DATA);
};
const getData = async () => {
const { code, data } = await getWorksDetail(workId.value);
if (code === 200) {
const { type, files } = data;
const _data = { ...data, videoInfo: cloneDeep(INITIAL_VIDEO_INFO) };
// 初始化视频数据
if (type === EnumManuscriptType.Video && files.length) {
_data.videoInfo.uploadStatus = 'end';
const { name, size, duration, url } = files[0];
_data.videoInfo.name = name;
_data.videoInfo.size = formatFileSize(size);
_data.videoInfo.time = formatDuration(duration);
_data.videoInfo.poster = convertVideoUrlToCoverUrl(url);
}
dataSource.value = cloneDeep(_data);
remoteDataSource.value = cloneDeep(_data);
}
};
const onChange = (val) => {
console.log('onChange', val);
dataSource.value = val;
};
const onUpdateVideoInfo = (newVideoInfo) => {
@ -88,7 +82,6 @@ export default {
router.push({ name: 'ManuscriptList' });
};
onMounted(() => {
// init();
workId && getData();
});