import React, { useState, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { clearNotifications, markAllNotificationsAsRead, markNotificationAsRead, setWebSocketConnected, } from '../store/notificationCenter/notificationCenter.slice'; import RequestDetailSlideOver from '../pages/Permissions/components/RequestDetailSlideOver'; import { approvePermissionThunk, rejectPermissionThunk } from '../store/permissions/permissions.thunks'; import { showNotification } from '../store/notification.slice'; import { initWebSocket, acknowledgeNotification, closeWebSocket } from '../services/websocket'; export default function NotificationCenter({ show, onClose }) { const [showAll, setShowAll] = useState(false); const dispatch = useDispatch(); const { notifications, unreadCount, isConnected } = useSelector((state) => state.notificationCenter); const [selectedRequest, setSelectedRequest] = useState(null); const [showSlideOver, setShowSlideOver] = useState(false); const [showResponseInput, setShowResponseInput] = useState(false); const [currentRequestId, setCurrentRequestId] = useState(null); const [isApproving, setIsApproving] = useState(false); const [responseMessage, setResponseMessage] = useState(''); const { isAuthenticated } = useSelector((state) => state.auth); const displayedNotifications = showAll ? notifications : notifications.slice(0, 5); // 初始化WebSocket连接 useEffect(() => { // 只有在用户已登录的情况下才连接WebSocket if (isAuthenticated && !isConnected) { initWebSocket() .then(() => { dispatch(setWebSocketConnected(true)); console.log('Successfully connected to notification WebSocket'); }) .catch((error) => { console.error('Failed to connect to notification WebSocket:', error); dispatch(setWebSocketConnected(false)); // 可以在这里显示连接失败的通知 dispatch( showNotification({ message: '通知服务连接失败,部分功能可能不可用', type: 'warning', }) ); }); } // 组件卸载时关闭WebSocket连接 return () => { if (isConnected) { closeWebSocket(); dispatch(setWebSocketConnected(false)); } }; }, [isAuthenticated, isConnected, dispatch]); const handleClearAll = () => { dispatch(clearNotifications()); }; const handleMarkAllAsRead = () => { dispatch(markAllNotificationsAsRead()); }; const handleMarkAsRead = (notificationId) => { dispatch(markNotificationAsRead(notificationId)); // 同时发送确认消息到服务器 acknowledgeNotification(notificationId); }; const handleViewDetail = (notification) => { // 标记为已读 if (!notification.isRead) { handleMarkAsRead(notification.id); } if (notification.type === 'permission') { setSelectedRequest(notification); setShowSlideOver(true); } }; const handleCloseSlideOver = () => { setShowSlideOver(false); setTimeout(() => { setSelectedRequest(null); }, 300); }; const handleOpenResponseInput = (requestId, approving) => { setCurrentRequestId(requestId); setIsApproving(approving); setShowResponseInput(true); }; const handleCloseResponseInput = () => { setShowResponseInput(false); setCurrentRequestId(null); setResponseMessage(''); }; const handleProcessRequest = () => { if (!currentRequestId) return; const params = { id: currentRequestId, responseMessage, }; if (isApproving) { dispatch(approvePermissionThunk(params)); } else { dispatch(rejectPermissionThunk(params)); } }; if (!show) return null; return ( <>
通知中心
{unreadCount > 0 && {unreadCount}} {isConnected ? ( 已连接 ) : ( 未连接 )}
{displayedNotifications.length === 0 ? (

暂无通知

) : ( displayedNotifications.map((notification) => (
{notification.title}
{notification.time}

{notification.content}

{notification.hasDetail && ( )} {!notification.isRead && ( )}
)) )}
{notifications.length > 5 && (
)}
{/* 使用滑动面板组件 */} handleOpenResponseInput(id, true)} onReject={(id) => handleOpenResponseInput(id, false)} processingId={currentRequestId} approveRejectStatus={showResponseInput ? 'loading' : 'idle'} isApproving={isApproving} /> {/* 回复输入弹窗 */} {showResponseInput && (
{isApproving ? '批准' : '拒绝'}申请
)} ); }