Files
dukang/apps/h5-user/src/lib/promo.ts
T
2026-07-12 11:40:04 +08:00

71 lines
2.3 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.
import { apiBase } from './api';
export const PROMO_STORAGE_KEY = 'dukang_promo_code';
export const PROMO_PID_STORAGE_KEY = 'dukang_promo_pid';
function readPromoFromSearch(search: string): { code: string | null; pid: string | null } {
const params = new URLSearchParams(search.startsWith('?') ? search.slice(1) : search);
const code = params.get('promo')?.trim();
const pid = params.get('pid')?.trim();
return {
code: code ? code.toUpperCase() : null,
pid: pid || null,
};
}
/** 解析 URL 中的 ?promo= / ?pid= 并写入 sessionStorage */
export function capturePromoFromUrl(): string | null {
if (typeof window === 'undefined') return null;
let parsed = readPromoFromSearch(window.location.search);
if (!parsed.code && !parsed.pid && window.location.hash.includes('?')) {
const hashQuery = window.location.hash.slice(window.location.hash.indexOf('?'));
parsed = readPromoFromSearch(hashQuery);
}
if (parsed.code) {
sessionStorage.setItem(PROMO_STORAGE_KEY, parsed.code);
}
if (parsed.pid) {
sessionStorage.setItem(PROMO_PID_STORAGE_KEY, parsed.pid);
}
return parsed.code ?? sessionStorage.getItem(PROMO_STORAGE_KEY);
}
export function getStoredPromoCode(): string | null {
if (typeof window === 'undefined') return null;
return sessionStorage.getItem(PROMO_STORAGE_KEY);
}
export function getStoredPromoPid(): string | null {
if (typeof window === 'undefined') return null;
return sessionStorage.getItem(PROMO_PID_STORAGE_KEY);
}
/** 调用 /promo/touch 完成扫码归因(OptionalJwt:未登录也累加 scan_count */
export async function touchPromoIfNeeded(): Promise<void> {
const promoCode = getStoredPromoCode();
const qrcodeId = getStoredPromoPid();
if (!promoCode && !qrcodeId) return;
const headers: Record<string, string> = {
'Content-Type': 'application/json',
'X-Client-App': 'USER_H5',
};
const token = localStorage.getItem('accessToken');
if (token) headers.Authorization = `Bearer ${token}`;
try {
const res = await fetch(`${apiBase}/promo/touch`, {
method: 'POST',
headers,
body: JSON.stringify({
...(promoCode ? { promoCode } : {}),
...(qrcodeId ? { qrcodeId } : {}),
}),
});
const json = await res.json();
if (json.code !== 0) return;
} catch {
/* 静默失败,不阻断用户流程 */
}
}