refactor: reorganize project structure and implement self-managed i18n/theme for components

This commit is contained in:
yuding
2025-12-04 15:24:44 +08:00
parent 4dd923f19e
commit c45cdc9f7d
41 changed files with 3081 additions and 2010 deletions

80
src/services/locale.ts Normal file
View 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
View 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();