diff --git a/backend/src/main/java/com/openisle/model/NotificationType.java b/backend/src/main/java/com/openisle/model/NotificationType.java index d9735bc29..132af5176 100644 --- a/backend/src/main/java/com/openisle/model/NotificationType.java +++ b/backend/src/main/java/com/openisle/model/NotificationType.java @@ -32,6 +32,8 @@ public enum NotificationType { REGISTER_REQUEST, /** A user redeemed an activity reward */ ACTIVITY_REDEEM, + /** A user redeemed a point good */ + POINT_REDEEM, /** You won a lottery post */ LOTTERY_WIN, /** Your lottery post was drawn */ diff --git a/backend/src/main/java/com/openisle/service/NotificationService.java b/backend/src/main/java/com/openisle/service/NotificationService.java index b459456b7..d0d83c36a 100644 --- a/backend/src/main/java/com/openisle/service/NotificationService.java +++ b/backend/src/main/java/com/openisle/service/NotificationService.java @@ -141,6 +141,19 @@ public class NotificationService { } } + /** + * Create notifications for all admins when a user redeems a point good. + * Old redeem notifications from the same user are removed first. + */ + @org.springframework.transaction.annotation.Transactional + public void createPointRedeemNotifications(User user, String content) { + notificationRepository.deleteByTypeAndFromUser(NotificationType.POINT_REDEEM, user); + for (User admin : userRepository.findByRole(Role.ADMIN)) { + createNotification(admin, NotificationType.POINT_REDEEM, null, null, + null, user, null, content); + } + } + public List listPreferences(String username) { User user = userRepository.findByUsername(username) .orElseThrow(() -> new com.openisle.exception.NotFoundException("User not found")); diff --git a/backend/src/main/java/com/openisle/service/PointMallService.java b/backend/src/main/java/com/openisle/service/PointMallService.java index 6ca552953..c930ca7f6 100644 --- a/backend/src/main/java/com/openisle/service/PointMallService.java +++ b/backend/src/main/java/com/openisle/service/PointMallService.java @@ -31,7 +31,7 @@ public class PointMallService { } user.setPoint(user.getPoint() - good.getCost()); userRepository.save(user); - notificationService.createActivityRedeemNotifications(user, good.getName() + ": " + contact); + notificationService.createPointRedeemNotifications(user, good.getName() + ": " + contact); return user.getPoint(); } } diff --git a/backend/src/test/java/com/openisle/service/NotificationServiceTest.java b/backend/src/test/java/com/openisle/service/NotificationServiceTest.java index c4ca007a1..a01d3c95b 100644 --- a/backend/src/test/java/com/openisle/service/NotificationServiceTest.java +++ b/backend/src/test/java/com/openisle/service/NotificationServiceTest.java @@ -144,6 +144,30 @@ class NotificationServiceTest { verify(nRepo).save(any(Notification.class)); } + @Test + void createPointRedeemNotificationsDeletesOldOnes() { + NotificationRepository nRepo = mock(NotificationRepository.class); + UserRepository uRepo = mock(UserRepository.class); + ReactionRepository rRepo = mock(ReactionRepository.class); + EmailSender email = mock(EmailSender.class); + PushNotificationService push = mock(PushNotificationService.class); + Executor executor = Runnable::run; + NotificationService service = new NotificationService(nRepo, uRepo, email, push, rRepo, executor); + org.springframework.test.util.ReflectionTestUtils.setField(service, "websiteUrl", "https://ex.com"); + + User admin = new User(); + admin.setId(10L); + User user = new User(); + user.setId(20L); + + when(uRepo.findByRole(Role.ADMIN)).thenReturn(List.of(admin)); + + service.createPointRedeemNotifications(user, "contact"); + + verify(nRepo).deleteByTypeAndFromUser(NotificationType.POINT_REDEEM, user); + verify(nRepo).save(any(Notification.class)); + } + @Test void createNotificationSendsEmailForCommentReply() { NotificationRepository nRepo = mock(NotificationRepository.class); diff --git a/frontend_nuxt/pages/message.vue b/frontend_nuxt/pages/message.vue index 0755fcd09..788e525ef 100644 --- a/frontend_nuxt/pages/message.vue +++ b/frontend_nuxt/pages/message.vue @@ -130,6 +130,12 @@ 申请进行奶茶兑换,联系方式是:{{ item.content }} +