"use server"; import { z } from "zod"; import { eq } from "drizzle-orm"; import { db } from "@/lib/db"; import { users } from "@/lib/db/schema"; import { hashPassword } from "@/lib/auth/password"; const registerSchema = z .object({ name: z.string().min(1, "请输入姓名/昵称").max(100), email: z.string().email("请输入有效的邮箱地址").max(255), password: z.string().min(8, "密码长度至少需要 8 个字符"), confirmPassword: z.string().min(1, "请确认密码"), }) .refine((data: { password: string; confirmPassword: string }) => data.password === data.confirmPassword, { message: "两次输入的密码不一致", path: ["confirmPassword"], }); export type RegisterState = { success?: boolean; error?: string; fieldErrors?: Record; }; export async function registerAction( prevState: RegisterState | null, formData: FormData ): Promise { const rawData = { name: formData.get("name"), email: formData.get("email"), password: formData.get("password"), confirmPassword: formData.get("confirmPassword"), }; const parsed = registerSchema.safeParse(rawData); if (!parsed.success) { return { success: false, fieldErrors: parsed.error.flatten().fieldErrors, }; } const { name, email, password } = parsed.data; const normalizedEmail = email.toLowerCase().trim(); try { // 检查邮箱是否已被注册 const [existing] = await db .select() .from(users) .where(eq(users.email, normalizedEmail)) .limit(1); if (existing) { return { success: false, error: "该邮箱已被注册,请直接登录", }; } // 使用 Argon2 哈希密码 const passwordHash = await hashPassword(password); // 插入新用户 await db.insert(users).values({ name: name.trim(), email: normalizedEmail, passwordHash, isActive: true, }); return { success: true, }; } catch (err) { console.error("Registration error:", err); return { success: false, error: "注册失败,请稍后重试", }; } }