bixi
Version:
企业级中后台前端解决方案
115 lines (104 loc) • 3.55 kB
text/typescript
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);
}
}
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(`[/mock]%c${req.method}->${req.urlWithParams}->request`, 'background:#107cee;color:#000', req);
console.log(`[/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));
}
}