Skip to content

Commit 1f52fcc

Browse files
authored
Merge pull request #16 from ccaaffee/feat/searchbyname
feat: add searching cafe by name with pagination
2 parents dc53327 + b165c79 commit 1f52fcc

File tree

4 files changed

+94
-2
lines changed

4 files changed

+94
-2
lines changed

src/cafe/cafe.controller.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
BadRequestException,
23
Body,
34
Controller,
45
Delete,
@@ -59,7 +60,7 @@ export class CafeController {
5960
summary: 'get my liked cafe list',
6061
})
6162
@ApiOkResponse({
62-
type: Array<PaginationCafeListResDto>,
63+
type: PaginationCafeListResDto,
6364
description: 'Cafe list that I liked',
6465
})
6566
@ApiInternalServerErrorResponse({
@@ -75,6 +76,28 @@ export class CafeController {
7576
return await this.cafeService.getMyLikeCafeList(user.uuid, query);
7677
}
7778

79+
@ApiOperation({
80+
summary: 'search cafe by name',
81+
})
82+
@ApiOkResponse({
83+
type: PaginationCafeListResDto,
84+
description: 'Cafe list containing search keyword',
85+
})
86+
@ApiInternalServerErrorResponse({
87+
description: 'Internal Server Error',
88+
})
89+
@Get('search/name')
90+
async searchCafeByName(
91+
@Query('name') name: string,
92+
@Query() query: PaginationDto,
93+
): Promise<PaginationCafeListResDto> {
94+
if (!name || name.trim() === '') {
95+
throw new BadRequestException('Name is required');
96+
}
97+
98+
return await this.cafeService.searchCafeByName(name, query);
99+
}
100+
78101
@ApiOperation({
79102
summary: 'get detailed cafe info',
80103
})

src/cafe/cafe.repository.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,54 @@ export class CafeRepository {
8585
};
8686
}
8787

88+
async searchCafeByName(
89+
name: string,
90+
query: PaginationDto,
91+
): Promise<{
92+
data: GeneralCafeResDto[];
93+
hasNextPage: boolean;
94+
}> {
95+
const page = query.page;
96+
const take = query.take;
97+
98+
const skip = (page - 1) * take;
99+
const limit = take + 1; // +1 to check for the next page
100+
101+
const rawResult = await this.prismaService.cafe.findMany({
102+
where: {
103+
name: {
104+
contains: name,
105+
},
106+
},
107+
skip: skip,
108+
take: limit,
109+
include: {
110+
images: {
111+
select: {
112+
id: true,
113+
order: true,
114+
url: true,
115+
cafeId: true,
116+
name: true,
117+
createdAt: true,
118+
},
119+
orderBy: { order: 'asc' },
120+
},
121+
},
122+
});
123+
124+
let hasNextPage = false;
125+
if (rawResult.length > take) {
126+
hasNextPage = true;
127+
rawResult.pop();
128+
}
129+
130+
return {
131+
data: rawResult,
132+
hasNextPage,
133+
};
134+
}
135+
88136
// image는 null로 처리
89137
async createCafe(createCafeDto: CreateCafeDto) {
90138
return await this.prismaService.cafe.create({

src/cafe/cafe.service.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,24 @@ export class CafeService {
5353
return result;
5454
}
5555

56+
async searchCafeByName(name: string, query: PaginationDto) {
57+
const { data, hasNextPage } = await this.cafeRepository.searchCafeByName(
58+
name,
59+
query,
60+
);
61+
62+
const cafeList = await this.applyS3SignedUrlsForCafeList(data);
63+
64+
const result: PaginationCafeListResDto = {
65+
data: cafeList,
66+
nextPage: hasNextPage ? query.page + 1 : null,
67+
cafeCount: data.length,
68+
hasNextPage,
69+
};
70+
71+
return result;
72+
}
73+
5674
async getNearCafeList(
5775
query: GetNearCafeListDto,
5876
): Promise<GeneralCafeResDto[]> {

src/cafe/dto/req/pagination.dto.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ApiProperty } from '@nestjs/swagger';
22
import { Type } from 'class-transformer';
3-
import { IsNumber, IsOptional } from 'class-validator';
3+
import { IsNumber, IsOptional, Max, Min } from 'class-validator';
44

55
export class PaginationDto {
66
@ApiProperty({
@@ -9,6 +9,7 @@ export class PaginationDto {
99
required: false,
1010
})
1111
@IsNumber()
12+
@Min(1)
1213
@IsOptional()
1314
@Type(() => Number)
1415
page: number = 1;
@@ -18,6 +19,8 @@ export class PaginationDto {
1819
description: 'Number of pages to get(default: 20)',
1920
required: false,
2021
})
22+
@Min(1)
23+
@Max(1)
2124
@IsNumber()
2225
@IsOptional()
2326
@Type(() => Number)

0 commit comments

Comments
 (0)