Skip to content

Commit 455c569

Browse files
authored
Merge pull request #185 from prgrms-web-devcourse-final-project/feat/22-post
Feat[post]:게시글 페이징 기능 추가
2 parents 189d231 + 2b46b12 commit 455c569

File tree

9 files changed

+197
-124
lines changed

9 files changed

+197
-124
lines changed

backend/src/main/java/com/ai/lawyer/domain/poll/repository/PollRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ public interface PollRepository extends JpaRepository<Poll, Long> {
1414

1515
@Query("SELECT p FROM Poll p LEFT JOIN PollVote v ON p = v.poll GROUP BY p ORDER BY COUNT(v) DESC")
1616
List<Poll> findTopPollsByVoteCount(Pageable pageable);
17-
}
17+
}

backend/src/main/java/com/ai/lawyer/domain/poll/repository/PollVoteRepository.java

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,30 +24,19 @@ public interface PollVoteRepository extends JpaRepository<PollVote, Long> {
2424
@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")
2525
java.util.List<Object[]> countStaticsByPollOptionIds(@Param("pollOptionIds") java.util.List<Long> pollOptionIds);
2626

27-
boolean existsByPoll_PollIdAndMember_MemberId(Long pollId, Long memberId);
28-
29-
@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)
30-
List<Object[]> getGenderOptionStatics(@Param("pollId") Long pollId);
31-
32-
@Query(value = "SELECT CASE WHEN m.age < 20 THEN '10대' WHEN m.age < 30 THEN '20대' " +
33-
"WHEN m.age < 40 THEN '30대' WHEN m.age < 50 THEN '40대' WHEN m.age < 60 THEN '50대' " +
34-
"WHEN m.age < 70 THEN '60대' WHEN m.age < 80 THEN '70대' ELSE '80대 이상' " +
35-
"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)
36-
List<Object[]> getAgeGenderStatics(@Param("pollId") Long pollId);
37-
3827
@Query("SELECT o.option, " +
39-
"CASE WHEN m.age < 20 THEN '10대' WHEN m.age < 30 THEN '20대' " +
40-
"WHEN m.age < 40 THEN '30대' WHEN m.age < 50 THEN '40대' WHEN m.age < 60 THEN '50대' " +
41-
"WHEN m.age < 70 THEN '60대' WHEN m.age < 80 THEN '70대' ELSE '80대 이상' END, " +
42-
"COUNT(v) " +
43-
"FROM PollVote v JOIN v.pollOptions o JOIN v.member m " +
44-
"WHERE o.poll.pollId = :pollId " +
45-
"GROUP BY o.option, " +
46-
"CASE WHEN m.age < 20 THEN '10대' WHEN m.age < 30 THEN '20대' " +
47-
"WHEN m.age < 40 THEN '30대' WHEN m.age < 50 THEN '40대' WHEN m.age < 60 THEN '50대' " +
48-
"WHEN m.age < 70 THEN '60대' WHEN m.age < 80 THEN '70대' ELSE '80대 이상' END")
28+
"CASE WHEN m.age < 20 THEN '10대' WHEN m.age < 30 THEN '20대' " +
29+
"WHEN m.age < 40 THEN '30대' WHEN m.age < 50 THEN '40대' WHEN m.age < 60 THEN '50대' " +
30+
"WHEN m.age < 70 THEN '60대' WHEN m.age < 80 THEN '70대' ELSE '80대 이상' END, " +
31+
"COUNT(v) " +
32+
"FROM PollVote v JOIN v.pollOptions o JOIN v.member m " +
33+
"WHERE o.poll.pollId = :pollId " +
34+
"GROUP BY o.option, " +
35+
"CASE WHEN m.age < 20 THEN '10대' WHEN m.age < 30 THEN '20대' " +
36+
"WHEN m.age < 40 THEN '30대' WHEN m.age < 50 THEN '40대' WHEN m.age < 60 THEN '50대' " +
37+
"WHEN m.age < 70 THEN '60대' WHEN m.age < 80 THEN '70대' ELSE '80대 이상' END")
4938
List<Object[]> getOptionAgeStatics(@Param("pollId") Long pollId);
5039

5140
@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")
5241
List<Object[]> getOptionGenderStatics(@Param("pollId") Long pollId);
53-
}
42+
}

backend/src/main/java/com/ai/lawyer/domain/poll/service/PollServiceImpl.java

Lines changed: 88 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ public List<PollDto> getPollsByStatus(PollDto.PollStatus status) {
102102
autoCloseIfNeeded(poll);
103103
}
104104
List<PollDto> pollDtos = polls.stream()
105-
.filter(p -> p.getStatus().name().equals(status.name()))
106-
.map(p -> status == PollDto.PollStatus.CLOSED
107-
? getPollWithStatistics(p.getPollId())
108-
: convertToDto(p))
109-
.toList();
105+
.filter(p -> p.getStatus().name().equals(status.name()))
106+
.map(p -> status == PollDto.PollStatus.CLOSED
107+
? getPollWithStatistics(p.getPollId())
108+
: convertToDto(p))
109+
.toList();
110110
return pollDtos;
111111
}
112112

@@ -170,20 +170,20 @@ public PollStaticsResponseDto getPollStatics(Long pollId) {
170170
if (opt == null) continue;
171171
Long pollItemsId = opt.getPollItemsId();
172172
PollAgeStaticsDto.AgeGroupCountDto dto = PollAgeStaticsDto.AgeGroupCountDto.builder()
173-
.option(option)
174-
.ageGroup(arr[1] != null ? arr[1].toString() : null)
175-
.voteCount(arr[2] != null ? ((Number)arr[2]).longValue() : 0L)
176-
.build();
173+
.option(option)
174+
.ageGroup(arr[1] != null ? arr[1].toString() : null)
175+
.voteCount(arr[2] != null ? ((Number)arr[2]).longValue() : 0L)
176+
.build();
177177
ageGroupMap.computeIfAbsent(pollItemsId, k -> new java.util.ArrayList<>()).add(dto);
178178
}
179179
java.util.List<PollAgeStaticsDto> optionAgeStatics = new java.util.ArrayList<>();
180180
for (int i = 0; i < options.size(); i++) {
181181
PollOptions opt = options.get(i);
182182
optionAgeStatics.add(PollAgeStaticsDto.builder()
183-
.pollItemsId(opt.getPollItemsId())
184-
.pollOptionIndex(i + 1)
185-
.ageGroupCounts(ageGroupMap.getOrDefault(opt.getPollItemsId(), java.util.Collections.emptyList()))
186-
.build());
183+
.pollItemsId(opt.getPollItemsId())
184+
.pollOptionIndex(i + 1)
185+
.ageGroupCounts(ageGroupMap.getOrDefault(opt.getPollItemsId(), java.util.Collections.emptyList()))
186+
.build());
187187
}
188188
// gender 통계 그룹핑
189189
List<Object[]> optionGenderRaw = pollVoteRepository.getOptionGenderStatics(pollId);
@@ -194,27 +194,27 @@ public PollStaticsResponseDto getPollStatics(Long pollId) {
194194
if (opt == null) continue;
195195
Long pollItemsId = opt.getPollItemsId();
196196
PollGenderStaticsDto.GenderCountDto dto = PollGenderStaticsDto.GenderCountDto.builder()
197-
.option(option)
198-
.gender(arr[1] != null ? arr[1].toString() : null)
199-
.voteCount(arr[2] != null ? ((Number)arr[2]).longValue() : 0L)
200-
.build();
197+
.option(option)
198+
.gender(arr[1] != null ? arr[1].toString() : null)
199+
.voteCount(arr[2] != null ? ((Number)arr[2]).longValue() : 0L)
200+
.build();
201201
genderGroupMap.computeIfAbsent(pollItemsId, k -> new java.util.ArrayList<>()).add(dto);
202202
}
203203
java.util.List<PollGenderStaticsDto> optionGenderStatics = new java.util.ArrayList<>();
204204
for (int i = 0; i < options.size(); i++) {
205205
PollOptions opt = options.get(i);
206206
optionGenderStatics.add(PollGenderStaticsDto.builder()
207-
.pollItemsId(opt.getPollItemsId())
208-
.pollOptionIndex(i + 1)
209-
.genderCounts(genderGroupMap.getOrDefault(opt.getPollItemsId(), java.util.Collections.emptyList()))
210-
.build());
207+
.pollItemsId(opt.getPollItemsId())
208+
.pollOptionIndex(i + 1)
209+
.genderCounts(genderGroupMap.getOrDefault(opt.getPollItemsId(), java.util.Collections.emptyList()))
210+
.build());
211211
}
212212
return PollStaticsResponseDto.builder()
213-
.postId(postId)
214-
.pollId(pollId)
215-
.optionAgeStatics(optionAgeStatics)
216-
.optionGenderStatics(optionGenderStatics)
217-
.build();
213+
.postId(postId)
214+
.pollId(pollId)
215+
.optionAgeStatics(optionAgeStatics)
216+
.optionGenderStatics(optionGenderStatics)
217+
.build();
218218
}
219219

220220
// 최대 7일 동안 투표 가능 (초기 요구사항)
@@ -252,15 +252,15 @@ public PollDto getTopPollByStatus(PollDto.PollStatus status) {
252252
if (result.isEmpty()) {
253253
// 종료된 투표가 없으면 빈 PollDto 반환
254254
return PollDto.builder()
255-
.pollId(null)
256-
.postId(null)
257-
.voteTitle(null)
258-
.status(status)
259-
.createdAt(null)
260-
.closedAt(null)
261-
.pollOptions(java.util.Collections.emptyList())
262-
.totalVoteCount(0L)
263-
.build();
255+
.pollId(null)
256+
.postId(null)
257+
.voteTitle(null)
258+
.status(status)
259+
.createdAt(null)
260+
.closedAt(null)
261+
.pollOptions(java.util.Collections.emptyList())
262+
.totalVoteCount(0L)
263+
.build();
264264
}
265265
Long pollId = (Long) result.get(0)[0];
266266
return getPoll(pollId);
@@ -270,13 +270,13 @@ public PollDto getTopPollByStatus(PollDto.PollStatus status) {
270270
public List<PollDto> getTopNPollsByStatus(PollDto.PollStatus status, int n) {
271271
Pageable pageable = org.springframework.data.domain.PageRequest.of(0, n);
272272
List<Object[]> result = pollVoteRepository.findTopNPollByStatus(
273-
com.ai.lawyer.domain.poll.entity.Poll.PollStatus.valueOf(status.name()), pageable);
273+
com.ai.lawyer.domain.poll.entity.Poll.PollStatus.valueOf(status.name()), pageable);
274274
List<PollDto> pollDtos = new java.util.ArrayList<>();
275275
for (Object[] row : result) {
276276
Long pollId = (Long) row[0];
277277
pollDtos.add(status == PollDto.PollStatus.CLOSED
278-
? getPollWithStatistics(pollId)
279-
: getPoll(pollId));
278+
? getPollWithStatistics(pollId)
279+
: getPoll(pollId));
280280
}
281281
return pollDtos;
282282
}
@@ -323,17 +323,17 @@ public PollDto updatePoll(Long pollId, PollUpdateDto pollUpdateDto) {
323323
if (optionDto.getPollItemsId() != null) {
324324
// update
325325
PollOptions option = existingOptions.stream()
326-
.filter(o -> o.getPollItemsId().equals(optionDto.getPollItemsId()))
327-
.findFirst().orElse(null);
326+
.filter(o -> o.getPollItemsId().equals(optionDto.getPollItemsId()))
327+
.findFirst().orElse(null);
328328
if (option != null) {
329329
option.setOption(optionDto.getContent());
330330
pollOptionsRepository.save(option);
331331
}
332332
} else {
333333
PollOptions newOption = PollOptions.builder()
334-
.poll(poll)
335-
.option(optionDto.getContent())
336-
.build();
334+
.poll(poll)
335+
.option(optionDto.getContent())
336+
.build();
337337
pollOptionsRepository.save(newOption);
338338
}
339339
}
@@ -381,17 +381,17 @@ public void patchUpdatePoll(Long pollId, PollUpdateDto pollUpdateDto) {
381381
for (var optionDto : pollUpdateDto.getPollOptions()) {
382382
if (optionDto.getPollItemsId() != null) {
383383
PollOptions option = existingOptions.stream()
384-
.filter(o -> o.getPollItemsId().equals(optionDto.getPollItemsId()))
385-
.findFirst().orElse(null);
384+
.filter(o -> o.getPollItemsId().equals(optionDto.getPollItemsId()))
385+
.findFirst().orElse(null);
386386
if (option != null) {
387387
option.setOption(optionDto.getContent());
388388
pollOptionsRepository.save(option);
389389
}
390390
} else {
391391
PollOptions newOption = PollOptions.builder()
392-
.poll(poll)
393-
.option(optionDto.getContent())
394-
.build();
392+
.poll(poll)
393+
.option(optionDto.getContent())
394+
.build();
395395
pollOptionsRepository.save(newOption);
396396
}
397397
}
@@ -428,50 +428,50 @@ public PollDto getPollWithStatistics(Long pollId) {
428428
PollOptions option = options.get(i);
429429
Long voteCount = pollVoteRepository.countByPollOptionId(option.getPollItemsId());
430430
List<PollStaticsDto> statics = staticsRaw.stream()
431-
.filter(arr -> ((Long)arr[0]).equals(option.getPollItemsId()))
432-
.map(arr -> {
433-
String gender = arr[1] != null ? arr[1].toString() : null;
434-
Integer age = arr[2] != null ? ((Number)arr[2]).intValue() : null;
435-
String ageGroup = getAgeGroup(age);
436-
return PollStaticsDto.builder()
437-
.gender(gender)
438-
.ageGroup(ageGroup)
439-
.voteCount((Long)arr[3])
440-
.build();
441-
})
442-
.toList();
431+
.filter(arr -> ((Long)arr[0]).equals(option.getPollItemsId()))
432+
.map(arr -> {
433+
String gender = arr[1] != null ? arr[1].toString() : null;
434+
Integer age = arr[2] != null ? ((Number)arr[2]).intValue() : null;
435+
String ageGroup = getAgeGroup(age);
436+
return PollStaticsDto.builder()
437+
.gender(gender)
438+
.ageGroup(ageGroup)
439+
.voteCount((Long)arr[3])
440+
.build();
441+
})
442+
.toList();
443443
optionDtos.add(PollOptionDto.builder()
444-
.pollItemsId(option.getPollItemsId())
445-
.content(option.getOption())
446-
.voteCount(voteCount)
447-
.statics(statics)
448-
.pollOptionIndex(i + 1)
449-
.build());
444+
.pollItemsId(option.getPollItemsId())
445+
.content(option.getOption())
446+
.voteCount(voteCount)
447+
.statics(statics)
448+
.pollOptionIndex(i + 1)
449+
.build());
450450
}
451451
} else {
452452
optionDtos = new ArrayList<>();
453453
for (int i = 0; i < options.size(); i++) {
454454
PollOptions option = options.get(i);
455455
Long voteCount = pollVoteRepository.countByPollOptionId(option.getPollItemsId());
456456
optionDtos.add(PollOptionDto.builder()
457-
.pollItemsId(option.getPollItemsId())
458-
.content(option.getOption())
459-
.voteCount(voteCount)
460-
.statics(null)
461-
.pollOptionIndex(i + 1)
462-
.build());
457+
.pollItemsId(option.getPollItemsId())
458+
.content(option.getOption())
459+
.voteCount(voteCount)
460+
.statics(null)
461+
.pollOptionIndex(i + 1)
462+
.build());
463463
}
464464
}
465465
return PollDto.builder()
466-
.pollId(poll.getPollId())
467-
.postId(poll.getPost() != null ? poll.getPost().getPostId() : null)
468-
.voteTitle(poll.getVoteTitle())
469-
.status(PollDto.PollStatus.valueOf(poll.getStatus().name()))
470-
.createdAt(poll.getCreatedAt())
471-
.closedAt(poll.getClosedAt())
472-
.pollOptions(optionDtos)
473-
.totalVoteCount(totalVoteCount)
474-
.build();
466+
.pollId(poll.getPollId())
467+
.postId(poll.getPost() != null ? poll.getPost().getPostId() : null)
468+
.voteTitle(poll.getVoteTitle())
469+
.status(PollDto.PollStatus.valueOf(poll.getStatus().name()))
470+
.createdAt(poll.getCreatedAt())
471+
.closedAt(poll.getClosedAt())
472+
.pollOptions(optionDtos)
473+
.totalVoteCount(totalVoteCount)
474+
.build();
475475
}
476476

477477
private PollDto convertToDto(Poll poll) {
@@ -482,12 +482,12 @@ private PollDto convertToDto(Poll poll) {
482482
PollOptions option = options.get(i);
483483
Long voteCount = pollVoteRepository.countByPollOptionId(option.getPollItemsId());
484484
optionDtos.add(PollOptionDto.builder()
485-
.pollItemsId(option.getPollItemsId())
486-
.content(option.getOption())
487-
.voteCount(voteCount)
488-
.statics(null)
489-
.pollOptionIndex(i + 1)
490-
.build());
485+
.pollItemsId(option.getPollItemsId())
486+
.content(option.getOption())
487+
.voteCount(voteCount)
488+
.statics(null)
489+
.pollOptionIndex(i + 1)
490+
.build());
491491
}
492492
LocalDateTime expectedCloseAt = poll.getReservedCloseAt() != null ? poll.getReservedCloseAt() : poll.getCreatedAt().plusDays(7);
493493
return PollDto.builder()
@@ -568,4 +568,4 @@ public void validatePollCreate(PollForPostDto dto) {
568568
public void validatePollCreate(PollCreateDto dto) {
569569
validatePollCommon(dto.getVoteTitle(), dto.getPollOptions(), dto.getReservedCloseAt());
570570
}
571-
}
571+
}

0 commit comments

Comments
 (0)