diff --git a/mock/user.js b/mock/user.js index 86d52e3b22da57ba305c0f6a1994cdc301923492..dd3f240282f8cb93e2ae3da04960124c6e81182e 100644 --- a/mock/user.js +++ b/mock/user.js @@ -36,6 +36,7 @@ export default { }, ], notifyCount: 12, + unreadCount: 11, country: 'China', geographic: { province: { diff --git a/src/components/GlobalHeader/RightContent.js b/src/components/GlobalHeader/RightContent.js index 260f38b1fceba7f6936f064b31f0ee004a8bf4dc..e916fb838a2e3db54beb1fa28e87be14b6d2be08 100644 --- a/src/components/GlobalHeader/RightContent.js +++ b/src/components/GlobalHeader/RightContent.js @@ -40,6 +40,28 @@ export default class GlobalHeaderRight extends PureComponent { return groupBy(newNotices, 'type'); } + getUnreadData = noticeData => { + const unreadMsg = {}; + Object.entries(noticeData).forEach(([key, value]) => { + if (!unreadMsg[key]) { + unreadMsg[key] = 0; + } + if (Array.isArray(value)) { + unreadMsg[key] = value.filter(item => !item.read).length; + } + }); + return unreadMsg; + }; + + changeReadState = clickedItem => { + const { id } = clickedItem; + const { dispatch } = this.props; + dispatch({ + type: 'global/changeNoticeReadState', + payload: id, + }); + }; + render() { const { currentUser, @@ -71,6 +93,7 @@ export default class GlobalHeaderRight extends PureComponent { ); const noticeData = this.getNoticeData(); + const unreadMsg = this.getUnreadData(noticeData); let className = styles.right; if (theme === 'dark') { className = `${styles.right} ${styles.dark}`; @@ -104,9 +127,10 @@ export default class GlobalHeaderRight extends PureComponent { { console.log(item, tabProps); // eslint-disable-line + this.changeReadState(item, tabProps); }} locale={{ emptyText: formatMessage({ id: 'component.noticeIcon.empty' }), @@ -119,6 +143,7 @@ export default class GlobalHeaderRight extends PureComponent { clearClose > { + onClear = name => { const { onClear, clearClose } = this.props; - onClear(name) + onClear(name); if (clearClose) { this.popover.click(); } - } + }; onTabChange = tabType => { const { onTabChange } = this.props; @@ -52,18 +52,18 @@ export default class NoticeIcon extends PureComponent { return null; } const panes = React.Children.map(children, child => { - const title = - child.props.list && child.props.list.length > 0 - ? `${child.props.title} (${child.props.list.length})` - : child.props.title; + const { list, title, name, count } = child.props; + const len = list && list.length ? list.length : 0; + const msgCount = count || count === 0 ? count : len; + const tabTitle = msgCount > 0 ? `${title} (${msgCount})` : title; return ( - + this.onItemClick(item, child.props)} - onClear={() => this.onClear(child.props.name)} - title={child.props.title} + onClear={() => this.onClear(name)} + title={title} locale={locale} /> @@ -107,7 +107,7 @@ export default class NoticeIcon extends PureComponent { popupAlign={popupAlign} onVisibleChange={onPopupVisibleChange} {...popoverProps} - ref={node => { this.popover = ReactDOM.findDOMNode(node)}} // eslint-disable-line + ref={node => (this.popover = ReactDOM.findDOMNode(node))} // eslint-disable-line > {trigger} diff --git a/src/models/global.js b/src/models/global.js index 62f5c6a2d47ddc3e6dd54e8b453af8eadf92a636..34cff599b1072d2df8615f09e634a5e2548de0bf 100644 --- a/src/models/global.js +++ b/src/models/global.js @@ -9,15 +9,21 @@ export default { }, effects: { - *fetchNotices(_, { call, put }) { + *fetchNotices(_, { call, put, select }) { const data = yield call(queryNotices); yield put({ type: 'saveNotices', payload: data, }); + const unreadCount = yield select( + state => state.global.notices.filter(item => !item.read).length + ); yield put({ type: 'user/changeNotifyCount', - payload: data.length, + payload: { + totalCount: data.length, + unreadCount, + }, }); }, *clearNotices({ payload }, { put, select }) { @@ -26,9 +32,37 @@ export default { payload, }); const count = yield select(state => state.global.notices.length); + const unreadCount = yield select( + state => state.global.notices.filter(item => !item.read).length + ); yield put({ type: 'user/changeNotifyCount', - payload: count, + payload: { + totalCount: count, + unreadCount, + }, + }); + }, + *changeNoticeReadState({ payload }, { put, select }) { + const notices = yield select(state => + state.global.notices.map(item => { + const notice = { ...item }; + if (notice.id === payload) { + notice.read = true; + } + return notice; + }) + ); + yield put({ + type: 'saveNotices', + payload: notices, + }); + yield put({ + type: 'user/changeNotifyCount', + payload: { + totalCount: notices.length, + unreadCount: notices.filter(item => !item.read).length, + }, }); }, }, diff --git a/src/models/user.js b/src/models/user.js index 3ceb127ca4b6056ae62c98ecd9e068c918b286da..c84ebbcfc8ed31efef71df8e8fc7d350894a1722 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -43,7 +43,8 @@ export default { ...state, currentUser: { ...state.currentUser, - notifyCount: action.payload, + notifyCount: action.payload.totalCount, + unreadCount: action.payload.unreadCount, }, }; },