chore: add most visited blog route

This commit is contained in:
mahyargdz
2025-04-12 16:22:17 +03:30
parent 4ae735b048
commit 39cce1c380
4 changed files with 94 additions and 2 deletions
@@ -54,6 +54,13 @@ export class BlogsController {
return this.blogsService.getBlogBySlug(paramDto.slug);
}
@ApiOperation({ summary: "Get most visited blogs" })
@SkipAuth()
@Get("most-visited")
getMostVisitedBlogs() {
return this.blogsService.getMostVisitedBlogs();
}
@ApiOperation({ summary: "Create a new blog (admin route)" })
@Post()
@AdminRoute()
@@ -34,6 +34,9 @@ export class Blog extends BaseEntity {
@Column({ type: "boolean", default: true })
isActive: boolean;
@Column({ type: "int", default: 0 })
viewCount: number;
@ManyToOne(() => User, (user) => user.blogs)
author: User;
+26 -2
View File
@@ -148,16 +148,28 @@ export class BlogsService {
}
//*********************************** */
async getBlogById(id: string) {
async getBlogById(id: string, isAdmin: boolean = false) {
const blog = await this.findBlogById(id);
const comments = await this.blogCommentsRepository.findBlogCommentsByBlogId(id);
if (!isAdmin) {
blog.viewCount += 1;
await this.blogsRepository.save(blog);
}
return { blog, comments };
}
//*********************************** */
async getBlogBySlug(slug: string) {
async getBlogBySlug(slug: string, isAdmin: boolean = false) {
const blog = await this.blogsRepository.findOneBySlug(slug);
if (!blog) throw new BadRequestException(BlogMessage.BLOG_NOT_FOUND);
if (!isAdmin) {
blog.viewCount += 1;
await this.blogsRepository.save(blog);
}
return { blog };
}
//*********************************** */
@@ -238,4 +250,16 @@ export class BlogsService {
if (!blog) throw new BadRequestException(BlogMessage.BLOG_NOT_FOUND);
return blog;
}
async incrementViewCount(id: string) {
const blog = await this.findBlogById(id);
blog.viewCount += 1;
await this.blogsRepository.save(blog);
return { message: "View count incremented successfully" };
}
async getMostVisitedBlogs() {
const blogs = await this.blogsRepository.getMostVisitedBlogs();
return { blogs };
}
}
@@ -30,6 +30,7 @@ export class BlogsRepository extends Repository<Blog> {
createdAt: true,
content: true,
tags: true,
viewCount: true,
category: {
id: true,
title: true,
@@ -48,6 +49,34 @@ export class BlogsRepository extends Repository<Blog> {
async findOneBySlug(slug: string): Promise<Blog | null> {
return this.findOne({
where: { slug, deletedAt: IsNull(), isActive: true },
relations: {
author: true,
category: true,
},
select: {
id: true,
title: true,
previewContent: true,
metaTitle: true,
metaDescription: true,
imageUrl: true,
slug: true,
createdAt: true,
content: true,
tags: true,
viewCount: true,
category: {
id: true,
title: true,
iconUrl: true,
description: true,
},
author: {
id: true,
firstName: true,
lastName: true,
},
},
});
}
@@ -75,6 +104,7 @@ export class BlogsRepository extends Repository<Blog> {
"blog.imageUrl",
"blog.slug",
"blog.createdAt",
"blog.viewCount",
"category.id",
"category.iconUrl",
"category.title",
@@ -133,4 +163,32 @@ export class BlogsRepository extends Repository<Blog> {
return queryBuilder.getManyAndCount();
}
async getMostVisitedBlogs(limit: number = 5) {
return this.createQueryBuilder("blog")
.where("blog.deletedAt IS NULL")
.andWhere("blog.isActive = :isActive", { isActive: true })
.leftJoinAndSelect("blog.category", "category")
.leftJoinAndSelect("blog.author", "author")
.select([
"blog.id",
"blog.title",
"blog.previewContent",
"blog.metaTitle",
"blog.metaDescription",
"blog.imageUrl",
"blog.slug",
"blog.createdAt",
"blog.viewCount",
"category.id",
"category.iconUrl",
"category.title",
"author.id",
"author.firstName",
"author.lastName",
])
.orderBy("blog.viewCount", "DESC")
.take(limit)
.getMany();
}
}