index.jsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import { useState, useEffect } from 'react'
  2. import { List, Avatar, Tag, Skeleton, Divider, message, Typography } from 'antd'
  3. import InfiniteScroll from 'react-infinite-scroll-component'
  4. import { queryMessageList, sendMessage } from '@/services/staff'
  5. import AddMessage from './components/AddMessage'
  6. import consts from '@/consts'
  7. import { useRequest, useIntl, useAccess } from 'umi'
  8. import ws, { CmdType } from '@/utils/ws'
  9. import { useModal } from '@/components/ModalStore'
  10. import MarkDown from 'react-markdown'
  11. const Notification = () => {
  12. const intl = useIntl()
  13. const dispatchModal = useModal()
  14. const { Paragraph } = Typography
  15. const [state, setState] = useState({
  16. loading: false,
  17. list: [],
  18. hasMore: false,
  19. current: 1,
  20. pageSize: 15,
  21. total: 0
  22. })
  23. const initData = async params => {
  24. setState({ ...state, loading: true })
  25. const {
  26. data: { message: list = [], total },
  27. code = -1
  28. } = await queryMessageList({ ...params, pageSize: state.pageSize })
  29. if (code === consts.RET_CODE.SUCCESS) {
  30. setState({
  31. ...state,
  32. list: params?.current === 1 ? list : state.list.concat(list),
  33. total,
  34. loading: false,
  35. hasMore: total > params.current * state.pageSize,
  36. current: params?.current || 1
  37. })
  38. }
  39. }
  40. useEffect(() => {
  41. initData({ current: 1 })
  42. }, [])
  43. const loadMoreData = () => {
  44. initData({ current: state.current + 1 })
  45. }
  46. const { run: trySendMessage } = useRequest(sendMessage, {
  47. manual: true,
  48. onSuccess: result => {
  49. initData({ current: state.current })
  50. ws.sendMessage({
  51. cmd: CmdType.NoticeOrMessage,
  52. ...result
  53. })
  54. },
  55. onError: e => {
  56. message.error(e.message)
  57. }
  58. })
  59. const hasPerm = useAccess()?.validatePermByType('notification_add')
  60. return (
  61. <div className="bg-hex-ffffff rounded-md px-6 pb-6">
  62. <div className="flex justify-between items-center">
  63. <div className="py-4 text-xl">通知中心</div>
  64. {hasPerm ? <AddMessage onConfirm={trySendMessage} /> : null}
  65. </div>
  66. <div
  67. id="scrollableDiv"
  68. className="pr-4"
  69. style={{
  70. height: `calc(100vh - 156px - 1.5rem)`,
  71. overflowY: 'auto'
  72. }}
  73. >
  74. <InfiniteScroll
  75. dataLength={state.total}
  76. next={loadMoreData}
  77. hasMore={state.hasMore}
  78. loader={<Skeleton avatar paragraph={{ rows: 1 }} active />}
  79. endMessage={<Divider plain>别再滚啦,已是尽头</Divider>}
  80. scrollableTarget="scrollableDiv"
  81. >
  82. <List
  83. itemLayout="vertical"
  84. dataSource={state.list}
  85. renderItem={item => (
  86. <List.Item
  87. key={item.id}
  88. extra={
  89. <span width={200} className="mt-1 text-hex-aaa">
  90. {item.createTime}
  91. </span>
  92. }
  93. >
  94. <List.Item.Meta
  95. avatar={<Avatar src={item.avatar} />}
  96. title={
  97. <span
  98. className="cursor-pointer text-primary"
  99. onClick={() => dispatchModal('D_NOTICE_DETAIL', { item })}
  100. >
  101. {item.title}
  102. </span>
  103. }
  104. description={
  105. <div className="mb-1 flex items-center">
  106. <Tag color="purple">
  107. {intl.formatMessage({ id: `component.globalHeader.${item.msgType}` })}
  108. </Tag>
  109. <span className="ml-2px">&apos;发布范围&apos;,</span>
  110. <span className="ml-2">全公司</span>
  111. </div>
  112. }
  113. />
  114. <Paragraph ellipsis={{ rows: 4 }}>
  115. <MarkDown>{item.content}</MarkDown>
  116. </Paragraph>
  117. {/* <div className="mt-1 text-hex-aaa">{item.createTime}</div> */}
  118. </List.Item>
  119. )}
  120. />
  121. </InfiniteScroll>
  122. </div>
  123. </div>
  124. )
  125. }
  126. export default Notification