定制竞赛-issue

This commit is contained in:
谢思 2022-03-29 22:49:21 +08:00 committed by 何童崇
parent 507fe8788f
commit d7b3303bcb
6 changed files with 83 additions and 50 deletions

View File

@ -3,7 +3,7 @@ import { Table, Pagination } from 'antd';
import './index.scss'; import './index.scss';
export default (props) => { export default (props) => {
const {className, loading, dataSource, columns, handleRow, total, setCurPage, current, rowSelection, expandedRowRender, expandIconColumnIndex, expandIconAsCell, onShowSizeChange, showSizeChanger, pagination, scroll } = props; const {className, loading, dataSource, columns, handleRow, total, setCurPage, current, rowSelection, expandedRowRender, expandIconColumnIndex, expandIconAsCell, onShowSizeChange, showSizeChanger, pagination, scroll,pageSize } = props;
return ( return (
<div className={`pagination-table ${className}`}> <div className={`pagination-table ${className}`}>
@ -29,6 +29,7 @@ export default (props) => {
current={current} current={current}
total={total} total={total}
showSizeChanger={showSizeChanger} showSizeChanger={showSizeChanger}
pageSize={pageSize}
/>} />}
</div> </div>

View File

@ -1,18 +1,15 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { Link, Route, Switch } from "react-router-dom"; import { Link, Route, Switch } from "react-router-dom";
import { withRouter } from "react-router"; import { withRouter } from "react-router";
import { getImageUrl, SnackbarHOC } from "educoder"; import { SnackbarHOC } from "educoder";
import { CNotificationHOC } from "../modules/courses/common/CNotificationHOC"; import { CNotificationHOC } from "../modules/courses/common/CNotificationHOC";
import { TPMIndexHOC } from "../modules/tpm/TPMIndexHOC"; import { TPMIndexHOC } from "../modules/tpm/TPMIndexHOC";
import Loadable from "react-loadable"; import Loadable from "react-loadable";
import Loading from "../Loading"; import Loading from "../Loading";
// import { getUserInfo } from './expert/api';
import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC"; import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC";
import './qz2022/index.scss'; import './qz2022/index.scss';
import { Button, Dropdown, Menu, Popover, Spin } from "antd"; import { Menu, Popover, Spin } from "antd";
import banner from './qz2022/image/banner.png' import banner from './qz2022/image/banner.png'
import { paths } from "./qz2022/static";
import { getQz2022, userCompetitionStatus } from "./qz2022/api"; import { getQz2022, userCompetitionStatus } from "./qz2022/api";
const Introduce = Loadable({ const Introduce = Loadable({
@ -52,17 +49,6 @@ const Management = Loadable({
loading: Loading, loading: Loading,
}) })
const menu = (
<Menu>
<Menu.Item>
<Link to={{ pathname: `/competition/qz2022/management/applys` }}>报名列表</Link>
</Menu.Item>
<Menu.Item>
<Link to={{ pathname: `/competition/qz2022/management/production` }}>作品列表</Link>
</Menu.Item>
</Menu>
);
const Qz2022 = (props) => { const Qz2022 = (props) => {
const {history, current_user} = props; const {history, current_user} = props;
const {location} = history; const {location} = history;
@ -72,8 +58,21 @@ const Qz2022 = (props) => {
const [qzDetail, setQzDetail] = useState(); const [qzDetail, setQzDetail] = useState();
const [enrollStatus, setEnrollStatus] = useState(); const [enrollStatus, setEnrollStatus] = useState();
const menu = (
<Menu>
<Menu.Item>
<Link to={{ pathname: current_user && current_user.login ? `/competition/qz2022/management/applys` :'' }} onClick={()=>{current_user && !current_user.login && props.showLoginDialog()}}>报名列表</Link>
</Menu.Item>
<Menu.Item>
<Link to={{ pathname: current_user && current_user.login ? `/competition/qz2022/management/production` :'' }} onClick={()=>{current_user && !current_user.login && props.showLoginDialog()}}>作品列表</Link>
</Menu.Item>
</Menu>
);
useEffect(()=>{ useEffect(()=>{
setActive(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght)); setActive(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght));
// document.body.scrollTop = 0;
// window.scrollTo(0,0);
}, [pathname]) }, [pathname])
useEffect(()=>{ useEffect(()=>{
@ -119,12 +118,15 @@ const Qz2022 = (props) => {
<li className={active === "apply" ? "active" : ""}> <li className={active === "apply" ? "active" : ""}>
<Link to={{ pathname: applyStatus ? '/competition/qz2022/apply' :'' }} onClick={()=>{current_user && current_user.login ? !applyStatus && props.showNotification("当前不处于报名时间") : props.showLoginDialog()}}>参赛报名</Link> <Link to={{ pathname: applyStatus ? '/competition/qz2022/apply' :'' }} onClick={()=>{current_user && current_user.login ? !applyStatus && props.showNotification("当前不处于报名时间") : props.showLoginDialog()}}>参赛报名</Link>
</li> </li>
{/* <li className={active === "refer" ? "active" : ""}>
<Link to={{ pathname: referStatus ? `/competition/qz2022/refer` : '' }} onClick={()=>{current_user && current_user.login ? !referStatus && props.showNotification("未到作品提交时间,请耐心等待") : props.showLoginDialog()}}>提案提交</Link>
</li> */}
<li className={active === "refer" ? "active" : ""}> <li className={active === "refer" ? "active" : ""}>
<Link to={{ pathname: `/competition/qz2022/refer`}}>提案提交</Link> <Link to={{ pathname: referStatus ? `/competition/qz2022/refer` : '' }} onClick={()=>{current_user && current_user.login ? !referStatus && props.showNotification("未到作品提交时间,请耐心等待") : props.showLoginDialog()}}>提案提交</Link>
</li> </li>
{/* <li className={active === "apply" ? "active" : ""}>
<Link to={{ pathname: '/competition/qz2022/apply'}}>参赛报名</Link>
</li> */}
{/* <li className={active === "refer" ? "active" : ""}>
<Link to={{ pathname: `/competition/qz2022/refer`}}>提案提交</Link>
</li> */}
<li className={active === "statistics" ? "active" : ""}> <li className={active === "statistics" ? "active" : ""}>
<Link to={{ pathname: `/competition/qz2022/statistics` }}>数据统计</Link> <Link to={{ pathname: `/competition/qz2022/statistics` }}>数据统计</Link>
</li> </li>
@ -134,7 +136,7 @@ const Qz2022 = (props) => {
<li className={active === "contact" ? "active" : ""}> <li className={active === "contact" ? "active" : ""}>
<Link to={{ pathname: `/competition/qz2022/contact` }}>联系我们</Link> <Link to={{ pathname: `/competition/qz2022/contact` }}>联系我们</Link>
</li> </li>
{current_user && current_user.login && current_user.admin && <li className={(active === "applys" || active === "production") ? "active" : ""}> {qzDetail && qzDetail.is_manager && <li className={(active === "applys" || active === "production") ? "active" : ""}>
<Popover content={menu} placement="bottomRight" overlayClassName="qz_manage"> <Popover content={menu} placement="bottomRight" overlayClassName="qz_manage">
<a>后台管理</a> <a>后台管理</a>
</Popover> </Popover>

View File

@ -12,11 +12,10 @@ import apply_two from "../image/apply_two.png";
import apply_notice from "../image/apply_notice.png"; import apply_notice from "../image/apply_notice.png";
import './index.scss'; import './index.scss';
import '../../index.scss';
const Option = Select.Option; const Option = Select.Option;
export default Form.create()((props) => { export default Form.create()((props) => {
const {form, qzDetail, enrollStatus, setReload} = props const {form, qzDetail, enrollStatus, setReload} = props;
const {getFieldDecorator, validateFields, setFieldsValue } = form; const {getFieldDecorator, validateFields, setFieldsValue } = form;
const [members, setMembers] = useState([]); const [members, setMembers] = useState([]);
const [errorMessage, setErrorMessage] = useState(undefined); const [errorMessage, setErrorMessage] = useState(undefined);
@ -104,38 +103,38 @@ export default Form.create()((props) => {
{!(enrollStatus && enrollStatus.enroll_status) && <Form className="info_form"> {!(enrollStatus && enrollStatus.enroll_status) && <Form className="info_form">
{helper('参赛单位', {helper('参赛单位',
'org_name', 'org_name',
[{ required: true, message: "请正确输入报名信息" }, [{ required: true, message: "请正确输入参赛单位" },
{ max: 32, message: '超出限制长度32位字符请重新编辑' }], { max: 32, message: '超出限制长度32位字符请重新编辑' }],
<Input placeholder="请输入参赛单位" onBlur={()=>{verify("org_name")}}/> <Input placeholder="请输入参赛单位" onBlur={()=>{verify("org_name")}}/>
)} )}
{helper('参赛团队负责人姓名', {helper('参赛团队负责人姓名',
'leader', 'leader',
[{ required: true, message: "请正确输入报名信息" }, [{ required: true, message: "请正确输入负责人姓名" },
{ max: 32, message: '超出限制长度32位字符请重新编辑' }], { max: 32, message: '超出限制长度32位字符请重新编辑' }],
<Input placeholder="请输入参赛团队负责人姓名" onBlur={()=>{verify("leader")}}/> <Input placeholder="请输入参赛团队负责人姓名" onBlur={()=>{verify("leader")}}/>
)} )}
{qzDetail && qzDetail.is_local && helper('职务', {qzDetail && qzDetail.is_local && helper('职务',
'org_job', 'org_job',
[{ required: true, message: "请正确输入报名信息" }, [{ required: true, message: "请正确输入职务" },
{ max: 32, message: '超出限制长度32位字符请重新编辑' }], { max: 32, message: '超出限制长度32位字符请重新编辑' }],
<Input placeholder="请输入职务" onBlur={()=>{verify("org_job")}}/> <Input placeholder="请输入职务" onBlur={()=>{verify("org_job")}}/>
)} )}
{qzDetail && qzDetail.is_local && helper('军衔', {qzDetail && qzDetail.is_local && helper('军衔',
'org_rank', 'org_rank',
[{ required: true, message: "请正确输入报名信息" }, [{ required: true, message: "请正确输入JXJXJX" },
{ max: 32, message: '超出限制长度32位字符请重新编辑' }], { max: 32, message: '超出限制长度32位字符请重新编辑' }],
<Input placeholder="请输入军衔" onBlur={()=>{verify("org_rank")}}/> <Input placeholder="请输入JXJXJX" onBlur={()=>{verify("org_rank")}}/>
)} )}
{helper('赛区', {helper('赛区',
'zone', 'zone',
[{ required: true, message: "请正确输入报名信息" }], [{ required: true, message: "请正确输入赛区" }],
<Select placeholder="请选择赛区" onBlur={()=>{verify("zone")}}> <Select placeholder="请选择赛区" onBlur={()=>{verify("zone")}}>
{qzDetail && qzDetail.zones.map((item,i)=> {return <Option value={item} key={i}>{item}</Option>})} {qzDetail && qzDetail.zones.map((item,i)=> {return <Option value={item} key={i}>{item}</Option>})}
</Select> </Select>
)} )}
{helper('赛项', {helper('赛项',
'sub_competition', 'sub_competition',
[{ required: true, message: "请正确输入报名信息" }], [{ required: true, message: "请正确输入赛项" }],
<Select placeholder="请选择赛项" onBlur={()=>{verify("sub_competition")}}> <Select placeholder="请选择赛项" onBlur={()=>{verify("sub_competition")}}>
{qzDetail && qzDetail.sub_competitions.map((item,i)=> {return <Option value={item} key={i}>{item}</Option>})} {qzDetail && qzDetail.sub_competitions.map((item,i)=> {return <Option value={item} key={i}>{item}</Option>})}
</Select> </Select>
@ -147,15 +146,15 @@ export default Form.create()((props) => {
</Radio.Group> </Radio.Group>
{helper('课题来源', {helper('课题来源',
'subject_source_name', 'subject_source_name',
[{ required: true, message: "请正确输入报名信息" }, [{ required: true, message: "请正确输入课题来源" },
{ max: 32, message: '超出限制长度32位字符请重新编辑' }], { max: 32, message: '超出限制长度32位字符请重新编辑' }],
<Input placeholder="请输入项目名称" onBlur={()=>{verify("subject_source_name")}} disabled={sourceBy === 0}/> <Input placeholder="请输入项目名称" onBlur={()=>{verify("subject_source_name")}} disabled={sourceBy === 0}/>
)} )}
</div>} </div>}
{helper('电话', {helper('电话',
'phone', 'phone',
[{ required: true, message: "请正确输入报名信息" }, [{ required: true, message: "请正确输入电话" },
{pattern: /^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$/, message: "请输入正确的手机号"}], {pattern: /(\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$/, message: "请输入正确的手机号"}],
<Input placeholder="请输入电话" onBlur={()=>{verify("phone")}}/> <Input placeholder="请输入电话" onBlur={()=>{verify("phone")}}/>
)} )}
<div> <div>
@ -174,8 +173,8 @@ export default Form.create()((props) => {
<div><span>赛区 : </span>{enrollStatus && enrollStatus.enroll_info.zone}</div> <div><span>赛区 : </span>{enrollStatus && enrollStatus.enroll_info.zone}</div>
<div className="info-right"><span>赛项 : </span>{enrollStatus && enrollStatus.enroll_info.sub_competition}</div> <div className="info-right"><span>赛项 : </span>{enrollStatus && enrollStatus.enroll_info.sub_competition}</div>
<div><span>课题来源 : </span>{enrollStatus && enrollStatus.enroll_info.subject_source_type === 0 ? "自主提报" : enrollStatus.enroll_info.subject_source_name || '--'}</div> <div><span>课题来源 : </span>{enrollStatus && enrollStatus.enroll_info.subject_source_type === 0 ? "自主提报" : enrollStatus.enroll_info.subject_source_name || '--'}</div>
<div className="info-right"><span>成员 : </span>{enrollStatus && enrollStatus.enroll_info.members && enrollStatus.enroll_info.members.map(item=>{return item.real_name + ' '})}</div>
<div><span>电话 : </span>{enrollStatus && enrollStatus.enroll_info.phone}</div> <div><span>电话 : </span>{enrollStatus && enrollStatus.enroll_info.phone}</div>
<div className="info-right ellipsis_div"><span>成员 : </span>{enrollStatus && enrollStatus.enroll_info.members && enrollStatus.enroll_info.members.map(item=>{return item.real_name + ' '})}</div>
</div>} </div>}
</div> </div>
{!(enrollStatus && enrollStatus.enroll_status) && <div className="apply_but"> {!(enrollStatus && enrollStatus.enroll_status) && <div className="apply_but">

View File

@ -70,7 +70,6 @@
border: 0.5px solid rgba(153, 153, 153, 0.3); border: 0.5px solid rgba(153, 153, 153, 0.3);
margin: 20px 70px 30px 25px; margin: 20px 70px 30px 25px;
div{ div{
display: inline-block;
display: inline-block; display: inline-block;
width: 50%; width: 50%;
border-right: 1px solid rgba(153, 153, 153, 0.3); border-right: 1px solid rgba(153, 153, 153, 0.3);
@ -79,6 +78,9 @@
padding-left: 40px; padding-left: 40px;
line-height: 44px; line-height: 44px;
} }
.ellipsis_div{
width: 100%;
}
.info-right{ .info-right{
border-right: none; border-right: none;
} }

View File

@ -31,10 +31,8 @@ class EditableCell extends React.Component {
return <Form.Item > return <Form.Item >
{form.getFieldDecorator(dataIndex, { {form.getFieldDecorator(dataIndex, {
rules: [ rules: [
{ {required: true,message: `${title}不能为空.`,},
required: true, {max: 32, message: '超出限制长度32位字符,请重新编辑' }
message: `${title}不能为空.`,
},
], ],
validateFirst: true, validateFirst: true,
})(<Input onPressEnter={(e)=>{this.save(dataIndex,e)}} onBlur={(e)=>{this.save(dataIndex,e)}} placeholder="请输入"/>)} })(<Input onPressEnter={(e)=>{this.save(dataIndex,e)}} onBlur={(e)=>{this.save(dataIndex,e)}} placeholder="请输入"/>)}
@ -72,14 +70,38 @@ class EditableTable extends React.Component {
title: '姓名', title: '姓名',
dataIndex: 'real_name', dataIndex: 'real_name',
editable: true, editable: true,
width: "40%"
},
{
title: '单位',
dataIndex: 'org_name',
editable: true,
width: '50%',
},
{
title: '操作',
dataIndex: 'operation',
width: '10%',
render: (text, record) =>
this.state.dataSource.length >= 1 ? (
<Popconfirm title="确定删除此成员?" onConfirm={() => this.handleDelete(record.key)}>
<img src={apply_delete} className="apply_delete"/>
</Popconfirm>
) : null,
},
];
if(props.isLocal){
this.columns = [{
title: '姓名',
dataIndex: 'real_name',
editable: true,
}, },
{ {
title: '单位', title: '单位',
dataIndex: 'org_name', dataIndex: 'org_name',
editable: true, editable: true,
width: '30%', width: '30%',
}, },{
{
title: '职务', title: '职务',
dataIndex: 'org_job', dataIndex: 'org_job',
editable: true, editable: true,
@ -99,9 +121,8 @@ class EditableTable extends React.Component {
<img src={apply_delete} className="apply_delete"/> <img src={apply_delete} className="apply_delete"/>
</Popconfirm> </Popconfirm>
) : null, ) : null,
}, },];
]; }
this.state = { this.state = {
dataSource: [ dataSource: [
{ {

View File

@ -22,9 +22,12 @@ function Introduce({history:{location:{pathname}},qzDetail }) {
useEffect(() => { useEffect(() => {
setType(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght)); setType(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght));
setZone('-1');
setSubCompetition('-1');
}, [pathname]); }, [pathname]);
useEffect(()=>{ useEffect(()=>{
setLoading(true);
const params = { const params = {
zone: zone === '-1' ? undefined : zone, zone: zone === '-1' ? undefined : zone,
sub_competition: subCompetition === '-1' ? undefined : subCompetition sub_competition: subCompetition === '-1' ? undefined : subCompetition
@ -36,6 +39,8 @@ function Introduce({history:{location:{pathname}},qzDetail }) {
setTotal(response.count); setTotal(response.count);
setDataList(response.data.data); setDataList(response.data.data);
} }
}).finally(()=>{
setLoading(false);
}) })
}else{ }else{
// //
@ -44,6 +49,8 @@ function Introduce({history:{location:{pathname}},qzDetail }) {
setTotal(response.count); setTotal(response.count);
setDataList(response.data.data); setDataList(response.data.data);
} }
}).finally(()=>{
setLoading(false);
}) })
} }
}, [type, zone, subCompetition]) }, [type, zone, subCompetition])
@ -107,7 +114,7 @@ function Introduce({history:{location:{pathname}},qzDetail }) {
title: '作品', title: '作品',
dataIndex: 'attachments', dataIndex: 'attachments',
render:(text, record)=>{ render:(text, record)=>{
return <Tooltip title={text && text[0].title}><a href={current_main_site_url+text && text[0].url} className="attachments_a">{text && text[0].title}</a></Tooltip>; return <Tooltip title={text[0] && text[0].title}><a href={current_main_site_url+(text[0] && text[0].url)} className="attachments_a">{text[0] && text[0].title}</a></Tooltip>;
} }
}, },
]; ];
@ -175,7 +182,7 @@ function Introduce({history:{location:{pathname}},qzDetail }) {
} }
const customExpandIcon = (props) => { const customExpandIcon = (props) => {
if(props.record.members.length > 0){ if(props.record.members && props.record.members.length > 0){
if (props.expanded) { if (props.expanded) {
return <a style={{ color: 'black',marginRight:8 }} onClick={e => { return <a style={{ color: 'black',marginRight:8 }} onClick={e => {
props.onExpand(props.record, e); props.onExpand(props.record, e);
@ -186,7 +193,7 @@ function Introduce({history:{location:{pathname}},qzDetail }) {
}}>查看成员<i className="iconfont icon-jiantou9 font-12 ml5"></i></a> }}>查看成员<i className="iconfont icon-jiantou9 font-12 ml5"></i></a>
} }
}else{ }else{
return <span style={{marginRight:8 }}></span> return <span style={{color:'gray' }}>查看成员</span>
} }
} }
@ -200,7 +207,7 @@ function Introduce({history:{location:{pathname}},qzDetail }) {
赛区 赛区
<Select defaultValue="-1" style={{ width: 200 }} onChange={(value)=>{setZone(value)}}> <Select defaultValue="-1" style={{ width: 200 }} onChange={(value)=>{setZone(value)}}>
<Option value='-1'>所有赛区</Option> <Option value='-1'>所有赛区</Option>
{qzDetail && qzDetail.zones.map((item,i)=> {return <Option value={item} key={i}>{item}</Option>})} {qzDetail && qzDetail.manager_zones.map((item,i)=> {return <Option value={item} key={i}>{item}</Option>})}
</Select> </Select>
<span className="ml30">赛项</span> <span className="ml30">赛项</span>
<Select defaultValue="-1" style={{ width: 200 }} onChange={(value)=>{setSubCompetition(value)}}> <Select defaultValue="-1" style={{ width: 200 }} onChange={(value)=>{setSubCompetition(value)}}>
@ -222,7 +229,8 @@ function Introduce({history:{location:{pathname}},qzDetail }) {
expandedRowRender={qzDetail && qzDetail.is_local ? expandRow : expandRowWai} expandedRowRender={qzDetail && qzDetail.is_local ? expandRow : expandRowWai}
expandIconColumnIndex={8} expandIconColumnIndex={8}
expandIconAsCell={false} expandIconAsCell={false}
expandIcon={customExpandIcon}/> expandIcon={customExpandIcon}
pageSize={10}/>
</div> </div>
) )
} }