Files
lotteryAdmin/src/lib/admin-locale.ts
kang 65eaeecf8c feat(agents, i18n): enhance agent management and settlement features with new translations and UI updates
Added new translations for agent management and settlement features in English, Nepali, and Chinese, improving multi-language support. Updated the agents console to reflect changes in funding modes and player details, enhancing user experience. Refactored the admin permission gate to include new logic for handling bound line agents, ensuring better permission management. Additionally, streamlined the UI for agent-related pages and improved navigation to the settlement center, consolidating related functionalities for better accessibility.
2026-06-04 18:01:05 +08:00

135 lines
3.7 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 { 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<AdminApiLocale, string> = {
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";
}
/** 与 `<html lang>` 对齐的 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<typeof AxiosHeaders.concat>[0],
);
headers.set("X-Locale", loc);
headers.set("Accept-Language", acceptLanguage(loc));
merged.headers = headers;
return merged;
}