"use client" import { cn } from "@/lib/utils" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { z } from "zod" import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form" import { useForm } from "react-hook-form" import { zodResolver } from "@hookform/resolvers/zod" import { useRouter } from "next/navigation" import { useEffect, useState, useCallback } from "react" import { gql, useMutation } from "@apollo/client" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { DialogClose, DialogFooter } from "@/components/ui/dialog" import { IconCircleCheckFilled, IconLoader } from "@tabler/icons-react" const CREATE_USER = gql` mutation CreateUser($username: String!, $email: String!, $role: String!, $password: String!) { createUser(input: { username: $username email: $email role: $role password: $password }) { id } } ` const schema = z.object({ username: z.string().min(1, "用户名不能为空"), password: z.string().min(1, "密码不能为空"), role: z.enum(["ADMIN", "USER"]), email: z.email() }) export default function CreateUserForm({ className, ...props }: React.ComponentProps<"form">) { const router = useRouter(); const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const [isGenerating, setIsGenerating] = useState(false) const [createUser, { loading }] = useMutation(CREATE_USER) const form = useForm>({ resolver: zodResolver(schema), defaultValues: { username: "", email: "", password: "", role: "USER" as const, }, }) async function onSubmit(values: z.infer) { try { setIsLoading(true); setError(null); await createUser({ variables: { username: values.username, password: values.password, role: values.role, email: values.email } }); // 重置表单 form.reset(); // 重新生成密码 generateRandomPassword(); } catch (err) { setError(err instanceof Error ? err.message : '创建用户失败,请重试'); } finally { setIsLoading(false); } } // 生成随机密码的函数 const generateRandomPassword = useCallback(() => { setIsGenerating(true) // 模拟生成过程 setTimeout(() => { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*' let password = '' // 确保包含至少一个大写字母、一个小写字母、一个数字和一个特殊字符 password += chars[Math.floor(Math.random() * 26)] // 大写字母 password += chars[26 + Math.floor(Math.random() * 26)] // 小写字母 password += chars[52 + Math.floor(Math.random() * 10)] // 数字 password += chars[62 + Math.floor(Math.random() * 8)] // 特殊字符 // 添加剩余的随机字符,总长度为12 for (let i = 4; i < 12; i++) { password += chars[Math.floor(Math.random() * chars.length)] } // 打乱密码字符顺序 password = password.split('').sort(() => Math.random() - 0.5).join('') form.setValue('password', password) setIsGenerating(false) // toast.success('随机密码已生成') }, 500) }, [form]) useEffect(() => { generateRandomPassword() }, [generateRandomPassword]) return (
{error && (
{error}
)}
( 用户名 * )} />
( 邮箱 * )} />
( 角色 * )} />
(
密码 *
)} />
) }