提交 f3b116bd authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 dfcefd42
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react'
import { UserOutlined, LogoutOutlined, BellOutlined } from '@ant-design/icons'; import { UserOutlined, LogoutOutlined, BellOutlined } from '@ant-design/icons'
import { Button, Space, Dropdown, Drawer, Row, Col, Image } from 'antd'; import { Button, Space, Dropdown, Drawer, Row, Col, Image } from 'antd'
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom'
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux'
import msgWebsocket from '@/common/websocket/websocket'; import msgWebsocket from '@/common/websocket/websocket'
import { setUserInfo } from '@/store/modules/user'; import { setUserInfo } from '@/store/modules/user'
import { getUserInfo, getMessageList, getMessageCount, setRead, setAllRead } from '../request'; import { getUserInfo, getMessageList, getMessageCount, setRead, setAllRead } from '../request'
import bell from '../../assets/images/bell.png'; import bell from '../../assets/images/bell.png'
import point1 from '../../assets/images/point1.png'; import point1 from '../../assets/images/point1.png'
import quit from '../../assets/images/quit.png'; import quit from '../../assets/images/quit.png'
import slide from '../../assets/images/slide.png'; import slide from '../../assets/images/slide.png'
const items = [ const items = [
{ {
key: 'userinfo', key: 'userinfo',
label: ( label: (
<Button type='link' href='/userinfo'> <Button type="link" href="/userinfo">
个人中心 个人中心
</Button> </Button>
), )
}, }
]; ]
const UserInfo = ({ props, extraSlot }) => { const UserInfo = ({ props, extraSlot }) => {
const navigator = useNavigate(); const navigator = useNavigate()
const dispatch = useDispatch(); const dispatch = useDispatch()
const [showDrawer, setShowDrawer] = useState(false); const [showDrawer, setShowDrawer] = useState(false)
const drawerRef = useRef(null); const drawerRef = useRef(null)
const { userInfo } = useSelector((state) => state.user); const { userInfo } = useSelector(state => state.user)
const [userInfos, setUserInfos] = useState({}); const [userInfos, setUserInfos] = useState({})
const [messageList, setMessageList] = useState([]); const [messageList, setMessageList] = useState([])
const [page, setPage] = useState(1); const [page, setPage] = useState(1)
const [page_size, setpage_size] = useState(10); const [page_size, setpage_size] = useState(10)
const [drawerScrolled, setDrawerScrolled] = useState(false); const [drawerScrolled, setDrawerScrolled] = useState(false)
const [unreadMessagesNum, setUnreadMessagesNum] = useState(0); const [unreadMessagesNum, setUnreadMessagesNum] = useState(0)
const heartbeatInterval = useRef(null); const heartbeatInterval = useRef(null)
const [isReadSet, setIsReadSet] = useState(false); const [isReadSet, setIsReadSet] = useState(false)
const { const { webSocketInit, wsMessage, setWsMessage, reconnect, sendMessage, closeWebSocket, wsReadyState } = msgWebsocket({})
webSocketInit, const [messageListLoaded, setMessageListLoaded] = useState(false) // 新增状态来表示消息列表是否已加载
wsMessage,
setWsMessage,
reconnect,
sendMessage,
closeWebSocket,
wsReadyState,
} = msgWebsocket({});
const [messageListLoaded, setMessageListLoaded] = useState(false); // 新增状态来表示消息列表是否已加载
// 推出登录 // 推出登录
const signOut = () => { const signOut = () => {
localStorage.clear(); localStorage.clear()
navigator('/login'); navigator('/login')
}; }
const getInfo = async () => { const getInfo = async () => {
const data = await getUserInfo(); const data = await getUserInfo()
dispatch(setUserInfo(data)); dispatch(setUserInfo(data))
setUserInfos(data); setUserInfos(data)
}; }
// 所有消息中心 // 所有消息中心
// 未读数 // 未读数
const noneRead = async () => { const noneRead = async () => {
const { num } = await getMessageCount(); const { num } = await getMessageCount()
setUnreadMessagesNum(num); setUnreadMessagesNum(num)
}; }
// 部分已读 // 部分已读
const setMessageReaded = async (id) => { const setMessageReaded = async id => {
setRead({ id }); setRead({ id })
}; }
// 全部已读 // 全部已读
const setMessageALLReaded = async () => { const setMessageALLReaded = async () => {
setAllRead(); setAllRead()
setUnreadMessagesNum(0); setUnreadMessagesNum(0)
}; }
const getMessage = async () => { const getMessage = async () => {
const { list } = await getMessageList({ page: 1, page_size }); const { list } = await getMessageList({ page: 1, page_size })
setMessageList(list); setMessageList(list)
setMessageListLoaded(true); // 设置消息列表已加载的状态为true setMessageListLoaded(true) // 设置消息列表已加载的状态为true
}; }
// 加载下一页消息 // 加载下一页消息
const loadNextPage = async () => { const loadNextPage = async () => {
const nextPage = page + 1; const nextPage = page + 1
const { list } = await getMessageList({ page: nextPage, page_size }); const { list } = await getMessageList({ page: nextPage, page_size })
setPage(nextPage); setPage(nextPage)
setMessageList((prevList) => [...prevList, ...list]); setMessageList(prevList => [...prevList, ...list])
}; }
useEffect(() => { useEffect(() => {
getInfo(); getInfo()
getMessage(); getMessage()
noneRead(); noneRead()
}, []); }, [])
// 设置全部已读,且只调用一次 // 设置全部已读,且只调用一次
useEffect(() => { useEffect(() => {
if (!isReadSet && showDrawer && unreadMessagesNum > 0) { if (!isReadSet && showDrawer && unreadMessagesNum > 0) {
setIsReadSet(true); setIsReadSet(true)
} else if (!showDrawer) { } else if (!showDrawer) {
// noneRead(); // noneRead();
} }
}, [showDrawer, unreadMessagesNum, isReadSet]); }, [showDrawer, unreadMessagesNum, isReadSet])
// 加载消息的websocket // 加载消息的websocket
// useEffect(() => { useEffect(() => {
// if (userInfos.id > 0) { if (userInfos.id > 0) {
// const wsUrl = `${import.meta.env.VITE_API_WEBSOCKET_URL}/ws`; const wsUrl = `${import.meta.env.VITE_API_WEBSOCKET_URL}/ws`
// // 建立websokect链接 // 建立websokect链接
// webSocketInit(wsUrl); webSocketInit(wsUrl)
// // 获取websocket消息 // 获取websocket消息
// if (Object.entries(wsMessage).length > 0) { if (Object.entries(wsMessage).length > 0) {
// console.log('收到消息了'); console.log('收到消息了')
// console.log(wsMessage); console.log(wsMessage)
// // 收到消息一个未读消息 // 收到消息一个未读消息
// setUnreadMessagesNum(unreadMessagesNum + 1); setUnreadMessagesNum(unreadMessagesNum + 1)
// } }
// } }
// }, [userInfos, wsMessage, wsReadyState]); }, [userInfos, wsMessage, wsReadyState])
// 重连websocket // 重连websocket
// useEffect(() => { // useEffect(() => {
...@@ -133,50 +125,47 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -133,50 +125,47 @@ const UserInfo = ({ props, extraSlot }) => {
// return () => clearInterval(heartbeatInterval.current); // return () => clearInterval(heartbeatInterval.current);
// } // }
// }, [userInfos, wsReadyState]); // }, [userInfos, wsReadyState]);
let reconnectTimeoutId; let reconnectTimeoutId
// 重连websocket // 重连websocket
useEffect(() => { useEffect(() => {
// ...其他逻辑不变... // ...其他逻辑不变...
// 重连逻辑修改 // 重连逻辑修改
if (wsReadyState.key === 3) { if (wsReadyState.key === 3) {
clearTimeout(reconnectTimeoutId); clearTimeout(reconnectTimeoutId)
reconnectTimeoutId = setTimeout(reconnect, 3000); // 3秒后重试 reconnectTimeoutId = setTimeout(reconnect, 3000) // 3秒后重试
} }
// 清理函数中取消定时器 // 清理函数中取消定时器
return () => { return () => {
clearTimeout(reconnectTimeoutId); clearTimeout(reconnectTimeoutId)
clearInterval(heartbeatInterval.current); clearInterval(heartbeatInterval.current)
}; }
}, [userInfos, wsReadyState]); }, [userInfos, wsReadyState])
// 滚动消息抽屉翻页 // 滚动消息抽屉翻页
useEffect(() => { useEffect(() => {
if (showDrawer) { if (showDrawer) {
const handleScroll = () => { const handleScroll = () => {
const drawerElement = document.querySelector('.ant-drawer-body'); const drawerElement = document.querySelector('.ant-drawer-body')
if ( if (drawerElement && drawerElement.scrollTop + drawerElement.clientHeight >= drawerElement.scrollHeight) {
drawerElement &&
drawerElement.scrollTop + drawerElement.clientHeight >= drawerElement.scrollHeight
) {
// 在抽屉滚动到底部时加载下一页数据 // 在抽屉滚动到底部时加载下一页数据
loadNextPage(); loadNextPage()
setDrawerScrolled(true); setDrawerScrolled(true)
// 更新滚动位置,使用户能够继续向上滚动 // 更新滚动位置,使用户能够继续向上滚动
drawerElement.scrollTop = drawerElement.scrollHeight - drawerElement.clientHeight; drawerElement.scrollTop = drawerElement.scrollHeight - drawerElement.clientHeight
} else { } else {
setDrawerScrolled(false); setDrawerScrolled(false)
} }
}; }
// 添加滚动事件监听 // 添加滚动事件监听
document.querySelector('.ant-drawer-body').addEventListener('scroll', handleScroll); document.querySelector('.ant-drawer-body').addEventListener('scroll', handleScroll)
// 在组件卸载时移除滚动事件监听 // 在组件卸载时移除滚动事件监听
return () => { return () => {
document.querySelector('.ant-drawer-body').removeEventListener('scroll', handleScroll); document.querySelector('.ant-drawer-body').removeEventListener('scroll', handleScroll)
}; }
} }
}, [drawerScrolled, showDrawer]); }, [drawerScrolled, showDrawer])
// //
// useEffect(() => { // useEffect(() => {
...@@ -220,9 +209,8 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -220,9 +209,8 @@ const UserInfo = ({ props, extraSlot }) => {
position: 'relative', position: 'relative',
width: '16px', width: '16px',
height: '19px', height: '19px',
pointerEvents: 'none', pointerEvents: 'none'
}} }}>
>
<Image src={bell} style={{ width: 14 }} /> <Image src={bell} style={{ width: 14 }} />
<Image <Image
src={point1} src={point1}
...@@ -231,11 +219,11 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -231,11 +219,11 @@ const UserInfo = ({ props, extraSlot }) => {
top: -18, top: -18,
right: -5, right: -5,
width: '12px', width: '12px',
height: '12px', height: '12px'
}} }}
/> />
</span> </span>
); )
} else { } else {
return ( return (
<span <span
...@@ -243,17 +231,16 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -243,17 +231,16 @@ const UserInfo = ({ props, extraSlot }) => {
display: 'inline-block', display: 'inline-block',
width: '16px', width: '16px',
height: '19px', height: '19px',
pointerEvents: 'none', pointerEvents: 'none'
}} }}>
>
<Image src={bell} style={{ width: 14 }} /> <Image src={bell} style={{ width: 14 }} />
</span> </span>
); )
} }
}; }
return ( return (
<div className='header-user'> <div className="header-user">
<Drawer <Drawer
open={showDrawer} open={showDrawer}
// closeIcon={false} // closeIcon={false}
...@@ -264,13 +251,12 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -264,13 +251,12 @@ const UserInfo = ({ props, extraSlot }) => {
width: '22px', width: '22px',
height: '18px', height: '18px',
cursor: 'pointer', cursor: 'pointer',
pointerEvents: 'none', pointerEvents: 'none'
}} }}>
>
<Image <Image
src={slide} src={slide}
style={{ style={{
width: 14, width: 14
}} }}
/> />
</span> </span>
...@@ -280,19 +266,17 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -280,19 +266,17 @@ const UserInfo = ({ props, extraSlot }) => {
style={{ style={{
fontSize: '14px', fontSize: '14px',
color: '#999', color: '#999',
cursor: 'pointer', cursor: 'pointer'
}} }}
draggable='false' draggable="false"
onClick={() => setMessageALLReaded()} onClick={() => setMessageALLReaded()}>
>
全部已读 全部已读
</span> </span>
} }
onClose={() => { onClose={() => {
setShowDrawer(false); setShowDrawer(false)
setMessageListLoaded(false); setMessageListLoaded(false)
}} }}>
>
{/* <div {/* <div
style={{ style={{
display: 'flex', display: 'flex',
...@@ -347,14 +331,13 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -347,14 +331,13 @@ const UserInfo = ({ props, extraSlot }) => {
messageList.map((item, index) => ( messageList.map((item, index) => (
<Row <Row
key={item.id} key={item.id}
className='processItem' className="processItem"
style={{ style={{
borderRadius: 4, borderRadius: 4,
border: '1px solid #E4E4E4', border: '1px solid #E4E4E4',
padding: 15, padding: 15,
marginBottom: 20, marginBottom: 20
}} }}>
>
<Col span={1} style={{ marginRight: 15 }}> <Col span={1} style={{ marginRight: 15 }}>
<Button <Button
style={{ style={{
...@@ -363,7 +346,7 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -363,7 +346,7 @@ const UserInfo = ({ props, extraSlot }) => {
display: 'inline-block', display: 'inline-block',
width: '19px', width: '19px',
height: '22px', height: '22px',
pointerEvents: 'none', pointerEvents: 'none'
}} }}
icon={ icon={
index < unreadMessagesNum && item.status === 0 ? ( index < unreadMessagesNum && item.status === 0 ? (
...@@ -373,9 +356,8 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -373,9 +356,8 @@ const UserInfo = ({ props, extraSlot }) => {
position: 'relative', position: 'relative',
width: '16px', width: '16px',
height: '19px', height: '19px',
pointerEvents: 'none', pointerEvents: 'none'
}} }}>
>
<Image src={bell} style={{ width: 14 }} /> <Image src={bell} style={{ width: 14 }} />
<Image <Image
src={point1} src={point1}
...@@ -384,7 +366,7 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -384,7 +366,7 @@ const UserInfo = ({ props, extraSlot }) => {
top: -18, top: -18,
right: -5, right: -5,
width: '12px', width: '12px',
height: '12px', height: '12px'
}} }}
/> />
</span> </span>
...@@ -394,70 +376,65 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -394,70 +376,65 @@ const UserInfo = ({ props, extraSlot }) => {
display: 'inline-block', display: 'inline-block',
width: '16px', width: '16px',
height: '19px', height: '19px',
pointerEvents: 'none', pointerEvents: 'none'
}} }}>
>
<Image src={bell} style={{ width: 14 }} /> <Image src={bell} style={{ width: 14 }} />
</span> </span>
) )
} }></Button>
></Button>
</Col> </Col>
<Col span={22} className='process'> <Col span={22} className="process">
<div <div
className='head' className="head"
style={{ style={{
display: 'flex', display: 'flex',
justifyContent: 'space-between', justifyContent: 'space-between',
marginBottom: 10, marginBottom: 10
}} }}>
>
<strong>审核通知</strong> <strong>审核通知</strong>
<span <span
className='date' className="date"
style={{ style={{
color: '#999999', color: '#999999',
fontSize: 12, fontSize: 12
}} }}>
>
{item.create_time} {item.create_time}
</span> </span>
</div> </div>
<div <div
className='content' className="content"
onClick={() => { onClick={() => {
item.isRead = true; item.isRead = true
if (item.type === 1) { if (item.type === 1) {
const handleType1 = async () => { const handleType1 = async () => {
await navigator('/books/audit/dataset'); await navigator('/books/audit/dataset')
await setMessageReaded(item.id); await setMessageReaded(item.id)
await getMessage(); await getMessage()
await noneRead(); await noneRead()
}; }
handleType1(); handleType1()
} else if (item.type === 2) { } else if (item.type === 2) {
const handleType2 = async () => { const handleType2 = async () => {
await navigator('/books/sale/dataset'); await navigator('/books/sale/dataset')
await setMessageReaded(item.id); await setMessageReaded(item.id)
await getMessage(); await getMessage()
await noneRead(); await noneRead()
}; }
handleType2(); handleType2()
// setUnreadMessagesNum(0); // setUnreadMessagesNum(0);
} else { } else {
const handleType3 = async () => { const handleType3 = async () => {
await setMessageReaded(item.id); await setMessageReaded(item.id)
await getMessage(); await getMessage()
await noneRead(); await noneRead()
}; }
handleType3(); handleType3()
} }
setShowDrawer(false); setShowDrawer(false)
}} }}
style={{ cursor: 'pointer' }} style={{ cursor: 'pointer' }}>
>
{item.content} {item.content}
</div> </div>
</Col> </Col>
...@@ -467,7 +444,7 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -467,7 +444,7 @@ const UserInfo = ({ props, extraSlot }) => {
<Space> <Space>
<div <div
className='header-user-bell' className="header-user-bell"
style={{ style={{
width: 36, width: 36,
height: 36, height: 36,
...@@ -475,46 +452,36 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -475,46 +452,36 @@ const UserInfo = ({ props, extraSlot }) => {
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
border: 'none', border: 'none',
marginTop: '10px', marginTop: '10px'
}} }}>
>
<Button <Button
style={{ style={{
border: 'none', border: 'none',
background: '#f6f6f6', background: '#f6f6f6'
}} }}
onClick={() => { onClick={() => {
setPage(1); setPage(1)
setShowDrawer(true); setShowDrawer(true)
getMessage(); getMessage()
// setMessageReaded(); // setMessageReaded();
}} }}
icon={renderBellIcon()} icon={renderBellIcon()}></Button>
></Button>
</div> </div>
<Dropdown menu={{ items }} arrow> <Dropdown menu={{ items }} arrow>
<Button <Button
type='link' type="link"
className='logout' className="logout"
onClick={(e) => e.preventDefault()} onClick={e => e.preventDefault()}
style={{ style={{
padding: 10, padding: 10,
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
border: 'none', border: 'none',
marginTop: '10px', marginTop: '10px'
}} }}>
>
<Space> <Space>
{userInfos.pic ? ( {userInfos.pic ? <img src={userInfos.pic} style={{ width: '25px', height: '28px', borderRadius: '50%', marginTop: '6px' }} /> : <UserOutlined />}
<img
src={userInfos.pic}
style={{ width: '25px', height: '28px', borderRadius: '50%', marginTop: '6px' }}
/>
) : (
<UserOutlined />
)}
{/* {<UserOutlined />} */} {/* {<UserOutlined />} */}
{userInfos.real_name} {userInfos.real_name}
</Space> </Space>
...@@ -526,15 +493,14 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -526,15 +493,14 @@ const UserInfo = ({ props, extraSlot }) => {
height: 36, height: 36,
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center'
}} }}>
>
<Button <Button
type='link' type="link"
onClick={signOut} onClick={signOut}
className='logout' className="logout"
style={{ style={{
marginTop: '10px', marginTop: '10px'
}} }}
icon={ icon={
<span <span
...@@ -545,19 +511,17 @@ const UserInfo = ({ props, extraSlot }) => { ...@@ -545,19 +511,17 @@ const UserInfo = ({ props, extraSlot }) => {
pointerEvents: 'none', pointerEvents: 'none',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center'
}} }}>
>
<Image src={quit} style={{ width: 18 }} /> <Image src={quit} style={{ width: 18 }} />
</span> </span>
} }>
>
{/* <LogoutOutlined /> */} {/* <LogoutOutlined /> */}
</Button> </Button>
</div> </div>
</Space> </Space>
</div> </div>
); )
}; }
export default UserInfo; export default UserInfo
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论