forked from Gitlink/forgeplus-react
glcc支持多个项目报名+首页时间配置从后台读取
This commit is contained in:
parent
fab7510783
commit
9e521b4ace
|
|
@ -160,7 +160,7 @@
|
|||
},
|
||||
"source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.nlark.com/source-map/download/source-map-0.5.7.tgz",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
|
||||
}
|
||||
}
|
||||
|
|
@ -1296,13 +1296,13 @@
|
|||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.nlark.com/inherits/download/inherits-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
|
||||
"integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
|
||||
"dev": true
|
||||
},
|
||||
"util": {
|
||||
"version": "0.10.3",
|
||||
"resolved": "https://registry.nlark.com/util/download/util-0.10.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
|
||||
"integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
|
@ -2561,7 +2561,7 @@
|
|||
"dependencies": {
|
||||
"define-property": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.nlark.com/define-property/download/define-property-1.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
|
||||
"integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
|
||||
"requires": {
|
||||
"is-descriptor": "^1.0.0"
|
||||
|
|
@ -2869,7 +2869,7 @@
|
|||
"dependencies": {
|
||||
"resolve": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npm.taobao.org/resolve/download/resolve-1.1.7.tgz",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
|
||||
"integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs="
|
||||
}
|
||||
}
|
||||
|
|
@ -3661,7 +3661,7 @@
|
|||
"dependencies": {
|
||||
"define-property": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.nlark.com/define-property/download/define-property-0.2.5.tgz",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
|
||||
"requires": {
|
||||
"is-descriptor": "^0.1.0"
|
||||
|
|
@ -6386,7 +6386,7 @@
|
|||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.nlark.com/path-to-regexp/download/path-to-regexp-0.1.7.tgz?cache=0&sync_timestamp=1618847046445&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fpath-to-regexp%2Fdownload%2Fpath-to-regexp-0.1.7.tgz",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
|
||||
"dev": true
|
||||
},
|
||||
|
|
@ -6859,7 +6859,7 @@
|
|||
"dependencies": {
|
||||
"core-js": {
|
||||
"version": "1.2.7",
|
||||
"resolved": "https://registry.npmmirror.com/core-js/download/core-js-1.2.7.tgz",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
|
||||
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
|
||||
},
|
||||
"promise": {
|
||||
|
|
@ -8069,7 +8069,7 @@
|
|||
"dependencies": {
|
||||
"pify": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.nlark.com/pify/download/pify-3.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
||||
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
|
||||
}
|
||||
}
|
||||
|
|
@ -11630,7 +11630,7 @@
|
|||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.nlark.com/punycode/download/punycode-1.4.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
|
||||
"dev": true
|
||||
}
|
||||
|
|
@ -16594,7 +16594,7 @@
|
|||
"dependencies": {
|
||||
"jsesc": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.nlark.com/jsesc/download/jsesc-0.5.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
|
||||
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
|
||||
"dev": true
|
||||
}
|
||||
|
|
@ -17517,7 +17517,7 @@
|
|||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/ms/download/ms-2.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true
|
||||
}
|
||||
|
|
@ -17629,7 +17629,7 @@
|
|||
"dependencies": {
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.nlark.com/extend-shallow/download/extend-shallow-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
|
|
@ -18110,7 +18110,7 @@
|
|||
},
|
||||
"define-property": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.nlark.com/define-property/download/define-property-0.2.5.tgz",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||
"integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
|
||||
"requires": {
|
||||
"is-descriptor": "^0.1.0"
|
||||
|
|
@ -18118,7 +18118,7 @@
|
|||
},
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.nlark.com/extend-shallow/download/extend-shallow-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
|
|
@ -18126,7 +18126,7 @@
|
|||
},
|
||||
"source-map": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.nlark.com/source-map/download/source-map-0.5.7.tgz",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
|
||||
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
|
||||
}
|
||||
}
|
||||
|
|
@ -18143,7 +18143,7 @@
|
|||
"dependencies": {
|
||||
"define-property": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.nlark.com/define-property/download/define-property-1.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
|
||||
"integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
|
||||
"requires": {
|
||||
"is-descriptor": "^1.0.0"
|
||||
|
|
@ -20018,7 +20018,7 @@
|
|||
"dependencies": {
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.nlark.com/inherits/download/inherits-2.0.3.tgz",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"dev": true
|
||||
}
|
||||
|
|
@ -20394,7 +20394,7 @@
|
|||
"dependencies": {
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.nlark.com/extend-shallow/download/extend-shallow-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
|
@ -20575,7 +20575,7 @@
|
|||
},
|
||||
"fill-range": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-4.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
||||
"integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
|
@ -20587,7 +20587,7 @@
|
|||
"dependencies": {
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.nlark.com/extend-shallow/download/extend-shallow-2.0.1.tgz",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
|
@ -20653,7 +20653,7 @@
|
|||
},
|
||||
"is-number": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.nlark.com/is-number/download/is-number-3.0.0.tgz",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
|
||||
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
|
@ -20662,7 +20662,7 @@
|
|||
"dependencies": {
|
||||
"kind-of": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
|
|
|||
|
|
@ -212,4 +212,13 @@ export function getGlccSettings(params) {
|
|||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除项目报名信息
|
||||
export function deleteApplyInfo(data) {
|
||||
return fetch({
|
||||
url: `/api/applyInformation/delete`,
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,291 @@
|
|||
import React , { useCallback, useEffect , useState } from 'react';
|
||||
import { Button, Form, Input, Select, Upload, message, Popconfirm } from 'antd';
|
||||
import {getUploadActionUrl} from 'educoder';
|
||||
import {applyGlcc, updateApplyGlcc} from '../api';
|
||||
import TextArea from 'antd/lib/input/TextArea';
|
||||
import { main_site_url } from '../fetch';
|
||||
import TaskApply from './taskApply';
|
||||
import './index.scss';
|
||||
import { FlexAJ } from '../../forge/Component/layout';
|
||||
const Option = Select.Option;
|
||||
// 编辑项目、课题报名信息
|
||||
function EditRepoApplyInfo(props) {
|
||||
const {form, applyInfo, current_user, round, cateList, setReload, isAddRepo, setIsAddRepo, setIsEdit, setEditRepoCount} = props;
|
||||
const phonereg = /(^|\s*\+?0?0?86|\D)(1\d{2})[-\s]{0,3}(\d{4})[-\s]{0,3}(\d{4})(?=\D|$)/
|
||||
const emailreg = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/
|
||||
const {getFieldDecorator, validateFields, setFieldsValue, validateFieldsAndScroll } = form;
|
||||
const [imageUrl, setImageUrl] = useState(undefined);
|
||||
// 提交按钮loading效果
|
||||
const [loading, setLoading] = useState(false);
|
||||
// 课题报名个数
|
||||
const [taskCount, setTaskCount] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
if(applyInfo){
|
||||
const {projectName, projectType, gitlinkUrl, contactName, contactPhone, projectIntro, registrationTaskList, projectLogoId, contactMail} = applyInfo;
|
||||
const taskInfo = {};
|
||||
const taskCountArr = []
|
||||
registrationTaskList.map((item, index)=>{
|
||||
taskCountArr.push(index+1);
|
||||
const{taskName, taskUrl, taskDifficulty, taskReward, tutorName, tutorMail, taskDesc, tutorPhone} = item;
|
||||
taskInfo[`taskName${index+1}`] = taskName;
|
||||
taskInfo[`taskUrl${index+1}`] = taskUrl;
|
||||
taskInfo[`taskDifficulty${index+1}`] = taskDifficulty;
|
||||
taskInfo[`taskReward${index+1}`] = taskReward;
|
||||
taskInfo[`tutorName${index+1}`] = tutorName;
|
||||
taskInfo[`tutorMail${index+1}`] = tutorMail;
|
||||
taskInfo[`taskDesc${index+1}`] = taskDesc;
|
||||
taskInfo[`tutorPhone${index+1}`] = tutorPhone;
|
||||
})
|
||||
setTaskCount(taskCountArr);
|
||||
setTimeout(() => {
|
||||
setFieldsValue({
|
||||
projectName, projectType, gitlinkUrl, contactName, contactPhone, projectIntro, contactMail,
|
||||
...taskInfo,
|
||||
logo: {file:{response:{id: projectLogoId}}}
|
||||
})
|
||||
}, 100);
|
||||
}else{
|
||||
setTaskCount([1])
|
||||
}
|
||||
}, [])
|
||||
|
||||
const helper = useCallback(
|
||||
(label, extra, name, rules, widget) => (
|
||||
<Form.Item label={label} extra={extra}>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
</Form.Item>
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
// 当用户输入结束时 检验用户输入是否符合规范
|
||||
function verify(dataIndex){
|
||||
validateFields([dataIndex],(error, values)=>{
|
||||
if(error && error[dataIndex]){
|
||||
return;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 报名夏令营
|
||||
function handleSubmit(e){
|
||||
e.preventDefault();
|
||||
validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
const registrationTaskList = []
|
||||
taskCount && taskCount.map(item=>{
|
||||
registrationTaskList.push({
|
||||
taskName: values[`taskName${item}`],
|
||||
taskUrl: values[`taskUrl${item}`],
|
||||
taskDifficulty: values[`taskDifficulty${item}`],
|
||||
taskReward: values[`taskReward${item}`],
|
||||
tutorName: values[`tutorName${item}`],
|
||||
tutorMail: values[`tutorMail${item}`],
|
||||
taskDesc: values[`taskDesc${item}`],
|
||||
tutorPhone: values[`tutorPhone${item}`],
|
||||
round
|
||||
})
|
||||
})
|
||||
const {projectName, projectType, gitlinkUrl, contactName, contactPhone, projectIntro, contactMail} = values;
|
||||
const params ={
|
||||
projectName, projectType, gitlinkUrl, contactName, contactPhone, projectIntro, registrationTaskList, round, contactMail,
|
||||
projectLogoId: values.logo.file.response.id+"",
|
||||
userId: current_user.user_id,
|
||||
userName: current_user.username
|
||||
}
|
||||
setLoading(true);
|
||||
if(applyInfo){
|
||||
// 用户已经报名项目
|
||||
params[`id`] = applyInfo.id;
|
||||
updateApplyGlcc(params).then(response=>{
|
||||
if(response && response.message === "success"){
|
||||
message.success("修改成功");
|
||||
setReload();
|
||||
}
|
||||
setLoading(false);
|
||||
setIsEdit(false);
|
||||
setEditRepoCount(0);
|
||||
setTimeout(() => {
|
||||
scrollToRepoInfo()
|
||||
}, 100);
|
||||
})
|
||||
return
|
||||
}
|
||||
applyGlcc(params).then(response=>{
|
||||
if(response && response.message === "success"){
|
||||
message.success("报名成功");
|
||||
isAddRepo && setIsAddRepo(false);
|
||||
setReload();
|
||||
}
|
||||
setLoading(false);
|
||||
window.scrollTo(0,950);
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 检查文件上传是否符合规定
|
||||
function beforeUpload(file){
|
||||
const isLt100M = file.size / 1024 / 1024 < 20;
|
||||
if (!isLt100M) {
|
||||
message.error(`文件大小必须小于${20}M!`);
|
||||
}
|
||||
const isType = file.type === "image/png" || file.type === "image/jpg" || file.type === "image/jpeg";
|
||||
if (!isType) {
|
||||
message.error("只能上传png、jpg、jpeg格式文件");
|
||||
}
|
||||
return isLt100M && isType;
|
||||
}
|
||||
function getBase64(img, callback) {
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener('load', () => callback(reader.result));
|
||||
reader.readAsDataURL(img);
|
||||
reader.onload = function(e) {
|
||||
setImageUrl(e.target.result); // 上传的图片的编码
|
||||
}
|
||||
}
|
||||
|
||||
// 上传完成后
|
||||
function handleChange(info){
|
||||
if(info && info.file && info.file.status === "done"){
|
||||
getBase64(info.file.originFileObj, imageUrl =>
|
||||
setImageUrl(imageUrl)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 添加课题输入框
|
||||
function addTaskApplyForm(){
|
||||
setTaskCount(taskCount.concat([taskCount.length+1]));
|
||||
}
|
||||
|
||||
// 删除课题报名
|
||||
function deleteTaskApply(index){
|
||||
const arr = [...taskCount];
|
||||
arr.splice(index-1, 1)
|
||||
setTaskCount(arr);
|
||||
}
|
||||
|
||||
// 取消编辑点击函数
|
||||
function cancelEdit(){
|
||||
if(isAddRepo){
|
||||
// 新增项目信息
|
||||
setIsAddRepo(false);
|
||||
return
|
||||
}
|
||||
// 编辑项目信息
|
||||
setIsEdit(false);
|
||||
setEditRepoCount(0);
|
||||
setTimeout(() => {
|
||||
scrollToRepoInfo()
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// 屏幕滚动到当前项目区域
|
||||
function scrollToRepoInfo(){
|
||||
const element = document.getElementById(`repoShowId${applyInfo.id}`);
|
||||
window.scrollTo(0, element.offsetTop-100);
|
||||
}
|
||||
|
||||
return(
|
||||
<div className='applyInfoBox'>
|
||||
<div className='titleG font-18 mb10' id="editRepoInfoId">项目信息</div>
|
||||
{taskCount && <Form className="pt20 glcc_info_form" onSubmit={handleSubmit}>
|
||||
{helper('项目名称',
|
||||
'',
|
||||
'projectName',
|
||||
[{ required: true, message: "请输入项目名称,长度限制32个字符" },
|
||||
{ max: 32, message: '超出限制长度32位字符,请重新编辑' }],
|
||||
<Input placeholder="请输入项目名称,长度限制32个字符" onBlur={()=>{verify("name")}}/>
|
||||
)}
|
||||
{helper('项目分类',
|
||||
'',
|
||||
'projectType',
|
||||
[{ required: true, message: "请选择项目分类" }],
|
||||
<Select placeholder="请选择项目分类">
|
||||
{cateList && cateList.map(item=> {return <Option value={item.name} key={item.id}>{item.name}</Option>})}
|
||||
</Select>
|
||||
)}
|
||||
{helper('GitLink地址',
|
||||
'',
|
||||
'gitlinkUrl',
|
||||
[{ required: true, message: "请输入GitLink项目地址" },
|
||||
{ max: 252, message: '超出限制长度252位字符,请重新编辑' }],
|
||||
<Input placeholder="请输入GitLink项目地址" onBlur={()=>{verify("gitlink")}}/>
|
||||
)}
|
||||
{helper('联系人姓名',
|
||||
'',
|
||||
'contactName',
|
||||
[{ required: true, message: "请输入项目联系人姓名" },
|
||||
{ max: 32, message: '超出限制长度32位字符,请重新编辑' }],
|
||||
<Input placeholder="请输入项目联系人姓名" onBlur={()=>{verify("name")}}/>
|
||||
)}
|
||||
{helper('联系人电话',
|
||||
'',
|
||||
'contactPhone',
|
||||
[{ required: true, message: "输入项目联系人手机号码" },
|
||||
{ pattern: phonereg, message: "请输入正确的手机号码"},],
|
||||
<Input placeholder="输入项目联系人手机号码" onBlur={()=>{verify("name")}}/>
|
||||
)}
|
||||
{helper('联系人邮箱',
|
||||
'',
|
||||
'contactMail',
|
||||
[{ required: true, message: "输入项目联系人邮箱" },
|
||||
{ pattern: emailreg, message: "请输入正确的邮箱地址"},],
|
||||
<Input placeholder="输入项目联系人邮箱" onBlur={()=>{verify("name")}}/>
|
||||
)}
|
||||
<div className='introArea'>{helper('社区简介',
|
||||
'',
|
||||
'projectIntro',
|
||||
[{ required: true, message: "请输入社区简介" },
|
||||
{ max: 200, message: '超出限制长度200位字符,请重新编辑' }],
|
||||
<TextArea placeholder="请输入社区简介" onBlur={()=>{verify("intro")}} rows={4}/>
|
||||
)}</div>
|
||||
<div className='introArea'>{helper('项目logo',
|
||||
'限制上传格式为:png、jpg、jpeg,限制20M。建议上传大小为382*228',
|
||||
'logo',
|
||||
[{ required: true, message: "请正确上传项目logo" }],
|
||||
<Upload
|
||||
listType="picture-card"
|
||||
className="avatar-uploader"
|
||||
showUploadList={false}
|
||||
action={getUploadActionUrl()}
|
||||
accept=".png,.jpg,.jpeg"
|
||||
beforeUpload={beforeUpload}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{(imageUrl || applyInfo) ? <img src={imageUrl || `${main_site_url}/api/attachments/${applyInfo && applyInfo.projectLogoId}`} alt="avatar" style={{ maxWidth: '100px', maxHeight: '100px' }} /> : <div>
|
||||
<i className='iconfont icon-tianjiadaohang font-30'></i>
|
||||
<div className="ant-upload-text font-13">请上传logo图片</div>
|
||||
</div>}
|
||||
</Upload>
|
||||
)}</div>
|
||||
{taskCount.map((item, index)=>{
|
||||
return <div className='taskApplyBox' key={item}>
|
||||
<FlexAJ className='taskApplyTitleBox'>
|
||||
<div className='taskApplyTitle font-16'>课题信息(<span>{index+1}</span>/5)</div>
|
||||
{index>0 && <Button type="link" onClick={()=>{deleteTaskApply(item)}}><i className='iconfont icon-shanchuicon3 mr5 font-15'></i>删除</Button>}
|
||||
</FlexAJ>
|
||||
<TaskApply helper={helper} taskKey={item} phonereg={phonereg} emailreg={emailreg}/>
|
||||
</div>
|
||||
})}
|
||||
{taskCount && taskCount.length<5 && <div>
|
||||
<Button type="primary" className='taskApplyBox' style={{width: "100px", height: "36px"}} onClick={addTaskApplyForm}>添加课题</Button>
|
||||
</div>}
|
||||
<Form.Item className='subInfo introArea'>
|
||||
{(isAddRepo || applyInfo) && <Popconfirm
|
||||
title={<span>取消编辑将清除已填写的所有项目信息,请谨慎操作</span>}
|
||||
onConfirm={cancelEdit}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
>
|
||||
<Button className='mr20' style={{height: '36px', width: '110px'}}>取消</Button>
|
||||
</Popconfirm>}
|
||||
<Button type="primary" htmlType="submit" className='sub' loading={loading}>提交</Button>
|
||||
</Form.Item>
|
||||
</Form>}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Form.create()(EditRepoApplyInfo);
|
||||
|
|
@ -1,38 +1,23 @@
|
|||
import React , { useCallback, useEffect , useState } from 'react';
|
||||
import { Breadcrumb, Button, Form, Input, Select, Upload, Modal, message } from 'antd';
|
||||
import {getUploadActionUrl} from 'educoder';
|
||||
import {getUserApplyInfo, applyGlcc, updateApplyGlcc} from '../api';
|
||||
import React , { useEffect , useState } from 'react';
|
||||
import { Breadcrumb, message } from 'antd';
|
||||
import {getUserApplyInfo} from '../api';
|
||||
import axios from 'axios';
|
||||
import TextArea from 'antd/lib/input/TextArea';
|
||||
import { main_site_url } from '../fetch';
|
||||
import TaskApply from './taskApply';
|
||||
import RepoInfo from './repoInfo';
|
||||
import EditInfo from './editInfo';
|
||||
import banner from "../img/banner.png";
|
||||
import apply1 from "../img/apply1.png";
|
||||
import './index.scss';
|
||||
import { FlexAJ } from '../../forge/Component/layout';
|
||||
const Option = Select.Option;
|
||||
// 项目、课题报名
|
||||
function Apply(props) {
|
||||
const phonereg = /(^|\s*\+?0?0?86|\D)(1\d{2})[-\s]{0,3}(\d{4})[-\s]{0,3}(\d{4})(?=\D|$)/
|
||||
const emailreg = /^[a-zA-Z0-9]+([.\-_\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/
|
||||
const {form, current_user, showNotification, round} = props;
|
||||
const {getFieldDecorator, validateFields, setFieldsValue, validateFieldsAndScroll } = form;
|
||||
const {current_user, round} = props;
|
||||
const [reload, setReload] = useState(undefined);
|
||||
const [imageUrl, setImageUrl] = useState(undefined);
|
||||
// 提交按钮loading效果
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [cateList, setCateList] = useState([]);
|
||||
const [userApplyInfo, setUserApplyInfo] = useState(undefined);
|
||||
// 课题报名个数
|
||||
const [taskCount, setTaskCount] = useState([1]);
|
||||
|
||||
const helper = useCallback(
|
||||
(label, extra, name, rules, widget) => (
|
||||
<Form.Item label={label} extra={extra}>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
</Form.Item>
|
||||
),
|
||||
[]
|
||||
);
|
||||
const [userApplyInfo, setUserApplyInfo] = useState([]);
|
||||
// 添加一个项目
|
||||
const [isAddRepo, setIsAddRepo] = useState(false);
|
||||
// 编辑项目个数
|
||||
const [editRepoCount, setEditRepoCount] = useState(0);
|
||||
|
||||
useEffect(()=>{
|
||||
// 进入此页面置顶
|
||||
|
|
@ -55,145 +40,38 @@ function Apply(props) {
|
|||
current_user && round && getUserApplyInfo({userId: current_user.user_id, round}).then(response=>{
|
||||
if(response && response.message === "success"){
|
||||
setUserApplyInfo(response.data);
|
||||
if(!response.data){
|
||||
return
|
||||
}
|
||||
const {projectName, projectType, gitlinkUrl, contactName, contactPhone, projectIntro, registrationTaskList, projectLogoId, contactMail} = response.data;
|
||||
const taskInfo = {};
|
||||
const taskCountArr = []
|
||||
registrationTaskList.map((item, index)=>{
|
||||
taskCountArr.push(index+1);
|
||||
const{taskName, taskUrl, taskDifficulty, taskReward, tutorName, tutorMail, taskDesc, tutorPhone} = item;
|
||||
taskInfo[`taskName${index+1}`] = taskName;
|
||||
taskInfo[`taskUrl${index+1}`] = taskUrl;
|
||||
taskInfo[`taskDifficulty${index+1}`] = taskDifficulty;
|
||||
taskInfo[`taskReward${index+1}`] = taskReward;
|
||||
taskInfo[`tutorName${index+1}`] = tutorName;
|
||||
taskInfo[`tutorMail${index+1}`] = tutorMail;
|
||||
taskInfo[`taskDesc${index+1}`] = taskDesc;
|
||||
taskInfo[`tutorPhone${index+1}`] = tutorPhone;
|
||||
})
|
||||
setTaskCount(taskCountArr);
|
||||
setFieldsValue({
|
||||
projectName, projectType, gitlinkUrl, contactName, contactPhone, projectIntro, contactMail,
|
||||
...taskInfo,
|
||||
logo: {file:{response:{id: projectLogoId}}}
|
||||
})
|
||||
}
|
||||
})
|
||||
}, [reload])
|
||||
|
||||
// 当用户输入结束时 检验用户输入是否符合规范
|
||||
function verify(dataIndex){
|
||||
validateFields([dataIndex],(error, values)=>{
|
||||
if(error && error[dataIndex]){
|
||||
return;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 报名夏令营
|
||||
function handleSubmit(e){
|
||||
e.preventDefault();
|
||||
validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
const registrationTaskList = []
|
||||
taskCount && taskCount.map(item=>{
|
||||
registrationTaskList.push({
|
||||
taskName: values[`taskName${item}`],
|
||||
taskUrl: values[`taskUrl${item}`],
|
||||
taskDifficulty: values[`taskDifficulty${item}`],
|
||||
taskReward: values[`taskReward${item}`],
|
||||
tutorName: values[`tutorName${item}`],
|
||||
tutorMail: values[`tutorMail${item}`],
|
||||
taskDesc: values[`taskDesc${item}`],
|
||||
tutorPhone: values[`tutorPhone${item}`],
|
||||
round
|
||||
})
|
||||
})
|
||||
const {projectName, projectType, gitlinkUrl, contactName, contactPhone, projectIntro, contactMail} = values;
|
||||
const params ={
|
||||
projectName, projectType, gitlinkUrl, contactName, contactPhone, projectIntro, registrationTaskList, round, contactMail,
|
||||
projectLogoId: values.logo.file.response.id+"",
|
||||
userId: current_user.user_id,
|
||||
userName: current_user.username
|
||||
}
|
||||
setLoading(true);
|
||||
if(userApplyInfo){
|
||||
// 用户已经报名项目
|
||||
params[`id`] = userApplyInfo.id;
|
||||
updateApplyGlcc(params).then(response=>{
|
||||
if(response && response.message === "success"){
|
||||
message.success("修改成功");
|
||||
setReload(Math.random());
|
||||
}
|
||||
setLoading(false);
|
||||
window.scrollTo(0,0);
|
||||
})
|
||||
return
|
||||
}
|
||||
applyGlcc(params).then(response=>{
|
||||
if(response && response.message === "success"){
|
||||
message.success("报名成功");
|
||||
setReload(Math.random());
|
||||
}
|
||||
setLoading(false);
|
||||
window.scrollTo(0,0);
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 检查文件上传是否符合规定
|
||||
function beforeUpload(file){
|
||||
const isLt100M = file.size / 1024 / 1024 < 20;
|
||||
if (!isLt100M) {
|
||||
showNotification(`文件大小必须小于${20}M!`);
|
||||
}
|
||||
const isType = file.type === "image/png" || file.type === "image/jpg" || file.type === "image/jpeg";
|
||||
if (!isType) {
|
||||
showNotification("只能上传png、jpg、jpeg格式文件");
|
||||
}
|
||||
return isLt100M && isType;
|
||||
}
|
||||
function getBase64(img, callback) {
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener('load', () => callback(reader.result));
|
||||
reader.readAsDataURL(img);
|
||||
reader.onload = function(e) {
|
||||
setImageUrl(e.target.result); // 上传的图片的编码
|
||||
// 添加项目点击函数
|
||||
function addRepoBut(){
|
||||
if(isAddRepo || editRepoCount){
|
||||
scrollToEdit();
|
||||
message.error("请先提交当前项目信息");
|
||||
return;
|
||||
}
|
||||
setIsAddRepo(true);
|
||||
setTimeout(() => {
|
||||
scrollToEdit()
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// 上传完成后
|
||||
function handleChange(info){
|
||||
if(info && info.file && info.file.status === "done"){
|
||||
getBase64(info.file.originFileObj, imageUrl =>
|
||||
setImageUrl(imageUrl)
|
||||
);
|
||||
}
|
||||
// 屏幕滚动到编辑区域
|
||||
function scrollToEdit(){
|
||||
const element = document.getElementById("editRepoInfoId");
|
||||
window.scrollTo(0, element.offsetTop-80);
|
||||
}
|
||||
|
||||
// 添加课题输入框
|
||||
function addTaskApplyForm(){
|
||||
setTaskCount(taskCount.concat([taskCount.length+1]));
|
||||
}
|
||||
|
||||
// 删除课题报名
|
||||
function deleteTaskApply(index){
|
||||
const arr = [...taskCount];
|
||||
arr.splice(index-1, 1)
|
||||
setTaskCount(arr);
|
||||
}
|
||||
return(
|
||||
<div className="glcc_apply">
|
||||
<img className="glcc-banner" src={banner} alt=''></img>
|
||||
{/* <img className="glcc-banner" src={banner} alt=''></img> */}
|
||||
<div className='apply'>
|
||||
<Breadcrumb className='pt20 font-16 breadcrumbGlcc'>
|
||||
<Breadcrumb.Item><a href="/glcc">开源夏令营</a></Breadcrumb.Item>
|
||||
<Breadcrumb.Item>项目报名</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
{userApplyInfo && <div className='applySuccess mt20 font-15'>您已报名成功,可实时修改您的报名信息再次提交。请关注夏令营首页新闻公告获得更多活动资讯!</div>}
|
||||
{userApplyInfo.length > 0 && <div className='applySuccess mt20 font-15'>您已报名成功,可实时修改您的报名信息再次提交。请关注夏令营首页新闻公告获得更多活动资讯!</div>}
|
||||
<div className={`explain`}>
|
||||
<p className='font-15 c000'>申请说明</p>
|
||||
<div>1、项目报名时间为<span className='c000'>4月29日—5月30日</span>,请在报名截止时间(北京时间<span className='c000'>2022年5月30日24点</span>)前提交报名信息。</div>
|
||||
|
|
@ -201,98 +79,16 @@ function Apply(props) {
|
|||
<div>3、如果您的项目还未迁移到GitLink上,迁移事项请查看<a href='https://forum.gitlink.org.cn/forums/7296/detail' target="_blank" className='link'>迁移说明文档</a>。如在迁移过程中遇到问题,请加qq群: 1071514693 联系qq群管理员。</div>
|
||||
<div>4、提交社区和题目信息后,欢迎与组委会联系沟通宣传推广和后续合作工作。联系人微信: _TigerWang(备注GitLink编程夏令营)</div>
|
||||
</div>
|
||||
<div className='pt20 font-18'><img src={apply1} alt="" width="25px" className="mr10"/>项目报名</div>
|
||||
<div className='applyInfoBox mt20'>
|
||||
<div className='titleG font-18 mb10'>项目信息</div>
|
||||
<Form className="pt20 glcc_info_form" onSubmit={handleSubmit}>
|
||||
{helper('项目名称',
|
||||
'',
|
||||
'projectName',
|
||||
[{ required: true, message: "请输入项目名称,长度限制32个字符" },
|
||||
{ max: 32, message: '超出限制长度32位字符,请重新编辑' }],
|
||||
<Input placeholder="请输入项目名称,长度限制32个字符" onBlur={()=>{verify("name")}}/>
|
||||
)}
|
||||
{helper('项目分类',
|
||||
'',
|
||||
'projectType',
|
||||
[{ required: true, message: "请选择项目分类" }],
|
||||
<Select placeholder="请选择项目分类">
|
||||
{cateList && cateList.map(item=> {return <Option value={item.name} key={item.id}>{item.name}</Option>})}
|
||||
</Select>
|
||||
)}
|
||||
{helper('GitLink地址',
|
||||
'',
|
||||
'gitlinkUrl',
|
||||
[{ required: true, message: "请输入GitLink项目地址" },
|
||||
{ max: 252, message: '超出限制长度252位字符,请重新编辑' }],
|
||||
<Input placeholder="请输入GitLink项目地址" onBlur={()=>{verify("gitlink")}}/>
|
||||
)}
|
||||
{helper('联系人姓名',
|
||||
'',
|
||||
'contactName',
|
||||
[{ required: true, message: "请输入项目联系人姓名" },
|
||||
{ max: 32, message: '超出限制长度32位字符,请重新编辑' }],
|
||||
<Input placeholder="请输入项目联系人姓名" onBlur={()=>{verify("name")}}/>
|
||||
)}
|
||||
{helper('联系人电话',
|
||||
'',
|
||||
'contactPhone',
|
||||
[{ required: true, message: "输入项目联系人手机号码" },
|
||||
{ pattern: phonereg, message: "请输入正确的手机号码"},],
|
||||
<Input placeholder="输入项目联系人手机号码" onBlur={()=>{verify("name")}}/>
|
||||
)}
|
||||
{helper('联系人邮箱',
|
||||
'',
|
||||
'contactMail',
|
||||
[{ required: true, message: "输入项目联系人邮箱" },
|
||||
{ pattern: emailreg, message: "请输入正确的邮箱地址"},],
|
||||
<Input placeholder="输入项目联系人邮箱" onBlur={()=>{verify("name")}}/>
|
||||
)}
|
||||
<div className='introArea'>{helper('社区简介',
|
||||
'',
|
||||
'projectIntro',
|
||||
[{ required: true, message: "请输入社区简介" },
|
||||
{ max: 200, message: '超出限制长度200位字符,请重新编辑' }],
|
||||
<TextArea placeholder="请输入社区简介" onBlur={()=>{verify("intro")}} rows={4}/>
|
||||
)}</div>
|
||||
<div className='introArea'>{helper('项目logo',
|
||||
'限制上传格式为:png、jpg、jpeg,限制20M。建议上传大小为382*228',
|
||||
'logo',
|
||||
[{ required: true, message: "请正确上传项目logo" }],
|
||||
<Upload
|
||||
listType="picture-card"
|
||||
className="avatar-uploader"
|
||||
showUploadList={false}
|
||||
action={getUploadActionUrl()}
|
||||
accept=".png,.jpg,.jpeg"
|
||||
beforeUpload={beforeUpload}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{(imageUrl || userApplyInfo) ? <img src={imageUrl || `${main_site_url}/api/attachments/${userApplyInfo.projectLogoId}`} alt="avatar" style={{ maxWidth: '100px', maxHeight: '100px' }} /> : <div>
|
||||
<i className='iconfont icon-tianjiadaohang font-30'></i>
|
||||
<div className="ant-upload-text font-13">请上传logo图片</div>
|
||||
</div>}
|
||||
</Upload>
|
||||
)}</div>
|
||||
{taskCount.map((item, index)=>{
|
||||
return <div className='taskApplyBox' key={item}>
|
||||
<FlexAJ className='taskApplyTitleBox'>
|
||||
<div className='taskApplyTitle font-16'>课题信息(<span>{index+1}</span>/5)</div>
|
||||
{index>0 && <Button type="link" onClick={()=>{deleteTaskApply(item)}}><i className='iconfont icon-shanchuicon3 mr5 font-15'></i>删除</Button>}
|
||||
</FlexAJ>
|
||||
<TaskApply helper={helper} taskKey={item} phonereg={phonereg} emailreg={emailreg}/>
|
||||
</div>
|
||||
})}
|
||||
{taskCount && taskCount.length<5 && <div>
|
||||
<Button type="primary" className='taskApplyBox' style={{width: "100px", height: "36px"}} onClick={addTaskApplyForm}>添加课题</Button>
|
||||
</div>}
|
||||
<Form.Item className='subInfo introArea'>
|
||||
<Button type="primary" htmlType="submit" className='sub' loading={loading}>提交</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
<FlexAJ className='pt20 font-18 pb20'>
|
||||
<span><img src={apply1} alt="" width="25px" className="mr10"/>项目报名</span>
|
||||
{userApplyInfo.length > 0 && <a className='font-16 addRepoBut' onClick={addRepoBut}><i className='iconfont icon-tianjia_tianchong mr5 font-22'></i>添加项目</a>}
|
||||
</FlexAJ>
|
||||
{userApplyInfo.length > 0 && <div className='repoListBox'>
|
||||
{userApplyInfo.map((item, index)=><div className='repoList mb20' key={index}><RepoInfo cateList={cateList} applyInfo={item} current_user={current_user} round={round} setReload={()=>{setReload(Math.random())}} isAddRepo={isAddRepo} editRepoCount={editRepoCount} setEditRepoCount={setEditRepoCount} repoCount={userApplyInfo.length} scrollToEdit={scrollToEdit}/></div>)}
|
||||
</div>}
|
||||
{(!userApplyInfo.length || isAddRepo) && <EditInfo isAddRepo={isAddRepo} setIsAddRepo={setIsAddRepo} round={round} cateList={cateList} current_user={current_user} setReload={()=>{setReload(Math.random())}}/>}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Form.create()(Apply);
|
||||
export default Apply;
|
||||
|
|
@ -76,7 +76,7 @@
|
|||
text-align: center;
|
||||
margin: 40px 0 70px -60px;
|
||||
.sub{
|
||||
width: 200px;
|
||||
width: 110px;
|
||||
height: 36px;
|
||||
background-color: #466aff;
|
||||
border-color: #466aff;
|
||||
|
|
@ -169,4 +169,98 @@
|
|||
position: relative;
|
||||
left: -17px;
|
||||
}
|
||||
}
|
||||
.repoListBox{
|
||||
background-color:rgba(255, 255, 255, 0.27);
|
||||
border:1px solid #ffffff;
|
||||
padding: 15px 15px 0;
|
||||
}
|
||||
.repoList{
|
||||
border-bottom: 1px dashed #bec5d5;
|
||||
&:hover{
|
||||
background-color:#ffffff;
|
||||
border-radius:4px;
|
||||
box-shadow:0px 0px 10px rgba(84, 124, 255, 0.28);
|
||||
.taskApplyInfo{
|
||||
background-color:rgba(236, 242, 255, 0.83);
|
||||
}
|
||||
}
|
||||
}
|
||||
.flexStartBox{
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
.repoName{
|
||||
font-weight:700;
|
||||
color:#333333;
|
||||
}
|
||||
}
|
||||
.repoInfo{
|
||||
padding: 20px 10px 30px 10px;
|
||||
.repoLogo{
|
||||
width:36px;
|
||||
height:36px;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.repoType{
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
line-height: normal;
|
||||
color:#465474;
|
||||
border:1px solid #6680bb;
|
||||
border-radius:4px;
|
||||
}
|
||||
.repoOthersInfo{
|
||||
color:#465474;
|
||||
word-break: break-all;
|
||||
}
|
||||
.labelInfoBox{
|
||||
width: 75px;
|
||||
display: inline-block;
|
||||
&.gitlinkUrl{
|
||||
width: 95px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.taskApplyInfo{
|
||||
background-color:rgba(251, 252, 255, 0.8);
|
||||
border:1px solid #ffffff;
|
||||
padding: 20px;
|
||||
.taskDifficulty{
|
||||
display: inline-block;
|
||||
width:27px;
|
||||
height:24px;
|
||||
border:1px solid #0ba840;
|
||||
border-radius:6px;
|
||||
color:#0ba840;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
&.diff2{
|
||||
color:#ffb300;
|
||||
border-color:#ffb300;
|
||||
}
|
||||
&.diff3{
|
||||
color:#ff0000;
|
||||
border-color:#ff1d1d;
|
||||
}
|
||||
}
|
||||
.taskRewardBox{
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
.addRepoBut{
|
||||
color: $primary-color;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
.openTaskBox{
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
.openTask{
|
||||
color: $primary-color;
|
||||
border:1px solid $primary-color;
|
||||
border-radius:6px;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
import { Button, Row, Col, Popconfirm, message } from "antd";
|
||||
import React, { useState } from "react";
|
||||
import EditInfo from "./editInfo";
|
||||
import { FlexAJ } from "../../forge/Component/layout";
|
||||
import { main_site_url } from "../fetch";
|
||||
import './index.scss';
|
||||
import { deleteApplyInfo } from "../api";
|
||||
// 项目、课题信息展示
|
||||
function RepoInfo(props) {
|
||||
const {applyInfo:{id, projectLogoId, projectName, projectType, contactName, contactPhone, contactMail, gitlinkUrl, projectIntro, registrationTaskList}, setReload, editRepoCount, setEditRepoCount, repoCount, isAddRepo, scrollToEdit} = props;
|
||||
// 课题难度:低、中、高
|
||||
const difficultyList = ['', '低', '中', '高'];
|
||||
const [isEdit, setIsEdit] = useState(false);
|
||||
const [showAllTask, setShowAllTask] = useState(false);
|
||||
|
||||
// 编辑项目信息
|
||||
function editRepoBut(){
|
||||
if(editRepoCount || isAddRepo){
|
||||
scrollToEdit();
|
||||
message.error("请先提交当前项目信息");
|
||||
return;
|
||||
}
|
||||
setEditRepoCount(editRepoCount+1);
|
||||
setIsEdit(true);
|
||||
}
|
||||
|
||||
// 删除项目
|
||||
function deleteBut(){
|
||||
deleteApplyInfo({ids: [id], round: 2}).then(res=>{
|
||||
message.success("删除成功");
|
||||
setReload();
|
||||
})
|
||||
}
|
||||
|
||||
// 课题信息展示
|
||||
const showTask = (task) => {
|
||||
const {id, taskDifficulty, taskName, taskReward, tutorName, tutorPhone, tutorMail, taskDesc, taskUrl} = task;
|
||||
return <div className="taskApplyInfo mt20" key={id}>
|
||||
<FlexAJ>
|
||||
<div>
|
||||
<div className={`taskDifficulty diff${taskDifficulty} font-14 mr10`}>{difficultyList[taskDifficulty]}</div>
|
||||
<span className="repoName font-16">{taskName}</span>
|
||||
</div>
|
||||
<span className="font-20 taskRewardBox">¥ {taskReward}</span>
|
||||
</FlexAJ>
|
||||
<div style={{flex: 1}} className="font-15 ml35 mt10">
|
||||
<Row gutter={16}>
|
||||
<Col span={12}><div className="repoOthersInfo"><span className="labelInfoBox">导师信息:</span>{tutorName}({tutorPhone} | {tutorMail})</div></Col>
|
||||
<Col span={12}><div className="repoOthersInfo"><span className="labelInfoBox">课题链接:</span>{taskUrl}</div></Col>
|
||||
</Row>
|
||||
<div className="repoOthersInfo mt10"><span className="labelInfoBox">课题简介:</span>{taskDesc}</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
return (
|
||||
isEdit ? <EditInfo {...props} setIsEdit={setIsEdit}/> : <div className="flexStartBox repoInfo">
|
||||
<img className="repoLogo mr10" src={`${main_site_url}/api/attachments/${projectLogoId}`} alt= { `${projectName}-glcc`} />
|
||||
<div style={{flex: 1, width: 0}} className="font-15" id={`repoShowId${id}`}>
|
||||
{/* 项目信息 */}
|
||||
<FlexAJ>
|
||||
<div>
|
||||
<span className="repoName font-16">{projectName}</span>
|
||||
<span className="repoType ml20">{projectType}</span>
|
||||
</div>
|
||||
<div>
|
||||
<Button type="link" onClick={editRepoBut}><i className='iconfont icon-a-bianji12 mr5 font-12'></i>编辑</Button>
|
||||
{repoCount > 1 && <Popconfirm
|
||||
title={<span>删除项目将清除项目信息及所有课题信息,<br/>请谨慎操作。</span>}
|
||||
onConfirm={deleteBut}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
>
|
||||
<Button type="link"><i className='iconfont icon-shanchuicon3 mr5 font-15'></i>删除</Button>
|
||||
</Popconfirm>}
|
||||
</div>
|
||||
</FlexAJ>
|
||||
{/* <Rows label={["官网地址", "GitLink地址"]} content={[]}/> */}
|
||||
<Row gutter={16}>
|
||||
<Col span={12}><div className="repoOthersInfo mt15"><span className="labelInfoBox">导师信息:</span>{contactName}({contactPhone} | {contactMail})</div></Col>
|
||||
<Col span={12}><div className="repoOthersInfo mt15"><span className="labelInfoBox gitlinkUrl">GitLink地址:</span>{gitlinkUrl}</div></Col>
|
||||
</Row>
|
||||
<div className="repoOthersInfo mt10"><span className="labelInfoBox">社区简介:</span>{projectIntro}</div>
|
||||
|
||||
{/* 课题信息list */}
|
||||
{/* 多个课题(仅展示一个课题) 单个课题 */}
|
||||
{registrationTaskList && registrationTaskList.length > 1 && !showAllTask && <div>
|
||||
{showTask(registrationTaskList[0])}
|
||||
<div className="openTaskBox"><a onClick={()=>{setShowAllTask(!showAllTask)}} className="openTask">展开课题<i className="iconfont icon-xiala1 ml10 font-14"></i></a></div>
|
||||
</div>}
|
||||
{/* 多个课题同时展示 */}
|
||||
{registrationTaskList && (registrationTaskList.length === 1 || showAllTask) && <React.Fragment>
|
||||
{registrationTaskList.map(item=>showTask(item))}
|
||||
{showAllTask && <div className="openTaskBox"><a onClick={()=>{setShowAllTask(!showAllTask)}} className="openTask">收起课题<i className="iconfont icon-xiala2 ml10 font-14"></i></a></div>}
|
||||
</React.Fragment>}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default RepoInfo;
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
import React , { useCallback, useEffect , useState } from 'react';
|
||||
import { Breadcrumb, Button, Form, Input, Select, Upload, Modal, InputNumber } from 'antd';
|
||||
import React from 'react';
|
||||
import {Form, Input, Select } from 'antd';
|
||||
import TextArea from 'antd/lib/input/TextArea';
|
||||
const Option = Select.Option;
|
||||
// 课题信息编辑
|
||||
function TaskApply(props) {
|
||||
const {helper, disabled, taskKey, phonereg, emailreg} = props;
|
||||
// 低、中、高
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import './index.scss';
|
|||
// round:2022届(1) 2023届(2)
|
||||
// period: 项目报名阶段(0)
|
||||
export default (props) => {
|
||||
const { current_user, isGlccApplyDate, showNotification, studentApplyStart, history, secondStudentApplyDate, isStudentApplyDate, checkedTaskId, checkTime1, checkTime2, checkTime3, round, match:{params:{id}}, period, showLoginDialog} = props;
|
||||
const { current_user, isGlccApplyDate, showNotification, studentApplyStart, history, secondStudentApplyDate, isStudentApplyDate, checkedTaskId, checkTime1, checkTime2, checkTime3, round, match:{params:{id}}, period, showLoginDialog, glccSettings} = props;
|
||||
function goToApply() {
|
||||
if (isGlccApplyDate) {
|
||||
if (current_user && current_user.login) {
|
||||
|
|
@ -75,7 +75,7 @@ export default (props) => {
|
|||
history.push(url);
|
||||
return
|
||||
}
|
||||
showLoginDialog();
|
||||
showLoginDialog(`/glcc/apply`);
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
@ -198,7 +198,7 @@ export default (props) => {
|
|||
</div>
|
||||
</div>
|
||||
<Lightspot period={period} history={history} current_user={current_user} round={round} showLoginDialog={showLoginDialog}/>
|
||||
<TimerShaft round={round}/>
|
||||
<TimerShaft round={round} glccSettings={glccSettings}/>
|
||||
<Award />
|
||||
<News />
|
||||
<Partner round={round}/>
|
||||
|
|
|
|||
|
|
@ -10,11 +10,12 @@ function Lightspot(props) {
|
|||
const {current_user, period, history, round, showLoginDialog} = props;
|
||||
|
||||
function goToApply(){
|
||||
const url = period === 0 ? `/glcc/apply` : `/glcc/subjects`;
|
||||
if(current_user && !current_user.login){
|
||||
showLoginDialog();
|
||||
showLoginDialog(url);
|
||||
return;
|
||||
}
|
||||
history.push(period === 0 ? `/glcc/apply` : `/glcc/subjects`);
|
||||
history.push(url);
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ const stepArr = [{
|
|||
},
|
||||
{
|
||||
title: "Step2",
|
||||
date: "5.30-6.3",
|
||||
date: "5.31-6.3",
|
||||
content: "课题审核及公布"
|
||||
},
|
||||
{
|
||||
|
|
@ -104,9 +104,30 @@ const stepArr = [{
|
|||
}
|
||||
]
|
||||
|
||||
function TimerShaft({round}) {
|
||||
function TimerShaft({round, glccSettings}) {
|
||||
if(glccSettings && glccSettings.length > 12){
|
||||
stepArr[1].date = getRangeTime(glccSettings[0].value);
|
||||
stepArr[2].date = getRangeTime(glccSettings[1].value);
|
||||
stepArr[3].date = getRangeTime(glccSettings[2].value);
|
||||
stepArr[4].date = getTime(glccSettings[3].value);
|
||||
stepArr[5].date = getRangeTime(glccSettings[11].value);
|
||||
stepArr[6].date = getTime(glccSettings[7].value);
|
||||
stepArr[7].date = getRangeTime(glccSettings[12].value);
|
||||
stepArr[8].date = getTime(glccSettings[9].value);
|
||||
stepArr[9].date = getTime(glccSettings[4].value);
|
||||
}
|
||||
const step = round === 2 ? stepArr : stepArr2022
|
||||
|
||||
// 截取月份/日期
|
||||
function getRangeTime(value){
|
||||
return value.split(",").map(item=>`${new Date(item).getMonth()+1}.${new Date(item).getDate()}`).join("-");
|
||||
}
|
||||
|
||||
function getTime(value){
|
||||
const time = new Date(value.split(",")[0]);
|
||||
return `${new Date(time).getMonth()+1}.${new Date(time).getDate()}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="timerShaft">
|
||||
<div className="glcc-content">
|
||||
|
|
|
|||
|
|
@ -80,7 +80,10 @@ const Glcc = (propsF) => {
|
|||
const {current_user, showLoginDialog, match:{params:{id}}} = propsF;
|
||||
// round:2022届(1) 2023届(2)
|
||||
const [round, setRound] = useState(2);
|
||||
// glcc 所处阶段 0(项目报名)
|
||||
const [period, setPeriod] = useState(undefined);
|
||||
// glcc后台时间配置
|
||||
const [glccSettings, setGLccSetting] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
if(id && id === "2022"){
|
||||
|
|
@ -91,6 +94,7 @@ const Glcc = (propsF) => {
|
|||
// 获取当前glcc配置
|
||||
getGlccSettings({round: 2}).then(res=>{
|
||||
if(res && res.message === "success"){
|
||||
setGLccSetting(res.data);
|
||||
const nowTime = new Date().getTime();
|
||||
setPeriod(res.data.findIndex(item=>judge(nowTime, item.value)));
|
||||
}
|
||||
|
|
@ -269,7 +273,7 @@ const Glcc = (propsF) => {
|
|||
<Route
|
||||
path="/glcc/:id"
|
||||
render={(props) => (
|
||||
<Home period={period} round={round} {...propsF} {...props} studentApplyStart={studentApplyStart} isStudentApplyDate={isStudentApplyDate} secondStudentApplyDate={secondStudentApplyDate} checkedTaskId={checkedTaskId} checkTime1={checkTime1} checkTime2={checkTime2} checkTime3={checkTime3}/>
|
||||
<Home period={period} round={round} {...propsF} {...props} studentApplyStart={studentApplyStart} isStudentApplyDate={isStudentApplyDate} secondStudentApplyDate={secondStudentApplyDate} checkedTaskId={checkedTaskId} checkTime1={checkTime1} checkTime2={checkTime2} checkTime3={checkTime3} glccSettings={glccSettings}/>
|
||||
)}
|
||||
></Route>
|
||||
|
||||
|
|
@ -277,7 +281,7 @@ const Glcc = (propsF) => {
|
|||
<Route
|
||||
path="/glcc"
|
||||
render={(props) => (
|
||||
<Home period={period} round={round} {...propsF} {...props} studentApplyStart={studentApplyStart} isStudentApplyDate={isStudentApplyDate} secondStudentApplyDate={secondStudentApplyDate} checkedTaskId={checkedTaskId} checkTime1={checkTime1} checkTime2={checkTime2} checkTime3={checkTime3}/>
|
||||
<Home period={period} round={round} {...propsF} {...props} studentApplyStart={studentApplyStart} isStudentApplyDate={isStudentApplyDate} secondStudentApplyDate={secondStudentApplyDate} checkedTaskId={checkedTaskId} checkTime1={checkTime1} checkTime2={checkTime2} checkTime3={checkTime3} glccSettings={glccSettings}/>
|
||||
)}
|
||||
></Route>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue