feat(playlist): 添加歌单内删除歌曲功能
- 在 MusicList 组件中添加删除歌曲选项- 在 PlaylistDetail 组件中实现删除歌曲逻辑 - 优化用户交互,增加删除确认提示和删除成功提示 - 更新歌单歌曲数量和列表显示
This commit is contained in:
@@ -105,6 +105,10 @@
|
|||||||
<el-dropdown-item command="downloadLyric">下载歌词</el-dropdown-item>
|
<el-dropdown-item command="downloadLyric">下载歌词</el-dropdown-item>
|
||||||
<el-dropdown-item v-if="detailInMore" command="goToMusicDetail">音乐详情</el-dropdown-item>
|
<el-dropdown-item v-if="detailInMore" command="goToMusicDetail">音乐详情</el-dropdown-item>
|
||||||
<el-dropdown-item command="share" v-if="false">分享</el-dropdown-item>
|
<el-dropdown-item command="share" v-if="false">分享</el-dropdown-item>
|
||||||
|
<el-dropdown-item v-if="isCreator" command="deleteFromPlaylist" class="text-red-500" divided>
|
||||||
|
<el-icon><Delete /></el-icon>
|
||||||
|
从歌单中删除
|
||||||
|
</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
@@ -181,10 +185,14 @@ const props = defineProps({
|
|||||||
detailInMore: {
|
detailInMore: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
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()
|
const router = useRouter()
|
||||||
|
|
||||||
@@ -307,6 +315,12 @@ const toggleLike = async (music) => {
|
|||||||
|
|
||||||
// 处理下拉菜单命令
|
// 处理下拉菜单命令
|
||||||
const handleCommand = (command, music) => {
|
const handleCommand = (command, music) => {
|
||||||
|
// 对于某些命令,直接 emit 出去给父组件处理
|
||||||
|
if (['deleteFromPlaylist'].includes(command)) {
|
||||||
|
emit('command', command, music)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case 'addToPlaylist':
|
case 'addToPlaylist':
|
||||||
playerStore.addToPlaylist(music)
|
playerStore.addToPlaylist(music)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useRoute, useRouter } from 'vue-router'
|
|||||||
import { usePlayerStore } from '../stores/player'
|
import { usePlayerStore } from '../stores/player'
|
||||||
import { useUserStore } from '../stores/user'
|
import { useUserStore } from '../stores/user'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
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 { getMusicStatus } from '../api/music'
|
||||||
import { getCommentList, addComment, deleteComment as apiDeleteComment } from '../api/comment'
|
import { getCommentList, addComment, deleteComment as apiDeleteComment } from '../api/comment'
|
||||||
import { connect, subscribe, unsubscribe, disconnect } from '../utils/websocket' // 导入 WebSocket 工具
|
import { connect, subscribe, unsubscribe, disconnect } from '../utils/websocket' // 导入 WebSocket 工具
|
||||||
@@ -453,6 +453,9 @@ const handleCommand = (command, music) => {
|
|||||||
case 'downloadLyric':
|
case 'downloadLyric':
|
||||||
downloadFile('lyric', music)
|
downloadFile('lyric', music)
|
||||||
break
|
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 订阅实例
|
// WebSocket 订阅实例
|
||||||
let commentSubscription = null;
|
let commentSubscription = null;
|
||||||
|
|
||||||
@@ -582,6 +625,8 @@ onUnmounted(() => {
|
|||||||
:loading="loading"
|
:loading="loading"
|
||||||
:show-pagination="false"
|
:show-pagination="false"
|
||||||
:detail-in-more="true"
|
:detail-in-more="true"
|
||||||
|
:is-creator="isCreator"
|
||||||
|
@command="handleCommand"
|
||||||
/>
|
/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user