import React, { useState, useEffect } from 'react' import { APP_VERSION } from '../config/version' export default function Admin() { const [users, setUsers] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState('') const [showAddModal, setShowAddModal] = useState(false) const [editingUser, setEditingUser] = useState(null) const [newUser, setNewUser] = useState({ username: '', password: '', email: '', role: 'user' }) const token = localStorage.getItem('token') // 检查权限 const userStr = localStorage.getItem('user') let user = null try { user = userStr ? JSON.parse(userStr) : null } catch (e) {} if (!user || user.role !== 'admin') { return (
🚫
无权访问
仅管理员可以访问用户管理界面
) } useEffect(() => { fetchUsers() }, []) const fetchUsers = async () => { try { const res = await fetch('/api/admin/users?page=1&limit=100', { headers: { 'Authorization': `Bearer ${token}` } }) if (!res.ok) throw new Error('获取用户列表失败') const data = await res.json() setUsers(data) } catch (err) { setError(err.message) } finally { setLoading(false) } } const handleDeleteUser = async (userId, username) => { if (!confirm(`确定要删除用户 "${username}" 吗?`)) return try { const res = await fetch(`/api/admin/users/${userId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` } }) if (!res.ok) throw new Error('删除失败') fetchUsers() } catch (err) { alert(err.message) } } const handleAddUser = async () => { if (!newUser.username || !newUser.password) { alert('用户名和密码为必填项') return } // 如果 email 为空,不传这个字段 const payload = { ...newUser } if (!payload.email) { delete payload.email } try { const res = await fetch('/api/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify(payload) }) if (!res.ok) { const data = await res.json() throw new Error(data.detail || '添加失败') } alert('添加成功!') setShowAddModal(false) setNewUser({ username: '', password: '', email: '', role: 'user' }) fetchUsers() } catch (err) { alert(err.message) } } const handleEditUser = async () => { if (!editingUser.username) { alert('用户名不能为空') return } // 验证密码 if (editingUser.newPassword || editingUser.confirmPassword) { if (!editingUser.newPassword || !editingUser.confirmPassword) { alert('请填写完整密码信息') return } if (editingUser.newPassword !== editingUser.confirmPassword) { alert('两次输入的密码不一致') return } if (editingUser.newPassword.length < 6) { alert('密码至少 6 个字符') return } } try { // 准备更新数据 const updateData = { username: editingUser.username, email: editingUser.email, role: editingUser.role } // 如果有新密码,添加到更新数据 if (editingUser.newPassword && editingUser.newPassword.trim()) { updateData.password = editingUser.newPassword } const res = await fetch(`/api/admin/users/${editingUser.id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify(updateData) }) if (!res.ok) { const data = await res.json() throw new Error(data.detail || '更新失败') } alert('更新成功!') setEditingUser(null) fetchUsers() } catch (err) { alert(err.message) } } if (loading) return
加载中...
if (error) return
⚠️ {error}
return (

⚙️ 用户管理

{/* 用户列表 - 卡片式布局 */}
{users.map((user) => (
{user.username}
{user.role === 'admin' ? '👑 管理员' : '👤 用户'}
📧 {user.email || '未设置'} | 📱 {user.phone || '未设置'}
藏品数
window.location.hash = '#/list?userId=' + user.id} title='点击查看'>{user.collection_count || 0}
注册时间:{user.created_at ? new Date(user.created_at).toLocaleDateString('zh-CN') : '-'}
{user.role !== 'admin' && ( )}
))}
{users.length === 0 && (
暂无用户数据
)} {/* 添加用户模态框 */} {showAddModal && (

添加用户

setNewUser({ ...newUser, username: e.target.value })} style={{ width: '100%', padding: '10px', background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '8px', color: '#fff' }} />
setNewUser({ ...newUser, password: e.target.value })} style={{ width: '100%', padding: '10px', background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '8px', color: '#fff' }} />
setNewUser({ ...newUser, email: e.target.value })} style={{ width: '100%', padding: '10px', background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '8px', color: '#fff' }} />
)} {/* 编辑用户模态框 */} {editingUser && (

编辑用户

{/* 第一部分:基本信息 */}

📋 基本信息

setEditingUser({ ...editingUser, username: e.target.value })} style={{ width: '100%', padding: '10px', background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '8px', color: '#fff' }} />
setEditingUser({ ...editingUser, email: e.target.value })} style={{ width: '100%', padding: '10px', background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '8px', color: '#fff' }} />
{/* 第二部分:修改密码 */}

🔐 修改密码(可选)

setEditingUser({ ...editingUser, newPassword: e.target.value })} placeholder="请输入新密码(至少 6 位)" style={{ width: '100%', padding: '10px', background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '8px', color: '#fff' }} />
setEditingUser({ ...editingUser, confirmPassword: e.target.value })} placeholder="请再次输入新密码" style={{ width: '100%', padding: '10px', background: 'rgba(255,255,255,0.05)', border: '1px solid rgba(255,255,255,0.1)', borderRadius: '8px', color: '#fff' }} />
)} {/* 版本号 - 移到表格下方,避免被底部导航遮挡 */}
v{APP_VERSION}
) }