import { prisma } from "@/lib/prisma"; import { POINTS_RULES, DAILY_LIMITS, getLevelInfo, getReasonLabel } from "@/lib/level-config"; export { getLevelInfo, getReasonLabel }; async function getTodayEarned(userId: number, reason: string): Promise { const startOfDay = new Date(); startOfDay.setHours(0, 0, 0, 0); const endOfDay = new Date(startOfDay); endOfDay.setDate(endOfDay.getDate() + 1); const result = await prisma.pointsHistory.aggregate({ where: { userId, reason, createdAt: { gte: startOfDay, lt: endOfDay, }, }, _sum: { points: true, }, }); return result._sum.points || 0; } export async function rewardPoints( userId: number, reason: keyof typeof POINTS_RULES, detail?: string, refType?: string, refId?: number ): Promise<{ success: boolean; points: number; message: string }> { const points = POINTS_RULES[reason]; const dailyLimit = DAILY_LIMITS[reason as keyof typeof DAILY_LIMITS]; if (dailyLimit) { const todayEarned = await getTodayEarned(userId, reason); if (todayEarned >= dailyLimit) { return { success: false, points: 0, message: `今日${reason}积分已达上限(${dailyLimit})`, }; } } await prisma.$transaction(async (tx) => { await tx.user.update({ where: { id: userId }, data: { points: { increment: points } }, }); await tx.pointsHistory.create({ data: { userId, points, reason, detail: detail || null, refType: refType || null, refId: refId || null, }, }); }); return { success: true, points, message: `+${points}积分` }; } export async function getUserPointsHistory( userId: number, page = 1, pageSize = 20 ) { const [history, total] = await Promise.all([ prisma.pointsHistory.findMany({ where: { userId }, orderBy: { createdAt: "desc" }, skip: (page - 1) * pageSize, take: pageSize, }), prisma.pointsHistory.count({ where: { userId } }), ]); return { history, total, page, pageSize }; } export async function getUserStats(userId: number) { const user = await prisma.user.findUnique({ where: { id: userId }, select: { points: true, level: true, comments: { select: { id: true } }, forumTopics: { select: { id: true } }, forumPosts: { select: { id: true } }, reviews: { select: { id: true } }, }, }); if (!user) return null; return { points: user.points, level: getLevelInfo(user.points), commentCount: user.comments.length, topicCount: user.forumTopics.length, postCount: user.forumPosts.length, reviewCount: user.reviews.length, }; }