feat: 上传视频/图片处理

This commit is contained in:
rd
2025-08-01 11:49:15 +08:00
parent 1cb33bd3ad
commit c211693d1f
7 changed files with 444 additions and 169 deletions

View File

@ -1,7 +1,7 @@
<script lang="jsx">
import { Button, Message as AMessage } from '@arco-design/web-vue';
import TextOverTips from '@/components/text-over-tips';
import EditForm from '../components/edit-form';
import EditForm, { ENUM_UPLOAD_STATUS, INITIAL_VIDEO_INFO } from '../components/edit-form';
import CancelUploadModal from './cancel-upload-modal.vue';
import UploadSuccessModal from './upload-success-modal.vue';
@ -11,15 +11,14 @@ import { postWorksBatch } from '@/api/all/generationWorkshop.ts';
import icon1 from '@/assets/img/creative-generation-workshop/icon-photo.png';
import icon2 from '@/assets/img/creative-generation-workshop/icon-video.png';
const generateMockData = (count = 20) =>
const generateMockData = (count = 4) =>
Array.from({ length: count }, (_, i) => ({
id: `${i + 1}`,
title: '',
desc: '',
title: `标题${i + 1}`,
content: '挖到宝了!这个平价好物让我素颜出门都自信✨挖到宝了!这个平价好物让我素颜出门都自信✨',
type: 1,
project_ids: [],
type: i % 2 === 0 ? EnumManuscriptType.Image : EnumManuscriptType.Video,
files: [],
videoInfo: cloneDeep(INITIAL_VIDEO_INFO),
}));
export default {
@ -29,6 +28,7 @@ export default {
setup(props, { emit, expose }) {
const formRef = ref(null);
const route = useRoute();
const router = useRouter();
const cancelUploadModal = ref(null);
const uploadSuccessModal = ref(null);
const works = ref([]);
@ -43,6 +43,14 @@ export default {
const validateDataSource = () => {
return new Promise((resolve) => {
const uploadingVideos = works.value.filter(
(item) => item.videoInfo?.uploadStatus === ENUM_UPLOAD_STATUS.UPLOADING,
);
if (uploadingVideos.length > 0) {
AMessage.warning(`${uploadingVideos.length} 个视频正在上传中,请等待上传完成后再提交`);
return;
}
works.value.forEach((item) => {
if (!item.title?.trim()) {
errorDataCards.value.push(item);
@ -64,24 +72,32 @@ export default {
});
};
const onSubmit = async (check) => {
uploadLoading.value = true;
const filteredWorks = map(works.value, (work) => omit(work, 'videoInfo'));
const { code, data } = await postWorksBatch({ works: filteredWorks });
if (code === 200) {
uploadLoading.value = false;
if (check) {
uploadSuccessModal.value?.open(workId);
} else {
router.push({ name: 'ManuscriptList' });
}
}
};
const onUpload = async (e, check = false) => {
console.log('onUpload', works.value);
formRef.value
?.validate()
.then(() => {
validateDataSource().then(async (res) => {
const { code, data } = await postWorksBatch({ works: works.value });
if (code === 200) {
uploadLoading.value = false;
if (check) {
uploadSuccessModal.value?.open(workId);
} else {
router.push({ name: 'ManuscriptList' });
}
}
});
return validateDataSource();
})
.then(() => {
onSubmit(check);
})
.catch((err) => {
console.log('catch');
errorDataCards.value.push(err);
});
};
@ -95,8 +111,9 @@ export default {
deleteErrorCard(selectCardInfo.value);
});
};
const onselect = (item) => {
selectCardInfo.value = item;
const onSelect = (item) => {
formRef.value.resetForm();
selectCardInfo.value = cloneDeep(item);
};
const deleteErrorCard = (item) => {
@ -112,7 +129,7 @@ export default {
if (item.id === selectCardInfo.value.id) {
if (works.value.length) {
const _target = works.value[0] ?? {};
selectCardInfo.value = _target;
selectCardInfo.value = cloneDeep(_target);
} else {
selectCardInfo.value = {};
}
@ -149,7 +166,7 @@ export default {
};
const getData = () => {
works.value = generateMockData();
selectCardInfo.value = works.value[0] ?? {};
selectCardInfo.value = cloneDeep(works.value[0] ?? {});
};
const getCardClass = (item) => {
if (selectCardInfo.value.id === item.id) {
@ -160,6 +177,22 @@ export default {
}
return '';
};
const onChange = (val) => {
const index = works.value.findIndex((v) => v.id === selectCardInfo.value.id);
if (index !== -1) {
works.value[index] = cloneDeep(val);
}
selectCardInfo.value = val;
};
const onUpdateVideoInfo = (newVideoInfo) => {
const index = works.value.findIndex((v) => v.id === selectCardInfo.value.id);
if (index !== -1) {
works.value[index].videoInfo = cloneDeep(newVideoInfo);
}
selectCardInfo.value.videoInfo = { ...selectCardInfo.value.videoInfo, ...newVideoInfo };
};
onMounted(() => {
getData();
});
@ -168,7 +201,13 @@ export default {
<>
<div class="manuscript-upload-wrap bg-#fff rounded-8px border-1px border-#D7D7D9 border-solid flex">
<div class="left flex-1 overflow-y-auto p-24px">
<EditForm ref={formRef} v-model={selectCardInfo.value} onReValidate={handleReValidate} />
<EditForm
ref={formRef}
formData={selectCardInfo.value}
onReValidate={handleReValidate}
onChange={onChange}
onUpdateVideoInfo={onUpdateVideoInfo}
/>
</div>
{works.value.length > 1 && (
<div class="right pt-24px pb-12px flex flex-col">
@ -185,7 +224,7 @@ export default {
class={`group relative mb-12px px-8px py-12px flex flex-col rounded-8px bg-#F7F8FA border-1px border-solid border-transparent transition-all duration-300 cursor-pointer hover:bg-#E6E6E8 ${getCardClass(
item,
)}`}
onClick={() => onselect(item)}
onClick={() => onSelect(item)}
>
<icon-close-circle-fill
size={16}