index.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. import { useCallback, useEffect, useState } from 'react'
  2. import { Tag, message } from 'antd'
  3. import { groupBy } from 'lodash-es'
  4. import { useModel, history } from 'umi'
  5. import NoticeIcon from './NoticeIcon'
  6. import styles from './index.less'
  7. import dayjs from 'dayjs'
  8. import { queryNoticeList, updateNotice } from '@/services/login'
  9. import consts from '@/consts'
  10. import { useModal } from '@/components/ModalStore'
  11. export type GlobalHeaderRightProps = {
  12. fetchingNotices?: boolean
  13. onNoticeVisibleChange?: (visible: boolean) => void
  14. onNoticeClear?: (tabName?: string) => void
  15. }
  16. const getNoticeData = notices => {
  17. if (!notices || notices.length === 0 || !Array.isArray(notices)) {
  18. return {}
  19. }
  20. const newNotices = notices.map(notice => {
  21. const newNotice = { ...notice }
  22. if (newNotice.datetime) {
  23. newNotice.createTime = dayjs(notice.datetime as string).diff(dayjs(), 'date')
  24. }
  25. if (newNotice.id) {
  26. newNotice.key = newNotice.id
  27. }
  28. if (newNotice.extra && newNotice.status) {
  29. const color = {
  30. todo: '',
  31. processing: 'blue',
  32. urgent: 'red',
  33. doing: 'gold'
  34. }[newNotice.status]
  35. newNotice.extra = (
  36. <Tag
  37. color={color}
  38. style={{
  39. marginRight: 0
  40. }}
  41. >
  42. {newNotice.extra}
  43. </Tag>
  44. ) as any
  45. }
  46. return newNotice
  47. })
  48. return groupBy(newNotices, 'msgType')
  49. }
  50. const getUnreadData = (noticeData: Record<string, API.NoticeIconItem[]>) => {
  51. const unreadMsg: Record<string, number> = {}
  52. Object.keys(noticeData).forEach(key => {
  53. const value = noticeData[key]
  54. if (!unreadMsg[key]) {
  55. unreadMsg[key] = 0
  56. }
  57. if (Array.isArray(value)) {
  58. unreadMsg[key] = value.filter(item => !item.read).length
  59. }
  60. })
  61. return unreadMsg
  62. }
  63. const NoticeIconView = () => {
  64. const { initialState, setInitialState } = useModel('@@initialState')
  65. const { currentUser } = initialState || {}
  66. const [notices, setNotices] = useState([])
  67. const dispatchModal = useModal()
  68. const getNotices = useCallback(async () => {
  69. const { code = -1, data } = await queryNoticeList({ current: 1, pageSize: 50 })
  70. if (code === consts.RET_CODE.SUCCESS) {
  71. setNotices(data.message)
  72. }
  73. }, [])
  74. useEffect(() => {
  75. getNotices()
  76. }, [])
  77. const noticeData = getNoticeData(notices)
  78. const unreadMsg = getUnreadData(noticeData || {})
  79. const changeReadState = async item => {
  80. if (item.isRead) return
  81. const { code = -1 } = await updateNotice({ ids: [item.id] })
  82. if (code === consts.RET_CODE.SUCCESS) {
  83. setNotices(
  84. notices.map(i => {
  85. const notice = { ...i }
  86. if (notice.id === item.id) {
  87. notice.isRead = true
  88. }
  89. return notice
  90. })
  91. )
  92. setInitialState({
  93. ...initialState,
  94. currentUser: { ...currentUser, unreadCount: currentUser.unreadCount - 1 }
  95. })
  96. }
  97. dispatchModal('D_NOTICE_DETAIL', { item })
  98. }
  99. const clearReadState = async (title: string, key: string) => {
  100. if (initialState?.currentUser?.[`${title}HasClear`]) return
  101. const ids = []
  102. setNotices(
  103. notices.map(item => {
  104. const notice = { ...item }
  105. if (notice.msgType === key) {
  106. notice.isRead = true
  107. ids.push(item.id)
  108. }
  109. return notice
  110. })
  111. )
  112. const { code = -1 } = await updateNotice({ ids })
  113. if (code === consts.RET_CODE.SUCCESS) {
  114. message.success(`${'清空了'} ${title}`)
  115. setInitialState({
  116. ...initialState,
  117. currentUser: {
  118. ...currentUser,
  119. unreadCount: currentUser.unreadCount - ids.length,
  120. [`${title}HasClear`]: true
  121. }
  122. })
  123. }
  124. }
  125. return (
  126. <NoticeIcon
  127. className={styles.action}
  128. count={currentUser && currentUser.unreadCount}
  129. onItemClick={item => {
  130. changeReadState(item)
  131. }}
  132. onClear={(title: string, key: string) => clearReadState(title, key)}
  133. loading={false}
  134. clearText="清空"
  135. viewMoreText="查看更多"
  136. onViewMore={() => history.push('/hr/notification')}
  137. clearClose
  138. >
  139. <NoticeIcon.Tab
  140. tabKey="notification"
  141. count={unreadMsg.notification}
  142. list={noticeData.notification}
  143. title="通知"
  144. emptyText="你已查看所有通知"
  145. showViewMore
  146. />
  147. {/* <NoticeIcon.Tab
  148. tabKey="message"
  149. count={unreadMsg.message}
  150. list={noticeData.message}
  151. title="消息"
  152. emptyText="您已读完所有消息"
  153. showViewMore
  154. />
  155. <NoticeIcon.Tab
  156. tabKey="event"
  157. title="待办"
  158. emptyText="你已完成所有待办"
  159. count={unreadMsg.event}
  160. list={noticeData.event}
  161. showViewMore
  162. /> */}
  163. </NoticeIcon>
  164. )
  165. }
  166. export default NoticeIconView