Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a9a5107
feat: Implement backend vote features (sorting, DTO, etc.)
hangyeoli Apr 6, 2025
e840896
setLikeAndDisLike ์ถ”๊ฐ€
hangyeoli Apr 6, 2025
5562cf8
์ž„์‹œ ์ €์žฅ ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ปค๋ฐ‹
hangyeoli Apr 6, 2025
1056b10
fe vote page
hangyeoli Apr 7, 2025
9eb0208
Merge develop branch
hangyeoli Apr 26, 2025
81b8063
Merge branch develop
hangyeoli Apr 26, 2025
22e638c
fix: vote ๊ฐ€๋Šฅ ์‹๋‹น ํŒฉํ† ๋ฆฌ ๋ฉ”์†Œ๋“œ ์ถ”๊ฐ€, patch๋กœ ๋ณ€๊ฒฝ
hangyeoli Apr 26, 2025
4b6a5ba
Add: validation annotations to RestaurantRequest
hangyeoli Apr 26, 2025
5d2488c
Refactor: Improve Integer to Long conversion in UserRestaurantVoteSerโ€ฆ
hangyeoli Apr 26, 2025
cc9c5bb
Refactor: Add validateRestaurantExists method to RestaurantService anโ€ฆ
hangyeoli Apr 26, 2025
7d0f102
Merge feat/82/be/vote into feat/89/fe/votepage
hangyeoli Apr 26, 2025
e5573fd
fix: ์ด๋ฆ„ ๊ธฐ์ค€ ์ค‘๋ณต ์ œ๊ฑฐ ๋กœ์ง ์ถ”๊ฐ€
hangyeoli Apr 27, 2025
e8ef770
ffix/90/be/vote ๋ณ€๊ฒฝ์‚ฌํ•ญ ๋ณ‘ํ•ฉ
hangyeoli Apr 27, 2025
80fb057
feat: ํˆฌํ‘œ ์•ˆ์ •ํ™” ๊ธฐ๋Šฅ ์ถ”๊ฐ€
hangyeoli Apr 27, 2025
b6a1148
fix: ์ƒˆ๋กœ ๊ณ ์นจ ์ „๊นŒ์ง€ ์œ„์น˜ ๊ณ ์ •
hangyeoli Apr 27, 2025
40e82fb
fix: ์ƒํƒœ๊ด€๋ฆฌ ๋กœ์ง ๋ณ€๊ฒฝ
hangyeoli Apr 27, 2025
80fbad6
feat: ํˆฌํ‘œ ํŽ˜์ด์ง€์—์„œ ์Šคํฌ๋žฉ/์ƒ์„ธ๋ณด๊ธฐ ๋ฒ„ํŠผ ์ถ”๊ฐ€
hangyeoli Apr 27, 2025
4ab1cf2
bug: main page์—์„œ ์ „ํ™˜์‹œ ๋กœ๋”ฉ๋ฌธ์ œ ํ•ด๊ฒฐ
hangyeoli Apr 28, 2025
a271368
fix: ์Šคํฌ๋žฉ ์ƒํƒœ๊ด€๋ฆฌ ๊ฐœ์„ 
hangyeoli Apr 28, 2025
091f5e8
feat: ์ƒ์„ธ ์ •๋ณด ํƒญํ•ด์„œ ๋‹ซ๊ธฐ ์ถ”๊ฐ€
hangyeoli Apr 28, 2025
968fd14
feat: 5์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ ์š”์ฒญ๋ชจ์•„์„œ ์ฒ˜๋ฆฌ ๊ตฌํ˜„/์š”์ฒญ ์ œํ•œ ์ถ”๊ฐ€
hangyeoli Apr 28, 2025
4107a59
fix: ํˆฌํ‘œ count ๋ฒ„๊ทธ ์ˆ˜์ •
hangyeoli May 4, 2025
cc36d4c
fix: ํ•˜๋‹จ ์ •๋ณด ํŒจ๋„ ๊ฐ„๋žตํ™”
hangyeoli May 5, 2025
d4b1827
fix: ๋ฐฐ์น˜ ํˆฌํ‘œ ์˜ค๋ฅ˜ ๊ฐœ์„ 
hangyeoli May 5, 2025
cc90c51
Merge branch 'develop' into fix/89/fe/votepage
hangyeoli May 5, 2025
b974dc5
fix: ํˆฌํ‘œ ์ƒˆ๋กœ๊ณ ์นจ ์‹œ ์ดˆ๊ธฐํ™” ๋˜๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ
hangyeoli May 8, 2025
6c2e160
Merge remote-tracking branch 'origin/fix/89/fe/votepage' into fix/89/โ€ฆ
hangyeoli May 8, 2025
f1b1ed6
fix: vote type dto ๋กœ ๋ณ€๊ฒฝ
hangyeoli May 8, 2025
4154723
merge: develop ๋ธŒ๋žœ์น˜ ๋ณ‘ํ•ฉ
hangyeoli May 11, 2025
30f40c8
fix: develop ์ฝ”๋“œ์™€ ๋‹ค๋ฅธ๋ถ€๋ถ„ ์ˆ˜์ •
hangyeoli May 12, 2025
2241d98
fix: develop ์ฝ”๋“œ์™€ ๋‹ค๋ฅธ๋ถ€๋ถ„ ์ˆ˜์ •
hangyeoli May 12, 2025
b2db78d
fix: ์•ฑ ์ข…๋ฃŒ ํ›„ ์‹คํ–‰ํ•ด๋„ ํˆฌํ‘œ ์ƒํƒœ ์œ ์ง€๋˜๊ฒŒ ์ˆ˜์ •
hangyeoli May 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions be/src/main/java/com/yumst/be/global/exception/ErrorResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.yumst.be.global.exception;

import lombok.Getter;

@Getter
public class ErrorResponse {
private final String message;
private final int status;

public ErrorResponse(ErrorCode errorCode) {
this.message = errorCode.getMessage();
this.status = errorCode.getHttpStatus().value();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.yumst.be.restaurant.domain.RestaurantNaverReviewFeatureCount;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

Expand All @@ -15,4 +16,11 @@ public interface NaverReviewFeatureCountRepository extends JpaRepository<Restaur
"ORDER BY r.reviewCount DESC " +
"LIMIT 2")
List<RestaurantNaverReviewFeatureCount> findTop2ByRestaurantIdOrderByReviewCountDesc(String restaurantId);
}

@Query("SELECT r " +
"FROM RestaurantNaverReviewFeatureCount r " +
"JOIN FETCH r.naverReviewFeature " +
"WHERE r.restaurantId IN :restaurantIds " +
"ORDER BY r.restaurantId, r.reviewCount DESC")
List<RestaurantNaverReviewFeatureCount> findTop2FeaturesForRestaurantIds(@Param("restaurantIds") List<String> restaurantIds);
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,183 @@
package com.yumst.be.restaurant.repository;

import com.yumst.be.restaurant.domain.Restaurant;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Optional;

public interface RestaurantRepository extends JpaRepository<Restaurant, Long> {
Optional<Restaurant> findByRestaurantId(String restaurantId);
List<Restaurant> findTop10RestaurantsByCrawlCompleteTrue();

// ๊ฑฐ๋ฆฌ์ˆœ ์ •๋ ฌ
@Query(value =
"WITH RankedRestaurants AS (" +
" SELECT " +
" r.restaurant_id, r.name, r.category, r.thumbnail_url, " +
" ST_Distance(" +
" geography(ST_SetSRID(ST_MakePoint(CAST(r.longitude AS float), CAST(r.latitude AS float)), 4326)), " +
" geography(ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326))" +
" ) as dist, " +
" COALESCE(bool_or(us.restaurant_id IS NOT NULL), false) as is_scrapped, " +
" COALESCE(SUM(CASE WHEN v_all.vote_type = 'LIKE' THEN 1 ELSE 0 END), 0) as like_count, " +
" COALESCE(SUM(CASE WHEN v_all.vote_type = 'DISLIKE' THEN 1 ELSE 0 END), 0) as dislike_count, " +
" MAX(v_user.vote_type) as user_vote_status, " +
" ROW_NUMBER() OVER (PARTITION BY r.name ORDER BY ST_Distance(" +
" geography(ST_SetSRID(ST_MakePoint(CAST(r.longitude AS float), CAST(r.latitude AS float)), 4326)), " +
" geography(ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326)))\n" +
" ) as row_num " +
" FROM " +
" restaurant r " +
" LEFT JOIN user_restaurant_scrap us ON r.restaurant_id = us.restaurant_id AND us.user_id = :userId " +
" LEFT JOIN user_restaurant_vote v_all ON r.restaurant_id = v_all.restaurant_id " +
" LEFT JOIN user_restaurant_vote v_user ON r.restaurant_id = v_user.restaurant_id AND v_user.user_id = :userId " +
" WHERE " +
" r.crawl_complete = true AND " +
" ST_DWithin(" +
" geography(ST_SetSRID(ST_MakePoint(CAST(r.longitude AS float), CAST(r.latitude AS float)), 4326)), " +
" geography(ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326)), " +
" :radius * 1000" +
" ) " +
" GROUP BY r.restaurant_id, r.name, r.category, r.thumbnail_url, r.longitude, r.latitude" +
") " +
"SELECT restaurant_id, name, category, thumbnail_url, dist, is_scrapped, like_count, dislike_count, user_vote_status " +
"FROM RankedRestaurants " +
"WHERE row_num = 1 " +
"ORDER BY dist ASC",
countQuery = "SELECT COUNT(DISTINCT r.name) " +
"FROM restaurant r " +
"WHERE r.crawl_complete = true AND " +
"ST_DWithin(" +
" geography(ST_SetSRID(ST_MakePoint(CAST(r.longitude AS float), CAST(r.latitude AS float)), 4326)), " +
" geography(ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326)), " +
" :radius * 1000" +
")",
nativeQuery = true)
Page<Object[]> findNearbyRestaurantsOrderByDistance(
@Param("userId") String userId,
@Param("latitude") Double latitude,
@Param("longitude") Double longitude,
@Param("radius") Double radius,
Pageable pageable
);

// ์ข‹์•„์š”์ˆœ ์ •๋ ฌ
@Query(value =
"WITH RankedRestaurants AS (" +
" SELECT " +
" r.restaurant_id, r.name, r.category, r.thumbnail_url, " +
" ST_Distance(" +
" geography(ST_SetSRID(ST_MakePoint(CAST(r.longitude AS float), CAST(r.latitude AS float)), 4326)), " +
" geography(ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326))" +
" ) as dist, " +
" COALESCE(bool_or(us.restaurant_id IS NOT NULL), false) as is_scrapped, " +
" COALESCE(SUM(CASE WHEN v_all.vote_type = 'LIKE' THEN 1 ELSE 0 END), 0) as like_count, " +
" COALESCE(SUM(CASE WHEN v_all.vote_type = 'DISLIKE' THEN 1 ELSE 0 END), 0) as dislike_count, " +
" MAX(v_user.vote_type) as user_vote_status, " +
" ROW_NUMBER() OVER (PARTITION BY r.name ORDER BY ST_Distance(" +
" geography(ST_SetSRID(ST_MakePoint(CAST(r.longitude AS float), CAST(r.latitude AS float)), 4326)), " +
" geography(ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326)))\n" +
" ) as row_num " +
" FROM " +
" restaurant r " +
" LEFT JOIN user_restaurant_scrap us ON r.restaurant_id = us.restaurant_id AND us.user_id = :userId " +
" LEFT JOIN user_restaurant_vote v_all ON r.restaurant_id = v_all.restaurant_id " +
" LEFT JOIN user_restaurant_vote v_user ON r.restaurant_id = v_user.restaurant_id AND v_user.user_id = :userId " +
" WHERE " +
" r.crawl_complete = true AND " +
" ST_DWithin(" +
" geography(ST_SetSRID(ST_MakePoint(CAST(r.longitude AS float), CAST(r.latitude AS float)), 4326)), " +
" geography(ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326)), " +
" :radius * 1000" +
" ) " +
" GROUP BY r.restaurant_id, r.name, r.category, r.thumbnail_url, r.longitude, r.latitude" +
") " +
"SELECT restaurant_id, name, category, thumbnail_url, dist, is_scrapped, like_count, dislike_count, user_vote_status " +
"FROM RankedRestaurants " +
"WHERE row_num = 1 " +
"ORDER BY like_count DESC, dist ASC",
countQuery = "SELECT COUNT(DISTINCT r.name) " +
"FROM restaurant r " +
"WHERE r.crawl_complete = true AND " +
"ST_DWithin(" +
" geography(ST_SetSRID(ST_MakePoint(CAST(r.longitude AS float), CAST(r.latitude AS float)), 4326)), " +
" geography(ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326)), " +
" :radius * 1000" +
")",
nativeQuery = true)
Page<Object[]> findNearbyRestaurantsOrderByLikes(
@Param("userId") String userId,
@Param("latitude") Double latitude,
@Param("longitude") Double longitude,
@Param("radius") Double radius,
Pageable pageable
);

// ์‹ซ์–ด์š”์ˆœ ์ •๋ ฌ
@Query(value =
"WITH RankedRestaurants AS (" +
" SELECT " +
" r.restaurant_id, r.name, r.category, r.thumbnail_url, " +
" ST_Distance(" +
" geography(ST_SetSRID(ST_MakePoint(CAST(r.longitude AS float), CAST(r.latitude AS float)), 4326)), " +
" geography(ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326))" +
" ) as dist, " +
" COALESCE(bool_or(us.restaurant_id IS NOT NULL), false) as is_scrapped, " +
" COALESCE(SUM(CASE WHEN v_all.vote_type = 'LIKE' THEN 1 ELSE 0 END), 0) as like_count, " +
" COALESCE(SUM(CASE WHEN v_all.vote_type = 'DISLIKE' THEN 1 ELSE 0 END), 0) as dislike_count, " +
" MAX(v_user.vote_type) as user_vote_status, " +
" ROW_NUMBER() OVER (PARTITION BY r.name ORDER BY ST_Distance(" +
" geography(ST_SetSRID(ST_MakePoint(CAST(r.longitude AS float), CAST(r.latitude AS float)), 4326)), " +
" geography(ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326)))\n" +
" ) as row_num " +
" FROM " +
" restaurant r " +
" LEFT JOIN user_restaurant_scrap us ON r.restaurant_id = us.restaurant_id AND us.user_id = :userId " +
" LEFT JOIN user_restaurant_vote v_all ON r.restaurant_id = v_all.restaurant_id " +
" LEFT JOIN user_restaurant_vote v_user ON r.restaurant_id = v_user.restaurant_id AND v_user.user_id = :userId " +
" WHERE " +
" r.crawl_complete = true AND " +
" ST_DWithin(" +
" geography(ST_SetSRID(ST_MakePoint(CAST(r.longitude AS float), CAST(r.latitude AS float)), 4326)), " +
" geography(ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326)), " +
" :radius * 1000" +
" ) " +
" GROUP BY r.restaurant_id, r.name, r.category, r.thumbnail_url, r.longitude, r.latitude" +
") " +
"SELECT restaurant_id, name, category, thumbnail_url, dist, is_scrapped, like_count, dislike_count, user_vote_status " +
"FROM RankedRestaurants " +
"WHERE row_num = 1 " +
"ORDER BY dislike_count DESC, dist ASC",
countQuery = "SELECT COUNT(DISTINCT r.name) " +
"FROM restaurant r " +
"WHERE r.crawl_complete = true AND " +
"ST_DWithin(" +
" geography(ST_SetSRID(ST_MakePoint(CAST(r.longitude AS float), CAST(r.latitude AS float)), 4326)), " +
" geography(ST_SetSRID(ST_MakePoint(:longitude, :latitude), 4326)), " +
" :radius * 1000" +
")",
nativeQuery = true)
Page<Object[]> findNearbyRestaurantsOrderByDislikes(
@Param("userId") String userId,
@Param("latitude") Double latitude,
@Param("longitude") Double longitude,
@Param("radius") Double radius,
Pageable pageable
);

@Query(
"SELECT r " +
"FROM Restaurant r " +
"WHERE r.crawlComplete = true " +
// "r.naverInformation.name like concat('%', '์ญˆ๊พธ๋ฏธ๋ธ”๋ฃจ์Šค', '%') " +
"ORDER BY r.naverInformation.rating DESC " +
"LIMIT 10"
)
List<Restaurant> findTop10RestaurantsByCrawlCompleteTrueOrderByNaverInformation();

Restaurant findFirstByOpenDataInformation_BusinessNameContainingAndOpenDataInformation_FullAddressContaining(String businessName, String fullAddress);
}
}
Loading