-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathMemberCommandService.java
More file actions
216 lines (184 loc) · 8 KB
/
MemberCommandService.java
File metadata and controls
216 lines (184 loc) · 8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
package fitfit.domain.member.service;
import fitfit.domain.member.converter.MemberConverter;
import fitfit.domain.member.dto.MemberDataDTO;
import fitfit.domain.member.dto.MemberRequestDTO;
import fitfit.domain.member.dto.MemberResponseDTO;
import fitfit.domain.member.entity.Member;
import fitfit.domain.member.mapping.MemberTerm;
import fitfit.domain.member.repository.MemberRepository;
import fitfit.domain.member.repository.MemberTermRepository;
import fitfit.domain.term.entity.Term;
import fitfit.domain.term.repository.TermRepository;
import fitfit.domain.token.provider.JwtProvider;
import fitfit.domain.token.repository.MemberTokenRepository;
import fitfit.global.apiPayload.code.status.ErrorStatus;
import fitfit.global.apiPayload.exception.handler.MemberHandler;
import fitfit.global.apiPayload.exception.handler.TermHandler;
import fitfit.global.enums.MemberStatus;
import fitfit.global.enums.Provider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
public class MemberCommandService implements MemberCommandUseCase{
private final MemberRepository memberRepository;
private final JwtProvider jwtProvider;
private final MemberTokenRepository memberTokenRepository;
private final MemberTermRepository memberTermRepository;
private final TermRepository termRepository;
private static final String DEFAULT_BODY_IMG_URL = "https://fitfit-profile-img.s3.ap-northeast-2.amazonaws.com/default_body_img.jpg";
@Override
@Transactional
public Member findOrCreateMember(MemberDataDTO.MemberData memberData, Provider provider) {
return memberRepository.findByProviderId(memberData.getSub())
.orElseGet(() -> {
// 새 멤버 생성
Member createdMember = memberRepository.save(MemberConverter.toMember(memberData, provider));
return createdMember;
});
}
@Override
@Transactional
public MemberResponseDTO.TermAgreementResponse termAgreement(String authorization, MemberRequestDTO.TermAgreementRequest request) {
// JWT 토큰 검증 및 멤버 ID 추출
Long memberId = jwtProvider.getMemberIdAndValidateToken(authorization);
// 회원 조회
Member findMember = memberRepository.findById(memberId)
.orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND));
// 약관 동의 처리
processTermAgreement(findMember, request);
// 회원 상태 AGREE로 변경
findMember.updateStatus(MemberStatus.AGREE);
memberRepository.save(findMember);
// 응답 반환
return MemberConverter.toTermAgreementResponse(findMember);
}
/**
* 약관 동의 처리를 담당하는 메서드
*/
private void processTermAgreement(Member member, MemberRequestDTO.TermAgreementRequest request) {
List<Long> agreeTermIdList = request.getAgreeTermIdList();
List<Long> disagreeTermIdList = request.getDisagreeTermIdList();
// 필수 약관 동의 검증
if (!validateRequiredTerms(agreeTermIdList)) {
throw new TermHandler(ErrorStatus.REQUIRED_TERM_NOT_AGREED);
}
// 동의한 약관 처리
processAgreedTerms(member, agreeTermIdList);
// 미동의한 약관 처리
processDisagreedTerms(member, disagreeTermIdList);
}
// 필수 약관 동의 여부 검증
private boolean validateRequiredTerms(List<Long> agreeTermIdList) {
if (agreeTermIdList == null) return false;
List<Term> requiredTerms = termRepository.findByIsRequiredTrue();
for (Term term : requiredTerms) {
if (!agreeTermIdList.contains(term.getId())) {
return false;
}
}
return true;
}
/**
* 동의한 약관들을 처리하는 메서드
*/
private void processAgreedTerms(Member member, List<Long> agreeTermIdList) {
for (Long termId : agreeTermIdList) {
Term term = getTermOrThrow(termId);
updateMemberTermAgreement(member, term, true);
}
}
/**
* 미동의한 약관들을 처리하는 메서드
*/
private void processDisagreedTerms(Member member, List<Long> disagreeTermIdList) {
// null 처리
if (disagreeTermIdList == null) return;
for (Long termId : disagreeTermIdList) {
Term term = getTermOrThrow(termId);
updateMemberTermAgreement(member, term, false);
}
}
/**
* 약관을 조회하거나 예외를 발생시키는 메서드
*/
private Term getTermOrThrow(Long termId) {
return termRepository.findById(termId)
.orElseThrow(() -> new TermHandler(ErrorStatus.TERM_NOT_FOUND));
}
/**
* 멤버-약관 동의 상태를 업데이트하는 메서드
*/
private void updateMemberTermAgreement(Member member, Term term, boolean isAgree) {
memberTermRepository.findByMemberAndTerm(member, term)
.ifPresentOrElse(
mt -> mt.updateIsAgree(isAgree),
() -> {
MemberTerm newMemberTerm = MemberConverter.toMemberTerm(member, term, isAgree);
memberTermRepository.save(newMemberTerm);
}
);
}
@Override
@Transactional
public MemberResponseDTO.MemberSignupResponse memberSignup(String authorization, MemberRequestDTO.MemberSignupRequest request) {
// JWT 토큰 검증 및 멤버 ID 추출
Long memberId = jwtProvider.getMemberIdAndValidateToken(authorization);
// 회원 조회
Member findMember = memberRepository.findById(memberId)
.orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND));
// 회원가입 처리
processMemberSignup(findMember, request);
// 응답 반환
return MemberConverter.toMemberSignupResponse(findMember);
}
/**
* 회원가입 처리를 담당하는 메서드
* 단일책임원칙에 따라 회원가입 로직을 분리
*/
private void processMemberSignup(Member member, MemberRequestDTO.MemberSignupRequest request) {
// 필수 추가 정보 검증
if (!validateAdditionalInfo(request)) {
throw new MemberHandler(ErrorStatus.INVALID_MEMBER_INFO);
}
// 추가 정보 저장
updateMemberInfo(member, request);
// 회원 상태 ACTIVE로 변경
member.updateStatus(MemberStatus.ACTIVE);
memberRepository.save(member);
}
// 추가 정보 필수 입력값 검증
private boolean validateAdditionalInfo(MemberRequestDTO.MemberSignupRequest request) {
return request.getNickname() != null &&
request.getName() != null &&
request.getHeight() != null &&
request.getWeight() != null &&
request.getPhoneNumber() != null &&
request.getGender() != null &&
request.getBirth() != null;
}
/**
* 회원 정보를 업데이트하는 메서드
*/
private void updateMemberInfo(Member member, MemberRequestDTO.MemberSignupRequest request) {
member.updateNickname(request.getNickname());
member.updateName(request.getName());
member.updateWeight(request.getWeight());
member.updateHeight(request.getHeight());
member.updatePhoneNumber(request.getPhoneNumber());
member.updateBirth(request.getBirth());
member.updateGender(request.getGender());
if (request.getStyleList() != null) {
member.updatePreferredStyle(request.getStyleList());
}
if (request.getFullBodyImgUrl() != null) {
member.updateFullBodyImgUrl(request.getFullBodyImgUrl());
} else {
member.updateFullBodyImgUrl(DEFAULT_BODY_IMG_URL);
}
}
}