import { prisma } from '@/lib/prisma' export type CreditType = 'system_gift' | 'subscription_monthly' | 'user_purchase' export interface CreditSummary { totalBalance: number activeCredits: { id: string amount: number type: CreditType note: string | null expiresAt: Date | null createdAt: Date }[] expiredCredits: { id: string amount: number type: CreditType note: string | null expiresAt: Date | null createdAt: Date }[] } /** * 获取用户的信用额度总览 */ export async function getUserCreditSummary(userId: string): Promise { const now = new Date() // 获取所有信用记录 const allCredits = await prisma.credit.findMany({ where: { userId, isActive: true }, orderBy: { createdAt: 'desc' } }) const activeCredits = [] const expiredCredits = [] let totalBalance = 0 for (const credit of allCredits) { const creditData = { id: credit.id, amount: credit.amount, type: credit.type as CreditType, note: credit.note, expiresAt: credit.expiresAt, createdAt: credit.createdAt } // 检查是否过期 if (credit.expiresAt && credit.expiresAt < now) { expiredCredits.push(creditData) // 标记过期的信用为非激活状态 await prisma.credit.update({ where: { id: credit.id }, data: { isActive: false } }) } else { activeCredits.push(creditData) totalBalance += credit.amount } } return { totalBalance, activeCredits, expiredCredits } } /** * 为新用户添加系统赠送的5USD信用额度(1个月后过期) */ export async function addSystemGiftCredit(userId: string): Promise { const expiresAt = new Date() expiresAt.setMonth(expiresAt.getMonth() + 1) // 1个月后过期 await prisma.credit.create({ data: { userId, amount: 5.0, type: 'system_gift', note: '系统赠送 - 新用户礼包', expiresAt, isActive: true } }) } /** * 为Pro用户添加月度信用额度 */ export async function addMonthlySubscriptionCredit(userId: string): Promise { const expiresAt = new Date() expiresAt.setMonth(expiresAt.getMonth() + 1) // 1个月后过期 await prisma.credit.create({ data: { userId, amount: 20.0, type: 'subscription_monthly', note: 'Pro套餐月度额度', expiresAt, isActive: true } }) } /** * 用户购买信用额度(永久有效) */ export async function addUserPurchaseCredit( userId: string, amount: number, note?: string ): Promise { await prisma.credit.create({ data: { userId, amount, type: 'user_purchase', note: note || '用户充值', expiresAt: null, // 永久有效 isActive: true } }) } /** * 检查Pro用户是否需要刷新月度额度 */ export async function checkAndRefreshProMonthlyCredit(userId: string): Promise { // 获取用户信息 const user = await prisma.user.findUnique({ where: { id: userId }, select: { subscribePlan: true } }) if (!user || user.subscribePlan !== 'pro') { return false } // 查找最近的月度订阅额度 const lastMonthlyCredit = await prisma.credit.findFirst({ where: { userId, type: 'subscription_monthly', isActive: true }, orderBy: { createdAt: 'desc' } }) const now = new Date() // 如果没有月度额度记录,或者最近的已过期,则添加新的 if (!lastMonthlyCredit || (lastMonthlyCredit.expiresAt && lastMonthlyCredit.expiresAt < now)) { await addMonthlySubscriptionCredit(userId) return true } return false } /** * 消费信用额度 */ export async function consumeCredit(userId: string, amount: number): Promise { const creditSummary = await getUserCreditSummary(userId) if (creditSummary.totalBalance < amount) { return false // 余额不足 } // 按优先级消费额度:先消费即将过期的,再消费永久的 const sortedCredits = creditSummary.activeCredits.sort((a, b) => { // 有过期时间的排在前面,没有过期时间的排在后面 if (a.expiresAt && !b.expiresAt) return -1 if (!a.expiresAt && b.expiresAt) return 1 if (a.expiresAt && b.expiresAt) { return a.expiresAt.getTime() - b.expiresAt.getTime() } return a.createdAt.getTime() - b.createdAt.getTime() }) let remainingAmount = amount for (const credit of sortedCredits) { if (remainingAmount <= 0) break const consumeFromThis = Math.min(credit.amount, remainingAmount) const newAmount = credit.amount - consumeFromThis if (newAmount <= 0) { // 这个额度用完了,标记为非激活 await prisma.credit.update({ where: { id: credit.id }, data: { isActive: false } }) } else { // 更新剩余额度 await prisma.credit.update({ where: { id: credit.id }, data: { amount: newAmount } }) } remainingAmount -= consumeFromThis } return true } /** * 获取订阅计划的限制 * @deprecated 请使用 SubscriptionService.getUserPermissions() 替代 */ export function getSubscriptionLimits(plan: string) { // 保留向后兼容性,但建议使用新的订阅服务 switch (plan) { case 'pro': return { promptLimit: 5000, // 修正为正确的 Pro 限制 maxVersionLimit: 10, monthlyCredit: 20.0 } case 'free': default: return { promptLimit: 500, // 修正为正确的免费限制 maxVersionLimit: 3, monthlyCredit: 0.0 // 免费版没有月度额度 } } }