import React, { useState, useEffect, useCallback } from 'react'; import axios from '../../services/axios'; import { adminAPI } from '../../services/api'; import { toast } from 'react-toastify'; import Pagination from '../../components/Pagination'; import '../../styles/Pagination.css'; import { debounce } from '../../utils/debounce'; const UserManagement = () => { const [users, setUsers] = useState([]); const [page, setPage] = useState(1); const [itemsPerPage, setItemsPerPage] = useState(10); const [totalPages, setTotalPages] = useState(1); const [totalItems, setTotalItems] = useState(0); const [loading, setLoading] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [sortBy, setSortBy] = useState('created_at'); const [sortOrder, setSortOrder] = useState('desc'); const [showAddModal, setShowAddModal] = useState(false); const [showEditModal, setShowEditModal] = useState(false); const [currentUser, setCurrentUser] = useState(null); const [currentLoginUser, setCurrentLoginUser] = useState(null); const [formData, setFormData] = useState({ username: '', email: '', password: '', is_active: true, daily_limit: 100 }); const [selectedUsers, setSelectedUsers] = useState([]); const [showBatchModal, setShowBatchModal] = useState(false); const [batchAction, setBatchAction] = useState(''); // 获取用户列表 const fetchUsers = async (reset = false) => { try { setLoading(true); const currentPage = reset ? 1 : page; if (reset) setPage(1); const response = await axios.get('/api/admin/users', { params: { page: currentPage, per_page: itemsPerPage, search: searchQuery, sort_by: sortBy, sort_order: sortOrder } }); const { users: newUsers, total_pages, total_users } = response.data; setUsers(newUsers); setTotalPages(total_pages); setTotalItems(total_users); } catch (error) { console.error('获取用户列表失败:', error); toast.error('获取用户列表失败'); } finally { setLoading(false); } }; const handlePageChange = (newPage) => { setPage(newPage); }; const handleItemsPerPageChange = (newItemsPerPage) => { setItemsPerPage(newItemsPerPage); setPage(1); }; // 防抖搜索函数 const debouncedSearch = useCallback( debounce(() => { fetchUsers(true); }, 500), [] ); useEffect(() => { fetchCurrentUser(); }, []); useEffect(() => { debouncedSearch(); }, [searchQuery, debouncedSearch]); useEffect(() => { fetchUsers(); }, [sortBy, sortOrder, itemsPerPage, page]); // 获取当前登录用户信息 const fetchCurrentUser = async () => { try { const res = await axios.get('/api/auth/me'); setCurrentLoginUser(res.data); } catch (err) { console.error('获取当前用户信息失败', err); } }; // 处理表单变化 const handleChange = (e) => { const { name, value, type, checked } = e.target; setFormData({ ...formData, [name]: type === 'checkbox' ? checked : value }); }; // 打开添加用户模态框 const handleAddUser = () => { setFormData({ username: '', email: '', password: '', is_active: false, daily_quota: 5 }); setShowAddModal(true); }; // 打开编辑用户模态框 const handleEditUser = (user) => { setCurrentUser(user); setFormData({ username: user.username, email: user.email, password: '', // 不显示现有密码 is_active: user.is_active, daily_quota: user.daily_quota }); setShowEditModal(true); }; // 提交添加用户 const submitAddUser = async () => { try { if (!formData.username || !formData.password) { toast.warning('用户名和密码为必填项'); return; } await axios.post('/api/admin/users', formData); toast.success('用户添加成功'); setShowAddModal(false); fetchUsers(); } catch (err) { toast.error('添加用户失败,可能用户名已存在'); console.error(err); } }; // 提交编辑用户 const submitEditUser = async () => { try { if (!currentUser) return; // 准备要发送的数据,不包含空密码 const updateData = { ...formData }; if (!updateData.password) { delete updateData.password; } await axios.put(`/api/admin/users/${currentUser.id}`, updateData); toast.success('用户更新成功'); setShowEditModal(false); fetchUsers(); } catch (err) { toast.error('更新用户失败'); console.error(err); } }; // 删除用户 const handleDeleteUser = async (userId) => { if (window.confirm('确定要删除这个用户吗?此操作不可恢复。')) { try { await adminAPI.deleteUser(userId); toast.success('用户已删除'); fetchUsers(); } catch (err) { toast.error('删除用户失败'); console.error(err); } } }; // 处理用户选择 const handleSelectUser = (userId) => { setSelectedUsers(prev => prev.includes(userId) ? prev.filter(id => id !== userId) : [...prev, userId] ); }; // 全选/取消全选 const handleSelectAll = () => { if (selectedUsers.length === users.length) { setSelectedUsers([]); } else { setSelectedUsers(users.map(user => user.id)); } }; // 批量操作 const handleBatchAction = (action) => { if (selectedUsers.length === 0) { toast.warning('请先选择用户'); return; } setBatchAction(action); setShowBatchModal(true); }; // 执行批量操作 const executeBatchAction = async () => { try { let successCount = 0; if (batchAction === 'delete') { if (!window.confirm(`确定要删除选中的 ${selectedUsers.length} 个用户吗?此操作不可恢复。`)) { return; } for (const userId of selectedUsers) { try { await adminAPI.deleteUser(userId); successCount++; } catch (err) { console.error(`删除用户 ${userId} 失败:`, err); } } toast.success(`成功删除 ${successCount}/${selectedUsers.length} 个用户`); } else if (batchAction === 'activate') { for (const userId of selectedUsers) { try { await adminAPI.updateUser(userId, { is_active: true }); successCount++; } catch (err) { console.error(`激活用户 ${userId} 失败:`, err); } } toast.success(`成功激活 ${successCount}/${selectedUsers.length} 个用户`); } else if (batchAction === 'deactivate') { for (const userId of selectedUsers) { try { await adminAPI.updateUser(userId, { is_active: false }); successCount++; } catch (err) { console.error(`禁用用户 ${userId} 失败:`, err); } } toast.success(`成功禁用 ${successCount}/${selectedUsers.length} 个用户`); } setShowBatchModal(false); setSelectedUsers([]); fetchUsers(); } catch (err) { toast.error('批量操作失败'); console.error(err); } }; // 切换用户激活状态 const toggleUserStatus = async (userId, currentStatus) => { try { await axios.put(`/api/admin/users/${userId}`, { is_active: !currentStatus }); toast.success(`用户已${!currentStatus ? '激活' : '禁用'}`); fetchUsers(); } catch (err) { toast.error('更新用户状态失败'); console.error(err); } }; if (loading && page === 1) { return (
| 0} ref={(el) => { if (el) { el.indeterminate = selectedUsers.length > 0 && selectedUsers.length < users.length; } }} onChange={handleSelectAll} /> | ID | 用户名 | 邮箱 | 状态 | 每日限额 | 注册时间 | 操作 |
|---|---|---|---|---|---|---|---|
| 暂无用户数据 | |||||||
| handleSelectUser(user.id)} /> | {user.id} | {user.username} | {user.email} | {user.is_active ? '已激活' : '未激活'} | {user.daily_quota} | {new Date(user.created_at).toLocaleString()} |
|
确定要删除选中的 {selectedUsers.length} 个用户吗?此操作不可恢复。
)} {batchAction === 'activate' && (确定要激活选中的 {selectedUsers.length} 个用户吗?
)} {batchAction === 'deactivate' && (确定要禁用选中的 {selectedUsers.length} 个用户吗?
)}