refactor: reorganize project structure and implement self-managed i18n/theme for components
This commit is contained in:
80
src/services/locale.ts
Normal file
80
src/services/locale.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { LocaleType, TranslationDictionary } from '../locales/types';
|
||||
import { zhCN } from '../locales/zh-CN';
|
||||
import { enUS } from '../locales/en-US';
|
||||
|
||||
type LocaleChangeListener = (locale: LocaleType) => void;
|
||||
|
||||
/**
|
||||
* 语言管理器类
|
||||
*/
|
||||
export class LocaleManager {
|
||||
private currentLocale: LocaleType = 'zh-CN';
|
||||
private messages: Record<LocaleType, TranslationDictionary> = {
|
||||
'zh-CN': zhCN,
|
||||
'en-US': enUS,
|
||||
};
|
||||
private listeners: LocaleChangeListener[] = [];
|
||||
|
||||
constructor() {
|
||||
// 默认初始化
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前语言
|
||||
*/
|
||||
public getLocale(): LocaleType {
|
||||
return this.currentLocale;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换语言
|
||||
*/
|
||||
public setLocale(locale: LocaleType) {
|
||||
if (this.currentLocale === locale) return;
|
||||
this.currentLocale = locale;
|
||||
this.notifyListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* 翻译核心方法
|
||||
*/
|
||||
public t(key: string): string {
|
||||
if (!key) return '';
|
||||
|
||||
const keys = key.split('.');
|
||||
let value: any = this.messages[this.currentLocale];
|
||||
|
||||
for (const k of keys) {
|
||||
if (value && typeof value === 'object' && k in value) {
|
||||
value = value[k];
|
||||
} else {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return value as string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅变更
|
||||
*/
|
||||
public subscribe(listener: LocaleChangeListener): () => void {
|
||||
this.listeners.push(listener);
|
||||
return () => {
|
||||
this.listeners = this.listeners.filter(l => l !== listener);
|
||||
};
|
||||
}
|
||||
|
||||
private notifyListeners() {
|
||||
this.listeners.forEach(listener => listener(this.currentLocale));
|
||||
}
|
||||
}
|
||||
|
||||
// --- 导出单例 ---
|
||||
export const localeManager = new LocaleManager();
|
||||
|
||||
// --- 导出便捷方法 ---
|
||||
/**
|
||||
* 全局翻译函数
|
||||
* @param key 键路径 (如 'toolbar.home')
|
||||
*/
|
||||
export const t = (key: string): string => localeManager.t(key);
|
||||
70
src/services/theme.ts
Normal file
70
src/services/theme.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { ThemeConfig } from '../themes/types';
|
||||
import { darkTheme, lightTheme } from '../themes/presets';
|
||||
|
||||
type ThemeChangeListener = (theme: ThemeConfig) => void;
|
||||
|
||||
/**
|
||||
* 主题管理器 (单例)
|
||||
*/
|
||||
export class ThemeManager {
|
||||
private currentTheme: ThemeConfig = darkTheme;
|
||||
private listeners: ThemeChangeListener[] = [];
|
||||
|
||||
constructor() {
|
||||
// 默认初始化
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前主题配置
|
||||
*/
|
||||
public getTheme(): ThemeConfig {
|
||||
return this.currentTheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换预设主题
|
||||
* @param themeName 'dark' | 'light'
|
||||
*/
|
||||
public setTheme(themeName: 'dark' | 'light') {
|
||||
if (themeName === 'light') {
|
||||
this.applyTheme(lightTheme);
|
||||
} else {
|
||||
this.applyTheme(darkTheme);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用自定义主题配置
|
||||
* @param theme 配置对象
|
||||
*/
|
||||
public setCustomTheme(theme: ThemeConfig) {
|
||||
this.applyTheme(theme);
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部应用主题逻辑
|
||||
*/
|
||||
private applyTheme(theme: ThemeConfig) {
|
||||
this.currentTheme = theme;
|
||||
this.notifyListeners();
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅主题变更
|
||||
*/
|
||||
public subscribe(listener: ThemeChangeListener): () => void {
|
||||
this.listeners.push(listener);
|
||||
// 立即回调一次当前状态
|
||||
listener(this.currentTheme);
|
||||
return () => {
|
||||
this.listeners = this.listeners.filter(l => l !== listener);
|
||||
};
|
||||
}
|
||||
|
||||
private notifyListeners() {
|
||||
this.listeners.forEach(listener => listener(this.currentTheme));
|
||||
}
|
||||
}
|
||||
|
||||
// 导出单例
|
||||
export const themeManager = new ThemeManager();
|
||||
Reference in New Issue
Block a user