import React, { useEffect, useState } from 'react'; import { Button, Modal, Form, Input, Space, message, Switch, TreeSelect, Select, Tag, Dropdown } from 'antd'; import { PlusOutlined, EditOutlined, DeleteOutlined, KeyOutlined, TeamOutlined, MoreOutlined } from '@ant-design/icons'; import type { MenuProps } from 'antd'; import { useTableData } from '@/hooks/useTableData'; import * as service from './service'; import type { UserResponse, UserRequest, UserQuery, Role } from './types'; import type { DepartmentResponse } from '../Department/types'; import { getDepartmentTree } from '../Department/service'; import { Table, TableHeader, TableBody, TableHead, TableRow, TableCell, } from "@/components/ui/table"; interface Column { accessorKey?: keyof UserResponse; id?: string; header: string; size: number; cell?: (props: { row: { original: UserResponse } }) => React.ReactNode; } interface TreeNode { title: string; value: number; children?: TreeNode[]; } const UserPage: React.FC = () => { const [form] = Form.useForm(); const [passwordForm] = Form.useForm(); const [modalVisible, setModalVisible] = useState(false); const [resetPasswordModalVisible, setResetPasswordModalVisible] = useState(false); const [editingUser, setEditingUser] = useState(null); const [departments, setDepartments] = useState([]); const [roleModalVisible, setRoleModalVisible] = useState(false); const [selectedUser, setSelectedUser] = useState(null); const [selectedRoles, setSelectedRoles] = useState([]); const [allRoles, setAllRoles] = useState([]); const { list, loading, pagination, handleTableChange, handleCreate, handleUpdate, handleDelete, refresh } = useTableData({ service: { list: service.getUsers, create: service.createUser, update: service.updateUser, delete: service.deleteUser }, defaultParams: { sortField: 'createTime', sortOrder: 'desc' }, config: { message: { createSuccess: '创建用户成功', updateSuccess: '更新用户成功', deleteSuccess: '删除用户成功' } } }); useEffect(() => { service.getAllRoles().then(roles => setAllRoles(roles)); loadDepartmentTree(); }, []); const loadDepartmentTree = async () => { try { const data = await getDepartmentTree(); setDepartments(data); } catch (error) { message.error('加载部门数据失败'); } }; const getTreeData = (departments: DepartmentResponse[]): TreeNode[] => { return departments.map(dept => ({ title: dept.name, value: dept.id, children: dept.children ? getTreeData(dept.children) : undefined })); }; const handleAdd = () => { setEditingUser(null); form.resetFields(); form.setFieldsValue({ enabled: true }); setModalVisible(true); }; const handleEdit = (record: UserResponse) => { setEditingUser(record); form.setFieldsValue({ ...record, password: undefined // 不显示密码 }); setModalVisible(true); }; const handleResetPassword = (record: UserResponse) => { setEditingUser(record); passwordForm.resetFields(); setResetPasswordModalVisible(true); }; const handleResetPasswordSubmit = async () => { try { const values = await passwordForm.validateFields(); if (editingUser) { await service.resetPassword(editingUser.id, values.password); message.success('密码重置成功'); setResetPasswordModalVisible(false); refresh(); } } catch (error: any) { message.error(error.message || '密码重置失败'); } }; const handleSubmit = async () => { try { const values = await form.validateFields(); if (editingUser) { await handleUpdate(editingUser.id, values); } else { await handleCreate(values); } setModalVisible(false); refresh(); } catch (error: any) { message.error(error.message || '操作失败'); } }; const handleAssignRoles = (record: UserResponse) => { setSelectedUser(record); setSelectedRoles(record.roles?.map(role => role.id) || []); setRoleModalVisible(true); }; const handleAssignRoleSubmit = async () => { if (selectedUser) { try { await service.assignRoles(selectedUser.id, selectedRoles); message.success('角色分配成功'); setRoleModalVisible(false); refresh(); } catch (error) { message.error('角色分配失败'); } } }; const columns: Column[] = [ { accessorKey: 'id', header: 'ID', size: 60, }, { accessorKey: 'username', header: '用户名', size: 100, }, { accessorKey: 'nickname', header: '昵称', size: 100, }, { accessorKey: 'email', header: '邮箱', size: 200, }, { accessorKey: 'departmentName', header: '部门', size: 150, }, { accessorKey: 'enabled', header: '状态', size: 100, cell: ({ row }) => ( {row.original.enabled ? '启用' : '禁用'} ), }, { accessorKey: 'phone', header: '手机号', size: 120, }, { header: '角色', size: 120, cell: ({ row }) => row.original.roles?.map(role => role.name).join(', ') || '-', }, { accessorKey: 'createTime', header: '创建时间', size: 150, }, { accessorKey: 'updateTime', header: '更新时间', size: 150, }, { id: 'actions', header: '操作', size: 180, cell: ({ row }) => { const record = row.original; const items: MenuProps['items'] = [ { key: 'resetPassword', icon: , label: '重置密码', onClick: () => handleResetPassword(record) }, { key: 'assignRoles', icon: , label: '分配角色', onClick: () => handleAssignRoles(record), disabled: record.username === 'admin' } ]; if (record.username !== 'admin') { items.push({ key: 'delete', icon: , label: '删除', danger: true, onClick: () => handleDelete(record.id) }); } return (
{columns.map((column) => ( {column.header} ))} {list.map((row) => ( {columns.map((column) => ( {column.cell ? column.cell({ row: { original: row } }) : column.accessorKey ? String(row[column.accessorKey]) : null} ))} ))}
setModalVisible(false)} width={600} >
{!editingUser && ( )}
setResetPasswordModalVisible(false)} >
({ validator(_, value) { if (!value || getFieldValue('password') === value) { return Promise.resolve(); } return Promise.reject(new Error('两次输入的密码不一致')); }, }), ]} >
setRoleModalVisible(false)} width={600} >
); }; export default UserPage;