mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-03-17 01:20:46 +08:00
Merge pull request #793 from nagisa77/codex/add-participant-info-to-vote-response
feat: expose poll option participants
This commit is contained in:
@@ -12,5 +12,5 @@ public class PollDto {
|
|||||||
private List<String> options;
|
private List<String> options;
|
||||||
private Map<Integer, Integer> votes;
|
private Map<Integer, Integer> votes;
|
||||||
private LocalDateTime endTime;
|
private LocalDateTime endTime;
|
||||||
private List<AuthorDto> participants;
|
private Map<Integer, List<AuthorDto>> participants;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,12 @@ import com.openisle.dto.PostSummaryDto;
|
|||||||
import com.openisle.dto.ReactionDto;
|
import com.openisle.dto.ReactionDto;
|
||||||
import com.openisle.dto.LotteryDto;
|
import com.openisle.dto.LotteryDto;
|
||||||
import com.openisle.dto.PollDto;
|
import com.openisle.dto.PollDto;
|
||||||
|
import com.openisle.dto.AuthorDto;
|
||||||
import com.openisle.model.CommentSort;
|
import com.openisle.model.CommentSort;
|
||||||
import com.openisle.model.Post;
|
import com.openisle.model.Post;
|
||||||
import com.openisle.model.LotteryPost;
|
import com.openisle.model.LotteryPost;
|
||||||
import com.openisle.model.PollPost;
|
import com.openisle.model.PollPost;
|
||||||
|
import com.openisle.model.PollParticipant;
|
||||||
import com.openisle.model.User;
|
import com.openisle.model.User;
|
||||||
import com.openisle.service.CommentService;
|
import com.openisle.service.CommentService;
|
||||||
import com.openisle.service.ReactionService;
|
import com.openisle.service.ReactionService;
|
||||||
@@ -19,6 +21,7 @@ import org.springframework.stereotype.Component;
|
|||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/** Mapper responsible for converting posts into DTOs. */
|
/** Mapper responsible for converting posts into DTOs. */
|
||||||
@@ -102,7 +105,10 @@ public class PostMapper {
|
|||||||
p.setOptions(pp.getOptions());
|
p.setOptions(pp.getOptions());
|
||||||
p.setVotes(pp.getVotes());
|
p.setVotes(pp.getVotes());
|
||||||
p.setEndTime(pp.getEndTime());
|
p.setEndTime(pp.getEndTime());
|
||||||
p.setParticipants(pp.getParticipants().stream().map(userMapper::toAuthorDto).collect(Collectors.toList()));
|
Map<Integer, List<AuthorDto>> participants = pp.getParticipants().stream()
|
||||||
|
.collect(Collectors.groupingBy(PollParticipant::getOptionIndex,
|
||||||
|
Collectors.mapping(ppart -> userMapper.toAuthorDto(ppart.getUser()), Collectors.toList())));
|
||||||
|
p.setParticipants(participants);
|
||||||
dto.setPoll(p);
|
dto.setPoll(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.openisle.model;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a single vote in a poll, capturing which user selected which option.
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@Table(name = "poll_participants")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class PollParticipant {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "post_id", nullable = false)
|
||||||
|
private PollPost post;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "user_id", nullable = false)
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
@Column(name = "option_index", nullable = false)
|
||||||
|
private int optionIndex;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -30,11 +30,8 @@ public class PollPost extends Post {
|
|||||||
@Column(name = "vote_count")
|
@Column(name = "vote_count")
|
||||||
private Map<Integer, Integer> votes = new HashMap<>();
|
private Map<Integer, Integer> votes = new HashMap<>();
|
||||||
|
|
||||||
@ManyToMany
|
@OneToMany(mappedBy = "post", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||||
@JoinTable(name = "poll_participants",
|
private Set<PollParticipant> participants = new HashSet<>();
|
||||||
joinColumns = @JoinColumn(name = "post_id"),
|
|
||||||
inverseJoinColumns = @JoinColumn(name = "user_id"))
|
|
||||||
private Set<User> participants = new HashSet<>();
|
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
private LocalDateTime endTime;
|
private LocalDateTime endTime;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.openisle.model.Comment;
|
|||||||
import com.openisle.model.NotificationType;
|
import com.openisle.model.NotificationType;
|
||||||
import com.openisle.model.LotteryPost;
|
import com.openisle.model.LotteryPost;
|
||||||
import com.openisle.model.PollPost;
|
import com.openisle.model.PollPost;
|
||||||
|
import com.openisle.model.PollParticipant;
|
||||||
import com.openisle.repository.PostRepository;
|
import com.openisle.repository.PostRepository;
|
||||||
import com.openisle.repository.LotteryPostRepository;
|
import com.openisle.repository.LotteryPostRepository;
|
||||||
import com.openisle.repository.PollPostRepository;
|
import com.openisle.repository.PollPostRepository;
|
||||||
@@ -293,13 +294,19 @@ public class PostService {
|
|||||||
}
|
}
|
||||||
User user = userRepository.findByUsername(username)
|
User user = userRepository.findByUsername(username)
|
||||||
.orElseThrow(() -> new com.openisle.exception.NotFoundException("User not found"));
|
.orElseThrow(() -> new com.openisle.exception.NotFoundException("User not found"));
|
||||||
if (post.getParticipants().contains(user)) {
|
boolean alreadyVoted = post.getParticipants().stream()
|
||||||
|
.anyMatch(p -> p.getUser().equals(user));
|
||||||
|
if (alreadyVoted) {
|
||||||
throw new IllegalArgumentException("User already voted");
|
throw new IllegalArgumentException("User already voted");
|
||||||
}
|
}
|
||||||
if (optionIndex < 0 || optionIndex >= post.getOptions().size()) {
|
if (optionIndex < 0 || optionIndex >= post.getOptions().size()) {
|
||||||
throw new IllegalArgumentException("Invalid option");
|
throw new IllegalArgumentException("Invalid option");
|
||||||
}
|
}
|
||||||
post.getParticipants().add(user);
|
PollParticipant participant = new PollParticipant();
|
||||||
|
participant.setPost(post);
|
||||||
|
participant.setUser(user);
|
||||||
|
participant.setOptionIndex(optionIndex);
|
||||||
|
post.getParticipants().add(participant);
|
||||||
post.getVotes().merge(optionIndex, 1, Integer::sum);
|
post.getVotes().merge(optionIndex, 1, Integer::sum);
|
||||||
return pollPostRepository.save(post);
|
return pollPostRepository.save(post);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user