diff --git a/backend/src/main/java/com/openisle/dto/PostChangeLogDto.java b/backend/src/main/java/com/openisle/dto/PostChangeLogDto.java index ce5d55201..296287f0a 100644 --- a/backend/src/main/java/com/openisle/dto/PostChangeLogDto.java +++ b/backend/src/main/java/com/openisle/dto/PostChangeLogDto.java @@ -29,4 +29,5 @@ public class PostChangeLogDto { private LocalDateTime newPinnedAt; private Boolean oldFeatured; private Boolean newFeatured; + private Integer amount; } diff --git a/backend/src/main/java/com/openisle/mapper/PostChangeLogMapper.java b/backend/src/main/java/com/openisle/mapper/PostChangeLogMapper.java index 52611c5d7..cb0d1a9f1 100644 --- a/backend/src/main/java/com/openisle/mapper/PostChangeLogMapper.java +++ b/backend/src/main/java/com/openisle/mapper/PostChangeLogMapper.java @@ -52,6 +52,8 @@ public class PostChangeLogMapper { } else if (log instanceof PostFeaturedChangeLog f) { dto.setOldFeatured(f.isOldFeatured()); dto.setNewFeatured(f.isNewFeatured()); + } else if (log instanceof PostDonateChangeLog d) { + dto.setAmount(d.getAmount()); } return dto; } diff --git a/backend/src/main/java/com/openisle/model/PostChangeType.java b/backend/src/main/java/com/openisle/model/PostChangeType.java index c09a5555a..eeee99cbb 100644 --- a/backend/src/main/java/com/openisle/model/PostChangeType.java +++ b/backend/src/main/java/com/openisle/model/PostChangeType.java @@ -10,4 +10,5 @@ public enum PostChangeType { FEATURED, VOTE_RESULT, LOTTERY_RESULT, + DONATE, } diff --git a/backend/src/main/java/com/openisle/model/PostDonateChangeLog.java b/backend/src/main/java/com/openisle/model/PostDonateChangeLog.java new file mode 100644 index 000000000..50eed96eb --- /dev/null +++ b/backend/src/main/java/com/openisle/model/PostDonateChangeLog.java @@ -0,0 +1,19 @@ +package com.openisle.model; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Table; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +@Entity +@Table(name = "post_donate_change_logs") +public class PostDonateChangeLog extends PostChangeLog { + + @Column(nullable = false) + private int amount; +} diff --git a/backend/src/main/java/com/openisle/service/PointService.java b/backend/src/main/java/com/openisle/service/PointService.java index 52a732512..7b4af0f96 100644 --- a/backend/src/main/java/com/openisle/service/PointService.java +++ b/backend/src/main/java/com/openisle/service/PointService.java @@ -25,6 +25,7 @@ public class PointService { private final CommentRepository commentRepository; private final PointHistoryRepository pointHistoryRepository; private final NotificationService notificationService; + private final PostChangeLogService postChangeLogService; public int awardForPost(String userName, Long postId) { User user = userRepository.findByUsername(userName).orElseThrow(); @@ -304,6 +305,7 @@ public class PointService { null, String.valueOf(amount) ); + postChangeLogService.recordDonation(post, donor, amount); DonationResponse response = buildDonationResponse(post); response.setBalance(donor.getPoint()); return response; @@ -322,19 +324,38 @@ public class PointService { ); List donations = histories .stream() - .map(history -> { - DonationDto dto = new DonationDto(); - User donor = history.getFromUser(); - if (donor != null) { - dto.setUserId(donor.getId()); - dto.setUsername(donor.getUsername()); - dto.setAvatar(donor.getAvatar()); - } - dto.setAmount(history.getAmount()); - dto.setCreatedAt(history.getCreatedAt()); - return dto; - }) - .collect(Collectors.toList()); + .collect(Collectors.collectingAndThen(Collectors.toMap( + history -> { + User donor = history.getFromUser(); + if (donor != null && donor.getId() != null) { + return "user:" + donor.getId(); + } + return "history:" + history.getId(); + }, + history -> { + DonationDto dto = new DonationDto(); + User donor = history.getFromUser(); + if (donor != null) { + dto.setUserId(donor.getId()); + dto.setUsername(donor.getUsername()); + dto.setAvatar(donor.getAvatar()); + } + dto.setAmount(history.getAmount()); + dto.setCreatedAt(history.getCreatedAt()); + return dto; + }, + (left, right) -> { + left.setAmount(left.getAmount() + right.getAmount()); + if ( + left.getCreatedAt() == null || + (right.getCreatedAt() != null && right.getCreatedAt().isAfter(left.getCreatedAt())) + ) { + left.setCreatedAt(right.getCreatedAt()); + } + return left; + }, + java.util.LinkedHashMap::new + ), map -> new java.util.ArrayList<>(map.values()))); Long total = pointHistoryRepository.sumAmountByPostAndType( post, PointHistoryType.DONATE_RECEIVED diff --git a/backend/src/main/java/com/openisle/service/PostChangeLogService.java b/backend/src/main/java/com/openisle/service/PostChangeLogService.java index df78a266d..0d3fd28ad 100644 --- a/backend/src/main/java/com/openisle/service/PostChangeLogService.java +++ b/backend/src/main/java/com/openisle/service/PostChangeLogService.java @@ -115,6 +115,15 @@ public class PostChangeLogService { logRepository.save(log); } + public void recordDonation(Post post, User donor, int amount) { + PostDonateChangeLog log = new PostDonateChangeLog(); + log.setPost(post); + log.setUser(donor); + log.setType(PostChangeType.DONATE); + log.setAmount(amount); + logRepository.save(log); + } + public void deleteLogsForPost(Post post) { logRepository.deleteByPost(post); } diff --git a/frontend_nuxt/components/PostChangeLogItem.vue b/frontend_nuxt/components/PostChangeLogItem.vue index b9ead1887..c55d15763 100644 --- a/frontend_nuxt/components/PostChangeLogItem.vue +++ b/frontend_nuxt/components/PostChangeLogItem.vue @@ -42,6 +42,9 @@ 系统已「精密计算」抽奖结果 (=゚ω゚)ノ + 为文章打赏了 {{ log.amount ?? 0 }} 积分
{{ log.time }}
{ return 'check-one' } else if (l.type === 'LOTTERY_RESULT') { return 'gift' + } else if (l.type === 'DONATE') { + return 'financing' } else { return 'info' } @@ -436,6 +438,7 @@ const mapChangeLog = (l) => ({ newCategory: l.newCategory, oldTags: l.oldTags, newTags: l.newTags, + amount: l.amount, icon: changeLogIcon(l), })