diff --git a/src/main/java/com/example/spot/api/code/status/SuccessStatus.java b/src/main/java/com/example/spot/api/code/status/SuccessStatus.java index b68a066f..cd5bcb9f 100644 --- a/src/main/java/com/example/spot/api/code/status/SuccessStatus.java +++ b/src/main/java/com/example/spot/api/code/status/SuccessStatus.java @@ -32,6 +32,7 @@ public enum SuccessStatus implements BaseCode { _MEMBER_EMAIL_CHECK_COMPLETED(HttpStatus.OK, "MEMBER2013", "회원 이메일 사용 가능 여부 조회 완료"), _RSA_PUBLIC_KEY_FOUND(HttpStatus.OK, "MEMBER2014", "RSA Public Key 조회 완료"), _MEMBER_SIGNUP_CHECK_COMPLETED(HttpStatus.OK, "MEMBER2015", "회원 가입 유무 조회 완료"), + _MEMBER_NICKNAME_CHECK_COMPLETED(HttpStatus.NO_CONTENT, "MEMBER2016", "회원 닉네임 사용 가능 여부 조회 완료"), //스터디 게시글 관련 응답 _STUDY_POST_CREATED(HttpStatus.CREATED, "STUDYPOST3001", "스터디 게시글 작성 완료"), diff --git a/src/main/java/com/example/spot/repository/MemberRepository.java b/src/main/java/com/example/spot/repository/MemberRepository.java index c1f8fea2..9e4d6edd 100644 --- a/src/main/java/com/example/spot/repository/MemberRepository.java +++ b/src/main/java/com/example/spot/repository/MemberRepository.java @@ -15,6 +15,8 @@ public interface MemberRepository extends JpaRepository { boolean existsByEmail(String email); + boolean existsByNickname(String nickname); + Optional findByEmail(String email); Optional findByLoginId(String loginId); diff --git a/src/main/java/com/example/spot/service/auth/AuthService.java b/src/main/java/com/example/spot/service/auth/AuthService.java index 24574d02..174e8e3c 100644 --- a/src/main/java/com/example/spot/service/auth/AuthService.java +++ b/src/main/java/com/example/spot/service/auth/AuthService.java @@ -1,5 +1,6 @@ package com.example.spot.service.auth; +import com.example.spot.web.dto.member.MemberRequestDTO.SignUpDetailDTO; import com.example.spot.web.dto.rsa.Rsa; import com.example.spot.web.dto.member.MemberRequestDTO; import com.example.spot.web.dto.member.MemberResponseDTO; @@ -16,7 +17,7 @@ public interface AuthService { // 리프레시 토큰을 사용하여 새로운 액세스 토큰을 발급 TokenDTO reissueToken(String refreshToken); - MemberResponseDTO.MemberInfoCreationDTO signUpAndPartialUpdate(String nickname, Boolean personalInfo, Boolean idInfo); + MemberResponseDTO.MemberInfoCreationDTO signUpAndPartialUpdate(SignUpDetailDTO sign); MemberResponseDTO.InactiveMemberDTO withdraw(); @@ -45,4 +46,6 @@ public interface AuthService { MemberResponseDTO.AvailabilityDTO checkEmailAvailability(String email); MemberResponseDTO.CheckMemberDTO checkIsSpotMember(Long loginId); + + MemberResponseDTO.NicknameDuplicateDTO checkNicknameAvailability(String nickname); } diff --git a/src/main/java/com/example/spot/service/auth/AuthServiceImpl.java b/src/main/java/com/example/spot/service/auth/AuthServiceImpl.java index bc21b495..d82c7617 100644 --- a/src/main/java/com/example/spot/service/auth/AuthServiceImpl.java +++ b/src/main/java/com/example/spot/service/auth/AuthServiceImpl.java @@ -10,7 +10,9 @@ import com.example.spot.repository.MemberThemeRepository; import com.example.spot.repository.PreferredRegionRepository; import com.example.spot.repository.StudyReasonRepository; +import com.example.spot.web.dto.member.MemberRequestDTO.SignUpDetailDTO; import com.example.spot.web.dto.member.MemberResponseDTO.CheckMemberDTO; +import com.example.spot.web.dto.member.MemberResponseDTO.NicknameDuplicateDTO; import com.example.spot.web.dto.rsa.Rsa; import com.example.spot.domain.auth.RefreshToken; import com.example.spot.domain.auth.VerificationCode; @@ -137,15 +139,15 @@ public TokenDTO reissueToken(String refreshToken) { /* ----------------------------- 공통 회원 관리 API ------------------------------------- */ @Override - public MemberResponseDTO.MemberInfoCreationDTO signUpAndPartialUpdate(String nickname, Boolean personalInfo, Boolean idInfo) { + public MemberResponseDTO.MemberInfoCreationDTO signUpAndPartialUpdate(SignUpDetailDTO request) { // Authorization Long memberId = SecurityUtils.getCurrentUserId(); Member member = memberRepository.findById(memberId) .orElseThrow(() -> new GeneralException(ErrorStatus._MEMBER_NOT_FOUND)); - member.setNickname(nickname); - member.updateTerm(personalInfo, idInfo); + member.setNickname(request.getNickname()); + member.updateTerm(request.getPersonalInfo(), request.getIdInfo()); member = memberRepository.save(member); return MemberResponseDTO.MemberInfoCreationDTO.toDTO(member); @@ -681,6 +683,12 @@ public CheckMemberDTO checkIsSpotMember(Long loginId) { return CheckMemberDTO.toDTO(memberExistsByCheckList); } + @Override + public NicknameDuplicateDTO checkNicknameAvailability(String nickname) { + boolean isDuplicate = memberRepository.existsByNickname(nickname); + return new NicknameDuplicateDTO(nickname, isDuplicate); + } + /** * 임시 비밀번호를 발급하는 메서드입니다. * 알파벳 대소문자, 숫자, 특수기호를 혼합하여 13자리 비밀번호를 생성합니다. diff --git a/src/main/java/com/example/spot/web/controller/AuthController.java b/src/main/java/com/example/spot/web/controller/AuthController.java index a1677450..daa692f0 100644 --- a/src/main/java/com/example/spot/web/controller/AuthController.java +++ b/src/main/java/com/example/spot/web/controller/AuthController.java @@ -3,6 +3,7 @@ import com.example.spot.api.ApiResponse; import com.example.spot.api.code.status.SuccessStatus; import com.example.spot.security.utils.SecurityUtils; +import com.example.spot.web.dto.member.MemberResponseDTO.NicknameDuplicateDTO; import com.example.spot.web.dto.rsa.Rsa; import com.example.spot.service.auth.AuthService; import com.example.spot.validation.annotation.TextLength; @@ -49,6 +50,23 @@ public ApiResponse reissueToken(HttpServletRequest request, /* ----------------------------- 공통 회원 관리 API ------------------------------------- */ + // 닉네임 중복 확인 + @Tag(name = "회원 관리 API - 개발 완료", description = "회원 관리 API") + @Operation(summary = "[공통 회원 관리] 닉네임 중복 확인 API", + description = """ + ## [공통 회원 관리] 닉네임 중복 확인 API입니다. + * Request Params : String nickname + * Response Body : Boolean isAvailable + + 중복된 이메일이 존재하면 duplicate 필드가 true로 설정됩니다. + """) + @GetMapping("/check/nickname") + public ApiResponse checkNicknameAvailability( + @RequestParam @TextLength(max = 8) String nickname) { + NicknameDuplicateDTO nicknameDuplicateDTO = authService.checkNicknameAvailability(nickname); + return ApiResponse.onSuccess(SuccessStatus._MEMBER_NICKNAME_CHECK_COMPLETED, nicknameDuplicateDTO); + } + @Tag(name = "회원 관리 API - 개발 완료", description = "회원 관리 API") @Operation(summary = "[공통 회원 관리] 닉네임 생성 및 약관 동의 API", description = """ @@ -59,10 +77,8 @@ public ApiResponse reissueToken(HttpServletRequest request, """) @PostMapping("/sign-up/update") public ApiResponse signUpAndPartialUpdate( - @RequestParam @TextLength(max = 8) String nickname, - @RequestParam Boolean personalInfo, - @RequestParam Boolean idInfo) { - MemberResponseDTO.MemberInfoCreationDTO memberInfoCreationDTO = authService.signUpAndPartialUpdate(nickname, personalInfo, idInfo); + @RequestBody MemberRequestDTO.SignUpDetailDTO signUpDetailDTO) { + MemberResponseDTO.MemberInfoCreationDTO memberInfoCreationDTO = authService.signUpAndPartialUpdate(signUpDetailDTO); return ApiResponse.onSuccess(SuccessStatus._MEMBER_UPDATED, memberInfoCreationDTO); } diff --git a/src/main/java/com/example/spot/web/dto/member/MemberRequestDTO.java b/src/main/java/com/example/spot/web/dto/member/MemberRequestDTO.java index 4a8580ca..0684cf3e 100644 --- a/src/main/java/com/example/spot/web/dto/member/MemberRequestDTO.java +++ b/src/main/java/com/example/spot/web/dto/member/MemberRequestDTO.java @@ -22,6 +22,14 @@ public static class SignInDTO { private final String password; } + @Getter + @RequiredArgsConstructor + public static class SignUpDetailDTO { + String nickname; + Boolean personalInfo; + Boolean idInfo; + } + @Getter @Builder @RequiredArgsConstructor diff --git a/src/main/java/com/example/spot/web/dto/member/MemberResponseDTO.java b/src/main/java/com/example/spot/web/dto/member/MemberResponseDTO.java index 368299ed..bbd5ae89 100644 --- a/src/main/java/com/example/spot/web/dto/member/MemberResponseDTO.java +++ b/src/main/java/com/example/spot/web/dto/member/MemberResponseDTO.java @@ -218,5 +218,16 @@ public static InactiveMemberDTO toDTO(Member member) { } } + @Getter + public static class NicknameDuplicateDTO { + private final String nickname; + private final boolean isDuplicate; + + public NicknameDuplicateDTO(String nickname, boolean isDuplicate) { + this.nickname = nickname; + this.isDuplicate = isDuplicate; + } + } + }