From 8dab1503320862ef3fe1f2e68f46fe98241a4854 Mon Sep 17 00:00:00 2001
From: ikmkj <1@qq,com>
Date: Tue, 29 Jul 2025 21:18:51 +0800
Subject: [PATCH] =?UTF-8?q?feat(playlist):=20=E6=B7=BB=E5=8A=A0=E6=AD=8C?=
=?UTF-8?q?=E5=8D=95=E5=86=85=E5=88=A0=E9=99=A4=E6=AD=8C=E6=9B=B2=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 在 MusicList 组件中添加删除歌曲选项- 在 PlaylistDetail 组件中实现删除歌曲逻辑
- 优化用户交互,增加删除确认提示和删除成功提示
- 更新歌单歌曲数量和列表显示
---
music-qianduan/src/components/MusicList.vue | 16 ++++++-
music-qianduan/src/views/PlaylistDetail.vue | 47 ++++++++++++++++++++-
2 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/music-qianduan/src/components/MusicList.vue b/music-qianduan/src/components/MusicList.vue
index 8eef1ca..544003f 100644
--- a/music-qianduan/src/components/MusicList.vue
+++ b/music-qianduan/src/components/MusicList.vue
@@ -105,6 +105,10 @@
下载歌词
音乐详情
分享
+
+
+ 从歌单中删除
+
@@ -181,10 +185,14 @@ const props = defineProps({
detailInMore: {
type: Boolean,
default: false
+ },
+ isCreator: {
+ type: Boolean,
+ default: false
}
})
-const emit = defineEmits(['update:currentPage', 'update:pageSize', 'page-change', 'collect-change', 'like-change'])
+const emit = defineEmits(['update:currentPage', 'update:pageSize', 'page-change', 'collect-change', 'like-change', 'command'])
const router = useRouter()
@@ -307,6 +315,12 @@ const toggleLike = async (music) => {
// 处理下拉菜单命令
const handleCommand = (command, music) => {
+ // 对于某些命令,直接 emit 出去给父组件处理
+ if (['deleteFromPlaylist'].includes(command)) {
+ emit('command', command, music)
+ return
+ }
+
switch (command) {
case 'addToPlaylist':
playerStore.addToPlaylist(music)
diff --git a/music-qianduan/src/views/PlaylistDetail.vue b/music-qianduan/src/views/PlaylistDetail.vue
index cbc9574..4ed2157 100644
--- a/music-qianduan/src/views/PlaylistDetail.vue
+++ b/music-qianduan/src/views/PlaylistDetail.vue
@@ -4,7 +4,7 @@ import { useRoute, useRouter } from 'vue-router'
import { usePlayerStore } from '../stores/player'
import { useUserStore } from '../stores/user'
import { ElMessage, ElMessageBox } from 'element-plus'
-import { getPlaylistById, toggleCollectPlaylist, deletePlaylist as apiDeletePlaylist, isPlaylistCollected, updatePlaylist, playPlaylist } from '../api/playlist'
+import { getPlaylistById, toggleCollectPlaylist, deletePlaylist as apiDeletePlaylist, isPlaylistCollected, updatePlaylist, playPlaylist, removeMusicFromPlaylist } from '../api/playlist'
import { getMusicStatus } from '../api/music'
import { getCommentList, addComment, deleteComment as apiDeleteComment } from '../api/comment'
import { connect, subscribe, unsubscribe, disconnect } from '../utils/websocket' // 导入 WebSocket 工具
@@ -453,6 +453,9 @@ const handleCommand = (command, music) => {
case 'downloadLyric':
downloadFile('lyric', music)
break
+ case 'deleteFromPlaylist':
+ deleteFromPlaylist(music)
+ break
}
}
@@ -472,6 +475,46 @@ const downloadFile = (type, music) => {
})
}
+// 从歌单中删除歌曲
+const deleteFromPlaylist = async (music) => {
+ if (!isCreator.value) {
+ ElMessage.warning('只有创建者才能删除歌曲')
+ return
+ }
+
+ try {
+ await ElMessageBox.confirm(`确定要从歌单中移除歌曲《${music.name}》吗?`, '提示', {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning'
+ })
+
+ const res = await removeMusicFromPlaylist(playlistId.value, music.id)
+ if (res.code === 200) {
+ ElMessage.success('歌曲已移除')
+ // 从 UI 中移除歌曲
+ const index = playlist.value.songs.findIndex(s => s.id === music.id)
+ if (index !== -1) {
+ playlist.value.songs.splice(index, 1)
+ }
+ // 更新歌曲数量
+ if (playlist.value.musicCount > 0) {
+ playlist.value.musicCount--
+ }
+ if (playlist.value.songCount > 0) {
+ playlist.value.songCount--
+ }
+ } else {
+ ElMessage.error(res.message || '移除失败')
+ }
+ } catch (error) {
+ if (error !== 'cancel') {
+ console.error('移除歌曲失败:', error)
+ ElMessage.error('移除失败,请稍后重试')
+ }
+ }
+}
+
// WebSocket 订阅实例
let commentSubscription = null;
@@ -582,6 +625,8 @@ onUnmounted(() => {
:loading="loading"
:show-pagination="false"
:detail-in-more="true"
+ :is-creator="isCreator"
+ @command="handleCommand"
/>