add serialize

This commit is contained in:
liuyi 2025-05-20 09:52:51 +08:00
parent 0b98e1c899
commit e2f1180a14
3 changed files with 58 additions and 1 deletions

View File

@ -8,17 +8,22 @@ import {
Patch, Patch,
Post, Post,
Query, Query,
SerializeOptions,
UseInterceptors,
ValidationPipe, ValidationPipe,
} from '@nestjs/common'; } from '@nestjs/common';
import { CreatePostDto, QueryPostDto, UpdatePostDto } from '@/modules/content/dtos/post.dto'; import { CreatePostDto, QueryPostDto, UpdatePostDto } from '@/modules/content/dtos/post.dto';
import { PostService } from '@/modules/content/services/post.service'; import { PostService } from '@/modules/content/services/post.service';
import { AppInterceptor } from '@/modules/core/providers/app.interceptor';
@UseInterceptors(AppInterceptor)
@Controller('posts') @Controller('posts')
export class PostController { export class PostController {
constructor(private postService: PostService) {} constructor(private postService: PostService) {}
@Get() @Get()
@SerializeOptions({ groups: ['post-list'] })
async list( async list(
@Query( @Query(
new ValidationPipe({ new ValidationPipe({
@ -35,11 +40,13 @@ export class PostController {
} }
@Get(':id') @Get(':id')
@SerializeOptions({ groups: ['post-detail'] })
async show(@Param('id', new ParseUUIDPipe()) id: string) { async show(@Param('id', new ParseUUIDPipe()) id: string) {
return this.postService.detail(id); return this.postService.detail(id);
} }
@Post() @Post()
@SerializeOptions({ groups: ['post-detail'] })
async store( async store(
@Body( @Body(
new ValidationPipe({ new ValidationPipe({
@ -57,6 +64,7 @@ export class PostController {
} }
@Patch() @Patch()
@SerializeOptions({ groups: ['post-detail'] })
async update( async update(
@Body( @Body(
new ValidationPipe({ new ValidationPipe({
@ -74,6 +82,7 @@ export class PostController {
} }
@Delete(':id') @Delete(':id')
@SerializeOptions({ groups: ['post-detail'] })
async delete(@Param('id', new ParseUUIDPipe()) id: string) { async delete(@Param('id', new ParseUUIDPipe()) id: string) {
return this.postService.delete(id); return this.postService.delete(id);
} }

View File

@ -1,4 +1,4 @@
import { Expose } from 'class-transformer'; import { Exclude, Expose, Type } from 'class-transformer';
import { import {
BaseEntity, BaseEntity,
Column, Column,
@ -10,36 +10,49 @@ import {
import { PostBodyType } from '@/modules/content/constants'; import { PostBodyType } from '@/modules/content/constants';
@Exclude()
@Entity('content_posts') @Entity('content_posts')
export class PostEntity extends BaseEntity { export class PostEntity extends BaseEntity {
@Expose()
@PrimaryColumn({ type: 'varchar', generated: 'uuid', length: 36 }) @PrimaryColumn({ type: 'varchar', generated: 'uuid', length: 36 })
id: string; id: string;
@Expose()
@Column({ comment: '文章标题' }) @Column({ comment: '文章标题' })
title: string; title: string;
@Expose({ groups: ['post-detail'] })
@Column({ comment: '文章内容', type: 'text' }) @Column({ comment: '文章内容', type: 'text' })
body: string; body: string;
@Expose()
@Column({ comment: '文章描述', nullable: true }) @Column({ comment: '文章描述', nullable: true })
summary?: string; summary?: string;
@Expose()
@Expose() @Expose()
@Column({ comment: '关键字', type: 'simple-array', nullable: true }) @Column({ comment: '关键字', type: 'simple-array', nullable: true })
keywords?: string[]; keywords?: string[];
@Expose()
@Column({ comment: '文章类型', type: 'enum', enum: PostBodyType, default: PostBodyType.HTML }) @Column({ comment: '文章类型', type: 'enum', enum: PostBodyType, default: PostBodyType.HTML })
type: PostBodyType; type: PostBodyType;
@Expose()
@Column({ comment: '发布时间', type: 'varchar', nullable: true }) @Column({ comment: '发布时间', type: 'varchar', nullable: true })
publishedAt?: Date | null; publishedAt?: Date | null;
@Expose()
@Column({ comment: '自定义文章排序', default: 0 }) @Column({ comment: '自定义文章排序', default: 0 })
customOrder: number; customOrder: number;
@Expose()
@Type(() => Date)
@CreateDateColumn({ comment: '创建时间' }) @CreateDateColumn({ comment: '创建时间' })
createdAt?: Date; createdAt?: Date;
@Expose()
@Type(() => Date)
@UpdateDateColumn({ comment: '更新时间', nullable: true }) @UpdateDateColumn({ comment: '更新时间', nullable: true })
updatedAt?: Date; updatedAt?: Date;
} }

View File

@ -0,0 +1,35 @@
import {
ClassSerializerContextOptions,
ClassSerializerInterceptor,
PlainLiteralObject,
StreamableFile,
} from '@nestjs/common';
import { isArray, isNil, isObject } from 'lodash';
export class AppInterceptor extends ClassSerializerInterceptor {
serialize(
response: PlainLiteralObject | Array<PlainLiteralObject>,
options: ClassSerializerContextOptions,
): PlainLiteralObject | Array<PlainLiteralObject> {
if ((!isObject(response) && !isArray(response)) || response instanceof StreamableFile) {
return response;
}
if (isArray(response)) {
return (response as PlainLiteralObject[]).map((item) => {
return !isObject(item) ? item : this.transformToPlain(item, options);
});
}
if ('meta' in response && 'items' in response) {
const items = !isNil(response.items) && isArray(response.items) ? response.items : [];
return {
...response,
items: (items as PlainLiteralObject[]).map((item) => {
return isObject(item) ? this.transformToPlain(item, options) : item;
}),
};
}
return super.transformToPlain(response, options);
}
}