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: "pluginPage", label: "插件页面", path: "/plugin-pages/:pluginId/:routeKey", hash: "#/plugin-pages/:pluginId/:routeKey", 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)}`; } if (pageId === "pluginPage" && params.pluginId && params.routeKey) { const query = new URLSearchParams(); if (params.serverId) { query.set("serverInstanceId", params.serverId); } const suffix = query.toString(); return `#/plugin-pages/${encodeURIComponent(params.pluginId)}/${encodeURIComponent(params.routeKey)}${suffix ? `?${suffix}` : ""}`; } 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 [normalizedPath, rawQuery = ""] = normalized.split("?", 2); const segments = normalizedPath.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]) } }; } if (segments[0] === "plugin-pages" && segments.length > 2) { const serverId = new URLSearchParams(rawQuery).get("serverInstanceId") ?? undefined; return { route: routeForPage("pluginPage"), params: { pluginId: decodeURIComponent(segments[1]), routeKey: decodeURIComponent(segments[2]), serverId } }; } 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; }