Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] 마이페이지 API 구현 #124

Merged
merged 9 commits into from
Feb 11, 2024
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ build/
!**/src/main/**/build/
!**/src/test/**/build/

umbba-test.http
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

포스트맨이 아니라 IntelliJ의 .http 테스트 활용하신건가요!
신기해서 저도 찾아봤습니당
https://ksh-coding.tistory.com/97


## Querydsl
umbba-domain/src/main/generated

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class SecurityConfig {

private static final String[] AUTH_WHITELIST = {
"/kakao/**", "/login", "/reissue",
"/qna/**", "onboard/**", "/home", "/dummy",
"/qna/**", "onboard/**", "/home", "/dummy", "/user/me",
// "/log-out",
"/test", "/profile", "/health", "/actuator/health",
"/alarm/qna", "/alarm/drink",
Comment on lines 23 to 27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

생각해보니까 인증이 필요 없는 API들만 여기 추가되어야하는건데,
일단 테스트를 위해 다 추가해놨던게 그대로 있었네요 ...
다음에 한번에 싹 빼는걸로 합시당

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞아요 ,,ㅋㅋㅋㅋ 좋습니당

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package sopt.org.umbba.api.controller.qna;

import static sopt.org.umbba.api.config.jwt.JwtProvider.*;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
Expand Down Expand Up @@ -92,4 +94,10 @@ public ApiResponse<GetInvitationResponseDto> invitation(Principal principal) {
return ApiResponse.success(SuccessType.GET_INVITE_CODE_SUCCESS, qnAService.getInvitation(JwtProvider.getUserFromPrincial(principal)));
}

@GetMapping("/user/me")
@ResponseStatus(HttpStatus.OK)
public ApiResponse<MyUserInfoResponseDto> getMyUserInfo(Principal principal) {
return ApiResponse.success(SuccessType.GET_MY_USER_INFO_SUCCESS, qnAService.getUserInfo(getUserFromPrincial(principal)));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package sopt.org.umbba.api.controller.qna.dto.response;

import static sopt.org.umbba.domain.domain.parentchild.ParentchildRelation.*;

import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

import lombok.Builder;
import lombok.Getter;
import sopt.org.umbba.domain.domain.parentchild.Parentchild;
import sopt.org.umbba.domain.domain.parentchild.ParentchildRelation;
import sopt.org.umbba.domain.domain.qna.QnA;
import sopt.org.umbba.domain.domain.user.User;

@Getter
@Builder
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class MyUserInfoResponseDto {

private String myUsername;
private String myUserType;
private String opponentUsername;
private String opponentUserType;

private String parentchildRelation;
private Boolean isMeChild;

private String section;
private Long matchedDate;
private Integer qnaCnt;

public static MyUserInfoResponseDto of(User myUser, User opponentUser, Parentchild parentchild, QnA qnA, long date, int qnaCnt) {

return MyUserInfoResponseDto.builder()
.myUsername(myUser.getUsername())
.myUserType(getUserType(parentchild.getRelation(), myUser.isMeChild()))
.opponentUsername(opponentUser.getUsername())
.opponentUserType(getUserType(parentchild.getRelation(), opponentUser.isMeChild()))
.parentchildRelation(parentchild.getRelation().getValue())
.isMeChild(myUser.isMeChild())
.section(qnA.getQuestion().getSection().getValue())
.matchedDate(date) // 일수와 문답 수는 다를 수 있음
.qnaCnt(qnaCnt).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요건 무슨 용도의 파일인가요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

어엇 잘못 들어간 파일 같네요 삭제하겠습니다 !!

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import sopt.org.umbba.api.controller.qna.dto.response.MyUserInfoResponseDto;
import sopt.org.umbba.api.controller.qna.dto.request.TodayAnswerRequestDto;
import sopt.org.umbba.api.controller.qna.dto.response.*;
import sopt.org.umbba.api.service.notification.NotificationService;
Expand All @@ -19,6 +21,12 @@
import sopt.org.umbba.domain.domain.user.repository.UserRepository;

import javax.validation.constraints.NotNull;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -200,6 +208,35 @@ public void filterAllQuestion(Long userId) {
}
}

// 마이페이지 - 부모자식 관계 정보 조회
public MyUserInfoResponseDto getUserInfo(final Long userId) {

User myUser = getUserById(userId);
Parentchild parentchild = getParentchildByUser(myUser);
User opponentUser = getOpponentByParentchild(parentchild, userId);
// TODO 상대 미연결인 부분에 대한 반환값 추가 예정
/*List<User> opponentUserList = userRepository.findUserByParentChild(parentchild)
.stream()
.filter(user -> !user.getId().equals(userId))
.collect(Collectors.toList());

if (opponentUserList.isEmpty()) {
return MyUserInfoResponseDto.of(myUser, opponentUser, parentchild, todayQnA, 0, 0);
}*/

QnA todayQnA = getTodayQnAByParentchild(parentchild);
List<QnA> qnaList = getQnAListByParentchild(parentchild);

long qnaCnt = qnaList.stream()
.filter(qnA -> qnA.isChildAnswer() && qnA.isParentAnswer())
.count();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DB 수정 완료해서 getCount만으로 처리해도 될것같습니다!


LocalDateTime firstQnADate = parentchild.getQnaList().get(0).getCreatedAt();
long qnaDate = ChronoUnit.DAYS.between(firstQnADate, LocalDateTime.now());

return MyUserInfoResponseDto.of(myUser, opponentUser, parentchild, todayQnA, qnaDate, (int)qnaCnt);
}

/*
리팩토링을 위해 아래로 뺀 메서드들
*/
Expand Down Expand Up @@ -227,7 +264,7 @@ private List<QnA> getQnAListByParentchild(Parentchild parentchild) {
return qnaList;
}

private QnA getTodayQnAByParentchild(Parentchild parentchild) {
protected QnA getTodayQnAByParentchild(Parentchild parentchild) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

q;
protected로 하신 이유가 궁금합니다~!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

흠흠 이게 긴 사연이 있는데요!! 일단 잘못 들어간 게 맞구요 ㅎㅎ

바꾸게 된 과정에 대해 설명을 드려보자면,

  1. 원래 유저 정보 조회를 QnAService 보다는 다른 서비스 클래스로 분리하는 게 맞다고 생각해서 기능 상으로 도메인이 더 부합한 ParentchildService에서 구현을 하고자 했습니다!
  2. 하지만 오늘의 질문, Parentchild 조회 등 동일한 로직이 QnAService에 여럿 쓰이고 있어 해당 로직을 protected로 열어두고 호출하려 했으나,, Service에서 다른 Service를 의존하는 상황 자체가 순환 참조를 발생시킬 우려가 있다고 판단했습니다.
  3. 결론! 일단 QnAService에서 구현을 해두고 주로 쓰이는 QnAService의 조회 로직을 분리하기 위해 전면 리팩토링을 진행하기로 했습니다 허헛
  4. 그래서 다시 private으로 바꾸겠습니다 .. 감사합니다!!

List<QnA> qnaList = parentchild.getQnaList();
if (qnaList == null || qnaList.isEmpty()) {
throw new CustomException(ErrorType.PARENTCHILD_HAVE_NO_QNALIST);
Expand Down Expand Up @@ -305,10 +342,6 @@ else if (childList.get(3) != YES || parentList.get(3) != YES) {
}


/*
리팩토링을 위해 아래로 뺀 메서드들 끝
*/

// 메인페이지 정보
public GetMainViewResponseDto getMainInfo(Long userId) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public enum SuccessType {
PUSH_ALARM_SUCCESS(HttpStatus.OK, "푸시알림 전송에 성공했습니다."),
PUSH_ALARM_PERIODIC_SUCCESS(HttpStatus.OK, "오늘의 질문 푸시알림 활성에 성공했습니다."),
REMIND_QUESTION_SUCCESS(HttpStatus.OK, "상대방에게 질문을 리마인드 하는 데 성공했습니다."),
GET_MY_USER_INFO_SUCCESS(HttpStatus.OK, "마이페이지 내 정보 조회에 성공했습니다."),
TEST_SUCCESS(HttpStatus.OK, "데모데이 테스트용 API 호출에 성공했습니다."),
RESTART_QNA_SUCCESS(HttpStatus.OK, "7일 이후 문답이 정상적으로 시작되었습니다."),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ public static ParentchildRelation relation(String gender, String relationInfo, b
throw new CustomException(ErrorType.INVALID_PARENT_CHILD_RELATION_INFO);
}

// 아들 | 딸 | 엄마 | 아빠 구분
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아주 좋습니당!

public static String getUserType(ParentchildRelation relation, boolean isChild) {
if (relation.childGender.equals("여자")) {
if (isChild) return "딸";
else return "엄마";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p5;
갠취이긴 하지만 삼항연산자로 뺴도 좋아보여요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은 의견 감사합니다 !!!

} else {
if (isChild) return "아들";
else return "아빠";
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금 예시로 있는 DB가 딱 그런 케이슨데요 (어쩌다보니)
초대하는 측에서 분명 엄마랑 하겠다고 골랐는데, 초대 받는 상대가 자기 성별을 남자로 골라버린 경우죠
이 경우 성별이 남자여도 엄마로 표시하기로 정했던 것 같습니다 (사회적으로는 엄마일...수도.. 있으니까요?)

암튼 그래서 지금 DB에 엄마-아들 관계로 되어 있음 + 둘다 성별은 남자임 이런 상태인데
my_user_type을 아빠가 아닌 엄마로 표시해줄 수 있도록! 로직이 수정되면 좋을것 같습니다!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네넵 그럼 User의 gender 필드 기준이 아닌, relation에 저장된 값과 isChild 기준으로 반환하는 로직으로 수정하겠습니다!!



// 자식 유저와 부모 유저의 gender와 isMeChild 필드를 통해 ParentchildRelation을 구분하는 로직
public static boolean validate(List<User> parentChildUsers, ParentchildRelation relation) {
Expand Down
Loading