import { NextRequest, NextResponse } from "next/server" import { getServerSession } from "next-auth" import { authOptions } from "@/lib/auth" import { prisma } from "@/lib/prisma" import { hash } from "bcryptjs" import { z } from "zod" import { sendInvitationEmail } from "@/lib/mail" const inviteSchema = z.object({ email: z.string().email("请输入有效的邮箱地址"), role: z.enum(["EDITOR", "VIEWER"], { errorMap: () => ({ message: "请选择有效的角色" }), }), password: z.string().min(6, "密码至少需要6位").optional(), }) // 邀请协作者 export async function POST( req: NextRequest, { params }: { params: Promise<{ treeId: string }> } ) { try { const session = await getServerSession(authOptions) if (!session?.user?.id) { return NextResponse.json({ error: "未授权" }, { status: 401 }) } const { treeId } = await params const body = await req.json() const { email, role, password } = inviteSchema.parse(body) // 1. 检查权限 const tree = await prisma.familyTree.findFirst({ where: { id: treeId, ownerId: session.user.id } }) if (!tree) { return NextResponse.json({ error: "家族树不存在或无权邀请" }, { status: 404 }) } // 2. 检查目标用户是否存在 let user = await prisma.user.findUnique({ where: { email } }) let isNewUser = false // 3. 如果用户不存在,创建新用户 if (!user) { if (!password) { return NextResponse.json({ error: "新用户必须设置初始密码" }, { status: 400 }) } const hashedPassword = await hash(password, 12) user = await prisma.user.create({ data: { email, password: hashedPassword, name: email.split('@')[0], // 使用邮箱前缀作为默认用户名 } }) isNewUser = true } // 4. 检查是否已经是协作者或所有者 if (user.id === tree.ownerId) { return NextResponse.json({ error: "不能邀请自己" }, { status: 400 }) } const existingCollaborator = await prisma.treeCollaborator.findUnique({ where: { treeId_userId: { treeId, userId: user.id } } }) if (existingCollaborator) { // 如果已存在,更新角色 await prisma.treeCollaborator.update({ where: { id: existingCollaborator.id }, data: { role } }) return NextResponse.json({ message: "用户已是协作者,角色已更新", isNewUser: false }) } // 5. 添加协作者 await prisma.treeCollaborator.create({ data: { treeId, userId: user.id, role, invitedBy: session.user.id } }) // 6. 发送邀请邮件 try { await sendInvitationEmail( email, session.user.name || session.user.email || "用户", tree.name, role, isNewUser ? password : undefined ) } catch (emailError) { console.error("发送邀请邮件失败:", emailError) // 邮件发送失败不影响邀请结果,但记录日志 } return NextResponse.json({ message: isNewUser ? "新用户已创建并添加为协作者,邮件已发送" : "用户已添加为协作者,邮件已发送", isNewUser }, { status: 201 }) } catch (error) { if (error instanceof z.ZodError) { return NextResponse.json( { error: error.errors[0].message }, { status: 400 } ) } console.error("邀请协作者失败:", error) return NextResponse.json( { error: "邀请协作者失败" }, { status: 500 } ) } }