Skip to content

Commit fd1831e

Browse files
authored
✨ feat : 메뉴 상세 조회 API 구현
✨ feat : 메뉴 상세 조회 API 구현
2 parents 4be1f1a + 8662baa commit fd1831e

10 files changed

Lines changed: 87 additions & 8 deletions

File tree

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ repositories {
2525

2626
dependencies {
2727
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
28+
2829
implementation 'org.springframework.boot:spring-boot-starter-web'
2930
compileOnly 'org.projectlombok:lombok'
3031
runtimeOnly 'com.mysql:mysql-connector-j'

src/main/java/com/example/Centralthon/domain/menu/exception/MenuErrorCode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
@Getter
88
@AllArgsConstructor
99
public enum MenuErrorCode implements BaseResponseCode {
10-
MENU_NOT_FOUND("MENU_NOT_FOUND_404_1",404,"반경 내에 반찬 매물이 없습니다.");
10+
MENU_NOT_FOUND("MENU_NOT_FOUND_404_1",404,"존재하지 않는 메뉴 입니다.");
1111

1212
private final String code;
1313
private final int httpStatus;

src/main/java/com/example/Centralthon/domain/menu/exception/MenuNotFoundException.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,5 @@
33
import com.example.Centralthon.global.exception.BaseException;
44

55
public class MenuNotFoundException extends BaseException {
6-
public MenuNotFoundException() {
7-
super(MenuErrorCode.MENU_NOT_FOUND);
8-
}
6+
public MenuNotFoundException() {super(MenuErrorCode.MENU_NOT_FOUND);}
97
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package com.example.Centralthon.domain.menu.service;
22

3+
import com.example.Centralthon.domain.menu.web.dto.*;
34
import com.example.Centralthon.domain.menu.web.dto.NearbyMenusRes;
45
import com.example.Centralthon.domain.menu.web.dto.StoresByMenuRes;
5-
import jakarta.validation.constraints.NotNull;
66
import java.util.List;
77

88
public interface MenuService {
99
List<NearbyMenusRes> nearbyMenus(double latitude, double longitude);
1010

1111
List<StoresByMenuRes> storesByMenu(String name, double lat, double lng);
12+
13+
List<MenuDetailsRes> details(MenuIdsReq menus);
1214
}

src/main/java/com/example/Centralthon/domain/menu/service/MenuServiceImpl.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import com.example.Centralthon.domain.menu.entity.Menu;
44
import com.example.Centralthon.domain.menu.exception.MenuNotFoundException;
55
import com.example.Centralthon.domain.menu.repository.MenuRepository;
6-
import com.example.Centralthon.domain.menu.web.dto.NearbyMenusRes;
7-
import com.example.Centralthon.domain.menu.web.dto.StoresByMenuRes;
6+
import com.example.Centralthon.domain.menu.web.dto.*;
87
import com.example.Centralthon.domain.store.entity.Store;
98
import com.example.Centralthon.global.util.geo.BoundingBox;
109
import com.example.Centralthon.global.util.geo.GeoUtils;
@@ -13,6 +12,8 @@
1312
import org.springframework.transaction.annotation.Transactional;
1413

1514
import java.time.LocalDateTime;
15+
import java.util.*;
16+
import java.util.stream.Collectors;
1617
import java.util.Comparator;
1718
import java.util.LinkedHashMap;
1819
import java.util.List;
@@ -75,4 +76,17 @@ public List<StoresByMenuRes> storesByMenu(String name, double lat, double lng) {
7576
))
7677
.toList();
7778
}
79+
80+
@Override
81+
@Transactional(readOnly=true)
82+
public List<MenuDetailsRes> details(MenuIdsReq menus) {
83+
List<Menu> menuList = menuRepository.findAllById(menus.getMenuIds());
84+
85+
if (menuList.isEmpty()) {throw new MenuNotFoundException();}
86+
87+
return menuList.stream()
88+
.map(menu -> MenuDetailsRes.from(menu))
89+
.toList();
90+
}
91+
7892
}

src/main/java/com/example/Centralthon/domain/menu/web/controller/MenuController.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
package com.example.Centralthon.domain.menu.web.controller;
22

33
import com.example.Centralthon.domain.menu.service.MenuService;
4+
5+
import com.example.Centralthon.domain.menu.web.dto.*;
6+
import com.example.Centralthon.global.response.SuccessResponse;
7+
import jakarta.validation.Valid;
8+
49
import com.example.Centralthon.domain.menu.web.dto.NearbyMenusRes;
510
import com.example.Centralthon.domain.menu.web.dto.StoresByMenuRes;
611
import com.example.Centralthon.global.response.SuccessResponse;
12+
713
import lombok.RequiredArgsConstructor;
814
import org.springframework.http.HttpStatus;
915
import org.springframework.http.ResponseEntity;
@@ -40,4 +46,12 @@ public ResponseEntity<SuccessResponse<List<StoresByMenuRes>>> storesByMenu(
4046

4147
return ResponseEntity.status(HttpStatus.OK).body(SuccessResponse.from(stores));
4248
}
49+
50+
//메뉴 상세 조회
51+
@PostMapping("/details")
52+
public ResponseEntity<SuccessResponse<List<MenuDetailsRes>>> details(@RequestBody @Valid MenuIdsReq menus){
53+
List<MenuDetailsRes> menuList = menuService.details(menus);
54+
55+
return ResponseEntity.status(HttpStatus.OK).body(SuccessResponse.from(menuList));
56+
}
4357
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.example.Centralthon.domain.menu.web.dto;
2+
3+
import com.example.Centralthon.domain.menu.entity.Menu;
4+
import com.example.Centralthon.domain.menu.entity.enums.MenuCategory;
5+
6+
import java.math.BigDecimal;
7+
import java.math.RoundingMode;
8+
9+
public record MenuDetailsRes(
10+
long menuId,
11+
String name,
12+
MenuCategory category,
13+
int costPrice,
14+
int salePrice,
15+
int salePercent,
16+
String storeName
17+
) {
18+
public static MenuDetailsRes from(Menu menu) {
19+
return new MenuDetailsRes(
20+
menu.getId(),
21+
menu.getName(),
22+
menu.getCategory(),
23+
menu.getCostPrice(),
24+
menu.getSalePrice(),
25+
calculateDiscount(menu.getCostPrice(), menu.getSalePrice()),
26+
menu.getStore().getName()
27+
);
28+
}
29+
30+
private static int calculateDiscount(int cost, int sale) {
31+
return BigDecimal.valueOf(cost - sale)
32+
.multiply(BigDecimal.valueOf(100))
33+
.divide(BigDecimal.valueOf(cost), 0, RoundingMode.HALF_UP)
34+
.intValue();
35+
}
36+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.example.Centralthon.domain.menu.web.dto;
2+
3+
import jakarta.validation.constraints.Min;
4+
import jakarta.validation.constraints.NotEmpty;
5+
import jakarta.validation.constraints.NotNull;
6+
import lombok.Getter;
7+
import java.util.List;
8+
9+
@Getter
10+
public class MenuIdsReq {
11+
@NotEmpty(message = "menuIds 리스트가 비어있습니다.")
12+
private List<@NotNull(message = "menuId는 null일 수 없습니다.") Long> menuIds;
13+
}

src/main/java/com/example/Centralthon/global/exception/GlobalExceptionHandler.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010

1111
import org.springframework.web.HttpRequestMethodNotSupportedException;
1212
import org.springframework.web.bind.MethodArgumentNotValidException;
13+
1314
import org.springframework.web.bind.MissingServletRequestParameterException;
15+
1416
import org.springframework.web.bind.annotation.ExceptionHandler;
1517
import org.springframework.web.bind.annotation.RestControllerAdvice;
1618
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

src/main/java/com/example/Centralthon/global/response/SuccessResponse.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ public SuccessResponse(T data, BaseResponseCode baseResponseCode) {
2121
this.data = data;
2222
}
2323

24-
// 201 Created 응답
2524
public static <T> SuccessResponse<T> created(T data) {
2625
return new SuccessResponse<>(data, SuccessResponseCode.SUCCESS_CREATED);
2726
}

0 commit comments

Comments
 (0)