/**
* 从 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 !== '/';
}