diff --git a/be/src/restaurant/restaurant.controller.ts b/be/src/restaurant/restaurant.controller.ts index c3a918e..0f7c676 100644 --- a/be/src/restaurant/restaurant.controller.ts +++ b/be/src/restaurant/restaurant.controller.ts @@ -25,7 +25,7 @@ import { LocationDto } from "./dto/location.dto"; @ApiTags("Home") @Controller("restaurant") export class RestaurantController { - constructor(private restaurantService: RestaurantService) {} + constructor(private restaurantService: RestaurantService) { } @Get("autocomplete/:partialRestaurantName") @UseGuards(AuthGuard("jwt")) @ApiBearerAuth() @@ -162,6 +162,12 @@ export class RestaurantController { type: String, description: "검색 반경", }) + @ApiQuery({ + name: "limit", + required: false, + type: String, + description: "응답 개수", + }) @ApiResponse({ status: 200, description: "전체 음식점 리스트 요청 성공", @@ -174,8 +180,9 @@ export class RestaurantController { @UsePipes(new ValidationPipe()) entireRestaurantList( @GetUser() tokenInfo: TokenInfo, - @Query() locationDto: LocationDto + @Query() locationDto: LocationDto, + @Query("limit") limit: string ) { - return this.restaurantService.entireRestaurantList(locationDto, tokenInfo); + return this.restaurantService.entireRestaurantList(locationDto, tokenInfo, limit); } } diff --git a/be/src/restaurant/restaurant.repository.ts b/be/src/restaurant/restaurant.repository.ts index 370a144..cf15d1a 100644 --- a/be/src/restaurant/restaurant.repository.ts +++ b/be/src/restaurant/restaurant.repository.ts @@ -178,7 +178,9 @@ export class RestaurantRepository extends Repository { } } - async entireRestaurantList(locationDto: LocationDto, tokenInfo: TokenInfo) { + async entireRestaurantList(locationDto: LocationDto, tokenInfo: TokenInfo, limit: string = "40") { + const limitNum = parseInt(limit); + return this.createQueryBuilder("restaurant") .leftJoin( UserRestaurantListEntity, @@ -208,6 +210,7 @@ export class RestaurantRepository extends Repository { location, ST_GeomFromText('POINT(${locationDto.longitude} ${locationDto.latitude})', 4326)) < ${locationDto.radius}` ) + .limit(limitNum) .getRawMany(); } diff --git a/be/src/restaurant/restaurant.service.ts b/be/src/restaurant/restaurant.service.ts index 2187aeb..3f36fd6 100644 --- a/be/src/restaurant/restaurant.service.ts +++ b/be/src/restaurant/restaurant.service.ts @@ -45,6 +45,22 @@ export class RestaurantService implements OnModuleInit { }) .getCount(); + const reviewInfo = await this.reviewRepository + .createQueryBuilder("review") + .leftJoin("review.reviewLikes", "reviewLike") + .select(["review.id", "review.reviewImage"],) + .groupBy("review.id") + .where("review.restaurant_id = :restaurantId and review.reviewImage is NOT NULL", { restaurantId: restaurant.restaurant_id }) + .orderBy("COUNT(CASE WHEN reviewLike.isLike = true THEN 1 ELSE NULL END)", "DESC") + .getRawOne(); + if (reviewInfo) { + restaurant.restaurant_reviewImage = this.awsService.getImageURL(reviewInfo.review_reviewImage); + } + else { + restaurant.restaurant_reviewImage = this.awsService.getImageURL("review/images/defaultImage.png"); + } + + restaurant.restaurant_reviewCnt = reviewCount; } @@ -71,6 +87,7 @@ export class RestaurantService implements OnModuleInit { "review.restroomCleanliness", "review.overallExperience", "user.nickName as reviewer", + "user.profileImage", "review.createdAt", "review.reviewImage", "reviewLike.isLike as isLike" @@ -84,6 +101,7 @@ export class RestaurantService implements OnModuleInit { const reviewList = reviews.slice(0, 3); reviewList.forEach((element) => { if (element.review_reviewImage) element.review_reviewImage = this.awsService.getImageURL(element.review_reviewImage); + if (element.user_profileImage) element.user_profileImage = this.awsService.getImageURL(element.user_profileImage); }) restaurant.reviews = reviewList; return restaurant; @@ -112,16 +130,33 @@ export class RestaurantService implements OnModuleInit { }) .getCount(); + const reviewInfo = await this.reviewRepository + .createQueryBuilder("review") + .leftJoin("review.reviewLikes", "reviewLike") + .select(["review.id", "review.reviewImage"],) + .groupBy("review.id") + .where("review.restaurant_id = :restaurantId and review.reviewImage is NOT NULL", { restaurantId: restaurant.restaurant_id }) + .orderBy("COUNT(CASE WHEN reviewLike.isLike = true THEN 1 ELSE NULL END)", "DESC") + .getRawOne(); + if (reviewInfo) { + restaurant.restaurant_reviewImage = this.awsService.getImageURL(reviewInfo.review_reviewImage); + } + else { + restaurant.restaurant_reviewImage = this.awsService.getImageURL("review/images/defaultImage.png"); + } + + restaurant.restaurant_reviewCnt = reviewCount; } return restaurants; } - async entireRestaurantList(locationDto: LocationDto, tokenInfo: TokenInfo) { + async entireRestaurantList(locationDto: LocationDto, tokenInfo: TokenInfo, limit: string) { const restaurants = await this.restaurantRepository.entireRestaurantList( locationDto, - tokenInfo + tokenInfo, + limit ); for (const restaurant of restaurants) { @@ -131,7 +166,20 @@ export class RestaurantService implements OnModuleInit { restaurantId: restaurant.restaurant_id, }) .getCount(); - + const reviewInfo = await this.reviewRepository + .createQueryBuilder("review") + .leftJoin("review.reviewLikes", "reviewLike") + .select(["review.id", "review.reviewImage"],) + .groupBy("review.id") + .where("review.restaurant_id = :restaurantId and review.reviewImage is NOT NULL", { restaurantId: restaurant.restaurant_id }) + .orderBy("COUNT(CASE WHEN reviewLike.isLike = true THEN 1 ELSE NULL END)", "DESC") + .getRawOne(); + if (reviewInfo) { + restaurant.restaurant_reviewImage = this.awsService.getImageURL(reviewInfo.review_reviewImage); + } + else { + restaurant.restaurant_reviewImage = this.awsService.getImageURL("review/images/defaultImage.png"); + } restaurant.restaurant_reviewCnt = reviewCount; } diff --git a/be/src/review/dto/reviewInfo.dto.ts b/be/src/review/dto/reviewInfo.dto.ts index 86be463..768f376 100644 --- a/be/src/review/dto/reviewInfo.dto.ts +++ b/be/src/review/dto/reviewInfo.dto.ts @@ -26,7 +26,9 @@ export class ReviewInfoDto { example: "0", description: "transportation Accessibility for visiting", }) - @Transform(({ value }) => parseInt(value)) + @Transform(({ value }) => { + return !value ? null : parseInt(value, 10); + }) @IsInt() @IsOptional() @Min(0) @@ -37,7 +39,9 @@ export class ReviewInfoDto { example: "0", description: "condition of the restaurant's parking area", }) - @Transform(({ value }) => parseInt(value)) + @Transform(({ value }) => { + return !value ? null : parseInt(value, 10); + }) @IsInt() @IsOptional() @Min(0) diff --git a/be/src/review/entities/review.entity.ts b/be/src/review/entities/review.entity.ts index 55e4be4..cd930a1 100644 --- a/be/src/review/entities/review.entity.ts +++ b/be/src/review/entities/review.entity.ts @@ -39,7 +39,7 @@ export class ReviewInfoEntity { @Column({ type: "text" }) overallExperience: string; - @Column({ type: "text", nullable: true }) + @Column({ type: "text", nullable: true, default: null }) reviewImage: string; @CreateDateColumn({ name: "created_at" }) diff --git a/be/src/review/review.repository.ts b/be/src/review/review.repository.ts index e206d85..f46b362 100644 --- a/be/src/review/review.repository.ts +++ b/be/src/review/review.repository.ts @@ -50,6 +50,7 @@ export class ReviewRepository extends Repository { "review.restroomCleanliness", "review.overallExperience", "user.nickName as reviewer", + "user.profileImage", "review.createdAt", "review.reviewImage", "reviewLike.isLike as isLike", @@ -81,6 +82,7 @@ export class ReviewRepository extends Repository { "review.restroomCleanliness", "review.overallExperience", "user.nickName as reviewer", + "user.profileImage", "review.createdAt", "review.reviewImage", "reviewLike.isLike as isLike", @@ -113,6 +115,7 @@ export class ReviewRepository extends Repository { "review.restroomCleanliness", "review.overallExperience", "user.nickName as reviewer", + "user.profileImage", "review.createdAt", "review.reviewImage", "reviewLike.isLike as isLike", diff --git a/be/src/review/review.service.ts b/be/src/review/review.service.ts index 0d9b9be..5b3d502 100644 --- a/be/src/review/review.service.ts +++ b/be/src/review/review.service.ts @@ -3,12 +3,14 @@ import { ReviewRepository } from './review.repository'; import { TokenInfo } from 'src/user/user.decorator'; import { ReviewLikeRepository } from './review.like.repository'; import { SortInfoDto } from 'src/utils/sortInfo.dto'; +import { AwsService } from 'src/aws/aws.service'; @Injectable() export class ReviewService { constructor( private reviewRepository: ReviewRepository, - private reviewLikeRepository: ReviewLikeRepository + private reviewLikeRepository: ReviewLikeRepository, + private awsService: AwsService ) { } async getSortedReviews(tokenInfo: TokenInfo, restaurantId: number, getSortedReviewsDto: SortInfoDto) { @@ -30,7 +32,7 @@ export class ReviewService { .where("reviewLike.reviewId = :reviewId", { reviewId: review.review_id }) .groupBy("reviewLike.isLike") .getRawMany(); - + if (review.user_profileImage) review.user_profileImage = this.awsService.getImageURL(review.user_profileImage); review.likeCount = Number(likeCounts.find(lc => lc.status === true)?.count) || 0; review.dislikeCount = Number(likeCounts.find(lc => lc.status === false)?.count) || 0; } diff --git a/be/src/user/entities/user.entity.ts b/be/src/user/entities/user.entity.ts index 90c4b27..7eaa7ee 100644 --- a/be/src/user/entities/user.entity.ts +++ b/be/src/user/entities/user.entity.ts @@ -37,7 +37,7 @@ export class User { @Column({ type: "varchar", length: 20, nullable: true }) provider: string | null; - @Column({ type: "text", default : "profile/images/defaultprofile.png"}) + @Column({ type: "text", default: "profile/images/defaultprofile.png" }) profileImage: string; @CreateDateColumn({ type: "timestamp" }) @@ -55,7 +55,7 @@ export class User { @OneToMany(() => FollowEntity, (follow) => follow.followedUserId) follower: FollowEntity[]; - @OneToMany(() => UserRestaurantListEntity, (list) => list.userId) + @OneToMany(() => UserRestaurantListEntity, (list) => list.user) restaurant: UserRestaurantListEntity[]; @OneToMany(() => ReviewInfoEntity, (review) => review.user) diff --git a/be/src/user/user.service.ts b/be/src/user/user.service.ts index c5a9730..c8e8ad5 100644 --- a/be/src/user/user.service.ts +++ b/be/src/user/user.service.ts @@ -128,6 +128,21 @@ export class UserService { }) .getCount(); + const reviewInfo = await this.reviewRepository + .createQueryBuilder("review") + .leftJoin("review.reviewLikes", "reviewLike") + .select(["review.id", "review.reviewImage"],) + .groupBy("review.id") + .where("review.restaurant_id = :restaurantId and review.reviewImage is NOT NULL", { restaurantId: restaurant.restaurant_id }) + .orderBy("COUNT(CASE WHEN reviewLike.isLike = true THEN 1 ELSE NULL END)", "DESC") + .getRawOne(); + if (reviewInfo) { + restaurant.restaurant_reviewImage = this.awsService.getImageURL(reviewInfo.review_reviewImage); + } + else { + restaurant.restaurant_reviewImage = this.awsService.getImageURL("review/images/defaultImage.png"); + } + restaurant.isMy = true; restaurant.restaurant_reviewCnt = reviewCount; } @@ -294,6 +309,9 @@ export class UserService { reviewImage = `review/images/${uuid}.png`; reviewEntity.reviewImage = reviewImage; } + else { + reviewEntity.reviewImage = `review/images/defaultImage.png`; + } const userEntity = new User(); userEntity.id = tokenInfo["id"]; reviewEntity.user = userEntity;