forked from Gitlink/forgeplus-react
启智2022 静态页面50%
This commit is contained in:
parent
744153b4bd
commit
53ff8c47ce
|
@ -69,6 +69,11 @@ const Expert = Loadable({
|
|||
loader: () => import('./military/expert'),
|
||||
loading: Loading,
|
||||
})
|
||||
// 启智2022 (为此竞赛定制化页面以及内容)
|
||||
const Qz2022 = Loadable({
|
||||
loader: () => import('./military/qz2022'),
|
||||
loading: Loading,
|
||||
})
|
||||
//403页面
|
||||
const Shixunauthority = Loadable({
|
||||
loader: () => import('./modules/403/Shixunauthority'),
|
||||
|
@ -375,7 +380,9 @@ class App extends Component {
|
|||
{/*任务*/}
|
||||
<Route path="/task" component={Task} />
|
||||
{/*专家评审*/}
|
||||
<Route path="/expert" component={Expert} />
|
||||
<Route path="/expert" component={Expert} />
|
||||
{/*启智2022*/}
|
||||
<Route path="/competition/qz2022" component={Qz2022} />
|
||||
|
||||
<Route exact path="/explore/all"
|
||||
render={
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
}
|
||||
|
||||
.newFooter {
|
||||
position: absolute;
|
||||
// position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
background: #323232;
|
||||
|
|
|
@ -3,10 +3,10 @@ import { Table, Pagination } from 'antd';
|
|||
import './index.scss';
|
||||
|
||||
export default (props) => {
|
||||
const { 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 } = props;
|
||||
|
||||
return (
|
||||
<div className='pagination-table'>
|
||||
<div className={`pagination-table ${className}`}>
|
||||
<Table
|
||||
{...props}
|
||||
loading={loading}
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { Link, Route, Switch } from "react-router-dom";
|
||||
import { withRouter } from "react-router";
|
||||
import { getImageUrl, SnackbarHOC } from "educoder";
|
||||
import { CNotificationHOC } from "../modules/courses/common/CNotificationHOC";
|
||||
import { TPMIndexHOC } from "../modules/tpm/TPMIndexHOC";
|
||||
import Loadable from "react-loadable";
|
||||
import Loading from "../Loading";
|
||||
import { getUserInfo } from './expert/api';
|
||||
import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC";
|
||||
import './qz2022/index.scss';
|
||||
import { Button, Dropdown, Menu, Spin } from "antd";
|
||||
import banner from './qz2022/image/banner.png'
|
||||
import { paths } from "./qz2022/static";
|
||||
|
||||
const Introduce = Loadable({
|
||||
loader: () => import('./qz2022/introduce'),
|
||||
loading: Loading,
|
||||
})
|
||||
const Fingerpost = Loadable({
|
||||
loader: () => import('./qz2022/fingerpost'),
|
||||
loading: Loading,
|
||||
})
|
||||
const Notice = Loadable({
|
||||
loader: () => import('./qz2022/notice'),
|
||||
loading: Loading,
|
||||
})
|
||||
const NoticeDetail = Loadable({
|
||||
loader: () => import('./qz2022/notice/detail.jsx'),
|
||||
loading: Loading,
|
||||
})
|
||||
const Apply = Loadable({
|
||||
loader: () => import('./qz2022/apply'),
|
||||
loading: Loading,
|
||||
})
|
||||
const Management = Loadable({
|
||||
loader: () => import('./qz2022/management'),
|
||||
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 history:{location:{pathname}}
|
||||
const {history} = props;
|
||||
const {location} = history;
|
||||
const {pathname} = location;
|
||||
const [active, setActive] = useState();
|
||||
console.log(active);
|
||||
|
||||
useEffect(()=>{
|
||||
setActive(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght));
|
||||
}, [pathname])
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{/* banner图+选项 */}
|
||||
<img src={banner} className="qz_banner"/>
|
||||
<div className="qz2022">
|
||||
{paths.indexOf(active) !== -1 && <ul className="qz2022Menu mt20 qz_main">
|
||||
<li className={active === "introduce" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/competition/qz2022/introduce` }}>大赛介绍</Link>
|
||||
</li>
|
||||
<li className={active === "fingerpost" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/competition/qz2022/fingerpost` }}>大赛指南</Link>
|
||||
</li>
|
||||
<li className={active === "notice" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/competition/qz2022/notice` }}>通知公告</Link>
|
||||
</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" : ""}>
|
||||
<Link to={{ pathname: `/competition/qz2022/statistics` }}>数据统计</Link>
|
||||
</li>
|
||||
<li className={active === "chat" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/competition/qz2022/chat` }}>交流互动</Link>
|
||||
</li>
|
||||
<li className={active === "contact" ? "active" : ""}>
|
||||
<Link to={{ pathname: `/competition/qz2022/contact` }}>联系我们</Link>
|
||||
</li>
|
||||
<li className={(active === "applys" || active === "production") ? "active" : ""}>
|
||||
<Dropdown overlay={menu} placement="bottomRight" overlayClassName="qz_manage">
|
||||
<a>后台管理</a>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>}
|
||||
{paths.indexOf(active) !== -1 && <div className="menu_border mt20 qz_main"></div>}
|
||||
<Spin spinning={false} wrapperClassName="spinstyle qzCont" tip="正在同步镜像" size="large">
|
||||
<Switch {...props}>
|
||||
{/* 大赛介绍 */}
|
||||
<Route path="/competition/qz2022/introduce"
|
||||
render={
|
||||
() => (<Introduce {...props} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 大赛指南 */}
|
||||
<Route path="/competition/qz2022/fingerpost"
|
||||
render={
|
||||
() => (<Fingerpost {...props} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 通知公告详情页 */}
|
||||
<Route path="/competition/qz2022/notice/:noticeId"
|
||||
render={
|
||||
() => (<NoticeDetail {...props} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 通知公告 */}
|
||||
<Route path="/competition/qz2022/notice"
|
||||
render={
|
||||
() => (<Notice {...props} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 参赛报名 */}
|
||||
<Route path="/competition/qz2022/apply"
|
||||
render={
|
||||
() => (<Apply {...props} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 后台管理-报名列表 */}
|
||||
<Route path="/competition/qz2022/management/applys"
|
||||
render={
|
||||
() => (<Management {...props} />)
|
||||
}
|
||||
></Route>
|
||||
{/* 后台管理-作品列表 */}
|
||||
<Route path="/competition/qz2022/management/production"
|
||||
render={
|
||||
() => (<Management {...props} />)
|
||||
}
|
||||
></Route>
|
||||
</Switch>
|
||||
</Spin>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default withRouter(
|
||||
ImageLayerOfCommentHOC({
|
||||
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
|
||||
parentSelector: ".newMain",
|
||||
})(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Qz2022))))
|
||||
);
|
|
@ -0,0 +1,255 @@
|
|||
import fetch,{main_web_site_url} from './fetch';
|
||||
import { notification } from 'antd';
|
||||
|
||||
// 专家列表查询
|
||||
export async function expertList(params) {
|
||||
let res = await fetch({
|
||||
url: '/api/experts/',
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
if (res.data) {
|
||||
return res.data;
|
||||
} else {
|
||||
notification.open({
|
||||
message: "提示",
|
||||
description: res.message || '请求错误',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//删除专家
|
||||
export function deleteExpert(expertId) {
|
||||
return fetch({
|
||||
url: `/api/experts/${expertId}?isDelete=1`,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
export function getUserInfo() {
|
||||
return fetch({
|
||||
url: '/user/getUserInfo',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 查看当前登录用户专家信息
|
||||
export function getCurrentExpert(params) {
|
||||
return fetch({
|
||||
url: '/api/experts/getCurrentExpert',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
//专家注册
|
||||
export async function expertRegister(data){
|
||||
let res = await fetch({
|
||||
url: '/api/experts/register',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
//更新专家信息
|
||||
export async function expertUpdate(data){
|
||||
let res = await fetch({
|
||||
url: '/api/experts/',
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
//管理员审核专家信息
|
||||
export async function registerCheck(data){
|
||||
let res = await fetch({
|
||||
url: '/api/experts/adminCheckExpert',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
// 获取文件信息
|
||||
export function getFile(id) {
|
||||
return fetch({
|
||||
url: `/busiAttachments/${id}`,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
// 获取评审任务列表
|
||||
export function getExpertTasks(params) {
|
||||
return fetch({
|
||||
url: `/api/taskExpert/getExpertTasksPageList`,
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 获取竞赛作品列表
|
||||
export function getCompetition(id) {
|
||||
return fetch({
|
||||
url: `${main_web_site_url}/api/v1/competitions/${id}/works`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 获取竞赛详情接口
|
||||
export function getCompetitionDetail(id) {
|
||||
return fetch({
|
||||
url: `${main_web_site_url}/api/v1/competitions/${id}`,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
|
||||
// 查看竞赛/任务的评分细则
|
||||
export function getScoringDetails(params) {
|
||||
return fetch({
|
||||
url: `/api/expertScoringDetails/getExpertScoringDetailsList`,
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 查看最终得分排行
|
||||
export function getFinalScoreRankingList(params) {
|
||||
return fetch({
|
||||
url: `/api/expertScoringDetails/getFinalScoreRankingList`,
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 查看单个竞赛/任务的所有评分细则
|
||||
export function getOpsScoringDetails(params) {
|
||||
return fetch({
|
||||
url: `/api/expertScoringDetails/getOpsExpertScoringDetailsList`,
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
// 初始化评分细则
|
||||
export function initScoringDetails(data){
|
||||
return fetch({
|
||||
url: '/api/expertScoringDetails/initExpertScoringDetails',
|
||||
method: 'post',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
// 更新评分细则
|
||||
export function updateScoringDetails(data){
|
||||
return fetch({
|
||||
url: '/api/expertScoringDetails/',
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
//评选胜出者和公示者
|
||||
export function selectWinnersAndPublicists(data){
|
||||
return fetch({
|
||||
url: '/api/expertScoringDetails/selectWinnersAndPublicists',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
//查看胜出者和公示名单
|
||||
export function getWinnersAndPublicists(params) {
|
||||
return fetch({
|
||||
url: `/api/expertScoringDetails/getWinnersAndPublicists`,
|
||||
method: 'get',
|
||||
params,
|
||||
});
|
||||
}
|
||||
|
||||
//获取创客任务评审规则
|
||||
export async function getRules(params){
|
||||
let response = await fetch({
|
||||
url: `/api/taskRuleCriteria/getRuleAndCriteria`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
if(response && response.message === "success"){
|
||||
let criterias = [];
|
||||
response.data.criteriaOne && (criterias[criterias.length] = (criterias.length+1)+"、"+response.data.criteriaOne);
|
||||
response.data.criteriaTwo && (criterias[criterias.length] = (criterias.length+1)+"、"+response.data.criteriaTwo);
|
||||
response.data.criteriaThree && (criterias[criterias.length] = (criterias.length+1)+"、"+response.data.criteriaThree);
|
||||
response.data.criteriaFour && (criterias[criterias.length] = (criterias.length+1)+"、"+response.data.criteriaFour);
|
||||
response.data.criteriaFive && (criterias[criterias.length] = (criterias.length+1)+"、"+response.data.criteriaFive);
|
||||
response.data.criterias = criterias;
|
||||
response.data.reviewData = response.data.reviewStartOn.substring(0,response.data.reviewStartOn.length-3) + " ~ " + response.data.reviewEndOn.substring(0,response.data.reviewEndOn.length-3)
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
//编辑评审规则(第一次)
|
||||
export async function editRules(data){
|
||||
let res = await fetch({
|
||||
url: '/api/taskRuleCriteria/editRuleAndCriteria',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
//更新评审规则(第一次)
|
||||
export async function updateRules(data){
|
||||
let res = await fetch({
|
||||
url: '/api/taskRuleCriteria/',
|
||||
method: 'put',
|
||||
data,
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
//为创客任务添加评审专家
|
||||
export async function assignExperts(data){
|
||||
let res = await fetch({
|
||||
url: '/api/taskExpert/assignExperts',
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
//删除指派专家
|
||||
export function deleteExperts(taskExpertId,isDelete) {
|
||||
return fetch({
|
||||
url: `/api/taskExpert/${taskExpertId}?isDelete=${isDelete}`,
|
||||
method: 'delete'
|
||||
});
|
||||
}
|
||||
|
||||
//已选专家列表
|
||||
export function selectExpertList(params) {
|
||||
return fetch({
|
||||
url: `/api/taskExpert/selectedExpertPageList`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
//竞赛任务列表
|
||||
export function getCompetitionList(params) {
|
||||
return fetch({
|
||||
url: `/api/competitionExpert/getCompetitionList`,
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
// 修改竞赛是否加入专家评审流程
|
||||
export function updateCompetitionReview(data) {
|
||||
return fetch({
|
||||
url: `${main_web_site_url}/api/v1/competitions/update_expert_audit`,
|
||||
method: 'post',
|
||||
data,
|
||||
});
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
import React, { useState, useCallback, useMemo, useEffect } from "react";
|
||||
import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal } from 'antd';
|
||||
import {competitionArea, competitionType} from '../static.js';
|
||||
import { Link } from "react-router-dom";
|
||||
import { formatDuring } from 'educoder';
|
||||
import EditTable from "../editTable";
|
||||
|
||||
import './index.scss';
|
||||
import '../../index.scss';
|
||||
const Option = Select.Option;
|
||||
|
||||
export default Form.create()(({ match, history, showNotification, form, current_user }) => {
|
||||
const { getFieldDecorator, validateFields, setFieldsValue } = form;
|
||||
const [applyStatue, setApplyState] = useState();
|
||||
// form表单公共处理函数
|
||||
const helper = useCallback(
|
||||
(label, name, rules, widget) => (
|
||||
<Form.Item label={label}>
|
||||
{getFieldDecorator(name, { rules, validateFirst: true })(widget)}
|
||||
</Form.Item>
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="qz_main">
|
||||
<div className="step">
|
||||
<span>报名</span>
|
||||
|
||||
</div>
|
||||
<div className="apply_information">
|
||||
<div>填报报名信息</div>
|
||||
{/* 报名表单 */}
|
||||
<Form>
|
||||
{helper('参赛单位',
|
||||
'expertName',
|
||||
[{ required: true, message: "参赛单位不能为空" },
|
||||
{ max: 32, message: '长度不能超过32个字符' }],
|
||||
<Input placeholder="请输入参赛单位"/>
|
||||
)}
|
||||
{helper('参赛团队负责人姓名',
|
||||
'expertName',
|
||||
[{ required: true, message: "参赛团队负责人不能为空" },
|
||||
{ max: 32, message: '长度不能超过32个字符' }],
|
||||
<Input placeholder="请输入参赛团队负责人姓名"/>
|
||||
)}
|
||||
{helper('职务',
|
||||
'expertName',
|
||||
[{ required: true, message: "职务不能为空" },
|
||||
{ max: 32, message: '长度不能超过32个字符' }],
|
||||
<Input placeholder="请输入职务"/>
|
||||
)}
|
||||
{helper('军衔',
|
||||
'expertName',
|
||||
[{ required: true, message: "军衔不能为空" },
|
||||
{ max: 32, message: '长度不能超过32个字符' }],
|
||||
<Input placeholder="请输入军衔"/>
|
||||
)}
|
||||
{helper('赛区',
|
||||
'expertName',
|
||||
[{ required: true, message: "军衔不能为空" }],
|
||||
<Select style={{ width: 200 }} placeholder="请选择赛区">
|
||||
{competitionArea.map(item=> {return <Option value={item.value}>{item.title}</Option>})}
|
||||
</Select>
|
||||
)}
|
||||
{helper('赛项',
|
||||
'expertName',
|
||||
[{ required: true, message: "军衔不能为空" }],
|
||||
<Select style={{ width: 200 }} placeholder="请选择赛项">
|
||||
{competitionType.map(item=> {return <Option value={item.value}>{item.title}</Option>})}
|
||||
</Select>
|
||||
)}
|
||||
<div>
|
||||
{helper('课题来源',
|
||||
'expertName',
|
||||
[{ required: true, message: "课题来源不能为空" },
|
||||
{ max: 32, message: '长度不能超过32个字符' }],
|
||||
<Input placeholder="请输入项目名称"/>
|
||||
)}
|
||||
</div>
|
||||
{helper('电话',
|
||||
'expertName',
|
||||
[{ required: true, message: "电话不能为空" },
|
||||
{ max: 32, message: '长度不能超过32个字符' }],
|
||||
<Input placeholder="请输入联系方式"/>
|
||||
)}
|
||||
<div>
|
||||
<p>成员</p>
|
||||
{/* */}
|
||||
<EditTable/>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})
|
|
@ -0,0 +1,185 @@
|
|||
import React, { useState, useCallback, useMemo, useEffect } from "react";
|
||||
import { Table, Input, Button, Popconfirm, Form } from 'antd';
|
||||
import './index.scss';
|
||||
|
||||
const EditableContext = React.createContext();
|
||||
|
||||
const EditableRow = ({ form, index, ...props }) => (
|
||||
<EditableContext.Provider value={form}>
|
||||
<tr {...props} />
|
||||
</EditableContext.Provider>
|
||||
);
|
||||
|
||||
const EditableFormRow = Form.create()(EditableRow);
|
||||
|
||||
class EditableCell extends React.Component {
|
||||
|
||||
save = (dataIndex, e) => {
|
||||
const { record, handleSave } = this.props;
|
||||
console.log(dataIndex);
|
||||
this.form.validateFields([dataIndex],(error, values) => {
|
||||
if (error && error[e.currentTarget.id]) {
|
||||
return;
|
||||
}
|
||||
handleSave({ ...record, ...values });
|
||||
});
|
||||
};
|
||||
|
||||
renderCell = form => {
|
||||
this.form = form;
|
||||
const {dataIndex, title } = this.props;
|
||||
return <Form.Item >
|
||||
{form.getFieldDecorator(dataIndex, {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: `${title}不能为空.`,
|
||||
},
|
||||
],
|
||||
validateFirst: true,
|
||||
})(<Input onPressEnter={this.save} onBlur={(e)=>{this.save(dataIndex,e)}} placeholder="请输入"/>)}
|
||||
</Form.Item>
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
editable,
|
||||
dataIndex,
|
||||
title,
|
||||
record,
|
||||
index,
|
||||
handleSave,
|
||||
children,
|
||||
...restProps
|
||||
} = this.props;
|
||||
return (
|
||||
<td {...restProps}>
|
||||
{editable ? (
|
||||
<EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>
|
||||
) : (
|
||||
children
|
||||
)}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EditableTable extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.columns = [
|
||||
{
|
||||
title: '姓名',
|
||||
dataIndex: 'name',
|
||||
width: '30%',
|
||||
editable: true,
|
||||
},
|
||||
{
|
||||
title: '单位',
|
||||
dataIndex: 'age',
|
||||
editable: true,
|
||||
},
|
||||
{
|
||||
title: '职务',
|
||||
dataIndex: 'address',
|
||||
editable: true,
|
||||
},
|
||||
{
|
||||
title: '军衔',
|
||||
dataIndex: 'militaryRank',
|
||||
editable: true,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'operation',
|
||||
render: (text, record) =>
|
||||
this.state.dataSource.length >= 1 ? (
|
||||
<Popconfirm title="确定删除此成员?" onConfirm={() => this.handleDelete(record.key)}>
|
||||
<a>删除</a>
|
||||
</Popconfirm>
|
||||
) : null,
|
||||
},
|
||||
];
|
||||
|
||||
this.state = {
|
||||
dataSource: [
|
||||
{
|
||||
key: '0',
|
||||
name: '',
|
||||
age: '',
|
||||
address: '',
|
||||
militaryRank: ''
|
||||
}
|
||||
],
|
||||
count: 1,
|
||||
};
|
||||
}
|
||||
|
||||
handleDelete = key => {
|
||||
const dataSource = [...this.state.dataSource];
|
||||
this.setState({ dataSource: dataSource.filter(item => item.key !== key) });
|
||||
};
|
||||
|
||||
handleAdd = () => {
|
||||
const { count, dataSource } = this.state;
|
||||
const newData = {
|
||||
key: count,
|
||||
};
|
||||
this.setState({
|
||||
dataSource: [...dataSource, newData],
|
||||
count: count + 1,
|
||||
});
|
||||
};
|
||||
|
||||
handleSave = row => {
|
||||
const newData = [...this.state.dataSource];
|
||||
const index = newData.findIndex(item => row.key === item.key);
|
||||
const item = newData[index];
|
||||
newData.splice(index, 1, {
|
||||
...item,
|
||||
...row,
|
||||
});
|
||||
this.setState({ dataSource: newData });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { dataSource } = this.state;
|
||||
const components = {
|
||||
body: {
|
||||
row: EditableFormRow,
|
||||
cell: EditableCell,
|
||||
},
|
||||
};
|
||||
const columns = this.columns.map(col => {
|
||||
if (!col.editable) {
|
||||
return col;
|
||||
}
|
||||
return {
|
||||
...col,
|
||||
onCell: record => ({
|
||||
record,
|
||||
editable: col.editable,
|
||||
dataIndex: col.dataIndex,
|
||||
title: col.title,
|
||||
handleSave: this.handleSave,
|
||||
}),
|
||||
};
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={this.handleAdd} type="primary" style={{ marginBottom: 16 }}>
|
||||
添加成员
|
||||
</Button>
|
||||
<Table
|
||||
components={components}
|
||||
rowClassName={() => 'editable-row'}
|
||||
bordered
|
||||
dataSource={dataSource}
|
||||
columns={columns}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default EditableTable;
|
|
@ -0,0 +1,15 @@
|
|||
.editable-cell {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.editable-cell-value-wrap {
|
||||
padding: 5px 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.editable-row .editable-cell-value-wrap {
|
||||
height: 30px;
|
||||
border: 1px solid #d9d9d9;
|
||||
border-radius: 4px;
|
||||
padding: 4px 11px;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
import javaFetch from '../javaFetch';
|
||||
|
||||
|
||||
let settings = localStorage.chromesetting && JSON.parse(localStorage.chromesetting);
|
||||
let actionUrl = settings && settings.api_urls && settings.api_urls.task ? settings.api_urls.task : 'https://task.osredm.com';
|
||||
const service = javaFetch(actionUrl);
|
||||
export const httpUrl = actionUrl;
|
||||
export const main_web_site_url = settings && settings.main_web_site_url;
|
||||
export default service;
|
|
@ -0,0 +1,22 @@
|
|||
import React, { useState, useCallback, useMemo, useEffect } 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';
|
||||
const Option = Select.Option;
|
||||
|
||||
function Introduce({ form, showNotification, match, history }) {
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
da指南
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
export default Introduce;
|
Binary file not shown.
After Width: | Height: | Size: 2.2 MiB |
Binary file not shown.
After Width: | Height: | Size: 488 KiB |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="15" viewBox="0 0 18 15">
|
||||
<path id="首页" d="M198.845,235.719h-15.6a1.2,1.2,0,0,1-1.2-1.237,1.121,1.121,0,0,1,1.2-1.237h15.6a1.238,1.238,0,0,1,0,2.474Zm0,6.186h-15.6a1.2,1.2,0,0,1-1.2-1.237c0-.773.45-1.082,1.2-1.082h15.6a1.172,1.172,0,0,1,1.2,1.082A1.311,1.311,0,0,1,198.845,241.9Zm0,6.34h-15.6a1.2,1.2,0,0,1-1.2-1.237,1.121,1.121,0,0,1,1.2-1.237h15.6a1.238,1.238,0,0,1,0,2.474Z" transform="translate(-182.045 -233.245)" fill="#181818"/>
|
||||
</svg>
|
After Width: | Height: | Size: 507 B |
|
@ -0,0 +1,85 @@
|
|||
// 启智2022主页样式
|
||||
.qz_banner{
|
||||
width: 100vw;
|
||||
height: 380px;
|
||||
}
|
||||
.qz2022 {
|
||||
font-size: 16px;
|
||||
.qz2022Menu {
|
||||
// width: 1200px;
|
||||
// margin: 0 auto;
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
a{color:#2e3341;}
|
||||
li.active{
|
||||
background-color: #fafafa;
|
||||
a{
|
||||
font-weight:700;
|
||||
color:#2e5bfe;
|
||||
font-size:18px;
|
||||
}
|
||||
}
|
||||
li.active::before{
|
||||
position: absolute;
|
||||
top: 55px;
|
||||
width: 70px;
|
||||
content: '';
|
||||
height: 2px;
|
||||
background: #4154f1;
|
||||
}
|
||||
}
|
||||
.menu_border {
|
||||
// width: 1200px;
|
||||
height: 1px;
|
||||
// margin: 0 auto;
|
||||
background-image: linear-gradient(90deg,#ffffff 0%,#373f5e 43.51%,#373f5e 54.81%,#ffffff 100%
|
||||
);
|
||||
}
|
||||
.qzCont{
|
||||
border-radius:4px;
|
||||
box-shadow:0px 3px 12px #ecf0ff;
|
||||
}
|
||||
}
|
||||
.qz_manage{
|
||||
top: 510px !important;
|
||||
.ant-dropdown-menu-item > a{
|
||||
color: #333;
|
||||
&:hover{color:#4154f1 !important;}
|
||||
}
|
||||
}
|
||||
.qz_manage:after,.qz_manage .after{
|
||||
content: '';
|
||||
display:block;
|
||||
width:0;
|
||||
height:0;
|
||||
overflow:hidden;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
border:9px;
|
||||
border-style:dashed dashed solid dashed;
|
||||
border-color:transparent transparent #fff transparent;
|
||||
position:absolute;
|
||||
left: 51px;
|
||||
top: -16px;
|
||||
}
|
||||
// 公共样式
|
||||
.qz_main{
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
// 按钮样式
|
||||
.but_2e5{
|
||||
border: none;
|
||||
background-color:#2e5bfe;
|
||||
padding: 0 14px;
|
||||
height: 36px;
|
||||
border-radius: 4px;
|
||||
span{
|
||||
color: #fff;
|
||||
}
|
||||
&:hover, &:focus{
|
||||
background-color: #2e5bfe;
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
import React, { useState, useCallback, useMemo, useEffect } 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';
|
||||
const Option = Select.Option;
|
||||
|
||||
function Introduce({ form, showNotification, match, history }) {
|
||||
useEffect(() => {
|
||||
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
da
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
export default Introduce;
|
|
@ -0,0 +1,131 @@
|
|||
import React, { useState, useCallback, useMemo, useEffect } 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 {competitionArea, competitionType} from '../static.js';
|
||||
import PaginationTable from "../../components/paginationTable";
|
||||
|
||||
import './index.scss';
|
||||
import '../index.scss';
|
||||
const Option = Select.Option;
|
||||
|
||||
function Introduce({ form, showNotification, match, history:{location:{pathname}} }) {
|
||||
// 报名列表和作品列表到指向此处,type做区分,0报名,1作品
|
||||
const [type, setType] = useState(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght));
|
||||
const [reload, setReload] = useState();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [curPage, setCurPage] = useState(1);
|
||||
const [pageSize, setPageSize] = useState(10);
|
||||
const [dataList, setDataList] = useState([]);
|
||||
const [total, setTotal] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
setType(pathname.substring(pathname.lastIndexOf('/')+1, pathname.lenght));
|
||||
}, [pathname]);
|
||||
|
||||
const columns_apply = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
title: '参赛单位',
|
||||
dataIndex: 'index'
|
||||
},
|
||||
{
|
||||
title: '参赛负责人',
|
||||
dataIndex: 'containerName',
|
||||
key: 'containerName',
|
||||
},
|
||||
{
|
||||
title: '职务',
|
||||
dataIndex: 'reviewEndOn',
|
||||
key: 'reviewEndOn',
|
||||
},
|
||||
{
|
||||
title: '军衔',
|
||||
dataIndex: 'surplus',
|
||||
key: 'surplus',
|
||||
},
|
||||
{
|
||||
title: '电话',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
},
|
||||
{
|
||||
title: '赛项',
|
||||
dataIndex: 'status',
|
||||
key: 'action',
|
||||
},
|
||||
{
|
||||
title: '课题来源',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
},
|
||||
{
|
||||
title: '成员',
|
||||
dataIndex: 'status',
|
||||
key: 'action',
|
||||
}
|
||||
];
|
||||
}, []);
|
||||
|
||||
const columns_production = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
title: '参赛单位',
|
||||
dataIndex: 'index'
|
||||
},
|
||||
{
|
||||
title: '参赛负责人',
|
||||
dataIndex: 'containerName',
|
||||
key: 'containerName',
|
||||
},
|
||||
{
|
||||
title: '赛区',
|
||||
dataIndex: 'reviewEndOn',
|
||||
key: 'reviewEndOn',
|
||||
},
|
||||
{
|
||||
title: '赛项',
|
||||
dataIndex: 'surplus',
|
||||
key: 'surplus',
|
||||
},
|
||||
{
|
||||
title: '作品',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
},
|
||||
];
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="qz_management">
|
||||
|
||||
<div className="qz_manage_head">启智2022{type === "applys" ? "报名" : "作品"}列表</div>
|
||||
|
||||
<div className="search">
|
||||
<div>
|
||||
赛区:
|
||||
<Select defaultValue="-1" style={{ width: 200 }}>
|
||||
<Option value='-1'>所有赛区</Option>
|
||||
{competitionArea.map(item=> {return <Option value={item.value}>{item.title}</Option>})}
|
||||
</Select>
|
||||
<span className="ml30">赛项:</span>
|
||||
<Select defaultValue="-1" style={{ width: 200 }}>
|
||||
<Option value='-1'>所有赛项</Option>
|
||||
{competitionType.map(item=> {return <Option value={item.value}>{item.title}</Option>})}
|
||||
</Select>
|
||||
</div>
|
||||
{type === "applys" && <Button className="but_2e5">导出</Button>}
|
||||
</div>
|
||||
|
||||
<PaginationTable
|
||||
className="qzManageTable"
|
||||
loading={loading}
|
||||
dataSource={dataList}
|
||||
columns={type==="applys" ? columns_apply : columns_production}
|
||||
total={total}
|
||||
setCurPage={setCurPage}
|
||||
current={curPage}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Introduce;
|
|
@ -0,0 +1,20 @@
|
|||
.qz_management{
|
||||
width: 1200px;
|
||||
margin: 35px auto 0;
|
||||
background: #fff;
|
||||
padding-bottom: 20px;
|
||||
.qz_manage_head{
|
||||
color: #181818;
|
||||
padding: 12px 0 13px 30px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.search {
|
||||
color: #000;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 20px 30px;
|
||||
}
|
||||
.pagination-table.qzManageTable {
|
||||
padding: 0 30px;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import React, { useState, useCallback, useMemo, useEffect } from "react";
|
||||
import { Input, Select, Button, Form, DatePicker, Table, Pagination, Upload, Modal, Breadcrumb } from 'antd';
|
||||
import { Link } from "react-router-dom";
|
||||
import { formatDuring } from 'educoder';
|
||||
import icon from '../image/notice_breadcrumb.svg';
|
||||
|
||||
import './index.scss';
|
||||
import './detail.scss';
|
||||
const Option = Select.Option;
|
||||
|
||||
function NoticeDetail({ form, showNotification, match, history }) {
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="qz_notice">
|
||||
<div className="qz_main notice_detal pt30">
|
||||
<div className="breadCrumb">
|
||||
<img src={icon} className="mr12 icon_d"/>
|
||||
<Link to={"/competition/qz2022/notice"}><span className="font-16 _999">通知公告</span></Link>
|
||||
<span className="mr10 ml10 _999">/</span>
|
||||
<span className="font-16 _18">公告详情</span>
|
||||
</div>
|
||||
<div className="notice_title _1818 font-18">启智2022大赛即将开始报名!</div>
|
||||
<div className="notice_time">发布时间: 2021年3月31日</div>
|
||||
<div className="_1818">“启智 2022 创意征集行动”为军委联合参谋部、科学技术委员会联合举办,军事科学院、航天科技集团协手创办的大型竞赛。现竞赛已临近报名阶段,报名安排如下:</div>
|
||||
|
||||
<div className="_1818 notice_small_title">【报名时间】</div>
|
||||
<div className="_1818">2022年4月1日~2022年4月30日</div>
|
||||
|
||||
<div className="_1818 notice_small_title">【报名方式】</div>
|
||||
<div className="_1818 last_de">参赛成员需于2022年4月30日24:00前在本竞赛“参赛报名”页面提交本人信息、赛队成员信息、所选子赛区及子赛项信息,并认真核对报名材料,务必与线下报名表信息一致。</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default NoticeDetail;
|
|
@ -0,0 +1,3 @@
|
|||
.menu_border+.qz2022Menu{
|
||||
display: none;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
import React, { useState, useCallback, useMemo, useEffect } 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';
|
||||
const Option = Select.Option;
|
||||
|
||||
function Notice({ form, showNotification, match, history }) {
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="qz_notice">
|
||||
<div className="qz_main not">
|
||||
<Link to={"/competition/qz2022/notice/1"}>
|
||||
<div className="qz_notice_cont">
|
||||
<div className="notCont_head">启智2022大赛即将开始报名!</div>
|
||||
<div className="font-15">“启智 2022 创意征集行动”为军委联合参谋部、科学技术委员会联合举办,军事科学院、航天科技集团协手创办的大型竞赛。现竞赛已临近报名阶段,报名安排如下...</div>
|
||||
<p>2022-03-31</p>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default Notice;
|
|
@ -0,0 +1,63 @@
|
|||
.qz_notice{
|
||||
min-height: 445px;
|
||||
>.qz_main.not{
|
||||
margin-top: 48px;
|
||||
background-image: url('../image/notice_bj.png');
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
>.qz_main.notice_detal{
|
||||
min-height: 65vh;
|
||||
>.breadCrumb .icon_d{margin-top: -4px;}
|
||||
}
|
||||
.qz_notice_cont{
|
||||
background-color:#ffffff;
|
||||
border-radius:4px;
|
||||
box-shadow:0px 3px 12px #ecf0ff;
|
||||
padding: 18px 30px 25px 20px;
|
||||
color:#2e3341;
|
||||
cursor: pointer;
|
||||
>.notCont_head{
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
font-weight:bold;
|
||||
color:#2e5bfe;
|
||||
border-bottom: 1px solid rgba(153, 153, 153, 0.2);
|
||||
}
|
||||
>p{
|
||||
text-align: right;
|
||||
color:#666666;
|
||||
}
|
||||
>.font-15{
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
}
|
||||
._999{
|
||||
color: #999;
|
||||
&:hover{color: #2e5bfe;}
|
||||
}
|
||||
._1818{color: #181818;}
|
||||
// 详情页样式
|
||||
.notice_title{
|
||||
text-align: center;
|
||||
font-weight:bold;
|
||||
margin: 60px 0 30px;
|
||||
}
|
||||
.notice_time{
|
||||
color:#2e3341;
|
||||
text-align: right;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 1px dashed #979797;
|
||||
}
|
||||
.notice_small_title{
|
||||
font-weight:bold;
|
||||
margin-top: 30px;
|
||||
}
|
||||
.last_de{
|
||||
padding-bottom: 40px;
|
||||
margin-bottom: 50px;
|
||||
border-bottom: 1px dashed #979797;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// 赛区*(必填项,placeholder:请选择赛区,下拉列表选择,选项为:陆J分赛区、海J分赛区、空J分赛区、火箭J分赛区、战略支援部队分赛区、联勤保障分赛区、武J部队分赛区)
|
||||
// 赛项*(必填项,placeholder:请选择赛项,下拉列表选择,选项为:战略方向,作战领域,前沿技术)
|
||||
// 赛区配置
|
||||
export const competitionArea = [
|
||||
{ value: '0', title: "陆军分赛区"},
|
||||
{ value: '1', title: "海军分赛区"},
|
||||
{ value: '2', title: "空军分赛区"},
|
||||
{ value: '3', title: "火箭军分赛区"},
|
||||
{ value: '4', title: "战略支援部队分赛区"},
|
||||
{ value: '5', title: "联勤保障分赛区"},
|
||||
{ value: '6', title: "武军部队分赛区"}
|
||||
];
|
||||
// 赛项配置
|
||||
export const competitionType = [
|
||||
{ value: '0', title: "战略方向"},
|
||||
{ value: '1', title: "作战领域"},
|
||||
{ value: '2', title: "前沿技术"},
|
||||
];
|
||||
|
||||
// 启智2022所有的路由后缀
|
||||
export const paths = ["introduce", "fingerpost", "notice", "apply", "refer", "statistics", "chat", "contact", "applys", "production"]
|
Loading…
Reference in New Issue