diff --git a/src/main/java/zipdabang/server/base/Code.java b/src/main/java/zipdabang/server/base/Code.java index f6d75ff..6ca6d95 100644 --- a/src/main/java/zipdabang/server/base/Code.java +++ b/src/main/java/zipdabang/server/base/Code.java @@ -57,6 +57,7 @@ public enum Code { //NOT_FOUND NOTIFICATION_NOT_FOUND(HttpStatus.OK, 4010, "공지를 찾을 수 없습니다."), + //BAD_REQUEST REFRESH_TOKEN_NOT_FOUND(HttpStatus.OK, 4050,"refresh token이 필요합니다."), //BAD_REQUEST @@ -81,6 +82,8 @@ public enum Code { //BAD_REQUEST NO_REPORT_EXIST(HttpStatus.OK, 4060, "해당 id를 가진 신고 목록이 없습니다. 잘못 보내줬어요"), + //BAD_REQUEST + DEREGISTER_FAIL(HttpStatus.OK, 4061, "탈퇴할 수 없는 유저입니다. 탈퇴 불가 사유가 존재합니다."), // market error //recipe error @@ -107,6 +110,8 @@ public enum Code { RECIPE_OWNER(HttpStatus.OK, 4109, "본인의 레시피입니다. 신고/차단할 수 없습니다"), //BAD_REQUEST COMMENT_OWNER(HttpStatus.OK, 4110, "본인의 댓글입니다. 신고/차단할 수 없습니다"), + //BAD_REQUEST + NO_TEMP_RECIPE_EXIST(HttpStatus.OK, 4111, "해당 임시저장 Id가 존재하지 않습니다."), //INTERNAL_SERVER_ERROR INTERNAL_ERROR(HttpStatus.OK, 5000, "Internal server Error"), //INTERNAL_SERVER_ERROR diff --git a/src/main/java/zipdabang/server/converter/MemberConverter.java b/src/main/java/zipdabang/server/converter/MemberConverter.java index b04776e..d1c5823 100644 --- a/src/main/java/zipdabang/server/converter/MemberConverter.java +++ b/src/main/java/zipdabang/server/converter/MemberConverter.java @@ -13,6 +13,10 @@ import zipdabang.server.domain.enums.SocialType; import zipdabang.server.domain.etc.Uuid; import zipdabang.server.domain.member.*; +import zipdabang.server.domain.member.Deregister; +import zipdabang.server.domain.member.Terms; +import zipdabang.server.domain.member.Member; +import zipdabang.server.domain.member.MemberPreferCategory; import zipdabang.server.repository.memberRepositories.MemberRepository; import zipdabang.server.utils.converter.TimeConverter; import zipdabang.server.utils.dto.OAuthJoin; @@ -302,6 +306,11 @@ public static MemberResponseDto.InqueryListDto toInqueryListDto(Page in .currentPageElements(inqueryPage.getNumberOfElements()) .totalElements(inqueryPage.getTotalElements()) .totalPage(inqueryPage.getTotalPages()) + + public static Deregister toDeregister(String phoneNum, MemberRequestDto.DeregisterDto request) { + return Deregister.builder() + .phoneNum(phoneNum) + .feedback(request.getFeedback()) .build(); } } diff --git a/src/main/java/zipdabang/server/converter/RecipeConverter.java b/src/main/java/zipdabang/server/converter/RecipeConverter.java index 121f754..bd10027 100644 --- a/src/main/java/zipdabang/server/converter/RecipeConverter.java +++ b/src/main/java/zipdabang/server/converter/RecipeConverter.java @@ -2,11 +2,14 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.cloud.client.loadbalancer.RetryableStatusCodeException; import org.springframework.data.domain.Page; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; //import zipdabang.server.aws.s3.AmazonS3Manager; import zipdabang.server.aws.s3.AmazonS3Manager; +import zipdabang.server.base.Code; +import zipdabang.server.base.exception.handler.RecipeException; import zipdabang.server.domain.Report; import zipdabang.server.domain.etc.Uuid; import zipdabang.server.domain.member.Member; @@ -18,18 +21,23 @@ import javax.annotation.PostConstruct; import java.io.IOException; +import java.rmi.RemoteException; import java.util.List; +import java.util.Optional; import java.util.concurrent.atomic.AtomicLong; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; +import static org.apache.logging.log4j.ThreadContext.isEmpty; + @Slf4j @Component @RequiredArgsConstructor public class RecipeConverter { private final RecipeRepository recipeRepository; + private final TempStepRepository tempStepRepository; private final RecipeCategoryMappingRepository recipeCategoryMappingRepository; private final LikesRepository likesRepository; private final ScrapRepository scrapRepository; @@ -41,6 +49,7 @@ public class RecipeConverter { private final TimeConverter timeConverter; private static RecipeRepository staticRecipeRepository; + private static TempStepRepository staticTempStepRepository; private static RecipeCategoryMappingRepository staticRecipeCategoryMappingRepository; @@ -66,6 +75,7 @@ public void init() { this.staticLikesRepository = this.likesRepository; this.staticScrapRepository = this.scrapRepository; this.staticTimeConverter = this.timeConverter; + this.staticTempStepRepository = this.tempStepRepository; } public static RecipeResponseDto.RecipePageListDto toPagingRecipeDtoList(Page recipes, Member member) { @@ -130,6 +140,8 @@ private static RecipeResponseDto.RecipeSimpleDto toResponseRecipeSimpleDto(Recip public static List toStep(RecipeRequestDto.CreateRecipeDto request, Recipe recipe, List stepImages) { return request.getSteps().stream() .map(step-> { + if (step.getDescription() == null) + throw new RecipeException(Code.NULL_RECIPE_ERROR); try { return toStepDto(step, recipe, stepImages); } catch (IOException e) { @@ -139,6 +151,18 @@ public static List toStep(RecipeRequestDto.CreateRecipeDto request, Recipe .collect(Collectors.toList()); } + public static List toTempStep(RecipeRequestDto.TempRecipeDto request, TempRecipe tempRecipe, List stepImages) { + return request.getSteps().stream() + .map(step-> { + try { + return toTempStepDto(step, tempRecipe, stepImages); + } catch (IOException e) { + throw new RuntimeException(e); + } + }) + .collect(Collectors.toList()); + } + public static List toRecipeCategory(RecipeRequestDto.CreateRecipeDto request, Recipe recipe) { return request.getCategoryId().stream() .map(recipeCategoryId -> toRecipeCategoryMappingDto(recipeCategoryId, recipe)) @@ -151,6 +175,12 @@ public static List toIngredient(RecipeRequestDto.CreateRecipeDto req .collect(Collectors.toList()); } + public static List toTempIngredient(RecipeRequestDto.TempRecipeDto request, TempRecipe tempRecipe) { + return request.getIngredients().stream() + .map(ingredient -> toTempIngredientDto(ingredient, tempRecipe)) + .collect(Collectors.toList()); + } + public static RecipeResponseDto.RecipeStatusDto toRecipeStatusDto(Recipe recipe) { return RecipeResponseDto.RecipeStatusDto.builder() .recipeId(recipe.getId()) @@ -158,6 +188,13 @@ public static RecipeResponseDto.RecipeStatusDto toRecipeStatusDto(Recipe recipe) .build(); } + public static RecipeResponseDto.TempRecipeStatusDto toTempRecipeStatusDto(TempRecipe tempRecipe) { + return RecipeResponseDto.TempRecipeStatusDto.builder() + .tempId(tempRecipe.getId()) + .calledAt(staticTimeConverter.ConvertTime(tempRecipe.getCreatedAt())) + .build(); + } + public static RecipeResponseDto.RecipeInfoDto toRecipeInfoDto(Recipe recipe, Boolean isOwner, Boolean isLiked, Boolean isScrapped, Member member) { return RecipeResponseDto.RecipeInfoDto.builder() @@ -230,13 +267,35 @@ public static Recipe toRecipe(RecipeRequestDto.CreateRecipeDto request, Multipar String imageUrl = null; if(thumbnail != null) imageUrl = uploadThumbnail(thumbnail); + else + throw new RecipeException(Code.NULL_RECIPE_ERROR); recipe.setThumbnail(imageUrl); return recipe; } + public static TempRecipe toTempRecipe(RecipeRequestDto.TempRecipeDto request, MultipartFile thumbnail, Member member) throws IOException { + + TempRecipe tempRecipe = TempRecipe.builder() + .isInfluencer(member.isInfluencer()) + .name(request.getName()) + .intro(request.getIntro()) + .recipeTip(request.getRecipeTip()) + .time(request.getTime()) + .member(member) + .build(); + + + String imageUrl = null; + if(thumbnail != null) + imageUrl = uploadThumbnail(thumbnail); + tempRecipe.setThumbnail(imageUrl); + - private static String uploadThumbnail(MultipartFile thumbnail) throws IOException { + return tempRecipe; + } + + public static String uploadThumbnail(MultipartFile thumbnail) throws IOException { Uuid uuid = staticAmazonS3Manager.createUUID(); String keyName = staticAmazonS3Manager.generateRecipeKeyName(uuid); String fileUrl = staticAmazonS3Manager.uploadFile(keyName, thumbnail); @@ -271,11 +330,55 @@ private static Step toStepDto(RecipeRequestDto.StepDto step, Recipe recipe, List String imageUrl = null; if(stepImages != null) imageUrl = uploadStepImage(stepImage); + else + throw new RecipeException(Code.NULL_RECIPE_ERROR); createdStep.setImage(imageUrl); return createdStep; } + private static TempStep toTempStepDto(RecipeRequestDto.TempStepDto step, TempRecipe tempRecipe, List stepImages) throws IOException { + TempStep createdTempStep = TempStep.builder() + .imageUrl(step.getStepUrl()) + .stepNum(step.getStepNum()) + .description(step.getDescription()) + .tempRecipe(tempRecipe) + .build(); + + Optional findTempStep = staticTempStepRepository.findByTempRecipeAndStepNum(tempRecipe, step.getStepNum()); + + if(step.getStepUrl() == null) { + if(findTempStep.isPresent() && findTempStep.get().getImageUrl() != null) { + staticAmazonS3Manager.deleteFile(RecipeConverter.toKeyName(findTempStep.get().getImageUrl()).substring(1)); + } + + if (stepImages != null) { + MultipartFile stepImage = null; + + for (int i = 0; i < stepImages.size(); i++) { + Integer imageNum = Integer.parseInt(stepImages.get(i).getOriginalFilename().substring(0, 1)) + 1; + if (imageNum == step.getStepNum()) { + stepImage = stepImages.get(i); + break; + } + } + + String imageUrl = null; + if (stepImage != null) { + imageUrl = uploadStepImage(stepImage); + createdTempStep.setImage(imageUrl); + } + } + } + else{ + createdTempStep.setImage(step.getStepUrl()); + } + + staticTempStepRepository.delete(findTempStep.get()); + + return createdTempStep; + } + private static String uploadStepImage(MultipartFile stepImage) throws IOException { Uuid uuid = staticAmazonS3Manager.createUUID(); String keyName = staticAmazonS3Manager.generateStepKeyName(uuid); @@ -293,6 +396,14 @@ private static Ingredient toIngredientDto(RecipeRequestDto.NewIngredientDto ingr .build(); } + private static TempIngredient toTempIngredientDto(RecipeRequestDto.NewIngredientDto ingredient, TempRecipe tempRecipe) { + return TempIngredient.builder() + .name(ingredient.getIngredientName()) + .quantity(ingredient.getQuantity()) + .tempRecipe(tempRecipe) + .build(); + } + public static Likes toLikes(Recipe recipe, Member member) { return Likes.builder() .recipe(recipe) diff --git a/src/main/java/zipdabang/server/domain/enums/DeregisterType.java b/src/main/java/zipdabang/server/domain/enums/DeregisterType.java new file mode 100644 index 0000000..2b2495c --- /dev/null +++ b/src/main/java/zipdabang/server/domain/enums/DeregisterType.java @@ -0,0 +1,19 @@ +package zipdabang.server.domain.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum DeregisterType { + + NOTHING_TO_BUY("사고싶은 물건이 없어요."), + DISINTERESTED("앱을 이용하지 않아요."), + UNCOMFORTABLE("앱 이용이 불편해요."), + NEW_REGISTER("새 계정을 만들고 싶어요."), + MET_RUDE_USER("비매너 유저를 만났어요."), + OTHERS("기타"), + INAPPROPRIATE_USER("불건전한 서비스 이용"); + + private final String description; +} diff --git a/src/main/java/zipdabang/server/domain/member/Deregister.java b/src/main/java/zipdabang/server/domain/member/Deregister.java new file mode 100644 index 0000000..5fb119c --- /dev/null +++ b/src/main/java/zipdabang/server/domain/member/Deregister.java @@ -0,0 +1,31 @@ +package zipdabang.server.domain.member; + +import lombok.*; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +import zipdabang.server.domain.common.BaseEntity; + +import javax.persistence.*; +import java.util.List; + +@Entity +@Builder +@Getter +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@DynamicInsert +@DynamicUpdate +public class Deregister extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(length = 18) + private String phoneNum; + + @OneToMany(mappedBy = "deregister", cascade = CascadeType.ALL, orphanRemoval = true) + private List deregisterReasonList; + + private String feedback; + +} diff --git a/src/main/java/zipdabang/server/domain/member/DeregisterReason.java b/src/main/java/zipdabang/server/domain/member/DeregisterReason.java new file mode 100644 index 0000000..3e75a89 --- /dev/null +++ b/src/main/java/zipdabang/server/domain/member/DeregisterReason.java @@ -0,0 +1,31 @@ +package zipdabang.server.domain.member; + +import lombok.*; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +import zipdabang.server.domain.common.BaseEntity; +import zipdabang.server.domain.enums.DeregisterType; + +import javax.persistence.*; + +@Entity +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PUBLIC) +@DynamicInsert +@DynamicUpdate +public class DeregisterReason extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "deregister_id") + private Deregister deregister; + + @Enumerated(EnumType.STRING) + private DeregisterType deregisterType; + +} diff --git a/src/main/java/zipdabang/server/domain/member/Member.java b/src/main/java/zipdabang/server/domain/member/Member.java index 025e17e..ec8a7e8 100644 --- a/src/main/java/zipdabang/server/domain/member/Member.java +++ b/src/main/java/zipdabang/server/domain/member/Member.java @@ -128,4 +128,7 @@ public void setDetailInfo(MemberResponseDto.MemberDetailInfoDto memberDetailInfo public void setNickname(String nickname) { this.nickname = nickname; } + + public void inactivateStatus(){ + this.status = StatusType.INACTIVE;} } diff --git a/src/main/java/zipdabang/server/domain/recipe/Ingredient.java b/src/main/java/zipdabang/server/domain/recipe/Ingredient.java index a3f3bc7..1f4903d 100644 --- a/src/main/java/zipdabang/server/domain/recipe/Ingredient.java +++ b/src/main/java/zipdabang/server/domain/recipe/Ingredient.java @@ -21,9 +21,10 @@ public class Ingredient extends BaseEntity { @Column(nullable = false) private Long id; + @Column(nullable = false) private String name; - @Column(length = 100) + @Column(length = 100, nullable = false) private String quantity; @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/java/zipdabang/server/domain/recipe/Recipe.java b/src/main/java/zipdabang/server/domain/recipe/Recipe.java index 0118478..ac64d75 100644 --- a/src/main/java/zipdabang/server/domain/recipe/Recipe.java +++ b/src/main/java/zipdabang/server/domain/recipe/Recipe.java @@ -25,19 +25,22 @@ public class Recipe extends BaseEntity { @Column(nullable = false) private Long id; + @Column(nullable = false) private Boolean isInfluencer; + @Column(nullable = false) private String name; - @Column(columnDefinition = "TEXT") + @Column(columnDefinition = "TEXT", nullable = false) private String thumbnailUrl; - @Column(length = 500) + @Column(length = 500, nullable = false) private String intro; - @Column(length = 500) + @Column(length = 500, nullable = false) private String recipeTip; + @Column(nullable = false) private String time; @Column(columnDefinition = "FLOAT DEFAULT 0") diff --git a/src/main/java/zipdabang/server/domain/recipe/Step.java b/src/main/java/zipdabang/server/domain/recipe/Step.java index 97d4898..65255b8 100644 --- a/src/main/java/zipdabang/server/domain/recipe/Step.java +++ b/src/main/java/zipdabang/server/domain/recipe/Step.java @@ -21,12 +21,13 @@ public class Step extends BaseEntity { @Column(nullable = false) private Long id; + @Column(nullable = false) private Integer stepNum; - @Column(columnDefinition = "TEXT") + @Column(columnDefinition = "TEXT", nullable = false) private String imageUrl; - @Column(columnDefinition = "TEXT") + @Column(columnDefinition = "TEXT", nullable = false) private String description; @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/java/zipdabang/server/domain/recipe/TempIngredient.java b/src/main/java/zipdabang/server/domain/recipe/TempIngredient.java new file mode 100644 index 0000000..6529a7f --- /dev/null +++ b/src/main/java/zipdabang/server/domain/recipe/TempIngredient.java @@ -0,0 +1,39 @@ +package zipdabang.server.domain.recipe; + +import lombok.*; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +import zipdabang.server.domain.common.BaseEntity; + +import javax.persistence.*; + +@Entity +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@DynamicInsert +@DynamicUpdate +public class TempIngredient extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false) + private Long id; + + private String name; + + private String quantity; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "temp_id", nullable = false) + private TempRecipe tempRecipe; + + public TempIngredient setTempRecipe(TempRecipe tempRecipe){ + if(this.tempRecipe != null) + tempRecipe.getIngredientList().remove(this); + this.tempRecipe = tempRecipe; + tempRecipe.getIngredientList().add(this); + + return this; + } +} diff --git a/src/main/java/zipdabang/server/domain/recipe/TempRecipe.java b/src/main/java/zipdabang/server/domain/recipe/TempRecipe.java new file mode 100644 index 0000000..3296467 --- /dev/null +++ b/src/main/java/zipdabang/server/domain/recipe/TempRecipe.java @@ -0,0 +1,75 @@ +package zipdabang.server.domain.recipe; + +import lombok.*; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +import org.springframework.web.multipart.MultipartFile; +import zipdabang.server.converter.RecipeConverter; +import zipdabang.server.domain.common.BaseEntity; +import zipdabang.server.domain.member.Member; +import zipdabang.server.web.dto.requestDto.RecipeRequestDto; + +import javax.persistence.*; +import java.io.IOException; +import java.util.List; + +@Slf4j +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@DynamicInsert +@DynamicUpdate +@Entity +public class TempRecipe extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false) + private Long id; + + @Column(nullable = false) + private Boolean isInfluencer; + + private String name; + + @Column(columnDefinition = "TEXT") + private String thumbnailUrl; + + @Column(length = 500) + private String intro; + + @Column(length = 500) + private String recipeTip; + + private String time; + + + //updated_at + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id", nullable = false) + private Member member; + + @OneToMany(mappedBy = "tempRecipe", cascade = CascadeType.ALL) + private List stepList; + + @OneToMany(mappedBy = "tempRecipe", cascade = CascadeType.ALL) + private List ingredientList; + + + public TempRecipe setThumbnail(String imageUrl) { + log.info("setThumbnail 호출됨"); + this.thumbnailUrl = imageUrl; + return this; + } + + public TempRecipe updateInfo(RecipeRequestDto.TempRecipeDto request) { + this.name = request.getName(); + this.intro = request.getIntro(); + this.recipeTip = request.getRecipeTip(); + this.time = request.getTime(); + + return this; + } +} diff --git a/src/main/java/zipdabang/server/domain/recipe/TempStep.java b/src/main/java/zipdabang/server/domain/recipe/TempStep.java new file mode 100644 index 0000000..3d50e4d --- /dev/null +++ b/src/main/java/zipdabang/server/domain/recipe/TempStep.java @@ -0,0 +1,49 @@ +package zipdabang.server.domain.recipe; + +import lombok.*; +import org.hibernate.annotations.DynamicInsert; +import org.hibernate.annotations.DynamicUpdate; +import zipdabang.server.domain.common.BaseEntity; + +import javax.persistence.*; + +@Entity +@Getter +@Builder +@AllArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@DynamicInsert +@DynamicUpdate +public class TempStep extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(nullable = false) + private Long id; + + @Column(nullable = false) + private Integer stepNum; + + @Column(columnDefinition = "TEXT") + private String imageUrl; + + @Column(columnDefinition = "TEXT") + private String description; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "temp_id", nullable = false) + private TempRecipe tempRecipe; + + public TempStep setImage(String imageUrl) { + this.imageUrl = imageUrl; + return this; + } + + public TempStep setTempRecipe(TempRecipe tempRecipe){ + if(this.tempRecipe != null) + tempRecipe.getStepList().remove(this); + this.tempRecipe = tempRecipe; + tempRecipe.getStepList().add(this); + + return this; + } +} diff --git a/src/main/java/zipdabang/server/repository/memberRepositories/DeregisterReasonRepository.java b/src/main/java/zipdabang/server/repository/memberRepositories/DeregisterReasonRepository.java new file mode 100644 index 0000000..20de545 --- /dev/null +++ b/src/main/java/zipdabang/server/repository/memberRepositories/DeregisterReasonRepository.java @@ -0,0 +1,9 @@ +package zipdabang.server.repository.memberRepositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import zipdabang.server.domain.member.DeregisterReason; + +public interface DeregisterReasonRepository extends JpaRepository { + +} diff --git a/src/main/java/zipdabang/server/repository/memberRepositories/DeregisterRepository.java b/src/main/java/zipdabang/server/repository/memberRepositories/DeregisterRepository.java new file mode 100644 index 0000000..87a5eb0 --- /dev/null +++ b/src/main/java/zipdabang/server/repository/memberRepositories/DeregisterRepository.java @@ -0,0 +1,8 @@ +package zipdabang.server.repository.memberRepositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import zipdabang.server.domain.member.Deregister; + +public interface DeregisterRepository extends JpaRepository { + +} diff --git a/src/main/java/zipdabang/server/repository/recipeRepositories/IngredientRepository.java b/src/main/java/zipdabang/server/repository/recipeRepositories/IngredientRepository.java index 198c062..966c12d 100644 --- a/src/main/java/zipdabang/server/repository/recipeRepositories/IngredientRepository.java +++ b/src/main/java/zipdabang/server/repository/recipeRepositories/IngredientRepository.java @@ -2,6 +2,10 @@ import org.springframework.data.jpa.repository.JpaRepository; import zipdabang.server.domain.recipe.Ingredient; +import zipdabang.server.domain.recipe.TempIngredient; +import zipdabang.server.domain.recipe.TempRecipe; + +import java.util.List; public interface IngredientRepository extends JpaRepository { } diff --git a/src/main/java/zipdabang/server/repository/recipeRepositories/TempIngredientRepository.java b/src/main/java/zipdabang/server/repository/recipeRepositories/TempIngredientRepository.java new file mode 100644 index 0000000..a5977d3 --- /dev/null +++ b/src/main/java/zipdabang/server/repository/recipeRepositories/TempIngredientRepository.java @@ -0,0 +1,13 @@ +package zipdabang.server.repository.recipeRepositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import zipdabang.server.domain.recipe.TempIngredient; +import zipdabang.server.domain.recipe.TempRecipe; + +import java.util.List; +import java.util.Optional; + +public interface TempIngredientRepository extends JpaRepository { + + void deleteAllByTempRecipe(TempRecipe tempRecipe); +} diff --git a/src/main/java/zipdabang/server/repository/recipeRepositories/TempRecipeRepository.java b/src/main/java/zipdabang/server/repository/recipeRepositories/TempRecipeRepository.java new file mode 100644 index 0000000..5c53495 --- /dev/null +++ b/src/main/java/zipdabang/server/repository/recipeRepositories/TempRecipeRepository.java @@ -0,0 +1,7 @@ +package zipdabang.server.repository.recipeRepositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import zipdabang.server.domain.recipe.TempRecipe; + +public interface TempRecipeRepository extends JpaRepository { +} diff --git a/src/main/java/zipdabang/server/repository/recipeRepositories/TempStepRepository.java b/src/main/java/zipdabang/server/repository/recipeRepositories/TempStepRepository.java new file mode 100644 index 0000000..a3b4609 --- /dev/null +++ b/src/main/java/zipdabang/server/repository/recipeRepositories/TempStepRepository.java @@ -0,0 +1,16 @@ +package zipdabang.server.repository.recipeRepositories; + +import org.springframework.data.jpa.repository.JpaRepository; +import zipdabang.server.domain.recipe.TempRecipe; +import zipdabang.server.domain.recipe.TempStep; + +import java.util.List; +import java.util.Optional; + +public interface TempStepRepository extends JpaRepository { + Optional findByTempRecipeAndStepNum(TempRecipe tempRecipe, Integer stepNum); + + void deleteAllByTempRecipe(TempRecipe tempRecipe); + + List findAllByTempRecipe(TempRecipe tempRecipe); +} diff --git a/src/main/java/zipdabang/server/service/MemberService.java b/src/main/java/zipdabang/server/service/MemberService.java index 65a02a0..63607db 100644 --- a/src/main/java/zipdabang/server/service/MemberService.java +++ b/src/main/java/zipdabang/server/service/MemberService.java @@ -4,6 +4,7 @@ import org.springframework.data.domain.PageRequest; import zipdabang.server.domain.Category; import zipdabang.server.domain.member.Inquery; +import zipdabang.server.domain.enums.DeregisterType; import zipdabang.server.domain.member.Member; import zipdabang.server.domain.member.Terms; import zipdabang.server.redis.domain.RefreshToken; @@ -42,7 +43,13 @@ public interface MemberService { String tempLoginService(); + Inquery createInquery(Member member, MemberRequestDto.InqueryDto request); Page findInquery(Member member, Integer page); + public void memberDeregister(Member member, MemberRequestDto.DeregisterDto request); + public Long saveDeregisterInfo(String phoneNum, MemberRequestDto.DeregisterDto request); + public void inactivateMember(Member member); + + public void saveDeregisterReasons(Long deregisterId, List deregisterTypeList); } diff --git a/src/main/java/zipdabang/server/service/RecipeService.java b/src/main/java/zipdabang/server/service/RecipeService.java index c038568..bf916bf 100644 --- a/src/main/java/zipdabang/server/service/RecipeService.java +++ b/src/main/java/zipdabang/server/service/RecipeService.java @@ -3,10 +3,7 @@ import org.springframework.data.domain.Page; import org.springframework.web.multipart.MultipartFile; import zipdabang.server.domain.member.Member; -import zipdabang.server.domain.recipe.Comment; -import zipdabang.server.domain.recipe.Recipe; -import zipdabang.server.domain.recipe.RecipeBanner; -import zipdabang.server.domain.recipe.RecipeCategory; +import zipdabang.server.domain.recipe.*; import zipdabang.server.web.dto.requestDto.RecipeRequestDto; import java.io.IOException; @@ -56,4 +53,8 @@ public interface RecipeService { Long reportComment(Long recipeId, Long commentId, Long reportId, Member member); Long reportRecipe(Long recipeId, Long reportId, Member member); + + TempRecipe tempCreate(RecipeRequestDto.TempRecipeDto request, MultipartFile thumbnail, List stepImages, Member member) throws IOException; + + TempRecipe tempUpdate(Long tempId, RecipeRequestDto.TempRecipeDto request, MultipartFile thumbnail, List stepImages, Member member) throws IOException; } diff --git a/src/main/java/zipdabang/server/service/serviceImpl/MemberServiceImpl.java b/src/main/java/zipdabang/server/service/serviceImpl/MemberServiceImpl.java index 614b739..2271700 100644 --- a/src/main/java/zipdabang/server/service/serviceImpl/MemberServiceImpl.java +++ b/src/main/java/zipdabang/server/service/serviceImpl/MemberServiceImpl.java @@ -16,6 +16,7 @@ import zipdabang.server.base.exception.handler.MemberException; import zipdabang.server.converter.MemberConverter; import zipdabang.server.domain.Category; +import zipdabang.server.domain.enums.DeregisterType; import zipdabang.server.domain.enums.SocialType; import zipdabang.server.domain.etc.Uuid; import zipdabang.server.domain.member.Member; @@ -32,6 +33,7 @@ import zipdabang.server.repository.memberRepositories.InqueryRepository; import zipdabang.server.repository.memberRepositories.MemberRepository; import zipdabang.server.repository.memberRepositories.PreferCategoryRepository; +import zipdabang.server.repository.memberRepositories.*; import zipdabang.server.service.MemberService; import zipdabang.server.utils.dto.OAuthJoin; import zipdabang.server.utils.dto.OAuthResult; @@ -69,6 +71,8 @@ public class MemberServiceImpl implements MemberService { private final InqueryRepository inqueryRepository; private final AmazonS3Manager s3Manager; + private final DeregisterRepository deregisterRepository; + private final DeregisterReasonRepository deregisterReasonRepository; @Value("${paging.size}") private Integer pageSize; @@ -269,4 +273,46 @@ public List findMemberPreferCategories(Member member) { } return categoryList; } + + @Override + @Transactional + public void memberDeregister(Member member, MemberRequestDto.DeregisterDto request) { + inactivateMember(member); + Long deregisterId = saveDeregisterInfo(member.getPhoneNum(), request); + saveDeregisterReasons(deregisterId,request.getDeregisterTypes()); + + } + + @Override + @Transactional + public void inactivateMember(Member member) { + member.inactivateStatus(); + } + + @Override + @Transactional + public Long saveDeregisterInfo(String phoneNum, MemberRequestDto.DeregisterDto request) { + Deregister deregister = MemberConverter.toDeregister(phoneNum, request); + deregisterRepository.save(deregister); + + for (DeregisterType deregisterType : request.getDeregisterTypes()) { + deregisterReasonRepository.save( + DeregisterReason.builder() + .deregister(deregister) + .deregisterType(deregisterType) + .build()); + + } + + return deregister.getId(); + } + + @Override + @Transactional + public void saveDeregisterReasons(Long deregisterId, List deregisterTypeList) { +// for (DeregisterType deregisterType : deregisterTypeList) { +// DeregisterReason.builder() +// . +// } + } } diff --git a/src/main/java/zipdabang/server/service/serviceImpl/RecipeServiceImpl.java b/src/main/java/zipdabang/server/service/serviceImpl/RecipeServiceImpl.java index 60e633e..15c7c40 100644 --- a/src/main/java/zipdabang/server/service/serviceImpl/RecipeServiceImpl.java +++ b/src/main/java/zipdabang/server/service/serviceImpl/RecipeServiceImpl.java @@ -42,11 +42,14 @@ public class RecipeServiceImpl implements RecipeService { private final RecipeRepository recipeRepository; + private final TempRecipeRepository tempRecipeRepository; private final RecipeCategoryMappingRepository recipeCategoryMappingRepository; private final RecipeCategoryRepository recipeCategoryRepository; private final RecipeBannerRepository recipeBannerRepository; private final StepRepository stepRepository; + private final TempStepRepository tempStepRepository; private final IngredientRepository ingredientRepository; + private final TempIngredientRepository tempIngredientRepository; private final LikesRepository likesRepository; private final ScrapRepository scrapRepository; private final AmazonS3Manager amazonS3Manager; @@ -59,7 +62,6 @@ public class RecipeServiceImpl implements RecipeService { private final JPAQueryFactory queryFactory; - private final JPAQueryFactory jpaQueryFactory; @Value("${paging.size}") Integer pageSize; @@ -98,6 +100,93 @@ public Recipe create(RecipeRequestDto.CreateRecipeDto request, MultipartFile thu return recipe; } + @Override + @Transactional(readOnly = false) + public TempRecipe tempCreate(RecipeRequestDto.TempRecipeDto request, MultipartFile thumbnail, List stepImages, Member member) throws IOException { + + log.info("service: ", request.toString()); + + TempRecipe buildTempRecipe = RecipeConverter.toTempRecipe(request, thumbnail, member); + TempRecipe tempRecipe = tempRecipeRepository.save(buildTempRecipe); + + if (request.getStepCount() > 0) { + RecipeConverter.toTempStep(request, tempRecipe, stepImages).stream() + .map(step -> tempStepRepository.save(step)) + .collect(Collectors.toList()) + .stream() + .map(step -> step.setTempRecipe(tempRecipe)); + } + + if(request.getIngredientCount() > 0) { + RecipeConverter.toTempIngredient(request, tempRecipe).stream() + .map(ingredient -> tempIngredientRepository.save(ingredient)) + .collect(Collectors.toList()) + .stream() + .map(ingredient -> ingredient.setTempRecipe(tempRecipe)); + } + + return tempRecipe; + } + + @Override + @Transactional(readOnly = false) + public TempRecipe tempUpdate(Long tempId, RecipeRequestDto.TempRecipeDto request, MultipartFile thumbnail, List stepImages, Member member) throws IOException { + + log.info("service: ", request.toString()); + + TempRecipe tempRecipe = tempRecipeRepository.findById(tempId).orElseThrow(() -> new RecipeException(Code.NO_TEMP_RECIPE_EXIST)); + + //recipe + String thumbnailUrl = null; + if (request.getThumbnailUrl() == null){ + if (tempRecipe.getThumbnailUrl() != null) + amazonS3Manager.deleteFile(RecipeConverter.toKeyName(tempRecipe.getThumbnailUrl()).substring(1)); + + if(thumbnail != null) + thumbnailUrl = RecipeConverter.uploadThumbnail(thumbnail); + + } + else { + thumbnailUrl = request.getThumbnailUrl(); + } + + tempRecipe.setThumbnail(thumbnailUrl); + tempRecipe.updateInfo(request); + + + //step + if(request.getStepCount() > 0) { + RecipeConverter.toTempStep(request, tempRecipe, stepImages).stream() + .map(step -> tempStepRepository.save(step)) + .collect(Collectors.toList()) + .stream() + .map(step -> step.setTempRecipe(tempRecipe)); + } + else{ + tempStepRepository.findAllByTempRecipe(tempRecipe).stream() + .filter(step -> step.getImageUrl() != null) + .forEach(step -> amazonS3Manager.deleteFile(RecipeConverter.toKeyName(step.getImageUrl()).substring(1))); + tempStepRepository.deleteAllByTempRecipe(tempRecipe); + } + + //ingredient + if(request.getIngredientCount() >0) { + tempIngredientRepository.deleteAllByTempRecipe(tempRecipe); + + RecipeConverter.toTempIngredient(request, tempRecipe).stream() + .map(ingredient -> tempIngredientRepository.save(ingredient)) + .collect(Collectors.toList()) + .stream() + .map(ingredient -> ingredient.setTempRecipe(tempRecipe)); + } + else{ + tempIngredientRepository.deleteAllByTempRecipe(tempRecipe); + } + + return tempRecipe; + + } + @Transactional(readOnly = false) @Override public Recipe getRecipe(Long recipeId, Member member) { diff --git a/src/main/java/zipdabang/server/validation/annotation/CheckDeregister.java b/src/main/java/zipdabang/server/validation/annotation/CheckDeregister.java new file mode 100644 index 0000000..00bd66c --- /dev/null +++ b/src/main/java/zipdabang/server/validation/annotation/CheckDeregister.java @@ -0,0 +1,18 @@ +package zipdabang.server.validation.annotation; + +import zipdabang.server.validation.validator.CheckDeregisterValidator; +import zipdabang.server.validation.validator.CheckTempMemberValidator; + +import javax.validation.Constraint; +import javax.validation.Payload; +import java.lang.annotation.*; + +@Documented +@Constraint(validatedBy = CheckDeregisterValidator.class) +@Target( { ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER }) +@Retention(RetentionPolicy.RUNTIME) +public @interface CheckDeregister { + String message() default "탈퇴가 불가능한 유저입니다."; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/src/main/java/zipdabang/server/validation/validator/CheckDeregisterValidator.java b/src/main/java/zipdabang/server/validation/validator/CheckDeregisterValidator.java new file mode 100644 index 0000000..76391b3 --- /dev/null +++ b/src/main/java/zipdabang/server/validation/validator/CheckDeregisterValidator.java @@ -0,0 +1,33 @@ +package zipdabang.server.validation.validator; + +import zipdabang.server.base.Code; +import zipdabang.server.domain.member.Deregister; +import zipdabang.server.domain.member.Member; +import zipdabang.server.validation.annotation.CheckDeregister; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; + +public class CheckDeregisterValidator implements ConstraintValidator { + + @Override + public void initialize(CheckDeregister constraintAnnotation) { + ConstraintValidator.super.initialize(constraintAnnotation); + } + + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { + if (value instanceof Member) { + Member member = (Member) value; + if (member.getZipCode()==null) { + return true; + } + if (member.getZipCode().equals("TEST")) { + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate(Code.DEREGISTER_FAIL.toString()).addConstraintViolation(); + return false; + } + } + return true; + } +} diff --git a/src/main/java/zipdabang/server/web/controller/MemberRestController.java b/src/main/java/zipdabang/server/web/controller/MemberRestController.java index 020a826..1143996 100644 --- a/src/main/java/zipdabang/server/web/controller/MemberRestController.java +++ b/src/main/java/zipdabang/server/web/controller/MemberRestController.java @@ -36,6 +36,7 @@ import zipdabang.server.utils.dto.OAuthJoin; import zipdabang.server.validation.annotation.CheckPage; import zipdabang.server.validation.annotation.CheckTempMember; +import zipdabang.server.validation.annotation.CheckDeregister; import zipdabang.server.web.dto.requestDto.MemberRequestDto; import zipdabang.server.web.dto.responseDto.MemberResponseDto; @@ -58,11 +59,11 @@ @Slf4j @RequiredArgsConstructor @ApiResponses({ - @ApiResponse(responseCode = "4003",description = "UNAUTHORIZED, 토큰 모양이 이상함, 토큰 제대로 주세요",content = @Content(schema = @Schema(implementation = ResponseDto.class))), - @ApiResponse(responseCode = "4005",description = "UNAUTHORIZED, 엑세스 토큰 만료, 리프레시 토큰 사용",content = @Content(schema = @Schema(implementation = ResponseDto.class))), - @ApiResponse(responseCode = "4008",description = "UNAUTHORIZED, 토큰 없음, 토큰 줘요",content = @Content(schema = @Schema(implementation = ResponseDto.class))), - @ApiResponse(responseCode = "4052",description = "BAD_REQUEST, 사용자가 없습니다. 이 api에서 이거 생기면 백앤드 개발자 호출",content = @Content(schema = @Schema(implementation = ResponseDto.class))), - @ApiResponse(responseCode = "5000",description = "SERVER ERROR, 백앤드 개발자에게 알려주세요",content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4003", description = "UNAUTHORIZED, 토큰 모양이 이상함, 토큰 제대로 주세요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4005", description = "UNAUTHORIZED, 엑세스 토큰 만료, 리프레시 토큰 사용", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4008", description = "UNAUTHORIZED, 토큰 없음, 토큰 줘요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4052", description = "BAD_REQUEST, 사용자가 없습니다. 이 api에서 이거 생기면 백앤드 개발자 호출", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "5000", description = "SERVER ERROR, 백앤드 개발자에게 알려주세요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), }) @Tag(name = "유저 관련 API", description = "로그인, 회원가입, 마이 페이지에서 필요한 API모음") public class MemberRestController { @@ -181,7 +182,6 @@ public ResponseDto showMyProfile(@AuthMember } - // 내 선호 음료 조회 @Operation(summary = "[figma 더보기 - 즐겨마시는 음료 종류 1] 유저 선호 카테고리 조회 API ✔️", description = "유저 선호 카테고리 조회 API입니다.") @Parameters({ @@ -198,7 +198,6 @@ public ResponseDto memberPreferCatego } - // 회원정보 조회 및 수정 APIs @@ -213,7 +212,7 @@ public ResponseDto memberPreferCatego public ResponseDto showMyInfo(@AuthMember Member member) { List memberPreferCategories = memberService.findMemberPreferCategories(member); MemberResponseDto.MemberPreferCategoryDto memberPreferCategoryDto = MemberConverter.toMemberPreferCategoryDto(memberPreferCategories); - return ResponseDto.of(MemberConverter.toMemberInfoDto(member,memberPreferCategoryDto)); + return ResponseDto.of(MemberConverter.toMemberInfoDto(member, memberPreferCategoryDto)); } @Operation(summary = "[figma 더보기 - 회원 정보 1] 프로필사진 수정 API ✔️", description = "프로필사진 수정 API입니다.") @@ -223,10 +222,10 @@ public ResponseDto showMyInfo(@AuthMemb @ApiResponses({ @ApiResponse(responseCode = "2000", description = "OK 성공 , 프로필사진 수정 완료"), }) - @PatchMapping(value = "/myInfo/profileImage",consumes = { MediaType.MULTIPART_FORM_DATA_VALUE }) + @PatchMapping(value = "/myInfo/profileImage", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) public ResponseDto updateProfileImage(@AuthMember Member member, @ModelAttribute MemberRequestDto.changeProfileDto request) throws IOException { memberService.updateMemberProfileImage(member, request); - return ResponseDto.of(MemberConverter.toMemberStatusDto(member.getMemberId(),"updateProfileImage")); + return ResponseDto.of(MemberConverter.toMemberStatusDto(member.getMemberId(), "updateProfileImage")); } @Operation(summary = "[figma 더보기 - 회원 정보 수정 1] 기본정보 수정 API ✔️", description = "기본정보 수정 API입니다.") @@ -240,7 +239,7 @@ public ResponseDto updateProfileImage(@AuthMe public ResponseDto updateBasicInfo(@AuthMember Member member, @RequestBody MemberResponseDto.MemberBasicInfoDto request) { memberService.updateMemberBasicInfo(member, request); - return ResponseDto.of(MemberConverter.toMemberStatusDto(member.getMemberId(),"updateBasicInfo")); + return ResponseDto.of(MemberConverter.toMemberStatusDto(member.getMemberId(), "updateBasicInfo")); } @Operation(summary = "[figma 더보기 - 회원 정보 수정 2] 상세정보 수정 API ✔️", description = "상세정보 수정 API입니다.") @@ -253,7 +252,7 @@ public ResponseDto updateBasicInfo(@AuthMembe @PatchMapping("/myInfo/detailInfo") public ResponseDto updateDetailInfo(@AuthMember Member member, @RequestBody MemberResponseDto.MemberDetailInfoDto request) { memberService.updateMemberDetailInfo(member, request); - return ResponseDto.of(MemberConverter.toMemberStatusDto(member.getMemberId(),"updateDetailInfo")); + return ResponseDto.of(MemberConverter.toMemberStatusDto(member.getMemberId(), "updateDetailInfo")); } @Operation(summary = "[figma 더보기 - 회원 정보 수정 3] 닉네임 수정 API ✔️", description = "닉네임 수정 API입니다.") @@ -266,7 +265,7 @@ public ResponseDto updateDetailInfo(@AuthMemb @PatchMapping("/myInfo/nickname") public ResponseDto updateNickname(@AuthMember Member member, @RequestBody MemberRequestDto.changeNicknameDto request) { memberService.updateMemberNickname(member, request.getNickname()); - return ResponseDto.of(MemberConverter.toMemberStatusDto(member.getMemberId(),"updateNickname")); + return ResponseDto.of(MemberConverter.toMemberStatusDto(member.getMemberId(), "updateNickname")); } @@ -282,12 +281,10 @@ public ResponseDto updateNickname(@AuthMember public ResponseDto updatePreferCategories(@AuthMember Member member, @RequestBody MemberRequestDto.changeCategoryDto request) { List categories = request.getCategories(); memberService.updateMemberPreferCategory(member, request); - return ResponseDto.of(MemberConverter.toMemberStatusDto(member.getMemberId(),"updatePreferCategories")); + return ResponseDto.of(MemberConverter.toMemberStatusDto(member.getMemberId(), "updatePreferCategories")); } - - //닉네임 중복검사 @Operation(summary = "🎪[figma 회원가입까지 - 닉네임 입력 1,2,3] 닉네임 중복검사 API ✔️", description = "닉네임 중복검사 API입니다.") @ApiResponses({ @@ -336,10 +333,10 @@ public ResponseDto showTerms() { @Operation(summary = "🎪figma[온보딩1] 나중에 로그인하기 API ✔️", description = "나중에 로그인하기 API 입니다.") @ApiResponses({ - @ApiResponse(responseCode = "2000",description = "OK 성공, access Token 하나만 반환함"), + @ApiResponse(responseCode = "2000", description = "OK 성공, access Token 하나만 반환함"), }) @PostMapping("/members/temp-login") - public ResponseDto tempLogin(){ + public ResponseDto tempLogin() { return ResponseDto.of(MemberConverter.toTempLoginDto(memberService.tempLoginService())); } @@ -369,4 +366,24 @@ public ResponseDto showInquery(@CheckTempMembe Page inqueryPage = memberService.findInquery(member, page); return ResponseDto.of(MemberConverter.toInqueryListDto(inqueryPage)); } + @Operation(summary = "[figma 더보기 - 회원 탈퇴] 회원 탈퇴 API ✔️", description = "회원 탈퇴 API입니다.
테스트를 위해 임시로 해당 유저의 상세주소를 \"TEST\" 로 설정하면(상세정보 수정 API - zipCode) 탈퇴 불가능한 경우로 처리되도록 해놨습니다.
deregisterTypes 종류
"+ + "- NOTHING_TO_BUY(\"사고싶은 물건이 없어요.\"),
" + + "- DISINTERESTED(\"앱을 이용하지 않아요.\"),
" + + "- UNCOMFORTABLE(\"앱 이용이 불편해요.\"),
" + + "- NEW_REGISTER(\"새 계정을 만들고 싶어요.\"),
" + + "- MET_RUDE_USER(\"비매너 유저를 만났어요.\"),
" + + "- OTHERS(\"기타\")") + @Parameters({ + @Parameter(name = "member", hidden = true), + }) + @ApiResponses({ + @ApiResponse(responseCode = "2000", description = "OK 성공, 유저 비활성화 완료"), + @ApiResponse(responseCode = "4061", description = "탈퇴할 수 없는 유저입니다. 탈퇴 불가 사유가 존재합니다."), + }) + @PatchMapping("/members/deregister") + public ResponseDto deregister(@CheckDeregister @AuthMember Member member, MemberRequestDto.DeregisterDto request) { + memberService.memberDeregister(member, request); + return ResponseDto.of(MemberConverter.toMemberStatusDto(member.getMemberId(), "deregister")); + + } } diff --git a/src/main/java/zipdabang/server/web/controller/RecipeRestController.java b/src/main/java/zipdabang/server/web/controller/RecipeRestController.java index 28e8608..a23489e 100644 --- a/src/main/java/zipdabang/server/web/controller/RecipeRestController.java +++ b/src/main/java/zipdabang/server/web/controller/RecipeRestController.java @@ -21,10 +21,7 @@ import zipdabang.server.base.exception.handler.RecipeException; import zipdabang.server.converter.RecipeConverter; import zipdabang.server.domain.member.Member; -import zipdabang.server.domain.recipe.Comment; -import zipdabang.server.domain.recipe.Recipe; -import zipdabang.server.domain.recipe.RecipeBanner; -import zipdabang.server.domain.recipe.RecipeCategory; +import zipdabang.server.domain.recipe.*; import zipdabang.server.service.RecipeService; import zipdabang.server.validation.annotation.CheckTempMember; import zipdabang.server.web.dto.requestDto.RecipeRequestDto; @@ -69,6 +66,39 @@ public ResponseDto createRecipe( return ResponseDto.of(RecipeConverter.toRecipeStatusDto(recipe)); } + @Operation(summary = "레시피 임시저장, 레시피 임시저장 등록 API 🔑 ✔", description = "레시피 임시저장 화면 API입니다. ") + @ApiResponses({ + @ApiResponse(responseCode = "2000"), + @ApiResponse(responseCode = "4003", description = "UNAUTHORIZED, 토큰 모양이 이상함, 토큰 제대로 주세요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4005", description = "UNAUTHORIZED, 엑세스 토큰 만료, 리프레시 토큰 사용", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4008", description = "UNAUTHORIZED, 토큰 없음, 토큰 줘요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4052", description = "BAD_REQUEST, 사용자가 없습니다. 이 api에서 이거 생기면 백앤드 개발자 호출", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "4111", description = "BAD_REQUEST, 해당 임시저장 Id가 존재하지 않습니다.", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + @ApiResponse(responseCode = "5000", description = "SERVER ERROR, 백앤드 개발자에게 알려주세요", content = @Content(schema = @Schema(implementation = ResponseDto.class))), + }) + @Parameters({ + @Parameter(name = "member", hidden = true), + }) + @PostMapping(value = {"/members/recipes/temp/{tempId}", "/members/recipes/temp"}) + public ResponseDto createTempRecipe( + @PathVariable(required = false) Long tempId, + @RequestPart(value = "content") RecipeRequestDto.TempRecipeDto request, + @RequestPart(value = "thumbnail", required = false) MultipartFile thumbnail, + @RequestPart(value = "stepImages", required = false) List stepImages, + @CheckTempMember @AuthMember Member member) throws IOException { + + log.info("사용자가 준 정보 : {}", request.toString()); + + TempRecipe tempRecipe; + + if (tempId==null) + tempRecipe = recipeService.tempCreate(request, thumbnail, stepImages, member); + else + tempRecipe = recipeService.tempUpdate(tempId, request, thumbnail, stepImages, member); + + return ResponseDto.of(RecipeConverter.toTempRecipeStatusDto(tempRecipe)); + } + @Operation(summary = "🍹figma 레시피 상세페이지, 레시피 상세 정보 조회 API 🔑 ✔", description = "레시피 조회 화면 API입니다. 댓글은 처음 10개만 가져오고 나머지는 댓글 page api 드림") @ApiResponses({ @ApiResponse(responseCode = "2000"), diff --git a/src/main/java/zipdabang/server/web/dto/requestDto/MemberRequestDto.java b/src/main/java/zipdabang/server/web/dto/requestDto/MemberRequestDto.java index 8b15759..ed9fd3d 100644 --- a/src/main/java/zipdabang/server/web/dto/requestDto/MemberRequestDto.java +++ b/src/main/java/zipdabang/server/web/dto/requestDto/MemberRequestDto.java @@ -2,12 +2,15 @@ import lombok.Getter; import lombok.Setter; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; import java.util.List; import org.springframework.lang.Nullable; import org.springframework.web.multipart.MultipartFile; +import zipdabang.server.domain.enums.DeregisterType; import zipdabang.server.web.dto.responseDto.MemberResponseDto; public class MemberRequestDto { @@ -150,6 +153,7 @@ public static class IssueTokenDto{ String refreshToken; } +<<<<<<< HEAD @Getter @Setter public static class InqueryDto{ @@ -164,6 +168,12 @@ public static class InqueryDto{ @Nullable List imageList; + @Getter + @Setter + public static class DeregisterDto { + @Enumerated(EnumType.STRING) + private List deregisterTypes; + private String feedback; } } diff --git a/src/main/java/zipdabang/server/web/dto/requestDto/RecipeRequestDto.java b/src/main/java/zipdabang/server/web/dto/requestDto/RecipeRequestDto.java index e814c78..270c928 100644 --- a/src/main/java/zipdabang/server/web/dto/requestDto/RecipeRequestDto.java +++ b/src/main/java/zipdabang/server/web/dto/requestDto/RecipeRequestDto.java @@ -24,6 +24,20 @@ public static class CreateRecipeDto{ List ingredients; } + @Getter @Setter + public static class TempRecipeDto{ + + String thumbnailUrl; + String name; + String time; + String intro; + String recipeTip; + Integer stepCount; + Integer ingredientCount; + List steps; + List ingredients; + } + @Getter public static class NewIngredientDto{ private String ingredientName; @@ -36,6 +50,13 @@ public static class StepDto{ private String description; } + @Getter + public static class TempStepDto{ + private String stepUrl; + private Integer stepNum; + private String description; + } + @Getter public static class createCommentDto { private String comment; diff --git a/src/main/java/zipdabang/server/web/dto/responseDto/RecipeResponseDto.java b/src/main/java/zipdabang/server/web/dto/responseDto/RecipeResponseDto.java index 37ce0c8..19d3d76 100644 --- a/src/main/java/zipdabang/server/web/dto/responseDto/RecipeResponseDto.java +++ b/src/main/java/zipdabang/server/web/dto/responseDto/RecipeResponseDto.java @@ -20,6 +20,15 @@ public static class RecipeStatusDto{ private String calledAt; } + @Builder + @Getter + @AllArgsConstructor(access = AccessLevel.PROTECTED) + @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class TempRecipeStatusDto{ + private Long tempId; + private String calledAt; + } + @Builder @Getter @AllArgsConstructor(access = AccessLevel.PROTECTED)