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:
2026-09-22 15:26:29 +08:00
parent 3e87f67442
commit 153788327b
3 changed files with 23 additions and 22 deletions
-15
View File
@@ -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('/');
}
}
+16
View File
@@ -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('/');
}
}
+7 -7
View File
@@ -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 4react-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>
);