Files
browser/platform_web/routes/routes.ts
T
2026-07-11 14:56:10 +08:00

142 lines
3.9 KiB
TypeScript

import type { PageId, PageParams, PageRoute } from "../contracts/page";
import type { CurrentUserView } from "../contracts/workspace";
import { isPlatformAdmin } from "../contracts/workspace";
export const firstPartyRoutes: PageRoute[] = [
{
id: "profileSettings",
label: "个人设置",
path: "/profile",
hash: "#/profile",
description: "个人资料与界面偏好",
requiredCapability: "profile.settings.manage",
showInNav: false
},
{
id: "home",
label: "平台概览",
path: "/",
hash: "#/home",
description: "平台运行健康概览",
requiredCapability: "platform.overview.read",
showInNav: true
},
{
id: "servers",
label: "服务器管理",
path: "/servers",
hash: "#/servers",
description: "服务器列表、状态与生命周期",
requiredCapability: "servers.read",
showInNav: true
},
{
id: "serverDetail",
label: "服务器详情",
path: "/servers/:serverId",
hash: "#/servers/:serverId",
description: "单服务器日常运维工作台",
requiredCapability: "servers.read",
showInNav: false
},
{
id: "plugins",
label: "插件市场",
path: "/plugins",
hash: "#/plugins",
description: "插件发现、安装状态与文档",
requiredCapability: "plugins.market.read",
showInNav: true
},
{
id: "users",
label: "用户管理",
path: "/users",
hash: "#/users",
description: "用户、角色和访问审核",
requiredCapability: "users.manage",
showInNav: true
},
{
id: "aiProviders",
label: "AI 提供商管理",
path: "/ai-providers",
hash: "#/aiProviders",
description: "平台中介模型配置",
requiredCapability: "aiProviders.manage",
showInNav: true
},
{
id: "maintenance",
label: "系统维护",
path: "/maintenance",
hash: "#/maintenance",
description: "审计事件与运行节点健康",
requiredCapability: "system.maintenance",
showInNav: true
}
];
const routesById = new Map(firstPartyRoutes.map((route) => [route.id, route]));
export interface ResolvedRoute {
route: PageRoute;
params: PageParams;
}
export function routeForPage(pageId: PageId): PageRoute {
return routesById.get(pageId) ?? firstPartyRoutes[0];
}
export function hashForPage(pageId: PageId, params: PageParams = {}): string {
const route = routeForPage(pageId);
if (pageId === "serverDetail" && params.serverId) {
return `#/servers/${encodeURIComponent(params.serverId)}`;
}
return route.hash;
}
export function defaultPageForUser(user: CurrentUserView): PageId {
return isPlatformAdmin(user) ? "home" : "servers";
}
export function navigationRoutesForUser(user: CurrentUserView): PageRoute[] {
return firstPartyRoutes.filter((route) => route.showInNav && user.capabilities.includes(route.requiredCapability));
}
export function canAccessRoute(user: CurrentUserView, pageId: PageId): boolean {
const route = routesById.get(pageId);
if (!route) {
return false;
}
return user.capabilities.includes(route.requiredCapability);
}
export function resolveRouteHash(hash: string, user?: CurrentUserView): ResolvedRoute {
const fallback: ResolvedRoute = {
route: routeForPage(user ? defaultPageForUser(user) : "servers"),
params: {}
};
const normalized = hash.replace(/^#/, "");
if (!normalized || normalized === "/") {
return fallback;
}
const segments = normalized.replace(/^\//, "").split("/").filter(Boolean);
if (segments.length === 0) {
return fallback;
}
if (segments[0] === "servers" && segments.length > 1) {
return { route: routeForPage("serverDetail"), params: { serverId: decodeURIComponent(segments[1]) } };
}
const key = segments[0];
const byId = routesById.get(key as PageId);
if (byId) {
return { route: byId, params: {} };
}
const byPath = firstPartyRoutes.find((route) => route.path === `/${key}`);
if (byPath) {
return { route: byPath, params: {} };
}
return fallback;
}