Merge pull request '开源夏令营二期issue' (#378) from tongChong/forgeplus-react:feature_GLCC into gitlink_server

This commit is contained in:
xxq250 2022-05-20 14:43:16 +08:00
commit a07ca37bab
11 changed files with 111 additions and 64 deletions

View File

@ -33,7 +33,7 @@ export default Form.create()(
const [fileList, setFileList] = useState(undefined);
const [attachment, setAttachment] = useState(undefined);
const [options , setOptions] = useState(undefined);
const stable = history && history.location && history.location.state.stable;
const stable = history && history.location && history.location.state&&history.location.state.stable;
const { projectsId, versionId , owner } = match.params;
useEffect(()=>{

View File

@ -10,7 +10,7 @@ function Award() {
<div className="glcc-content">
<div className="award-item">
<div className="award-tit">丰厚现金奖励</div>
<div className="award-content">根据课题开发耗时对应奖金从<span className="number">6000</span>元至<span className="number">12000</span>元不等详细可以课题详情中具体奖金标准</div>
<div className="award-content">根据课题开发耗时对应奖金从<span className="number">6000</span>元至<span className="number">12000</span>元不等可在课题详情中查看具体奖金标准</div>
<div className="award-line"></div>
</div>

View File

@ -46,7 +46,7 @@ const stepArr = [{
{
title: "Step2",
date: "10.21-11.11",
content: "评选公布优秀项目和学员&学员",
content: "评选公布优秀项目和学员",
noArrow: true,
}
]

View File

@ -34,30 +34,13 @@ export default ({ detail, projectId, applyTaskId, current_user, showLoginDialog,
}
},[detail])
// detail && (detail.registrationTaskList = [{
// id: 1,
// taskName: 'aaaa',
// tutorName: 'daoshi',
// tutorMail: 'email',
// taskDesc: 'sfdjhdf,hsldf',
// taskUrl: 'url',
// taskReward: '9000'
// },{
// id: 2,
// taskName: 'aaaa',
// tutorName: 'daoshi',
// tutorMail: 'email',
// taskDesc: 'sfdjhdf,hsldfaaaaaaaaaaaaaaaa',
// taskUrl: 'url',
// taskReward: '9000'
// }])
return (
info ? <div className={`projectDetailBox ${detail ? '':'byTask'}`}>
<div className="projectDetailHead">
<span className='name'>{info.projectName}</span>
{info.projectType && <span className='type'>{info.projectType}</span>}
<p>GitLink项目地址: {info.gitlinkUrl}</p>
<div>项目简介: {info.projectIntro}</div>
<p>GitLink项目地址:&nbsp;&nbsp;<a href={info.gitlinkUrl} className='linkUrl'>{info.gitlinkUrl}</a></p>
<div>项目简介:&nbsp;&nbsp;{info.projectIntro}</div>
</div>
{info.registrationTaskList && info.registrationTaskList.length > 0 ? info.registrationTaskList.map(item=>{
return <div className='taskItem mt20'>
@ -68,7 +51,7 @@ export default ({ detail, projectId, applyTaskId, current_user, showLoginDialog,
</div>
<div className="center">
<div className="taskDesc">{item.taskDesc}</div>
<div className="taskUrl">课题链接: &nbsp;&nbsp;<span>{item.taskUrl}</span></div>
<div className="taskUrl">课题链接: &nbsp;&nbsp;<span><a href={info.gitlinkUrl}>{item.taskUrl}</a></span></div>
<div>{(isStudentApplyDate || studentApplyEnd) && (applyTaskId && item.id && Object.keys(applyTaskId).includes(item.id.toString()) ? <Button onClick={()=>{window.location.href=`/glcc/student/apply/${item.id}`}} className='lookDetail'>报名详情</Button> : isStudentApplyDate && <Button type='primary' className='applyBut' onClick={()=>{applyTask(item.id)}}>申请课题</Button>)}</div>
</div>
<div className="right oneLine"> {item.taskReward}</div>

View File

@ -34,7 +34,7 @@ function Project(propsF) {
useEffect(()=>{
// current_user user_id
getStudentApplyInfo({userId: current_user && current_user.user_id}).then(response=>{
current_user && current_user.login && getStudentApplyInfo({userId: current_user.user_id}).then(response=>{
if(response && response.message === "success"){
// setData(response.data.rows);
const data = {};
@ -44,13 +44,13 @@ function Project(propsF) {
setApplyTaskId(data);
}
})
},[studentInfoReset])
},[studentInfoReset, current_user])
return(
<div className="glcc_project">
<img className="glcc-banner" src={banner} alt=''></img>
<div className='head'>
<Link to="/glcc/student/2" className={pathname.lastIndexOf('/2') !== -1 ? 'active' : ''}>课题列表</Link>
<Link to="/glcc/student/1" className={pathname.lastIndexOf('/1') !== -1 ? 'active' : ''}>项目列表</Link>
<Link to="/glcc/student/2" className={!pathname.endsWith('/1') ? 'active' : ''}>课题列表</Link>
<Link to="/glcc/student/1" className={pathname.endsWith('/1') ? 'active' : ''}>项目列表</Link>
</div>
<div className='gobackBox'>
<a href='/glcc'>开源夏令营 / </a>
@ -70,6 +70,12 @@ function Project(propsF) {
<TaskList applyTaskId={applyTaskId} setStudentInfoReset={setStudentInfoReset} current_user={current_user} showLoginDialog={showLoginDialog} isStudentApplyDate={isStudentApplyDate} studentApplyEnd={studentApplyEnd}/>
)}
></Route>
<Route
path="/glcc/student"
render={(props) => (
<TaskList applyTaskId={applyTaskId} setStudentInfoReset={setStudentInfoReset} current_user={current_user} showLoginDialog={showLoginDialog} isStudentApplyDate={isStudentApplyDate} studentApplyEnd={studentApplyEnd}/>
)}
></Route>
</Switch>
</Spin>
</div>

View File

@ -88,6 +88,7 @@
color:#465474;
padding-bottom: 12px;
border-bottom: 1px dashed #bec5d5;
line-height: 36px;
.name{
font-weight:700;
color:#3753c5;
@ -99,6 +100,10 @@
border-radius:4px;
margin-left: 12px;
padding: 4px 6px;
line-height: 26px;
}
.linkUrl{
color: #466aff;
}
}
.taskItem {
@ -137,7 +142,7 @@
.taskUrl{
color:#465474;
font-size:16px;
span{color:#466aff;}
a{color:#466aff;}
}
.applyBut{
background-color:#466aff;
@ -171,7 +176,15 @@
padding: 30px 30px 50px;
}
}
.lookDetail:hover, .lookDetail:focus{
.lookDetail{
border-color: #466aff;
color: #466aff;
&:hover{
border-color: #5d7cff;
color: #5d7cff;
}
&:focus{
border-color: #1140ff;
color: #1140ff;
}
}

View File

@ -35,7 +35,7 @@ function ProjectList({applyTaskId, current_user, showLoginDialog, isStudentApply
<Spin spinning={loading}>
<div className='projectListBox'>
{data && data.map((item, index)=>{
return <Popover placement= {(index+1)%3 === 0 ? 'bottomRight' : (index+1)%3%2 === 0 ? 'bottom' : 'bottomLeft'} content={<ProjectDetail detail={item} applyTaskId={applyTaskId} current_user={current_user} showLoginDialog={showLoginDialog}/>} trigger='click' overlayClassName='projectItemPopover' autoAdjustOverflow={false} isStudentApplyDate={isStudentApplyDate} studentApplyEnd={studentApplyEnd}>
return <Popover placement= {(index+1)%3 === 0 ? 'bottomRight' : (index+1)%3%2 === 0 ? 'bottom' : 'bottomLeft'} content={<ProjectDetail detail={item} applyTaskId={applyTaskId} current_user={current_user} showLoginDialog={showLoginDialog} isStudentApplyDate={isStudentApplyDate} studentApplyEnd={studentApplyEnd}/>} trigger='click' overlayClassName='projectItemPopover' autoAdjustOverflow={false}>
<div className={`projectItem ${(index+1)%3 === 0 || (index+1)%3%2 === 0 ? '' : 'firstBox'}`}>
<div className="border"></div>
<div className="projectLogo"><img src={`${main_site_url}/api/attachments/${item.projectLogoId}`} alt=''/></div>

View File

@ -17,9 +17,10 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
const [total, setTotal] = useState(0);
const [pageSize, setPageSize] = useState(20);
const [loading, setLoading] = useState(false);
const [expandedRowKeys, setExpandedRowKeys] = useState([]);
const columns = [
{ title: '序号', dataIndex: 'index', align: 'center', className:"taskTableColumns", width: '6%', render: (text, item, index) => index + 1 },
{ 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: '28%', ellipsis: true, render: (text, item) => <Tooltip title={text} placement="topLeft"><span onClick={()=>{window.location.href=item.taskUrl}}>{text}</span></Tooltip> },
{ title: '项目名称', dataIndex: 'projectName', className:"taskTableColumns", width: '28%', ellipsis: true, render: (text) => <Tooltip title={text} placement="topLeft">{text}</Tooltip> },
{ title: '课题奖金', dataIndex: 'taskReward', className:"taskTableColumns", width: `${isStudentApplyDate || studentApplyEnd ? '15%' : ''}`, render: (text) => <span> {text}</span> },
@ -54,6 +55,17 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
return <ProjectDetail detail={null} projectId={record.regId} applyTaskId={applyTaskId} current_user={current_user} showLoginDialog={showLoginDialog} isStudentApplyDate={isStudentApplyDate} studentApplyEnd={studentApplyEnd}/>
}
//
function onExpand(expanded, record){
const keys = new Set(expandedRowKeys);
if(expanded){
keys.add(record.id);
}else{
keys.delete(record.id);
}
setExpandedRowKeys(Array.from(keys));
}
//
function applyTask(id){
//
@ -88,6 +100,7 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
// pagesize
function onShowSizeChange(current, pageSize){
setCurrent(1);
setPageSize(pageSize);
}
@ -104,6 +117,7 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
}
useEffect(() => {
setExpandedRowKeys([]);
setLoading(true);
const params = {
curPage: current,
@ -128,7 +142,7 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
return (
<div className="taskList listBox">
<div className="list">
<div className='search'><Search placeholder='请输入课题名称进行搜索' allowClear enterButton onSearch={(value) => { setKeyword(value) }} /></div>
<div className='search'><Search placeholder='请输入课题名称进行搜索' allowClear enterButton onSearch={(value) => { setCurrent(1); setKeyword(value) }} /></div>
<Table
loading={loading}
columns={columns}
@ -137,7 +151,10 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
expandIconColumnIndex={4}
expandIconAsCell={false}
expandIcon={customExpandIcon}
pagination={{pageSize: pageSize, total: total, showSizeChanger: true, onShowSizeChange:onShowSizeChange, showQuickJumper: true, onChange: changePage}}
rowKey={'id'}
expandedRowKeys={expandedRowKeys}
onExpand={onExpand}
pagination={{current: current, pageSize: pageSize, total: total, showSizeChanger: true, onShowSizeChange:onShowSizeChange, showQuickJumper: true, onChange: changePage}}
/>
</div>
<Modal

View File

@ -20,8 +20,9 @@
font-size: 15px;
color: #353f5e;
}
.taskTableColumns.taskName a{
.ant-table-tbody .taskTableColumns.taskName span{
color: #2545c9;
cursor: pointer;
}
.ant-table-thead > tr > .taskTableColumns, .ant-table-tbody > tr > .taskTableColumns{
background-color:#F1F6FF;

View File

@ -9,7 +9,6 @@ import banner from "../img/banner.png";
import studentSvg from "../img/student.png";
import './index.scss';
import { Link } from 'react-router-dom';
import { color } from 'echarts/lib/theme/light';
const Option = Select.Option;
const gradeList = [
@ -22,17 +21,19 @@ const gradeList = [
{ id: '研二', name: '研二' },
{ id: '研三', name: '研三' }];
function Apply(props) {
const { form, current_user, showNotification, isGlccApplyDate, match } = props;
const { form, current_user, showNotification, match } = props;
const taskId = Number(match.params.taskId);
//
// current_user && (current_user.user_id = 6)
// current_user && (current_user.userName = "使")
const isStudentApplyDate = new Date().getTime() > new Date('2022-05-26').getTime() && new Date().getTime() < new Date('2022-06-26').getTime();
const { getFieldDecorator, validateFields, setFieldsValue, validateFieldsAndScroll } = form;
const [imageUrl, setImageUrl] = useState(undefined);
const [loading, setLoading] = useState(false);
const [reload, setReload] = useState();
const [userApplyInfo, setUserApplyInfo] = useState(undefined);
const [editable, setEditable] = useState(true);
const [editable, setEditable] = useState(isStudentApplyDate);
const [files, setFiles] = useState([]);
const [files1, setFiles1] = useState([]);
const initTask = {
@ -43,20 +44,25 @@ function Apply(props) {
const [myTaskList, setMyTaskList] = useState([]);
const [allTaskList, setAllTaskList] = useState([]);
//
//
useEffect(() => {
//
// setTimeout(()=>{
setTimeout(()=>{
let clientWidth = document.body.clientWidth;
let scrollHeight = 500 * clientWidth / 1920;
window.scrollTo(0, scrollHeight);
});
// window.scrollTo(0, 50);
if (!isGlccApplyDate) {
if (new Date().getTime() < new Date('2022-05-26').getTime()) {
//
window.location.href = "/glcc";
window.location.href = "/glcc/student/2";
} else if (current_user && current_user.login) {
} else {
window.location.href = "/login?go_page=/glcc";
window.location.href = `/login?go_page=/glcc/student/apply/${taskId}`;
}
}, [])
@ -255,12 +261,11 @@ function Apply(props) {
//
function bookChange(info, i) {
if (info.file.status === 'uploading' || info.file.status === "done" || info.file.status === 'removed') {
setLoading(true);
// setLoading(true);
if (info.file.status === "done") {
changeTaskItem('memoAttachmentId', info.fileList[0].response && info.fileList[0].response.data.id, i)
}
if (info.file.status === 'removed') {
console.log(1111)
changeTaskItem('memoAttachmentId', '', i);
}
console.log(info.fileList);
@ -271,9 +276,9 @@ function Apply(props) {
}
}
if (info.file.status === "done" || info.file.status === 'removed') {
setLoading(false);
}
// if (info.file.status === "done" || info.file.status === 'removed') {
// setLoading(false);
// }
}
//
@ -342,7 +347,7 @@ function Apply(props) {
<div className='apply'>
<Breadcrumb className='glcc_breadcrumb font-16'>
<Breadcrumb.Item><Link to="/glcc">开源夏令营</Link></Breadcrumb.Item>
<Breadcrumb.Item><Link to="/glcc/student/2">查看项目</Link></Breadcrumb.Item>
<Breadcrumb.Item><Link to="/glcc/student/2">课题及项目列表</Link></Breadcrumb.Item>
<Breadcrumb.Item style={{ color: '#202D40' }}>学生报名</Breadcrumb.Item>
</Breadcrumb>
@ -385,7 +390,7 @@ function Apply(props) {
{getFieldDecorator("location", {
rules: []
})(
<Cascader popupClassName="glcc_cascader" placeholder="请选择省份城市" options={locData} className={editable ? "" : "disabledInput"} disabled={editable ? false : true} />
<Cascader expandTrigger="hover" popupClassName="glcc_cascader" placeholder="请选择省份城市" options={locData} className={editable ? "" : "disabledInput"} disabled={editable ? false : true} />
)}
</Form.Item>
{helper('所在年级',
@ -401,7 +406,7 @@ function Apply(props) {
'phone',
[{ required: true, message: "请正确输入联系电话" },
{ max: 14, message: '超出限制长度14位字符请重新编辑' },
{ pattern: /^(^(\d{3,4}-)?\d{7,8})$|(13[0-9]{9})$/, message: '请正确输入联系电话' }],
{ pattern: /(^(\d{3,4}-)?\d{7,8})$|([1][3,4,5,6,7,8,9][0-9]{9})/, message: '请正确输入联系电话' }],
<Input placeholder="请输入联系电话" onBlur={() => { verify("phone") }} className={editable ? "" : "disabledInput"} disabled={editable ? false : true} />
)}
{helper('邮箱地址',
@ -419,28 +424,28 @@ function Apply(props) {
'请以图片的形式上传学生证明大小不超过5M格式为png、jpg、jpeg',
'proveAttachmentId',
[{ required: true, message: "请正确上传学生证明" }],
userApplyInfo && userApplyInfo.proveAttachmentId ? <div className='projectLogo'><img src={`${getUrl()}/api/attachments/${userApplyInfo.proveAttachmentId}`} 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>
<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' }} /> : userApplyInfo && userApplyInfo.proveAttachmentId ?
<div><img src={`${getUrl()}/api/attachments/${userApplyInfo.proveAttachmentId}`} alt='' /></div> : <div>
<i className='iconfont icon-tianjiadaohang font-30'></i>
<div className="ant-upload-text font-13">请上传学生证明</div>
</div>}
</Upload>
</Upload>
)}</div>
{
myTaskList.map((item, i) => {
return (
<Fragment key={item.taskId + '' + i}>
<h4 className="item-tit">课题信息<span className="item-tit-num">{i + 1}</span>/2) {myTaskList.length > 1 && <span className="delete"><i className="iconfont icon-shanchu mr5" onClick={() => { deleteTask(i) }}></i>删除</span>}</h4>
<h4 className="item-tit">课题信息<span className="item-tit-num">{i + 1}</span>/2) {myTaskList.length > 1 && <span className="delete" onClick={() => { deleteTask(i) }}><i className="iconfont icon-shanchu mr5"></i>删除</span>}</h4>
{helper('课题名称',
'',
'taskId' + i,
@ -458,7 +463,7 @@ function Apply(props) {
</Select>
)}
<div className='introArea'>{helper('自荐书',
<div className="memoExtra">自荐书示例<span >https://forum.gitlink.org.cn/forums/7299/detail</span></div>,
<div className="memoExtra">自荐书示例<a href="https://forum.gitlink.org.cn/forums/7299/detail" target="_black">https://forum.gitlink.org.cn/forums/7299/detail</a></div>,
'memo' + i,
[{ required: true, message: "请正确输入自荐书" },
{ max: 500, message: '超出限制长度500位字符请重新编辑' }],

View File

@ -293,7 +293,7 @@
.memoExtra {
margin-top: 12px;
margin-bottom: -10px;
span {
a {
color: #466aff;
}
}
@ -312,4 +312,26 @@
border: 1px solid #fff;
border-radius: 4px;
box-shadow: 0px 0px 12px rgba(203, 220, 255, 0.47);
.ant-select-dropdown-menu-item{
&:hover{
background-color: #e9efff;
}
}
}
.glcc_cascader{
.ant-cascader-menu{
width: 240px;
&::-webkit-scrollbar-track{
background-color: #E2E9FF;
}
&::-webkit-scrollbar-thumb{
background-color: #BCCCFF;
}
}
.ant-cascader-menu:first-child{
width: 250px;
}
}