Merge branch 'cs_news' of http://106.75.45.236:3000/Gitlink/forgeplus-react into feature_news

This commit is contained in:
谢思 2023-06-30 16:47:19 +08:00
commit 6df8caaf21
31 changed files with 1254 additions and 227 deletions

View File

@ -3962,36 +3962,37 @@ html>body #ajax-indicator {
color: #FF6832;
border:1px solid #FF6832;
}
.head-nav::-webkit-scrollbar {
display: none;
}
.head-nav {
text-align: center;
height: 58px;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
.head-nav ul#header-nav{
overflow: hidden;
white-space: nowrap;
overflow-x: auto;
overflow-y: auto;
display: flex;
align-self: flex-start;
}
.head-nav ul#header-nav li{
.head-nav li{
height: 58px;
line-height: 58px;
cursor: pointer;
font-size: 16px;
padding-right:40px;
}
.head-nav ul#header-nav a {
.head-nav a {
color: #fff;
margin: 0 20px;
}
.head-nav ul#header-nav li a:hover,.head-nav ul#header-nav li.active a {
.head-nav li a:hover,.head-nav li.active a {
color: #5091FF;
}

File diff suppressed because one or more lines are too long

View File

@ -333,7 +333,7 @@ class App extends Component {
<MuiThemeProvider theme={theme}>
<LoginDialog {...this.props} {...this.state} Modifyloginvalue={() => this.Modifyloginvalue()}></LoginDialog>
{/* <GlccModal /> */}
{!pathName || (pathName && pathName.toLowerCase().indexOf("glcc") === -1) ? <SiderBar {...this.props}/> : <SiderBarHelp/>}
{!pathName || (pathName && pathName.toLowerCase() !== 'glcc') ? <SiderBar {...this.props}/> : <SiderBarHelp/>}
{/* <Router> */}
<Switch>
{/* wiki预览 */}

View File

@ -45,6 +45,8 @@ class NewHeader extends Component {
visiblemyss: false,
openSearch:false,
visible:false, //浮动消息框展示控制
showSubMenu: false,
zoneList: [], // 专区列表
}
}
componentDidMount() {
@ -57,6 +59,8 @@ class NewHeader extends Component {
}
window._header_componentHandler = this;
this.getZoneList(settings && settings.common.zone +'/api')
try {
window.sessionStorage.setItem("yslgeturls", JSON.stringify(window.location.href))
} catch (e) {}
@ -191,6 +195,24 @@ class NewHeader extends Component {
});
}
getZoneList = (httpUrl) =>{
const url = `${httpUrl}/zone/open/list`
axios.get(url).then((response) => {
if (response && response.data && response.data.data && response.data.data.length > 0) {
let newArray = [];
response.data.data.forEach((e, i) => {
newArray[i] = {
name: e.name,
link: `/zone/${e.key}`
}
});
this.setState({ zoneList: newArray })
} else {
}
}).catch((error) => {
});
}
matchpaths = (url) => {
const { match } = this.props;
const isDev = window.location.port == 3007;
@ -207,6 +229,10 @@ class NewHeader extends Component {
return false
}
}
matchZone = () => {
return window.location.href.includes('/zone/')
}
checkProfile=(url)=>{
const { showCompeleteDialog , completeProfile } = this.props;
@ -273,6 +299,8 @@ class NewHeader extends Component {
user,
isRender,
visible,
showSubMenu,
zoneList
} = this.state;
let search_url = settings && settings.common && settings.common.search;
return (
@ -301,16 +329,16 @@ class NewHeader extends Component {
</div>
{
settings && settings.nav_logo_url ?
<a href={settings && settings.new_course.default_url} className={"fl mr50"}>
<a href={settings && settings.new_course.default_url} className={"fl mr30"}>
<img alt="可控开源社区" className="logoimg" src={getImageUrl(`/${settings.nav_logo_url}`)}></img>
</a>
:
""
}
<div className="head-nav pr" id={"head-navpre1"}>
{/* <div className="head-nav pr"> */}
{
settings && settings.navbar && settings.navbar.length > 0 ?
<ul id="header-nav">
<ul id="header-nav" className="head-nav pr">
{
settings.navbar && settings.navbar.map((item, key) => {
var new_link = item.link;
@ -318,16 +346,37 @@ class NewHeader extends Component {
var waiLian = (new_link && str.filter(item=>new_link.indexOf(item)>-1) );
var wl = waiLian && waiLian.length>0;
return (
<li key={key} className={`${this.matchpaths(new_link) === true ? 'pr active' : 'pr'}`} style={{display:!is_hidden ? 'flex' : 'none'} }>
<li key={key}
className={`${this.matchpaths(new_link) === true ? 'pr active' : 'pr'}`}
style={{display:!is_hidden ? 'flex' : 'none'} }
>
<a href={new_link} target={wl ? "_self":"_blank"}>{item.name}</a>
</li>
)
})
}
{
// 特色专区下拉菜单
zoneList && zoneList.length > 0 &&
<li
className={`${this.matchZone() === true ? 'active drop-li' : 'drop-li'}`}
onMouseOver={ () => { this.setState( {showSubMenu: true }) } }
onMouseOut={ () => { this.setState( {showSubMenu: false }) } }
>
<a onClick={ () => { this.setState( {showSubMenu: true }) } }>特色专区</a>
<ul className={ `drop-down ${ showSubMenu ? 'drop-down-show' : '' }` } style={{ height : showSubMenu ? `${ zoneList.length * 46}px` : 0 }}>
{
zoneList.map((e, k) => {
return <li className="drop-down-item" key={ k }><a href={ e.link } className="task-hide" title={ e.name } target="_blank">{ e.name }</a></li>
})
}
</ul>
</li>
}
</ul>
: ""
}
</div>
{/* </div> */}
<div className="head-right">
{ search_url && <HeadSearch {...this.props}/>}
{

View File

@ -363,4 +363,48 @@
color: #FFFFFF!important;
background-color: #355CFF;
}
}
}
.head-nav {
.pr {
justify-content: center;
}
.drop-li {
display: flex;
flex-direction: column;
align-items: center;
.drop-down {
position: fixed;
top: 58px;
background-color: #ffffff;
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
transition: height 0.2s ease-in-out;
overflow: hidden;
box-shadow:0px 0px 6px rgba(6, 44, 107, 0.15);
.drop-down-item {
height: 46px !important;
line-height: 46px !important;
padding-right:unset;
position: relative;
a {
color: #252b3a !important;
display: inline-block;
height: 100%;
max-width: 160px;
}
&:hover {
background-color: #ebf0ff;
}
// &:not(:last-child) {
// border-bottom: solid 1px #cccccc42;
// }
}
}
}
}
@media screen and (max-width: 1200px){
.drop-down{
right: 200px;
}
}

View File

@ -0,0 +1,46 @@
import React from 'react';
import Slider from 'react-slick';
import { getImageUrl } from 'educoder';
import Left from '../../../home/Img/left.png';
import Right from '../../../home/Img/right.png';
import banner from '../img/mainbanner.png'
let setting={
dots:true,
infinite: true,
speed: 2000,
slidesToShow: 1,
slidesToScroll: 1,
pauseOnDotsHover:true,
autoplaySpeed:5000,
pauseOnFocus:true,
autoplay:true,
arrows:true,
prevArrow: <img className='slick-prev slick-arrow' src={Left} width="70px" alt=""/>,
nextArrow: <img className='slick-prev slick-arrow' src={Right} width="70px" alt=""/>
}
function TopEdition(props) {
const { bannerList } = props
return(
<Slider {...setting}>
{
bannerList && bannerList.length > 0 ?
bannerList.map((i,k)=>{
return(
<div className={`regform`} key={ k }>
<div style={{backgroundImage:`url(${i})`}}></div>
</div>
)
})
:
<div className={`regform`} style={{backgroundImage:`url(${banner})`}}>
</div>
}
</Slider>
)
}
export default TopEdition;

View File

@ -36,7 +36,7 @@ function Contributor(props) {
{
showList.map((i,k)=>{
return(
<div className="container">
<div className="container" key={ k }>
{ i.name &&
<div className="c_item">
<Link to={`/${i.login}`}><img src={i.imageUrl} alt="" /></Link>

View File

@ -16,70 +16,46 @@ const settings = {
};
function Partner(props) {
const [ topics ,setTopics ] = useState(undefined);
const [ moreTypes ,setMoreTypes ] = useState(false);
const { id, partnerList } = props;
useEffect(()=>{
getUnit(partnerList);
},[id])
function getUnit(array){
const newArray = [];
for(let i = 0; i< array.length;) {
newArray.push(array.slice(i, i += 5));
const newArray = array
setMoreTypes(array.length > 0)
while(newArray[1] && newArray[1].length + newArray[0].length <= 5) {
newArray[0] = [...newArray[0], ...newArray.splice(1, 1)[0]]
}
setTopics(newArray)
}
function Init() {
let box = document.getElementById('scrollBox1');
scrollUp();
var myTimer = setInterval(scrollUp, 10);
// container
box.onmouseover = () => {
clearInterval(myTimer);
}
// container
// 6060
box.onmouseout = () => {
myTimer = setInterval(scrollUp, 10);
}
}
function scrollUp() {
let box = document.getElementById('scrollBox1');
if(box){
let con1 = document.getElementById('box1');
if (box.scrollLeft >= con1.clientWidth) {
box.scrollLeft = 0;
} else {
box.scrollLeft++;
}
}
}
return(
<div id={"scrollBox1"}>
<ul className="boxmain zone_part_lists">
{
topics && topics.length>0 ?
<Slider {...settings} className="unitMainSlider">
{
topics.map((i, k)=>{
return(
<div key={ k } className="slickMainline">
{
i.map((j,k1)=>{
return(
topics.map((i, k)=>{
return(
<li key={ k }>
{
i.map((j,k1)=>{
return(
<div className="zone_part_item" key={ k1 }>
{ j.typeName && moreTypes && <span className="task-hide">{j.typeName}</span>}
<a key={ k1 } href={j.link} target="_blank"><img src={j.logo} alt=""/></a>
)
})
}
</div>
)
})
}
</Slider>
:""
</div>
)
})
}
</li>
)
})
:
""
}
</div>
</ul>
)
}
export default Partner;

View File

@ -49,7 +49,7 @@ function Projects(props) {
(projectList.length < 3 ?
projectList.map((i,k)=>{
return(
<div className="container">
<div className="container" key={ k }>
<div className="zone_p_item">
{i.projectProperties && i.projectProperties.authorImageUrl && <img className="info_img" src={i.projectProperties.authorImageUrl} alt="" /> }
<p className="z_p_title task-hide" onClick={()=>window.open(i.projectURL)}>{i.projectProperties && i.projectProperties.name}</p>
@ -63,7 +63,7 @@ function Projects(props) {
{
projectList.map((i,k)=>{
return(
<div className="container">
<div className="container" key={ k }>
<div className="zone_p_item">
{i.projectProperties && i.projectProperties.authorImageUrl && <img className="info_img" src={i.projectProperties.authorImageUrl} alt="" /> }
<p className="z_p_title task-hide" onClick={()=>window.open(i.projectURL)}>{i.projectProperties && i.projectProperties.name}</p>

View File

@ -3,6 +3,7 @@ import { Menu } from 'antd';
import banner from '../img/mainbanner.png'
import { Link } from 'react-router-dom';
import { tempConfig } from '../tempInfo';
import TopEdition from './TopEdition'
@ -34,10 +35,11 @@ function PublicBanner(props){
},[pathname])
return(
<div className="in_banner" style={{backgroundImage:`url(${(data && data.bannerList && data.bannerList.split(",")[0]) || banner})`}}>
<div className="in_banner">
<TopEdition bannerList={ data && data.bannerList && data.bannerList.split(",") }></TopEdition>
{
data &&
<div>
<div className="zone_content">
<p className="main_t">{data.mainTitle}</p>
<p className="sub_t">{data.subTitle}</p>
</div>

View File

@ -53,7 +53,18 @@ function HeaderPage(props){
const url = `${httpUrl}/zone/open/${id}/partners/list`;
axios.get(url).then(result=>{
if(result){
setParterList(result.data.rows);
const array = result.data.rows;
const newArray = [];
for(let i in array) {
let e = array[i]
if (e.zonePartnersList && e.zonePartnersList.length > 0) {
e.zonePartnersList[0].typeName = e.typeName;
}
if ( e.zonePartnersList.length > 0 ) {
newArray.push(e.zonePartnersList);
}
}
setParterList(newArray);
}
}).catch(error=>{})
}

View File

@ -29,13 +29,13 @@ function HeaderPage(props){
const [ newsList, setNewsList ] = useState(undefined);
const [ partnerList, setParterList ] = useState(undefined);
const { deptId } = props.match.params;
const { data, id, temp } = props;
const { data, id, temp, history } = props;
const vision = [
{imageUrl: vision0, title: '促进技术创新和应用', content: '通过开源硬件社区的建设,可以让更多的人参与到硬件开发中来,激发大众的创造力和创新精神,从而推动硬件领域的技术创新和实际应用。'},
{imageUrl: vision1, title: '降低硬件开发成本', content: '通过共享开源硬件设计和资源,可以帮助个人和小型企业降低硬件开发的成本,打破品牌垄断,促进市场竞争。'},
{imageUrl: vision2, title: '推广教育和普及知识', content: '通过开源硬件社区的建设,可以提供更多的硬件开发教育和知识普及资源,为学生、教师和爱好者等不同群体提供更多的学习机会和平台。'},
{imageUrl: vision3, title: '加强国际合作和交流', content: '开源硬件社区可以促进国内外的交流和合作,扩大中国在全球开源硬件领域的影响力,推动中外企业和机构之间的技术合作和交流。'}
{imageUrl: vision0, title: '促进技术创新和应用', content: '通过开源芯片社区的建设,可以让更多的人参与到硬件开发中来,激发大众的创造力和创新精神,从而推动硬件领域的技术创新和实际应用。'},
{imageUrl: vision1, title: '降低硬件开发成本', content: '通过共享开源芯片设计和资源,可以帮助个人和小型企业降低硬件开发的成本,打破品牌垄断,促进市场竞争。'},
{imageUrl: vision2, title: '推广教育和普及知识', content: '通过开源芯片社区的建设,可以提供更多的硬件开发教育和知识普及资源,为学生、教师和爱好者等不同群体提供更多的学习机会和平台。'},
{imageUrl: vision3, title: '加强国际合作和交流', content: '开源芯片社区可以促进国内外的交流和合作,扩大中国在全球开源芯片领域的影响力,推动中外企业和机构之间的技术合作和交流。'}
]
const communityInfo = [
@ -106,7 +106,18 @@ function HeaderPage(props){
const url = `${httpUrl}/zone/open/${id}/partners/list`;
axios.get(url).then(result=>{
if(result){
setParterList(result.data.rows);
const array = result.data.rows;
const newArray = [];
for(let i in array) {
let e = array[i]
if (e.zonePartnersList && e.zonePartnersList.length > 0) {
e.zonePartnersList[0].typeName = e.typeName;
}
if ( e.zonePartnersList.length > 0 ) {
newArray.push(e.zonePartnersList);
}
}
setParterList(newArray);
}
}).catch(error=>{})
}
@ -132,7 +143,7 @@ function HeaderPage(props){
{
vision.map((i, k) => {
return (
<div className="vision_item">
<div className="vision_item" key={ k }>
<div className="vision_icon">
<img src={i.imageUrl} alt="" />
</div>
@ -169,8 +180,8 @@ function HeaderPage(props){
newsList.map((i,k)=>{
return(
k > 0 &&
<Link to={`/zone/${deptId}/newdetail/${i.id}`}>
<li className="new_item">
<div onClick={() => { history.push(`/zone/${deptId}/newdetail/${i.id}`) }}>
<li className="new_item" style={{ display: 'inline-block' }}>
<p className="task-hide">
<span className="item_index">{k + 1}</span>
<Link className="zone_n_title" to={`/zone/${deptId}/newdetail/${i.id}`}>{i.name}</Link>
@ -184,7 +195,7 @@ function HeaderPage(props){
<span className="flexCenter zone_btn">查看详情<img src={guideArrow} alt="" width="14px"/></span>
</p>
</li>
</Link>
</div>
)
})
}
@ -214,9 +225,9 @@ function HeaderPage(props){
<p className="sub_title mb50"><img src={ra} alt="" className="mr5" />成为社区成员尽情发挥您的创意</p>
<div className="c_role boxmain">
{
communityInfo.map(i => {
communityInfo.map((i, k) => {
return (
<div className="c_role_item">
<div className="c_role_item" key={ k }>
<p className="role_level">{ i.level }</p>
<p className="role_todo">{ i.todo }</p>
<div className="dot"></div>
@ -237,7 +248,7 @@ function HeaderPage(props){
{
growPathInfo.map((i, k) => {
return (
<div className="grow_path_item">
<div className="grow_path_item" key={ k }>
{ k % 2 === 1 && <div className="dot"></div> }
<div className="grow_path_type">
<div></div>
@ -256,9 +267,9 @@ function HeaderPage(props){
<div className="line"></div>
<div className="grow_introduction boxmain pt40">
{
introDetail.map(i => {
introDetail.map((i, k) => {
return (
<div className="intro_item">
<div className="intro_item" key={ k }>
<p className="intro_title">
<img src={i.icon} alt="" className="mr3" />
{ i.title }

View File

@ -1,5 +1,5 @@
import React,{ useState , useEffect } from 'react';
import { Breadcrumb , Divider } from 'antd';
import { Breadcrumb , Divider, Spin } from 'antd';
import liulan from '../img/liulan.png';
import RenderHtml from '../../../components/render-html';
import { Base64 } from 'js-base64';
@ -12,6 +12,7 @@ function NewsDetail(props){
const [ detail , setDetail ] = useState(undefined);
const [ cmsDir , setCmsDir ] = useState(undefined);
const [ content , setContent]=useState(undefined);
const [ isSpin , setIsSpin]=useState(false);
const temp = props.temp
useEffect(()=>{
@ -22,44 +23,48 @@ function NewsDetail(props){
},[id])
function getDetails(){
setIsSpin(true)
getNewsDetail(id).then(result=>{
if(result){
let data = result.data.data;
setDetail(data);
setCmsDir(data.cmsDir);
setContent(Base64.decode(data.content));
setIsSpin(false)
}
}).catch(error=>{})
}
return(
<div className="detail_news_all">
{
detail &&
<div style={{width:'1200px',margin:"0px auto",padding:"30px 0px"}}>
<Breadcrumb separator=">">
<Breadcrumb.Item href={`/zone/${deptId}/news`}>{tempConfig[temp].mainTitle}</Breadcrumb.Item>
{ cmsDir && <Breadcrumb.Item href={`/zone/${deptId}/news/${cmsDir.id}`}>{cmsDir.name}</Breadcrumb.Item> }
<Breadcrumb.Item>正文</Breadcrumb.Item>
</Breadcrumb>
<div className="info_text">
<div className="info_text_main">
<p className="i_name">{detail.name}</p>
<ul className="i_ul_value">
{ cmsDir && <li>{cmsDir.name}</li> }
{ cmsDir && <li>发布于{detail.publishTime}</li> }
{ detail.visits && <li><img src={liulan} alt="" className="mr5" />{detail.visits}</li> }
</ul>
<Spin spinning={isSpin} size="large">
{
detail &&
<div style={{width:'1200px',margin:"0px auto",padding:"30px 0px"}}>
<Breadcrumb separator=">">
<Breadcrumb.Item href={`/zone/${deptId}/news`}>{tempConfig[temp].mainTitle}</Breadcrumb.Item>
{ cmsDir && <Breadcrumb.Item href={`/zone/${deptId}/news/${cmsDir.id}`}>{cmsDir.name}</Breadcrumb.Item> }
<Breadcrumb.Item>正文</Breadcrumb.Item>
</Breadcrumb>
<div className="info_text">
<div className="info_text_main">
<p className="i_name">{detail.name}</p>
<ul className="i_ul_value">
{ cmsDir && <li><a href={ detail.publishUserUrl } ><img src={ detail.publishUserImage } alt="" className="headimg" /> { detail.publishUserNickname }</a></li> }
{ cmsDir && <li>发布于{detail.publishTime}</li> }
{ detail.visits && <li><img src={liulan} alt="" className="mr5" />{detail.visits}</li> }
</ul>
</div>
<Divider dashed={true} />
{
content ?
<RenderHtml className="informations_detail imageLayerParent" value={content} url={props.history.location} />
:
<span>暂无详情~</span>
}
</div>
<Divider dashed={true} />
{
content ?
<RenderHtml className="informations_detail imageLayerParent" value={content} url={props.history.location} />
:
<span>暂无详情~</span>
}
</div>
</div>
}
}
</Spin>
</div>
)
}

View File

@ -28,13 +28,17 @@
height: 450px;
position: relative;
padding-bottom: 88px;
&>div{
.zone_content {
position: absolute;
display: flex;
width: 1200px;
margin: 0px auto;
flex-direction: column;
justify-content: center;
height: 100%;
top: 0;
left: 50%;
transform: translate(-50%, 0);
padding-bottom: 88px;
.main_t{
color:#78d0f5;
font-size:40px;
@ -414,6 +418,14 @@
justify-content: center;
}
.detail_news_all{
display: flex;
flex-direction: column;
align-items: center;
min-height: 600px;
justify-content: unset;
.ant-spin-spinning {
margin: auto;
}
.detail_banners{
background-image: url(./img/subbanner.png);
background-size: 100% 100%;
@ -458,6 +470,20 @@
height: 20px;
line-height: 20px;
margin-right: 25px;
a {
display: flex;
align-items: center;
height: 20px;
overflow: visible;
color: #466aff;
}
.headimg {
width: 26px;
height: 26px;
margin-right: 4px;
border-radius: 50%;
vertical-align: middle;
}
}
}
}
@ -867,37 +893,6 @@
}
}
}
.zone_parter{
background-color: #fff;
padding:70px 0px 90px;
.zone_part_lists{
display: flex;
flex-wrap: wrap;
margin-top: 70px;
li{
width: 170px;
height: 70px;
line-height: 70px;
margin-left: 36px;
margin-bottom: 30px!important;
color:#1f2329;
font-size:20px;
text-align: center;
background-color:#ffffff;
border-radius:8px;
box-shadow:0px 0px 15px rgba(28, 48, 175, 0.08);
&:first-child,&:nth-child(12){
margin-left: 0px;
}
&:nth-child(7){
margin-left: 103px;
}
&:nth-child(11){
margin-right: 103px;
}
}
}
}
}
.zone_VIP_box{
padding:50px 0px;
@ -1053,45 +1048,51 @@
.zone_parter{
background-color: #fff;
padding:70px 0px 90px;
#scrollBox1{
max-height: 332px;
overflow: hidden;
margin: 35px 0px 0px;
width: 100%;
.unitMainSlider{
width: 1200px;
margin:0px auto;
.slick-list{
height: 140px;
width: 100%;
overflow: hidden;
.slickMainline{
display: flex!important;
padding:10px 2px;
align-items: center;
justify-content: center;
a{
background: #FFFFFF;
box-shadow: 0px 1px 8px 1px rgba(0, 0, 0, 0.06);
border-radius: 4px;
border: 1px solid #FFFFFF;
margin-right: 20px;
padding:20px;
height: 120px;
width: 220px;
display: flex;
align-items: center;
justify-content: center;
&:hover{
border: 1px solid #8FCEFF;
}
img{
max-width: 100%;
max-height: 100%;
}
&:last-child{
margin-right: 0px;
}
.zone_part_lists{
display: flex;
flex-direction: column;
margin-top: 70px;
li {
display: flex;
justify-content: flex-start;
align-items: flex-end;
flex-wrap: wrap;
.zone_part_item {
color:#1f2329;
font-size:20px;
line-height:28px;
display: flex;
flex-direction: column;
align-items: flex-start;
span {
display: inline-block;
width: 200px;
}
a {
display: inline-block;
width: 220px;
height: 88px;
line-height: 88px;
margin-right: 20px;
margin-top: 20px;
margin-bottom: 30px!important;
color:#1f2329;
font-size:20px;
text-align: center;
background-color:#ffffff;
border-radius:8px;
box-shadow:0px 0px 15px rgba(28, 48, 175, 0.08);
transition: 0.1s linear;
img{
max-height: 66px;
}
&:hover {
transform: translate(0, -5px);
}
}
&:nth-child(n + 6) {
a {
margin-top: 0px;
}
}
}
@ -1113,6 +1114,108 @@
}
}
}
.in_banner{
position: relative;
.slick-track{
height: 450px;
display: flex;
.slick-slide{
position: relative;
height:100%;
div{
height: 100%;
.regform{
&>div{
overflow: hidden;
height: 100%;
width: 100vw;
position: relative;
background-repeat: no-repeat;
background-size: 100% 100%;
}
}
}
}
}
.slick-slider{
min-width: 100vw;
position: relative;
&:hover{
.slick-arrow{
display: block!important;
cursor: pointer;
z-index: 2;
}
}
.slick-arrow{
width: 50px;
height: 50px;
position: absolute;
z-index: 1000;
display: none!important;
&:hover{
i{
color: rgba(225,225,225,0.8);
}
}
i{
font-size: 50px!important;
color: rgba(225,225,225,0.3);
transition: 0.3s;
}
&.slick-prev{
left: 50px;
}
&.slick-next{
right: 50px;
}
}
.slick-dots{
width: 1200px;
text-align: left;
left: 50%;
margin-left: -600px;
bottom: 25%;
position: absolute;
display: flex!important;
z-index: 2;
li{
background-color: rgba(225,225,225,0.5);
position: relative;
height: 3px;
width: 46px;
margin-right: 15px;
&::after{
position: absolute;
left: 0px;
width: 0px;
top:0px;
height: 100%;
content: "";
transition: 5.2s;
transition-property: width;
}
&.slick-active::after{
background-color: #fff;
width: 100%;
}
button{
position: absolute;
width: 100%;
height: 10px;
left:0px;
background-color: transparent!important;
border:none;
cursor: pointer;
color: transparent;
&::before {
content: "";
}
}
}
}
}
}
.informations_detail.markdown-body{
&>p{
line-height: 32px;

View File

@ -97,7 +97,7 @@ class Index extends Component {
owner = owner.filter(item=>item.id === user_id);
}
this.props.form.setFieldsValue({
user_id:owner && owner[0].name
user_id:owner && owner[0].id
})
owner && this.setState({
owners_id:owner[0].id,

View File

@ -45,8 +45,7 @@ export function studentApplyEdit(data) {
});
}
// 获取当前学生用户报名信息
// 课题列表
// 项目列表
export function projectList(params) {
return fetch({
url: `/api/applyInformation/list`,
@ -55,6 +54,15 @@ export function projectList(params) {
});
}
// 0元项目列表
export function freeProjectList(params) {
return fetch({
url: `/api/applyInformation/projectListFor0`,
method: 'get',
params
});
}
// 课题列表
export function taskList(params) {
return fetch({
@ -64,6 +72,15 @@ export function taskList(params) {
});
}
// 0元课题列表
export function freeTaskList(params) {
return fetch({
url: `/api/applyInformation/taskListFor0`,
method: 'get',
params
});
}
// 项目id查询项目详情
export function getProjectById(id, params) {
return fetch({

View File

@ -75,7 +75,7 @@ function Apply(props) {
<div className={`explain`}>
<p className='font-15 c000'>申请说明</p>
<div>1项目报名时间为<span className='c000'>4月29日5月30日</span>请在报名截止时间北京时间<span className='c000'>2023年5月30日24点</span>前提交报名信息</div>
<div>2本次GLCC夏令营建议使用GitLink为代码托管平台学生基于GitLink上项目完成编程任务同时也欢迎使用其他代码托管平台的项目参与活动目前GLCC只对夏令营期间使用GitLink托管的项目提供部分金支持</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><span className='c000'>5奖金默认由项目方支持请根据课题难度设定金额若您可能无法支撑本课题奖金GLCC组委会将进行资助评审择优资助如未获得资助将下线该课题</span></div>

View File

@ -2,8 +2,6 @@ import React, { useEffect, useState } from 'react';
import { Input, Table, Tooltip } from 'antd';
import { getPassList, hasAuditRole } from '../api';
import ProjectDetail from '../project/component/projectDetail';
// banner
import resultBanner from "../img/resultBanner.png";
// banner
import resultBanner2 from "../img/resultBanner2.png";
import bgPng from "../img/bgPng.png";
@ -12,7 +10,7 @@ import '../project/index.scss';
const { Search } = Input;
//
function CheckResult({current_user, history}) {
function CheckResult({current_user, history, round}) {
//
const [keyword, setKeyword] = useState(undefined);
const [data, setData] = useState([]);
@ -22,7 +20,6 @@ function CheckResult({current_user, history}) {
const [pageSize, setPageSize] = useState(20);
const [loading, setLoading] = useState(false);
const [expandedRowKeys, setExpandedRowKeys] = useState([]);
const time = new Date().getTime() > new Date('2022/06/28 1:0').getTime() && new Date().getTime() < new Date('2022/07/01 0:0').getTime();
useEffect(()=>{
//
@ -44,6 +41,7 @@ function CheckResult({current_user, history}) {
curPage: current,
keyword,
pageSize,
round
}
getPassList(params).then(response => {
if (response && response.message === "success") {
@ -58,9 +56,9 @@ function CheckResult({current_user, history}) {
{ 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: 'school', className:"columnsResult taskName", width: '12%', ellipsis: true,render: (text) => <Tooltip title={text} placement="topLeft"><span className='toolTipSpan'>{text}</span></Tooltip>},
{ title: '学生专业', dataIndex: 'profession', className:"columnsResult taskName", width: '12%', ellipsis: true, render: (text) => <Tooltip title={text} placement="topLeft"><span className='toolTipSpan'>{text}</span></Tooltip>},
{ title: '学生专业', dataIndex: 'profession', className:"columnsResult taskName", width: '12%', ellipsis: true, render: (text) => <Tooltip title={text} placement="topLeft"><span className='toolTipSpan'>{text || '-'}</span></Tooltip>},
{ 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/2023/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: 'action', align: 'center', className:"columnsResult actionBox"},
]
@ -107,11 +105,10 @@ function CheckResult({current_user, history}) {
return (
<div className="resultListBox">
{time && <img className="resultBanner" src={resultBanner} alt=""></img>}
{new Date().getTime() > new Date('2022/07/01 12:0').getTime() && <img className="resultBanner" src={resultBanner2} alt=""></img>}
<img className="resultBanner" src={resultBanner2} alt=""></img>
<div className='bgBox'>
<div className="resultList">
<div className='goBackBox'><a href='/glcc'>开源夏令营 / </a>入选学生名单{time && '预'}公示</div>
<div className='goBackBox'><a href='/glcc'>开源夏令营 / </a>入选学生名单公示</div>
<Search className='search' placeholder='请输入学生姓名或课题名称进行搜索' allowClear enterButton onSearch={(value) => { setCurrent(1); setKeyword(value) }} />
<Table
loading={loading}

View File

@ -0,0 +1,47 @@
import React, { useState } from 'react';
import { Button, Tooltip } from 'antd';
import Nodata from '../../../forge/Nodata';
import { useEffect } from 'react';
import { getProjectById } from '../../api';
export default ({ detail, projectId }) => {
const [info, setInfo] = useState(detail);
useEffect(()=>{
if(!detail && projectId){
// Id
getProjectById(projectId, {round: 2, isFree: true}).then(response=>{
if(response && response.message === 'success'){
setInfo(response.data)
}
})
}
},[detail])
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项目地址:&nbsp;&nbsp;<a href={info.gitlinkUrl} className='linkUrl' target={"_blank"}>{info.gitlinkUrl}</a></p>
<div>项目简介:&nbsp;&nbsp;{info.projectIntro}</div>
</div>
{/* 课题列表 */}
{info.registrationTaskList && info.registrationTaskList.length ? info.registrationTaskList.map((item, index)=>{
return <div className='taskItem mt20' key={index}>
<div className="left">
<div className="taskTitle"><Tooltip title={item.taskName}>{item.taskName}</Tooltip></div>
<div className='mt20 oneLine leftWidth'>导师姓名: &nbsp;&nbsp;{item.tutorName}</div>
{item.tutorMail && <div className='mb20 email oneLine leftWidth'>邮箱地址: &nbsp;&nbsp;<span><Tooltip title={item.tutorMail}>{item.tutorMail}</Tooltip></span></div>}
</div>
<div className="center">
<div className="taskDesc"><Tooltip title={item.taskDesc}>{item.taskDesc}</Tooltip></div>
{item.taskUrl && <div className="taskUrl oneLine">课题链接: &nbsp;&nbsp;<a href={item.taskUrl} target={"_blank"}>{item.taskUrl}</a></div>}
<div></div>
</div>
<div className="right oneLine taskUrl"><span className='taskReward'>{item.taskReward}</span></div>
</div>
}) : <Nodata _html="课题暂无数据" small={true}/>}
</div>: <div className="projectDetailBox nodata"><Nodata _html="暂无数据" small={true}/></div>
)
}

View File

@ -0,0 +1,66 @@
import React from 'react';
import { Spin } from 'antd';
import { Route, Switch } from "react-router-dom";
import banner from "../img/studentProject2.png";
import './index.scss';
import Loadable from "react-loadable";
import Loading from "../../Loading";
import { Link } from 'react-router-dom';
import { useEffect } from 'react';
//
const ProjectList = Loadable({
loader: () => import("./projectList"),
loading: Loading,
});
//
const TaskList = Loadable({
loader: () => import("./taskList"),
loading: Loading,
});
function FreeProject(propsF) {
const {location: {pathname}} = propsF;
useEffect(()=>{
window.scrollTo(0, 0);
},[])
console.log('FreeProject');
return(
<div className="glcc_project">
<div className='projectBannerBox'>
<img className="glcc-banner" src={banner} alt=''></img>
</div>
<div className='head'>
<Link to={`/glcc/freesubject`} className={!pathname.endsWith('freeproject') ? 'active' : ''}>课题列表</Link>
<Link to={`/glcc/freeproject`} className={pathname.endsWith('freeproject') ? 'active' : ''}>项目列表</Link>
</div>
<div className='gobackBox'>
<a href={`/glcc`}>开源夏令营 / </a>
无奖金课题及项目列表
</div>
<div className="head_introduce mt30 mb30">
<h4 className="head_tit">申请说明</h4>
<div className="head_content">1参与GitLink编程夏令营无奖金项目的同学请通过邮件或电话与课题导师直接沟通并根据导师课题要求完成课题无需在GLCC平台报名课题</div>
<div className="head_content">2参与GitLink编程夏令营无奖金项目的同学如完成课题并经导师评定通过将获得证书或证明1但无课题奖金</div>
<div className="head_content">3活动最终解释权归GLCC所有</div>
</div>
<Spin spinning={false}>
<Switch {...propsF}>
<Route
path="/glcc/freeproject"
render={(props) => (
<ProjectList {...propsF} {...props}/>
)}
></Route>
<Route
path="/glcc/freesubject"
render={(props) => (
<TaskList {...propsF} {...props}/>
)}
></Route>
</Switch>
</Spin>
</div>
)
}
export default FreeProject;

View File

@ -0,0 +1,229 @@
.glcc_project{
background-color: #ebf2ff;
.head{
background-color:rgba(188, 208, 255, 0.27);
border:1px solid #ffffff;
text-align: center;
a{
padding: 18px 20px 20px;
display: inline-block;
color: #273778;
font-size: 18px;
font-weight:700;
line-height: 30px;
&.active{
border-bottom: 1px solid #5474df;;
}
&:last-child{
margin-left: 40px;
}
}
}
.gobackBox{
width: 1200px;
margin: 0 auto;
padding: 25px 0 12px;
color: #202d40;
font-size: 16px;
border-bottom: 1px dashed #bec5d5;
a{
color:#a4aabb;
}
}
.listBox{
background-image:linear-gradient(180deg,#ebf2ff 0%,#ebf2ff 43.09%,#f3f4f8 100%);
position: relative;
.bgPng3, .bgPng4{
width: 146px;
position: absolute;
z-index: 0;
top: 162px;
left: 100px;
}
.bgPng4{
top: 450px;
left: auto;
right: 310px;
}
}
}
.glcc-banner {
width: 100%;
}
// 项目详情框
.projectDetailBox{
&.byTask{
background-image:linear-gradient(180deg,#f1f5ff 0%,#ffffff 100%);
border:1px solid #ffffff;
border-radius:4px;
box-shadow:0px 0px 10px rgba(100, 141, 255, 0.2);
padding: 30px 30px 50px;
.taskItem{
.center{
width: 640px;
}
}
}
&.nodata{width: 200px;}
font-size:15px;
line-height:30px;
.projectDetailHead{
color:#465474;
padding-bottom: 12px;
border-bottom: 1px dashed #bec5d5;
line-height: 36px;
&.byResult{
margin: -15px -10px -40px;
border-bottom: none;
}
.name{
font-weight:700;
color:#3753c5;
font-size:20px;
}
.type{
display: inline-block;
border:1px solid #6680bb;
border-radius:4px;
margin-left: 12px;
padding: 4px 6px;
line-height: 26px;
}
.linkUrl{
color: #466aff;
}
}
.taskItem {
display: flex;
justify-content: space-between;
border:1px solid #ffffff;
&:hover{ box-shadow: 0px 0px 12px rgba(71, 105, 198, 0.4);}
.oneLine{
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.left{
width: 316px;
background-image: url('../img/projectDetailTaskBg.png');
background-size: 100% 100%;
padding: 22px 20px;
color:#25304a;
.taskTitle{
color:#1834a7;
font-size:18px;
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
}
.email span{color:#466aff;}
.leftWidth{width: 270px;}
}
.center{
width: 665px;
text-align: left;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
.taskDesc{
color:#6b6b6b;
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
}
.taskUrl{
color:#465474;
font-size:16px;
line-height: 28px;
margin-bottom: 5px;
a{color:#466aff;}
}
.applyBut{
background-color:#466aff;
border-color: #466aff;
&:hover{background-color:#5d7cff;}
&:focus{background-color:#1140ff;}
}
.taskReward{color:#ff8800;}
}
.right{
margin-top: 35px;
padding-right: 10px;
width: 120px;
font-weight:700;
color:#ff8800;
font-size:24px;
}
}
}
.ant-popover.projectItemPopover{
width: 1200px;
z-index: 1000;
.ant-popover-content .ant-popover-arrow{
border-width: 12px;
}
}
.projectItemPopover .ant-popover-inner{
transform: translateY(8px);
background-image:linear-gradient(180deg,#f1f5ff 0%,#ffffff 100%);
border:1px solid #ffffff;
border-radius:4px;
box-shadow:0px 0px 10px rgba(100, 141, 255, 0.2);
.ant-popover-inner-content{
padding: 30px 30px 50px;
}
}
.lookDetail{
border-color: #466aff;
color: #466aff;
&:hover{
border-color: #5d7cff;
color: #5d7cff;
}
&:focus{
border-color: #1140ff;
color: #1140ff;
}
}
.projectBannerBox{
position: relative;
.stuApplytimeBox{
background-image: url('../img/studentProject1.png');
position: absolute;
color: #FFDC95;
font-size: 20px;
bottom: 28%;
left: 50%;
margin-left: -250px;
width: 500px;
height: 60px;
line-height: 60px;
text-align: center;
background-size: 100% 100%;
}
}
.head_introduce {
width: 1200px;
margin: 0 auto;
background: #e4edff;
padding: 20px;
}
.head_tit {
color: #000000;
font-size: 15px;
line-height: 2;
}
.head_content {
color: #6c7283;
font-size: 14px;
line-height: 38px;
}
.head_bold {
font-weight: 700;
color: #333;
}

View File

@ -0,0 +1,75 @@
import React, { useEffect, useState } from 'react';
import { Input, Popover, Spin } from 'antd';
import { main_site_url } from '../../fetch';
import './index.scss';
import { freeProjectList, projectList } from '../../api';
import ProjectDetail from '../component/projectDetail';
import bgPng from "../../img/bgPng.png";
import logo from "../../img/logo.png";
import star from "../../img/star.png";
import Nodata from '../../../forge/Nodata';
const { Search } = Input;
//
function ProjectList() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(true);
const params = {
curPage: 1,
pageSize: 10000,
round: 2
}
freeProjectList(params).then(response => {
if (response && response.message === "success") {
setData(response.data.rows);
}
setLoading(false);
})
}, [])
// taskList
function changeVisible(visible, item) {
if (visible) {
let height = document.documentElement.clientWidth / 1920 * 500 + 70 + document.querySelector(`.${item.gitlinkLastUrl}`).offsetTop + item.registrationTaskList.length * 320;
document.querySelector('#taskList').style.height = height + 'px';
} else {
document.querySelector('#taskList').style.height = 'auto';
}
}
return (
<div id="taskList" className="taskList listBox">
<Spin spinning={loading}>
<div className='projectListBox'>
{data && data.map((item, index) => {
return <Popover
onVisibleChange={(visible) => { changeVisible(visible, item) }}
key={index}
placement={(index + 1) % 3 === 0 ? 'bottomRight' : (index + 1) % 3 % 2 === 0 ? 'bottom' : 'bottomLeft'}
content={<ProjectDetail detail={item}/>}
trigger='click'
overlayClassName='projectItemPopover'
autoAdjustOverflow={false}
>
<div className={`projectItem ${(index + 1) % 3 === 0 || (index + 1) % 3 % 2 === 0 ? '' : 'firstBox'} ${item.projectName.replace(/ /g, '')} ${item.gitlinkLastUrl}`}>
<div className="border"></div>
<div className="projectLogo">
<img className="projectLogoImg" src={item.projectLogoId ? `${main_site_url}/api/attachments/${item.projectLogoId}` : logo} alt='' />
</div>
<div className="title">{item.projectName}</div>
<div className="intro">{item.projectIntro}</div>
</div>
</Popover>
})}
</div>
{data && !data.length && <div style={{paddingBottom: '50px'}}><Nodata _html="暂无数据"/></div>}
</Spin>
<img src={bgPng} alt='' className='bgPng3' />
<img src={bgPng} alt='' className='bgPng4' />
</div>
)
}
export default ProjectList;

View File

@ -0,0 +1,85 @@
.projectListBox{
width: 1200px;
margin: 0 auto;
position: relative;
z-index: 1;
display: flex;
flex-wrap: wrap;
// justify-content: space-between;
.projectItem{
position: relative;
width: 30%;
background-image: linear-gradient(180deg,rgba(232, 237, 255, 0.85) 0%,rgba(255, 255, 255, 0.85) 100%);
border: 1px solid;
border-color: #ffffff;
border-radius: 4px;
box-shadow:0px 0px 8px rgba(93, 131, 255, 0.26);
text-align: center;
margin-bottom: 50px;
background-image: url('../../img/projectBg.png');
background-size: 100% 100%;
margin-left: 5%;
&.firstBox{
margin-left: 0;
}
&:hover{
cursor: pointer;
background-image: none;
// #E8EDFF#FFFFFF85%
background-image: linear-gradient(180deg,rgba(232, 237, 255, 0.85) 0%,rgba(255, 255, 255, 0.85) 100%);
}
.border{
height: 5px;
background-color:#657edf;
border-radius:2px 2px 0px 0px;
}
.projectLogoStar{
position: absolute;
top:30px;
right: 130px;
width: 28px;
z-index: 10;
transform: rotate(46deg);
}
.projectLogo{
position: relative;
width: 100px;
height: 100px;
border: 1px solid #fff;
background-color: #fff;
border-radius: 50%;
text-align: center;
overflow: hidden;
margin: 25px auto 10px;
line-height: 95px;
.projectLogoImg{
width: 100%;
// height: 100%;
// display: block;
}
}
.title{
color:#2a51bf;
font-size:17px;
line-height:30px;
margin-bottom: 15px;
padding: 0 50px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.intro{
color:#4f5d84;
font-size:15px;
margin-bottom: 15px;
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
text-align: left;
padding: 0 14px;
}
}
}

View File

@ -0,0 +1,106 @@
import React, { useEffect, useState } from 'react';
import { Table, Tooltip } from 'antd';
import './index.scss';
import { freeTaskList, taskList } from '../../api';
import ProjectDetail from '../component/projectDetail';
import bgPng from "../../img/bgPng.png";
//
function TaskList() {
const [data, setData] = useState([]);
// table
const [current, setCurrent] = useState(1);
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) => <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>{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> },
{ title: '操作', dataIndex: 'action', align: 'center', className:"actionColumns taskTableColumns"},
]
const customExpandIcon = (props) => {
if (props.expanded) {
return <a className='actionBox' style={{marginRight: 8 }} onClick={e => {
props.onExpand(props.record, e);
}}><i className='iconfont icon-ketixiangqingicon mr5'></i>项目详情<i className="iconfont icon-changyongtubiao-xianxingdaochu-zhuanqu- font-12 ml5 down mr10"></i></a>
} else {
return <a className='actionBox' style={{marginRight: 8 }} onClick={e => {
props.onExpand(props.record, e);
}}><i className='iconfont icon-ketixiangqingicon mr5'></i>项目详情<i className="iconfont icon-jiantou9 font-12 ml5 down mr10"></i></a>
}
}
const expandRow = (record) => {
return <ProjectDetail detail={null} projectId={record.regId}/>
}
//
function onExpand(expanded, record){
const keys = new Set(expandedRowKeys);
if(expanded){
keys.add(record.id);
}else{
keys.delete(record.id);
}
setExpandedRowKeys(Array.from(keys));
}
// pagesize
function onShowSizeChange(current, pageSize){
window.scrollTo(0, 0);
setCurrent(1);
setPageSize(pageSize);
}
//
function changePage(page, pageSize){
window.scrollTo(0, 0);
setCurrent(page);
}
useEffect(() => {
setExpandedRowKeys([]);
setLoading(true);
const params = {
curPage: current,
pageSize,
round: 2
}
freeTaskList(params).then(response => {
if (response && response.message === "success") {
setData(response.data.rows);
setTotal(response.data.total);
}
setLoading(false);
})
}, [current, pageSize])
return (
<div className="taskList listBox">
<div className="listTable">
<Table
loading={loading}
columns={columns}
dataSource={data}
expandedRowRender={expandRow}
expandIconColumnIndex={5}
expandIconAsCell={false}
expandIcon={customExpandIcon}
rowKey={'id'}
expandedRowKeys={expandedRowKeys}
onExpand={onExpand}
pagination={{current: current, pageSize: pageSize, total: total, showSizeChanger: true, onShowSizeChange:onShowSizeChange, showQuickJumper: true, onChange: changePage}}
/>
</div>
<img src={bgPng} alt='' className='bgPng3'/>
<img src={bgPng} alt='' className='bgPng4'/>
</div>
)
}
export default TaskList;

View File

@ -0,0 +1,116 @@
.taskList{
padding-bottom: 50px;
.ant-table{
border: 1px solid white;
}
.ant-pagination-item-active, .ant-pagination-item:hover, .ant-pagination-next:not(.ant-pagination-disabled) .ant-pagination-item-link:hover, .ant-select-selection:hover, .ant-pagination-options-quick-jumper:hover input{
border-color: #466aff;
a{color: #466aff;}
}
.ant-pagination-disabled .ant-pagination-item-link:hover .anticon{
color: rgba(0, 0, 0, 0.25);
}
.listTable{
width: 1200px;
margin: 0 auto;
position: relative;
z-index: 1;
}
}
.taskTableColumns span div span{
font-size: 16px;
font-weight:700;
color:#273778;
}
.taskTableColumns span{
font-size: 15px;
color: #353f5e;
}
.ant-table-tbody .taskTableColumns.taskName span{
color: #2545c9;
}
.ant-table-thead > tr > .taskTableColumns, .ant-table-tbody > tr > .taskTableColumns{
background-color:#F1F6FF;
border-bottom: 1px dashed #bec5d5;
}
.ant-table-tbody > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > .taskTableColumns{
background-color:#fbfbfc;
}
.actionColumns{
display: flex;
.actionBox, .actionBox span{
cursor: pointer;
color: #466aff;
&:hover{color:#5d7cff !important;}
&:active{color:#1140ff !important;}
&.disabled .disabled{
&:hover, &:active{color:#a4aabb !important;}
color:#a4aabb;
cursor: not-allowed;
}
}
.applyTask, span.applyTask{
color:#eb9350;
&:hover{color: #FFB074 !important;}
&:active{color:#D66A17 !important;}
}
.cancelApply{visibility: hidden;}
}
tr:hover .actionColumns .cancelApply{
visibility: visible;
color: #E31E1E;
}
.cancelApplyTask{
.ant-modal-close{top: 0px !important;}
.ant-modal-header{
padding: 8px 20px;
background-color: #e9edff;
.ant-modal-title{text-align: left;}
}
.carefulIcon{
width: 36px;
height: 36px;
background: #ca0002;
display: inline-block;
border-radius: 50%;
text-align: center;
line-height: 36px;
font-size: 18px;
color: white;
margin-right: 15px;
}
.tilTask{
color:#333333;
font-size:16px;
margin-left: 35px;
}
.tipTask{
color:#666666;
font-size:14px;
margin: 10px 0 10px 37px!important;
}
.tipTaskTime{
font-size: 36px;
color: #df0002;
}
.ant-modal-footer{
border-top: none;
text-align: center;
padding-bottom: 50px;
.ant-btn{
&.ant-btn-default{
color: #df0002;
}
&:hover{
border-color: #466aff;
color: #466aff;
&.ant-btn-default{
border-color: #df0002;
color: #df0002;}
}
}
.ant-btn-default{
margin-left:43px;
}
}
}

View File

@ -22,7 +22,7 @@ import './index.scss';
// period: "repoApply"
// match:{params:{id=2023}}
export default (props) => {
const { current_user, history, round, match:{params:{id=2023}}, period, showLoginDialog, glccSettings, repoPublic, showMatchingBut} = props;
const { current_user, history, round, match:{params:{id=2023}}, period, showLoginDialog, glccSettings, repoPublic, showMatchingBut, isResultPublic} = props;
useEffect(() => {
if (!current_user.user_id) {
@ -30,10 +30,6 @@ export default (props) => {
}
}, [])
function goToCheckResult(){
history.push("/glcc/result");
}
//
function gotoCheckLogin(url){
if(current_user && current_user.login){
@ -86,11 +82,20 @@ export default (props) => {
{repoPublic && <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-none"><span className="til">有奖金项目</span> </span>
</div>
<div className="pt6">掌握项目课题详细信息</div>
</Link>}
{/* 0元项目 */}
<Link to={`/glcc/freeproject`} 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第二次报名 */}
{(period === "stuApply" || period === "stuApply1") && <div className="apply" onClick={()=>{gotoCheckLogin(`/glcc/${id}/subjects`)}}>
<div>
@ -108,14 +113,15 @@ export default (props) => {
</div>
<div className="pt6">以赛代筛挖掘高潜力人才</div>
</div>}
{/* 6.28.-7.1 审核结果仅对导师可见7.1之后对所有用户可见*/}
{/* {resultTime2 && <div className="apply" onClick={goToCheckResult}>
{/* 学生-课题匹配结果公示 */}
{isResultPublic && <div className="apply" onClick={()=>{history.push("/glcc/result");}}>
<div>
<img src={apply2} alt="" className="applyIcon" />
<span className="til">名单{resultTime1 ? '预' : ''}公示</span>
<span className="til">名单公示</span>
</div>
<div className="pt6">查看各课题入选学生名单</div>
</div>} */}
</div>}
{/* 学生结项考核 */}
{/* {!hasRole && checkedTaskId && <Link className="apply" to={`/glcc/submission`}>

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

View File

@ -46,6 +46,12 @@ const Project = Loadable({
loader: () => import("./project"),
loading: Loading,
});
// 0
const FreeProject = Loadable({
loader: () => import("./freeProject"),
loading: Loading,
});
//
const TaskDetail = Loadable({
loader: () => import("./project/taskDetail"),
@ -92,6 +98,9 @@ const Glcc = (propsF) => {
const [applyRepo, setApplyRepo] = useState(false);
// -
const [isMatching, setIsMatching] = useState(false);
// -
const [isResultPublic, setIsResultPublic] = useState(false);
console.log('isResultPublic', isResultPublic);
useEffect(()=>{
if(id && id === "2022"){
@ -113,8 +122,11 @@ const Glcc = (propsF) => {
// -
const matching = res.data.filter(item=>item.name === "matching");
matching[0] && setIsMatching(judge(nowTime, matching[0].value, "range"))
// /
const filterRepoPublic = res.data.filter(item=>["repoPublic", "repoApply1"].indexOf(item.name) === -1);
// -
const resultPublic = res.data.filter(item=>item.name === "stuPublic");
resultPublic[0] && setIsResultPublic(judge(nowTime, resultPublic[0].value, "range"))
//
const filterRepoPublic = res.data.filter(item=>["repoPublic", "repoApply1", "matching", "stuPublic"].indexOf(item.name) === -1);
const periodIndex = filterRepoPublic.findIndex(item=>judge(nowTime, item.value, "range"));
periodIndex !== -1 && setPeriod(filterRepoPublic[periodIndex].name);
}
@ -234,6 +246,15 @@ const Glcc = (propsF) => {
<Check {...propsF} {...props} currentRound={currentRound}/>
)}
></Route>}
{/* 导师-学生配对结果公示页面 */}
{isResultPublic && <Route
path="/glcc/result"
render={(props) => (
<Result current_user={current_user} history={props.history} round={round}/>
)}
></Route>}
{/* 帮助中心 */}
<Route
path="/glcc/help"
@ -263,6 +284,21 @@ const Glcc = (propsF) => {
)}
></Route>}
{/* 0元项目/课题列表 */}
<Route
path="/glcc/freesubject"
render={(props) => (
<FreeProject {...propsF} {...props}/>
)}
></Route>
<Route
path="/glcc/freeproject"
render={(props) => (
<FreeProject {...propsF} {...props}/>
)}
></Route>
{/* openmmlab列表 */}
<Route
path="/glcc/openmmlab"
@ -271,14 +307,6 @@ const Glcc = (propsF) => {
)}
></Route>
{/* 审核结果页面 */}
<Route
path="/glcc/result"
render={(props) => (
<Result current_user={current_user} history={props.history}/>
)}
></Route>
{/* 中期审核-结果公示 */}
<Route
path="/glcc/:id/final/result"
@ -307,7 +335,7 @@ const Glcc = (propsF) => {
<Route
path="/glcc/:id"
render={(props) => (
<Home repoPublic={repoPublic} period={period} round={round} {...propsF} {...props} checkedTaskId={checkedTaskId} glccSettings={glccSettings} showMatchingBut={isMatching && hasRole}/>
<Home repoPublic={repoPublic} period={period} round={round} {...propsF} {...props} checkedTaskId={checkedTaskId} glccSettings={glccSettings} showMatchingBut={isMatching && hasRole} isResultPublic={isResultPublic}/>
)}
></Route>
@ -315,7 +343,7 @@ const Glcc = (propsF) => {
<Route
path="/glcc"
render={(props) => (
<Home repoPublic={repoPublic} period={period} round={round} {...propsF} {...props} checkedTaskId={checkedTaskId} glccSettings={glccSettings} showMatchingBut={isMatching && hasRole}/>
<Home repoPublic={repoPublic} period={period} round={round} {...propsF} {...props} checkedTaskId={checkedTaskId} glccSettings={glccSettings} showMatchingBut={isMatching && hasRole} isResultPublic={isResultPublic}/>
)}
></Route>

View File

@ -10,7 +10,7 @@ export default ({ detail, projectId, applyTaskId, period, showTask=true, applyTa
useEffect(()=>{
if(!detail && projectId){
// Id
getProjectById(projectId, {round}).then(response=>{
getProjectById(projectId, {round, isFree: false}).then(response=>{
if(response && response.message === 'success'){
setInfo(response.data)
}

View File

@ -52,9 +52,9 @@ function TaskDetail(props) {
{/* 课题申请时间范围内: 申请课题 */}
{/* 第一次报名 */}
{round === currentRound && period==="stuApply" && !(applyTaskId && Object.keys(applyTaskId).includes(taskId.toString())) && <Button type='primary' className='applyBut detailBut' onClick={()=>{applyTask(taskId)}}>申请课题</Button>}
{detail.taskReward > 0 && round === currentRound && period==="stuApply" && !(applyTaskId && Object.keys(applyTaskId).includes(taskId.toString())) && <Button type='primary' className='applyBut detailBut' onClick={()=>{applyTask(taskId)}}>申请课题</Button>}
{/* 第二次报名 锁定状态 */}
{round === currentRound && period === "stuApply1" && !(applyTaskId && Object.keys(applyTaskId).includes(taskId.toString())) && (detail.locked ? <Tooltip title={"该课题已有学生入选"}><Button type='primary' className='mr10 detailBut' disabled>申请课题</Button></Tooltip> : <Button type='primary' className='applyBut mr10 detailBut' onClick={()=>{applyTask(taskId)}}>申请课题</Button>)}
{detail.taskReward > 0 && round === currentRound && period === "stuApply1" && !(applyTaskId && Object.keys(applyTaskId).includes(taskId.toString())) && (detail.locked ? <Tooltip title={"该课题已有学生入选"}><Button type='primary' className='mr10 detailBut' disabled>申请课题</Button></Tooltip> : <Button type='primary' className='applyBut mr10 detailBut' onClick={()=>{applyTask(taskId)}}>申请课题</Button>)}
</div>
<img src={bgPng} alt='' className='bgPng1'/>
<img src={bgPng} alt='' className='bgPng2'/>

View File

@ -21,6 +21,8 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
const [expandedRowKeys, setExpandedRowKeys] = useState([]);
//
const [apply, setApply] = useState(false);
//
const [isAvailable, setIsAvailable] = useState(false);
const columns = [
{ title: '序号', dataIndex: 'index', align: 'center', className:"taskTableColumns", width: '6%', render: (text, item, index) => <span>{(current-1)*pageSize+index + 1}</span> },
@ -130,8 +132,10 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
keyword,
pageSize,
userId: apply ? current_user.user_id : '',
round
round,
locked: isAvailable ? false : undefined
}
console.log('params', params);
taskList(params).then(response => {
if (response && response.message === "success") {
const data = response.data.rows;
@ -152,13 +156,16 @@ function TaskList({applyTaskId, setStudentInfoReset, current_user, showLoginDial
}
setLoading(false);
})
}, [keyword, current, pageSize, applyTaskId, apply, round])
}, [keyword, current, pageSize, applyTaskId, apply, round, isAvailable])
return (
<div className="taskList listBox">
<div className="list">
<div className='search task'>
{round === 2 && current_user && current_user.login ? <Checkbox onChange={(e)=>{setCurrent(1);setApply(e.target.checked)}}>已报名</Checkbox> : <div></div>}
<div>
{round === 2 && current_user && current_user.login ? <Checkbox onChange={(e)=>{setCurrent(1);setApply(e.target.checked)}}>已报名</Checkbox> : <div></div>}
{round === 2 && period === "stuApply1" && <Checkbox onChange={(e)=>{setCurrent(1);setIsAvailable(e.target.checked)}}>可申请课题</Checkbox>}
</div>
<Search className='taskSearch' placeholder='请输入课题/项目名称进行搜索' allowClear enterButton onSearch={(value) => { setCurrent(1); setKeyword(value) }} />
<div></div>
</div>