Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eatery 2.1.1 Update #421

Merged
merged 6 commits into from
Jan 4, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,14 @@ public SliceResponse<SearchMembersByKeywordResponse> searchMembersByKeywordV1_1(
summary = "λ‚΄ 정보 μˆ˜μ •",
description = "<p><strong>Latest version: v1.1</strong>" +
"<p>λ‚΄ 정보λ₯Ό μˆ˜μ •ν•©λ‹ˆλ‹€." +
"<p>ν”„λ‘œν•„ μ΄λ―Έμ§€λŠ” μˆ˜μ •ν•˜κ³ μž ν•˜λŠ” κ²½μš°μ—λ§Œ μš”μ²­ν•΄μ•Ό ν•˜κ³ , μˆ˜μ •ν•˜μ§€ μ•ŠλŠ” 경우 μš”μ²­ λ°μ΄ν„°μ—μ„œ μ œμ™Έν•΄μ•Όν•©λ‹ˆλ‹€.",
"<p>ν”„λ‘œν•„ μ΄λ―Έμ§€λŠ” μˆ˜μ •ν•˜κ³ μž ν•˜λŠ” κ²½μš°μ—λ§Œ μš”μ²­ 데이터에 ν¬ν•¨ν•˜κ³ , μˆ˜μ •ν•˜μ§€ μ•ŠλŠ” 경우 μš”μ²­ λ°μ΄ν„°μ—μ„œ μ œμ™Έν•΄μ•Όν•©λ‹ˆλ‹€.",
security = @SecurityRequirement(name = "access-token")
)
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "409", description = "이미 μ‚¬μš©μ€‘μΈ λ‹‰λ„€μž„μΈ 경우"),
@ApiResponse(responseCode = "422", description = "μœ νš¨ν•˜μ§€ μ•Šμ€ λ‹‰λ„€μž„μΈ 경우.", content = @Content)
})
@PutMapping(value = "/v1/members", headers = API_MINOR_VERSION_HEADER_NAME + "=1", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public MemberResponse updateMemberV1_1(
@AuthenticationPrincipal UserPrincipal userPrincipal,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public static MemberDto from(Member entity) {
}

public Member toEntity() {
return Member.of(
return Member.create(
this.getProfileImageUrl(),
this.getProfileThumbnailImageUrl(),
this.getSocialUid(),
Expand All @@ -72,4 +72,8 @@ public Member toEntity() {
this.getGender()
);
}

public void setNickname(String nickname) {
this.nickname = nickname;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,5 @@ public class MemberUpdateRequest {
private Gender gender;

@Schema(description = "λ³€κ²½ν•˜κ³ μž ν•˜λŠ” ν”„λ‘œν•„ 이미지")
@NotNull
private MultipartFile profileImage;
}
107 changes: 52 additions & 55 deletions src/main/java/com/zelusik/eatery/domain/member/entity/Member.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package com.zelusik.eatery.domain.member.entity;

import com.zelusik.eatery.domain.favorite_food_category.entity.FavoriteFoodCategory;
import com.zelusik.eatery.domain.member.constant.Gender;
import com.zelusik.eatery.domain.member.constant.LoginType;
import com.zelusik.eatery.domain.member.constant.RoleType;
import com.zelusik.eatery.domain.member.converter.RoleTypesConverter;
import com.zelusik.eatery.global.common.entity.BaseTimeEntity;
import com.zelusik.eatery.domain.favorite_food_category.entity.FavoriteFoodCategory;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.LinkedList;
Expand All @@ -35,81 +36,59 @@ public class Member extends BaseTimeEntity {
@Column(name = "member_id", nullable = false)
private Long id;

@Setter(AccessLevel.PRIVATE)
@Column(nullable = false)
@NotBlank
private String profileImageUrl;

@Setter(AccessLevel.PRIVATE)
@Column(nullable = false)
@NotBlank
private String profileThumbnailImageUrl;

@Column(nullable = false, unique = true)
@NotBlank
@Column(unique = true)
private String socialUid;

@Column(nullable = false)
@NotNull
@Enumerated(EnumType.STRING)
private LoginType loginType;

@Column(nullable = false)
@NotEmpty
@Convert(converter = RoleTypesConverter.class)
private Set<RoleType> roleTypes;

private String email;

@Setter(AccessLevel.PRIVATE)
@Column(nullable = false, length = 15)
private String nickname;
@NotNull
@Embedded
private MemberNickname nickname;

@Setter(AccessLevel.PRIVATE)
private LocalDate birthDay;

private Integer ageRange;

@Setter(AccessLevel.PRIVATE)
@NotNull
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private Gender gender;

@OneToMany(mappedBy = "member")
private List<FavoriteFoodCategory> favoriteFoodCategories = new LinkedList<>();

@Setter(AccessLevel.PRIVATE)
private LocalDateTime deletedAt;

public static Member of(
@NonNull String profileImageUrl,
@NonNull String profileThumbnailImageUrl,
@NonNull String socialUid,
@NonNull LoginType loginType,
@NonNull Set<RoleType> roleTypes,
@Nullable String email,
@NonNull String nickname,
@Nullable Integer ageRange,
@Nullable Gender gender
) {
return of(null, profileImageUrl, profileThumbnailImageUrl, socialUid, loginType, roleTypes, email, nickname, null, ageRange, gender, null, null, null);
}
@OneToMany(mappedBy = "member")
private List<FavoriteFoodCategory> favoriteFoodCategories = new LinkedList<>();

public static Member of(
public Member(
@Nullable Long id,
@NonNull String profileImageUrl,
@NonNull String profileThumbnailImageUrl,
@NonNull String socialUid,
@NonNull LoginType loginType,
@NonNull Set<RoleType> roleTypes,
@NotNull String profileImageUrl,
@NotNull String profileThumbnailImageUrl,
@NotNull String socialUid,
@NotNull LoginType loginType,
@NotNull Set<RoleType> roleTypes,
@Nullable String email,
@NonNull String nickname,
@NotNull String nickname,
@Nullable LocalDate birthDay,
@Nullable Integer ageRange,
@Nullable Gender gender,
@Nullable LocalDateTime createdAt,
@Nullable LocalDateTime updatedAt,
@Nullable LocalDateTime deletedAt
) {
return new Member(id, profileImageUrl, profileThumbnailImageUrl, socialUid, loginType, roleTypes, email, nickname, birthDay, ageRange, gender, createdAt, updatedAt, deletedAt);
}

private Member(@Nullable Long id, @NonNull String profileImageUrl, @NonNull String profileThumbnailImageUrl, @NonNull String socialUid, @NonNull LoginType loginType, @NonNull Set<RoleType> roleTypes, @Nullable String email, @NonNull String nickname, @Nullable LocalDate birthDay, @Nullable Integer ageRange, @Nullable Gender gender, @Nullable LocalDateTime createdAt, @Nullable LocalDateTime updatedAt, @Nullable LocalDateTime deletedAt) {
super(createdAt, updatedAt);
this.id = id;
this.profileImageUrl = profileImageUrl;
Expand All @@ -118,32 +97,50 @@ private Member(@Nullable Long id, @NonNull String profileImageUrl, @NonNull Stri
this.loginType = loginType;
this.roleTypes = roleTypes;
this.email = email;
this.nickname = nickname;
this.nickname = new MemberNickname(nickname);
this.birthDay = birthDay;
this.ageRange = ageRange;
this.gender = gender;
this.deletedAt = deletedAt;
}

public static Member create(
@NotNull String profileImageUrl,
@NotNull String profileThumbnailImageUrl,
@NotNull String socialUid,
@NotNull LoginType loginType,
@NotNull Set<RoleType> roleTypes,
@Nullable String email,
@NotNull String nickname,
@Nullable Integer ageRange,
@Nullable Gender gender
) {
return new Member(null, profileImageUrl, profileThumbnailImageUrl, socialUid, loginType, roleTypes, email, nickname, null, ageRange, gender, null, null, null);
}

public String getNickname() {
return nickname.getNickname();
}

public void update(String profileImageUrl, String profileThumbnailImageUrl, String nickname, LocalDate birthDay, Gender gender) {
this.setProfileImageUrl(profileImageUrl);
this.setProfileThumbnailImageUrl(profileThumbnailImageUrl);
this.setNickname(nickname);
this.setBirthDay(birthDay);
this.setGender(gender);
this.profileImageUrl = profileImageUrl;
this.profileThumbnailImageUrl = profileThumbnailImageUrl;
this.nickname = new MemberNickname(nickname);
this.birthDay = birthDay;
this.gender = gender;
}

public void update(String nickname, LocalDate birthDay, Gender gender) {
this.setNickname(nickname);
this.setBirthDay(birthDay);
this.setGender(gender);
this.nickname = new MemberNickname(nickname);
this.birthDay = birthDay;
this.gender = gender;
}

public void rejoin() {
this.setDeletedAt(null);
this.deletedAt = null;
}

public void softDelete() {
this.setDeletedAt(LocalDateTime.now());
this.deletedAt = LocalDateTime.now();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.zelusik.eatery.domain.member.entity;

import com.zelusik.eatery.domain.member.exception.InvalidNicknameException;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.validation.constraints.NotBlank;
import java.util.Objects;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@Embeddable
public class MemberNickname {


private static final int MEMBER_NICKNAME_MIN_LEN = 2;
private static final int MEMBER_NICKNAME_MAX_LEN = 15;

@NotBlank
@Column(nullable = false, length = 15)
String nickname;

public MemberNickname(String nickname) {
validateNickname(nickname);
this.nickname = nickname;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o instanceof String that) {
return this.getNickname().equals(that);
}
if (o instanceof MemberNickname that) {
return this.getNickname().equals(that.getNickname());
}
return false;
}

@Override
public int hashCode() {
return Objects.hash(getNickname());
}

private static void validateNickname(String nickname) {
int nicknameLength = nickname.length();
if (nicknameLength < MEMBER_NICKNAME_MIN_LEN || nicknameLength > MEMBER_NICKNAME_MAX_LEN) {
throw new InvalidNicknameException(String.format("%dκΈ€μž 이상, %dκΈ€μž μ΄ν•˜μ˜ λ‹‰λ„€μž„μ„ μž…λ ₯ν•΄μ£Όμ„Έμš”.", MEMBER_NICKNAME_MIN_LEN, MEMBER_NICKNAME_MAX_LEN));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.zelusik.eatery.domain.member.exception;

import com.zelusik.eatery.global.common.exception.UnprocessableEntityException;
import com.zelusik.eatery.global.exception.constant.CustomExceptionType;

public class InvalidNicknameException extends UnprocessableEntityException {

public InvalidNicknameException(String optionalMessage) {
super(CustomExceptionType.INVALID_NICKNAME, optionalMessage);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.zelusik.eatery.domain.member.exception;

import com.zelusik.eatery.global.common.exception.ConflictException;
import com.zelusik.eatery.global.exception.constant.CustomExceptionType;

public class NicknameDuplicationException extends ConflictException {

public NicknameDuplicationException() {
super(CustomExceptionType.NICKNAME_DUPLICATION);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryQCustom {

boolean existsByNickname(String nickname);

Optional<Member> findByIdAndDeletedAtNull(Long memberId);

Optional<Member> findBySocialUid(String socialUid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.StringExpression;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.zelusik.eatery.domain.member.entity.QMember;
import com.zelusik.eatery.global.common.constant.FoodCategoryValue;
import com.zelusik.eatery.domain.review.constant.ReviewKeywordValue;
import com.zelusik.eatery.domain.member.entity.Member;
import com.zelusik.eatery.domain.member.dto.MemberWithProfileInfoDto;
import com.zelusik.eatery.domain.member.entity.Member;
import com.zelusik.eatery.domain.member.entity.QMember;
import com.zelusik.eatery.domain.member.exception.MemberNotFoundByIdException;
import com.zelusik.eatery.domain.review.constant.ReviewKeywordValue;
import com.zelusik.eatery.global.common.constant.FoodCategoryValue;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
Expand Down Expand Up @@ -120,7 +120,7 @@ private FoodCategoryValue getMostEatenFoodCategory(long memberId) {
@Override
public Slice<Member> searchByKeyword(String searchKeyword, Pageable pageable) {
List<Member> content = queryFactory.selectFrom(member)
.where(isMemberNotDeleted(), member.nickname.containsIgnoreCase(searchKeyword))
.where(isMemberNotDeleted(), member.nickname.nickname.containsIgnoreCase(searchKeyword))
.offset(pageable.getOffset())
.limit(pageable.getPageSize() + 1)
.fetch();
Expand Down
Loading
Loading