Skip to content

Commit

Permalink
Feat: 회원가입, 아이디 중복체크 API 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
yxhwxn committed Jul 29, 2024
1 parent 6163946 commit 04ebdb0
Show file tree
Hide file tree
Showing 11 changed files with 227 additions and 8 deletions.
44 changes: 44 additions & 0 deletions src/main/java/com/cmc/suppin/member/controller/MemberApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.cmc.suppin.member.controller;

import com.cmc.suppin.global.presentation.ApiResponse;
import com.cmc.suppin.member.controller.dto.MemberRequestDTO;
import com.cmc.suppin.member.controller.dto.MemberResponseDTO;
import com.cmc.suppin.member.converter.MemberConverter;
import com.cmc.suppin.member.domain.Member;
import com.cmc.suppin.member.service.command.MemberCommandService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@RestController
@Slf4j
@RequiredArgsConstructor
@Validated
@Tag(name = "Member", description = "Member 관련 API")
@RequestMapping("/api/members")
public class MemberApi {

private final MemberCommandService memberCommandService;


@PostMapping("/join")
@Operation(summary = "회원가입 API", description = "request 파라미터 : id, password, name, phone, email")
public ApiResponse<MemberResponseDTO.JoinResultDTO> join(@RequestBody @Valid MemberRequestDTO.JoinDTO request) {
Member member = memberCommandService.join(request);

return ApiResponse.onSuccess(MemberConverter.toJoinResultDTO(member));

}

@GetMapping("/checkUserId")
@Operation(summary = "아이디 중복 체크 API", description = "request : userId, response: 중복이면 false, 중복 아니면 true")
public ApiResponse<MemberResponseDTO.IdConfirmResultDTO> checkUserId(@RequestBody MemberRequestDTO.IdConfirmDTO request) {
boolean checkUserId = memberCommandService.confirmUserId(request);

return ApiResponse.onSuccess(MemberConverter.toIdConfirmResultDTO(checkUserId));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.cmc.suppin.member.controller.dto;

import jakarta.persistence.Id;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

public class MemberRequestDTO {

@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class JoinDTO {
@NotBlank(message = "아이디를 입력해주세요")
@Id
private String userId;

@NotBlank(message = "이름을 입력해주세요")
private String name;

@NotBlank(message = "비밀번호를 입력해주세요")
@Pattern(regexp = "(?=.*[0-9])(?=.*[a-zA-Z])(?=.*\\W)(?=\\S+$).{8,16}", message = "비밀번호는 8~16자 영문, 숫자, 특수문자를 사용하세요.")
private String password;

@NotBlank(message = "이메일을 입력해주세요")
@Email(message = "이메일 형식이 올바르지 않습니다.")
private String email;

@NotBlank(message = "휴대폰 번호를 입력해주세요")
private String phone;
}

@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class IdConfirmDTO {
private String userId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.cmc.suppin.member.controller.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

public class MemberResponseDTO {

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class JoinResultDTO {
Long memberId;
String userId;
String name;
String email;
LocalDateTime createdAt;
}

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class IdConfirmResultDTO {
Boolean checkUserId;
}
}
Empty file.
36 changes: 36 additions & 0 deletions src/main/java/com/cmc/suppin/member/converter/MemberConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.cmc.suppin.member.converter;

import com.cmc.suppin.member.controller.dto.MemberRequestDTO;
import com.cmc.suppin.member.controller.dto.MemberResponseDTO;
import com.cmc.suppin.member.domain.Member;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class MemberConverter {

public Member toEntity(MemberRequestDTO.JoinDTO request, BCryptPasswordEncoder encoder) {
return Member.builder()
.userId(request.getUserId())
.name(request.getName())
.password(encoder.encode(request.getPassword()))
.email(request.getEmail())
.phoneNumber(request.getPhone())
.build();
}

public static MemberResponseDTO.JoinResultDTO toJoinResultDTO(Member member) {
return MemberResponseDTO.JoinResultDTO.builder()
.memberId(member.getId())
.userId(member.getUserId())
.name(member.getName())
.email(member.getEmail())
.createdAt(member.getCreatedAt())
.build();
}

public static MemberResponseDTO.IdConfirmResultDTO toIdConfirmResultDTO(boolean checkUserId) {
return MemberResponseDTO.IdConfirmResultDTO.builder()
.checkUserId(checkUserId)
.build();
}

}
15 changes: 9 additions & 6 deletions src/main/java/com/cmc/suppin/member/domain/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
import com.cmc.suppin.event.domain.Event;
import com.cmc.suppin.global.domain.BaseDateTimeEntity;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import lombok.*;
import org.hibernate.annotations.DynamicInsert;

import java.util.ArrayList;
import java.util.List;

@Entity
@Getter
@Setter
@Builder
@DynamicInsert
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Member extends BaseDateTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -21,12 +24,12 @@ public class Member extends BaseDateTimeEntity {
@OneToMany(mappedBy = "member")
private List<Event> eventList = new ArrayList<>();

@Column(columnDefinition = "VARCHAR(30)", nullable = false)
private String userId;

@Column(columnDefinition = "VARCHAR(20)", nullable = false)
private String name;

@Column(columnDefinition = "VARCHAR(30)", nullable = false)
private String nickname;

@Column(columnDefinition = "VARCHAR(30)", nullable = false)
private String email;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

public interface MemberRepository extends JpaRepository<Member, Long> {

Boolean existsByName(String name);
Boolean existsByUserId(String userId);

Member findByName(String name);
Member findByUserId(String userId);
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.cmc.suppin.member.service.command;

import com.cmc.suppin.member.controller.dto.MemberRequestDTO;
import com.cmc.suppin.member.domain.Member;

public interface MemberCommandService {

Member join(MemberRequestDTO.JoinDTO request);

Boolean confirmUserId(MemberRequestDTO.IdConfirmDTO request);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.cmc.suppin.member.service.command;

import com.cmc.suppin.member.controller.dto.MemberRequestDTO;
import com.cmc.suppin.member.converter.MemberConverter;
import com.cmc.suppin.member.domain.Member;
import com.cmc.suppin.member.domain.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
@RequiredArgsConstructor
@Transactional
public class MemberCommandServiceImpl implements MemberCommandService {

private final MemberRepository memberRepository;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final MemberConverter memberConverter;

/**
* 회원가입
*/
@Override
public Member join(MemberRequestDTO.JoinDTO request) {
// 중복된 아이디 체크
if (memberRepository.existsByUserId(request.getUserId())) {
throw new IllegalArgumentException("이미 존재하는 유저입니다.");
}

// DTO를 Entity로 변환
Member member = memberConverter.toEntity(request, bCryptPasswordEncoder);

// 회원 정보 저장
memberRepository.save(member);

return member;
}

/**
* ID 중복 확인
*/
@Override
public Boolean confirmUserId(MemberRequestDTO.IdConfirmDTO request) {
// 아이디 중복 체크
return !memberRepository.existsByUserId(request.getUserId());
}
}
2 changes: 2 additions & 0 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
spring:
server:
port: 8080
datasource:
url: ${DB_URL}
username: ${DB_USER}
Expand Down

0 comments on commit 04ebdb0

Please sign in to comment.