191 lines
5.9 KiB
JavaScript
191 lines
5.9 KiB
JavaScript
import React, { useState } from 'react';
|
||
import { Card, Button, Form, Input, Upload, App, Modal, Select } from 'antd';
|
||
import { UploadOutlined, CloudUploadOutlined, LinkOutlined } from '@ant-design/icons';
|
||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||
import { createProject, updateProject, submitProject, uploadProjectFile } from '../../api';
|
||
|
||
const { TextArea } = Input;
|
||
const { Option } = Select;
|
||
|
||
const ProjectSubmission = ({ competitionId, initialValues, onCancel, onSuccess }) => {
|
||
const { message } = App.useApp();
|
||
const [form] = Form.useForm();
|
||
const [fileList, setFileList] = useState([]);
|
||
const queryClient = useQueryClient();
|
||
|
||
// Reset form when initialValues changes (important for switching between create/edit)
|
||
React.useEffect(() => {
|
||
if (initialValues) {
|
||
form.setFieldsValue(initialValues);
|
||
} else {
|
||
form.resetFields();
|
||
}
|
||
}, [initialValues, form]);
|
||
|
||
const createMutation = useMutation({
|
||
mutationFn: createProject,
|
||
onSuccess: () => {
|
||
message.success('项目创建成功');
|
||
queryClient.invalidateQueries(['projects']);
|
||
onSuccess();
|
||
},
|
||
onError: (error) => {
|
||
message.error(`创建失败: ${error.message}`);
|
||
}
|
||
});
|
||
|
||
const updateMutation = useMutation({
|
||
mutationFn: (data) => updateProject(initialValues.id, data),
|
||
onSuccess: () => {
|
||
message.success('项目更新成功');
|
||
queryClient.invalidateQueries(['projects']);
|
||
onSuccess();
|
||
},
|
||
onError: (error) => {
|
||
message.error(`更新失败: ${error.message}`);
|
||
}
|
||
});
|
||
|
||
const uploadMutation = useMutation({
|
||
mutationFn: uploadProjectFile,
|
||
onSuccess: (data) => {
|
||
message.success('文件上传成功');
|
||
setFileList([...fileList, data]); // Add file to list (assuming response format)
|
||
},
|
||
onError: (error) => {
|
||
message.error(`上传失败: ${error.message}`);
|
||
}
|
||
});
|
||
|
||
const onFinish = (values) => {
|
||
const data = {
|
||
...values,
|
||
competition: competitionId,
|
||
// Handle file URLs/IDs if needed in create/update
|
||
};
|
||
|
||
if (initialValues?.id) {
|
||
updateMutation.mutate(data);
|
||
} else {
|
||
createMutation.mutate(data);
|
||
}
|
||
};
|
||
|
||
const handleUpload = ({ file, onSuccess, onError }) => {
|
||
if (!initialValues?.id) {
|
||
message.warning('请先保存项目基本信息再上传文件');
|
||
// Prevent default upload
|
||
onError(new Error('请先保存项目'));
|
||
return;
|
||
}
|
||
|
||
const formData = new FormData();
|
||
formData.append('file', file);
|
||
formData.append('project', initialValues?.id || ''); // Need project ID first usually
|
||
|
||
uploadMutation.mutate(formData, {
|
||
onSuccess: (data) => {
|
||
onSuccess(data);
|
||
},
|
||
onError: (error) => {
|
||
onError(error);
|
||
}
|
||
});
|
||
};
|
||
|
||
return (
|
||
<Modal
|
||
title={initialValues?.id ? "修改已提交项目" : "提交新项目"}
|
||
open={true}
|
||
onCancel={onCancel}
|
||
footer={null}
|
||
width={800}
|
||
>
|
||
<Form
|
||
form={form}
|
||
layout="vertical"
|
||
onFinish={onFinish}
|
||
initialValues={initialValues}
|
||
>
|
||
<Form.Item
|
||
name="title"
|
||
label="项目名称"
|
||
rules={[{ required: true, message: '请输入项目名称' }]}
|
||
>
|
||
<Input placeholder="请输入项目名称" />
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
name="description"
|
||
label="项目简介"
|
||
rules={[{ required: true, message: '请输入项目简介' }]}
|
||
>
|
||
<TextArea rows={4} placeholder="简要描述您的项目创意和功能" />
|
||
</Form.Item>
|
||
|
||
<Form.Item
|
||
name="team_info"
|
||
label="团队介绍"
|
||
>
|
||
<TextArea rows={3} placeholder="介绍您的团队成员和分工" />
|
||
</Form.Item>
|
||
|
||
{initialValues?.status === 'submitted' && (
|
||
<div style={{ marginBottom: 24, color: '#faad14' }}>
|
||
注意:您已正式提交该项目,修改后需要重新审核(如适用)。
|
||
</div>
|
||
)}
|
||
|
||
<Form.Item
|
||
name="cover_image_url"
|
||
label="封面图片链接"
|
||
rules={[{ type: 'url', message: '请输入有效的URL' }]}
|
||
>
|
||
<Input prefix={<LinkOutlined />} placeholder="https://example.com/image.jpg" />
|
||
</Form.Item>
|
||
|
||
{/* File Upload Section - Only visible if project exists */}
|
||
{initialValues?.id && (
|
||
<Form.Item label="项目附件 (PPT/PDF/视频)">
|
||
<Upload
|
||
customRequest={handleUpload}
|
||
listType="picture"
|
||
maxCount={5}
|
||
>
|
||
<Button icon={<CloudUploadOutlined />}>上传文件 (最大50MB)</Button>
|
||
</Upload>
|
||
</Form.Item>
|
||
)}
|
||
|
||
<Form.Item>
|
||
<div style={{ display: 'flex', justifyContent: 'flex-end', gap: 10 }}>
|
||
<Button onClick={onCancel}>取消</Button>
|
||
<Button type="primary" htmlType="submit" loading={createMutation.isLoading || updateMutation.isLoading}>
|
||
{initialValues?.id ? '保存修改' : '保存草稿'}
|
||
</Button>
|
||
{initialValues?.id && (
|
||
<Button
|
||
type="primary"
|
||
danger
|
||
onClick={() => {
|
||
Modal.confirm({
|
||
title: '确认提交?',
|
||
content: '提交后将无法修改,确认提交吗?',
|
||
onOk: () => submitProject(initialValues.id).then(() => {
|
||
message.success('提交成功');
|
||
onSuccess();
|
||
})
|
||
})
|
||
}}
|
||
>
|
||
正式提交
|
||
</Button>
|
||
)}
|
||
</div>
|
||
</Form.Item>
|
||
</Form>
|
||
</Modal>
|
||
);
|
||
};
|
||
|
||
export default ProjectSubmission; |