262 lines
6.4 KiB
Vue
Raw Normal View History

<template>
<div class="message-center">
<!-- 顶部Tab导航 -->
<div class="tab-container">
<n-tabs v-model:value="activeTab" type="line" size="large" class="message-tabs" @update:value="handleTabChange">
<n-tab-pane name="notification" tab="即时消息">
<template #tab>
<div class="tab-item">
<span>即时消息</span>
<n-badge :value="notificationCount" :show="notificationCount > 0" class="tab-badge">
</n-badge>
</div>
</template>
</n-tab-pane>
<n-tab-pane name="comment" tab="评论和@">
<template #tab>
<div class="tab-item">
<span>评论和@</span>
<n-badge :value="commentCount" :show="commentCount > 0" class="tab-badge">
</n-badge>
</div>
</template>
</n-tab-pane>
<n-tab-pane name="favorite" tab="赞和收藏">
<template #tab>
<div class="tab-item">
<span>赞和收藏</span>
<n-badge :value="favoriteCount" :show="favoriteCount > 0" class="tab-badge">
</n-badge>
</div>
</template>
</n-tab-pane>
<n-tab-pane name="system" tab="系统消息">
<template #tab>
<div class="tab-item">
<span>系统消息</span>
<n-badge :value="systemCount" :show="systemCount > 0" class="tab-badge">
</n-badge>
</div>
</template>
</n-tab-pane>
</n-tabs>
</div>
<!-- Tab内容区域 -->
<div class="tab-content">
<div v-show="activeTab === 'notification'">
<NotificationMessages />
</div>
<div v-show="activeTab === 'comment'">
<CommentLikes />
</div>
<div v-show="activeTab === 'favorite'">
<FavoriteMessages />
</div>
<div v-show="activeTab === 'system'">
<SystemMessages />
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { NBadge, NTabs, NTabPane, useMessage } from 'naive-ui'
import { ChatApi } from '@/api'
// 导入子组件
import NotificationMessages from './components/NotificationMessages.vue'
import CommentLikes from './components/CommentLikes.vue'
import FavoriteMessages from './components/FavoriteMessages.vue'
import SystemMessages from './components/SystemMessages.vue'
// 响应式数据
const activeTab = ref('notification') // 当前激活的tab
const message = useMessage()
// 各类消息数量(角标显示)
const notificationCount = ref(0) // 即时消息数量
const commentCount = ref(0) // 评论和@数量
const favoriteCount = ref(0) // 赞和收藏数量
const systemCount = ref(0) // 系统消息数量
// 加载状态
const loading = ref(false)
// 缓存和防抖
const cacheTimestamp = ref(0)
const CACHE_DURATION = 30000 // 30秒缓存
let refreshTimer: NodeJS.Timeout | null = null
// 生命周期钩子
onMounted(() => {
// 初始化逻辑
loadMessageCounts()
})
onUnmounted(() => {
// 清理定时器
if (refreshTimer) {
clearTimeout(refreshTimer)
refreshTimer = null
}
})
// 加载各类消息数量
const loadMessageCounts = async (forceRefresh = false) => {
// 检查缓存
const now = Date.now()
if (!forceRefresh && now - cacheTimestamp.value < CACHE_DURATION) {
return
}
loading.value = true
try {
// 并行加载各类消息数量
await Promise.allSettled([
loadNotificationCount(),
loadCommentCount(),
loadFavoriteCount(),
loadSystemCount()
])
cacheTimestamp.value = now
} catch (error) {
console.error('加载消息数量失败:', error)
message.error('加载消息数量失败')
} finally {
loading.value = false
}
}
// 防抖刷新
const debouncedRefresh = () => {
if (refreshTimer) {
clearTimeout(refreshTimer)
}
refreshTimer = setTimeout(() => {
loadMessageCounts(true)
}, 1000)
}
// 加载即时消息数量
const loadNotificationCount = async () => {
try {
const response = await ChatApi.getUnreadCount()
if (response.data) {
notificationCount.value = response.data.total || 0
return
}
} catch (error) {
console.warn('获取未读消息数量失败,尝试备用方案:', error)
}
// 备用方案:通过会话列表计算未读数量
try {
const chatsResponse = await ChatApi.getMyChats()
if (chatsResponse.data?.success) {
notificationCount.value = chatsResponse.data.result.reduce((total: number, chat: any) => {
return total + (chat.unreadCount || 0)
}, 0)
}
} catch (chatError) {
console.error('获取会话列表失败:', chatError)
notificationCount.value = 0
}
}
// 加载评论和@数量
const loadCommentCount = async () => {
try {
// TODO: 实现评论和@消息数量API
commentCount.value = 0
} catch (error) {
console.error('获取评论数量失败:', error)
commentCount.value = 0
}
}
// 加载赞和收藏数量
const loadFavoriteCount = async () => {
try {
// TODO: 实现赞和收藏消息数量API
favoriteCount.value = 0
} catch (error) {
console.error('获取收藏数量失败:', error)
favoriteCount.value = 0
}
}
// 加载系统消息数量
const loadSystemCount = async () => {
try {
// TODO: 实现系统消息数量API
systemCount.value = 0
} catch (error) {
console.error('获取系统消息数量失败:', error)
systemCount.value = 0
}
}
// Tab切换处理
const handleTabChange = (tabName: string) => {
activeTab.value = tabName
// 切换Tab时刷新对应数据
debouncedRefresh()
}
</script>
<style scoped>
.message-center {
padding: 20px;
background-color: #fff;
}
.tab-container {
margin-bottom: 9px;
}
.message-tabs {
--n-tab-text-color: #666;
--n-tab-text-color-active: #1890ff;
--n-bar-color: #1890ff;
}
.tab-item {
position: relative;
display: flex;
align-items: center;
gap: 8px;
}
.tab-badge {
position: relative;
top: -2px;
}
.tab-content {
min-height: 400px;
}
/* 调整badge样式 */
:deep(.n-badge) {
--n-color: #ff4d4f;
--n-text-color: #fff;
--n-font-size: 12px;
}
/* 调整tabs整体样式 */
:deep(.n-tabs .n-tabs-nav .n-tabs-nav-scroll-content) {
gap: 32px;
}
:deep(.n-tabs .n-tabs-tab) {
padding: 12px 0;
font-size: 16px;
font-weight: 500;
}
</style>