From d11c26c5ac20f0fe12593fb024b383425f0a4c88 Mon Sep 17 00:00:00 2001 From: vapao Date: Wed, 15 Jan 2020 21:12:16 +0800 Subject: [PATCH] =?UTF-8?q?A=20=E6=B7=BB=E5=8A=A0=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spug_api/apps/notify/views.py | 4 +- spug_web/src/layout/Header.js | 113 ++++++++++++++++++++++---- spug_web/src/layout/layout.module.css | 21 +++++ 3 files changed, 122 insertions(+), 16 deletions(-) diff --git a/spug_api/apps/notify/views.py b/spug_api/apps/notify/views.py index db2df19..9efc41d 100644 --- a/spug_api/apps/notify/views.py +++ b/spug_api/apps/notify/views.py @@ -13,8 +13,8 @@ class NotifyView(View): def patch(self, request): form, error = JsonParser( - Argument('id', type=int, help='参数错误') + Argument('ids', type=list, help='参数错误') ).parse(request.body) if error is None: - Notify.objects.filter(pk=form.id).update(unread=False) + Notify.objects.filter(id__in=form.ids).update(unread=False) return json_response(error=error) diff --git a/spug_web/src/layout/Header.js b/spug_web/src/layout/Header.js index 618e063..a130b81 100644 --- a/spug_web/src/layout/Header.js +++ b/spug_web/src/layout/Header.js @@ -1,29 +1,105 @@ +/** + * Copyright (c) OpenSpug Organization. https://github.com/openspug/spug + * Copyright (c) + * Released under the MIT License. + */ import React from 'react'; -import { Layout, Dropdown, Menu, Icon, Avatar } from 'antd'; +import { Layout, Dropdown, Menu, List, Icon, Badge, Avatar } from 'antd'; import styles from './layout.module.css'; 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: [] + } + } + + componentDidMount() { + this.fetch(); + this.interval = setInterval(this.fetch, 30000) + } + + 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 = () => { history.push('/'); http.get('/api/account/logout/') }; + handleRead = (e, item) => { + e.stopPropagation(); + 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 = ( + + + 个人中心 + + + + 退出登录 + + + ); + + notify = () => ( + + + ( + this.handleRead(e, item)}> + } + title={{item.title}} + description={[ +
{item.content}
, +
{moment(item['created_at']).fromNow()}
+ ]}/> +
+ )}/> + {this.state.notifies.length === 0 && ( +
+ not found +
暂无未读通知
+
+ )} +
this.handleReadAll()}>全部 已读
+
+
+ ); + render() { - const menu = ( - - - 个人中心 - - - - 退出登录 - - - ); + const {notifies, read} = this.state; return (
@@ -31,13 +107,22 @@ export default class extends React.Component {
- + {localStorage.getItem('nickname')}
+
+ + + + + + + +
) diff --git a/spug_web/src/layout/layout.module.css b/spug_web/src/layout/layout.module.css index 3abe405..4619f71 100644 --- a/spug_web/src/layout/layout.module.css +++ b/spug_web/src/layout/layout.module.css @@ -67,6 +67,27 @@ .action:hover { background: rgb(233, 247, 254); } +.notify { + width: 350px; + padding: 0; +} +.notify :global(.ant-dropdown-menu-item:hover) { + background-color: #fff; +} +.notifyItem { + align-items: center; + cursor: pointer; + padding: 12px 24px; +} +.notifyItem:hover { + background-color: rgb(233, 247, 254); +} +.notifyFooter { + line-height: 46px; + text-align: center; + cursor: pointer; + border-top: 1px solid #e8e8e8; +} .footer { margin: 48px 0 24px;