From d97570b3386855c770db7e6e80292c9dc6d2ad56 Mon Sep 17 00:00:00 2001 From: vapao Date: Tue, 24 Nov 2020 22:51:00 +0800 Subject: [PATCH] ant migrate v4 --- spug_web/src/layout/Footer.js | 36 ++++--- spug_web/src/layout/Header.js | 134 +++++-------------------- spug_web/src/layout/Notification.js | 84 ++++++++++++++++ spug_web/src/layout/Sider.js | 2 +- spug_web/src/layout/index.js | 87 +++++++++------- spug_web/src/layout/layout.module.less | 93 +++++++++++------ spug_web/src/menus.js | 44 -------- spug_web/src/routes.js | 98 ++++++++++++++---- 8 files changed, 316 insertions(+), 262 deletions(-) create mode 100644 spug_web/src/layout/Notification.js delete mode 100644 spug_web/src/menus.js diff --git a/spug_web/src/layout/Footer.js b/spug_web/src/layout/Footer.js index 1960384..a965536 100644 --- a/spug_web/src/layout/Footer.js +++ b/spug_web/src/layout/Footer.js @@ -9,24 +9,22 @@ import { CopyrightOutlined, GithubOutlined } from '@ant-design/icons'; import styles from './layout.module.less'; -export default class extends React.Component { - render() { - return ( - -
-
- 官网 - - 文档 -
-
- Copyright 2020 By OpenSpug -
+export default function () { + return ( + +
+
+ 官网 + + 文档
- - ) - } +
+ Copyright 2020 By OpenSpug +
+
+
+ ) } diff --git a/spug_web/src/layout/Header.js b/spug_web/src/layout/Header.js index 00378e9..628cc6d 100644 --- a/spug_web/src/layout/Header.js +++ b/spug_web/src/layout/Header.js @@ -5,68 +5,22 @@ */ import React from 'react'; import { Link } from 'react-router-dom'; -import { Layout, Dropdown, Menu, List, Badge, Avatar } from 'antd'; -import { - CheckOutlined, - MenuFoldOutlined, - MenuUnfoldOutlined, - UserOutlined, - LogoutOutlined, - NotificationOutlined -} from '@ant-design/icons'; +import { Layout, Dropdown, Menu, Avatar } from 'antd'; +import { MenuFoldOutlined, MenuUnfoldOutlined, UserOutlined, LogoutOutlined } from '@ant-design/icons'; +import Notification from './Notification'; import styles from './layout.module.less'; import http from '../libs/http'; import history from '../libs/history'; import avatar from './avatar.png'; -import moment from 'moment'; -export default class extends React.Component { - constructor(props) { - super(props); - this.inerval = null; - this.state = { - loading: true, - notifies: [], - read: [] - } - } +export default function (props) { - componentDidMount() { - this.fetch(); - this.interval = setInterval(this.fetch, 60000) - } - - componentWillUnmount() { - this.interval && clearInterval(this.interval) - } - - fetch = () => { - this.setState({loading: true}); - http.get('/api/notify/') - .then(res => this.setState({notifies: res, read: []})) - .finally(() => this.setState({loading: false})) - }; - - handleLogout = () => { + function handleLogout() { history.push('/'); http.get('/api/account/logout/') - }; + } - handleRead = (e, item) => { - e.stopPropagation(); - if (this.state.read.indexOf(item.id) === -1) { - this.state.read.push(item.id); - this.setState({read: this.state.read}); - http.patch('/api/notify/', {ids: [item.id]}) - } - }; - - handleReadAll = () => { - const ids = this.state.notifies.map(x => x.id); - this.setState({read: ids}); - http.patch('/api/notify/', {ids}) - }; - menu = ( + const UserMenu = ( @@ -74,66 +28,28 @@ export default class extends React.Component { - + 退出登录 ); - notify = () => ( - - - ( - this.handleRead(e, item)}> - } - title={{item.title}} - description={[ -
{item.content}
, -
{moment(item['created_at']).fromNow()}
- ]}/> -
- )}/> - {this.state.notifies.length !== 0 && ( -
this.handleReadAll()}>全部 已读
- )} -
-
- ); - - render() { - const {notifies, read} = this.state; - return ( - -
-
- {this.props.collapsed ? : } -
-
- - - - {localStorage.getItem('nickname')} - - -
-
- - - - - - - -
+ return ( + +
+
+ {props.collapsed ? : }
- - ) - } +
+ +
+ + + + {localStorage.getItem('nickname')} + + +
+
+ ) } \ No newline at end of file diff --git a/spug_web/src/layout/Notification.js b/spug_web/src/layout/Notification.js new file mode 100644 index 0000000..13eed2d --- /dev/null +++ b/spug_web/src/layout/Notification.js @@ -0,0 +1,84 @@ +import React, { useState, useEffect } from 'react'; +import { Menu, List, Dropdown, Badge } from 'antd'; +import { CheckOutlined, NotificationOutlined } from '@ant-design/icons'; +import { http } from 'libs'; +import moment from 'moment'; +import styles from './layout.module.less'; + +let interval; + +export default function () { + const [loading, setLoading] = useState(false); + const [notifies, setNotifies] = useState([]); + const [reads, setReads] = useState([]); + + useEffect(() => { + fetch(); + interval = setInterval(fetch, 60000); + return () => { + if (interval) clearInterval(interval) + } + }, []) + + function fetch() { + setLoading(true); + http.get('/api/notify/') + .then(res => { + setNotifies(res); + setReads([]) + }) + .finally(() => setLoading(false)) + } + + function handleRead(e, item) { + e.stopPropagation(); + if (reads.indexOf(item.id) === -1) { + reads.push(item.id); + setReads(reads) + http.patch('/api/notify/', {ids: [item.id]}) + } + } + + function handleReadAll() { + const ids = notifies.map(x => x.id); + setReads(ids); + http.patch('/api/notify/', {ids}) + } + + return ( +
+ + + ( + handleRead(e, item)}> + } + title={{item.title}} + description={[ +
{item.content}
, +
{moment(item['created_at']).fromNow()}
+ ]}/> +
+ )}/> + {notifies.length !== 0 && ( +
全部 已读
+ )} +
+ + )}> + + + + + +
+
+ ) +} \ No newline at end of file diff --git a/spug_web/src/layout/Sider.js b/spug_web/src/layout/Sider.js index a5b7677..b0de8b3 100644 --- a/spug_web/src/layout/Sider.js +++ b/spug_web/src/layout/Sider.js @@ -1,7 +1,7 @@ import React from 'react'; import { Layout, Menu } from 'antd'; import { hasPermission, history } from 'libs'; -import styles from './layout.module.css'; +import styles from './layout.module.less'; import menus from '../routes'; import logo from './logo-spug.png'; import logoText from './logo-text.png'; diff --git a/spug_web/src/layout/index.js b/spug_web/src/layout/index.js index c3e1f8d..ebface9 100644 --- a/spug_web/src/layout/index.js +++ b/spug_web/src/layout/index.js @@ -3,47 +3,64 @@ * Copyright (c) * Released under the AGPL-3.0 License. */ -import React from 'react'; +import React, { useState } from 'react'; +import { Switch, Route } from 'react-router-dom'; import { Layout } from 'antd'; import Sider from './Sider'; import Header from './Header'; import Footer from './Footer' -import { Router } from '../libs/router'; -import { updatePermissions} from '../libs'; -import styles from './layout.module.css'; +import routes from '../routes'; +import { updatePermissions, hasPermission } from 'libs'; +import styles from './layout.module.less'; +const Routes = []; -export default class extends React.Component { - constructor(props) { - super(props); - this.initPermissions(); - this.state = { - collapsed: false +function initRoutes(routes) { + for (let route of routes) { + if (route.component) { + if (!route.auth || hasPermission(route.auth)) { + Routes.push() + } + } else if (route.child) { + initRoutes(route.child) } } - - initPermissions() { - const data = localStorage.getItem('permissions'); - const hostPerms = localStorage.getItem('host_perms'); - const isSuper = localStorage.getItem('is_supper') === 'true'; - data && updatePermissions(isSuper, JSON.parse(hostPerms), JSON.parse(data)) - } - - render() { - return ( - - - -
this.setState({collapsed: !this.state.collapsed})} - /> - - -