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

Feat#95 #96

Merged
merged 6 commits into from
Feb 10, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ dependencies {
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.springframework.boot:spring-boot-starter-validation'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springdoc:springdoc-openapi-ui:1.6.15'
implementation 'io.springfox:springfox-swagger2:2.9.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ public enum ErrorStatus implements BaseErrorCode {
POST_SCRAP_NOT_FOUND(HttpStatus.NOT_FOUND, "POST4004", "글에 대한 스크랩 데이터를 찾을 수 없습니다."),
POST_GENERAL_POLL_NOT_FOUND(HttpStatus.NOT_FOUND, "POST4005", "글에 대한 일반 투표 데이터를 찾을 수 없습니다."),
POST_CARD_POLL_NOT_FOUND(HttpStatus.NOT_FOUND, "POST4006", "글에 대한 카드 투표 데이터를 찾을 수 없습니다."),
TITLE_TEXT_LIMIT(HttpStatus.BAD_REQUEST,"POST4007","최소 5자 이상, 30자 미만 입력해 주세요"),
CONTENT_TEXT_LIMIT(HttpStatus.BAD_REQUEST,"POST4008","최소 5자 이상, 1000자 미만 입력해 주세요"),
CANDIDATE_TEXT_LIMIT(HttpStatus.BAD_REQUEST,"POST4009","최소 1자 이상, 30자 미만 입력해 주세요"),
DEADLINE_LIMIT(HttpStatus.BAD_REQUEST,"POST4010","최소 1분~최대30일로 입력해 주세요"),
CANDIDATE_NOT_FOUND(HttpStatus.NOT_FOUND,"POST4011","후보를 찾을 수 없습니다"),
TOO_MUCH_FIXED(HttpStatus.NOT_FOUND,"POST4012","이미 2회 이상 수정 했습니다"),
NOT_ENOUGH_POINT(HttpStatus.BAD_REQUEST,"POST4013","해당 유저의 포인트가 부족 합니다"),

// 댓글 관련 응답
COMMENT_NOT_FOUND(HttpStatus.NOT_FOUND, "COMMENT4001", "댓글을 찾을 수 없습니다."),
Expand Down
105 changes: 105 additions & 0 deletions src/main/java/friend/spring/converter/PostConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ public static PostResponseDTO.PostDetailResponse postDetailResponse(Post post, B
List<Integer> percent=null;
List<String> voteResult=null;
Integer value=null;
Boolean isVote=false;
Boolean isLike=!post.getPostLikeList().stream().filter(like->like.getUser().getId().equals(userId)).collect(Collectors.toList()).isEmpty();
Boolean isComment=!post.getCommentList().stream().filter(like->like.getUser().getId().equals(userId)).collect(Collectors.toList()).isEmpty();
if(post.getUser().getId().equals(userId)){
Expand All @@ -254,12 +255,15 @@ public static PostResponseDTO.PostDetailResponse postDetailResponse(Post post, B
if(post.getVoteType()==PostVoteType.GAUGE){
if(engage){
value=post.getGaugePoll().getGauge();
isVote=true;
}
return PostResponseDTO.PostDetailResponse.builder()
.nickname(post.getUser().getNickname())
.createdAt(post.getCreatedAt())
.title(post.getTitle())
.content(post.getContent())
.OnGoing(post.getGaugePoll().getVoteOnGoing())
.isVoted(isVote)
.file(FileConverter.toFileDTO(post.getFileList()))
.gauge(value)
.point(post.getPoint())
Expand Down Expand Up @@ -318,12 +322,48 @@ public static PostResponseDTO.PostDetailResponse postDetailResponse(Post post, B
return String.format("%d/%d", selectionCount, totalVotes);
})
.collect(Collectors.toList());
isVote=true;
if(myPost){
// 투표수가 가장 많은 후보의 선택률 계산
OptionalDouble hightestCandidate = candidateSelectionCounts.values().stream()
.mapToDouble(aLong -> (double) aLong / totalVotes)
.max();

// 선택률이 가장 높은 후보의 ID들 찾기
List<Long> mostVotedCandidateIds = candidateSelectionCounts.entrySet().stream()
.filter(entry -> Double.compare(entry.getValue(), hightestCandidate.getAsDouble() * totalVotes) == 0)
.map(Map.Entry::getKey)
.collect(Collectors.toList());

// 가장 높은 투표를 받은 후보들을 userChoiceList에 담기
userChoiceList = post.getGeneralPoll().getCandidateList().stream()
.filter(candidate -> mostVotedCandidateIds.contains(candidate.getId()))
.map(PostConverter::toPollOptionResDTO)
.collect(Collectors.toList());

percent = mostVotedCandidateIds.stream()
.map(candidateId -> {
long selectionCount = candidateSelectionCounts.getOrDefault(candidateId, 0L);
return (int) ((double) selectionCount / totalVotes * 100);
})
.collect(Collectors.toList());

// 사용자가 선택한 후보의 투표 결과 정보 계산 (선택 인원/총 인원)
voteResult = mostVotedCandidateIds.stream()
.map(candidateId -> {
long selectionCount = candidateSelectionCounts.getOrDefault(candidateId, 0L);
return String.format("%d/%d", selectionCount, totalVotes);
})
.collect(Collectors.toList());
}
}
return PostResponseDTO.PostDetailResponse.builder()
.nickname(post.getUser().getNickname())
.createdAt(post.getCreatedAt())
.title(post.getTitle())
.content(post.getContent())
.OnGoing(post.getGeneralPoll().getVoteOnGoing())
.isVoted(isVote)
.file(FileConverter.toFileDTO(post.getFileList()))
.pollTitle(post.getGeneralPoll().getPollTitle())
.pollOption(pollOptionDTOList)
Expand Down Expand Up @@ -370,6 +410,7 @@ public static PostResponseDTO.PostDetailResponse postDetailResponse(Post post, B
.flatMap(vote -> vote.getSelect_list().stream())
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));


// 사용자가 선택한 후보의 선택률 계산
percent = userSelectedCandidateIds.stream()
.map(candidateId -> {
Expand All @@ -385,12 +426,76 @@ public static PostResponseDTO.PostDetailResponse postDetailResponse(Post post, B
return String.format("%d/%d", selectionCount, totalVotes);
})
.collect(Collectors.toList());
isVote=true;
if(myPost){
// 투표수가 가장 많은 후보의 선택률 계산
OptionalDouble hightestCandidate = candidateSelectionCounts.values().stream()
.mapToDouble(aLong -> (double) aLong / totalVotes)
.max();

// 선택률이 가장 높은 후보의 ID들 찾기
List<Long> mostVotedCandidateIds = candidateSelectionCounts.entrySet().stream()
.filter(entry -> Double.compare(entry.getValue(), hightestCandidate.getAsDouble() * totalVotes) == 0)
.map(Map.Entry::getKey)
.collect(Collectors.toList());


percent = mostVotedCandidateIds.stream()
.map(candidateId -> {
long selectionCount = candidateSelectionCounts.getOrDefault(candidateId, 0L);
return (int) ((double) selectionCount / totalVotes * 100);
})
.collect(Collectors.toList());

// 사용자가 선택한 후보의 투표 결과 정보 계산 (선택 인원/총 인원)
voteResult = mostVotedCandidateIds.stream()
.map(candidateId -> {
long selectionCount = candidateSelectionCounts.getOrDefault(candidateId, 0L);
return String.format("%d/%d", selectionCount, totalVotes);
})
.collect(Collectors.toList());
}
if(myPost){
// 투표수가 가장 많은 후보의 선택률 계산
OptionalDouble hightestCandidate = candidateSelectionCounts.entrySet().stream()
.mapToDouble(entry -> (double) entry.getValue() / totalVotes)
.max();

// 선택률이 가장 높은 후보의 ID들 찾기
List<Long> mostVotedCandidateIds = candidateSelectionCounts.entrySet().stream()
.filter(entry -> entry.getValue() == hightestCandidate.getAsDouble() * totalVotes)
.map(Map.Entry::getKey)
.collect(Collectors.toList());

// 가장 높은 투표를 받은 후보들을 userChoiceList에 담기
userChoiceList = post.getCardPoll().getCandidateList().stream()
.filter(candidate -> mostVotedCandidateIds.contains(candidate.getId()))
.map(PostConverter::toPollOptionResDTO)
.collect(Collectors.toList());

percent = mostVotedCandidateIds.stream()
.map(candidateId -> {
long selectionCount = candidateSelectionCounts.getOrDefault(candidateId, 0L);
return (int) ((double) selectionCount / totalVotes * 100);
})
.collect(Collectors.toList());

// 사용자가 선택한 후보의 투표 결과 정보 계산 (선택 인원/총 인원)
voteResult = mostVotedCandidateIds.stream()
.map(candidateId -> {
long selectionCount = candidateSelectionCounts.getOrDefault(candidateId, 0L);
return String.format("%d/%d", selectionCount, totalVotes);
})
.collect(Collectors.toList());
}
}
return PostResponseDTO.PostDetailResponse.builder()
.nickname(post.getUser().getNickname())
.createdAt(post.getCreatedAt())
.title(post.getTitle())
.content(post.getContent())
.OnGoing(post.getCardPoll().getVoteOnGoing())
.isVoted(isVote)
.file(FileConverter.toFileDTO(post.getFileList()))
.pollTitle(post.getCardPoll().getPollTitle())
.pollOption(pollOptionDTOList)
Expand Down
13 changes: 12 additions & 1 deletion src/main/java/friend/spring/domain/Card_poll.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ public class Card_poll extends BaseEntity {

@Column(nullable = true)
@Builder.Default
private Timestamp deadline= Timestamp.valueOf(LocalDateTime.now().plusHours(1)); // 디폴트 시간 1시간 설정.
private LocalDateTime deadline= LocalDateTime.now().plusHours(1); // 디폴트 시간 1시간 설정.
Copy link
Member

@MinYeongPark MinYeongPark Feb 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분에서 deadline이 -9(UTC 차이) + 1시간인 값이 디폴트로 들어가게 되더라구요..!!

https://red-mimmu.tistory.com/105
이 글 참고해서 한번 서울로 시간 조정되도록 반영해보겠습니다! -> 반영한 커밋 하나 날렸습니다!

Copy link
Member

@MinYeongPark MinYeongPark Feb 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
Swagger에서 deadline에서 default로 뜨는 값도 LocalDateTime.now().plusHours(1); 으로 자동으로 뜨게 하고 싶었는데,, 여러 설정을 변경해봤지만 여기에서는 계속 UTC 시간으로 뜨네요,,

프론트분들이 보내주실 때는 값을 설정해서 주시게 되니까,, 그대로 진행해도 괜찮을 것 같습니다..!!😂

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

감사합니다!!!


@Column(nullable = true)
@Builder.Default
private Boolean VoteOnGoing=true;

@Builder.Default
@OneToMany(mappedBy = "cardPoll", cascade = CascadeType.ALL)
Expand All @@ -44,6 +48,13 @@ public class Card_poll extends BaseEntity {
public void setPost(Post post) {
this.post = post;
}

public void setDeadline(LocalDateTime deadline){
this.deadline=deadline;
}
public void setVoteOnGoing(Boolean voteOnGoing){
this.VoteOnGoing=voteOnGoing;
}
public void setMultipleChoice(Boolean multipleChoice){
this.multipleChoice=multipleChoice;
}
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/friend/spring/domain/Gauge_poll.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ public class Gauge_poll extends BaseEntity {

@Builder.Default
@Column(nullable = true)
private Timestamp deadline= Timestamp.valueOf(LocalDateTime.now().plusHours(1)); // 디폴트 시간 1시간 설정.
private LocalDateTime deadline= LocalDateTime.now().plusHours(1); // 디폴트 시간 1시간 설정.

@Column(nullable = true)
@Builder.Default
private Boolean VoteOnGoing=true;

@OneToOne(mappedBy = "gaugePoll", cascade = CascadeType.ALL)
@JoinColumn(name = "post_id")
Expand All @@ -42,6 +46,14 @@ public void setPost(Post post) {
this.post = post;
}

public void setDeadline(LocalDateTime deadline){
this.deadline=deadline;
}

public void setVoteOnGoing(Boolean voteOnGoing){
this.VoteOnGoing=voteOnGoing;
}

public void setGauge(Integer gauge) {
this.gauge = gauge;
}
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/friend/spring/domain/General_poll.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ public class General_poll extends BaseEntity {

@Column(nullable = true)
@Builder.Default
private Timestamp deadline= Timestamp.valueOf(LocalDateTime.now().plusHours(1)); // 디폴트 시간 1시간 설정.
private LocalDateTime deadline= LocalDateTime.now().plusHours(1); // 디폴트 시간 1시간 설정.

@Column(nullable = true)
@Builder.Default
private Boolean VoteOnGoing=true;

@Builder.Default
@OneToMany(mappedBy = "generalPoll", cascade = CascadeType.ALL)
Expand All @@ -46,6 +50,12 @@ public void setPost(Post post) {
this.post = post;
}

public void setDeadline(LocalDateTime deadline){
this.deadline=deadline;
}
public void setVoteOnGoing(Boolean voteOnGoing){
this.VoteOnGoing=voteOnGoing;
}
public void setMultipleChoice(Boolean multipleChoice){
this.multipleChoice=multipleChoice;
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/friend/spring/domain/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import lombok.*;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -50,6 +51,10 @@ public class Post extends BaseEntity {
@Column(nullable = true)
private Integer point;

@Builder.Default
@Column(nullable = false)
private Integer isFixed=0;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
Expand Down Expand Up @@ -162,7 +167,12 @@ public void setContent(String content){
this.content=content;
}

public void setIsFixed(Integer isFixed){
this.isFixed=isFixed;
}

public void setStateDel(){
this.state=PostState.DELETED;
}

}
2 changes: 1 addition & 1 deletion src/main/java/friend/spring/service/PostQueryService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import java.util.Optional;

public interface PostQueryService {
Optional<Post> getPostDetail(Long postId);
Post getPostDetail(Long postId);
Boolean checkEngage(Long userId, Long postId);

Post ParentPost(Long parentid);
Expand Down
19 changes: 12 additions & 7 deletions src/main/java/friend/spring/service/PostQueryServiceImpl.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package friend.spring.service;

import friend.spring.apiPayload.GeneralException;
import friend.spring.apiPayload.code.status.ErrorStatus;
import friend.spring.converter.PostConverter;
import friend.spring.domain.*;
import friend.spring.domain.enums.PostState;
Expand All @@ -22,6 +24,7 @@
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
Expand All @@ -35,11 +38,10 @@ public class PostQueryServiceImpl implements PostQueryService{
private final JwtTokenProvider jwtTokenProvider;
@Override
@Transactional
public Optional<Post> getPostDetail(Long postId){
Optional<Post> postOptional=postRepository.findById(postId);
Post post = postOptional.get();
public Post getPostDetail(Long postId){
Post post=postRepository.findById(postId).orElseThrow(() -> new GeneralException(ErrorStatus.POST_NOT_FOUND));
post.setView(post.getView()+1);
return postOptional;
return post;
}

@Override
Expand All @@ -53,23 +55,26 @@ public Boolean checkEngage(Long postId,Long userId){
if(post.getPostType()== PostType.VOTE){
if(post.getVoteType()== PostVoteType.GENERAL){
List<General_vote> vote=generalVoteRepository.findByUserId(userId);
if (!vote.isEmpty()) { // 목록이 비어 있지 않으면 true를 반환
Boolean isIn=vote.stream().filter(pollPost->pollPost.getGeneralPoll()==post.getGeneralPoll()).collect(Collectors.toList()).isEmpty();
if (!isIn) { // 목록이 비어 있지 않으면 true를 반환
return true;
}
}
}
if(post.getPostType()== PostType.VOTE){
if(post.getVoteType()== PostVoteType.CARD){
List<Card_vote> vote=cardVoteRepository.findByUserId(userId);
if (!vote.isEmpty()) { // 목록이 비어 있지 않으면 true를 반환
Boolean isIn=vote.stream().filter(pollPost->pollPost.getCardPoll()==post.getCardPoll()).collect(Collectors.toList()).isEmpty();
if (!isIn) { // 목록이 비어 있지 않으면 true를 반환
return true;
}
}
}
if(post.getPostType()== PostType.VOTE){
if(post.getVoteType()== PostVoteType.GAUGE){
List<Gauge_vote> vote=gaugeVoteRepository.findByUserId(userId);
if (!vote.isEmpty()) { // 목록이 비어 있지 않으면 true를 반환
Boolean isIn=vote.stream().filter(pollPost->pollPost.getGaugePoll()==post.getGaugePoll()).collect(Collectors.toList()).isEmpty();
if (!isIn) { // 목록이 비어 있지 않으면 true를 반환
return true;
}
}
Expand Down
Loading