'use client'; import * as React from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; import { Button } from '@nice/ui/components/button'; import { Input } from '@nice/ui/components/input'; import { Textarea } from '@nice/ui/components/textarea'; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from '@nice/ui/components/form'; import { CheckIcon, X as XIcon } from 'lucide-react'; import { useQuery } from '@tanstack/react-query'; import { useTRPC, useUser } from '@fenghuo/client'; import { DeptSelect } from '@/components/selector/dept-select'; import { MultipleRoleSelector } from '@/components/selector/role-select'; import { UserWithRelations, userWithRelationsSelect } from '@fenghuo/common'; import { toast } from '@nice/ui/components/sonner'; import { SystemPermission, useAuth } from '@/components/providers/auth-provider'; import { useEffect } from 'react'; const UserEditFormSchema = z.object({ username: z.string().min(1, { message: '请输入账户名称' }), password: z.string().optional(), confirmPassword: z.string().optional(), roleIds: z.string().array(), organizationId: z.string().optional(), description: z.string().optional(), }).refine((data) => { // 如果设置了密码,则必须确认密码一致(仅对当前用户修改自己密码时) if (data.password && data.password.length > 0) { return data.password === data.confirmPassword; } return true; }, { message: '两次输入的密码不一致', path: ['confirmPassword'], }); type UserEditFormValues = z.infer; // 加载状态组件 function LoadingIndicator() { return (

加载用户信息中...

); } interface UserEditFormProps { userId: string; isCurrentUser?: boolean; } export function UserEditForm({ userId }: UserEditFormProps) { const { update, changePassword } = useUser(); const { user: currentUser } = useAuth(); const isCurrentUser = React.useMemo(() => { return currentUser!.id === userId; }, [currentUser]); // 权限检查 const userPermissions = currentUser?.permissions || []; const isSuperAdmin = userPermissions.includes(SystemPermission.SUPER_ADMIN); const hasUserEditPermission = userPermissions.includes(SystemPermission.USER_EDIT); const canEditUser = isSuperAdmin || hasUserEditPermission || isCurrentUser; // 密码修改权限:超级管理员和有USER_EDIT权限的用户可以直接修改他人密码 const canDirectlyChangePassword = isSuperAdmin || hasUserEditPermission; // 当前用户修改自己密码需要确认密码 const needPasswordConfirmation = isCurrentUser && !canDirectlyChangePassword; const trpc = useTRPC(); // 初始化表单 const form = useForm({ resolver: zodResolver(UserEditFormSchema), mode: 'onChange', // 启用onChange模式以实时检测变化 defaultValues: { username: '', password: '', confirmPassword: '', roleIds: [], organizationId: '', description: '', }, }); // 获取用户数据 const { data: user, isLoading: isLoadingUser } = useQuery({ ...trpc.user.findFirst.queryOptions({ where: { id: userId, }, select: userWithRelationsSelect, }), enabled: !!userId, }) as { data: UserWithRelations | undefined; isLoading: boolean }; // 当用户数据加载完成时,初始化表单 useEffect(() => { if (user) { // 获取用户的所有角色ID const userRoleIds = user.roles?.map((r) => r.id) || []; const organization = user.organization; const initialValues = { username: user.username || '', roleIds: userRoleIds, organizationId: organization?.id || '', description: user.description || '', password: '', confirmPassword: '' }; form.reset(initialValues); } }, [user, form]); // 检测表单是否有变化 const hasChanges = form.formState.isDirty; // 检测密码字段是否有值 const passwordValue = form.watch('password'); const hasPasswordChange = passwordValue && passwordValue.length > 0; // 处理表单提交 const onSubmit = async (values: UserEditFormValues) => { if (!canEditUser) { toast.error('您没有权限编辑此用户'); return; } try { const { roleIds, confirmPassword, ...others } = values; // 如果密码为空,则不更新密码字段 const updateData: any = { ...others, roles: { set: roleIds.map(id => ({ id })) } }; // 只有当密码不为空时才包含密码字段 if (!others.password || others.password.trim() === '') { delete updateData.password; } await update.mutateAsync({ where: { id: userId }, data: updateData }); // 清空密码字段 form.setValue('password', ''); form.setValue('confirmPassword', ''); toast.success('用户信息更新成功'); } catch (error: any) { console.error('更新用户失败:', error); toast.error('保存失败', { description: error?.message || '更新失败,请重试', duration: 5000, }); } }; // 显示加载状态 if (isLoadingUser) { return ; } return (
{/* 基本信息区域 */}

基本信息

{/* 账户名称 */} ( 账户名称 * )} /> {/* 角色选择 */} ( 角色 * )} /> {/* 部门选择 */} ( 所属部门 { const departmentValue = Array.isArray(value) ? value[0] || '' : value; field.onChange(departmentValue); }} placeholder="选择部门" className="w-full" disabled={!canEditUser} /> )} />
{/* 个人简介区域 */}

个人简介

( 简介内容