90 lines
2.7 KiB
TypeScript
90 lines
2.7 KiB
TypeScript
|
|
import { pb } from './pocketbase'
|
||
|
|
import type { AppNotification } from '@/types'
|
||
|
|
|
||
|
|
export async function listNotifications(options?: {
|
||
|
|
page?: number
|
||
|
|
limit?: number
|
||
|
|
unreadOnly?: boolean
|
||
|
|
}): Promise<{ items: AppNotification[], total: number }> {
|
||
|
|
const { page = 1, limit = 50, unreadOnly = false } = options || {}
|
||
|
|
const user = pb.authStore.model
|
||
|
|
if (!user) return { items: [], total: 0 }
|
||
|
|
|
||
|
|
let filter = `user="${user.id}"`
|
||
|
|
if (unreadOnly) filter += ' && read=false'
|
||
|
|
|
||
|
|
const result = await pb.collection('notifications').getList(page, limit, {
|
||
|
|
filter,
|
||
|
|
sort: '-created'
|
||
|
|
})
|
||
|
|
return { items: result.items as unknown as AppNotification[], total: result.totalItems }
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function markAsRead(notificationId: string): Promise<AppNotification> {
|
||
|
|
return pb.collection('notifications').update(notificationId, { read: true }) as unknown as Promise<AppNotification>
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function markAllAsRead(): Promise<void> {
|
||
|
|
const user = pb.authStore.model
|
||
|
|
if (!user) return
|
||
|
|
|
||
|
|
let page = 1
|
||
|
|
const batchSize = 50
|
||
|
|
let hasMore = true
|
||
|
|
|
||
|
|
while (hasMore) {
|
||
|
|
const result = await pb.collection('notifications').getList(page, batchSize, {
|
||
|
|
filter: `user="${user.id}" && read=false`
|
||
|
|
})
|
||
|
|
|
||
|
|
if (result.items.length === 0) break
|
||
|
|
|
||
|
|
await Promise.all(
|
||
|
|
result.items.map(item => pb.collection('notifications').update(item.id, { read: true }))
|
||
|
|
)
|
||
|
|
|
||
|
|
hasMore = result.items.length === batchSize && page * batchSize < result.totalItems
|
||
|
|
page++
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function deleteNotification(notificationId: string): Promise<void> {
|
||
|
|
await pb.collection('notifications').delete(notificationId)
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function batchDelete(notificationIds: string[]): Promise<void> {
|
||
|
|
const batchSize = 20
|
||
|
|
for (let i = 0; i < notificationIds.length; i += batchSize) {
|
||
|
|
const batch = notificationIds.slice(i, i + batchSize)
|
||
|
|
await Promise.all(batch.map(id => pb.collection('notifications').delete(id)))
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function createNotification(data: {
|
||
|
|
user: string
|
||
|
|
type: string
|
||
|
|
title: string
|
||
|
|
content?: string
|
||
|
|
relatedId?: string
|
||
|
|
relatedType?: string
|
||
|
|
}): Promise<AppNotification> {
|
||
|
|
return pb.collection('notifications').create(data) as unknown as Promise<AppNotification>
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function subscribeNotifications(
|
||
|
|
callback: (data: { action: string, record: AppNotification }) => void
|
||
|
|
): Promise<() => void> {
|
||
|
|
const user = pb.authStore.model
|
||
|
|
if (!user) return () => {}
|
||
|
|
|
||
|
|
await pb.collection('notifications').subscribe('*', (e) => {
|
||
|
|
if (e.record?.user === user.id) {
|
||
|
|
callback({ action: e.action, record: e.record as unknown as AppNotification })
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
return () => {
|
||
|
|
pb.collection('notifications').unsubscribe('*')
|
||
|
|
}
|
||
|
|
}
|