Skip to content

Commit

Permalink
Merge pull request #82 from everymeals/feature/store-get-review
Browse files Browse the repository at this point in the history
[feature/store-get-review] 주변 식당 (store) 리뷰 조회 API
  • Loading branch information
Qbeom0925 authored Jan 27, 2024
2 parents ba26d8e + eeea7e1 commit aaa1b55
Show file tree
Hide file tree
Showing 9 changed files with 283 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import static everymeal.server.store.entity.StoreSortVo.SORT_RECENT;
import static everymeal.server.store.entity.StoreSortVo.SORT_RECOMMENDEDCNOUNT;
import static everymeal.server.store.entity.StoreSortVo.SORT_REVIEWCOUNT;
import static everymeal.server.store.entity.StoreSortVo.SORT_REVIEWMARKCOUNT;

import everymeal.server.global.dto.response.ApplicationResponse;
import everymeal.server.global.util.authresolver.Auth;
Expand All @@ -14,6 +15,7 @@
import everymeal.server.store.controller.dto.response.LikedStoreGetRes;
import everymeal.server.store.controller.dto.response.StoreGetRes;
import everymeal.server.store.controller.dto.response.StoreGetReviewRes;
import everymeal.server.store.controller.dto.response.StoresGetReviews;
import everymeal.server.store.service.StoreService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
Expand Down Expand Up @@ -231,4 +233,58 @@ public ApplicationResponse<Page<StoreGetReviewRes>> getStoreReview(
authenticatedUser == null ? null : authenticatedUser.getIdx(),
PageRequest.of(offset, limit)));
}

@GetMapping("/reviews")
@SecurityRequirement(name = "jwt-user-auth")
@Operation(summary = "식당 리뷰 조회", description = "식당 리뷰를 조회합니다")
public ApplicationResponse<Page<StoresGetReviews>> getStoreReviews(
@RequestParam(value = "offset", defaultValue = "0")
@Schema(title = "페이지 번호", example = "0", description = "페이지 번호는 0부터 시작합니다.")
Integer offset,
@RequestParam(value = "limit", defaultValue = "10")
@Schema(
title = "Data 갯수",
example = "10",
description = "한 페이지에 보여지는 데이터 수 입니다.")
Integer limit,
@RequestParam(value = "order")
@Schema(
title = "정렬 기준",
description = "정렬 기준은 기획에 따라 변경 가능합니다.",
allowableValues = {
SORT_NAME,
SORT_DISTANCE,
SORT_RECOMMENDEDCNOUNT,
SORT_REVIEWCOUNT,
SORT_GRADE,
SORT_RECENT,
SORT_REVIEWMARKCOUNT
})
String order,
@RequestParam(value = "group", required = false, defaultValue = "all")
@Schema(
title = "그룹",
description = "그룹",
allowableValues = {
"all",
"etc",
"recommend",
"restaurant",
"cafe",
"bar",
"korean",
"chinese",
"japanese",
"western",
})
String group,
@RequestParam(value = "grade", required = false)
@Schema(
title = "평점",
description = "평점",
allowableValues = {"1", "2", "3", "4", "5"})
Integer grade) {
return ApplicationResponse.ok(
storeService.getStoresReviews(PageRequest.of(offset, limit), order, group, grade));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package everymeal.server.store.controller.dto.response;


import everymeal.server.global.util.TimeFormatUtil;
import everymeal.server.global.util.aws.S3Util;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public record StoresGetReviews(
Long reviewIdx,
String content,
Integer grade,
LocalDateTime createdAt,
String formattedCreatedAt,
String nickName,
String profileImageUrl,
Long reviewMarksCnt,
List<String> images,
Long storeIdx,
String storeName) {

public static List<StoresGetReviews> of(List<Map<String, Object>> storesReviews) {
return storesReviews.stream()
.map(
storeReview -> {
List<String> images = null;
if (storeReview.get("images") != null) {
images =
Arrays.asList(
((String) storeReview.get("images")).split(","));
images.replaceAll(S3Util::getImgUrl);
}
LocalDateTime createdAt = (LocalDateTime) storeReview.get("createdAt");
return new StoresGetReviews(
(Long) storeReview.get("reviewIdx"),
(String) storeReview.get("content"),
(Integer) storeReview.get("grade"),
createdAt,
TimeFormatUtil.getTimeFormat(
createdAt == null ? LocalDateTime.now() : createdAt),
(String) storeReview.get("nickname"),
(String) storeReview.get("profileImgUrl"),
(Long) storeReview.get("reviewMarksCnt"),
images,
(Long) storeReview.get("storeIdx"),
(String) storeReview.get("storeName"));
})
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ public interface StoreSortVo {
String SORT_REVIEWCOUNT = "reviewCount";
String SORT_GRADE = "grade";
String SORT_RECENT = "registDate";
String SORT_REVIEWMARKCOUNT = "reviewMarksCnt";
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,8 @@ Long getUserLikesStoreCount(
List<Map<String, Object>> getStoreReview(Map<String, Object> parameter);

Long getStoreReviewCnt(Map<String, Object> parameter);

List<Map<String, Object>> getStoresReviews(Map<String, Object> parameter);

Long getStoresReviewsCnt(Map<String, Object> parameter);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import everymeal.server.store.controller.dto.response.LikedStoreGetRes;
import everymeal.server.store.controller.dto.response.StoreGetRes;
import everymeal.server.store.controller.dto.response.StoreGetReviewRes;
import everymeal.server.store.controller.dto.response.StoresGetReviews;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
Expand All @@ -24,4 +25,7 @@ Page<StoreGetRes> getStoresKeyword(
Long campusIdx, String keyword, Long idx, PageRequest pageRequest);

Page<StoreGetReviewRes> getStoreReview(Long storeIdx, Long aLong, PageRequest of);

Page<StoresGetReviews> getStoresReviews(
PageRequest pageRequest, String order, String group, Integer grade);
}
17 changes: 17 additions & 0 deletions src/main/java/everymeal/server/store/service/StoreServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import everymeal.server.store.controller.dto.response.LikedStoreGetRes;
import everymeal.server.store.controller.dto.response.StoreGetRes;
import everymeal.server.store.controller.dto.response.StoreGetReviewRes;
import everymeal.server.store.controller.dto.response.StoresGetReviews;
import everymeal.server.store.entity.Store;
import everymeal.server.store.repository.StoreMapper;
import everymeal.server.store.repository.StoreRepository;
Expand Down Expand Up @@ -164,4 +165,20 @@ public Page<StoreGetReviewRes> getStoreReview(

return new PageImpl<>(result, pageRequest, storeReviewCnt);
}

@Override
public Page<StoresGetReviews> getStoresReviews(
PageRequest pageRequest, String order, String group, Integer grade) {
Map<String, Object> parameter = new HashMap<>();
parameter.put("limit", pageRequest.getPageSize());
parameter.put("offset", pageRequest.getOffset());
parameter.put("order", order);
parameter.put("group", group);
parameter.put("grade", grade);

List<Map<String, Object>> storesReviews = storeMapper.getStoresReviews(parameter);
Long storesReviewsCnt = storeMapper.getStoresReviewsCnt(parameter);
List<StoresGetReviews> result = StoresGetReviews.of(storesReviews);
return new PageImpl<>(result, pageRequest, storesReviewsCnt);
}
}
61 changes: 61 additions & 0 deletions src/main/resources/mybatis/mappers/StoreMapper.xml
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,67 @@
<include refid="everymeal.server.PagingMapper.PagingCountEnd" />
</select>

<select id="getStoresReviews" resultType="java.util.Map">
<include refid="everymeal.server.PagingMapper.Paging" />
<include refid="getStoresReviewsSQL" />
<include refid="everymeal.server.PagingMapper.PagingEnd" />
</select>

<select id="getStoresReviewsCnt" resultType="java.lang.Long">
<include refid="everymeal.server.PagingMapper.PagingCount" />
<include refid="getStoresReviewsSQL" />
<include refid="everymeal.server.PagingMapper.PagingCountEnd" />
</select>

<sql id="getStoresReviewsSQL">
select r.idx as 'reviewIdx',
r.content as 'content',
r.grade as 'grade',
r.created_at as 'createdAt',
u.nickname as 'nickname',
u.profile_img_url as 'profileImgUrl',
(select count(*)
from review_marks rm
where r.idx = rm.review_idx) as 'reviewMarksCnt',
GROUP_CONCAT(i.image_url SEPARATOR ',') AS 'images',
s.idx as 'storeIdx',
s.name as 'storeName'
from reviews r
left join users u on r.user_idx = u.idx and u.is_deleted = false
left join images i on r.idx = i.review_idx and i.is_deleted = false
left join store s on r.store_idx = s.idx and s.is_deleted = false
where CASE
WHEN #{group} = 'recommend' THEN s.recommended_count > 0
WHEN #{group} = 'restaurant' THEN s.category_detail IN ('한식', '중식', '일식', '양식')
WHEN #{group} = 'cafe' THEN s.category_detail IN ('카페', '디저트')
WHEN #{group} = 'bar' THEN s.category_detail = '술집'
WHEN #{group} = 'all' THEN 1 = 1
ELSE s.category_detail IN
('한식', '중식', '일식', '양식', '카페', '디저트', '술집', '기타', '패스트푸드', '분식')
END
AND (
CASE
WHEN #{grade} = 1 THEN r.grade BETWEEN 0 AND 1
WHEN #{grade} = 2 THEN r.grade BETWEEN 1 AND 2
WHEN #{grade} = 3 THEN r.grade BETWEEN 2 AND 3
WHEN #{grade} = 4 THEN r.grade BETWEEN 3 AND 4
WHEN #{grade} = 5 THEN r.grade BETWEEN 4 AND 5
ELSE r.grade BETWEEN 0 AND 5
END
)
group by r.idx, s.idx, s.name, s.distance, s.recommended_count, s.review_count, s.grade, s.created_at
ORDER BY CASE #{order}
WHEN 'name' THEN s.name
WHEN 'distance' THEN s.distance
WHEN 'recommendedCount' THEN s.recommended_count
WHEN 'reviewCount' THEN s.review_count
WHEN 'grade' THEN s.grade
WHEN 'registDate' THEN s.created_at
WHEN 'reviewMarksCnt' THEN reviewMarksCnt
ELSE s.created_at
END DESC
</sql>

<sql id="getStoreReviewSQL">
<![CDATA[
SELECT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,4 +245,46 @@ void getStoreReviewsUser() throws Exception {
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("OK"));
}

@DisplayName("가게 리뷰 조회 API")
@Test
void getStoreReview() throws Exception {
// given
int offset = 0;
int limit = 10;
String order = "reviewMarksCnt";
String group = "etc";

// when then
mockMvc.perform(
get("/api/v1/stores/reviews")
.param("order", order)
.param("group", group)
.param("offset", String.valueOf(offset))
.param("limit", String.valueOf(limit)))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("OK"));
}

@DisplayName("가게 리뷰 조회 _ 홈 리뷰모아보기")
@Test
void getStoreReviewForHome() throws Exception {
// given
int offset = 0;
int limit = 3;
String order = "reviewMarksCnt";
String group = "all";

// when then
mockMvc.perform(
get("/api/v1/stores/reviews")
.param("order", order)
.param("group", group)
.param("offset", String.valueOf(offset))
.param("limit", String.valueOf(limit)))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("OK"));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package everymeal.server.store.service;

import static everymeal.server.store.entity.StoreSortVo.SORT_NAME;
import static everymeal.server.store.entity.StoreSortVo.SORT_REVIEWMARKCOUNT;
import static org.assertj.core.api.Assertions.assertThat;

import everymeal.server.global.IntegrationTestSupport;
Expand All @@ -11,6 +12,7 @@
import everymeal.server.store.controller.dto.response.LikedStoreGetRes;
import everymeal.server.store.controller.dto.response.StoreGetRes;
import everymeal.server.store.controller.dto.response.StoreGetReviewRes;
import everymeal.server.store.controller.dto.response.StoresGetReviews;
import everymeal.server.store.entity.GradeStatistics;
import everymeal.server.store.entity.Store;
import everymeal.server.store.repository.StoreMapper;
Expand Down Expand Up @@ -325,6 +327,50 @@ void getStoreReviews() {
assertThat(storeReview.getContent().get(0).content()).isEqualTo("content");
}

@DisplayName("가게 리뷰 조회 - 페이징")
@Test
@Transactional
void getStoreReviewsPaging() {
// given
University save =
universityRepository.saveAndFlush(
University.builder().name("서울대학교").campusName("관악캠퍼스").build());
List<University> universities =
universityRepository.findByNameAndCampusNameAndIsDeletedFalse("서울대학교", "관악캠퍼스");
University university = universities.get(0);

Store store = createEntity("샌드위치", 3, university, "치킨");
storeRepository.saveAndFlush(store);

User user = getUser(university, 1);
userRepository.saveAndFlush(user);

Review review = createReviewEntity(store, user);
reviewRepository.saveAndFlush(review);

List<Image> images =
List.of(
createImageEntity("1", review),
createImageEntity("2", review),
createImageEntity("3", review),
createImageEntity("4", review),
createImageEntity("5", review),
createImageEntity("6", review));
imageRepository.saveAllAndFlush(images);

entityManager.flush();
entityManager.clear();

// when
Page<StoresGetReviews> storesReviews =
storeService.getStoresReviews(
PageRequest.of(0, 10), SORT_REVIEWMARKCOUNT, "all", null);

// then
assertThat(storesReviews.getContent()).hasSize(1);
assertThat(storesReviews.getContent().get(0).content()).isEqualTo("content");
}

private Image createImageEntity(String urlNumber, Review review) {
return Image.builder().imageUrl("url" + urlNumber).review(review).build();
}
Expand Down

0 comments on commit aaa1b55

Please sign in to comment.