forked from Gitlink/forgeplus-react
初始化后台管理分支代码
This commit is contained in:
parent
3ac6021d9e
commit
d1d9213527
|
@ -104,6 +104,7 @@ module.exports = {
|
|||
src: path.join(paths.appSrc), // 整个源代码目录
|
||||
forge: path.join(paths.appSrc, 'forge'),
|
||||
military: path.join(paths.appSrc, 'military'),
|
||||
components: path.join(paths.appSrc, 'components'),
|
||||
// Support React Native Web
|
||||
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
||||
"react-native": "react-native-web",
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"educoder": ["./src/common/educoder.js"],
|
||||
"forge":["./src/forge"],
|
||||
"military":["./src/military"],
|
||||
"components":["./src/components"],
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
|
|
|
@ -137,7 +137,7 @@ const HomePage = Loadable({
|
|||
|
||||
// 管理页面
|
||||
const Managements = Loadable({
|
||||
loader: () => import('./military/managements'),
|
||||
loader: () => import('./managements/index'),
|
||||
loading: Loading,
|
||||
})
|
||||
// const CreateMerge = Loadable({
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
/* eslint-disable react/jsx-no-duplicate-props */
|
||||
import React, { useState } from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { Modal, Button } from 'antd';
|
||||
import './index.scss';
|
||||
|
||||
// 函数式调用删除、通知等模态框
|
||||
|
||||
InitModal.defaultProps = {
|
||||
okText: '确认', //确定按钮的文字
|
||||
cancelText: '取消', //取消按钮的文字
|
||||
className: '', //传入的模态框类名
|
||||
inputId: 'copyText', //要复制的文本的ID
|
||||
onCancel:()=>{}, //取消的回调
|
||||
onOk:()=>{}, //确认的回调
|
||||
title:'提示', //模态框名字
|
||||
contentTitle:'', //内容标题
|
||||
content:'', //详细内容
|
||||
afterClose:()=>{}, //关闭模态框以后的回调
|
||||
};
|
||||
|
||||
// 使用函数调用删除组件
|
||||
export default function DelModal(props) {
|
||||
renderModal({ ...props, type: 'delete' })
|
||||
}
|
||||
|
||||
// 使用函数调用选择模态框组件
|
||||
export function Confirm(props) {
|
||||
renderModal({ ...props, type: 'confirm' })
|
||||
}
|
||||
|
||||
function renderModal(props) {
|
||||
const { type, afterClose } = props;
|
||||
const div = document.createElement('div');
|
||||
document.body.appendChild(div);
|
||||
|
||||
function destroy() {
|
||||
afterClose && afterClose();
|
||||
const unmountResult = ReactDOM.unmountComponentAtNode(div);
|
||||
if (unmountResult && div.parentNode) {
|
||||
div.parentNode.removeChild(div);
|
||||
}
|
||||
}
|
||||
|
||||
function modalType(type) {
|
||||
if (type === 'delete') {
|
||||
return <InitModal
|
||||
title="删除"
|
||||
contentTitle="确定要删除吗?"
|
||||
okText="确认删除"
|
||||
{...props}
|
||||
|
||||
afterClose={destroy}
|
||||
contentTitle={<React.Fragment>
|
||||
<i className="red-circle iconfont icon-shanchu_tc_icon mr3"></i>
|
||||
{props.contentTitle}
|
||||
</React.Fragment>}
|
||||
/>
|
||||
} else if (type === 'confirm') {
|
||||
return <InitModal title="选择" afterClose={destroy} {...props} />
|
||||
} else {
|
||||
return <InitModal title="选择" afterClose={destroy} {...props} />
|
||||
}
|
||||
}
|
||||
|
||||
function render() {
|
||||
setTimeout(() => {
|
||||
ReactDOM.render(
|
||||
modalType(type),
|
||||
div,
|
||||
);
|
||||
});
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
// 选择模态框组件
|
||||
function InitModal({
|
||||
onCancel,
|
||||
onOk,
|
||||
title,
|
||||
contentTitle,
|
||||
content,
|
||||
okText,
|
||||
cancelText,
|
||||
afterClose,
|
||||
className,
|
||||
}) {
|
||||
|
||||
const [visible, setVisible] = useState(true);
|
||||
|
||||
function onCancelModal() {
|
||||
setVisible(false);
|
||||
onCancel && onCancel()
|
||||
}
|
||||
|
||||
function onSuccess() {
|
||||
setVisible(false);
|
||||
onOk && onOk();
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal
|
||||
visible={visible}
|
||||
onCancel={onCancelModal}
|
||||
afterClose={afterClose}
|
||||
title={title}
|
||||
className={`myself-modal ${className}`}
|
||||
centered
|
||||
footer={[
|
||||
<Button type="default" key="back" onClick={onCancelModal}>
|
||||
{cancelText}
|
||||
</Button>,
|
||||
<Button className="foot-submit" key="submit" onClick={onSuccess}>
|
||||
{okText}
|
||||
</Button>,
|
||||
]}
|
||||
>
|
||||
<div>
|
||||
{contentTitle && <p className="content-title">{contentTitle}</p>}
|
||||
<p className="content-descibe">{content}</p>
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
.myself-modal {
|
||||
.ant-modal-header {
|
||||
padding: 9px 24px;
|
||||
background: #f8f8f8;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.ant-modal-title {
|
||||
text-align: left;
|
||||
}
|
||||
.ant-modal-close {
|
||||
top: 0px !important;
|
||||
}
|
||||
.ant-modal-close-x {
|
||||
font-size: 24px;
|
||||
}
|
||||
.ant-modal-body {
|
||||
text-align: center;
|
||||
}
|
||||
.content-title {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 2rem 0 1rem !important;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
letter-spacing: 0;
|
||||
line-height: 29px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.red-circle {
|
||||
align-self: flex-start;
|
||||
color: #ca0002;
|
||||
font-size: 1.5rem !important;
|
||||
}
|
||||
.content-descibe {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
line-height: 33px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.ant-modal-footer {
|
||||
padding: 2rem 0;
|
||||
text-align: center;
|
||||
border: 0;
|
||||
.ant-btn {
|
||||
width: 6rem;
|
||||
}
|
||||
}
|
||||
.foot-submit {
|
||||
margin-left: 3rem;
|
||||
color: #df0002;
|
||||
&:hover {
|
||||
border-color: #df0002;
|
||||
}
|
||||
}
|
||||
.ant-btn-default:hover,
|
||||
.ant-btn-default:active,
|
||||
.ant-btn-default:focus {
|
||||
background: #f3f4f6;
|
||||
color: #333;
|
||||
border-color: #d0d0d0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
import React, { Fragment } from 'react';
|
||||
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;
|
||||
|
||||
return (
|
||||
<div className='pagination-table'>
|
||||
<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>
|
||||
|
||||
)
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
.pagination-table {
|
||||
.ant-table {
|
||||
border: 1px solid #ececec;
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
.ant-table-thead tr th div {
|
||||
color: #181818;
|
||||
font-weight: 500;
|
||||
}
|
||||
.ant-table-wrapper {
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
.ant-table-hide-scrollbar {
|
||||
margin-bottom: -5px;
|
||||
overflow-y: hidden !important;
|
||||
::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table-thead > tr > th, .ant-table-tbody > tr > td{
|
||||
padding: 14px 8px;
|
||||
}
|
||||
|
||||
.ant-pagination {
|
||||
margin-top: 1.25rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
// .ant-table-row-cell-break-word{
|
||||
// .ant-btn{
|
||||
// display: inline-block;
|
||||
// }
|
||||
// }
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
import React, { useState ,useEffect } from 'react';
|
||||
import { Link } from "react-router-dom";
|
||||
import { Menu,Icon, Dropdown, } from 'antd';
|
||||
import './index.scss';
|
||||
|
||||
const { SubMenu } = Menu;
|
||||
|
||||
export default (props) => {
|
||||
|
||||
const {current_user,history}=props;
|
||||
const main_web_site_url =localStorage.chromesetting&& JSON.parse(localStorage.chromesetting).main_web_site_url;
|
||||
const current_main_site_url =localStorage.chromesetting&& JSON.parse(localStorage.chromesetting).current_main_site_url;
|
||||
const noticeUrl =localStorage.chromesetting&& JSON.parse(localStorage.chromesetting).api_urls.notice;
|
||||
useEffect(()=>{
|
||||
sessionStorage.setItem('current_user',JSON.stringify(current_user));
|
||||
},[current_user.login]);
|
||||
|
||||
|
||||
const [current,setCurrent]=useState(JSON.parse(sessionStorage.adminRouter||'[]'));
|
||||
const [title,setTitle]=useState('');
|
||||
|
||||
function handleClick (e){
|
||||
setCurrent([e.key]);
|
||||
setTitle(e.item.props.title);
|
||||
sessionStorage.setItem( 'adminRouter',JSON.stringify([e.key]));
|
||||
};
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className="layouts">
|
||||
<Menu
|
||||
defaultSelectedKeys={['1']}
|
||||
defaultOpenKeys={['sub1']}
|
||||
mode="inline"
|
||||
>
|
||||
<SubMenu
|
||||
key="sub1"
|
||||
title={
|
||||
<span>
|
||||
<Icon type="mail" />
|
||||
<span>概览</span>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<Menu.Item key="1" onClick={() => { history.push('/global') }}>全局统计</Menu.Item>
|
||||
<Menu.Item key="6" onClick={() => { history.push('/member') }}>成员工作统计</Menu.Item>
|
||||
<Menu.Item key="7" onClick={() => { history.push('/activity') }}>项目活跃度统计</Menu.Item>
|
||||
</SubMenu>
|
||||
|
||||
|
||||
<SubMenu
|
||||
key="task"
|
||||
title={
|
||||
<span>
|
||||
<Icon type="mail" />
|
||||
<span>创客空间</span>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<SubMenu title="基础数据" >
|
||||
<Menu.Item><a href={`${main_web_site_url}/admin/categories/list`}>任务领域</a></Menu.Item>
|
||||
<Menu.Item><a href={`${main_web_site_url}/admin/industries/list`}>行业信息</a></Menu.Item>
|
||||
<Menu.Item><a href={`${main_web_site_url}/admin/placements/list`}>职位信息</a></Menu.Item>
|
||||
<Menu.Item><a href={`${main_web_site_url}/admin/task_templates/list`}>需求导入模板</a></Menu.Item>
|
||||
<Menu.Item><a href={`${main_web_site_url}/admin/agreement_setting`}>签订协议内容</a></Menu.Item>
|
||||
<Menu.Item><a href={`${main_web_site_url}/admin/sign_agreement_setting`}>应征投稿协议内容</a></Menu.Item>
|
||||
</SubMenu>
|
||||
<SubMenu title="代办事项" >
|
||||
<Menu.Item title="task" key="delayManage"><Link to="/managements/task/delayManage">延期任务处理</Link></Menu.Item>
|
||||
<Menu.Item title="task" key="payProof"><Link to="/managements/task/payProof">支付报酬凭证上传</Link></Menu.Item>
|
||||
</SubMenu>
|
||||
<Menu.Item title="task" key="taskAdmin"><Link to="/managements/task/taskAdmin">创客任务列表</Link></Menu.Item>
|
||||
</SubMenu>
|
||||
|
||||
</Menu>
|
||||
</div>
|
||||
|
||||
);
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
.layouts {
|
||||
background: #aaa;
|
||||
position: fixed;
|
||||
top: 70px;
|
||||
left:0;
|
||||
width: 10vw;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
.layouts{
|
||||
display: none;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,229 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
|
||||
import { Route, Switch } from "react-router-dom";
|
||||
import { withRouter } from "react-router";
|
||||
import { 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 AdminRouter from "../military/components/adminRouter";
|
||||
import { ImageLayerOfCommentHOC } from "../modules/page/layers/ImageLayerOfCommentHOC";
|
||||
import Layouts from "./components/layouts";
|
||||
import './index.scss';
|
||||
|
||||
{/* 任务管理审核 */}
|
||||
const TaskManage = Loadable({
|
||||
loader: () => import("../military/task/taskManage"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
{/* 成果管理审核 */}
|
||||
const PaperManage = Loadable({
|
||||
loader: () => import("../military/task/paperManage"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
{/* 成果申诉管理审核 */}
|
||||
const PaperComplain = Loadable({
|
||||
loader: () => import("../military/task/paperComplain"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const ProofManage = Loadable({
|
||||
loader: () => import("../military/task/proofManage"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const PublicityComplain = Loadable({
|
||||
loader: () => import("../military/task/publicityComplain"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const AgreementManage = Loadable({
|
||||
loader: () => import("../military/task/agreementManage"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const PayProof = Loadable({
|
||||
loader: () => import("../military/task/payProof"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const TaskAdmin = Loadable({
|
||||
loader: () => import("../military/task/taskAdmin"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
const DelayManage = Loadable({
|
||||
loader: () => import("../military/task/delayManage"),
|
||||
loading: Loading,
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 专家库
|
||||
const ExpertList = Loadable({
|
||||
loader: () => import("../military/expert/expertList"),
|
||||
loading: Loading,
|
||||
});
|
||||
// 专家审核
|
||||
const RegisterList = Loadable({
|
||||
loader: () => import("../military/expert/registerList"),
|
||||
loading: Loading,
|
||||
});
|
||||
//创客任务评审规则
|
||||
const ReviewRules = Loadable({
|
||||
loader : () => import("../military/expert/reviewRules"),
|
||||
loading: Loading,
|
||||
});
|
||||
//创客任务选择评审专家
|
||||
const SelectExpert = Loadable({
|
||||
loader: () => import("../military/expert/selectExpert"),
|
||||
loading: Loading,
|
||||
});
|
||||
//创客任务评审结果查看
|
||||
const ReviewResult = Loadable({
|
||||
loader: () => import("../military/expert/reviewResult"),
|
||||
loading: Loading,
|
||||
});
|
||||
//竞赛评审任务列表
|
||||
const CompetitionList = Loadable({
|
||||
loader: () => import("../military/expert/competionList"),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
const Managements = (propsF) => {
|
||||
|
||||
return (
|
||||
<div className="newMain clearfix managements">
|
||||
{/* <AdminRouter {...propsF} /> */}
|
||||
<Layouts {...propsF} />
|
||||
<Switch {...propsF}>
|
||||
{/* 任务管理审核 */}
|
||||
<Route
|
||||
path="/managements/task/taskManage/:publishMode"
|
||||
render={(props) => (
|
||||
<TaskManage {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 成果管理审核 */}
|
||||
<Route
|
||||
path="/managements/task/paperManage"
|
||||
render={(props) => (
|
||||
<PaperManage {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 成果申诉管理审核 */}
|
||||
<Route
|
||||
path="/managements/task/paperComplain"
|
||||
render={(props) => (
|
||||
<PaperComplain {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 公示期成果申诉管理审核 */}
|
||||
<Route
|
||||
path="/managements/task/publicityComplain"
|
||||
render={(props) => (
|
||||
<PublicityComplain {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 佐证管理审核 */}
|
||||
<Route
|
||||
path="/managements/task/proofManage"
|
||||
render={(props) => (
|
||||
<ProofManage {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 管理员协议审核 */}
|
||||
<Route
|
||||
path="/managements/task/agreementManage"
|
||||
render={(props) => (
|
||||
<AgreementManage {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 管理员上传支付凭证 */}
|
||||
<Route
|
||||
path="/managements/task/payProof"
|
||||
render={(props) => (
|
||||
<PayProof {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 管理员任务列表 */}
|
||||
<Route
|
||||
path="/managements/task/taskAdmin"
|
||||
render={(props) => (
|
||||
<TaskAdmin {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
{/* 延期管理 */}
|
||||
<Route
|
||||
path="/managements/task/delayManage"
|
||||
render={(props) => (
|
||||
<DelayManage {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
|
||||
|
||||
|
||||
{/* 专家审核 */}
|
||||
<Route
|
||||
path="/managements/expert/register"
|
||||
render={(props) => (
|
||||
<RegisterList {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
{/* 专家库列表 */}
|
||||
<Route
|
||||
path="/managements/expert/list"
|
||||
render={(props) => (
|
||||
<ExpertList {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
{/* 创客任务评审规则 */}
|
||||
<Route
|
||||
path="/managements/expert/task/review/rules/:containerType/:containerId"
|
||||
render={(props) => (
|
||||
<ReviewRules {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
{/* 创客任务选择评审专家 */}
|
||||
<Route
|
||||
path="/managements/expert/task/review/select/:containerType/:containerId"
|
||||
render={(props) => (
|
||||
<SelectExpert {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
{/* 创客任务评审结果查看 */}
|
||||
<Route
|
||||
path="/managements/expert/task/review/results/:containerType/:containerId"
|
||||
render={(props) => (
|
||||
<ReviewResult {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
{/* 竞赛评审任务列表 */}
|
||||
<Route
|
||||
path="/managements/expert/competition"
|
||||
render={(props) => (
|
||||
<CompetitionList {...propsF} {...props} />
|
||||
)}
|
||||
></Route>
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default withRouter(
|
||||
ImageLayerOfCommentHOC({
|
||||
imgSelector: ".imageLayerParent img, .imageLayerParent .imageTarget",
|
||||
parentSelector: ".newMain",
|
||||
})(CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(Managements))))
|
||||
);
|
|
@ -0,0 +1,5 @@
|
|||
.managements{
|
||||
.centerbox{
|
||||
margin-left: 10vw;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue