-
Notifications
You must be signed in to change notification settings - Fork 0
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
feat: 미션 상태 업데이트 배치 스케줄러 구현 #81
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,5 @@ | ||
package com.nexters.goalpanzi.application.mission; | ||
|
||
import com.nexters.goalpanzi.application.mission.dto.request.MissionFilter; | ||
import com.nexters.goalpanzi.application.mission.dto.response.MemberRankResponse; | ||
import com.nexters.goalpanzi.application.mission.dto.response.MissionDetailResponse; | ||
import com.nexters.goalpanzi.application.mission.dto.response.MissionsResponse; | ||
|
@@ -22,7 +21,6 @@ | |
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.util.List; | ||
import java.util.Objects; | ||
|
||
@Transactional(readOnly = true) | ||
@RequiredArgsConstructor | ||
|
@@ -60,23 +58,22 @@ private void validateAlreadyJoin(final Member member, final Mission mission) { | |
}); | ||
} | ||
|
||
public MissionsResponse findAllByMemberId(final Long memberId, final List<MissionFilter> filter) { | ||
public MissionsResponse findAllByMemberId(final Long memberId, final List<MissionStatus> filter) { | ||
Member member = memberRepository.getMember(memberId); | ||
List<MissionMember> missionMembers = missionMemberRepository.findAllWithMissionByMemberId(memberId) | ||
List<MissionMember> missionMembers = missionMemberRepository.findAllWithMissionByMemberId(memberId); | ||
if (filter == null || filter.isEmpty()) { | ||
return MissionsResponse.of(member, missionMembers); | ||
} | ||
|
||
List<MissionMember> filteredMissionMembers = missionMembers | ||
.stream() | ||
.filter(it -> isMissionStatusMatching(filter, it.getMission())) | ||
.filter(it -> isMissionStatusMatching(filter, it)) | ||
.toList(); | ||
return MissionsResponse.of(member, missionMembers); | ||
return MissionsResponse.of(member, filteredMissionMembers); | ||
} | ||
|
||
private boolean isMissionStatusMatching(final List<MissionFilter> filters, final Mission mission) { | ||
for (MissionFilter filter : filters) { | ||
MissionStatus missionStatus = filter.toMissionStatus(); | ||
if (missionStatus != null && Objects.equals(missionStatus, MissionStatus.fromMission(mission))) { | ||
return true; | ||
} | ||
} | ||
return filters.isEmpty(); | ||
private boolean isMissionStatusMatching(final List<MissionStatus> filters, final MissionMember missionMember) { | ||
return filters.contains(missionMember.getMissionStatus()); | ||
} | ||
|
||
@Transactional | ||
|
@@ -99,4 +96,17 @@ public MemberRankResponse getMissionRank(final Long missionId, final Long member | |
|
||
return MemberRankResponse.from(memberRanks.getRankByMember(member)); | ||
} | ||
|
||
@Transactional | ||
public void batchUpdateStatus() { | ||
List<Mission> missions = missionRepository.findAll(); | ||
missions.forEach(mission -> { | ||
List<MissionMember> missionMembers = missionMemberRepository.findAllByMissionId(mission.getId()); | ||
int memberCount = missionMembers.size(); | ||
missionMembers | ||
.forEach(missionMember -> { | ||
missionMember.updateMissionStatus(mission, memberCount); | ||
}); | ||
}); | ||
} | ||
Comment on lines
+101
to
+111
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍👍 |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -84,4 +84,9 @@ private void validateAuthority(final Long memberId, final Mission mission) { | |
throw new ForbiddenException(ErrorCode.CANNOT_DELETE_MISSION); | ||
} | ||
} | ||
|
||
@Transactional | ||
public void batchUpdate(final Long missionId) { | ||
|
||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 메서드는 아직 구현 전인가용?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아 이거 지워놓을게 ! |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,14 @@ | ||
package com.nexters.goalpanzi.application.mission.dto.response; | ||
|
||
import com.nexters.goalpanzi.domain.mission.MissionStatus; | ||
import io.swagger.v3.oas.annotations.media.Schema; | ||
|
||
public record MissionResponse( | ||
@Schema(description = "미션 ID", requiredMode = Schema.RequiredMode.REQUIRED) | ||
Long missionId, | ||
@Schema(description = "목표 행동", requiredMode = Schema.RequiredMode.REQUIRED) | ||
String description | ||
String description, | ||
@Schema(description = "미션 상태", requiredMode = Schema.RequiredMode.REQUIRED) | ||
MissionStatus missionStatus | ||
) { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,13 +14,14 @@ public record MissionsResponse( | |
List<MissionResponse> missions | ||
) { | ||
|
||
public static MissionsResponse of(Member member, List<MissionMember> missionVerifications) { | ||
public static MissionsResponse of(Member member, List<MissionMember> missionMembers) { | ||
return new MissionsResponse( | ||
new ProfileResponse(member.getNickname(), member.getCharacterType()), | ||
missionVerifications.stream() | ||
missionMembers.stream() | ||
.map(missionVerification -> new MissionResponse( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기 iterator 부분 |
||
missionVerification.getMission().getId(), | ||
missionVerification.getMission().getDescription()) | ||
missionVerification.getMission().getDescription(), | ||
missionVerification.getMissionStatus()) | ||
) | ||
.toList() | ||
); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,12 +4,23 @@ | |
import lombok.Getter; | ||
|
||
import java.time.LocalDateTime; | ||
import java.util.List; | ||
|
||
import static com.nexters.goalpanzi.exception.ErrorCode.UNKNOWN_MISSION; | ||
|
||
@Getter | ||
public enum MissionStatus { | ||
|
||
PENDING("대기"), | ||
ONGOING("진행중"), | ||
// 미션 시작 전 | ||
CREATED("생성"), | ||
|
||
// 미션 진행 기간, | ||
CANCELED("취소"), | ||
IN_PROGRESS("진행중"), | ||
DELETED("삭제"), | ||
|
||
// 미션 종료일 이후 | ||
PENDING_COMPLETION("종료 대기"), | ||
COMPLETED("완료"); | ||
|
||
private final String description; | ||
|
@@ -18,21 +29,35 @@ public enum MissionStatus { | |
this.description = description; | ||
} | ||
|
||
public static MissionStatus fromMission(final Mission mission) { | ||
public static MissionStatus fromMission( | ||
final Mission mission, | ||
final Integer currentMemberCount, | ||
final MissionMember missionMember | ||
) { | ||
LocalDateTime now = LocalDateTime.now(); | ||
LocalDateTime missionStart = TimeUtil.combineDateAndTime( | ||
mission.getMissionStartDate(), TimeUtil.of(mission.getUploadStartTime()) | ||
); | ||
LocalDateTime missionEnd = TimeUtil.combineDateAndTime( | ||
mission.getMissionEndDate(), TimeUtil.of(mission.getUploadEndTime()) | ||
); | ||
LocalDateTime missionStart = mission.getMissionUploadStartDateTime(); | ||
LocalDateTime missionEnd = mission.getMissionUploadEndDateTime(); | ||
|
||
if (now.isBefore(missionStart)) { | ||
return PENDING; | ||
} else if (now.isAfter(missionEnd)) { | ||
return CREATED; | ||
} | ||
|
||
if (mission.isMissionPeriod() && currentMemberCount <= 1) { | ||
return CANCELED; | ||
} | ||
|
||
if (mission.isMissionPeriod() && currentMemberCount > 1) { | ||
return IN_PROGRESS; | ||
} | ||
|
||
if (now.isAfter(missionEnd) && !missionMember.getCheckCompleted()) { | ||
return PENDING_COMPLETION; | ||
} | ||
|
||
if (now.isAfter(missionEnd) && missionMember.getCheckCompleted()) { | ||
return COMPLETED; | ||
} else { | ||
return ONGOING; | ||
} | ||
Comment on lines
41
to
59
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍👍 |
||
|
||
throw new IllegalArgumentException(UNKNOWN_MISSION.getMessage(mission, missionMember)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.nexters.goalpanzi.schedule; | ||
|
||
import org.quartz.Job; | ||
import org.quartz.JobBuilder; | ||
import org.quartz.JobDetail; | ||
import org.quartz.ScheduleBuilder; | ||
import org.quartz.Trigger; | ||
import org.quartz.TriggerBuilder; | ||
import org.springframework.scheduling.quartz.QuartzJobBean; | ||
|
||
public abstract class AbstractJob<T extends Trigger> extends QuartzJobBean implements Job { | ||
|
||
private static final String JOB_PREFIX = "MissionMateService-Job-"; | ||
private static final String TRIGGER_PREFIX = "MissionMate-Trigger-"; | ||
|
||
public JobDetail getJobDetail() { | ||
return JobBuilder.newJob(this.getClass()) | ||
.withIdentity(JOB_PREFIX + this.getClass().getSimpleName()) | ||
.build(); | ||
} | ||
|
||
public Trigger getTrigger() { | ||
return TriggerBuilder.newTrigger() | ||
.withSchedule(getScheduleBuilder()) | ||
.withIdentity(TRIGGER_PREFIX + this.getClass().getSimpleName()) | ||
.build(); | ||
} | ||
|
||
protected abstract ScheduleBuilder<T> getScheduleBuilder(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.nexters.goalpanzi.schedule; | ||
|
||
import org.quartz.Job; | ||
import org.quartz.JobDetail; | ||
import org.quartz.Trigger; | ||
|
||
public interface CustomAutomationJob extends Job { | ||
Trigger getTrigger(); | ||
JobDetail getJobDetail(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍👍