index.tsx 3.8 KB

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