import { AxiosHeaders, type AxiosRequestConfig } from "axios"; /** 与 Laravel `NegotiateLotteryLocale`、`lottery.locales.supported`(zh/en/ne)一致 */ export type AdminApiLocale = "zh" | "en" | "ne"; export const ADMIN_API_LOCALES: readonly AdminApiLocale[] = ["zh", "en", "ne"]; export const ADMIN_LOCALE_LABELS: Record = { zh: "简体中文", en: "English", ne: "नेपाली", }; const STORAGE_KEY = "lottery_admin_ui_locale"; let overrideLocale: AdminApiLocale | null = null; function isApiLocale(value: string): value is AdminApiLocale { return value === "zh" || value === "en" || value === "ne"; } /** 覆盖后续 API 请求的 `X-Locale`(传 `null` 取消覆盖,改回 `document.documentElement.lang` / 默认) */ export function setAdminRequestLocale(locale: string | null): void { if (locale === null) { overrideLocale = null; return; } const p = locale.trim().toLowerCase().split("-")[0] ?? ""; overrideLocale = isApiLocale(p) ? p : null; } function requestLocale(): AdminApiLocale { if (overrideLocale) { return overrideLocale; } if (typeof document !== "undefined") { const tag = document.documentElement.lang.trim().toLowerCase(); const primary = tag.split("-")[0] ?? tag; if (isApiLocale(primary)) { return primary; } } // 与 i18n `ADMIN_DEFAULT_LANGUAGE`(zh)一致,避免界面中文而校验仍为英文 return "zh"; } /** 当前生效的语言(与即将发出的 API 头一致) */ export function getAdminRequestLocale(): AdminApiLocale { return requestLocale(); } function acceptLanguage(loc: AdminApiLocale): string { if (loc === "zh") { return "zh-CN,zh;q=0.9,en;q=0.8"; } if (loc === "ne") { return "ne,ne-NP;q=0.9,en;q=0.8"; } return "en-US,en;q=0.9"; } /** 与 `` 对齐的 BCP 47 标签 */ export function adminHtmlLang(loc: AdminApiLocale): string { if (loc === "zh") { return "zh-Hans"; } if (loc === "ne") { return "ne"; } return "en"; } /** 读取用户上次选择的界面语言(无则 null) */ export function getStoredAdminUiLocale(): AdminApiLocale | null { if (typeof window === "undefined") { return null; } const raw = window.localStorage.getItem(STORAGE_KEY)?.trim().toLowerCase(); if (raw && isApiLocale(raw)) { return raw; } return null; } function writeStoredUiLocale(loc: AdminApiLocale): void { if (typeof window === "undefined") { return; } window.localStorage.setItem(STORAGE_KEY, loc); } /** * 切换界面语言:写入 localStorage、同步 `document.documentElement.lang`、设置 API `X-Locale` 覆盖。 */ export function applyAdminUiLocale(loc: AdminApiLocale): void { setAdminRequestLocale(loc); writeStoredUiLocale(loc); if (typeof document !== "undefined") { document.documentElement.lang = adminHtmlLang(loc); } } /** 启动时从 localStorage 恢复(应在客户端尽早调用一次) */ export function hydrateAdminUiLocale(): AdminApiLocale | null { if (typeof window === "undefined") { return null; } const stored = getStoredAdminUiLocale(); if (stored) { setAdminRequestLocale(stored); document.documentElement.lang = adminHtmlLang(stored); return stored; } setAdminRequestLocale("zh"); return null; } /** 供 `admin-http`:`X-Locale` + `Accept-Language` */ export function withAdminLocaleHeaders( config: AxiosRequestConfig, ): AxiosRequestConfig { const loc = requestLocale(); const merged: AxiosRequestConfig = { ...config }; const headers = AxiosHeaders.concat( merged.headers as Parameters[0], ); headers.set("X-Locale", loc); headers.set("Accept-Language", acceptLanguage(loc)); merged.headers = headers; return merged; }