import React, { useState, useEffect } from 'react'; import apiClient from '../../utils/apiClient'; import { buildApiUrl, API_ENDPOINTS } from '../../config/api'; import { Plus, Edit, Trash2, KeyRound, User, Mail, Shield, Search, X } from 'lucide-react'; import ConfirmDialog from '../../components/ConfirmDialog'; import FormModal from '../../components/FormModal'; import Toast from '../../components/Toast'; import ListTable from '../../components/ListTable'; import './UserManagement.css'; const UserManagement = () => { const [users, setUsers] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(10); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [showUserModal, setShowUserModal] = useState(false); const [isEditing, setIsEditing] = useState(false); const [currentUser, setCurrentUser] = useState(null); const [deleteConfirmInfo, setDeleteConfirmInfo] = useState(null); const [resetConfirmInfo, setResetConfirmInfo] = useState(null); const [roles, setRoles] = useState([]); const [toasts, setToasts] = useState([]); const [searchText, setSearchText] = useState(''); // 搜索文本 // Toast helper functions const showToast = (message, type = 'info') => { const id = Date.now(); setToasts(prev => [...prev, { id, message, type }]); }; const removeToast = (id) => { setToasts(prev => prev.filter(toast => toast.id !== id)); }; useEffect(() => { fetchUsers(); fetchRoles(); }, [page, pageSize, searchText]); const fetchUsers = async () => { setLoading(true); try { let url = `${API_ENDPOINTS.USERS.LIST}?page=${page}&size=${pageSize}`; if (searchText) { url += `&search=${encodeURIComponent(searchText)}`; } const response = await apiClient.get(buildApiUrl(url)); setUsers(response.data.users); setTotal(response.data.total); } catch (err) { setError('无法加载用户列表'); } finally { setLoading(false); } }; const fetchRoles = async () => { try { const response = await apiClient.get(buildApiUrl(API_ENDPOINTS.USERS.ROLES)); setRoles(response.data); } catch (err) { console.error('Error fetching roles:', err); // 如果无法获取角色列表,使用默认值 setRoles([ { role_id: 1, role_name: '平台管理员' }, { role_id: 2, role_name: '普通用户' } ]); } }; const handleAddUser = async (e) => { e.preventDefault(); try { await apiClient.post(buildApiUrl(API_ENDPOINTS.USERS.CREATE), currentUser); handleCloseModal(); setError(''); fetchUsers(); showToast('用户添加成功', 'success'); } catch (err) { console.error('Error adding user:', err); setError(err.response?.data?.message || '新增用户失败'); } }; const handleUpdateUser = async (e) => { e.preventDefault(); try { const updateData = { caption: currentUser.caption, email: currentUser.email, role_id: currentUser.role_id }; if (currentUser.username && currentUser.username.trim()) { updateData.username = currentUser.username; } await apiClient.put(buildApiUrl(API_ENDPOINTS.USERS.UPDATE(currentUser.user_id)), updateData); handleCloseModal(); setError(''); fetchUsers(); showToast('用户修改成功', 'success'); } catch (err) { console.error('Error updating user:', err); setError(err.response?.data?.message || '修改用户失败'); } }; const handleDeleteUser = async () => { try { await apiClient.delete(buildApiUrl(API_ENDPOINTS.USERS.DELETE(deleteConfirmInfo.user_id))); setDeleteConfirmInfo(null); showToast('用户删除成功', 'success'); fetchUsers(); } catch (err) { console.error('Error deleting user:', err); showToast('删除用户失败,请重试', 'error'); setDeleteConfirmInfo(null); } }; const handleResetPassword = async () => { try { await apiClient.post(buildApiUrl(API_ENDPOINTS.USERS.RESET_PASSWORD(resetConfirmInfo.user_id))); setResetConfirmInfo(null); showToast('密码重置成功', 'success'); } catch (err) { console.error('Error resetting password:', err); showToast('重置密码失败,请重试', 'error'); setResetConfirmInfo(null); } }; const handleOpenModal = (user = null) => { if (user) { setIsEditing(true); setCurrentUser({ ...user }); } else { setIsEditing(false); setCurrentUser({ username: '', caption: '', email: '', role_id: 2 }); } setError(''); setShowUserModal(true); }; const handleCloseModal = () => { setShowUserModal(false); setCurrentUser(null); setError(''); }; const handleSave = async () => { if (isEditing) { await handleUpdateUser({ preventDefault: () => {} }); } else { await handleAddUser({ preventDefault: () => {} }); } }; const handleInputChange = (field, value) => { setCurrentUser(prev => ({ ...prev, [field]: value })); }; const openDeleteConfirm = (user) => { setDeleteConfirmInfo({ user_id: user.user_id, caption: user.caption }); }; const openResetConfirm = (user) => { setResetConfirmInfo({ user_id: user.user_id, caption: user.caption }); }; const columns = [ { title: 'ID', dataIndex: 'user_id', key: 'user_id' }, { title: '用户名', dataIndex: 'username', key: 'username' }, { title: '姓名', dataIndex: 'caption', key: 'caption' }, { title: '邮箱', dataIndex: 'email', key: 'email' }, { title: '角色', dataIndex: 'role_name', key: 'role_name' }, { title: '创建时间', dataIndex: 'created_at', key: 'created_at', render: (item) => new Date(item.created_at).toLocaleString() }, { title: '操作', key: 'action', fixed: 'right', width: '150px', render: (item) => (
) } ]; return (

用户列表

{ setSearchText(e.target.value); setPage(1); // 重置到第一页 }} /> {searchText && ( )}
{error &&

{error}

} setPage(p) }} rowKey="user_id" showPagination={true} /> {/* 用户表单模态框 */} } > {error &&
{error}
} {currentUser && ( <>
handleInputChange('username', e.target.value)} placeholder="请输入用户名" required />
handleInputChange('caption', e.target.value)} placeholder="请输入姓名" required />
handleInputChange('email', e.target.value)} placeholder="请输入邮箱" required />
{!isEditing && (

注:新用户的默认密码为系统配置的默认密码,用户可登录后自行修改

)} )}
{/* 删除用户确认对话框 */} setDeleteConfirmInfo(null)} onConfirm={handleDeleteUser} title="删除用户" message={`确定要删除用户"${deleteConfirmInfo?.caption}"吗?此操作无法撤销。`} confirmText="确定删除" cancelText="取消" type="danger" /> {/* 重置密码确认对话框 */} setResetConfirmInfo(null)} onConfirm={handleResetPassword} title="重置密码" message={`确定要重置用户"${resetConfirmInfo?.caption}"的密码吗?重置后密码将恢复为系统默认密码。`} confirmText="确定重置" cancelText="取消" type="warning" /> {/* Toast notifications */} {toasts.map(toast => ( removeToast(toast.id)} /> ))}
); }; export default UserManagement;