Files
Henry_Du 4ce4649aaf
Build VoiceHub FPK / build-fpk (push) Failing after 56m5s
Build and Push Docker Image / build-and-push (push) Canceled after 1h9m35s
初次提交
2026-09-06 08:19:02 +08:00

130 lines
3.8 KiB
TypeScript

import { and, count, desc, eq } from 'drizzle-orm'
import { createError, defineEventHandler, getQuery } from 'h3'
import { db } from '~/drizzle/db'
import { notifications, songCollaborators, songs } from '~/drizzle/schema'
export default defineEventHandler(async (event) => {
// 检查用户认证
const user = event.context.user
if (!user) {
throw createError({
statusCode: 401,
message: '需要登录才能获取通知'
})
}
try {
// 获取查询参数
const query = getQuery(event)
const page = Math.max(1, parseInt(query.page as string) || 1)
const limit = Math.min(50, Math.max(1, parseInt(query.limit as string) || 10))
const offset = (page - 1) * limit
// 获取总通知数量
const totalCountResult = await db
.select({ count: count() })
.from(notifications)
.where(eq(notifications.userId, user.id))
const totalCount = totalCountResult[0]?.count || 0
const totalPages = Math.ceil(totalCount / limit)
// 获取分页通知数据
const userNotifications = await db
.select()
.from(notifications)
.where(eq(notifications.userId, user.id))
.orderBy(desc(notifications.createdAt))
.limit(limit)
.offset(offset)
// 丰富通知数据,特别是对于联合投稿邀请
const enrichedNotifications = await Promise.all(
userNotifications.map(async (notification) => {
if (notification.type === 'COLLABORATION_INVITE' && notification.songId) {
// 1. 检查歌曲是否存在
const songExists = await db
.select({ id: songs.id })
.from(songs)
.where(eq(songs.id, notification.songId))
.limit(1)
.then((res) => res.length > 0)
if (!songExists) {
return {
...notification,
handled: true,
status: 'INVALID',
isValid: false,
message: notification.message // 保持原消息,前端会显示已失效
}
}
// 2. 查询对应的邀请状态
const collab = await db
.select()
.from(songCollaborators)
.where(
and(
eq(songCollaborators.songId, notification.songId),
eq(songCollaborators.userId, user.id)
)
)
.limit(1)
if (collab.length > 0) {
return {
...notification,
handled: collab[0].status !== 'PENDING',
status: collab[0].status,
isValid: true,
repliedAt: collab[0].updatedAt || collab[0].createdAt // 假设更新时间为回复时间
}
} else {
// 如果找不到邀请记录,说明可能已经被撤回或删除
return {
...notification,
handled: true,
status: 'INVALID',
isValid: false,
message: notification.message
}
}
}
return {
...notification,
handled: false, // 默认未处理,或者不适用
isValid: true
}
})
)
// 计算未读通知数量
const unreadCountResult = await db
.select({ count: count() })
.from(notifications)
.where(and(eq(notifications.userId, user.id), eq(notifications.read, false)))
const unreadCount = unreadCountResult[0]?.count || 0
return {
notifications: enrichedNotifications,
unreadCount,
pagination: {
currentPage: page,
totalPages,
totalCount,
limit,
hasNextPage: page < totalPages,
hasPrevPage: page > 1
}
}
} catch (err) {
console.error('获取通知失败:', err)
throw createError({
statusCode: 500,
message: '获取通知失败'
})
}
})