chore: criticism pagination
This commit is contained in:
@@ -132,4 +132,5 @@ export const enum CriticismMessage {
|
||||
CONTENT_IS_REQUIRED = "متن انتقادات مورد نیاز است",
|
||||
CONTENT_IS_STRING = "متن انتقادات باید رشته باشد",
|
||||
NOT_FOUND = "انتقادی با این ایدی یافت نشد",
|
||||
SEARCH_QUERY_STRING = "رشته جستجو باید یک رشته باشد",
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { ApiPropertyOptional } from "@nestjs/swagger";
|
||||
import { IsDateString, IsOptional, IsString } from "class-validator";
|
||||
|
||||
import { PaginationDto } from "../../../common/DTO/pagination.dto";
|
||||
import { CriticismMessage } from "../../../common/enums/message.enum";
|
||||
|
||||
export class SearchCriticismQueryDto extends PaginationDto {
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
@ApiPropertyOptional({ description: "since query", example: "2025-01-27" })
|
||||
since?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString({ message: CriticismMessage.SEARCH_QUERY_STRING })
|
||||
@ApiPropertyOptional({ description: "Search query", example: "search query" })
|
||||
q?: string;
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
import { Body, Controller, Delete, Get, Param, Post } from "@nestjs/common";
|
||||
import { Body, Controller, Delete, Get, Param, Post, Query } from "@nestjs/common";
|
||||
import { ApiOperation, ApiTags } from "@nestjs/swagger";
|
||||
|
||||
import { CreateCriticismDto } from "./DTO/create-criticism.dto";
|
||||
import { SearchCriticismQueryDto } from "./DTO/search-criticism-query.dto";
|
||||
import { CriticismsService } from "./providers/criticisms.service";
|
||||
import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
|
||||
import { Roles } from "../../common/decorators/roles.decorator";
|
||||
import { UserDec } from "../../common/decorators/user.decorator";
|
||||
import { ParamDto } from "../../common/DTO/param.dto";
|
||||
import { User } from "../users/entities/user.entity";
|
||||
import { RoleEnum } from "../users/enums/role.enum";
|
||||
|
||||
@Controller("criticisms")
|
||||
@@ -13,18 +16,19 @@ import { RoleEnum } from "../users/enums/role.enum";
|
||||
export class CriticismController {
|
||||
constructor(private readonly criticismService: CriticismsService) {}
|
||||
|
||||
@AuthGuards()
|
||||
@ApiOperation({ summary: "Create a new criticism" })
|
||||
@Post()
|
||||
create(@Body() createDto: CreateCriticismDto) {
|
||||
return this.criticismService.create(createDto);
|
||||
create(@Body() createDto: CreateCriticismDto, @UserDec() user: User) {
|
||||
return this.criticismService.create(createDto, user.id);
|
||||
}
|
||||
|
||||
@AuthGuards()
|
||||
@Roles(RoleEnum.ADMIN)
|
||||
@ApiOperation({ summary: "Get all Criticism ===> login as admin" })
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.criticismService.findAll();
|
||||
findAll(@Query() queryDto: SearchCriticismQueryDto) {
|
||||
return this.criticismService.findAll(queryDto);
|
||||
}
|
||||
|
||||
@AuthGuards()
|
||||
|
||||
@@ -7,9 +7,10 @@ import { Criticism } from "./entities/criticism.entity";
|
||||
import { CriticismsService } from "./providers/criticisms.service";
|
||||
import { CriticismFileRepository } from "./repositories/criticisms-file.repository";
|
||||
import { CriticismRepository } from "./repositories/criticisms.repository";
|
||||
import { UsersModule } from "../users/users.module";
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Criticism, CriticismFile])],
|
||||
imports: [TypeOrmModule.forFeature([Criticism, CriticismFile]), UsersModule],
|
||||
providers: [CriticismsService, CriticismRepository, CriticismFileRepository],
|
||||
controllers: [CriticismController],
|
||||
exports: [],
|
||||
|
||||
@@ -1,19 +1,24 @@
|
||||
import { Column, Entity, OneToMany } from "typeorm";
|
||||
import { Column, Entity, Index, ManyToOne, OneToMany } from "typeorm";
|
||||
|
||||
import { CriticismFile } from "./criticism-file.entity";
|
||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||
import { User } from "../../users/entities/user.entity";
|
||||
|
||||
@Entity()
|
||||
export class Criticism extends BaseEntity {
|
||||
@Column({ type: "int", generated: "identity", insert: false })
|
||||
numericId: number;
|
||||
|
||||
@Index("title")
|
||||
@Column({ type: "varchar", length: 150, nullable: false })
|
||||
title: string;
|
||||
|
||||
@Column({ type: "text", nullable: false })
|
||||
content: string;
|
||||
|
||||
@ManyToOne(() => User, (user) => user.criticisms, { nullable: false, onDelete: "CASCADE" })
|
||||
user: User;
|
||||
|
||||
@Column({ type: "boolean", default: false })
|
||||
isRead: boolean;
|
||||
|
||||
|
||||
@@ -1,19 +1,27 @@
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
|
||||
import { CommonMessage, CriticismMessage } from "../../../common/enums/message.enum";
|
||||
import { UsersService } from "../../users/providers/users.service";
|
||||
import { PaginationUtils } from "../../utils/providers/pagination.utils";
|
||||
import { CreateCriticismDto } from "../DTO/create-criticism.dto";
|
||||
import { SearchCriticismQueryDto } from "../DTO/search-criticism-query.dto";
|
||||
import { CriticismRepository } from "../repositories/criticisms.repository";
|
||||
|
||||
@Injectable()
|
||||
export class CriticismsService {
|
||||
constructor(private readonly criticismRepository: CriticismRepository) {}
|
||||
constructor(
|
||||
private readonly criticismRepository: CriticismRepository,
|
||||
private readonly usersService: UsersService,
|
||||
) {}
|
||||
|
||||
async create(createDto: CreateCriticismDto) {
|
||||
async create(createDto: CreateCriticismDto, userId: string) {
|
||||
const { user } = await this.usersService.findOneById(userId);
|
||||
const files = createDto.files.map((file) => {
|
||||
return { fileUrl: file };
|
||||
});
|
||||
const criticism = this.criticismRepository.create({
|
||||
...createDto,
|
||||
user,
|
||||
files,
|
||||
});
|
||||
await this.criticismRepository.save(criticism);
|
||||
@@ -25,10 +33,25 @@ export class CriticismsService {
|
||||
|
||||
//##################################### ##
|
||||
|
||||
async findAll() {
|
||||
const criticisms = await this.criticismRepository.find();
|
||||
async findAll(queryDto: SearchCriticismQueryDto) {
|
||||
const { limit, skip } = PaginationUtils(queryDto);
|
||||
|
||||
const queryBuilder = this.criticismRepository.createQueryBuilder("criticism");
|
||||
|
||||
if (queryDto.since) {
|
||||
queryBuilder.andWhere("criticism.createdAt >= :since", { since: queryDto.since });
|
||||
}
|
||||
|
||||
if (queryDto.q) {
|
||||
queryBuilder.andWhere("criticism.title LIKE :q", { q: `%${queryDto.q}%` });
|
||||
}
|
||||
queryBuilder.orderBy("criticism.createdAt", "DESC");
|
||||
|
||||
const [criticisms, count] = await queryBuilder.skip(skip).take(limit).getManyAndCount();
|
||||
|
||||
return {
|
||||
criticisms,
|
||||
count,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Column, Entity, ManyToMany, ManyToOne, OneToMany } from "typeorm";
|
||||
import { Role } from "./role.entity";
|
||||
import { UserGroup } from "./user-group.entity";
|
||||
import { BaseEntity } from "../../../common/entities/base.entity";
|
||||
import { Criticism } from "../../criticisms/entities/criticism.entity";
|
||||
import { TicketMessage } from "../../tickets/entities/ticket-message.entity";
|
||||
import { Ticket } from "../../tickets/entities/ticket.entity";
|
||||
|
||||
@@ -43,4 +44,7 @@ export class User extends BaseEntity {
|
||||
|
||||
@ManyToMany(() => UserGroup, (group) => group.users)
|
||||
groups: UserGroup[];
|
||||
|
||||
@OneToMany(() => Criticism, (criticism) => criticism.user)
|
||||
criticisms: Criticism[];
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
||||
import { BadRequestException, Injectable } from "@nestjs/common";
|
||||
import slugify from "slugify";
|
||||
import { In, Not } from "typeorm";
|
||||
|
||||
@@ -31,7 +31,6 @@ export class UsersService {
|
||||
name: true,
|
||||
},
|
||||
};
|
||||
private logger = new Logger(UsersService.name);
|
||||
constructor(
|
||||
private userRepository: UserRepository,
|
||||
private roleRepository: RoleRepository,
|
||||
@@ -40,8 +39,15 @@ export class UsersService {
|
||||
|
||||
/************************************************************ */
|
||||
|
||||
async findOneById(id: string) {
|
||||
const user = await this.userRepository.findOneBy({ id });
|
||||
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||
return { user };
|
||||
}
|
||||
|
||||
/************************************************************ */
|
||||
|
||||
async getMe(userId: string) {
|
||||
this.logger.debug("sss");
|
||||
const user = await this.userRepository.findOne({ where: { id: userId }, select: this.userSelect });
|
||||
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
|
||||
return { user };
|
||||
|
||||
Reference in New Issue
Block a user