import { NextRequest, NextResponse } from 'next/server' import { getServerSession } from 'next-auth' import { authOptions } from '@/lib/auth' import { prisma } from '@/lib/prisma' import { randomBytes } from 'crypto' import { resolveBaseUrl } from '@/lib/config' // GET - 获取邀请链接列表(仅管理员) export async function GET(req: NextRequest) { try { const session = await getServerSession(authOptions) const isSuperAdmin = (session?.user as any)?.isSuperAdmin if (!session || ((session.user as any)?.role !== 'ADMIN' && !isSuperAdmin)) { return NextResponse.json( { error: '无权限' }, { status: 403 } ) } // 支持分页 const { searchParams } = new URL(req.url) const page = parseInt(searchParams.get('page') || '1', 10) const pageSize = Math.min(parseInt(searchParams.get('pageSize') || '20', 10), 100) // 最大100条 const skip = (page - 1) * pageSize // 并行查询总数和数据 const [total, invitations] = await Promise.all([ prisma.invitation.count(), prisma.invitation.findMany({ orderBy: { createdAt: 'desc' }, skip, take: pageSize, select: { id: true, code: true, createdBy: true, maxUses: true, currentUses: true, expiresAt: true, isActive: true, createdAt: true, // 不返回敏感信息 } }) ]) // 生成完整邀请链接(统一使用集中配置策略) const baseUrl = resolveBaseUrl(req) const invitationsWithUrl = invitations.map(invitation => ({ ...invitation, inviteUrl: `${baseUrl}/register?invite=${invitation.code}`, })) return NextResponse.json({ invitations: invitationsWithUrl, pagination: { page, pageSize, total, totalPages: Math.ceil(total / pageSize) } }) } catch (error) { console.error('[Invitations] GET error:', error) return NextResponse.json( { error: '获取邀请链接失败' }, { status: 500 } ) } } // POST - 创建邀请链接(仅管理员) export async function POST(req: NextRequest) { try { const session = await getServerSession(authOptions) const isSuperAdmin = (session?.user as any)?.isSuperAdmin if (!session || ((session.user as any)?.role !== 'ADMIN' && !isSuperAdmin)) { return NextResponse.json( { error: '无权限' }, { status: 403 } ) } const { maxUses, expiresInDays } = await req.json() const userId = (session.user as any).id // 生成唯一邀请码(8位随机字符串) const code = randomBytes(4).toString('hex').toUpperCase() // 计算过期时间 const expiresAt = expiresInDays ? new Date(Date.now() + expiresInDays * 24 * 60 * 60 * 1000) : null const invitation = await prisma.invitation.create({ data: { code, createdBy: userId, maxUses: maxUses || 1, expiresAt, }, }) // 生成完整邀请链接(统一使用集中配置策略) const baseUrl = resolveBaseUrl(req) const inviteUrl = `${baseUrl}/register?invite=${code}` return NextResponse.json({ ...invitation, inviteUrl, }) } catch (error) { console.error('[Invitations] POST error:', error) return NextResponse.json( { error: '创建邀请链接失败' }, { status: 500 } ) } }