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 afc1871..1cbf656 100644
--- a/refrigerator/.idea/modules/refrigerator.main.iml
+++ b/refrigerator/.idea/modules/refrigerator.main.iml
@@ -5,4 +5,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
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..505ee16
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/aggregate/recipe/RecipeStep.java
@@ -0,0 +1,36 @@
+package moja.refrigerator.aggregate.recipe;
+
+import com.fasterxml.jackson.annotation.JsonBackReference;
+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_Source_pk")
+ private RecipeSource recipeSources;
+
+ @ManyToOne
+ @JoinColumn(name = "recipe_pk")
+ @JsonBackReference
+ private Recipe recipe;
+
+}
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..3752bff 100644
--- a/refrigerator/src/main/java/moja/refrigerator/controller/recipe/RecipeController.java
+++ b/refrigerator/src/main/java/moja/refrigerator/controller/recipe/RecipeController.java
@@ -29,10 +29,13 @@ public RecipeController(RecipeService recipeService) {
@PostMapping
public void 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
+ , recipeSources
+ , recipeStepSources
);
}
@@ -52,9 +55,10 @@ public void deleteRecipe(@RequestParam long recipePk){
@PutMapping
public void 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);
+ recipeService.updateRecipe(request,recipeSources,recipeStepSources);
}
@GetMapping("/recommend")
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/RecipeStepUpdateRequest.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeStepUpdateRequest.java
new file mode 100644
index 0000000..67b1d78
--- /dev/null
+++ b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/request/RecipeStepUpdateRequest.java
@@ -0,0 +1,10 @@
+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와 일치
+}
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/RecipeResponse.java b/refrigerator/src/main/java/moja/refrigerator/dto/recipe/response/RecipeResponse.java
index 5686857..4ac9525 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,7 @@ 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/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/service/recipe/RecipeService.java b/refrigerator/src/main/java/moja/refrigerator/service/recipe/RecipeService.java
index 81c69a5..44fe069 100644
--- a/refrigerator/src/main/java/moja/refrigerator/service/recipe/RecipeService.java
+++ b/refrigerator/src/main/java/moja/refrigerator/service/recipe/RecipeService.java
@@ -16,14 +16,16 @@
public interface RecipeService {
void createRecipe(RecipeCreateRequest request
- ,List files
+ ,List recipeSources
+ ,List recipeStepSources
);
List getAllRecipes();
RecipeDetailResponse getRecipe(long id);
void deleteRecipe(long recipePk);
void 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..70a17f6 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.*;
@@ -42,6 +40,7 @@ public class RecipeServiceImpl implements RecipeService {
private final RecipeIngredientRepository recipeIngredientRepository;
private final ReplacableIngredientRepository replacableIngredientRepository;
private final RecipeLikeDislikeRepository recipeLikeDislikeRepository;
+ private final RecipeStepRepository recipeStepRepository;
@Value("${cloud.aws.s3.bucket}")
private String bucket;
@@ -58,7 +57,8 @@ public RecipeServiceImpl(
IngredientMyRefrigeratorRepository ingredientMyRefrigeratorRepository,
RecipeIngredientRepository recipeIngredientRepository,
ReplacableIngredientRepository replacableIngredientRepository,
- RecipeLikeDislikeRepository recipeLikeDislikeRepository
+ RecipeLikeDislikeRepository recipeLikeDislikeRepository,
+ RecipeStepRepository recipeStepRepository
) {
this.recipeRepository = recipeRepository;
this.userRepository = userRepository;
@@ -71,6 +71,7 @@ public RecipeServiceImpl(
this.recipeIngredientRepository = recipeIngredientRepository;
this.replacableIngredientRepository = replacableIngredientRepository;
this.recipeLikeDislikeRepository = recipeLikeDislikeRepository;
+ this.recipeStepRepository = recipeStepRepository;
}
private boolean isImageFile(String fileName) {
String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
@@ -81,10 +82,64 @@ private boolean isVideoFile(String fileName) {
String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
return List.of("mp4", "avi", "mov", "wmv").contains(extension);
}
+ // 파일 처리 전용 메서드
+ private RecipeSource processAndSaveFile(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);
+ }
+ }
+
+
@Override
@Transactional(propagation = Propagation.REQUIRED)
- public void createRecipe(RecipeCreateRequest request, List files) {
+ public void createRecipe(RecipeCreateRequest request
+ ,List recipeSources
+ ,List recipeStepSources
+ ) {
Recipe recipe = new Recipe();
recipe.setRecipeName(request.getRecipeName());
recipe.setRecipeContent(request.getRecipeContent());
@@ -99,45 +154,36 @@ 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) {
+ processAndSaveFile(file, recipe, "recipe/");
+ }
+ }
- 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);
+ RecipeSource stepSource = processAndSaveFile(file, recipe, "recipe/step/");
+ newStep.setRecipeSources(stepSource); // 파일 매핑
}
+
+ recipe.getRecipeStep().add(newStep);
}
}
+
recipeRepository.save(recipe);
}
@@ -162,15 +208,26 @@ 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 (RecipeSource recipeSource : sources) {
+ amazonS3Client.deleteObject(new DeleteObjectRequest(bucket, "recipe/step/"+recipeSource.getRecipeSourceServername()));
}
}
recipeRepository.delete(recipe);
}
+
+
@Override
@Transactional
- public void updateRecipe(RecipeUpdateRequest request, List files) {
+ public void updateRecipe(RecipeUpdateRequest request
+ ,List recipeSources
+ ,List recipeStepSources
+ ) {
Recipe recipe = recipeRepository.findByRecipePk(request.getRecipePk())
.orElseThrow(() -> new IllegalArgumentException("Recipe not found"));
@@ -183,7 +240,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 +258,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,6 +297,41 @@ public void updateRecipe(RecipeUpdateRequest request, List files)
}
}
+ //시간 문제로 레시피 step 전부 삭제 후 생성하는거로 대처
+ List steps = recipe.getRecipeStep();
+ if(steps != null && !steps.isEmpty()) {
+ for (RecipeSource recipeSource : sources) {
+ amazonS3Client.deleteObject(new DeleteObjectRequest(bucket, "recipe/step/"+recipeSource.getRecipeSourceServername()));
+ }
+ //기존 사진 소스 다 삭제 후
+ 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("------------------------------");
+ MultipartFile file = recipeStepSources.get(i);
+ RecipeSource stepSource = processAndSaveFile(file, recipe, "recipe/step/");
+ newStep.setRecipeSources(stepSource); // 파일 매핑
+ }
+
+ recipe.getRecipeStep().add(newStep);
+ }
+ }
+
+
+
recipeRepository.save(recipe);
}