2025-03-11 11:43:22 +08:00
|
|
|
import React, { useState, forwardRef, useEffect } from 'react';
|
|
|
|
|
import { Form, Modal, Input, Radio, Upload, Button, Icon, message } from 'antd';
|
2021-06-11 09:25:59 +08:00
|
|
|
import Axios from 'axios';
|
2025-03-11 11:43:22 +08:00
|
|
|
import { getUploadActionUrl, appendFileSizeToUploadFileAll } from 'educoder';
|
2021-06-11 09:25:59 +08:00
|
|
|
|
2025-03-11 11:43:22 +08:00
|
|
|
const JoinProjectForm = Form.create({
|
|
|
|
|
name: 'join_project_form',
|
|
|
|
|
})(
|
|
|
|
|
forwardRef((props) => {
|
|
|
|
|
const { getFieldDecorator, validateFields } = props.form;
|
|
|
|
|
const { onOk, onCancel } = props;
|
2021-06-11 09:25:59 +08:00
|
|
|
|
2025-03-11 11:43:22 +08:00
|
|
|
useEffect(() => {
|
|
|
|
|
if (props.visible) {
|
|
|
|
|
props.form.setFieldsValue({
|
|
|
|
|
code: '',
|
|
|
|
|
role: 'developer',
|
|
|
|
|
});
|
2021-06-11 09:25:59 +08:00
|
|
|
}
|
2025-03-11 11:43:22 +08:00
|
|
|
}, [props.visible])
|
2021-06-11 09:25:59 +08:00
|
|
|
|
2025-03-11 11:43:22 +08:00
|
|
|
function checkValue(rule, value, callback) {
|
|
|
|
|
if (!value) {
|
2021-06-11 09:25:59 +08:00
|
|
|
callback();
|
|
|
|
|
}
|
2025-03-11 11:43:22 +08:00
|
|
|
if (value.length < 6 || value.length > 6) {
|
|
|
|
|
callback('请输入6位数的邀请码');
|
2021-06-11 09:25:59 +08:00
|
|
|
}
|
|
|
|
|
callback();
|
2025-03-11 11:43:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const handleOk = () => {
|
|
|
|
|
validateFields((error, values) => {
|
|
|
|
|
if (!error) {
|
|
|
|
|
onOk(values);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Modal
|
|
|
|
|
title="加入项目"
|
|
|
|
|
width="480px"
|
|
|
|
|
visible={props.visible}
|
|
|
|
|
centered={true}
|
|
|
|
|
onOk={handleOk}
|
|
|
|
|
onCancel={onCancel}
|
|
|
|
|
>
|
|
|
|
|
<Form layout="inline" className="inviteForm">
|
|
|
|
|
<Form.Item label="项目邀请码">
|
|
|
|
|
{getFieldDecorator('code', {
|
|
|
|
|
rules: [
|
|
|
|
|
{ required: true, message: '请输入6位项目邀请码' },
|
|
|
|
|
{ validator: checkValue },
|
|
|
|
|
],
|
|
|
|
|
})(
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="请输入6位项目邀请码"
|
|
|
|
|
autoComplete="off"
|
|
|
|
|
maxLength="6"
|
|
|
|
|
style={{ width: '300px' }}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</Form.Item>
|
|
|
|
|
<Form.Item label="选择角色">
|
|
|
|
|
{getFieldDecorator('role', {
|
|
|
|
|
rules: [{ required: true, message: '请选择角色' }],
|
|
|
|
|
})(
|
|
|
|
|
<Radio.Group>
|
|
|
|
|
<Radio value="manager">管理员</Radio>
|
|
|
|
|
<Radio value="developer">开发者</Radio>
|
|
|
|
|
<Radio value="reporter">报告者</Radio>
|
|
|
|
|
</Radio.Group>
|
|
|
|
|
)}
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Form>
|
|
|
|
|
</Modal>
|
|
|
|
|
);
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const PersonalInfoForm = Form.create({
|
|
|
|
|
name: 'personal_info_form',
|
|
|
|
|
})(
|
|
|
|
|
forwardRef((props) => {
|
|
|
|
|
const { getFieldDecorator, validateFields } = props.form;
|
|
|
|
|
const { onOk, onCancel, contentFileList, uploadProps } = props;
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (props.visible) {
|
|
|
|
|
props.form.setFieldsValue({
|
|
|
|
|
remarks: '',
|
|
|
|
|
attachment_id: '',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}, [props.visible])
|
2021-06-11 09:25:59 +08:00
|
|
|
|
2025-03-11 11:43:22 +08:00
|
|
|
const handleOk = () => {
|
|
|
|
|
validateFields((error, values) => {
|
|
|
|
|
if (!error) {
|
|
|
|
|
const attachmentId = contentFileList.map((item) => {
|
|
|
|
|
return item.response ? item.response.id : item.id;
|
|
|
|
|
});
|
|
|
|
|
onOk({ ...values, attachment_id: attachmentId.join(',') });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Modal
|
|
|
|
|
title="填写个人信息"
|
|
|
|
|
width="480px"
|
|
|
|
|
visible={props.visible}
|
|
|
|
|
centered={true}
|
|
|
|
|
onOk={handleOk}
|
|
|
|
|
onCancel={onCancel}
|
|
|
|
|
>
|
|
|
|
|
<Form layout="inline" className="inviteForm2">
|
|
|
|
|
<Form.Item label="个人情况">
|
|
|
|
|
{getFieldDecorator('remarks', {
|
|
|
|
|
rules: [{ required: true, message: '请输入个人情况' }],
|
|
|
|
|
})(
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="请输入个人情况"
|
|
|
|
|
// autoComplete="off"
|
|
|
|
|
maxLength={200}
|
|
|
|
|
style={{ width: '300px', pointerEvents: 'auto' }} // 确保 pointer-events 为 auto
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</Form.Item>
|
|
|
|
|
<Form.Item label="个人资料" style={{ flexWrap: 'nowrap' }}>
|
|
|
|
|
{getFieldDecorator('attachment_id', {
|
|
|
|
|
rules: [],
|
|
|
|
|
})(
|
|
|
|
|
<Upload {...uploadProps}>
|
|
|
|
|
<Button type="default" className='mr5'>
|
|
|
|
|
<Icon type="upload" /> 上传附件
|
|
|
|
|
</Button>
|
|
|
|
|
(单个文件最大20MB)
|
|
|
|
|
</Upload>
|
|
|
|
|
)}
|
|
|
|
|
</Form.Item>
|
|
|
|
|
</Form>
|
|
|
|
|
</Modal>
|
|
|
|
|
);
|
2021-06-11 09:25:59 +08:00
|
|
|
})
|
2025-03-11 11:43:22 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
export default forwardRef((props) => {
|
|
|
|
|
const [visible, setVisible] = useState(false);
|
|
|
|
|
const [infoVis, setInfoVis] = useState(false);
|
|
|
|
|
const [contentFileList, setContentFileList] = useState([]);
|
|
|
|
|
// 新增状态用于保存加入项目表单的数据
|
|
|
|
|
const [joinProjectValues, setJoinProjectValues] = useState({});
|
|
|
|
|
|
|
|
|
|
const uploadProps = {
|
|
|
|
|
fileList: contentFileList,
|
|
|
|
|
multiple: false,
|
|
|
|
|
action: `${getUploadActionUrl()}`,
|
|
|
|
|
onChange: (info) => {
|
|
|
|
|
let content = info.fileList;
|
|
|
|
|
setContentFileList(appendFileSizeToUploadFileAll(content));
|
|
|
|
|
},
|
|
|
|
|
onRemove: (file) => {
|
|
|
|
|
if (file.response != undefined) {
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
content: '是否确认删除?',
|
|
|
|
|
onOk: () => {
|
|
|
|
|
deleteAttachment(file);
|
|
|
|
|
},
|
|
|
|
|
onCancel() {
|
|
|
|
|
console.log('Cancel');
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
beforeUpload: (file) => {
|
|
|
|
|
console.log('beforeUpload', file.name);
|
|
|
|
|
const isLt150M = file.size / 1024 / 1024 <= 20;
|
|
|
|
|
if (!isLt150M) {
|
|
|
|
|
message.error('文件大小必须不超过20MB!');
|
|
|
|
|
}
|
|
|
|
|
return isLt150M;
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const deleteAttachment = (file) => {
|
|
|
|
|
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`;
|
|
|
|
|
Axios.delete(url, {})
|
|
|
|
|
.then((response) => {
|
|
|
|
|
if (response.data) {
|
|
|
|
|
const { status } = response.data;
|
|
|
|
|
if (status === 0) {
|
|
|
|
|
setContentFileList([]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.log(error);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleJoinProjectOk = (values) => {
|
|
|
|
|
const url = `/applied_projects.json`;
|
|
|
|
|
setJoinProjectValues({ ...values })
|
|
|
|
|
Axios.post(url, {
|
|
|
|
|
applied_project: {
|
|
|
|
|
alert_remarks: false,
|
|
|
|
|
...values,
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
.then((result) => {
|
|
|
|
|
if (result) {
|
|
|
|
|
setVisible(false);
|
2025-03-11 16:48:08 +08:00
|
|
|
if (result.data.data.need_verify) {
|
2025-03-11 11:43:22 +08:00
|
|
|
setInfoVis(true);
|
|
|
|
|
} else {
|
|
|
|
|
props.showNotification('申请已提交,请等待项目管理者审核!');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.log(error);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handlePersonalInfoOk = (values) => {
|
|
|
|
|
const url = `/applied_projects.json`;
|
|
|
|
|
let attachmentId = contentFileList.map(item => {
|
|
|
|
|
return item.response ? item.response.id : item.id
|
|
|
|
|
})
|
|
|
|
|
Axios.post(url, {
|
2025-03-11 15:50:55 +08:00
|
|
|
applied_project: {
|
2025-03-11 11:43:22 +08:00
|
|
|
...joinProjectValues,
|
|
|
|
|
alert_remarks: true,
|
|
|
|
|
...values,
|
|
|
|
|
attachment_id: attachmentId.join(','),
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
.then((result) => {
|
|
|
|
|
if (result && result.data) {
|
|
|
|
|
setInfoVis(false);
|
|
|
|
|
setContentFileList([]);
|
|
|
|
|
props.showNotification('申请已提交,请等待项目管理者审核!');
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
console.log(error);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<React.Fragment>
|
|
|
|
|
<JoinProjectForm
|
|
|
|
|
visible={visible}
|
|
|
|
|
onOk={handleJoinProjectOk}
|
|
|
|
|
onCancel={() => setVisible(false)}
|
|
|
|
|
/>
|
|
|
|
|
<PersonalInfoForm
|
|
|
|
|
visible={infoVis}
|
|
|
|
|
onOk={handlePersonalInfoOk}
|
|
|
|
|
onCancel={() => setInfoVis(false)}
|
|
|
|
|
contentFileList={contentFileList}
|
|
|
|
|
uploadProps={uploadProps}
|
|
|
|
|
/>
|
|
|
|
|
<a onClick={() => setVisible(true)}>加入项目</a>
|
|
|
|
|
</React.Fragment>
|
|
|
|
|
);
|
|
|
|
|
});
|