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,69 @@
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 com.moplus.moplus_server.client.submit.domain.ProgressStatus;
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,
ProgressStatus progressStatus
) {
public static DailyProgressResponse of(LocalDate date, ProgressStatus progressStatus) {
return new DailyProgressResponse(date, progressStatus);
}
}

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,91 @@
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.client.submit.domain.ProgressStatus;
import com.moplus.moplus_server.client.submit.service.ProblemSubmitGetService;
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 static final LocalDate today = LocalDate.now();
private static final LocalDate monday = today.with(DayOfWeek.MONDAY);
private static final LocalDate friday = today.with(DayOfWeek.FRIDAY);
private final ProblemSetStatisticRepository problemSetStatisticRepository;
private final PublishGetService publishGetService;
private final ProblemSetGetService problemSetGetService;
private final ProblemSubmitGetService problemSubmitGetService;

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

List<Publish> publishes = publishGetService.getPublishesBetweenDates(monday, friday);

List<DailyProgressResponse> dailyProgresses = getDailyProgresses(memberId, publishes);
List<ProblemSetHomeFeedResponse> problemSets = getWeekdayProblemSets(publishes);

return HomeFeedResponse.of(dailyProgresses, problemSets);
}

private List<DailyProgressResponse> getDailyProgresses(Long memberId, List<Publish> publishes) {
Map<LocalDate, ProgressStatus> progressStatuses = problemSubmitGetService.getProgressStatuses(memberId,
publishes);

List<DailyProgressResponse> responses = new ArrayList<>();
for (LocalDate date = monday; !date.isAfter(friday); date = date.plusDays(1)) {
ProgressStatus status = progressStatuses.getOrDefault(date, ProgressStatus.NOT_STARTED);
responses.add(DailyProgressResponse.of(date, status));
}

return responses;
}

private List<ProblemSetHomeFeedResponse> getWeekdayProblemSets(List<Publish> publishes) {

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
@@ -0,0 +1,68 @@
package com.moplus.moplus_server.client.problem.controller;

import com.moplus.moplus_server.client.problem.dto.response.AllProblemGetResponse;
import com.moplus.moplus_server.client.problem.dto.response.ChildProblemClientGetResponse;
import com.moplus.moplus_server.client.problem.dto.response.ProblemClientGetResponse;
import com.moplus.moplus_server.client.problem.dto.response.PublishClientGetResponse;
import com.moplus.moplus_server.client.problem.service.ProblemsGetService;
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 java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "클라이언트 문제 조회", description = "클라이언트 문제 조회 관련 API")
@RestController
@RequestMapping("/api/v1/client")
@RequiredArgsConstructor
public class ProblemGetController {

private final ProblemsGetService problemsGetService;

@GetMapping("problem/all/{year}/{month}")
@Operation(summary = "전체 문제 조회", description = "월별 문제들에 대한 진행도와 정보들을 조회합니다.")
public ResponseEntity<List<AllProblemGetResponse>> getAllProblem(
@PathVariable("year") int year,
@PathVariable("month") int month,
@AuthUser Member member
) {
return ResponseEntity.ok(problemsGetService.getAllProblem(member.getId(), year, month));
}

@GetMapping("problem/{publishId}")
@Operation(summary = "특정 발행 속 문항들 조회", description = "사용자에게 보여지는 특정 발행에 속한 문항을 조회합니다.")
public ResponseEntity<PublishClientGetResponse> getProblemsInPublish(
@PathVariable("publishId") Long publishId,
@AuthUser Member member
) {
return ResponseEntity.ok(problemsGetService.getProblemsInPublish(member.getId(), publishId));
}

@GetMapping("problem/{publishId}/{problemId}")
@Operation(summary = "문항 조회", description = "사용자에게 보여지는 문항을 조회합니다.")
public ResponseEntity<ProblemClientGetResponse> getProblem(
@PathVariable("publishId") Long publishId,
@PathVariable("problemId") Long problemId,
@AuthUser Member member
) {
return ResponseEntity.ok(problemsGetService.getProblem(member.getId(), publishId, problemId));
}

@GetMapping("problem/{publishId}/{problemId}/{childProblemId}")
@Operation(summary = "새끼문항 조회", description = "사용자에게 보여지는 새끼문항을 조회합니다.")
public ResponseEntity<ChildProblemClientGetResponse> getChildProblem(
@PathVariable("publishId") Long publishId,
@PathVariable("problemId") Long problemId,
@PathVariable("childProblemId") Long childProblemId,
@AuthUser Member member
) {
return ResponseEntity.ok(
problemsGetService.getChildProblem(member.getId(), publishId, problemId, childProblemId));
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.moplus.moplus_server.client.submit.dto.response;
package com.moplus.moplus_server.client.problem.dto.response;

import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus;
import com.moplus.moplus_server.client.submit.dto.response.DayProgress;
import java.time.LocalDate;
import java.util.List;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.moplus.moplus_server.client.submit.dto.response;
package com.moplus.moplus_server.client.problem.dto.response;

import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmitStatus;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.moplus.moplus_server.client.submit.dto.response;
package com.moplus.moplus_server.client.problem.dto.response;

import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmitStatus;
import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus;
Expand All @@ -15,7 +15,8 @@ public record ProblemClientGetResponse(
ProblemSubmitStatus status,
List<ChildProblemSubmitStatus> childProblemStatuses
) {
public static ProblemClientGetResponse of(Problem problem, ProblemSubmitStatus status, List<ChildProblemSubmitStatus> childProblemStatuses, int number) {
public static ProblemClientGetResponse of(Problem problem, ProblemSubmitStatus status,
List<ChildProblemSubmitStatus> childProblemStatuses, int number) {
return ProblemClientGetResponse.builder()
.number(number)
.imageUrl(problem.getMainProblemImageUrl())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.moplus.moplus_server.client.problem.dto.response;

import com.moplus.moplus_server.client.submit.domain.ChildProblemSubmitStatus;
import com.moplus.moplus_server.client.submit.domain.ProblemSubmitStatus;
import java.util.List;
import lombok.Builder;

@Builder
public record ProblemFeedProgressesGetResponse(
int number,
ProblemSubmitStatus status,
List<ChildProblemSubmitStatus> childProblemStatuses
) {
public static ProblemFeedProgressesGetResponse of(ProblemSubmitStatus status,
List<ChildProblemSubmitStatus> childProblemStatuses, int number) {
return ProblemFeedProgressesGetResponse.builder()
.number(number)
.status(status)
.childProblemStatuses(childProblemStatuses)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.moplus.moplus_server.client.problem.dto.response;

import com.moplus.moplus_server.admin.publish.domain.Publish;
import com.moplus.moplus_server.domain.problemset.domain.ProblemSet;
import java.time.LocalDate;
import java.util.List;
import lombok.Builder;

@Builder
public record PublishClientGetResponse(
Long publishId,
LocalDate date,
String title,
List<ProblemFeedProgressesGetResponse> problems
) {

public static PublishClientGetResponse of(Publish publish, ProblemSet problemSet,
List<ProblemFeedProgressesGetResponse> problems) {
return PublishClientGetResponse.builder()
.publishId(publish.getId())
.date(publish.getPublishedDate())
.title(problemSet.getTitle().getValue())
.problems(problems)
.build();
}
}
Loading