import { inject , Injectable , InjectionToken } from '@angular/core' ; import { BehaviorSubject , Observable } from 'rxjs' ; import { filter } from 'rxjs/operators' ; import { AlainConfigService , AlainThemeI18nConfig } from '@delon/util/config' ; import type { NzSafeAny } from 'ng-zorro-antd/core/types' ; import { _HttpClient } from '../http/http.client' ; export interface AlainI18NService { [ key ] : NzSafeAny ; /**
     * Call `use` to trigger change notification
     *
     * 调用 `use` 触发变更通知
     */ readonly change : Observable < string > ; /**
     * Get the default language
     *
     * 获取默认语言
     */ readonly defaultLang : string ; /**
     * Get current language
     *
     * 获取当前语言
     */ readonly currentLang : string ; param emit use ( lang , data ? ) : void ; /**
     * Return to the current language list
     *
     * 返回当前语言列表
     */ getLangs ( ) : NzSafeAny [ ] ; param params param isSafe fanyi ( path , params ? ) : string ; } export const ALAIN_I18N_TOKEN = new InjectionToken < AlainI18NService > ( 'alainI18nToken' , { providedIn : 'root' , factory : ( ) => new AlainI18NServiceFake ( inject ( AlainConfigService ) ) } ) ; @ Injectable ( ) export abstract class AlainI18nBaseService implements AlainI18NService { private cog : AlainThemeI18nConfig ; protected _change$ = new BehaviorSubject < string | null > ( null ) ; protected _currentLang : string = '' ; protected _defaultLang : string = '' ; protected _data : Record < string , string > = { } ; get change ( ) : Observable < string > { return this . _change$ . asObservable ( ) . pipe ( filter ( w => w != null ) ) as Observable < string > ; } get defaultLang ( ) : string { return this . _defaultLang ; } get currentLang ( ) : string { return this . _currentLang ; } get data ( ) : Record < string , string > { return this . _data ; } constructor ( cogSrv ) { this . cog = cogSrv . merge ( 'themeI18n' , { interpolation : [ '{{' , '}}' ] } ) ! ; } example flatData ( data , parentKey ) { const res = { } ; for ( const key of Object . keys ( data ) ) { const value = data [ key ] ; if ( typeof value === 'object' ) { const child = this . flatData ( value as Record < string , unknown > , parentKey . concat ( key ) ) ; Object . keys ( child ) . forEach ( childKey => ( res [ childKey ] = child [ childKey ] ) ) ; } else { res [ ( key ? parentKey . concat ( key ) : parentKey ) . join ( '.' ) ] = `${ value }` ; } } return res ; } abstract use ( lang , data ? ) ; abstract getLangs ( ) ; fanyi ( path , params ? ) { let content = this . _data [ path ] || '' ; if ( ! content ) return path ; if ( params ) { const interpolation = this . cog . interpolation ! ! ; Object . keys ( params ) . forEach ( key => ( content = content . replace ( new RegExp ( `${ interpolation [ 0 ] }\s?${ key }\s?${ interpolation [ 1 ] }` , 'g' ) , `${ params [ key ] }` ) ) ) ; } return content ; } } @ Injectable ( { providedIn : 'root' } ) export class AlainI18NServiceFake extends AlainI18nBaseService { use ( lang , data ) { this . _data = this . flatData ( data , [ ] ) ; this . _currentLang = lang ; this . _change$ . next ( lang ) ; } getLangs ( ) { return [ ] ; } }