import { IMiddleware } from '@midwayjs/core'; import { Middleware, App } from '@midwayjs/decorator'; import { NextFunction, Context, Application } from '@midwayjs/koa'; import { VOBase } from '../interface/VOBase'; import { get } from 'lodash'; import { ErrorVO } from '../interface/ErrorVO'; import { ServiceError } from '../error/service.error'; /** * 返回结果处理拦截器 * 响应头的content-type含有'/files'的情况为请求文件,重写响应头即可 * 正常请求都要通过视图处理基类(VOBase)格式化后返回 */ @Middleware() export class ResponseMiddleware implements IMiddleware { @App() app: Application; resolve() { return async (ctx: Context, next: NextFunction) => { await next(); // 过滤掉 api文档的请求 const swaggerPath = this.app.getConfig()?.swagger?.swaggerPath; const url = get(ctx, 'request.originalUrl'); if (!url.includes(swaggerPath)) { //检查返回头,如果返回头中有/files,那就说明是读取文件.不能更改body const response = ctx.response; const resHeaderContentType = response.header['content-type'] as string; // 没有数据的情况,保证也可以返回 if (!resHeaderContentType || !resHeaderContentType.includes('/files')) { const body = response.body; if (body instanceof ServiceError) { const r = new ErrorVO(body); return r; } const nb = new VOBase(body as object); return nb; } else { response.set('content-type', resHeaderContentType.replace('/files', '')); } } }; } static getName(): string { return 'response'; } }