This commit is contained in:
谢思 2022-03-29 14:33:58 +08:00 committed by 何童崇
parent 4e5b2dea73
commit a4e453a221
12 changed files with 252 additions and 212 deletions

View File

@ -68,6 +68,7 @@ export function appendFileSizeToUploadFile(item) {
return `${item.title}${uploadNameSizeSeperator}${item.filesize}` return `${item.title}${uploadNameSizeSeperator}${item.filesize}`
} }
export function appendFileSizeToUploadFileAll(fileList) { export function appendFileSizeToUploadFileAll(fileList) {
console.log('fileList',fileList);
return fileList && fileList.map(item => { return fileList && fileList.map(item => {
if (item.name.indexOf(uploadNameSizeSeperator) == -1) { if (item.name.indexOf(uploadNameSizeSeperator) == -1) {
return Object.assign({}, item, { name: `${item.name}${uploadNameSizeSeperator}${bytesToSize(item.size)}` }) return Object.assign({}, item, { name: `${item.name}${uploadNameSizeSeperator}${bytesToSize(item.size)}` })

View File

@ -13,6 +13,7 @@ import './qz2022/index.scss';
import { Button, Dropdown, Menu, Popover, Spin } from "antd"; import { Button, Dropdown, 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 { paths } from "./qz2022/static";
import { getQz2022, userCompetitionStatus } from "./qz2022/api";
const Introduce = Loadable({ const Introduce = Loadable({
loader: () => import('./qz2022/introduce'), loader: () => import('./qz2022/introduce'),
@ -63,17 +64,36 @@ const menu = (
); );
const Qz2022 = (props) => { const Qz2022 = (props) => {
// const history:{location:{pathname}} const {history, current_user} = props;
const {history} = props;
const {location} = history; const {location} = history;
const {pathname} = location; const {pathname} = location;
const [active, setActive] = useState(); const [active, setActive] = useState();
console.log(active); const [reload, setReload] = useState();
const [qzDetail, setQzDetail] = useState();
const [enrollStatus, setEnrollStatus] = useState();
useEffect(()=>{ useEffect(()=>{
setActive(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght)); setActive(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght));
}, [pathname]) }, [pathname])
useEffect(()=>{
// 获取启智2022详情
getQz2022().then(response=>{
if(response && response.status===200){
setQzDetail(response.data.data);
}
})
}, [])
useEffect(()=>{
// 获取用户参与竞赛状态
userCompetitionStatus('qz2022').then(response=>{
if(response && response.status === 200){
setEnrollStatus(response.data.data);
}
})
}, [reload])
return ( return (
<React.Fragment> <React.Fragment>
{/* banner图+选项 */} {/* banner图+选项 */}
@ -89,12 +109,12 @@ const Qz2022 = (props) => {
<li className={active === "notice" ? "active" : ""}> <li className={active === "notice" ? "active" : ""}>
<Link to={{ pathname: `/competition/qz2022/notice` }}>通知公告</Link> <Link to={{ pathname: `/competition/qz2022/notice` }}>通知公告</Link>
</li> </li>
<li className={active === "apply" ? "active" : ""}> {current_user && current_user.login ? <li className={active === "apply" ? "active" : ""}>
<Link to={{ pathname: `/competition/qz2022/apply` }}>参赛报名</Link> <Link to={{ pathname: `/competition/qz2022/apply` }}>参赛报名</Link>
</li> </li> : props.showLoginDialog}
<li className={active === "refer" ? "active" : ""}> {current_user && current_user.login ? <li className={active === "refer" ? "active" : ""}>
<Link to={{ pathname: `/competition/qz2022/refer` }}>提案提交</Link> <Link to={{ pathname: `/competition/qz2022/refer` }}>提案提交</Link>
</li> </li> : props.showLoginDialog}
<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>
@ -104,11 +124,11 @@ 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>
<li className={(active === "applys" || active === "production") ? "active" : ""}> {current_user && current_user.login && current_user.admin && <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>
</li> </li>}
</ul>} </ul>}
{paths.indexOf(active) !== -1 && <div className="menu_border mt20 qz_main"></div>} {paths.indexOf(active) !== -1 && <div className="menu_border mt20 qz_main"></div>}
<Spin spinning={false} wrapperClassName="spinstyle qzCont" tip="正在同步镜像" size="large"> <Spin spinning={false} wrapperClassName="spinstyle qzCont" tip="正在同步镜像" size="large">
@ -122,7 +142,7 @@ const Qz2022 = (props) => {
{/* 大赛指南 */} {/* 大赛指南 */}
<Route path="/competition/qz2022/fingerpost" <Route path="/competition/qz2022/fingerpost"
render={ render={
() => (<Fingerpost {...props} />) () => (<Fingerpost {...props} qzDetail={qzDetail}/>)
} }
></Route> ></Route>
{/* 通知公告详情页 */} {/* 通知公告详情页 */}
@ -140,7 +160,13 @@ const Qz2022 = (props) => {
{/* 参赛报名 */} {/* 参赛报名 */}
<Route path="/competition/qz2022/apply" <Route path="/competition/qz2022/apply"
render={ render={
() => (<Apply {...props} />) () => (<Apply {...props} qzDetail={qzDetail} enrollStatus={enrollStatus} setReload={setReload}/>)
}
></Route>
{/* 提案提交 */}
<Route path="/competition/qz2022/refer"
render={
() => (<Refer {...props} enrollStatus={enrollStatus}/>)
} }
></Route> ></Route>
{/* 交流互动 */} {/* 交流互动 */}

View File

@ -1,31 +1,18 @@
import fetch,{ current_main_site_url} from './fetch';
import axios from 'axios'; import axios from 'axios';
// 用户参与启智2022状态?debug=teacher
// 用户参与启智2022状态
export async function userCompetitionStatus(id) { export async function userCompetitionStatus(id) {
let res = await fetch({ return axios.get(`/competition_infos/${id}/enroll_status.json`);
url: `${current_main_site_url}/api/competition_infos/${id}/enroll_status.json`,
method: 'get'
});
return res;
} }
// 启智2022详情接口 // 启智2022详情接口
export function getQz2022() { export function getQz2022() {
return fetch({ return axios.get(`/competition_infos/qz2022.json`);
url: `${current_main_site_url}/api/competition_infos/qz2022.json`,
method: 'get'
});
} }
// 报名启智2022 竞赛 // 报名启智2022 竞赛?debug=teacher
export async function enrollCompetition(data){ export async function enrollCompetition(data){
return fetch({ return axios.post(`/competition_infos/qz2022/enroll.json`,data);
url: `${current_main_site_url}/api/competition_infos/qz2022/enroll.json`,
method: 'post',
data,
});
} }
// 统计启智2022 竞赛 // 统计启智2022 竞赛
@ -39,35 +26,15 @@ export async function stattistics(data){
// 竞赛提交作品 // 竞赛提交作品
export async function uploadCompetition(data){ export async function uploadCompetition(data){
return fetch({ return axios.post(`/competition_infos/qz2022/upload.json`,data);
url: `${current_main_site_url}/api/competition_infos/qz2022/upload.json`,
method: 'post',
data,
});
} }
// 管理-竞赛报名列表 // 管理-竞赛报名列表?debug=admin
export function getQzEnrollList(params) { export function getQzEnrollList(params) {
return fetch({ return axios.get(`/competition_infos/qz2022/enroll_list.json`,params={params});
url: `${current_main_site_url}/api/competition_infos/qz2022/enroll_list.json`,
method: 'get',
params
});
} }
// 管理-竞赛报名列表导出 // 管理-竞赛提交作品列表&debug=admin
export function exportEnrollList(params) {
return fetch({
url: `${current_main_site_url}/api/competition_infos/qz2022/enroll_list.xlsx`,
method: 'get',
});
}
// 管理-竞赛提交作品列表
export function getQzProList(params) { export function getQzProList(params) {
return fetch({ return axios.get(`/competition_infos/qz2022/enroll_list.json?upload=true`,params={params});
url: `${current_main_site_url}/api/competition_infos/qz2022/enroll_list.json?upload=true`,
method: 'get',
params
});
} }

View File

@ -1,9 +1,7 @@
import React, { useState, useCallback, useMemo, useEffect, useRef } from "react"; import React, {useState, useCallback} from "react";
import { Input, Select, Button, Form, message, DatePicker, Table, Pagination, Upload, Modal } from 'antd'; import { Input, Select, Button, Form, message, Radio } from 'antd';
import {competitionArea, competitionType} from '../static.js'; import {enrollCompetition} from '../api';
import { Link } from "react-router-dom"; import {httpUrl} from '../fetch';
import { formatDuring } from 'educoder';
import {userCompetitionStatus, enrollCompetition} from '../api';
import EditTable from "../editTable"; import EditTable from "../editTable";
import apply_top from "../image/apply_top.png"; import apply_top from "../image/apply_top.png";
import apply_down from "../image/apply_down.png"; import apply_down from "../image/apply_down.png";
@ -18,11 +16,11 @@ import '../../index.scss';
const Option = Select.Option; const Option = Select.Option;
export default Form.create()((props) => { export default Form.create()((props) => {
const { match, history, showNotification, form, current_user, qzDetail} = props const {form, qzDetail, enrollStatus, setReload} = props
const { getFieldDecorator, validateFields, setFieldsValue } = form; const {getFieldDecorator, validateFields, setFieldsValue } = form;
const [applyStatue, setApplyState] = useState(undefined);
const [members, setMembers] = useState([]); const [members, setMembers] = useState([]);
const [errorMessage, setErrorMessage] = useState(undefined); const [errorMessage, setErrorMessage] = useState(undefined);
const [sourceBy, setSourceBy] = useState(1);
// form // form
const helper = useCallback( const helper = useCallback(
@ -34,15 +32,6 @@ export default Form.create()((props) => {
[] []
); );
useEffect(() => {
// 2022
userCompetitionStatus('qz2022').then(response=>{
if(response && response.message === "success"){
setApplyState(response.data.enroll_status);
}
})
}, []);
// //
function verify(dataIndex){ function verify(dataIndex){
validateFields([dataIndex],(error, values)=>{ validateFields([dataIndex],(error, values)=>{
@ -72,37 +61,47 @@ export default Form.create()((props) => {
// //
const params = { const params = {
...values, ...values,
members members,
subject_source_type: sourceBy,
} }
enrollCompetition(params).then(response=>{ enrollCompetition(params).then(response=>{
if(response && response.message === "success"){ if(response && response.data.message === "success"){
setReload(Math.random());
message.success('报名成功') message.success('报名成功')
}else{
message.error(response.message);
} }
}) })
} }
}) })
} }
return ( return (
<div className="qz_main"> <div className="qz_main">
<div className="step"> <div className="step">
<span className="left_tit">&nbsp;&nbsp;报名</span> <span className="left_tit">&nbsp;&nbsp;报名</span>
<img src={apply_top} className="step_icon"/> <img src={apply_top} className="step_icon"/>
<div className="border_dashed"></div> <div className="border_dashed"></div>
<img src={applyStatue ? apply_one : apply_one_active} className="step_icon"/> <div className="img_span">
<img src={enrollStatus && enrollStatus.enroll_status ? apply_one : apply_one_active} className="step_icon"/>
个人信息
</div>
<div className="border_dashed"></div> <div className="border_dashed"></div>
<img src={applyStatue ? apply_two_active : apply_two} className="step_icon"/> <div className="img_span">
<img src={enrollStatus && enrollStatus.enroll_status ? apply_two_active : apply_two} className="step_icon"/>
报名成功
</div>
<div className="border_dashed"></div> <div className="border_dashed"></div>
<img src={apply_down} className="step_icon"/> <img src={apply_down} className="step_icon"/>
</div> </div>
{!applyStatue && <div className="apply_tip font-15"> {!(enrollStatus && enrollStatus.enroll_status) && <div className="apply_tip font-15">
<img src={apply_notice} className="apply_notice"/> <img src={apply_notice} className="apply_notice"/>
请认真核对报名信息务必与线下报名表信息一致 请认真核对报名信息务必与线下报名表信息一致
</div>} </div>}
<div className="apply_information mb60"> <div className="apply_information mb60">
<div className="info_head">{!applyStatue && '填写'}报名信息</div> <div className="info_head">{!(enrollStatus && enrollStatus.enroll_status) && '填写'}报名信息</div>
{/* 报名表单 */} {/* 报名表单 */}
{!applyStatue && <Form className="info_form"> {!(enrollStatus && enrollStatus.enroll_status) && <Form className="info_form">
{helper('参赛单位', {helper('参赛单位',
'org_name', 'org_name',
[{ required: true, message: "请正确输入报名信息" }, [{ required: true, message: "请正确输入报名信息" },
@ -131,22 +130,26 @@ export default Form.create()((props) => {
'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={i} 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={i} key={i}>{item}</Option>})} {qzDetail && qzDetail.sub_competitions.map((item,i)=> {return <Option value={item} key={i}>{item}</Option>})}
</Select> </Select>
)} )}
{qzDetail && qzDetail.is_local && <div className="class_from"> {qzDetail && qzDetail.is_local && <div className="class_from">
<Radio.Group onChange={(e)=>{setSourceBy(e.target.value)}} value={sourceBy} defaultValue={1}>
<Radio value={1}>计划支持</Radio>
<Radio value={0}>自主提报</Radio>
</Radio.Group>
{helper('课题来源', {helper('课题来源',
'subject_source_type', 'subject_source_name',
[{ required: true, message: "请正确输入报名信息" }, [{ required: true, message: "请正确输入报名信息" },
{ max: 32, message: '超出限制长度32位字符请重新编辑' }], { max: 32, message: '超出限制长度32位字符请重新编辑' }],
<Input placeholder="请输入项目名称" onBlur={()=>{verify("subject_source_type")}}/> <Input placeholder="请输入项目名称" onBlur={()=>{verify("subject_source_name")}} disabled={sourceBy === 0}/>
)} )}
</div>} </div>}
{helper('电话', {helper('电话',
@ -163,25 +166,25 @@ export default Form.create()((props) => {
</div> </div>
</Form>} </Form>}
{/* 已报名,报名信息 */} {/* 已报名,报名信息 */}
{applyStatue && <div className="info"> {enrollStatus && enrollStatus.enroll_status && <div className="info">
<div><span>参赛单位 : </span></div> <div><span>参赛单位 : </span>{enrollStatus && enrollStatus.enroll_info.org_name}</div>
<div className="info-right"><span>参赛团队负责人姓名 : </span></div> <div className="info-right"><span>参赛团队负责人姓名 : </span>{enrollStatus && enrollStatus.enroll_info.leader}</div>
<div><span>职务 : </span></div> <div><span>职务 : </span>{enrollStatus && enrollStatus.enroll_info.org_job}</div>
<div className="info-right"><span>JXJXJX : </span></div> <div className="info-right"><span>JXJXJX : </span>{enrollStatus && enrollStatus.enroll_info.org_rank}</div>
<div><span>赛区 : </span></div> <div><span>赛区 : </span>{enrollStatus && enrollStatus.enroll_info.zone}</div>
<div className="info-right"><span>赛项 : </span></div> <div className="info-right"><span>赛项 : </span>{enrollStatus && enrollStatus.enroll_info.sub_competition}</div>
<div><span>课题来源 : </span></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></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></div> <div><span>电话 : </span>{enrollStatus && enrollStatus.enroll_info.phone}</div>
</div>} </div>}
</div> </div>
{!applyStatue && <div className="apply_but"> {!(enrollStatus && enrollStatus.enroll_status) && <div className="apply_but">
<Button type="primary" className="submit_info" onClick={applySubmit}> <Button type="primary" className="submit_info" onClick={applySubmit}>
提交资料 提交资料
</Button> </Button>
<Button className="add_member cancel_submit ml20"> <a href={httpUrl+'/busiAttachments/download/391'}><Button className="add_member download ml20">
取消 下载报名表
</Button> </Button></a>
</div>} </div>}
</div> </div>
) )

View File

@ -1,7 +1,7 @@
.step{ .step{
display: flex; display: flex;
align-items: center; align-items: center;
margin: 50px 0 60px; margin: 30px 0 40px;
.left_tit{ .left_tit{
height: 20px; height: 20px;
line-height: 19px; line-height: 19px;
@ -16,6 +16,12 @@
margin: 0 12px; margin: 0 12px;
border-bottom: 1px dashed #bac1c9; border-bottom: 1px dashed #bac1c9;
} }
.img_span{
display: flex;
flex-direction: column;
align-items: center;
margin-top: 25px;
}
} }
.apply_tip{ .apply_tip{
background-color:#fff5eb; background-color:#fff5eb;
@ -47,7 +53,17 @@
.ant-input:hover{border-color:#2e5bfe;} .ant-input:hover{border-color:#2e5bfe;}
} }
.class_from{ .class_from{
display: inline; position: relative;
display: inline-block;
width: 46.5%;
}
.class_from .ant-form-item{
width: 71%;
}
.class_from>.ant-radio-group{
position: absolute;
left: 36%;
top: 10px;
} }
} }
.info{ .info{
@ -113,11 +129,11 @@
.apply_but{ .apply_but{
padding-bottom: 60px; padding-bottom: 60px;
text-align: center; text-align: center;
.cancel_submit, .submit_info{ .download, .submit_info{
padding: 0 18px; padding: 0 18px;
height: 36px; height: 36px;
} }
.cancel_submit{ .download{
padding: 0 30px; padding: 0 10px;
} }
} }

View File

@ -1,22 +1,14 @@
import React, { useState, useCallback, useMemo, useEffect } from "react"; import React from "react";
import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal } from 'antd';
import { Link } from "react-router-dom";
import { formatDuring } from 'educoder';
import './index.scss'; import './index.scss';
import '../../index.scss'; import '../../index.scss';
const Option = Select.Option;
function Introduce({ form, showNotification, match, history }) {
useEffect(() => {
}, []);
function Introduce({qzDetail }) {
return ( return (
<React.Fragment> <div className="qz_main fingerpost">
da指南 <div className="fingerpost_head font-18 mb20">2022年赛程说明</div>
</React.Fragment> <div className="fingerpost_cont" dangerouslySetInnerHTML={{ __html: qzDetail && qzDetail.guide }}></div>
</div>
) )
} }
export default Introduce; export default Introduce;

View File

@ -0,0 +1,8 @@
.fingerpost{
.fingerpost_head{
padding: 60px 0 30px;
text-align: center;
border-bottom: 1px dashed #979797;
font-weight: bold;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 MiB

After

Width:  |  Height:  |  Size: 2.6 MiB

View File

@ -1,23 +1,19 @@
import React, { useState, useCallback, useMemo, useEffect } from "react"; import React, { useState, useMemo, useEffect } from "react";
import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal, Icon } from 'antd'; import {Select, Button, Tooltip } from 'antd';
import { Link } from "react-router-dom"; import {current_main_site_url} from '../fetch';
import { formatDuring } from 'educoder';
import {competitionArea, competitionType} from '../static.js';
import PaginationTable from "../../components/paginationTable"; import PaginationTable from "../../components/paginationTable";
import './index.scss'; import './index.scss';
import '../index.scss'; import '../index.scss';
import { getQzEnrollList, getQzProList, exportEnrollList } from "../api.js"; import { getQzEnrollList, getQzProList } from "../api.js";
const Option = Select.Option; const Option = Select.Option;
function Introduce({ form, showNotification, match, history:{location:{pathname}},qzDetail }) { function Introduce({history:{location:{pathname}},qzDetail }) {
console.log(qzDetail);
// type01 // type01
const [type, setType] = useState(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght)); const [type, setType] = useState(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght));
const [reload, setReload] = useState(); const [reload, setReload] = useState();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [curPage, setCurPage] = useState(1); const [curPage, setCurPage] = useState(1);
const [pageSize, setPageSize] = useState(10);
const [dataList, setDataList] = useState([]); const [dataList, setDataList] = useState([]);
const [total, setTotal] = useState(0); const [total, setTotal] = useState(0);
// //
@ -29,7 +25,6 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
}, [pathname]); }, [pathname]);
useEffect(()=>{ useEffect(()=>{
console.log(zone, subCompetition);
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
@ -37,24 +32,23 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
if(type === "applys"){ if(type === "applys"){
// //
getQzEnrollList(params).then(response=>{ getQzEnrollList(params).then(response=>{
console.log(response); if(response && response.status === 200){
if(response && response.message === "success"){
setTotal(response.count); setTotal(response.count);
setDataList(response.data); setDataList(response.data.data);
} }
}) })
}else{ }else{
// //
getQzProList(params).then(response=>{ getQzProList(params).then(response=>{
if(response && response.message === "success"){ if(response && response.status === 200){
setTotal(response.count); setTotal(response.count);
setDataList(response.data); setDataList(response.data.data);
} }
}) })
} }
}, [type, zone, subCompetition]) }, [type, zone, subCompetition])
const columns_apply = useMemo(() => { let columns_apply = useMemo(() => {
return [ return [
{ {
title: '参赛单位', title: '参赛单位',
@ -67,16 +61,7 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
dataIndex: 'leader', dataIndex: 'leader',
key: 'leader', key: 'leader',
}, },
{
title: '职务',
dataIndex: 'org_job',
key: 'org_job',
},
{
title: 'JXJXJX',
dataIndex: 'org_rank',
key: 'org_rank',
},
{ {
title: '电话', title: '电话',
dataIndex: 'phone', dataIndex: 'phone',
@ -85,29 +70,15 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
{ {
title: '赛区', title: '赛区',
dataIndex: 'zone', dataIndex: 'zone',
render:(text, record)=>{
return (qzDetail && qzDetail.zones[text]) || '--';
}
}, },
{ {
title: '赛项', title: '赛项',
dataIndex: 'sub_competition', dataIndex: 'sub_competition'
render:(text, record)=>{
return (qzDetail && qzDetail.sub_competitions[text]) || '--';
}
},
{
title: '课题来源',
dataIndex: 'subject_source_type',
render:(text, record)=>{
return text === '0' ? "自主提报" : record.subject_source_name || '--';
}
}, },
{ {
title: '成员', title: '成员',
dataIndex: 'members', dataIndex: 'members',
render:(text, record)=>{ render:(text, record)=>{
console.log('members', text);
return ''; return '';
} }
} }
@ -126,24 +97,44 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
}, },
{ {
title: '赛区', title: '赛区',
dataIndex: 'zone', dataIndex: 'zone'
render:(text, record)=>{
return (qzDetail && qzDetail.zones[text]) || '--';
}
}, },
{ {
title: '赛项', title: '赛项',
dataIndex: 'sub_competition', dataIndex: 'sub_competition'
render:(text, record)=>{
return (qzDetail && qzDetail.sub_competitions[text]) || '--';
}
}, },
{ {
title: '作品', title: '作品',
dataIndex: 'sttachments', dataIndex: 'attachments',
render:(text, record)=>{
return <Tooltip title={text[0].title}><a href={current_main_site_url+text[0].url} className="attachments_a">{text[0].title}</a></Tooltip>;
}
}, },
]; ];
}, [qzDetail]); }, [qzDetail, reload]);
//
if(qzDetail && qzDetail.is_local && columns_apply[2].title !== "职务"){
// JXJXJX
columns_apply.splice(2,0,{
title: '职务',
dataIndex: 'org_job',
key: 'org_job',
},
{
title: 'JXJXJX',
dataIndex: 'org_rank',
key: 'org_rank',
},);
columns_apply.splice(7,0,
{
title: '课题来源',
dataIndex: 'subject_source_type',
render:(text, record)=>{
return text === 0 ? "自主提报" : record.subject_source_name || '--';
}
},)
}
const expandRow = (record) =>{ const expandRow = (record) =>{
return <div className="expandRowManage"> return <div className="expandRowManage">
@ -165,13 +156,25 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
})} })}
</div> </div>
} }
// JXJXJX
const customExpandIcon1 = useMemo((props)=>{ const expandRowWai = (record) =>{
// console.log(props); return <div className="expandRowManage">
},[dataList]) <div className="row">
<div>序号</div>
<div>姓名</div>
<div className="job">单位</div>
</div>
{record.members && record.members.map((item, index)=>{
return <div className="row">
<div>{index+1}</div>
<div>{item.real_name}</div>
<div className="job">{item.org_job}</div>
</div>
})}
</div>
}
const customExpandIcon = (props) => { const customExpandIcon = (props) => {
console.log(props);
if(props.record.members.length > 0){ if(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 => {
@ -187,10 +190,6 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
} }
} }
function exportApplyInfo(){
exportEnrollList();
}
return ( return (
<div className="qz_management"> <div className="qz_management">
@ -209,7 +208,7 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
{qzDetail && qzDetail.sub_competitions.map((item,i)=> {return <Option value={i} key={i}>{item}</Option>})} {qzDetail && qzDetail.sub_competitions.map((item,i)=> {return <Option value={i} key={i}>{item}</Option>})}
</Select> </Select>
</div> </div>
{type === "applys" && <Button className="but_2e5" onClick={exportApplyInfo}>导出</Button>} <a href={current_main_site_url+`/api/competition_infos/qz2022/enroll_list.xlsx${type === "applys"? '':"?upload=true"}`}><Button className="but_2e5">导出</Button></a>
</div> </div>
<PaginationTable <PaginationTable
@ -220,7 +219,7 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
total={total} total={total}
setCurPage={setCurPage} setCurPage={setCurPage}
current={curPage} current={curPage}
expandedRowRender={expandRow} expandedRowRender={qzDetail && qzDetail.is_local ? expandRow : expandRowWai}
expandIconColumnIndex={8} expandIconColumnIndex={8}
expandIconAsCell={false} expandIconAsCell={false}
expandIcon={customExpandIcon}/> expandIcon={customExpandIcon}/>

View File

@ -21,6 +21,21 @@
display: inline-block; display: inline-block;
width: 17%; width: 17%;
text-align: center; text-align: center;
padding-top: 15px;
&.job{width: 30%;} &.job{width: 30%;}
&:first-child{
padding-top: 0;
padding-bottom: 15px;
}
}
.expandRowManage .row{
border-bottom: 1px solid #ececec;
margin: 0 -8px;
}
.expandRowManage .row:last-child{
border-bottom: none;
}
.attachments_a{
color: #2e5bfe;
} }
} }

View File

@ -1,10 +1,12 @@
import React, { useState, useCallback, useMemo, useEffect } from "react"; import React, { useState, useCallback, useMemo, useEffect } from "react";
import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal, Icon } from 'antd'; import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal, Icon, message } from 'antd';
import { appendFileSizeToUploadFileAll } from 'educoder'; import { appendFileSizeToUploadFileAll } from 'educoder';
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { formatDuring } from 'educoder'; import { formatDuring } from 'educoder';
import {httpUrl} from '../fetch.js'; import {httpUrl, current_main_site_url} from '../fetch.js';
import {uploadCompetition} from '../api'; import {uploadCompetition, uploadFile} from '../api';
import {getFile} from '../../expert/api';
import { Confirm } from '../../components/ModalFun';
import refer_tip from "../image/refer_tip.svg"; import refer_tip from "../image/refer_tip.svg";
import refer from "../image/refer.svg"; import refer from "../image/refer.svg";
@ -12,45 +14,37 @@ import './index.scss';
import '../../index.scss'; import '../../index.scss';
const Option = Select.Option; const Option = Select.Option;
function Introduce({ form, showNotification, match, history }) { function Introduce({ form, showNotification, match, history, enrollStatus }) {
// loading // loading
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [referStatue, setReferState] = useState(true); const [files, setFiles] = useState();
const [files, setFiles] = useState(undefined);
const showUploadList = {
}
useEffect(() => { useEffect(() => {
if(enrollStatus && enrollStatus.upload_status){
}, []); enrollStatus.attachments.map(item=>{
item.uid = 'rc-upload'+item.id;
item.name = item.title;
item.status = "done";
});
setFiles(enrollStatus.attachments);
}
}, [enrollStatus]);
function handleChange(info) { function handleChange(info) {
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') { if (info.file.status === 'uploading' || info.file.status == "done" || info.file.status === 'removed') {
setLoading(true); setLoading(true);
let fileList = info.fileList; setFiles(appendFileSizeToUploadFileAll(info.fileList).slice(-1))
setFiles(appendFileSizeToUploadFileAll(fileList));
if (info.file.response) {
for (let i = 0; i < fileList.length; i++) {
if (fileList[i].response && !fileList[i].response.data) {
fileList.splice(i, 1);
}
}
if (!info.file.response.data) {
info.file.response && showNotification(info.file.response.message)
}
}
} }
if(info.file.status == "done"){ if(info.file.status == "done" || info.file.status === 'removed'){
setLoading(false); setLoading(false);
} }
} }
// //
function download(file){ function download(file){
const fileId = file.response.data.id; const fileId = file.id || file.response.id;
window.open(`${httpUrl}/busiAttachments/download/${fileId}`); window.open(`${current_main_site_url}/api/attachments/${fileId}`);
} }
// //
@ -65,18 +59,25 @@ function Introduce({ form, showNotification, match, history }) {
// //
function referProduction(){ function referProduction(){
if(files && files.length === 1){ if(files && files.length === 1){
uploadCompetition({"attachment_ids":Array.from(files[0].response.data.id)}).then(response=>{ const params = {
console.log(response); "attachment_ids": [files[0].response.id]
}
uploadCompetition(params).then(response=>{
if(response && response.status === 200){
message.success('提交作品成功');
}else{
message.error(response.data.message);
}
}) })
} }
} }
return ( return (
<div className="qz_main refer"> <div className="qz_main refer">
<img src={refer} className="refer_img mb20"/> <img src={refer} className="refer_img mb20"/>
<Upload <Upload
accept=".zip,.rar,.tar" accept=".zip,.rar,.tar"
action={`${httpUrl}/busiAttachments/upload`} // action?debug=admin
action={`${current_main_site_url}/api/attachments.json?debug=admin`}
fileList={files} fileList={files}
onChange={handleChange} onChange={handleChange}
onDownload={download} onDownload={download}
@ -88,7 +89,9 @@ function Introduce({ form, showNotification, match, history }) {
> >
<Button className="upload"><Icon type="upload" />上传</Button> <Button className="upload"><Icon type="upload" />上传</Button>
</Upload> </Upload>
<div className="refer_tip mt20">上传小于等于256m的作品压缩包仅限上传一个压缩包,格式如下: .zip, .rar, .tar</div> <Modal/>
{enrollStatus && enrollStatus.upload_status && <div className="refer_tip mt20 cover"><i className="iconfont icon-erciqueren_icon mr10"></i>您已上传作品压缩包再次上传将会覆盖您上一次的提交</div>}
<div className="refer_tip mt20">上传单个作品压缩包仅限上传一个压缩包</div>
<div className="refer_bor"></div> <div className="refer_bor"></div>
<Button type="primary" onClick={referProduction} loading={loading}>提交作品</Button> <Button type="primary" onClick={referProduction} loading={loading}>提交作品</Button>
</div> </div>

View File

@ -15,6 +15,13 @@
.refer_tip{ .refer_tip{
color:#595959; color:#595959;
font-size:15px; font-size:15px;
&.cover{
color: red;
margin-bottom: -20px;
}
&.cover .icon-erciqueren_icon{
color: #FA2D2D;
}
} }
.refer_bor{ .refer_bor{
width: 40vw; width: 40vw;
@ -31,6 +38,9 @@
right: -55px; right: -55px;
.anticon{padding-right: 10px;} .anticon{padding-right: 10px;}
} }
& a:link{
color: #2e5bfe;
}
} }
.ant-upload-list-item:hover .ant-upload-list-item-info{background: none;} .ant-upload-list-item:hover .ant-upload-list-item-info{background: none;}
} }