返回 AiToEarn
api-result.decorator.ts
根目录 / project / aitoearn-electron / server / src / common / decorators / api-result.decorator.ts
1 import {
2 applyDecorators,
3 HttpStatus,
4 RequestMethod,
5 Type,
6 } from '@nestjs/common';
7 import { METHOD_METADATA } from '@nestjs/common/constants';
8 import { ApiExtraModels, ApiResponse, getSchemaPath } from '@nestjs/swagger';
9
10 import { ResOp } from '../model/response.model';
11
12 const baseTypeNames = ['String', 'Number', 'Boolean'];
13
14 function genBaseProp(type: Type<any>) {
15 if (baseTypeNames.includes(type.name))
16 return { type: type.name.toLocaleLowerCase() };
17 else return { $ref: getSchemaPath(type) };
18 }
19
20 /**
21 * @description: 生成返回结果装饰器
22 */
23 export function ApiResult<TModel extends Type<any>>({
24 type,
25 isPage,
26 status,
27 }: {
28 type?: TModel | TModel[];
29 isPage?: boolean;
30 status?: HttpStatus;
31 }) {
32 let prop = null;
33
34 if (Array.isArray(type)) {
35 if (isPage) {
36 prop = {
37 type: 'object',
38 properties: {
39 items: {
40 type: 'array',
41 items: { $ref: getSchemaPath(type[0]) },
42 },
43 meta: {
44 type: 'object',
45 properties: {
46 itemCount: { type: 'number', default: 0 },
47 totalItems: { type: 'number', default: 0 },
48 itemsPerPage: { type: 'number', default: 0 },
49 totalPages: { type: 'number', default: 0 },
50 currentPage: { type: 'number', default: 0 },
51 },
52 },
53 },
54 };
55 } else {
56 prop = {
57 type: 'array',
58 items: genBaseProp(type[0]),
59 };
60 }
61 } else if (type) {
62 prop = genBaseProp(type);
63 } else {
64 prop = { type: 'null', default: null };
65 }
66
67 const model = Array.isArray(type) ? type[0] : type;
68
69 return applyDecorators(
70 ApiExtraModels(model),
71 (
72 target: object,
73 key: string | symbol,
74 descriptor: TypedPropertyDescriptor<any>,
75 ) => {
76 queueMicrotask(() => {
77 const isPost =
78 Reflect.getMetadata(METHOD_METADATA, descriptor.value) ===
79 RequestMethod.POST;
80
81 ApiResponse({
82 status: status ?? (isPost ? HttpStatus.CREATED : HttpStatus.OK),
83 schema: {
84 allOf: [
85 { $ref: getSchemaPath(ResOp) },
86 {
87 properties: {
88 data: prop,
89 },
90 },
91 ],
92 },
93 })(target, key, descriptor);
94 });
95 },
96 );
97 }
98
98 lines TYPESCRIPT