From 8243f47ae2a99b1533f1b58885be5942fe92ca2a Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sat, 5 Oct 2024 11:58:36 +0900 Subject: [PATCH 01/16] =?UTF-8?q?feat:=20=EC=88=98=EA=B0=95=EC=83=9D=20?= =?UTF-8?q?=EB=AA=85=EB=8B=A8=20=EC=A1=B0=ED=9A=8C=EB=A5=BC=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EB=A0=88=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AssignmentHistoryCustomRepository.java | 2 ++ ...AssignmentHistoryCustomRepositoryImpl.java | 31 ++++++------------- .../dao/AssignmentHistoryQueryMethod.java | 31 +++++++++++++++++++ .../dao/AssignmentHistoryRepository.java | 1 + .../study/dao/AttendanceCustomRepository.java | 2 ++ .../dao/AttendanceCustomRepositoryImpl.java | 10 ++++++ .../study/dao/StudyAchievementRepository.java | 12 +++++++ .../study/dao/StudyHistoryRepository.java | 6 ++-- 8 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryQueryMethod.java create mode 100644 src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementRepository.java diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryCustomRepository.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryCustomRepository.java index cd5addbc8..0bda9e1c1 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryCustomRepository.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryCustomRepository.java @@ -11,5 +11,7 @@ public interface AssignmentHistoryCustomRepository { List findAssignmentHistoriesByStudentAndStudyId(Member member, Long studyId); + List findByStudyIdAndMemberIds(Long studyId, List memberIds); + void deleteByStudyIdAndMemberId(Long studyId, Long memberId); } diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryCustomRepositoryImpl.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryCustomRepositoryImpl.java index df884bfc6..7b3f98724 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryCustomRepositoryImpl.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryCustomRepositoryImpl.java @@ -1,19 +1,18 @@ package com.gdschongik.gdsc.domain.study.dao; -import static com.gdschongik.gdsc.domain.study.domain.AssignmentSubmissionStatus.*; import static com.gdschongik.gdsc.domain.study.domain.QAssignmentHistory.*; import static com.gdschongik.gdsc.domain.study.domain.QStudyDetail.studyDetail; import com.gdschongik.gdsc.domain.member.domain.Member; import com.gdschongik.gdsc.domain.study.domain.AssignmentHistory; import com.gdschongik.gdsc.domain.study.domain.Study; -import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import java.util.List; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor -public class AssignmentHistoryCustomRepositoryImpl implements AssignmentHistoryCustomRepository { +public class AssignmentHistoryCustomRepositoryImpl + implements AssignmentHistoryCustomRepository, AssignmentHistoryQueryMethod { private final JPAQueryFactory queryFactory; @@ -28,18 +27,6 @@ public boolean existsSubmittedAssignmentByMemberAndStudy(Member member, Study st return fetchOne != null; } - private BooleanExpression eqMember(Member member) { - return member == null ? null : assignmentHistory.member.eq(member); - } - - private BooleanExpression eqStudy(Study study) { - return study == null ? null : assignmentHistory.studyDetail.study.eq(study); - } - - private BooleanExpression isSubmitted() { - return assignmentHistory.submissionStatus.in(FAILURE, SUCCESS); - } - @Override public List findAssignmentHistoriesByStudentAndStudyId(Member currentMember, Long studyId) { return queryFactory @@ -50,10 +37,6 @@ public List findAssignmentHistoriesByStudentAndStudyId(Member .fetch(); } - private BooleanExpression eqStudyId(Long studyId) { - return studyId != null ? studyDetail.study.id.eq(studyId) : null; - } - @Override public void deleteByStudyIdAndMemberId(Long studyId, Long memberId) { queryFactory @@ -62,7 +45,13 @@ public void deleteByStudyIdAndMemberId(Long studyId, Long memberId) { .execute(); } - private BooleanExpression eqMemberId(Long memberId) { - return memberId != null ? assignmentHistory.member.id.eq(memberId) : null; + @Override + public List findByStudyIdAndMemberIds(Long studyId, List memberIds) { + return queryFactory + .selectFrom(assignmentHistory) + .innerJoin(assignmentHistory.studyDetail, studyDetail) + .fetchJoin() + .where(assignmentHistory.member.id.in(memberIds), eqStudyId(studyId)) + .fetch(); } } diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryQueryMethod.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryQueryMethod.java new file mode 100644 index 000000000..6b06147d2 --- /dev/null +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryQueryMethod.java @@ -0,0 +1,31 @@ +package com.gdschongik.gdsc.domain.study.dao; + +import static com.gdschongik.gdsc.domain.study.domain.AssignmentSubmissionStatus.*; +import static com.gdschongik.gdsc.domain.study.domain.QAssignmentHistory.*; +import static com.gdschongik.gdsc.domain.study.domain.QStudyDetail.*; + +import com.gdschongik.gdsc.domain.member.domain.Member; +import com.gdschongik.gdsc.domain.study.domain.Study; +import com.querydsl.core.types.dsl.BooleanExpression; + +public interface AssignmentHistoryQueryMethod { + default BooleanExpression eqMember(Member member) { + return member == null ? null : assignmentHistory.member.eq(member); + } + + default BooleanExpression eqStudy(Study study) { + return study == null ? null : assignmentHistory.studyDetail.study.eq(study); + } + + default BooleanExpression isSubmitted() { + return assignmentHistory.submissionStatus.in(FAILURE, SUCCESS); + } + + default BooleanExpression eqStudyId(Long studyId) { + return studyId != null ? studyDetail.study.id.eq(studyId) : null; + } + + default BooleanExpression eqMemberId(Long memberId) { + return memberId != null ? assignmentHistory.member.id.eq(memberId) : null; + } +} diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryRepository.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryRepository.java index 1c882f5ee..4e11bf86c 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryRepository.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AssignmentHistoryRepository.java @@ -8,5 +8,6 @@ public interface AssignmentHistoryRepository extends JpaRepository, AssignmentHistoryCustomRepository { + // todo: public 제거 public Optional findByMemberAndStudyDetail(Member member, StudyDetail studyDetail); } diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AttendanceCustomRepository.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AttendanceCustomRepository.java index e04482f5d..f7a488e8e 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AttendanceCustomRepository.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AttendanceCustomRepository.java @@ -7,5 +7,7 @@ public interface AttendanceCustomRepository { List findByMemberAndStudyId(Member member, Long studyId); + List findByStudyIdAndMemberIds(Long studyId, List memberIds); + void deleteByStudyIdAndMemberId(Long studyId, Long memberId); } diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AttendanceCustomRepositoryImpl.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AttendanceCustomRepositoryImpl.java index af382f4d2..c85ecfa2d 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AttendanceCustomRepositoryImpl.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AttendanceCustomRepositoryImpl.java @@ -26,6 +26,16 @@ public List findByMemberAndStudyId(Member member, Long studyId) { .fetch(); } + @Override + public List findByStudyIdAndMemberIds(Long studyId, List memberIds) { + return queryFactory + .selectFrom(attendance) + .innerJoin(attendance.studyDetail, studyDetail) + .fetchJoin() + .where(attendance.student.id.in(memberIds), eqStudyId(studyId)) + .fetch(); + } + private BooleanExpression eqMemberId(Long memberId) { return memberId != null ? attendance.student.id.eq(memberId) : null; } diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementRepository.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementRepository.java new file mode 100644 index 000000000..af775f69b --- /dev/null +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementRepository.java @@ -0,0 +1,12 @@ +package com.gdschongik.gdsc.domain.study.dao; + +import com.gdschongik.gdsc.domain.member.domain.Member; +import com.gdschongik.gdsc.domain.study.domain.Study; +import com.gdschongik.gdsc.domain.study.domain.StudyAchievement; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface StudyAchievementRepository extends JpaRepository { + + List findByStudentAndStudy(Member student, Study study); +} diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyHistoryRepository.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyHistoryRepository.java index 4bf4303ea..02b61fceb 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyHistoryRepository.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyHistoryRepository.java @@ -5,12 +5,12 @@ import com.gdschongik.gdsc.domain.study.domain.StudyHistory; import java.util.List; import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; public interface StudyHistoryRepository extends JpaRepository { - List findByStudyId(Long studyId); - List findAllByStudent(Member member); Optional findByStudentAndStudy(Member member, Study study); @@ -18,4 +18,6 @@ public interface StudyHistoryRepository extends JpaRepository findByStudentAndStudyId(Member member, Long studyId); + + Page findByStudyId(Long studyId, Pageable pageable); } From 7f1be83af2f34d4eff2ae23c2ed735bf9612cc78 Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sat, 5 Oct 2024 12:13:00 +0900 Subject: [PATCH 02/16] =?UTF-8?q?refactor:=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EC=BF=BC=EB=A6=AC=EA=B0=80=20=ED=95=9C=EB=B2=88=EB=A7=8C=20?= =?UTF-8?q?=EB=82=98=EA=B0=80=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dao/AttendanceCustomRepositoryImpl.java | 1 - .../dao/StudyAchievementCustomRepository.java | 8 ++++++ .../StudyAchievementCustomRepositoryImpl.java | 27 +++++++++++++++++++ .../study/dao/StudyAchievementRepository.java | 9 ++----- 4 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementCustomRepository.java create mode 100644 src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementCustomRepositoryImpl.java diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AttendanceCustomRepositoryImpl.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AttendanceCustomRepositoryImpl.java index c85ecfa2d..91cccd2f3 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dao/AttendanceCustomRepositoryImpl.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/AttendanceCustomRepositoryImpl.java @@ -1,6 +1,5 @@ package com.gdschongik.gdsc.domain.study.dao; -import static com.gdschongik.gdsc.domain.member.domain.QMember.member; import static com.gdschongik.gdsc.domain.study.domain.QAttendance.attendance; import static com.gdschongik.gdsc.domain.study.domain.QStudyDetail.studyDetail; diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementCustomRepository.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementCustomRepository.java new file mode 100644 index 000000000..2b14404f6 --- /dev/null +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementCustomRepository.java @@ -0,0 +1,8 @@ +package com.gdschongik.gdsc.domain.study.dao; + +import com.gdschongik.gdsc.domain.study.domain.StudyAchievement; +import java.util.List; + +public interface StudyAchievementCustomRepository { + List findByStudyIdAndMemberIds(Long studyId, List memberIds); +} diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementCustomRepositoryImpl.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementCustomRepositoryImpl.java new file mode 100644 index 000000000..6c06f9afe --- /dev/null +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementCustomRepositoryImpl.java @@ -0,0 +1,27 @@ +package com.gdschongik.gdsc.domain.study.dao; + +import static com.gdschongik.gdsc.domain.study.domain.QStudyAchievement.*; + +import com.gdschongik.gdsc.domain.study.domain.StudyAchievement; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.List; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class StudyAchievementCustomRepositoryImpl implements StudyAchievementCustomRepository { + + private final JPAQueryFactory queryFactory; + + @Override + public List findByStudyIdAndMemberIds(Long studyId, List memberIds) { + return queryFactory + .selectFrom(studyAchievement) + .where(studyAchievement.student.id.in(memberIds), eqStudyId(studyId)) + .fetch(); + } + + private BooleanExpression eqStudyId(Long studyId) { + return studyId != null ? studyAchievement.study.id.eq(studyId) : null; + } +} diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementRepository.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementRepository.java index af775f69b..361e1a35d 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementRepository.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementRepository.java @@ -1,12 +1,7 @@ package com.gdschongik.gdsc.domain.study.dao; -import com.gdschongik.gdsc.domain.member.domain.Member; -import com.gdschongik.gdsc.domain.study.domain.Study; import com.gdschongik.gdsc.domain.study.domain.StudyAchievement; -import java.util.List; import org.springframework.data.jpa.repository.JpaRepository; -public interface StudyAchievementRepository extends JpaRepository { - - List findByStudentAndStudy(Member student, Study study); -} +public interface StudyAchievementRepository + extends JpaRepository, StudyAchievementCustomRepository {} From 6747b937e23b92e86ad423ac830d51549423a0c8 Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sat, 5 Oct 2024 12:13:46 +0900 Subject: [PATCH 03/16] =?UTF-8?q?feat:=20curriculum=20=ED=9C=B4=EA=B0=95?= =?UTF-8?q?=20=EC=97=AC=EB=B6=80=20=EC=A0=84=EB=8B=AC=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gdschongik/gdsc/domain/study/domain/vo/Curriculum.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/domain/vo/Curriculum.java b/src/main/java/com/gdschongik/gdsc/domain/study/domain/vo/Curriculum.java index 7f299e45c..0a982af34 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/domain/vo/Curriculum.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/domain/vo/Curriculum.java @@ -60,4 +60,8 @@ public static Curriculum generateCurriculum( public boolean isOpen() { return status == StudyStatus.OPEN; } + + public boolean isCancelled() { + return status == StudyStatus.CANCELLED; + } } From 526b60bd407cb065f38eef5f21a2ae7976244e54 Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sat, 5 Oct 2024 12:14:04 +0900 Subject: [PATCH 04/16] =?UTF-8?q?feat:=20=ED=8E=98=EC=9D=B4=EC=A7=95=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gdsc/domain/study/api/MentorStudyController.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/api/MentorStudyController.java b/src/main/java/com/gdschongik/gdsc/domain/study/api/MentorStudyController.java index d85ba3af1..06eb3695d 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/api/MentorStudyController.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/api/MentorStudyController.java @@ -10,6 +10,8 @@ import jakarta.validation.Valid; import java.util.List; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -35,10 +37,10 @@ public ResponseEntity> getStudiesInCharge() { return ResponseEntity.ok(response); } - @Operation(summary = "스터디 수강생 명단 조회", description = "해당 스터디의 수강생 명단을 조회합니다") + @Operation(summary = "스터디 수강생 관리", description = "해당 스터디의 수강생을 관리합니다") @GetMapping("/{studyId}/students") - public ResponseEntity> getStudyStudents(@PathVariable Long studyId) { - List response = mentorStudyService.getStudyStudents(studyId); + public ResponseEntity> getStudyStudents(@PathVariable Long studyId, Pageable pageable) { + Page response = mentorStudyService.getStudyStudents(studyId, pageable); return ResponseEntity.ok(response); } From 27c983ed409698e6e7f6173cc50777651c71ea57 Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sat, 5 Oct 2024 12:14:31 +0900 Subject: [PATCH 05/16] =?UTF-8?q?feat:=20=ED=9C=B4=EA=B0=95=20enum=20?= =?UTF-8?q?=EA=B0=92=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/AssignmentSubmissionStatusResponse.java | 7 ++++++- .../study/dto/response/AttendanceStatusResponse.java | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AssignmentSubmissionStatusResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AssignmentSubmissionStatusResponse.java index 50fb311df..f5fb68434 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AssignmentSubmissionStatusResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AssignmentSubmissionStatusResponse.java @@ -9,7 +9,8 @@ public enum AssignmentSubmissionStatusResponse { NOT_SUBMITTED("미제출"), FAILURE("제출 실패"), - SUCCESS("제출 성공"); + SUCCESS("제출 성공"), + CANCELLED("휴강"); private final String value; @@ -23,4 +24,8 @@ public static AssignmentSubmissionStatusResponse from(AssignmentHistory assignme return FAILURE; } } + + public static AssignmentSubmissionStatusResponse getCancelled() { + return CANCELLED; + } } diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AttendanceStatusResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AttendanceStatusResponse.java index 3eb730bd9..6fac26b65 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AttendanceStatusResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AttendanceStatusResponse.java @@ -11,11 +11,16 @@ public enum AttendanceStatusResponse { ATTENDED("출석"), NOT_ATTENDED("미출석"), - BEFORE_ATTENDANCE("출석전"); + BEFORE_ATTENDANCE("출석전"), + CANCELLED("휴강"); private final String value; public static AttendanceStatusResponse of(StudyDetail studyDetail, LocalDate now, boolean isAttended) { + if (studyDetail.getCurriculum().isCancelled()) { + return CANCELLED; + } + if (studyDetail.getAttendanceDay().isAfter(now)) { return BEFORE_ATTENDANCE; } From 1ee2e40a9549f64ccc52edd63f9a2ac94f23f25d Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sat, 5 Oct 2024 12:15:04 +0900 Subject: [PATCH 06/16] =?UTF-8?q?feat:=20=EC=88=98=EA=B0=95=EC=83=9D=20?= =?UTF-8?q?=EB=AA=85=EB=8B=A8=20=EC=A1=B0=ED=9A=8C=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../study/application/MentorStudyService.java | 80 +++++++++++++++++-- .../dto/response/StudyStudentResponse.java | 55 ++++++++++++- .../study/dto/response/StudyTodoResponse.java | 12 +++ 3 files changed, 138 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java b/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java index ed972f338..031bdc561 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java @@ -3,6 +3,9 @@ import static com.gdschongik.gdsc.global.exception.ErrorCode.STUDY_NOT_FOUND; import com.gdschongik.gdsc.domain.member.domain.Member; +import com.gdschongik.gdsc.domain.study.dao.AssignmentHistoryRepository; +import com.gdschongik.gdsc.domain.study.dao.AttendanceRepository; +import com.gdschongik.gdsc.domain.study.dao.StudyAchievementRepository; import com.gdschongik.gdsc.domain.study.dao.StudyAnnouncementRepository; import com.gdschongik.gdsc.domain.study.dao.StudyDetailRepository; import com.gdschongik.gdsc.domain.study.dao.StudyHistoryRepository; @@ -17,14 +20,20 @@ import com.gdschongik.gdsc.domain.study.dto.request.StudyUpdateRequest; import com.gdschongik.gdsc.domain.study.dto.response.StudyResponse; import com.gdschongik.gdsc.domain.study.dto.response.StudyStudentResponse; +import com.gdschongik.gdsc.domain.study.dto.response.StudyTodoResponse; import com.gdschongik.gdsc.global.exception.CustomException; import com.gdschongik.gdsc.global.exception.ErrorCode; import com.gdschongik.gdsc.global.util.MemberUtil; +import java.time.LocalDate; +import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -34,12 +43,15 @@ public class MentorStudyService { private final MemberUtil memberUtil; + private final StudyValidator studyValidator; + private final StudyDetailValidator studyDetailValidator; private final StudyRepository studyRepository; private final StudyAnnouncementRepository studyAnnouncementRepository; private final StudyHistoryRepository studyHistoryRepository; - private final StudyValidator studyValidator; private final StudyDetailRepository studyDetailRepository; - private final StudyDetailValidator studyDetailValidator; + private final StudyAchievementRepository studyAchievementRepository; + private final AttendanceRepository attendanceRepository; + private final AssignmentHistoryRepository assignmentHistoryRepository; @Transactional(readOnly = true) public List getStudiesInCharge() { @@ -49,15 +61,71 @@ public List getStudiesInCharge() { } @Transactional(readOnly = true) - public List getStudyStudents(Long studyId) { + public Page getStudyStudents(Long studyId, Pageable pageable) { Member currentMember = memberUtil.getCurrentMember(); Study study = studyRepository.findById(studyId).orElseThrow(() -> new CustomException(ErrorCode.STUDY_NOT_FOUND)); - studyValidator.validateStudyMentor(currentMember, study); - List studyHistories = studyHistoryRepository.findByStudyId(studyId); - return studyHistories.stream().map(StudyStudentResponse::from).toList(); + List studyDetails = studyDetailRepository.findAllByStudyId(studyId); + Page studyHistories = studyHistoryRepository.findByStudyId(studyId, pageable); + List studentIds = studyHistories.getContent().stream() + .map(studyHistory -> studyHistory.getStudent().getId()) + .toList(); + + List attendances = attendanceRepository.findByStudyIdAndMemberIds(studyId, studentIds); + List assignmentHistories = + assignmentHistoryRepository.findByStudyIdAndMemberIds(studyId, studentIds); + List studyAchievements = + studyAchievementRepository.findByStudyIdAndMemberIds(studyId, studentIds); + + List response = new ArrayList<>(); + studyHistories.forEach(studyHistory -> { + List currentStudyAchievements = studyAchievements.stream() + .filter(studyAchievement -> studyAchievement + .getStudent() + .getId() + .equals(studyHistory.getStudent().getId())) + .toList(); + List currentAttendances = attendances.stream() + .filter(attendance -> attendance + .getStudent() + .getId() + .equals(studyHistory.getStudent().getId())) + .toList(); + List currentAssignmentHistories = assignmentHistories.stream() + .filter(assignmentHistory -> assignmentHistory + .getMember() + .getId() + .equals(studyHistory.getStudent().getId())) + .toList(); + + List studyTodos = new ArrayList<>(); + studyDetails.forEach(studyDetail -> { + studyTodos.add(StudyTodoResponse.createAttendanceType( + studyDetail, LocalDate.now(), isAttended(currentAttendances, studyDetail))); + studyTodos.add(StudyTodoResponse.createAssignmentType( + studyDetail, getSubmittedAssignment(currentAssignmentHistories, studyDetail))); + }); + + response.add(StudyStudentResponse.of(studyHistory, currentStudyAchievements, studyTodos)); + }); + + return new PageImpl<>(response, pageable, studyHistories.getTotalElements()); + } + + private boolean isAttended(List attendances, StudyDetail studyDetail) { + return attendances.stream() + .anyMatch(attendance -> attendance.getStudyDetail().getId().equals(studyDetail.getId())); + } + + private AssignmentHistory getSubmittedAssignment( + List assignmentHistories, StudyDetail studyDetail) { + return assignmentHistories.stream() + .filter(assignmentHistory -> + assignmentHistory.getStudyDetail().getId().equals(studyDetail.getId())) + .findFirst() + .orElse(null); } @Transactional diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java index fd616fdb2..df8abdaf0 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java @@ -1,7 +1,13 @@ package com.gdschongik.gdsc.domain.study.dto.response; +import static com.gdschongik.gdsc.domain.study.domain.AchievementType.*; + +import com.gdschongik.gdsc.domain.study.domain.AchievementType; +import com.gdschongik.gdsc.domain.study.domain.StudyAchievement; import com.gdschongik.gdsc.domain.study.domain.StudyHistory; +import com.gdschongik.gdsc.domain.study.dto.response.StudyTodoResponse.StudyTodoType; import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; public record StudyStudentResponse( @Schema(description = "멤버 아이디") Long memberId, @@ -9,14 +15,57 @@ public record StudyStudentResponse( @Schema(description = "학번") String studentId, @Schema(description = "디스코드 사용자명") String discordUsername, @Schema(description = "디스코드 닉네임") String nickname, - @Schema(description = "깃허브 링크") String githubLink) { - public static StudyStudentResponse from(StudyHistory studyHistory) { + @Schema(description = "깃허브 링크") String githubLink, + @Schema(description = "1차 우수 스터디원") boolean isFirstRoundOutstandingStudent, + @Schema(description = "2차 우수 스터디원") boolean isSecondRoundOutstandingStudent, + @Schema(description = "과제 및 출석 이력") List studyTodos, + @Schema(description = "과제 수행률") double assignmentRate, + @Schema(description = "출석률") double attendanceRate) { + public static StudyStudentResponse of( + StudyHistory studyHistory, List studyAchievements, List studyTodos) { + List assignments = studyTodos.stream() + .filter(studyTodoResponse -> studyTodoResponse.todoType() == StudyTodoType.ASSIGNMENT) + .toList(); + + List attendances = studyTodos.stream() + .filter(studyTodoResponse -> studyTodoResponse.todoType() == StudyTodoType.ATTENDANCE) + .toList(); + + long successAssignmentsCount = assignments.stream() + .filter(studyTodoResponse -> + studyTodoResponse.assignmentSubmissionStatus() == AssignmentSubmissionStatusResponse.SUCCESS) + .count(); + + long cancelledAssignmentsCount = assignments.stream() + .filter(studyTodoResponse -> + studyTodoResponse.assignmentSubmissionStatus() == AssignmentSubmissionStatusResponse.CANCELLED) + .count(); + + long attendedCount = attendances.stream() + .filter(studyTodoResponse -> studyTodoResponse.attendanceStatus() == AttendanceStatusResponse.ATTENDED) + .count(); + + long cancelledAttendanceCount = attendances.stream() + .filter(studyTodoResponse -> studyTodoResponse.attendanceStatus() == AttendanceStatusResponse.CANCELLED) + .count(); + return new StudyStudentResponse( studyHistory.getStudent().getId(), studyHistory.getStudent().getName(), studyHistory.getStudent().getStudentId(), studyHistory.getStudent().getDiscordUsername(), studyHistory.getStudent().getNickname(), - studyHistory.getRepositoryLink()); + studyHistory.getRepositoryLink(), + isOutstandingStudent(FIRST_ROUND_OUTSTANDING_STUDENT, studyAchievements), + isOutstandingStudent(SECOND_ROUND_OUTSTANDING_STUDENT, studyAchievements), + studyTodos, + (double) successAssignmentsCount * 100 / (assignments.size() - cancelledAssignmentsCount), + (double) (attendedCount * 100) / (attendances.size() - cancelledAttendanceCount)); + } + + private static boolean isOutstandingStudent( + AchievementType achievementType, List studyAchievements) { + return studyAchievements.stream() + .anyMatch(studyAchievement -> studyAchievement.getAchievementType() == achievementType); } } diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyTodoResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyTodoResponse.java index 7399b6181..8722a1132 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyTodoResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyTodoResponse.java @@ -11,6 +11,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; +// todo: 활용이 다양해졌으므로 rename 필요 public record StudyTodoResponse( Long studyDetailId, @Schema(description = "현 주차수") Long week, @@ -32,6 +33,17 @@ public static StudyTodoResponse createAttendanceType(StudyDetail studyDetail, Lo } public static StudyTodoResponse createAssignmentType(StudyDetail studyDetail, AssignmentHistory assignmentHistory) { + if (studyDetail.getAssignment().isCancelled()) { + return new StudyTodoResponse( + studyDetail.getId(), + studyDetail.getWeek(), + ASSIGNMENT, + null, + null, + null, + AssignmentSubmissionStatusResponse.getCancelled()); + } + return new StudyTodoResponse( studyDetail.getId(), studyDetail.getWeek(), From 7c4f1a77ffa99d7c0ba36a7e956ae234dc65aabd Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sat, 5 Oct 2024 12:21:15 +0900 Subject: [PATCH 07/16] =?UTF-8?q?fix:=20=ED=9C=B4=EA=B0=95=EC=9D=BC=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20=EB=B0=9C=EC=83=9D=ED=95=98=EB=8A=94=20NPE?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/AssignmentSubmissionStatusResponse.java | 4 ---- .../domain/study/dto/response/StudyTodoResponse.java | 12 +++++++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AssignmentSubmissionStatusResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AssignmentSubmissionStatusResponse.java index f5fb68434..293c8e57b 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AssignmentSubmissionStatusResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AssignmentSubmissionStatusResponse.java @@ -24,8 +24,4 @@ public static AssignmentSubmissionStatusResponse from(AssignmentHistory assignme return FAILURE; } } - - public static AssignmentSubmissionStatusResponse getCancelled() { - return CANCELLED; - } } diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyTodoResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyTodoResponse.java index 8722a1132..3cf92a5c7 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyTodoResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyTodoResponse.java @@ -22,6 +22,16 @@ public record StudyTodoResponse( @Schema(description = "과제 제출 상태 (과제타입일 때만 사용)") AssignmentSubmissionStatusResponse assignmentSubmissionStatus) { public static StudyTodoResponse createAttendanceType(StudyDetail studyDetail, LocalDate now, boolean isAttended) { + if (studyDetail.getCurriculum().isCancelled()) { + return new StudyTodoResponse( + studyDetail.getId(), + studyDetail.getWeek(), + ATTENDANCE, + null, + AttendanceStatusResponse.CANCELLED, + null, + null); + } return new StudyTodoResponse( studyDetail.getId(), studyDetail.getWeek(), @@ -41,7 +51,7 @@ public static StudyTodoResponse createAssignmentType(StudyDetail studyDetail, As null, null, null, - AssignmentSubmissionStatusResponse.getCancelled()); + AssignmentSubmissionStatusResponse.CANCELLED); } return new StudyTodoResponse( From 5fa5e05dbcfeecdd317617c6dd34dc813fe366b1 Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sat, 5 Oct 2024 12:37:09 +0900 Subject: [PATCH 08/16] =?UTF-8?q?refactor:=20static=20import=20=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../study/dto/response/StudyStudentResponse.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java index df8abdaf0..9ea4580b2 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java @@ -1,11 +1,12 @@ package com.gdschongik.gdsc.domain.study.dto.response; import static com.gdschongik.gdsc.domain.study.domain.AchievementType.*; +import static com.gdschongik.gdsc.domain.study.dto.response.AssignmentSubmissionStatusResponse.*; +import static com.gdschongik.gdsc.domain.study.dto.response.StudyTodoResponse.StudyTodoType.*; import com.gdschongik.gdsc.domain.study.domain.AchievementType; import com.gdschongik.gdsc.domain.study.domain.StudyAchievement; import com.gdschongik.gdsc.domain.study.domain.StudyHistory; -import com.gdschongik.gdsc.domain.study.dto.response.StudyTodoResponse.StudyTodoType; import io.swagger.v3.oas.annotations.media.Schema; import java.util.List; @@ -24,21 +25,19 @@ public record StudyStudentResponse( public static StudyStudentResponse of( StudyHistory studyHistory, List studyAchievements, List studyTodos) { List assignments = studyTodos.stream() - .filter(studyTodoResponse -> studyTodoResponse.todoType() == StudyTodoType.ASSIGNMENT) + .filter(studyTodoResponse -> studyTodoResponse.todoType() == ASSIGNMENT) .toList(); List attendances = studyTodos.stream() - .filter(studyTodoResponse -> studyTodoResponse.todoType() == StudyTodoType.ATTENDANCE) + .filter(studyTodoResponse -> studyTodoResponse.todoType() == ATTENDANCE) .toList(); long successAssignmentsCount = assignments.stream() - .filter(studyTodoResponse -> - studyTodoResponse.assignmentSubmissionStatus() == AssignmentSubmissionStatusResponse.SUCCESS) + .filter(studyTodoResponse -> studyTodoResponse.assignmentSubmissionStatus() == SUCCESS) .count(); long cancelledAssignmentsCount = assignments.stream() - .filter(studyTodoResponse -> - studyTodoResponse.assignmentSubmissionStatus() == AssignmentSubmissionStatusResponse.CANCELLED) + .filter(studyTodoResponse -> studyTodoResponse.assignmentSubmissionStatus() == CANCELLED) .count(); long attendedCount = attendances.stream() From 223286d63626f1d6ec95a955e834e22ee94863ce Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sun, 6 Oct 2024 01:41:34 +0900 Subject: [PATCH 09/16] =?UTF-8?q?refactor:=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=A1=9C=20?= =?UTF-8?q?=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/StudyStudentResponse.java | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java index 9ea4580b2..39da17313 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java @@ -32,21 +32,11 @@ public static StudyStudentResponse of( .filter(studyTodoResponse -> studyTodoResponse.todoType() == ATTENDANCE) .toList(); - long successAssignmentsCount = assignments.stream() - .filter(studyTodoResponse -> studyTodoResponse.assignmentSubmissionStatus() == SUCCESS) - .count(); - - long cancelledAssignmentsCount = assignments.stream() - .filter(studyTodoResponse -> studyTodoResponse.assignmentSubmissionStatus() == CANCELLED) - .count(); + long successAssignmentsCount = countAssignmentByStatus(assignments, SUCCESS); + long cancelledAssignmentsCount = countAssignmentByStatus(assignments, CANCELLED); - long attendedCount = attendances.stream() - .filter(studyTodoResponse -> studyTodoResponse.attendanceStatus() == AttendanceStatusResponse.ATTENDED) - .count(); - - long cancelledAttendanceCount = attendances.stream() - .filter(studyTodoResponse -> studyTodoResponse.attendanceStatus() == AttendanceStatusResponse.CANCELLED) - .count(); + long attendedCount = countAttendanceByStatus(attendances, AttendanceStatusResponse.ATTENDED); + long cancelledAttendanceCount = countAttendanceByStatus(attendances, AttendanceStatusResponse.CANCELLED); return new StudyStudentResponse( studyHistory.getStudent().getId(), @@ -67,4 +57,17 @@ private static boolean isOutstandingStudent( return studyAchievements.stream() .anyMatch(studyAchievement -> studyAchievement.getAchievementType() == achievementType); } + + private static long countAssignmentByStatus( + List assignments, AssignmentSubmissionStatusResponse status) { + return assignments.stream() + .filter(studyTodoResponse -> studyTodoResponse.assignmentSubmissionStatus() == status) + .count(); + } + + private static long countAttendanceByStatus(List attendances, AttendanceStatusResponse status) { + return attendances.stream() + .filter(studyTodoResponse -> studyTodoResponse.attendanceStatus() == status) + .count(); + } } From b60e06763cb43bc95e4562010a0cf712dc7a7ea5 Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sun, 6 Oct 2024 18:59:18 +0900 Subject: [PATCH 10/16] =?UTF-8?q?refactor:=20=EA=B3=BC=EC=A0=9C=20?= =?UTF-8?q?=ED=9C=B4=EA=B0=95=EC=8B=9C=EC=97=90=EB=8F=84=20=EC=A0=95?= =?UTF-8?q?=EC=A0=81=20=ED=8C=A9=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/AssignmentSubmissionStatusResponse.java | 6 +++++- .../study/dto/response/StudyStudentCurriculumResponse.java | 2 +- .../gdsc/domain/study/dto/response/StudyTodoResponse.java | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AssignmentSubmissionStatusResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AssignmentSubmissionStatusResponse.java index 293c8e57b..b0d9b3935 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AssignmentSubmissionStatusResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/AssignmentSubmissionStatusResponse.java @@ -1,6 +1,7 @@ package com.gdschongik.gdsc.domain.study.dto.response; import com.gdschongik.gdsc.domain.study.domain.AssignmentHistory; +import com.gdschongik.gdsc.domain.study.domain.StudyDetail; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -14,7 +15,10 @@ public enum AssignmentSubmissionStatusResponse { private final String value; - public static AssignmentSubmissionStatusResponse from(AssignmentHistory assignmentHistory) { + public static AssignmentSubmissionStatusResponse of(AssignmentHistory assignmentHistory, StudyDetail studyDetail) { + if (studyDetail.getAssignment().isCancelled()) { + return CANCELLED; + } if (assignmentHistory == null) { return NOT_SUBMITTED; } diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentCurriculumResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentCurriculumResponse.java index d2c1aaa4a..0c6c84e0b 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentCurriculumResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentCurriculumResponse.java @@ -37,7 +37,7 @@ public static StudyStudentCurriculumResponse of( studyDetail.getCurriculum().getDifficulty(), AttendanceStatusResponse.of(studyDetail, now.toLocalDate(), isAttended), studyDetail.getAssignment().getStatus(), - AssignmentSubmissionStatusResponse.from(assignmentHistory), + AssignmentSubmissionStatusResponse.of(assignmentHistory, studyDetail), assignmentHistory != null ? assignmentHistory.getSubmissionFailureType() : NOT_SUBMITTED, assignmentHistory != null ? assignmentHistory.getSubmissionLink() : null); } diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyTodoResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyTodoResponse.java index 3cf92a5c7..ce7d58577 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyTodoResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyTodoResponse.java @@ -51,7 +51,7 @@ public static StudyTodoResponse createAssignmentType(StudyDetail studyDetail, As null, null, null, - AssignmentSubmissionStatusResponse.CANCELLED); + AssignmentSubmissionStatusResponse.of(null, studyDetail)); } return new StudyTodoResponse( @@ -61,7 +61,7 @@ public static StudyTodoResponse createAssignmentType(StudyDetail studyDetail, As studyDetail.getAssignment().getDeadline(), null, studyDetail.getAssignment().getTitle(), - AssignmentSubmissionStatusResponse.from(assignmentHistory)); + AssignmentSubmissionStatusResponse.of(assignmentHistory, studyDetail)); } @Getter From 4dbd45f4e53f5c116e305981d84fbd0104517cf3 Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sun, 6 Oct 2024 19:06:11 +0900 Subject: [PATCH 11/16] =?UTF-8?q?fix:=200=EC=9C=BC=EB=A1=9C=20=EB=82=98?= =?UTF-8?q?=EB=88=84=EB=8A=94=20=EC=9D=BC=EC=9D=B4=20=EB=B0=9C=EC=83=9D?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/study/dto/response/StudyStudentResponse.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java index 39da17313..9f6ec5d2d 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java @@ -48,8 +48,12 @@ public static StudyStudentResponse of( isOutstandingStudent(FIRST_ROUND_OUTSTANDING_STUDENT, studyAchievements), isOutstandingStudent(SECOND_ROUND_OUTSTANDING_STUDENT, studyAchievements), studyTodos, - (double) successAssignmentsCount * 100 / (assignments.size() - cancelledAssignmentsCount), - (double) (attendedCount * 100) / (attendances.size() - cancelledAttendanceCount)); + assignments.size() != cancelledAssignmentsCount + ? (double) successAssignmentsCount * 100 / (assignments.size() - cancelledAssignmentsCount) + : 0, + attendances.size() != cancelledAttendanceCount + ? (double) (attendedCount * 100) / (attendances.size() - cancelledAttendanceCount) + : 0); } private static boolean isOutstandingStudent( From 7841254333dc4b5ddd47e6c58fcc52ebec8612cc Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sun, 6 Oct 2024 19:11:01 +0900 Subject: [PATCH 12/16] =?UTF-8?q?fix:=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EC=9D=98=20content=EB=A5=BC=20=EA=B0=80=EC=A0=B8=EC=99=80?= =?UTF-8?q?=EC=84=9C=20forEach=EB=A5=BC=20=EB=8F=8C=EB=A6=AC=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gdsc/domain/study/application/MentorStudyService.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java b/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java index 031bdc561..f0b290dcd 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java @@ -73,14 +73,14 @@ public Page getStudyStudents(Long studyId, Pageable pageab .map(studyHistory -> studyHistory.getStudent().getId()) .toList(); + List studyAchievements = + studyAchievementRepository.findByStudyIdAndMemberIds(studyId, studentIds); List attendances = attendanceRepository.findByStudyIdAndMemberIds(studyId, studentIds); List assignmentHistories = assignmentHistoryRepository.findByStudyIdAndMemberIds(studyId, studentIds); - List studyAchievements = - studyAchievementRepository.findByStudyIdAndMemberIds(studyId, studentIds); List response = new ArrayList<>(); - studyHistories.forEach(studyHistory -> { + studyHistories.getContent().forEach(studyHistory -> { List currentStudyAchievements = studyAchievements.stream() .filter(studyAchievement -> studyAchievement .getStudent() From 991d43b5942141f274d526c9c3289a90877f8283 Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Sun, 6 Oct 2024 19:14:11 +0900 Subject: [PATCH 13/16] =?UTF-8?q?refactor:=20errorcode=20static=20import?= =?UTF-8?q?=20=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gdsc/domain/study/application/MentorStudyService.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java b/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java index f0b290dcd..03927c1c7 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java @@ -22,7 +22,6 @@ import com.gdschongik.gdsc.domain.study.dto.response.StudyStudentResponse; import com.gdschongik.gdsc.domain.study.dto.response.StudyTodoResponse; import com.gdschongik.gdsc.global.exception.CustomException; -import com.gdschongik.gdsc.global.exception.ErrorCode; import com.gdschongik.gdsc.global.util.MemberUtil; import java.time.LocalDate; import java.util.ArrayList; @@ -63,8 +62,7 @@ public List getStudiesInCharge() { @Transactional(readOnly = true) public Page getStudyStudents(Long studyId, Pageable pageable) { Member currentMember = memberUtil.getCurrentMember(); - Study study = - studyRepository.findById(studyId).orElseThrow(() -> new CustomException(ErrorCode.STUDY_NOT_FOUND)); + Study study = studyRepository.findById(studyId).orElseThrow(() -> new CustomException(STUDY_NOT_FOUND)); studyValidator.validateStudyMentor(currentMember, study); List studyDetails = studyDetailRepository.findAllByStudyId(studyId); From d9cab13454239a9cf7a48f97d1c0caac2dba0cdb Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Mon, 7 Oct 2024 12:33:29 +0900 Subject: [PATCH 14/16] =?UTF-8?q?refactor:=20filter=EB=A5=BC=20map?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=8C=80=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../study/application/MentorStudyService.java | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java b/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java index 03927c1c7..0988720a0 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/application/MentorStudyService.java @@ -1,6 +1,7 @@ package com.gdschongik.gdsc.domain.study.application; -import static com.gdschongik.gdsc.global.exception.ErrorCode.STUDY_NOT_FOUND; +import static com.gdschongik.gdsc.global.exception.ErrorCode.*; +import static java.util.stream.Collectors.*; import com.gdschongik.gdsc.domain.member.domain.Member; import com.gdschongik.gdsc.domain.study.dao.AssignmentHistoryRepository; @@ -26,8 +27,8 @@ import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -70,33 +71,30 @@ public Page getStudyStudents(Long studyId, Pageable pageab List studentIds = studyHistories.getContent().stream() .map(studyHistory -> studyHistory.getStudent().getId()) .toList(); - List studyAchievements = studyAchievementRepository.findByStudyIdAndMemberIds(studyId, studentIds); List attendances = attendanceRepository.findByStudyIdAndMemberIds(studyId, studentIds); List assignmentHistories = assignmentHistoryRepository.findByStudyIdAndMemberIds(studyId, studentIds); + // StudyAchievement, Attendance, AssignmentHistory에 대해 Member의 id를 key로 하는 Map 생성 + Map> studyAchievementMap = studyAchievements.stream() + .collect(groupingBy( + studyAchievement -> studyAchievement.getStudent().getId())); + Map> attendanceMap = attendances.stream() + .collect(groupingBy(attendance -> attendance.getStudent().getId())); + Map> assignmentHistoryMap = assignmentHistories.stream() + .collect(groupingBy( + assignmentHistory -> assignmentHistory.getMember().getId())); + List response = new ArrayList<>(); studyHistories.getContent().forEach(studyHistory -> { - List currentStudyAchievements = studyAchievements.stream() - .filter(studyAchievement -> studyAchievement - .getStudent() - .getId() - .equals(studyHistory.getStudent().getId())) - .toList(); - List currentAttendances = attendances.stream() - .filter(attendance -> attendance - .getStudent() - .getId() - .equals(studyHistory.getStudent().getId())) - .toList(); - List currentAssignmentHistories = assignmentHistories.stream() - .filter(assignmentHistory -> assignmentHistory - .getMember() - .getId() - .equals(studyHistory.getStudent().getId())) - .toList(); + List currentStudyAchievements = + studyAchievementMap.getOrDefault(studyHistory.getStudent().getId(), new ArrayList<>()); + List currentAttendances = + attendanceMap.getOrDefault(studyHistory.getStudent().getId(), new ArrayList<>()); + List currentAssignmentHistories = + assignmentHistoryMap.getOrDefault(studyHistory.getStudent().getId(), new ArrayList<>()); List studyTodos = new ArrayList<>(); studyDetails.forEach(studyDetail -> { @@ -175,12 +173,12 @@ public void updateStudy(Long studyId, StudyUpdateRequest request) { List studyDetails = studyDetailRepository.findAllByStudyIdOrderByWeekAsc(studyId); // StudyDetail ID를 추출하여 Set으로 저장 - Set studyDetailIds = studyDetails.stream().map(StudyDetail::getId).collect(Collectors.toSet()); + Set studyDetailIds = studyDetails.stream().map(StudyDetail::getId).collect(toSet()); // 요청된 StudyCurriculumCreateRequest의 StudyDetail ID를 추출하여 Set으로 저장 Set requestIds = request.studyCurriculums().stream() .map(StudyCurriculumCreateRequest::studyDetailId) - .collect(Collectors.toSet()); + .collect(toSet()); studyDetailValidator.validateUpdateStudyDetail(studyDetailIds, requestIds); From 961dea14aa8704b6595455314e85fd2b6d32ed6e Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Tue, 8 Oct 2024 21:22:03 +0900 Subject: [PATCH 15/16] =?UTF-8?q?refactor:=20where=EC=9D=98=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=20=EC=88=9C=EC=84=9C=20=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/study/dao/StudyAchievementCustomRepositoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementCustomRepositoryImpl.java b/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementCustomRepositoryImpl.java index 6c06f9afe..8eb3a9f46 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementCustomRepositoryImpl.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dao/StudyAchievementCustomRepositoryImpl.java @@ -17,7 +17,7 @@ public class StudyAchievementCustomRepositoryImpl implements StudyAchievementCus public List findByStudyIdAndMemberIds(Long studyId, List memberIds) { return queryFactory .selectFrom(studyAchievement) - .where(studyAchievement.student.id.in(memberIds), eqStudyId(studyId)) + .where(eqStudyId(studyId), studyAchievement.student.id.in(memberIds)) .fetch(); } From 3f40fb346d306be3eae770b55b2576a1bcf968da Mon Sep 17 00:00:00 2001 From: "chosw1002@naver.com" Date: Tue, 8 Oct 2024 21:31:01 +0900 Subject: [PATCH 16/16] =?UTF-8?q?refactor:=20=EC=82=BC=ED=95=AD=20?= =?UTF-8?q?=EC=97=B0=EC=82=B0=EC=9E=90=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=EB=A1=9C=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../study/dto/response/StudyStudentResponse.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java index 9f6ec5d2d..598aa160b 100644 --- a/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java +++ b/src/main/java/com/gdschongik/gdsc/domain/study/dto/response/StudyStudentResponse.java @@ -48,12 +48,8 @@ public static StudyStudentResponse of( isOutstandingStudent(FIRST_ROUND_OUTSTANDING_STUDENT, studyAchievements), isOutstandingStudent(SECOND_ROUND_OUTSTANDING_STUDENT, studyAchievements), studyTodos, - assignments.size() != cancelledAssignmentsCount - ? (double) successAssignmentsCount * 100 / (assignments.size() - cancelledAssignmentsCount) - : 0, - attendances.size() != cancelledAttendanceCount - ? (double) (attendedCount * 100) / (attendances.size() - cancelledAttendanceCount) - : 0); + calculateRateOrZero(successAssignmentsCount, assignments.size() - cancelledAssignmentsCount), + calculateRateOrZero(attendedCount, attendances.size() - cancelledAttendanceCount)); } private static boolean isOutstandingStudent( @@ -74,4 +70,8 @@ private static long countAttendanceByStatus(List attendances, .filter(studyTodoResponse -> studyTodoResponse.attendanceStatus() == status) .count(); } + + private static double calculateRateOrZero(long dividend, long divisor) { + return divisor == 0 ? 0 : (double) dividend * 100 / divisor; + } }