/** * 方案 A:生产直连 api.ideship.com PATHBASE;开发仍走 Vite 代理旧路径。 */ const SPA_API_PREFIXES = [ 'upstreamInterface', 'upstreamInterfaceConfig', 'upstreamInterfaceConfigEdit', 'downstreamInterface', 'appList', 'requestLog', 'callStatistics', 'apiDebugger', 'apiTest', 'trackApi', ] as const const DEFAULT_PROD_API = 'https://api.ideship.com' function prodApiOrigin(): string { const override = (import.meta.env.VITE_API_ORIGIN as string | undefined)?.trim() return (override || DEFAULT_PROD_API).replace(/\/$/, '') } function isItfxSpaPath(afterApi: string): boolean { const seg = afterApi.split('/')[0] ?? '' return (SPA_API_PREFIXES as readonly string[]).some( (p) => seg === p || afterApi.startsWith(`${p}/`), ) } /** 生产:遗留路径 → https://api.ideship.com/{itfx|track|admin}/... */ export function rewriteBrowserApiPath(url: string): string { if (!url || import.meta.env.DEV) return url if (/^https?:\/\//i.test(url) || url.startsWith('data:') || url.startsWith('blob:')) { return url } let path = url.startsWith('/') ? url : `/${url}` const origin = prodApiOrigin() // 已是绝对 PATHBASE 相对路径 → 挂到 api 域名 if ( path.startsWith('/itfx/') || path === '/itfx' || path.startsWith('/track/') || path === '/track' || path.startsWith('/admin/') || path === '/admin' ) { return `${origin}${path}` } if (path.startsWith('/api/apiwechat')) { return `${origin}/admin${path.slice(4)}` } // 旧站 /api/upload/* → Admin wwwroot(勿进 /itfx) if (path.startsWith('/api/upload/') || path === '/api/upload') { const rest = path === '/api/upload' ? '' : path.slice('/api/upload'.length) return `${origin}/admin/uploads${rest}` } if (path.startsWith('/api/')) { const rest = path.slice(5) if (isItfxSpaPath(rest)) { return path // 仍是前端路由,勿打到 API } return `${origin}/itfx/${rest}` } if (path.startsWith('/Track')) { return `${origin}/track${path}` } if (path.startsWith('/trackApi/')) { return `${origin}/track/${path.slice('/trackApi/'.length)}` } return path }