From 9c5a49a47f312d3f1f6ab8be98822c5b0098be31 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 23 Oct 2025 15:29:55 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AE=8C=E5=96=84=E6=8F=90=E6=A1=88?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E6=B5=81=E7=A8=8B=EF=BC=8C=E9=98=B2=E6=AD=A2?= =?UTF-8?q?=E9=87=8D=E5=A4=8D=E9=80=9A=E7=9F=A5=EF=BC=8C=E6=8F=90=E6=A1=88?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E8=87=AA=E5=8A=A8=E6=8F=92=E5=85=A5=E5=88=86?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/openisle/model/NotificationType.java | 4 ++ .../com/openisle/service/PostService.java | 33 ++++++++--- frontend_nuxt/pages/index.vue | 7 +-- frontend_nuxt/pages/message.vue | 58 +++++++++++++++++-- frontend_nuxt/utils/notification.js | 6 +- 5 files changed, 88 insertions(+), 20 deletions(-) diff --git a/backend/src/main/java/com/openisle/model/NotificationType.java b/backend/src/main/java/com/openisle/model/NotificationType.java index 74262c9b2..6bf7c0224 100644 --- a/backend/src/main/java/com/openisle/model/NotificationType.java +++ b/backend/src/main/java/com/openisle/model/NotificationType.java @@ -46,6 +46,10 @@ public enum NotificationType { POLL_RESULT_OWNER, /** A poll you participated in has concluded */ POLL_RESULT_PARTICIPANT, + /** Your category proposal has concluded */ + CATEGORY_PROPOSAL_RESULT_OWNER, + /** A category proposal you participated in has concluded */ + CATEGORY_PROPOSAL_RESULT_PARTICIPANT, /** Your post was featured */ POST_FEATURED, /** Someone donated to your post */ diff --git a/backend/src/main/java/com/openisle/service/PostService.java b/backend/src/main/java/com/openisle/service/PostService.java index 4ff13c11e..7457c947c 100644 --- a/backend/src/main/java/com/openisle/service/PostService.java +++ b/backend/src/main/java/com/openisle/service/PostService.java @@ -70,6 +70,7 @@ public class PostService { private final PointService pointService; private final PostChangeLogService postChangeLogService; private final PointHistoryRepository pointHistoryRepository; + private final CategoryService categoryService; private final ConcurrentMap> scheduledFinalizations = new ConcurrentHashMap<>(); @@ -112,7 +113,8 @@ public class PostService { PointHistoryRepository pointHistoryRepository, @Value("${app.post.publish-mode:DIRECT}") PublishMode publishMode, RedisTemplate redisTemplate, - SearchIndexEventPublisher searchIndexEventPublisher + SearchIndexEventPublisher searchIndexEventPublisher, + CategoryService categoryService ) { this.postRepository = postRepository; this.userRepository = userRepository; @@ -141,6 +143,7 @@ public class PostService { this.redisTemplate = redisTemplate; this.searchIndexEventPublisher = searchIndexEventPublisher; + this.categoryService = categoryService; } @EventListener(ApplicationReadyEvent.class) @@ -429,8 +432,11 @@ public class PostService { boolean quorumMet = totalParticipants >= cp.getQuorum(); int approvePercent = totalParticipants > 0 ? (approveVotes * 100) / totalParticipants : 0; boolean thresholdMet = approvePercent >= cp.getApproveThreshold(); + boolean approved = false; + String rejectReason = null; if (quorumMet && thresholdMet) { cp.setProposalStatus(CategoryProposalStatus.APPROVED); + approved = true; } else { cp.setProposalStatus(CategoryProposalStatus.REJECTED); String reason; @@ -442,6 +448,7 @@ public class PostService { reason = "赞成率不足"; } cp.setRejectReason(reason); + rejectReason = reason; } cp.setResultSnapshot( "approveVotes=" + @@ -452,28 +459,37 @@ public class PostService { approvePercent ); categoryProposalPostRepository.save(cp); + if (approved) { + categoryService.createCategory(cp.getProposedName(), cp.getDescription(), "star", null); + } if (cp.getAuthor() != null) { notificationService.createNotification( cp.getAuthor(), - NotificationType.POLL_RESULT_OWNER, + NotificationType.CATEGORY_PROPOSAL_RESULT_OWNER, cp, null, + approved, null, null, - null, - null + approved ? null : rejectReason ); } for (User participant : cp.getParticipants()) { + if ( + cp.getAuthor() != null && + java.util.Objects.equals(participant.getId(), cp.getAuthor().getId()) + ) { + continue; + } notificationService.createNotification( participant, - NotificationType.POLL_RESULT_PARTICIPANT, + NotificationType.CATEGORY_PROPOSAL_RESULT_PARTICIPANT, cp, null, + approved, null, null, - null, - null + approved ? null : rejectReason ); } postChangeLogService.recordVoteResult(cp); @@ -576,6 +592,9 @@ public class PostService { pollPostRepository .findById(postId) .ifPresent(pp -> { + if (pp instanceof CategoryProposalPost) { + return; + } if (pp.isResultAnnounced()) { return; } diff --git a/frontend_nuxt/pages/index.vue b/frontend_nuxt/pages/index.vue index 10e106510..78a7160a7 100644 --- a/frontend_nuxt/pages/index.vue +++ b/frontend_nuxt/pages/index.vue @@ -1,10 +1,5 @@ + + @@ -775,6 +817,10 @@ const formatType = (t) => { return '发布的投票结果已公布' case 'POLL_RESULT_PARTICIPANT': return '参与的投票结果已公布' + case 'CATEGORY_PROPOSAL_RESULT_OWNER': + return '分类提案结果已公布' + case 'CATEGORY_PROPOSAL_RESULT_PARTICIPANT': + return '参与的分类提案结果已公布' default: return t } diff --git a/frontend_nuxt/utils/notification.js b/frontend_nuxt/utils/notification.js index 9d71e2a54..c13f1d9cd 100644 --- a/frontend_nuxt/utils/notification.js +++ b/frontend_nuxt/utils/notification.js @@ -28,6 +28,8 @@ const iconMap = { POLL_VOTE: 'ChartHistogram', POLL_RESULT_OWNER: 'RankingList', POLL_RESULT_PARTICIPANT: 'ChartLine', + CATEGORY_PROPOSAL_RESULT_OWNER: 'TagOne', + CATEGORY_PROPOSAL_RESULT_PARTICIPANT: 'TagOne', MENTION: 'HashtagKey', POST_DELETED: 'ClearIcon', POST_FEATURED: 'Star', @@ -254,7 +256,9 @@ function createFetchNotifications() { } else if ( n.type === 'POLL_VOTE' || n.type === 'POLL_RESULT_OWNER' || - n.type === 'POLL_RESULT_PARTICIPANT' + n.type === 'POLL_RESULT_PARTICIPANT' || + n.type === 'CATEGORY_PROPOSAL_RESULT_OWNER' || + n.type === 'CATEGORY_PROPOSAL_RESULT_PARTICIPANT' ) { arr.push({ ...n,