竞赛关注功能+第三方测试issue

This commit is contained in:
谢思 2022-10-18 17:02:38 +08:00
parent b64d29a9a6
commit 9e24f56395
13 changed files with 328 additions and 8 deletions

View File

@ -74,6 +74,11 @@ const Competition = Loadable({
loader: () => import('./military/competition'),
loading: Loading,
})
// 我关注的竞赛列表
const MyFocusCompetitions = Loadable({
loader: () => import('./military/competition/myFocus'),
loading: Loading,
})
//403页面
const Shixunauthority = Loadable({
loader: () => import('./modules/403/Shixunauthority'),
@ -387,6 +392,8 @@ class App extends Component {
<Route path="/task" component={Task} />
{/*专家评审*/}
<Route path="/expert" component={Expert} />
{/* 我关注的竞赛列表 */}
<Route path="/competition/myFocus" component={MyFocusCompetitions} />
{/*启智2022*/}
<Route path="/competition/:competitionId" component={Competition} />

View File

@ -84,11 +84,11 @@ export default (props) => {
);
if (Array.isArray(item.children) && item.children.length > 0) {
return (
<SubMenu key={item.key} children={item.children} title={title}>{getMenuList(item.children)}</SubMenu>
<SubMenu key={item.key} children={item.children} title={item.title}>{getMenuList(item.children)}</SubMenu>
);
} else {
return (
<Menu.Item title={title} key={item.key}>
<Menu.Item title={item.title} key={item.key}>
{item.location ? <Link to={item.location} onClick={() => { itemClick(item) }}>{title}</Link>
: title}
</Menu.Item>

View File

@ -8,12 +8,12 @@ import Loadable from "react-loadable";
import Loading from "../Loading";
import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC";
import './competition/index.scss';
import { Menu, Popover, Spin } from "antd";
import { Menu, message, Popover, Spin } from "antd";
import InfoModal from './competition/components/infoModal';
// import banner from './competition/image/banner.jpg';
// import banner_local from './competition/image/banner_local.jpg';
import logo from './competition/image/logo.png';
import { getCompetitionDetail, userCompetitionStatus } from "./competition/api";
import { getCompetitionDetail, userCompetitionStatus, follow, unFollow } from "./competition/api";
// import { paths } from "./competition/static";
import Login from './components/login';
@ -163,6 +163,31 @@ const Competition = (props) => {
}
}
// 关注和取消关注
function follow1(){
follow({
id: competitionId,
target_type: 'competition_info'
}).then(res=>{
if(res && res.status === 200){
message.success('关注成功');
setReloadDetail(Math.random());
}
})
}
function unfollow(){
unFollow({
id: competitionId,
target_type: 'competition_info'
}).then(res=>{
if(res && res.status === 200){
message.success('取消关注成功');
setReloadDetail(Math.random());
}
})
}
const is_local = qzDetail && qzDetail.is_local;
const banner_url = qzDetail && qzDetail.banner_url && getImageUrl(qzDetail.banner_url);
@ -224,6 +249,21 @@ const Competition = (props) => {
<a>后台管理</a>
</Popover>
</li>}
{/* 关注 */}
{qzDetail && <li>
<span className='detail_tag_btn '>
{
!qzDetail.watched ? <span className='detail_tag_btn_name' onClick={follow1}>
<i className="iconfont icon-kongxing font-16 mr3"></i>
关注
</span> : <span className='detail_tag_btn_name' onClick={unfollow}>
<i className="iconfont icon-shixing color-orange font-16 mr3"></i>
取消关注
</span>
}
<span className="detail_tag_btn_count">{qzDetail.watchers_count}</span>
</span>
</li>}
</ul>
{/* } */}
{/* {paths.indexOf(active) !== -1 && */}

View File

@ -83,4 +83,19 @@ export async function updateTemplate(data, competitionId) {
export async function rankingList(competitionId, params) {
return axios.get(`/competition_infos/${competitionId}/ranking_list.json`, { params });
}
// 竞赛关注
export async function follow(data) {
return axios.post(`/watchers/follow.json`, data);
}
// 竞赛取消关注
export async function unFollow(data) {
return axios.delete(`/watchers/unfollow.json`, {data});
}
// 我关注的竞赛列表
export async function focusCompetitionList(params) {
return axios.get(`/competition_infos.json`, { params });
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

View File

@ -150,3 +150,38 @@ html {
font-size: calc(125% + (100vw - 2880px) / 400);
}
}
.detail_tag_btn{
height:32px;
line-height: 32px;
border-radius:5px;
border:1px solid #D0D0D0;
display: flex;
align-items: center;
margin-left: 10px;
padding:0px;
background-color:#FAFBFC;
box-shadow: none;
.detail_tag_btn_name{
cursor: pointer;
padding:0px 10px;
text-align: center;
height: 30px;
line-height: 30px;
border-radius:5px 0px 0px 5px;
&:hover
{
background-color: #F3F4F6;
}
span{
color: #333!important;
}
}
.detail_tag_btn_count{
width: 42px;
text-align: center;
background: #fff;
border-radius: 0px 4px 4px 0px;
height:100%;
border-left: 1px solid #D0D0D0;
}
}

View File

@ -0,0 +1,98 @@
import React, { useEffect, useState } from "react";
import { withRouter } from "react-router";
import { SnackbarHOC, getImageUrl } from "educoder";
import { ImageLayerOfCommentHOC } from "../../../modules/page/layers/ImageLayerOfCommentHOC";
import { CNotificationHOC } from "../../../modules/courses/common/CNotificationHOC";
import { TPMIndexHOC } from "../../../modules/tpm/TPMIndexHOC";
import bg2 from '../image/myfocus1.png';
import title1 from '../image/myfocus2.png';
import title2 from '../image/myfocus3.png';
import {focusCompetitionList} from '../api.js'
import './index.scss';
import { Input } from "antd";
import RenderHtml from "src/components/render-html";
import Nodata from "src/forge/Nodata";
const MyFocusCompetitions = (props) => {
const {current_user, mygetHelmetapi} = props;
const [list, setList] = useState([]);
const [search, setSearch] = useState(undefined);
useEffect(()=>{
if(current_user && current_user.login){
//
focusCompetitionList({
category: 'watched',
name: search
}).then(res=>{
if(res && res.status === 200){
const nowTime = Date.parse(new Date());
res.data.data.map(item =>{
if(item.enroll_date && item.upload_date){
if(nowTime < Date.parse(new Date(item.enroll_date))){
//
item.comState = 1;
}else if(nowTime < Date.parse(new Date(item.upload_date))){
//
item.comState = 2;
}else{
//
item.comState = 3;
}
}
if(item.created_at && item.upload_date){
item.comTime = item.created_at.substring(0, 10).replaceAll('-', '.') + '-' + item.upload_date.substring(0, 10).replaceAll('-', '.')
}
item.content = item.content.replaceAll('font-size', '');
item.content = item.content.replaceAll('line-height', '');
})
setList(res.data.data);
}
})
}
},[search])
return (
<div className="myFocusBgBox">
<img src={bg2} alt="" className="bg2"/>
<div className="myFocusList">
<div className="titleMan">
<img src={title1} alt="" width={100}/>
竞赛管理
<img src={title2} alt="" width={100}/>
</div>
<div className="searchCom">
<div className="font-15 til">我关注的竞赛</div>
<Input.Search placeholder="请输入竞赛名称进行搜索" enterButton allowClear onSearch={(e)=>{setSearch(e)}}/>
<div style={{width: '120px'}}></div>
</div>
<div className="listBox mt30">
{list && list.map((item, index)=>{
return <div className="flexBox itemBoxCom" key={index}>
{item.banner_url && <div className="comImgBox mr20"><img src={mygetHelmetapi.current_main_site_url + item.banner_url} alt=""/></div>}
<div className="contCom">
<a className="title font-20" href={`/competition/${item.identifier}`}>{item.title}</a>
<RenderHtml className="comContentIntro font-14" value={item.content}/>
<div className="flexBox ot font-14">
<div>
<span className="timeTitleComItem mr15">竞赛时间</span>
<span>{item.comTime}</span>
</div>
<span className={`statusComItem status${item.comState}`}>{item.comState === 1 ? '报名中' : item.comState === 2 ? '提案提交中' : '已结束'}</span>
</div>
</div>
</div>
})}
{list && !list.length && <Nodata _html="暂无数据"/>}
</div>
</div>
</div>
)
}
export default withRouter(
ImageLayerOfCommentHOC({
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
parentSelector: ".newMain",
})(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(MyFocusCompetitions))))
);

View File

@ -0,0 +1,124 @@
.myFocusBgBox{
position: relative;
z-index: 0;
background-image:linear-gradient(175.09deg,#f3f9ff 0%,#d6e9ff 100%);
min-height: 75vh;
padding-bottom: 100px;
.bg1, .bg2{
width: 1100px;
position: absolute;
bottom: 0;
right: 0;
z-index: -1;
}
.myFocusList{
position: relative;
z-index: 1;
width: 1200px;
margin: 0 auto;
}
.titleMan, .searchCom, .flexBox{
display: flex;
align-items: center;
justify-content: center;
}
.titleMan{
padding: 20px 0 10px;
font-weight:500;
color:#2e3341;
font-size:30px;
}
.searchCom{
justify-content: space-between;
color:#2e3341;
.til{
position: relative;
&::after{
content: '';
position: absolute;
bottom: 2.5px;
left: 0;
width:19px;
height:2px;
background-color:#4154f1;
border-radius:20px;
}
}
.ant-input-search{
width: 480px;
}
.ant-input, .ant-btn{
height: 44px;
}
.ant-input:hover{
border-color: #6e81ff;
}
}
.listBox{
padding: 0 30px;
background-image:linear-gradient(178.28deg,#ecf3f9 0%,#ffffff 100%);
border:1.5px solid #ffffff;
box-shadow:0px 3px 12px rgba(181, 210, 255, 0.23);
.itemBoxCom{
justify-content: start;
padding: 20px 0;
border-bottom: 1px dashed #c5d8ec;
}
.itemBoxCom:last-child{
border-bottom: none;
}
.comImgBox{
width:300px;
// height:220px;
img{
width: 100%;
height: 100%;
}
}
.contCom{
flex: 1;
}
.title{
color:#2e3341;
}
.comContentIntro{
-webkit-line-clamp: 2;
display: -webkit-box;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
word-break: break-all;
overflow: hidden;
margin: 15px 0 55px;
color:#595959;
}
.timeTitleComItem{
display: inline-block;
padding: 2px 10px;
color:#4154f1;
border:1px solid #4154f1;
border-radius:4px;
}
.ot{
justify-content: space-between;
color:#2e3341;
}
.statusComItem{
color:#ffffff;
width:78px;
height:32px;
background-image:linear-gradient(175.37deg,#ffaa00 0%,#ff7617 100%);
border-radius:4px;
text-align: center;
}
.status2{
background-image:linear-gradient(171.48deg,#418df1 0%,#4154f1 100%);
}
.status3{
background-image:linear-gradient(175.48deg,#26b34a 0%,#04c6c2 100%);
}
}
.noFocusCom{
text-align: center;
margin: 100px 0 100px;
}
}

View File

@ -585,7 +585,7 @@ class NewHeader extends Component {
} else if (url.indexOf('explore') > -1 && match.path.indexOf('explore') > -1) {
return true
// 开源项目,路由改版后,比较麻烦,因此使用多个进行判断
} else if (url.indexOf('explore') > -1 && match.url.indexOf(pathname) > -1) {
} else if (url.indexOf('explore') > -1 && match.url.indexOf(pathname) > -1 && match.url.indexOf('admins') === -1) {
return true
// 公告
} else if (url.indexOf('/notice') > -1 && match.path.indexOf('/notice') > -1) {
@ -594,7 +594,7 @@ class NewHeader extends Component {
} else if (url.indexOf('/task') > -1 && match.path.indexOf('/task') > -1) {
return true
// 管理
} else if (url.indexOf('/managements') > -1 && match.path.indexOf('/managements') > -1) {
} else if (url.indexOf('/managements') > -1 && (match.path.indexOf('/managements') > -1 || match.path.indexOf('/administration') > -1)) {
return true
} else if (['http://117.50.100.12:8080','https://osredm.com','http://111.8.36.180:8000','http://localhost:3007'].includes(url) && match.path === '/') {
return true

View File

@ -52,7 +52,7 @@ body>.-task-title {
.indexHOC > .ant-spin-nested-loading {
/* background: #000; */
height: 100%;
margin-bottom: 107px;
margin-bottom: 180px;
}
.indexHOC .homePage+.ant-spin-nested-loading {
margin-bottom: 0;

View File

@ -293,7 +293,8 @@ export function TPMIndexHOC(WrappedComponent, headFoot) {
resetUserInfo: this.fetchUsers,
showCompeleteDialog: this.showCompeleteDialog
};
let competition = this.props.match.path.includes('/competition');
// 定制竞赛页面无顶部导航栏
let competition = this.props.match.path.includes('/competition') && !this.props.match.path.includes('/myFocus');
return (
<div className="indexHOC">
<SystemNotice