From f77e1213350245a58e4f2969206e296c0dccd153 Mon Sep 17 00:00:00 2001
From: ikmkj <1@qq,com>
Date: Fri, 25 Jul 2025 20:22:49 +0800
Subject: [PATCH] =?UTF-8?q?feat(comment):=20=E6=B7=BB=E5=8A=A0=E6=AD=8C?=
=?UTF-8?q?=E5=8D=95=E8=AF=A6=E6=83=85=E9=A1=B5=E8=AF=84=E8=AE=BA=E5=9B=9E?=
=?UTF-8?q?=E5=A4=8D=E4=B8=8E=E5=B1=95=E5=BC=80=E5=8A=9F=E8=83=BD=20-=20?=
=?UTF-8?q?=E5=AE=9E=E7=8E=B0=E8=AF=84=E8=AE=BA=E5=9B=9E=E5=A4=8D=E8=BE=93?=
=?UTF-8?q?=E5=85=A5=E4=B8=8E=E6=8F=90=E4=BA=A4=E5=8A=9F=E8=83=BD=EF=BC=8C?=
=?UTF-8?q?=E6=94=AF=E6=8C=81@=E7=94=A8=E6=88=B7=E5=90=8D=20-=20=E6=B7=BB?=
=?UTF-8?q?=E5=8A=A0=E5=9B=9E=E5=A4=8D=E5=B1=95=E5=BC=80=E4=B8=8E=E6=94=B6?=
=?UTF-8?q?=E8=B5=B7=E4=BA=A4=E4=BA=92=EF=BC=8C=E6=94=AF=E6=8C=81=E6=9F=A5?=
=?UTF-8?q?=E7=9C=8B=E5=AD=90=E8=AF=84=E8=AE=BA=20-=20=E4=BD=BF=E7=94=A8?=
=?UTF-8?q?=20WebSocket=20=E6=8E=A5=E6=94=B6=E6=96=B0=E8=AF=84=E8=AE=BA?=
=?UTF-8?q?=E4=B8=8E=E5=9B=9E=E5=A4=8D=EF=BC=8C=E5=B9=B6=E5=A4=84=E7=90=86?=
=?UTF-8?q?=E7=94=A8=E6=88=B7=E5=A4=B4=E5=83=8F=E5=9B=BE=E7=89=87=20-=20?=
=?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AF=84=E8=AE=BA=E5=B1=95=E7=A4=BA=E7=BB=93?=
=?UTF-8?q?=E6=9E=84=EF=BC=8C=E5=8C=BA=E5=88=86=E4=B8=BB=E8=AF=84=E8=AE=BA?=
=?UTF-8?q?=E4=B8=8E=E5=AD=90=E8=AF=84=E8=AE=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
music-qianduan/src/views/PlaylistDetail.vue | 143 +++++++++++++++++---
1 file changed, 127 insertions(+), 16 deletions(-)
diff --git a/music-qianduan/src/views/PlaylistDetail.vue b/music-qianduan/src/views/PlaylistDetail.vue
index 2821a9f..920ca72 100644
--- a/music-qianduan/src/views/PlaylistDetail.vue
+++ b/music-qianduan/src/views/PlaylistDetail.vue
@@ -7,6 +7,7 @@ import { ElMessage, ElMessageBox } from 'element-plus'
import { getPlaylistById, toggleCollectPlaylist, deletePlaylist as apiDeletePlaylist } from '../api/playlist'
import { getCommentList, addComment, deleteComment as apiDeleteComment } from '../api/comment'
import { connect, subscribe, unsubscribe, disconnect } from '../utils/websocket' // 导入 WebSocket 工具
+import { processImageUrl } from '../utils/imageUtils'
const route = useRoute()
const router = useRouter()
@@ -25,6 +26,18 @@ const comments = ref([])
// 评论内容
const commentContent = ref('')
+// 回复内容
+const replyContent = ref('')
+
+// 回复对象
+const replyTo = ref(null)
+
+// 正在回复的评论
+const replyingTo = ref(null)
+
+// 展开的评论
+const expandedComments = ref([])
+
// 加载状态
const loading = ref(false)
@@ -158,15 +171,48 @@ const deleteComment = async (commentId) => {
}
}
+// 切换回复可见性
+const toggleReplies = (comment) => {
+ const commentId = comment.id;
+ const index = expandedComments.value.indexOf(commentId);
+ if (index > -1) {
+ expandedComments.value.splice(index, 1);
+ if (replyingTo.value === commentId) {
+ cancelReply();
+ }
+ } else {
+ expandedComments.value.push(commentId);
+ setReplyTo(comment);
+ }
+};
+
+// 设置回复
+const setReplyTo = (comment) => {
+ replyingTo.value = comment.id;
+ replyTo.value = comment;
+ replyContent.value = `@${comment.user.username} `;
+ if (!expandedComments.value.includes(comment.id)) {
+ expandedComments.value.push(comment.id);
+ }
+}
+
+// 取消回复
+const cancelReply = () => {
+ replyingTo.value = null
+ replyTo.value = null
+ replyContent.value = ''
+}
+
// 提交评论
-const submitComment = async () => {
+const submitComment = async (isReply = false) => {
if (!userStore.isLoggedIn) {
ElMessage.warning('请先登录')
router.push('/login')
return
}
- if (!commentContent.value.trim()) {
+ const content = isReply ? replyContent.value : commentContent.value
+ if (!content.trim()) {
ElMessage.warning('评论内容不能为空')
return
}
@@ -175,14 +221,17 @@ const submitComment = async () => {
const res = await addComment({
targetId: playlistId.value,
targetType: 2, // 2表示歌单
- content: commentContent.value
+ content: content,
+ parentId: isReply ? replyingTo.value : null
})
if (res.code === 200) {
- // 添加成功,评论将通过 WebSocket 推送,无需手动刷新
- // await fetchComments() // 移除手动刷新
- commentContent.value = ''
- ElMessage.success('评论已发送') // 提示语可以调整
+ if (isReply) {
+ replyContent.value = ''
+ } else {
+ commentContent.value = ''
+ }
+ ElMessage.success('评论已发送')
} else {
ElMessage.error(res.message || '评论失败')
}
@@ -259,15 +308,26 @@ onMounted(() => {
connect(() => {
const destination = `/topic/comments/2/${playlistId.value}`; // 2 代表歌单类型
commentSubscription = subscribe(destination, (newComment) => {
- // 收到新评论,添加到列表开头
if (newComment && newComment.id) {
- // 检查是否已存在(防止重复添加,虽然理论上不应发生)
- if (!comments.value.some(c => c.id === newComment.id)) {
- comments.value.unshift(newComment); // 添加到开头
- console.log('New comment received via WebSocket:', newComment);
- }
+ if (newComment.user && newComment.user.avatar) {
+ newComment.user.avatar = processImageUrl(newComment.user.avatar);
+ }
+
+ if (newComment.parentId) {
+ const parentComment = comments.value.find(c => c.id === newComment.parentId);
+ if (parentComment) {
+ if (!parentComment.children) {
+ parentComment.children = [];
+ }
+ parentComment.children.push(newComment);
+ }
+ } else {
+ if (!comments.value.some(c => c.id === newComment.id)) {
+ comments.value.unshift(newComment);
+ }
+ }
} else {
- console.warn("Received invalid comment data via WebSocket:", newComment);
+ console.warn("Received invalid comment data via WebSocket:", newComment);
}
});
}, (error) => {
@@ -413,7 +473,9 @@ onUnmounted(() => {
:rows="3"
placeholder="发表你的评论..."
/>
-