front/src/utils/advisorInviteStorage.ts
zzh a703d1efdd feat: 顾问新客邀请链接与岗位职级字典
注册经 ?advisor= 绑定所属顾问(Account);用户抽屉展示邀请链接;岗位/职级走字典;去掉组织类型岗位。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-03 12:45:13 +08:00

100 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/** 顾问邀请归因暂存:7 天 last-touch(与客户邀请码并列,参数名为 advisor) */
const ADVISOR_INVITE_STORAGE_KEY = 'oms_advisor_invite_v1'
const ADVISOR_INVITE_TTL_MS = 7 * 24 * 60 * 60 * 1000
type AdvisorInvitePayload = {
code: string
ts: number
}
function safeParse(raw: string | null): AdvisorInvitePayload | null {
if (!raw) return null
try {
const parsed = JSON.parse(raw) as AdvisorInvitePayload
if (!parsed?.code || typeof parsed.ts !== 'number') return null
return { code: String(parsed.code).trim(), ts: parsed.ts }
} catch {
return null
}
}
function isExpired(ts: number, now = Date.now()): boolean {
return now - ts > ADVISOR_INVITE_TTL_MS
}
export function stashAdvisorInvite(advisorCode?: string | null): void {
const code = String(advisorCode ?? '').trim()
if (!code) return
const payload: AdvisorInvitePayload = { code, ts: Date.now() }
const raw = JSON.stringify(payload)
try {
localStorage.setItem(ADVISOR_INVITE_STORAGE_KEY, raw)
} catch {
/* ignore */
}
try {
sessionStorage.setItem(ADVISOR_INVITE_STORAGE_KEY, raw)
} catch {
/* ignore */
}
}
export function readStashedAdvisorInvite(): string {
const now = Date.now()
const fromSession = safeParse(
(() => {
try {
return sessionStorage.getItem(ADVISOR_INVITE_STORAGE_KEY)
} catch {
return null
}
})(),
)
if (fromSession && !isExpired(fromSession.ts, now)) {
return fromSession.code
}
const fromLocal = safeParse(
(() => {
try {
return localStorage.getItem(ADVISOR_INVITE_STORAGE_KEY)
} catch {
return null
}
})(),
)
if (fromLocal && !isExpired(fromLocal.ts, now)) {
stashAdvisorInvite(fromLocal.code)
return fromLocal.code
}
if (fromLocal || fromSession) {
clearStashedAdvisorInvite()
}
return ''
}
export function clearStashedAdvisorInvite(): void {
try {
localStorage.removeItem(ADVISOR_INVITE_STORAGE_KEY)
} catch {
/* ignore */
}
try {
sessionStorage.removeItem(ADVISOR_INVITE_STORAGE_KEY)
} catch {
/* ignore */
}
}
/** 解析顾问邀请:query.advisor → 7 天暂存 */
export function resolveAdvisorInvite(query: Record<string, unknown>): string {
const fromQuery = String(query.advisor ?? '').trim()
if (fromQuery) {
stashAdvisorInvite(fromQuery)
return fromQuery
}
return readStashedAdvisorInvite()
}