38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
/**
|
||
* 一次性补资料链接的路径解析。
|
||
*
|
||
* 公开链接形如:`https://<域名>/supplement/<token>`,与后台 HashRouter 完全隔离。
|
||
* 命名空间判定用于路由分发:`/supplement` 及子路径整段交给公开页,
|
||
* 避免落到后台路由或打手端 SPA。
|
||
*/
|
||
|
||
export function isCollectMaterialLinkPath(pathname: unknown): boolean {
|
||
return splitPathSegments(pathname)[0] === 'supplement'
|
||
}
|
||
|
||
/**
|
||
* 只认 `/supplement/<一段 token>`:
|
||
* - `/supplement/abc` 命中,结尾多余斜杠容忍;
|
||
* - `/supplement`、`/supplement/a/b` 不命中(页面展示链接无效)。
|
||
*/
|
||
export function resolveCollectMaterialLinkToken(pathname: unknown): string {
|
||
const segments = splitPathSegments(pathname)
|
||
if (segments.length !== 2 || segments[0] !== 'supplement') return ''
|
||
return decodeTokenSegment(segments[1])
|
||
}
|
||
|
||
function splitPathSegments(pathname: unknown): string[] {
|
||
const normalized = String(pathname ?? '').trim()
|
||
if (!normalized.startsWith('/')) return []
|
||
|
||
return normalized.split(/[?#]/)[0].replace(/\/+$/, '').split('/').filter(Boolean)
|
||
}
|
||
|
||
function decodeTokenSegment(segment: string): string {
|
||
try {
|
||
return decodeURIComponent(segment)
|
||
} catch {
|
||
return segment
|
||
}
|
||
}
|