From c7588d3de8b73c55b3d6c2982c290d066749a616 Mon Sep 17 00:00:00 2001 From: ikmkj Date: Wed, 11 Mar 2026 13:33:53 +0800 Subject: [PATCH] =?UTF-8?q?feat(comment):=20=E5=AE=9E=E7=8E=B0=E8=AF=84?= =?UTF-8?q?=E8=AE=BA=E5=88=A0=E9=99=A4=E7=9A=84WebSocket=E5=AE=9E=E6=97=B6?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 后端服务删除评论时通过WebSocket广播删除事件 - 前端音乐详情页接收删除消息并从列表中移除对应评论 - 前端歌单详情页支持删除事件处理并更新评论计数 - 前端歌手详情页实现删除事件处理和评论计数更新 - 支持父子评论层级结构的删除操作 - 统一WebSocket消息格式包含删除状态和评论ID信息 --- .../service/impl/CommentServiceImpl.java | 18 +++++++++++++++ music-qianduan/src/views/MusicDetail.vue | 20 +++++++++++++++- music-qianduan/src/views/PlaylistDetail.vue | 23 ++++++++++++++++++- music-qianduan/src/views/SingerDetail.vue | 23 ++++++++++++++++++- 4 files changed, 81 insertions(+), 3 deletions(-) diff --git a/music-houduan/src/main/java/com/test/musichouduan/service/impl/CommentServiceImpl.java b/music-houduan/src/main/java/com/test/musichouduan/service/impl/CommentServiceImpl.java index fdfa260..a19ab52 100644 --- a/music-houduan/src/main/java/com/test/musichouduan/service/impl/CommentServiceImpl.java +++ b/music-houduan/src/main/java/com/test/musichouduan/service/impl/CommentServiceImpl.java @@ -28,7 +28,9 @@ import org.springframework.transaction.annotation.Transactional; import jakarta.persistence.criteria.Predicate; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; @@ -221,6 +223,14 @@ public class CommentServiceImpl implements CommentService { } } + // 通过 WebSocket 广播删除事件 + String destination = String.format("/topic/comments/%d/%d", comment.getTargetType(), comment.getTargetId()); + Map deleteEvent = new HashMap<>(); + deleteEvent.put("deleted", true); + deleteEvent.put("id", id); + deleteEvent.put("parentId", comment.getParentId()); + messagingTemplate.convertAndSend(destination, deleteEvent); + return true; } @@ -343,6 +353,14 @@ public class CommentServiceImpl implements CommentService { } } + // 通过 WebSocket 广播删除事件 + String destination = String.format("/topic/comments/%d/%d", comment.getTargetType(), comment.getTargetId()); + Map deleteEvent = new HashMap<>(); + deleteEvent.put("deleted", true); + deleteEvent.put("id", id); + deleteEvent.put("parentId", comment.getParentId()); + messagingTemplate.convertAndSend(destination, deleteEvent); + return true; } diff --git a/music-qianduan/src/views/MusicDetail.vue b/music-qianduan/src/views/MusicDetail.vue index 17c2935..57fec97 100644 --- a/music-qianduan/src/views/MusicDetail.vue +++ b/music-qianduan/src/views/MusicDetail.vue @@ -490,7 +490,25 @@ const setupWebSocket = () => { if (!music.value) return; connect(() => { const destination = `/topic/comments/1/${music.value.id}`; // 1 代表音乐类型 - commentSubscription = subscribe(destination, (newComment) => { + commentSubscription = subscribe(destination, (message) => { + // 处理删除事件 + if (message && message.deleted) { + const deletedId = message.id; + if (message.parentId) { + // 删除子评论 + const parentComment = comments.value.find(c => c.id === message.parentId); + if (parentComment && parentComment.children) { + parentComment.children = parentComment.children.filter(c => c.id !== deletedId); + } + } else { + // 删除父评论 + comments.value = comments.value.filter(c => c.id !== deletedId); + } + return; + } + + // 处理新增评论 + const newComment = message; if (newComment && newComment.id) { if (newComment.user && newComment.user.avatar) { newComment.user.avatar = processImageUrl(newComment.user.avatar); diff --git a/music-qianduan/src/views/PlaylistDetail.vue b/music-qianduan/src/views/PlaylistDetail.vue index 75264f7..fc3ee24 100644 --- a/music-qianduan/src/views/PlaylistDetail.vue +++ b/music-qianduan/src/views/PlaylistDetail.vue @@ -525,7 +525,28 @@ onMounted(() => { // 连接 WebSocket 并订阅评论 connect(() => { const destination = `/topic/comments/2/${playlistId.value}`; // 2 代表歌单类型 - commentSubscription = subscribe(destination, (newComment) => { + commentSubscription = subscribe(destination, (message) => { + // 处理删除事件 + if (message && message.deleted) { + const deletedId = message.id; + if (message.parentId) { + // 删除子评论 + const parentComment = comments.value.find(c => c.id === message.parentId); + if (parentComment && parentComment.children) { + parentComment.children = parentComment.children.filter(c => c.id !== deletedId); + } + } else { + // 删除父评论 + comments.value = comments.value.filter(c => c.id !== deletedId); + } + if (playlist.value && playlist.value.commentCount > 0) { + playlist.value.commentCount--; + } + return; + } + + // 处理新增评论 + const newComment = message; if (newComment && newComment.id) { if (newComment.user && newComment.user.avatar) { newComment.user.avatar = processImageUrl(newComment.user.avatar); diff --git a/music-qianduan/src/views/SingerDetail.vue b/music-qianduan/src/views/SingerDetail.vue index 8a17f7e..49fabfd 100644 --- a/music-qianduan/src/views/SingerDetail.vue +++ b/music-qianduan/src/views/SingerDetail.vue @@ -441,7 +441,28 @@ onMounted(() => { // 连接 WebSocket 并订阅评论 connect(() => { const destination = `/topic/comments/3/${singerId.value}`; // 3 代表歌手类型 - commentSubscription = subscribe(destination, (newComment) => { + commentSubscription = subscribe(destination, (message) => { + // 处理删除事件 + if (message && message.deleted) { + const deletedId = message.id; + if (message.parentId) { + // 删除子评论 + const parentComment = comments.value.find(c => c.id === message.parentId); + if (parentComment && parentComment.children) { + parentComment.children = parentComment.children.filter(c => c.id !== deletedId); + } + } else { + // 删除父评论 + comments.value = comments.value.filter(c => c.id !== deletedId); + } + if (singer.value && singer.value.commentCount > 0) { + singer.value.commentCount--; + } + return; + } + + // 处理新增评论 + const newComment = message; if (newComment && newComment.id) { if (newComment.user && newComment.user.avatar) { newComment.user.avatar = processImageUrl(newComment.user.avatar);