UNPKG

@alauda-fe/common

Version:

Alauda frontend team common codes.

310 lines (309 loc) 10.9 kB
/** * @packageDocumentation * @module translate */ import { HttpClient } from '@angular/common/http'; import { OnDestroy } from '@angular/core'; import { Observable } from 'rxjs'; import { TranslateKey, TranslateOptions, Translation, Translations, TemplateData } from './types'; import * as i0 from "@angular/core"; /** * 国际化翻译服务 * * 特性: * - 支持多层级翻译优先级(远程翻译 > 手动添加翻译 > 配置翻译) * - 支持动态语言切换 * - 支持 ICU Message Format 模板插值 * - 支持宽松模式语言匹配 * - 支持异步远程翻译加载 */ export declare class TranslateService implements OnDestroy { private readonly http; private readonly baseHref; /** 翻译添加通知流 */ private readonly translationsAdded$$; readonly translationsAdded$: Observable<void>; /** 组件销毁通知流 */ private readonly destroy$$; /** 本地翻译列表(优先级:后加入的优先级更高) */ readonly translationsList: Array<Readonly<Translations>>; /** 远程翻译列表(优先级最高) */ readonly remoteTranslationsList: Array<Readonly<Translations>>; /** 翻译配置选项 */ readonly options: TranslateOptions; /** 当前语言环境 */ locale: string; /** 当前语言环境(响应式) */ readonly locale$: Observable<string>; /** 获取支持的语言列表 */ get locales(): string[]; /** 获取回退语言 */ get fallbackLocale(): string; constructor(http: HttpClient, baseHref: string, options: TranslateOptions, translationList: Translations[]); /** * 组件销毁清理 */ ngOnDestroy(): void; /** * 获取翻译文本并进行模板插值 * 支持两种模板语法: * 1. 传统的 {{ key }} 语法,使用 lodash template 处理 * 2. ICU Message Format 语法,使用 IntlMessageFormat 处理 * @param key - 翻译键或翻译对象 * @param data - 模板数据(支持基本类型、Date、对象和数组) * @returns 翻译后的文本 * * @example * ```typescript * // lodash template 语法 * translate.get('hello', { name: 'World' }) // 模板: "Hello {{ name }}" * * // ICU Message Format 语法 * translate.get('itemCount', { count: 5 }) // 模板: "Items: {count, number}" * translate.get('createdAt', { date: new Date() }) // 模板: "Created: {date, date, short}" * ``` */ get(key: TranslateKey, data?: TemplateData): string; /** * 获取原始翻译文本模板(不进行插值处理) * @param key - 翻译键或翻译对象 * @returns 原始翻译模板文本 */ getRaw(key: TranslateKey): string; /** * 切换到下一个支持的语言环境 */ toggleLocale(): void; /** * 设置当前语言环境 * @param locale - 要设置的语言环境 */ setLocale(locale: string): void; /** * 手动添加翻译包 * @param translations - 要添加的翻译包 */ addTranslations(translations: Translations): void; /** * 添加远程翻译包 * @param remoteUrl - 远程翻译文件URL */ addRemoteTranslations(remoteUrl: string): void; /** * 从远程URL获取翻译数据 * @param remoteUrl - 远程URL * @param locale - 可选的语言环境(用于URL模板替换) * @returns 翻译数据的Observable */ fetchTranslation(remoteUrl: string): Observable<Translations>; fetchTranslation(remoteUrl: string, locale: string): Observable<Translation>; /** * 获取初始语言环境 */ private getInitialLocale; /** * 获取初始翻译列表 */ private getInitializeTranslations; /** * 加载远程翻译 */ private loadRemoteTranslations; /** * 转换模板数据为 ICU 兼容格式 * @param data - 模板数据 * @returns ICU 兼容的数据对象 */ private normalizeIcuData; /** * 转换对象的所有属性为 ICU 兼容值 */ private convertObjectToIcuData; /** * 将单个值转换为 ICU 兼容类型 * 按照 ICU MessageFormat 规范,只支持 string | number | Date */ private convertValueToIcuValue; /** * 处理模板错误 */ private handleTemplateError; /** * 使用 lodash template 格式化文本 * @param message - 包含 {{ }} 语法的模板字符串 * @param data - 模板数据 * @returns 格式化后的字符串 */ private formatLodashTemplate; /** * 标准化模板数据为对象格式 * @param data - 原始模板数据 * @returns 标准化后的对象或数组(为了向后兼容) */ private normalizeTemplateData; /** * 使用 ICU message format 格式化文本 */ private formatIcuMessage; /** * 格式化数字 * @param value - 要格式化的数字 * @param options - 格式化选项 * @returns 格式化后的数字字符串 * * @example * formatNumber(1234.56) // "1,234.56" * formatNumber(0.85, { style: 'percent' }) // "85%" * formatNumber(1234.56, { style: 'currency', currency: 'CNY' }) // "¥1,234.56" */ formatNumber(value: number, options?: Intl.NumberFormatOptions): string; /** * 格式化货币 * @param value - 要格式化的金额 * @param currency - 货币代码,默认为 CNY * @param options - 其他格式化选项 * @returns 格式化后的货币字符串 * * @example * formatCurrency(1234.56) // en-US: "CN¥1,234.56", zh-CN: "¥1,234.56" * formatCurrency(1234.56, 'USD') // en-US: "$1,234.56", zh-CN: "US$1,234.56" */ formatCurrency(value: number, currency?: string, options?: Omit<Intl.NumberFormatOptions, 'style' | 'currency'>): string; /** * 格式化百分比 * @param value - 要格式化的值(0.85 表示 85%) * @param options - 格式化选项 * @returns 格式化后的百分比字符串 * * @example * formatPercent(0.85) // "85%" * formatPercent(0.8567, { minimumFractionDigits: 2 }) // "85.67%" */ formatPercent(value: number, options?: Omit<Intl.NumberFormatOptions, 'style'>): string; /** * 格式化日期 * @param date - 要格式化的日期 * @param options - Intl.DateTimeFormatOptions 格式配置 * @returns 格式化后的日期字符串 * * @example * formatDate(new Date()) // en-US: "01/01/2025", zh-CN: "2025/01/01" * formatDate(new Date(), { dateStyle: 'full' }) // "2024年8月20日星期二" * formatDate(new Date(), { year: 'numeric', month: '2-digit', day: '2-digit' }) // 根据locale格式化 * formatDate(new Date(), { year: 'numeric', month: 'long' }) // "2024年8月" */ formatDate(date: Date | string | number, options?: Intl.DateTimeFormatOptions): string; /** * 格式化日期和时间 * @param date - 要格式化的日期时间 * @param options - Intl.DateTimeFormatOptions 格式配置 * @returns 格式化后的日期时间字符串 * * @example * formatDateTime(new Date()) // en-US: "01/01/2025, 14:30:00", zh-CN: "2025/01/01 14:30:00" * formatDateTime(new Date(), { dateStyle: 'medium', timeStyle: 'short' }) // "2024年8月20日 14:30" * formatDateTime(new Date(), { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false }) // 根据locale格式化 */ formatDateTime(date: Date | string | number, options?: Intl.DateTimeFormatOptions): string; /** * 格式化相对时间 * @param value - 时间差值(数字)或日期对象 * @param unit - 时间单位(当value为数字时必须提供) * @param options - 格式化选项 * @returns 格式化后的相对时间字符串 * * @example * // 手动指定单位 * formatRelativeTime(-1, 'day') // en-US: "yesterday", zh-CN: "昨天" * formatRelativeTime(2, 'hour') // en-US: "in 2 hours", zh-CN: "2小时后" * formatRelativeTime(-30, 'minute') // en-US: "30 minutes ago", zh-CN: "30分钟前" * * // 自动计算单位 * formatRelativeTime(new Date(Date.now() - 60000)) // "1 minute ago" * formatRelativeTime(new Date(Date.now() + 7200000)) // "in 2 hours" * formatRelativeTime(new Date(Date.now() - 86400000)) // "yesterday" */ formatRelativeTime(value: Date, options?: Intl.RelativeTimeFormatOptions): string; formatRelativeTime(value: number, unit: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions): string; /** * 根据日期计算相对时间差值和最合适的单位 * @param date - 目标日期 * @returns 包含时间差值和单位的对象 */ private calculateRelativeTime; /** * 根据日期格式配置格式化日期 * 使用标准 Intl.DateTimeFormatOptions 确保格式可预测性 */ private formatDateByOptions; /** * 处理无效语言环境 */ private handleInvalidLocale; /** * 验证语言环境是否有效 */ private isValidLocale; /** * 检查重复翻译(开发模式) */ private checkForDuplicateTranslations; /** * 标准化远程URL */ private normalizeRemoteUrl; /** * 验证远程URL(开发模式) */ private validateRemoteUrl; /** * 创建远程翻译请求 */ private createRemoteTranslationRequest; /** * 创建多语言请求 */ private createMultiLocaleRequest; /** * 创建单语言请求 */ private createSingleLocaleRequest; /** * 执行翻译请求 */ private performTranslationRequest; /** * 验证fetchTranslation参数 */ private validateFetchTranslationParams; /** * 通过键查找翻译文本 */ private getTranslationByKey; /** * 在所有翻译源中查找键值 */ private findInAllTranslations; /** * 在翻译列表中查找键值 */ private findInTranslationsList; /** * 在单个翻译对象中查找键值 */ private findInTranslation; /** * 从Translation对象中获取翻译值(支持宽松匹配和回退逻辑) */ private getTranslationByObject; /** * 验证翻译值(开发模式) */ private validateTranslationValue; /** * 比较翻译键(开发模式下检查重复) */ private compareTranslationKeys; static ɵfac: i0.ɵɵFactoryDeclaration<TranslateService, [null, null, { optional: true; }, { optional: true; }]>; static ɵprov: i0.ɵɵInjectableDeclaration<TranslateService>; }