Skip to content

Commit

Permalink
feature: 회원 정보 조회 기능 추가 (#142)
Browse files Browse the repository at this point in the history
* feat: 새 스킨 조회 기능 및 테스트 코드 추가

* chore: jpa관련 config 설정

- 버전 호환오류로 인한 기본 Template설정

* feat: 기본 새 스킨 조회 query 추가

* feat: 회원과 벌레에 대한 조회 쿼리 및 테스트 코드 추가

* feat: 회원 정보 조회 기능 및 테스트 코드 추가

* refactor: 회원과 Item 서비스의 의존성 순환을 피하기 위해 inventorySearchService 생성

* refactor: 회원과 Item 서비스의 의존성 순환을 피하기 위해 inventorySearchService 생성

* feat: 회원 정보 조회 API 추가

* style: 메서드 접근 제어자에 따른 순서 변경

* refactor: inventorySearchService 제거 후 memberService에서 repository 추가

* refactor: transform에서 stream으로 동작 변경

* style: 리뷰 반영
  • Loading branch information
parksey authored Nov 23, 2023
1 parent 0d29e0a commit 6876104
Show file tree
Hide file tree
Showing 25 changed files with 1,906 additions and 4,409 deletions.
66 changes: 61 additions & 5 deletions src/main/java/com/moabam/api/application/member/MemberMapper.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
package com.moabam.api.application.member;

import static com.moabam.global.common.util.GlobalConstant.*;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import com.moabam.api.domain.bug.Bug;
import com.moabam.api.domain.item.Inventory;
import com.moabam.api.domain.member.BadgeType;
import com.moabam.api.domain.member.Member;
import com.moabam.api.dto.member.DeleteMemberResponse;
import com.moabam.api.dto.member.BadgeResponse;
import com.moabam.api.dto.member.MemberInfo;
import com.moabam.api.dto.member.MemberInfoResponse;
import com.moabam.api.dto.member.MemberInfoSearchResponse;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
Expand All @@ -17,10 +31,52 @@ public static Member toMember(Long socialId) {
.build();
}

public static DeleteMemberResponse toDeleteMemberResponse(Long memberId, String socialId) {
return DeleteMemberResponse.builder()
.socialId(socialId)
.id(memberId)
public static MemberInfoSearchResponse toMemberInfoSearchResponse(List<MemberInfo> memberInfos) {
MemberInfo infos = memberInfos.get(0);
List<BadgeType> badgeTypes = memberInfos.stream()
.map(MemberInfo::badges)
.filter(Objects::nonNull)
.toList();

return MemberInfoSearchResponse.builder()
.nickname(infos.nickname())
.profileImage(infos.profileImage())
.intro(infos.intro())
.totalCertifyCount(infos.totalCertifyCount())
.badges(new HashSet<>(badgeTypes))
.goldenBug(infos.goldenBug())
.morningBug(infos.morningBug())
.nightBug(infos.nightBug())
.build();
}

public static MemberInfoResponse toMemberInfoResponse(MemberInfoSearchResponse memberInfoSearchResponse,
List<Inventory> inventories) {
long certifyCount = memberInfoSearchResponse.totalCertifyCount();

return MemberInfoResponse.builder()
.nickname(memberInfoSearchResponse.nickname())
.profileImage(memberInfoSearchResponse.profileImage())
.intro(memberInfoSearchResponse.intro())
.level(certifyCount / LEVEL_DIVISOR)
.exp(certifyCount % LEVEL_DIVISOR)
.birds(defaultSkins(inventories))
.badges(badgedNames(memberInfoSearchResponse.badges()))
.goldenBug(memberInfoSearchResponse.goldenBug())
.morningBug(memberInfoSearchResponse.morningBug())
.nightBug(memberInfoSearchResponse.nightBug())
.build();
}

private static List<BadgeResponse> badgedNames(Set<BadgeType> badgeTypes) {
return BadgeType.memberBadgeMap(badgeTypes);
}

private static Map<String, String> defaultSkins(List<Inventory> inventories) {
return inventories.stream()
.collect(Collectors.toMap(
inventory -> inventory.getItem().getType().name(),
inventory -> inventory.getItem().getImage()
));
}
}
47 changes: 47 additions & 0 deletions src/main/java/com/moabam/api/application/member/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,27 @@
import static com.moabam.global.error.model.ErrorMessage.*;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.moabam.api.application.auth.mapper.AuthMapper;
import com.moabam.api.domain.item.Inventory;
import com.moabam.api.domain.item.repository.InventorySearchRepository;
import com.moabam.api.domain.member.Member;
import com.moabam.api.domain.member.repository.MemberRepository;
import com.moabam.api.domain.member.repository.MemberSearchRepository;
import com.moabam.api.dto.auth.AuthorizationTokenInfoResponse;
import com.moabam.api.dto.auth.LoginResponse;
import com.moabam.api.dto.member.MemberInfo;
import com.moabam.api.dto.member.MemberInfoResponse;
import com.moabam.api.dto.member.MemberInfoSearchResponse;
import com.moabam.global.auth.model.AuthMember;
import com.moabam.global.common.util.ClockHolder;
import com.moabam.global.common.util.GlobalConstant;
import com.moabam.global.error.exception.BadRequestException;
import com.moabam.global.error.exception.NotFoundException;

import lombok.RequiredArgsConstructor;
Expand All @@ -25,6 +34,7 @@
public class MemberService {

private final MemberRepository memberRepository;
private final InventorySearchRepository inventorySearchRepository;
private final MemberSearchRepository memberSearchRepository;
private final ClockHolder clockHolder;

Expand Down Expand Up @@ -58,9 +68,46 @@ public void delete(Member member) {
memberRepository.delete(member);
}

public MemberInfoResponse searchInfo(AuthMember authMember, Long memberId) {
Long searchId = authMember.id();
boolean isMe = confirmMe(searchId, memberId);

if (!isMe) {
searchId = memberId;
}

MemberInfoSearchResponse memberInfoSearchResponse = findMemberInfo(searchId, isMe);
List<Inventory> inventories = getDefaultSkin(searchId);

return MemberMapper.toMemberInfoResponse(memberInfoSearchResponse, inventories);
}

private List<Inventory> getDefaultSkin(Long searchId) {
List<Inventory> inventories = inventorySearchRepository.findBirdsDefaultSkin(searchId);
if (inventories.size() != GlobalConstant.DEFAULT_SKIN_SIZE) {
throw new BadRequestException(INVALID_DEFAULT_SKIN_SIZE);
}

return inventories;
}

private Member signUp(Long socialId) {
Member member = MemberMapper.toMember(socialId);

return memberRepository.save(member);
}

private MemberInfoSearchResponse findMemberInfo(Long searchId, boolean isMe) {
List<MemberInfo> memberInfos = memberSearchRepository.findMemberAndBadges(searchId, isMe);

if (memberInfos.isEmpty()) {
throw new BadRequestException(MEMBER_NOT_FOUND);
}

return MemberMapper.toMemberInfoSearchResponse(memberInfos);
}

private boolean confirmMe(Long myId, Long memberId) {
return Objects.isNull(memberId) || myId.equals(memberId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,14 @@ public List<Item> findItems(Long memberId, ItemType type) {
.select(item)
.fetch();
}

public List<Inventory> findBirdsDefaultSkin(Long searchId) {
return jpaQueryFactory.selectFrom(inventory)
.join(inventory.item)
.on(inventory.item.id.eq(item.id))
.where(
inventory.memberId.eq(searchId),
inventory.isDefault.isTrue()
).fetch();
}
}
48 changes: 48 additions & 0 deletions src/main/java/com/moabam/api/domain/member/Badge.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.moabam.api.domain.member;

import static java.util.Objects.*;

import java.time.LocalDateTime;

import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.NoArgsConstructor;

@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EntityListeners(AuditingEntityListener.class)
public class Badge {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

@Column(name = "member_id", nullable = false)
private Long memberId;

@Enumerated(EnumType.STRING)
@Column(name = "type", nullable = false)
private BadgeType type;

@CreatedDate
@Column(name = "created_at", updatable = false, nullable = false)
private LocalDateTime createdAt;

@Builder
private Badge(Long memberId, BadgeType type) {
this.memberId = requireNonNull(memberId);
this.type = requireNonNull(type);
}
}
35 changes: 35 additions & 0 deletions src/main/java/com/moabam/api/domain/member/BadgeType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.moabam.api.domain.member;

import java.util.Arrays;
import java.util.List;
import java.util.Set;

import com.moabam.api.dto.member.BadgeResponse;

import lombok.Getter;

@Getter
public enum BadgeType {

MORNING_BIRTH("MORNING", "오목눈이 탄생"),
MORNING_ADULT("MORNING", "어른 오목눈이"),
NIGHT_BIRTH("NIGHT", "부엉이 탄생"),
NIGHT_ADULT("NIGHT", "어른 부엉이");

private final String period;
private final String korean;

BadgeType(String period, String korean) {
this.period = period;
this.korean = korean;
}

public static List<BadgeResponse> memberBadgeMap(Set<BadgeType> badgeTypes) {
return Arrays.stream(BadgeType.values())
.map(badgeType -> BadgeResponse.builder()
.badge(badgeType)
.unlock(badgeTypes.contains(badgeType))
.build())
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.moabam.api.domain.member.repository;

import org.springframework.data.jpa.repository.JpaRepository;

import com.moabam.api.domain.member.Badge;

public interface BadgeRepository extends JpaRepository<Badge, Long> {

}
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package com.moabam.api.domain.member.repository;

import static com.moabam.api.domain.member.QBadge.*;
import static com.moabam.api.domain.member.QMember.*;
import static com.moabam.api.domain.room.QParticipant.*;

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

import org.springframework.stereotype.Repository;

import com.moabam.api.domain.member.Member;
import com.moabam.api.dto.member.MemberInfo;
import com.moabam.global.common.util.DynamicQuery;
import com.querydsl.core.types.Expression;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;

import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -43,4 +49,29 @@ public Optional<Member> findMemberNotManager(Long memberId) {
)
.fetchFirst());
}

public List<MemberInfo> findMemberAndBadges(Long searchId, boolean isMe) {
List<Expression<?>> selectExpression = new ArrayList<>(List.of(
member.nickname,
member.profileImage,
member.intro,
member.totalCertifyCount,
badge.type));

if (isMe) {
selectExpression.addAll(List.of(
member.bug.goldenBug,
member.bug.morningBug,
member.bug.nightBug));
}

return jpaQueryFactory
.select(Projections.constructor(MemberInfo.class, selectExpression.toArray(new Expression<?>[0])))
.from(member)
.leftJoin(badge).on(member.id.eq(badge.memberId))
.where(
DynamicQuery.generateIsNull(true, member.deletedAt),
member.id.eq(searchId)
).fetch();
}
}
13 changes: 13 additions & 0 deletions src/main/java/com/moabam/api/dto/member/BadgeResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.moabam.api.dto.member;

import com.moabam.api.domain.member.BadgeType;

import lombok.Builder;

@Builder
public record BadgeResponse(
BadgeType badge,
boolean unlock
) {

}
20 changes: 20 additions & 0 deletions src/main/java/com/moabam/api/dto/member/MemberInfo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.moabam.api.dto.member;

import com.moabam.api.domain.member.BadgeType;

public record MemberInfo(
String nickname,
String profileImage,
String intro,
long totalCertifyCount,
BadgeType badges,
Integer goldenBug,
Integer morningBug,
Integer nightBug
) {

public MemberInfo(String nickname, String profileImage, String intro,
long totalCertifyCount, BadgeType badges) {
this(nickname, profileImage, intro, totalCertifyCount, badges, null, null, null);
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/moabam/api/dto/member/MemberInfoResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.moabam.api.dto.member;

import static com.fasterxml.jackson.annotation.JsonInclude.Include.*;

import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonInclude;

import lombok.Builder;

@Builder
public record MemberInfoResponse(
String nickname,
String profileImage,
String intro,
long level,
long exp,
Map<String, String> birds,
List<BadgeResponse> badges,
@JsonInclude(NON_NULL) Integer goldenBug,
@JsonInclude(NON_NULL) Integer morningBug,
@JsonInclude(NON_NULL) Integer nightBug
) {

}
Loading

0 comments on commit 6876104

Please sign in to comment.