比赛
All checks were successful
Deploy to Server / deploy (push) Successful in 37s

This commit is contained in:
jeremygan2021
2026-03-10 11:09:15 +08:00
parent 724dd3857c
commit 417cda952d
11 changed files with 778 additions and 3 deletions

View File

@@ -0,0 +1,169 @@
import React, { useState } from 'react';
import { Card, Button, Form, Input, Upload, message, 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 [form] = Form.useForm();
const [fileList, setFileList] = useState([]);
const queryClient = useQueryClient();
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 }) => {
const formData = new FormData();
formData.append('file', file);
formData.append('project', initialValues?.id || ''); // Need project ID first usually
// Upload logic might need adjustment: create project first, then upload files?
// Or upload to temp storage then link?
// For simplicity, let's assume we create project first if not exists
if (!initialValues?.id) {
message.warning('请先保存项目基本信息再上传文件');
return;
}
uploadMutation.mutate(formData);
};
return (
<Modal
title={initialValues ? "编辑项目" : "提交新项目"}
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>
<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}>
保存草稿
</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;