diff --git a/build.gradle b/build.gradle index e42d1d3..15854a4 100644 --- a/build.gradle +++ b/build.gradle @@ -25,6 +25,7 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' diff --git a/src/main/java/com/example/Centralthon/domain/menu/exception/MenuErrorCode.java b/src/main/java/com/example/Centralthon/domain/menu/exception/MenuErrorCode.java index fe5c192..3e53d4c 100644 --- a/src/main/java/com/example/Centralthon/domain/menu/exception/MenuErrorCode.java +++ b/src/main/java/com/example/Centralthon/domain/menu/exception/MenuErrorCode.java @@ -7,7 +7,7 @@ @Getter @AllArgsConstructor public enum MenuErrorCode implements BaseResponseCode { - MENU_NOT_FOUND("MENU_NOT_FOUND_404_1",404,"반경 내에 반찬 매물이 없습니다."); + MENU_NOT_FOUND("MENU_NOT_FOUND_404_1",404,"존재하지 않는 메뉴 입니다."); private final String code; private final int httpStatus; diff --git a/src/main/java/com/example/Centralthon/domain/menu/exception/MenuNotFoundException.java b/src/main/java/com/example/Centralthon/domain/menu/exception/MenuNotFoundException.java index 8dbb4d1..a6a5f24 100644 --- a/src/main/java/com/example/Centralthon/domain/menu/exception/MenuNotFoundException.java +++ b/src/main/java/com/example/Centralthon/domain/menu/exception/MenuNotFoundException.java @@ -3,7 +3,5 @@ import com.example.Centralthon.global.exception.BaseException; public class MenuNotFoundException extends BaseException { - public MenuNotFoundException() { - super(MenuErrorCode.MENU_NOT_FOUND); - } + public MenuNotFoundException() {super(MenuErrorCode.MENU_NOT_FOUND);} } diff --git a/src/main/java/com/example/Centralthon/domain/menu/service/MenuService.java b/src/main/java/com/example/Centralthon/domain/menu/service/MenuService.java index 5057130..812fe1b 100644 --- a/src/main/java/com/example/Centralthon/domain/menu/service/MenuService.java +++ b/src/main/java/com/example/Centralthon/domain/menu/service/MenuService.java @@ -1,12 +1,14 @@ package com.example.Centralthon.domain.menu.service; +import com.example.Centralthon.domain.menu.web.dto.*; import com.example.Centralthon.domain.menu.web.dto.NearbyMenusRes; import com.example.Centralthon.domain.menu.web.dto.StoresByMenuRes; -import jakarta.validation.constraints.NotNull; import java.util.List; public interface MenuService { List nearbyMenus(double latitude, double longitude); List storesByMenu(String name, double lat, double lng); + + List details(MenuIdsReq menus); } diff --git a/src/main/java/com/example/Centralthon/domain/menu/service/MenuServiceImpl.java b/src/main/java/com/example/Centralthon/domain/menu/service/MenuServiceImpl.java index 7c3dfcf..25eca1e 100644 --- a/src/main/java/com/example/Centralthon/domain/menu/service/MenuServiceImpl.java +++ b/src/main/java/com/example/Centralthon/domain/menu/service/MenuServiceImpl.java @@ -3,8 +3,7 @@ import com.example.Centralthon.domain.menu.entity.Menu; import com.example.Centralthon.domain.menu.exception.MenuNotFoundException; import com.example.Centralthon.domain.menu.repository.MenuRepository; -import com.example.Centralthon.domain.menu.web.dto.NearbyMenusRes; -import com.example.Centralthon.domain.menu.web.dto.StoresByMenuRes; +import com.example.Centralthon.domain.menu.web.dto.*; import com.example.Centralthon.domain.store.entity.Store; import com.example.Centralthon.global.util.geo.BoundingBox; import com.example.Centralthon.global.util.geo.GeoUtils; @@ -13,6 +12,8 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; @@ -75,4 +76,17 @@ public List storesByMenu(String name, double lat, double lng) { )) .toList(); } + + @Override + @Transactional(readOnly=true) + public List details(MenuIdsReq menus) { + List menuList = menuRepository.findAllById(menus.getMenuIds()); + + if (menuList.isEmpty()) {throw new MenuNotFoundException();} + + return menuList.stream() + .map(menu -> MenuDetailsRes.from(menu)) + .toList(); + } + } diff --git a/src/main/java/com/example/Centralthon/domain/menu/web/controller/MenuController.java b/src/main/java/com/example/Centralthon/domain/menu/web/controller/MenuController.java index 4f40c25..b442449 100644 --- a/src/main/java/com/example/Centralthon/domain/menu/web/controller/MenuController.java +++ b/src/main/java/com/example/Centralthon/domain/menu/web/controller/MenuController.java @@ -1,9 +1,15 @@ package com.example.Centralthon.domain.menu.web.controller; import com.example.Centralthon.domain.menu.service.MenuService; + +import com.example.Centralthon.domain.menu.web.dto.*; +import com.example.Centralthon.global.response.SuccessResponse; +import jakarta.validation.Valid; + import com.example.Centralthon.domain.menu.web.dto.NearbyMenusRes; import com.example.Centralthon.domain.menu.web.dto.StoresByMenuRes; import com.example.Centralthon.global.response.SuccessResponse; + import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -40,4 +46,12 @@ public ResponseEntity>> storesByMenu( return ResponseEntity.status(HttpStatus.OK).body(SuccessResponse.from(stores)); } + + //메뉴 상세 조회 + @PostMapping("/details") + public ResponseEntity>> details(@RequestBody @Valid MenuIdsReq menus){ + List menuList = menuService.details(menus); + + return ResponseEntity.status(HttpStatus.OK).body(SuccessResponse.from(menuList)); + } } diff --git a/src/main/java/com/example/Centralthon/domain/menu/web/dto/MenuDetailsRes.java b/src/main/java/com/example/Centralthon/domain/menu/web/dto/MenuDetailsRes.java new file mode 100644 index 0000000..636c51a --- /dev/null +++ b/src/main/java/com/example/Centralthon/domain/menu/web/dto/MenuDetailsRes.java @@ -0,0 +1,36 @@ +package com.example.Centralthon.domain.menu.web.dto; + +import com.example.Centralthon.domain.menu.entity.Menu; +import com.example.Centralthon.domain.menu.entity.enums.MenuCategory; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +public record MenuDetailsRes( + long menuId, + String name, + MenuCategory category, + int costPrice, + int salePrice, + int salePercent, + String storeName +) { + public static MenuDetailsRes from(Menu menu) { + return new MenuDetailsRes( + menu.getId(), + menu.getName(), + menu.getCategory(), + menu.getCostPrice(), + menu.getSalePrice(), + calculateDiscount(menu.getCostPrice(), menu.getSalePrice()), + menu.getStore().getName() + ); + } + + private static int calculateDiscount(int cost, int sale) { + return BigDecimal.valueOf(cost - sale) + .multiply(BigDecimal.valueOf(100)) + .divide(BigDecimal.valueOf(cost), 0, RoundingMode.HALF_UP) + .intValue(); + } +} diff --git a/src/main/java/com/example/Centralthon/domain/menu/web/dto/MenuIdsReq.java b/src/main/java/com/example/Centralthon/domain/menu/web/dto/MenuIdsReq.java new file mode 100644 index 0000000..2c3e8ba --- /dev/null +++ b/src/main/java/com/example/Centralthon/domain/menu/web/dto/MenuIdsReq.java @@ -0,0 +1,13 @@ +package com.example.Centralthon.domain.menu.web.dto; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import java.util.List; + +@Getter +public class MenuIdsReq { + @NotEmpty(message = "menuIds 리스트가 비어있습니다.") + private List<@NotNull(message = "menuId는 null일 수 없습니다.") Long> menuIds; +} diff --git a/src/main/java/com/example/Centralthon/global/exception/GlobalExceptionHandler.java b/src/main/java/com/example/Centralthon/global/exception/GlobalExceptionHandler.java index 33d6bc9..9b779b1 100644 --- a/src/main/java/com/example/Centralthon/global/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/example/Centralthon/global/exception/GlobalExceptionHandler.java @@ -10,7 +10,9 @@ import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MethodArgumentNotValidException; + import org.springframework.web.bind.MissingServletRequestParameterException; + import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; diff --git a/src/main/java/com/example/Centralthon/global/response/SuccessResponse.java b/src/main/java/com/example/Centralthon/global/response/SuccessResponse.java index f1119fc..690f31a 100644 --- a/src/main/java/com/example/Centralthon/global/response/SuccessResponse.java +++ b/src/main/java/com/example/Centralthon/global/response/SuccessResponse.java @@ -21,7 +21,6 @@ public SuccessResponse(T data, BaseResponseCode baseResponseCode) { this.data = data; } - // 201 Created 응답 public static SuccessResponse created(T data) { return new SuccessResponse<>(data, SuccessResponseCode.SUCCESS_CREATED); }