2024. 5. 26. 17:50ㆍProject/Naver Cafe
카페 회원이 자신의 정보를 수정할 수 있는 기능을 구현한다. 회원정보 수정을 요청하면 수정할 정보를 입력할 수 있는 수정 양식이 사용자에게 전달되고 사용자가 확인(적용)을 누르면 해당 정보가 DB에 반영되는 기능이 될 것이다.
CafeMember
package CloneCoding.NaverCafe.domain.cafeMember;
import static CloneCoding.NaverCafe.domain.cafeMember.enums.CafeMemberPosition.*;
@Entity
@Table(name = "CAFE_MEMBER", uniqueConstraints = {
@UniqueConstraint(
name = "ACCOUNT_ID_UNIQUE",
columnNames = {"CAFE_ID", "ACCOUNT_ID"}
),
@UniqueConstraint(
name = "USERNAME_UNIQUE",
columnNames = {"CAFE_ID", "NICKNAME"}
)})
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class CafeMember {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@Column(name = "ACCOUNT_ID")
private String accountId;
@Column(name = "NICKNAME")
private String nickname;
@Column(name = "PROFILE_IMAGE")
@Builder.Default
private String profileImage = "default_image";
@Column(name = "DESCRIPTION")
@Builder.Default
private String description = "자기소개를 입력해주세요";
@Column(name = "GENDER_AGE_OPEN")
@Builder.Default
private boolean genderAgeOpen = true;
@Column(name = "MY_BLOG_OPEN")
@Builder.Default
private boolean myBlogOpen = false;
@Column(name = "POPULAR_MEMBER_PUSH")
@Builder.Default
private boolean popularMemberPush = true;
@Column(name = "GENDER")
private String gender;
@Column(name = "BIRTHDAY")
private LocalDate birthday;
@Column(name = "POSITION")
@Builder.Default
private String position = CAFE_MEMBER.name();
@Column(name = "GRADE")
@Builder.Default
private String grade = "-";
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CAFE_ID")
private Cafe cafeId;
public void update(RequestUpdateCafeMember request) {
this.profileImage = request.getProfileImage();
if (!request.getNickname().isEmpty()) {
this.nickname = request.getNickname();
}
this.description = request.getDescription();
this.genderAgeOpen = request.isOpenSetting();
this.myBlogOpen = request.isMyBlogOpen();
this.popularMemberPush = request.isPopularMemberPush();
}
}
카페 회원 엔티티 클래스이다. 카페 회원을 DB에 저장할 때 필요한 정보들을 가지고 있다. 특이사항으로는 해당 클래스와 매핑된 테이블은 CAFE 테이블과 ManyToOne 연관관계를 가지는데 덕분에 카페 별로 계정ID, 별명에 대해 중복을 방지하려면 복합키를 사용해 유니크 설정을해 줄 필요가 있었다. @Table의 uniqueConstraints에 @UniqueConstraint으로 유니크키(들)을 설정해준다. 결과적으로 cafeId와 accountId(or nickname) 둘 모두 같은 레코드가 있다면 DB 반영을 막고 없다면 반영하는 식의 유니크 설정이 적용되었다.
- update() : CafeMember 객체를 전달받은 request 정보로 수정하는 메서드
ResponseUpdateForm
package CloneCoding.NaverCafe.domain.cafeMember.dto;
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ResponseUpdateForm {
private String profileImage;
private String nickname;
private String description;
private boolean genderAgeOpen;
private boolean myBlogOpen;
private boolean popularMemberPush;
}
사용자가 회원정보를 양식을 통해 수정할 때 제공될 데이터를 전달하는 DTO이다. 기존 카페 회원의 프로필 이미지, 별명, 자기소개, 각종 설정을 전달한다. 사용자는 수정하기 전 자신의 현재 정보를 확인할 수 있을 것이다.
RequestUpdateCafeMember
package CloneCoding.NaverCafe.domain.cafeMember.dto;
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class RequestUpdateCafeMember {
@NotNull
private String profileImage;
@NotNull
@Size(min = 2, max = 20, message = "별명은 2 ~ 20자로 제한됩니다.")
@Pattern(regexp = "^[a-zA-Z0-9]+", message = "별명은 영소문자, 영대문자, 숫자만 입력 가능합니다.")
private String nickname;
@NotNull
private String description;
@NotNull
private boolean openSetting;
@NotNull
private boolean myBlogOpen;
@NotNull
private boolean popularMemberPush;
}
사용자는 수정양식에 따라 데이터를 입력해 서버에 수정을 요청할 텐데 그때 사용자의 요청 데이터를 전달하는 DTO이다. 모든 필드는 null 값을 허용하지 않으며 그 중 nickname은 제약조건을 갖는다.
CafeMemberController
package CloneCoding.NaverCafe.domain.cafeMember.controller;
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/{cafe_url}")
public class CafeMemberController {
private final CafeMemberService cafeMemberService;
@GetMapping("/update")
public ResponseUpdateForm getUpdateForm(@PathVariable("cafe_url") String url,
@RequestHeader("Authorization") String token) {
log.info("카페 회원정보 수정 양식 요청");
return cafeMemberService.createUpdateForm(url, token);
}
@PutMapping("/update")
public String updateCafeMember(@PathVariable("cafe_url") String url,
@RequestBody @Valid RequestUpdateCafeMember request,
@RequestHeader("Authorization") String token) {
log.info("카페 회원정보 수정 요청");
return cafeMemberService.updateCafeMember(url, request, token);
}
}
- getUpdateForm() : cafeMemberService의 createUpdateForm() 메서드를 호출하고 결과를 반환
- updateCafeMember() : cafeMemberService의 updateCafeMember() 메서드를 호출하고 결과를 반환
CafeMemberServiceImpl
package CloneCoding.NaverCafe.domain.cafeMember.service;
@Service
@RequiredArgsConstructor
public class CafeMemberServiceImpl implements CafeMemberService {
private final CafeMemberRepository cafeMemberRepository;
private final CafeRepository cafeRepository;
private final MemberRepository memberRepository;
private final AesUtil aesUtil;
@Override
public ResponseUpdateForm createUpdateForm(String url, String token) {
Cafe findCafe = checkCafe(url);
CafeMember findCafeMember = checkCafeMember(findCafe, token);
return ResponseUpdateForm.builder()
.profileImage(findCafeMember.getProfileImage())
.nickname(findCafeMember.getNickname())
.description(findCafeMember.getDescription())
.genderAgeOpen(findCafeMember.isGenderAgeOpen())
.myBlogOpen(findCafeMember.isMyBlogOpen())
.popularMemberPush(findCafeMember.isPopularMemberPush())
.build();
}
@Override
public String updateCafeMember(String url, RequestUpdateCafeMember request, String token) {
Cafe findCafe = checkCafe(url);
CafeMember findCafeMember = checkCafeMember(findCafe, token);
findCafeMember.update(request);
cafeMemberRepository.save(findCafeMember);
return UPDATE_CAFE_MEMBER_INFO.getMessage();
}
private Cafe checkCafe(String url) {
return cafeRepository.findByUrl(url);
}
private CafeMember checkCafeMember(Cafe cafe, String token) {
String accountId = aesUtil.aesDecode(token);
return cafeMemberRepository.findByAccountId(cafe, accountId);
}
}
- createUpdateForm() : 회원정보 수정을 요청한 회원의 정보로 ResponseUpdateForm 객체를 생성해 반환
- updateCafeMember() : 회원이 요청한 정보로 기존 회원의 정보를 수정, 엔티티 저장 후에 결과 메시지 반환
- checkCafe() : findByUrl() 메서드를 호출해 결과 값을 반환
- chekcCafeMember() : 토큰을 복호화해 얻은 계정ID로 카페회원을 조회 후, 조회한 CafeMember 객체 반환
QueryCafeMemberRepository
package CloneCoding.NaverCafe.domain.cafeMember.repository;
@Repository
@RequiredArgsConstructor
public class QueryCafeMemberRepositoryImpl implements QueryCafeMemberRepository {
private final JPAQueryFactory query;
@Override
public CafeMember findByAccountId(Cafe cafe, String accountId) {
return Optional.ofNullable(query
.selectFrom(cafeMember)
.where(cafeMember.cafeId.eq(cafe), cafeMember.accountId.eq(accountId))
.fetchOne())
.orElseThrow(() -> new NoSuchElementException("해당 계정 정보를 가진 카페 회원이 존재하지 않습니다."));
}
}
- findByAccountId() : accountId를 가지고 CAFE_MEMBER 테이블에서 일치하는 데이터를 조회 후 반환
API TEST
카페 회원정보 수정 요청시 사용자에게 전달될 현재 회원의 정보이다. 사용자는 이를 확인하고 수정할 내용을 입력할 것이다.
사용자가 입력한 정보로 회원정보를 수정한 결과이다. 수정 이후 완료 메시지가 정상 출력되며, 다시 한 번 수정 양식을 호출하니 변경된 정보가 전달되는 것을 확인할 수 있다.
'Project > Naver Cafe' 카테고리의 다른 글
[클론 코딩] 네이버 카페 - 카페 생성시 기본 게시판 (0) | 2024.05.28 |
---|---|
[클론 코딩] 네이버 카페 - 카페 탈퇴 (0) | 2024.05.26 |
[클론 코딩] 네이버 카페 - 카페 회원 가입 (0) | 2024.05.22 |
[클론 코딩] 네이버 카페 - 카페 만들기 (0) | 2024.05.22 |
[클론 코딩] 네이버 카페 - 메모 (0) | 2024.05.12 |