import { useState, useEffect } from 'react'; import { Dropdown, Avatar, Space, Typography, message, Modal, Form, Input, Button } from 'antd'; import { UserOutlined, LogoutOutlined, TeamOutlined, CrownOutlined, LockOutlined } from '@ant-design/icons'; import { authApi } from '../services/api'; import type { User } from '../types'; import type { MenuProps } from 'antd'; import { useNavigate } from 'react-router-dom'; const { Text } = Typography; export default function UserMenu() { const navigate = useNavigate(); const [currentUser, setCurrentUser] = useState(null); const [showChangePassword, setShowChangePassword] = useState(false); const [changePasswordForm] = Form.useForm(); const [changingPassword, setChangingPassword] = useState(false); useEffect(() => { loadCurrentUser(); }, []); const loadCurrentUser = async () => { try { const user = await authApi.getCurrentUser(); setCurrentUser(user); } catch (error) { console.error('获取用户信息失败:', error); } }; const handleLogout = async () => { try { await authApi.logout(); message.success('已退出登录'); window.location.href = '/login'; } catch (error) { console.error('退出登录失败:', error); message.error('退出登录失败'); } }; const handleShowUserManagement = () => { if (!currentUser?.is_admin) { message.warning('只有管理员可以访问用户管理'); return; } navigate('/user-management'); }; const handleChangePassword = async (values: { oldPassword: string; newPassword: string }) => { try { setChangingPassword(true); await authApi.setPassword(values.newPassword); message.success('密码修改成功'); setShowChangePassword(false); changePasswordForm.resetFields(); } catch (error: any) { console.error('修改密码失败:', error); message.error(error.response?.data?.detail || '修改密码失败'); } finally { setChangingPassword(false); } }; const menuItems: MenuProps['items'] = [ { key: 'user-info', label: (
{currentUser?.display_name || currentUser?.username}
Trust Level: {currentUser?.trust_level} {currentUser?.is_admin && ' · 管理员'}
), disabled: true, }, { type: 'divider', }, ...(currentUser?.is_admin ? [ { key: 'user-management', icon: , label: '用户管理', onClick: handleShowUserManagement, }, { type: 'divider' as const, } ] : []), { key: 'change-password', icon: , label: '修改密码', onClick: () => setShowChangePassword(true), }, { type: 'divider', }, { key: 'logout', icon: , label: '退出登录', onClick: handleLogout, }, ]; if (!currentUser) { return null; } return ( <>
{ e.currentTarget.style.background = 'var(--color-bg-container)'; // 悬浮时变实 e.currentTarget.style.transform = 'translateY(-2px)'; e.currentTarget.style.boxShadow = 'var(--shadow-elevated)'; }} onMouseLeave={(e) => { e.currentTarget.style.background = 'rgba(255, 255, 255, 0.6)'; e.currentTarget.style.transform = 'translateY(0)'; e.currentTarget.style.boxShadow = 'var(--shadow-card)'; }} >
} size={40} style={{ backgroundColor: 'var(--color-primary)', border: '3px solid #fff', boxShadow: 'var(--shadow-card)', }} /> {currentUser.is_admin && (
)}
{currentUser.display_name || currentUser.username} {currentUser.is_admin ? '👑 管理员' : `🎖️ Trust Level ${currentUser.trust_level}`}
{ setShowChangePassword(false); changePasswordForm.resetFields(); }} footer={null} width={480} centered >
} placeholder="请输入新密码(至少6个字符)" autoComplete="new-password" /> ({ validator(_, value) { if (!value || getFieldValue('newPassword') === value) { return Promise.resolve(); } return Promise.reject(new Error('两次输入的密码不一致')); }, }), ]} > } placeholder="请再次输入新密码" autoComplete="new-password" />
); }