diff --git a/web/src/access.ts b/web/src/access.ts
deleted file mode 100644
index 99da5fb..0000000
--- a/web/src/access.ts
+++ /dev/null
@@ -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('/');
- }
-}
diff --git a/web/src/app.ts b/web/src/app.ts
new file mode 100644
index 0000000..f36b3a7
--- /dev/null
+++ b/web/src/app.ts
@@ -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('/');
+ }
+}
diff --git a/web/src/layouts/index.tsx b/web/src/layouts/index.tsx
index 91aa8cd..4f14fa0 100644
--- a/web/src/layouts/index.tsx
+++ b/web/src/layouts/index.tsx
@@ -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(),子路由用 渲染
+// (渲染器不传 children prop,用 children 会导致整页空白且无任何报错)。
+export default function Layout() {
+ const location = useLocation();
+ if (location.pathname === '/login') return ;
const metadata = pageMetadata(location.pathname);
return (
@@ -61,7 +61,7 @@ export default function Layout({ children, location }: { children: ReactNode; lo
}}
>
- {children}
+
);