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

[OING-323] feat: 일간 캘린더 API 추가 #244

Merged
merged 6 commits into from
Apr 28, 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
4 changes: 4 additions & 0 deletions common/src/main/java/com/oing/service/MemberBridge.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.oing.service;

import java.util.List;

/**
* no5ing-server
* User: CChuYong
Expand Down Expand Up @@ -31,4 +33,6 @@ public interface MemberBridge {
* @return 삭제된 사용자인지 여부
*/
boolean isDeletedMember(String memberId);

List<String> getFamilyMembersIdsByFamilyId(String familyId);
}
4 changes: 4 additions & 0 deletions common/src/main/java/com/oing/service/MissionBridge.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package com.oing.service;

import java.time.LocalDate;

public interface MissionBridge {

String getContentByMissionId(String missionId);

String getContentByDate(LocalDate date);

String getTodayMissionId();
}
68 changes: 52 additions & 16 deletions gateway/src/main/java/com/oing/controller/CalendarController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,32 @@
import com.oing.domain.BannerImageType;
import com.oing.domain.Post;
import com.oing.domain.PostType;
import com.oing.dto.response.ArrayResponse;
import com.oing.dto.response.BannerResponse;
import com.oing.dto.response.CalendarResponse;
import com.oing.dto.response.FamilyMonthlyStatisticsResponse;
import com.oing.dto.response.*;
import com.oing.restapi.CalendarApi;
import com.oing.service.FamilyService;
import com.oing.service.MemberService;
import com.oing.service.PostService;
import com.oing.service.*;
import com.oing.util.OptimizedImageUrlGenerator;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

import static com.oing.domain.PostType.MISSION;
import static com.oing.domain.PostType.SURVIVAL;

@Controller
@RequiredArgsConstructor
public class CalendarController implements CalendarApi {

private final PostController postController;
private final MissionBridge missionBridge;
private final MemberBridge memberBridge;

private final MemberService memberService;
private final PostService postService;
private final FamilyService familyService;
Expand All @@ -32,19 +37,49 @@ public class CalendarController implements CalendarApi {


@Override
public ArrayResponse<CalendarResponse> getMonthlyCalendar(String yearMonth, String familyId) {
public ArrayResponse<DailyCalendarResponse> getDailyCalendar(String yearMonthDay, String loginMemberId, String loginFamilyId) {
List<DailyCalendarResponse> dailyCalendarResponses = new ArrayList<>();
LocalDate date = LocalDate.parse(yearMonthDay, DateTimeFormatter.ISO_DATE);

Collection<PostResponse> survivalPosts = postController.fetchDailyFeeds(1, 10, date, null, "ASC", SURVIVAL, loginMemberId, true).results();
Collection<PostResponse> missionPosts = postController.fetchDailyFeeds(1, 10, date, null, "ASC", MISSION, loginMemberId, true).results();
String missionContent = missionBridge.getContentByDate(date);
boolean allFamilyMembersUploaded = getAllFamilyMembersUploaded(survivalPosts, loginFamilyId);

dailyCalendarResponses.addAll(convertToDailyCalendarResponse(survivalPosts, missionContent, allFamilyMembersUploaded));
dailyCalendarResponses.addAll(convertToDailyCalendarResponse(missionPosts, missionContent, allFamilyMembersUploaded));
return ArrayResponse.of(dailyCalendarResponses);
}

private boolean getAllFamilyMembersUploaded(Collection<PostResponse> survivalPosts, String familyId) {
HashSet<String> uploadedFamilyMembers = survivalPosts.stream().map(PostResponse::authorId).collect(Collectors.toCollection(HashSet::new));
List<String> familyMembersIds = memberService.getFamilyMembersIdsByFamilyIdAndJoinAtBefore(familyId, LocalDate.now());

return uploadedFamilyMembers.containsAll(familyMembersIds);
}

private List<DailyCalendarResponse> convertToDailyCalendarResponse(Collection<PostResponse> posts, String missionContent, boolean allFamilyMembersUploaded) {
return posts.stream().map(post -> switch (PostType.fromString(post.type())) {
case MISSION -> new DailyCalendarResponse(post.createdAt().toLocalDate(), MISSION, post.postId(), post.imageUrl(), missionContent, allFamilyMembersUploaded);
case SURVIVAL -> new DailyCalendarResponse(post.createdAt().toLocalDate(), SURVIVAL, post.postId(), post.imageUrl(), null, allFamilyMembersUploaded);
}).toList();
}


@Override
public ArrayResponse<MonthlyCalendarResponse> getMonthlyCalendar(String yearMonth, String familyId) {
if (yearMonth == null) yearMonth = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));

LocalDate startDate = LocalDate.parse(yearMonth + "-01"); // yyyy-MM-dd 패턴으로 파싱
LocalDate endDate = startDate.plusMonths(1);

List<Post> daysLatestPosts = postService.findLatestPostOfEveryday(startDate, endDate, familyId);
List<CalendarResponse> calendarResponses = convertToCalendarResponse(daysLatestPosts, familyId);
return new ArrayResponse<>(calendarResponses);
List<MonthlyCalendarResponse> monthlyCalendarRespons = convertToMonthlyCalendarResponse(daysLatestPosts, familyId);
return new ArrayResponse<>(monthlyCalendarRespons);
}

private List<CalendarResponse> convertToCalendarResponse(List<Post> daysLatestPosts, String familyId) {
List<CalendarResponse> calendarResponses = new ArrayList<>();
private List<MonthlyCalendarResponse> convertToMonthlyCalendarResponse(List<Post> daysLatestPosts, String familyId) {
List<MonthlyCalendarResponse> monthlyCalendarRespons = new ArrayList<>();

for (Post dayLatestPost : daysLatestPosts) {
LocalDate postDate = dayLatestPost.getCreatedAt().toLocalDate();
Expand All @@ -54,20 +89,20 @@ private List<CalendarResponse> convertToCalendarResponse(List<Post> daysLatestPo
List<String> familyMembersIds = memberService.getFamilyMembersIdsByFamilyIdAndJoinAtBefore(familyId, postDate.plusDays(1));
boolean allFamilyMembersUploaded = true;
for (String memberId : familyMembersIds) {
if (!postService.existsByMemberIdAndFamilyIdAndTypeAndCreatedAt(memberId, familyId, PostType.SURVIVAL, postDate)) {
if (!postService.existsByMemberIdAndFamilyIdAndTypeAndCreatedAt(memberId, familyId, SURVIVAL, postDate)) {
allFamilyMembersUploaded = false;
break;
}
}

calendarResponses.add(new CalendarResponse(
monthlyCalendarRespons.add(new MonthlyCalendarResponse(
dayLatestPost.getCreatedAt().toLocalDate(),
dayLatestPost.getId(),
optimizedImageUrlGenerator.getThumbnailUrlGenerator(dayLatestPost.getPostImgUrl()),
allFamilyMembersUploaded
));
}
return calendarResponses;
return monthlyCalendarRespons;
}


Expand Down Expand Up @@ -98,7 +133,7 @@ public BannerResponse getBanner(String yearMonth, String familyId) {
if (postService.existsByFamilyIdAndCreatedAt(familyId, startDate)) {
List<String> familyMembersIds = memberService.getFamilyMembersIdsByFamilyIdAndJoinAtBefore(familyId, startDate.plusDays(1));
for (String memberId : familyMembersIds) {
if (!postService.existsByMemberIdAndFamilyIdAndTypeAndCreatedAt(memberId, familyId, PostType.SURVIVAL, startDate)) {
if (!postService.existsByMemberIdAndFamilyIdAndTypeAndCreatedAt(memberId, familyId, SURVIVAL, startDate)) {
allFamilyMembersUploaded = false;
break;
}
Expand Down Expand Up @@ -162,6 +197,7 @@ private BannerImageType getBannerImageType(int familyLevel) {
return bannerImageType;
}


@Override
public FamilyMonthlyStatisticsResponse getSummary(String yearMonth, String loginMemberId) {
String[] yearMonthArray = yearMonth.split("-");
Expand Down
20 changes: 18 additions & 2 deletions gateway/src/main/java/com/oing/restapi/CalendarApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,25 @@
@RequestMapping("/v1/calendar")
public interface CalendarApi {

@Operation(summary = "월별 캘린더 조회", description = "월별로 캘린더를 조회합니다. 각 날짜의 대표 게시글 정보와 가족 구성원 전부의 업로드 여부가가 조회되며, 해당 날짜에 게시글이 있는 경우만 response 에 포함됩니다.")
@Operation(summary = "일간 캘린더 조회", description = "일간 캘린더를 조회합니다. 주어진 날에 업로드된 게시글들이 조회되며 정책에 따라, 게시일자 오름차순 / 생존신고 게시글 → 미션 게시글 순서로 정렬됩니다.")
@GetMapping(params = {"type=DAILY"})
ArrayResponse<DailyCalendarResponse> getDailyCalendar(
@RequestParam
@Parameter(description = "조회할 년월일", example = "2021-12-25")
String yearMonthDay,

@Parameter(hidden = true)
@LoginMemberId
String loginMemberId,

@Parameter(hidden = true)
@LoginFamilyId
String loginFamilyId
);

@Operation(summary = "월간 캘린더 조회", description = "월간 캘린더를 조회합니다. 각 날짜의 대표 게시글 정보와 가족 구성원 전부의 업로드 여부가가 조회되며, 해당 날짜에 게시글이 있는 경우만 response 에 포함됩니다.")
@GetMapping(params = {"type=MONTHLY"})
ArrayResponse<CalendarResponse> getMonthlyCalendar(
ArrayResponse<MonthlyCalendarResponse> getMonthlyCalendar(
@RequestParam
@Parameter(description = "조회할 년월", example = "2021-12")
String yearMonth,
Expand Down
9 changes: 9 additions & 0 deletions gateway/src/main/java/com/oing/service/MemberBridgeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

/**
* no5ing-server
* User: CChuYong
Expand Down Expand Up @@ -48,4 +50,11 @@ public boolean isInSameFamily(String memberIdFirst, String memberIdSecond) {
public boolean isDeletedMember(String memberId) {
return memberRepository.existsByIdAndDeletedAtNotNull(memberId);
}

@Override
public List<String> getFamilyMembersIdsByFamilyId(String familyId) {
return memberRepository.findAllByFamilyIdAndDeletedAtIsNull(familyId).stream()
.map(Member::getId)
.toList();
}
}
5 changes: 5 additions & 0 deletions gateway/src/main/java/com/oing/service/MissionBridgeImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public String getContentByMissionId(String missionId) {
return missionService.getMissionByMissionId(missionId).getContent();
}

@Override
public String getContentByDate(LocalDate date) {
return missionService.getMissionByDate(date).content();
}

@Override
public String getTodayMissionId() {
LocalDate today = ZonedDateTime.now().toLocalDate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.oing.domain.Post;
import com.oing.domain.PostType;
import com.oing.dto.response.ArrayResponse;
import com.oing.dto.response.CalendarResponse;
import com.oing.dto.response.MonthlyCalendarResponse;
import com.oing.service.MemberService;
import com.oing.service.PostService;
import com.oing.util.OptimizedImageUrlGenerator;
Expand Down Expand Up @@ -60,7 +60,7 @@ class CalendarControllerTest {


@Test
void 월별_캘린더_조회_테스트() {
void 월간_캘린더_조회_테스트() {
// Given
String yearMonth = "2023-11";
String familyId = testMember1.getFamilyId();
Expand Down Expand Up @@ -111,11 +111,11 @@ class CalendarControllerTest {
when(postService.findLatestPostOfEveryday(startDate, endDate, familyId)).thenReturn(representativePosts);

// When
ArrayResponse<CalendarResponse> weeklyCalendar = calendarController.getMonthlyCalendar(yearMonth, familyId);
ArrayResponse<MonthlyCalendarResponse> weeklyCalendar = calendarController.getMonthlyCalendar(yearMonth, familyId);

// Then
assertThat(weeklyCalendar.results())
.extracting(CalendarResponse::representativePostId)
.extracting(MonthlyCalendarResponse::representativePostId)
.containsExactly("1", "2", "3", "4");
}
}
Loading
Loading