Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2025-03-14T20:25:51+0900",
date = "2025-03-24T01:02:22+0900",
comments = "version: 1.6.3, compiler: javac, environment: Java 17.0.10 (JetBrains s.r.o.)"
)
@Component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2025-03-15T21:23:23+0900",
date = "2025-03-24T01:02:22+0900",
comments = "version: 1.6.3, compiler: javac, environment: Java 17.0.10 (JetBrains s.r.o.)"
)
@Component
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.moplus.moplus_server.admin.publish.service;

import com.moplus.moplus_server.domain.problemset.domain.ProblemSet;
import com.moplus.moplus_server.domain.problemset.repository.ProblemSetRepository;
import com.moplus.moplus_server.admin.publish.domain.Publish;
import com.moplus.moplus_server.admin.publish.dto.response.PublishMonthGetResponse;
import com.moplus.moplus_server.admin.publish.dto.response.PublishProblemSetResponse;
import com.moplus.moplus_server.domain.problemset.domain.ProblemSet;
import com.moplus.moplus_server.domain.problemset.repository.ProblemSetRepository;
import com.moplus.moplus_server.domain.publish.repository.PublishRepository;
import com.moplus.moplus_server.global.error.exception.ErrorCode;
import com.moplus.moplus_server.global.error.exception.InvalidValueException;
Expand Down Expand Up @@ -42,6 +42,7 @@ public List<PublishMonthGetResponse> getPublishMonth(int year, int month) {
.collect(Collectors.toList());
}


private Map<Long, ProblemSet> getProblemSetMap(List<Publish> publishes) {
List<Long> problemSetIds = publishes.stream()
.map(Publish::getProblemSetId)
Expand All @@ -62,4 +63,9 @@ private PublishMonthGetResponse convertToResponse(Publish publish, Map<Long, Pro
PublishProblemSetResponse.of(problemSet)
);
}

@Transactional(readOnly = true)
public List<Publish> getPublishesBetweenDates(LocalDate startDate, LocalDate endDate) {
return publishRepository.findByPublishedDateBetween(startDate, endDate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.moplus.moplus_server.client.homefeed.controller;

import com.moplus.moplus_server.client.homefeed.dto.response.HomeFeedResponse;
import com.moplus.moplus_server.client.homefeed.service.HomeFeedFacadeService;
import com.moplus.moplus_server.global.annotation.AuthUser;
import com.moplus.moplus_server.member.domain.Member;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "홈 피드 조회", description = "홈 피드 관련 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/client/home-feed")
public class HomeFeedController {

private final HomeFeedFacadeService homeFeedFacadeService;

@Operation(summary = "홈 피드 조회", description = "회원의 홈 피드 정보를 조회합니다.")
@GetMapping("")
public HomeFeedResponse getHomeFeed(@AuthUser Member member) {
return homeFeedFacadeService.getHomeFeed(member);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.moplus.moplus_server.client.homefeed.dto.response;

import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSetGetResponse;
import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSummaryResponse;
import java.time.LocalDate;
import java.util.List;

public record HomeFeedResponse(
List<DailyProgressResponse> dailyProgresses,
List<ProblemSetHomeFeedResponse> problemSets
) {
public static HomeFeedResponse of(
List<DailyProgressResponse> dailyProgresses,
List<ProblemSetHomeFeedResponse> problemSets
) {
return new HomeFeedResponse(dailyProgresses, problemSets);
}

public record DailyProgressResponse(
LocalDate date,
double progressRate
) {
public static DailyProgressResponse of(LocalDate date, double progressRate) {
return new DailyProgressResponse(date, progressRate);
}
}
Comment on lines +19 to +26
Copy link
Contributor

Choose a reason for hiding this comment

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

오 record안에 또 record를 만들 수 있군요... 어차피 해당 응답 Dto에서만 사용하는 Dto들은 한 곳에 모아둔걸까요?


public record ProblemSetHomeFeedResponse(
LocalDate date,
Long problemSetId,
String title,
Long submitCount,
ProblemHomeFeedResponse problemHomeFeedResponse
) {
public static ProblemSetHomeFeedResponse of(LocalDate date, ProblemSetGetResponse problemSetGetResponse,
Long submitCount) {
return new ProblemSetHomeFeedResponse(
date,
problemSetGetResponse.id(),
problemSetGetResponse.title(),
submitCount,
ProblemHomeFeedResponse.of(problemSetGetResponse.problemSummaries().get(0))
);
}

public static ProblemSetHomeFeedResponse of(LocalDate date) {
return new ProblemSetHomeFeedResponse(
date,
null,
null,
null,
null
);
}
}

public record ProblemHomeFeedResponse(
Long problemId,
String mainProblemImageUrl
) {
public static ProblemHomeFeedResponse of(ProblemSummaryResponse problemSummaryResponse) {
return new ProblemHomeFeedResponse(
problemSummaryResponse.problemId(),
problemSummaryResponse.mainProblemImageUrl()
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.moplus.moplus_server.client.homefeed.service;

import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSetGetResponse;
import com.moplus.moplus_server.admin.publish.domain.Publish;
import com.moplus.moplus_server.admin.publish.service.PublishGetService;
import com.moplus.moplus_server.client.homefeed.dto.response.HomeFeedResponse;
import com.moplus.moplus_server.client.homefeed.dto.response.HomeFeedResponse.DailyProgressResponse;
import com.moplus.moplus_server.client.homefeed.dto.response.HomeFeedResponse.ProblemSetHomeFeedResponse;
import com.moplus.moplus_server.domain.problemset.service.ProblemSetGetService;
import com.moplus.moplus_server.member.domain.Member;
import com.moplus.moplus_server.statistic.Problem.domain.ProblemSetStatistic;
import com.moplus.moplus_server.statistic.Problem.repository.ProblemSetStatisticRepository;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class HomeFeedFacadeService {

private final ProblemSetStatisticRepository problemSetStatisticRepository;
private final PublishGetService publishGetService;
private final ProblemSetGetService problemSetGetService;

@Transactional(readOnly = true)
public HomeFeedResponse getHomeFeed(Member member) {
Long memberId = member.getId();

List<DailyProgressResponse> dailyProgresses = new ArrayList<>(); // 다음 PR에서 구현
List<ProblemSetHomeFeedResponse> problemSets = getWeekdayProblemSets();

return HomeFeedResponse.of(dailyProgresses, problemSets);
}

private List<ProblemSetHomeFeedResponse> getWeekdayProblemSets() {
LocalDate today = LocalDate.now();
LocalDate monday = today.with(DayOfWeek.MONDAY);
LocalDate friday = today.with(DayOfWeek.FRIDAY);

// 월요일부터 금요일까지의 발행된 문제 세트 조회
List<Publish> publishes = publishGetService.getPublishesBetweenDates(monday, friday);
Map<LocalDate, Publish> publishByDate = publishes.stream()
.collect(Collectors.toMap(Publish::getPublishedDate, publish -> publish));

// 문제 세트 정보 조회
List<Long> problemSetIds = publishes.stream()
.map(Publish::getProblemSetId)
.toList();
Map<Long, ProblemSetGetResponse> problemSetMap = problemSetGetService.getProblemSets(problemSetIds).stream()
.collect(Collectors.toMap(ProblemSetGetResponse::id, response -> response));

// 월요일부터 금요일까지의 모든 날짜에 대한 응답 생성
List<ProblemSetHomeFeedResponse> responses = new ArrayList<>();
for (LocalDate date = monday; !date.isAfter(friday); date = date.plusDays(1)) {
Publish publish = publishByDate.get(date);
if (publish != null) {
ProblemSetGetResponse problemSet = problemSetMap.get(publish.getProblemSetId());
Long submitCount = problemSetStatisticRepository.findById(problemSet.id())
.map(ProblemSetStatistic::getSubmitCount)
.orElse(0L);
responses.add(ProblemSetHomeFeedResponse.of(date, problemSet, submitCount));
} else {
responses.add(ProblemSetHomeFeedResponse.of(date));
}
}

return responses;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ public interface ProblemSubmitRepository extends JpaRepository<ProblemSubmit, Lo

Optional<ProblemSubmit> findByMemberIdAndPublishIdAndProblemId(Long memberId, Long publishId, Long problemId);

default ProblemSubmit findByMemberIdAndPublishIdAndProblemIdElseThrow(Long memberId, Long publishId, Long problemId) {
default ProblemSubmit findByMemberIdAndPublishIdAndProblemIdElseThrow(Long memberId, Long publishId,
Long problemId) {
return findByMemberIdAndPublishIdAndProblemId(memberId, publishId, problemId).orElseThrow(
() -> new NotFoundException(ErrorCode.PROBLEM_SUBMIT_NOT_CONFIRMED));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package com.moplus.moplus_server.domain.problemset.service;

import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSetGetResponse;
import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSummaryResponse;
import com.moplus.moplus_server.admin.publish.domain.Publish;
import com.moplus.moplus_server.domain.concept.domain.ConceptTag;
import com.moplus.moplus_server.domain.concept.repository.ConceptTagRepository;
import com.moplus.moplus_server.domain.problem.domain.problem.Problem;
import com.moplus.moplus_server.domain.problem.repository.ProblemRepository;
import com.moplus.moplus_server.domain.problemset.domain.ProblemSet;
import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSetGetResponse;
import com.moplus.moplus_server.admin.problemset.dto.response.ProblemSummaryResponse;
import com.moplus.moplus_server.domain.problemset.repository.ProblemSetRepository;
import com.moplus.moplus_server.admin.publish.domain.Publish;
import com.moplus.moplus_server.domain.publish.repository.PublishRepository;
import com.moplus.moplus_server.global.error.exception.BusinessException;
import com.moplus.moplus_server.global.error.exception.ErrorCode;
Expand Down Expand Up @@ -55,4 +55,11 @@ public ProblemSetGetResponse getProblemSet(Long problemSetId) {
}
return ProblemSetGetResponse.of(problemSet, publishedDates, problemSummaries);
}

@Transactional(readOnly = true)
public List<ProblemSetGetResponse> getProblemSets(List<Long> problemSetIds) {
return problemSetIds.stream()
.map(this::getProblemSet)
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.moplus.moplus_server.statistic.Problem.service;

import com.moplus.moplus_server.statistic.Problem.repository.ProblemSetStatisticRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class CountStatisticsGetService {

private final ProblemSetStatisticRepository problemSetStatisticRepository;

@Transactional(readOnly = true)
public Long getProblemSetCount(Long id) {
return problemSetStatisticRepository.findByIdElseThrow(id).getSubmitCount();
}
}