import React, { useState, useEffect } from 'react'; import { useNavigate, useLocation } from 'react-router-dom'; import { Button } from "@heroui/button"; import { Dropdown, DropdownTrigger, DropdownMenu, DropdownItem } from "@heroui/dropdown"; import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, useDisclosure } from "@heroui/modal"; import { Input } from "@heroui/input"; import { toast } from 'react-hot-toast'; import { Logo } from '@/components/icons'; import { updatePassword } from '@/api'; import { safeLogout } from '@/utils/logout'; import { siteConfig } from '@/config/site'; interface MenuItem { path: string; label: string; icon: React.ReactNode; adminOnly?: boolean; } interface PasswordForm { newUsername: string; currentPassword: string; newPassword: string; confirmPassword: string; } export default function AdminLayout({ children, }: { children: React.ReactNode; }) { const navigate = useNavigate(); const location = useLocation(); const { isOpen, onOpen, onOpenChange } = useDisclosure(); const [isMobile, setIsMobile] = useState(false); const [mobileMenuVisible, setMobileMenuVisible] = useState(false); const [username, setUsername] = useState(''); const [isAdmin, setIsAdmin] = useState(false); const [passwordLoading, setPasswordLoading] = useState(false); const [passwordForm, setPasswordForm] = useState({ newUsername: '', currentPassword: '', newPassword: '', confirmPassword: '' }); // 菜单项配置 const menuItems: MenuItem[] = [ { path: '/dashboard', label: '仪表板', icon: ( ) }, { path: '/forward', label: '转发管理', icon: ( ) }, { path: '/tunnel', label: '隧道管理', icon: ( ), adminOnly: true }, { path: '/node', label: '节点监控', icon: ( ), adminOnly: true }, { path: '/limit', label: '限速管理', icon: ( ), adminOnly: true }, { path: '/user', label: '用户管理', icon: ( ), adminOnly: true }, { path: '/config', label: '网站配置', icon: ( ), adminOnly: true } ]; // 检查移动端 const checkMobile = () => { setIsMobile(window.innerWidth <= 768); if (window.innerWidth > 768) { setMobileMenuVisible(false); } }; useEffect(() => { // 获取用户信息 const name = localStorage.getItem('name') || 'Admin'; // 兼容处理:如果没有admin字段,根据role_id判断(0为管理员) let adminFlag = localStorage.getItem('admin') === 'true'; if (localStorage.getItem('admin') === null) { const roleId = parseInt(localStorage.getItem('role_id') || '1', 10); adminFlag = roleId === 0; // 补充设置admin字段,避免下次再次判断 localStorage.setItem('admin', adminFlag.toString()); } setUsername(name); setIsAdmin(adminFlag); // 响应式检查 checkMobile(); window.addEventListener('resize', checkMobile); return () => { window.removeEventListener('resize', checkMobile); }; }, []); // 退出登录 const handleLogout = () => { safeLogout(); navigate('/'); }; // 切换移动端菜单 const toggleMobileMenu = () => { setMobileMenuVisible(!mobileMenuVisible); }; // 隐藏移动端菜单 const hideMobileMenu = () => { setMobileMenuVisible(false); }; // 菜单点击处理 const handleMenuClick = (path: string) => { navigate(path); if (isMobile) { hideMobileMenu(); } }; // 密码表单验证 const validatePasswordForm = (): boolean => { if (!passwordForm.newUsername.trim()) { toast.error('请输入新用户名'); return false; } if (passwordForm.newUsername.length < 3) { toast.error('用户名长度至少3位'); return false; } if (!passwordForm.currentPassword) { toast.error('请输入当前密码'); return false; } if (!passwordForm.newPassword) { toast.error('请输入新密码'); return false; } if (passwordForm.newPassword.length < 6) { toast.error('新密码长度不能少于6位'); return false; } if (passwordForm.newPassword !== passwordForm.confirmPassword) { toast.error('两次输入密码不一致'); return false; } return true; }; // 提交密码修改 const handlePasswordSubmit = async () => { if (!validatePasswordForm()) return; setPasswordLoading(true); try { const response = await updatePassword(passwordForm); if (response.code === 0) { toast.success('密码修改成功,请重新登录'); onOpenChange(); handleLogout(); } else { toast.error(response.msg || '密码修改失败'); } } catch (error) { toast.error('修改密码时发生错误'); console.error('修改密码错误:', error); } finally { setPasswordLoading(false); } }; // 重置密码表单 const resetPasswordForm = () => { setPasswordForm({ newUsername: '', currentPassword: '', newPassword: '', confirmPassword: '' }); }; // 过滤菜单项(根据权限) const filteredMenuItems = menuItems.filter(item => !item.adminOnly || isAdmin ); return (
{/* 移动端遮罩层 */} {isMobile && mobileMenuVisible && (
)} {/* 左侧菜单栏 */} {/* 主内容区域 */}
{/* 顶部导航栏 */}
{/* 移动端菜单按钮 */} {isMobile && ( )}
{/* 用户菜单 */} } onPress={onOpen} > 修改密码 } className="text-danger" color="danger" onPress={handleLogout} > 退出登录
{/* 主内容 */}
{children}
{/* 修改密码弹窗 */} { onOpenChange(); resetPasswordForm(); }} size="2xl" scrollBehavior="outside" backdrop="blur" placement="center" > {(onClose: () => void) => ( <> 修改密码
) => setPasswordForm(prev => ({ ...prev, newUsername: e.target.value }))} variant="bordered" /> ) => setPasswordForm(prev => ({ ...prev, currentPassword: e.target.value }))} variant="bordered" /> ) => setPasswordForm(prev => ({ ...prev, newPassword: e.target.value }))} variant="bordered" /> ) => setPasswordForm(prev => ({ ...prev, confirmPassword: e.target.value }))} variant="bordered" />
)}
); }