v0.16.0: 后台体验升级——i18n(默认英文)/浅深主题/字号放大/关站维护页/个人设置(头像·语言·主题·密码·MCP Token)/权限管理(菜单+MCP·API)/询盘抽屉翻倍+PHP序列化数据清洗(22.7万行)+去裸JSON
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* # 模块 后台 i18n 核心(React 上下文 + t 函数)
|
||||
* 词典以中文源串为 key(各页面直接 t("中文字符串")),en 词典提供英文译文,
|
||||
* 缺词回退源串(中文)。默认英文:localStorage 未设置时 locale=en。
|
||||
*/
|
||||
import { createContext, useContext, useEffect, useState, type ReactNode } from "react";
|
||||
import {
|
||||
getAdminLocalePref,
|
||||
setAdminLocalePref,
|
||||
type AdminDict,
|
||||
type AdminLocaleDef,
|
||||
} from "./shared";
|
||||
import { en } from "./locales/en";
|
||||
|
||||
// 客户端安全部分原样转出
|
||||
export { ADMIN_LOCALES, ADMIN_LOCALE_STORAGE_KEY, ADMIN_THEME_STORAGE_KEY, getAdminLocalePref, setAdminLocalePref, getAdminThemePref, setAdminThemePref } from "./shared";
|
||||
export type { AdminDict, AdminLocaleDef, AdminTheme } from "./shared";
|
||||
|
||||
/** # 成员变量 词典注册表(locale → AdminDict;en 启动即注册) **/
|
||||
const dicts = new Map<string, AdminDict>([["en", en]]);
|
||||
|
||||
/** # 函数 注册某语言的后台词典 */
|
||||
export function registerAdminDict(code: string, dict: AdminDict): void {
|
||||
dicts.set(code, dict);
|
||||
}
|
||||
|
||||
/** # 函数 构造后台翻译函数:按词典查 key,缺词回退源串(中文),支持 {var} 插值 */
|
||||
export function createAdminT(locale: string) {
|
||||
const d = dicts.get(locale);
|
||||
return (key: string, vars?: Record<string, string | number>): string => {
|
||||
let s: string = d?.[key] ?? key;
|
||||
if (vars) for (const [k, v] of Object.entries(vars)) s = s.replaceAll(`{${k}}`, String(v));
|
||||
return s;
|
||||
};
|
||||
}
|
||||
|
||||
/** # 类型 后台 t 函数 **/
|
||||
export type AdminT = ReturnType<typeof createAdminT>;
|
||||
|
||||
// ---- React 上下文 ----
|
||||
/** # 成员变量 后台语言上下文(默认英文) **/
|
||||
const AdminLocaleContext = createContext<{ locale: string; setLocale: (code: string) => void; t: AdminT }>({
|
||||
locale: "en",
|
||||
setLocale: () => {},
|
||||
t: createAdminT("en"),
|
||||
});
|
||||
|
||||
/** # 组件 后台语言提供者(纯客户端:SSR 渲染英文,水合后读 localStorage 切换,无水合不一致) */
|
||||
export function AdminLocaleProvider(props: { children: ReactNode }) {
|
||||
const [locale, setLocaleState] = useState("en");
|
||||
// 水合后应用本地偏好(effect 中 setState 不触发水合校验)
|
||||
useEffect(() => {
|
||||
setLocaleState(getAdminLocalePref());
|
||||
}, []);
|
||||
/** # 函数 切换后台语言:写 localStorage → 重渲染(组件树即时切换,无需整页刷新) */
|
||||
const setLocale = (code: string) => {
|
||||
setAdminLocalePref(code);
|
||||
setLocaleState(code);
|
||||
};
|
||||
const t = createAdminT(locale);
|
||||
return <AdminLocaleContext.Provider value={{ locale, setLocale, t }}>{props.children}</AdminLocaleContext.Provider>;
|
||||
}
|
||||
|
||||
/** # 函数 组件内取后台语言上下文(locale / setLocale / t) */
|
||||
export function useAdminI18n() {
|
||||
return useContext(AdminLocaleContext);
|
||||
}
|
||||
|
||||
/** # 函数 组件内取后台翻译函数(便捷别名) */
|
||||
export function useAdminT(): AdminT {
|
||||
return useContext(AdminLocaleContext).t;
|
||||
}
|
||||
Reference in New Issue
Block a user