@alauda-fe/common
Version:
Alauda frontend team common codes.
310 lines (309 loc) • 10.9 kB
TypeScript
/**
* @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>;
}