first commit
This commit is contained in:
129
src/layouts/index.tsx
Normal file
129
src/layouts/index.tsx
Normal file
@@ -0,0 +1,129 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Link, Outlet, useNavigate } from 'umi';
|
||||
import { Layout as AntLayout, Input, Button, Avatar, Dropdown, Menu, Space, Badge } from 'antd';
|
||||
import { SearchOutlined, UserOutlined, BellOutlined, BookOutlined, MessageOutlined } from '@ant-design/icons';
|
||||
import { userApi } from '../services/api';
|
||||
import type { User } from '../services/mockData';
|
||||
import styles from './index.less';
|
||||
|
||||
const { Header, Content } = AntLayout;
|
||||
|
||||
export default function Layout() {
|
||||
const navigate = useNavigate();
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// 获取用户信息
|
||||
userApi.getCurrentUser().then(res => {
|
||||
if (res.success) {
|
||||
setUser(res.data);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const handleSearch = () => {
|
||||
if (searchValue.trim()) {
|
||||
navigate(`/?search=${encodeURIComponent(searchValue)}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyPress = (e: React.KeyboardEvent) => {
|
||||
if (e.key === 'Enter') {
|
||||
handleSearch();
|
||||
}
|
||||
};
|
||||
|
||||
const userMenu = (
|
||||
<Menu>
|
||||
<Menu.Item key="profile">
|
||||
<UserOutlined /> 个人中心
|
||||
</Menu.Item>
|
||||
<Menu.Item key="settings">
|
||||
设置
|
||||
</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item key="logout">
|
||||
退出登录
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
return (
|
||||
<AntLayout className={styles.layout}>
|
||||
<Header className={styles.header}>
|
||||
<div className={styles.headerContent}>
|
||||
{/* Logo区域 */}
|
||||
<div className={styles.logo}>
|
||||
<Link to="/" className={styles.logoLink}>
|
||||
AutoBeeAgent
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* 搜索框 */}
|
||||
<div className={styles.search}>
|
||||
<Input
|
||||
placeholder="搜索热门话题..."
|
||||
value={searchValue}
|
||||
onChange={(e) => setSearchValue(e.target.value)}
|
||||
onKeyPress={handleKeyPress}
|
||||
prefix={<SearchOutlined />}
|
||||
// suffix={
|
||||
// <Button
|
||||
// type="primary"
|
||||
// size="small"
|
||||
// onClick={handleSearch}
|
||||
// loading={loading}
|
||||
// >
|
||||
// AI搜索
|
||||
// </Button>
|
||||
// }
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 用户信息 */}
|
||||
<div className={styles.userInfo}>
|
||||
<Space size="middle">
|
||||
<Button type="text" icon={<BookOutlined />}>
|
||||
学习
|
||||
</Button>
|
||||
<Badge count={0}>
|
||||
<Button type="text" icon={<BellOutlined />}>
|
||||
消息
|
||||
</Button>
|
||||
</Badge>
|
||||
{user ? (
|
||||
<Dropdown overlay={userMenu} placement="bottomRight">
|
||||
<div className={styles.userProfile}>
|
||||
<Avatar src={user.avatar} icon={<UserOutlined />} />
|
||||
<span className={styles.userName}>{user.name}</span>
|
||||
</div>
|
||||
</Dropdown>
|
||||
) : (
|
||||
<Button type="primary" onClick={() => navigate('/login')}>
|
||||
登录
|
||||
</Button>
|
||||
)}
|
||||
</Space>
|
||||
</div>
|
||||
</div>
|
||||
</Header>
|
||||
|
||||
<Content className={styles.content}>
|
||||
<Outlet />
|
||||
</Content>
|
||||
|
||||
{/* 浮动客服按钮 */}
|
||||
<div className={styles.floatingService}>
|
||||
<Button
|
||||
type="primary"
|
||||
shape="circle"
|
||||
icon={<MessageOutlined />}
|
||||
size="large"
|
||||
className={styles.serviceButton}
|
||||
/>
|
||||
</div>
|
||||
</AntLayout>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user