update
Some checks failed
deploy / deploy (push) Has been cancelled

This commit is contained in:
toom1996
2026-08-16 00:56:59 +08:00
parent 31cb7a125a
commit 781242ede0
26 changed files with 1814 additions and 1214 deletions

56
src/i18n/dictionary.ts Normal file
View File

@ -0,0 +1,56 @@
import { DEFAULT_LOCALE, type Locale } from './config';
/**
* 单文件翻译字典。
*
* 设计(按你的要求):
* - key 就是「英文原文」,直接当文案用,无需额外维护英文副本;
* - value 只存「非默认语言」的翻译(本项目默认语言是 en,所以只存 cn 等);
* - 英文环境调用 t(key) 直接返回 key 本身;
* - 其它语言从 value 里取对应翻译,取不到就回退英文(开发环境会告警,方便发现漏翻)。
*
* 新增一条:直接加一行 `'英文原文': { cn: '中文' }` 即可;
* 当前是英文时根本不需要在字典里登记,写了 t('Nice day!') 就能渲染 "Nice day!"。
*/
// 除默认语言外的所有语言(如 'cn')。加新语言(ja 等)时这里会自动包含。
type OtherLocale = Exclude<Locale, typeof DEFAULT_LOCALE>;
type TranslationEntry = Partial<Record<OtherLocale, string>>;
export const dict: Record<string, TranslationEntry> = {
Portfolio: { cn: '作品集' },
'All Shows': { cn: '全部走秀' },
'Latest Projects': { cn: '最新项目' },
About: { cn: '关于' },
'Contact Us': { cn: '联系我们' },
Login: { cn: '登录' },
Signup: { cn: '注册' },
Contact: { cn: '联系' },
'Back to top': { cn: '回到顶部' },
'© 2026 PORTFOLIO STUDIO. ALL RIGHTS RESERVED.': { cn: '© 2026 PORTFOLIO STUDIO. 保留所有权利。' },
Previous: { cn: '上一组' },
Next: { cn: '下一组' },
};
/** 把 {name} 形式的占位符替换成参数值。 */
function interpolate(text: string, params?: Record<string, string | number>): string {
if (!params) return text;
return text.replace(/\{(\w+)\}/g, (_, k) => (k in params ? String(params[k]) : `{${k}}`));
}
/**
* 取翻译:
* - 当前是默认语言(en)→ 直接返回 key(英文原文);
* - 其它语言 → 优先取字典里的翻译,缺失则回退英文并返回 key(不会白屏)。
*/
export function translate(key: string, locale: Locale, params?: Record<string, string | number>): string {
if (locale === DEFAULT_LOCALE) return interpolate(key, params);
const localized = dict[key]?.[locale as OtherLocale];
if (localized) return interpolate(localized, params);
if (import.meta.env.DEV) {
console.warn(`[i18n] 缺少 "${locale}" 翻译:"${key}",已回退英文`);
}
return interpolate(key, params);
}