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 @@ -14,4 +14,4 @@ public interface PollRepository extends JpaRepository<Poll, Long> {

@Query("SELECT p FROM Poll p LEFT JOIN PollVote v ON p = v.poll GROUP BY p ORDER BY COUNT(v) DESC")
List<Poll> findTopPollsByVoteCount(Pageable pageable);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,19 @@ public interface PollVoteRepository extends JpaRepository<PollVote, Long> {
@Query("SELECT v.pollOptions.pollItemsId, v.member.gender, v.member.age, COUNT(v.pollVoteId) FROM PollVote v WHERE v.pollOptions.pollItemsId IN :pollOptionIds GROUP BY v.pollOptions.pollItemsId, v.member.gender, v.member.age")
java.util.List<Object[]> countStaticsByPollOptionIds(@Param("pollOptionIds") java.util.List<Long> pollOptionIds);

boolean existsByPoll_PollIdAndMember_MemberId(Long pollId, Long memberId);

@Query(value = "SELECT po.option, m.gender, COUNT(*) FROM poll_vote pv JOIN poll_options po ON pv.poll_items_id = po.poll_items_id JOIN member m ON pv.member_id = m.member_id WHERE po.poll_id = :pollId GROUP BY po.option, m.gender", nativeQuery = true)
List<Object[]> getGenderOptionStatics(@Param("pollId") Long pollId);

@Query(value = "SELECT CASE WHEN m.age < 20 THEN '10대' WHEN m.age < 30 THEN '20대' " +
"WHEN m.age < 40 THEN '30대' WHEN m.age < 50 THEN '40대' WHEN m.age < 60 THEN '50대' " +
"WHEN m.age < 70 THEN '60대' WHEN m.age < 80 THEN '70대' ELSE '80대 이상' " +
"END AS ageGroup, m.gender, COUNT(*) FROM poll_vote pv JOIN member m ON pv.member_id = m.member_id JOIN poll_options po ON pv.poll_items_id = po.poll_items_id WHERE po.poll_id = :pollId GROUP BY ageGroup, m.gender", nativeQuery = true)
List<Object[]> getAgeGenderStatics(@Param("pollId") Long pollId);

@Query("SELECT o.option, " +
"CASE WHEN m.age < 20 THEN '10대' WHEN m.age < 30 THEN '20대' " +
"WHEN m.age < 40 THEN '30대' WHEN m.age < 50 THEN '40대' WHEN m.age < 60 THEN '50대' " +
"WHEN m.age < 70 THEN '60대' WHEN m.age < 80 THEN '70대' ELSE '80대 이상' END, " +
"COUNT(v) " +
"FROM PollVote v JOIN v.pollOptions o JOIN v.member m " +
"WHERE o.poll.pollId = :pollId " +
"GROUP BY o.option, " +
"CASE WHEN m.age < 20 THEN '10대' WHEN m.age < 30 THEN '20대' " +
"WHEN m.age < 40 THEN '30대' WHEN m.age < 50 THEN '40대' WHEN m.age < 60 THEN '50대' " +
"WHEN m.age < 70 THEN '60대' WHEN m.age < 80 THEN '70대' ELSE '80대 이상' END")
"CASE WHEN m.age < 20 THEN '10대' WHEN m.age < 30 THEN '20대' " +
"WHEN m.age < 40 THEN '30대' WHEN m.age < 50 THEN '40대' WHEN m.age < 60 THEN '50대' " +
"WHEN m.age < 70 THEN '60대' WHEN m.age < 80 THEN '70대' ELSE '80대 이상' END, " +
"COUNT(v) " +
"FROM PollVote v JOIN v.pollOptions o JOIN v.member m " +
"WHERE o.poll.pollId = :pollId " +
"GROUP BY o.option, " +
"CASE WHEN m.age < 20 THEN '10대' WHEN m.age < 30 THEN '20대' " +
"WHEN m.age < 40 THEN '30대' WHEN m.age < 50 THEN '40대' WHEN m.age < 60 THEN '50대' " +
"WHEN m.age < 70 THEN '60대' WHEN m.age < 80 THEN '70대' ELSE '80대 이상' END")
List<Object[]> getOptionAgeStatics(@Param("pollId") Long pollId);

@Query("SELECT o.option, m.gender, COUNT(v) FROM PollVote v JOIN v.pollOptions o JOIN v.member m WHERE o.poll.pollId = :pollId GROUP BY o.option, m.gender")
List<Object[]> getOptionGenderStatics(@Param("pollId") Long pollId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ public List<PollDto> getPollsByStatus(PollDto.PollStatus status) {
autoCloseIfNeeded(poll);
}
List<PollDto> pollDtos = polls.stream()
.filter(p -> p.getStatus().name().equals(status.name()))
.map(p -> status == PollDto.PollStatus.CLOSED
? getPollWithStatistics(p.getPollId())
: convertToDto(p))
.toList();
.filter(p -> p.getStatus().name().equals(status.name()))
.map(p -> status == PollDto.PollStatus.CLOSED
? getPollWithStatistics(p.getPollId())
: convertToDto(p))
.toList();
return pollDtos;
}

Expand Down Expand Up @@ -170,20 +170,20 @@ public PollStaticsResponseDto getPollStatics(Long pollId) {
if (opt == null) continue;
Long pollItemsId = opt.getPollItemsId();
PollAgeStaticsDto.AgeGroupCountDto dto = PollAgeStaticsDto.AgeGroupCountDto.builder()
.option(option)
.ageGroup(arr[1] != null ? arr[1].toString() : null)
.voteCount(arr[2] != null ? ((Number)arr[2]).longValue() : 0L)
.build();
.option(option)
.ageGroup(arr[1] != null ? arr[1].toString() : null)
.voteCount(arr[2] != null ? ((Number)arr[2]).longValue() : 0L)
.build();
ageGroupMap.computeIfAbsent(pollItemsId, k -> new java.util.ArrayList<>()).add(dto);
}
java.util.List<PollAgeStaticsDto> optionAgeStatics = new java.util.ArrayList<>();
for (int i = 0; i < options.size(); i++) {
PollOptions opt = options.get(i);
optionAgeStatics.add(PollAgeStaticsDto.builder()
.pollItemsId(opt.getPollItemsId())
.pollOptionIndex(i + 1)
.ageGroupCounts(ageGroupMap.getOrDefault(opt.getPollItemsId(), java.util.Collections.emptyList()))
.build());
.pollItemsId(opt.getPollItemsId())
.pollOptionIndex(i + 1)
.ageGroupCounts(ageGroupMap.getOrDefault(opt.getPollItemsId(), java.util.Collections.emptyList()))
.build());
}
// gender 통계 그룹핑
List<Object[]> optionGenderRaw = pollVoteRepository.getOptionGenderStatics(pollId);
Expand All @@ -194,27 +194,27 @@ public PollStaticsResponseDto getPollStatics(Long pollId) {
if (opt == null) continue;
Long pollItemsId = opt.getPollItemsId();
PollGenderStaticsDto.GenderCountDto dto = PollGenderStaticsDto.GenderCountDto.builder()
.option(option)
.gender(arr[1] != null ? arr[1].toString() : null)
.voteCount(arr[2] != null ? ((Number)arr[2]).longValue() : 0L)
.build();
.option(option)
.gender(arr[1] != null ? arr[1].toString() : null)
.voteCount(arr[2] != null ? ((Number)arr[2]).longValue() : 0L)
.build();
genderGroupMap.computeIfAbsent(pollItemsId, k -> new java.util.ArrayList<>()).add(dto);
}
java.util.List<PollGenderStaticsDto> optionGenderStatics = new java.util.ArrayList<>();
for (int i = 0; i < options.size(); i++) {
PollOptions opt = options.get(i);
optionGenderStatics.add(PollGenderStaticsDto.builder()
.pollItemsId(opt.getPollItemsId())
.pollOptionIndex(i + 1)
.genderCounts(genderGroupMap.getOrDefault(opt.getPollItemsId(), java.util.Collections.emptyList()))
.build());
.pollItemsId(opt.getPollItemsId())
.pollOptionIndex(i + 1)
.genderCounts(genderGroupMap.getOrDefault(opt.getPollItemsId(), java.util.Collections.emptyList()))
.build());
}
return PollStaticsResponseDto.builder()
.postId(postId)
.pollId(pollId)
.optionAgeStatics(optionAgeStatics)
.optionGenderStatics(optionGenderStatics)
.build();
.postId(postId)
.pollId(pollId)
.optionAgeStatics(optionAgeStatics)
.optionGenderStatics(optionGenderStatics)
.build();
}

// 최대 7일 동안 투표 가능 (초기 요구사항)
Expand Down Expand Up @@ -252,15 +252,15 @@ public PollDto getTopPollByStatus(PollDto.PollStatus status) {
if (result.isEmpty()) {
// 종료된 투표가 없으면 빈 PollDto 반환
return PollDto.builder()
.pollId(null)
.postId(null)
.voteTitle(null)
.status(status)
.createdAt(null)
.closedAt(null)
.pollOptions(java.util.Collections.emptyList())
.totalVoteCount(0L)
.build();
.pollId(null)
.postId(null)
.voteTitle(null)
.status(status)
.createdAt(null)
.closedAt(null)
.pollOptions(java.util.Collections.emptyList())
.totalVoteCount(0L)
.build();
}
Long pollId = (Long) result.get(0)[0];
return getPoll(pollId);
Expand All @@ -270,13 +270,13 @@ public PollDto getTopPollByStatus(PollDto.PollStatus status) {
public List<PollDto> getTopNPollsByStatus(PollDto.PollStatus status, int n) {
Pageable pageable = org.springframework.data.domain.PageRequest.of(0, n);
List<Object[]> result = pollVoteRepository.findTopNPollByStatus(
com.ai.lawyer.domain.poll.entity.Poll.PollStatus.valueOf(status.name()), pageable);
com.ai.lawyer.domain.poll.entity.Poll.PollStatus.valueOf(status.name()), pageable);
List<PollDto> pollDtos = new java.util.ArrayList<>();
for (Object[] row : result) {
Long pollId = (Long) row[0];
pollDtos.add(status == PollDto.PollStatus.CLOSED
? getPollWithStatistics(pollId)
: getPoll(pollId));
? getPollWithStatistics(pollId)
: getPoll(pollId));
}
return pollDtos;
}
Expand Down Expand Up @@ -323,17 +323,17 @@ public PollDto updatePoll(Long pollId, PollUpdateDto pollUpdateDto) {
if (optionDto.getPollItemsId() != null) {
// update
PollOptions option = existingOptions.stream()
.filter(o -> o.getPollItemsId().equals(optionDto.getPollItemsId()))
.findFirst().orElse(null);
.filter(o -> o.getPollItemsId().equals(optionDto.getPollItemsId()))
.findFirst().orElse(null);
if (option != null) {
option.setOption(optionDto.getContent());
pollOptionsRepository.save(option);
}
} else {
PollOptions newOption = PollOptions.builder()
.poll(poll)
.option(optionDto.getContent())
.build();
.poll(poll)
.option(optionDto.getContent())
.build();
pollOptionsRepository.save(newOption);
}
}
Expand Down Expand Up @@ -381,17 +381,17 @@ public void patchUpdatePoll(Long pollId, PollUpdateDto pollUpdateDto) {
for (var optionDto : pollUpdateDto.getPollOptions()) {
if (optionDto.getPollItemsId() != null) {
PollOptions option = existingOptions.stream()
.filter(o -> o.getPollItemsId().equals(optionDto.getPollItemsId()))
.findFirst().orElse(null);
.filter(o -> o.getPollItemsId().equals(optionDto.getPollItemsId()))
.findFirst().orElse(null);
if (option != null) {
option.setOption(optionDto.getContent());
pollOptionsRepository.save(option);
}
} else {
PollOptions newOption = PollOptions.builder()
.poll(poll)
.option(optionDto.getContent())
.build();
.poll(poll)
.option(optionDto.getContent())
.build();
pollOptionsRepository.save(newOption);
}
}
Expand Down Expand Up @@ -428,50 +428,50 @@ public PollDto getPollWithStatistics(Long pollId) {
PollOptions option = options.get(i);
Long voteCount = pollVoteRepository.countByPollOptionId(option.getPollItemsId());
List<PollStaticsDto> statics = staticsRaw.stream()
.filter(arr -> ((Long)arr[0]).equals(option.getPollItemsId()))
.map(arr -> {
String gender = arr[1] != null ? arr[1].toString() : null;
Integer age = arr[2] != null ? ((Number)arr[2]).intValue() : null;
String ageGroup = getAgeGroup(age);
return PollStaticsDto.builder()
.gender(gender)
.ageGroup(ageGroup)
.voteCount((Long)arr[3])
.build();
})
.toList();
.filter(arr -> ((Long)arr[0]).equals(option.getPollItemsId()))
.map(arr -> {
String gender = arr[1] != null ? arr[1].toString() : null;
Integer age = arr[2] != null ? ((Number)arr[2]).intValue() : null;
String ageGroup = getAgeGroup(age);
return PollStaticsDto.builder()
.gender(gender)
.ageGroup(ageGroup)
.voteCount((Long)arr[3])
.build();
})
.toList();
optionDtos.add(PollOptionDto.builder()
.pollItemsId(option.getPollItemsId())
.content(option.getOption())
.voteCount(voteCount)
.statics(statics)
.pollOptionIndex(i + 1)
.build());
.pollItemsId(option.getPollItemsId())
.content(option.getOption())
.voteCount(voteCount)
.statics(statics)
.pollOptionIndex(i + 1)
.build());
}
} else {
optionDtos = new ArrayList<>();
for (int i = 0; i < options.size(); i++) {
PollOptions option = options.get(i);
Long voteCount = pollVoteRepository.countByPollOptionId(option.getPollItemsId());
optionDtos.add(PollOptionDto.builder()
.pollItemsId(option.getPollItemsId())
.content(option.getOption())
.voteCount(voteCount)
.statics(null)
.pollOptionIndex(i + 1)
.build());
.pollItemsId(option.getPollItemsId())
.content(option.getOption())
.voteCount(voteCount)
.statics(null)
.pollOptionIndex(i + 1)
.build());
}
}
return PollDto.builder()
.pollId(poll.getPollId())
.postId(poll.getPost() != null ? poll.getPost().getPostId() : null)
.voteTitle(poll.getVoteTitle())
.status(PollDto.PollStatus.valueOf(poll.getStatus().name()))
.createdAt(poll.getCreatedAt())
.closedAt(poll.getClosedAt())
.pollOptions(optionDtos)
.totalVoteCount(totalVoteCount)
.build();
.pollId(poll.getPollId())
.postId(poll.getPost() != null ? poll.getPost().getPostId() : null)
.voteTitle(poll.getVoteTitle())
.status(PollDto.PollStatus.valueOf(poll.getStatus().name()))
.createdAt(poll.getCreatedAt())
.closedAt(poll.getClosedAt())
.pollOptions(optionDtos)
.totalVoteCount(totalVoteCount)
.build();
}

private PollDto convertToDto(Poll poll) {
Expand All @@ -482,12 +482,12 @@ private PollDto convertToDto(Poll poll) {
PollOptions option = options.get(i);
Long voteCount = pollVoteRepository.countByPollOptionId(option.getPollItemsId());
optionDtos.add(PollOptionDto.builder()
.pollItemsId(option.getPollItemsId())
.content(option.getOption())
.voteCount(voteCount)
.statics(null)
.pollOptionIndex(i + 1)
.build());
.pollItemsId(option.getPollItemsId())
.content(option.getOption())
.voteCount(voteCount)
.statics(null)
.pollOptionIndex(i + 1)
.build());
}
LocalDateTime expectedCloseAt = poll.getReservedCloseAt() != null ? poll.getReservedCloseAt() : poll.getCreatedAt().plusDays(7);
return PollDto.builder()
Expand Down Expand Up @@ -568,4 +568,4 @@ public void validatePollCreate(PollForPostDto dto) {
public void validatePollCreate(PollCreateDto dto) {
validatePollCommon(dto.getVoteTitle(), dto.getPollOptions(), dto.getReservedCloseAt());
}
}
}
Loading