/** * 从 HTML 标签获取基础路径 * * 用于 React Router 的 basename 配置,使 SPA 路由能正确处理子路径部署。 * * @example * ```tsx * import { BrowserRouter } from 'react-router-dom'; * import { getBasePath } from '@org/frontend-core'; * * function App() { * return ( * * ... * * ); * } * ``` * * @returns 基础路径(不含结尾斜杠),如 '/portal/apps/personal' 或 '' */ export function getBasePath(): string { const base = document.querySelector('base')?.getAttribute('href'); if (!base || base === '/') { return ''; } // 移除结尾斜杠,React Router basename 不需要结尾斜杠 return base.replace(/\/+$/, ''); } /** * 获取 API 请求的基础路径 * * 根据架构设计,API 路径遵循 `/portal/api/{service}/*` 规范, * 与前端静态资源路径 `/portal/apps/{app-name}/` 分离。 * * 本函数从 标签路径中提取应用名称,转换为网关 API 路径。 * * @example * ```tsx * import { getApiBasePath } from '@org/frontend-core'; * * // 假设 * const url = `${getApiBasePath()}/users/profile`; * // 结果: '/portal/api/personal/users/profile' * * fetch(url); * ``` * * @returns API 基础路径,如 '/portal/api/personal' 或 '/api' */ export function getApiBasePath(): string { const basePath = getBasePath(); if (!basePath) { return '/api'; } // 匹配 /portal/apps/{app-name} 模式,转换为 /portal/api/{app-name} const match = basePath.match(/^\/portal\/apps\/([^/]+)$/); if (match) { const appName = match[1]; return `/portal/api/${appName}`; } // 回退:非标准路径保持原逻辑 return `${basePath}/api`; } /** * 获取指定服务的网关 API 基路径 * * 从 标签提取平台前缀(如 `/portal`),然后构建 API 路径。 * 支持以下 场景: * - `/portal/` → `/portal/api/{serviceName}` * - `/portal/apps/personal/` → `/portal/api/{serviceName}` * - `/` → `/api/{serviceName}` * * @example * ```tsx * import { getGatewayApiBasePath } from '@org/frontend-core'; * * // 假设 * const PERSONAL_API = getGatewayApiBasePath('personal'); * // 结果: '/portal/api/personal' * * fetch(`${PERSONAL_API}/users/profile`); * ``` * * @param serviceName - 服务名称,如 'personal', 'market', 'organization', 'base' * @returns 网关 API 路径,如 '/portal/api/personal' 或 '/api/personal' */ export function getGatewayApiBasePath(serviceName: string): string { const basePath = getBasePath(); if (!basePath) { return `/api/${serviceName}`; } // 提取平台前缀:/portal/apps/xxx → /portal,/portal → /portal const platformPrefix = basePath.match(/^(\/[^/]+)/)?.[1] || ''; return `${platformPrefix}/api/${serviceName}`; } /** * 检查当前是否部署在子路径下 * * @returns true 如果存在非根路径的 标签 */ export function hasSubPath(): boolean { const basePath = getBasePath(); return basePath !== '' && basePath !== '/'; }