diff --git a/frontend_nuxt/components/HeaderComponent.vue b/frontend_nuxt/components/HeaderComponent.vue index 95534f137..5963eb5bc 100644 --- a/frontend_nuxt/components/HeaderComponent.vue +++ b/frontend_nuxt/components/HeaderComponent.vue @@ -6,10 +6,7 @@ - +
- - {{ messageUnreadCount }} - - + {{ + unreadMessageCount + }}
@@ -106,10 +102,7 @@ const props = defineProps({ const isLogin = computed(() => authState.loggedIn) const isMobile = useIsMobile() -const { count: totalUnreadCount, channelUnreadCount, fetchUnreadCount } = useUnreadCount() -const messageUnreadCount = computed(() => - Math.max(totalUnreadCount.value - channelUnreadCount.value, 0), -) +const { count: unreadMessageCount, fetchUnreadCount } = useUnreadCount() const avatar = ref('') const showSearch = ref(false) const searchDropdown = ref(null) @@ -420,16 +413,6 @@ onMounted(async () => { box-sizing: border-box; } -.messages-unread-dot { - position: absolute; - top: -2px; - right: -4px; - width: 8px; - height: 8px; - border-radius: 50%; - background-color: #ff4d4f; -} - .rss-icon { animation: rss-glow 2s 3; } diff --git a/frontend_nuxt/composables/useUnreadCount.js b/frontend_nuxt/composables/useUnreadCount.js index 58aeecbaa..381b67d6a 100644 --- a/frontend_nuxt/composables/useUnreadCount.js +++ b/frontend_nuxt/composables/useUnreadCount.js @@ -1,123 +1,93 @@ -import { ref, watch } from 'vue' -import { useWebSocket } from './useWebSocket' -import { getToken } from '~/utils/auth' +import { ref, watch, onMounted } from 'vue'; +import { useWebSocket } from './useWebSocket'; +import { getToken } from '~/utils/auth'; -const count = ref(0) -const channelUnreadCount = ref(0) -let isInitialized = false -let wsSubscription = null +const count = ref(0); +let isInitialized = false; +let wsSubscription = null; export function useUnreadCount() { - const config = useRuntimeConfig() - const API_BASE_URL = config.public.apiBaseUrl - const { subscribe, isConnected, connect } = useWebSocket() + const config = useRuntimeConfig(); + const API_BASE_URL = config.public.apiBaseUrl; + const { subscribe, isConnected, connect } = useWebSocket(); - const fetchTotalUnreadCount = async () => { - const token = getToken() + const fetchUnreadCount = async () => { + const token = getToken(); if (!token) { - count.value = 0 - return + count.value = 0; + return; } try { const response = await fetch(`${API_BASE_URL}/api/messages/unread-count`, { headers: { Authorization: `Bearer ${token}` }, - }) + }); if (response.ok) { - const data = await response.json() - count.value = data + const data = await response.json(); + count.value = data; } } catch (error) { - console.error('Failed to fetch unread count:', error) + console.error('Failed to fetch unread count:', error); } - } - - const fetchChannelUnreadCount = async () => { - const token = getToken() - if (!token) { - channelUnreadCount.value = 0 - return - } - try { - const response = await fetch(`${API_BASE_URL}/api/channels`, { - headers: { Authorization: `Bearer ${token}` }, - }) - if (response.ok) { - const channels = await response.json() - channelUnreadCount.value = channels.reduce((sum, ch) => sum + (ch.unreadCount || 0), 0) - } - } catch (error) { - console.error('Failed to fetch channel unread count:', error) - } - } - - const fetchUnreadCount = async () => { - await Promise.all([fetchTotalUnreadCount(), fetchChannelUnreadCount()]) - } + }; const initialize = async () => { - const token = getToken() + const token = getToken(); if (!token) { - count.value = 0 - channelUnreadCount.value = 0 - return + count.value = 0; + return; } // 总是获取最新的未读数量 - fetchUnreadCount() - + fetchUnreadCount(); + // 确保WebSocket连接 if (!isConnected.value) { - connect(token) + connect(token); } - + // 设置WebSocket监听 - await setupWebSocketListener() - } + await setupWebSocketListener(); + }; const setupWebSocketListener = async () => { // 只有在还没有订阅的情况下才设置监听 if (!wsSubscription) { - watch( - isConnected, - (newValue) => { - if (newValue && !wsSubscription) { - const destination = `/user/queue/unread-count` - wsSubscription = subscribe(destination, (message) => { - const unreadCount = parseInt(message.body, 10) - if (!isNaN(unreadCount)) { - count.value = unreadCount - fetchChannelUnreadCount() - } - }) - } - }, - { immediate: true }, - ) + + watch(isConnected, (newValue) => { + if (newValue && !wsSubscription) { + const destination = `/user/queue/unread-count`; + wsSubscription = subscribe(destination, (message) => { + const unreadCount = parseInt(message.body, 10); + if (!isNaN(unreadCount)) { + count.value = unreadCount; + } + }); + } + }, { immediate: true }); } - } + }; // 自动初始化逻辑 - 确保每次调用都能获取到未读数量并设置监听 - const token = getToken() + const token = getToken(); if (token) { if (!isInitialized) { - isInitialized = true - initialize() // 完整初始化,包括WebSocket监听 + isInitialized = true; + initialize(); // 完整初始化,包括WebSocket监听 } else { // 即使已经初始化,也要确保获取最新的未读数量并确保WebSocket监听存在 - fetchUnreadCount() - + fetchUnreadCount(); + // 确保WebSocket连接和监听都存在 if (!isConnected.value) { - connect(token) + connect(token); } - setupWebSocketListener() + setupWebSocketListener(); } } return { count, - channelUnreadCount, fetchUnreadCount, initialize, - } -} + }; +} \ No newline at end of file