refactor: 迁移 UI 组件库从 Ant Design 至 TDesign
- 替换 antd 为 tdesign-react 作为主要 UI 组件库 - 引入 Recharts 替代 @ant-design/charts 实现图表功能 - 移除主题系统相关代码(ThemeContext、themes 目录) - 更新所有组件以适配 TDesign 组件 API - 更新测试用例以匹配新的组件实现 - 新增 TDesign 和 Recharts 集成规范文档
This commit is contained in:
@@ -1,23 +1,12 @@
|
||||
import { useState } from 'react';
|
||||
import { Layout, Menu, theme } from 'antd';
|
||||
import { CloudServerOutlined, BarChartOutlined, SettingOutlined } from '@ant-design/icons';
|
||||
import { Layout, Menu } from 'tdesign-react';
|
||||
import { ServerIcon, ChartLineIcon, SettingIcon } from 'tdesign-icons-react';
|
||||
import { Outlet, useLocation, useNavigate } from 'react-router';
|
||||
import { useTheme } from '@/contexts/ThemeContext';
|
||||
|
||||
const menuItems = [
|
||||
{ key: '/providers', label: '供应商管理', icon: <CloudServerOutlined /> },
|
||||
{ key: '/stats', label: '用量统计', icon: <BarChartOutlined /> },
|
||||
{ type: 'divider' as const },
|
||||
{ key: '/settings', label: '设置', icon: <SettingOutlined /> },
|
||||
];
|
||||
const { MenuItem } = Menu;
|
||||
|
||||
export function AppLayout() {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const { effectiveThemeId } = useTheme();
|
||||
const isDark = effectiveThemeId === 'dark';
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const { token } = theme.useToken();
|
||||
|
||||
const getPageTitle = () => {
|
||||
if (location.pathname === '/providers') return '供应商管理';
|
||||
@@ -28,12 +17,8 @@ export function AppLayout() {
|
||||
|
||||
return (
|
||||
<Layout style={{ minHeight: '100vh' }}>
|
||||
<Layout.Sider
|
||||
collapsible
|
||||
collapsed={collapsed}
|
||||
onCollapse={setCollapsed}
|
||||
breakpoint="lg"
|
||||
theme={isDark ? 'dark' : 'light'}
|
||||
<Layout.Aside
|
||||
width="232px"
|
||||
style={{
|
||||
overflow: 'hidden',
|
||||
height: '100vh',
|
||||
@@ -50,33 +35,38 @@ export function AppLayout() {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
color: token.colorText,
|
||||
fontSize: collapsed ? '1rem' : '1.25rem',
|
||||
fontSize: '1.25rem',
|
||||
fontWeight: 600,
|
||||
transition: 'all 0.2s',
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
{collapsed ? 'AI' : 'AI Gateway'}
|
||||
AI Gateway
|
||||
</div>
|
||||
<Menu
|
||||
theme={isDark ? 'dark' : 'light'}
|
||||
mode="inline"
|
||||
selectedKeys={[location.pathname]}
|
||||
items={menuItems}
|
||||
onClick={({ key }) => navigate(key)}
|
||||
value={location.pathname}
|
||||
onChange={(value) => navigate(value as string)}
|
||||
style={{ flex: 1, overflow: 'auto' }}
|
||||
/>
|
||||
>
|
||||
<MenuItem value="/providers" icon={<ServerIcon />}>
|
||||
供应商管理
|
||||
</MenuItem>
|
||||
<MenuItem value="/stats" icon={<ChartLineIcon />}>
|
||||
用量统计
|
||||
</MenuItem>
|
||||
<MenuItem value="/settings" icon={<SettingIcon />}>
|
||||
设置
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</div>
|
||||
</Layout.Sider>
|
||||
<Layout style={{ marginLeft: collapsed ? 80 : 200, transition: 'all 0.2s' }}>
|
||||
</Layout.Aside>
|
||||
<Layout style={{ marginLeft: 232 }}>
|
||||
<Layout.Header
|
||||
style={{
|
||||
padding: '0 2rem',
|
||||
background: token.colorBgContainer,
|
||||
background: '#fff',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
borderBottom: `1px solid ${token.colorBorderSecondary}`,
|
||||
borderBottom: '1px solid #e7e7e7',
|
||||
}}
|
||||
>
|
||||
<h1 style={{ margin: 0, fontSize: '1.25rem' }}>{getPageTitle()}</h1>
|
||||
|
||||
Reference in New Issue
Block a user