diff --git a/refrigerator/.idea/modules.xml b/refrigerator/.idea/modules.xml
index bdc72c3..738a4c5 100644
--- a/refrigerator/.idea/modules.xml
+++ b/refrigerator/.idea/modules.xml
@@ -3,6 +3,7 @@
+
\ No newline at end of file
diff --git a/refrigerator/.idea/modules/refrigerator.main.iml b/refrigerator/.idea/modules/refrigerator.main.iml
index 397c268..1cbf656 100644
--- a/refrigerator/.idea/modules/refrigerator.main.iml
+++ b/refrigerator/.idea/modules/refrigerator.main.iml
@@ -4,9 +4,6 @@
-
-
-
@@ -16,7 +13,9 @@
-
+
+
+
diff --git a/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/Recipe.java b/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/Recipe.java
index 575058e..5c8068b 100644
--- a/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/Recipe.java
+++ b/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/Recipe.java
@@ -56,6 +56,10 @@ public class Recipe {
@JsonManagedReference
private List recipeSource = new ArrayList<>() ; // 여러 Source가 들어갈 수 있으니까 list로 수정
+ @OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL, orphanRemoval = true,fetch = FetchType.LAZY)
+ @JsonManagedReference
+ private List recipeStep = new ArrayList<>();
+
@JoinColumn(name = "recipe_category")
@ManyToOne
diff --git a/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/RecipeSource.java b/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/RecipeSource.java
index c69c19b..8862847 100644
--- a/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/RecipeSource.java
+++ b/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/RecipeSource.java
@@ -8,6 +8,7 @@
import lombok.Data;
import java.time.LocalDateTime;
+import java.util.List;
@Data
@Entity
diff --git a/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/RecipeStep.java b/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/RecipeStep.java
new file mode 100644
index 0000000..8d13e90
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/RecipeStep.java
@@ -0,0 +1,37 @@
+package moja.refrigerator.aggregate.recipe;
+
+import com.fasterxml.jackson.annotation.JsonBackReference;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonManagedReference;
+import jakarta.persistence.*;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+@Entity
+@Table(name = "tbl_recipe_step")
+public class RecipeStep {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "recipe_step_pk")
+ private long recipeStepPk;
+
+ @Column(name = "recipe_step_order")
+ private int recipeStepOrder;
+
+ @Column(name = "recipe_step_content")
+ private String recipeStepContent;
+
+ @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
+ @JsonManagedReference
+ @JoinColumn(name = "recipe_step_source_pk")
+ private RecipeStepSource recipeStepSource;
+
+ @ManyToOne
+ @JoinColumn(name = "recipe_pk")
+ @JsonBackReference
+ private Recipe recipe;
+
+}
diff --git a/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/RecipeStepSource.java b/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/RecipeStepSource.java
new file mode 100644
index 0000000..fcd7090
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/RecipeStepSource.java
@@ -0,0 +1,41 @@
+package moja.refrigerator.aggregate.recipe;
+
+import com.fasterxml.jackson.annotation.JsonBackReference;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import jakarta.persistence.*;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+@Entity
+@Table(name="tbl_recipe_step_source")
+public class RecipeStepSource {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "recipe_step_source_pk")
+ private long recipeStepSourcePk;
+
+ @Column(name = "recipe_step_source_save") // 저장위치
+ private String recipeStepSourceSave;
+
+ @Column(name = "recipe_step_source_create_time")
+ @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd", timezone = "Asia/Seoul")
+ private LocalDateTime recipeStepSourceCreateTime = LocalDateTime.now();
+
+ @Column(name = "recipe_step_source_file_name",nullable = false) // 저장 파일 명
+ private String recipeStepSourceFileName;
+
+ @Column(name = "recipe_step_source_servername") // 서버 저장한 이름 추가.
+ private String recipeStepSourceServername;
+
+ @JoinColumn(name = "recipe_step_source_type") // 자료타입 동영상 or 사진
+ @ManyToOne
+ private RecipeSourceType recipeStepSourceType;
+
+ @JsonBackReference
+ @OneToOne(fetch = FetchType.EAGER)
+ @JoinColumn(name="recipe_step_pk")
+ private RecipeStep recipeStep;
+}
diff --git a/refrigerator/src/main/java/moja/refrigerator/aggregate/user/Follow.java b/refrigerator/src/main/java/moja/refrigerator/aggregate/user/Follow.java
index 80eaa90..caaddfa 100644
--- a/refrigerator/src/main/java/moja/refrigerator/aggregate/user/Follow.java
+++ b/refrigerator/src/main/java/moja/refrigerator/aggregate/user/Follow.java
@@ -12,11 +12,11 @@ public class Follow {
@Column(name = "follow_pk")
private long followPk;
- @ManyToOne
+ @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "follower")
private User follower;
- @ManyToOne
+ @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "following")
private User following;
}
diff --git a/refrigerator/src/main/java/moja/refrigerator/aggregate/user/User.java b/refrigerator/src/main/java/moja/refrigerator/aggregate/user/User.java
index 03eb039..524bcdc 100644
--- a/refrigerator/src/main/java/moja/refrigerator/aggregate/user/User.java
+++ b/refrigerator/src/main/java/moja/refrigerator/aggregate/user/User.java
@@ -5,6 +5,7 @@
import org.hibernate.annotations.CreationTimestamp;
import java.time.LocalDate;
+import java.util.List;
@Entity
@Table(name = "tbl_user")
@@ -33,4 +34,10 @@ public class User {
@Column(name = "user_role")
private String userRole = "ROLE_USER";
+
+ @OneToMany(mappedBy = "follower", cascade = CascadeType.REMOVE)
+ private List following;
+
+ @OneToMany(mappedBy = "following", cascade = CascadeType.REMOVE)
+ private List followers;
}
diff --git a/refrigerator/src/main/java/moja/refrigerator/config/WebConfig.java b/refrigerator/src/main/java/moja/refrigerator/config/WebConfig.java
new file mode 100644
index 0000000..9b946ae
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/config/WebConfig.java
@@ -0,0 +1,18 @@
+package moja.refrigerator.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ .allowedOrigins("http://localhost:5173")
+ .allowedMethods("GET", "POST", "PUT", "DELETE")
+ .allowedHeaders("*")
+ .allowCredentials(true)
+ .maxAge(3600);
+ }
+}
\ No newline at end of file
diff --git a/refrigerator/src/main/java/moja/refrigerator/controller/recipe/RecipeController.java b/refrigerator/src/main/java/moja/refrigerator/controller/recipe/RecipeController.java
index 03ecb0a..c619f98 100644
--- a/refrigerator/src/main/java/moja/refrigerator/controller/recipe/RecipeController.java
+++ b/refrigerator/src/main/java/moja/refrigerator/controller/recipe/RecipeController.java
@@ -27,12 +27,15 @@ public RecipeController(RecipeService recipeService) {
}
@PostMapping
- public void createRecipe(
+ public Recipe createRecipe(
@RequestPart RecipeCreateRequest request
- , @RequestPart (required =false) List files
+ ,@RequestPart (name="recipeSources",required =false) List recipeSources
+ ,@RequestPart (name="recipeStepSources",required =false) List recipeStepSources
){
- recipeService.createRecipe(request
- , files
+
+ return recipeService.createRecipe(request
+ , recipeSources
+ , recipeStepSources
);
}
@@ -50,11 +53,12 @@ public void deleteRecipe(@RequestParam long recipePk){
}
@PutMapping
- public void updateRecipe(
+ public Recipe updateRecipe(
@RequestPart RecipeUpdateRequest request
- ,@RequestPart (required =false) List files
+ ,@RequestPart (name="recipeSources",required =false) List recipeSources
+ ,@RequestPart (name="recipeStepSources",required =false) List recipeStepSources
){
- recipeService.updateRecipe(request,files);
+ return recipeService.updateRecipe(request,recipeSources,recipeStepSources);
}
@GetMapping("/recommend")
diff --git a/refrigerator/src/main/java/moja/refrigerator/controller/user/UserController.java b/refrigerator/src/main/java/moja/refrigerator/controller/user/UserController.java
index c841068..5c716e1 100644
--- a/refrigerator/src/main/java/moja/refrigerator/controller/user/UserController.java
+++ b/refrigerator/src/main/java/moja/refrigerator/controller/user/UserController.java
@@ -1,5 +1,7 @@
package moja.refrigerator.controller.user;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import moja.refrigerator.dto.user.request.PasswordResetRequest;
import moja.refrigerator.dto.user.request.PasswordUpdateRequest;
import moja.refrigerator.dto.user.request.UserCreateRequest;
@@ -60,4 +62,11 @@ public ResponseEntity> toggleFollow(@PathVariable Long userPk) {
followService.toggleFollow(userPk);
return ResponseEntity.ok().body("팔로우 상태가 변경되었습니다.");
}
+
+ // 회원 탈퇴
+ @PostMapping("/delete")
+ public ResponseEntity> delete(HttpServletRequest request, HttpServletResponse response) {
+ userService.deleteUser(request, response);
+ return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
+ }
}
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/ingredient/response/IngredientResponse.java b/refrigerator/src/main/java/moja/refrigerator/dto/ingredient/response/IngredientResponse.java
index bda5d0b..e5220a0 100644
--- a/refrigerator/src/main/java/moja/refrigerator/dto/ingredient/response/IngredientResponse.java
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/ingredient/response/IngredientResponse.java
@@ -13,6 +13,10 @@ public class IngredientResponse {
private long remainExpirationDate;
private int seasonDate;
private String ingredientStorage;
+ private long ingredientManagementPk;
+ private boolean isBookmarked;
+ private String ingredientCategory;
+ private long ingredientBookmarkPk;
// ModelMapper 를 위한 기본 생성자 생성
public IngredientResponse() {}
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeCreateRequest.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeCreateRequest.java
index ef8640d..fe1ee5d 100644
--- a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeCreateRequest.java
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeCreateRequest.java
@@ -1,9 +1,9 @@
package moja.refrigerator.dto.recipe.request;
import lombok.Data;
-import moja.refrigerator.aggregate.recipe.RecipeCategory;
-import moja.refrigerator.aggregate.recipe.RecipeSource;
-import moja.refrigerator.aggregate.user.User;
+import moja.refrigerator.aggregate.recipe.RecipeStep;
+
+import java.util.List;
@Data
public class RecipeCreateRequest {
@@ -11,12 +11,8 @@ public class RecipeCreateRequest {
private int recipeCookingTime;
private int recipeDifficulty;
private String recipeContent;
-// private long recipeSource;
private int recipeCategoryPk;
+ private List recipeSteps;
private long userPk;
-// private long recipePk; // 자동 추가
-// private String recipeCreateTime; //자동 추가
-// private String recipeUpdateTime; //자동 추가
-// private long recipeViews; // 조회 시 올리는 것으로
}
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeStepRequest.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeStepRequest.java
new file mode 100644
index 0000000..a7acb05
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeStepRequest.java
@@ -0,0 +1,9 @@
+package moja.refrigerator.dto.recipe.request;
+
+import lombok.Data;
+
+@Data
+public class RecipeStepRequest {
+ private int recipeStepOrder; // JSON에 있는 필드와 이름 동일해야 함
+ private String recipeStepContent; // JSON의 recipeStepContent와 일치
+}
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeStepSourceRequest.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeStepSourceRequest.java
new file mode 100644
index 0000000..a306892
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeStepSourceRequest.java
@@ -0,0 +1,18 @@
+package moja.refrigerator.dto.recipe.request;
+
+import lombok.Data;
+import moja.refrigerator.aggregate.recipe.RecipeSourceType;
+
+import java.time.LocalDateTime;
+
+@Data
+public class RecipeStepSourceRequest {
+ private long recipeStepSourcePk;
+ private String recipeStepSourceSave;
+ private LocalDateTime recipeStepSourceCreateTime;
+ private String recipeStepSourceFileName;
+ private String recipeStepSourceServername;
+ private RecipeSourceType recipeStepSourceType;
+
+
+}
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeStepUpdateRequest.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeStepUpdateRequest.java
new file mode 100644
index 0000000..e56a406
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeStepUpdateRequest.java
@@ -0,0 +1,11 @@
+package moja.refrigerator.dto.recipe.request;
+
+import lombok.Data;
+
+@Data
+public class RecipeStepUpdateRequest {
+ private Long recipeStepPk;
+ private int recipeStepOrder; // JSON에 있는 필드와 이름 동일해야 함
+ private String recipeStepContent; // JSON의 recipeStepContent와 일치
+ private RecipeStepSourceRequest recipeStepSource;
+}
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeUpdateRequest.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeUpdateRequest.java
index dd7c2d9..da9bea1 100644
--- a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeUpdateRequest.java
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeUpdateRequest.java
@@ -3,6 +3,8 @@
import lombok.Data;
+import java.util.List;
+
@Data
public class RecipeUpdateRequest {
private long recipePk;
@@ -13,5 +15,6 @@ public class RecipeUpdateRequest {
private String recipeSource;
private String recipeCategory;
private String userPk;
+ private List recipeSteps;
}
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeDetailResponse.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeDetailResponse.java
index 0fcf203..6570fc1 100644
--- a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeDetailResponse.java
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeDetailResponse.java
@@ -4,6 +4,7 @@
import java.util.List;
import lombok.Data;
+import moja.refrigerator.aggregate.recipe.RecipeSource;
import moja.refrigerator.dto.ingredient.response.IngredientResponse;
@Data
@@ -17,9 +18,10 @@ public class RecipeDetailResponse {
private LocalDateTime recipeCreateTime;;
private LocalDateTime recipeUpdateTime;
- private String recipeSource;
+ private List recipeSource;
private String userPk;
private String recipeCategory;
private List ingredients;
+ private List recipeStep;
}
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeRecommendResponse.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeRecommendResponse.java
index efdb622..14be138 100644
--- a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeRecommendResponse.java
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeRecommendResponse.java
@@ -14,4 +14,7 @@ public class RecipeRecommendResponse {
private long remainExpirationDays;
private String urgentIngredientName;
private List ingredients;
+
+ private List mainImages; // 메인 이미지들
+ private List steps;
}
\ No newline at end of file
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeResponse.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeResponse.java
index 5686857..c2038b0 100644
--- a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeResponse.java
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeResponse.java
@@ -3,6 +3,7 @@
import lombok.Data;
import moja.refrigerator.aggregate.recipe.RecipeCategory;
import moja.refrigerator.aggregate.recipe.RecipeSource;
+import moja.refrigerator.aggregate.recipe.RecipeStep;
import moja.refrigerator.aggregate.user.User;
import java.time.LocalDateTime;
@@ -22,6 +23,8 @@ public class RecipeResponse {
private LocalDateTime recipeUpdateTime;
private List recipeSource;
+
+ private List recipeStep;
private User user;
private RecipeCategory recipeCategory;
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeSourceInfo.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeSourceInfo.java
new file mode 100644
index 0000000..18a37bb
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeSourceInfo.java
@@ -0,0 +1,9 @@
+package moja.refrigerator.dto.recipe.response;
+
+import lombok.Data;
+
+@Data
+public class RecipeSourceInfo {
+ private String filePath;
+ private String originalName;
+}
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeStepResponse.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeStepResponse.java
new file mode 100644
index 0000000..1a52f2b
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeStepResponse.java
@@ -0,0 +1,12 @@
+package moja.refrigerator.dto.recipe.response;
+
+import lombok.Data;
+
+@Data
+public class RecipeStepResponse {
+
+ private int recipeStepOrder;
+ private String recipeStepContent;
+ private RecipeStepSourceResponse recipeStepSource;
+
+}
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeStepSourceResponse.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeStepSourceResponse.java
new file mode 100644
index 0000000..5b51094
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeStepSourceResponse.java
@@ -0,0 +1,16 @@
+package moja.refrigerator.dto.recipe.response;
+
+import lombok.Data;
+import moja.refrigerator.aggregate.recipe.RecipeSourceType;
+
+import java.time.LocalDateTime;
+
+@Data
+public class RecipeStepSourceResponse {
+ private long recipeStepSourcePk;
+ private String recipeStepSourceSave;
+ private LocalDateTime recipeStepSourceCreateTime;
+ private String recipeStepSourceFileName;
+ private String recipeStepSourceServername;
+ private RecipeSourceType recipeStepSourceType;
+}
diff --git a/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeStepWithImage.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeStepWithImage.java
new file mode 100644
index 0000000..e5c380e
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeStepWithImage.java
@@ -0,0 +1,13 @@
+package moja.refrigerator.dto.recipe.response;
+
+import lombok.Data;
+
+import java.util.List;
+
+
+@Data
+public class RecipeStepWithImage {
+ private int order;
+ private String content;
+ private List images;
+}
diff --git a/refrigerator/src/main/java/moja/refrigerator/repository/recipe/RecipeStepRepository.java b/refrigerator/src/main/java/moja/refrigerator/repository/recipe/RecipeStepRepository.java
new file mode 100644
index 0000000..ecfb529
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/repository/recipe/RecipeStepRepository.java
@@ -0,0 +1,8 @@
+package moja.refrigerator.repository.recipe;
+
+import moja.refrigerator.aggregate.recipe.RecipeStep;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface RecipeStepRepository extends JpaRepository {
+
+}
diff --git a/refrigerator/src/main/java/moja/refrigerator/repository/recipe/RecipeStepSourceRepository.java b/refrigerator/src/main/java/moja/refrigerator/repository/recipe/RecipeStepSourceRepository.java
new file mode 100644
index 0000000..867b71d
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/repository/recipe/RecipeStepSourceRepository.java
@@ -0,0 +1,8 @@
+package moja.refrigerator.repository.recipe;
+
+import moja.refrigerator.aggregate.recipe.RecipeIngredient;
+import moja.refrigerator.aggregate.recipe.RecipeStepSource;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface RecipeStepSourceRepository extends JpaRepository {
+}
diff --git a/refrigerator/src/main/java/moja/refrigerator/service/ingredient/IngredientServiceImpl.java b/refrigerator/src/main/java/moja/refrigerator/service/ingredient/IngredientServiceImpl.java
index 9842b63..19d7968 100644
--- a/refrigerator/src/main/java/moja/refrigerator/service/ingredient/IngredientServiceImpl.java
+++ b/refrigerator/src/main/java/moja/refrigerator/service/ingredient/IngredientServiceImpl.java
@@ -65,6 +65,7 @@ public void createIngredient(IngredientCreateRequest request, Long userPk, Long
@Transactional(readOnly = true)
public List getIngredient(Long userPk) {
List ingredients = ingredientMyRefrigeratorRepository.findByUserUserPk(userPk);
+ List ingredientBookmarks = ingredientBookmarkRepository.findAllByUser_UserPk(userPk);
LocalDate currentDate = LocalDate.now();
AtomicInteger counter = new AtomicInteger(1);
@@ -76,6 +77,17 @@ public List getIngredient(Long userPk) {
response.setIngredientName(ingredient.getIngredientManagement().getIngredientName());
response.setSeasonDate(ingredient.getIngredientManagement().getSeasonDate());
response.setIngredientStorage(ingredient.getIngredientManagement().getIngredientStorage().getIngredientStorage());
+ response.setIngredientCategory(ingredient.getIngredientManagement().getIngredientCategory().getIngredientCategory());
+ boolean isBookmark = false;
+ for (IngredientBookmark ingredientBookmark : ingredientBookmarks) {
+ if (ingredientBookmark.getIngredientMyRefrigerator().getIngredientMyRefrigeratorPk()
+ == ingredient.getIngredientMyRefrigeratorPk()) {
+ isBookmark = true;
+ response.setIngredientBookmarkPk(ingredientBookmark.getIngredientBookmarkPk());
+ break;
+ }
+ }
+ response.setBookmarked(isBookmark);
// 현재 날짜 기준, 유통기한 남은 일수 계산
LocalDate expirationDate = LocalDate.parse(ingredient.getExpirationDate());
diff --git a/refrigerator/src/main/java/moja/refrigerator/service/recipe/RecipeService.java b/refrigerator/src/main/java/moja/refrigerator/service/recipe/RecipeService.java
index 81c69a5..4d6f885 100644
--- a/refrigerator/src/main/java/moja/refrigerator/service/recipe/RecipeService.java
+++ b/refrigerator/src/main/java/moja/refrigerator/service/recipe/RecipeService.java
@@ -15,15 +15,17 @@
import java.util.List;
public interface RecipeService {
- void createRecipe(RecipeCreateRequest request
- ,List files
+ Recipe createRecipe(RecipeCreateRequest request
+ ,List recipeSources
+ ,List recipeStepSources
);
List getAllRecipes();
RecipeDetailResponse getRecipe(long id);
void deleteRecipe(long recipePk);
- void updateRecipe(
+ Recipe updateRecipe(
RecipeUpdateRequest request
- ,List files
+ ,List recipeSources
+ ,List recipeStepSources
);
List getRecommendedRecipes(Long userPk);
RecipeRecommendResponse getRandomRecipe();
diff --git a/refrigerator/src/main/java/moja/refrigerator/service/recipe/RecipeServiceImpl.java b/refrigerator/src/main/java/moja/refrigerator/service/recipe/RecipeServiceImpl.java
index 42030fb..1ef91e0 100644
--- a/refrigerator/src/main/java/moja/refrigerator/service/recipe/RecipeServiceImpl.java
+++ b/refrigerator/src/main/java/moja/refrigerator/service/recipe/RecipeServiceImpl.java
@@ -7,9 +7,7 @@
import moja.refrigerator.aggregate.recipe.*;
import moja.refrigerator.aggregate.user.User;
import moja.refrigerator.dto.recipe.RecipeMatchResult;
-import moja.refrigerator.dto.recipe.request.RecipeCreateRequest;
-import moja.refrigerator.dto.recipe.request.RecipeLikeRequest;
-import moja.refrigerator.dto.recipe.request.RecipeUpdateRequest;
+import moja.refrigerator.dto.recipe.request.*;
import moja.refrigerator.dto.recipe.response.*;
import moja.refrigerator.repository.ingredient.IngredientMyRefrigeratorRepository;
import moja.refrigerator.repository.recipe.*;
@@ -28,6 +26,11 @@
import java.util.*;
import java.util.stream.Collectors;
+/**
+ * Implementation of the RecipeService interface, providing business logic for managing recipes.
+ * This class interacts with various repositories for CRUD operations related to recipes, ingredients, files, and user data,
+ * as well as Amazon S3 for file storage.
+ */
@Service
public class RecipeServiceImpl implements RecipeService {
@@ -42,6 +45,8 @@ public class RecipeServiceImpl implements RecipeService {
private final RecipeIngredientRepository recipeIngredientRepository;
private final ReplacableIngredientRepository replacableIngredientRepository;
private final RecipeLikeDislikeRepository recipeLikeDislikeRepository;
+ private final RecipeStepRepository recipeStepRepository;
+ private final RecipeStepSourceRepository recipeStepSourceRepository;
@Value("${cloud.aws.s3.bucket}")
private String bucket;
@@ -58,7 +63,9 @@ public RecipeServiceImpl(
IngredientMyRefrigeratorRepository ingredientMyRefrigeratorRepository,
RecipeIngredientRepository recipeIngredientRepository,
ReplacableIngredientRepository replacableIngredientRepository,
- RecipeLikeDislikeRepository recipeLikeDislikeRepository
+ RecipeLikeDislikeRepository recipeLikeDislikeRepository,
+ RecipeStepRepository recipeStepRepository,
+ RecipeStepSourceRepository recipeStepSourceRepository
) {
this.recipeRepository = recipeRepository;
this.userRepository = userRepository;
@@ -71,6 +78,8 @@ public RecipeServiceImpl(
this.recipeIngredientRepository = recipeIngredientRepository;
this.replacableIngredientRepository = replacableIngredientRepository;
this.recipeLikeDislikeRepository = recipeLikeDislikeRepository;
+ this.recipeStepRepository = recipeStepRepository;
+ this.recipeStepSourceRepository = recipeStepSourceRepository;
}
private boolean isImageFile(String fileName) {
String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
@@ -81,10 +90,114 @@ private boolean isVideoFile(String fileName) {
String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
return List.of("mp4", "avi", "mov", "wmv").contains(extension);
}
+ // 파일 처리 전용 메서드
+ private RecipeSource RecipeSourceSaveFile(MultipartFile file, Recipe recipe, String pathPrefix) {
+ try {
+ if (file == null || file.isEmpty()) {
+ return null;
+ }
+ String originalFileName = file.getOriginalFilename();
+ if (originalFileName == null) {
+ throw new IllegalArgumentException("Empty file name is not allowed");
+ }
+
+ // 파일 이름 생성 및 저장 경로 설정
+ UUID uuid = UUID.randomUUID();
+ String serverFileName = uuid + "_" + originalFileName;
+ String fileUrl = "https://" + bucket + "/" + pathPrefix + serverFileName;
+
+ // RecipeSource 생성 및 설정
+ RecipeSource recipeSource = new RecipeSource();
+ recipeSource.setRecipeSourceServername(serverFileName);
+ recipeSource.setRecipeSourceSave(fileUrl);
+ recipeSource.setRecipeSourceFileName(originalFileName);
+
+ // 파일 타입 처리
+ RecipeSourceType recipeSourceType;
+ if (isImageFile(originalFileName)) {
+ recipeSourceType = recipeSourceTypeRepository.findById(1)
+ .orElseThrow(() -> new IllegalArgumentException("Image type not found"));
+ } else if (isVideoFile(originalFileName)) {
+ recipeSourceType = recipeSourceTypeRepository.findById(2)
+ .orElseThrow(() -> new IllegalArgumentException("Video type not found"));
+ } else {
+ throw new IllegalArgumentException("Unsupported file type: " + originalFileName);
+ }
+ recipeSource.setRecipeSourceType(recipeSourceType);
+ recipeSource.setRecipe(recipe);
+
+
+ // AWS S3에 파일 업로드
+ ObjectMetadata metadata = new ObjectMetadata();
+ metadata.setContentType(file.getContentType());
+ metadata.setContentLength(file.getSize());
+ amazonS3Client.putObject(bucket, pathPrefix + serverFileName, file.getInputStream(), metadata);
+
+ // RecipeSource 저장
+ recipeSourceRepository.save(recipeSource);
+ return recipeSource;
+ } catch (IOException e) {
+ throw new RuntimeException("File upload failed: " + e.getMessage(), e);
+ }
+ }
+
+ private RecipeStepSource RecipeStepSourceSaveFile(MultipartFile file, RecipeStep recipeStep, String pathPrefix) {
+ try {
+ if (file == null || file.isEmpty()) {
+ return null;
+ }
+ String originalFileName = file.getOriginalFilename();
+ if (originalFileName == null) {
+ throw new IllegalArgumentException("Empty file name is not allowed");
+ }
+
+ // 파일 이름 생성 및 저장 경로 설정
+ UUID uuid = UUID.randomUUID();
+ String serverFileName = uuid + "_" + originalFileName;
+ String fileUrl = "https://" + bucket + "/" + pathPrefix + serverFileName;
+
+ // RecipeSource 생성 및 설정
+ RecipeStepSource recipeSource = new RecipeStepSource();
+ recipeSource.setRecipeStepSourceServername(serverFileName);
+ recipeSource.setRecipeStepSourceSave(fileUrl);
+ recipeSource.setRecipeStepSourceFileName(originalFileName);
+
+ // 파일 타입 처리
+ RecipeSourceType recipeSourceType;
+ if (isImageFile(originalFileName)) {
+ recipeSourceType = recipeSourceTypeRepository.findById(1)
+ .orElseThrow(() -> new IllegalArgumentException("Image type not found"));
+ } else if (isVideoFile(originalFileName)) {
+ recipeSourceType = recipeSourceTypeRepository.findById(2)
+ .orElseThrow(() -> new IllegalArgumentException("Video type not found"));
+ } else {
+ throw new IllegalArgumentException("Unsupported file type: " + originalFileName);
+ }
+ recipeSource.setRecipeStepSourceType(recipeSourceType);
+ recipeSource.setRecipeStep(recipeStep);
+
+ // AWS S3에 파일 업로드
+ ObjectMetadata metadata = new ObjectMetadata();
+ metadata.setContentType(file.getContentType());
+ metadata.setContentLength(file.getSize());
+ amazonS3Client.putObject(bucket, pathPrefix + serverFileName, file.getInputStream(), metadata);
+
+ // RecipeSource 저장
+ recipeStepSourceRepository.save(recipeSource);
+ return recipeSource;
+
+ } catch (IOException e) {
+ throw new RuntimeException("File upload failed: " + e.getMessage(), e);
+ }
+ }
+
@Override
@Transactional(propagation = Propagation.REQUIRED)
- public void createRecipe(RecipeCreateRequest request, List files) {
+ public Recipe createRecipe(RecipeCreateRequest request
+ ,List recipeSources
+ ,List recipeStepSources
+ ) {
Recipe recipe = new Recipe();
recipe.setRecipeName(request.getRecipeName());
recipe.setRecipeContent(request.getRecipeContent());
@@ -99,46 +212,38 @@ public void createRecipe(RecipeCreateRequest request, List files)
.orElseThrow(IllegalArgumentException::new);
recipe.setRecipeCategory(recipeCategory);
- if(files != null && !files.isEmpty()) {
- for(MultipartFile file : files) {
- try {
- String recipeSourceFileName = file.getOriginalFilename();
- UUID uuid = UUID.randomUUID();
- String recipeSourceServername = uuid + recipeSourceFileName;
- String recipeSourceSave = "https://" + bucket + "/recipe/" + recipeSourceServername;
-
- RecipeSource recipeSource = new RecipeSource();
- recipeSource.setRecipeSourceServername(recipeSourceServername);
- recipeSource.setRecipeSourceSave(recipeSourceSave);
- recipeSource.setRecipeSourceFileName(recipeSourceFileName);
-
- RecipeSourceType recipeSourceType;
- if(isImageFile(recipeSourceFileName)) {
- recipeSourceType = recipeSourceTypeRepository.findById(1)
- .orElseThrow(IllegalArgumentException::new);
- } else if (isVideoFile(recipeSourceFileName)) {
- recipeSourceType = recipeSourceTypeRepository.findById(2)
- .orElseThrow(IllegalArgumentException::new);
- } else {
- throw new IllegalArgumentException("Unsupported file type");
- }
+ if(recipeSources != null && !recipeSources.isEmpty()) {
+ for(MultipartFile file : recipeSources) {
+ RecipeSource recipeSource = RecipeSourceSaveFile(file, recipe, "recipe/");
+ recipe.getRecipeSource().add(recipeSource);
+ }
+ }
- ObjectMetadata objectMetadata = new ObjectMetadata();
- objectMetadata.setContentType(file.getContentType());
- objectMetadata.setContentLength(file.getSize());
- amazonS3Client.putObject(bucket, recipeSourceServername, file.getInputStream(), objectMetadata);
- recipeSource.setRecipeSourceType(recipeSourceType);
- recipeSource.setRecipe(recipe);
- recipeSourceRepository.save(recipeSource);
- break;
- } catch (IOException e) {
- System.out.println(e.getMessage());
+ List recipeSteps = request.getRecipeSteps();
+ if(recipeSteps != null ) {
+ for (int i = 0; i < recipeSteps.size(); i++) {
+ RecipeStepRequest step = recipeSteps.get(i);
+
+ // RecipeStep 저장
+ RecipeStep newStep = new RecipeStep();
+ newStep.setRecipeStepOrder(i + 1);
+ newStep.setRecipeStepContent(step.getRecipeStepContent());
+ newStep.setRecipe(recipe);
+
+ if (recipeStepSources != null && recipeStepSources.size() > i) {
+ System.out.println("------------------------------");
+ MultipartFile file = recipeStepSources.get(i);
+ RecipeStepSource stepSource = RecipeStepSourceSaveFile(file, newStep, "recipe/step/");
+ newStep.setRecipeStepSource(stepSource); // 파일 매핑
}
+
+ recipe.getRecipeStep().add(newStep);
}
}
recipeRepository.save(recipe);
+ return recipe;
}
@Override
@@ -162,15 +267,29 @@ public void deleteRecipe(long recipePk) {
List sources = recipe.getRecipeSource();
if(sources != null && !sources.isEmpty()) {
for (RecipeSource recipeSource : sources) {
- amazonS3Client.deleteObject(new DeleteObjectRequest(bucket, recipeSource.getRecipeSourceServername()));
+ amazonS3Client.deleteObject(new DeleteObjectRequest(bucket, "recipe/"+recipeSource.getRecipeSourceServername()));
+ }
+ }
+ List steps = recipe.getRecipeStep();
+ if(steps != null && !steps.isEmpty()) {
+ for (RecipeStep recipeStep : steps) {
+ RecipeStepSource stepSource = recipeStep.getRecipeStepSource();
+ if(stepSource != null) {
+ amazonS3Client.deleteObject(new DeleteObjectRequest(bucket, "recipe/step/"+stepSource.getRecipeStepSourceServername()));
+ }
}
}
recipeRepository.delete(recipe);
}
+
+
@Override
@Transactional
- public void updateRecipe(RecipeUpdateRequest request, List files) {
+ public Recipe updateRecipe(RecipeUpdateRequest request
+ ,List recipeSources
+ ,List recipeStepSources
+ ) {
Recipe recipe = recipeRepository.findByRecipePk(request.getRecipePk())
.orElseThrow(() -> new IllegalArgumentException("Recipe not found"));
@@ -183,7 +302,7 @@ public void updateRecipe(RecipeUpdateRequest request, List files)
}
List sources = recipe.getRecipeSource();
- List uploadedFileNames = files.stream()
+ List uploadedFileNames = recipeSources.stream()
.map(MultipartFile::getOriginalFilename)
.toList();
@@ -201,7 +320,7 @@ public void updateRecipe(RecipeUpdateRequest request, List files)
.map(RecipeSource::getRecipeSourceFileName)
.toList();
- List filesToAdd = files.stream()
+ List filesToAdd = recipeSources.stream()
.filter(file -> !existingFileNames.contains(file.getOriginalFilename()))
.toList();
@@ -240,7 +359,46 @@ public void updateRecipe(RecipeUpdateRequest request, List files)
}
}
+ //시간 문제로 레시피 step 전부 삭제 후 생성하는거로 대처
+ List steps = recipe.getRecipeStep();
+ if(steps != null && !steps.isEmpty()) {
+ for (RecipeStep step : steps) {
+ RecipeStepSource stepSource = step.getRecipeStepSource();
+ if(stepSource != null) {
+ amazonS3Client.deleteObject(new DeleteObjectRequest(bucket, "recipe/step/"+stepSource.getRecipeStepSourceServername()));
+
+ }
+ }
+ //기존 사진 소스 다 삭제 후
+ recipe.getRecipeStep().clear();
+ }
+
+ List recipeSteps = request.getRecipeSteps();
+
+ if(recipeSteps != null ) {
+ for (int i = 0; i < recipeSteps.size(); i++) {
+ RecipeStepUpdateRequest step = recipeSteps.get(i);
+
+ // RecipeStep 저장
+ RecipeStep newStep = new RecipeStep();
+ newStep.setRecipeStepOrder(i + 1);
+ newStep.setRecipeStepContent(step.getRecipeStepContent());
+ newStep.setRecipe(recipe);
+
+ if (recipeStepSources != null && recipeStepSources.size() > i) {
+ System.out.println("------------------------------22");
+ MultipartFile file = recipeStepSources.get(i);
+ RecipeStepSource stepSource = RecipeStepSourceSaveFile(file, newStep, "recipe/step/");
+ newStep.setRecipeStepSource(stepSource); // 파일 매핑
+ }
+
+ recipe.getRecipeStep().add(newStep);
+ }
+ }
+
recipeRepository.save(recipe);
+
+ return recipe;
}
@@ -258,12 +416,52 @@ public List getRecommendedRecipes(Long userPk) {
response.setMatchRate(result.getMatchRate());
response.setRemainExpirationDays(result.getRemainExpirationDays());
response.setUrgentIngredientName(result.getUrgentIngredientName());
+
+ Recipe recipe = result.getRecipe();
+
+ // 메인 레시피 이미지 설정
+ List mainImages = recipe.getRecipeSource().stream()
+ .filter(source -> source.getRecipeSourceType().getRecipeSourceType().equals("MAIN"))
+ .map(this::convertToRecipeSourceInfo)
+ .collect(Collectors.toList());
+ response.setMainImages(mainImages);
+
+ // 스텝별 정보와 이미지 설정
+ List steps = recipe.getRecipeStep().stream()
+ .map(step -> {
+ RecipeStepWithImage stepInfo = new RecipeStepWithImage();
+ stepInfo.setOrder(step.getRecipeStepOrder());
+ stepInfo.setContent(step.getRecipeStepContent());
+
+ // 스텝 이미지 처리
+ if (step.getRecipeStepSource() != null) {
+ RecipeSourceInfo stepImage = new RecipeSourceInfo();
+ stepImage.setFilePath(step.getRecipeStepSource().getRecipeStepSourceSave() + "/" +
+ step.getRecipeStepSource().getRecipeStepSourceServername());
+ stepImage.setOriginalName(step.getRecipeStepSource().getRecipeStepSourceFileName());
+ stepInfo.setImages(Collections.singletonList(stepImage));
+ } else {
+ stepInfo.setImages(Collections.emptyList());
+ }
+
+ return stepInfo;
+ })
+ .collect(Collectors.toList());
+ response.setSteps(steps);
+
return response;
})
.sorted(Comparator.comparingLong(RecipeRecommendResponse::getRemainExpirationDays))
.collect(Collectors.toList());
}
+ private RecipeSourceInfo convertToRecipeSourceInfo(RecipeSource source) {
+ RecipeSourceInfo info = new RecipeSourceInfo();
+ info.setFilePath(source.getRecipeSourceSave() + "/" + source.getRecipeSourceServername());
+ info.setOriginalName(source.getRecipeSourceFileName());
+ return info;
+ }
+
private RecipeMatchResult checkRecipeMatch(Recipe recipe, List userIngredients) {
List recipeIngredients = recipeIngredientRepository.findByRecipe(recipe);
LocalDate currentDate = LocalDate.now();
diff --git a/refrigerator/src/main/java/moja/refrigerator/service/user/UserService.java b/refrigerator/src/main/java/moja/refrigerator/service/user/UserService.java
index cfb1abd..c999a75 100644
--- a/refrigerator/src/main/java/moja/refrigerator/service/user/UserService.java
+++ b/refrigerator/src/main/java/moja/refrigerator/service/user/UserService.java
@@ -1,5 +1,7 @@
package moja.refrigerator.service.user;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import moja.refrigerator.dto.user.request.PasswordResetRequest;
import moja.refrigerator.dto.user.request.PasswordUpdateRequest;
import moja.refrigerator.dto.user.request.UserCreateRequest;
@@ -10,4 +12,5 @@ public interface UserService {
void updateUser(UserUpdateRequest request);
void resetPassword(PasswordResetRequest request);
void updatePassword(PasswordUpdateRequest request);
+ void deleteUser(HttpServletRequest request, HttpServletResponse response);
}
diff --git a/refrigerator/src/main/java/moja/refrigerator/service/user/UserServiceImpl.java b/refrigerator/src/main/java/moja/refrigerator/service/user/UserServiceImpl.java
index 7329781..7308101 100644
--- a/refrigerator/src/main/java/moja/refrigerator/service/user/UserServiceImpl.java
+++ b/refrigerator/src/main/java/moja/refrigerator/service/user/UserServiceImpl.java
@@ -1,5 +1,7 @@
package moja.refrigerator.service.user;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import moja.refrigerator.aggregate.user.User;
import moja.refrigerator.dto.user.request.PasswordResetRequest;
@@ -7,6 +9,7 @@
import moja.refrigerator.dto.user.request.UserCreateRequest;
import moja.refrigerator.dto.user.request.UserUpdateRequest;
import moja.refrigerator.exception.user.DuplicateUserException;
+import moja.refrigerator.jwt.LogoutFilter;
import moja.refrigerator.repository.user.UserRepository;
import moja.refrigerator.service.email.EmailService;
import org.modelmapper.ModelMapper;
@@ -28,6 +31,7 @@ public class UserServiceImpl implements UserService {
private final BCryptPasswordEncoder passwordEncoder;
private final ModelMapper modelMapper;
private final EmailService emailService;
+ private final LogoutFilter logoutFilter;
@Override
@Transactional
@@ -114,6 +118,22 @@ public void updatePassword(PasswordUpdateRequest request) {
user.setUserPw(passwordEncoder.encode(request.getNewPw()));
}
+ @Override
+ @Transactional
+ public void deleteUser(HttpServletRequest request, HttpServletResponse response) {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ String userId = authentication.getName();
+
+ User user = userRepository.findByUserId(userId)
+ .orElseThrow(() -> new UsernameNotFoundException("사용자를 찾을 수 없습니다."));
+
+ // 유저 삭제
+ userRepository.delete(user);
+
+ // 로그아웃 처리 (토큰 블랙리스트에 추가)
+ logoutFilter.logout(request, response, authentication);
+ }
+
private void checkDuplicateUser(UserCreateRequest request) {
List errors = new ArrayList<>();
if (userRepository.existsByUserId(request.getUserId())) {