| import { Outlet, useLocation, useNavigate } from 'react-router'; |
| import { Layout, Menu, Dropdown, Button, Flex } from 'antd'; |
| import { HomeOutlined, AppstoreOutlined, DownOutlined } from '@ant-design/icons'; |
| import { useEffect, useMemo } from 'react'; |
| import logo from "./assets/logo.png"; |
| import { useAppDispatch, useAppSelector } from './store/hooks'; |
| import { getUserInfo } from './feature/user/userSlice'; |
| import { logout } from './feature/auth/authSlice'; |
| const { Header } = Layout; |
| |
| const AppLayout = () => { |
| const location = useLocation(); |
| const navigate = useNavigate(); |
| const userState = useAppSelector(state => state.user); |
| const dispatch = useAppDispatch(); |
| |
| useEffect(() => { |
| dispatch(getUserInfo()) |
| }, [dispatch]) |
| |
| // 判断是否在登录、注册或找回密码页面 |
| const isAuthPage = useMemo(() => { |
| return ['/login', '/register', '/forget'].includes(location.pathname); |
| }, [location.pathname]); |
| |
| // 导航项配置 |
| const menuItems = [ |
| { |
| key: 'home', |
| label: '主页', |
| icon: <HomeOutlined />, |
| path: '/', |
| }, |
| { |
| key: 'tasks', |
| label: '任务清单', |
| icon: <AppstoreOutlined />, |
| path: '/tasks', |
| }, |
| ]; |
| |
| // 处理登出逻辑 |
| const handleLogout = () => { |
| dispatch(logout()) |
| navigate('/login'); // 重定向到登录页 |
| }; |
| |
| // 下拉菜单内容 |
| const dropdownMenuItems = [ |
| { |
| key: 'profile', |
| label: '个人中心', |
| onClick: () => navigate('/profile'), |
| }, |
| { |
| key: 'logout', |
| label: '登出', |
| onClick: handleLogout, |
| }, |
| ]; |
| |
| return ( |
| <Layout style={{ minHeight: '100vh', width: '100%' }}> |
| <Header className="header" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}> |
| {/* logo */} |
| <Flex justify='center' align='center'> |
| <img src={logo} alt="Logo" height='48px' /> |
| <div style={{ color: 'white', marginLeft: '10px' }}> |
| 创驿 |
| </div> |
| </Flex> |
| |
| <div style={{ |
| height: '30px', |
| width: '1px', |
| backgroundColor: 'white', |
| margin: '0 20px', |
| }}></div> |
| |
| {/* 中间导航菜单 */} |
| <Menu |
| mode="horizontal" |
| theme="dark" |
| selectedKeys={[location.pathname === '/' ? 'home' : location.pathname.slice(1)]} |
| items={menuItems.map(item => ({ |
| ...item, |
| onClick: () => navigate(item.path), |
| }))} |
| style={{ flex: 1 }} |
| /> |
| |
| {/* 右侧用户名和下拉菜单 */} |
| {!isAuthPage && ( |
| <div style={{ display: 'flex', alignItems: 'center', color: 'white' }}> |
| <span>{userState.username}</span> |
| <Dropdown |
| trigger={['click']} |
| menu={{ items: dropdownMenuItems }} |
| > |
| <Button type="text" icon={<DownOutlined />} style={{ marginLeft: '10px', color: 'white' }} /> |
| </Dropdown> |
| </div> |
| )} |
| </Header> |
| <Layout.Content style={{ padding: '24px' }}> |
| <Outlet /> |
| </Layout.Content> |
| <Layout.Footer style={{ textAlign: 'center' }}> |
| © 2025 创驿 - 愿做你创作路上的同行者 |
| </Layout.Footer> |
| </Layout> |
| ); |
| }; |
| |
| export default AppLayout; |