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

[FIX] 뱃지 전체 조회 수정 #193

Merged
merged 3 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 33 additions & 6 deletions src/main/java/com/smeme/server/dto/badge/BadgeListResponseDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,44 @@
import com.smeme.server.model.badge.Badge;
import com.smeme.server.model.badge.BadgeType;
import com.smeme.server.model.badge.MemberBadge;
import lombok.Builder;
import lombok.*;

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

public record BadgeListResponseDTO(
List<BadgeResponseDTO> badges
List<BadgeTypeResponseDTO> badgeTypes
) {
public static BadgeListResponseDTO of(List<Badge> badges, List<MemberBadge> memberBadges) {
return new BadgeListResponseDTO(badges.stream()
.map(badge -> BadgeResponseDTO.of(badge, memberBadges))
.toList());
public static BadgeListResponseDTO of(Map<BadgeType, List<Badge>> badgeMap, List<MemberBadge> memberBadges) {
val badgeTypes = getBadgesType(badgeMap, memberBadges);
return new BadgeListResponseDTO(badgeTypes);
}

private static List<BadgeTypeResponseDTO> getBadgesType(Map<BadgeType, List<Badge>> badgeMap, List<MemberBadge> memberBadges) {
return badgeMap.keySet().stream()
.map(type -> BadgeTypeResponseDTO.of(type, badgeMap.get(type), memberBadges))
.toList();
}

@Builder
public record BadgeTypeResponseDTO(
BadgeType badgeType,
String badgeTypeName,
List<BadgeResponseDTO> badges
) {
public static BadgeTypeResponseDTO of(BadgeType type, List<Badge> badges, List<MemberBadge> memberBadges) {
return BadgeTypeResponseDTO.builder()
.badgeType(type)
.badgeTypeName(type.getDescription())
.badges(getBadges(badges, memberBadges))
.build();
}

private static List<BadgeResponseDTO> getBadges(List<Badge> badges, List<MemberBadge> memberBadges) {
return badges.stream()
.map(badge -> BadgeResponseDTO.of(badge, memberBadges))
.toList();
}
}

@Builder
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.smeme.server.repository.badge;

import com.smeme.server.model.badge.Badge;

import java.util.List;

public interface BadgeCustomRepository {
List<Badge> findAllOrderById();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,5 @@
import com.smeme.server.model.badge.Badge;
import org.springframework.data.jpa.repository.JpaRepository;

public interface BadgeRepository extends JpaRepository<Badge, Long> {

public interface BadgeRepository extends JpaRepository<Badge, Long>, BadgeCustomRepository {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.smeme.server.repository.badge;

import com.querydsl.jpa.impl.JPAQueryFactory;
import com.smeme.server.model.badge.Badge;
import lombok.*;
import org.springframework.stereotype.Repository;
import java.util.List;

import static com.smeme.server.model.badge.QBadge.badge;

@Repository
@RequiredArgsConstructor
public class BadgeRepositoryImpl implements BadgeCustomRepository {

private final JPAQueryFactory queryFactory;

@Override
public List<Badge> findAllOrderById() {
return queryFactory
.selectFrom(badge)
.orderBy(badge.id.asc())
.fetch();
}
}
23 changes: 19 additions & 4 deletions src/main/java/com/smeme/server/service/BadgeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@
import com.smeme.server.dto.badge.BadgeListResponseDTO;
import com.smeme.server.model.Member;
import com.smeme.server.model.badge.Badge;
import com.smeme.server.model.badge.BadgeType;
import com.smeme.server.model.badge.MemberBadge;
import com.smeme.server.repository.badge.BadgeRepository;
import com.smeme.server.repository.badge.MemberBadgeRepository;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import lombok.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.smeme.server.util.message.ErrorMessage.INVALID_BADGE;

Expand All @@ -24,9 +28,20 @@ public class BadgeService {
private final BadgeRepository badgeRepository;

public BadgeListResponseDTO getBadgeList(Long memberId) {
List<Badge> badges = badgeRepository.findAll();
List<MemberBadge> memberBadges = memberBadgeRepository.findAllByMemberId(memberId);
return BadgeListResponseDTO.of(badges, memberBadges);
val badges = badgeRepository.findAllOrderById();
val badgeMap = classifiedByType(badges);
val memberBadges = memberBadgeRepository.findAllByMemberId(memberId);
return BadgeListResponseDTO.of(badgeMap, memberBadges);
}

private Map<BadgeType, List<Badge>> classifiedByType(List<Badge> badges) {
val badgeMap = new HashMap<BadgeType, List<Badge>>();
badges.forEach(badge -> putBadgeMap(badgeMap, badge));
return badgeMap;
}

private void putBadgeMap(Map<BadgeType, List<Badge>> badgeMap, Badge badge) {
badgeMap.computeIfAbsent(badge.getType(), k -> new ArrayList<>()).add(badge);
}

@Transactional
Expand Down
41 changes: 29 additions & 12 deletions src/main/resources/static/docs/open-api-3.0.1.json
Original file line number Diff line number Diff line change
Expand Up @@ -466,11 +466,11 @@
"content" : {
"application/json;charset=UTF-8" : {
"schema" : {
"$ref" : "#/components/schemas/api-v2-members-badges1519826817"
"$ref" : "#/components/schemas/api-v2-members-badges1884183897"
},
"examples" : {
"뱃지 목록 조회 Example" : {
"value" : "{\n \"success\" : true,\n \"message\" : \"뱃지 리스트 조회 성공\",\n \"data\" : {\n \"badges\" : [ {\n \"name\" : \"연속 3일 일기 뱃지1\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지2\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지3\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지4\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지5\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n } ]\n }\n}"
"value" : "{\n \"success\" : true,\n \"message\" : \"뱃지 리스트 조회 성공\",\n \"data\" : {\n \"badgeTypes\" : [ {\n \"badgeType\" : \"COMBO\",\n \"badgeTypeName\" : \"연속 3일 일기 뱃지\",\n \"badges\" : [ {\n \"name\" : \"연속 3일 일기 뱃지1\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지2\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지3\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지4\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지5\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n } ]\n }, {\n \"badgeType\" : \"COMBO\",\n \"badgeTypeName\" : \"연속 3일 일기 뱃지\",\n \"badges\" : [ {\n \"name\" : \"연속 3일 일기 뱃지1\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지2\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지3\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지4\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지5\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n } ]\n }, {\n \"badgeType\" : \"COMBO\",\n \"badgeTypeName\" : \"연속 3일 일기 뱃지\",\n \"badges\" : [ {\n \"name\" : \"연속 3일 일기 뱃지1\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지2\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지3\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지4\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지5\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n } ]\n }, {\n \"badgeType\" : \"COMBO\",\n \"badgeTypeName\" : \"연속 3일 일기 뱃지\",\n \"badges\" : [ {\n \"name\" : \"연속 3일 일기 뱃지1\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지2\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지3\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지4\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지5\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n } ]\n }, {\n \"badgeType\" : \"COMBO\",\n \"badgeTypeName\" : \"연속 3일 일기 뱃지\",\n \"badges\" : [ {\n \"name\" : \"연속 3일 일기 뱃지1\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지2\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지3\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지4\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n }, {\n \"name\" : \"연속 3일 일기 뱃지5\",\n \"type\" : \"COMBO\",\n \"imageUrl\" : \"https://...\"\n } ]\n } ]\n }\n}"
}
}
}
Expand Down Expand Up @@ -907,29 +907,46 @@
}
}
},
"api-v2-members-badges1519826817" : {
"api-v2-members-badges1884183897" : {
"type" : "object",
"properties" : {
"data" : {
"type" : "object",
"properties" : {
"badges" : {
"badgeTypes" : {
"type" : "array",
"description" : "뱃지 목록",
"description" : "뱃지 타입 목록",
"items" : {
"type" : "object",
"properties" : {
"imageUrl" : {
"type" : "string",
"description" : "뱃지 이미지 URL"
"badges" : {
"type" : "array",
"description" : "타입별 뱃지 리스트",
"items" : {
"type" : "object",
"properties" : {
"imageUrl" : {
"type" : "string",
"description" : "뱃지 이미지 URL"
},
"name" : {
"type" : "string",
"description" : "뱃지 이름"
},
"type" : {
"type" : "string",
"description" : "뱃지 타입"
}
}
}
},
"name" : {
"badgeType" : {
"type" : "string",
"description" : "뱃지 이름"
"description" : "뱃지 타입"
},
"type" : {
"badgeTypeName" : {
"type" : "string",
"description" : "뱃지 타입"
"description" : "뱃지 타입 이름"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,13 @@ void success_getBadgesList() throws Exception {
fieldWithPath("success").type(BOOLEAN).description("응답 성공 여부"),
fieldWithPath("message").type(STRING).description("응답 메시지"),
fieldWithPath("data").type(OBJECT).description("응답 데이터"),
fieldWithPath("data.badges").type(ARRAY).description("뱃지 목록"),
fieldWithPath("data.badges[].name").type(STRING).description("뱃지 이름"),
fieldWithPath("data.badges[].type").type(STRING).description("뱃지 타입"),
fieldWithPath("data.badges[].imageUrl").type(STRING).description("뱃지 이미지 URL")
fieldWithPath("data.badgeTypes").type(ARRAY).description("뱃지 타입 목록"),
fieldWithPath("data.badgeTypes[].badgeType").type(STRING).description("뱃지 타입"),
fieldWithPath("data.badgeTypes[].badgeTypeName").type(STRING).description("뱃지 타입 이름"),
fieldWithPath("data.badgeTypes[].badges").type(ARRAY).description("타입별 뱃지 리스트"),
fieldWithPath("data.badgeTypes[].badges[].name").type(STRING).description("뱃지 이름"),
fieldWithPath("data.badgeTypes[].badges[].type").type(STRING).description("뱃지 타입"),
fieldWithPath("data.badgeTypes[].badges[].imageUrl").type(STRING).description("뱃지 이미지 URL")
)
.build();
// when
Expand Down
13 changes: 12 additions & 1 deletion src/test/java/com/smeme/server/fixture/badge/BadgeFixture.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.smeme.server.fixture.badge;

import com.smeme.server.dto.badge.BadgeListResponseDTO;
import com.smeme.server.dto.badge.BadgeListResponseDTO.BadgeTypeResponseDTO;
import com.smeme.server.dto.badge.BadgeResponseDTO;
import com.smeme.server.model.badge.BadgeType;

Expand All @@ -24,7 +25,17 @@ public static BadgeResponseDTO createBadgeResponseDTO() {
}

public static BadgeListResponseDTO createBadgeListResponseDTO() {
return new BadgeListResponseDTO(createBadgeResponses());
return new BadgeListResponseDTO(createBadgeTypesResponse());
}

private static List<BadgeTypeResponseDTO> createBadgeTypesResponse() {
return Stream.iterate(1, i -> i + 1).limit(5)
.map(i -> createBadgeTypeResponse())
.toList();
}

private static BadgeTypeResponseDTO createBadgeTypeResponse() {
return new BadgeTypeResponseDTO(BADGE_TYPE, BADGE_NAME, createBadgeResponses());
}

private static List<BadgeListResponseDTO.BadgeResponseDTO> createBadgeResponses() {
Expand Down
Loading