refactor(admin): 控制台改为路由表驱动的动态路由 (react-router)
控制台从 useState 切 tab + 硬编码条件渲染,改为路由注册表驱动 + 真实 URL 路由, 加页面只需在 routes.tsx 加一条,不动外壳。 - 依赖 react-router-dom v7;App=HashRouter(静态托管/桌面内嵌都能深链) - routes.tsx:路由注册表(单一事实源,导航+内容都派生);real 页面 lazy 懒加载(代码分割) - shell/AppShell:NavLink 分组导航(配置/平台) + Routes + Suspense + 健康灯,全从注册表派生 - 页面归入 pages/(ModelsPage 移入),components/Soon 占位复用 - 验证:npm build✓(ModelsPage 独立 chunk=懒加载生效);真实浏览器——默认重定向 #/models、 nav 切换改 URL hash、深链 #/guardrails 直达、浏览器后退回 #/datasources、active 高亮 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { lazy, type ReactNode } from "react";
|
||||
import { Soon } from "./components/Soon";
|
||||
|
||||
// 路由注册表 —— 控制台的单一事实源:导航 + 内容都从这里派生。
|
||||
// 新增页面 = 在此加一条;real 页面用 lazy 懒加载(代码分割)。
|
||||
const ModelsPage = lazy(() => import("./pages/ModelsPage").then((m) => ({ default: m.ModelsPage })));
|
||||
|
||||
export interface RouteDef {
|
||||
path: string;
|
||||
label: string;
|
||||
group: string;
|
||||
ready?: boolean;
|
||||
element: ReactNode;
|
||||
}
|
||||
|
||||
export const routes: RouteDef[] = [
|
||||
{
|
||||
path: "/models",
|
||||
label: "模型",
|
||||
group: "配置",
|
||||
ready: true,
|
||||
element: <ModelsPage />,
|
||||
},
|
||||
{
|
||||
path: "/datasources",
|
||||
label: "数据源",
|
||||
group: "配置",
|
||||
element: (
|
||||
<Soon
|
||||
title="数据源(向量库 / 图库 / 全文)"
|
||||
desc="配置 Milvus(:19530) / Neo4j(:7687) / Bleve 连接 + 测试连接 + 状态。复用模型控制面同套路(配置→NATS 下发→mcp-go 热更新)。RAG 核心链。"
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "/tenants",
|
||||
label: "租户",
|
||||
group: "平台",
|
||||
element: <Soon title="租户 / 工作区" desc="多租户隔离、配额、用户与计费。垂直行业平台级复制的基座。" />,
|
||||
},
|
||||
{
|
||||
path: "/guardrails",
|
||||
label: "护栏",
|
||||
group: "平台",
|
||||
element: <Soon title="护栏" desc="输入/输出 Guardrail 规则(脱敏 / 免责 / 强制引用)。受监管垂直必备。" />,
|
||||
},
|
||||
];
|
||||
|
||||
export const defaultPath = "/models";
|
||||
|
||||
// 派生分组导航(保持注册顺序)。
|
||||
export function navGroups(): Array<{ group: string; items: RouteDef[] }> {
|
||||
const out: Array<{ group: string; items: RouteDef[] }> = [];
|
||||
for (const r of routes) {
|
||||
let g = out.find((x) => x.group === r.group);
|
||||
if (!g) {
|
||||
g = { group: r.group, items: [] };
|
||||
out.push(g);
|
||||
}
|
||||
g.items.push(r);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
Reference in New Issue
Block a user