Skip to content
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

Feature/#219 마일스톤 랭킹 순위 조정 #220

Merged
merged 4 commits into from
Oct 18, 2024
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 @@ -8,9 +8,11 @@
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
Expand All @@ -30,6 +32,7 @@
import sw_css.admin.milestone.application.dto.response.MilestoneHistoryResponse;
import sw_css.admin.milestone.application.dto.response.MilestoneScoreResponse;
import sw_css.admin.milestone.persistence.StudentAndMilestoneScoreInfo;
import sw_css.admin.milestone.persistence.StudentAndMilestoneTotalScoreInfoMapping;
import sw_css.member.application.dto.response.StudentMemberReferenceResponse;
import sw_css.milestone.application.dto.response.MilestoneScoreOfStudentResponse;
import sw_css.milestone.domain.MilestoneCategory;
Expand Down Expand Up @@ -173,31 +176,31 @@ public Page<MilestoneScoreResponse> findAllMilestoneHistoryScores(final String s
final Pageable pageable) {
final LocalDate parsedStartDate = parseDate(startDate);
final LocalDate parsedEndDate = parseDate(endDate);
final long categoryCount = milestoneCategoryRepository.count();
final List<StudentAndMilestoneScoreInfo> milestoneHistoryInfos = milestoneScoreRepository.findMilestoneScoresWithStudentInfoByPeriod(
parsedStartDate, parsedEndDate, pageable.getPageNumber() * pageable.getPageSize() * categoryCount,
pageable.getPageSize() * categoryCount);
final List<StudentAndMilestoneTotalScoreInfoMapping> milestoneHistoryInfos = milestoneScoreRepository.findMilestoneScoresWithStudentInfoByPeriod(
parsedStartDate, parsedEndDate, pageable.getPageNumber() * pageable.getPageSize() * 1L, pageable.getPageSize() * 1L);

System.out.println(milestoneHistoryInfos);

final Long totalMilestoneHistoryInfoCount = milestoneScoreRepository.countAllMilestoneScoresWithStudentInfoByPeriod();
final Map<StudentMemberReferenceResponse, List<StudentAndMilestoneScoreInfo>> groupedMilestoneScoresByStudentId = milestoneHistoryInfos.stream()
.collect(groupingBy(
(info -> new StudentMemberReferenceResponse(info.studentId(), info.studentName()))));
final List<MilestoneScoreResponse> content = groupedMilestoneScoresByStudentId.entrySet()
.stream()
.map(entry -> new MilestoneScoreResponse(
entry.getKey(),
entry.getValue()
.stream()
.map(info -> new MilestoneScoreOfStudentResponse(
info.categoryId(), info.categoryName(), info.milestoneGroup(),
info.limitScore(), info.score()))
.collect(groupingBy(MilestoneScoreOfStudentResponse::group))))
.sorted(Comparator.comparing(
(MilestoneScoreResponse response) -> response.milestoneScores().entrySet().stream()
.flatMap(entry -> entry.getValue().stream())
.mapToInt(MilestoneScoreOfStudentResponse::score)
.sum()
).reversed())
.toList();

final List<MilestoneScoreResponse> content = milestoneHistoryInfos.stream().map(entry -> {
Long[] categoryIds = Arrays.stream(entry.categoryIds().split(",")).map(Long::valueOf).toArray(Long[]::new);
String[] categoryNames = entry.categoryNames().split(",");
MilestoneGroup[] milestoneGroups = Arrays.stream(entry.milestoneGroups().split(",")).map(MilestoneGroup::valueOf).toArray(MilestoneGroup[]::new);
Integer[] scores = Arrays.stream(entry.scores().split(",")).map(Integer::valueOf).toArray(Integer[]::new);
Integer[] limitScores = Arrays.stream(entry.limitScores().split(",")).map(Integer::valueOf).toArray(Integer[]::new);

return new MilestoneScoreResponse(
new StudentMemberReferenceResponse(entry.studentId(), entry.studentName()),
IntStream.range(0, categoryIds.length).mapToObj(i -> new MilestoneScoreOfStudentResponse(
categoryIds[i], categoryNames[i], milestoneGroups[i], limitScores[i], scores[i]))
.sorted(Comparator.comparing(MilestoneScoreOfStudentResponse::id))
.collect(groupingBy(MilestoneScoreOfStudentResponse::group))
);
}).toList();

System.out.println(content);

return new PageImpl<>(content, pageable, totalMilestoneHistoryInfoCount);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package sw_css.admin.milestone.persistence;

import jakarta.persistence.ColumnResult;
import java.lang.reflect.Array;
import java.util.List;
import sw_css.milestone.domain.MilestoneGroup;

public record StudentAndMilestoneTotalScoreInfoMapping(
Long studentId,
String studentName,
String categoryIds,
String categoryNames,
String milestoneGroups,
String limitScores,
String scores,
Long totalScore) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Array;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLRestriction;
import sw_css.admin.milestone.domain.MilestoneHistoryExcelData;
import sw_css.admin.milestone.persistence.StudentAndMilestoneScoreInfo;
import sw_css.admin.milestone.persistence.StudentAndMilestoneTotalScoreInfoMapping;
import sw_css.base.BaseEntity;
import sw_css.member.domain.StudentMember;
import sw_css.milestone.exception.MilestoneHistoryException;
Expand All @@ -47,6 +49,21 @@
@ColumnResult(name = "score", type = Integer.class)
}
))
@SqlResultSetMapping(
name = "StudentAndMilestoneTotalScoreInfoMapping",
classes = @ConstructorResult(
targetClass = StudentAndMilestoneTotalScoreInfoMapping.class,
columns = {
@ColumnResult(name = "studentId", type = Long.class),
@ColumnResult(name = "studentName", type = String.class),
@ColumnResult(name = "categoryIds", type = String.class),
@ColumnResult(name = "categoryNames", type = String.class),
@ColumnResult(name = "milestoneGroups", type = String.class),
@ColumnResult(name = "limitScores", type = String.class),
@ColumnResult(name = "scores", type = String.class),
@ColumnResult(name = "totalScore", type = Long.class),
}
))
public class MilestoneHistory extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import java.time.LocalDate;
import java.util.List;
import sw_css.admin.milestone.persistence.StudentAndMilestoneScoreInfo;
import sw_css.admin.milestone.persistence.StudentAndMilestoneTotalScoreInfoMapping;

public interface MilestoneScoreRepository {
List<StudentAndMilestoneScoreInfo> findMilestoneScoresWithStudentInfoByPeriod(LocalDate startDate,
LocalDate endDate, Long page,
Long pageSize);
List<StudentAndMilestoneTotalScoreInfoMapping> findMilestoneScoresWithStudentInfoByPeriod(LocalDate startDate,
LocalDate endDate, Long page,
Long pageSize);

List<StudentAndMilestoneScoreInfo> findAllMilestoneScoresWithStudentInfoByPeriod(LocalDate startDate,
LocalDate endDate);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import sw_css.admin.milestone.persistence.StudentAndMilestoneScoreInfo;
import sw_css.admin.milestone.persistence.StudentAndMilestoneTotalScoreInfoMapping;
import sw_css.milestone.domain.repository.MilestoneScoreRepository;

@Repository
Expand All @@ -16,12 +17,13 @@ public class MilestoneScoreRepositoryImpl implements MilestoneScoreRepository {
private EntityManager entityManager;

@Override
public List<StudentAndMilestoneScoreInfo> findMilestoneScoresWithStudentInfoByPeriod(LocalDate startDate,
LocalDate endDate,
Long page, Long pageSize) {
public List<StudentAndMilestoneTotalScoreInfoMapping> findMilestoneScoresWithStudentInfoByPeriod(LocalDate startDate,
LocalDate endDate,
Long page, Long pageSize) {

String sql =
"select test.studentId, test.studentName, test.category_id as categoryId, test.name as categoryName ,test.milestone_group as milestoneGroup, test.limit_score as limitScore, ifNull(least(if(sum(test.limit_count)=0,max(test.milestone_score),sum(test.milestone_score)),test.limit_score),0) as score from "
"select t.studentId, t.studentName, group_concat(t.categoryId) as categoryIds, group_concat(t.categoryName) as categoryNames, group_concat(t.milestoneGroup) as milestoneGroups, group_concat(t.limitScore) as limitScores, group_concat(t.score) as scores, sum(t.score) as totalScore from "
+ "(SELECT test.studentId, test.studentName, test.category_id as categoryId, test.name as categoryName ,test.milestone_group as milestoneGroup, test.limit_score as limitScore, ifNull(least(if(sum(test.limit_count)=0,max(test.milestone_score),sum(test.milestone_score)),test.limit_score),0) as score from "
+ " (SELECT s2.studentId, s2.studentName,mc.limit_score,m.category_id,mc.name,mc.milestone_group, m.limit_count,m.score,least(sum(mh.count), greatest(m.limit_count,1)), least(sum(mh.count), greatest(m.limit_count,1))*m.score as milestone_score "
+ "FROM (SELECT DISTINCT(COALESCE(mh.student_id, sm.id)) as studentId, COALESCE(m.name,'') as studentName FROM student_member sm "
+ "LEFT JOIN milestone_history mh on mh.student_id=sm.id "
Expand All @@ -35,10 +37,12 @@ public List<StudentAndMilestoneScoreInfo> findMilestoneScoresWithStudentInfoByPe
+ "LEFT JOIN milestone_history mh on m.id=mh.milestone_id and mh.student_id=s2.studentId and mh.activated_at <= :endDate AND mh.activated_at >= :startDate AND mh.is_deleted=false AND mh.status='APPROVED' "
+ "group by s2.studentId, studentName, m.id) as test "
+ "group by test.studentId, test.studentName, test.category_id "
+ "order by test.studentId, test.category_id "
+ "order by test.category_id) t "
+ "group by t.studentId, t.studentName "
+ "order by totalScore DESC "
+ "LIMIT :page, :pageSize";

Query query = entityManager.createNativeQuery(sql, "StudentAndMilestoneScoreInfoMapping");
Query query = entityManager.createNativeQuery(sql, "StudentAndMilestoneTotalScoreInfoMapping");
query.setParameter("startDate", startDate);
query.setParameter("endDate", endDate);
query.setParameter("page", page);
Expand Down
4 changes: 2 additions & 2 deletions backend/src/main/resources/data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,11 @@ values (1, '비교과', 20, 2);
insert into milestone (category_id, name, score, limit_count)
values (2, '수준3 이상', 60, 0);
insert into milestone (category_id, name, score, limit_count)
values (2, '수준2 이상', 50, 0);
values (2, '수준2 이상', 30, 0);
insert into milestone (category_id, name, score, limit_count)
values (3, 'PCCP Lv.3 이상', 60, 0);
insert into milestone (category_id, name, score, limit_count)
values (3, 'PCCP Lv.1 이상', 50, 0);
values (3, 'PCCP Lv.1 이상', 40, 0);
insert into milestone (category_id, name, score, limit_count)
values (4, 'SW관련 경진대회 및 공모전 수상', 20, 3);
insert into milestone (category_id, name, score, limit_count)
Expand Down
Binary file modified backend/src/main/resources/static/files/history_standard.pdf
Binary file not shown.
Binary file modified frontend/public/images/milestone/milestone_img03.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion frontend/src/app/(client)/(withSidebar)/milestone/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const Page = () => (
로그인 후, 메인 페이지와 마이페이지에서 확인하실 수 있습니다.
</S.Information>
</S.InformationList>
<S.ImageWrapper maxWidth="890px" maxHeight="1028px">
<S.ImageWrapper maxWidth="800px" maxHeight="10000">
<Image src="/images/milestone/milestone_img03.png" priority={false} alt="" fill />
</S.ImageWrapper>
</S.Content>
Expand Down