forgeplus-react/src/pages/Competitions/Detail/index.tsx

739 lines
26 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { FC, useEffect, useState, useRef } from 'react';
import {
GlobalSettingModelState,
ConnectProps,
Loading,
connect,
Dispatch,
Link,
useParams,
UserModelState,
useLocation,
} from 'umi';
import styles from './index.less';
import AuthModel from '@/components/AuthenticationModel'
import AddSubmitModel from './AddSubmitModel'
import { Breadcrumb, Button, Menu, message, Spin, Modal } from 'antd';
//查看内容
import SeeItem from './SeeItem';
//编辑内容
import UpItem from './Update';
import RanKing from './Ranking'//排行榜
import Award from './AwardPdf' //获奖证书
import ENV from '@/utils/env';
import { openNewWindow,setDocumentTitle } from '@/utils/util';
import { handleVerifyLogin, handleVerify } from '@/utils/verifyLogin';
import { isSuperAdmin } from '@/utils/authority';
import SubmitResult from './SubmitResult'
import MakeItem from './MakeItem'
import Entrance from './Entrance'
import QR from './mCode.png';
import JoinTeam from '../Entered/Enteredmodel/JoinModel'
import AddteamsModel from '../Entered/Enteredmodel/Addteams';
import InitGitLink from './components/InitGitLink'
import PhoneModal from '../components/PhoneModal'
import env from '@/utils/env';
import ClaModal from '../components/ClaModal';
import SubCompetition from './components/SubCompetition';
interface PageProps extends ConnectProps {
globalSetting: GlobalSettingModelState;
loading: Loading;
dispatch: Dispatch;
user: UserModelState;
}
const competitionDetails: FC<PageProps> = ({
globalSetting,
loading,
dispatch,
user,
...props
}) => {
const [HeaderDetail, setHeaderDetail] = useState<any>({
avatar_url: ""
});
const [StaffDetail, setStaffDetail] = useState<any>([])
const { identifier } = useParams();
const [ItemData, setItemData] = useState<any>([]);
//打开编辑还是打开查看
const [ISsee, setIssee] = useState(true);
const [MenuItem, setMenuItem] = useState<any>([]);
const [ModelType, setModelType] = useState<any>([]);
//点击了排行榜
const [isRanKing, setIsRanKing] = useState<any>(false);
//获取排行榜
const [ChartRules, setChartRules] = useState<any>(false);
//点击了获奖证书
const [isAward, setIsAward] = useState<any>(false);
//获奖证书信息
const [Prize, setPrize] = useState<any>([]);
//获取个人信息 Accounts
const [Accounts, SetAccounts] = useState<any>([]);
//设置选中的条目
let [Selectkey, setSeleckjey] = useState<any>([]);
//md_tab
const [MdTab, setMdTab] = useState<any>(false);
//getTabResults
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 [ subGitlinkShow , setSubGitlinkShow ] =useState<any>(false);
const [ subComShow , setSubComShow ] = useState<any>(false);
const [ subComList , setSubComList] = useState<any>([]);
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 loction = useLocation();
const see = useRef(null);
useEffect(()=>{
if(user?.userInfo?.is_new){
setSubGitlinkShow(true);
}
},[user?.userInfo])
useEffect(() => {
if (identifier) {
setTimeout(() => {
init();
}, 200);
}
}, [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])
useEffect(() => {
if (HeaderDetail?.competition_modules?.length > 0) {
if (loction?.query?.active === '赛题发布') {
const item = HeaderDetail?.competition_modules?.find((e: any) => e.name === '赛题发布');
if (item) {
getrightdatas(item);
return;
}
}
getrightdatas(HeaderDetail?.competition_modules?.[0]);
}
}, [HeaderDetail])
async function getrightdatas(item: any) {
setSeleckjey(item.id);
Selectkey = item.id;
setMenuItem(item);
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);
getChartRules();
} else if (item.module_type === "certificate") {
setIsAward(true);
setIsRanKing(false)
setIssee(false);
getPrize();
} else if (item.module_type === "md_tab") {
setMdTab(true);
setIssee(false);
localStorage.setItem('issee','2');
setIsRanKing(false)
setIsAward(false);
// getChartRules();
getTabResults();
} 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 (!handleVerify(dispatch)) {
return;
}
if(HeaderDetail.teacher_need_phone||HeaderDetail.member_need_phone){
setshowphone(true)
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);
if(filterArr && filterArr.length >0 ){
setSubComShow(true);
setSubComList(filterArr[0]);
return;
}
}
}
let data =await dispatch({
type: 'competitions/GetKylinId',
payload: {
owner:user?.userInfo?.login
}
})
let a =data.data;
let filter = a.filter((i:any)=>i.toString() === item?.id.toString());
let flag = filter && filter.length>0 ? true : false;
if(flag){
if(!user?.userInfo?.sign_cla){
setVisible(true);
return;
}
}
if (HeaderDetail?.is_authentication && !user?.userInfo?.authentication) {
dispatch({
type: 'shixunsDetail/setActionTabs',
payload: {
key: 'Banner-Auth',
},
})
return
}
if (HeaderDetail?.enroll_url) {
openNewWindow(HeaderDetail?.enroll_url);
return
}
if (url === "ismodel") {
if (item.member_of_course === true) {
openNewWindow(`/classrooms/${item.course_id}`)
} else {
if (!item.invite_code) {
message.info('本竞赛只面向部分学校/单位开放,你暂时没有参赛资格')
return
}
const result = await dispatch({
type: 'competitions/addApplytojoincourse',
payload: {
invite_code: item.invite_code,
student: 1
}
});
if (result.status === 0) {
openNewWindow(`/classrooms/${item.course_id}`);
}
}
} else {
if (StaffDetail.enrolled === true) {
openNewWindow(url)
return;
}
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 = data.data;
// 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(
await dispatch({
type: 'competitions/ChartRules',
payload: {
identifier: identifier
}
})
)
}
async function getCharts(id: any) {
let data = await dispatch({
type: 'competitions/Charts',
payload: {
identifier: identifier,
stage_id: id
}
})
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',
payload: {
identifier: identifier,
stage_id: id
}
})
if(localStorage.getItem('issee')==='1') return
setItemData(data);
}
async function getTabResults() {
setTabResults(
await dispatch({
type: 'competitions/TabResults',
payload: {
identifier: identifier,
competition_module_id: Selectkey,
}
})
)
}
async function getPrize() {
let data = await dispatch({
type: 'competitions/Prize',
payload: {
identifier: identifier,
user_id: user?.userInfo?.user_id,
//user_id:39416
}
})
setPrize(data);
}
//个人信息 Accounts
async function getAccounts() {
let data = await dispatch({
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('-------',(HeaderDetail.identifier === "track1_2023" || HeaderDetail.identifier === "track2_2023" || HeaderDetail.identifier === "track4_2023" )?false:(StaffDetail.enrolled && !HeaderDetail.need_attachment));
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"} style={{ display: 'flex', background: '#fff', position: 'relative',padding:'20px 12px' }} >
<Spin spinning={loading.effects['competitions/getHeader']} >
<div style={{ height: '355px', width: "800px" }}>
{
HeaderDetail?.avatar_url && HeaderDetail?.avatar_url !== null && <img style={{ height: '355px', width: '800px' }} src={ENV.IMG_SERVER + '/' + HeaderDetail?.avatar_url} />
}
{
!HeaderDetail?.avatar_url && HeaderDetail?.avatar_url == null && <img style={{ height: '355px', width: '800px' }} src={ENV.IMG_SERVER + `/images/educoder/competitions/mainbanner.jpg`} />
}
</div>
</Spin>
<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 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>
<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')
}
}} 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={(HeaderDetail.identifier === "track1_2023" || HeaderDetail.identifier === "track2_2023" || HeaderDetail.identifier === "track4_2023" )?false:(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.identifier === "track1_2023" || HeaderDetail.identifier === "track2_2023" || HeaderDetail.identifier === "track4_2023" ) ? "立即报名" : 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}>
<div className={styles.flex1}>
{/* selectedKeys要求string类型 */}
<Menu selectedKeys={[`${Selectkey}`]} >
{HeaderDetail && HeaderDetail.competition_modules && HeaderDetail.competition_modules.map((item: any, index: number) => {
if (item.module_type != "enroll") {
return (
<Menu.Item className={styles.menuItem} onClick={() => {
if (item?.is_authentication) {
if (!handleVerify(dispatch)) {
return;
}
message.info('加入战队才能查看');
return
}
// if(item?.item?.has_url){
// window.visible(item?.module_url)
// return
// }
getrightdatas(item)
}} key={item.id} >{item.name}</Menu.Item>
)
}
})}
</Menu>
</div>
<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 &&!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 />
<AddSubmitModel getResults={getResults} />
<Modal
visible={isshowType}
// visible
footer={null}
width={720}
title="提示"
centered={true}
onCancel={() => setisshowType(false)}
>
<div className={styles.modal}>
<div></div>
<div><span style={{ color: '#FF8C29' }}>300,000</span></div>
<div>12512000RMB/ </div>
<div>2耀殿</div>
<div>3+</div>
<div></div>
<Button type="primary" onClick={() => openNewWindow('https://competition.huaweicloud.com/information/1000041485/introduction')}></Button>
</div>
</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);
dispatch({
type: 'user/getUserInfo',
payload: {}
})
}}/>
</div>
)
}; export default connect(
({
loading,
globalSetting,
user,
}: {
loading: Loading;
globalSetting: GlobalSettingModelState;
user: UserModelState;
}) => ({
globalSetting,
loading: loading,
user
}),
)(competitionDetails);