import { useCallback, useEffect, useRef, useState } from 'react'; import { Badge, Divider, List, Popover, Button, Empty, Typography } from 'antd'; import { BellOutlined } from '@ant-design/icons'; import { useNavigate } from 'react-router-dom'; import { useMessageStore } from '../stores/message'; import { useThemeMode } from '../hooks/useThemeMode'; import { actionInboxApi, type ActionItem } from '../api/health/actionInbox'; const { Text } = Typography; export default function NotificationPanel() { const navigate = useNavigate(); const unreadCount = useMessageStore((s) => s.unreadCount); const recentMessages = useMessageStore((s) => s.recentMessages); const markAsRead = useMessageStore((s) => s.markAsRead); const isDark = useThemeMode(); const initializedRef = useRef(false); const [pendingActions, setPendingActions] = useState([]); const fetchPendingActions = useCallback(async () => { try { const resp = await actionInboxApi.list({ status: 'pending', page_size: 3 }); setPendingActions(resp.data); } catch { // 静默失败,不影响通知面板 } }, []); useEffect(() => { if (initializedRef.current) return; initializedRef.current = true; const { fetchUnreadCount, fetchRecentMessages, connectSSE } = useMessageStore.getState(); fetchUnreadCount(); fetchRecentMessages(); fetchPendingActions(); const disconnectSSE = connectSSE(); const interval = setInterval(() => { fetchUnreadCount(); fetchRecentMessages(); fetchPendingActions(); }, 60000); return () => { clearInterval(interval); disconnectSSE(); initializedRef.current = false; }; }, [fetchPendingActions]); const totalBadge = unreadCount + pendingActions.length; const content = (
通知 {unreadCount > 0 && ( )}
{recentMessages.length === 0 ? ( ) : ( ( { if (!item.is_read) { markAsRead(item.id); } navigate('/messages'); }} onMouseEnter={(e) => { if (item.is_read) { e.currentTarget.style.background = isDark ? '#0f172a' : '#f1f5f9'; } }} onMouseLeave={(e) => { if (item.is_read) { e.currentTarget.style.background = 'transparent'; } }} >
{item.title} {!item.is_read && ( )}
{item.body}
)} /> )} {recentMessages.length > 0 && (
)} {/* 待办预览区域 */}
待办事项
{pendingActions.length === 0 ? ( 暂无待办 ) : ( ( navigate('/health/action-inbox')} > {item.title}} description={ {item.patient_name} } /> )} /> )}
); return (
{ e.currentTarget.style.background = isDark ? '#0f172a' : '#f8fafc'; }} onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; }} >
); }