forked from Gitlink/forgeplus-react
联调参赛报名、提交作品、管理页面接口(还有缺陷)
This commit is contained in:
parent
65d616b116
commit
aa805dc22c
|
@ -10,7 +10,7 @@ import Loading from "../Loading";
|
||||||
// import { getUserInfo } from './expert/api';
|
// 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, 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";
|
||||||
|
|
||||||
|
@ -101,9 +101,9 @@ const Qz2022 = (props) => {
|
||||||
<Link to={{ pathname: `/competition/qz2022/contact` }}>联系我们</Link>
|
<Link to={{ pathname: `/competition/qz2022/contact` }}>联系我们</Link>
|
||||||
</li>
|
</li>
|
||||||
<li className={(active === "applys" || active === "production") ? "active" : ""}>
|
<li className={(active === "applys" || active === "production") ? "active" : ""}>
|
||||||
<Dropdown overlay={menu} placement="bottomRight" overlayClassName="qz_manage">
|
<Popover content={menu} placement="bottomRight" overlayClassName="qz_manage">
|
||||||
<a>后台管理</a>
|
<a>后台管理</a>
|
||||||
</Dropdown>
|
</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>}
|
||||||
|
@ -154,13 +154,13 @@ const Qz2022 = (props) => {
|
||||||
{/* 后台管理-报名列表 */}
|
{/* 后台管理-报名列表 */}
|
||||||
<Route path="/competition/qz2022/management/applys"
|
<Route path="/competition/qz2022/management/applys"
|
||||||
render={
|
render={
|
||||||
() => (<Management {...props} />)
|
() => (<Management {...props} qzDetail={qzDetail}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
{/* 后台管理-作品列表 */}
|
{/* 后台管理-作品列表 */}
|
||||||
<Route path="/competition/qz2022/management/production"
|
<Route path="/competition/qz2022/management/production"
|
||||||
render={
|
render={
|
||||||
() => (<Management {...props} />)
|
() => (<Management {...props} qzDetail={qzDetail}/>)
|
||||||
}
|
}
|
||||||
></Route>
|
></Route>
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
|
@ -21,12 +21,46 @@ export function getQz2022() {
|
||||||
// 报名启智2022 竞赛
|
// 报名启智2022 竞赛
|
||||||
export async function enrollCompetition(data){
|
export async function enrollCompetition(data){
|
||||||
return fetch({
|
return fetch({
|
||||||
url: `${current_main_site_url}/api/competition_infos/${id}/enroll.json`,
|
url: `${current_main_site_url}/api/competition_infos/qz2022/enroll.json`,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data,
|
data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 竞赛提交作品
|
||||||
|
export async function uploadCompetition(data){
|
||||||
|
return fetch({
|
||||||
|
url: `${current_main_site_url}/api/competition_infos/qz2022/upload.json`,
|
||||||
|
method: 'post',
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 管理-竞赛报名列表
|
||||||
|
export function getQzEnrollList(params) {
|
||||||
|
return fetch({
|
||||||
|
url: `${current_main_site_url}/api/competition_infos/qz2022/enroll_list.json`,
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 管理-竞赛报名列表导出
|
||||||
|
export function exportEnrollList(params) {
|
||||||
|
return fetch({
|
||||||
|
url: `${current_main_site_url}/api/competition_infos/qz2022/enroll_list.xlsx`,
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 管理-竞赛提交作品列表
|
||||||
|
export function getQzProList(params) {
|
||||||
|
return fetch({
|
||||||
|
url: `${current_main_site_url}/api/competition_infos/qz2022/enroll_list.json?upload=true`,
|
||||||
|
method: 'get',
|
||||||
|
params
|
||||||
|
});
|
||||||
|
}
|
||||||
//删除专家
|
//删除专家
|
||||||
export function deleteExpert(expertId) {
|
export function deleteExpert(expertId) {
|
||||||
return fetch({
|
return fetch({
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React, { useState, useCallback, useMemo, useEffect } from "react";
|
import React, { useState, useCallback, useMemo, useEffect, useRef } from "react";
|
||||||
import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal } from 'antd';
|
import { Input, Select, Button, Form, message, DatePicker, Table, Pagination, Upload, Modal } from 'antd';
|
||||||
import {competitionArea, competitionType} from '../static.js';
|
import {competitionArea, competitionType} from '../static.js';
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { formatDuring } from 'educoder';
|
import { formatDuring } from 'educoder';
|
||||||
|
@ -22,6 +22,7 @@ export default Form.create()((props) => {
|
||||||
const { getFieldDecorator, validateFields, setFieldsValue } = form;
|
const { getFieldDecorator, validateFields, setFieldsValue } = form;
|
||||||
const [applyStatue, setApplyState] = useState(undefined);
|
const [applyStatue, setApplyState] = useState(undefined);
|
||||||
const [members, setMembers] = useState([]);
|
const [members, setMembers] = useState([]);
|
||||||
|
const [errorMessage, setErrorMessage] = useState(undefined);
|
||||||
|
|
||||||
// form表单公共处理函数
|
// form表单公共处理函数
|
||||||
const helper = useCallback(
|
const helper = useCallback(
|
||||||
|
@ -53,22 +54,35 @@ export default Form.create()((props) => {
|
||||||
|
|
||||||
//提交报名信息
|
//提交报名信息
|
||||||
function applySubmit(){
|
function applySubmit(){
|
||||||
|
// 检查用户输入的成员属性是否完全
|
||||||
|
if(members.length > 0){
|
||||||
|
let all = false;
|
||||||
|
members.map(item=>{
|
||||||
|
all = Object.keys(item).length === 5;
|
||||||
|
})
|
||||||
|
if(!all){
|
||||||
|
setErrorMessage("成员信息未填写完成");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
validateFields((error, values)=>{
|
validateFields((error, values)=>{
|
||||||
if(error){
|
if(error){
|
||||||
return
|
return
|
||||||
}else{
|
}else{
|
||||||
console.log('正确输入');
|
|
||||||
// 用户输入正确 报名该竞赛
|
// 用户输入正确 报名该竞赛
|
||||||
const params = {
|
const params = {
|
||||||
...values,
|
...values,
|
||||||
|
members
|
||||||
}
|
}
|
||||||
// enrollCompetition(params).then(response=>{
|
enrollCompetition(params).then(response=>{
|
||||||
// console.log(response);
|
if(response && response.message === "success"){
|
||||||
// })
|
message.success('报名成功')
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
console.log('members', members);
|
|
||||||
return (
|
return (
|
||||||
<div className="qz_main">
|
<div className="qz_main">
|
||||||
<div className="step">
|
<div className="step">
|
||||||
|
@ -137,11 +151,13 @@ console.log('members', members);
|
||||||
</div>}
|
</div>}
|
||||||
{helper('电话',
|
{helper('电话',
|
||||||
'phone',
|
'phone',
|
||||||
[{ required: true, message: "请正确输入报名信息" }],
|
[{ required: true, message: "请正确输入报名信息" },
|
||||||
<Input placeholder="超出限制长度32位字符,请重新编辑" onBlur={()=>{verify("phone")}}/>
|
{pattern: /^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$/, message: "请输入正确的手机号"}],
|
||||||
|
<Input placeholder="请输入电话" onBlur={()=>{verify("phone")}}/>
|
||||||
)}
|
)}
|
||||||
<div>
|
<div>
|
||||||
<p>成员</p>
|
<p className="mt10">成员 : </p>
|
||||||
|
<p className="error_message">{errorMessage}</p>
|
||||||
{/* */}
|
{/* */}
|
||||||
<EditTable setMembers={setMembers}/>
|
<EditTable setMembers={setMembers}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -43,6 +43,8 @@
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 33%;
|
width: 33%;
|
||||||
margin-right: 160px;
|
margin-right: 160px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
.ant-input:hover{border-color:#2e5bfe;}
|
||||||
}
|
}
|
||||||
.class_from{
|
.class_from{
|
||||||
display: inline;
|
display: inline;
|
||||||
|
@ -104,6 +106,9 @@
|
||||||
&:hover{cursor: pointer;}
|
&:hover{cursor: pointer;}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.error_message{
|
||||||
|
color: #f5222d;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.apply_but{
|
.apply_but{
|
||||||
padding-bottom: 60px;
|
padding-bottom: 60px;
|
||||||
|
|
|
@ -17,7 +17,6 @@ class EditableCell extends React.Component {
|
||||||
|
|
||||||
save = (dataIndex, e) => {
|
save = (dataIndex, e) => {
|
||||||
const { record, handleSave } = this.props;
|
const { record, handleSave } = this.props;
|
||||||
console.log(dataIndex);
|
|
||||||
this.form.validateFields([dataIndex],(error, values) => {
|
this.form.validateFields([dataIndex],(error, values) => {
|
||||||
if (error && error[e.currentTarget.id]) {
|
if (error && error[e.currentTarget.id]) {
|
||||||
return;
|
return;
|
||||||
|
@ -67,28 +66,27 @@ class EditableCell extends React.Component {
|
||||||
|
|
||||||
class EditableTable extends React.Component {
|
class EditableTable extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
console.log(props,'表格');
|
|
||||||
super(props);
|
super(props);
|
||||||
this.columns = [
|
this.columns = [
|
||||||
{
|
{
|
||||||
title: '姓名',
|
title: '姓名',
|
||||||
dataIndex: 'name',
|
dataIndex: 'real_name',
|
||||||
editable: true,
|
editable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '单位',
|
title: '单位',
|
||||||
dataIndex: 'age',
|
dataIndex: 'org_name',
|
||||||
editable: true,
|
editable: true,
|
||||||
width: '30%',
|
width: '30%',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '职务',
|
title: '职务',
|
||||||
dataIndex: 'address',
|
dataIndex: 'org_job',
|
||||||
editable: true,
|
editable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'JXJXJX',
|
title: 'JXJXJX',
|
||||||
dataIndex: 'militaryRank',
|
dataIndex: 'org_rank',
|
||||||
editable: true,
|
editable: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -108,10 +106,6 @@ class EditableTable extends React.Component {
|
||||||
dataSource: [
|
dataSource: [
|
||||||
{
|
{
|
||||||
key: '0',
|
key: '0',
|
||||||
name: '',
|
|
||||||
age: '',
|
|
||||||
address: '',
|
|
||||||
militaryRank: ''
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
count: 1,
|
count: 1,
|
||||||
|
|
|
@ -42,12 +42,13 @@
|
||||||
}
|
}
|
||||||
.qzCont {
|
.qzCont {
|
||||||
min-height: 35vh;
|
min-height: 35vh;
|
||||||
border-radius: 4px;
|
border-radius:4px;
|
||||||
box-shadow: 0px 3px 12px #ecf0ff;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.qz_manage {
|
.qz_manage {
|
||||||
top: 510px !important;
|
.ant-popover-inner-content{
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
.ant-dropdown-menu-item > a {
|
.ant-dropdown-menu-item > a {
|
||||||
color: #333;
|
color: #333;
|
||||||
&:hover {
|
&:hover {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
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 } from 'antd';
|
import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal, Icon } from 'antd';
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { formatDuring } from 'educoder';
|
import { formatDuring } from 'educoder';
|
||||||
import {competitionArea, competitionType} from '../static.js';
|
import {competitionArea, competitionType} from '../static.js';
|
||||||
|
@ -7,9 +7,11 @@ import PaginationTable from "../../components/paginationTable";
|
||||||
|
|
||||||
import './index.scss';
|
import './index.scss';
|
||||||
import '../index.scss';
|
import '../index.scss';
|
||||||
|
import { getQzEnrollList, getQzProList, exportEnrollList } from "../api.js";
|
||||||
const Option = Select.Option;
|
const Option = Select.Option;
|
||||||
|
|
||||||
function Introduce({ form, showNotification, match, history:{location:{pathname}} }) {
|
function Introduce({ form, showNotification, match, history:{location:{pathname}},qzDetail }) {
|
||||||
|
console.log(qzDetail);
|
||||||
// 报名列表和作品列表到指向此处,type做区分,0报名,1作品
|
// 报名列表和作品列表到指向此处,type做区分,0报名,1作品
|
||||||
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();
|
||||||
|
@ -18,103 +20,196 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
|
||||||
const [pageSize, setPageSize] = useState(10);
|
const [pageSize, setPageSize] = useState(10);
|
||||||
const [dataList, setDataList] = useState([]);
|
const [dataList, setDataList] = useState([]);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
|
// 赛区 赛项
|
||||||
|
const [zone, setZone] = useState(undefined);
|
||||||
|
const [subCompetition, setSubCompetition] = useState(undefined);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setType(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght));
|
setType(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght));
|
||||||
}, [pathname]);
|
}, [pathname]);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
console.log(zone, subCompetition);
|
||||||
|
const params = {
|
||||||
|
zone: zone === '-1' ? undefined : zone,
|
||||||
|
sub_competition: subCompetition === '-1' ? undefined : subCompetition
|
||||||
|
}
|
||||||
|
if(type === "applys"){
|
||||||
|
// 报名列表
|
||||||
|
getQzEnrollList(params).then(response=>{
|
||||||
|
console.log(response);
|
||||||
|
if(response && response.message === "success"){
|
||||||
|
setTotal(response.count);
|
||||||
|
setDataList(response.data);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
// 提交作品列表
|
||||||
|
getQzProList(params).then(response=>{
|
||||||
|
if(response && response.message === "success"){
|
||||||
|
setTotal(response.count);
|
||||||
|
setDataList(response.data);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [type, zone, subCompetition])
|
||||||
|
|
||||||
const columns_apply = useMemo(() => {
|
const columns_apply = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
title: '参赛单位',
|
title: '参赛单位',
|
||||||
dataIndex: 'index'
|
dataIndex: 'org_name',
|
||||||
|
width: '10%',
|
||||||
|
align: 'center'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '参赛负责人',
|
title: '参赛负责人',
|
||||||
dataIndex: 'containerName',
|
dataIndex: 'leader',
|
||||||
key: 'containerName',
|
key: 'leader',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '职务',
|
title: '职务',
|
||||||
dataIndex: 'reviewEndOn',
|
dataIndex: 'org_job',
|
||||||
key: 'reviewEndOn',
|
key: 'org_job',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'JXJXJX',
|
title: 'JXJXJX',
|
||||||
dataIndex: 'surplus',
|
dataIndex: 'org_rank',
|
||||||
key: 'surplus',
|
key: 'org_rank',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '电话',
|
title: '电话',
|
||||||
dataIndex: 'status',
|
dataIndex: 'phone',
|
||||||
key: 'status',
|
key: 'phone',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '赛区',
|
||||||
|
dataIndex: 'zone',
|
||||||
|
render:(text, record)=>{
|
||||||
|
return (qzDetail && qzDetail.zones[text]) || '--';
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '赛项',
|
title: '赛项',
|
||||||
dataIndex: 'status',
|
dataIndex: 'sub_competition',
|
||||||
key: 'action',
|
render:(text, record)=>{
|
||||||
|
return (qzDetail && qzDetail.sub_competitions[text]) || '--';
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '课题来源',
|
title: '课题来源',
|
||||||
dataIndex: 'status',
|
dataIndex: 'subject_source_type',
|
||||||
key: 'status',
|
render:(text, record)=>{
|
||||||
|
return text === '0' ? "自主提报" : record.subject_source_name || '--';
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '成员',
|
title: '成员',
|
||||||
dataIndex: 'status',
|
dataIndex: 'members',
|
||||||
key: 'action',
|
render:(text, record)=>{
|
||||||
|
console.log('members', text);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}, []);
|
}, [qzDetail]);
|
||||||
|
|
||||||
const columns_production = useMemo(() => {
|
const columns_production = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
title: '参赛单位',
|
title: '参赛单位',
|
||||||
dataIndex: 'index'
|
dataIndex: 'org_name'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '参赛负责人',
|
title: '参赛负责人',
|
||||||
dataIndex: 'containerName',
|
dataIndex: 'leader',
|
||||||
key: 'containerName',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '赛区',
|
title: '赛区',
|
||||||
dataIndex: 'reviewEndOn',
|
dataIndex: 'zone',
|
||||||
key: 'reviewEndOn',
|
render:(text, record)=>{
|
||||||
|
return (qzDetail && qzDetail.zones[text]) || '--';
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '赛项',
|
title: '赛项',
|
||||||
dataIndex: 'surplus',
|
dataIndex: 'sub_competition',
|
||||||
key: 'surplus',
|
render:(text, record)=>{
|
||||||
|
return (qzDetail && qzDetail.sub_competitions[text]) || '--';
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '作品',
|
title: '作品',
|
||||||
dataIndex: 'status',
|
dataIndex: 'sttachments',
|
||||||
key: 'status',
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, []);
|
}, [qzDetail]);
|
||||||
|
|
||||||
|
const expandRow = (record) =>{
|
||||||
|
return <div className="expandRowManage">
|
||||||
|
<div className="row">
|
||||||
|
<div>序号</div>
|
||||||
|
<div>姓名</div>
|
||||||
|
<div className="job">单位</div>
|
||||||
|
<div>职务</div>
|
||||||
|
<div>军衔</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>{item.org_rank}</div>
|
||||||
|
<div>{item.org_name}</div>
|
||||||
|
</div>
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const customExpandIcon1 = useMemo((props)=>{
|
||||||
|
// console.log(props);
|
||||||
|
},[dataList])
|
||||||
|
|
||||||
|
const customExpandIcon = (props) => {
|
||||||
|
console.log(props);
|
||||||
|
if(props.record.members.length > 0){
|
||||||
|
if (props.expanded) {
|
||||||
|
return <a style={{ color: 'black',marginRight:8 }} onClick={e => {
|
||||||
|
props.onExpand(props.record, e);
|
||||||
|
}}>查看成员<i className="iconfont icon-changyongtubiao-xianxingdaochu-zhuanqu- font-12 ml5"></i></a>
|
||||||
|
} else {
|
||||||
|
return <a style={{ color: 'black' ,marginRight:8 }} onClick={e => {
|
||||||
|
props.onExpand(props.record, e);
|
||||||
|
}}>查看成员<i className="iconfont icon-jiantou9 font-12 ml5"></i></a>
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return <span style={{marginRight:8 }}></span>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function exportApplyInfo(){
|
||||||
|
exportEnrollList();
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="qz_management">
|
<div className="qz_management">
|
||||||
|
|
||||||
<div className="qz_manage_head">启智2022{type === "applys" ? "报名" : "作品"}列表</div>
|
<div className="qz_manage_head">启智2022{type === "applys" ? "报名" : "作品"}列表</div>
|
||||||
|
|
||||||
<div className="search">
|
<div className="search">
|
||||||
<div>
|
<div className="font-14">
|
||||||
赛区:
|
赛区:
|
||||||
<Select defaultValue="-1" style={{ width: 200 }}>
|
<Select defaultValue="-1" style={{ width: 200 }} onChange={(value)=>{setZone(value)}}>
|
||||||
<Option value='-1'>所有赛区</Option>
|
<Option value='-1'>所有赛区</Option>
|
||||||
{competitionArea.map(item=> {return <Option value={item.value}>{item.title}</Option>})}
|
{qzDetail && qzDetail.zones.map((item,i)=> {return <Option value={i} key={i}>{item}</Option>})}
|
||||||
</Select>
|
</Select>
|
||||||
<span className="ml30">赛项:</span>
|
<span className="ml30">赛项:</span>
|
||||||
<Select defaultValue="-1" style={{ width: 200 }}>
|
<Select defaultValue="-1" style={{ width: 200 }} onChange={(value)=>{setSubCompetition(value)}}>
|
||||||
<Option value='-1'>所有赛项</Option>
|
<Option value='-1'>所有赛项</Option>
|
||||||
{competitionType.map(item=> {return <Option value={item.value}>{item.title}</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">导出</Button>}
|
{type === "applys" && <Button className="but_2e5" onClick={exportApplyInfo}>导出</Button>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PaginationTable
|
<PaginationTable
|
||||||
|
@ -124,7 +219,11 @@ function Introduce({ form, showNotification, match, history:{location:{pathname}
|
||||||
columns={type==="applys" ? columns_apply : columns_production}
|
columns={type==="applys" ? columns_apply : columns_production}
|
||||||
total={total}
|
total={total}
|
||||||
setCurPage={setCurPage}
|
setCurPage={setCurPage}
|
||||||
current={curPage}/>
|
current={curPage}
|
||||||
|
expandedRowRender={expandRow}
|
||||||
|
expandIconColumnIndex={8}
|
||||||
|
expandIconAsCell={false}
|
||||||
|
expandIcon={customExpandIcon}/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,4 +17,10 @@
|
||||||
.pagination-table.qzManageTable {
|
.pagination-table.qzManageTable {
|
||||||
padding: 0 30px;
|
padding: 0 30px;
|
||||||
}
|
}
|
||||||
|
.expandRowManage .row div{
|
||||||
|
display: inline-block;
|
||||||
|
width: 17%;
|
||||||
|
text-align: center;
|
||||||
|
&.job{width: 30%;}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { Upload, Button } from 'antd';
|
||||||
|
import { appendFileSizeToUploadFileAll } from 'educoder';
|
||||||
|
import { httpUrl } from '../fetch';
|
||||||
|
|
||||||
|
function Uploads({ className, size, actionUrl, fileList, showNotification, load, accept, disabled,count }) {
|
||||||
|
const [files, setFiles] = useState(undefined);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (fileList) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
}, [fileList]);
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
let f = appendFileSizeToUploadFileAll(fileList);
|
||||||
|
setFiles(f);
|
||||||
|
}
|
||||||
|
function onAttachmentRemove(file) {
|
||||||
|
if (!file.percent || file.percent === 100) {
|
||||||
|
deleteAttachment(file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function deleteAttachment(file) {
|
||||||
|
let id = (file.response && file.response.data && file.response.data.id) || file.id;
|
||||||
|
|
||||||
|
// 暂时不直接删除上传的文件,只在最后保存的时候进行修改
|
||||||
|
let nf = files.filter(item => {
|
||||||
|
let itemId = (item.response && item.response.data && item.response.data.id) || item.id;
|
||||||
|
return itemId !== id;
|
||||||
|
});
|
||||||
|
setFiles(nf);
|
||||||
|
backFiles(nf);
|
||||||
|
}
|
||||||
|
|
||||||
|
function backFiles(fileList) {
|
||||||
|
let filesId = [];
|
||||||
|
for (const item of fileList) {
|
||||||
|
if (item) {
|
||||||
|
let itemId = (item.response && item.response.data && item.response.data.id) || item.id;
|
||||||
|
itemId && filesId.push(itemId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
load && load(fileList, filesId.join());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function handleChange(info) {
|
||||||
|
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
|
||||||
|
let fileList = info.fileList;
|
||||||
|
if(count){
|
||||||
|
fileList = fileList.slice(-count);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
backFiles(fileList);
|
||||||
|
if (!info.file.response.data) {
|
||||||
|
info.file.response && showNotification(info.file.response.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function beforeUpload(file) {
|
||||||
|
const isLt100M = file.size / 1024 / 1024 < size;
|
||||||
|
if (!isLt100M) {
|
||||||
|
showNotification(`文件大小必须小于${size}MB!`);
|
||||||
|
}
|
||||||
|
return isLt100M;
|
||||||
|
}
|
||||||
|
|
||||||
|
const upload = {
|
||||||
|
name: 'file',
|
||||||
|
fileList: files,
|
||||||
|
disabled: disabled,
|
||||||
|
action: (httpUrl || actionUrl) + `/busiAttachments/upload`,
|
||||||
|
onChange: handleChange,
|
||||||
|
onRemove: onAttachmentRemove,
|
||||||
|
beforeUpload: beforeUpload,
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<Upload {...upload} className={className}>
|
||||||
|
<Button type="primary" disabled={disabled}>点击上传</Button>
|
||||||
|
<span className="ml10 color-grey-9">(你可以上传小于<span className="color-red">{size}MB</span>的文件)</span>
|
||||||
|
</Upload>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default Uploads;
|
|
@ -1,8 +1,10 @@
|
||||||
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 } from 'antd';
|
||||||
|
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} from '../fetch.js';
|
||||||
|
import {uploadCompetition} from '../api';
|
||||||
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";
|
||||||
|
|
||||||
|
@ -11,23 +13,84 @@ import '../../index.scss';
|
||||||
const Option = Select.Option;
|
const Option = Select.Option;
|
||||||
|
|
||||||
function Introduce({ form, showNotification, match, history }) {
|
function Introduce({ form, showNotification, match, history }) {
|
||||||
const [referStatue, setreferState] = useState(true);
|
// 上传文件时 按钮loading效果
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [referStatue, setReferState] = useState(true);
|
||||||
|
const [files, setFiles] = useState(undefined);
|
||||||
|
|
||||||
|
const showUploadList = {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
function handleChange(info) {
|
||||||
|
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
|
||||||
|
setLoading(true);
|
||||||
|
let fileList = info.fileList;
|
||||||
|
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"){
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 支持文件下载
|
||||||
|
function download(file){
|
||||||
|
const fileId = file.response.data.id;
|
||||||
|
window.open(`${httpUrl}/busiAttachments/download/${fileId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 进行文件大小检查
|
||||||
|
function beforeUpload(file){
|
||||||
|
const isLt100M = file.size / 1024 / 1024 < 256;
|
||||||
|
if (!isLt100M) {
|
||||||
|
showNotification(`文件大小必须小于${256}MB!`);
|
||||||
|
}
|
||||||
|
return isLt100M;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 作品提交
|
||||||
|
function referProduction(){
|
||||||
|
if(files && files.length === 1){
|
||||||
|
uploadCompetition({"attachment_ids":Array.from(files[0].response.data.id)}).then(response=>{
|
||||||
|
console.log(response);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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"
|
||||||
action={`${httpUrl}/busiAttachments/upload`}
|
action={`${httpUrl}/busiAttachments/upload`}
|
||||||
|
fileList={files}
|
||||||
|
onChange={handleChange}
|
||||||
|
onDownload={download}
|
||||||
|
beforeUpload={beforeUpload}
|
||||||
|
showUploadList={{
|
||||||
|
showDownloadIcon: true,
|
||||||
|
downloadIcon: <i className="iconfont icon-xiazai-icon"></i>
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Button className="upload"><Icon type="upload" />上传</Button>
|
<Button className="upload"><Icon type="upload" />上传</Button>
|
||||||
</Upload>
|
</Upload>
|
||||||
<div className="refer_tip mt20">上传小于等于256m的作品压缩包(仅限上传一个压缩包)</div>
|
<div className="refer_tip mt20">上传小于等于256m的作品压缩包(仅限上传一个压缩包,格式如下: .zip, .rar, .tar)</div>
|
||||||
<div className="refer_bor"></div>
|
<div className="refer_bor"></div>
|
||||||
<Button type="primary">提交作品</Button>
|
<Button type="primary" onClick={referProduction} loading={loading}>提交作品</Button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,4 +24,13 @@
|
||||||
>span{
|
>span{
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
.ant-upload-list-item-info{
|
||||||
|
color: #2e5bfe;
|
||||||
|
:hover{color: #2e5bfe;}
|
||||||
|
.ant-upload-list-item-card-actions{
|
||||||
|
right: -55px;
|
||||||
|
.anticon{padding-right: 10px;}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ant-upload-list-item:hover .ant-upload-list-item-info{background: none;}
|
||||||
}
|
}
|
Loading…
Reference in New Issue