From aabee386e9b9802fafb510e9d4a9ce3055fc19a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9D=80?= <113881692+knxxxn@users.noreply.github.com> Date: Thu, 19 Sep 2024 03:21:24 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20base=20ingredient=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/brand/api/BrandController.java | 59 +++++++------ .../domain/brand/api/BrandService.java | 86 +++++++++++-------- .../domain/brand/domain/BaseIngredient.java | 45 ++++++++++ .../recipic/domain/brand/domain/Brand.java | 5 +- .../domain/brand/domain/BrandIngredient.java | 16 ++-- .../brand/domain/BrandIngredientId.java | 12 +-- .../domain/brand/domain/Ingredient.java | 26 +++--- .../repository/BaseIngredientRepository.java | 10 +++ .../repository/BrandIngredientRepository.java | 1 - .../brand/repository/BrandRepository.java | 3 +- .../repository/IngredientRepository.java | 16 +--- 11 files changed, 174 insertions(+), 105 deletions(-) create mode 100644 src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredient.java create mode 100644 src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientRepository.java diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java index 35faf05..fd2d311 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java @@ -1,14 +1,12 @@ package CaffeineCoder.recipic.domain.brand.api; - import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.LinkedHashMap; - @RestController @RequestMapping("/api/brand") public class BrandController { @@ -19,51 +17,64 @@ public BrandController(BrandService brandService) { this.brandService = brandService; } - // /ingredients 엔드포인트를 GET 방식으로 변경 - @GetMapping("/ingredients") - public ResponseEntity> getIngredientsByBrandName(@RequestParam("brandName") String brandName) { - // @RequestBody 대신 @RequestParam을 사용하여 쿼리 매개변수로 brandName을 받음 - List> ingredients = brandService.getIngredientsByBrandName(brandName); + // BaseIngredient 추가 API + @PostMapping("/add-baseingredient") + public ResponseEntity> addBaseIngredientToBrand(@RequestBody Map request) { + String brandName = (String) request.get("brandName"); + String ingredientName = (String) request.get("ingredientName"); + Long quantity = request.get("quantity") instanceof Integer + ? Long.valueOf((Integer) request.get("quantity")) + : (Long) request.get("quantity"); + String unit = (String) request.get("unit"); + Integer cost = (Integer) request.get("cost"); + Double calorie = request.get("calorie") instanceof Integer + ? Double.valueOf((Integer) request.get("calorie")) + : (Double) request.get("calorie"); + + boolean success = brandService.addBaseIngredientToBrand(brandName, ingredientName, quantity, unit, cost, calorie); Map response = new LinkedHashMap<>(); - response.put("isSuccess", true); - response.put("response", ingredients); + response.put("isSuccess", success); + response.put("message", success ? "Base Ingredient added successfully" : "Failed to add Base Ingredient"); return ResponseEntity.ok(response); } + // Ingredient 추가 API @PostMapping("/add-ingredient") - public ResponseEntity> addIngredientToBrand(@RequestBody Map request) { - String brandName = (String) request.get("brandName"); + public ResponseEntity> addIngredient(@RequestBody Map request) { String ingredientName = (String) request.get("ingredientName"); - - // quantity는 클라이언트에서 Long 타입으로 보내야함 Long quantity = request.get("quantity") instanceof Integer ? Long.valueOf((Integer) request.get("quantity")) : (Long) request.get("quantity"); - String unit = (String) request.get("unit"); Integer cost = (Integer) request.get("cost"); - - // calorie는 Double로 변환 Double calorie = request.get("calorie") instanceof Integer ? Double.valueOf((Integer) request.get("calorie")) : (Double) request.get("calorie"); - boolean success = brandService.addIngredientToBrand(brandName, ingredientName, quantity, unit, cost, calorie); + boolean success = brandService.addIngredient(ingredientName, quantity, unit, cost, calorie); Map response = new LinkedHashMap<>(); response.put("isSuccess", success); - if (success) { - response.put("message", "Ingredient added successfully."); - } else { - response.put("message", "Failed to add ingredient."); - } + response.put("message", success ? "Ingredient added successfully" : "Failed to add Ingredient"); + + return ResponseEntity.ok(response); + } + + // 브랜드 이름으로 BaseIngredient 조회 API + @GetMapping("/baseingredients") + public ResponseEntity> getBaseIngredientsByBrandName(@RequestParam("brandName") String brandName) { + List> baseIngredients = brandService.getBaseIngredientsByBrandName(brandName); + + Map response = new LinkedHashMap<>(); + response.put("isSuccess", true); + response.put("response", baseIngredients); return ResponseEntity.ok(response); } - //모든 브랜드 가져오기 + // 모든 브랜드 가져오기 @GetMapping("/list") public ResponseEntity> getAllBrands() { List> brands = brandService.getAllBrands(); diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java index 8c2d41a..2fd0d82 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java @@ -1,13 +1,13 @@ package CaffeineCoder.recipic.domain.brand.api; -import CaffeineCoder.recipic.domain.brand.dto.IngredientDTO; +import CaffeineCoder.recipic.domain.brand.domain.BaseIngredient; import CaffeineCoder.recipic.domain.brand.domain.Brand; import CaffeineCoder.recipic.domain.brand.domain.BrandIngredient; import CaffeineCoder.recipic.domain.brand.domain.Ingredient; +import CaffeineCoder.recipic.domain.brand.repository.BaseIngredientRepository; import CaffeineCoder.recipic.domain.brand.repository.BrandIngredientRepository; import CaffeineCoder.recipic.domain.brand.repository.BrandRepository; import CaffeineCoder.recipic.domain.brand.repository.IngredientRepository; -import jakarta.persistence.criteria.CriteriaBuilder; import org.springframework.stereotype.Service; import java.util.LinkedHashMap; @@ -22,46 +22,40 @@ public class BrandService { private final BrandRepository brandRepository; private final BrandIngredientRepository brandIngredientRepository; private final IngredientRepository ingredientRepository; + private final BaseIngredientRepository baseIngredientRepository; - public BrandService(BrandRepository brandRepository, BrandIngredientRepository brandIngredientRepository, IngredientRepository ingredientRepository) { + public BrandService(BrandRepository brandRepository, BrandIngredientRepository brandIngredientRepository, + IngredientRepository ingredientRepository, BaseIngredientRepository baseIngredientRepository) { this.brandRepository = brandRepository; this.brandIngredientRepository = brandIngredientRepository; this.ingredientRepository = ingredientRepository; + this.baseIngredientRepository = baseIngredientRepository; } - public List> getIngredientsByBrandName(String brandName) { - Brand brand = brandRepository.findByBrandName(brandName) - .orElseThrow(() -> new RuntimeException("Brand not found")); - - return brandIngredientRepository.findByBrand(brand) - .stream() - .map(brandIngredient -> { - Ingredient ingredient = brandIngredient.getIngredient(); - - IngredientDTO dto = new IngredientDTO.Builder() - .ingredientId(ingredient.getIngredientId()) - .name(ingredient.getIngredientName()) - .quantity(ingredient.getQuantity()) - .unit(ingredient.getUnit()) - .cost(ingredient.getCost()) - .calorie(ingredient.getCalorie()) - .build(); - - return dto.toMap(); - }) - .collect(Collectors.toList()); - } - - public boolean addIngredientToBrand(String brandName, String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { - + // BaseIngredient 추가 + public boolean addBaseIngredientToBrand(String brandName, String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { Optional optionalBrand = brandRepository.findByBrandName(brandName); if (optionalBrand.isEmpty()) { return false; } Brand brand = optionalBrand.get(); - // 새로운 Ingredient 객체 생성 + // BaseIngredient 생성 및 저장 + BaseIngredient baseIngredient = new BaseIngredient(ingredientName, quantity, unit, cost, calorie); + baseIngredientRepository.save(baseIngredient); + + // BrandIngredient 객체 생성 및 저장 (BaseIngredient와 연결) + BrandIngredient brandIngredient = new BrandIngredient(); + brandIngredient.setBaseIngredient(baseIngredient); + brandIngredient.setBrand(brand); + brandIngredientRepository.save(brandIngredient); + return true; + } + + // Ingredient 추가 (BrandIngredient와는 별도로 관리) + public boolean addIngredient(String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { + // Ingredient 생성 및 저장 Ingredient ingredient = Ingredient.builder() .ingredientName(ingredientName) .quantity(quantity) @@ -73,16 +67,31 @@ public boolean addIngredientToBrand(String brandName, String ingredientName, Lon // Ingredient 저장 ingredientRepository.save(ingredient); - // BrandIngredient 객체 생성 - BrandIngredient brandIngredient = new BrandIngredient(); - brandIngredient.setIngredient(ingredient); - brandIngredient.setBrand(brand); - brandIngredientRepository.save(brandIngredient); - return true; } - //모든 브랜드 가져오기 + // 브랜드 이름으로 BaseIngredient 가져오기 + public List> getBaseIngredientsByBrandName(String brandName) { + Brand brand = brandRepository.findByBrandName(brandName) + .orElseThrow(() -> new RuntimeException("Brand not found")); + + return brandIngredientRepository.findByBrand(brand) + .stream() + .map(brandIngredient -> { + BaseIngredient baseIngredient = brandIngredient.getBaseIngredient(); + Map baseIngredientMap = new LinkedHashMap<>(); + baseIngredientMap.put("ingredientId", baseIngredient.getBaseIngredientId()); + baseIngredientMap.put("name", baseIngredient.getIngredientName()); + baseIngredientMap.put("quantity", baseIngredient.getQuantity()); + baseIngredientMap.put("unit", baseIngredient.getUnit()); + baseIngredientMap.put("cost", baseIngredient.getCost()); + baseIngredientMap.put("calorie", baseIngredient.getCalorie()); + return baseIngredientMap; + }) + .collect(Collectors.toList()); + } + + // 모든 브랜드 가져오기 public List> getAllBrands() { return brandRepository.findAll().stream() .map(brand -> { @@ -93,8 +102,9 @@ public List> getAllBrands() { }) .collect(Collectors.toList()); } - + + // 브랜드 ID로 브랜드 이름 가져오기 public String getBrandNameByBrandId(Integer brandId) { return brandRepository.findBrandNameByBrandId(brandId); } -} +} \ No newline at end of file diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredient.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredient.java new file mode 100644 index 0000000..555d7c5 --- /dev/null +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredient.java @@ -0,0 +1,45 @@ +package CaffeineCoder.recipic.domain.brand.domain; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor +public class BaseIngredient { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "baseingredient_id") + private Integer baseIngredientId; + + @Column(name = "ingredient_name", nullable = false) + private String ingredientName; + + @Column(name = "quantity", nullable = false) + private Long quantity; + + @Column(name = "unit", nullable = false) + private String unit; + + @Column(name = "cost") + private Integer cost; + + @Column(name = "calorie") + private Double calorie; + + // Ingredient와의 관계 설정 (OneToMany) + @OneToMany(mappedBy = "baseIngredient", cascade = CascadeType.ALL, orphanRemoval = true) + private List ingredients; + + public BaseIngredient(String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { + this.ingredientName = ingredientName; + this.quantity = quantity; + this.unit = unit; + this.cost = cost; + this.calorie = calorie; + } +} diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Brand.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Brand.java index ddb04cb..44431a8 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Brand.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Brand.java @@ -22,7 +22,8 @@ public class Brand { @OneToMany(mappedBy = "brand", cascade = CascadeType.ALL, orphanRemoval = true) private List brandIngredients; - public Integer getBrandId() { - return brandId; + public Brand(Integer brandId, String brandName) { + this.brandId = brandId; + this.brandName = brandName; } } diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BrandIngredient.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BrandIngredient.java index d73c1b4..be6c98c 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BrandIngredient.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BrandIngredient.java @@ -18,21 +18,21 @@ public class BrandIngredient { private Brand brand; @ManyToOne - @MapsId("ingredientId") - @JoinColumn(name = "ingredient_id") - private Ingredient ingredient; + @MapsId("baseIngredientId") + @JoinColumn(name = "baseingredient_id") + private BaseIngredient baseIngredient; - public void setIngredient(Ingredient ingredient) { - this.ingredient = ingredient; + public void setBaseIngredient(BaseIngredient baseIngredient) { + this.baseIngredient = baseIngredient; if (this.brand != null) { - this.id = new BrandIngredientId(this.brand.getBrandId(), ingredient.getIngredientId()); + this.id = new BrandIngredientId(this.brand.getBrandId(), baseIngredient.getBaseIngredientId()); } } public void setBrand(Brand brand) { this.brand = brand; - if (this.ingredient != null) { - this.id = new BrandIngredientId(brand.getBrandId(), this.ingredient.getIngredientId()); + if (this.baseIngredient != null) { + this.id = new BrandIngredientId(brand.getBrandId(), this.baseIngredient.getBaseIngredientId()); } } } diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BrandIngredientId.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BrandIngredientId.java index 3beb5df..25086c8 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BrandIngredientId.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BrandIngredientId.java @@ -16,12 +16,12 @@ public class BrandIngredientId implements Serializable { @Column(name = "brand_id") private Integer brandId; - @Column(name = "ingredient_id") - private Integer ingredientId; + @Column(name = "baseingredient_id") + private Integer baseIngredientId; - public BrandIngredientId(Integer brandId, Integer ingredientId) { + public BrandIngredientId(Integer brandId, Integer baseIngredientId) { this.brandId = brandId; - this.ingredientId = ingredientId; + this.baseIngredientId = baseIngredientId; } @Override @@ -30,11 +30,11 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; BrandIngredientId that = (BrandIngredientId) o; return Objects.equals(brandId, that.brandId) && - Objects.equals(ingredientId, that.ingredientId); + Objects.equals(baseIngredientId, that.baseIngredientId); } @Override public int hashCode() { - return Objects.hash(brandId, ingredientId); + return Objects.hash(brandId, baseIngredientId); } } diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Ingredient.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Ingredient.java index 0366ae6..5e590c2 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Ingredient.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Ingredient.java @@ -3,9 +3,11 @@ import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; @Entity @Getter +@NoArgsConstructor public class Ingredient { @Id @@ -13,31 +15,33 @@ public class Ingredient { @Column(name = "ingredient_id") private Integer ingredientId; - @Column(name = "ingredient_name") - private String ingredientName; // 재료 이름 + @Column(name = "ingredient_name", nullable = false) + private String ingredientName; @Column(name = "quantity") - private Long quantity; // 양 + private Long quantity; @Column(name = "unit") - private String unit; // 단위 + private String unit; @Column(name = "cost") - private Integer cost; // 비용 + private Integer cost; @Column(name = "calorie") - private Double calorie; // 칼로리 + private Double calorie; + + // BaseIngredient와의 관계 설정 (ManyToOne) + @ManyToOne + @JoinColumn(name = "baseingredient_id", nullable = false) // 외래 키인 baseingredient_id를 명시 + private BaseIngredient baseIngredient; @Builder - public Ingredient(String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { + public Ingredient(String ingredientName, Long quantity, String unit, Integer cost, Double calorie, BaseIngredient baseIngredient) { this.ingredientName = ingredientName; this.quantity = quantity; this.unit = unit; this.cost = cost; this.calorie = calorie; - } - - // 기본 생성자 추가 - protected Ingredient() { + this.baseIngredient = baseIngredient; } } diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientRepository.java b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientRepository.java new file mode 100644 index 0000000..af3b28c --- /dev/null +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientRepository.java @@ -0,0 +1,10 @@ +package CaffeineCoder.recipic.domain.brand.repository; + +import CaffeineCoder.recipic.domain.brand.domain.BaseIngredient; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface BaseIngredientRepository extends JpaRepository { + +} diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BrandIngredientRepository.java b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BrandIngredientRepository.java index c7fac28..1b2860d 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BrandIngredientRepository.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BrandIngredientRepository.java @@ -12,4 +12,3 @@ public interface BrandIngredientRepository extends JpaRepository { List findByBrand(Brand brand); } - diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BrandRepository.java b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BrandRepository.java index 7bb2c4c..5222110 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BrandRepository.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BrandRepository.java @@ -8,9 +8,9 @@ import java.util.Optional; - @Repository public interface BrandRepository extends JpaRepository { + Optional findByBrandName(String brandName); @Query("SELECT b.brandId FROM Brand b WHERE b.brandName = :name") @@ -18,5 +18,4 @@ public interface BrandRepository extends JpaRepository { @Query("SELECT b.brandName FROM Brand b WHERE b.brandId = :brandId") String findBrandNameByBrandId(@Param("brandId") Integer brandId); - } diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/IngredientRepository.java b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/IngredientRepository.java index befa044..c964e40 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/IngredientRepository.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/IngredientRepository.java @@ -2,22 +2,12 @@ import CaffeineCoder.recipic.domain.brand.domain.Ingredient; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; -import java.util.Optional; +import java.util.List; @Repository public interface IngredientRepository extends JpaRepository { - @Query("SELECT i.ingredientId FROM Ingredient i WHERE i.ingredientName = :name") - Optional findByName(@Param("name") String name); - - @Modifying - @Transactional - @Query("DELETE FROM RecipeIngredient ri WHERE ri.recipe.recipeId = :recipeId") - void deleteByRecipeId(@Param("recipeId") Integer recipeId); - + // BaseIngredient로 연결된 Ingredient 목록 조회 + List findByBaseIngredient_BaseIngredientId(Integer baseIngredientId); } From 042d0e2417d704d2dd7e49e0acfa13cfed6c70dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9D=80?= <113881692+knxxxn@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:36:01 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=EB=B2=A0=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=9E=AC=EB=A3=8C=20=EC=B6=94=EA=B0=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/brand/api/BrandController.java | 22 +- .../domain/brand/api/BrandService.java | 39 +-- .../domain/brand/domain/BaseIngredient.java | 8 + .../recipic/domain/brand/domain/Brand.java | 4 +- .../domain/brand/domain/Ingredient.java | 2 +- .../repository/BaseIngredientRepository.java | 8 + .../brand/repository/BrandRepository.java | 8 +- .../repository/IngredientRepository.java | 10 +- .../domain/recipe/api/RecipeController.java | 3 - .../recipe/application/RecipeRankService.java | 27 +- .../recipe/application/RecipeService.java | 305 ++++++++---------- .../domain/recipe/dao/RecipeRepository.java | 51 ++- .../recipic/domain/recipe/domain/Recipe.java | 28 +- .../recipe/domain/RecipeIngredient.java | 17 +- .../recipe/domain/RecipeIngredientId.java | 14 +- .../recipic/domain/recipe/dto/RecipeDto.java | 26 +- .../domain/recipe/dto/RecipeRequestDto.java | 7 +- .../domain/recipe/dto/RecipeResponseDto.java | 5 +- 18 files changed, 279 insertions(+), 305 deletions(-) diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java index fd2d311..792d140 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java @@ -17,21 +17,17 @@ public BrandController(BrandService brandService) { this.brandService = brandService; } - // BaseIngredient 추가 API + // BaseIngredient 추가 API (brandId 사용) @PostMapping("/add-baseingredient") public ResponseEntity> addBaseIngredientToBrand(@RequestBody Map request) { - String brandName = (String) request.get("brandName"); + Integer brandId = (Integer) request.get("brandId"); String ingredientName = (String) request.get("ingredientName"); - Long quantity = request.get("quantity") instanceof Integer - ? Long.valueOf((Integer) request.get("quantity")) - : (Long) request.get("quantity"); + Long quantity = Long.parseLong(request.get("quantity").toString()); String unit = (String) request.get("unit"); Integer cost = (Integer) request.get("cost"); - Double calorie = request.get("calorie") instanceof Integer - ? Double.valueOf((Integer) request.get("calorie")) - : (Double) request.get("calorie"); + Double calorie = Double.parseDouble(request.get("calorie").toString()); - boolean success = brandService.addBaseIngredientToBrand(brandName, ingredientName, quantity, unit, cost, calorie); + boolean success = brandService.addBaseIngredientToBrand(brandId, ingredientName, quantity, unit, cost, calorie); Map response = new LinkedHashMap<>(); response.put("isSuccess", success); @@ -44,14 +40,10 @@ public ResponseEntity> addBaseIngredientToBrand(@RequestBody @PostMapping("/add-ingredient") public ResponseEntity> addIngredient(@RequestBody Map request) { String ingredientName = (String) request.get("ingredientName"); - Long quantity = request.get("quantity") instanceof Integer - ? Long.valueOf((Integer) request.get("quantity")) - : (Long) request.get("quantity"); + Long quantity = Long.parseLong(request.get("quantity").toString()); String unit = (String) request.get("unit"); Integer cost = (Integer) request.get("cost"); - Double calorie = request.get("calorie") instanceof Integer - ? Double.valueOf((Integer) request.get("calorie")) - : (Double) request.get("calorie"); + Double calorie = Double.parseDouble(request.get("calorie").toString()); boolean success = brandService.addIngredient(ingredientName, quantity, unit, cost, calorie); diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java index 2fd0d82..118b358 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java @@ -32,29 +32,30 @@ public BrandService(BrandRepository brandRepository, BrandIngredientRepository b this.baseIngredientRepository = baseIngredientRepository; } - // BaseIngredient 추가 - public boolean addBaseIngredientToBrand(String brandName, String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { - Optional optionalBrand = brandRepository.findByBrandName(brandName); + // BaseIngredient 추가 (brandId 사용) + public boolean addBaseIngredientToBrand(Integer brandId, String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { + Optional optionalBrand = brandRepository.findById(brandId); if (optionalBrand.isEmpty()) { - return false; + throw new RuntimeException("Brand not found with ID: " + brandId); } Brand brand = optionalBrand.get(); // BaseIngredient 생성 및 저장 BaseIngredient baseIngredient = new BaseIngredient(ingredientName, quantity, unit, cost, calorie); - baseIngredientRepository.save(baseIngredient); - - // BrandIngredient 객체 생성 및 저장 (BaseIngredient와 연결) - BrandIngredient brandIngredient = new BrandIngredient(); - brandIngredient.setBaseIngredient(baseIngredient); - brandIngredient.setBrand(brand); - brandIngredientRepository.save(brandIngredient); + baseIngredient.setBrand(brand); // Brand와 연결 + baseIngredientRepository.save(baseIngredient); // 저장 return true; } - // Ingredient 추가 (BrandIngredient와는 별도로 관리) + // Ingredient 추가 (BaseIngredient와 관계) public boolean addIngredient(String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { + // BaseIngredient를 찾음 + Optional optionalBaseIngredient = baseIngredientRepository.findByIngredientName(ingredientName); + if (optionalBaseIngredient.isEmpty()) { + return false; + } + // Ingredient 생성 및 저장 Ingredient ingredient = Ingredient.builder() .ingredientName(ingredientName) @@ -62,9 +63,9 @@ public boolean addIngredient(String ingredientName, Long quantity, String unit, .unit(unit) .cost(cost) .calorie(calorie) + .baseIngredient(optionalBaseIngredient.get()) .build(); - // Ingredient 저장 ingredientRepository.save(ingredient); return true; @@ -75,10 +76,9 @@ public List> getBaseIngredientsByBrandName(String brandName) Brand brand = brandRepository.findByBrandName(brandName) .orElseThrow(() -> new RuntimeException("Brand not found")); - return brandIngredientRepository.findByBrand(brand) + return baseIngredientRepository.findByBrand(brand) .stream() - .map(brandIngredient -> { - BaseIngredient baseIngredient = brandIngredient.getBaseIngredient(); + .map(baseIngredient -> { Map baseIngredientMap = new LinkedHashMap<>(); baseIngredientMap.put("ingredientId", baseIngredient.getBaseIngredientId()); baseIngredientMap.put("name", baseIngredient.getIngredientName()); @@ -102,9 +102,4 @@ public List> getAllBrands() { }) .collect(Collectors.toList()); } - - // 브랜드 ID로 브랜드 이름 가져오기 - public String getBrandNameByBrandId(Integer brandId) { - return brandRepository.findBrandNameByBrandId(brandId); - } -} \ No newline at end of file +} diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredient.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredient.java index 555d7c5..ad96473 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredient.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredient.java @@ -31,6 +31,10 @@ public class BaseIngredient { @Column(name = "calorie") private Double calorie; + @ManyToOne + @JoinColumn(name = "brand_id", nullable = false) + private Brand brand; + // Ingredient와의 관계 설정 (OneToMany) @OneToMany(mappedBy = "baseIngredient", cascade = CascadeType.ALL, orphanRemoval = true) private List ingredients; @@ -42,4 +46,8 @@ public BaseIngredient(String ingredientName, Long quantity, String unit, Integer this.cost = cost; this.calorie = calorie; } + + public void setBrand(Brand brand) { + this.brand = brand; + } } diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Brand.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Brand.java index 44431a8..8604d4a 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Brand.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Brand.java @@ -16,11 +16,11 @@ public class Brand { @Column(name = "brand_id") private Integer brandId; - @Column(name = "brand_name", nullable = false) + @Column(name = "brand_name", nullable = false, unique = true) private String brandName; @OneToMany(mappedBy = "brand", cascade = CascadeType.ALL, orphanRemoval = true) - private List brandIngredients; + private List baseIngredients; public Brand(Integer brandId, String brandName) { this.brandId = brandId; diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Ingredient.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Ingredient.java index 5e590c2..98ae12e 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Ingredient.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Ingredient.java @@ -32,7 +32,7 @@ public class Ingredient { // BaseIngredient와의 관계 설정 (ManyToOne) @ManyToOne - @JoinColumn(name = "baseingredient_id", nullable = false) // 외래 키인 baseingredient_id를 명시 + @JoinColumn(name = "baseingredient_id", nullable = false) private BaseIngredient baseIngredient; @Builder diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientRepository.java b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientRepository.java index af3b28c..75d96bc 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientRepository.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientRepository.java @@ -1,10 +1,18 @@ package CaffeineCoder.recipic.domain.brand.repository; import CaffeineCoder.recipic.domain.brand.domain.BaseIngredient; +import CaffeineCoder.recipic.domain.brand.domain.Brand; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; +import java.util.Optional; + @Repository public interface BaseIngredientRepository extends JpaRepository { + // BaseIngredient 이름으로 찾기 + Optional findByIngredientName(String ingredientName); + + List findByBrand(Brand brand); } diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BrandRepository.java b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BrandRepository.java index 5222110..94e6c96 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BrandRepository.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BrandRepository.java @@ -1,15 +1,17 @@ package CaffeineCoder.recipic.domain.brand.repository; +import CaffeineCoder.recipic.domain.brand.domain.BaseIngredient; import CaffeineCoder.recipic.domain.brand.domain.Brand; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; @Repository -public interface BrandRepository extends JpaRepository { +public interface BrandRepository extends JpaRepository { Optional findByBrandName(String brandName); @@ -18,4 +20,8 @@ public interface BrandRepository extends JpaRepository { @Query("SELECT b.brandName FROM Brand b WHERE b.brandId = :brandId") String findBrandNameByBrandId(@Param("brandId") Integer brandId); + + @Query("SELECT bi FROM BaseIngredient bi JOIN bi.brand b WHERE b.brandName = :brandName") + List findBaseIngredientsByBrandName(@Param("brandName") String brandName); + } diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/IngredientRepository.java b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/IngredientRepository.java index c964e40..08bd95b 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/IngredientRepository.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/IngredientRepository.java @@ -2,12 +2,16 @@ import CaffeineCoder.recipic.domain.brand.domain.Ingredient; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import java.util.List; +import java.util.Optional; @Repository public interface IngredientRepository extends JpaRepository { - // BaseIngredient로 연결된 Ingredient 목록 조회 - List findByBaseIngredient_BaseIngredientId(Integer baseIngredientId); + + // Ingredient 이름으로 찾기 + @Query("SELECT i FROM Ingredient i WHERE i.ingredientName = :name") + Optional findByIngredientName(@Param("name") String name); } diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/api/RecipeController.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/api/RecipeController.java index 8d36d97..ce2a270 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/api/RecipeController.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/api/RecipeController.java @@ -61,7 +61,4 @@ public ApiResponse getScraps( @RequestParam(value = "size", defaultValue = "10") int size) { return ApiUtils.success(recipeService.getQueriedRecipes(keyword, page, size)); } - - - } \ No newline at end of file diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeRankService.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeRankService.java index 4ca36cc..2b77506 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeRankService.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeRankService.java @@ -7,7 +7,6 @@ import CaffeineCoder.recipic.domain.recipe.dto.RecipeResponseDto; import CaffeineCoder.recipic.domain.scrap.dao.ScrapRepository; import CaffeineCoder.recipic.domain.user.application.UserService; -import CaffeineCoder.recipic.domain.user.dao.UserRepository; import CaffeineCoder.recipic.domain.user.domain.User; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.PageRequest; @@ -23,28 +22,21 @@ public class RecipeRankService { private final ScrapRepository scrapRepository; private final CommentRepository commentRepository; private final UserService userService; - private final BrandService brandService; - public List getTop5NormalRecipes() { - List topRecipeIds = scrapRepository.findTop5NormalRecipesByScrapCount(PageRequest.of(0, 5)); List topRecipes = new ArrayList<>(); - - for(int i=0; i new RuntimeException("Recipe not found")); - int scrapCount = scrapRepository.countByRecipeId(recipe.getRecipeId()); - int commentCount = commentRepository.countByRecipeId(recipe.getRecipeId()); - + for (int recipeId : topRecipeIds) { + Recipe recipe = recipeRepository.findById(recipeId).orElseThrow(() -> new RuntimeException("Recipe not found")); User user = userService.findUser(recipe.getUserId()); - String brandName = brandService.getBrandNameByBrandId(recipe.getBrandId()); + int scrapCount = scrapRepository.countByRecipeId(recipeId); + String brandName = recipe.getBrandName(); // getBrandId 대신 getBrandName 사용 - topRecipes.add(RecipeResponseDto.fromEntity(recipe,user,brandName, scrapCount,commentCount)); + topRecipes.add(RecipeResponseDto.fromEntity(recipe, user, brandName, scrapCount, 0)); } - return topRecipes; } @@ -54,18 +46,17 @@ public List getTop5CelebrityRecipes() { List topRecipes = new ArrayList<>(); - for(int i=0; i new RuntimeException("Recipe not found")); + for (int recipeId : topRecipeIds) { + Recipe recipe = recipeRepository.findById(recipeId).orElseThrow(() -> new RuntimeException("Recipe not found")); int scrapCount = scrapRepository.countByRecipeId(recipe.getRecipeId()); int commentCount = commentRepository.countByRecipeId(recipe.getRecipeId()); User user = userService.findUser(recipe.getUserId()); - String brandName = brandService.getBrandNameByBrandId(recipe.getBrandId()); + String brandName = recipe.getBrandName(); // getBrandId 대신 getBrandName 사용 - topRecipes.add(RecipeResponseDto.fromEntity(recipe,user,brandName, scrapCount,commentCount)); + topRecipes.add(RecipeResponseDto.fromEntity(recipe, user, brandName, scrapCount, commentCount)); } return topRecipes; } - } diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeService.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeService.java index 9c32e2d..cdac26a 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeService.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeService.java @@ -1,18 +1,18 @@ package CaffeineCoder.recipic.domain.recipe.application; import CaffeineCoder.recipic.domain.brand.api.BrandService; +import CaffeineCoder.recipic.domain.brand.domain.BaseIngredient; +import CaffeineCoder.recipic.domain.brand.domain.Brand; +import CaffeineCoder.recipic.domain.brand.domain.Ingredient; +import CaffeineCoder.recipic.domain.brand.repository.BaseIngredientRepository; import CaffeineCoder.recipic.domain.brand.repository.BrandRepository; import CaffeineCoder.recipic.domain.brand.repository.IngredientRepository; import CaffeineCoder.recipic.domain.comment.dao.CommentLikeRepository; import CaffeineCoder.recipic.domain.comment.dao.CommentRepository; -import CaffeineCoder.recipic.domain.comment.domain.Comment; -import CaffeineCoder.recipic.domain.comment.dto.CommentDto; import CaffeineCoder.recipic.domain.jwtSecurity.util.SecurityUtil; import CaffeineCoder.recipic.domain.recipe.dao.RecipeIngredientRepository; import CaffeineCoder.recipic.domain.recipe.dao.RecipeRepository; import CaffeineCoder.recipic.domain.recipe.domain.Recipe; -import CaffeineCoder.recipic.domain.brand.domain.Ingredient; - import CaffeineCoder.recipic.domain.recipe.domain.RecipeIngredient; import CaffeineCoder.recipic.domain.recipe.domain.RecipeIngredientId; import CaffeineCoder.recipic.domain.recipe.dto.*; @@ -24,7 +24,6 @@ import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; @@ -33,15 +32,14 @@ import org.springframework.transaction.annotation.Transactional; import java.sql.Timestamp; -import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; - @Service @RequiredArgsConstructor public class RecipeService { + private final RecipeRepository recipeRepository; private final RecipeIngredientRepository recipeIngredientRepository; private final BrandRepository brandRepository; @@ -49,22 +47,23 @@ public class RecipeService { private final ScrapRepository scrapRepository; private final CommentRepository commentRepository; private final CommentLikeRepository commentLikeRepository; + private final BaseIngredientRepository baseIngredientRepository; private final UserRepository userRepository; private final BrandService brandService; private final ScrapService scrapService; private final UserService userService; - + @Transactional public void registerRecipe(RecipeRequestDto recipeRequestDto) { Long userId = SecurityUtil.getCurrentMemberId(); - // brandName으로 brandId 찾기 - Integer brandId = brandRepository.findBrandIdByBrandName(recipeRequestDto.getBrandName()) - .orElseThrow(() -> new RuntimeException("Brand not found: " + recipeRequestDto.getBrandName())); + // brandId로 Brand 찾기 + Brand brand = brandRepository.findById(recipeRequestDto.getBrandId()) + .orElseThrow(() -> new RuntimeException("Brand not found")); Recipe recipe = Recipe.builder() .userId(userId) - .brandId(brandId) // brandName 대신 brandId 설정 + .brand(brand) // brandName 대신 brand 엔티티 직접 사용 .title(recipeRequestDto.getTitle()) .description(recipeRequestDto.getDescription()) .imageUrl(recipeRequestDto.getThumbnailUrl()) @@ -75,22 +74,29 @@ public void registerRecipe(RecipeRequestDto recipeRequestDto) { Recipe savedRecipe = recipeRepository.save(recipe); + // BaseIngredient와 Ingredient 구분하여 처리 List recipeIngredients = recipeRequestDto.getSelectedRecipes().stream() .map(selectedRecipe -> { - // ingredientName으로 ingredientId 찾기 - Integer ingredientId = ingredientRepository.findByName(selectedRecipe.getIngredientName()) - .orElseThrow(() -> new RuntimeException("Ingredient not found: " + selectedRecipe.getIngredientName())); + RecipeIngredient.RecipeIngredientBuilder recipeIngredientBuilder = RecipeIngredient.builder(); + RecipeIngredientId recipeIngredientId; - RecipeIngredientId recipeIngredientId = new RecipeIngredientId( - ingredientId, - savedRecipe.getRecipeId() - ); + if (selectedRecipe.isBaseIngredient()) { + BaseIngredient baseIngredient = baseIngredientRepository.findByIngredientName(selectedRecipe.getIngredientName()) + .orElseThrow(() -> new RuntimeException("Base Ingredient not found: " + selectedRecipe.getIngredientName())); - return RecipeIngredient.builder() + recipeIngredientId = new RecipeIngredientId(baseIngredient.getIngredientName(), savedRecipe.getRecipeId()); + recipeIngredientBuilder.baseIngredient(baseIngredient); + } else { + Ingredient ingredient = ingredientRepository.findByIngredientName(selectedRecipe.getIngredientName()) + .orElseThrow(() -> new RuntimeException("Ingredient not found: " + selectedRecipe.getIngredientName())); + + recipeIngredientId = new RecipeIngredientId(ingredient.getIngredientName(), savedRecipe.getRecipeId()); + recipeIngredientBuilder.ingredient(ingredient); + } + + return recipeIngredientBuilder .id(recipeIngredientId) .recipe(savedRecipe) - .ingredient(ingredientRepository.findById(ingredientId) - .orElseThrow(() -> new RuntimeException("Ingredient not found: " + ingredientId))) .count(selectedRecipe.getCount()) .build(); }) @@ -105,53 +111,40 @@ public RecipeDetailResponseDto getRecipeDetail(Integer recipeId) { .orElseThrow(() -> new RuntimeException("Recipe not found")); boolean isScrapped = false; - - // 현재 인증된 사용자가 있는지 확인 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null && authentication.isAuthenticated() && !(authentication instanceof AnonymousAuthenticationToken)) { - Long currentMemberId = SecurityUtil.getCurrentMemberId(); - if (currentMemberId != null) { isScrapped = scrapService.isScrapped(currentMemberId, recipeId); } } - // Fetch scrap count int scrapCount = scrapRepository.countByRecipeId(recipeId); List ingredients = recipeIngredientRepository.findByRecipeId(recipeId); - List includeIngredients = ingredients.stream() .map(ingredient -> { - // Get the ingredientId Integer ingredientId = ingredient.getIngredient().getIngredientId(); - - // Find Ingredient using ingredientId from the repository Ingredient foundIngredient = ingredientRepository.findById(ingredientId) - .orElse(null); // 해당 재료가 없을 경우 null 처리 + .orElse(null); - // Build IncludeIngredientDto with Ingredient object and count return IncludeIngredientDto.builder() - .ingredient(foundIngredient) // Ingredient 객체 자체를 포함 - .count(ingredient.getCount()) // 해당 재료의 수량 포함 + .ingredient(foundIngredient) + .count(ingredient.getCount()) .build(); }) .collect(Collectors.toList()); + Optional optionalUser = userRepository.findById(recipe.getUserId()); + User user = optionalUser.orElseThrow(() -> new RuntimeException("User not found")); - - Optional OptionalUser = userRepository.findById(recipe.getUserId()); - User user = OptionalUser.orElseThrow(() -> new RuntimeException("User not found")); - - String brandName = brandService.getBrandNameByBrandId(recipe.getBrandId()); - + String brandName = recipe.getBrandName(); return RecipeDetailResponseDto.builder() .recipeId(recipe.getRecipeId()) .userNickName(user.getNickName()) - .userProfileImageUrl(user.getProfileImageUrl()) // Set the profile image URL here + .userProfileImageUrl(user.getProfileImageUrl()) .brandName(brandName) .title(recipe.getTitle()) .description(recipe.getDescription()) @@ -165,128 +158,13 @@ public RecipeDetailResponseDto getRecipeDetail(Integer recipeId) { .build(); } - - - - public List getQueriedRecipes(String keyword, int page, int size) { - if(keyword.equals("-1")){ - return getAllRecipes(page, size); - } - - Optional brandId= brandRepository.findBrandIdByBrandName(keyword); - - if(brandId.isEmpty()){ - return Collections.emptyList(); - } - - Page recipeDtoPage = recipeRepository.findRecipesByBrandId(brandId.get(), PageRequest.of(page, size,Sort.by(Sort.Direction.DESC, "createdAt"))); - - List recipeDtos = recipeDtoPage.getContent(); - - List recipeResponseDtos = recipeDtos.stream() - .map(this::getRecipeDtoToRecipeResponseDto) - .collect(Collectors.toList()); - - return recipeResponseDtos; - - } - - - public List getAllRecipes(int page, int size) { - - Page recipePage = recipeRepository.findAll(PageRequest.of(page, size,Sort.by(Sort.Direction.DESC, "createdAt"))); - - List recipes = recipePage.getContent(); - - - - List recipeResponseDtos = recipes.stream() - .map(this::getRecipeToRecipeResponseDto) - .collect(Collectors.toList()); - - return recipeResponseDtos; - } - - public List getUserQueriedRecipes(String keyword, int page, int size, Long userId) { - if(keyword.equals("-1")){ - return getAllUserRecipes(page, size, userId); - } - - Optional brandId= brandRepository.findBrandIdByBrandName(keyword); - - if(brandId.isEmpty()){ - return Collections.emptyList(); - } - - Page recipeDtoPage = recipeRepository.findRecipesByBrandIdAndUserId(brandId.get(), userId, PageRequest.of(page, size,Sort.by(Sort.Direction.DESC, "createdAt"))); - - List recipeDtos = recipeDtoPage.getContent(); - - List recipeResponseDtos = recipeDtos.stream() - .map(this::getRecipeDtoToRecipeResponseDto) - .collect(Collectors.toList()); - - return recipeResponseDtos; - - } - - public List getAllUserRecipes(int page, int size, Long userId) { - Page recipeDtoPage = recipeRepository.findRecipesByUserId(userId, PageRequest.of(page, size,Sort.by(Sort.Direction.DESC, "createdAt"))); - - List recipeDtos = recipeDtoPage.getContent(); - - List recipeResponseDtos = recipeDtos.stream() - .map(this::getRecipeDtoToRecipeResponseDto) - .collect(Collectors.toList()); - - return recipeResponseDtos; - } - - public List getUserQueriedScrapedRecipes(String keyword, int page, int size, List recipeIds) { - if(keyword.equals("-1")){ - return getUserAllScrapedRecipes(page, size, recipeIds); - } - - Optional brandId= brandRepository.findBrandIdByBrandName(keyword); - - if(brandId.isEmpty()){ - return Collections.emptyList(); - } - - Pageable pageable = PageRequest.of(page, size); - Page recipeDtoPages = recipeRepository.findRecipesByBrandIdAndRecipeIds( - brandId.get(), recipeIds, pageable); - - List recipeDtos = recipeDtoPages.getContent(); - - List recipeResponseDtos = recipeDtos.stream() - .map(this::getRecipeDtoToRecipeResponseDto) - .collect(Collectors.toList()); - - return recipeResponseDtos; - } - - public List getUserAllScrapedRecipes(int page, int size, List recipeIds) { - Pageable pageable = PageRequest.of(page, size); - Page recipeDtoPages = recipeRepository.findRecipesByRecipeIds(recipeIds, pageable); - - List recipeDtos = recipeDtoPages.getContent(); - - List recipeResponseDtos = recipeDtos.stream() - .map(this::getRecipeDtoToRecipeResponseDto) - .collect(Collectors.toList()); - - return recipeResponseDtos; - } - - @Transactional public boolean deleteRecipe(Integer recipeId) { - // 현재 인증된 사용자의 ID + // 현재 인증된 사용자의 ID를 가져옴 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); Long userId = Long.parseLong(authentication.getName()); - // 해당 ID의 레시피 찾기 + // 해당 ID의 레시피를 찾기 Recipe recipe = recipeRepository.findById(recipeId) .orElseThrow(() -> new IllegalArgumentException("Recipe not found")); @@ -304,7 +182,6 @@ public boolean deleteRecipe(Integer recipeId) { return true; } - @Transactional public boolean updateRecipe(RecipeRequestDto recipeRequestDto) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); @@ -319,16 +196,16 @@ public boolean updateRecipe(RecipeRequestDto recipeRequestDto) { throw new IllegalArgumentException("You are not authorized to update this recipe"); } - // brandName으로 brandId 찾기 - Integer brandId = brandRepository.findBrandIdByBrandName(recipeRequestDto.getBrandName()) - .orElseThrow(() -> new RuntimeException("Brand not found: " + recipeRequestDto.getBrandName())); + // brandId로 Brand 찾기 + Brand brand = brandRepository.findById(recipeRequestDto.getBrandId()) + .orElseThrow(() -> new IllegalArgumentException("Brand not found")); // 레시피 수정 recipe.updateRecipe( recipeRequestDto.getTitle(), recipeRequestDto.getDescription(), recipeRequestDto.getThumbnailUrl(), - brandId, // brandId 설정 + brand, // brandName 대신 brand 엔티티를 넘김 recipeRequestDto.getIsCelebrity() ); @@ -340,20 +217,20 @@ public boolean updateRecipe(RecipeRequestDto recipeRequestDto) { List recipeIngredients = recipeRequestDto.getSelectedRecipes().stream() .map(selectedRecipe -> { - // ingredientName으로 ingredientId 찾기 - Integer ingredientId = ingredientRepository.findByName(selectedRecipe.getIngredientName()) - .orElseThrow(() -> new RuntimeException("Ingredient not found: " + selectedRecipe.getIngredientName())); + String ingredientName = ingredientRepository.findByIngredientName(selectedRecipe.getIngredientName()) + .orElseThrow(() -> new RuntimeException("Ingredient not found: " + selectedRecipe.getIngredientName())) + .getIngredientName(); RecipeIngredientId recipeIngredientId = new RecipeIngredientId( - ingredientId, + ingredientName, recipe.getRecipeId() ); return RecipeIngredient.builder() .id(recipeIngredientId) .recipe(recipe) - .ingredient(ingredientRepository.findById(ingredientId) - .orElseThrow(() -> new RuntimeException("Ingredient not found: " + ingredientId))) + .ingredient(ingredientRepository.findByIngredientName(ingredientName) + .orElseThrow(() -> new RuntimeException("Ingredient not found: " + ingredientName))) .count(selectedRecipe.getCount()) .build(); }) @@ -363,28 +240,100 @@ public boolean updateRecipe(RecipeRequestDto recipeRequestDto) { return true; } + + + public List getQueriedRecipes(String keyword, int page, int size) { + if (keyword.equals("-1")) { + return getAllRecipes(page, size); + } + + // brandName으로 검색 + String brandName = keyword; + + Page recipeDtoPage = recipeRepository.findRecipesByBrandName(brandName, PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"))); + List recipeDtos = recipeDtoPage.getContent(); + + return recipeDtos.stream() + .map(this::getRecipeDtoToRecipeResponseDto) + .collect(Collectors.toList()); + } + + public List getUserQueriedRecipes(String keyword, int page, int size, Long userId) { + if (keyword.equals("-1")) { + return getAllUserRecipes(page, size, userId); + } + + // brandName으로 검색 + String brandName = keyword; + + Page recipeDtoPage = recipeRepository.findRecipesByBrandNameAndUserId(brandName, userId, PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"))); + List recipeDtos = recipeDtoPage.getContent(); + + return recipeDtos.stream() + .map(this::getRecipeDtoToRecipeResponseDto) + .collect(Collectors.toList()); + } + + public List getUserQueriedScrapedRecipes(String keyword, int page, int size, List recipeIds) { + if (keyword.equals("-1")) { + return getUserAllScrapedRecipes(page, size, recipeIds); + } + + // brandName으로 검색 + String brandName = keyword; + + Page recipeDtoPage = recipeRepository.findRecipesByBrandNameAndRecipeIds(brandName, recipeIds, PageRequest.of(page, size)); + List recipeDtos = recipeDtoPage.getContent(); + + return recipeDtos.stream() + .map(this::getRecipeDtoToRecipeResponseDto) + .collect(Collectors.toList()); + } + + + public List getAllRecipes(int page, int size) { + Page recipePage = recipeRepository.findAll(PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"))); + List recipes = recipePage.getContent(); + + return recipes.stream() + .map(this::getRecipeToRecipeResponseDto) + .collect(Collectors.toList()); + } + + public List getAllUserRecipes(int page, int size, Long userId) { + Page recipeDtoPage = recipeRepository.findRecipesByUserId(userId, PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"))); + List recipeDtos = recipeDtoPage.getContent(); + + return recipeDtos.stream() + .map(this::getRecipeDtoToRecipeResponseDto) + .collect(Collectors.toList()); + } + + public List getUserAllScrapedRecipes(int page, int size, List recipeIds) { + Page recipeDtoPages = recipeRepository.findRecipesByRecipeIds(recipeIds, PageRequest.of(page, size)); + List recipeDtos = recipeDtoPages.getContent(); + + return recipeDtos.stream() + .map(this::getRecipeDtoToRecipeResponseDto) + .collect(Collectors.toList()); + } + private RecipeResponseDto getRecipeDtoToRecipeResponseDto(RecipeDto recipeDto) { int scrapCount = scrapRepository.countByRecipeId(recipeDto.recipeId()); int commentCount = commentRepository.countByRecipeId(recipeDto.recipeId()); User user = userService.findUser(recipeDto.userId()); - - String brandName = brandService.getBrandNameByBrandId(recipeDto.brandId()); + String brandName = recipeDto.brandName(); return RecipeResponseDto.fromDto(recipeDto, user, brandName, scrapCount, commentCount); } private RecipeResponseDto getRecipeToRecipeResponseDto(Recipe recipe) { RecipeDto recipeDto = RecipeDto.fromEntity(recipe); - int scrapCount = scrapRepository.countByRecipeId(recipeDto.recipeId()); int commentCount = commentRepository.countByRecipeId(recipeDto.recipeId()); User user = userService.findUser(recipeDto.userId()); - - String brandName = brandService.getBrandNameByBrandId(recipeDto.brandId()); + String brandName = recipeDto.brandName(); return RecipeResponseDto.fromDto(recipeDto, user, brandName, scrapCount, commentCount); } - - - } diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/dao/RecipeRepository.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/dao/RecipeRepository.java index b5bccbd..3f9c9f2 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/dao/RecipeRepository.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/dao/RecipeRepository.java @@ -2,7 +2,6 @@ import CaffeineCoder.recipic.domain.recipe.domain.Recipe; import CaffeineCoder.recipic.domain.recipe.dto.RecipeDto; -import CaffeineCoder.recipic.domain.recipe.dto.RecipeResponseDto; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; @@ -14,84 +13,84 @@ @Repository public interface RecipeRepository extends JpaRepository { + @Query("SELECT new CaffeineCoder.recipic.domain.recipe.dto.RecipeDto(" + "r.recipeId, " + "r.userId, " + - "r.brandId, " + + "b.brandName, " + // Brand 엔티티에서 brandName을 가져옴 "r.title, " + "r.description, " + "r.imageUrl, " + "r.isCelebrity, " + "r.createdAt, " + "r.status) " + - "FROM Recipe r " + - "WHERE r.brandId = :brandId") - Page findRecipesByBrandId(@Param("brandId") Integer brandId, Pageable pageable); + "FROM Recipe r JOIN r.brand b " + // Recipe와 Brand를 조인 + "WHERE r.userId = :userId") + Page findRecipesByUserId( + @Param("userId") Long userId, + Pageable pageable); @Query("SELECT new CaffeineCoder.recipic.domain.recipe.dto.RecipeDto(" + "r.recipeId, " + "r.userId, " + - "r.brandId, " + + "b.brandName, " + // Brand 엔티티에서 brandName을 가져옴 "r.title, " + "r.description, " + "r.imageUrl, " + "r.isCelebrity, " + "r.createdAt, " + "r.status) " + - "FROM Recipe r " + - "WHERE r.brandId = :brandId AND r.userId = :userId") - Page findRecipesByBrandIdAndUserId(@Param("brandId") Integer brandId, - @Param("userId") Long userId, - Pageable pageable); + "FROM Recipe r JOIN Brand b ON r.brand.brandId = b.brandId " + // Recipe와 Brand를 명시적으로 조인 + "WHERE b.brandName = :brandName") + Page findRecipesByBrandName(@Param("brandName") String brandName, Pageable pageable); @Query("SELECT new CaffeineCoder.recipic.domain.recipe.dto.RecipeDto(" + "r.recipeId, " + "r.userId, " + - "r.brandId, " + + "b.brandName, " + // Brand 엔티티에서 brandName을 가져옴 "r.title, " + "r.description, " + "r.imageUrl, " + "r.isCelebrity, " + "r.createdAt, " + "r.status) " + - "FROM Recipe r " + - "WHERE r.userId = :userId") - Page findRecipesByUserId(@Param("userId") Long userId, Pageable pageable); + "FROM Recipe r JOIN r.brand b " + // Recipe와 Brand를 조인 + "WHERE b.brandName = :brandName AND r.userId = :userId") + Page findRecipesByBrandNameAndUserId( + @Param("brandName") String brandName, + @Param("userId") Long userId, + Pageable pageable); @Query("SELECT new CaffeineCoder.recipic.domain.recipe.dto.RecipeDto(" + "r.recipeId, " + "r.userId, " + - "r.brandId, " + + "b.brandName, " + // Brand 엔티티에서 brandName을 가져옴 "r.title, " + "r.description, " + "r.imageUrl, " + "r.isCelebrity, " + "r.createdAt, " + "r.status) " + - "FROM Recipe r " + - "WHERE r.brandId = :brandId AND r.recipeId IN :recipeIds") - Page findRecipesByBrandIdAndRecipeIds( - @Param("brandId") Integer brandId, + "FROM Recipe r JOIN r.brand b " + // Recipe와 Brand를 조인 + "WHERE b.brandName = :brandName AND r.recipeId IN :recipeIds") + Page findRecipesByBrandNameAndRecipeIds( + @Param("brandName") String brandName, @Param("recipeIds") List recipeIds, Pageable pageable); @Query("SELECT new CaffeineCoder.recipic.domain.recipe.dto.RecipeDto(" + "r.recipeId, " + "r.userId, " + - "r.brandId, " + + "b.brandName, " + // Brand 엔티티에서 brandName을 가져옴 "r.title, " + "r.description, " + "r.imageUrl, " + "r.isCelebrity, " + "r.createdAt, " + "r.status) " + - "FROM Recipe r " + + "FROM Recipe r JOIN r.brand b " + // Recipe와 Brand를 조인 "WHERE r.recipeId IN :recipeIds") Page findRecipesByRecipeIds( @Param("recipeIds") List recipeIds, Pageable pageable); - - } - - diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/Recipe.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/Recipe.java index ba0f2d3..d3231a3 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/Recipe.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/Recipe.java @@ -1,5 +1,6 @@ package CaffeineCoder.recipic.domain.recipe.domain; +import CaffeineCoder.recipic.domain.brand.domain.Brand; import CaffeineCoder.recipic.domain.comment.domain.Comment; import CaffeineCoder.recipic.domain.scrap.domain.Scrap; import jakarta.persistence.*; @@ -25,8 +26,9 @@ public class Recipe { @Column(name = "user_id") private Long userId; - @Column(name = "brand_id") - private Integer brandId; + @ManyToOne + @JoinColumn(name = "brand_id") + private Brand brand; @Column(name = "title") private String title; @@ -40,7 +42,7 @@ public class Recipe { @Column(name = "is_celebrity") private Boolean isCelebrity; - @Column(name = "created_at") + @Column(name = "created_at", updatable = false) private Timestamp createdAt; @Column(name = "status") @@ -57,9 +59,9 @@ public class Recipe { private List scraps; @Builder - public Recipe(Long userId, Integer brandId, String title, String description, String imageUrl, Boolean isCelebrity, Timestamp createdAt, Integer status) { + public Recipe(Long userId, Brand brand, String title, String description, String imageUrl, Boolean isCelebrity, Timestamp createdAt, Integer status) { this.userId = userId; - this.brandId = brandId; + this.brand = brand; this.title = title; this.description = description; this.imageUrl = imageUrl; @@ -68,12 +70,24 @@ public Recipe(Long userId, Integer brandId, String title, String description, St this.status = status; } + @PrePersist + protected void onCreate() { + if (this.createdAt == null) { + this.createdAt = new Timestamp(System.currentTimeMillis()); + } + } + // 게시글 수정 메소드 - public void updateRecipe(String title, String description, String imageUrl, Integer brandId, Boolean isCelebrity) { + public void updateRecipe(String title, String description, String imageUrl, Brand brand, Boolean isCelebrity) { this.title = title; this.description = description; this.imageUrl = imageUrl; - this.brandId = brandId; + this.brand = brand; this.isCelebrity = isCelebrity; } + + // Brand의 이름을 반환하는 메서드 + public String getBrandName() { + return this.brand != null ? this.brand.getBrandName() : null; + } } diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredient.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredient.java index 68f1e3c..694836f 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredient.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredient.java @@ -1,5 +1,6 @@ package CaffeineCoder.recipic.domain.recipe.domain; +import CaffeineCoder.recipic.domain.brand.domain.BaseIngredient; import CaffeineCoder.recipic.domain.brand.domain.Ingredient; import jakarta.persistence.*; import lombok.Builder; @@ -19,19 +20,27 @@ public class RecipeIngredient { @JoinColumn(name = "recipe_id") private Recipe recipe; + // 일반 재료 매핑 @ManyToOne - @MapsId("ingredientId") - @JoinColumn(name = "ingredient_id") + @MapsId("ingredientName") + @JoinColumn(name = "ingredient_name", referencedColumnName = "ingredient_name") private Ingredient ingredient; + // 기본 재료 매핑 + @ManyToOne + @MapsId("ingredientName") + @JoinColumn(name = "base_ingredient_name", referencedColumnName = "ingredient_name") + private BaseIngredient baseIngredient; + @Column(name = "count") private Integer count; @Builder - public RecipeIngredient(RecipeIngredientId id, Recipe recipe, Ingredient ingredient, Integer count) { + public RecipeIngredient(RecipeIngredientId id, Recipe recipe, Ingredient ingredient, BaseIngredient baseIngredient, Integer count) { this.id = id; this.recipe = recipe; this.ingredient = ingredient; + this.baseIngredient = baseIngredient; this.count = count; } -} \ No newline at end of file +} diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredientId.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredientId.java index ae0a82b..9bac237 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredientId.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredientId.java @@ -13,14 +13,14 @@ @NoArgsConstructor public class RecipeIngredientId implements Serializable { - @Column(name = "ingredient_id") - private Integer ingredientId; + @Column(name = "ingredient_name") + private String ingredientName; @Column(name = "recipe_id") private Integer recipeId; - public RecipeIngredientId(Integer ingredientId, Integer recipeId) { - this.ingredientId = ingredientId; + public RecipeIngredientId(String ingredientName, Integer recipeId) { + this.ingredientName = ingredientName; this.recipeId = recipeId; } @@ -29,12 +29,12 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; RecipeIngredientId that = (RecipeIngredientId) o; - return Objects.equals(ingredientId, that.ingredientId) && + return Objects.equals(ingredientName, that.ingredientName) && Objects.equals(recipeId, that.recipeId); } @Override public int hashCode() { - return Objects.hash(ingredientId, recipeId); + return Objects.hash(ingredientName, recipeId); } -} \ No newline at end of file +} diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeDto.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeDto.java index 236d246..b33148d 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeDto.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeDto.java @@ -5,26 +5,26 @@ import java.sql.Timestamp; public record RecipeDto( - Integer recipeId, - Long userId, - Integer brandId, - String title, - String description, - String imageUrl, - Boolean isCelebrity, - Timestamp createdAt, - Integer status + Integer recipeId, + Long userId, + String brandName, // brandId -> brandName으로 변경 + String title, + String description, + String imageUrl, + Boolean isCelebrity, + Timestamp createdAt, + Integer status ) { - public static RecipeDto of(Integer recipeId, Long userId, Integer brandId, String title, String description, String imageUrl, Boolean isCelebrity, Timestamp createdAt, Integer status) { - return new RecipeDto(recipeId, userId, brandId, title, description, imageUrl, isCelebrity, createdAt, status); + public static RecipeDto of(Integer recipeId, Long userId, String brandName, String title, String description, String imageUrl, Boolean isCelebrity, Timestamp createdAt, Integer status) { + return new RecipeDto(recipeId, userId, brandName, title, description, imageUrl, isCelebrity, createdAt, status); } public static RecipeDto fromEntity(Recipe recipe) { return new RecipeDto( recipe.getRecipeId(), recipe.getUserId(), - recipe.getBrandId(), + recipe.getBrandName(), recipe.getTitle(), recipe.getDescription(), recipe.getImageUrl(), @@ -34,5 +34,3 @@ public static RecipeDto fromEntity(Recipe recipe) { ); } } - - diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeRequestDto.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeRequestDto.java index 996a2fb..e872f1d 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeRequestDto.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeRequestDto.java @@ -14,7 +14,7 @@ public class RecipeRequestDto { private Integer recipeId; - private String brandName; + private Integer brandId; private String title; private String thumbnailUrl; private List selectedRecipes; @@ -28,5 +28,10 @@ public class RecipeRequestDto { public static class SelectedRecipeDto { private String ingredientName; private Integer count; + private Boolean isBaseIngredient; // BaseIngredient 여부 + + public Boolean isBaseIngredient() { + return isBaseIngredient; + } } } diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeResponseDto.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeResponseDto.java index 8fa7a8c..ac88dc3 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeResponseDto.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeResponseDto.java @@ -24,14 +24,14 @@ public static RecipeResponseDto of(Integer recipeId, String userName,String user } //추후 댓글 개수도 추가 - public static RecipeResponseDto fromEntity(Recipe recipe, User user,String brandName, int scrapCount, int commentCount) { + public static RecipeResponseDto fromEntity(Recipe recipe, User user, String brandName, int scrapCount, int commentCount) { return new RecipeResponseDto( recipe.getRecipeId(), user.getNickName(), user.getProfileImageUrl(), recipe.getTitle(), recipe.getImageUrl(), - brandName, + brandName, // 추가된 brandName recipe.getDescription(), recipe.getIsCelebrity(), recipe.getCreatedAt(), @@ -40,7 +40,6 @@ public static RecipeResponseDto fromEntity(Recipe recipe, User user,String brand commentCount ); } - public static RecipeResponseDto fromDto(RecipeDto recipeDto,User user,String brandName, int scrapCount, int commentCount) { return new RecipeResponseDto( recipeDto.recipeId(), From 7d5d168d728456e70ab4f91de9a4c9e42f88f7ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9D=80?= <113881692+knxxxn@users.noreply.github.com> Date: Thu, 19 Sep 2024 22:56:25 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20side=20=EC=9E=AC=EB=A3=8C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/brand/api/BrandController.java | 18 ++++++++++-- .../domain/brand/api/BrandService.java | 29 +++++++++++++++++-- .../recipe/application/RecipeRankService.java | 4 +-- .../recipe/application/RecipeService.java | 2 +- .../recipic/domain/recipe/dto/RecipeDto.java | 2 +- 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java index 792d140..7f91b39 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java @@ -36,16 +36,18 @@ public ResponseEntity> addBaseIngredientToBrand(@RequestBody return ResponseEntity.ok(response); } - // Ingredient 추가 API + // Ingredient 추가 API (BaseIngredient에 연결) @PostMapping("/add-ingredient") public ResponseEntity> addIngredient(@RequestBody Map request) { + Integer baseIngredientId = (Integer) request.get("baseIngredientId"); // BaseIngredient의 ID를 받음 String ingredientName = (String) request.get("ingredientName"); Long quantity = Long.parseLong(request.get("quantity").toString()); String unit = (String) request.get("unit"); Integer cost = (Integer) request.get("cost"); Double calorie = Double.parseDouble(request.get("calorie").toString()); - boolean success = brandService.addIngredient(ingredientName, quantity, unit, cost, calorie); + // baseIngredientId를 추가해서 호출 + boolean success = brandService.addIngredient(baseIngredientId, ingredientName, quantity, unit, cost, calorie); Map response = new LinkedHashMap<>(); response.put("isSuccess", success); @@ -66,6 +68,18 @@ public ResponseEntity> getBaseIngredientsByBrandName(@Reques return ResponseEntity.ok(response); } + // 특정 BaseIngredient에 매핑된 Ingredient 조회 API + @GetMapping("/baseingredient/{baseIngredientId}/ingredients") + public ResponseEntity> getIngredientsByBaseIngredientId(@PathVariable Integer baseIngredientId) { + List> ingredients = brandService.getIngredientsByBaseIngredientId(baseIngredientId); + + Map response = new LinkedHashMap<>(); + response.put("isSuccess", true); + response.put("response", ingredients); + + return ResponseEntity.ok(response); + } + // 모든 브랜드 가져오기 @GetMapping("/list") public ResponseEntity> getAllBrands() { diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java index 118b358..92f0f5c 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java @@ -49,9 +49,9 @@ public boolean addBaseIngredientToBrand(Integer brandId, String ingredientName, } // Ingredient 추가 (BaseIngredient와 관계) - public boolean addIngredient(String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { + public boolean addIngredient(Integer baseIngredientId, String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { // BaseIngredient를 찾음 - Optional optionalBaseIngredient = baseIngredientRepository.findByIngredientName(ingredientName); + Optional optionalBaseIngredient = baseIngredientRepository.findById(baseIngredientId); if (optionalBaseIngredient.isEmpty()) { return false; } @@ -91,6 +91,31 @@ public List> getBaseIngredientsByBrandName(String brandName) .collect(Collectors.toList()); } + // BaseIngredient에 매핑된 Ingredient 조회 + public List> getIngredientsByBaseIngredientId(Integer baseIngredientId) { + Optional optionalBaseIngredient = baseIngredientRepository.findById(baseIngredientId); + + if (optionalBaseIngredient.isEmpty()) { + throw new RuntimeException("BaseIngredient not found with ID: " + baseIngredientId); + } + + BaseIngredient baseIngredient = optionalBaseIngredient.get(); + + // BaseIngredient에 매핑된 Ingredient들을 가져와 Map으로 변환 + return baseIngredient.getIngredients().stream() + .map(ingredient -> { + Map ingredientMap = new LinkedHashMap<>(); + ingredientMap.put("ingredientId", ingredient.getIngredientId()); + ingredientMap.put("name", ingredient.getIngredientName()); + ingredientMap.put("quantity", ingredient.getQuantity()); + ingredientMap.put("unit", ingredient.getUnit()); + ingredientMap.put("cost", ingredient.getCost()); + ingredientMap.put("calorie", ingredient.getCalorie()); + return ingredientMap; + }) + .collect(Collectors.toList()); + } + // 모든 브랜드 가져오기 public List> getAllBrands() { return brandRepository.findAll().stream() diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeRankService.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeRankService.java index 2b77506..53307ed 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeRankService.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeRankService.java @@ -32,7 +32,7 @@ public List getTop5NormalRecipes() { User user = userService.findUser(recipe.getUserId()); int scrapCount = scrapRepository.countByRecipeId(recipeId); - String brandName = recipe.getBrandName(); // getBrandId 대신 getBrandName 사용 + String brandName = recipe.getBrandName(); topRecipes.add(RecipeResponseDto.fromEntity(recipe, user, brandName, scrapCount, 0)); } @@ -52,7 +52,7 @@ public List getTop5CelebrityRecipes() { int commentCount = commentRepository.countByRecipeId(recipe.getRecipeId()); User user = userService.findUser(recipe.getUserId()); - String brandName = recipe.getBrandName(); // getBrandId 대신 getBrandName 사용 + String brandName = recipe.getBrandName(); topRecipes.add(RecipeResponseDto.fromEntity(recipe, user, brandName, scrapCount, commentCount)); } diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeService.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeService.java index cdac26a..2dd0b21 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeService.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeService.java @@ -205,7 +205,7 @@ public boolean updateRecipe(RecipeRequestDto recipeRequestDto) { recipeRequestDto.getTitle(), recipeRequestDto.getDescription(), recipeRequestDto.getThumbnailUrl(), - brand, // brandName 대신 brand 엔티티를 넘김 + brand, recipeRequestDto.getIsCelebrity() ); diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeDto.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeDto.java index b33148d..6af3269 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeDto.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeDto.java @@ -7,7 +7,7 @@ public record RecipeDto( Integer recipeId, Long userId, - String brandName, // brandId -> brandName으로 변경 + String brandName, String title, String description, String imageUrl, From 6dcd0b352558602a4ef3ef20704c92da913fad8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9D=80?= <113881692+knxxxn@users.noreply.github.com> Date: Mon, 23 Sep 2024 23:43:53 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20=EB=B2=A0=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=9E=AC=EB=A3=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 사이즈 추가 및 베이스 엔티티 수정 --- .../domain/brand/api/BrandController.java | 8 +- .../domain/brand/api/BrandService.java | 66 +++---- .../domain/brand/domain/BaseIngredient.java | 26 +-- .../brand/domain/BaseIngredientSize.java | 30 ++++ .../domain/brand/domain/BrandIngredient.java | 14 +- .../domain/brand/domain/Ingredient.java | 6 +- .../brand/domain/RecipeBaseIngredient.java | 38 ++++ .../repository/BaseIngredientRepository.java | 1 - .../BaseIngredientSizeRepository.java | 9 + .../domain/recipe/api/RecipeController.java | 5 +- .../recipe/application/RecipeService.java | 168 ++++++++---------- .../dao/RecipeBaseIngredientRepository.java | 9 + .../dao/RecipeIngredientRepository.java | 1 + .../recipic/domain/recipe/domain/Recipe.java | 2 + .../recipe/domain/RecipeIngredient.java | 12 +- .../recipe/domain/RecipeIngredientId.java | 21 ++- .../recipe/dto/IncludeIngredientDto.java | 8 +- .../domain/recipe/dto/RecipeRequestDto.java | 7 +- 18 files changed, 234 insertions(+), 197 deletions(-) create mode 100644 src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredientSize.java create mode 100644 src/main/java/CaffeineCoder/recipic/domain/brand/domain/RecipeBaseIngredient.java create mode 100644 src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientSizeRepository.java create mode 100644 src/main/java/CaffeineCoder/recipic/domain/recipe/dao/RecipeBaseIngredientRepository.java diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java index 7f91b39..da2e18e 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandController.java @@ -22,12 +22,9 @@ public BrandController(BrandService brandService) { public ResponseEntity> addBaseIngredientToBrand(@RequestBody Map request) { Integer brandId = (Integer) request.get("brandId"); String ingredientName = (String) request.get("ingredientName"); - Long quantity = Long.parseLong(request.get("quantity").toString()); - String unit = (String) request.get("unit"); - Integer cost = (Integer) request.get("cost"); - Double calorie = Double.parseDouble(request.get("calorie").toString()); + String size = (String) request.get("size"); - boolean success = brandService.addBaseIngredientToBrand(brandId, ingredientName, quantity, unit, cost, calorie); + boolean success = brandService.addBaseIngredientToBrand(brandId, ingredientName, size); Map response = new LinkedHashMap<>(); response.put("isSuccess", success); @@ -36,6 +33,7 @@ public ResponseEntity> addBaseIngredientToBrand(@RequestBody return ResponseEntity.ok(response); } + // Ingredient 추가 API (BaseIngredient에 연결) @PostMapping("/add-ingredient") public ResponseEntity> addIngredient(@RequestBody Map request) { diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java index 92f0f5c..1886d3f 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/api/BrandService.java @@ -1,13 +1,7 @@ package CaffeineCoder.recipic.domain.brand.api; -import CaffeineCoder.recipic.domain.brand.domain.BaseIngredient; -import CaffeineCoder.recipic.domain.brand.domain.Brand; -import CaffeineCoder.recipic.domain.brand.domain.BrandIngredient; -import CaffeineCoder.recipic.domain.brand.domain.Ingredient; -import CaffeineCoder.recipic.domain.brand.repository.BaseIngredientRepository; -import CaffeineCoder.recipic.domain.brand.repository.BrandIngredientRepository; -import CaffeineCoder.recipic.domain.brand.repository.BrandRepository; -import CaffeineCoder.recipic.domain.brand.repository.IngredientRepository; +import CaffeineCoder.recipic.domain.brand.domain.*; +import CaffeineCoder.recipic.domain.brand.repository.*; import org.springframework.stereotype.Service; import java.util.LinkedHashMap; @@ -20,54 +14,49 @@ public class BrandService { private final BrandRepository brandRepository; - private final BrandIngredientRepository brandIngredientRepository; - private final IngredientRepository ingredientRepository; private final BaseIngredientRepository baseIngredientRepository; + private final IngredientRepository ingredientRepository; + private final BaseIngredientSizeRepository baseIngredientSizeRepository; - public BrandService(BrandRepository brandRepository, BrandIngredientRepository brandIngredientRepository, - IngredientRepository ingredientRepository, BaseIngredientRepository baseIngredientRepository) { + public BrandService(BrandRepository brandRepository, BaseIngredientRepository baseIngredientRepository, + IngredientRepository ingredientRepository, BaseIngredientSizeRepository baseIngredientSizeRepository) { this.brandRepository = brandRepository; - this.brandIngredientRepository = brandIngredientRepository; - this.ingredientRepository = ingredientRepository; this.baseIngredientRepository = baseIngredientRepository; + this.ingredientRepository = ingredientRepository; + this.baseIngredientSizeRepository = baseIngredientSizeRepository; } // BaseIngredient 추가 (brandId 사용) - public boolean addBaseIngredientToBrand(Integer brandId, String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { - Optional optionalBrand = brandRepository.findById(brandId); - if (optionalBrand.isEmpty()) { - throw new RuntimeException("Brand not found with ID: " + brandId); - } - Brand brand = optionalBrand.get(); + public boolean addBaseIngredientToBrand(Integer brandId, String ingredientName, String size) { + Brand brand = brandRepository.findById(brandId) + .orElseThrow(() -> new RuntimeException("Brand not found with ID: " + brandId)); // BaseIngredient 생성 및 저장 - BaseIngredient baseIngredient = new BaseIngredient(ingredientName, quantity, unit, cost, calorie); - baseIngredient.setBrand(brand); // Brand와 연결 - baseIngredientRepository.save(baseIngredient); // 저장 + BaseIngredient baseIngredient = new BaseIngredient(ingredientName, brand); + baseIngredientRepository.save(baseIngredient); + + // BaseIngredientSize도 생성 및 저장 + BaseIngredientSize baseIngredientSize = new BaseIngredientSize(size, baseIngredient); + baseIngredientSizeRepository.save(baseIngredientSize); return true; } - // Ingredient 추가 (BaseIngredient와 관계) + // Ingredient 추가 (BaseIngredient와 연결) public boolean addIngredient(Integer baseIngredientId, String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { - // BaseIngredient를 찾음 - Optional optionalBaseIngredient = baseIngredientRepository.findById(baseIngredientId); - if (optionalBaseIngredient.isEmpty()) { - return false; - } + BaseIngredient baseIngredient = baseIngredientRepository.findById(baseIngredientId) + .orElseThrow(() -> new RuntimeException("BaseIngredient not found with ID: " + baseIngredientId)); - // Ingredient 생성 및 저장 Ingredient ingredient = Ingredient.builder() .ingredientName(ingredientName) .quantity(quantity) .unit(unit) .cost(cost) .calorie(calorie) - .baseIngredient(optionalBaseIngredient.get()) + .baseIngredient(baseIngredient) .build(); ingredientRepository.save(ingredient); - return true; } @@ -82,10 +71,6 @@ public List> getBaseIngredientsByBrandName(String brandName) Map baseIngredientMap = new LinkedHashMap<>(); baseIngredientMap.put("ingredientId", baseIngredient.getBaseIngredientId()); baseIngredientMap.put("name", baseIngredient.getIngredientName()); - baseIngredientMap.put("quantity", baseIngredient.getQuantity()); - baseIngredientMap.put("unit", baseIngredient.getUnit()); - baseIngredientMap.put("cost", baseIngredient.getCost()); - baseIngredientMap.put("calorie", baseIngredient.getCalorie()); return baseIngredientMap; }) .collect(Collectors.toList()); @@ -93,13 +78,8 @@ public List> getBaseIngredientsByBrandName(String brandName) // BaseIngredient에 매핑된 Ingredient 조회 public List> getIngredientsByBaseIngredientId(Integer baseIngredientId) { - Optional optionalBaseIngredient = baseIngredientRepository.findById(baseIngredientId); - - if (optionalBaseIngredient.isEmpty()) { - throw new RuntimeException("BaseIngredient not found with ID: " + baseIngredientId); - } - - BaseIngredient baseIngredient = optionalBaseIngredient.get(); + BaseIngredient baseIngredient = baseIngredientRepository.findById(baseIngredientId) + .orElseThrow(() -> new RuntimeException("BaseIngredient not found with ID: " + baseIngredientId)); // BaseIngredient에 매핑된 Ingredient들을 가져와 Map으로 변환 return baseIngredient.getIngredients().stream() diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredient.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredient.java index ad96473..a880a26 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredient.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredient.java @@ -19,35 +19,19 @@ public class BaseIngredient { @Column(name = "ingredient_name", nullable = false) private String ingredientName; - @Column(name = "quantity", nullable = false) - private Long quantity; - - @Column(name = "unit", nullable = false) - private String unit; - - @Column(name = "cost") - private Integer cost; - - @Column(name = "calorie") - private Double calorie; + @OneToMany(mappedBy = "baseIngredient", cascade = CascadeType.ALL, orphanRemoval = true) + private List baseIngredientSizes; @ManyToOne @JoinColumn(name = "brand_id", nullable = false) private Brand brand; - // Ingredient와의 관계 설정 (OneToMany) @OneToMany(mappedBy = "baseIngredient", cascade = CascadeType.ALL, orphanRemoval = true) - private List ingredients; + private List ingredients; // Ingredient와 연결 - public BaseIngredient(String ingredientName, Long quantity, String unit, Integer cost, Double calorie) { + public BaseIngredient(String ingredientName, Brand brand) { this.ingredientName = ingredientName; - this.quantity = quantity; - this.unit = unit; - this.cost = cost; - this.calorie = calorie; - } - - public void setBrand(Brand brand) { this.brand = brand; } } + diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredientSize.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredientSize.java new file mode 100644 index 0000000..a7a423a --- /dev/null +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BaseIngredientSize.java @@ -0,0 +1,30 @@ +package CaffeineCoder.recipic.domain.brand.domain; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor +public class BaseIngredientSize { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "baseingredient_size_id") + private Integer baseIngredientSizeId; + + @Column(name = "size", nullable = false) + private String size; + + @ManyToOne + @JoinColumn(name = "baseingredient_id", nullable = false) + private BaseIngredient baseIngredient; + + public BaseIngredientSize(String size, BaseIngredient baseIngredient) { + this.size = size; + this.baseIngredient = baseIngredient; + } +} + + diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BrandIngredient.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BrandIngredient.java index be6c98c..e012c6c 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BrandIngredient.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/BrandIngredient.java @@ -22,17 +22,9 @@ public class BrandIngredient { @JoinColumn(name = "baseingredient_id") private BaseIngredient baseIngredient; - public void setBaseIngredient(BaseIngredient baseIngredient) { - this.baseIngredient = baseIngredient; - if (this.brand != null) { - this.id = new BrandIngredientId(this.brand.getBrandId(), baseIngredient.getBaseIngredientId()); - } - } - - public void setBrand(Brand brand) { + public BrandIngredient(Brand brand, BaseIngredient baseIngredient) { this.brand = brand; - if (this.baseIngredient != null) { - this.id = new BrandIngredientId(brand.getBrandId(), this.baseIngredient.getBaseIngredientId()); - } + this.baseIngredient = baseIngredient; + this.id = new BrandIngredientId(brand.getBrandId(), baseIngredient.getBaseIngredientId()); } } diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Ingredient.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Ingredient.java index 98ae12e..aae165a 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Ingredient.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/Ingredient.java @@ -18,10 +18,10 @@ public class Ingredient { @Column(name = "ingredient_name", nullable = false) private String ingredientName; - @Column(name = "quantity") + @Column(name = "quantity", nullable = false) private Long quantity; - @Column(name = "unit") + @Column(name = "unit", nullable = false) private String unit; @Column(name = "cost") @@ -30,7 +30,7 @@ public class Ingredient { @Column(name = "calorie") private Double calorie; - // BaseIngredient와의 관계 설정 (ManyToOne) + // BaseIngredient와 관계 설정 (ManyToOne) @ManyToOne @JoinColumn(name = "baseingredient_id", nullable = false) private BaseIngredient baseIngredient; diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/domain/RecipeBaseIngredient.java b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/RecipeBaseIngredient.java new file mode 100644 index 0000000..706a58e --- /dev/null +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/domain/RecipeBaseIngredient.java @@ -0,0 +1,38 @@ +package CaffeineCoder.recipic.domain.brand.domain; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import CaffeineCoder.recipic.domain.recipe.domain.Recipe; + +@Entity +@Getter +@NoArgsConstructor +public class RecipeBaseIngredient { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "recipe_baseingredient_id") + private Integer recipeBaseIngredientId; + + @ManyToOne + @JoinColumn(name = "recipe_id", nullable = false) + private Recipe recipe; + + @ManyToOne + @JoinColumn(name = "baseingredient_id", nullable = false) + private BaseIngredient baseIngredient; + + public RecipeBaseIngredient(Recipe recipe, BaseIngredient baseIngredient) { + this.recipe = recipe; + this.baseIngredient = baseIngredient; + } + + public void setRecipe(Recipe recipe) { + this.recipe = recipe; + } + + public void setBaseIngredient(BaseIngredient baseIngredient) { + this.baseIngredient = baseIngredient; + } +} diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientRepository.java b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientRepository.java index 75d96bc..ff13e4d 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientRepository.java +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientRepository.java @@ -13,6 +13,5 @@ public interface BaseIngredientRepository extends JpaRepository findByIngredientName(String ingredientName); - List findByBrand(Brand brand); } diff --git a/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientSizeRepository.java b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientSizeRepository.java new file mode 100644 index 0000000..3d5da99 --- /dev/null +++ b/src/main/java/CaffeineCoder/recipic/domain/brand/repository/BaseIngredientSizeRepository.java @@ -0,0 +1,9 @@ +package CaffeineCoder.recipic.domain.brand.repository; + +import CaffeineCoder.recipic.domain.brand.domain.BaseIngredientSize; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface BaseIngredientSizeRepository extends JpaRepository { +} diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/api/RecipeController.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/api/RecipeController.java index 79cfce0..b82abab 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/api/RecipeController.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/api/RecipeController.java @@ -21,7 +21,6 @@ public class RecipeController { private final RecipeService recipeService; public RecipeController(RecipeService recipeService) { - this.recipeService = recipeService; } @@ -30,7 +29,7 @@ public ResponseEntity> registerRecipe( @RequestPart(value="recipe") RecipeRequestDto recipeRequestDto, @RequestPart(value="thumbnailImage") MultipartFile thumbnailImage ) { - recipeService.registerRecipe(recipeRequestDto,thumbnailImage); + recipeService.registerRecipe(recipeRequestDto, thumbnailImage); return ResponseEntity.ok(Map.of("isSuccess", true)); } @@ -69,4 +68,4 @@ public ApiResponse getScraps( @RequestParam(value = "size", defaultValue = "10") int size) { return ApiUtils.success(recipeService.getQueriedRecipes(keyword, page, size)); } -} \ No newline at end of file +} diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeService.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeService.java index c8d2e20..a124991 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeService.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/application/RecipeService.java @@ -7,7 +7,6 @@ import CaffeineCoder.recipic.domain.brand.repository.BaseIngredientRepository; import CaffeineCoder.recipic.domain.brand.repository.BrandRepository; import CaffeineCoder.recipic.domain.brand.repository.IngredientRepository; -import CaffeineCoder.recipic.domain.comment.dao.CommentLikeRepository; import CaffeineCoder.recipic.domain.comment.dao.CommentRepository; import CaffeineCoder.recipic.domain.jwtSecurity.util.SecurityUtil; import CaffeineCoder.recipic.domain.recipe.dao.RecipeIngredientRepository; @@ -21,7 +20,6 @@ import CaffeineCoder.recipic.domain.user.application.UserService; import CaffeineCoder.recipic.domain.user.dao.UserRepository; import CaffeineCoder.recipic.domain.user.domain.User; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; @@ -48,10 +46,9 @@ public class RecipeService { private final RecipeIngredientRepository recipeIngredientRepository; private final BrandRepository brandRepository; private final IngredientRepository ingredientRepository; + private final BaseIngredientRepository baseIngredientRepository; private final ScrapRepository scrapRepository; private final CommentRepository commentRepository; - private final CommentLikeRepository commentLikeRepository; - private final BaseIngredientRepository baseIngredientRepository; private final UserRepository userRepository; private final BrandService brandService; private final ScrapService scrapService; @@ -61,18 +58,14 @@ public class RecipeService { @Value("${spring.cloud.gcp.storage.bucket}") private String bucketName; - public void registerRecipe(RecipeRequestDto recipeRequestDto, MultipartFile thumbnailImage) { - - @Transactional - public void registerRecipe(RecipeRequestDto recipeRequestDto) { + public void registerRecipe(RecipeRequestDto recipeRequestDto, MultipartFile thumbnailImage) { Long userId = SecurityUtil.getCurrentMemberId(); - // brandId로 Brand 찾기 Brand brand = brandRepository.findById(recipeRequestDto.getBrandId()) .orElseThrow(() -> new RuntimeException("Brand not found")); - String uuid = null; // 유저가 이미지를 없애도록 수정한 경우 + String uuid = null; try { if (!thumbnailImage.isEmpty()) { @@ -82,11 +75,9 @@ public void registerRecipe(RecipeRequestDto recipeRequestDto) { e.printStackTrace(); } - - Recipe recipe = Recipe.builder() .userId(userId) - .brand(brand) // brandName 대신 brand 엔티티 직접 사용 + .brand(brand) .title(recipeRequestDto.getTitle()) .description(recipeRequestDto.getDescription()) .imageUrl(uuid) @@ -97,7 +88,6 @@ public void registerRecipe(RecipeRequestDto recipeRequestDto) { Recipe savedRecipe = recipeRepository.save(recipe); - // BaseIngredient와 Ingredient 구분하여 처리 List recipeIngredients = recipeRequestDto.getSelectedRecipes().stream() .map(selectedRecipe -> { RecipeIngredient.RecipeIngredientBuilder recipeIngredientBuilder = RecipeIngredient.builder(); @@ -107,13 +97,21 @@ public void registerRecipe(RecipeRequestDto recipeRequestDto) { BaseIngredient baseIngredient = baseIngredientRepository.findByIngredientName(selectedRecipe.getIngredientName()) .orElseThrow(() -> new RuntimeException("Base Ingredient not found: " + selectedRecipe.getIngredientName())); - recipeIngredientId = new RecipeIngredientId(baseIngredient.getIngredientName(), savedRecipe.getRecipeId()); + recipeIngredientId = new RecipeIngredientId( + savedRecipe.getRecipeId(), + null, + baseIngredient.getBaseIngredientId() + ); recipeIngredientBuilder.baseIngredient(baseIngredient); } else { Ingredient ingredient = ingredientRepository.findByIngredientName(selectedRecipe.getIngredientName()) .orElseThrow(() -> new RuntimeException("Ingredient not found: " + selectedRecipe.getIngredientName())); - recipeIngredientId = new RecipeIngredientId(ingredient.getIngredientName(), savedRecipe.getRecipeId()); + recipeIngredientId = new RecipeIngredientId( + savedRecipe.getRecipeId(), + ingredient.getIngredientId(), + null + ); recipeIngredientBuilder.ingredient(ingredient); } @@ -128,7 +126,6 @@ public void registerRecipe(RecipeRequestDto recipeRequestDto) { recipeIngredientRepository.saveAll(recipeIngredients); } - public RecipeDetailResponseDto getRecipeDetail(Integer recipeId) { Recipe recipe = recipeRepository.findById(recipeId) .orElseThrow(() -> new RuntimeException("Recipe not found")); @@ -148,19 +145,24 @@ public RecipeDetailResponseDto getRecipeDetail(Integer recipeId) { List ingredients = recipeIngredientRepository.findByRecipeId(recipeId); List includeIngredients = ingredients.stream() .map(ingredient -> { - Integer ingredientId = ingredient.getIngredient().getIngredientId(); - Ingredient foundIngredient = ingredientRepository.findById(ingredientId) - .orElse(null); - - return IncludeIngredientDto.builder() - .ingredient(foundIngredient) - .count(ingredient.getCount()) - .build(); + if (ingredient.getIngredient() != null) { + Ingredient foundIngredient = ingredient.getIngredient(); + return IncludeIngredientDto.builder() + .ingredient(foundIngredient) + .count(ingredient.getCount()) + .build(); + } else { + BaseIngredient foundBaseIngredient = ingredient.getBaseIngredient(); + return IncludeIngredientDto.builder() + .baseIngredient(foundBaseIngredient) + .count(ingredient.getCount()) + .build(); + } }) .collect(Collectors.toList()); - Optional optionalUser = userRepository.findById(recipe.getUserId()); - User user = optionalUser.orElseThrow(() -> new RuntimeException("User not found")); + User user = userRepository.findById(recipe.getUserId()) + .orElseThrow(() -> new RuntimeException("User not found")); String brandName = recipe.getBrandName(); @@ -183,24 +185,19 @@ public RecipeDetailResponseDto getRecipeDetail(Integer recipeId) { @Transactional public boolean deleteRecipe(Integer recipeId) { - // 현재 인증된 사용자의 ID를 가져옴 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - Long userId = Long.parseLong(authentication.getName()); + Long userId = SecurityUtil.getCurrentMemberId(); - // 해당 ID의 레시피를 찾기 Recipe recipe = recipeRepository.findById(recipeId) .orElseThrow(() -> new IllegalArgumentException("Recipe not found")); - // 레시피 작성자와 현재 사용자가 같은지 확인 if (!recipe.getUserId().equals(userId)) { throw new IllegalArgumentException("You are not authorized to delete this recipe"); } - // 레시피와 관련된 스크랩과 댓글 삭제 scrapRepository.deleteByRecipeId(recipeId); commentRepository.deleteByRecipeId(recipeId); - // 레시피 삭제 recipeRepository.deleteById(recipeId); return true; } @@ -208,24 +205,19 @@ public boolean deleteRecipe(Integer recipeId) { @Transactional public boolean updateRecipe(RecipeRequestDto recipeRequestDto, MultipartFile thumbnailImage) { Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); - Long userId = Long.parseLong(authentication.getName()); + Long userId = SecurityUtil.getCurrentMemberId(); - // 수정할 레시피를 찾기 - Recipe recipe = recipeRepository.findById(Integer.valueOf(recipeRequestDto.getRecipeId())) + Recipe recipe = recipeRepository.findById(recipeRequestDto.getRecipeId()) .orElseThrow(() -> new IllegalArgumentException("Recipe not found")); - // 레시피 작성자와 현재 사용자가 같은지 확인 if (!recipe.getUserId().equals(userId)) { throw new IllegalArgumentException("You are not authorized to update this recipe"); } - // brandId로 Brand 찾기 Brand brand = brandRepository.findById(recipeRequestDto.getBrandId()) .orElseThrow(() -> new IllegalArgumentException("Brand not found")); - // 레시피 수정 - - String uuid = null; // 유저가 이미지를 없애도록 수정한 경우 + String uuid = null; try { if (!thumbnailImage.isEmpty()) { @@ -235,44 +227,55 @@ public boolean updateRecipe(RecipeRequestDto recipeRequestDto, MultipartFile thu e.printStackTrace(); } - if(uuid == null){ + if (uuid == null) { uuid = recipe.getImageUrl(); } recipe.updateRecipe( recipeRequestDto.getTitle(), recipeRequestDto.getDescription(), - recipeRequestDto.getThumbnailUrl(), - brand, uuid, - brandId, // brandId 설정 + brand, recipeRequestDto.getIsCelebrity() ); - // 레시피 저장 recipeRepository.save(recipe); - // 기존 재료 삭제 후 재추가 recipeIngredientRepository.deleteByRecipeId(recipe.getRecipeId()); List recipeIngredients = recipeRequestDto.getSelectedRecipes().stream() .map(selectedRecipe -> { - String ingredientName = ingredientRepository.findByIngredientName(selectedRecipe.getIngredientName()) - .orElseThrow(() -> new RuntimeException("Ingredient not found: " + selectedRecipe.getIngredientName())) - .getIngredientName(); - - RecipeIngredientId recipeIngredientId = new RecipeIngredientId( - ingredientName, - recipe.getRecipeId() - ); + RecipeIngredientId recipeIngredientId; - return RecipeIngredient.builder() - .id(recipeIngredientId) - .recipe(recipe) - .ingredient(ingredientRepository.findByIngredientName(ingredientName) - .orElseThrow(() -> new RuntimeException("Ingredient not found: " + ingredientName))) - .count(selectedRecipe.getCount()) - .build(); + if (selectedRecipe.isBaseIngredient()) { + BaseIngredient baseIngredient = baseIngredientRepository.findByIngredientName(selectedRecipe.getIngredientName()) + .orElseThrow(() -> new RuntimeException("Base Ingredient not found: " + selectedRecipe.getIngredientName())); + recipeIngredientId = new RecipeIngredientId( + recipe.getRecipeId(), + null, + baseIngredient.getBaseIngredientId() + ); + return RecipeIngredient.builder() + .id(recipeIngredientId) + .recipe(recipe) + .baseIngredient(baseIngredient) + .count(selectedRecipe.getCount()) + .build(); + } else { + Ingredient ingredient = ingredientRepository.findByIngredientName(selectedRecipe.getIngredientName()) + .orElseThrow(() -> new RuntimeException("Ingredient not found: " + selectedRecipe.getIngredientName())); + recipeIngredientId = new RecipeIngredientId( + recipe.getRecipeId(), + ingredient.getIngredientId(), + null + ); + return RecipeIngredient.builder() + .id(recipeIngredientId) + .recipe(recipe) + .ingredient(ingredient) + .count(selectedRecipe.getCount()) + .build(); + } }) .collect(Collectors.toList()); @@ -281,16 +284,12 @@ public boolean updateRecipe(RecipeRequestDto recipeRequestDto, MultipartFile thu return true; } - public List getQueriedRecipes(String keyword, int page, int size) { if (keyword.equals("-1")) { return getAllRecipes(page, size); } - // brandName으로 검색 - String brandName = keyword; - - Page recipeDtoPage = recipeRepository.findRecipesByBrandName(brandName, PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"))); + Page recipeDtoPage = recipeRepository.findRecipesByBrandName(keyword, PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"))); List recipeDtos = recipeDtoPage.getContent(); return recipeDtos.stream() @@ -298,58 +297,45 @@ public List getQueriedRecipes(String keyword, int page, int s .collect(Collectors.toList()); } + @Transactional(readOnly = true) public List getUserQueriedRecipes(String keyword, int page, int size, Long userId) { if (keyword.equals("-1")) { return getAllUserRecipes(page, size, userId); } - // brandName으로 검색 - String brandName = keyword; - - Page recipeDtoPage = recipeRepository.findRecipesByBrandNameAndUserId(brandName, userId, PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"))); - List recipeDtos = recipeDtoPage.getContent(); - - return recipeDtos.stream() + Page recipeDtoPage = recipeRepository.findRecipesByBrandNameAndUserId(keyword, userId, PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"))); + return recipeDtoPage.getContent().stream() .map(this::getRecipeDtoToRecipeResponseDto) .collect(Collectors.toList()); } + @Transactional(readOnly = true) public List getUserQueriedScrapedRecipes(String keyword, int page, int size, List recipeIds) { if (keyword.equals("-1")) { return getUserAllScrapedRecipes(page, size, recipeIds); } - // brandName으로 검색 - String brandName = keyword; - - Page recipeDtoPage = recipeRepository.findRecipesByBrandNameAndRecipeIds(brandName, recipeIds, PageRequest.of(page, size)); - List recipeDtos = recipeDtoPage.getContent(); - - return recipeDtos.stream() + Page recipeDtoPage = recipeRepository.findRecipesByBrandNameAndRecipeIds(keyword, recipeIds, PageRequest.of(page, size)); + return recipeDtoPage.getContent().stream() .map(this::getRecipeDtoToRecipeResponseDto) .collect(Collectors.toList()); } - - public List getAllRecipes(int page, int size) { + private List getAllRecipes(int page, int size) { Page recipePage = recipeRepository.findAll(PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"))); - List recipes = recipePage.getContent(); - - return recipes.stream() + return recipePage.getContent().stream() .map(this::getRecipeToRecipeResponseDto) .collect(Collectors.toList()); } - public List getAllUserRecipes(int page, int size, Long userId) { + private List getAllUserRecipes(int page, int size, Long userId) { Page recipeDtoPage = recipeRepository.findRecipesByUserId(userId, PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"))); - List recipeDtos = recipeDtoPage.getContent(); - - return recipeDtos.stream() + return recipeDtoPage.getContent().stream() .map(this::getRecipeDtoToRecipeResponseDto) .collect(Collectors.toList()); } - public List getUserAllScrapedRecipes(int page, int size, List recipeIds) { + private List getUserAllScrapedRecipes(int page, int size, List recipeIds) { Page recipeDtoPages = recipeRepository.findRecipesByRecipeIds(recipeIds, PageRequest.of(page, size)); List recipeDtos = recipeDtoPages.getContent(); diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/dao/RecipeBaseIngredientRepository.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/dao/RecipeBaseIngredientRepository.java new file mode 100644 index 0000000..b8b8d35 --- /dev/null +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/dao/RecipeBaseIngredientRepository.java @@ -0,0 +1,9 @@ +package CaffeineCoder.recipic.domain.recipe.dao; + +import CaffeineCoder.recipic.domain.brand.domain.RecipeBaseIngredient; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface RecipeBaseIngredientRepository extends JpaRepository { +} diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/dao/RecipeIngredientRepository.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/dao/RecipeIngredientRepository.java index 2a4ffe5..1dda47b 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/dao/RecipeIngredientRepository.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/dao/RecipeIngredientRepository.java @@ -14,6 +14,7 @@ @Repository public interface RecipeIngredientRepository extends JpaRepository { + @Query("SELECT ri FROM RecipeIngredient ri WHERE ri.recipe.recipeId = :recipeId") List findByRecipeId(@Param("recipeId") Integer recipeId); diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/Recipe.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/Recipe.java index d3231a3..6a6cd66 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/Recipe.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/Recipe.java @@ -86,6 +86,8 @@ public void updateRecipe(String title, String description, String imageUrl, Bran this.isCelebrity = isCelebrity; } + + // Brand의 이름을 반환하는 메서드 public String getBrandName() { return this.brand != null ? this.brand.getBrandName() : null; diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredient.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredient.java index 694836f..872b770 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredient.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredient.java @@ -20,16 +20,16 @@ public class RecipeIngredient { @JoinColumn(name = "recipe_id") private Recipe recipe; - // 일반 재료 매핑 + // 사이드 재료 매핑 @ManyToOne - @MapsId("ingredientName") - @JoinColumn(name = "ingredient_name", referencedColumnName = "ingredient_name") + @MapsId("ingredientId") + @JoinColumn(name = "ingredient_id", referencedColumnName = "ingredient_id", insertable = false, updatable = false) private Ingredient ingredient; - // 기본 재료 매핑 + // 베이스 재료 매핑 @ManyToOne - @MapsId("ingredientName") - @JoinColumn(name = "base_ingredient_name", referencedColumnName = "ingredient_name") + @MapsId("baseIngredientId") + @JoinColumn(name = "baseingredient_id", referencedColumnName = "baseingredient_id", insertable = false, updatable = false) private BaseIngredient baseIngredient; @Column(name = "count") diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredientId.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredientId.java index 9bac237..e672c39 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredientId.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/domain/RecipeIngredientId.java @@ -13,15 +13,19 @@ @NoArgsConstructor public class RecipeIngredientId implements Serializable { - @Column(name = "ingredient_name") - private String ingredientName; - @Column(name = "recipe_id") private Integer recipeId; - public RecipeIngredientId(String ingredientName, Integer recipeId) { - this.ingredientName = ingredientName; + @Column(name = "ingredient_id", nullable = true) + private Integer ingredientId; + + @Column(name = "baseingredient_id", nullable = true) + private Integer baseIngredientId; + + public RecipeIngredientId(Integer recipeId, Integer ingredientId, Integer baseIngredientId) { this.recipeId = recipeId; + this.ingredientId = ingredientId; + this.baseIngredientId = baseIngredientId; } @Override @@ -29,12 +33,13 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; RecipeIngredientId that = (RecipeIngredientId) o; - return Objects.equals(ingredientName, that.ingredientName) && - Objects.equals(recipeId, that.recipeId); + return Objects.equals(recipeId, that.recipeId) && + Objects.equals(ingredientId, that.ingredientId) && + Objects.equals(baseIngredientId, that.baseIngredientId); } @Override public int hashCode() { - return Objects.hash(ingredientName, recipeId); + return Objects.hash(recipeId, ingredientId, baseIngredientId); } } diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/IncludeIngredientDto.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/IncludeIngredientDto.java index 6bd5bd1..e638416 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/IncludeIngredientDto.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/IncludeIngredientDto.java @@ -1,5 +1,6 @@ package CaffeineCoder.recipic.domain.recipe.dto; +import CaffeineCoder.recipic.domain.brand.domain.BaseIngredient; import CaffeineCoder.recipic.domain.brand.domain.Ingredient; import lombok.Builder; import lombok.Getter; @@ -7,14 +8,13 @@ @Getter public class IncludeIngredientDto { private Ingredient ingredient; + private BaseIngredient baseIngredient; private Integer count; @Builder - public IncludeIngredientDto(Ingredient ingredient, Integer count) { + public IncludeIngredientDto(Ingredient ingredient, BaseIngredient baseIngredient, Integer count) { this.ingredient = ingredient; + this.baseIngredient = baseIngredient; this.count = count; } - - // Getters and Setters } - diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeRequestDto.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeRequestDto.java index bd53827..0a1776a 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeRequestDto.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/dto/RecipeRequestDto.java @@ -20,6 +20,11 @@ public class RecipeRequestDto { private List selectedRecipes; private String description; private Boolean isCelebrity; + private String thumbnailUrl; + + public String getThumbnailUrl() { + return thumbnailUrl; + } @Getter @NoArgsConstructor @@ -28,7 +33,7 @@ public class RecipeRequestDto { public static class SelectedRecipeDto { private String ingredientName; private Integer count; - private Boolean isBaseIngredient; // BaseIngredient 여부 + private Boolean isBaseIngredient; public Boolean isBaseIngredient() { return isBaseIngredient; From 118983d3f894c93281134a9b65fda723d205374a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=82=98=EC=9D=80?= <113881692+knxxxn@users.noreply.github.com> Date: Mon, 23 Sep 2024 23:49:41 +0900 Subject: [PATCH 5/5] =?UTF-8?q?feat:=20=EB=A0=88=EC=8B=9C=ED=94=BC=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20api=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../recipic/domain/recipe/api/RecipeController.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/CaffeineCoder/recipic/domain/recipe/api/RecipeController.java b/src/main/java/CaffeineCoder/recipic/domain/recipe/api/RecipeController.java index b82abab..94b7f6c 100644 --- a/src/main/java/CaffeineCoder/recipic/domain/recipe/api/RecipeController.java +++ b/src/main/java/CaffeineCoder/recipic/domain/recipe/api/RecipeController.java @@ -34,9 +34,8 @@ public ResponseEntity> registerRecipe( return ResponseEntity.ok(Map.of("isSuccess", true)); } - @DeleteMapping("/remove") - public ResponseEntity> deleteRecipe(@RequestBody Map request) { - Integer recipeId = request.get("recipeId"); + @GetMapping("/remove") + public ResponseEntity> deleteRecipe(@RequestParam Integer recipeId) { boolean isSuccess = recipeService.deleteRecipe(recipeId); Map response = new HashMap<>();