import { useEffect, useState, useCallback } from 'react'; import { useModel, request } from '@umijs/max'; import { notification as antdNotification } from 'antd'; import { Notification, NotificationType } from '@/types'; export const useNotifications = () => { const { initialState } = useModel('@@initialState'); const { stompClient } = useModel('stomp'); const [notifications, setNotifications] = useState([]); const [unreadCount, setUnreadCount] = useState(0); const fetchUnreadNotifications = useCallback(async () => { if (!initialState?.currentUser) return; try { const res = await request('/user-api/message/unread'); setNotifications(res); setUnreadCount(res.length); } catch (error) { console.error('Failed to fetch unread notifications', error); } }, [initialState?.currentUser]); useEffect(() => { fetchUnreadNotifications(); }, [fetchUnreadNotifications]); useEffect(() => { if (initialState?.currentUser && stompClient?.connected) { const subscription = stompClient.subscribe( '/user/queue/notification', (message) => { try { const newNotification: Notification = JSON.parse(message.body); setNotifications((prev) => [newNotification, ...prev]); setUnreadCount((prev) => prev + 1); antdNotification.open({ message: getNotificationTitle(newNotification.type), description: newNotification.content, }); } catch (error) { console.error('Failed to parse notification', error); } } ); return () => { subscription.unsubscribe(); }; } }, [initialState?.currentUser, stompClient]); const markAsRead = useCallback(async (ids: number[]) => { try { await request('/api/user/notifications/read', { method: 'POST', data: ids, }); setNotifications((prev) => prev.map((n) => (ids.includes(n.id) ? { ...n, read: true } : n)) ); setUnreadCount((prev) => prev - ids.length); } catch (error) { console.error('Failed to mark notifications as read', error); } }, []); const getNotificationTitle = (type: NotificationType) => { switch (type) { case NotificationType.FRIEND_REQUEST: return '好友请求'; case NotificationType.FRIEND_ACCEPTED: return '好友请求已接受'; case NotificationType.NEW_COMMENT: return '有新的评论'; case NotificationType.NEW_LIKE: return '有新的点赞'; default: return '系统通知'; } }; return { notifications, unreadCount, markAsRead }; };