const WORKER_TOKEN_KEY = 'order-site-worker-token' const WORKER_EXPIRES_AT_KEY = 'order-site-worker-token-expires-at' const WORKER_ID_KEY = 'order-site-worker-id' const WORKER_USERNAME_KEY = 'order-site-worker-username' const WORKER_STATUS_KEY = 'order-site-worker-status' const WORKER_DEVICE_ID_KEY = 'order-site-worker-device-id' const WORKER_SESSION_STORAGE_KEYS = new Set([ WORKER_TOKEN_KEY, WORKER_EXPIRES_AT_KEY, WORKER_ID_KEY, WORKER_USERNAME_KEY, WORKER_STATUS_KEY, ]) export function getWorkerToken() { return localStorage.getItem(WORKER_TOKEN_KEY) || '' } export function getWorkerDeviceId() { let deviceId = localStorage.getItem(WORKER_DEVICE_ID_KEY) || '' if (!deviceId) { deviceId = typeof crypto.randomUUID === 'function' ? crypto.randomUUID() : `${Date.now()}-${Math.random().toString(36).slice(2)}` localStorage.setItem(WORKER_DEVICE_ID_KEY, deviceId) } return deviceId } export function getWorkerTokenExpiresAt() { return localStorage.getItem(WORKER_EXPIRES_AT_KEY) || '' } export function getWorkerId() { const value = Number(localStorage.getItem(WORKER_ID_KEY) || 0) return Number.isFinite(value) && value > 0 ? value : 0 } export function getWorkerUsername() { return localStorage.getItem(WORKER_USERNAME_KEY) || '' } export function getWorkerStatus() { return localStorage.getItem(WORKER_STATUS_KEY) || '' } export function setWorkerSession( token: string, expiresAt: string, worker?: { workerId: number; username: string; status: string }, ) { localStorage.setItem(WORKER_TOKEN_KEY, token) localStorage.setItem(WORKER_EXPIRES_AT_KEY, expiresAt) if (worker?.workerId) { localStorage.setItem(WORKER_ID_KEY, String(worker.workerId)) } if (worker?.username) { localStorage.setItem(WORKER_USERNAME_KEY, worker.username) } if (worker?.status) { localStorage.setItem(WORKER_STATUS_KEY, worker.status) } } export function clearWorkerSession() { localStorage.removeItem(WORKER_TOKEN_KEY) localStorage.removeItem(WORKER_EXPIRES_AT_KEY) localStorage.removeItem(WORKER_ID_KEY) localStorage.removeItem(WORKER_USERNAME_KEY) localStorage.removeItem(WORKER_STATUS_KEY) } /** 清理失效会话并通知当前标签页,避免并发请求各自重复跳转。 */ export function expireWorkerSession() { const hadSession = Boolean(getWorkerToken() || getWorkerTokenExpiresAt()) clearWorkerSession() if (hadSession && typeof window !== 'undefined') { window.dispatchEvent(new Event('worker-session-expired')) } return hadSession } export function isWorkerSessionStorageKey(key: string | null) { return Boolean(key && WORKER_SESSION_STORAGE_KEYS.has(key)) } export function getWorkerSessionExpiryDelay(expiresAt: string, now = Date.now()) { if (!expiresAt) return null const expiresAtMs = Date.parse(expiresAt) if (!Number.isFinite(expiresAtMs)) return null return Math.max(0, expiresAtMs - now) } export function hasWorkerSession() { const token = getWorkerToken() const expiresAt = getWorkerTokenExpiresAt() if (!token) return false if (isExpired(expiresAt)) { clearWorkerSession() return false } return true } function isExpired(expiresAt: string) { const delay = getWorkerSessionExpiryDelay(expiresAt) return delay !== null && delay <= 0 }