import { useEffect, useState } from 'react' import { BrowserRouter, Link, Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom' import { App, ConfigProvider, Layout, Menu, Typography, Button, Tag, Space, Spin, type MenuProps } from 'antd' import { AccountBookOutlined, ApiOutlined, DashboardOutlined, FileSearchOutlined, LogoutOutlined, SettingOutlined, ShopOutlined, UserOutlined, } from '@ant-design/icons' import { getMe, logout, type CurrentMember, getStoredToken } from './api' import Dashboard from './pages/Dashboard' import Sites from './pages/Sites' import Rules from './pages/Rules' import Payments from './pages/Payments' import Accounts from './pages/Accounts' import Settlements from './pages/Settlements' import Orders from './pages/Orders' import Login from './pages/Login' import './style.css' type MenuItem = Required['items'][number] & { superadminOnly?: boolean } const ALL_MENU_ITEMS: MenuItem[] = [ { key: '/', icon: , label: 仪表盘 }, { key: '/sites', icon: , label: 分销网站, superadminOnly: true }, { key: '/sold', icon: , label: 售出账号 }, { key: '/receive', icon: , label: 分销收号 }, { key: '/settlements', icon: , label: 结算管理 }, { key: '/payments', icon: , label: 支付通道 }, { key: '/accounts', icon: , label: 账号展示 }, { key: '/rules', icon: , label: 比例与税费 }, ] function MainLayout({ member, onLogout }: { member: CurrentMember; onLogout: () => void }) { const location = useLocation() const menuItems = ALL_MENU_ITEMS.filter((item) => !item.superadminOnly || member.is_superadmin) const selectedKey = menuItems.some((item) => item.key === location.pathname) ? location.pathname : '/' const roleLabel = member.is_superadmin ? '平台超级管理员' : member.member_type === 'operator' ? '分销运营' : member.member_type === 'finance' ? '分销财务' : '分销成员' return (
HFB 分销后台
{member.is_superadmin ? ( 平台全局管理模式 ) : ( {member.site_name || '当前分销站点'} · {member.domain || member.site_code} )} 主站 hao858.com · 分销管理系统
{member.nickname || member.username} {roleLabel}
} /> {member.is_superadmin && } />} } /> } /> } /> } /> } /> } /> } /> } />
) } function AppContent() { const [member, setMember] = useState(null) const [loading, setLoading] = useState(true) const navigate = useNavigate() const location = useLocation() useEffect(() => { let active = true const checkAuth = async () => { // If no token exists and no session, skip getMe if (!getStoredToken() && location.pathname === '/login') { if (active) setLoading(false) return } try { const profile = await getMe() if (active) { setMember(profile) if (location.pathname === '/login') { navigate('/', { replace: true }) } } } catch { if (active) { setMember(null) if (location.pathname !== '/login') { navigate('/login', { replace: true }) } } } finally { if (active) setLoading(false) } } checkAuth() return () => { active = false } }, [location.pathname, navigate]) const handleLogout = async () => { await logout() setMember(null) navigate('/login', { replace: true }) } const handleLoginSuccess = (current: CurrentMember) => { setMember(current) navigate('/', { replace: true }) } if (loading) { return (
) } if (location.pathname === '/login') { return } if (!member) { return } return } export default function AppShell() { return ( ) }