import { Injectable, InjectionToken, Injector } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { NaUtils } from '@ng-arthur-mobile/common'; import { map, switchMap, tap, catchError } from 'rxjs/operators'; import { of, throwError } from 'rxjs'; export interface IStartupConfigResource { /** 前缀 */ prefix: string; /** 后缀 */ suffix: string; } export const NA_STARTUP_CONFIG = new InjectionToken( 'NA_STARTUP_CONFIG' ); /** * 用于应用启动时 * * 一般用来获取应用所需要的基础数据等 * * @export */ @Injectable() export class NaStartupService { private _startupConfig: any = {}; private initialized = false; private cache = new Map(); constructor(private client: HttpClient) { } /** * 启动加载 * * TODO ssr注入`HttpClient`在使用client时会有异常 * @param startupConfig 启动配置文件 */ // load(startupConfig: IStartupConfigResource): Promise { // return new Promise((resolve, reject) => { // const filePath = startupConfig.prefix + startupConfig.suffix; // this.client.get(filePath).subscribe( // (next: any) => { // const rtnData = Object.assign({}, next); // const profiles = next.profiles; // if (profiles && profiles.active) { // const file = startupConfig.prefix + '-' + profiles.active + startupConfig.suffix; // const params = {}; // // params[NaConstant.HTTP.RTN_ERROR_PROMPT] = false; // this.client.get(file, {params: params}).subscribe( // data => { // NaUtils.mergeJSON(rtnData, data); // console.log(data, rtnData); // resolve(true); // }, // err => { // console.log(err); // reject(err); // }, // () => { // this._startupConfig = rtnData; // } // ); // } // }, // error => { // console.error(`the profiles does not exist or error. please check the profiles active.`, error); // reject(error); // } // ); // }); // } load(startupConfig: IStartupConfigResource) { const filePath = startupConfig.prefix + startupConfig.suffix; return this.client.get(filePath).pipe( switchMap((value: any) => { const rtnData = Object.assign({}, value); const profiles = value.profiles; if (profiles && profiles.active) { const file = startupConfig.prefix + '-' + profiles.active + startupConfig.suffix; const params = {}; // params[NaConstant.HTTP.RTN_ERROR_PROMPT] = false; return this.client.get(file, { params: params }).pipe( map((resp: any) => { NaUtils.mergeJSON(rtnData, resp); return rtnData; }) ); } else { return of(rtnData); } }), tap(next => { this._startupConfig = next; this.initialized = true; }), catchError(err => { console.error(`the profiles does not exist or error. please check the profiles active.`, err); return throwError(err); }) ) .toPromise(); } get(key: string) { if (!this.initialized) { throw new Error('未加载完毕!'); } return this.getValue(this._startupConfig, key); } private getValue(target: any, key: string): any { if (this.cache.has(key)) { return this.cache.get(key); } const keys = key.split('.'); key = ''; do { key += keys.shift(); if (NaUtils.isDefined(target) && NaUtils.isDefined(target[key]) && (typeof target[key] === 'object' || !keys.length)) { target = target[key]; key = ''; } else if (!keys.length) { target = undefined; } else { key += '.'; } } while (keys.length); this.cache.set(key, target); return target; } // private find(data: any, key: string) { // const keys = key.split('.'); // let val = data; // if (val == null) { // alert('pls init config'); // throw new Error('pls init config, use APP_INITIALIZER'); // } // keys.forEach(k => { // if (val) { // val = val[k]; // } // }); // return val; // } }