Skip to content

Commit

Permalink
[MERGE] Merge pull request #131 from Team-WSS/feat/#111
Browse files Browse the repository at this point in the history
[FEAT] 본인 프로필 수정 기능 구현
  • Loading branch information
Kim-TaeUk authored Aug 8, 2024
2 parents 5dd8d0b + fae1938 commit 8b3ffd0
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 12 deletions.
11 changes: 11 additions & 0 deletions src/main/java/org/websoso/WSSServer/controller/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.websoso.WSSServer.dto.user.ProfileGetResponse;
import org.websoso.WSSServer.dto.user.ProfileStatusResponse;
import org.websoso.WSSServer.dto.user.RegisterUserInfoRequest;
import org.websoso.WSSServer.dto.user.UpdateMyProfileRequest;
import org.websoso.WSSServer.dto.user.UserNovelCountGetResponse;
import org.websoso.WSSServer.service.UserNovelService;
import org.websoso.WSSServer.service.UserService;
Expand Down Expand Up @@ -92,6 +93,16 @@ public ResponseEntity<MyProfileResponse> getMyProfileInfo(Principal principal) {
.body(userService.getMyProfileInfo(user));
}

@PatchMapping("/my-profile")
public ResponseEntity<Void> updateMyProfileInfo(Principal principal,
@RequestBody @Valid UpdateMyProfileRequest updateMyProfileRequest) {
User user = userService.getUserOrException(Long.valueOf(principal.getName()));
userService.updateMyProfileInfo(user, updateMyProfileRequest);
return ResponseEntity
.status(NO_CONTENT)
.build();
}

@GetMapping("/profile/{userId}")
public ResponseEntity<ProfileGetResponse> getProfileInfo(Principal principal,
@PathVariable("userId") Long userId) {
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/org/websoso/WSSServer/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.websoso.WSSServer.domain.common.Gender;
import org.websoso.WSSServer.domain.common.Role;
import org.websoso.WSSServer.dto.user.RegisterUserInfoRequest;
import org.websoso.WSSServer.dto.user.UpdateMyProfileRequest;
import org.websoso.WSSServer.dto.user.UserBasicInfo;

@Entity
Expand Down Expand Up @@ -67,6 +68,18 @@ public void updateProfileStatus(Boolean profileStatus) {
this.isProfilePublic = profileStatus;
}

public void updateUserProfile(UpdateMyProfileRequest updateMyProfileRequest) {
if (updateMyProfileRequest.avatarId() != null) {
this.avatarId = updateMyProfileRequest.avatarId();
}
if (updateMyProfileRequest.nickname() != null) {
this.nickname = updateMyProfileRequest.nickname();
}
if (updateMyProfileRequest.intro() != null) {
this.intro = updateMyProfileRequest.intro();
}
}

public void updateUserInfo(RegisterUserInfoRequest registerUserInfoRequest) {
this.nickname = registerUserInfoRequest.nickname();
this.gender = Gender.valueOf(registerUserInfoRequest.gender());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.websoso.WSSServer.dto.user;

import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.util.List;
import org.websoso.WSSServer.validation.NullAllowedNicknameConstraint;

public record UpdateMyProfileRequest(
Byte avatarId,

@NullAllowedNicknameConstraint
String nickname,

@Size(max = 60, message = "소개글은 60자를 초과할 수 없습니다.")
String intro,

@NotNull(message = "선호 장르는 null일 수 없습니다.")
List<String> genrePreferences
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ public enum CustomUserError implements ICustomError {
INVALID_GENDER("USER-011", "성별은 M 또는 F여야 합니다.", BAD_REQUEST),
INVALID_GENDER_NULL("USER-012", "성별은 null일 수 없습니다.", BAD_REQUEST),
INVALID_GENDER_BLANK("USER-013", "성별은 빈칸일 수 없습니다.", BAD_REQUEST),
ALREADY_SET_NICKNAME("USER-014", "닉네임은 이미 설정된 닉네임과 동일합니다.", BAD_REQUEST);
ALREADY_SET_NICKNAME("USER-014", "닉네임은 이미 설정된 닉네임과 동일합니다.", BAD_REQUEST),
ALREADY_SET_AVATAR("USER-015", "아바타는 이미 설정된 아바타와 동일합니다.", BAD_REQUEST),
ALREADY_SET_INTRO("USER-016", "소개글은 이미 설정된 소개글과 동일합니다.", BAD_REQUEST);

private final String code;
private final String description;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@
public interface GenrePreferenceRepository extends JpaRepository<GenrePreference, Long> {

List<GenrePreference> findByUser(User user);

void deleteAllByUser(User user);
}
50 changes: 39 additions & 11 deletions src/main/java/org/websoso/WSSServer/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import static org.websoso.WSSServer.exception.error.CustomAvatarError.AVATAR_NOT_FOUND;
import static org.websoso.WSSServer.exception.error.CustomGenreError.GENRE_NOT_FOUND;
import static org.websoso.WSSServer.exception.error.CustomUserError.ALREADY_SET_AVATAR;
import static org.websoso.WSSServer.exception.error.CustomUserError.ALREADY_SET_INTRO;
import static org.websoso.WSSServer.exception.error.CustomUserError.ALREADY_SET_NICKNAME;
import static org.websoso.WSSServer.exception.error.CustomUserError.ALREADY_SET_PROFILE_STATUS;
import static org.websoso.WSSServer.exception.error.CustomUserError.DUPLICATED_NICKNAME;
Expand All @@ -25,6 +27,8 @@
import org.websoso.WSSServer.dto.user.ProfileGetResponse;
import org.websoso.WSSServer.dto.user.ProfileStatusResponse;
import org.websoso.WSSServer.dto.user.RegisterUserInfoRequest;
import org.websoso.WSSServer.dto.user.UpdateMyProfileRequest;
import org.websoso.WSSServer.exception.error.CustomUserError;
import org.websoso.WSSServer.exception.exception.CustomAvatarException;
import org.websoso.WSSServer.exception.exception.CustomGenreException;
import org.websoso.WSSServer.exception.exception.CustomUserException;
Expand All @@ -46,12 +50,10 @@ public class UserService {

@Transactional(readOnly = true)
public NicknameValidation isNicknameAvailable(User user, String nickname) {
if (user.getNickname() != null && user.getNickname().equals(nickname)) {
throw new CustomUserException(ALREADY_SET_NICKNAME, "nickname with given is already set");
}
if (userRepository.existsByNickname(nickname)) {
throw new CustomUserException(DUPLICATED_NICKNAME, "nickname is duplicated.");
}
checkIfAlreadySetOrThrow(user.getNickname(), nickname,
ALREADY_SET_NICKNAME, "nickname with given is already set");
checkNicknameIfAlreadyExist(nickname);

return NicknameValidation.of(true);
}

Expand All @@ -76,9 +78,9 @@ public ProfileStatusResponse getProfileStatus(User user) {
}

public void editProfileStatus(User user, EditProfileStatusRequest editProfileStatusRequest) {
if (user.getIsProfilePublic().equals(editProfileStatusRequest.isProfilePublic())) {
throw new CustomUserException(ALREADY_SET_PROFILE_STATUS, "profile status with given is already set");
}
checkIfAlreadySetOrThrow(user.getIsProfilePublic(), editProfileStatusRequest.isProfilePublic(),
ALREADY_SET_PROFILE_STATUS, "profile status with given is already set");

user.updateProfileStatus(editProfileStatusRequest.isProfilePublic());
}

Expand All @@ -96,6 +98,25 @@ public MyProfileResponse getMyProfileInfo(User user) {
return MyProfileResponse.of(user, avatar, genrePreferences);
}

public void updateMyProfileInfo(User user, UpdateMyProfileRequest updateMyProfileRequest) {
checkIfAlreadySetOrThrow(user.getAvatarId(), updateMyProfileRequest.avatarId(),
ALREADY_SET_AVATAR, "avatarId with given is already set");

checkIfAlreadySetOrThrow(user.getNickname(), updateMyProfileRequest.nickname(),
ALREADY_SET_NICKNAME, "nickname with given is already set");
checkNicknameIfAlreadyExist(updateMyProfileRequest.nickname());

checkIfAlreadySetOrThrow(user.getIntro(), updateMyProfileRequest.intro(),
ALREADY_SET_INTRO, "intro with given is already set");

genrePreferenceRepository.deleteAllByUser(user);

List<GenrePreference> newPreferGenres = createGenrePreferences(user, updateMyProfileRequest.genrePreferences());
genrePreferenceRepository.saveAll(newPreferGenres);

user.updateUserProfile(updateMyProfileRequest);
}

@Transactional(readOnly = true)
public ProfileGetResponse getProfileInfo(User visitor, Long ownerId) {
User owner = getUserOrException(ownerId);
Expand All @@ -114,18 +135,25 @@ private Avatar findAvatarByIdOrThrow(Byte avatarId) {
}

public void registerUserInfo(User user, RegisterUserInfoRequest registerUserInfoRequest) {
validateNickname(registerUserInfoRequest.nickname());
checkNicknameIfAlreadyExist(registerUserInfoRequest.nickname());
user.updateUserInfo(registerUserInfoRequest);
List<GenrePreference> preferGenres = createGenrePreferences(user, registerUserInfoRequest.genrePreferences());
genrePreferenceRepository.saveAll(preferGenres);
}

private void validateNickname(String nickname) {
private void checkNicknameIfAlreadyExist(String nickname) {
if (userRepository.existsByNickname(nickname)) {
throw new CustomUserException(DUPLICATED_NICKNAME, "nickname is duplicated.");
}
}

private <T> void checkIfAlreadySetOrThrow(T currentValue, T newValue,
CustomUserError customUserError, String message) {
if (newValue != null && newValue.equals(currentValue)) {
throw new CustomUserException(customUserError, message);
}
}

private List<GenrePreference> createGenrePreferences(User user, List<String> genreNames) {
return genreNames
.stream()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.websoso.WSSServer.validation;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Documented
@Constraint(validatedBy = NullAllowedNicknameValidator.class)
@Target({PARAMETER, FIELD})
@Retention(RUNTIME)
public @interface NullAllowedNicknameConstraint {

String message() default "invalid nickname";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.websoso.WSSServer.validation;

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class NullAllowedNicknameValidator implements ConstraintValidator<NullAllowedNicknameConstraint, String> {

private final NicknameValidator nicknameValidator;

@Override
public void initialize(NullAllowedNicknameConstraint nickname) {
}

@Override
public boolean isValid(String nickname, ConstraintValidatorContext constraintValidatorContext) {
if (nickname == null) {
return true;
}
return nicknameValidator.isValid(nickname, constraintValidatorContext);
}
}

0 comments on commit 8b3ffd0

Please sign in to comment.