diff --git a/src/main/java/EatPic/spring/domain/user/controller/UserController.java b/src/main/java/EatPic/spring/domain/user/controller/UserController.java index c17202b..fed1147 100644 --- a/src/main/java/EatPic/spring/domain/user/controller/UserController.java +++ b/src/main/java/EatPic/spring/domain/user/controller/UserController.java @@ -1,44 +1,47 @@ package EatPic.spring.domain.user.controller; +import EatPic.spring.domain.user.converter.UserConverter; import EatPic.spring.domain.user.dto.*; import EatPic.spring.domain.user.dto.request.LoginRequestDTO; import EatPic.spring.domain.user.dto.request.SignupRequestDTO; +import EatPic.spring.domain.user.dto.response.CheckNicknameResponseDTO; import EatPic.spring.domain.user.dto.response.LoginResponseDTO; import EatPic.spring.domain.user.dto.response.SignupResponseDTO; -import EatPic.spring.domain.user.entity.User; -import EatPic.spring.domain.user.service.UserBadgeService; import EatPic.spring.domain.user.service.UserService; import EatPic.spring.global.common.ApiResponse; +import EatPic.spring.global.common.code.status.ErrorStatus; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import jakarta.servlet.http.HttpServletRequest; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.Map; @RestController +@RestControllerAdvice @RequestMapping("/api/auth") @RequiredArgsConstructor public class UserController{ private final UserService userService; - // 회원 가입 요청 + // 이메일 회원 가입 요청 @PostMapping("/signup") @Operation(summary = "이메일 회원가입 요청") - public ResponseEntity signup(@Valid @RequestBody SignupRequestDTO request) { - return ResponseEntity.ok(userService.signup(request)); + public ApiResponse signup(@Valid @RequestBody SignupRequestDTO request) { + return ApiResponse.onSuccess(userService.signup(request)); } + // 이메일 로그인 요청 @PostMapping("/login/email") @Operation(summary = "이메일 로그인 요청") public ApiResponse login(@RequestBody @Valid LoginRequestDTO request) { return ApiResponse.onSuccess(userService.loginUser(request)); } + // 유저 로그인 인증 @GetMapping("/users") @Operation(summary = "유저 내 정보 조회 - 인증 필요", security = { @SecurityRequirement(name = "JWT TOKEN") } @@ -50,16 +53,33 @@ public ApiResponse getMyInfo(HttpServletRequest request) { // 이메일 중복 검사 @GetMapping("/check-email") @Operation(summary = "이메일 중복 검사") - public ResponseEntity> checkEmail(@RequestParam String email) { + public ApiResponse> checkEmail(@RequestParam String email) { boolean isDuplicate = userService.isEmailDuplicate(email); - return ResponseEntity.ok(Map.of("isDuplicate", isDuplicate)); + return ApiResponse.onSuccess(Map.of("isDuplicate", isDuplicate)); } // 유저 아이디 중복 검사 @GetMapping("/check-user-id") @Operation(summary = "유저 아이디 중복 검사") - public ResponseEntity> checkUserId(@RequestParam String nameId) { + public ApiResponse> checkUserId(@RequestParam String nameId) { boolean isDuplicate = userService.isnameIdDuplicate(nameId); - return ResponseEntity.ok(Map.of("isDuplicate", isDuplicate)); + return ApiResponse.onSuccess(Map.of("isDuplicate", isDuplicate)); + } + + // 닉네임 중복 검사 + @GetMapping("/check-nickname") + @Operation(summary = "닉네임 중복 검사") + public ApiResponse checkNickname(@RequestParam String nickname) { + boolean isDuplicate = userService.isNicknameDuplicate(nickname); + + if(isDuplicate) { + return ApiResponse.onFailure( + ErrorStatus.DUPLICATE_NICKNAME.getCode(), + ErrorStatus.DUPLICATE_NICKNAME.getMessage(), + UserConverter.toCheckNicknameResponseDto(nickname, false) + ); + } + + return ApiResponse.onSuccess(UserConverter.toCheckNicknameResponseDto(nickname, true)); } } diff --git a/src/main/java/EatPic/spring/domain/user/converter/UserConverter.java b/src/main/java/EatPic/spring/domain/user/converter/UserConverter.java index b44c76d..ace403c 100644 --- a/src/main/java/EatPic/spring/domain/user/converter/UserConverter.java +++ b/src/main/java/EatPic/spring/domain/user/converter/UserConverter.java @@ -4,6 +4,7 @@ import EatPic.spring.domain.reaction.dto.ReactionResponseDTO; import EatPic.spring.domain.reaction.entity.ReactionType; import EatPic.spring.domain.user.dto.UserInfoDTO; +import EatPic.spring.domain.user.dto.response.CheckNicknameResponseDTO; import EatPic.spring.domain.user.dto.response.LoginResponseDTO; import EatPic.spring.domain.user.dto.response.UserResponseDTO; import EatPic.spring.domain.user.entity.User; @@ -96,4 +97,12 @@ public static UserResponseDTO.UserActionResponseDto toUserActionResponseDto(User .targetUserId(userFollow.getTargetUser().getId()) .build(); } + + // 닉네임 중복 검사 + public static CheckNicknameResponseDTO toCheckNicknameResponseDto(String nickname, boolean isDuplicate) { + return CheckNicknameResponseDTO.builder() + .nickname(nickname) + .isDuplicate(isDuplicate) + .build(); + } } diff --git a/src/main/java/EatPic/spring/domain/user/dto/response/CheckNicknameResponseDTO.java b/src/main/java/EatPic/spring/domain/user/dto/response/CheckNicknameResponseDTO.java new file mode 100644 index 0000000..c19a4e1 --- /dev/null +++ b/src/main/java/EatPic/spring/domain/user/dto/response/CheckNicknameResponseDTO.java @@ -0,0 +1,16 @@ +package EatPic.spring.domain.user.dto.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Builder +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class CheckNicknameResponseDTO { + private String nickname; + private boolean isDuplicate; +} diff --git a/src/main/java/EatPic/spring/domain/user/service/UserService.java b/src/main/java/EatPic/spring/domain/user/service/UserService.java index acfe43a..30af2c7 100644 --- a/src/main/java/EatPic/spring/domain/user/service/UserService.java +++ b/src/main/java/EatPic/spring/domain/user/service/UserService.java @@ -18,6 +18,8 @@ public interface UserService { UserResponseDTO.UserActionResponseDto blockUser(HttpServletRequest request, Long targetUserId); boolean isEmailDuplicate(String email); boolean isnameIdDuplicate(String nameId); + boolean isNicknameDuplicate(String nickname); + // UserQueryService UserInfoDTO getUserInfo(HttpServletRequest request); UserResponseDTO.UserActionResponseDto followUser(HttpServletRequest request, Long targetUserId); diff --git a/src/main/java/EatPic/spring/domain/user/service/UserServiceImpl.java b/src/main/java/EatPic/spring/domain/user/service/UserServiceImpl.java index 5149671..44ad5df 100644 --- a/src/main/java/EatPic/spring/domain/user/service/UserServiceImpl.java +++ b/src/main/java/EatPic/spring/domain/user/service/UserServiceImpl.java @@ -41,7 +41,6 @@ public class UserServiceImpl implements UserService{ private final UserBadgeService userBadgeService; private final PasswordEncoder passwordEncoder; private final JwtTokenProvider jwtTokenProvider; - //private final UserDetailsService userDetailsService; // 회원가입 public SignupResponseDTO signup(SignupRequestDTO request) { @@ -176,6 +175,12 @@ public boolean isnameIdDuplicate(String nameId){ return userRepository.existsByNameId(nameId); } + + // 닉네임 중복 검사 + public boolean isNicknameDuplicate(String nickname) { + return userRepository.existsByNickname(nickname); + } + @Override public User getLoginUser(HttpServletRequest request) { Authentication authentication = jwtTokenProvider.extractAuthentication(request); @@ -213,5 +218,6 @@ public UserResponseDTO.UserActionResponseDto followUser(HttpServletRequest reque userFollowRepository.save(follow); return UserConverter.toUserActionResponseDto(follow); + } } \ No newline at end of file diff --git a/src/main/java/EatPic/spring/global/common/code/status/ErrorStatus.java b/src/main/java/EatPic/spring/global/common/code/status/ErrorStatus.java index cac1e8e..da9e0ac 100644 --- a/src/main/java/EatPic/spring/global/common/code/status/ErrorStatus.java +++ b/src/main/java/EatPic/spring/global/common/code/status/ErrorStatus.java @@ -53,11 +53,14 @@ public enum ErrorStatus implements BaseErrorCode { // 유저 관련 응답 USER_NOT_FOUND(HttpStatus.BAD_REQUEST, "USER_001", "해당 유저는 존재하지 않는 유저입니다."), + MEMBER_NOT_FOUND(HttpStatus.BAD_REQUEST, "USER_002", "사용자가 없습니다."), + INVALID_PASSWORD(HttpStatus.BAD_REQUEST, "USER_003", "비밀번호가 불일치합니다."), + INVALID_TOKEN(HttpStatus.BAD_REQUEST, "USER_004", "유효하지 않은 토큰입니다."), CARD_DELETE_FORBIDDEN(HttpStatus.FORBIDDEN, "USER_005", "해당 카드를 삭제할 권한이 없습니다."), - MEMBER_NOT_FOUND(HttpStatus.BAD_REQUEST, "USER_404", "사용자가 없습니다."), - INVALID_PASSWORD(HttpStatus.BAD_REQUEST, "USER_401", "비밀번호가 불일치합니다."), - INVALID_TOKEN(HttpStatus.BAD_REQUEST, "USER_403", "유효하지 않은 토큰입니다."), - DUPLICATE_JOIN_REQUEST(HttpStatus.BAD_REQUEST, "USER_400", "해당 이메일로 이미 가입된 사용자가 존재합니다."), + DUPLICATE_JOIN_REQUEST(HttpStatus.BAD_REQUEST, "USER_006", "해당 이메일로 이미 가입된 사용자가 존재합니다."), + DUPLICATE_EMAIL(HttpStatus.BAD_REQUEST, "USER_007", "이미 사용중인 이메일입니다."), + DUPLICATE_NAMEID(HttpStatus.BAD_REQUEST, "USER_008", "이미 사용중인 아이디입니다."), + DUPLICATE_NICKNAME(HttpStatus.BAD_REQUEST, "USER_009", "이미 사용중인 닉네임입니다."), // 팔로우 관련 응답 FOLLOW_ALREADY_EXISTS(HttpStatus.BAD_REQUEST, "FOLLOW_001", "이미 팔로잉 중입니다"),