fix: swagger property
This commit is contained in:
@@ -1,5 +1,19 @@
|
||||
{
|
||||
"collection": "@nestjs/schematics",
|
||||
"sourceRoot": "src",
|
||||
"compilerOptions": {}
|
||||
"compilerOptions": {
|
||||
"plugins": [
|
||||
{
|
||||
"name": "@nestjs/swagger",
|
||||
"options": {
|
||||
"classValidatorShim": false,
|
||||
"introspectComments": true,
|
||||
"dtoFileNameSuffix": [
|
||||
".dto.ts",
|
||||
".model.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,24 @@
|
||||
import { Controller } from '@nestjs/common'
|
||||
import { Body, Controller, Param, Post, Put } from '@nestjs/common'
|
||||
import { ApiTags } from '@nestjs/swagger'
|
||||
import { Types } from 'mongoose'
|
||||
import { MongoIdDto } from '~/shared/dto/id.dto'
|
||||
import { PostModel } from './post.model'
|
||||
import { PostService } from './post.service'
|
||||
|
||||
@Controller('posts')
|
||||
@ApiTags('Post Routes')
|
||||
export class PostController {}
|
||||
export class PostController {
|
||||
constructor(private readonly postService: PostService) {}
|
||||
|
||||
@Post('/')
|
||||
async create(@Body() body: PostModel) {
|
||||
const _id = Types.ObjectId()
|
||||
|
||||
return await this.postService.create({
|
||||
...body,
|
||||
slug: body.slug ?? _id.toHexString(),
|
||||
})
|
||||
}
|
||||
@Put('/:id')
|
||||
async update(@Param() params: MongoIdDto) {}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import { ApiHideProperty, ApiProperty } from '@nestjs/swagger'
|
||||
import { index, modelOptions, prop, Ref, Severity } from '@typegoose/typegoose'
|
||||
import { Schema } from 'mongoose'
|
||||
import {
|
||||
ArrayUnique,
|
||||
IsBoolean,
|
||||
IsMongoId,
|
||||
IsNotEmpty,
|
||||
IsOptional,
|
||||
IsString,
|
||||
} from 'class-validator'
|
||||
import { CountMixed as Count, WriteBaseModel } from '~/shared/model/base.model'
|
||||
import { CategoryModel as Category } from '../category/category.model'
|
||||
|
||||
@@ -9,12 +17,19 @@ import { CategoryModel as Category } from '../category/category.model'
|
||||
@modelOptions({ options: { customName: 'Post', allowMixed: Severity.ALLOW } })
|
||||
export class PostModel extends WriteBaseModel {
|
||||
@prop({ trim: true, unique: true, required: true })
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
slug!: string
|
||||
|
||||
@prop()
|
||||
@IsOptional()
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
summary?: string
|
||||
|
||||
@prop({ ref: () => Category, required: true })
|
||||
@IsMongoId()
|
||||
@ApiProperty({ example: '5eb2c62a613a5ab0642f1f7a' })
|
||||
categoryId: Ref<Category>
|
||||
|
||||
@prop({
|
||||
@@ -23,22 +38,28 @@ export class PostModel extends WriteBaseModel {
|
||||
localField: 'categoryId',
|
||||
justOne: true,
|
||||
})
|
||||
@ApiHideProperty()
|
||||
public category: Ref<Category>
|
||||
|
||||
@prop({ default: false })
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
hide?: boolean
|
||||
|
||||
@prop({ default: true })
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
copyright?: boolean
|
||||
|
||||
@prop({
|
||||
type: String,
|
||||
})
|
||||
@IsNotEmpty({ each: true })
|
||||
@IsString({ each: true })
|
||||
@ArrayUnique()
|
||||
@IsOptional()
|
||||
tags?: string[]
|
||||
|
||||
@prop({ type: Count, default: { read: 0, like: 0 }, _id: false })
|
||||
@ApiHideProperty()
|
||||
count?: Count
|
||||
|
||||
@prop({ type: Schema.Types.Mixed })
|
||||
options?: Record<any, any>
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import {
|
||||
BadRequestException,
|
||||
forwardRef,
|
||||
Inject,
|
||||
Injectable,
|
||||
UnprocessableEntityException,
|
||||
} from '@nestjs/common'
|
||||
import { ReturnModelType } from '@typegoose/typegoose'
|
||||
import { omit } from 'lodash'
|
||||
import { InjectModel } from 'nestjs-typegoose'
|
||||
import { CannotFindException } from '~/common/exceptions/cant-find.exception'
|
||||
import { EventTypes } from '~/processors/gateway/events.types'
|
||||
import { WebEventsGateway } from '~/processors/gateway/web/events.gateway'
|
||||
import { CategoryService } from '../category/category.service'
|
||||
import { PostModel } from './post.model'
|
||||
|
||||
@@ -17,16 +20,20 @@ export class PostService {
|
||||
private readonly postModel: ReturnModelType<typeof PostModel>,
|
||||
@Inject(forwardRef(() => CategoryService))
|
||||
private categoryService: CategoryService,
|
||||
private readonly webgateway: WebEventsGateway,
|
||||
) {}
|
||||
|
||||
async create(post: Partial<PostModel>) {
|
||||
async create(post: PostModel) {
|
||||
const { categoryId } = post
|
||||
|
||||
const category = await this.categoryService.findCategoryById(
|
||||
categoryId as any as string,
|
||||
)
|
||||
if (!category) {
|
||||
throw new UnprocessableEntityException('分类丢失了 ಠ_ಠ')
|
||||
throw new BadRequestException('分类丢失了 ಠ_ಠ')
|
||||
}
|
||||
if (await this.isAvailableSlug(post.slug)) {
|
||||
throw new BadRequestException('slug 重复')
|
||||
}
|
||||
const res = await this.postModel.create({
|
||||
...post,
|
||||
@@ -35,14 +42,40 @@ export class PostService {
|
||||
modified: null,
|
||||
})
|
||||
// TODO: clean cache
|
||||
process.nextTick(async () => {
|
||||
this.webgateway.broadcast(EventTypes.POST_CREATE, {
|
||||
...res.toJSON(),
|
||||
category,
|
||||
})
|
||||
// TODO
|
||||
// this.service.RecordImageDimensions(newPostDocument._id)
|
||||
})
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
async findPostById(id: string) {
|
||||
async findById(id: string) {
|
||||
const doc = await this.postModel.findById(id).populate('category')
|
||||
if (!doc) {
|
||||
throw new CannotFindException()
|
||||
}
|
||||
return doc
|
||||
}
|
||||
|
||||
async updateById(id: string, data: Partial<PostModel>) {
|
||||
// 看看 category 改了没
|
||||
const { categoryId } = data
|
||||
if (categoryId) {
|
||||
}
|
||||
this.postModel.updateOne(
|
||||
{
|
||||
_id: id,
|
||||
},
|
||||
omit(data, ['id', '_id']),
|
||||
)
|
||||
}
|
||||
|
||||
async isAvailableSlug(slug: string) {
|
||||
return !!(await this.postModel.countDocuments({ slug }))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { ApiHideProperty } from '@nestjs/swagger'
|
||||
import { modelOptions, prop } from '@typegoose/typegoose'
|
||||
import { IsNotEmpty, IsString } from 'class-validator'
|
||||
import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator'
|
||||
export class BaseModel {
|
||||
@ApiHideProperty()
|
||||
created?: Date
|
||||
}
|
||||
|
||||
@@ -26,9 +28,12 @@ class Image {
|
||||
|
||||
export abstract class BaseCommentIndexModel extends BaseModel {
|
||||
@prop({ default: 0 })
|
||||
@ApiHideProperty()
|
||||
commentsIndex?: number
|
||||
|
||||
@prop({ default: true })
|
||||
@IsBoolean()
|
||||
@IsOptional()
|
||||
allowComment: boolean
|
||||
}
|
||||
|
||||
@@ -43,9 +48,11 @@ export abstract class WriteBaseModel extends BaseCommentIndexModel {
|
||||
text: string
|
||||
|
||||
@prop({ type: Image })
|
||||
@ApiHideProperty()
|
||||
images?: Image[]
|
||||
|
||||
@prop({ default: null })
|
||||
@ApiHideProperty()
|
||||
modified: Date | null
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user