forked from Gitlink/forgeplus-react
Merge pull request 'glcc启动2023届' (#529) from durian/forgeplus-react:feature_glcc into gitlink_server
This commit is contained in:
commit
0ca189ebe2
|
|
@ -1,8 +1,8 @@
|
|||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2340181 */
|
||||
src: url('iconfont.woff2?t=1680498859493') format('woff2'),
|
||||
url('iconfont.woff?t=1680498859493') format('woff'),
|
||||
url('iconfont.ttf?t=1680498859493') format('truetype');
|
||||
src: url('iconfont.woff2?t=1682485448664') format('woff2'),
|
||||
url('iconfont.woff?t=1682485448664') format('woff'),
|
||||
url('iconfont.ttf?t=1682485448664') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
|
|
@ -13,6 +13,42 @@
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-zanting:before {
|
||||
content: "\e96a";
|
||||
}
|
||||
|
||||
.icon-cangkuyuyanicon:before {
|
||||
content: "\e962";
|
||||
}
|
||||
|
||||
.icon-dongtaiicon1:before {
|
||||
content: "\e963";
|
||||
}
|
||||
|
||||
.icon-jingxuanxiangmu:before {
|
||||
content: "\e964";
|
||||
}
|
||||
|
||||
.icon-zuzhichengyuan1:before {
|
||||
content: "\e965";
|
||||
}
|
||||
|
||||
.icon-zuzhijieshao:before {
|
||||
content: "\e966";
|
||||
}
|
||||
|
||||
.icon-zuzhituandui:before {
|
||||
content: "\e967";
|
||||
}
|
||||
|
||||
.icon-shezhi6:before {
|
||||
content: "\e968";
|
||||
}
|
||||
|
||||
.icon-zidingyi:before {
|
||||
content: "\e969";
|
||||
}
|
||||
|
||||
.icon-a-zu37:before {
|
||||
content: "\e961";
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -5,6 +5,69 @@
|
|||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "887857",
|
||||
"name": "暂停",
|
||||
"font_class": "zanting",
|
||||
"unicode": "e96a",
|
||||
"unicode_decimal": 59754
|
||||
},
|
||||
{
|
||||
"icon_id": "34965902",
|
||||
"name": "仓库语言icon",
|
||||
"font_class": "cangkuyuyanicon",
|
||||
"unicode": "e962",
|
||||
"unicode_decimal": 59746
|
||||
},
|
||||
{
|
||||
"icon_id": "34965903",
|
||||
"name": "动态icon",
|
||||
"font_class": "dongtaiicon1",
|
||||
"unicode": "e963",
|
||||
"unicode_decimal": 59747
|
||||
},
|
||||
{
|
||||
"icon_id": "34965904",
|
||||
"name": "精选项目",
|
||||
"font_class": "jingxuanxiangmu",
|
||||
"unicode": "e964",
|
||||
"unicode_decimal": 59748
|
||||
},
|
||||
{
|
||||
"icon_id": "34965905",
|
||||
"name": "组织成员",
|
||||
"font_class": "zuzhichengyuan1",
|
||||
"unicode": "e965",
|
||||
"unicode_decimal": 59749
|
||||
},
|
||||
{
|
||||
"icon_id": "34965906",
|
||||
"name": "组织介绍",
|
||||
"font_class": "zuzhijieshao",
|
||||
"unicode": "e966",
|
||||
"unicode_decimal": 59750
|
||||
},
|
||||
{
|
||||
"icon_id": "34965907",
|
||||
"name": "组织团队",
|
||||
"font_class": "zuzhituandui",
|
||||
"unicode": "e967",
|
||||
"unicode_decimal": 59751
|
||||
},
|
||||
{
|
||||
"icon_id": "34965908",
|
||||
"name": "设置",
|
||||
"font_class": "shezhi6",
|
||||
"unicode": "e968",
|
||||
"unicode_decimal": 59752
|
||||
},
|
||||
{
|
||||
"icon_id": "34965909",
|
||||
"name": "自定义",
|
||||
"font_class": "zidingyi",
|
||||
"unicode": "e969",
|
||||
"unicode_decimal": 59753
|
||||
},
|
||||
{
|
||||
"icon_id": "34875122",
|
||||
"name": "组 37",
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -449,6 +449,10 @@ class App extends Component {
|
|||
></Route>
|
||||
|
||||
{/*glcc */}
|
||||
<Route
|
||||
path="/glcc/:id"
|
||||
render={(props) => <Glcc {...this.props} {...props} />}
|
||||
></Route>
|
||||
<Route
|
||||
path="/glcc"
|
||||
render={(props) => <Glcc {...this.props} {...props} />}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import fetch from './fetch';
|
||||
|
||||
// 获取当前用户项目报名信息
|
||||
// 获取当前用户项目报名信息(项目、课题)
|
||||
export function getUserApplyInfo(params) {
|
||||
return fetch({
|
||||
url: `/api/applyInformation/getUserApplyInfo`,
|
||||
|
|
@ -9,7 +9,7 @@ export function getUserApplyInfo(params) {
|
|||
});
|
||||
}
|
||||
|
||||
//报名夏令营
|
||||
//报名夏令营(项目、课题报名)
|
||||
export function applyGlcc(data) {
|
||||
return fetch({
|
||||
url: '/api/applyInformation/create',
|
||||
|
|
@ -18,6 +18,15 @@ export function applyGlcc(data) {
|
|||
});
|
||||
}
|
||||
|
||||
// 修改报名信息
|
||||
export function updateApplyGlcc(data) {
|
||||
return fetch({
|
||||
url: '/api/applyInformation/update',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
||||
//提交报名信息(学生)
|
||||
export function studentApply(data) {
|
||||
return fetch({
|
||||
|
|
@ -194,4 +203,13 @@ export function getMediumTermExamineInfoList(params) {
|
|||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 查看GLCC配置信息列表
|
||||
export function getGlccSettings(params) {
|
||||
return fetch({
|
||||
url: `/api/glccSettings/settingList`,
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
|
@ -1,24 +1,29 @@
|
|||
import React , { useCallback, useEffect , useState } from 'react';
|
||||
import { Breadcrumb, Button, Form, Input, Select, Upload, Modal } from 'antd';
|
||||
import { Breadcrumb, Button, Form, Input, Select, Upload, Modal, message } from 'antd';
|
||||
import {getUploadActionUrl} from 'educoder';
|
||||
import {getUserApplyInfo, applyGlcc} from '../api';
|
||||
import {getUserApplyInfo, applyGlcc, updateApplyGlcc} from '../api';
|
||||
import axios from 'axios';
|
||||
import TextArea from 'antd/lib/input/TextArea';
|
||||
import { main_site_url } from '../fetch';
|
||||
import TaskApply from './taskApply';
|
||||
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 {form, current_user, showNotification, isGlccApplyDate} = props;
|
||||
// 可用于开发时不同账号报名
|
||||
// current_user && (current_user.user_id = 6)
|
||||
// current_user && (current_user.userName = "创新使者")
|
||||
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 [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) => (
|
||||
|
|
@ -32,10 +37,7 @@ function Apply(props) {
|
|||
useEffect(()=>{
|
||||
// 进入此页面置顶
|
||||
window.scrollTo(0,0);
|
||||
if(!isGlccApplyDate){
|
||||
// 不在开源夏令营报名时间之内
|
||||
window.location.href="/glcc";
|
||||
}else if(current_user && current_user.login){
|
||||
if(current_user && current_user.login){
|
||||
// 获取项目分类参数
|
||||
const url = `/project_categories/pinned_index.json`;
|
||||
axios.get(url).then(result=>{
|
||||
|
|
@ -50,15 +52,36 @@ function Apply(props) {
|
|||
|
||||
useEffect(()=>{
|
||||
// 获取当前用户报名信息
|
||||
current_user && getUserApplyInfo({userId: current_user.user_id}).then(response=>{
|
||||
current_user && round && getUserApplyInfo({userId: current_user.user_id, round}).then(response=>{
|
||||
if(response && response.message === "success"){
|
||||
response.data && setFieldsValue({
|
||||
...response.data
|
||||
})
|
||||
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){
|
||||
|
|
@ -74,32 +97,58 @@ function Apply(props) {
|
|||
e.preventDefault();
|
||||
validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
Modal.confirm({
|
||||
title: "报名",
|
||||
content: "确定提交报名信息,提交后报名信息将无法修改",
|
||||
onOk: ()=>{
|
||||
const params ={
|
||||
...values,
|
||||
projectLogoId: values.logo.file.response.id,
|
||||
userId: current_user.user_id,
|
||||
userName: current_user.username
|
||||
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());
|
||||
}
|
||||
applyGlcc(params).then(response=>{
|
||||
if(response && response.message === "success"){
|
||||
showNotification("报名成功");
|
||||
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 < 2;
|
||||
const isLt100M = file.size / 1024 / 1024 < 20;
|
||||
if (!isLt100M) {
|
||||
showNotification(`文件大小必须小于${2}MB!`);
|
||||
showNotification(`文件大小必须小于${20}M!`);
|
||||
}
|
||||
const isType = file.type === "image/png" || file.type === "image/jpg" || file.type === "image/jpeg";
|
||||
if (!isType) {
|
||||
|
|
@ -124,83 +173,123 @@ function Apply(props) {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 添加课题输入框
|
||||
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>
|
||||
<div className='apply'>
|
||||
<Breadcrumb className='pt20 font-16'>
|
||||
<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'>
|
||||
<i className='iconfont icon-wancheng mr5'></i>您已报名成功,请关注活动后续新闻公告!
|
||||
</div>}
|
||||
<Form className="pt20 glcc_info_form" onSubmit={handleSubmit}>
|
||||
{helper('项目名称',
|
||||
'',
|
||||
'projectName',
|
||||
[{ required: true, message: "请正确输入项目名称" },
|
||||
{ max: 32, message: '超出限制长度32位字符,请重新编辑' }],
|
||||
<Input placeholder="请输入项目名称" onBlur={()=>{verify("name")}} disabled = {userApplyInfo ? true : false} className={userApplyInfo? "disabledInput":""}/>
|
||||
)}
|
||||
{helper('项目分类',
|
||||
'',
|
||||
'projectType',
|
||||
[],
|
||||
<Select placeholder="请选择项目分类" disabled = {userApplyInfo ? true : false} className={userApplyInfo? "disabledInput":""}>
|
||||
{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")}} disabled = {userApplyInfo ? true : false} className={userApplyInfo? "disabledInput":""}/>
|
||||
)}
|
||||
{helper('官网地址',
|
||||
'',
|
||||
'officialWebsiteUrl',
|
||||
[{ max: 252, message: '超出限制长度252位字符,请重新编辑' }],
|
||||
<Input placeholder="请输入官网地址" disabled = {userApplyInfo ? true : false} className={userApplyInfo? "disabledInput":""}/>
|
||||
)}
|
||||
<div className='introArea'>{helper('项目简介',
|
||||
'',
|
||||
'projectIntro',
|
||||
[{ required: true, message: "请正确输入项目简介" },
|
||||
{ max: 200, message: '超出限制长度200位字符,请重新编辑' }],
|
||||
<TextArea placeholder="请输入项目简介,长度不超过200字符" onBlur={()=>{verify("intro")}} rows={4} disabled = {userApplyInfo ? true : false} className={userApplyInfo? "disabledInput":""}/>
|
||||
)}</div>
|
||||
<div className='introArea'>{helper('项目logo',
|
||||
'logo格式为png、jpg、jpeg,限制上传大小2m,建议上传尺寸为382*228',
|
||||
'logo',
|
||||
[{ required: true, message: "请正确上传项目logo" }],
|
||||
userApplyInfo && userApplyInfo.projectLogoId ? <div className='projectLogo'><img src={`${main_site_url}/api/attachments/${userApplyInfo.projectLogoId}`} alt=''/></div>
|
||||
:<Upload
|
||||
listType="picture-card"
|
||||
className="avatar-uploader"
|
||||
showUploadList={false}
|
||||
action={getUploadActionUrl()}
|
||||
accept=".png,.jpg,.jpeg"
|
||||
beforeUpload={beforeUpload}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{imageUrl ? <img src={imageUrl} 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>
|
||||
<p className='introArea tips'>注: 课题及导师信息请在GitLink项目中以issue的形式编辑</p>
|
||||
{!userApplyInfo && <Form.Item className='subInfo introArea'>
|
||||
<Button type="primary" htmlType="submit" className='sub'>提交</Button>
|
||||
</Form.Item>}
|
||||
</Form>
|
||||
<div className={`explain ${userApplyInfo ? "mt70" : ""}`}>
|
||||
{userApplyInfo && <div className='applySuccess mt20 font-15'>您已报名成功,可实时修改您的报名信息再次提交。请关注夏令营首页新闻公告获得更多活动资讯!</div>}
|
||||
<div className={`explain`}>
|
||||
<p className='font-15 c000'>申请说明</p>
|
||||
<div>1、项目报名时间为<span className='c000'>4月15日—5月20日</span>,请在报名截止时间(北京时间<span className='c000'>2022年5月20日24点</span>)前提交报名信息。</div>
|
||||
<div>2、本次夏令营使用Gitlink为代码托管平台,学员基于Gitlink上项目数量完成课程任务。如果您的项目还未在Gitlink中,请现将项目迁移到Gitlink,迁移事项请查看<a href='https://forum.gitlink.org.cn/forums/7296/detail' target="_blank" className='link'>迁移说明文档</a>。如在迁移过程中遇到问题,请加qq群: 1071514693 联系qq群管理员。</div>
|
||||
<div>3、提交社区和项目信息后,欢迎与组委会联系沟通本次编程夏令营宣传推广和后续合作工作。联系人: _TigerWang(微信号,添加请备注Gitlink编程夏令营)</div>
|
||||
<div>1、项目报名时间为<span className='c000'>4月29日—5月30日</span>,请在报名截止时间(北京时间<span className='c000'>2022年5月30日24点</span>)前提交报名信息。</div>
|
||||
<div>2、本次GLCC夏令营建议使用GitLink为代码托管平台,学生基于GitLink上项目完成编程任务。同时也欢迎使用其他代码托管平台的项目参与活动。目前GLCC只对夏令营期间使用GitLink托管的项目提供部分资金支持。</div>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
.glcc_info_form{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 10px 25px 10px 0;
|
||||
.ant-row.ant-form-item{
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
|
|
@ -15,7 +16,7 @@
|
|||
justify-content: flex-end;
|
||||
}
|
||||
.ant-col.ant-form-item-control-wrapper {
|
||||
width: 78%;
|
||||
width: 77%;
|
||||
}
|
||||
.ant-form-item-label{
|
||||
margin-right: 15px;
|
||||
|
|
@ -90,11 +91,10 @@
|
|||
}
|
||||
}
|
||||
.explain{
|
||||
background-color:#f6f9fe;
|
||||
border:2px solid;
|
||||
border-color:#ffffff;
|
||||
margin-top: 35px;
|
||||
background-color:#e4edff;
|
||||
color:#6c7283;
|
||||
padding: 20px 30px 30px 20px;
|
||||
padding: 10px 30px 2px 20px;
|
||||
.c000{color: #000000;}
|
||||
div>.c000{font-weight: bold;}
|
||||
>div{margin: 10px 0;}
|
||||
|
|
@ -105,13 +105,68 @@
|
|||
}
|
||||
.applySuccess{
|
||||
height: 45px;
|
||||
border: 1px solid;
|
||||
border-color: #466aff;
|
||||
line-height: 45px;
|
||||
padding-left: 20px;
|
||||
color:#466aff;
|
||||
color:#2dab4d;
|
||||
border: 1px solid rgba(36, 167, 67, 0.61);
|
||||
background-color:rgba(82, 206, 152, 0.11);
|
||||
}
|
||||
.applyInfoBox{
|
||||
background-color:rgba(255, 255, 255, 0.27);
|
||||
border:1px solid #ffffff;
|
||||
.titleG{
|
||||
background-color:#e1e8ff;
|
||||
padding: 10px 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
.glcc-banner {
|
||||
width: 100%;
|
||||
}
|
||||
.breadcrumbGlcc{
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 1px dashed #bec5d5;
|
||||
}
|
||||
.taskApplyBox{
|
||||
width: 100%;
|
||||
margin-left: 50px;
|
||||
.taskApplyTitleBox{
|
||||
padding-bottom: 15px;
|
||||
border-bottom: 1px dashed #bec5d5;
|
||||
}
|
||||
.taskApplyTitle{
|
||||
color:#333333;
|
||||
padding-left: 15px;
|
||||
position: relative;
|
||||
&::before{
|
||||
content: "";
|
||||
width:5px;
|
||||
height:14px;
|
||||
background-color:$primary-color;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 6px;
|
||||
}
|
||||
&>span{
|
||||
color: $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
.taskApplyForm{
|
||||
.glcc_info_form{
|
||||
position: relative;
|
||||
left: -20px;
|
||||
.ant-row.ant-form-item{
|
||||
justify-content: space-between;
|
||||
}
|
||||
.ant-form-item-label{
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
.introArea .ant-form-item-label{
|
||||
width: 100px;
|
||||
position: relative;
|
||||
left: -17px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
import React , { useCallback, useEffect , useState } from 'react';
|
||||
import { Breadcrumb, Button, Form, Input, Select, Upload, Modal, InputNumber } from 'antd';
|
||||
import TextArea from 'antd/lib/input/TextArea';
|
||||
const Option = Select.Option;
|
||||
function TaskApply(props) {
|
||||
const {helper, disabled, taskKey, phonereg, emailreg} = props;
|
||||
// 低、中、高
|
||||
const difficultyList = [
|
||||
{id: 1, name: "低"},
|
||||
{id: 2, name: "中"},
|
||||
{id: 3, name: "高"}
|
||||
]
|
||||
|
||||
return(
|
||||
<div className="taskApplyForm">
|
||||
<div className="pt20 glcc_info_form">
|
||||
{helper('课题名称',
|
||||
'',
|
||||
`taskName${taskKey}`,
|
||||
[{ required: true, message: "请输入课题名称,长度限制32个字符" },
|
||||
{ max: 32, message: '超出限制长度32位字符,请重新编辑' }],
|
||||
<Input placeholder="请输入课题名称" disabled = {disabled} className={disabled? "disabledInput":""}/>
|
||||
)}
|
||||
{helper('课题链接',
|
||||
'',
|
||||
`taskUrl${taskKey}`,
|
||||
[{ required: true, message: "请输入课题链接" },
|
||||
{ max: 252, message: '超出限制长度252位字符,请重新编辑' }],
|
||||
<Input placeholder="请输入课题链接" disabled = {disabled} className={disabled? "disabledInput":""}/>
|
||||
)}
|
||||
{helper('课题难度',
|
||||
'',
|
||||
`taskDifficulty${taskKey}`,
|
||||
[{ required: true, message: "请选择课题难度" }],
|
||||
<Select placeholder="请选择课题难度" disabled = {disabled} className={disabled? "disabledInput":""}>
|
||||
{difficultyList && difficultyList.map(item=> {return <Option value={item.id} key={item.id}>{item.name}</Option>})}
|
||||
</Select>
|
||||
)}
|
||||
{helper('课题奖金',
|
||||
'',
|
||||
`taskReward${taskKey}`,
|
||||
[{ required: true, message: "请输入课题奖金" },
|
||||
{pattern: /^[1-9]+[0-9]*]*$/, message: "请输入正整数" },
|
||||
{ validator: (rule,val,callback) =>{
|
||||
if(val>=6000 && val<=12000){
|
||||
callback();
|
||||
}else{
|
||||
callback("区间为6000-12000元");
|
||||
}
|
||||
}}],
|
||||
<Input placeholder="请输入课题奖金" disabled = {disabled} className={disabled? "disabledInput":""}/>
|
||||
)}
|
||||
{helper('导师姓名',
|
||||
'',
|
||||
`tutorName${taskKey}`,
|
||||
[{ required: true, message: "请输入导师姓名" },
|
||||
{ max: 32, message: '超出限制长度32位字符,请重新编辑' }],
|
||||
<Input placeholder="请输入导师姓名" disabled = {disabled} className={disabled? "disabledInput":""}/>
|
||||
)}
|
||||
{helper('导师手机号',
|
||||
'',
|
||||
`tutorPhone${taskKey}`,
|
||||
[{ required: true, message: "请输入导师手机号" },
|
||||
{ pattern: phonereg, message: "请输入正确的电话号码"},],
|
||||
<Input placeholder="请输入导师手机号" disabled = {disabled} className={disabled? "disabledInput":""}/>
|
||||
)}
|
||||
{helper('导师邮箱',
|
||||
'',
|
||||
`tutorMail${taskKey}`,
|
||||
[{ required: true, message: "请输入导师邮箱地址" },
|
||||
{ pattern: emailreg, message: "请输入正确的邮箱地址"},],
|
||||
<Input placeholder="请输入导师邮箱地址" disabled = {disabled} className={disabled? "disabledInput":""}/>
|
||||
)}
|
||||
<div className='introArea'>{helper('课题简介',
|
||||
'',
|
||||
`taskDesc${taskKey}`,
|
||||
[{ required: true, message: "请输入课题简介" },
|
||||
{ max: 200, message: '超出限制长度200位字符,请重新编辑' }],
|
||||
<TextArea placeholder="请输入课题简介" rows={4} disabled = {disabled} className={disabled? "disabledInput":""}/>
|
||||
)}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Form.create()(TaskApply);
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
import React from "react";
|
||||
import { Table, Input, Button, Popconfirm, Form } from 'antd';
|
||||
import { Base64 } from 'js-base64';
|
||||
|
||||
import './index.scss';
|
||||
import apply_delete from "../../img/apply_delete.png";
|
||||
|
||||
const EditableContext = React.createContext();
|
||||
|
||||
const EditableRow = ({ form, index, ...props }) => (
|
||||
<EditableContext.Provider value={form}>
|
||||
<tr {...props} />
|
||||
</EditableContext.Provider>
|
||||
);
|
||||
|
||||
const EditableFormRow = Form.create()(EditableRow);
|
||||
|
||||
class EditableCell extends React.Component {
|
||||
|
||||
save = (dataIndex, e) => {
|
||||
const { record, handleSave } = this.props;
|
||||
this.form.validateFields([dataIndex],(error, values) => {
|
||||
handleSave({ ...record, ...values });
|
||||
if (error && error[e.currentTarget.id]) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
renderCell = form => {
|
||||
this.form = form;
|
||||
const {record, dataIndex, title } = this.props;
|
||||
return <Form.Item >
|
||||
{form.getFieldDecorator(dataIndex, {
|
||||
rules: [
|
||||
{required: true,message: `${title}不能为空.`,},
|
||||
{max: 32, message: '超出限制长度32位字符,请重新编辑' }
|
||||
],
|
||||
validateFirst: true,
|
||||
initialValue: record[dataIndex],
|
||||
})(<Input onPressEnter={(e)=>{this.save(dataIndex,e)}} onBlur={(e)=>{this.save(dataIndex,e)}} placeholder="请输入"/>)}
|
||||
</Form.Item>
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
editable,
|
||||
dataIndex,
|
||||
title,
|
||||
record,
|
||||
index,
|
||||
handleSave,
|
||||
children,
|
||||
...restProps
|
||||
} = this.props;
|
||||
return (
|
||||
<td {...restProps}>
|
||||
{editable ? (
|
||||
<EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EditableTable extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.columns = [
|
||||
{
|
||||
title: '姓名',
|
||||
dataIndex: 'real_name',
|
||||
editable: true,
|
||||
width: "40%"
|
||||
},
|
||||
{
|
||||
title: '单位',
|
||||
dataIndex: 'org_name',
|
||||
editable: true,
|
||||
width: '50%',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operation',
|
||||
width: '10%',
|
||||
render: (text, record) =>
|
||||
this.state.dataSource.length >= 1 ? (
|
||||
<Popconfirm title="确定删除此成员?" onConfirm={() => this.handleDelete(record.key)}>
|
||||
<img src={apply_delete} className="apply_delete" alt=""/>
|
||||
</Popconfirm>
|
||||
) : null,
|
||||
},
|
||||
];
|
||||
if(props.isLocal){
|
||||
this.columns = [{
|
||||
title: '姓名',
|
||||
dataIndex: 'real_name',
|
||||
editable: true,
|
||||
},
|
||||
{
|
||||
title: '单位',
|
||||
dataIndex: 'org_name',
|
||||
editable: true,
|
||||
width: '30%',
|
||||
},{
|
||||
title: '职务',
|
||||
dataIndex: 'org_job',
|
||||
editable: true,
|
||||
},
|
||||
{
|
||||
title: Base64.decode('5Yab6KGU'),
|
||||
dataIndex: 'org_rank',
|
||||
editable: true,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operation',
|
||||
width: '10%',
|
||||
render: (text, record) =>
|
||||
this.state.dataSource.length >= 1 ? (
|
||||
<Popconfirm title="确定删除此成员?" onConfirm={() => this.handleDelete(record.key)}>
|
||||
<img src={apply_delete} className="apply_delete" alt=""/>
|
||||
</Popconfirm>
|
||||
) : null,
|
||||
},];
|
||||
}
|
||||
this.state = {
|
||||
dataSource: this.props.members,
|
||||
count: this.props.members.length,
|
||||
};
|
||||
}
|
||||
|
||||
handleDelete = key => {
|
||||
const dataSource = [...this.state.dataSource];
|
||||
const newData = dataSource.filter(item => item.key !== key);
|
||||
this.setState({ dataSource: newData });
|
||||
this.props.setMembers(newData);
|
||||
};
|
||||
|
||||
handleAdd = () => {
|
||||
const { count, dataSource } = this.state;
|
||||
const newData = {
|
||||
key: count,
|
||||
};
|
||||
this.setState({
|
||||
dataSource: [...dataSource, newData],
|
||||
count: count + 1,
|
||||
});
|
||||
};
|
||||
|
||||
handleSave = row => {
|
||||
const newData = [...this.state.dataSource];
|
||||
const index = newData.findIndex(item => row.key === item.key);
|
||||
const item = newData[index];
|
||||
newData.splice(index, 1, {
|
||||
...item,
|
||||
...row,
|
||||
});
|
||||
this.setState({ dataSource: newData });
|
||||
this.props.setMembers(newData);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { dataSource } = this.state;
|
||||
const components = {
|
||||
body: {
|
||||
row: EditableFormRow,
|
||||
cell: EditableCell,
|
||||
},
|
||||
};
|
||||
const columns = this.columns.map(col => {
|
||||
if (!col.editable) {
|
||||
return col;
|
||||
}
|
||||
return {
|
||||
...col,
|
||||
onCell: record => ({
|
||||
record,
|
||||
editable: col.editable,
|
||||
dataIndex: col.dataIndex,
|
||||
title: col.title,
|
||||
handleSave: this.handleSave,
|
||||
}),
|
||||
};
|
||||
});
|
||||
return (
|
||||
<div className="apply_team">
|
||||
<Button onClick={this.handleAdd} type="primary" className="add_member">
|
||||
添加成员
|
||||
</Button>
|
||||
<div className="member_info">
|
||||
<Table
|
||||
components={components}
|
||||
rowClassName={() => 'editable-row'}
|
||||
dataSource={dataSource}
|
||||
columns={columns}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default EditableTable;
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
.editable-cell {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.editable-cell-value-wrap {
|
||||
padding: 5px 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.editable-row .editable-cell-value-wrap {
|
||||
height: 30px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
padding: 4px 11px;
|
||||
}
|
||||
|
||||
.member_info table{
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.member_info table tr:last-child td{
|
||||
border-bottom: none;
|
||||
}
|
||||
|
|
@ -18,20 +18,22 @@ import logo from "../img/openmmlab/logo1.png";
|
|||
import { hasAuditRole } from '../api';
|
||||
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 } = props;
|
||||
// function goToApply() {
|
||||
// if (isGlccApplyDate) {
|
||||
// if (current_user && current_user.login) {
|
||||
// window.location.href = "https://wj.qq.com/s2/10175205/e8df/";
|
||||
// } else {
|
||||
// window.location.href = "/login?go_page=https://wj.qq.com/s2/10175205/e8df/";
|
||||
// }
|
||||
// } else {
|
||||
// showNotification("不在报名时间,报名时间为4月15日~5月20日");
|
||||
// window.location.href = "/glcc";
|
||||
// }
|
||||
// }
|
||||
const { current_user, isGlccApplyDate, showNotification, studentApplyStart, history, secondStudentApplyDate, isStudentApplyDate, checkedTaskId, checkTime1, checkTime2, checkTime3, round, match:{params:{id}}, period, showLoginDialog} = props;
|
||||
function goToApply() {
|
||||
if (isGlccApplyDate) {
|
||||
if (current_user && current_user.login) {
|
||||
window.location.href = "https://wj.qq.com/s2/10175205/e8df/";
|
||||
} else {
|
||||
window.location.href = "/login?go_page=https://wj.qq.com/s2/10175205/e8df/";
|
||||
}
|
||||
} else {
|
||||
showNotification("不在报名时间,报名时间为4月15日~5月20日");
|
||||
window.location.href = "/glcc";
|
||||
}
|
||||
}
|
||||
|
||||
const [hasRole, setHasRole] = useState(false);
|
||||
const resultTime1 = new Date().getTime() > new Date('2022/06/28 1:0').getTime() && new Date().getTime() < new Date('2022/07/01 0:0').getTime();
|
||||
|
|
@ -67,6 +69,15 @@ export default (props) => {
|
|||
history.push("/glcc/result");
|
||||
}
|
||||
|
||||
// 页面跳转,判断是否登录
|
||||
function gotoCheckLogin(url){
|
||||
if(current_user && current_user.login){
|
||||
history.push(url);
|
||||
return
|
||||
}
|
||||
showLoginDialog();
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="glcc">
|
||||
{/* <Banner /> */}
|
||||
|
|
@ -74,54 +85,79 @@ export default (props) => {
|
|||
{/* <div > */}
|
||||
{/* <Link className="apply-btn" to={isGlccApplyDate ? current_user && current_user.login ? 'https://wj.qq.com/s2/10175205/e8df/' : '/login?go_page=/glcc/apply' : '/glcc'} onClick={()=>{!isGlccApplyDate && showNotification("不在报名时间,报名时间为4月15日~5月20日")}}> */}
|
||||
{/* <div className="apply-btn" onClick={goToApply}>
|
||||
<div className="apply-text">立即报名</div>
|
||||
<div className="apply-icon"><i className="font-14 iconfont icon-xiangyoujiantou "></i></div>
|
||||
</div> */}
|
||||
{/* 报名入口 */}
|
||||
<div className="applyBox">
|
||||
{/* 6.28.-7.1 审核结果仅对导师可见,7.1之后对所有用户可见*/}
|
||||
{resultTime2 && <div className="apply" onClick={goToCheckResult}>
|
||||
<div>
|
||||
<img src={apply2} alt="" className="applyIcon" />
|
||||
<span className="til">名单{resultTime1 ? '预' : ''}公示</span>
|
||||
</div>
|
||||
<div className="pt6">查看各课题入选学生名单</div>
|
||||
</div>}
|
||||
|
||||
{/* 学生结项考核 */}
|
||||
{!hasRole && checkTime1 && checkedTaskId && <Link className="apply" to={`/glcc/submission`}>
|
||||
<div>
|
||||
<img src={img1} alt="" className="applyIcon" />
|
||||
<span className="til">结项考核</span>
|
||||
</div>
|
||||
<div className="pt6">学生提交考核材料</div>
|
||||
</Link>}
|
||||
{/* 导师结项考核 */}
|
||||
{hasRole && new Date().getTime() > new Date('2022/10/01 8:0').getTime() && <Link className="apply" to={`/glcc/final/examination`}>
|
||||
<div>
|
||||
<img src={img1} alt="" className="applyIcon" />
|
||||
<span className="til">结项考核</span>
|
||||
</div>
|
||||
<div className="pt6">导师拟定结项考核结果</div>
|
||||
</Link>}
|
||||
{/* 结项考核结果公示页 */}
|
||||
{checkTime3 && <Link className="apply" to={`/glcc/final/result`}>
|
||||
<div className="apply-text">立即报名</div>
|
||||
<div className="apply-icon"><i className="font-14 iconfont icon-xiangyoujiantou "></i></div>
|
||||
</div> */}
|
||||
{/* 往期回顾 */}
|
||||
{round !== 2 && <div className="applyBox">
|
||||
<Link className="apply" to={`/glcc/${id}/final/result`}>
|
||||
<div>
|
||||
<img src={img1} alt="" className="applyIcon" />
|
||||
<span className="til">考核结果</span>
|
||||
</div>
|
||||
<div className="pt6">结项课题考核结果公示</div>
|
||||
</Link>}
|
||||
|
||||
{/* 项目报名 */}
|
||||
<Link to="/glcc/projects" className="apply project" >
|
||||
</Link>
|
||||
<Link to={`/glcc/${id}/projects`} className="apply project" >
|
||||
<div>
|
||||
<img src={apply1} alt="" className="applyIcon" />
|
||||
<span className="hover-none"><span className="til">查看项目</span> </span>
|
||||
{/* <span className="hover-show">项目报名已截止</span> */}
|
||||
</div>
|
||||
<div className="pt6">掌握项目课题详细信息</div>
|
||||
</Link>
|
||||
</div>}
|
||||
{/* 当前glcc */}
|
||||
{round === 2 && <div className="applyBox">
|
||||
{/* 项目报名入口 */}
|
||||
{period === 0 && <a onClick={()=>{gotoCheckLogin(`/glcc/apply`)}} className="apply project" >
|
||||
<div>
|
||||
<img src={apply1} alt="" className="applyIcon" />
|
||||
<span className="hover-none"><span className="til">项目报名</span> </span>
|
||||
{/* <span className="hover-show">项目报名已截止</span> */}
|
||||
</div>
|
||||
<div className="pt6">项目报名开启,导师席位虚位以待</div>
|
||||
</a>}
|
||||
{/* 6.28.-7.1 审核结果仅对导师可见,7.1之后对所有用户可见*/}
|
||||
{/* {resultTime2 && <div className="apply" onClick={goToCheckResult}>
|
||||
<div>
|
||||
<img src={apply2} alt="" className="applyIcon" />
|
||||
<span className="til">名单{resultTime1 ? '预' : ''}公示</span>
|
||||
</div>
|
||||
<div className="pt6">查看各课题入选学生名单</div>
|
||||
</div>} */}
|
||||
|
||||
{/* 学生结项考核 */}
|
||||
{/* {!hasRole && checkTime1 && checkedTaskId && <Link className="apply" to={`/glcc/submission`}>
|
||||
<div>
|
||||
<img src={img1} alt="" className="applyIcon" />
|
||||
<span className="til">结项考核</span>
|
||||
</div>
|
||||
<div className="pt6">学生提交考核材料</div>
|
||||
</Link>} */}
|
||||
{/* 导师结项考核 */}
|
||||
{/* {hasRole && new Date().getTime() > new Date('2022/10/01 8:0').getTime() && <Link className="apply" to={`/glcc/final/examination`}>
|
||||
<div>
|
||||
<img src={img1} alt="" className="applyIcon" />
|
||||
<span className="til">结项考核</span>
|
||||
</div>
|
||||
<div className="pt6">导师拟定结项考核结果</div>
|
||||
</Link>} */}
|
||||
{/* 结项考核结果公示页 */}
|
||||
{/* {checkTime3 && <Link className="apply" to={`/glcc/final/result`}>
|
||||
<div>
|
||||
<img src={img1} alt="" className="applyIcon" />
|
||||
<span className="til">考核结果</span>
|
||||
</div>
|
||||
<div className="pt6">结项课题考核结果公示</div>
|
||||
</Link>} */}
|
||||
|
||||
{/* 项目报名 */}
|
||||
{/* <Link to="/glcc/projects" className="apply project" >
|
||||
<div>
|
||||
<img src={apply1} alt="" className="applyIcon" />
|
||||
<span className="hover-none"><span className="til">查看项目</span> </span>
|
||||
</div>
|
||||
<div className="pt6">掌握项目课题详细信息</div>
|
||||
</Link> */}
|
||||
{/* 学生报名6.24结束第一次报名,6.29 1:00 - 6.30 24:00第二次报名 */}
|
||||
{/* <div className="apply" onClick={goToStudent}>
|
||||
<div>
|
||||
|
|
@ -139,7 +175,7 @@ export default (props) => {
|
|||
</div>
|
||||
<div className="pt6">以赛代筛,挖掘高潜力人才</div>
|
||||
</div>} */}
|
||||
</div>
|
||||
</div>}
|
||||
{/* </div> */}
|
||||
<div className="introduce">
|
||||
<div className="glcc-content">
|
||||
|
|
@ -149,7 +185,7 @@ export default (props) => {
|
|||
<img src={introduce} alt="" className="introduceImg" />
|
||||
</div>
|
||||
{/* 活动特邀合作单位 */}
|
||||
<div className="openMMlabBox">
|
||||
{round === 1 && <div className="openMMlabBox">
|
||||
<div className="logoTitle">
|
||||
<img src={logo} alt="" className="logo"/>
|
||||
<span className="title">活动特邀合作单位 OpenMMLab</span>
|
||||
|
|
@ -158,14 +194,14 @@ export default (props) => {
|
|||
</div>
|
||||
<div className="intro">OpenMMLab是深度学习时代最完整的计算机视觉开源算法体系。自开源以来,累计发布了超过20个算法库,有超过300个算法2300多个预训练模型。所有算法均具备风格统一、模型丰富、质量高、易复现等特点。在社区生态上,OpenMMLab一直秉持开放、认真、持续成长的原则,积极推动社区建设发展</div>
|
||||
<div className="goToButBox"><button className="goToBut" onClick={()=>{window.location.href='/glcc/openmmlab'}}>查看详情</button></div>
|
||||
</div>
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
<Lightspot isGlccApplyDate={isGlccApplyDate} current_user={current_user} showNotification={showNotification} goToStudent={goToStudent}/>
|
||||
<TimerShaft />
|
||||
<Lightspot period={period} history={history} current_user={current_user} round={round} showLoginDialog={showLoginDialog}/>
|
||||
<TimerShaft round={round}/>
|
||||
<Award />
|
||||
<News />
|
||||
<Partner />
|
||||
<Partner round={round}/>
|
||||
<Contact />
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,30 +1,20 @@
|
|||
import { Button } from 'antd';
|
||||
import React from 'react';
|
||||
import teacherImg from '../../img/teacher-img.png';
|
||||
import lightspot1 from '../../img/lightspot1.png';
|
||||
import lightspot2 from '../../img/lightspot2.png';
|
||||
import lightspot3 from '../../img/lightspot3.png';
|
||||
import lightspot4 from '../../img/lightspot4.png';
|
||||
|
||||
|
||||
import './index.scss';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
|
||||
function Lightspot(props) {
|
||||
const {current_user, isGlccApplyDate, showNotification, goToStudent} = props;
|
||||
const {current_user, period, history, round, showLoginDialog} = props;
|
||||
|
||||
function goToApply(){
|
||||
if(isGlccApplyDate){
|
||||
if(current_user && current_user.login){
|
||||
window.location.href="https://wj.qq.com/s2/10175205/e8df/";
|
||||
}else{
|
||||
window.location.href="/login?go_page=https://wj.qq.com/s2/10175205/e8df/";
|
||||
}
|
||||
}else{
|
||||
showNotification("不在报名时间,报名时间为4月15日~5月20日");
|
||||
window.location.href="/glcc";
|
||||
if(current_user && !current_user.login){
|
||||
showLoginDialog();
|
||||
return;
|
||||
}
|
||||
history.push(period === 0 ? `/glcc/apply` : `/glcc/subjects`);
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
@ -36,17 +26,13 @@ function Lightspot(props) {
|
|||
<div className="teacher-text">
|
||||
<h3 className="teacher-invite">有兴趣成为GLCC的导师吗?</h3>
|
||||
<div className="teacher-content">想要扩大项目知名度和影响力,为开源项目吸引新鲜血液,培养长期开发者。通过GitLink平台,与高校建立连接,指导开源新人传授他们的开源文化,享受开源的乐趣</div>
|
||||
{/* <Link className='applyBut' to={isGlccApplyDate ? current_user && current_user.login ? 'https://wj.qq.com/s2/10175205/e8df/' : '/login?go_page=/glcc/apply' : '/glcc'} onClick={()=>{!isGlccApplyDate && showNotification("不在报名时间,报名时间为4月15日~5月20日")}}>立即报名</Link> */}
|
||||
{/* onClick={goToApply} */}
|
||||
<div className='applyBut project'><span className='hover-none'>项目报名</span><span className='hover-show'>项目报名已截止</span></div>
|
||||
{period === 0 && round === 2 ? <div className='applyBut' onClick={goToApply}>立即报名</div> : <div className='applyBut project'><span className='hover-none'>项目报名</span><span className='hover-show'>{period === -1 ? "敬请期待" : "已结束"}</span></div>}
|
||||
</div>
|
||||
<div className="teacher-text">
|
||||
<h3 className="teacher-invite">你是开源新手,有兴趣参加GLCC吗?</h3>
|
||||
<div className="teacher-content">想要参与一线开源项目开发,熟悉开源社区运作流程,接受资深开源软件专家指导,获得丰厚奖金和实习机会。参加GLCC,开启全新的开源之旅。</div>
|
||||
{/* <Link className='applyBut' to={isGlccApplyDate ? current_user && current_user.login ? 'https://wj.qq.com/s2/10175205/e8df/' : '/login?go_page=/glcc/apply' : '/glcc'} onClick={()=>{!isGlccApplyDate && showNotification("不在报名时间,报名时间为4月15日~5月20日")}}>立即报名</Link> */}
|
||||
<div className='applyBut' onClick={goToStudent}>学生报名</div>
|
||||
{period === 2 && round === 2 ? <div className='applyBut' onClick={goToApply}>学生报名</div> : <div className='applyBut project'><span className='hover-none'>学生报名</span><span className='hover-show'>{period<2 && round === 2 ? "敬请期待" : "已结束"}</span></div>}
|
||||
</div>
|
||||
{/* <img className="teacher-img" src={teacherImg} alt=''></img> */}
|
||||
</div>
|
||||
|
||||
<div className="info-student">
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ import sponsor31 from '../../img/sponsor31.png';
|
|||
import sponsor32 from '../../img/sponsor32.png';
|
||||
import sponsor33 from '../../img/sponsor33.png';
|
||||
import sponsor41 from '../../img/sponsor41.png';
|
||||
|
||||
|
||||
import sponsor42 from '../../img/sponsor42.png';
|
||||
import sponsor43 from '../../img/sponsor43.png';
|
||||
import log34 from '../../img/34@2x.png';
|
||||
import log35 from '../../img/35@2x.png';
|
||||
import log36 from '../../img/36@2x.png';
|
||||
|
|
@ -38,13 +38,38 @@ import log69 from '../../img/69@2x.png';
|
|||
import log70 from '../../img/浙江大学.png';
|
||||
import logo1 from '../../img/logo1.png';
|
||||
import logo2 from '../../img/logo2.png';
|
||||
function Partner() {
|
||||
function Partner({round}) {
|
||||
|
||||
return (
|
||||
<div className="partner">
|
||||
<div className="glcc-content">
|
||||
<h3 className="glcc-tit">组织方及合作伙伴</h3>
|
||||
<div className='cont1 cont mb10'>
|
||||
{round === 2 && <div className='cont1 cont mb10'>
|
||||
<div>
|
||||
主办方
|
||||
<div onClick={() => { window.open("https://www.ccf.org.cn/") }} className='div8b9'><img src={ccf1} /></div>
|
||||
</div>
|
||||
<div>
|
||||
承办方
|
||||
<div onClick={() => { window.open("https://www.zhejianglab.com/home") }} className='div8b9'><img src={sponsor42} alt='之江实验室' className='gitlink'/></div>
|
||||
</div>
|
||||
<div>
|
||||
协办方
|
||||
<div className='flex_div'>
|
||||
<div onClick={() => { window.open("https://www.gitlink.org.cn/") }} className='div8b9 mr35'><img src={gitlink} className='gitlink' /></div>
|
||||
<div onClick={() => { window.open("http://111.8.36.180:81/#/about") }} className='div8b9'><img src={xjy} className='xjy' /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>}
|
||||
|
||||
{round === 2 && <div className='cont cont3 mt15'>
|
||||
钻石赞助商
|
||||
<div className='pt10'>
|
||||
<div className="sponsor" onClick={() => { window.open("https://www.bytedance.com/") }}><img src={sponsor43} className='gitlink' alt='字节跳动' /></div>
|
||||
</div>
|
||||
</div>}
|
||||
|
||||
{round === 1 && <div className='cont1 cont mb10'>
|
||||
<div>
|
||||
主办方
|
||||
<div onClick={() => { window.open("https://www.ccf.org.cn/") }} className='div8b9'><img src={ccf1} /></div>
|
||||
|
|
@ -60,39 +85,39 @@ function Partner() {
|
|||
<div onClick={() => { window.open("http://111.8.36.180:81/#/about") }} className='div8b9'><img src={xjy} className='xjy' /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>}
|
||||
|
||||
<div className='cont cont3 mt15'>
|
||||
{round === 1 && <div className='cont cont3 mt15'>
|
||||
特邀合作单位
|
||||
<div className='pt10'>
|
||||
<div className="sponsor" onClick={() => { window.open("https://github.com/open-mmlab") }}><img src={sponsor11} className='gitlink' alt='OpenMMLab' /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>}
|
||||
|
||||
<div className='cont cont3 mt15'>
|
||||
{round === 1 && <div className='cont cont3 mt15'>
|
||||
白金赞助商
|
||||
<div className='pt10'>
|
||||
<div className="sponsor" onClick={() => { window.open("http://www.baidu.com/") }}><img src={sponsor21} className='gitlink' alt='百度' /></div>
|
||||
<div className="sponsor" onClick={() => { window.open("https://www.antgroup.com/") }}><img src={sponsor22} className='gitlink' alt='蚂蚁集团' /></div>
|
||||
<div className="sponsor" onClick={() => { window.open("https://www.alibaba.com/") }}><img src={sponsor23} className='gitlink' alt='阿里巴巴' /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>}
|
||||
|
||||
<div className='cont cont3 mt15'>
|
||||
{round === 1 && <div className='cont cont3 mt15'>
|
||||
黄金赞助商
|
||||
<div className='pt10'>
|
||||
<div className="sponsor" onClick={() => { window.open("https://aws.amazon.com/cn/") }}><img src={sponsor31} className='gitlink' alt='亚马逊云科技' /></div>
|
||||
<div className="sponsor" onClick={() => { window.open("https://www.didiglobal.com/") }}><img src={sponsor32} className='gitlink' alt='滴滴出行' /></div>
|
||||
<div className="sponsor" onClick={() => { window.open("https://www.99cloud.net/") }}><img src={sponsor33} className='gitlink' alt='九州云' /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>}
|
||||
|
||||
<div className='cont cont3 mt15'>
|
||||
{round === 1 && <div className='cont cont3 mt15'>
|
||||
白银赞助商
|
||||
<div className='pt10'>
|
||||
<div className="sponsor" onClick={() => { window.open(" https://www.cloudwego.io/") }}><img src={sponsor41} className='gitlink' alt='cloudwego' /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>}
|
||||
|
||||
|
||||
<div className='cont cont3 mt15'>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import Step from './step';
|
||||
import './index.scss';
|
||||
|
||||
const stepArr = [{
|
||||
const stepArr2022 = [{
|
||||
title: "Step1",
|
||||
date: "4.15",
|
||||
content: "GLCC夏令营活动发布"
|
||||
|
|
@ -40,18 +40,72 @@ const stepArr = [{
|
|||
},
|
||||
{
|
||||
title: "Step2",
|
||||
date: "10.1-10.24",
|
||||
date: "10.1-10.21",
|
||||
content: "结项审核,并公示考核结果",
|
||||
},
|
||||
{
|
||||
title: "Step2",
|
||||
date: "10.24-11.11",
|
||||
date: "10.21-11.11",
|
||||
content: "评选公布优秀项目和学员",
|
||||
noArrow: true,
|
||||
}
|
||||
]
|
||||
const stepArr = [{
|
||||
title: "Step1",
|
||||
date: "4.29",
|
||||
content: "GLCC夏令营活动发布"
|
||||
},
|
||||
{
|
||||
title: "Step2",
|
||||
date: "4.29-5.30",
|
||||
content: "社区项目报名,提交课题"
|
||||
},
|
||||
{
|
||||
title: "Step2",
|
||||
date: "5.30-6.3",
|
||||
content: "公示项目、课题名单"
|
||||
},
|
||||
{
|
||||
title: "Step2",
|
||||
date: "6.4-6.21",
|
||||
content: "学生报名,提交Proposal"
|
||||
},
|
||||
{
|
||||
title: "Step2",
|
||||
date: "7.1",
|
||||
content: "公示入选学生名单",
|
||||
noArrow: true,
|
||||
},
|
||||
{
|
||||
title: "Step2",
|
||||
date: "7.1-8.11",
|
||||
content: "项目开发第一阶段",
|
||||
},
|
||||
{
|
||||
title: "Step2",
|
||||
date: "8.20",
|
||||
content: "中期考核,公示考核结果",
|
||||
},
|
||||
{
|
||||
title: "Step2",
|
||||
date: "8.21-9.28",
|
||||
content: "项目开发第二阶段",
|
||||
},
|
||||
{
|
||||
title: "Step2",
|
||||
date: "10.11",
|
||||
content: "结项审核,公示考核结果",
|
||||
},
|
||||
{
|
||||
title: "Step2",
|
||||
date: "10.22",
|
||||
content: "开源大赛闭幕式",
|
||||
noArrow: true,
|
||||
}
|
||||
]
|
||||
|
||||
function TimerShaft() {
|
||||
function TimerShaft({round}) {
|
||||
const step = round === 2 ? stepArr : stepArr2022
|
||||
|
||||
return (
|
||||
<div className="timerShaft">
|
||||
|
|
@ -59,7 +113,7 @@ function TimerShaft() {
|
|||
<h3 className="glcc-tit">时间规划</h3>
|
||||
<div className="time-content">
|
||||
{
|
||||
stepArr.map((item, i) => {
|
||||
step.map((item, i) => {
|
||||
return <Step {...item} title={`Step${i + 1}`} key={i}/>
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 540 B |
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
|
|
@ -11,7 +11,7 @@ import "./index.scss";
|
|||
import Loadable from "react-loadable";
|
||||
import Loading from "../Loading";
|
||||
import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC";
|
||||
import { getStudentApplyInfo } from "./api";
|
||||
import { getGlccSettings, getStudentApplyInfo } from "./api";
|
||||
import { message } from "antd";
|
||||
|
||||
|
||||
|
|
@ -77,7 +77,32 @@ const MiddleResult = Loadable({
|
|||
loading: Loading,
|
||||
});
|
||||
const Glcc = (propsF) => {
|
||||
const {current_user, showLoginDialog} = propsF;
|
||||
const {current_user, showLoginDialog, match:{params:{id}}} = propsF;
|
||||
// round:2022届(1) 2023届(2)
|
||||
const [round, setRound] = useState(2);
|
||||
const [period, setPeriod] = useState(undefined);
|
||||
|
||||
useEffect(()=>{
|
||||
if(id && id === "2022"){
|
||||
setRound(1);
|
||||
}
|
||||
}, [id])
|
||||
useEffect(()=>{
|
||||
// 获取当前glcc配置
|
||||
getGlccSettings({round: 2}).then(res=>{
|
||||
if(res && res.message === "success"){
|
||||
const nowTime = new Date().getTime();
|
||||
setPeriod(res.data.findIndex(item=>judge(nowTime, item.value)));
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
// 判断是否处于此段时间范围内
|
||||
function judge(nowTime, timeRnge){
|
||||
const timeArr = timeRnge.split(",").map(item=>{return new Date(item).getTime()});
|
||||
return nowTime > timeArr[0] && nowTime < timeArr[1]
|
||||
}
|
||||
|
||||
// 判断时间是否在开源夏令营报名时间内(4月15日~5月20日)
|
||||
const isGlccApplyDate = Date.parse(new Date()) < 1653062400000;
|
||||
|
||||
|
|
@ -108,8 +133,8 @@ const Glcc = (propsF) => {
|
|||
}, [])
|
||||
|
||||
useEffect(()=>{
|
||||
// 获取用户课题报名信息
|
||||
current_user && current_user.login && getStudentApplyInfo({userId: current_user.user_id}).then(response=>{
|
||||
// 获取用户课题报名信息(todo:学生报名阶段请求)
|
||||
false && current_user && current_user.login && getStudentApplyInfo({userId: current_user.user_id}).then(response=>{
|
||||
if(response && response.message === "success"){
|
||||
// setData(response.data.rows);
|
||||
const data = {};
|
||||
|
|
@ -155,12 +180,12 @@ const Glcc = (propsF) => {
|
|||
)}
|
||||
></Route>
|
||||
{/* 开源夏令营报名页面 */}
|
||||
<Route
|
||||
{period === 0 && <Route
|
||||
path="/glcc/apply"
|
||||
render={(props) => (
|
||||
<Apply {...propsF} {...props} isGlccApplyDate={isGlccApplyDate}/>
|
||||
<Apply round={round} {...propsF} {...props}/>
|
||||
)}
|
||||
></Route>
|
||||
></Route>}
|
||||
{/* 教师审核 */}
|
||||
<Route
|
||||
path="/glcc/mentoradmin"
|
||||
|
|
@ -176,22 +201,22 @@ const Glcc = (propsF) => {
|
|||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/glcc/subjects/detail/:taskId"
|
||||
path="/glcc/:id/subjects/detail/:taskId"
|
||||
render={(props) => (
|
||||
<TaskDetail {...propsF} {...props} isStudentApplyDate={isStudentApplyDate} secondStudentApplyDate={secondStudentApplyDate} applyTaskId={applyTaskId} applyTask={applyTask} />
|
||||
)}
|
||||
></Route>
|
||||
{/* 项目/课题列表 */}
|
||||
<Route
|
||||
path="/glcc/projects"
|
||||
path="/glcc/:id/projects"
|
||||
render={(props) => (
|
||||
<Project {...propsF} {...props} isStudentApplyDate={isStudentApplyDate} secondStudentApplyDate={secondStudentApplyDate} applyTaskId={applyTaskId} setStudentInfoReset={setStudentInfoReset} applyTask={applyTask}/>
|
||||
<Project round={round} {...propsF} {...props} isStudentApplyDate={isStudentApplyDate} secondStudentApplyDate={secondStudentApplyDate} applyTaskId={applyTaskId} setStudentInfoReset={setStudentInfoReset} applyTask={applyTask}/>
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 课题列表 */}
|
||||
<Route
|
||||
path="/glcc/subjects"
|
||||
path="/glcc/:id/subjects"
|
||||
render={(props) => (
|
||||
<Project {...propsF} {...props} isStudentApplyDate={isStudentApplyDate} secondStudentApplyDate={secondStudentApplyDate} applyTaskId={applyTaskId} setStudentInfoReset={setStudentInfoReset} cancelCount={cancelCount} applyTask={applyTask}/>
|
||||
)}
|
||||
|
|
@ -215,9 +240,9 @@ const Glcc = (propsF) => {
|
|||
|
||||
{/* 中期审核-结果公示 */}
|
||||
<Route
|
||||
path="/glcc/final/result"
|
||||
path="/glcc/:id/final/result"
|
||||
render={(props) => (
|
||||
<MiddleResult current_user={current_user} history={props.history} checkTime3={checkTime3}/>
|
||||
<MiddleResult id={id} round={round} current_user={current_user} history={props.history} checkTime3={checkTime3}/>
|
||||
)}
|
||||
></Route>
|
||||
|
||||
|
|
@ -237,11 +262,19 @@ const Glcc = (propsF) => {
|
|||
)}
|
||||
></Route>
|
||||
|
||||
{/* 首页 */}
|
||||
<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}/>
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 首页 */}
|
||||
<Route
|
||||
path="/glcc"
|
||||
render={(props) => (
|
||||
<Home {...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}/>
|
||||
)}
|
||||
></Route>
|
||||
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@
|
|||
}
|
||||
.-task-sidebar .glccHelp {
|
||||
height: auto;
|
||||
width: 48px;
|
||||
padding: 6px 16px;
|
||||
width: 38px;
|
||||
padding: 6px 10px;
|
||||
text-align: center;
|
||||
background-color: #f6f9fe;
|
||||
border: 1px solid #ffffff;
|
||||
|
|
@ -46,22 +46,31 @@
|
|||
box-shadow: 0px 0px 8px rgba(55, 148, 255, 0.16);
|
||||
color: #1e1e1e;
|
||||
font-size: 14px;
|
||||
line-height: 35px;
|
||||
line-height: 20px;
|
||||
word-break: break-word;
|
||||
cursor: pointer;
|
||||
.icon-bangzhuzhongxinicon,
|
||||
.icon-bangzhuzhongxinicon1 {
|
||||
.icon-bangzhuzhongxinicon1{
|
||||
color: #0654d6;
|
||||
margin-left: -3px;
|
||||
}
|
||||
.icon-zanting {
|
||||
color: #0654d6;
|
||||
}
|
||||
&:hover {
|
||||
color: #ffffff;
|
||||
background-color: #466aff;
|
||||
.icon-bangzhuzhongxinicon,
|
||||
.icon-bangzhuzhongxinicon1 {
|
||||
.icon-bangzhuzhongxinicon1,
|
||||
.icon-zanting {
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
.glccList{
|
||||
width: 21px;
|
||||
position: relative;
|
||||
left: -2px;
|
||||
}
|
||||
}
|
||||
.qqChatBox {
|
||||
position: fixed;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import '../project/index.scss';
|
|||
const { Search } = Input;
|
||||
|
||||
// 课题列表
|
||||
function CheckResult({current_user, history, checkTime3}) {
|
||||
function CheckResult({current_user, history, checkTime3, round, id}) {
|
||||
// 输入搜索框
|
||||
const [keyword, setKeyword] = useState(undefined);
|
||||
const [data, setData] = useState([]);
|
||||
|
|
@ -36,7 +36,8 @@ function CheckResult({current_user, history, checkTime3}) {
|
|||
curPage: current,
|
||||
keyword,
|
||||
pageSize,
|
||||
term: 2
|
||||
term: 2,
|
||||
round
|
||||
}
|
||||
getMediumTermExamineInfoList(params).then(response => {
|
||||
if (response && response.message === "success") {
|
||||
|
|
@ -54,7 +55,7 @@ function CheckResult({current_user, history, checkTime3}) {
|
|||
{ title: '序号', dataIndex: 'index', align: 'center', className:"columnsResult", width: '6%', render: (text, item, index) => <span>{(current-1)*pageSize+index + 1}</span> },
|
||||
{ title: '入选学生', dataIndex: 'studentName', className:"columnsResult taskName", width: '10%', ellipsis: true},
|
||||
{ title: '课题导师', dataIndex: 'tutorName', className:"columnsResult", width: '10%', ellipsis: true},
|
||||
{ title: '课题名称', dataIndex: 'taskName', className:"columnsResult", width: '20%', ellipsis: true, render: (text, item) => <Tooltip title={text} placement="topLeft"><span className='toolTipSpan link' onClick={()=>{window.open(`/glcc/subjects/detail/${item.taskId}`)}}>{text}</span></Tooltip> },
|
||||
{ title: '课题名称', dataIndex: 'taskName', className:"columnsResult", width: '20%', ellipsis: true, render: (text, item) => <Tooltip title={text} placement="topLeft"><span className='toolTipSpan link' onClick={()=>{window.open(`/glcc/${id}/subjects/detail/${item.taskId}`)}}>{text}</span></Tooltip> },
|
||||
{ title: '项目名称', dataIndex: 'projectName', className:"columnsResult", ellipsis: true, width: '14%', render: (text) => <Tooltip title={text} placement="topLeft"><span className='toolTipSpan'>{text}</span></Tooltip> },
|
||||
{ title: '项目简介', dataIndex: 'introduce', className:"columnsResult", width: '13%', ellipsis: true},
|
||||
{ title: '答辩视频', dataIndex: 'defenceVideoUrl', className:"columnsResult", width: '15%', ellipsis: true, render: (text, item) => <Tooltip title={text} placement="topLeft"><span className='toolTipSpan link' onClick={()=>{window.open(text)}}>{text}</span></Tooltip>},
|
||||
|
|
@ -106,7 +107,7 @@ function CheckResult({current_user, history, checkTime3}) {
|
|||
<img className="bannerInterim" src={resultBanner} alt=""></img>
|
||||
<div className='bgBox'>
|
||||
<div className="resultList">
|
||||
<div className='goBackBox'><a href='/glcc'>开源夏令营 / </a>结项课题考核结果公示</div>
|
||||
<div className='goBackBox'><a href={`/glcc/${id}`}>开源夏令营 / </a>结项课题考核结果公示</div>
|
||||
<div className='searchBox'>
|
||||
<Search className='search' placeholder='请输入学生姓名或课题名称进行搜索' allowClear enterButton onSearch={(value) => { setCurrent(1); setKeyword(value) }} />
|
||||
<div style={{width: 100}}></div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import Nodata from '../../../forge/Nodata';
|
|||
import { useEffect } from 'react';
|
||||
import { getProjectById } from '../../api';
|
||||
|
||||
export default ({ detail, projectId, applyTaskId, isStudentApplyDate, secondStudentApplyDate, showTask=true, applyTask }) => {
|
||||
export default ({ detail, projectId, applyTaskId, isStudentApplyDate, secondStudentApplyDate, showTask=true, applyTask, id }) => {
|
||||
const [info, setInfo] = useState(detail);
|
||||
|
||||
useEffect(()=>{
|
||||
|
|
@ -30,7 +30,7 @@ export default ({ detail, projectId, applyTaskId, isStudentApplyDate, secondStud
|
|||
{showTask && (info.registrationTaskList && info.registrationTaskList.length > 0 ? info.registrationTaskList.map((item, index)=>{
|
||||
return <div className='taskItem mt20' key={index}>
|
||||
<div className="left">
|
||||
<div className="taskTitle" onClick={()=>{window.location.href=`/glcc/subjects/detail/${item.id}`}}><Tooltip title={item.taskName}>{item.taskName}</Tooltip></div>
|
||||
<div className="taskTitle" onClick={()=>{window.location.href=`/glcc/${id}/subjects/detail/${item.id}`}}><Tooltip title={item.taskName}>{item.taskName}</Tooltip></div>
|
||||
<div className='mt20 oneLine leftWidth'>导师姓名: {item.tutorName}</div>
|
||||
{item.tutorMail && <div className='mb20 email oneLine leftWidth'>邮箱地址: <span><Tooltip title={item.tutorMail}>{item.tutorMail}</Tooltip></span></div>}
|
||||
</div>
|
||||
|
|
@ -48,7 +48,7 @@ export default ({ detail, projectId, applyTaskId, isStudentApplyDate, secondStud
|
|||
{secondStudentApplyDate && !(applyTaskId && Object.keys(applyTaskId).includes(item.id.toString())) && (item.locked ? <Tooltip title={"该课题已有学生入选"}><Button type='primary' className='mr10' disabled>申请课题</Button></Tooltip> : <Button type='primary' className='applyBut mr10' onClick={()=>{applyTask(item.id)}}>申请课题</Button>)}
|
||||
|
||||
{/* 查看课题详情按钮 */}
|
||||
<Button onClick={()=>{window.open(`/glcc/subjects/detail/${item.id}`)}} className='lookDetail'>课题详情</Button>
|
||||
<Button onClick={()=>{window.open(`/glcc/${id}/subjects/detail/${item.id}`)}} className='lookDetail'>课题详情</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="right oneLine taskUrl"><span className='taskReward'>¥{item.taskReward}</span></div>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ const TaskList = Loadable({
|
|||
});
|
||||
|
||||
function Project(propsF) {
|
||||
const {location} = propsF;
|
||||
const {location, match:{params:{id}}} = propsF;
|
||||
const {pathname} = location;
|
||||
useEffect(()=>{
|
||||
window.scrollTo(0, 0);
|
||||
|
|
@ -30,35 +30,35 @@ function Project(propsF) {
|
|||
<div className="glcc_project">
|
||||
<img className="glcc-banner" src={banner} alt=''></img>
|
||||
<div className='head'>
|
||||
<Link to="/glcc/subjects" className={!pathname.endsWith('projects') ? 'active' : ''}>课题列表</Link>
|
||||
<Link to="/glcc/projects" className={pathname.endsWith('projects') ? 'active' : ''}>项目列表</Link>
|
||||
<Link to={`/glcc/${id}/subjects`} className={!pathname.endsWith('projects') ? 'active' : ''}>课题列表</Link>
|
||||
<Link to={`/glcc/${id}/projects`} className={pathname.endsWith('projects') ? 'active' : ''}>项目列表</Link>
|
||||
</div>
|
||||
<div className='gobackBox'>
|
||||
<a href='/glcc'>开源夏令营 / </a>
|
||||
<a href={`/glcc/${id}`}>开源夏令营 / </a>
|
||||
课题及项目列表
|
||||
</div>
|
||||
<Spin spinning={false}>
|
||||
<Switch {...propsF}>
|
||||
<Route
|
||||
path="/glcc/projects/:gitlinkLastUrl"
|
||||
path="/glcc/:id/projects/:gitlinkLastUrl"
|
||||
render={(props) => (
|
||||
<ProjectList {...propsF} {...props}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/glcc/projects"
|
||||
path="/glcc/:id/projects"
|
||||
render={(props) => (
|
||||
<ProjectList {...propsF} {...props}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/glcc/subjects"
|
||||
path="/glcc/:id/subjects"
|
||||
render={(props) => (
|
||||
<TaskList {...propsF} {...props}/>
|
||||
)}
|
||||
></Route>
|
||||
<Route
|
||||
path="/glcc/student"
|
||||
path="/glcc/:id/student"
|
||||
render={(props) => (
|
||||
<TaskList {...propsF} {...props}/>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import star from "../../img/star.png";
|
|||
const { Search } = Input;
|
||||
|
||||
// 项目列表
|
||||
function ProjectList({ applyTaskId, isStudentApplyDate, location, match, secondStudentApplyDate, applyTask }) {
|
||||
function ProjectList({ applyTaskId, isStudentApplyDate, location, match, secondStudentApplyDate, applyTask, round, match:{params:{id}}}) {
|
||||
let gitlinkLastUrl = match.params.gitlinkLastUrl && match.params.gitlinkLastUrl.replace(/\./g, '');
|
||||
let openmmlab = location.search && location.search.split('=')[1];
|
||||
// 输入搜索框
|
||||
|
|
@ -23,7 +23,8 @@ function ProjectList({ applyTaskId, isStudentApplyDate, location, match, secondS
|
|||
const params = {
|
||||
curPage: 1,
|
||||
keyword,
|
||||
pageSize: 10000
|
||||
pageSize: 10000,
|
||||
round
|
||||
}
|
||||
projectList(params).then(response => {
|
||||
if (response && response.message === "success") {
|
||||
|
|
@ -83,7 +84,7 @@ function ProjectList({ applyTaskId, isStudentApplyDate, location, match, secondS
|
|||
onVisibleChange={(visible) => { changeVisible(visible, item) }}
|
||||
key={index}
|
||||
placement={(index + 1) % 3 === 0 ? 'bottomRight' : (index + 1) % 3 % 2 === 0 ? 'bottom' : 'bottomLeft'}
|
||||
content={<ProjectDetail detail={item} applyTaskId={applyTaskId} isStudentApplyDate={isStudentApplyDate} secondStudentApplyDate={secondStudentApplyDate} applyTask={applyTask}/>}
|
||||
content={<ProjectDetail id={id} detail={item} applyTaskId={applyTaskId} isStudentApplyDate={isStudentApplyDate} secondStudentApplyDate={secondStudentApplyDate} applyTask={applyTask}/>}
|
||||
trigger='click'
|
||||
overlayClassName='projectItemPopover'
|
||||
autoAdjustOverflow={false}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import './index.scss';
|
|||
|
||||
// 课题列表
|
||||
function TaskDetail(props) {
|
||||
const {match, location, isStudentApplyDate, secondStudentApplyDate, applyTaskId, applyTask} = props
|
||||
const {match, location, isStudentApplyDate, secondStudentApplyDate, applyTaskId, applyTask, match:{params:{id}}} = props
|
||||
const taskId = Number(match.params.taskId);
|
||||
const [detail, setDetail] = useState(undefined);
|
||||
|
||||
|
|
@ -26,8 +26,8 @@ function TaskDetail(props) {
|
|||
{detail && <div className="bgBox">
|
||||
<div className="detailBox">
|
||||
<div className='goBackBox'>
|
||||
<a href='/glcc'>开源夏令营 / </a>
|
||||
<a href='/glcc/subjects'>课题及项目列表 / </a>
|
||||
<a href={`/glcc/${id}`}>开源夏令营 / </a>
|
||||
<a href={`/glcc/${id}/subjects`}>课题及项目列表 / </a>
|
||||
课题详情
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import bgPng from "../../img/bgPng.png";
|
|||
const { Search } = Input;
|
||||
|
||||
// 课题列表
|
||||
function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDialog, isStudentApplyDate, secondStudentApplyDate,cancelCount,showNotification, applyTask}) {
|
||||
function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDialog, isStudentApplyDate, secondStudentApplyDate,cancelCount,showNotification, applyTask, round, match:{params:{id}}}) {
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [deleteTaskId, setDeleteTaskId] = useState(undefined);
|
||||
// 输入搜索框
|
||||
|
|
@ -24,7 +24,7 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
|
|||
|
||||
const columns = [
|
||||
{ title: '序号', dataIndex: 'index', align: 'center', className:"taskTableColumns", width: '6%', render: (text, item, index) => <span>{(current-1)*pageSize+index + 1}</span> },
|
||||
{ title: '课题名称', dataIndex: 'taskName', className:"taskTableColumns taskName", width: '24%', ellipsis: true, render: (text, item) => <Tooltip title={text} placement="topLeft"><span onClick={()=>{window.open(`/glcc/subjects/detail/${item.id}`)}}>{text}</span></Tooltip> },
|
||||
{ title: '课题名称', dataIndex: 'taskName', className:"taskTableColumns taskName", width: '24%', ellipsis: true, render: (text, item) => <Tooltip title={text} placement="topLeft"><span onClick={()=>{window.open(`/glcc/${id}/subjects/detail/${item.id}`)}}>{text}</span></Tooltip> },
|
||||
{ title: '课题类型', dataIndex: 'projectType', className:"taskTableColumns", width: '12%', ellipsis: true, },
|
||||
{ title: '项目名称', dataIndex: 'projectName', className:"taskTableColumns", width: '24%', ellipsis: true, render: (text) => <Tooltip title={text} placement="topLeft">{text}</Tooltip> },
|
||||
{ title: '课题奖金', dataIndex: 'taskReward', className:"taskTableColumns", ellipsis: true, width: '10%', render: (text) => <Tooltip title={text} placement="topLeft"><span>{text}</span></Tooltip> },
|
||||
|
|
@ -71,7 +71,7 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
|
|||
}
|
||||
|
||||
const expandRow = (record) => {
|
||||
return <ProjectDetail detail={null} projectId={record.regId} applyTaskId={applyTaskId} current_user={current_user} showLoginDialog={showLoginDialog} isStudentApplyDate={isStudentApplyDate} showNotification={showNotification} secondStudentApplyDate={secondStudentApplyDate} applyTask={applyTask}/>
|
||||
return <ProjectDetail id={id} detail={null} projectId={record.regId} applyTaskId={applyTaskId} current_user={current_user} showLoginDialog={showLoginDialog} isStudentApplyDate={isStudentApplyDate} showNotification={showNotification} secondStudentApplyDate={secondStudentApplyDate} applyTask={applyTask}/>
|
||||
}
|
||||
|
||||
// 展开收起行回调
|
||||
|
|
@ -128,7 +128,8 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
|
|||
curPage: current,
|
||||
keyword,
|
||||
pageSize,
|
||||
userId: apply ? current_user.user_id : ''
|
||||
userId: apply ? current_user.user_id : '',
|
||||
round
|
||||
}
|
||||
taskList(params).then(response => {
|
||||
if (response && response.message === "success") {
|
||||
|
|
@ -149,7 +150,7 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
|
|||
<div className="taskList listBox">
|
||||
<div className="list">
|
||||
<div className='search task'>
|
||||
{current_user && current_user.login ? <Checkbox onChange={(e)=>{setCurrent(1);setApply(e.target.checked)}}>已报名</Checkbox> : <div></div>}
|
||||
{round === 2 && current_user && current_user.login ? <Checkbox onChange={(e)=>{setCurrent(1);setApply(e.target.checked)}}>已报名</Checkbox> : <div></div>}
|
||||
<Search className='taskSearch' placeholder='请输入课题/项目名称进行搜索' allowClear enterButton onSearch={(value) => { setCurrent(1); setKeyword(value) }} />
|
||||
<div></div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ function SiderBar() {
|
|||
<i className='iconfont icon-bangzhuzhongxinicon font-20'></i>
|
||||
帮助中心
|
||||
</div>
|
||||
<div className={"glccHelp"} onClick={()=>window.open("/glcc/2022")}>
|
||||
<i className='iconfont icon-zanting font-17'></i>
|
||||
往期回顾
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue