feat(i18n): 管理端与玩家端三语支持(中/英/马来语)

- 管理后台 adminT 文案库、结算与代理端页面、表单校验
- 玩家端 vue-i18n 补全首页/公告/串关与 ms 文案
- Element Plus ms 语言包与共享 locale 工具
This commit is contained in:
2026-06-03 15:05:36 +08:00
parent 80adc0e928
commit cbfa18d1d3
63 changed files with 3081 additions and 1038 deletions

View File

@@ -1,6 +1,18 @@
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../../shared/prisma/prisma.service';
function pickContentTranslation<T extends { locale: string }>(
translations: T[],
locale: string,
): T | undefined {
const chain = [locale, 'en-US', 'zh-CN'];
for (const loc of chain) {
const hit = translations.find((tr) => tr.locale === loc);
if (hit) return hit;
}
return translations[0];
}
@Injectable()
export class ContentService {
constructor(private prisma: PrismaService) {}
@@ -19,10 +31,7 @@ export class ContentService {
});
return items.map((item) => {
const t =
item.translations.find((tr) => tr.locale === locale) ||
item.translations.find((tr) => tr.locale === 'en-US') ||
item.translations[0];
const t = pickContentTranslation(item.translations, locale);
return { ...item, translation: t };
});
}

View File

@@ -1,8 +1,6 @@
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../../../shared/prisma/prisma.service';
import { DEFAULT_LOCALE } from '@thebet365/shared';
const FALLBACK_ORDER = ['en-US', 'zh-CN', 'ms-MY'];
import { resolveTranslationFallback } from '@thebet365/shared';
@Injectable()
export class I18nService {
@@ -10,7 +8,7 @@ export class I18nService {
async getMessages(locale: string) {
const messages = await this.prisma.i18nMessage.findMany({
where: { locale: { in: [locale, ...FALLBACK_ORDER] } },
where: { locale: { in: [locale, 'en-US', 'zh-CN', 'ms-MY'] } },
});
const byKey: Record<string, Record<string, string>> = {};
@@ -21,10 +19,8 @@ export class I18nService {
const result: Record<string, string> = {};
for (const [key, locales] of Object.entries(byKey)) {
result[key] =
locales[locale] ||
FALLBACK_ORDER.map((l) => locales[l]).find(Boolean) ||
key;
const resolved = resolveTranslationFallback(locales, locale);
result[key] = resolved || key;
}
return result;
}