启智2022 静态页面50%

This commit is contained in:
谢思 2022-03-24 17:05:57 +08:00 committed by 何童崇
parent a4cd1b4c1d
commit 53cad9df93
27 changed files with 1575 additions and 1 deletions

View File

@ -55,6 +55,11 @@ const Task = Loadable({
loader: () => import('./military/task'),
loading: Loading,
})
//任务/需求
const Qz2022 = Loadable({
loader: () => import('./military/qz2022'),
loading: Loading,
});
//403页面
const Shixunauthority = Loadable({
loader: () => import('./modules/403/Shixunauthority'),
@ -269,6 +274,9 @@ class App extends Component {
{/*任务*/}
<Route path="/task" component={Task} />
{/*任务*/}
<Route path="/competition/qz2022" component={Qz2022} />
{/*403*/}
<Route path="/403" component={Shixunauthority} />

View File

@ -57,7 +57,9 @@ export function initAxiosInterceptors(props) {
var
proxy = "http://localhost:3000";
// proxy = "https://forge.osredm.com";
proxy = "http://117.50.100.12:49999";
// proxy = "http://117.50.100.12:49999";
proxy = "http://111.8.36.180:8000";
const requestMap = {};
window.setfalseInRequestMap = function (keyName) {

367
src/forge/Head/header.scss Normal file
View File

@ -0,0 +1,367 @@
.dropdownFlex{
display:flex;
background:#fff;
border-radius: 3px;
.ant-menu-vertical > .ant-menu-item{
border:none;
height: 35px;
line-height: 35px;
margin:0px;
&.ant-menu-item-selected{
background-color: #fff;
a{color: rgba(0, 0, 0, 0.65)!important;}
}
&.ant-menu-item-active{
a{color: #4cacff!important;}
}
}
.ant-menu-vertical{
border:none;
}
}
.currentImg{
width: 34px;
height: 34px;
border-radius: 50%;
margin-left: 15px;
}
.currentMenu{
width: 120px;
text-align: center;
padding:0px;
.currentName{
padding:0px 8px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
display: block;
}
li{
height: 40px;
line-height: 40px;
padding:0px!important;
cursor: default;
&:hover{
background-color: #fff;
}
&:first-child{
border-bottom: 1px solid #eee;
}
&:last-child{
border-top: 1px solid #eee;
a{
border-radius: 0px 0px 4px 4px;
}
}
a{
padding:0px;
margin:0px;
display: block;
color: #666;
&:hover{
color: #fff;
background: #4CACFF;
}
}
}
}
.newFooter {
// position: absolute;
bottom: 0;
width: 100%;
background: #323232;
clear: both;
min-width: 1200px;
z-index: 8;
left: 0px;
padding-bottom: 15px;
p {
margin-top: 0;
margin-bottom:0px !important;
}
.footerInfos{
display: flex;
max-width: 1200px;
margin:0px auto;
justify-content: space-around;
padding:60px 0px;
& >ul{
padding:0px 40px;
box-sizing: border-box;
max-width: 25%;
text-align: left;
li{
color: #fff;
font-weight: 300;
&:first-child{
font-size: 17px;
}
&>a,&>span{
color: #bbb;
}
&>a:hover{
color: #4cacff;
}
}
}
}
.footerCopy{
color: #bbb;
border-top: 1px solid #4e4e4e;
padding:10px 0px;
a{
color: #bbb;
&:hover{
color: #4cacff;
}
}
}
}
.inviteForm{
.ant-form-item{
margin-right: 0px;
}
.ant-form-item-label{
width: 110px;
text-align: right;
}
.ant-form-explain{
position: absolute;
}
}
// 右上角小铃铛单独样式
.notice-popover{
z-index: 1000001;
//popover小尖尖
.ant-popover-arrow{
display: none;
}
//popover框
.ant-popover-inner-content {
width: 386px;
height: 446px;
box-shadow: 0px 4px 8px 2px rgba(212, 212, 212, 0.5);
border-radius: 4px;
margin-top: -10px;
padding: 12px 1px 12px 0;
}
}
.messageHoverDiv .ant-menu-item{
margin-right: 24px !important;
}
.hoverNotice-head{
margin-left: 18px;
& .ant-badge{
font-size: 14px !important;
}
&>.ant-menu-horizontal {
border-bottom: 1px solid #e8e8e8 !important;
}
}
.hoverNotice-body{
height: 342px;
overflow-y: scroll;
& b{
font-weight: 400;
text-shadow: 0.5px 0 0 #333;
}
.none_panels{
height: 100%;
}
}
.message-icon{
position: relative;
.ant-scroll-number{
// right:12px;
padding: 0 0px;
}
}
.hoverNotice-buttom{
display: flex;
justify-content: space-between;
padding: 12px 18px;
a{
color: #466AFF;
&:hover{
opacity:0.85;
}
}
}
.noticeCont-back{
.pointer{
cursor: pointer;
}
&:hover{
background: #F3F4F6;
}
}
.noticeCont{
display: flex;
margin: 0 16px 0 18px;
padding: 12px 0 10px 0;
line-height: 24px;
border-bottom: 1px solid #EEEEEE;
cursor: default;
i{
font-size: 14px !important;
margin-right: 6px;
color: #333333;
}
.boldSpan{
font-weight: 400;
text-shadow: 0.5px 0 0 #333;
}
.noticeCont-text{
display: flex;
color:#333333;
flex:auto;
justify-content: space-between;
& .content-span{
word-break: break-all;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
& .atme-cont-span{
width: 272px;
}
& .notice-cont-span{
width: 255px;
}
.timeSpan{
font-size: 12px;
color: #666666;
}
.at-name{
margin-right: 12px;
}
}
}
.text-center{
text-align: center;
}
.footEdition{
background-color: #171B23;
.footContent{
display: flex;
align-items: flex-start;
padding:86px 0px;
justify-content: space-around;
width: 1200px;
margin:0px auto;
ul{
min-width: 120px;
text-align: left;
margin-right: 80px;
&.center{
text-align: center;
}
&>p{
height: 22px;
font-size: 16px;
font-weight: 400;
color: #FFFFFF;
line-height: 22px;
}
&>img{
width: 100px;
height: 100%;
margin-bottom: 30px;
margin-top: 25px;
border-radius: 10px;
}
li{
height: 20px;
font-size: 14px;
font-weight: 400;
line-height: 20px;
color: #BDC2D1;
margin-bottom: 15px!important;
a{
color: #BDC2D1!important;
&:hover{
text-decoration: underline;
}
}
&.thehead{
height: 25px;
font-size: 18px;
font-weight: 600;
color: #FFFFFF;
line-height: 25px;
margin-bottom: 20px!important;
}
}
.theline{
.imgCon{
width: 90px;
height: 90px;
padding:5px;
border-radius: 4px;
background-color: #fff;
img{
width: 100%;
border-radius: 3px;
}
}
}
}
}
}
.copyrightDesc{
font-size: 12px;
font-weight: 400;
color: #BDC2D1;
line-height: 28px;
padding:15px 0px;
text-align: center;
background-color: #1B212C;
a{
color: #BDC2D1!important;
}
}
.regBtn{
height: 40px;
background: #466AFF;
border-radius: 2px;
display: inline-block;
padding:0px 18px;
margin-left: 20px;
font-size: 14px;
font-weight: 400;
color: #FFFFFF!important;
line-height: 40px;
&:hover{
color: #FFFFFF!important;
background-color: #355CFF;
}
}

View File

@ -0,0 +1,36 @@
import React, { Fragment } from 'react';
import { Table, Pagination } from 'antd';
import './index.scss';
export default (props) => {
const {className, loading, dataSource, columns, handleRow, total, setCurPage, current, rowSelection, expandedRowRender, expandIconColumnIndex, expandIconAsCell, onShowSizeChange, showSizeChanger, pagination, scroll } = props;
return (
<div className={`pagination-table ${className}`}>
<Table
{...props}
loading={loading}
rowKey={(row,i) => row.id || i}
dataSource={dataSource}
columns={columns}
pagination={false}
onRow={handleRow}
rowSelection={rowSelection}
expandedRowRender={expandedRowRender}
expandIconColumnIndex={expandIconColumnIndex}
expandIconAsCell={expandIconAsCell}
scroll={scroll}
/>
{total > 10 && (!pagination) &&
<Pagination
showQuickJumper
onShowSizeChange={onShowSizeChange}
onChange={setCurPage}
current={current}
total={total}
showSizeChanger={showSizeChanger}
/>}
</div>
)
}

158
src/military/qz2022.js Normal file
View File

@ -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))))
);

255
src/military/qz2022/api.js Normal file
View File

@ -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,
});
}

View File

@ -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>
)
})

View File

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;

View File

View File

@ -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}} }) {
// type01
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;

View File

@ -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;
}
}

View File

@ -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;

View File

@ -0,0 +1,3 @@
.menu_border+.qz2022Menu{
display: none;
}

View File

@ -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;

View File

@ -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;
}
}

View File

View File

@ -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"]