feat(react19-migration): 阶段4 - 布局与通用组件

- T4.1: DefaultLayout (ProLayout + Suspense + Outlet)
- T4.2: SideMenu (AntD Menu + 递归菜单转换 + 图标映射)
- T4.3: HeaderRight (Dropdown + Avatar + 退出登录)
- T4.4: AuthGuard (认证守卫 → Navigate /login)
- T4.5: PermissionGuard (权限守卫 → permission/role 检查)
- T4.6: ChartContainer (AntV 图表容器)
- T4.7: useAntV Hook (图表生命周期管理)
- T4.8: usePermission Hook (权限检查封装)
- 安装 @ant-design/pro-components @ant-design/icons

验证: npx tsc --noEmit 通过
This commit is contained in:
张翔
2026-05-03 15:48:30 +08:00
parent 8a03923dd7
commit c5547cff06
10 changed files with 314 additions and 11 deletions
@@ -0,0 +1,39 @@
import { Suspense } from 'react'
import { Outlet } from 'react-router'
import { ProLayout } from '@ant-design/pro-components'
import { Spin } from 'antd'
import { useAppStore } from '@/stores/useAppStore'
import { useAuthStore } from '@/stores/useAuthStore'
import HeaderRight from './HeaderRight'
export default function DefaultLayout() {
const collapsed = useAppStore((s) => s.collapsed)
const toggleCollapsed = useAppStore((s) => s.toggleCollapsed)
const username = useAuthStore((s) => s.username)
return (
<ProLayout
title="Novalon 管理系统"
logo={null}
layout="mix"
collapsed={collapsed}
onCollapse={toggleCollapsed}
fixSiderbar
fixedHeader
menuItemRender={(item, dom) => <a onClick={() => item.onClick?.()}>{dom}</a>}
headerTitleRender={(logo, title) => (
<a onClick={toggleCollapsed} style={{ cursor: 'pointer' }}>
{logo}{title}
</a>
)}
avatarProps={{
title: username || '用户',
render: () => <HeaderRight />,
}}
>
<Suspense fallback={<Spin size="large" style={{ display: 'block', margin: '100px auto' }} />}>
<Outlet />
</Suspense>
</ProLayout>
)
}