Skip to content

Commit

Permalink
feat: 미션 기록 완료 리스트 (#281)
Browse files Browse the repository at this point in the history
* feat: 미션 기록 완료 리스트

* feat: 미션 기록 완료 리스트 Projection 개선

* refactor: 미션 완료 기록 리스트 조건 및 DTO 수정

* fix: completedAt Type 체크
  • Loading branch information
char-yb authored Sep 29, 2024
1 parent 76dc4b2 commit eaed214
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.depromeet.stonebed.domain.missionRecord.dto.response.MissionRecordCalendarResponse;
import com.depromeet.stonebed.domain.missionRecord.dto.response.MissionRecordCompleteTotal;
import com.depromeet.stonebed.domain.missionRecord.dto.response.MissionRecordIdResponse;
import com.depromeet.stonebed.domain.missionRecord.dto.response.MissionRecordTabListResponse;
import com.depromeet.stonebed.domain.missionRecord.dto.response.MissionTabResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
Expand All @@ -26,6 +27,12 @@ public class MissionRecordController {

private final MissionRecordService missionRecordService;

@Operation(summary = "미션 탭 완료된 기록 리스트", description = "미션 탭에서 완료된 기록 리스트를 조회한다.")
@GetMapping
public MissionRecordTabListResponse missionRecordsFind() {
return missionRecordService.findCompleteMissionRecords();
}

@Operation(summary = "미션 탭 상태 조회", description = "미션 탭의 상태를 조회한다.")
@GetMapping("/status")
public MissionTabResponse getMissionRecordStatus(@RequestParam Long missionId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.depromeet.stonebed.domain.missionRecord.dto.response.MissionRecordCalendarResponse;
import com.depromeet.stonebed.domain.missionRecord.dto.response.MissionRecordCompleteTotal;
import com.depromeet.stonebed.domain.missionRecord.dto.response.MissionRecordIdResponse;
import com.depromeet.stonebed.domain.missionRecord.dto.response.MissionRecordTabListResponse;
import com.depromeet.stonebed.domain.missionRecord.dto.response.MissionTabResponse;
import com.depromeet.stonebed.global.error.ErrorCode;
import com.depromeet.stonebed.global.error.exception.CustomException;
Expand Down Expand Up @@ -246,7 +247,7 @@ public MissionTabResponse getMissionTabStatus(Long missionId) {
mission.getTitle(),
mission.getIllustrationUrl(),
missionRecord.getContent(),
missionRecord.getUpdatedAt().toLocalDate());
missionRecord.getUpdatedAt().toLocalDate().toString());
}

@Transactional(propagation = Propagation.REQUIRES_NEW)
Expand Down Expand Up @@ -275,4 +276,12 @@ public void expiredMissionsToNotCompletedUpdate() {
LocalDateTime endOfYesterday = LocalDate.now().minusDays(1).atTime(23, 59, 59);
missionRecordRepository.updateExpiredMissionsToNotCompleted(endOfYesterday);
}

@Transactional(readOnly = true)
public MissionRecordTabListResponse findCompleteMissionRecords() {
final Member member = memberUtil.getCurrentMember();
return MissionRecordTabListResponse.from(
missionRecordRepository.findAllTabMissionsByMemberAndStatus(
member, MissionRecordStatus.COMPLETED));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.depromeet.stonebed.domain.missionRecord.dao;

import com.depromeet.stonebed.domain.member.domain.Member;
import com.depromeet.stonebed.domain.missionRecord.domain.MissionRecord;
import com.depromeet.stonebed.domain.missionRecord.domain.MissionRecordDisplay;
import com.depromeet.stonebed.domain.missionRecord.domain.MissionRecordStatus;
import com.depromeet.stonebed.domain.missionRecord.dto.response.MissionTabResponse;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.data.domain.Pageable;
Expand All @@ -17,4 +20,7 @@ List<MissionRecord> findByMemberIdAndCreatedAtFromWithPagination(
Pageable pageable);

void updateExpiredMissionsToNotCompleted(LocalDateTime dateTime);

List<MissionTabResponse> findAllTabMissionsByMemberAndStatus(
Member member, MissionRecordStatus status);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
package com.depromeet.stonebed.domain.missionRecord.dao;

import static com.depromeet.stonebed.domain.mission.domain.QMission.*;
import static com.depromeet.stonebed.domain.missionHistory.domain.QMissionHistory.*;
import static com.depromeet.stonebed.domain.missionRecord.domain.QMissionRecord.missionRecord;

import com.depromeet.stonebed.domain.member.domain.Member;
import com.depromeet.stonebed.domain.missionRecord.domain.MissionRecord;
import com.depromeet.stonebed.domain.missionRecord.domain.MissionRecordDisplay;
import com.depromeet.stonebed.domain.missionRecord.domain.MissionRecordStatus;
import com.depromeet.stonebed.domain.missionRecord.dto.response.MissionTabResponse;
import com.querydsl.core.types.ConstantImpl;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.DateTemplate;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand All @@ -24,7 +33,7 @@ public List<MissionRecord> findByMemberIdWithPagination(
Long memberId, List<MissionRecordDisplay> displays, Pageable pageable) {
return queryFactory
.selectFrom(missionRecord)
.where(isMemberId(memberId).and(InDisplays(displays)))
.where(isMemberId(memberId).and(inDisplays(displays)))
.orderBy(missionRecord.createdAt.asc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
Expand All @@ -43,7 +52,7 @@ public List<MissionRecord> findByMemberIdAndCreatedAtFromWithPagination(
isMemberId(memberId)
.and(createdAtFrom(createdAt))
.and(isCompleted())
.and(InDisplays(displays)))
.and(inDisplays(displays)))
.orderBy(missionRecord.createdAt.asc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
Expand All @@ -64,6 +73,51 @@ public void updateExpiredMissionsToNotCompleted(LocalDateTime currentTime) {
.execute();
}

@Override
public List<MissionTabResponse> findAllTabMissionsByMemberAndStatus(
Member member, MissionRecordStatus status) {
DateTemplate<String> completedAt =
Expressions.dateTemplate(
String.class,
"DATE_FORMAT({0}, {1})",
missionRecord.updatedAt,
ConstantImpl.create("%Y-%m-%d"));

DateTemplate<Integer> year =
Expressions.dateTemplate(Integer.class, "YEAR({0})", missionRecord.updatedAt);
DateTemplate<Integer> month =
Expressions.dateTemplate(Integer.class, "MONTH({0})", missionRecord.updatedAt);

int currentYear = LocalDate.now().getYear();
int currentMonth = LocalDate.now().getMonthValue();

return queryFactory
.select(
Projections.constructor(
MissionTabResponse.class,
missionRecord.id.as("recordId"),
missionRecord.imageUrl,
missionRecord.status,
mission.title.as("missionTitle"),
mission.illustrationUrl,
missionRecord.content,
completedAt))
.from(missionRecord)
.leftJoin(missionRecord.missionHistory, missionHistory)
.on(missionHistory.id.eq(missionRecord.missionHistory.id))
.leftJoin(missionHistory.mission, mission)
.on(mission.id.eq(missionHistory.mission.id))
.where(
missionRecord
.member
.eq(member)
.and(missionRecord.status.eq(status))
.and(year.eq(currentYear))
.and(month.eq(currentMonth)))
.orderBy(missionRecord.updatedAt.desc())
.fetch();
}

private BooleanExpression isMemberId(Long memberId) {
return missionRecord.member.id.eq(memberId);
}
Expand All @@ -76,7 +130,7 @@ private BooleanExpression isCompleted() {
return missionRecord.status.eq(MissionRecordStatus.COMPLETED);
}

private BooleanExpression InDisplays(List<MissionRecordDisplay> displays) {
private BooleanExpression inDisplays(List<MissionRecordDisplay> displays) {
return missionRecord.display.in(displays);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.depromeet.stonebed.domain.missionRecord.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;

public record MissionRecordTabListResponse(
@Schema(
description = "미션 탭 목록",
example =
"["
+ "{"
+ "\"recordId\": 1,"
+ "\"imageUrl\": \"example.jpeg\","
+ "\"status\": \"NOT_COMPLETED\","
+ "\"missionTitle\": \"산책하기\","
+ "\"illustrationUrl\": \"example.jpeg\","
+ "\"content\": \"오늘 마실다녀왔어요\","
+ "\"completedAt\": \"2021-10-10\""
+ "}"
+ "]")
List<MissionTabResponse> list) {
public static MissionRecordTabListResponse from(List<MissionTabResponse> list) {
return new MissionRecordTabListResponse(list);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.depromeet.stonebed.domain.missionRecord.dto.response;

import com.depromeet.stonebed.domain.missionRecord.domain.MissionRecordStatus;
import com.querydsl.core.annotations.QueryProjection;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate;

public record MissionTabResponse(
@Schema(description = "기록 ID", example = "1") Long recordId,
Expand All @@ -11,7 +11,25 @@ public record MissionTabResponse(
@Schema(description = "미션 제목", example = "산책하기") String missionTitle,
@Schema(description = "미션 일러스트 이미지", example = "example.jpeg") String illustrationUrl,
@Schema(description = "기록 내용", example = "오늘 마실다녀왔어요") String content,
@Schema(description = "완료 일자", example = "2021-10-10") LocalDate completedAt) {
@Schema(description = "완료 일자", example = "2021-10-10") String completedAt) {

@QueryProjection
public MissionTabResponse(
Long recordId,
String imageUrl,
MissionRecordStatus status,
String missionTitle,
String illustrationUrl,
String content,
String completedAt) {
this.recordId = recordId;
this.imageUrl = imageUrl;
this.status = status;
this.missionTitle = missionTitle;
this.illustrationUrl = illustrationUrl;
this.content = content;
this.completedAt = completedAt;
}

public static MissionTabResponse of(
Long recordId,
Expand All @@ -20,7 +38,7 @@ public static MissionTabResponse of(
String missionTitle,
String illustrationUrl,
String content,
LocalDate completedAt) {
String completedAt) {
return new MissionTabResponse(
recordId, imageUrl, status, missionTitle, illustrationUrl, content, completedAt);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,8 @@ class MissionRecordServiceTest extends FixtureMonkeySetUp {
then(response.imageUrl()).isEqualTo(missionRecord.getImageUrl());
then(response.status()).isEqualTo(MissionRecordStatus.COMPLETED);
then(response.recordId()).isEqualTo(missionRecord.getId());
then(response.completedAt()).isEqualTo(missionRecord.getUpdatedAt().toLocalDate());
then(response.completedAt())
.isEqualTo(missionRecord.getUpdatedAt().toLocalDate().toString());
then(response.content()).isEqualTo(missionRecord.getContent());

verify(memberUtil).getCurrentMember();
Expand Down

0 comments on commit eaed214

Please sign in to comment.