parent
ea48bd3da2
commit
d6ef8aa1db
@ -33,7 +33,7 @@
|
||||
}
|
||||
|
||||
.layout-header {
|
||||
height: 48px;
|
||||
height: 60px;
|
||||
align-items: center;
|
||||
padding: 0 16px 0 0;
|
||||
background: #fff;
|
||||
@ -45,23 +45,19 @@
|
||||
padding: 0 12px;
|
||||
cursor: pointer;
|
||||
transition: all .3s;
|
||||
line-height: 48px;
|
||||
height: 48px;
|
||||
line-height: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.layout-header-right-item {
|
||||
margin: 0 6px;
|
||||
display: inline;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.layout-header-right-item:hover {
|
||||
background-color: #eeeeee;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.nickname {
|
||||
line-height: 48px;
|
||||
height: 48px;
|
||||
line-height: 60px;
|
||||
height: 60px;
|
||||
width: 125px;
|
||||
text-align: left;
|
||||
padding: 0 5px;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, {Component} from 'react';
|
||||
import 'antd/dist/antd.css';
|
||||
import './App.css';
|
||||
import {Divider, Layout, Menu} from "antd";
|
||||
import {Col, Divider, Dropdown, Layout, Menu, Popconfirm, Row, Tooltip} from "antd";
|
||||
import {Link, Route, Switch} from "react-router-dom";
|
||||
import Dashboard from "./components/dashboard/Dashboard";
|
||||
import Asset from "./components/asset/Asset";
|
||||
@ -21,15 +21,21 @@ import {
|
||||
DashboardOutlined,
|
||||
DesktopOutlined,
|
||||
DisconnectOutlined,
|
||||
DownOutlined,
|
||||
GithubOutlined,
|
||||
IdcardOutlined,
|
||||
LinkOutlined,
|
||||
LoginOutlined,
|
||||
LogoutOutlined,
|
||||
QuestionCircleOutlined,
|
||||
SafetyCertificateOutlined,
|
||||
SettingOutlined,
|
||||
SolutionOutlined,
|
||||
TeamOutlined,
|
||||
UserOutlined,
|
||||
UserSwitchOutlined
|
||||
UserSwitchOutlined,
|
||||
MenuUnfoldOutlined,
|
||||
MenuFoldOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import Info from "./components/user/Info";
|
||||
import request from "./common/request";
|
||||
@ -37,18 +43,18 @@ import {message} from "antd/es";
|
||||
import Setting from "./components/setting/Setting";
|
||||
import BatchCommand from "./components/command/BatchCommand";
|
||||
import {isEmpty, NT_PACKAGE} from "./utils/utils";
|
||||
import {isAdmin} from "./service/permission";
|
||||
import {getCurrentUser, isAdmin} from "./service/permission";
|
||||
import UserGroup from "./components/user/UserGroup";
|
||||
import LoginLog from "./components/devops/LoginLog";
|
||||
import Term from "./components/access/Term";
|
||||
import Job from "./components/devops/Job";
|
||||
import {Header} from "antd/es/layout/layout";
|
||||
import LayoutHeader from "./components/user/LayoutHeader";
|
||||
import Security from "./components/devops/Security";
|
||||
|
||||
const {Footer, Sider} = Layout;
|
||||
|
||||
const {SubMenu} = Menu;
|
||||
const headerHeight = 60;
|
||||
|
||||
class App extends Component {
|
||||
|
||||
@ -113,8 +119,54 @@ class App extends Component {
|
||||
sessionStorage.setItem('openKeys', JSON.stringify(openKeys));
|
||||
}
|
||||
|
||||
confirm = async (e) => {
|
||||
let result = await request.post('/logout');
|
||||
if (result['code'] !== 1) {
|
||||
message.error(result['message']);
|
||||
} else {
|
||||
message.success('退出登录成功,即将跳转至登录页面。');
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const menu = (
|
||||
<Menu>
|
||||
|
||||
<Menu.Item>
|
||||
<Link to={'/info'}>
|
||||
<SolutionOutlined/>
|
||||
个人中心
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
|
||||
<Menu.Item>
|
||||
<a target='_blank' rel="noreferrer" href='https://github.com/dushixiang/next-terminal'>
|
||||
<GithubOutlined/>
|
||||
点个Star
|
||||
</a>
|
||||
</Menu.Item>
|
||||
|
||||
<Menu.Divider/>
|
||||
|
||||
<Menu.Item>
|
||||
|
||||
<Popconfirm
|
||||
key='login-btn-pop'
|
||||
title="您确定要退出登录吗?"
|
||||
onConfirm={this.confirm}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
placement="left"
|
||||
>
|
||||
<LogoutOutlined/>
|
||||
退出登录
|
||||
</Popconfirm>
|
||||
</Menu.Item>
|
||||
|
||||
</Menu>
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@ -126,7 +178,7 @@ class App extends Component {
|
||||
<Route path="/">
|
||||
<Layout className="layout" style={{minHeight: '100vh'}}>
|
||||
|
||||
<Sider collapsible collapsed={this.state.collapsed} onCollapse={this.onCollapse}>
|
||||
<Sider collapsible collapsed={this.state.collapsed} trigger={null}>
|
||||
<div className="logo">
|
||||
<img src='logo.svg' alt='logo'/>
|
||||
{
|
||||
@ -251,8 +303,38 @@ class App extends Component {
|
||||
|
||||
<Layout className="site-layout">
|
||||
<Header className="site-layout-background"
|
||||
style={{padding: 0, height: 48, zIndex: 20}}>
|
||||
<LayoutHeader key='layout-right-header'/>
|
||||
style={{padding: 0, height: headerHeight, zIndex: 20}}>
|
||||
<div className='layout-header'>
|
||||
<Row justify="space-around" align="middle" gutter={24} style={{height: headerHeight}}>
|
||||
<Col span={4} key={1} style={{height: headerHeight}}>
|
||||
{React.createElement(this.state.collapsed ? MenuUnfoldOutlined : MenuFoldOutlined, {
|
||||
className: 'trigger',
|
||||
onClick: this.onCollapse,
|
||||
})}
|
||||
</Col>
|
||||
<Col span={20} key={2} style={{textAlign: 'right'}}
|
||||
className={'layout-header-right'}>
|
||||
|
||||
<div className={'layout-header-right-item'}>
|
||||
<Tooltip placement="bottom" title={'使用帮助'}>
|
||||
<a target='_blank' rel="noreferrer"
|
||||
href='https://github.com/dushixiang/next-terminal/blob/master/docs/faq.md'>
|
||||
<QuestionCircleOutlined/>
|
||||
</a>
|
||||
</Tooltip>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<Dropdown overlay={menu}>
|
||||
<div className='nickname layout-header-right-item'>
|
||||
{getCurrentUser()['nickname']} <DownOutlined/>
|
||||
</div>
|
||||
</Dropdown>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
</div>
|
||||
</Header>
|
||||
|
||||
<Route path="/" exact component={Dashboard}/>
|
||||
|
@ -10,7 +10,8 @@ const {Title} = Typography;
|
||||
|
||||
class LoginForm extends Component {
|
||||
|
||||
formRef = React.createRef()
|
||||
formRef = React.createRef();
|
||||
totpInputRef = React.createRef();
|
||||
|
||||
state = {
|
||||
inLogin: false,
|
||||
@ -44,6 +45,8 @@ class LoginForm extends Component {
|
||||
loginAccount: params,
|
||||
totpModalVisible: true
|
||||
})
|
||||
|
||||
this.totpInputRef.current.focus();
|
||||
return;
|
||||
}
|
||||
if (result.code !== 1) {
|
||||
@ -74,8 +77,9 @@ class LoginForm extends Component {
|
||||
try {
|
||||
let result = await request.post('/loginWithTotp', loginAccount);
|
||||
|
||||
if (result.code !== 1) {
|
||||
throw new Error(result.message);
|
||||
if (result['code'] !== 1) {
|
||||
message.error(result['message']);
|
||||
return;
|
||||
}
|
||||
|
||||
// 跳转登录
|
||||
@ -129,12 +133,13 @@ class LoginForm extends Component {
|
||||
<Modal title="双因素认证" visible={this.state.totpModalVisible} confirmLoading={this.state.confirmLoading}
|
||||
maskClosable={false}
|
||||
centered={true}
|
||||
okButtonProps={{form:'totp-form', key: 'submit', htmlType: 'submit'}}
|
||||
onOk={() => {
|
||||
this.formRef.current
|
||||
.validateFields()
|
||||
.then(values => {
|
||||
this.formRef.current.resetFields();
|
||||
this.handleOk(values);
|
||||
// this.formRef.current.resetFields();
|
||||
})
|
||||
.catch(info => {
|
||||
|
||||
@ -142,10 +147,10 @@ class LoginForm extends Component {
|
||||
}}
|
||||
onCancel={this.handleCancel}>
|
||||
|
||||
<Form ref={this.formRef}>
|
||||
<Form id='totp-form' ref={this.formRef}>
|
||||
|
||||
<Form.Item name='totp' rules={[{required: true, message: '请输入双因素认证APP中显示的授权码'}]}>
|
||||
<Input prefix={<OneToOneOutlined/>} placeholder="请输入双因素认证APP中显示的授权码"/>
|
||||
<Input ref={this.totpInputRef} prefix={<OneToOneOutlined/>} placeholder="请输入双因素认证APP中显示的授权码"/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
|
@ -51,19 +51,6 @@ const confirm = Modal.confirm;
|
||||
const {Search} = Input;
|
||||
const {Content} = Layout;
|
||||
const {Title, Text} = Typography;
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
breadcrumbName: '资源管理',
|
||||
},
|
||||
{
|
||||
path: 'assets',
|
||||
breadcrumbName: '资产管理',
|
||||
}
|
||||
];
|
||||
|
||||
class Asset extends Component {
|
||||
|
||||
@ -660,18 +647,6 @@ class Asset extends Component {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="资产管理"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
|
||||
subTitle="资产"
|
||||
>
|
||||
</PageHeader>
|
||||
|
||||
<Content key='page-content' className="site-layout-background page-content">
|
||||
<div style={{marginBottom: 20}}>
|
||||
<Row justify="space-around" align="middle" gutter={24}>
|
||||
|
@ -43,16 +43,6 @@ const {Content} = Layout;
|
||||
const {Title, Text} = Typography;
|
||||
const {Search} = Input;
|
||||
const CheckboxGroup = Checkbox.Group;
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
path: 'command',
|
||||
breadcrumbName: '动态指令',
|
||||
}
|
||||
];
|
||||
|
||||
class DynamicCommand extends Component {
|
||||
|
||||
@ -534,18 +524,6 @@ class DynamicCommand extends Component {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="动态指令"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
|
||||
subTitle="批量动态指令执行"
|
||||
>
|
||||
</PageHeader>
|
||||
|
||||
<Content className="site-layout-background page-content">
|
||||
|
||||
<div style={{marginBottom: 20}}>
|
||||
|
@ -10,7 +10,6 @@ import {
|
||||
Layout,
|
||||
Menu,
|
||||
Modal,
|
||||
PageHeader,
|
||||
Row,
|
||||
Select,
|
||||
Space,
|
||||
@ -32,7 +31,6 @@ import {
|
||||
SyncOutlined,
|
||||
UndoOutlined
|
||||
} from '@ant-design/icons';
|
||||
import {itemRender} from "../../utils/utils";
|
||||
|
||||
import {hasPermission, isAdmin} from "../../service/permission";
|
||||
import dayjs from "dayjs";
|
||||
@ -41,16 +39,6 @@ const confirm = Modal.confirm;
|
||||
const {Search} = Input;
|
||||
const {Title, Text} = Typography;
|
||||
const {Content} = Layout;
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
path: 'credentials',
|
||||
breadcrumbName: '授权凭证',
|
||||
}
|
||||
];
|
||||
|
||||
class Credential extends Component {
|
||||
|
||||
@ -483,18 +471,6 @@ class Credential extends Component {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="授权凭证"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
|
||||
subTitle="访问资产的账户、密钥等"
|
||||
>
|
||||
</PageHeader>
|
||||
|
||||
<Content className="site-layout-background page-content">
|
||||
|
||||
<div style={{marginBottom: 20}}>
|
||||
|
@ -9,18 +9,6 @@ import {Area} from '@ant-design/charts';
|
||||
|
||||
import {isAdmin} from "../../service/permission";
|
||||
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
path: 'dashboard',
|
||||
breadcrumbName: '仪表盘',
|
||||
}
|
||||
];
|
||||
|
||||
class Dashboard extends Component {
|
||||
|
||||
state = {
|
||||
@ -79,17 +67,6 @@ class Dashboard extends Component {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="dashboard"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
subTitle="仪表盘"
|
||||
extra={[]}
|
||||
>
|
||||
</PageHeader>
|
||||
|
||||
<div className="page-card">
|
||||
|
||||
|
@ -40,16 +40,6 @@ const confirm = Modal.confirm;
|
||||
const {Content} = Layout;
|
||||
const {Title, Text} = Typography;
|
||||
const {Search} = Input;
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
path: 'job',
|
||||
breadcrumbName: '计划任务',
|
||||
}
|
||||
];
|
||||
|
||||
class Job extends Component {
|
||||
|
||||
@ -441,18 +431,6 @@ class Job extends Component {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="计划任务"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
|
||||
subTitle="计划任务"
|
||||
>
|
||||
</PageHeader>
|
||||
|
||||
<Content className="site-layout-background page-content">
|
||||
|
||||
<div style={{marginBottom: 20}}>
|
||||
|
@ -27,16 +27,6 @@ const confirm = Modal.confirm;
|
||||
const {Content} = Layout;
|
||||
const {Search} = Input;
|
||||
const {Title, Text} = Typography;
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
path: 'loginLog',
|
||||
breadcrumbName: '登录日志',
|
||||
}
|
||||
];
|
||||
|
||||
class LoginLog extends Component {
|
||||
|
||||
@ -280,18 +270,6 @@ class LoginLog extends Component {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="登录日志"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
|
||||
subTitle="只有登录成功的才会保存日志"
|
||||
>
|
||||
</PageHeader>
|
||||
|
||||
<Content className="site-layout-background page-content">
|
||||
<div style={{marginBottom: 20}}>
|
||||
<Row justify="space-around" align="middle" gutter={24}>
|
||||
|
@ -27,16 +27,6 @@ const confirm = Modal.confirm;
|
||||
const {Content} = Layout;
|
||||
const {Title, Text} = Typography;
|
||||
const {Search} = Input;
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
path: 'security',
|
||||
breadcrumbName: '访问安全',
|
||||
}
|
||||
];
|
||||
|
||||
class Security extends Component {
|
||||
|
||||
@ -296,18 +286,6 @@ class Security extends Component {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="访问安全"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
|
||||
subTitle="IP访问规则限制"
|
||||
>
|
||||
</PageHeader>
|
||||
|
||||
<Content className="site-layout-background page-content">
|
||||
|
||||
<div style={{marginBottom: 20}}>
|
||||
|
@ -30,16 +30,6 @@ const confirm = Modal.confirm;
|
||||
const {Content} = Layout;
|
||||
const {Search} = Input;
|
||||
const {Title, Text} = Typography;
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
path: 'offlineSession',
|
||||
breadcrumbName: '离线会话',
|
||||
}
|
||||
];
|
||||
|
||||
class OfflineSession extends Component {
|
||||
|
||||
@ -365,18 +355,6 @@ class OfflineSession extends Component {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="离线会话"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
|
||||
subTitle="离线会话管理"
|
||||
>
|
||||
</PageHeader>
|
||||
|
||||
<Content className="site-layout-background page-content">
|
||||
<div style={{marginBottom: 20}}>
|
||||
<Row justify="space-around" align="middle" gutter={24}>
|
||||
|
@ -31,16 +31,6 @@ const confirm = Modal.confirm;
|
||||
const {Content} = Layout;
|
||||
const {Search} = Input;
|
||||
const {Title, Text} = Typography;
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
path: 'onlineSession',
|
||||
breadcrumbName: '在线会话',
|
||||
}
|
||||
];
|
||||
|
||||
class OnlineSession extends Component {
|
||||
|
||||
@ -335,18 +325,6 @@ class OnlineSession extends Component {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="在线会话"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
|
||||
subTitle="查询实时在线会话"
|
||||
>
|
||||
</PageHeader>
|
||||
|
||||
<Content className="site-layout-background page-content">
|
||||
|
||||
<div style={{marginBottom: 20}}>
|
||||
|
@ -10,17 +10,6 @@ const {Option} = Select;
|
||||
const {TabPane} = Tabs;
|
||||
const {Title} = Typography;
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
path: 'setting',
|
||||
breadcrumbName: '系统设置',
|
||||
}
|
||||
];
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {span: 12},
|
||||
wrapperCol: {span: 12},
|
||||
@ -114,18 +103,6 @@ class Setting extends Component {
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="系统设置"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
|
||||
subTitle="系统设置"
|
||||
>
|
||||
</PageHeader>
|
||||
|
||||
<Content className="site-layout-background page-content">
|
||||
|
||||
<Tabs tabPosition={'left'} onChange={this.handleOnTabChange} tabBarStyle={{width: 150}}>
|
||||
|
@ -8,17 +8,6 @@ import {ExclamationCircleOutlined, ReloadOutlined} from "@ant-design/icons";
|
||||
const {Content} = Layout;
|
||||
const {Meta} = Card;
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
path: 'info',
|
||||
breadcrumbName: '个人中心',
|
||||
}
|
||||
];
|
||||
|
||||
const formItemLayout = {
|
||||
labelCol: {span: 3},
|
||||
wrapperCol: {span: 6},
|
||||
@ -121,17 +110,6 @@ class Info extends Component {
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="个人中心"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
|
||||
subTitle="个人中心"
|
||||
/>
|
||||
|
||||
<Content className="site-layout-background page-content">
|
||||
<h1>修改密码</h1>
|
||||
<Form ref={this.passwordFormRef} name="password" onFinish={this.changePassword}>
|
||||
|
@ -1,87 +0,0 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Col, Dropdown, Menu, message, Popconfirm, Row, Tooltip} from "antd";
|
||||
import request from "../../common/request";
|
||||
import {getCurrentUser} from "../../service/permission";
|
||||
import {GithubOutlined, LogoutOutlined, QuestionCircleOutlined, SolutionOutlined} from "@ant-design/icons";
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
class LayoutHeader extends Component {
|
||||
|
||||
confirm = async (e) => {
|
||||
let result = await request.post('/logout');
|
||||
if (result['code'] !== 1) {
|
||||
message.error(result['message']);
|
||||
} else {
|
||||
message.success('退出登录成功,即将跳转至登录页面。');
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
|
||||
const menu = (
|
||||
<Menu>
|
||||
|
||||
<Menu.Item>
|
||||
<Link to={'/info'}>
|
||||
<SolutionOutlined/>
|
||||
个人中心
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
|
||||
<Menu.Item>
|
||||
<a target='_blank' href='https://github.com/dushixiang/next-terminal'>
|
||||
<GithubOutlined/>
|
||||
点个Star
|
||||
</a>
|
||||
</Menu.Item>
|
||||
|
||||
<Menu.Divider/>
|
||||
|
||||
<Menu.Item>
|
||||
|
||||
<Popconfirm
|
||||
key='login-btn-pop'
|
||||
title="您确定要退出登录吗?"
|
||||
onConfirm={this.confirm}
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
placement="left"
|
||||
>
|
||||
<LogoutOutlined/>
|
||||
退出登录
|
||||
</Popconfirm>
|
||||
</Menu.Item>
|
||||
|
||||
</Menu>
|
||||
);
|
||||
|
||||
return (
|
||||
<div className='layout-header'>
|
||||
<Row justify="space-around" align="middle" gutter={24} style={{height: 48}}>
|
||||
<Col span={4} key={1} style={{height: 48}}> </Col>
|
||||
<Col span={20} key={2} style={{textAlign: 'right'}} className={'layout-header-right'}>
|
||||
|
||||
<div className={'layout-header-right-item'}>
|
||||
<Tooltip placement="bottom" title={'使用帮助'}>
|
||||
<a target='_blank' href='https://github.com/dushixiang/next-terminal/blob/master/docs/faq.md'>
|
||||
<QuestionCircleOutlined/>
|
||||
</a>
|
||||
</Tooltip>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<Dropdown overlay={menu}>
|
||||
<div className='nickname layout-header-right-item'>{getCurrentUser()['nickname']}</div>
|
||||
</Dropdown>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default LayoutHeader;
|
@ -34,7 +34,6 @@ import {
|
||||
SyncOutlined,
|
||||
UndoOutlined
|
||||
} from '@ant-design/icons';
|
||||
import LayoutHeader from "./LayoutHeader";
|
||||
import UserShareAsset from "./UserShareAsset";
|
||||
import {hasPermission} from "../../service/permission";
|
||||
import dayjs from "dayjs";
|
||||
@ -44,17 +43,6 @@ const {Search} = Input;
|
||||
const {Title, Text} = Typography;
|
||||
const {Content} = Layout;
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
path: 'user',
|
||||
breadcrumbName: '用户',
|
||||
}
|
||||
];
|
||||
|
||||
class User extends Component {
|
||||
|
||||
inputRefOfNickname = React.createRef();
|
||||
@ -473,18 +461,6 @@ class User extends Component {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="用户管理"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
|
||||
subTitle="平台用户管理"
|
||||
>
|
||||
</PageHeader>
|
||||
|
||||
<Content className="site-layout-background page-content">
|
||||
<div style={{marginBottom: 20}}>
|
||||
<Row justify="space-around" align="middle" gutter={24}>
|
||||
|
@ -15,17 +15,6 @@ const {Search} = Input;
|
||||
const {Title, Text} = Typography;
|
||||
const {Content} = Layout;
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '',
|
||||
breadcrumbName: '首页',
|
||||
},
|
||||
{
|
||||
path: 'user',
|
||||
breadcrumbName: '用户组',
|
||||
}
|
||||
];
|
||||
|
||||
class UserGroup extends Component {
|
||||
|
||||
inputRefOfName = React.createRef();
|
||||
@ -334,18 +323,6 @@ class UserGroup extends Component {
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageHeader
|
||||
className="site-page-header-ghost-wrapper"
|
||||
title="用户组管理"
|
||||
breadcrumb={{
|
||||
routes: routes,
|
||||
itemRender: itemRender
|
||||
}}
|
||||
|
||||
subTitle="平台用户管理"
|
||||
>
|
||||
</PageHeader>
|
||||
|
||||
<Content className="site-layout-background page-content">
|
||||
<div style={{marginBottom: 20}}>
|
||||
<Row justify="space-around" align="middle" gutter={24}>
|
||||
|
Loading…
Reference in New Issue
Block a user