import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Observable, of, throwError } from 'rxjs'; import { catchError, map, tap } from 'rxjs/operators'; import { PagedQueryResult, PagedQueryParam } from './models'; import { Utils } from './utils'; declare var isRunning: number; //用于记录有多少ajax请求正在运行 declare var lastActiveTime: Date; // 用于记录最后活动时间 export abstract class BaseService { protected headers = new HttpHeaders({ 'Content-Type': 'application/json' }); constructor(private http: HttpClient) { lastActiveTime = new Date(); } /** * 分页查询 * 参数:url URL地址, queryParam:用于查询的参数。waitLoading: 是否要显示等待加载(缺省true) */ protected searchPage(url: string, queryParam: PagedQueryParam, waitLoading: boolean = true): Observable> { if (waitLoading) { isRunning++; } if (!queryParam.pageNumber) { queryParam.pageNumber = 1; } if (!queryParam.pageSize) { queryParam.pageSize = 10; } if (url.indexOf("?") < 0) { url += "?x=1"; } url += this.toQueryString(queryParam, ""); return this.http.get>(url).pipe( tap(response => { if (waitLoading) { isRunning--; } lastActiveTime = new Date(); let rst: PagedQueryResult = response; this.processDate(rst.datas); }), catchError(err => this.handleError(err, waitLoading)) ); } /** * 把输入的Object转换成请求参数串。 * 如 obj = {a:1, b:[{i:3, k:4},{i:5}],则返回的请求串为: * "&a=1&b[0].i=3&b[0].k=4&b[1].i=6" * */ toQueryString(obj: any, propPrefix: string): string { let url = ""; let preParam = propPrefix; if (preParam) { preParam += "."; } if (obj == undefined) { return url; } if (typeof obj == 'object') { if (obj instanceof Array) { for (let i = 0; i < obj.length; i++) { if (typeof (obj[i]) == 'object') { url = url + this.toQueryString(obj[i], propPrefix + "[" + i + "]"); } else { url = url + "&" + propPrefix + "[" + i + "]" + "=" + this.formatValue(obj[i]); } } } else { for (let prop in obj) { if (prop != "constructor") { let pv = obj[prop]; if (pv) { if (typeof pv == 'function') continue; if (typeof pv == 'object') { url = url + this.toQueryString(pv, preParam + prop); } else { url = url + "&" + preParam + prop + "=" + this.formatValue(obj[prop]); } } } } } } else { url = url + "&" + propPrefix + "=" + this.formatValue(obj); } return url; } private formatValue(val: any) { if (val instanceof Date) { return val.getTime(); } return encodeURI(val); } /** * GET请求 * @param url URL地址 * @param data:用于查询的参数 * @param waitLoading: 是否要显示等待加载(缺省true) */ protected doGet(url: string, data?: any, waitLoading: boolean = true): Observable { if (data) { if (url.indexOf("?") < 0) { url += "?a=1"; } } url += this.toQueryString(data, ""); if (waitLoading) { isRunning++; } return this.http.get(url) .pipe( tap(resp => { if (waitLoading) { isRunning--; } lastActiveTime = new Date(); this.processDate(resp); }), catchError(err => this.handleError(err, waitLoading))); } /** * PUT请求 * @param url URL地址, * @param data:发送到服务器的数据 * @param waitLoading: 是否要显示等待加载(缺省true) */ protected doPut(url: string, data: any, waitLoading: boolean = true): Observable { if (waitLoading) { isRunning++; } return this.http .put(url, data, { headers: this.headers }) .pipe( tap(resp => { if (waitLoading) { isRunning--; } lastActiveTime = new Date(); this.processDate(resp); }), catchError(err => this.handleError(err, waitLoading))); } /** * POST请求 * @param url URL地址 * @param data:要post的数据 * @param waitLoading: 是否要显示等待加载(缺省true) * */ protected doPost(url: string, data: any, waitLoading: boolean = true): Observable { if (waitLoading) { isRunning++; } return this.http .post(url, JSON.stringify(data), { headers: this.headers }) .pipe( tap(response => { if (waitLoading) { isRunning--; } lastActiveTime = new Date(); this.processDate(response); return response; }), catchError(err => this.handleError(err, waitLoading))); } /** * DELETE请求 * @param url URL地址, * @param waitLoading: 是否要显示等待加载(缺省true) */ protected doDelete(url: string, waitLoading: boolean = true): Observable { if (waitLoading) { isRunning++; } return this.http.delete(url, { headers: this.headers }) .pipe( tap(response => this.processResponse(response, waitLoading)), catchError(err => this.handleError(err, waitLoading))); } protected processResponse(response: any, waitLoading: boolean) { if (waitLoading) { isRunning--; } lastActiveTime = new Date(); return this.processDate(response); } protected processDate(rst: any): any { if (rst) { if (Array.isArray(rst)) { for (let r of rst) { this.processDate(r); } } else { for (let p in rst) { if (typeof (rst[p]) == "object") { this.processDate(rst[p]); } else if (p.endsWith("Date") || p.endsWith("Time") || p.endsWith("Timestamp")) { if (typeof (rst[p]) == "number") { rst[p] = new Date(rst[p]); } else if (rst[p].length == 28 && rst[p].indexOf("T") == 10) {//"2017-11-29T12:18:54.921+0000" rst[p] = new Date(rst[p]); } } } } } return rst; } protected handleError(error: any, waitLoading: boolean): Observable { //console.error('An error occurred:'+ error); if (waitLoading) { isRunning--; } lastActiveTime = new Date(); let msg = Utils.resolveJsonErrorMessage(error); return throwError(msg); } }