mirror of
https://github.com/nagisa77/OpenIsle.git
synced 2026-02-19 05:21:15 +08:00
feat: implement lottery post type
This commit is contained in:
@@ -2,12 +2,15 @@ package com.openisle.service;
|
||||
|
||||
import com.openisle.model.Post;
|
||||
import com.openisle.model.PostStatus;
|
||||
import com.openisle.model.PostType;
|
||||
import com.openisle.model.PublishMode;
|
||||
import com.openisle.model.User;
|
||||
import com.openisle.model.Category;
|
||||
import com.openisle.model.Comment;
|
||||
import com.openisle.model.NotificationType;
|
||||
import com.openisle.model.LotteryPost;
|
||||
import com.openisle.repository.PostRepository;
|
||||
import com.openisle.repository.LotteryPostRepository;
|
||||
import com.openisle.repository.UserRepository;
|
||||
import com.openisle.repository.CategoryRepository;
|
||||
import com.openisle.repository.TagRepository;
|
||||
@@ -21,6 +24,8 @@ import com.openisle.model.Role;
|
||||
import com.openisle.exception.RateLimitException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import com.openisle.service.EmailSender;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
@@ -28,12 +33,19 @@ import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
@Service
|
||||
public class PostService {
|
||||
private final PostRepository postRepository;
|
||||
private final UserRepository userRepository;
|
||||
private final CategoryRepository categoryRepository;
|
||||
private final TagRepository tagRepository;
|
||||
private final LotteryPostRepository lotteryPostRepository;
|
||||
private PublishMode publishMode;
|
||||
private final NotificationService notificationService;
|
||||
private final SubscriptionService subscriptionService;
|
||||
@@ -44,12 +56,15 @@ public class PostService {
|
||||
private final NotificationRepository notificationRepository;
|
||||
private final PostReadService postReadService;
|
||||
private final ImageUploader imageUploader;
|
||||
private final TaskScheduler taskScheduler;
|
||||
private final EmailSender emailSender;
|
||||
|
||||
@org.springframework.beans.factory.annotation.Autowired
|
||||
public PostService(PostRepository postRepository,
|
||||
UserRepository userRepository,
|
||||
CategoryRepository categoryRepository,
|
||||
TagRepository tagRepository,
|
||||
LotteryPostRepository lotteryPostRepository,
|
||||
NotificationService notificationService,
|
||||
SubscriptionService subscriptionService,
|
||||
CommentService commentService,
|
||||
@@ -59,11 +74,14 @@ public class PostService {
|
||||
NotificationRepository notificationRepository,
|
||||
PostReadService postReadService,
|
||||
ImageUploader imageUploader,
|
||||
TaskScheduler taskScheduler,
|
||||
EmailSender emailSender,
|
||||
@Value("${app.post.publish-mode:DIRECT}") PublishMode publishMode) {
|
||||
this.postRepository = postRepository;
|
||||
this.userRepository = userRepository;
|
||||
this.categoryRepository = categoryRepository;
|
||||
this.tagRepository = tagRepository;
|
||||
this.lotteryPostRepository = lotteryPostRepository;
|
||||
this.notificationService = notificationService;
|
||||
this.subscriptionService = subscriptionService;
|
||||
this.commentService = commentService;
|
||||
@@ -73,6 +91,8 @@ public class PostService {
|
||||
this.notificationRepository = notificationRepository;
|
||||
this.postReadService = postReadService;
|
||||
this.imageUploader = imageUploader;
|
||||
this.taskScheduler = taskScheduler;
|
||||
this.emailSender = emailSender;
|
||||
this.publishMode = publishMode;
|
||||
}
|
||||
|
||||
@@ -88,7 +108,13 @@ public class PostService {
|
||||
Long categoryId,
|
||||
String title,
|
||||
String content,
|
||||
java.util.List<Long> tagIds) {
|
||||
java.util.List<Long> tagIds,
|
||||
PostType type,
|
||||
String prizeDescription,
|
||||
String prizeIcon,
|
||||
Integer prizeCount,
|
||||
LocalDateTime startTime,
|
||||
LocalDateTime endTime) {
|
||||
long recent = postRepository.countByAuthorAfter(username,
|
||||
java.time.LocalDateTime.now().minusMinutes(5));
|
||||
if (recent >= 1) {
|
||||
@@ -108,14 +134,31 @@ public class PostService {
|
||||
if (tags.isEmpty()) {
|
||||
throw new IllegalArgumentException("Tag not found");
|
||||
}
|
||||
Post post = new Post();
|
||||
PostType actualType = type != null ? type : PostType.NORMAL;
|
||||
Post post;
|
||||
if (actualType == PostType.LOTTERY) {
|
||||
LotteryPost lp = new LotteryPost();
|
||||
lp.setPrizeDescription(prizeDescription);
|
||||
lp.setPrizeIcon(prizeIcon);
|
||||
lp.setPrizeCount(prizeCount != null ? prizeCount : 0);
|
||||
lp.setStartTime(startTime);
|
||||
lp.setEndTime(endTime);
|
||||
post = lp;
|
||||
} else {
|
||||
post = new Post();
|
||||
}
|
||||
post.setType(actualType);
|
||||
post.setTitle(title);
|
||||
post.setContent(content);
|
||||
post.setAuthor(author);
|
||||
post.setCategory(category);
|
||||
post.setTags(new java.util.HashSet<>(tags));
|
||||
post.setTags(new HashSet<>(tags));
|
||||
post.setStatus(publishMode == PublishMode.REVIEW ? PostStatus.PENDING : PostStatus.PUBLISHED);
|
||||
post = postRepository.save(post);
|
||||
if (post instanceof LotteryPost) {
|
||||
post = lotteryPostRepository.save((LotteryPost) post);
|
||||
} else {
|
||||
post = postRepository.save(post);
|
||||
}
|
||||
imageUploader.addReferences(imageUploader.extractUrls(content));
|
||||
if (post.getStatus() == PostStatus.PENDING) {
|
||||
java.util.List<User> admins = userRepository.findByRole(com.openisle.model.Role.ADMIN);
|
||||
@@ -141,9 +184,42 @@ public class PostService {
|
||||
}
|
||||
}
|
||||
notificationService.notifyMentions(content, author, post, null);
|
||||
|
||||
if (post instanceof LotteryPost lp && lp.getEndTime() != null) {
|
||||
taskScheduler.schedule(() -> finalizeLottery(lp.getId()),
|
||||
java.util.Date.from(lp.getEndTime().atZone(ZoneId.systemDefault()).toInstant()));
|
||||
}
|
||||
return post;
|
||||
}
|
||||
|
||||
public void joinLottery(Long postId, String username) {
|
||||
LotteryPost post = lotteryPostRepository.findById(postId)
|
||||
.orElseThrow(() -> new com.openisle.exception.NotFoundException("Post not found"));
|
||||
User user = userRepository.findByUsername(username)
|
||||
.orElseThrow(() -> new com.openisle.exception.NotFoundException("User not found"));
|
||||
post.getParticipants().add(user);
|
||||
lotteryPostRepository.save(post);
|
||||
}
|
||||
|
||||
private void finalizeLottery(Long postId) {
|
||||
lotteryPostRepository.findById(postId).ifPresent(lp -> {
|
||||
List<User> participants = new ArrayList<>(lp.getParticipants());
|
||||
if (participants.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Collections.shuffle(participants);
|
||||
int winnersCount = Math.min(lp.getPrizeCount(), participants.size());
|
||||
java.util.Set<User> winners = new java.util.HashSet<>(participants.subList(0, winnersCount));
|
||||
lp.setWinners(winners);
|
||||
lotteryPostRepository.save(lp);
|
||||
for (User w : winners) {
|
||||
if (w.getEmail() != null) {
|
||||
emailSender.sendEmail(w.getEmail(), "你中奖了", "恭喜你在抽奖贴 \"" + lp.getTitle() + "\" 中获奖");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Post viewPost(Long id, String viewer) {
|
||||
Post post = postRepository.findById(id)
|
||||
|
||||
Reference in New Issue
Block a user