'use client' import React, { useState, useEffect } from 'react' import { useForm } from 'react-hook-form' import { z } from 'zod' import { zodResolver } from '@hookform/resolvers/zod' import { trpc } from '@/lib/trpc' import { updateUserSchema, userStatusOptions } from '@/lib/schema/user' import { Input } from '@/components/ui/input' import { Checkbox } from '@/components/ui/checkbox' import { Label } from '@/components/ui/label' import { toast } from 'sonner' import { FormDialog, FormActionBar, FormGridContent, FormCancelAction, FormSubmitAction, type FormFieldConfig } from '@/components/common/form-dialog' import { CheckboxGroup } from '@/components/common/checkbox-group' import { AdvancedSelect, SelectPopover, SelectTrigger, SelectContent, SelectInput, SelectItemList, SelectedName } from '@/components/common/advanced-select' import { useSmartSelectOptions } from '@/hooks/use-smart-select-options' type UpdateUserInput = z.infer const updateUserDefaultValues: UpdateUserInput = { id: '', name: '', status: '', deptCode: '', password: '', roleIds: [], isSuperAdmin: false, } interface UserUpdateDialogProps { userId: string | null isOpen: boolean onClose: () => void onUserUpdated: () => void } export function UserUpdateDialog({ userId, isOpen, onClose, onUserUpdated }: UserUpdateDialogProps) { // react-hook-form 管理更新表单 const updateForm = useForm({ resolver: zodResolver(updateUserSchema), defaultValues: updateUserDefaultValues, }) // 获取用户详情 const { data: user, isLoading: isLoadingUser } = trpc.users.getById.useQuery( { id: userId! }, { enabled: !!userId && isOpen } ) // 获取角色列表和院系列表 const { data: roles } = trpc.users.getRoles.useQuery() const { data: depts } = trpc.common.getDepts.useQuery() const deptOptions = React.useMemo(() => depts?.map(dept => ({ id: dept.code, name: dept.fullName, shortName: dept.name })) || [], [depts]) const { sortedOptions: sortedDeptOptions, logSelection: logDeptSelection } = useSmartSelectOptions({ options: deptOptions, context: 'user.update.dept', scope: 'personal', }) // 更新用户 mutation const updateUserMutation = trpc.users.update.useMutation({ onSuccess: () => { onClose() toast.success('用户更新成功') onUserUpdated() }, onError: (error) => { toast.error(error.message || '更新用户失败') }, }) // 定义字段配置 const formFields: FormFieldConfig[] = React.useMemo(() => [ { name: 'id', label: '用户ID', required: true, render: ({ field }) => ( ), }, { name: 'name', label: '姓名', render: ({ field }) => ( ), }, { name: 'status', label: '状态', render: ({ field }) => ( ), }, { name: 'deptCode', label: '所属院系', render: ({ field }) => ( {logDeptSelection(value); field.onChange(value)}} filterFunction={(option, searchValue) => { const search = searchValue.toLowerCase() return option.id.includes(search) || option.name.toLowerCase().includes(search) || (option.shortName && option.shortName.toLowerCase().includes(search)) }} > ), }, { name: 'password', label: '新密码', render: ({ field }) => ( ), }, { name: 'roleIds', label: '角色', render: ({ field }) => ( ), }, { name: 'isSuperAdmin', label: '超级管理员', render: ({ field }) => (
), }, ], [sortedDeptOptions, logDeptSelection, roles]) // 当用户数据加载完成时,重置表单 useEffect(() => { if (user && isOpen) { const defaultValues: UpdateUserInput = { id: user.id, name: user.name || '', status: user.status || '', deptCode: user.deptCode || '', password: '', // 密码字段默认为空,只有填写时才更新 roleIds: user.roles?.map((role) => role.id) || [], isSuperAdmin: user.isSuperAdmin || false, } updateForm.reset(defaultValues) } }, [user, isOpen, updateForm]) // 当对话框关闭时,清理状态 useEffect(() => { if (!isOpen) { updateForm.reset() } }, [isOpen, updateForm]) const handleSubmit = async (data: UpdateUserInput) => { updateUserMutation.mutate(data) } const handleClose = () => { onClose() } if (!isOpen) return null return ( 更新 ) }