UNPKG

bixi

Version:

企业级中后台前端解决方案

115 lines (104 loc) 3.55 kB
import { HttpBackend, HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse, HttpResponseBase, HTTP_INTERCEPTORS } from '@angular/common/http'; import { Injectable, Injector } from '@angular/core'; import { Observable, of, throwError } from 'rxjs'; import { delay } from 'rxjs/operators'; import { MOCK_CONFIG } from './mock-config.token'; import { MOCK_DATA_DEFAULT, MOCK_DEFULAT_CONFIG } from './mock.config'; import { MockService } from './mock.service'; import { IMockConfig, IMockRequest, ISafeAny } from './mock.type'; class HttpMockInterceptorHandler implements HttpHandler { constructor(private next: HttpHandler, private interceptor: HttpInterceptor) { } handle(req: HttpRequest<ISafeAny>): Observable<HttpEvent<ISafeAny>> { return this.interceptor.intercept(req, this.next); } } @Injectable() export class MockInterceptor implements HttpInterceptor { config: IMockConfig; constructor(private injector: Injector) { const injectConfig: IMockConfig = this.injector.get(MOCK_CONFIG); this.config = { ...MOCK_DEFULAT_CONFIG, ...injectConfig }; } intercept(req: HttpRequest<ISafeAny>, next: HttpHandler): Observable<HttpEvent<ISafeAny>> { const mockService = this.injector.get(MockService); const result = mockService.getCollect(req.method, req.url); if (!result) { // 跳出拦截器 return next.handle(req); } let res: ISafeAny; let resultValue = result.value; if (typeof resultValue === 'function') { resultValue = { value: resultValue }; } const mockValue = { ...MOCK_DATA_DEFAULT, ...resultValue }; if (mockValue.disable) { return next.handle(req); } switch (typeof mockValue.value) { case 'function': const mockReq: IMockRequest = { params: result?.params, query: result?.query, _httpReq: req }; try { res = mockValue.value.call(this, mockReq); } catch (e) { const { status, error } = e; res = new HttpErrorResponse({ url: req.url, status, error }); } break; default: res = mockValue?.value; } if (this.config.interceptors?.response) { res = this.config.interceptors.response(res); } if (!(res instanceof HttpResponseBase)) { res = new HttpResponse({ status: 200, url: req.url, body: res }); } if (this.config.log) { console.log(`[@bixi/mock]%c${req.method}->${req.urlWithParams}->request`, 'background:#107cee;color:#000', req); console.log(`[@bixi/mock]%c${req.method}->${req.urlWithParams}->response`, 'background:#107cee;color:#000', res); } const res$ = res instanceof HttpErrorResponse ? throwError(res) : of(res); if (!this.config.ignoreOtherInterceptors) { const interceptors = this.injector.get(HTTP_INTERCEPTORS, []); const nextInterceptors = interceptors.slice(interceptors.indexOf(this) + 1); if (nextInterceptors.length > 0) { return nextInterceptors.reduceRight( // 依次执行剩余拦截器 (_next: HttpHandler, _interceptor: HttpInterceptor) => new HttpMockInterceptorHandler(_next, _interceptor) , { handle: () => res$ } as HttpBackend).handle(req).pipe(delay(mockValue.delay || this.config.delay || 300)); } } return res$.pipe(delay(mockValue.delay || this.config.delay || 300)); } }