feat: 顶部通知铃铛与站内通知中心
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m7s
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 4m7s
This commit is contained in:
90
src/store/modules/notification.ts
Normal file
90
src/store/modules/notification.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref } from 'vue'
|
||||
import { NotificationService } from '@/api/modules/notification'
|
||||
import type { NotificationSummary } from '@/types/api'
|
||||
|
||||
const getCountValue = (data: number | { count?: number; unread_count?: number } | undefined) => {
|
||||
if (typeof data === 'number') return Math.max(0, data)
|
||||
return Math.max(0, data?.unread_count ?? data?.count ?? 0)
|
||||
}
|
||||
|
||||
export const useNotificationStore = defineStore('notificationStore', () => {
|
||||
const unreadCount = ref(0)
|
||||
const summary = ref<NotificationSummary>({ items: [], categories: {}, total_unread: 0 })
|
||||
const loading = ref(false)
|
||||
|
||||
const refreshUnreadCount = async () => {
|
||||
const response = await NotificationService.getUnreadCount()
|
||||
if (response.code === 0) {
|
||||
unreadCount.value = getCountValue(response.data)
|
||||
}
|
||||
return unreadCount.value
|
||||
}
|
||||
|
||||
const refreshSummary = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const response = await NotificationService.getUnreadSummary()
|
||||
if (response.code === 0 && response.data) {
|
||||
summary.value = {
|
||||
...response.data,
|
||||
items: (response.data.items || []).slice(0, 10)
|
||||
}
|
||||
if (response.data.total_unread !== undefined) {
|
||||
unreadCount.value = Math.max(0, response.data.total_unread)
|
||||
}
|
||||
}
|
||||
await refreshUnreadCount()
|
||||
return summary.value
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const markRead = async (id: number | string) => {
|
||||
const response = await NotificationService.markRead(id)
|
||||
if (response.code === 0) {
|
||||
unreadCount.value = Math.max(0, unreadCount.value - 1)
|
||||
summary.value = {
|
||||
...summary.value,
|
||||
items: summary.value.items.map((item) =>
|
||||
item.id === id ? { ...item, read: true, is_read: true, read_status: 'read' } : item
|
||||
)
|
||||
}
|
||||
await refreshUnreadCount()
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
const markAllRead = async () => {
|
||||
const response = await NotificationService.markAllRead()
|
||||
if (response.code === 0) {
|
||||
unreadCount.value = 0
|
||||
summary.value = {
|
||||
...summary.value,
|
||||
total_unread: 0,
|
||||
categories: Object.fromEntries(
|
||||
Object.keys(summary.value.categories || {}).map((key) => [key, 0])
|
||||
),
|
||||
items: summary.value.items.map((item) => ({
|
||||
...item,
|
||||
read: true,
|
||||
is_read: true,
|
||||
read_status: 'read'
|
||||
}))
|
||||
}
|
||||
await refreshUnreadCount()
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
return {
|
||||
unreadCount,
|
||||
summary,
|
||||
loading,
|
||||
refreshUnreadCount,
|
||||
refreshSummary,
|
||||
markRead,
|
||||
markAllRead
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user