NoticeIconView.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import { Component } from 'react';
  2. import type { ConnectProps } from 'umi';
  3. import { connect } from 'umi';
  4. import { Tag, message } from 'antd';
  5. import groupBy from 'lodash/groupBy';
  6. import moment from 'moment';
  7. import type { NoticeItem } from '@/models/global';
  8. import type { CurrentUser } from '@/models/user';
  9. import type { ConnectState } from '@/models/connect';
  10. import NoticeIcon from '../NoticeIcon';
  11. import styles from './index.less';
  12. export type GlobalHeaderRightProps = {
  13. notices?: NoticeItem[];
  14. currentUser?: CurrentUser;
  15. fetchingNotices?: boolean;
  16. onNoticeVisibleChange?: (visible: boolean) => void;
  17. onNoticeClear?: (tabName?: string) => void;
  18. } & Partial<ConnectProps>;
  19. class GlobalHeaderRight extends Component<GlobalHeaderRightProps> {
  20. componentDidMount() {
  21. const { dispatch } = this.props;
  22. if (dispatch) {
  23. dispatch({
  24. type: 'global/fetchNotices',
  25. });
  26. }
  27. }
  28. changeReadState = (clickedItem: NoticeItem): void => {
  29. const { id } = clickedItem;
  30. const { dispatch } = this.props;
  31. if (dispatch) {
  32. dispatch({
  33. type: 'global/changeNoticeReadState',
  34. payload: id,
  35. });
  36. }
  37. };
  38. handleNoticeClear = (title: string, key: string) => {
  39. const { dispatch } = this.props;
  40. message.success(`${'清空了'} ${title}`);
  41. if (dispatch) {
  42. dispatch({
  43. type: 'global/clearNotices',
  44. payload: key,
  45. });
  46. }
  47. };
  48. getNoticeData = (): Record<string, NoticeItem[]> => {
  49. const { notices = [] } = this.props;
  50. if (!notices || notices.length === 0 || !Array.isArray(notices)) {
  51. return {};
  52. }
  53. const newNotices = notices.map((notice) => {
  54. const newNotice = { ...notice };
  55. if (newNotice.datetime) {
  56. newNotice.datetime = moment(notice.datetime as string).fromNow();
  57. }
  58. if (newNotice.id) {
  59. newNotice.key = newNotice.id;
  60. }
  61. if (newNotice.extra && newNotice.status) {
  62. const color = {
  63. todo: '',
  64. processing: 'blue',
  65. urgent: 'red',
  66. doing: 'gold',
  67. }[newNotice.status];
  68. newNotice.extra = (
  69. <Tag
  70. color={color}
  71. style={{
  72. marginRight: 0,
  73. }}
  74. >
  75. {newNotice.extra}
  76. </Tag>
  77. );
  78. }
  79. return newNotice;
  80. });
  81. return groupBy(newNotices, 'type');
  82. };
  83. getUnreadData = (noticeData: Record<string, NoticeItem[]>) => {
  84. const unreadMsg: Record<string, number> = {};
  85. Object.keys(noticeData).forEach((key) => {
  86. const value = noticeData[key];
  87. if (!unreadMsg[key]) {
  88. unreadMsg[key] = 0;
  89. }
  90. if (Array.isArray(value)) {
  91. unreadMsg[key] = value.filter((item) => !item.read).length;
  92. }
  93. });
  94. return unreadMsg;
  95. };
  96. render() {
  97. const { currentUser, fetchingNotices, onNoticeVisibleChange } = this.props;
  98. const noticeData = this.getNoticeData();
  99. const unreadMsg = this.getUnreadData(noticeData);
  100. return (
  101. <NoticeIcon
  102. className={styles.action}
  103. count={currentUser && currentUser.unreadCount}
  104. onItemClick={(item) => {
  105. this.changeReadState(item as NoticeItem);
  106. }}
  107. loading={fetchingNotices}
  108. clearText="清空"
  109. viewMoreText="查看更多"
  110. onClear={this.handleNoticeClear}
  111. onPopupVisibleChange={onNoticeVisibleChange}
  112. onViewMore={() => message.info('Click on view more')}
  113. clearClose
  114. >
  115. <NoticeIcon.Tab
  116. tabKey="notification"
  117. count={unreadMsg.notification}
  118. list={noticeData.notification}
  119. title="通知"
  120. emptyText="你已查看所有通知"
  121. showViewMore
  122. />
  123. <NoticeIcon.Tab
  124. tabKey="message"
  125. count={unreadMsg.message}
  126. list={noticeData.message}
  127. title="消息"
  128. emptyText="您已读完所有消息"
  129. showViewMore
  130. />
  131. <NoticeIcon.Tab
  132. tabKey="event"
  133. title="待办"
  134. emptyText="你已完成所有待办"
  135. count={unreadMsg.event}
  136. list={noticeData.event}
  137. showViewMore
  138. />
  139. </NoticeIcon>
  140. );
  141. }
  142. }
  143. export default connect(({ user, global, loading }: ConnectState) => ({
  144. currentUser: user.currentUser,
  145. collapsed: global.collapsed,
  146. fetchingMoreNotices: loading.effects['global/fetchMoreNotices'],
  147. fetchingNotices: loading.effects['global/fetchNotices'],
  148. notices: global.notices,
  149. }))(GlobalHeaderRight);