Browse Source

✨ feat(admin): 重构用户管理页面使用 shadcn/ui 组件

- 将 Ant Design 替换为 shadcn/ui 组件库实现现代化界面
- 集成 react-hook-form 和 zod 进行表单验证
- 使用 lucide-react 图标库替换原有图标
- 添加加载骨架屏提升用户体验
- 优化日期格式化使用 date-fns 和中文本地化
- 实现响应式设计和更好的交互体验
- 重构表单对话框支持创建和编辑两种模式
yourname 6 months ago
parent
commit
79a6cda6a3
1 changed files with 558 additions and 294 deletions
  1. 558 294
      src/client/admin/pages/Users.tsx

+ 558 - 294
src/client/admin/pages/Users.tsx

@@ -1,36 +1,82 @@
 import React, { useState } from 'react';
 import React, { useState } from 'react';
-import {
-  Button, Table, Space, Form, Input, Select, Modal, Card, Typography, Tag, Popconfirm,
-  App
-} from 'antd';
 import { useQuery } from '@tanstack/react-query';
 import { useQuery } from '@tanstack/react-query';
-import dayjs from 'dayjs';
-import { roleClient, userClient } from '@/client/api';
+import { format } from 'date-fns';
+import { zhCN } from 'date-fns/locale';
+import { zodResolver } from '@hookform/resolvers/zod';
+import { useForm } from 'react-hook-form';
+import { toast } from 'sonner';
+import { Plus, Search, Edit, Trash2, Eye } from 'lucide-react';
+
+import { userClient } from '@/client/api';
 import type { InferResponseType, InferRequestType } from 'hono/client';
 import type { InferResponseType, InferRequestType } from 'hono/client';
 import { UserType } from '@/server/modules/users/user.enum';
 import { UserType } from '@/server/modules/users/user.enum';
+import { CreateUserDto, UpdateUserDto } from '@/server/modules/users/user.schema';
+
+import { Button } from '@/client/components/ui/button';
+import { Input } from '@/client/components/ui/input';
+import { Badge } from '@/client/components/ui/badge';
+import { Card, CardContent, CardHeader, CardTitle } from '@/client/components/ui/card';
+import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/client/components/ui/table';
+import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/client/components/ui/dialog';
+import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from '@/client/components/ui/form';
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/client/components/ui/select';
+import { Skeleton } from '@/client/components/ui/skeleton';
+import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from '@/client/components/ui/alert-dialog';
+
+import { DataTablePagination } from '@/client/admin/components/DataTablePagination';
 
 
 type UserListResponse = InferResponseType<typeof userClient.$get, 200>;
 type UserListResponse = InferResponseType<typeof userClient.$get, 200>;
-type RoleListResponse = InferResponseType<typeof roleClient.$get, 200>;
-type CreateRoleRequest = InferRequestType<typeof roleClient.$post>['json'];
 type UserDetailResponse = InferResponseType<typeof userClient[':id']['$get'], 200>;
 type UserDetailResponse = InferResponseType<typeof userClient[':id']['$get'], 200>;
 type CreateUserRequest = InferRequestType<typeof userClient.$post>['json'];
 type CreateUserRequest = InferRequestType<typeof userClient.$post>['json'];
 type UpdateUserRequest = InferRequestType<typeof userClient[':id']['$put']>['json'];
 type UpdateUserRequest = InferRequestType<typeof userClient[':id']['$put']>['json'];
 
 
-const { Title } = Typography;
+// 创建表单schema
+const createFormSchema = CreateUserDto;
+const updateFormSchema = UpdateUserDto;
 
 
 // 用户管理页面
 // 用户管理页面
 export const UsersPage = () => {
 export const UsersPage = () => {
-  const { message } = App.useApp();
   const [searchParams, setSearchParams] = useState({
   const [searchParams, setSearchParams] = useState({
     page: 1,
     page: 1,
     limit: 10,
     limit: 10,
     search: ''
     search: ''
   });
   });
-  const [modalVisible, setModalVisible] = useState(false);
-  const [modalTitle, setModalTitle] = useState('');
+  const [isModalOpen, setIsModalOpen] = useState(false);
+  const [isCreateForm, setIsCreateForm] = useState(true);
   const [editingUser, setEditingUser] = useState<any>(null);
   const [editingUser, setEditingUser] = useState<any>(null);
-  const [form] = Form.useForm();
+  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
+  const [userToDelete, setUserToDelete] = useState<number | null>(null);
 
 
+  // 创建表单
+  const createForm = useForm<CreateUserRequest>({
+    resolver: zodResolver(createFormSchema),
+    defaultValues: {
+      username: '',
+      password: '',
+      email: null,
+      phone: null,
+      nickname: null,
+      name: null,
+      userType: UserType.STUDENT,
+      isDisabled: 0
+    }
+  });
+
+  // 更新表单
+  const updateForm = useForm<UpdateUserRequest>({
+    resolver: zodResolver(updateFormSchema),
+    defaultValues: {
+      username: '',
+      email: null,
+      phone: null,
+      nickname: null,
+      name: null,
+      userType: UserType.STUDENT,
+      isDisabled: 0
+    }
+  });
+
+  // 获取用户列表
   const { data: usersData, isLoading, refetch } = useQuery({
   const { data: usersData, isLoading, refetch } = useQuery({
     queryKey: ['users', searchParams],
     queryKey: ['users', searchParams],
     queryFn: async () => {
     queryFn: async () => {
@@ -49,322 +95,540 @@ export const UsersPage = () => {
   });
   });
 
 
   const users = usersData?.data || [];
   const users = usersData?.data || [];
-  const pagination = {
-    current: searchParams.page,
-    pageSize: searchParams.limit,
-    total: usersData?.pagination?.total || 0
-  };
+  const totalCount = usersData?.pagination?.total || 0;
 
 
   // 处理搜索
   // 处理搜索
-  const handleSearch = (values: any) => {
-    setSearchParams(prev => ({
-      ...prev,
-      search: values.search || '',
-      page: 1
-    }));
+  const handleSearch = (e: React.FormEvent) => {
+    e.preventDefault();
+    setSearchParams(prev => ({ ...prev, page: 1 }));
   };
   };
 
 
-  // 处理分页变化
-  const handleTableChange = (newPagination: any) => {
-    setSearchParams(prev => ({
-      ...prev,
-      page: newPagination.current,
-      limit: newPagination.pageSize
-    }));
-  };
-
-  // 打开创建用户模态框
+  // 打开创建用户对话框
   const showCreateModal = () => {
   const showCreateModal = () => {
-    setModalTitle('创建用户');
+    setIsCreateForm(true);
     setEditingUser(null);
     setEditingUser(null);
-    form.resetFields();
-    setModalVisible(true);
+    createForm.reset();
+    setIsModalOpen(true);
   };
   };
 
 
-  // 打开编辑用户模态
+  // 打开编辑用户对话框
   const showEditModal = (user: any) => {
   const showEditModal = (user: any) => {
-    setModalTitle('编辑用户');
+    setIsCreateForm(false);
     setEditingUser(user);
     setEditingUser(user);
-    form.setFieldsValue({
-      ...user,
-      userType: user.userType || UserType.STUDENT
+    updateForm.reset({
+      username: user.username,
+      email: user.email,
+      phone: user.phone,
+      nickname: user.nickname,
+      name: user.name,
+      userType: user.userType,
+      isDisabled: user.isDisabled
     });
     });
-    setModalVisible(true);
+    setIsModalOpen(true);
   };
   };
 
 
-  // 处理模态框确认
-  const handleModalOk = async () => {
+  // 处理创建用户
+  const handleCreateSubmit = async (data: CreateUserRequest) => {
     try {
     try {
-      const values = await form.validateFields();
-      
-      if (editingUser) {
-        // 编辑用户
-        const res = await userClient[':id']['$put']({
-          param: { id: editingUser.id },
-          json: values
-        });
-        if (res.status !== 200) {
-          throw new Error('更新用户失败');
-        }
-        message.success('用户更新成功');
-      } else {
-        // 创建用户
-        const res = await userClient.$post({
-          json: values
-        });
-        if (res.status !== 201) {
-          throw new Error('创建用户失败');
-        }
-        message.success('用户创建成功');
+      const res = await userClient.$post({ json: data });
+      if (res.status !== 201) {
+        const error = await res.json();
+        throw new Error(error.message || '创建用户失败');
+      }
+      toast.success('用户创建成功');
+      setIsModalOpen(false);
+      createForm.reset();
+      refetch();
+    } catch (error) {
+      toast.error(error instanceof Error ? error.message : '创建失败,请重试');
+    }
+  };
+
+  // 处理更新用户
+  const handleUpdateSubmit = async (data: UpdateUserRequest) => {
+    if (!editingUser) return;
+    
+    try {
+      const res = await userClient[':id']['$put']({
+        param: { id: editingUser.id.toString() },
+        json: data
+      });
+      if (res.status !== 200) {
+        const error = await res.json();
+        throw new Error(error.message || '更新用户失败');
       }
       }
-      
-      setModalVisible(false);
-      form.resetFields();
-      refetch(); // 刷新用户列表
+      toast.success('用户更新成功');
+      setIsModalOpen(false);
+      updateForm.reset();
+      refetch();
     } catch (error) {
     } catch (error) {
-      console.error('表单提交失败:', error);
-      message.error('操作失败,请重试');
+      toast.error(error instanceof Error ? error.message : '更新失败,请重试');
     }
     }
   };
   };
 
 
+  // 打开删除确认对话框
+  const showDeleteDialog = (userId: number) => {
+    setUserToDelete(userId);
+    setDeleteDialogOpen(true);
+  };
+
   // 处理删除用户
   // 处理删除用户
-  const handleDelete = async (id: number) => {
+  const handleDelete = async () => {
+    if (!userToDelete) return;
+    
     try {
     try {
       const res = await userClient[':id']['$delete']({
       const res = await userClient[':id']['$delete']({
-        param: { id }
+        param: { id: userToDelete.toString() }
       });
       });
       if (res.status !== 204) {
       if (res.status !== 204) {
         throw new Error('删除用户失败');
         throw new Error('删除用户失败');
       }
       }
-      message.success('用户删除成功');
-      refetch(); // 刷新用户列表
+      toast.success('用户删除成功');
+      setDeleteDialogOpen(false);
+      setUserToDelete(null);
+      refetch();
     } catch (error) {
     } catch (error) {
-      console.error('删除用户失败:', error);
-      message.error('删除失败,请重试');
+      toast.error('删除失败,请重试');
     }
     }
   };
   };
-  
-  const columns = [
-    {
-      title: '用户名',
-      dataIndex: 'username',
-      key: 'username',
-    },
-    {
-      title: '昵称',
-      dataIndex: 'nickname',
-      key: 'nickname',
-    },
-    {
-      title: '邮箱',
-      dataIndex: 'email',
-      key: 'email',
-    },
-    {
-      title: '真实姓名',
-      dataIndex: 'name',
-      key: 'name',
-    },
-    {
-      title: '用户类型',
-      dataIndex: 'userType',
-      key: 'userType',
-      render: (userType: string) => (
-        <Tag color={userType === UserType.TEACHER ? 'blue' : 'green'}>
-          {userType === UserType.TEACHER ? '老师' : '学生'}
-        </Tag>
-      ),
-    },
-    {
-      title: '角色',
-      dataIndex: 'role',
-      key: 'role',
-      render: (role: string) => (
-        <Tag color={role === 'admin' ? 'red' : 'blue'}>
-          {role === 'admin' ? '管理员' : '普通用户'}
-        </Tag>
-      ),
-    },
-    {
-      title: '创建时间',
-      dataIndex: 'created_at',
-      key: 'created_at',
-      render: (date: string) => dayjs(date).format('YYYY-MM-DD HH:mm:ss'),
-    },
-    {
-      title: '操作',
-      key: 'action',
-      render: (_: any, record: any) => (
-        <Space size="middle">
-          <Button type="link" onClick={() => showEditModal(record)}>
-            编辑
-          </Button>
-          <Popconfirm
-            title="确定要删除此用户吗?"
-            onConfirm={() => handleDelete(record.id)}
-            okText="确定"
-            cancelText="取消"
-          >
-            <Button type="link" danger>
-              删除
-            </Button>
-          </Popconfirm>
-        </Space>
-      ),
-    },
-  ];
-  
+
+  // 加载状态
+  if (isLoading) {
+    return (
+      <div className="space-y-4">
+        <div className="flex justify-between items-center">
+          <Skeleton className="h-8 w-48" />
+          <Skeleton className="h-10 w-32" />
+        </div>
+        
+        <Card>
+          <CardHeader>
+            <Skeleton className="h-6 w-1/4" />
+          </CardHeader>
+          <CardContent>
+            <div className="space-y-3">
+              {[...Array(5)].map((_, i) => (
+                <div key={i} className="flex gap-4">
+                  <Skeleton className="h-10 flex-1" />
+                  <Skeleton className="h-10 flex-1" />
+                  <Skeleton className="h-10 flex-1" />
+                  <Skeleton className="h-10 w-20" />
+                </div>
+              ))}
+            </div>
+          </CardContent>
+        </Card>
+      </div>
+    );
+  }
+
   return (
   return (
-    <div>
-      <div className="mb-6 flex justify-between items-center">
-        <Title level={2}>用户管理</Title>
+    <div className="space-y-4">
+      {/* 页面标题 */}
+      <div className="flex justify-between items-center">
+        <h1 className="text-2xl font-bold">用户管理</h1>
+        <Button onClick={showCreateModal}>
+          <Plus className="mr-2 h-4 w-4" />
+          创建用户
+        </Button>
       </div>
       </div>
-      <Card className="shadow-md transition-all duration-300 hover:shadow-lg">
-        <Form layout="inline" onFinish={handleSearch} style={{ marginBottom: 16, padding: '16px 0' }}>
-          <Form.Item name="search" label="搜索">
-            <Input placeholder="用户名/昵称/邮箱" allowClear />
-          </Form.Item>
-          <Form.Item>
-            <Space>
-              <Button type="primary" htmlType="submit">
-                搜索
-              </Button>
-              <Button type="primary" onClick={showCreateModal}>
-                创建用户
-              </Button>
-            </Space>
-          </Form.Item>
-        </Form>
-
-        <Table
-          columns={columns}
-          dataSource={users}
-          loading={isLoading}
-          rowKey="id"
-          pagination={{
-            ...pagination,
-            showSizeChanger: true,
-            showQuickJumper: true,
-            showTotal: (total) => `共 ${total} 条记录`
-          }}
-          onChange={handleTableChange}
-          bordered
-          scroll={{ x: 'max-content' }}
-          rowClassName={(record, index) => index % 2 === 0 ? 'bg-white' : 'bg-gray-50'}
-        />
+
+      {/* 搜索区域 */}
+      <Card>
+        <CardHeader>
+          <CardTitle>用户列表</CardTitle>
+        </CardHeader>
+        <CardContent>
+          <form onSubmit={handleSearch} className="flex gap-2 mb-4">
+            <div className="relative flex-1 max-w-sm">
+              <Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
+              <Input
+                placeholder="搜索用户名/昵称/邮箱..."
+                value={searchParams.search}
+                onChange={(e) => setSearchParams(prev => ({ ...prev, search: e.target.value }))}
+                className="pl-8"
+              />
+            </div>
+            <Button type="submit" variant="outline">
+              搜索
+            </Button>
+          </form>
+
+          {/* 用户表格 */}
+          <div className="rounded-md border">
+            <Table>
+              <TableHeader>
+                <TableRow>
+                  <TableHead>用户名</TableHead>
+                  <TableHead>昵称</TableHead>
+                  <TableHead>邮箱</TableHead>
+                  <TableHead>真实姓名</TableHead>
+                  <TableHead>用户类型</TableHead>
+                  <TableHead>状态</TableHead>
+                  <TableHead>创建时间</TableHead>
+                  <TableHead className="text-right">操作</TableHead>
+                </TableRow>
+              </TableHeader>
+              <TableBody>
+                {users.map((user) => (
+                  <TableRow key={user.id}>
+                    <TableCell className="font-medium">{user.username}</TableCell>
+                    <TableCell>{user.nickname || '-'}</TableCell>
+                    <TableCell>{user.email || '-'}</TableCell>
+                    <TableCell>{user.name || '-'}</TableCell>
+                    <TableCell>
+                      <Badge 
+                        variant={user.userType === UserType.TEACHER ? 'default' : 'secondary'}
+                        className={user.userType === UserType.TEACHER ? 'bg-blue-100 text-blue-800' : 'bg-green-100 text-green-800'}
+                      >
+                        {user.userType === UserType.TEACHER ? '老师' : '学生'}
+                      </Badge>
+                    </TableCell>
+                    <TableCell>
+                      <Badge 
+                        variant={user.isDisabled === 0 ? 'default' : 'destructive'}
+                        className={user.isDisabled === 0 ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'}
+                      >
+                        {user.isDisabled === 0 ? '启用' : '禁用'}
+                      </Badge>
+                    </TableCell>
+                    <TableCell>
+                      {user.createdAt ? format(new Date(user.createdAt), 'yyyy-MM-dd HH:mm', { locale: zhCN }) : '-'}
+                    </TableCell>
+                    <TableCell className="text-right">
+                      <div className="flex justify-end gap-2">
+                        <Button
+                          variant="ghost"
+                          size="sm"
+                          onClick={() => showEditModal(user)}
+                        >
+                          <Edit className="h-4 w-4" />
+                        </Button>
+                        <Button
+                          variant="ghost"
+                          size="sm"
+                          onClick={() => showDeleteDialog(user.id)}
+                          className="text-destructive hover:text-destructive"
+                        >
+                          <Trash2 className="h-4 w-4" />
+                        </Button>
+                      </div>
+                    </TableCell>
+                  </TableRow>
+                ))}
+              </TableBody>
+            </Table>
+          </div>
+
+          {users.length === 0 && (
+            <div className="text-center py-8">
+              <p className="text-muted-foreground">暂无数据</p>
+            </div>
+          )}
+
+          {/* 分页 */}
+          <DataTablePagination
+            currentPage={searchParams.page}
+            pageSize={searchParams.limit}
+            totalCount={totalCount}
+            onPageChange={(page, limit) => setSearchParams(prev => ({ ...prev, page, limit }))}
+          />
+        </CardContent>
       </Card>
       </Card>
 
 
-      {/* 创建/编辑用户模态框 */}
-      <Modal
-        title={modalTitle}
-        open={modalVisible}
-        onOk={handleModalOk}
-        onCancel={() => {
-          setModalVisible(false);
-          form.resetFields();
-        }}
-        width={600}
-        centered
-        destroyOnClose
-        maskClosable={false}
-      >
-        <Form
-          form={form}
-          layout="vertical"
-          labelCol={{ span: 5 }}
-          wrapperCol={{ span: 19 }}
-        >
-          <Form.Item
-            name="username"
-            label="用户名"
-            required
-            rules={[
-              { required: true, message: '请输入用户名' },
-              { min: 3, message: '用户名至少3个字符' }
-            ]}
-          >
-            <Input placeholder="请输入用户名" />
-          </Form.Item>
-
-          <Form.Item
-            name="nickname"
-            label="昵称"
-            rules={[{ required: false, message: '请输入昵称' }]}
-          >
-            <Input placeholder="请输入昵称" />
-          </Form.Item>
-
-          <Form.Item
-            name="email"
-            label="邮箱"
-            rules={[
-              { required: false, message: '请输入邮箱' },
-              { type: 'email', message: '请输入有效的邮箱地址' }
-            ]}
-          >
-            <Input placeholder="请输入邮箱" />
-          </Form.Item>
-
-          <Form.Item
-            name="phone"
-            label="手机号"
-            rules={[
-              { required: false, message: '请输入手机号' },
-              { pattern: /^1[3-9]\d{9}$/, message: '请输入有效的手机号' }
-            ]}
-          >
-            <Input placeholder="请输入手机号" />
-          </Form.Item>
-
-          <Form.Item
-            name="name"
-            label="真实姓名"
-            rules={[{ required: false, message: '请输入真实姓名' }]}
-          >
-            <Input placeholder="请输入真实姓名" />
-          </Form.Item>
-
-          {!editingUser && (
-            <Form.Item
-              name="password"
-              label="密码"
-              required
-              rules={[
-                { required: true, message: '请输入密码' },
-                { min: 6, message: '密码至少6个字符' }
-              ]}
-            >
-              <Input.Password placeholder="请输入密码" />
-            </Form.Item>
+      {/* 创建/编辑用户对话框 */}
+      <Dialog open={isModalOpen} onOpenChange={setIsModalOpen}>
+        <DialogContent className="sm:max-w-[500px] max-h-[90vh] overflow-y-auto">
+          <DialogHeader>
+            <DialogTitle>{isCreateForm ? '创建用户' : '编辑用户'}</DialogTitle>
+            <DialogDescription>
+              {isCreateForm ? '创建一个新的用户账户' : '编辑现有用户信息'}
+            </DialogDescription>
+          </DialogHeader>
+
+          {isCreateForm ? (
+            <Form {...createForm}>
+              <form onSubmit={createForm.handleSubmit(handleCreateSubmit)} className="space-y-4">
+                <FormField
+                  control={createForm.control}
+                  name="username"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>用户名</FormLabel>
+                      <FormControl>
+                        <Input placeholder="请输入用户名" {...field} />
+                      </FormControl>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={createForm.control}
+                  name="password"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>密码</FormLabel>
+                      <FormControl>
+                        <Input type="password" placeholder="请输入密码" {...field} />
+                      </FormControl>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={createForm.control}
+                  name="nickname"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>昵称</FormLabel>
+                      <FormControl>
+                        <Input placeholder="请输入昵称" {...field} />
+                      </FormControl>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={createForm.control}
+                  name="email"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>邮箱</FormLabel>
+                      <FormControl>
+                        <Input type="email" placeholder="请输入邮箱" {...field} />
+                      </FormControl>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={createForm.control}
+                  name="phone"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>手机号</FormLabel>
+                      <FormControl>
+                        <Input type="tel" placeholder="请输入手机号" {...field} />
+                      </FormControl>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={createForm.control}
+                  name="name"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>真实姓名</FormLabel>
+                      <FormControl>
+                        <Input placeholder="请输入真实姓名" {...field} />
+                      </FormControl>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={createForm.control}
+                  name="userType"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>用户类型</FormLabel>
+                      <Select onValueChange={field.onChange} defaultValue={field.value}>
+                        <FormControl>
+                          <SelectTrigger>
+                            <SelectValue placeholder="请选择用户类型" />
+                          </SelectTrigger>
+                        </FormControl>
+                        <SelectContent>
+                          <SelectItem value={UserType.TEACHER}>老师</SelectItem>
+                          <SelectItem value={UserType.STUDENT}>学生</SelectItem>
+                        </SelectContent>
+                      </Select>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={createForm.control}
+                  name="isDisabled"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>状态</FormLabel>
+                      <Select onValueChange={(value) => field.onChange(parseInt(value))} defaultValue={field.value?.toString()}>
+                        <FormControl>
+                          <SelectTrigger>
+                            <SelectValue placeholder="请选择状态" />
+                          </SelectTrigger>
+                        </FormControl>
+                        <SelectContent>
+                          <SelectItem value="0">启用</SelectItem>
+                          <SelectItem value="1">禁用</SelectItem>
+                        </SelectContent>
+                      </Select>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <DialogFooter>
+                  <Button type="button" variant="outline" onClick={() => setIsModalOpen(false)}>
+                    取消
+                  </Button>
+                  <Button type="submit">创建</Button>
+                </DialogFooter>
+              </form>
+            </Form>
+          ) : (
+            <Form {...updateForm}>
+              <form onSubmit={updateForm.handleSubmit(handleUpdateSubmit)} className="space-y-4">
+                <FormField
+                  control={updateForm.control}
+                  name="username"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>用户名</FormLabel>
+                      <FormControl>
+                        <Input placeholder="请输入用户名" {...field} />
+                      </FormControl>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={updateForm.control}
+                  name="nickname"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>昵称</FormLabel>
+                      <FormControl>
+                        <Input placeholder="请输入昵称" {...field} />
+                      </FormControl>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={updateForm.control}
+                  name="email"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>邮箱</FormLabel>
+                      <FormControl>
+                        <Input type="email" placeholder="请输入邮箱" {...field} />
+                      </FormControl>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={updateForm.control}
+                  name="phone"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>手机号</FormLabel>
+                      <FormControl>
+                        <Input type="tel" placeholder="请输入手机号" {...field} />
+                      </FormControl>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={updateForm.control}
+                  name="name"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>真实姓名</FormLabel>
+                      <FormControl>
+                        <Input placeholder="请输入真实姓名" {...field} />
+                      </FormControl>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={updateForm.control}
+                  name="userType"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>用户类型</FormLabel>
+                      <Select onValueChange={field.onChange} defaultValue={field.value}>
+                        <FormControl>
+                          <SelectTrigger>
+                            <SelectValue placeholder="请选择用户类型" />
+                          </SelectTrigger>
+                        </FormControl>
+                        <SelectContent>
+                          <SelectItem value={UserType.TEACHER}>老师</SelectItem>
+                          <SelectItem value={UserType.STUDENT}>学生</SelectItem>
+                        </SelectContent>
+                      </Select>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <FormField
+                  control={updateForm.control}
+                  name="isDisabled"
+                  render={({ field }) => (
+                    <FormItem>
+                      <FormLabel>状态</FormLabel>
+                      <Select onValueChange={(value) => field.onChange(parseInt(value))} defaultValue={field.value?.toString()}>
+                        <FormControl>
+                          <SelectTrigger>
+                            <SelectValue placeholder="请选择状态" />
+                          </SelectTrigger>
+                        </FormControl>
+                        <SelectContent>
+                          <SelectItem value="0">启用</SelectItem>
+                          <SelectItem value="1">禁用</SelectItem>
+                        </SelectContent>
+                      </Select>
+                      <FormMessage />
+                    </FormItem>
+                  )}
+                />
+
+                <DialogFooter>
+                  <Button type="button" variant="outline" onClick={() => setIsModalOpen(false)}>
+                    取消
+                  </Button>
+                  <Button type="submit">更新</Button>
+                </DialogFooter>
+              </form>
+            </Form>
           )}
           )}
+        </DialogContent>
+      </Dialog>
 
 
-          <Form.Item
-            name="userType"
-            label="用户类型"
-            required
-            rules={[{ required: true, message: '请选择用户类型' }]}
-            initialValue={UserType.STUDENT}
-          >
-            <Select placeholder="请选择用户类型">
-              <Select.Option value={UserType.TEACHER}>老师</Select.Option>
-              <Select.Option value={UserType.STUDENT}>学生</Select.Option>
-            </Select>
-          </Form.Item>
-
-          <Form.Item
-            name="isDisabled"
-            label="状态"
-            required
-            rules={[{ required: true, message: '请选择状态' }]}
-            initialValue={0}
-          >
-            <Select placeholder="请选择状态">
-              <Select.Option value={0}>启用</Select.Option>
-              <Select.Option value={1}>禁用</Select.Option>
-            </Select>
-          </Form.Item>
-        </Form>
-      </Modal>
+      {/* 删除确认对话框 */}
+      <AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
+        <AlertDialogContent>
+          <AlertDialogHeader>
+            <AlertDialogTitle>确认删除</AlertDialogTitle>
+            <AlertDialogDescription>
+              确定要删除这个用户吗?此操作无法撤销。
+            </AlertDialogDescription>
+          </AlertDialogHeader>
+          <AlertDialogFooter>
+            <AlertDialogCancel>取消</AlertDialogCancel>
+            <AlertDialogAction onClick={handleDelete}>删除</AlertDialogAction>
+          </AlertDialogFooter>
+        </AlertDialogContent>
+      </AlertDialog>
     </div>
     </div>
   );
   );
 };
 };