fix(web): 修复布局渲染与全局认证守卫的三个真实缺陷(浏览器实测发现)
- Layout 崩溃:Umi 4 约定式全局布局不注入 location prop(undefined 直接白屏报错),改用 useLocation()
- 整页空白无报错:Umi 4 渲染器不传 children prop(RemoteComponent 以 createElement(Component, null) 渲染),布局必须自行渲染 <Outlet/>
- 认证守卫是死代码:onRouteChange 写在 access.ts 从未被调用(Umi 运行时配置只认 src/app.ts,且签名为 ({location}) 对象参数);移入 app.ts 并删除 access.ts
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
import { history } from '@umijs/max';
|
||||
|
||||
// 全局认证守卫(对齐 web.archived AuthGate 语义):
|
||||
// - localStorage('creatorhub.auth') 缺失 → 一律重定向 /login
|
||||
// - /login 已登录 → 重定向 /(避免重复登录)
|
||||
export function onRouteChange(clientRoutes: unknown, location: { pathname: string }) {
|
||||
const authed = localStorage.getItem('creatorhub.auth') !== null;
|
||||
if (!authed && location.pathname !== '/login') {
|
||||
history.replace('/login');
|
||||
return;
|
||||
}
|
||||
if (authed && location.pathname === '/login') {
|
||||
history.replace('/');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Umi 运行时配置:全局认证守卫(对齐 web.archived AuthGate 语义)。
|
||||
// onRouteChange 必须从 app.ts 导出才会被 Umi 调用;签名见 src/.umi/core/defineApp.ts。
|
||||
import { history } from '@umijs/max';
|
||||
|
||||
export function onRouteChange({ location }: { location: { pathname: string } }) {
|
||||
const authed = localStorage.getItem('creatorhub.auth') !== null;
|
||||
// - localStorage('creatorhub.auth') 缺失 → 一律重定向 /login
|
||||
if (!authed && location.pathname !== '/login') {
|
||||
history.replace('/login');
|
||||
return;
|
||||
}
|
||||
// - /login 已登录 → 重定向 /(避免重复登录)
|
||||
if (authed && location.pathname === '/login') {
|
||||
history.replace('/');
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,16 @@
|
||||
import { useRef, useState } from 'react';
|
||||
import { history } from '@umijs/max';
|
||||
import { history, Outlet, useLocation } from '@umijs/max';
|
||||
import { PageContainer, ProLayout } from '@ant-design/pro-components';
|
||||
import { Dropdown } from 'antd';
|
||||
import { LogoutOutlined } from '@ant-design/icons';
|
||||
import type { MenuDataItem } from '@ant-design/pro-components';
|
||||
import type { ReactNode } from 'react';
|
||||
import { pageMetadata, menu } from '@/utils/metadata';
|
||||
|
||||
// 菜单结构与 web.archived/src/app/Layout.jsx 完全一致(运营 / 资源 两组),页头标题规则对齐 pageMetadataRules。
|
||||
// /login 独立页:不走 ProLayout(对齐归档版布局分支)。
|
||||
export default function Layout({ children, location }: { children: ReactNode; location: { pathname: string } }) {
|
||||
if (location.pathname === '/login') return <>{children}</>;
|
||||
// Umi 4(react-router 6)全局布局:location 用 useLocation(),子路由用 <Outlet/> 渲染
|
||||
// (渲染器不传 children prop,用 children 会导致整页空白且无任何报错)。
|
||||
export default function Layout() {
|
||||
const location = useLocation();
|
||||
if (location.pathname === '/login') return <Outlet />;
|
||||
const metadata = pageMetadata(location.pathname);
|
||||
|
||||
return (
|
||||
@@ -61,7 +61,7 @@ export default function Layout({ children, location }: { children: ReactNode; lo
|
||||
}}
|
||||
>
|
||||
<PageContainer title={metadata.title} subTitle={metadata.subtitle} ghost>
|
||||
{children}
|
||||
<Outlet />
|
||||
</PageContainer>
|
||||
</ProLayout>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user