This commit is contained in:
@@ -30,8 +30,11 @@ const ProjectSubmission = ({ competitionId, initialValues, onCancel, onSuccess }
|
|||||||
const [pendingCoverImage, setPendingCoverImage] = useState(null);
|
const [pendingCoverImage, setPendingCoverImage] = useState(null);
|
||||||
const [pendingAttachments, setPendingAttachments] = useState([]);
|
const [pendingAttachments, setPendingAttachments] = useState([]);
|
||||||
const [isCreatingProject, setIsCreatingProject] = useState(false);
|
const [isCreatingProject, setIsCreatingProject] = useState(false);
|
||||||
|
const [currentProjectId, setCurrentProjectId] = useState(null);
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
const activeProjectId = currentProjectId || initialValues?.id;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (initialValues?.id) {
|
if (initialValues?.id) {
|
||||||
getProjects({ competition: competitionId, contestant: initialValues.id })
|
getProjects({ competition: competitionId, contestant: initialValues.id })
|
||||||
@@ -65,60 +68,6 @@ const ProjectSubmission = ({ competitionId, initialValues, onCancel, onSuccess }
|
|||||||
}
|
}
|
||||||
}, [initialValues, form]);
|
}, [initialValues, form]);
|
||||||
|
|
||||||
const handleUpload = ({ file, onSuccess, onError }) => {
|
|
||||||
console.log('handleUpload called', file.name);
|
|
||||||
|
|
||||||
if (!initialValues?.id) {
|
|
||||||
message.warning('请先保存项目基本信息再上传文件');
|
|
||||||
onError(new Error('请先保存项目'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fileUid = file.uid || Date.now().toString();
|
|
||||||
console.log('fileUid:', fileUid);
|
|
||||||
|
|
||||||
setUploadingFiles(prev => ({
|
|
||||||
...prev,
|
|
||||||
[fileUid]: { percent: 0, status: 'uploading' }
|
|
||||||
}));
|
|
||||||
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append('file', file);
|
|
||||||
formData.append('project', initialValues.id);
|
|
||||||
console.log('Sending upload request for project:', initialValues.id);
|
|
||||||
|
|
||||||
uploadProjectFile(formData)
|
|
||||||
.then(res => {
|
|
||||||
console.log('Upload success:', res);
|
|
||||||
setUploadingFiles(prev => ({
|
|
||||||
...prev,
|
|
||||||
[fileUid]: { percent: 100, status: 'done' }
|
|
||||||
}));
|
|
||||||
|
|
||||||
const newFile = {
|
|
||||||
uid: res.data.id,
|
|
||||||
id: res.data.id,
|
|
||||||
name: res.data.name || file.name,
|
|
||||||
url: res.data.file_url_display || res.data.file_url,
|
|
||||||
fileType: res.data.file_type,
|
|
||||||
status: 'done'
|
|
||||||
};
|
|
||||||
|
|
||||||
setUploadedFiles(prev => [...prev, newFile]);
|
|
||||||
message.success('文件上传成功');
|
|
||||||
onSuccess(res.data);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.error('Upload error:', err);
|
|
||||||
setUploadingFiles(prev => ({
|
|
||||||
...prev,
|
|
||||||
[fileUid]: { percent: 0, status: 'error' }
|
|
||||||
}));
|
|
||||||
message.error(`上传失败: ${err.response?.data?.detail || err.message}`);
|
|
||||||
onError(err);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const uploadPendingFiles = async (projectId) => {
|
const uploadPendingFiles = async (projectId) => {
|
||||||
const uploadedFilesList = [];
|
const uploadedFilesList = [];
|
||||||
|
|
||||||
@@ -288,29 +237,61 @@ const ProjectSubmission = ({ competitionId, initialValues, onCancel, onSuccess }
|
|||||||
showUploadList={false}
|
showUploadList={false}
|
||||||
accept="image/*"
|
accept="image/*"
|
||||||
beforeUpload={(file) => {
|
beforeUpload={(file) => {
|
||||||
console.log('Cover image selected:', file.name);
|
console.log('Cover image selected:', file.name, 'activeProjectId:', activeProjectId);
|
||||||
|
|
||||||
if (initialValues?.id) {
|
const doUpload = (projectId) => {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
|
|
||||||
uploadProjectFile(formData)
|
uploadProjectFile(formData)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
const imageUrl = res.data.file_url_display || res.data.file_url;
|
const imageUrl = res.data.file_url_display || res.data.file_url;
|
||||||
|
updateProject(projectId, { cover_image_url: imageUrl })
|
||||||
|
.then(() => {
|
||||||
form.setFieldsValue({ cover_image_url: imageUrl });
|
form.setFieldsValue({ cover_image_url: imageUrl });
|
||||||
message.success('封面上传成功');
|
message.success('封面上传成功');
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
message.error(`上传失败: ${err.response?.data?.detail || err.message}`);
|
console.error('更新封面失败:', err);
|
||||||
|
message.error(`更新封面失败: ${err.response?.data?.detail || err.message}`);
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('封面上传失败:', err);
|
||||||
|
const errorData = err.response?.data;
|
||||||
|
let errorMsg = '上传失败';
|
||||||
|
if (errorData) {
|
||||||
|
if (typeof errorData === 'object') {
|
||||||
|
errorMsg = Object.entries(errorData).map(([k, v]) => `${k}: ${Array.isArray(v) ? v.join(', ') : v}`).join('; ');
|
||||||
} else {
|
} else {
|
||||||
setPendingCoverImage(file);
|
errorMsg = String(errorData);
|
||||||
const reader = new FileReader();
|
}
|
||||||
reader.onload = () => {
|
}
|
||||||
form.setFieldsValue({ cover_image_url: reader.result });
|
message.error(`上传失败: ${errorMsg}`);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
reader.readAsDataURL(file);
|
|
||||||
message.info('封面已选择,提交时将自动上传');
|
if (activeProjectId) {
|
||||||
|
doUpload(activeProjectId);
|
||||||
|
} else {
|
||||||
|
message.loading('正在创建项目...', 0);
|
||||||
|
const tempData = {
|
||||||
|
title: '临时草稿',
|
||||||
|
description: '临时草稿',
|
||||||
|
competition: competitionId,
|
||||||
|
};
|
||||||
|
createProject(tempData)
|
||||||
|
.then(res => {
|
||||||
|
message.destroy();
|
||||||
|
const newProjectId = res.data.id;
|
||||||
|
setCurrentProjectId(newProjectId);
|
||||||
|
doUpload(newProjectId);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
message.destroy();
|
||||||
|
console.error('创建临时项目失败:', err);
|
||||||
|
message.error(`创建项目失败: ${err.response?.data?.detail || err.message}`);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return Upload.LIST_IGNORE;
|
return Upload.LIST_IGNORE;
|
||||||
@@ -412,7 +393,7 @@ const ProjectSubmission = ({ competitionId, initialValues, onCancel, onSuccess }
|
|||||||
maxCount={5}
|
maxCount={5}
|
||||||
accept=".ppt,.pptx,.pdf,.mp4,.mov,.avi,.webm,.jpg,.jpeg,.png,.gif,.webp,.doc,.docx"
|
accept=".ppt,.pptx,.pdf,.mp4,.mov,.avi,.webm,.jpg,.jpeg,.png,.gif,.webp,.doc,.docx"
|
||||||
beforeUpload={(file) => {
|
beforeUpload={(file) => {
|
||||||
console.log('beforeUpload triggered for:', file.name, 'initialValues:', initialValues);
|
console.log('beforeUpload triggered for:', file.name, 'activeProjectId:', activeProjectId);
|
||||||
const allowedExtensions = ['ppt', 'pptx', 'pdf', 'mp4', 'mov', 'avi', 'webm', 'jpg', 'jpeg', 'png', 'gif', 'webp', 'doc', 'docx'];
|
const allowedExtensions = ['ppt', 'pptx', 'pdf', 'mp4', 'mov', 'avi', 'webm', 'jpg', 'jpeg', 'png', 'gif', 'webp', 'doc', 'docx'];
|
||||||
const fileExt = file.name.split('.').pop()?.toLowerCase();
|
const fileExt = file.name.split('.').pop()?.toLowerCase();
|
||||||
|
|
||||||
@@ -427,19 +408,79 @@ const ProjectSubmission = ({ competitionId, initialValues, onCancel, onSuccess }
|
|||||||
return Upload.LIST_IGNORE;
|
return Upload.LIST_IGNORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasProjectId = initialValues?.id;
|
const doUpload = (projectId) => {
|
||||||
console.log('hasProjectId:', hasProjectId);
|
const fileUid = file.uid || Date.now().toString();
|
||||||
|
setUploadingFiles(prev => ({
|
||||||
|
...prev,
|
||||||
|
[fileUid]: { percent: 0, status: 'uploading' }
|
||||||
|
}));
|
||||||
|
|
||||||
if (hasProjectId) {
|
const formData = new FormData();
|
||||||
console.log('beforeUpload passed, manually calling handleUpload');
|
formData.append('file', file);
|
||||||
handleUpload({ file, onSuccess: () => {}, onError: () => {} });
|
formData.append('project', projectId);
|
||||||
|
|
||||||
|
uploadProjectFile(formData)
|
||||||
|
.then(res => {
|
||||||
|
console.log('Upload success:', res);
|
||||||
|
setUploadingFiles(prev => ({
|
||||||
|
...prev,
|
||||||
|
[fileUid]: { percent: 100, status: 'done' }
|
||||||
|
}));
|
||||||
|
|
||||||
|
const newFile = {
|
||||||
|
uid: res.data.id,
|
||||||
|
id: res.data.id,
|
||||||
|
name: res.data.name || file.name,
|
||||||
|
url: res.data.file_url_display || res.data.file_url,
|
||||||
|
fileType: res.data.file_type,
|
||||||
|
status: 'done'
|
||||||
|
};
|
||||||
|
|
||||||
|
setUploadedFiles(prev => [...prev, newFile]);
|
||||||
|
message.success('文件上传成功');
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('Upload error:', err);
|
||||||
|
setUploadingFiles(prev => ({
|
||||||
|
...prev,
|
||||||
|
[fileUid]: { percent: 0, status: 'error' }
|
||||||
|
}));
|
||||||
|
const errorData = err.response?.data;
|
||||||
|
let errorMsg = '上传失败';
|
||||||
|
if (errorData) {
|
||||||
|
if (typeof errorData === 'object') {
|
||||||
|
errorMsg = Object.entries(errorData).map(([k, v]) => `${k}: ${Array.isArray(v) ? v.join(', ') : v}`).join('; ');
|
||||||
} else {
|
} else {
|
||||||
if (pendingAttachments.length >= 5) {
|
errorMsg = String(errorData);
|
||||||
message.warning('最多只能上传5个文件');
|
|
||||||
return Upload.LIST_IGNORE;
|
|
||||||
}
|
}
|
||||||
setPendingAttachments(prev => [...prev, file]);
|
}
|
||||||
message.info('文件已添加到待上传列表,提交时将自动上传');
|
message.error(`上传失败: ${errorMsg}`);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (activeProjectId) {
|
||||||
|
console.log('Uploading to existing project');
|
||||||
|
doUpload(activeProjectId);
|
||||||
|
} else {
|
||||||
|
console.log('Creating temp project first');
|
||||||
|
message.loading('正在创建项目...', 0);
|
||||||
|
const tempData = {
|
||||||
|
title: '临时草稿',
|
||||||
|
description: '临时草稿',
|
||||||
|
competition: competitionId,
|
||||||
|
};
|
||||||
|
createProject(tempData)
|
||||||
|
.then(res => {
|
||||||
|
message.destroy();
|
||||||
|
const newProjectId = res.data.id;
|
||||||
|
setCurrentProjectId(newProjectId);
|
||||||
|
doUpload(newProjectId);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
message.destroy();
|
||||||
|
console.error('创建临时项目失败:', err);
|
||||||
|
message.error(`创建项目失败: ${err.response?.data?.detail || err.message}`);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return Upload.LIST_IGNORE;
|
return Upload.LIST_IGNORE;
|
||||||
}}
|
}}
|
||||||
@@ -455,7 +496,7 @@ const ProjectSubmission = ({ competitionId, initialValues, onCancel, onSuccess }
|
|||||||
<Button type="primary" htmlType="submit" loading={isCreatingProject}>
|
<Button type="primary" htmlType="submit" loading={isCreatingProject}>
|
||||||
{initialValues?.id ? '保存修改' : '保存草稿'}
|
{initialValues?.id ? '保存修改' : '保存草稿'}
|
||||||
</Button>
|
</Button>
|
||||||
{initialValues?.id && (
|
{(initialValues?.id || currentProjectId) && (
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
danger
|
danger
|
||||||
|
|||||||
Reference in New Issue
Block a user