feat:数据关联与树形数据嵌套结构的分类和评论实现

- 实现分类、评论、标签实体
- 使用了Materialized Path实现树形嵌套
- 对分类、评论、标签的存储库进行自定义改造
This commit is contained in:
2023-12-03 18:06:47 +08:00
parent cce9a6b179
commit 781962dce0
34 changed files with 1756 additions and 415 deletions
@@ -0,0 +1,95 @@
import {
Body,
Controller,
Delete,
Get,
Param,
ParseUUIDPipe,
Patch,
Post,
Query,
SerializeOptions,
UseInterceptors,
ValidationPipe,
} from '@nestjs/common';
import { CreateCategoryDto, QueryCategoryDto, UpdateCategoryDto } from '@/modules/content/dtos';
import { CategoryService } from '@/modules/content/services';
import { AppIntercepter } from '@/modules/core/providers';
@UseInterceptors(AppIntercepter)
@Controller('categories')
export class CategoryController {
constructor(protected service: CategoryService) {}
@Get('tree')
@SerializeOptions({ groups: ['category-tree'] })
async tree() {
return this.service.findTress();
}
@Get()
@SerializeOptions({ groups: ['category-list'] })
async list(
@Query(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
forbidUnknownValues: true,
validationError: { target: false },
}),
)
options: QueryCategoryDto,
) {
return this.service.paginate(options);
}
@Get(':id')
@SerializeOptions({ groups: ['category-detail'] })
async detail(@Param('id', new ParseUUIDPipe()) id: string) {
return this.service.detail(id);
}
@Post()
@SerializeOptions({ groups: ['category-detail'] })
async create(
@Body(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
forbidUnknownValues: true,
validationError: { target: false },
groups: ['create'],
}),
)
data: CreateCategoryDto,
) {
return this.service.create(data);
}
@Patch()
@SerializeOptions({ groups: ['category-detail'] })
async update(
@Body(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
forbidUnknownValues: true,
validationError: { target: false },
groups: ['update'],
}),
)
data: UpdateCategoryDto,
) {
return this.service.update(data);
}
@Delete(':id')
@SerializeOptions({ groups: ['category-detail'] })
async delete(@Param('id', new ParseUUIDPipe()) id: string) {
return this.service.delete(id);
}
}
@@ -0,0 +1,78 @@
import {
Body,
Controller,
Delete,
Get,
Param,
ParseUUIDPipe,
Post,
Query,
SerializeOptions,
UseInterceptors,
ValidationPipe,
} from '@nestjs/common';
import { CreateCommentDto, QueryCommentDto, QueryCommentTreeDto } from '@/modules/content/dtos';
import { CommentService } from '@/modules/content/services';
import { AppIntercepter } from '@/modules/core/providers';
@UseInterceptors(AppIntercepter)
@Controller('comments')
export class CommentController {
constructor(protected service: CommentService) {}
@Get('tree')
@SerializeOptions({ groups: ['comment-tree'] })
async tree(
@Query(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
forbidUnknownValues: true,
validationError: { target: false },
}),
)
query: QueryCommentTreeDto,
) {
return this.service.findTrees(query);
}
@Get()
@SerializeOptions({ groups: ['comment-list'] })
async list(
@Query(
new ValidationPipe({
transform: true,
forbidUnknownValues: true,
validationError: { target: false },
}),
)
query: QueryCommentDto,
) {
return this.service.paginate(query);
}
@Post()
@SerializeOptions({ groups: ['comment-detail'] })
async store(
@Body(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
forbidUnknownValues: true,
validationError: { target: false },
}),
)
data: CreateCommentDto,
) {
return this.service.create(data);
}
@Delete(':id')
@SerializeOptions({ groups: ['comment-detail'] })
async delete(@Param('id', new ParseUUIDPipe()) id: string) {
return this.service.delete(id);
}
}
+3
View File
@@ -1 +1,4 @@
export * from './category.controller';
export * from './comment.controller';
export * from './post.controller';
export * from './tag.controller';
@@ -13,10 +13,9 @@ import {
ValidationPipe,
} from '@nestjs/common';
import { CreatePostDto, UpdatePostDto } from '@/modules/content/dtos';
import { CreatePostDto, QueryPostDto, UpdatePostDto } from '@/modules/content/dtos';
import { PostService } from '@/modules/content/services';
import { AppIntercepter } from '@/modules/core/providers';
import { PaginateOptions } from '@/modules/database/types';
/**
* 文章控制器
@@ -39,7 +38,7 @@ export class PostController {
validationError: { target: false },
}),
)
options: PaginateOptions,
options: QueryPostDto,
) {
return this.postService.paginate(options);
}
@@ -0,0 +1,92 @@
import {
Body,
Controller,
Delete,
Get,
Param,
ParseUUIDPipe,
Patch,
Post,
Query,
SerializeOptions,
UseInterceptors,
ValidationPipe,
} from '@nestjs/common';
import { CreateTagDto, QueryCategoryDto, UpdateTagDto } from '@/modules/content/dtos';
import { TagService } from '@/modules/content/services';
import { AppIntercepter } from '@/modules/core/providers';
@UseInterceptors(AppIntercepter)
@Controller('tags')
export class TagController {
constructor(protected service: TagService) {}
@Get()
@SerializeOptions({})
async list(
@Query(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
forbidUnknownValues: true,
validationError: { target: false },
}),
)
options: QueryCategoryDto,
) {
return this.service.paginate(options);
}
@Get(':id')
@SerializeOptions({})
async detail(
@Param('id', new ParseUUIDPipe())
id: string,
) {
return this.service.detail(id);
}
@Post()
@SerializeOptions({})
async store(
@Body(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
forbidUnknownValues: true,
validationError: { target: false },
groups: ['create'],
}),
)
data: CreateTagDto,
) {
return this.service.create(data);
}
@Patch()
@SerializeOptions({})
async update(
@Body(
new ValidationPipe({
transform: true,
whitelist: true,
forbidNonWhitelisted: true,
forbidUnknownValues: true,
validationError: { target: false },
groups: ['update'],
}),
)
data: UpdateTagDto,
) {
return this.service.update(data);
}
@Delete(':id')
@SerializeOptions({})
async delete(@Param('id', new ParseUUIDPipe()) id: string) {
return this.service.delete(id);
}
}