- 统一生成包含部署基路径和 Hash 路由的知识库、工作流分享地址 - 未登录访问分享页时保留目标地址,并在登录成功后自动回跳 - 限定分享密钥作用域并补充失效、加载失败及回归测试
88 lines
2.4 KiB
TypeScript
88 lines
2.4 KiB
TypeScript
/**
|
|
* 判断当前路径是否对应指定的应用路由。
|
|
*/
|
|
function matchesRoutePath(pathname: string, routePath: string) {
|
|
const normalizedPathname = pathname.replace(/\/+$/, '');
|
|
const normalizedRoutePath = routePath.replace(/\/+$/, '');
|
|
return (
|
|
normalizedPathname === normalizedRoutePath ||
|
|
normalizedPathname.endsWith(normalizedRoutePath)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 解析 Hash 模式下当前激活的应用路由。
|
|
*/
|
|
function parseHashRoute(hash: string) {
|
|
if (!hash.startsWith('#/')) {
|
|
return null;
|
|
}
|
|
return new URL(hash.slice(1), 'http://easyflow.local');
|
|
}
|
|
|
|
/**
|
|
* 从指定应用路由读取查询参数。
|
|
*
|
|
* Hash 路由存在时仅信任 Hash 内的激活路由,避免 pathname 上遗留的分享参数
|
|
* 污染后续页面。
|
|
*/
|
|
export function readScopedRouteQueryParam(
|
|
routePath: string,
|
|
queryName: string,
|
|
url?: string,
|
|
): null | string {
|
|
const currentUrl =
|
|
url || (typeof window === 'undefined' ? '' : window.location.href);
|
|
if (!currentUrl) {
|
|
return null;
|
|
}
|
|
try {
|
|
const parsed = new URL(
|
|
currentUrl,
|
|
typeof window === 'undefined'
|
|
? 'http://localhost'
|
|
: window.location.origin,
|
|
);
|
|
const hashRoute = parseHashRoute(parsed.hash);
|
|
if (hashRoute) {
|
|
if (!matchesRoutePath(hashRoute.pathname, routePath)) {
|
|
return null;
|
|
}
|
|
return hashRoute.searchParams.get(queryName)?.trim() || null;
|
|
}
|
|
if (!matchesRoutePath(parsed.pathname, routePath)) {
|
|
return null;
|
|
}
|
|
return parsed.searchParams.get(queryName)?.trim() || null;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 将 Router 解析出的应用地址转换为可复制的绝对地址。
|
|
*
|
|
* Hash 路由下 Router 可能只返回 `#/path`,需显式补齐部署基路径。
|
|
*/
|
|
export function buildAbsoluteAppRouteUrl(href: string, origin?: string) {
|
|
const currentOrigin =
|
|
origin ||
|
|
(typeof window === 'undefined'
|
|
? 'http://localhost'
|
|
: window.location.origin);
|
|
if (!href.startsWith('#/') && !href.startsWith('/#/')) {
|
|
return new URL(href, currentOrigin).toString();
|
|
}
|
|
const configuredBase = import.meta.env.BASE_URL || '/';
|
|
const runtimeBase =
|
|
configuredBase === '/' &&
|
|
typeof window !== 'undefined' &&
|
|
window.location.pathname.endsWith('/')
|
|
? window.location.pathname
|
|
: configuredBase;
|
|
return new URL(
|
|
`${runtimeBase.replace(/\/?$/, '/')}${href.slice(href.indexOf('#'))}`,
|
|
currentOrigin,
|
|
).toString();
|
|
}
|