forked from Gitlink/forgeplus-react
竞赛增加签署CLA协议弹框
This commit is contained in:
parent
8c913b002b
commit
6cb2d854b7
|
@ -20399,6 +20399,7 @@
|
|||
"version": "2.3.2",
|
||||
"resolved": "https://registry.nlark.com/braces/download/braces-2.3.2.tgz",
|
||||
"integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"arr-flatten": "^1.1.0",
|
||||
"array-unique": "^0.3.2",
|
||||
|
@ -20416,6 +20417,7 @@
|
|||
"version": "2.0.1",
|
||||
"resolved": "https://registry.nlark.com/extend-shallow/download/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
|
@ -20446,6 +20448,7 @@
|
|||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/fill-range/download/fill-range-4.0.0.tgz",
|
||||
"integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"is-number": "^3.0.0",
|
||||
|
@ -20457,6 +20460,7 @@
|
|||
"version": "2.0.1",
|
||||
"resolved": "https://registry.nlark.com/extend-shallow/download/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
|
@ -20507,6 +20511,7 @@
|
|||
"version": "3.0.0",
|
||||
"resolved": "https://registry.nlark.com/is-number/download/is-number-3.0.0.tgz",
|
||||
"integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"kind-of": "^3.0.2"
|
||||
},
|
||||
|
@ -20515,6 +20520,7 @@
|
|||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz",
|
||||
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"is-buffer": "^1.1.5"
|
||||
}
|
||||
|
@ -20530,12 +20536,14 @@
|
|||
"kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-6.0.3.tgz",
|
||||
"integrity": "sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0="
|
||||
"integrity": "sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0=",
|
||||
"optional": true
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.nlark.com/micromatch/download/micromatch-3.1.10.tgz",
|
||||
"integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"arr-diff": "^4.0.0",
|
||||
"array-unique": "^0.3.2",
|
||||
|
@ -20591,6 +20599,7 @@
|
|||
"version": "2.1.1",
|
||||
"resolved": "https://registry.nlark.com/to-regex-range/download/to-regex-range-2.1.1.tgz",
|
||||
"integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"is-number": "^3.0.0",
|
||||
"repeat-string": "^1.6.1"
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 460 B |
|
@ -15,6 +15,8 @@ import { getCompetitionsList,
|
|||
AddTeam,
|
||||
ExitTeam,
|
||||
JoinTeam,
|
||||
SignCLA,
|
||||
GetKylinId,
|
||||
getStudents,
|
||||
getTeacher,
|
||||
SubmitTeam,
|
||||
|
@ -66,6 +68,8 @@ export interface CompetitionsType {
|
|||
AddTeam:Effect;
|
||||
ExitTeam:Effect;
|
||||
JoinTeam:Effect;
|
||||
SignCLA:Effect;
|
||||
GetKylinId:Effect;
|
||||
getStudents:Effect;
|
||||
getTeacher:Effect;
|
||||
SubmitTeam:Effect;
|
||||
|
@ -184,6 +188,16 @@ const CompetitionsModel: CompetitionsType = {
|
|||
const response = yield call(JoinTeam, payload);
|
||||
return response;
|
||||
},
|
||||
// 签署CLA协议
|
||||
*SignCLA({ payload, callback }, { call, put }) {
|
||||
const response = yield call(SignCLA, payload);
|
||||
return response;
|
||||
},
|
||||
// 获取kylin竞赛ID
|
||||
*GetKylinId({ payload, callback }, { call, put }) {
|
||||
const response = yield call(GetKylinId, payload);
|
||||
return response;
|
||||
},
|
||||
//查找老师 getTeacher
|
||||
*getTeacher({ payload, callback }, { call, put }) {
|
||||
const response = yield call(getTeacher, payload);
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
//1 2 3 排名数据样式
|
||||
import React, { useEffect, useRef, useState } from 'react'
|
||||
import {Card, Col, Button} from 'antd'
|
||||
import styles from './index.less'
|
||||
import ENV from '@/utils/env';
|
||||
import { Link } from 'umi';
|
||||
import env from '@/utils/env';
|
||||
import RenderHtml from '@/components/RenderHtml'
|
||||
|
||||
|
||||
interface RankItem{
|
||||
item:any
|
||||
index:any
|
||||
StaffDetail:any
|
||||
}
|
||||
const toChinesNum = (num: any) => {
|
||||
let changeNum = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; //changeNum[0] = "零"
|
||||
let unit = ["", "十", "百", "千", "万"];
|
||||
num = parseInt(num);
|
||||
let getWan = (temp: any) => {
|
||||
let strArr = temp.toString().split("").reverse();
|
||||
let newNum = "";
|
||||
for (var i = 0; i < strArr.length; i++) {
|
||||
newNum = (i == 0 && strArr[i] == 0 ? "" : (i > 0 && strArr[i] == 0 && strArr[i - 1] == 0 ? "" : changeNum[strArr[i]] + (strArr[i] == 0 ? unit[0] : unit[i]))) + newNum;
|
||||
}
|
||||
return newNum;
|
||||
}
|
||||
let overWan = Math.floor(num / 10000);
|
||||
let noWan: any = num % 10000;
|
||||
if (noWan.toString().length < 4) noWan = "0" + noWan;
|
||||
return overWan ? getWan(overWan) + "万" + getWan(noWan) : getWan(num);
|
||||
|
||||
}
|
||||
function RankingItem({item,index,StaffDetail}:RankItem){
|
||||
const [content,setcontent]=useState<any>(true);
|
||||
const [isopen,setisonen]=useState<any>(true);
|
||||
const divcontent=useRef<any>();
|
||||
return(
|
||||
<div style={{ border: '1px solid #E3EFFC', borderRadius: '2px', marginTop: 20 }}>
|
||||
<div style={{ padding: 10, display: 'flex',position:'relative' }}>
|
||||
<img src={env.IMG_SERVER +'/'+item?.pic} style={{ width: 220, height: 130, borderRadius: '4px' }} />
|
||||
<div style={{ marginLeft: 20,width:'75%' }}>
|
||||
<div style={{display:'flex',justifyContent:'space-between'}}>
|
||||
<span style={{ color: '#333333', fontWeight: 500, fontSize: '16px' }}>任务{toChinesNum(index+1)}:<span style={{color:'#333',fontWeight:'400'}}>{item?.name}</span></span>
|
||||
<span style={{color:'#9096A3'}}>关卡<span style={{color:'#333333',marginLeft:5}}>{item?.challenges_count}</span> </span>
|
||||
</div>
|
||||
|
||||
<div ref={divcontent} >
|
||||
<RenderHtml style={{maxHeight:content&&100}} value={item?.description} />
|
||||
</div>
|
||||
<div style={{textAlign:'center',color:'#145DFF',cursor:'pointer'}} onClick={()=>{
|
||||
setcontent(!content)
|
||||
}}>
|
||||
{content ? '阅读全文 ' : '收起全文 '}
|
||||
<i
|
||||
className={`iconfont font14 ${content
|
||||
? 'icon-jiantou9'
|
||||
: 'icon-changyongtubiao-xianxingdaochu-zhuanqu-'
|
||||
}`}
|
||||
></i>
|
||||
</div>
|
||||
|
||||
<div style={{marginTop:14,maxHeight:isopen&&58,overflow:'hidden'}}>
|
||||
{item?.challenges?.map((items:any,j:any)=>{
|
||||
return <div style={{marginTop:j===0?0:12}}>
|
||||
<i className="iconfont icon-shixunti2 c-light-primary font20"/>
|
||||
<span style={{marginLeft:10}}>第{j+1}关{items?.name}</span>
|
||||
</div>
|
||||
})}
|
||||
</div>
|
||||
<div style={{position:'absolute',bottom:14,right:10,color:'#145DFF',cursor:'pointer'}}>
|
||||
<span onClick={()=>{
|
||||
setisonen(!isopen)
|
||||
}}>{isopen?'展开':'收起'} <i
|
||||
className={`iconfont font14 ${isopen
|
||||
? 'icon-jiantou9'
|
||||
: 'icon-changyongtubiao-xianxingdaochu-zhuanqu-'
|
||||
}`}
|
||||
></i></span> {StaffDetail?.enrolled&&<Button onClick={()=>{
|
||||
window.open(`/shixuns/${item?.identifier}/challenges`)
|
||||
}} style={{marginLeft:30}} type="primary">开启挑战</Button>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}export default RankingItem
|
|
@ -0,0 +1,160 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Tabs, Input, Pagination, Table, Tooltip, Button, Spin } from 'antd'
|
||||
const { TabPane } = Tabs;
|
||||
import RankingNull from './RankingNuLL'
|
||||
import RenderHtml from '@/components/RenderHtml';
|
||||
import MarkdownEditor from '@/components/markdown-editor';
|
||||
import RankingList from './RankingList';
|
||||
import Fetch from '@/utils/fetch';
|
||||
import { useParams } from 'umi';
|
||||
import moment from 'moment';
|
||||
import env from '@/utils/env';
|
||||
import Challitems from './Challitems'
|
||||
|
||||
interface Ranking {
|
||||
ChartRules: any
|
||||
ItemData: any
|
||||
getCharts: any
|
||||
Selectkey: any
|
||||
getChartRules: any
|
||||
userinfo: any
|
||||
Editable: any
|
||||
dispatch: any
|
||||
HeaderDetail: any
|
||||
StaffDetail: any
|
||||
loading: boolean
|
||||
|
||||
}
|
||||
|
||||
function Ranking({loading, ChartRules, ItemData, getCharts, Selectkey, HeaderDetail, getChartRules, userinfo, Editable, dispatch, StaffDetail }: Ranking) {
|
||||
const [isUpdate, setIsupdate] = useState(false);
|
||||
const [defaultValue, setDefaultValue] = useState('');
|
||||
const [ClickButton, setClickButton] = useState(true);
|
||||
const [item, setItem] = useState<any>();
|
||||
const [items, setItems] = useState<any>();
|
||||
const { identifier } = useParams();
|
||||
let [params, setparams] = useState<any>({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
})
|
||||
let [openitem,setopenitem]=useState<any>();
|
||||
useEffect(() => {
|
||||
//进入初始化状态为第一个
|
||||
if (ClickButton&&ChartRules?.stages?.[0]) {
|
||||
getDate()
|
||||
}
|
||||
}, [ChartRules?.stages?.[0]])
|
||||
|
||||
const getDate=async()=>{
|
||||
let data = ChartRules?.stages?.[0];
|
||||
setItem(data);
|
||||
let datas = ChartRules?.stages?.[0]?.children?.[0];
|
||||
setItems(datas);
|
||||
params.id = datas?.id || data?.id,
|
||||
setparams({ ...params })
|
||||
await getCharts(
|
||||
{
|
||||
...params,
|
||||
stage_id: params.id
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
{ChartRules?.stages?.length > 0 ? null : <RankingNull />}
|
||||
|
||||
{ChartRules?.stages?.length > 0 && <Tabs tabBarStyle={{ height: 65, marginLeft: 35, marginRight: 30 }} animated={true} onChange={async (e) => {
|
||||
setIsupdate(false)
|
||||
let data = ChartRules?.stages?.filter(item => parseInt(e) === parseInt(item?.id))[0];
|
||||
let datas = data?.children?.[0];
|
||||
setItems(datas);
|
||||
setItem(data);
|
||||
setDefaultValue(ChartRules.rule_contents?.filter(item => parseInt(item.competition_stage_id) === parseInt(data?.id))?.[0]?.['content'] || '')
|
||||
params.page = 1,
|
||||
params.limit = 10,
|
||||
params.id = datas?.id || e,
|
||||
setparams({ ...params })
|
||||
await getCharts(
|
||||
{
|
||||
...params
|
||||
});
|
||||
|
||||
}}>
|
||||
{ChartRules && ChartRules.stages.map((item: any, index: any) => {
|
||||
return (
|
||||
<TabPane tab={item.name} key={item.id === null ? 0 : item.id}>
|
||||
|
||||
</TabPane>
|
||||
)
|
||||
|
||||
})}
|
||||
|
||||
</Tabs>}
|
||||
|
||||
{item?.children?.length > 0 && <Tabs activeKey={items?.id + ''} tabBarStyle={{ height: 65, marginLeft: 35, marginRight: 30 }} onChange={async(e) => {
|
||||
let data = item?.children?.filter(item => parseInt(e) === parseInt(item?.id))[0];
|
||||
setItems(data);
|
||||
params.page = 1,
|
||||
params.limit = 10,
|
||||
params.id = e,
|
||||
setparams({ ...params })
|
||||
await getCharts(
|
||||
{
|
||||
...params
|
||||
});
|
||||
|
||||
//获取参数
|
||||
}}>
|
||||
{item?.children?.map((item: any, index: any) => {
|
||||
return <TabPane tab={item.name} key={item.id === null ? 0 : item.id}>
|
||||
|
||||
</TabPane>
|
||||
})}
|
||||
</Tabs>}
|
||||
|
||||
<div style={{ height: 10, background: '#F5F5F5' }}>
|
||||
|
||||
</div>
|
||||
<div style={{ padding: "20px 30px" }}>
|
||||
<div style={{display:'flex',justifyContent:'space-between'}}>
|
||||
<span style={{color:'#9096A3'}}>作品提交时间
|
||||
<span style={{color:'#333333',marginLeft:5}}>{ItemData?.start_time}~{ItemData?.end_time}</span>
|
||||
</span>
|
||||
<span style={{color:'#9096A3'}}>成绩来源<span style={{color:'#333333',marginLeft:5}}>{ItemData?.score_source===0?'经验值':'预测准确率'}</span> </span>
|
||||
</div>
|
||||
|
||||
<Spin spinning={loading}>
|
||||
{ItemData?.results?.map((item: any, index: any) => {
|
||||
return (<Challitems StaffDetail={StaffDetail} item={item} index={index}/>)
|
||||
})}
|
||||
</Spin>
|
||||
|
||||
|
||||
<Pagination
|
||||
total={ItemData?.total_count}
|
||||
pageSize={10}
|
||||
hideOnSinglePage
|
||||
style={{ marginTop: 40, textAlign: 'center' }}
|
||||
showSizeChanger={false}
|
||||
current={params.page}
|
||||
onChange={(page: any, pageSize: any) => {
|
||||
params.page = page,
|
||||
setparams({ ...params })
|
||||
getCharts(
|
||||
{
|
||||
...params
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
{/* {ItemData?.teams?.length>0?<RankingList ItemData={ItemData}/>:null} */}
|
||||
|
||||
</div>
|
||||
)
|
||||
} export default Ranking
|
|
@ -0,0 +1,198 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Tabs, Input, Pagination, Table, Tooltip, Skeleton, Spin,Dropdown } from 'antd'
|
||||
const { TabPane } = Tabs;
|
||||
import RankingNull from './RankingNuLL'
|
||||
import RenderHtml from '@/components/RenderHtml';
|
||||
import MarkdownEditor from '@/components/markdown-editor';
|
||||
import RankingList from './RankingList';
|
||||
import Fetch from '@/utils/fetch';
|
||||
import { useParams } from 'umi';
|
||||
import moment from 'moment';
|
||||
import env from '@/utils/env';
|
||||
|
||||
interface Ranking {
|
||||
ChartRules: any
|
||||
ItemData: any
|
||||
getCharts: any
|
||||
Selectkey: any
|
||||
getChartRules: any
|
||||
userinfo: any
|
||||
Editable: any
|
||||
dispatch: any
|
||||
HeaderDetail: any
|
||||
StaffDetail: any
|
||||
loading: boolean
|
||||
|
||||
}
|
||||
|
||||
function Ranking({loading, ChartRules, ItemData, getCharts, Selectkey, HeaderDetail, getChartRules, userinfo, Editable, dispatch, StaffDetail }: Ranking) {
|
||||
const [isUpdate, setIsupdate] = useState(false);
|
||||
const [defaultValue, setDefaultValue] = useState('');
|
||||
const [ClickButton, setClickButton] = useState(true);
|
||||
const [item, setItem] = useState<any>();
|
||||
const [items, setItems] = useState<any>();
|
||||
const { identifier } = useParams();
|
||||
let [params, setparams] = useState<any>({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
sort:'desc',
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
//进入初始化状态为第一个
|
||||
if (ClickButton&&ChartRules?.stages?.[0]) {
|
||||
getDate()
|
||||
}
|
||||
}, [ChartRules?.stages?.[0]])
|
||||
|
||||
const getDate=async()=>{
|
||||
let data = ChartRules?.stages?.[0];
|
||||
setItem(data);
|
||||
let datas = ChartRules?.stages?.[0]?.children?.[0];
|
||||
setItems(datas);
|
||||
params.id = datas?.id || data?.id,
|
||||
setparams({ ...params })
|
||||
await getCharts(
|
||||
{
|
||||
...params,
|
||||
stage_id: params.id
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
{ChartRules?.stages?.length > 0 ? null : <RankingNull />}
|
||||
|
||||
{ChartRules?.stages?.length > 0 && <Tabs tabBarStyle={{ height: 65, marginLeft: 35, marginRight: 30 }} animated={true} onChange={async (e) => {
|
||||
setIsupdate(false)
|
||||
let data = ChartRules?.stages?.filter(item => parseInt(e) === parseInt(item?.id))[0];
|
||||
let datas = data?.children?.[0];
|
||||
setItems(datas);
|
||||
setItem(data);
|
||||
setDefaultValue(ChartRules.rule_contents?.filter(item => parseInt(item.competition_stage_id) === parseInt(data?.id))?.[0]?.['content'] || '')
|
||||
params.page = 1,
|
||||
params.limit = 10,
|
||||
params.id = datas?.id || e,
|
||||
setparams({ ...params })
|
||||
await getCharts(
|
||||
{
|
||||
...params
|
||||
});
|
||||
|
||||
}}>
|
||||
{ChartRules && ChartRules.stages.map((item: any, index: any) => {
|
||||
return (
|
||||
<TabPane tab={item.name} key={item.id === null ? 0 : item.id}>
|
||||
|
||||
</TabPane>
|
||||
)
|
||||
|
||||
})}
|
||||
|
||||
</Tabs>}
|
||||
|
||||
{item?.children?.length > 0 && <Tabs activeKey={items?.id + ''} onChange={async(e) => {
|
||||
let data = item?.children?.filter(item => parseInt(e) === parseInt(item?.id))[0];
|
||||
setItems(data);
|
||||
params.page = 1,
|
||||
params.limit = 10,
|
||||
params.id = e,
|
||||
setparams({ ...params })
|
||||
await getCharts(
|
||||
{
|
||||
...params
|
||||
});
|
||||
|
||||
//获取参数
|
||||
}}>
|
||||
{item?.children?.map((item: any, index: any) => {
|
||||
return <TabPane tab={item.name} key={item.id === null ? 0 : item.id}>
|
||||
|
||||
</TabPane>
|
||||
})}
|
||||
</Tabs>}
|
||||
|
||||
<div style={{ height: 10, background: '#F5F5F5' }}>
|
||||
|
||||
</div>
|
||||
<div style={{ padding: "20px 30px" }}>
|
||||
<span style={{cursor:'pointer',marginRight:20}} onClick={()=>{
|
||||
params.page = 1,
|
||||
params.sort=params.sort==='desc'?'asc':'desc';
|
||||
setparams({ ...params })
|
||||
getCharts(
|
||||
{
|
||||
...params
|
||||
});
|
||||
}}>
|
||||
按提交时间{params.sort==='asc'?'正':'倒'}序排序 <i
|
||||
className={`iconfont font14 ${params.sort==='asc'
|
||||
? 'icon-jiantou9'
|
||||
: 'icon-changyongtubiao-xianxingdaochu-zhuanqu-'
|
||||
}`}
|
||||
></i>
|
||||
</span> <Input.Search onSearch={(e) => {
|
||||
params.page = 1,
|
||||
params.search = e,
|
||||
setparams({ ...params })
|
||||
getCharts(
|
||||
{
|
||||
...params
|
||||
});
|
||||
}} style={{ width: '82%' }} placeholder='输入人员/战队名称进行搜索' />
|
||||
<Spin spinning={loading}>
|
||||
{ItemData?.results?.map((item: any, index: any) => {
|
||||
return (<div style={{ border: '1px solid #E3EFFC', height: 100, borderRadius: '2px 2px 0px 0px', marginTop: index === 0 ? 14 : 30 }}>
|
||||
<div style={{ height: 60, padding: 10, display: 'flex', alignItems: 'center' }}>
|
||||
<img src={env.IMG_SERVER + '/images/' + item?.image_url} style={{ width: 40, height: 40, borderRadius: '50%' }} />
|
||||
<div style={{ marginLeft: 10 }}>
|
||||
<span style={{ color: '#333333', fontWeight: 500, fontSize: '16px' }}>{item?.user_name}</span>
|
||||
<span style={{ color: '#999999', fontWeight: 400, fontSize: '14px', marginLeft: 60 }}>所属战队<span style={{ marginLeft: 10, color: '#333' }}>{item?.team_name || '- -'}</span></span>
|
||||
<span style={{ color: '#333333', fontWeight: 400, fontSize: '14px', marginLeft: 40 }}>学校 <span style={{ marginLeft: 10, color: '#333' }}>{item?.school_name || '- -'}</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ background: '#EEF2F8', height: 40, borderRadius: '0px 0px 2px 2px', paddingLeft: 60, paddingRight: 40, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<div>
|
||||
<span style={{ color: '#666666', fontSize: '12px' }}>提交时间:{item?.created_at}</span>
|
||||
<span style={{ color: '#666666', fontSize: '12px', margin: '0px 40px' }}>消耗内存:{item?.ts_mem || '- -'}MB</span>
|
||||
<span style={{ color: '#666666', fontSize: '12px' }}>代码执行时间:{item?.ts_time || '- -'}秒</span>
|
||||
</div>
|
||||
<a style={{ display: 'flex', alignItems: 'center' }} href={`/tasks/${item?.game_identifier}`} target="_blank">
|
||||
<i className="iconfont icon-chakandaima" style={{ marginRight: 4 }} />
|
||||
<span style={{ lineHeight: '14px' }}>查看代码</span>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>)
|
||||
})}
|
||||
</Spin>
|
||||
|
||||
|
||||
<Pagination
|
||||
total={ItemData?.total_count}
|
||||
pageSize={10}
|
||||
hideOnSinglePage
|
||||
style={{ marginTop: 40, textAlign: 'center' }}
|
||||
showSizeChanger={false}
|
||||
current={params.page}
|
||||
onChange={(page: any, pageSize: any) => {
|
||||
params.page = page,
|
||||
setparams({ ...params })
|
||||
getCharts(
|
||||
{
|
||||
...params
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
{/* {ItemData?.teams?.length>0?<RankingList ItemData={ItemData}/>:null} */}
|
||||
|
||||
</div>
|
||||
)
|
||||
} export default Ranking
|
|
@ -24,7 +24,6 @@
|
|||
font-weight: 400;
|
||||
color: #05101a;
|
||||
line-height: 30px;
|
||||
margin-top: 35px;
|
||||
}
|
||||
|
||||
.timesize {
|
||||
|
@ -41,7 +40,8 @@
|
|||
background: rgba(76, 172, 255, 1);
|
||||
border-radius: 4px;
|
||||
font-size: 24px;
|
||||
width: 100%;
|
||||
width: 156px;
|
||||
border-radius: 25px !important;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,7 @@ import {
|
|||
} from 'umi';
|
||||
import styles from './index.less';
|
||||
import AuthModel from '@/components/AuthenticationModel'
|
||||
import AddSubmitModel from './AddSubmitModel';
|
||||
import { Base64 } from 'js-base64';
|
||||
import AddSubmitModel from './AddSubmitModel'
|
||||
import { Breadcrumb, Button, Menu, message, Spin, Modal } from 'antd';
|
||||
//查看内容
|
||||
import SeeItem from './SeeItem';
|
||||
|
@ -22,13 +21,18 @@ import UpItem from './Update';
|
|||
import RanKing from './Ranking'//排行榜
|
||||
import Award from './AwardPdf' //获奖证书
|
||||
import ENV from '@/utils/env';
|
||||
import { getCookie, openNewWindow,setCookie,setDocumentTitle } from '@/utils/util';
|
||||
import { handleVerifyLogin, handleVerify , handleProfleCompletedModal } from '@/utils/verifyLogin';
|
||||
import { openNewWindow,setDocumentTitle } from '@/utils/util';
|
||||
import { handleVerifyLogin, handleVerify } from '@/utils/verifyLogin';
|
||||
import { isSuperAdmin } from '@/utils/authority';
|
||||
import SubmitResult from './SubmitResult';
|
||||
import SubCompetition from './components/SubCompetition';
|
||||
import SubmitResult from './SubmitResult'
|
||||
import MakeItem from './MakeItem'
|
||||
import Entrance from './Entrance'
|
||||
import QR from './mCode.png';
|
||||
import InitGitLink from './components/InitGitLink';
|
||||
import JoinTeam from '../Entered/Enteredmodel/JoinModel'
|
||||
import AddteamsModel from '../Entered/Enteredmodel/Addteams';
|
||||
import PhoneModal from '../components/PhoneModal'
|
||||
import env from '@/utils/env';
|
||||
import ClaModal from '../components/ClaModal';
|
||||
|
||||
interface PageProps extends ConnectProps {
|
||||
globalSetting: GlobalSettingModelState;
|
||||
|
@ -74,44 +78,52 @@ const competitionDetails: FC<PageProps> = ({
|
|||
const [TabResults, setTabResults] = useState<any>([]);
|
||||
//弹窗
|
||||
const [isshowType, setisshowType] = useState<any>();
|
||||
const [itLoading, setItLoading] = useState(true);
|
||||
|
||||
const [showmake,setshowmake]=useState<any>(false);
|
||||
const [entrance,setentrance]=useState<any>(false)
|
||||
|
||||
|
||||
const [isshowmodal,setisshowmodal]=useState<any>(false);
|
||||
const [isAddmodel, setIsAddmodel] = useState<any>(false) //新建战队
|
||||
const [isJoin, setJoin] = useState<any>(false) //加入战队
|
||||
const [isClick,setIsClick]=useState<any>(true)//增加参数 防止点击过快 多次调用
|
||||
const [showphone,setshowphone]=useState<any>(false);
|
||||
const [isopen,setisopen]=useState<any>(false);
|
||||
const [datas,setdatas]=useState<any>('');
|
||||
const [visible,setVisible]=useState<any>(false);
|
||||
|
||||
const [ subComShow , setSubComShow ] = useState<any>(false);
|
||||
const [ subGitlinkShow , setSubGitlinkShow ] = useState<any>(false);
|
||||
const [ subComList , setSubComList] = useState<any>([]);
|
||||
const loction = useLocation();
|
||||
const see = useRef(null);
|
||||
|
||||
useEffect(()=>{
|
||||
if(user?.userInfo?.is_new){
|
||||
setSubGitlinkShow(true);
|
||||
}
|
||||
},[user?.userInfo])
|
||||
|
||||
const see = useRef(null)
|
||||
useEffect(() => {
|
||||
async function init() {
|
||||
const res = await dispatch({
|
||||
type: 'competitions/getHeader',
|
||||
payload: {
|
||||
identifier: identifier
|
||||
}
|
||||
})
|
||||
setHeaderDetail(res)
|
||||
setDocumentTitle(res?.name || '竞赛');
|
||||
|
||||
setStaffDetail(await dispatch({
|
||||
type: 'competitions/getStaff',
|
||||
payload: {
|
||||
identifier: identifier
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
if (identifier) {
|
||||
init();
|
||||
//调用默认加载第一条数据
|
||||
}
|
||||
setDocumentTitle('竞赛')
|
||||
}, [identifier])
|
||||
|
||||
|
||||
async function init() {
|
||||
setStaffDetail(await dispatch({
|
||||
type: 'competitions/getStaff',
|
||||
payload: {
|
||||
identifier: identifier
|
||||
}
|
||||
}))
|
||||
const res = await dispatch({
|
||||
type: 'competitions/getHeader',
|
||||
payload: {
|
||||
identifier: identifier
|
||||
}
|
||||
})
|
||||
setHeaderDetail(res)
|
||||
setDocumentTitle(res?.name || '竞赛')
|
||||
}
|
||||
useEffect(() => {
|
||||
// console.log('--------',parseInt(loction?.query?.type)===1);
|
||||
|
||||
setisshowType(parseInt(loction?.query?.type) === 1)
|
||||
}, [loction])
|
||||
|
||||
|
@ -133,18 +145,33 @@ const competitionDetails: FC<PageProps> = ({
|
|||
setSeleckjey(item.id);
|
||||
Selectkey = item.id;
|
||||
setMenuItem(item);
|
||||
let data = await dispatch({
|
||||
type: 'competitions/getItem',
|
||||
payload: {
|
||||
url: item.module_url
|
||||
}
|
||||
})
|
||||
let data ;
|
||||
if(item.module_type==='entrance'){
|
||||
data = await dispatch({
|
||||
type: 'competitions/getItem',
|
||||
payload: {
|
||||
url: item.module_url,
|
||||
module_type:'entrance'
|
||||
}
|
||||
})
|
||||
}else{
|
||||
data = await dispatch({
|
||||
type: 'competitions/getItem',
|
||||
payload: {
|
||||
url: item.module_url,
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
setIsRanKing(false)
|
||||
setIsAward(false)
|
||||
setMdTab(false)
|
||||
setItemData(data);
|
||||
setshowmake(false);
|
||||
setentrance(false)
|
||||
|
||||
setModelType(item.module_type);
|
||||
|
||||
if (item.module_type === "chart") {
|
||||
setIsRanKing(true)
|
||||
setIssee(false);
|
||||
|
@ -157,44 +184,39 @@ const competitionDetails: FC<PageProps> = ({
|
|||
} else if (item.module_type === "md_tab") {
|
||||
setMdTab(true);
|
||||
setIssee(false);
|
||||
localStorage.setItem('issee','2');
|
||||
setIsRanKing(false)
|
||||
setIsAward(false);
|
||||
// getChartRules();
|
||||
getTabResults();
|
||||
} else {
|
||||
} else if(item.module_type === "md_shixun"){
|
||||
setshowmake(true);
|
||||
setIssee(false);
|
||||
getTabResults()
|
||||
} else if(item.module_type==='entrance'){
|
||||
setentrance(true);
|
||||
setIssee(false);
|
||||
getTabResults()
|
||||
} else {
|
||||
setIssee(true);
|
||||
localStorage.setItem('issee','1');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function gotocourse(e: any, item: any, url: string) {
|
||||
e.stopPropagation();
|
||||
|
||||
// if(HeaderDetail.teacher_need_phone||HeaderDetail.member_need_phone){
|
||||
// setshowphone(true)
|
||||
// return
|
||||
// }
|
||||
|
||||
if (!handleVerify(dispatch)) {
|
||||
return;
|
||||
}
|
||||
// 判断是否完善资料,未完善资料需弹出提示框
|
||||
if(!handleProfleCompletedModal()){
|
||||
return;
|
||||
}
|
||||
if(globalSetting?.setting?.sub_competitions){
|
||||
let subArr = globalSetting?.setting?.sub_competitions;
|
||||
if(subArr.length>0){
|
||||
let filterArr = subArr.filter((i:any)=>i.identifier === item.identifier);
|
||||
|
||||
let filterlist = filterArr && filterArr.length >0 && filterArr[0].list;
|
||||
|
||||
if(filterArr && filterArr.length >0 && (filterlist && filterlist.length>1)){
|
||||
setSubComShow(true);
|
||||
setSubComList(filterArr[0]);
|
||||
return;
|
||||
}else if(filterArr && filterArr.length >0 && (filterlist && filterlist.length===1)){
|
||||
window.location.href=filterArr[0].list[0].url;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HeaderDetail?.is_authentication && !user?.userInfo?.authentication) {
|
||||
dispatch({
|
||||
type: 'shixunsDetail/setActionTabs',
|
||||
|
@ -204,11 +226,10 @@ const competitionDetails: FC<PageProps> = ({
|
|||
})
|
||||
return
|
||||
}
|
||||
// if(item.identifier === "gcc-courses-2022"){
|
||||
// let arr = HeaderDetail.competition_modules?.filter((item:any)=>item.name === "赛事发布");
|
||||
// arr && arr.length > 0 && getrightdatas(arr[0]);
|
||||
// return;
|
||||
// }
|
||||
if (HeaderDetail?.enroll_url) {
|
||||
openNewWindow(HeaderDetail?.enroll_url);
|
||||
return
|
||||
}
|
||||
if (url === "ismodel") {
|
||||
if (item.member_of_course === true) {
|
||||
openNewWindow(`/classrooms/${item.course_id}`)
|
||||
|
@ -224,36 +245,69 @@ const competitionDetails: FC<PageProps> = ({
|
|||
student: 1
|
||||
}
|
||||
});
|
||||
if (result.statue === 0) {
|
||||
if (result.status === 0) {
|
||||
openNewWindow(`/classrooms/${item.course_id}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (url === "personal") {
|
||||
if (item.enroll_ended === true) {
|
||||
//已截止
|
||||
message.info(`报名已截止`);
|
||||
return;
|
||||
}
|
||||
if (StaffDetail.enrolled === true) {
|
||||
message.info(`你已经报名,不能重复报名!`);
|
||||
return;
|
||||
}
|
||||
const competitionTeamsresult = await dispatch({
|
||||
type: 'competitions/competitionTeams',
|
||||
payload: {
|
||||
identifier: item.identifier
|
||||
|
||||
if (StaffDetail.enrolled === true) {
|
||||
openNewWindow(url)
|
||||
return;
|
||||
}
|
||||
})
|
||||
if (competitionTeamsresult) {
|
||||
message.info('报名成功,预祝您夺得桂冠!')
|
||||
}
|
||||
} else {
|
||||
openNewWindow(url)
|
||||
// setisshowmodal(true);
|
||||
if(!user?.userInfo?.sign_cla){
|
||||
setVisible(true);
|
||||
return;
|
||||
}else{
|
||||
setisshowmodal(true);
|
||||
}
|
||||
// if (url === "personal") {
|
||||
// if (item.enroll_ended === true) {
|
||||
// //已截止
|
||||
// message.info(`报名已截止`);
|
||||
// return;
|
||||
// }
|
||||
// if (StaffDetail.enrolled === true) {
|
||||
// message.info(`你已经报名,不能重复报名!`);
|
||||
// return;
|
||||
// }
|
||||
// const competitionTeamsresult = await dispatch({
|
||||
// type: 'competitions/competitionTeams',
|
||||
// payload: {
|
||||
// identifier: item.identifier
|
||||
// }
|
||||
// })
|
||||
// if (competitionTeamsresult) {
|
||||
|
||||
// message.info('报名成功,预祝您夺得桂冠!')
|
||||
// }
|
||||
|
||||
// } else {
|
||||
// openNewWindow(url)
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
useEffect(()=>{
|
||||
if(user?.userInfo?.login){
|
||||
getId();
|
||||
}
|
||||
},[user?.userInfo])
|
||||
|
||||
async function getId() {
|
||||
let data =await dispatch({
|
||||
type: 'competitions/GetKylinId',
|
||||
payload: {
|
||||
owner:user?.userInfo?.login
|
||||
}
|
||||
})
|
||||
// data.data ||
|
||||
let a =["009"];
|
||||
console.log(a);
|
||||
let filter = a.filter((i:any)=>i === identifier.toString());
|
||||
console.log(filter && filter.length>0?true:false);
|
||||
}
|
||||
|
||||
async function getChartRules() {
|
||||
await setChartRules(
|
||||
|
@ -277,6 +331,35 @@ const competitionDetails: FC<PageProps> = ({
|
|||
setItemData(data);
|
||||
}
|
||||
|
||||
async function getshixunCharts(params: any) {
|
||||
setItLoading(true)
|
||||
let data = await dispatch({
|
||||
type: 'competitions/Results',
|
||||
payload: {
|
||||
identifier: identifier,
|
||||
stage_id: params?.id,
|
||||
...params
|
||||
}
|
||||
})
|
||||
setItemData(data);
|
||||
setItLoading(false)
|
||||
}
|
||||
|
||||
async function getEntrance(params: any) {
|
||||
setItLoading(true)
|
||||
let data = await dispatch({
|
||||
type: 'competitions/Results',
|
||||
payload: {
|
||||
identifier: identifier,
|
||||
stage_id: params?.id,
|
||||
module_type:'entrance',
|
||||
...params
|
||||
}
|
||||
})
|
||||
setItemData(data);
|
||||
setItLoading(false)
|
||||
}
|
||||
|
||||
async function getResults(id: any) {
|
||||
let data = await dispatch({
|
||||
type: 'competitions/Results',
|
||||
|
@ -285,10 +368,13 @@ const competitionDetails: FC<PageProps> = ({
|
|||
stage_id: id
|
||||
}
|
||||
})
|
||||
setItemData(data);
|
||||
if(localStorage.getItem('issee')==='1') return
|
||||
setItemData(data);
|
||||
}
|
||||
|
||||
|
||||
async function getTabResults() {
|
||||
|
||||
setTabResults(
|
||||
await dispatch({
|
||||
type: 'competitions/TabResults',
|
||||
|
@ -307,6 +393,7 @@ const competitionDetails: FC<PageProps> = ({
|
|||
payload: {
|
||||
identifier: identifier,
|
||||
user_id: user?.userInfo?.user_id,
|
||||
//user_id:39416
|
||||
}
|
||||
})
|
||||
setPrize(data);
|
||||
|
@ -317,21 +404,116 @@ const competitionDetails: FC<PageProps> = ({
|
|||
type: 'competitions/Accounts',
|
||||
payload: {
|
||||
id: user?.userInfo?.user_id,
|
||||
//user_id:39416
|
||||
}
|
||||
})
|
||||
SetAccounts(data);
|
||||
}
|
||||
|
||||
|
||||
async function addTeams(name: any) {
|
||||
if(!isClick){
|
||||
return
|
||||
}
|
||||
setIsClick(false);
|
||||
if (isadd()) {
|
||||
return
|
||||
}
|
||||
let data = await dispatch({
|
||||
type: 'competitions/AddTeam',
|
||||
payload: {
|
||||
identifier: identifier,
|
||||
name: name
|
||||
}
|
||||
})
|
||||
if (data && data.status === 0) {
|
||||
setdatas(data)
|
||||
// setisopen(true)
|
||||
init()
|
||||
setIsAddmodel(false);
|
||||
}else{
|
||||
setIsClick(true);
|
||||
}
|
||||
}
|
||||
function isadd() {
|
||||
//判断 如果不符合条件 不能加入竞赛
|
||||
if (user?.userInfo?.is_teacher) {
|
||||
if (StaffDetail?.teacher_staff?.mutiple_limited) {
|
||||
if (StaffDetail?.enrolled) {
|
||||
message.info('你已经报名,不能重复报名')
|
||||
setIsClick(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (StaffDetail?.member_staff?.mutiple_limited) {
|
||||
if (StaffDetail?.enrolled) {
|
||||
message.info('你已经报名,不能重复报名')
|
||||
setIsClick(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//判断竞赛是否关闭
|
||||
if (StaffDetail?.enroll_ended) {
|
||||
message.info('报名已截止,无需报名')
|
||||
setIsClick(true);
|
||||
return true;
|
||||
}
|
||||
//禁止老师or学生报名
|
||||
if (user?.userInfo?.is_teacher) {
|
||||
if (!StaffDetail.teacher_staff) {
|
||||
message.info('已禁止老师报名')
|
||||
setIsClick(true);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (!StaffDetail?.member_staff) {
|
||||
message.info('已禁止学生报名')
|
||||
setIsClick(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//加入战队
|
||||
async function JoinTeams(name: any) {
|
||||
if(!isClick){
|
||||
return
|
||||
}
|
||||
//判断 如果不符合条件 不能加入竞赛
|
||||
if (isadd()) {
|
||||
return
|
||||
}
|
||||
setIsClick(false);
|
||||
let data = await dispatch({
|
||||
type: 'competitions/JoinTeam',
|
||||
payload: {
|
||||
identifier: identifier,
|
||||
invite_code: name
|
||||
}
|
||||
})
|
||||
if (data && data.status === 0) {
|
||||
// setisopen(true)
|
||||
setdatas(data)
|
||||
setJoin(false);
|
||||
setIsClick(true);
|
||||
init()
|
||||
}else{
|
||||
setIsClick(true);
|
||||
}
|
||||
}
|
||||
// console.log('-------',useLocation().query.type);
|
||||
|
||||
|
||||
return (
|
||||
<div className={"edu-container minH500"}>
|
||||
<SubCompetition visible={subComShow} onClose={()=>setSubComShow(false)} filterlist={subComList}/>
|
||||
<InitGitLink visible={subGitlinkShow} onClose={()=>setSubGitlinkShow(false)}/>
|
||||
<Breadcrumb className="mt10" separator=">">
|
||||
<Breadcrumb.Item><Link to={"/competitions/index"}>在线竞赛</Link></Breadcrumb.Item>
|
||||
<Breadcrumb.Item>{HeaderDetail.name}{HeaderDetail.sub_title ? '-' + HeaderDetail.sub_title : null}</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
|
||||
<div className={"mt10 p12"} style={{ display: 'flex', background: '#fff', position: 'relative' }} >
|
||||
<div className={"mt10"} style={{ display: 'flex', background: '#fff', position: 'relative',padding:'20px 12px' }} >
|
||||
|
||||
<Spin spinning={loading.effects['competitions/getHeader']} >
|
||||
<div style={{ height: '355px', width: "800px" }}>
|
||||
|
@ -346,40 +528,50 @@ const competitionDetails: FC<PageProps> = ({
|
|||
|
||||
|
||||
|
||||
<div style={{ marginLeft: '10px', width: '400px' }}>
|
||||
{HeaderDetail.competition_status === 'ended' ? <img className={styles.commonimg} src={`${ENV.IMG_SERVER}/images/educoder/competitions/groups1.png`} /> : null}
|
||||
<div style={{ marginLeft: '20px', width: '400px' }}>
|
||||
{/* {HeaderDetail.competition_status === 'ended' ? <img className={styles.commonimg} src={`${ENV.IMG_SERVER}/images/educoder/competitions/groups1.png`} /> : null}
|
||||
{HeaderDetail.competition_status === 'nearly_published' ? <img className={styles.commonimg} src={`${ENV.IMG_SERVER}/images/educoder/competitions/groups2.png`} /> : null}
|
||||
{HeaderDetail.competition_status === 'progressing' ? <img className={styles.commonimg} src={`${ENV.IMG_SERVER}/images/educoder/competitions/groups3.png`} /> : null}
|
||||
<p className={`${styles.titlesize}`}>{HeaderDetail.name}{HeaderDetail.sub_title ? '-' + HeaderDetail.sub_title : null}</p>
|
||||
<p className={styles.timesize}><span style={{ color: '#9b9b9b' }}>竞赛时间:</span>{HeaderDetail.start_time}~{HeaderDetail.end_time}</p>
|
||||
<p className={styles.timesize}><span style={{ color: '#9b9b9b' }}>报名截止时间:</span>{HeaderDetail.enroll_end_time}</p>
|
||||
<p style={{ display: 'flex', justifyContent: 'space-around' }}>
|
||||
{!!HeaderDetail?.bonus && <span>奖金 <br /><span style={{ fontSize: '24px' }}>¥{parseInt(HeaderDetail && HeaderDetail.bonus).toLocaleString()}</span></span>}
|
||||
<span>浏览数 <br /><span style={{ fontSize: '24px' }}>{parseInt(HeaderDetail && HeaderDetail.visits_count).toLocaleString()}</span></span>
|
||||
<span>报名数 <br /><span style={{ fontSize: '24px' }}>{parseInt(HeaderDetail && HeaderDetail.member_count).toLocaleString()}</span></span>
|
||||
{HeaderDetail.competition_status === 'progressing' ? <img className={styles.commonimg} src={`${ENV.IMG_SERVER}/images/educoder/competitions/groups3.png`} /> : null} */}
|
||||
<p className={`${styles.titlesize}`} >{HeaderDetail.name}{HeaderDetail.sub_title ? '-' + HeaderDetail.sub_title : null}</p>
|
||||
<p style={{ display: 'flex', justifyContent: 'space-between', marginRight: 18 }}>
|
||||
{ <span style={{ display: 'flex', flexDirection:'column', alignItems:'center' }}><span>奖金</span>{!!HeaderDetail?.bonus ?<span style={{ fontSize: '24px' }}>¥{parseInt(HeaderDetail && HeaderDetail.bonus).toLocaleString()}</span>:<span style={{ fontSize: '24px' }}>暂无</span>}</span>}
|
||||
<span style={{ display: 'flex', flexDirection:'column', alignItems:'center' }}><span>浏览</span><span style={{ fontSize: '24px' }}>{parseInt(HeaderDetail && HeaderDetail.visits_count).toLocaleString()}</span></span>
|
||||
<span style={{ display: 'flex', flexDirection:'column', alignItems:'center' }}><span>报名</span><span style={{ fontSize: '24px' }}>{parseInt(HeaderDetail && HeaderDetail.member_count).toLocaleString()}</span></span>
|
||||
</p>
|
||||
{
|
||||
HeaderDetail.competition_status === "ended" ?
|
||||
<Button type="primary" className={styles.buttonsize} disabled={true} >已结束</Button> : null
|
||||
}
|
||||
{HeaderDetail.competition_status === 'nearly_published' ?
|
||||
<Button type="primary" className={styles.buttonsize} disabled={true} >未发布</Button> : null
|
||||
}
|
||||
{
|
||||
HeaderDetail.competition_status !== 'nearly_published' && HeaderDetail.enroll_end && HeaderDetail.competition_status !== 'ended' ?
|
||||
<Button type="primary" className={styles.buttonsize} disabled={true} >报名截止</Button> : null
|
||||
}
|
||||
{/* */}
|
||||
{HeaderDetail.competition_status === 'progressing' && HeaderDetail.enroll_end != true ? <Button type="primary" disabled={StaffDetail.enrolled && !HeaderDetail.need_attachment} className={styles.buttonsize} style={{fontSize:"18px"}} onClick={
|
||||
(e) => {
|
||||
if (StaffDetail.enrolled && HeaderDetail.need_attachment) {
|
||||
see.current?.handleVisible()
|
||||
return
|
||||
}
|
||||
gotocourse(e, HeaderDetail, HeaderDetail.mode === 2 ? 'ismodel' : HeaderDetail.personal ? 'personal' : `/competitions/index/${HeaderDetail.identifier}/enroll`)
|
||||
<p className={styles.timesize} style={{marginTop:30}}><span style={{ color: '#9b9b9b',marginTop:'30px' }}>竞赛时间:</span>{HeaderDetail.start_time}~{HeaderDetail.end_time}</p>
|
||||
<p className={styles.timesize}><span style={{ color: '#9b9b9b' }}>报名截止:</span>{HeaderDetail.enroll_end_time}</p>
|
||||
{HeaderDetail.competition_status === 'ended' ? <p className={styles.timesize}><span style={{ color: '#9b9b9b' }}>竞赛状态:</span>已结束</p> : null}
|
||||
{HeaderDetail.competition_status === 'nearly_published' ? <p className={styles.timesize}><span style={{ color: '#9b9b9b' }}>竞赛状态:</span>未发布</p> : null}
|
||||
{HeaderDetail.competition_status === 'progressing' ? <p className={styles.timesize}><span style={{ color: '#9b9b9b' }}>竞赛状态:</span>进行中</p> : null}
|
||||
|
||||
<div style={{display:'flex',justifyContent:'center'}}>
|
||||
{(HeaderDetail?.mode<=2&&StaffDetail.enrolled)&&<Button onClick={(e)=>{
|
||||
if(HeaderDetail?.mode===1){
|
||||
getrightdatas(HeaderDetail.competition_modules?.find((item:any)=>item.module_type==='entrance'))
|
||||
}else{
|
||||
gotocourse(e,HeaderDetail,'ismodel')
|
||||
}
|
||||
}>{StaffDetail.enrolled ? HeaderDetail.need_attachment ? '上传作品' : '已报名' : '立即报名'}</Button> : null}
|
||||
{user.userInfo.real_name != "游客" && <span onClick={(e) => gotocourse(e, HeaderDetail, `/competitions/index/${HeaderDetail.identifier}/enroll`)} className={styles.myteam}>{isSuperAdmin() ? '参赛战队>>' : '我的战队>>'}</span>}
|
||||
}} style={{background:'#07C160',color:'#fff',border:'1px solid #07C160',marginRight:20,display:HeaderDetail?.mode===2?'':(HeaderDetail?.mode===1&&HeaderDetail.competition_modules?.filter((item:any)=>item.module_type==='entrance')?.length>0)?'':'none'}} className={styles.buttonsize}>
|
||||
{HeaderDetail?.mode===1&&'赛题入口'}
|
||||
{HeaderDetail?.mode===2&&'进入课堂'}
|
||||
|
||||
</Button>}
|
||||
{HeaderDetail.competition_status === "ended" ? <Button type="primary" className={styles.buttonsize} disabled={true} >已结束</Button> : null}
|
||||
{HeaderDetail.competition_status === 'nearly_published' ? <Button type="primary" className={styles.buttonsize} disabled={true} >未发布</Button> : null}
|
||||
{HeaderDetail.competition_status !== 'nearly_published' && HeaderDetail.enroll_end && HeaderDetail.competition_status !== 'ended' ? <Button type="primary" className={styles.buttonsize} disabled={true} >报名截止</Button> : null}
|
||||
{HeaderDetail.competition_status === 'progressing' && HeaderDetail.enroll_end != true ? <Button type="primary" disabled={StaffDetail.enrolled && !HeaderDetail.need_attachment} className={styles.buttonsize} onClick={
|
||||
(e) => {
|
||||
if (StaffDetail.enrolled && HeaderDetail.need_attachment) {
|
||||
see.current?.handleVisible()
|
||||
return
|
||||
}
|
||||
gotocourse(e, HeaderDetail, HeaderDetail.mode === 2 ? 'ismodel' : HeaderDetail.personal ? 'personal' : `/competitions/index/${HeaderDetail.identifier}/enroll`)
|
||||
}
|
||||
}>{StaffDetail.enrolled ? HeaderDetail.need_attachment ? '上传作品' : '已报名' : HeaderDetail?.enroll_url ? '前往大赛官网报名' : '立即报名'}</Button> : null}
|
||||
</div>
|
||||
|
||||
|
||||
{user.userInfo.real_name != "游客" && !HeaderDetail?.enroll_url && <span onClick={(e) => gotocourse(e, HeaderDetail, HeaderDetail.mode === 2 ? 'ismodel' : HeaderDetail.personal ? 'personal' : `/competitions/index/${HeaderDetail.identifier}/enroll`)} className={styles.myteam}>{isSuperAdmin() ? '参赛战队>>' : '我的战队>>'}</span>}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.bootmdetail}>
|
||||
|
@ -398,7 +590,7 @@ const competitionDetails: FC<PageProps> = ({
|
|||
return
|
||||
}
|
||||
// if(item?.item?.has_url){
|
||||
// window.open(item?.module_url)
|
||||
// window.visible(item?.module_url)
|
||||
// return
|
||||
// }
|
||||
|
||||
|
@ -409,12 +601,14 @@ const competitionDetails: FC<PageProps> = ({
|
|||
})}
|
||||
</Menu>
|
||||
</div>
|
||||
<div className={styles.flex6}>
|
||||
<div className={styles.flex6} style={{padding:(showmake||entrance)&&0}}>
|
||||
{isAward ? <Award dispatch={dispatch} userid={user?.userInfo?.user_id} Prize={Prize} Accounts={Accounts} getAccounts={getAccounts} /> : null}
|
||||
{isRanKing ? <RanKing HeaderDetail={HeaderDetail} userinfo={user.userInfo} Editable={HeaderDetail?.permission?.editable} getCharts={getCharts} getChartRules={getChartRules} Selectkey={Selectkey} ChartRules={ChartRules} ItemData={ItemData} /> : null}
|
||||
{ISsee ? <SeeItem ref={see} StaffDetail={StaffDetail} HeaderDetail={HeaderDetail} userinfo={user.userInfo} Editable={HeaderDetail?.permission?.editable} ItemData={ItemData} setIssee={setIssee} ModelType={ModelType} dispatch={dispatch} /> : null}
|
||||
{!ISsee && !isRanKing && !isAward && !MdTab ? <UpItem userinfo={user.userInfo} ModelType={ModelType} getrightdatas={getrightdatas} dispatch={dispatch} MenuItem={MenuItem} setIssee={setIssee} identifier={identifier} ItemData={ItemData} /> : null}
|
||||
{MdTab && <SubmitResult dispatch={dispatch} StaffDetail={StaffDetail} userinfo={user.userInfo} HeaderDetail={HeaderDetail} Editable={HeaderDetail?.permission?.editable} getCharts={getResults} getChartRules={getTabResults} Selectkey={Selectkey} ChartRules={TabResults} ItemData={ItemData} />}
|
||||
{!ISsee &&!showmake&&!entrance&& !isRanKing && !isAward && !MdTab ? <UpItem userinfo={user.userInfo} ModelType={ModelType} getrightdatas={getrightdatas} dispatch={dispatch} MenuItem={MenuItem} setIssee={setIssee} identifier={identifier} ItemData={ItemData} /> : null}
|
||||
{MdTab && <SubmitResult dispatch={dispatch} StaffDetail={StaffDetail} userinfo={user.userInfo} HeaderDetail={HeaderDetail} Editable={HeaderDetail?.permission?.editable} getCharts={getResults} getChartRules={getTabResults} Selectkey={Selectkey} ChartRules={TabResults} ItemData={ItemData} />}
|
||||
{showmake && <MakeItem loading={itLoading} dispatch={dispatch} StaffDetail={StaffDetail} userinfo={user.userInfo} HeaderDetail={HeaderDetail} Editable={HeaderDetail?.permission?.editable} getCharts={getshixunCharts} getChartRules={getTabResults} Selectkey={Selectkey} ChartRules={TabResults} ItemData={ItemData} />}
|
||||
{entrance&& <Entrance loading={itLoading} dispatch={dispatch} StaffDetail={StaffDetail} userinfo={user.userInfo} HeaderDetail={HeaderDetail} Editable={HeaderDetail?.permission?.editable} getCharts={getEntrance} getChartRules={getTabResults} Selectkey={Selectkey} ChartRules={TabResults} ItemData={ItemData} />}
|
||||
</div>
|
||||
</div>
|
||||
<AuthModel />
|
||||
|
@ -440,6 +634,47 @@ const competitionDetails: FC<PageProps> = ({
|
|||
</Modal>
|
||||
|
||||
|
||||
<Modal
|
||||
title="选择参赛方式"
|
||||
visible={isshowmodal}
|
||||
onCancel={()=>{
|
||||
setisshowmodal(false)
|
||||
}}
|
||||
footer={false}
|
||||
>
|
||||
<div style={{display:'flex',justifyContent:'space-around',height:100,alignItems:'center'}}>
|
||||
<Button type="primary" style={{height:40}} onClick={()=>{
|
||||
setJoin(true)
|
||||
setisshowmodal(false)
|
||||
}}>加入战队参赛</Button>
|
||||
<Button style={{height:40}} onClick={()=>{
|
||||
setIsAddmodel(true)
|
||||
setisshowmodal(false)
|
||||
}}>去创建战队参赛</Button>
|
||||
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
{isJoin ? <JoinTeam isjoin={isJoin} setJoin={setJoin} JoinTeams={JoinTeams} /> : null}
|
||||
{isAddmodel ? <AddteamsModel isAddmodle={isAddmodel} setIsAdd={setIsAddmodel} createTeam={addTeams} /> : null}
|
||||
<PhoneModal datas={datas} isopen={isopen} setisopen={setisopen} isShowPhone={showphone} setIsShowPhone={setshowphone} user={user} dispatch={dispatch} onOK={async ()=>{
|
||||
const res = await dispatch({
|
||||
type: 'competitions/getHeader',
|
||||
payload: {
|
||||
identifier: identifier
|
||||
}
|
||||
})
|
||||
setHeaderDetail(res)
|
||||
|
||||
}} />
|
||||
<ClaModal
|
||||
visible={visible}
|
||||
onCancel={()=>{setVisible(false)}}
|
||||
onOk={()=>{
|
||||
setVisible(false);
|
||||
setisshowmodal(true);
|
||||
}}/>
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -13,9 +13,10 @@ interface managed{
|
|||
setIslookModel:any
|
||||
setTeam:any
|
||||
setMembers:any
|
||||
mode:any
|
||||
mode:any,
|
||||
kylinIdFlag:any
|
||||
}
|
||||
function managed({item,identifier,isTipsshow,type,setIslookModel,setTeam,setMembers,mode}:managed){
|
||||
function managed({item,identifier,isTipsshow,type,setIslookModel,setTeam,setMembers,mode,kylinIdFlag}:managed){
|
||||
|
||||
function jsCopy(){
|
||||
let aa=`copy_invite_code${item.id}`
|
||||
|
@ -42,7 +43,6 @@ function managed({item,identifier,isTipsshow,type,setIslookModel,setTeam,setMemb
|
|||
</Menu>
|
||||
)
|
||||
}
|
||||
console.log(mode);
|
||||
|
||||
return(
|
||||
<div className={styles.ManagedTeams} >
|
||||
|
@ -84,7 +84,11 @@ function managed({item,identifier,isTipsshow,type,setIslookModel,setTeam,setMemb
|
|||
</div>
|
||||
<div className={styles.width15} style={{justifyContent:'flex-end'}}>
|
||||
<span >战队成员:<span>{item.team_members?item.team_members.length:'--'}</span></span>
|
||||
<span onClick={()=>isSetting()} style={{color:'#1890FF',marginLeft:'10px',cursor:'pointer'}}>{type===1?'设置':'查看'}</span>
|
||||
{
|
||||
type === 2 || !kylinIdFlag ?
|
||||
<span onClick={()=>isSetting()} style={{color:'#1890FF',marginLeft:'10px',cursor:'pointer'}}>{type===1?'设置':'查看'}</span>
|
||||
:""
|
||||
}
|
||||
{item&&item.active||type===2?<span className={styles.borderjingao} style={{visibility:'hidden'}}></span>:
|
||||
<Tooltip placement="top" title={"请设置战队成员"}><span className={styles.borderjingao}>!</span></Tooltip>
|
||||
}
|
||||
|
|
|
@ -27,7 +27,10 @@ import DMpz from './dmpz.png';
|
|||
import Sjjx from './sjjx.png';
|
||||
import Xmcx from './xmcx.png';
|
||||
import Xmtz from './xmtz.png';
|
||||
import { openNewWindow } from '@/utils/util'
|
||||
import { openNewWindow,setDocumentTitle } from '@/utils/util'
|
||||
import PhoneModal from '../components/PhoneModal'
|
||||
import env from '@/utils/env';
|
||||
|
||||
|
||||
|
||||
interface PageProps extends ConnectProps {
|
||||
|
@ -71,6 +74,31 @@ const competitionDetails: FC<PageProps> = ({
|
|||
const [isClick,setIsClick]=useState<any>(true)//增加参数 防止点击过快 多次调用
|
||||
const [defaultData,setDetaultData] = useState<any>()
|
||||
const [isshowModal,setIsshowModal]=useState<any>(false);
|
||||
const [showphone,setshowphone]=useState<any>(false);
|
||||
const [isopen,setisopen]=useState<any>(false);
|
||||
const [datas,setdatas]=useState<any>();
|
||||
|
||||
const [ kylinIdFlag , setKylinIdFlag ] = useState<any>(false);
|
||||
|
||||
useEffect(()=>{
|
||||
if(user?.userInfo?.login && HeaderDetail?.id){
|
||||
getId();
|
||||
}
|
||||
},[user?.userInfo,HeaderDetail])
|
||||
|
||||
async function getId() {
|
||||
let data =await dispatch({
|
||||
type: 'competitions/GetKylinId',
|
||||
payload: {
|
||||
owner:user?.userInfo?.login
|
||||
}
|
||||
})
|
||||
let a =data.data;
|
||||
let filter = a.filter((i:any)=>i.toString() === HeaderDetail?.id.toString());
|
||||
console.log("result",a,filter);
|
||||
let flag = filter && filter.length>0 ? true : false;
|
||||
setKylinIdFlag(flag);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
async function init() {
|
||||
|
@ -95,6 +123,10 @@ const competitionDetails: FC<PageProps> = ({
|
|||
init();
|
||||
}
|
||||
}, [identifier])
|
||||
|
||||
useEffect(() => {
|
||||
setDocumentTitle('在线竞赛');
|
||||
});
|
||||
async function selectlist(keyword: any) {
|
||||
let data = await dispatch({
|
||||
type: 'competitions/getTeamList',
|
||||
|
@ -205,7 +237,9 @@ const competitionDetails: FC<PageProps> = ({
|
|||
}
|
||||
})
|
||||
if (data && data.status === 0) {
|
||||
message.info(`创建战队成功`);
|
||||
setisopen(true)
|
||||
setdatas(data)
|
||||
|
||||
if(ids.includes(parseInt(HeaderDetail?.id))){
|
||||
setIsshowModal(true);
|
||||
}
|
||||
|
@ -276,7 +310,8 @@ const competitionDetails: FC<PageProps> = ({
|
|||
}
|
||||
})
|
||||
if (data && data.status === 0) {
|
||||
message.info(`加入战队成功`);
|
||||
setisopen(true)
|
||||
setdatas(data)
|
||||
setJoin(false);
|
||||
setIsClick(true);
|
||||
selectlist(KeyWord);
|
||||
|
@ -317,17 +352,17 @@ const competitionDetails: FC<PageProps> = ({
|
|||
return (
|
||||
<div key={index}>
|
||||
<div className={styles.teamstitlesize} style={{ paddingRight: '36px' }}><span style={{ flex: '1' }} >管理的战队 ({MyCreteTeam.length})</span> {MyCreteTeam.filter(item => !item.active).length > 0 ? <span style={{ fontSize: '14px', color: '#F3730C' }}>您有{MyCreteTeam.filter(item => !item.active).length}个战队未满足参赛要求!为了不影响成绩,请设置战队成员</span> : ''}</div>
|
||||
<Managed mode={HeaderDetail.mode} item={item} type={1} identifier={identifier} isTipsshow={isTipsshow} setIslookModel={setIslookModel} setTeam={setTeam} setMembers={setMembers} />
|
||||
<Managed mode={HeaderDetail.mode} item={item} type={1} kylinIdFlag={kylinIdFlag} identifier={identifier} isTipsshow={isTipsshow} setIslookModel={setIslookModel} setTeam={setTeam} setMembers={setMembers} />
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<Managed mode={HeaderDetail.mode} key={index} item={item} type={1} identifier={identifier} isTipsshow={isTipsshow} setIslookModel={setIslookModel} setTeam={setTeam} setMembers={setMembers} />
|
||||
<Managed mode={HeaderDetail.mode} key={index} item={item} type={1} kylinIdFlag={kylinIdFlag} identifier={identifier} isTipsshow={isTipsshow} setIslookModel={setIslookModel} setTeam={setTeam} setMembers={setMembers} />
|
||||
)
|
||||
}
|
||||
})}
|
||||
|
||||
{isSelect || ManagedTeams && ManagedTeams.length>0 && ManagedTeams.map((item: any, index: any) => {
|
||||
{isSelect || ManagedTeams && ManagedTeams.map((item: any, index: any) => {
|
||||
if (index === 0) {
|
||||
return (
|
||||
<div key={index}>
|
||||
|
@ -375,7 +410,7 @@ const competitionDetails: FC<PageProps> = ({
|
|||
<AuthModel/>
|
||||
|
||||
<Modal
|
||||
visible={isshowModal}
|
||||
open={isshowModal}
|
||||
footer={null}
|
||||
title="报名成功"
|
||||
centered={true}
|
||||
|
@ -421,6 +456,15 @@ const competitionDetails: FC<PageProps> = ({
|
|||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
<PhoneModal datas={datas} isopen={isopen} setisopen={setisopen} isShowPhone={showphone} setIsShowPhone={setshowphone} user={user} dispatch={dispatch} onOK={async ()=>{
|
||||
setHeaderDetail(
|
||||
await dispatch({
|
||||
type: 'competitions/getHeader',
|
||||
payload: {
|
||||
identifier: identifier
|
||||
}
|
||||
}));
|
||||
}} />
|
||||
</div>
|
||||
)
|
||||
}; export default connect(
|
||||
|
|
|
@ -9,10 +9,11 @@ import {
|
|||
Loading,
|
||||
connect,
|
||||
Dispatch,
|
||||
useLocation,
|
||||
Link,
|
||||
} from 'umi';
|
||||
import html2pdf from 'html2pdf.js';
|
||||
import { openNewWindow, downLoadLink } from '@/utils/util'
|
||||
import { getJsonFromUrl, downLoadLink } from '@/utils/util'
|
||||
import { isCommonSuperAdminOrOperation } from '@/utils/authority'
|
||||
import { getCertificateInfo } from '@/service/competitions';
|
||||
import {certificateIcon} from '@/components/ImagesIcon';
|
||||
|
@ -28,8 +29,9 @@ const CompetitionsExportPage: FC<PageProps> = ({
|
|||
dispatch,
|
||||
...props
|
||||
}) => {
|
||||
const searchParams:any= useLocation();
|
||||
const [show, setShow] = useState(false)
|
||||
const [query, setQuery] = useState<any>(props.location.query)
|
||||
const [query, setQuery] = useState<any>(getJsonFromUrl())
|
||||
const reportElement = useRef();
|
||||
const dataType = [
|
||||
{ name: '最新', id: 'created_at' },
|
||||
|
@ -37,8 +39,8 @@ const CompetitionsExportPage: FC<PageProps> = ({
|
|||
];
|
||||
useEffect(() => {
|
||||
// setShow(true)
|
||||
// if (isCommonSuperAdminOrOperation() && !query.id) setShow(true);
|
||||
if (query.id) getData();
|
||||
// if (isCommonSuperAdminOrOperation() && !searchParams.get("id")) setShow(true);
|
||||
if (searchParams.get("id")) getData();
|
||||
}, [])
|
||||
|
||||
const getData = async () => {
|
||||
|
|
|
@ -7,21 +7,38 @@ import {
|
|||
connect,
|
||||
Dispatch,
|
||||
useLocation,
|
||||
UserModelState
|
||||
UserModelState,
|
||||
} from 'umi';
|
||||
import { Tabs, Pagination, Skeleton, List, Button, message, Upload } from 'antd';
|
||||
import Header from '@/components/Header';
|
||||
import {
|
||||
Tabs,
|
||||
Pagination,
|
||||
Skeleton,
|
||||
List,
|
||||
Button,
|
||||
message,
|
||||
Input,
|
||||
Modal
|
||||
} from 'antd';
|
||||
import { setDocumentTitle } from '@/utils/util';
|
||||
import styles from './index.less';
|
||||
import NoData from '@/components/NoData';
|
||||
import ENV from '@/utils/env'
|
||||
import AuthModel from '@/components/AuthenticationModel'
|
||||
import { isSuperAdmins } from '@/utils/authority'
|
||||
import ENV from '@/utils/env';
|
||||
import AuthModel from '@/components/AuthenticationModel';
|
||||
import { isSuperAdmins } from '@/utils/authority';
|
||||
import { openNewWindow } from '@/utils/util';
|
||||
import { handleVerifyLogin, handleVerify , handleProfleCompletedModal} from '@/utils/verifyLogin';
|
||||
import StatisticsItem from './Statistics/index'
|
||||
import { handleVerify } from '@/utils/verifyLogin';
|
||||
import StatisticsItem from './Statistics/index';
|
||||
import { mainbannerBg } from '@/components/ImagesIcon';
|
||||
import AdverModel from '@/components/HomeModal/Advertisement'
|
||||
import AdverModel from '@/components/HomeModal/Advertisement';
|
||||
// import CompetitionBanner from '@/assets/images/competition/competition-banner.png'
|
||||
import JoinTeam from '../Entered/Enteredmodel/JoinModel'
|
||||
import AddteamsModel from '../Entered/Enteredmodel/Addteams';
|
||||
import PhoneModal from '../components/PhoneModal';
|
||||
import ClaModal from '../components/ClaModal';
|
||||
// import { addSearchRecord } from '@/service/global';
|
||||
|
||||
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
interface PageProps extends ConnectProps {
|
||||
|
@ -29,10 +46,10 @@ interface PageProps extends ConnectProps {
|
|||
globalSetting: GlobalSettingModelState;
|
||||
loading: boolean;
|
||||
dispatch: Dispatch;
|
||||
user: UserModelState
|
||||
user: UserModelState;
|
||||
}
|
||||
|
||||
const competitionsPage: FC<PageProps> = ({
|
||||
const competitionsIndexPage: FC<PageProps> = ({
|
||||
competitions,
|
||||
globalSetting,
|
||||
loading,
|
||||
|
@ -41,33 +58,42 @@ const competitionsPage: FC<PageProps> = ({
|
|||
...props
|
||||
}) => {
|
||||
const location: any = useLocation();
|
||||
const searchParams:any= useLocation();
|
||||
const [isStatistics, setIsStatistics] = useState<any>(false);
|
||||
const [modeldata, setModeldata] = useState();
|
||||
console.log(location);
|
||||
const [isshowmodal, setisshowmodal] = useState<any>(false);
|
||||
const [isAddmodel, setIsAddmodel] = useState<any>(false) //新建战队
|
||||
const [isJoin, setJoin] = useState<any>(false) //加入战队
|
||||
const [isClick, setIsClick] = useState<any>(true)//增加参数 防止点击过快 多次调用
|
||||
let [items, setitems] = useState<any>([]);
|
||||
const [showphone,setshowphone]=useState<any>(false);
|
||||
const [isopen,setisopen]=useState<any>(false)
|
||||
const [datas,setdatas]=useState<any>()
|
||||
const [visible,setVisible]=useState<any>(false);
|
||||
|
||||
//出现页面右侧悬浮按钮
|
||||
useEffect(() => {
|
||||
dispatch({
|
||||
type: 'globalSetting/onlyShowBackTopToggle',
|
||||
payload: false
|
||||
payload: false,
|
||||
});
|
||||
return () => {
|
||||
dispatch({
|
||||
type: 'globalSetting/onlyShowBackTopToggle',
|
||||
payload: true
|
||||
payload: true,
|
||||
});
|
||||
}
|
||||
}, [])
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
// getHomeNotice();
|
||||
dispatch({
|
||||
type: 'competitions/getList',
|
||||
payload: { ...competitions.listParams,external:true },
|
||||
payload: { ...competitions.listParams },
|
||||
});
|
||||
}, [competitions.name]);
|
||||
useEffect(() => {
|
||||
setDocumentTitle('在线竞赛')
|
||||
setDocumentTitle('在线竞赛');
|
||||
});
|
||||
|
||||
async function getHomeNotice() {
|
||||
|
@ -75,27 +101,27 @@ const competitionsPage: FC<PageProps> = ({
|
|||
let data = await dispatch({
|
||||
type: 'homePage/getHomeNotice',
|
||||
payload: {},
|
||||
})
|
||||
});
|
||||
if (data) {
|
||||
let SystemUpdateadvtime = localStorage.getItem('SystemUpdateadvtime');
|
||||
localStorage.setItem('SystemUpdateadvtime', data.start_at);
|
||||
// let date=new Date();
|
||||
if (data?.id) {
|
||||
localStorage.setItem('isfirst', '0')
|
||||
localStorage.setItem('isfirst', '0');
|
||||
// localStorage.setItem('showtime',(date.getDate()+1).toString());
|
||||
} else {
|
||||
localStorage.setItem('isfirst', '2')
|
||||
localStorage.setItem('isfirst', '2');
|
||||
}
|
||||
setModeldata(data)
|
||||
setModeldata(data);
|
||||
}
|
||||
}
|
||||
|
||||
const onShowSizeChange = (current: any, pageSize: any) => {
|
||||
document.body.scrollIntoView()
|
||||
document.body.scrollIntoView();
|
||||
competitions.listParams.page = current;
|
||||
dispatch({
|
||||
type: 'competitions/getList',
|
||||
payload: { ...competitions.listParams, edu: location.query.edu , external:true },
|
||||
payload: { ...competitions.listParams, edu: searchParams.get("edu") },
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -105,75 +131,230 @@ const competitionsPage: FC<PageProps> = ({
|
|||
async function gotocourse(e: any, item: any, url: string) {
|
||||
e.stopPropagation();
|
||||
|
||||
|
||||
if (!handleVerify(dispatch)) {
|
||||
return;
|
||||
}
|
||||
// 判断是否完善资料,未完善资料需弹出提示框
|
||||
if(!handleProfleCompletedModal()){
|
||||
return;
|
||||
}
|
||||
if (item?.is_authentication && !user?.userInfo?.authentication) {
|
||||
dispatch({
|
||||
type: 'shixunsDetail/setActionTabs',
|
||||
payload: {
|
||||
key: 'Banner-Auth',
|
||||
},
|
||||
})
|
||||
return
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (url === "ismodel") {
|
||||
if (url === 'ismodel') {
|
||||
if (item.member_of_course === true) {
|
||||
openNewWindow(`/classrooms/${item.course_id}`)
|
||||
openNewWindow(`/classrooms/${item.course_id}`);
|
||||
} else {
|
||||
if (!item.invite_code) {
|
||||
message.info('本竞赛只面向部分学校/单位开放,你暂时没有参赛资格')
|
||||
return
|
||||
message.info('本竞赛只面向部分学校/单位开放,你暂时没有参赛资格');
|
||||
return;
|
||||
}
|
||||
const result = await dispatch({
|
||||
type: 'competitions/addApplytojoincourse',
|
||||
payload: {
|
||||
invite_code: item.invite_code,
|
||||
student: 1
|
||||
}
|
||||
student: 1,
|
||||
},
|
||||
});
|
||||
if (result.statue === 0) {
|
||||
if (result.status === 0) {
|
||||
openNewWindow(`/classrooms/${item.course_id}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (url === "personal") {
|
||||
//设置 通过权限弹出对应窗口
|
||||
if (item.enrolled === true) {
|
||||
openNewWindow(url);
|
||||
return;
|
||||
}
|
||||
|
||||
if (url === 'personal') {
|
||||
if (item.enroll_ended === true) {
|
||||
//已截止
|
||||
message.info(`报名已截止`);
|
||||
return;
|
||||
}
|
||||
if (item.enrolled === true) {
|
||||
message.info(`你已经报名,不能重复报名!`);
|
||||
return;
|
||||
}
|
||||
const competitionTeamsresult = await dispatch({
|
||||
type: 'competitions/competitionTeams',
|
||||
payload: {
|
||||
identifier: item.identifier
|
||||
}
|
||||
})
|
||||
if (competitionTeamsresult.statue === 0) {
|
||||
message.info('报名成功,预祝您夺得桂冠!')
|
||||
}
|
||||
|
||||
setisshowmodal(true);
|
||||
setitems(item);
|
||||
} else {
|
||||
openNewWindow(url)
|
||||
setisshowmodal(true);
|
||||
setitems(item);
|
||||
}
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
function tourl(url: string) {
|
||||
openNewWindow(url);
|
||||
}
|
||||
|
||||
//创建战队 AddTeam
|
||||
async function addTeams(name: any) {
|
||||
if (!isClick) {
|
||||
return
|
||||
}
|
||||
setIsClick(false);
|
||||
if (isadd()) {
|
||||
return
|
||||
}
|
||||
let data = await dispatch({
|
||||
type: 'competitions/AddTeam',
|
||||
payload: {
|
||||
identifier: items?.identifier,
|
||||
name: name
|
||||
}
|
||||
})
|
||||
if (data && data.status === 0) {
|
||||
// setisopen(true)
|
||||
setdatas(data)
|
||||
dispatch({
|
||||
type: 'competitions/getList',
|
||||
payload: { ...competitions.listParams },
|
||||
});
|
||||
setIsAddmodel(false)
|
||||
} else {
|
||||
setIsClick(true);
|
||||
}
|
||||
}
|
||||
function isadd() {
|
||||
//判断 如果不符合条件 不能加入竞赛
|
||||
if (user?.userInfo?.is_teacher) {
|
||||
if (items?.teacher_staff?.mutiple_limited) {
|
||||
if (items?.enrolled) {
|
||||
message.info('你已经报名,不能重复报名')
|
||||
setIsClick(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (items?.member_staff?.mutiple_limited) {
|
||||
if (items?.enrolled) {
|
||||
message.info('你已经报名,不能重复报名')
|
||||
setIsClick(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//判断竞赛是否关闭
|
||||
if (items?.enroll_ended) {
|
||||
message.info('报名已截止,无需报名')
|
||||
setIsClick(true);
|
||||
return true;
|
||||
}
|
||||
//禁止老师or学生报名
|
||||
if (user?.userInfo?.is_teacher) {
|
||||
if (!items.teacher_staff) {
|
||||
message.info('已禁止老师报名')
|
||||
setIsClick(true);
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (!items?.member_staff) {
|
||||
message.info('已禁止学生报名')
|
||||
setIsClick(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function tourl(url: string) {
|
||||
openNewWindow(url)
|
||||
//加入战队
|
||||
async function JoinTeams(name: any) {
|
||||
if (!isClick) {
|
||||
return
|
||||
}
|
||||
//判断 如果不符合条件 不能加入竞赛
|
||||
if (isadd()) {
|
||||
return
|
||||
}
|
||||
setIsClick(false);
|
||||
let data = await dispatch({
|
||||
type: 'competitions/JoinTeam',
|
||||
payload: {
|
||||
identifier: items?.identifier,
|
||||
invite_code: name
|
||||
}
|
||||
})
|
||||
if (data && data.status === 0) {
|
||||
// setisopen(true)
|
||||
setdatas(data)
|
||||
dispatch({
|
||||
type: 'competitions/getList',
|
||||
payload: { ...competitions.listParams },
|
||||
});
|
||||
setJoin(false)
|
||||
} else {
|
||||
setIsClick(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表数据点击跳转事件
|
||||
*/
|
||||
const onListClick = (item: any) => {
|
||||
if (item.external_url) {
|
||||
tourl(item.external_url);
|
||||
} else {
|
||||
tourl(
|
||||
item.competition_status === 'ended'
|
||||
? `/competitions/index/${item.identifier}`
|
||||
: item.competition_status === 'nearly_published'
|
||||
? item.permission.editable == true
|
||||
? `/competitions/index/${item.identifier}`
|
||||
: null
|
||||
: item.competition_status === 'progressing'
|
||||
? `/competitions/index/${item.identifier}`
|
||||
: null,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 列表报名点击事件
|
||||
*/
|
||||
const onLickSignUpClick = (event: any, item: any) => {
|
||||
// if(item.teacher_need_phone||item.member_need_phone){
|
||||
// event.stopPropagation();
|
||||
// setshowphone(true)
|
||||
// return
|
||||
// }
|
||||
event.stopPropagation();
|
||||
if (!handleVerify(dispatch)) {
|
||||
return;
|
||||
}
|
||||
if(!user?.userInfo?.sign_cla){
|
||||
setVisible(true);
|
||||
return;
|
||||
}
|
||||
if (item.external_url) {
|
||||
tourl(item.external_url);
|
||||
} else {
|
||||
gotocourse(
|
||||
event,
|
||||
item,
|
||||
item.mode === 2
|
||||
? 'ismodel'
|
||||
: item.personal
|
||||
? 'personal'
|
||||
: `/competitions/index/${item.identifier}/enroll`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// const [keyword, setKeyword] = useState('')
|
||||
// const handleSearch = (keyword: string) => {
|
||||
// competitions.listParams.keyword = encodeURIComponent(keyword);
|
||||
// competitions.listParams.page = 1;
|
||||
// if (keyword) {
|
||||
// addSearchRecord({ name: keyword, copywriting: keyword, position: 'Competition' })
|
||||
// }
|
||||
// dispatch({
|
||||
// type: 'competitions/getList',
|
||||
// payload: { ...competitions.listParams, edu: searchParams.get("edu") },
|
||||
// });
|
||||
// }
|
||||
return (
|
||||
<section className={styles.bg}>
|
||||
<aside className={styles.banner}>
|
||||
|
@ -187,25 +368,22 @@ const competitionsPage: FC<PageProps> = ({
|
|||
/>
|
||||
</a>
|
||||
</aside>
|
||||
|
||||
<section className="bg-white" style={{ height: '50px' }}>
|
||||
<aside className="edu-container">
|
||||
<div className='edu-container'>
|
||||
<div className={styles.tabsWrap}>
|
||||
<Tabs
|
||||
defaultActiveKey=""
|
||||
className={styles.tabs}
|
||||
tabBarStyle={{ color: '#000000' }}
|
||||
onChange={v => {
|
||||
if (v === 'statistics') {
|
||||
setIsStatistics(true)
|
||||
setIsStatistics(true);
|
||||
} else {
|
||||
setIsStatistics(false)
|
||||
setIsStatistics(false);
|
||||
}
|
||||
competitions.listParams.page = 1;
|
||||
competitions.listParams.category = v;
|
||||
competitions.listParams.page = 1;
|
||||
dispatch({
|
||||
type: 'competitions/getList',
|
||||
payload: { ...competitions.listParams,external:true },
|
||||
payload: { ...competitions.listParams },
|
||||
});
|
||||
}}
|
||||
>
|
||||
|
@ -213,104 +391,256 @@ const competitionsPage: FC<PageProps> = ({
|
|||
<TabPane tab="即将发布" key="nearly_published"></TabPane>
|
||||
<TabPane tab="进行中" key="progressing"></TabPane>
|
||||
<TabPane tab="往期比赛" key="ended"></TabPane>
|
||||
{isSuperAdmins() && <TabPane tab="数据统计" key="statistics"></TabPane>}
|
||||
{isSuperAdmins() && (
|
||||
<TabPane tab="数据统计" key="statistics"></TabPane>
|
||||
)}
|
||||
</Tabs>
|
||||
</aside>
|
||||
</section>
|
||||
{/* 无数据 */}
|
||||
{!isStatistics && <div>
|
||||
{competitions.count === 0 && <NoData />}
|
||||
<aside className="edu-container minH500">
|
||||
{/* 列表 */}
|
||||
<Skeleton
|
||||
loading={loading}
|
||||
active={true}
|
||||
avatar={{ size: 40 }}
|
||||
paragraph={{ rows: 5 }}
|
||||
>
|
||||
{competitions.competitions && <List
|
||||
itemLayout="vertical"
|
||||
size="large"
|
||||
dataSource={competitions.competitions}
|
||||
style={{ paddingTop: 10 }}
|
||||
renderItem={(item: any, key: number) => (
|
||||
<div className={styles.CompetitionsList} >
|
||||
{item.competition_status === "nearly_published" ?
|
||||
item.permission.editable == true ? "" : <div className={styles.CompetitionsListzhezhao}>即将发布 敬请期待</div> : ""}
|
||||
<List.Item
|
||||
onClick={() => tourl(item.competition_status === "ended" ? `/competitions/index/${item.identifier}` : item.competition_status === "nearly_published" ? item.permission.editable == true ? `/competitions/index/${item.identifier}` : null : item.competition_status === "progressing" ? `/competitions/index/${item.identifier}` : null)}
|
||||
className={styles.shadow}
|
||||
key={key}
|
||||
>
|
||||
<List.Item.Meta
|
||||
style={{ marginBottom: '0px' }}
|
||||
avatar={
|
||||
<div className={styles.divimg}>
|
||||
<img src={item && item.image ? `${ENV.IMG_SERVER}/` + item.image : require(`@/assets/images/banner/mainbanner.jpg`)} />
|
||||
</div>
|
||||
}
|
||||
title={<p style={{ alignItems: 'center', display: 'flex' }}><a
|
||||
className={styles.task_hide}>{item.name}{item.sub_title ? `——${item.sub_title}` : ''}</a>
|
||||
{item.competition_status && item.competition_status === 'nearly_published' ? <span className={styles.Comingtext}>即将发布</span> : ''}
|
||||
{item.competition_status && item.competition_status === 'progressing' ? <span className={styles.havetext}>进行中</span> : ''}
|
||||
{item.competition_status && item.competition_status === 'ended' ? <span className={styles.Finishedtext}>已结束</span> : ''}
|
||||
</div>
|
||||
{/* 无数据 */}
|
||||
{!isStatistics && (
|
||||
<div>
|
||||
{competitions.count === 0 && <NoData />}
|
||||
<aside className="edu-container minH500">
|
||||
{/* 列表 */}
|
||||
<Skeleton
|
||||
loading={loading}
|
||||
active={true}
|
||||
avatar={{ size: 40 }}
|
||||
paragraph={{ rows: 5 }}
|
||||
>
|
||||
{competitions.competitions && (
|
||||
<List
|
||||
itemLayout="vertical"
|
||||
size="large"
|
||||
dataSource={competitions.competitions}
|
||||
renderItem={(item: any, key: number) => (
|
||||
<div className={styles.CompetitionsList}>
|
||||
{item.competition_status === 'nearly_published' ? (
|
||||
item.permission.editable == true ? (
|
||||
''
|
||||
) : (
|
||||
<div className={styles.CompetitionsListzhezhao}>
|
||||
即将发布 敬请期待
|
||||
</div>
|
||||
)
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<List.Item
|
||||
onClick={() => onListClick(item)}
|
||||
className={styles.shadow}
|
||||
key={key}
|
||||
>
|
||||
<List.Item.Meta
|
||||
style={{ marginBottom: '0px' }}
|
||||
avatar={
|
||||
<img
|
||||
className={styles.divimg}
|
||||
src={
|
||||
item && item.image
|
||||
? `${ENV.IMG_SERVER}/` + item.image
|
||||
: mainbannerBg
|
||||
}
|
||||
/>
|
||||
}
|
||||
title={
|
||||
<p
|
||||
style={{ alignItems: 'center', display: 'flex' }}
|
||||
>
|
||||
<a className={styles.task_hide}>
|
||||
{item.name}
|
||||
{item.sub_title ? `——${item.sub_title}` : ''}
|
||||
</a>
|
||||
{item.competition_status &&
|
||||
item.competition_status === 'nearly_published' ? (
|
||||
<span className={`${styles.commonTextBox} ${styles.Comingtext}`}>
|
||||
即将发布
|
||||
</span>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{item.competition_status &&
|
||||
item.competition_status === 'progressing' ? (
|
||||
<span className={`${styles.commonTextBox} ${styles.havetext}`}>进行中</span>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{item.competition_status &&
|
||||
item.competition_status === 'ended' ? (
|
||||
<span className={`${styles.commonTextBox} ${styles.Finishedtext}`}>
|
||||
已结束
|
||||
</span>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</p>
|
||||
}
|
||||
description={
|
||||
<div className={styles.description}>
|
||||
<div
|
||||
className={styles.task_hide_2}
|
||||
style={{
|
||||
height: '43px',
|
||||
fontSize: '14px',
|
||||
color: '#666666',
|
||||
}}
|
||||
>
|
||||
{item.description
|
||||
? item.description
|
||||
: '暂无简介~'}
|
||||
</div>
|
||||
<div
|
||||
className={styles.bottomText}
|
||||
>
|
||||
<span>
|
||||
竞赛时间: {item.start_time}~{item.end_time}
|
||||
</span>
|
||||
<span style={{ marginLeft: '10px' }}>
|
||||
报名截止时间:
|
||||
{item && item.enroll_end_time
|
||||
? item.enroll_end_time
|
||||
: '暂无'}
|
||||
</span>
|
||||
<span style={{ marginLeft: '10px' }}>
|
||||
浏览数:
|
||||
{item && item.visits_count
|
||||
? item.visits_count
|
||||
: '暂无'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
width: '16%',
|
||||
alignItems: 'flex-end',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-around',
|
||||
}}
|
||||
>
|
||||
<div className={styles.info}>
|
||||
<div
|
||||
className={styles.bonus}
|
||||
style={{
|
||||
visibility:
|
||||
item && item.bonus ? 'visible' : 'hidden',
|
||||
}}
|
||||
>
|
||||
<span className={styles.rmb}>¥</span>
|
||||
{parseInt(item.bonus).toLocaleString()}
|
||||
</div>
|
||||
{item.member_count ? <div className={styles.applyInfo}>
|
||||
已报名:
|
||||
{item.competition_status === 'nearly_published'
|
||||
? '0'
|
||||
: item.member_count}
|
||||
</div> : ''}
|
||||
</div>
|
||||
{item && item.competition_status === 'ended' ? (
|
||||
<span
|
||||
className={styles.Unpublishedtext}
|
||||
onClick={e => noclick(e)}
|
||||
>
|
||||
已结束
|
||||
</span>
|
||||
) : null}
|
||||
{item &&
|
||||
item.competition_status === 'nearly_published' ? (
|
||||
<span
|
||||
className={styles.Unpublishedtext}
|
||||
onClick={e => noclick(e)}
|
||||
>
|
||||
未发布
|
||||
</span>
|
||||
) : null}
|
||||
{item &&
|
||||
item.competition_status !== 'nearly_published' &&
|
||||
item.enroll_end &&
|
||||
item.competition_status !== 'ended' ? (
|
||||
<span
|
||||
className={styles.Unpublishedtext}
|
||||
onClick={e => noclick(e)}
|
||||
>
|
||||
报名截止
|
||||
</span>
|
||||
) : null}
|
||||
|
||||
</p>}
|
||||
description={
|
||||
<div>
|
||||
<p className={styles.task_hide_2} style={{ height: '43px', fontSize: '14px', color: '#666666' }}>{item.description ? item.description : '暂无简介~'}</p>
|
||||
<p style={{ marginTop: '12px', fontSize: '12px', color: '#888888' }}>
|
||||
<span>竞赛时间: {item.start_time}~{item.end_time}</span>
|
||||
<span style={{ marginLeft: '20px' }}>报名截止时间:{item && item.enroll_end_time ? item.enroll_end_time : '暂无'}</span>
|
||||
<span style={{ marginLeft: '20px' }}>浏览数:{item && item.visits_count ? item.visits_count : '暂无'}</span>
|
||||
</p>
|
||||
</div>}
|
||||
/>
|
||||
<div style={{ width: '20%', alignItems: 'flex-end', display: 'flex', flexDirection: 'column', justifyContent: 'space-around' }}>
|
||||
<div style={{ textAlign: 'right' }}>
|
||||
<p style={{ fontSize: '28px', color: '#1890FF', visibility: item && item.bonus ? 'visible' : 'hidden', marginBottom: '0px' }}><span style={{ fontSize: '20px' }}>¥</span>{parseInt(item.bonus).toLocaleString()}</p>
|
||||
{item.member_count?
|
||||
<p style={{ color: '#BBBBBB', fontSize: '14px' }}>已报名:{item.competition_status === "nearly_published" ? "0" : item.member_count}</p>
|
||||
:""
|
||||
}
|
||||
{item &&
|
||||
item.competition_status === 'progressing' &&
|
||||
item.enroll_end != true &&
|
||||
!item.external_url ? (
|
||||
<Button
|
||||
className={styles.signup}
|
||||
onClick={e => onLickSignUpClick(e, item)}
|
||||
>
|
||||
{item?.enrolled ? '已报名' : '立即报名'}
|
||||
</Button>
|
||||
) : null}
|
||||
</div>
|
||||
</List.Item>
|
||||
</div>
|
||||
{item && item.competition_status === 'ended' ? <span className={styles.Unpublishedtext} onClick={(e) => noclick(e)}>已结束</span> : null}
|
||||
{item && item.competition_status === 'nearly_published' ? <span className={styles.Unpublishedtext} onClick={(e) => noclick(e)}>未发布</span> : null}
|
||||
{item && item.competition_status !== 'nearly_published' && item.enroll_end && item.competition_status !== 'ended' ? <span className={styles.Unpublishedtext} onClick={(e) => noclick(e)}>报名截止</span> : null}
|
||||
{item && item.competition_status === 'progressing' && item.enroll_end != true ? <Button className={styles.signup} onClick={
|
||||
(e) => gotocourse(e, item, item.mode === 2 ? 'ismodel' : item.personal ? 'personal' : `/competitions/index/${item.identifier}`)
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</Skeleton>
|
||||
<AuthModel />
|
||||
<AdverModel modeldata={modeldata} dispatch={dispatch} />
|
||||
<aside className="tc mb50 mt20">
|
||||
<Pagination
|
||||
hideOnSinglePage
|
||||
showSizeChanger={false}
|
||||
showQuickJumper
|
||||
onChange={onShowSizeChange}
|
||||
defaultPageSize={20}
|
||||
current={competitions.listParams.page}
|
||||
defaultCurrent={competitions.listParams.page}
|
||||
total={competitions.count}
|
||||
/>
|
||||
</aside>
|
||||
</aside>
|
||||
</div>
|
||||
)}
|
||||
{isStatistics && <StatisticsItem />}
|
||||
</div>
|
||||
<Modal
|
||||
title="选择参赛方式"
|
||||
centered={true}
|
||||
visible={isshowmodal}
|
||||
onCancel={() => {
|
||||
setisshowmodal(false)
|
||||
}}
|
||||
footer={false}
|
||||
>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-around', height: 100, alignItems: 'center' }}>
|
||||
<Button type="primary" style={{ height: 40 }} onClick={() => {
|
||||
setJoin(true)
|
||||
setisshowmodal(false)
|
||||
}}>加入战队参赛</Button>
|
||||
<Button style={{ height: 40 }} onClick={() => {
|
||||
setIsAddmodel(true)
|
||||
setisshowmodal(false)
|
||||
}}>去创建战队参赛</Button>
|
||||
|
||||
} style={{ cursor: 'pointer'}}>立即报名</Button> : null}
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
</div>
|
||||
|
||||
</List.Item>
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
/>
|
||||
|
||||
}
|
||||
</Skeleton>
|
||||
<AuthModel />
|
||||
<AdverModel modeldata={modeldata} dispatch={dispatch} />
|
||||
<aside className="tc mb50 mt20">
|
||||
<Pagination
|
||||
hideOnSinglePage
|
||||
showSizeChanger={false}
|
||||
onChange={onShowSizeChange}
|
||||
defaultPageSize={20}
|
||||
current={competitions.listParams.page}
|
||||
defaultCurrent={competitions.listParams.page}
|
||||
total={competitions.count}
|
||||
/>
|
||||
</aside>
|
||||
</aside>
|
||||
</div>}
|
||||
{
|
||||
isStatistics && <StatisticsItem />
|
||||
}
|
||||
{isJoin ? <JoinTeam isjoin={isJoin} setJoin={setJoin} JoinTeams={JoinTeams} /> : null}
|
||||
{isAddmodel ? <AddteamsModel isAddmodle={isAddmodel} setIsAdd={setIsAddmodel} createTeam={addTeams} /> : null}
|
||||
<PhoneModal datas={datas} isopen={isopen} setisopen={setisopen} isShowPhone={showphone} setIsShowPhone={setshowphone} user={user} dispatch={dispatch} onOK={()=>{
|
||||
dispatch({
|
||||
type: 'competitions/getList',
|
||||
payload: { ...competitions.listParams },
|
||||
});
|
||||
}} />
|
||||
<ClaModal
|
||||
visible={visible}
|
||||
onCancel={()=>{setVisible(false)}}
|
||||
onOk={()=>{
|
||||
setVisible(false);
|
||||
setisshowmodal(true);
|
||||
}}/>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
@ -319,17 +649,16 @@ export default connect(
|
|||
competitions,
|
||||
loading,
|
||||
globalSetting,
|
||||
user
|
||||
user,
|
||||
}: {
|
||||
competitions: CompetitionsModelState;
|
||||
loading: Loading;
|
||||
globalSetting: GlobalSettingModelState;
|
||||
user: UserModelState;
|
||||
|
||||
}) => ({
|
||||
competitions,
|
||||
globalSetting,
|
||||
loading: loading.models.competitions,
|
||||
user
|
||||
user,
|
||||
}),
|
||||
)(competitionsPage);
|
||||
)(competitionsIndexPage);
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
.claBox{
|
||||
div[class~="ant-modal-body"]{
|
||||
padding:0px;
|
||||
}
|
||||
.box{
|
||||
display: flex;
|
||||
position: relative;
|
||||
&>div{
|
||||
flex: 1;
|
||||
height: 43em;
|
||||
overflow: auto;
|
||||
padding:0em 2.5em 1.5em 2.5em;
|
||||
.title{
|
||||
font-weight: 500;
|
||||
color: #1f2329;
|
||||
font-size: 18px;
|
||||
height: 3.5em;
|
||||
padding-top: 1.5em;
|
||||
margin-bottom: 0px!important;
|
||||
position: absolute;
|
||||
left: 2em;
|
||||
top: 0;
|
||||
width: calc(50% - 4em);
|
||||
background-color: #fff;
|
||||
}
|
||||
.content p{
|
||||
color:#333333;
|
||||
font-size:14px;
|
||||
line-height:28px;
|
||||
text-indent:2em;
|
||||
margin-bottom: 0px!important;
|
||||
}
|
||||
}
|
||||
.rightBox{
|
||||
background-image:linear-gradient(116.34deg,#ffffff 0%,#e8f1ff 100%);
|
||||
border-radius:0px 16px 16px 0px;
|
||||
padding-top: 2em;
|
||||
.desc{
|
||||
background-color:rgba(175, 183, 194, 0.13);
|
||||
border-radius:6px;
|
||||
color:#4c5b76;
|
||||
font-size:14px;
|
||||
line-height: 20px;
|
||||
padding:1em;
|
||||
}
|
||||
.formWrap{
|
||||
margin-top: 1em;
|
||||
div[class~='ant-form-item-label']{
|
||||
color:#202d40;
|
||||
font-size:15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
import React, { FC, useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
CompetitionsModelState,
|
||||
GlobalSettingModelState,
|
||||
ConnectProps,
|
||||
Dispatch,
|
||||
connect,
|
||||
Loading,
|
||||
UserModelState,
|
||||
} from 'umi';
|
||||
import {
|
||||
Form,
|
||||
Modal,
|
||||
Tooltip,
|
||||
InputNumber,
|
||||
Input,
|
||||
Table,
|
||||
Button,
|
||||
Tabs,
|
||||
message,
|
||||
Checkbox,
|
||||
Select
|
||||
} from 'antd';
|
||||
import Fetch from '@/utils/fetch';
|
||||
import { useInterval } from '@/utils/hooks/useInterval';
|
||||
import { setmiyah } from '@/utils/util';
|
||||
import env from '@/utils/env';
|
||||
import Styles from './Cla.less';
|
||||
import Cla from '@/assets/images/competition/cla.png';
|
||||
|
||||
const phoneReg = /^1\d{10}$/;
|
||||
|
||||
interface PageProps extends ConnectProps {
|
||||
competitions: CompetitionsModelState;
|
||||
globalSetting: GlobalSettingModelState;
|
||||
loading: boolean;
|
||||
dispatch: Dispatch;
|
||||
user: UserModelState;
|
||||
visible: boolean;
|
||||
onCancel: () => void;
|
||||
onOk: () => void;
|
||||
}
|
||||
|
||||
const AddClamodal: FC<PageProps> = ({
|
||||
competitions,
|
||||
globalSetting,
|
||||
loading,
|
||||
dispatch,
|
||||
user,
|
||||
visible,
|
||||
onCancel = () => { },
|
||||
onOk = () => { },
|
||||
}) => {
|
||||
const [form] = Form.useForm();
|
||||
const { setFieldsValue , getFieldsValue , validateFields } = form;
|
||||
const [ checkCla , setCheckCla ] = useState(false);
|
||||
const [ checkClaFlag , setCheckClaFlag ] = useState(false);
|
||||
|
||||
useEffect(()=>{
|
||||
if(user?.userInfo){
|
||||
let info = user?.userInfo;
|
||||
setFieldsValue({
|
||||
GitLinkID:info.login,
|
||||
email:info.email,
|
||||
name:info.nickname,
|
||||
phoneNumber:info.phone,
|
||||
address:info.province,
|
||||
})
|
||||
}
|
||||
},[user?.userInfo])
|
||||
|
||||
|
||||
async function getCla(){
|
||||
await validateFields();
|
||||
let values = getFieldsValue();
|
||||
if(!checkClaFlag && checkCla){
|
||||
let data = await dispatch({
|
||||
type: 'competitions/SignCLA',
|
||||
payload: {
|
||||
owner:user?.userInfo?.login,
|
||||
login:user?.userInfo?.login,
|
||||
email:values?.email,
|
||||
nickname:values?.name,
|
||||
phone:values?.phoneNumber,
|
||||
address:values?.address,
|
||||
}
|
||||
})
|
||||
if (data && data.status === 0) {
|
||||
onOk();
|
||||
}
|
||||
}else{
|
||||
setCheckClaFlag(true);
|
||||
}
|
||||
}
|
||||
return(
|
||||
<Modal
|
||||
visible={visible}
|
||||
title=""
|
||||
footer={null}
|
||||
width="85em"
|
||||
wrapClassName={Styles.claBox}
|
||||
onCancel={onCancel}
|
||||
>
|
||||
<div className={Styles.box}>
|
||||
<div>
|
||||
<p className={Styles.title}><img src={Cla} width="21px" style={{marginRight:"14px"}}/>签署 Openkylin CLA</p>
|
||||
<div style={{height:"4.5em"}}></div>
|
||||
<div className={Styles.content}>
|
||||
<p>感谢您对向 GitLink 社区拥有或管理的项目贡献软件代码的兴趣。为明确任何个人或实体贡献内容而授予的知识产权许可,GitLink 必须对每位贡献者签署的贡献者许可协议进行归档,以证明就以下许可条件达成的一致。本协议是为了保护作为贡献者的您,也是为了保护社区和它的用户,它不会改变您将自己的贡献用于任何其他目的的权利。</p>
|
||||
<p>请在签署之前仔细阅读本文件,并自行保留一份副本作为您的记录。就您目前和将来向 GitLink 社区提交的贡献内容,您接受并同意以下条款。除了根据本协议授予 GitLink 社区、GitLink 社区所分发软件的接收者的许可外,您对于您的贡献内容保留所有权利、所有权和权益。</p>
|
||||
<p>1. 定义“您”(或“您的”)指与 GitLink 社区签署本协议的著作权人或经著作权人授权的法律实体。对于法律实体而言,提交贡献内容的实体以及其他任何控制该实体、受其控制或与其受到同一主体控制的实体被视为单个贡献者。为本定义之目的,“控制”是指:(i)通过合同或其他方式,直接或间接指导或管理该实体的权利,或(ii)持有该实体 50%或以上的发行股份,或(iii)间接持有该实体权益。</p><p>“贡献”是指由您有意地向 GitLink 社区提交,以便被包含或记载在任何GitLink 社区拥有或管理的产品或项目中的任何原创作品,包括对既存作品的任何修改和增加。为本定义之目的,“提交”是指向 GitLink 社区或其代表进行的任何形式的电子或书面交流,包括但不限于为讨论和改善作品为目的,通过GitLink 社区管理的(或以 GitLink 社区名义管理的)电子邮件列表、源代码控制系统和问题跟踪系统进行的交流。</p>
|
||||
<p>2. 著作权许可授予</p>
|
||||
<p>受限于本协议的条款和条件,您在此授予 GitLink 社区以及GitLink 社区发布软件的接收方永久性的、全球范围内的、非独占的、免许可费的、免版权费的和不可撤销的著作权许可,以复制、衍生、公开展示、公开执行、转授权和发布您的贡献及其衍生作品。</p>
|
||||
<p>3. 专利许可的授予</p>
|
||||
<p>受限于本协议的条款和条件,您在此授予 GitLink 社区以及GitLink 社区发布软件的接收方永久性的、全球范围内的、非独占的、免许可费的、免版权费的和不可撤销(本节规定的情形除外)的专利许可,以开发、利用、要约出售、出售、导入或以其他方式转让作品,但该许可仅适用于您有权许可的,且必然会被您的贡献内容侵权(贡献内容单独构成侵权、或与贡献内容的相关作品一同构成
|
||||
侵权)的专利申请范围。如果任何实体针对您或其他实体提起专利诉讼(包括诉讼中的交叉请求或反诉),主张您的贡献内容(或您参与贡献的作品)造成了直接性或辅助性的专利侵权,则任何根据本协议针对该贡献内容或作品授予该实体的专利许可应当在起诉之日终止。</p>
|
||||
<p>4. 您保证您依法有权授予上述许可。如果您的雇主对您创造的知识产权拥有权利,其中包括您的贡献,您承诺您的雇主已授权您提交该贡献,您的雇主已放弃您对 GitLink 社区的贡献的权利,或您的雇主已与 GitLink 社区签订单独的企业贡献者许可协议。</p>
|
||||
<p>5. 您保证您所有的贡献内容均为您的原创作品(关于为他人提交作品的规定,可参见第 7 节)。您保证您提交的贡献内容包括任何第三方许可或其他限制(包括但不限于相关专利或商标)的全部细节,只要该等许可或其他限制为您个人所知悉且与您的贡献内容的任何部分相关。如发生不受本协议约束的第三方指控您所贡献内容存在知识产权(包括并不限于著作权、专利权)法律瑕疵时,则由您负责与该第三方交涉,GitLink 社区不承担由此引起的一切法律和经济上的责任。</p>
|
||||
<p>6. 在您自愿提供支持的范围之外,您无需对您的贡献内容提供支持。您可以提供免费支持或收费支持,也可以完全不提供支持。除非适用法律另有规定或另有书面约定,您“按照现状”提供您的贡献内容,而不对其提供任何类型的保证或条件,无论明示还是默示,包括但不限于为任何特定目的对所有权、无侵权、适销性或适当性的保证或条件。</p>
|
||||
<p>7. 如果您希望提交并非您原创的作品,您可以在任何贡献内容之外单独向GitLink 社区提交,标注关于其来源和您个人所知悉的任何许可或其他限制(包括但不限于相关专利、商标和许可协议)的完整信息,并以显著方式标明该作品属于“以第三方名义提交:【填写姓名】”。</p>
|
||||
<p>8. 您同意在您获悉任何可能导致上述保证在任何方面不准确的事实或情况之时通知 GitLink 社区。</p>
|
||||
<p>9. 本协议受中华人民共和国法律管辖,并依据其进行解释,但冲突法规则除外。任何由本协议产生的法律诉讼或程序均应排他性地提交至中国长沙的法院进行审理,且各方在此不可撤销地同意该等关于属人管辖和法院地的安排。</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className={Styles.rightBox}>
|
||||
<div className={Styles.desc}>
|
||||
1、在报名前,请确保已签署openkylin项目cla协议<br/>2、完成签署后,您将同步注册一个openkylin账号
|
||||
</div>
|
||||
<Form
|
||||
form={form}
|
||||
className={Styles.formWrap}
|
||||
scrollToFirstError
|
||||
layout="vertical"
|
||||
>
|
||||
<Form.Item
|
||||
name="GitLinkID"
|
||||
label="GitLinkID"
|
||||
rules={[
|
||||
{ required: true, message: 'GitLinkID不能为空' },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入GitLinkID" disabled/>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="email"
|
||||
label="邮箱"
|
||||
rules={[
|
||||
{ required: true, message: '邮箱不能为空' },
|
||||
]}
|
||||
>
|
||||
<Input placeholder="请输入邮箱账号" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="name"
|
||||
label="姓名"
|
||||
rules={[
|
||||
{ required: true, message: '姓名不能为空' },
|
||||
]}
|
||||
>
|
||||
<Input maxLength={32} placeholder="请输入姓名" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="phoneNumber"
|
||||
label="手机号码"
|
||||
rules={[
|
||||
{ required: true, message: '手机号码不能为空' },
|
||||
]}
|
||||
>
|
||||
<Input maxLength={11} placeholder="请输入手机号码" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="address"
|
||||
label="联系地址"
|
||||
rules={[
|
||||
{ required: true, message: '联系地址不能为空' },
|
||||
]}
|
||||
>
|
||||
<Input maxLength={100} placeholder="请输入联系地址(不超过100个字)" />
|
||||
</Form.Item>
|
||||
<Checkbox
|
||||
value="readed"
|
||||
checked={checkCla}
|
||||
onChange={(e)=>{
|
||||
setCheckCla(e.target.checked);
|
||||
if(!e.target.checked){
|
||||
setCheckClaFlag(true);
|
||||
}else{
|
||||
setCheckClaFlag(false);
|
||||
}
|
||||
}
|
||||
}>我已阅读并同意签署</Checkbox>
|
||||
<div style={{color:"#ff4d4f",height:"20px"}}>{checkClaFlag && <p style={{margin:"0px"}}>请阅读并同意签署CLA协议</p> }</div>
|
||||
<Button type="primary" onClick={getCla} style={{width:"100%",height:"36px",backgroundColor:"#466aff"}}>签署</Button>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
export default connect(
|
||||
({
|
||||
competitions,
|
||||
loading,
|
||||
globalSetting,
|
||||
user,
|
||||
}: {
|
||||
competitions: CompetitionsModelState;
|
||||
loading: Loading;
|
||||
globalSetting: GlobalSettingModelState;
|
||||
user: UserModelState;
|
||||
}) => ({
|
||||
competitions,
|
||||
globalSetting,
|
||||
loading: loading.models.competitions,
|
||||
user,
|
||||
}),
|
||||
)(AddClamodal);
|
|
@ -0,0 +1,227 @@
|
|||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import {
|
||||
Steps,
|
||||
Modal,
|
||||
Tooltip,
|
||||
InputNumber,
|
||||
Input,
|
||||
Table,
|
||||
Button,
|
||||
Tabs,
|
||||
message,
|
||||
Checkbox,
|
||||
Select
|
||||
} from 'antd';
|
||||
import Fetch from '@/utils/fetch';
|
||||
import { useInterval } from '@/utils/hooks/useInterval';
|
||||
import { setmiyah } from '@/utils/util';
|
||||
import env from '@/utils/env';
|
||||
|
||||
const phoneReg = /^1\d{10}$/;
|
||||
|
||||
function Addmodal({
|
||||
isShowPhone,
|
||||
setIsShowPhone,
|
||||
user,
|
||||
dispatch,
|
||||
onOK,
|
||||
isopen,
|
||||
setisopen,
|
||||
datas,
|
||||
}: any) {
|
||||
|
||||
const [phone,setphone]=useState<any>('');
|
||||
const [PhoneValue,setPhoneValue]=useState<any>('')
|
||||
const [countdown, setCountdown] = useState<number>(60);
|
||||
const [countdownFlag, setCountdownFlag] = useState<boolean>();
|
||||
const [isShowPoint,setIsShowPoint]=useState<any>(false);
|
||||
const [isShowUntie,setIsShowUntie]=useState<any>(false);
|
||||
const [UntieValue,setUntieValue]=useState<any>('');
|
||||
|
||||
|
||||
const intervalId = useRef();
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
intervalId.current && clearInterval(intervalId.current);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useInterval(() => {
|
||||
if (!countdownFlag) {
|
||||
return;
|
||||
}else{
|
||||
setCountdown(60);
|
||||
}
|
||||
if (countdown > 0) {
|
||||
setCountdown(countdown - 1);
|
||||
} else {
|
||||
setCountdown(60);
|
||||
setCountdownFlag(false);
|
||||
intervalId.current && clearInterval(intervalId.current);
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
const handleGetCode = async () => {
|
||||
|
||||
//调用接口 获取该手机号是否被绑定
|
||||
let data=await Fetch(`/api/users/accounts/${user.userInfo?.login}/valid_phone.json`,{
|
||||
method: 'get',
|
||||
params:{
|
||||
phone
|
||||
}
|
||||
})
|
||||
if(data?.status===-1){return}
|
||||
if(data?.is_exists){
|
||||
setIsShowPoint(true)
|
||||
return
|
||||
}
|
||||
|
||||
let smscode = setmiyah(phone);
|
||||
const res = await dispatch({
|
||||
type: 'account/getCode',
|
||||
payload: { login:phone, type:3, smscode }
|
||||
});
|
||||
if (res.status === 1) {
|
||||
message.info('验证码已发送,请注意查收');
|
||||
setCountdownFlag(true);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Modal
|
||||
title="强制解绑"
|
||||
visible={isShowUntie}
|
||||
onCancel={()=>setIsShowUntie(false)}
|
||||
onOk={async ()=>{
|
||||
if(!UntieValue){
|
||||
message.info('验证码不能为空')
|
||||
return
|
||||
}
|
||||
|
||||
let data=await Fetch(
|
||||
`/api/users/accounts/${user?.userInfo?.login}/phone_force_unbind.json`,{
|
||||
method: 'POST',
|
||||
body:{
|
||||
code:UntieValue,
|
||||
phone,
|
||||
}
|
||||
}
|
||||
)
|
||||
if(data?.status===0){
|
||||
message.info('解绑成功')
|
||||
setCountdownFlag(false);
|
||||
setIsShowUntie(false)
|
||||
onOK()
|
||||
setIsShowPhone(false)
|
||||
setUntieValue('')
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div style={{padding:'8px 24px'}}>
|
||||
<p>若原账号只有绑定了手机号一种登录方式,强制解绑后会导致原账号无法登录,请确定是否强制解绑</p>
|
||||
<p>你的手机号:{phone}</p>
|
||||
<p>手机验证码:<Input value={UntieValue} size="large" onChange={(e)=>setUntieValue(e.target.value)} style={{width:'240px'}}/> <Button disabled={countdownFlag} type="primary" size="large" onClick={async()=>{
|
||||
|
||||
let smscode = setmiyah(phone);
|
||||
const res = await dispatch({
|
||||
type: 'account/getCode',
|
||||
payload: { login:phone, type:10, smscode }
|
||||
});
|
||||
|
||||
if (res.status === 1) {
|
||||
message.info('验证码已发送,请注意查收');
|
||||
setCountdownFlag(true);
|
||||
}
|
||||
}}>{countdownFlag ? `重新发送${countdown}s` : '获取验证码'}</Button></p>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal
|
||||
title="提示"
|
||||
visible={isShowPoint}
|
||||
onCancel={()=>{
|
||||
setIsShowPoint(false)
|
||||
}}
|
||||
okText="进行强制解绑"
|
||||
okButtonProps={{
|
||||
type:"primary",
|
||||
ghost:true,
|
||||
style:{width:"124px"}
|
||||
}}
|
||||
onOk={()=>{
|
||||
setIsShowUntie(true)
|
||||
setIsShowPoint(false)
|
||||
}}
|
||||
// footer={<div>
|
||||
// <Button style={{textAlign:'end'}} type="primary" onClick={()=>setIsShowModal(false)}>确 定</Button>
|
||||
// </div>}
|
||||
>
|
||||
<div style={{padding:'7px 24px'}}>
|
||||
<span>该手机号已经被绑定账号,如果需要将该手机号绑定在当前账号上,你可以进行下方任意一种解绑操作:</span>
|
||||
<br />
|
||||
<p style={{marginTop:'1em',display:'flex'}}>
|
||||
<span style={{flex:'1'}}>1、使用该手机号登录平台进行解绑,再将手机号绑定当前账号上。</span>
|
||||
</p>
|
||||
<p style={{marginTop:'1em',display:'flex'}}>
|
||||
<span style={{flex:'1'}}>2、强制解绑(强制解绑可能会导致解绑账号无法登录)</span>
|
||||
</p>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal
|
||||
title="绑定手机号"
|
||||
visible={isShowPhone}
|
||||
onCancel={()=>setIsShowPhone(false)}
|
||||
onOk={async ()=>{
|
||||
if (!phoneReg.test(phone)) {
|
||||
message.info("请输入有效的11位手机号码");
|
||||
return;
|
||||
}
|
||||
if(!PhoneValue){
|
||||
message.info("请输入验证码");
|
||||
return
|
||||
}
|
||||
const { login } = user.userInfo || {};
|
||||
const res = await dispatch({
|
||||
type: 'account/bindPhone',
|
||||
payload: { login, phone,code:PhoneValue }
|
||||
});
|
||||
if (res?.status === 0) {
|
||||
setIsShowPhone(false)
|
||||
onOK()
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div style={{padding:'8px 24px'}}>
|
||||
<p>平台已检测到您未绑定手机号,为了不影响使用报名功能,请先绑定手机号码</p>
|
||||
<p>你的手机号:<Input size="large" value={phone} onChange={(e:any)=>setphone(e.target.value)} style={{width:'240px'}}/></p>
|
||||
<p>手机验证码:<Input size="large" value={PhoneValue} onChange={(e:any)=>setPhoneValue(e.target.value)} style={{width:'240px'}}/> <Button disabled={countdownFlag} type="primary" size="large" onClick={async ()=>{
|
||||
if (!phoneReg.test(phone)) {
|
||||
message.info("请输入有效的11位手机号码");
|
||||
return;
|
||||
}
|
||||
handleGetCode()
|
||||
}}>{countdownFlag ? `重新发送${countdown}s` : '获取验证码'}</Button></p>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal
|
||||
visible={isopen}
|
||||
footer={false}
|
||||
onCancel={()=>setisopen(false)}
|
||||
centered={true}
|
||||
width={460}
|
||||
>
|
||||
<div>
|
||||
<div style={{marginTop:50,fontSize:26,color:'#3d3d3d',textAlign:'center',marginBottom:20}}><i style={{fontSize:26,color:'#52C41A'}} className="iconfont icon-tongguo" /> 报名成功</div>
|
||||
<div style={{alignItems:'center',textAlign:'center'}}>
|
||||
<img style={{width:180,border:'1px solid #eeeeef',padding:10,marginBottom:20}} src={env.IMG_SERVER+datas?.QR_code}/>
|
||||
<p style={{color:'#AAAAAA'}}>参赛者可扫码加入大赛官方交流群,获取最新竞赛通知</p>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
export default Addmodal;
|
|
@ -1,4 +1,5 @@
|
|||
import Fetch from '@/utils/fetch';
|
||||
import ENV from '@/utils/env';
|
||||
//获取在线竞赛列表
|
||||
export async function getCompetitionsList(params: any) {
|
||||
return Fetch('/api/competitions.json', {
|
||||
|
@ -92,6 +93,19 @@ export async function JoinTeam(params:any){
|
|||
body: params,
|
||||
});
|
||||
}
|
||||
// 签署CLA协议
|
||||
export async function SignCLA(params: any) {
|
||||
return Fetch(`${ENV.FORGE_SERVER}/api/v1/${params?.owner}/openkylin_sign`, {
|
||||
method: 'post',
|
||||
body: params
|
||||
});
|
||||
}
|
||||
// 签署CLA协议
|
||||
export async function GetKylinId(params: any) {
|
||||
return Fetch(`${ENV.FORGE_SERVER}/api/v1/${params?.owner}/openkylin_sign/competitions`, {
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
//查找老师
|
||||
export async function getTeacher(params:any){
|
||||
return Fetch(`/api/competitions/${params.identifier}/teachers.json`,{
|
||||
|
|
|
@ -17,3 +17,18 @@ export async function getSystemUpdate() {
|
|||
method: 'Get',
|
||||
});
|
||||
}
|
||||
|
||||
//添加搜索记录
|
||||
export type Position = 'Subject' | 'Course' | 'Shixun' | 'Competition' | 'Practice' | 'Memos' | 'ItemBank' | 'Exercise' | 'HomeworkCommon'
|
||||
|
||||
export type addRecordReq = {
|
||||
name: string;
|
||||
position: Position,
|
||||
copywriting: string
|
||||
}
|
||||
export async function addSearchRecord(params: addRecordReq) {
|
||||
return Fetch('/api/search_records', {
|
||||
method: 'post',
|
||||
body: params
|
||||
})
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
export const DEV = {
|
||||
PROXY_SERVER: "https://kepukehuan-data.educoder.net",
|
||||
PROXY_SERVER: "https://test-data.educoder.net",
|
||||
API_SERVER: "https://pre-data.educoder.net",
|
||||
REPORT_SERVER: "http://192.168.1.57:3001",
|
||||
IMG_SERVER: 'https://new-testali-cdn.educoder.net',
|
||||
FORGE: "https://code.educoder.net/",
|
||||
SSH_SERVER:"wss://webssh.educoder.net",
|
||||
QQLoginCB: encodeURIComponent("https://test-newweb.educoder.net"),
|
||||
FORGE_SERVER:"https://pre.gitlink.org.cn"
|
||||
FORGE_SERVER:"https://testforgeplus.trustie.net"
|
||||
}
|
||||
|
||||
export default DEV
|
|
@ -270,7 +270,6 @@ export default function request(url: string, option: any, flag?: boolean) {
|
|||
|
||||
try {
|
||||
if (d.status === 401 && (!newOptions.params?.hidePopLogin || !newOptions.body?.hidePopLogin)) {
|
||||
console.log("new:", newOptions)
|
||||
getDvaApp()._store.dispatch({
|
||||
type: 'user/showPopLogin',
|
||||
payload: {
|
||||
|
|
Loading…
Reference in New Issue