feat: openapi decorator

This commit is contained in:
Innei
2021-09-05 16:21:00 +08:00
parent a17afd068f
commit f4f147b488
8 changed files with 102 additions and 25 deletions

View File

@@ -0,0 +1,6 @@
import { ApiTags } from '@nestjs/swagger'
export const ApiName: ClassDecorator = (target) => {
const [name] = target.name.split('Controller')
ApiTags(name + ' Routes').call(null, target)
}

View File

@@ -1,12 +1,3 @@
/*
* @Author: Innei
* @Date: 2020-05-26 11:10:24
* @LastEditTime: 2020-05-30 14:12:53
* @LastEditors: Innei
* @FilePath: /mx-server/src/auth/auth.controller.ts
* @Copyright
*/
import {
Body,
Controller,
@@ -17,7 +8,7 @@ import {
Scope,
UseGuards,
} from '@nestjs/common'
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger'
import { ApiBearerAuth, ApiOperation } from '@nestjs/swagger'
import { Transform } from 'class-transformer'
import {
IsDate,
@@ -27,11 +18,10 @@ import {
IsString,
} from 'class-validator'
import { Auth } from '~/common/decorator/auth.decorator'
import { IsGuest, IsMaster as Master } from '~/common/decorator/role.decorator'
import { ApiName } from '~/common/decorator/openapi.decorator'
import { IsMaster as Master } from '~/common/decorator/role.decorator'
import { MongoIdDto } from '~/shared/dto/id.dto'
import { AdminEventsGateway } from '../../processors/gateway/admin/events.gateway'
import { AuthService } from './auth.service'
import { RolesGuard } from './roles.guard'
@@ -50,7 +40,7 @@ export class TokenDto {
path: 'auth',
scope: Scope.REQUEST,
})
@ApiTags('Auth Routes')
@ApiName
export class AuthController {
constructor(
private readonly authService: AuthService,

View File

@@ -11,10 +11,11 @@ import {
Query,
Req,
} from '@nestjs/common'
import { ApiOperation, ApiParam, ApiTags } from '@nestjs/swagger'
import { ApiOperation, ApiParam } from '@nestjs/swagger'
import { DocumentType } from '@typegoose/typegoose'
import { Auth } from '~/common/decorator/auth.decorator'
import { IpLocation, IpRecord } from '~/common/decorator/ip.decorator'
import { ApiName } from '~/common/decorator/openapi.decorator'
import { IsMaster } from '~/common/decorator/role.decorator'
import { CannotFindException } from '~/common/exceptions/cant-find.exception'
import { EventTypes } from '~/processors/gateway/events.types'
@@ -31,7 +32,7 @@ import {
import { CommentModel, CommentRefTypes, CommentState } from './comment.model'
import { CommentService } from './comment.service'
@Controller({ path: 'comments' })
@ApiTags('Comment Routes')
@ApiName
export class CommentController {
constructor(
private readonly commentService: CommentService,

View File

@@ -1,11 +1,11 @@
import { Controller, Get } from '@nestjs/common'
import { ApiTags } from '@nestjs/swagger'
import { ApiName } from '~/common/decorator/openapi.decorator'
import { UserService } from '../user/user.service'
@Controller({
path: '/init',
})
@ApiTags('Init Routes')
@ApiName
export class InitController {
constructor(private readonly userService: UserService) {}

View File

@@ -1,4 +1,30 @@
import { Controller } from '@nestjs/common'
import { Controller, Get } from '@nestjs/common'
import { ApiOperation } from '@nestjs/swagger'
import { IpLocation, IpRecord } from '~/common/decorator/ip.decorator'
import { ApiName } from '~/common/decorator/openapi.decorator'
import { IsMaster } from '~/common/decorator/role.decorator'
import { addConditionToSeeHideContent } from '~/utils/query.util'
import { NoteService } from './note.service'
@ApiName
@Controller({ path: 'notes' })
export class NoteController {}
export class NoteController {
constructor(private readonly noteService: NoteService) {}
@Get('latest')
@ApiOperation({ summary: '获取最新发布一篇记录' })
async getLatestOne(
@IsMaster() isMaster: boolean,
@IpLocation() location: IpRecord,
) {
const { latest, next } = await this.noteService.getLatestOne(
{
...addConditionToSeeHideContent(isMaster),
},
isMaster ? '+location +coordinates' : '-location -coordinates',
)
// this.noteService.shouldAddReadCount(latest, location.ip)
return { data: latest.toObject(), next: next.toObject() }
}
}

View File

@@ -1,5 +1,8 @@
import { Injectable } from '@nestjs/common'
import { DocumentType } from '@typegoose/typegoose'
import { FilterQuery } from 'mongoose'
import { InjectModel } from 'nestjs-typegoose'
import { CannotFindException } from '~/common/exceptions/cant-find.exception'
import { NoteModel } from './note.model'
@Injectable()
@@ -7,9 +10,58 @@ export class NoteService {
constructor(
@InjectModel(NoteModel)
private readonly noteModel: MongooseModel<NoteModel>,
) {}
) {
this.needCreateDefult()
}
public get model() {
return this.noteModel
}
async getLatestOne(
condition: FilterQuery<DocumentType<NoteModel>> = {},
projection: any = undefined,
) {
// TODO master
const latest = await this.noteModel
.findOne(condition, projection)
.sort({
created: -1,
})
.exec()
if (!latest) {
throw new CannotFindException()
}
// 是否存在上一条记录 (旧记录)
// 统一: next 为较老的记录 prev 为较新的记录
// FIXME may cause bug
const next = await this.noteModel
.findOne({
created: {
$lt: latest.created,
},
})
.sort({
created: -1,
})
.select('nid _id')
return {
latest,
next,
}
}
async needCreateDefult() {
await this.noteModel.countDocuments({}).then((count) => {
if (!count) {
this.noteModel.countDocuments({
title: '第一篇日记',
text: 'Hello World',
})
}
})
}
}

View File

@@ -12,10 +12,11 @@ import {
Query,
UseGuards,
} from '@nestjs/common'
import { ApiOperation, ApiTags } from '@nestjs/swagger'
import { ApiOperation } from '@nestjs/swagger'
import { Types } from 'mongoose'
import { Auth } from '~/common/decorator/auth.decorator'
import { Paginator } from '~/common/decorator/http.decorator'
import { ApiName } from '~/common/decorator/openapi.decorator'
import { IsMaster } from '~/common/decorator/role.decorator'
import { UpdateDocumentCount } from '~/common/decorator/update-count.decorator'
import { CannotFindException } from '~/common/exceptions/cant-find.exception'
@@ -31,7 +32,7 @@ import { PartialPostModel, PostModel } from './post.model'
import { PostService } from './post.service'
@Controller('posts')
@ApiTags('Post Routes')
@ApiName
@UseGuards(RolesGuard)
export class PostController {
constructor(private readonly postService: PostService) {}

View File

@@ -9,10 +9,11 @@ import {
UseGuards,
} from '@nestjs/common'
import { AuthGuard } from '@nestjs/passport'
import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger'
import { ApiBearerAuth, ApiOperation } from '@nestjs/swagger'
import { HttpCache } from '~/common/decorator/cache.decorator'
import { CurrentUser } from '~/common/decorator/current-user.decorator'
import { IpLocation, IpRecord } from '~/common/decorator/ip.decorator'
import { ApiName } from '~/common/decorator/openapi.decorator'
import { IsMaster } from '~/common/decorator/role.decorator'
import { getAvatar } from '~/utils/index.util'
import { AuthService } from '../auth/auth.service'
@@ -21,7 +22,7 @@ import { LoginDto, UserDto, UserPatchDto } from './user.dto'
import { UserDocument, UserModel } from './user.model'
import { UserService } from './user.service'
@ApiTags('User Routes')
@ApiName
@Controller(['master', 'user'])
export class UserController {
constructor(