✔️ 주요 코드 중심 분석 ✔️
회원 정보 수정 - 이름, 이메일, 전화번호
Front
const save = () => { // 저장버튼 클릭 시 input readOnly
// 1
const isUnchanged = Object.keys(updateUser).every((key) =>
updateUser[key] === member[key]);
if (isUnchanged) {
Toast('warning', '변경된 정보가 없습니다')
setEditMode(false);
return;
}
const allCheck = Object.values(saveCheck).every((value) => value === true);
if (!allCheck) {
Toast('error', '입력값을 확인해주세요')
return;
}
axios.put(`${url}/member/modifyInfo`, updateUser, { // 2
headers : {
Authorization :accessToken,
Refresh : getCookie("refreshToken")
}
})
.then((res) => {
dispatch({type:"member", payload: updateUser}); // 3
setEditMode(false);
Toast('success', '정상적으로 수정되었습니다')
})
.catch((error) => {
console.log(error);
})
};
- 변경된 정보가 없는 경우, 빈 값이 존재하는 경우 상황에 맞는 메시지를 보여주고 return
- member/modifyInfo 엔드포인트로 수정할 회원 정보 데이터를 담아 PUT 요청 전달
- Redux에 회원 정보를 저장하고 있으므로 해당 정보도 함께 변경해줌
- 일반 로그인 회원과 달리 소셜 로그인 회원은 전화번호만 수정이 가능함


Back
@PutMapping("/member/modifyInfo")
public ResponseEntity<Object> userInfoModify(@RequestBody ModifyReqDto modifyReqDto) {
Member member = mapper.modifyReqDtoToMember(modifyReqDto);
try {
member = memberService.modifyMember(member); // 1
ModifyResDto modifyResDto = mapper.memberToModifyResDto(member);
return new ResponseEntity<>(modifyResDto, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
public Member modifyMember(Member member) throws Exception {
Member modifyMember = memberRepository.findById(member.getId()); // 2
if(modifyMember == null) throw new Exception("존재하지 않는 회원입니다.");
modifyMember.setUserInfo(member.getName(), member.getNickname(),
member.getPhone(), member.getEmail()); // 3
memberRepository.save(modifyMember);
return modifyMember;
}
- 클라이언트에서 전달 받은 데이터를 통해 서비스 레이어로 해당 회원 정보 요청
- 데이터베이스에서 해당 회원의 아이디를 통해 Member 정보를 찾음
- Member 정보가 확인된 경우 변경할 회원 정보로 설정해준 후 저장
회원 정보 수정 - 비밀번호
Front
const originPw = (name, value) => {
if (name === 'pw' && value.trim() !== '' && value.length > 7) {
axios.post(`${url}/password`, {id: member.id, password: value}) // 1
.then((res) => {
if(res.data === true) { setPasswordMatch(true); }
else { setPasswordMatch(false); }
})
.catch((error) => { console.log(error); })
}
}
const pwSubmit = () => {
axios.put(`${url}/resetPw/${member.id}`, { password: password.newPw }) // 2
.then((res) => {
Toast('success', '비밀번호 재설정 완료되었습니다')
})
.catch((error) => {
Toast('error', '비밀번호 재설정 실패했습니다')
})
setPassword({ pw: '', newPw: '', newPwCheck: '' }); // 3
setPasswordMatch(false);
}
}
- password 엔드포인트로 아이디와 비밀번호를 담아 POST 요청 전달, 응답 데이터가 true인 경우 비밀번호 재설정 가능
- resetPw/{id} 엔드포인트로 비밀번호를 담아 PUT 요청 전달
- 입력했던 필드를 공백으로 지정하여 초기화
Back
@PostMapping("/password")
public ResponseEntity<Object> matchPassword(@RequestBody SearchPwDto searchPwDto) {
String id = searchPwDto.getId();
String phone = searchPwDto.getPassword();
try {
boolean result = memberService.matchPw(id, phone); // 1
return new ResponseEntity<>(result, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
}
}
public boolean matchPw(String id, String password) throws Exception {
Member member = memberRepository.findById(id);
if(member == null) throw new Exception("존재하지 않는 회원입니다.");
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); // 2
return encoder.matches(password, member.getPassword());
}
- 클라이언트에서 전달 받은 데이터를 통해 서비스 레이어로 해당 회원의 비밀번호 일치 여부 확인
- 저장되어 있는 비밀번호와 입력 받은 비밀번호가 일치하는지 확인하기 위해 해싱하여 비교
찜한 리뷰 리스트 / 찜한 카페 리스트
두 기능의 로직은 거의 유사하므로 찜한 리뷰를 중심으로 분석
Front
useEffect(() => {
axios.get(`${url}/member/wishReviewList/${memNo}?page=${currentPage-1}`, { // 1
headers: {
Authorization: accessToken,
"Content-Type": "application/json",
},
})
.then((res) => {
setWishReviewList(res.data.data);
setTotalPages(res.data.pageInfo.totalPages);
})
.catch((error) => {
console.error(error);
});
}, [memNo, currentPage]);
{showModal && ( // 2
<div className="modalBox">
<ReviewDetail modalDetail wishReviewNo = {wishReviewNo}/> // 3
<p className='closeBtn'><img src="/img/X.png" alt="x" onClick={closeModal}/></p>
</div>
)}
- member/wishReviewList/{memNo} 엔드포인트로 GET 요청 전달
- 리스트 중 특정 리뷰/카페를 선택하면 modal로 해당 리뷰/카페에 대한 정보를 보여줌
✅ wishReviewNo 관련 이슈는 아래 링크의 리뷰 상세 부분에서 확인
[CafeHub] 코드 분석 및 이슈 기록 - 리뷰 상세 / 리뷰 찜 / 리뷰 추천
sjin-record.tistory.com
Back
@GetMapping("member/wishReviewList/{memNo}")
public ResponseEntity<Object> getWishReview(@PathVariable Integer memNo,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "9") int size) {
try {
Pageable pageable = PageRequest.of(page, size);
MultiResponseDto<WishReviewDto> wishReviewList = wishReviewService.getWishReviewList(memNo, pageable);
return new ResponseEntity<>(wishReviewList, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
public MultiResponseDto<WishReviewDto> getWishReviewList(Integer memNo, Pageable pageable) throws Exception {
Page<WishReviewDto> wishReviewPage = wishRepository.findWishReviewList(memNo, pageable);
return new MultiResponseDto<>(wishReviewPage.getContent(), wishReviewPage);
}
'[Project] CafeHub' 카테고리의 다른 글
| [CafeHub] 배포 및 이슈 기록 - 눈물의 해킹 (0) | 2024.01.10 |
|---|---|
| [CafeHub] 코드 분석 및 이슈 기록 - 결제 (with. 토스 페이먼츠) (0) | 2024.01.10 |
| [CafeHub] 코드 분석 및 이슈 기록 - 카페 정보 (with. 카카오 지도) (0) | 2024.01.08 |
| [CafeHub] 코드 분석 및 이슈 기록 - 리뷰 상세 / 리뷰 찜 / 리뷰 추천 (0) | 2024.01.05 |
| [CafeHub] 코드 분석 및 이슈 기록 - 아이디 찾기 / 비밀번호 찾기 (0) | 2024.01.05 |