\update: the slugify method

This commit is contained in:
mahyargdz
2025-04-20 15:42:50 +03:30
parent 6b17c69980
commit 61b3f4a066
4 changed files with 27 additions and 9 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ export function databaseConfigs(): TypeOrmModuleAsyncOptions {
username: configService.getOrThrow<string>("DB_USER"), username: configService.getOrThrow<string>("DB_USER"),
password: configService.getOrThrow<string>("DB_PASS"), password: configService.getOrThrow<string>("DB_PASS"),
autoLoadEntities: true, autoLoadEntities: true,
synchronize: configService.getOrThrow<string>("NODE_ENV") == "production" ? false : false, synchronize: configService.getOrThrow<string>("NODE_ENV") == "production" ? false : true,
logging: configService.getOrThrow<string>("NODE_ENV") == "production" ? false : true, logging: configService.getOrThrow<string>("NODE_ENV") == "production" ? false : true,
migrationsTableName: "typeorm_migrations", migrationsTableName: "typeorm_migrations",
migrationsRun: false, migrationsRun: false,
+8 -1
View File
@@ -1,4 +1,4 @@
import { Column, DeleteDateColumn, Entity, ManyToOne, OneToMany } from "typeorm"; import { Column, DeleteDateColumn, Entity, Index, ManyToOne, OneToMany } from "typeorm";
import { BlogCategory } from "./blog-category.entity"; import { BlogCategory } from "./blog-category.entity";
import { BlogComment } from "./blog-comment.entity"; import { BlogComment } from "./blog-comment.entity";
@@ -8,9 +8,11 @@ import { User } from "../../users/entities/user.entity";
@Entity() @Entity()
export class Blog extends BaseEntity { export class Blog extends BaseEntity {
@Column({ type: "varchar", length: 250, unique: true }) @Column({ type: "varchar", length: 250, unique: true })
@Index()
title: string; title: string;
@Column({ type: "varchar", length: 250, unique: true }) @Column({ type: "varchar", length: 250, unique: true })
@Index()
slug: string; slug: string;
@Column({ type: "text" }) @Column({ type: "text" })
@@ -32,18 +34,23 @@ export class Blog extends BaseEntity {
tags: string[]; tags: string[];
@Column({ type: "boolean", default: true }) @Column({ type: "boolean", default: true })
@Index()
isActive: boolean; isActive: boolean;
@Column({ type: "int", default: 0 }) @Column({ type: "int", default: 0 })
@Index()
viewCount: number; viewCount: number;
@Column({ type: "boolean", default: false }) @Column({ type: "boolean", default: false })
@Index()
isPinned: boolean; isPinned: boolean;
@ManyToOne(() => User, (user) => user.blogs, { onDelete: "CASCADE", nullable: false }) @ManyToOne(() => User, (user) => user.blogs, { onDelete: "CASCADE", nullable: false })
@Index()
author: User; author: User;
@ManyToOne(() => BlogCategory, (category) => category.blogs, { nullable: false }) @ManyToOne(() => BlogCategory, (category) => category.blogs, { nullable: false })
@Index()
category: BlogCategory; category: BlogCategory;
@OneToMany(() => BlogComment, (comment) => comment.blog) @OneToMany(() => BlogComment, (comment) => comment.blog)
+17 -6
View File
@@ -1,5 +1,4 @@
import { BadRequestException, Injectable } from "@nestjs/common"; import { BadRequestException, Injectable } from "@nestjs/common";
import slugify from "slugify";
import { Not } from "typeorm"; import { Not } from "typeorm";
import { BlogMessage, CommonMessage } from "../../../common/enums/message.enum"; import { BlogMessage, CommonMessage } from "../../../common/enums/message.enum";
@@ -106,12 +105,13 @@ export class BlogsService {
const category = await this.findCategoryById(createBlogDto.categoryId); const category = await this.findCategoryById(createBlogDto.categoryId);
const slug = this.generateSlug(createBlogDto.slug); const slug = this.generateSlug(createBlogDto.slug);
console.log(slug);
const blog = this.blogsRepository.create({ const blog = this.blogsRepository.create({
...createBlogDto, ...createBlogDto,
slug,
author: { id: authorId }, author: { id: authorId },
category, category,
slug,
}); });
await this.blogsRepository.save(blog); await this.blogsRepository.save(blog);
@@ -140,10 +140,13 @@ export class BlogsService {
if (updateBlogDto.slug) { if (updateBlogDto.slug) {
const existBlog = await this.blogsRepository.findOne({ where: { slug: updateBlogDto.slug, id: Not(id) } }); const existBlog = await this.blogsRepository.findOne({ where: { slug: updateBlogDto.slug, id: Not(id) } });
if (existBlog) throw new BadRequestException(BlogMessage.BLOG_ALREADY_EXISTS); if (existBlog) throw new BadRequestException(BlogMessage.BLOG_ALREADY_EXISTS);
blog.slug = this.generateSlug(updateBlogDto.slug);
} }
await this.blogsRepository.save({ ...blog, ...updateBlogDto }); await this.blogsRepository.save({
...blog,
...updateBlogDto,
slug: this.generateSlug(updateBlogDto.slug ?? blog.slug),
});
return { return {
message: CommonMessage.UPDATE_SUCCESS, message: CommonMessage.UPDATE_SUCCESS,
@@ -258,8 +261,16 @@ export class BlogsService {
} }
//*********************************** */ //*********************************** */
private generateSlug(title: string): string { private generateSlug(slug: string): string {
return slugify(title, { lower: true, strict: true }); if (!slug) return "";
// Replace spaces and special characters with hyphens, preserve Farsi characters
return slug
.trim()
.replace(/[&\\#,+()$~%.'":*?<>{}]/g, "") // Remove special characters
.replace(/\s+/g, "-") // Replace spaces with hyphens
.replace(/-+/g, "-") // Replace multiple hyphens with single hyphen
.trim();
} }
//*********************************** */ //*********************************** */
@@ -122,7 +122,7 @@ export class DanakServicesRepository extends Repository<DanakService> {
// "averageRating", // "averageRating",
// ) // )
.andWhere("service.id = :serviceId", { serviceId }) .andWhere("service.id = :serviceId", { serviceId })
.groupBy("service.id,category.id, images.id, subscriptionPlans.id, reviews.id, user.id"); .groupBy("service.id,category.id, images.id, subscriptionPlans.id, reviews.id, user.id, directDiscount.id");
if (!isAdmin) { if (!isAdmin) {
serviceQueryBuilder serviceQueryBuilder