初步完成评论

This commit is contained in:
2025-06-07 03:21:27 +08:00
parent c872b55083
commit 3821ef6657
12 changed files with 208 additions and 4 deletions

View File

@@ -1,4 +1,4 @@
import { BadRequestException, Controller, Get, Param, ParseUUIDPipe } from '@nestjs/common';
import { BadRequestException, Body, Controller, Get, Param, ParseUUIDPipe, Post } from '@nestjs/common';
import { BlogService } from './blog.service';
@Controller('blog')
@@ -31,4 +31,31 @@ export class BlogController {
content: blogContent,
};
}
@Get(':id/comments')
async getBlogComments(
@Param('id', new ParseUUIDPipe({ version: '4' })) id: string,
) {
const blog = await this.blogService.findById(id);
if (!blog) throw new BadRequestException('文章不存在');
return await this.blogService.getComments(id);
}
// TODO鉴权该接口允许匿名评论但仍需验证userId合法性
@Post(':id/comment')
async createBlogComment(
@Param('id', new ParseUUIDPipe({ version: '4' })) id: string,
@Body() commentData: { content: string },
) {
const blog = await this.blogService.findById(id);
if (!blog) throw new BadRequestException('文章不存在');
const comment = {
...commentData,
blogId: id,
};
return await this.blogService.createComment(comment);
}
}

View File

@@ -3,9 +3,10 @@ import { BlogController } from './blog.controller';
import { BlogService } from './blog.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Blog } from './entity/Blog.entity';
import { BlogComment } from './entity/BlogComment';
@Module({
imports: [TypeOrmModule.forFeature([Blog])],
imports: [TypeOrmModule.forFeature([Blog, BlogComment])],
controllers: [BlogController],
providers: [BlogService],
exports: [BlogService],

View File

@@ -2,6 +2,7 @@ import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Blog } from './entity/Blog.entity';
import { Repository } from 'typeorm';
import { BlogComment } from './entity/BlogComment';
@Injectable()
export class BlogService {
@@ -9,6 +10,8 @@ export class BlogService {
constructor(
@InjectRepository(Blog)
private readonly blogRepository: Repository<Blog>,
@InjectRepository(BlogComment)
private readonly blogCommentRepository: Repository<BlogComment>,
) { }
async list() {
@@ -43,4 +46,19 @@ export class BlogService {
async incrementViewCount(id: string) {
await this.blogRepository.increment({ id }, 'viewCount', 1);
}
async getComments(id: string) {
return this.blogCommentRepository.find({
where: { blogId: id },
relations: ['user'],
order: {
createdAt: 'DESC',
}
});
}
async createComment(comment: Partial<BlogComment>) {
const newComment = this.blogCommentRepository.create(comment);
return this.blogCommentRepository.save(newComment);
}
}

View File

@@ -1,4 +1,5 @@
import { Column, CreateDateColumn, DeleteDateColumn, Entity, OneToMany, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
import { BlogComment } from "./BlogComment";
@Entity()
export class Blog {
@@ -27,4 +28,8 @@ export class Blog {
deletedAt: Date;
// 权限关系 TODO
// 关系
@OneToMany(() => BlogComment, blog => blog.id)
comments: BlogComment[];
}

View File

@@ -0,0 +1,33 @@
import { User } from "src/user/entities/user.entity";
import { Column, CreateDateColumn, DeleteDateColumn, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
@Entity()
export class BlogComment {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column()
content: string;
// @Column()
// ip: string;
// @Column()
// address: string;
@CreateDateColumn({ precision: 3 })
createdAt: Date;
@DeleteDateColumn({ precision: 3, nullable: true })
deletedAt: Date;
@ManyToOne(() => User, { nullable: true })
@JoinColumn({ name: 'userId' })
user: User | null;
@Column({ type: 'uuid', nullable: true })
blogId: string | null;
@Column({ type: 'uuid', nullable: true })
parentId: string | null;
}