feat(music-list): 添加音乐到用户歌单功能
- 新增"添加到我的歌单"选项,仅在用户登录时显示- 实现用户歌单获取和音乐添加到歌单的功能 - 添加相关API调用和错误处理 - 优化分页配置,使用本地状态管理
This commit is contained in:
@@ -100,7 +100,8 @@
|
|||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item command="addToPlaylist">添加到播放列表</el-dropdown-item>
|
<el-dropdown-item command="addToPlaylist">添加到播放列表</el-dropdown-item>
|
||||||
<el-dropdown-item command="playNext">下一首播放</el-dropdown-item>
|
<el-dropdown-item command="playNext">下一首播放</el-dropdown-item>
|
||||||
<el-dropdown-item command="downloadMusic">下载音乐</el-dropdown-item>
|
<el-dropdown-item v-if="userStore.isLoggedIn" command="showAddToPlaylistDialog" divided>添加到我的歌单</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="downloadMusic" :divided="!userStore.isLoggedIn">下载音乐</el-dropdown-item>
|
||||||
<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>
|
||||||
@@ -115,13 +116,30 @@
|
|||||||
<el-pagination
|
<el-pagination
|
||||||
v-model:current-page="localCurrentPage"
|
v-model:current-page="localCurrentPage"
|
||||||
v-model:page-size="localPageSize"
|
v-model:page-size="localPageSize"
|
||||||
:page-sizes="[10, 20, 50, 100]"
|
:page-sizes="pageSizes"
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
:total="total"
|
:total="total"
|
||||||
@size-change="handleSizeChange"
|
@size-change="handleSizeChange"
|
||||||
@current-change="handleCurrentChange"
|
@current-change="handleCurrentChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 添加到歌单弹窗 -->
|
||||||
|
<el-dialog v-model="isAddToPlaylistDialogVisible" title="添加到歌单" width="300px">
|
||||||
|
<div v-loading="loadingUserPlaylists" class="dialog-playlist-container">
|
||||||
|
<ul v-if="userPlaylists.length > 0" class="dialog-playlist-list">
|
||||||
|
<li
|
||||||
|
v-for="playlist in userPlaylists"
|
||||||
|
:key="playlist.id"
|
||||||
|
class="dialog-playlist-item"
|
||||||
|
@click="handleAddToPlaylist(currentMusicToAdd, playlist.id)"
|
||||||
|
>
|
||||||
|
{{ playlist.name }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<el-empty v-else-if="!loadingUserPlaylists" description="您还没有创建过歌单" />
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -130,7 +148,9 @@ import { ref, computed, watch } from 'vue'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { VideoPlay, VideoPause, Star, More, InfoFilled, Pointer } from '@element-plus/icons-vue'
|
import { VideoPlay, VideoPause, Star, More, InfoFilled, Pointer } from '@element-plus/icons-vue'
|
||||||
import { usePlayerStore } from '../stores/player'
|
import { usePlayerStore } from '../stores/player'
|
||||||
|
import { useUserStore } from '../stores/user'
|
||||||
import { toggleCollectMusic, toggleLikeMusic } from '../api/music'
|
import { toggleCollectMusic, toggleLikeMusic } from '../api/music'
|
||||||
|
import { getUserPlaylist, addMusicToPlaylist } from '../api/playlist'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -171,6 +191,7 @@ const router = useRouter()
|
|||||||
// 使用本地状态来代替直接绑定到props
|
// 使用本地状态来代替直接绑定到props
|
||||||
const localCurrentPage = ref(props.currentPage)
|
const localCurrentPage = ref(props.currentPage)
|
||||||
const localPageSize = ref(props.pageSize)
|
const localPageSize = ref(props.pageSize)
|
||||||
|
const pageSizes = [10, 20, 50, 100] // 添加分页大小选项
|
||||||
|
|
||||||
// 监听props变化,更新本地状态
|
// 监听props变化,更新本地状态
|
||||||
watch(() => props.currentPage, (newVal) => {
|
watch(() => props.currentPage, (newVal) => {
|
||||||
@@ -182,6 +203,52 @@ watch(() => props.pageSize, (newVal) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const playerStore = usePlayerStore()
|
const playerStore = usePlayerStore()
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
const userPlaylists = ref([])
|
||||||
|
const loadingUserPlaylists = ref(false)
|
||||||
|
const isAddToPlaylistDialogVisible = ref(false)
|
||||||
|
const currentMusicToAdd = ref(null)
|
||||||
|
|
||||||
|
// 获取用户创建的歌单
|
||||||
|
const fetchUserPlaylists = async () => {
|
||||||
|
if (!userStore.isLoggedIn) {
|
||||||
|
userPlaylists.value = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loadingUserPlaylists.value = true
|
||||||
|
try {
|
||||||
|
// 获取用户所有歌单,这里设置一个比较大的size
|
||||||
|
const res = await getUserPlaylist(1, 200)
|
||||||
|
if (res.code === 200) {
|
||||||
|
userPlaylists.value = res.data.records || res.data.list || []
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.message || '获取您的歌单失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取用户歌单失败:', error)
|
||||||
|
ElMessage.error('获取您的歌单失败')
|
||||||
|
} finally {
|
||||||
|
loadingUserPlaylists.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将音乐添加到歌单
|
||||||
|
const handleAddToPlaylist = async (music, playlistId) => {
|
||||||
|
if (!music || !playlistId) return
|
||||||
|
try {
|
||||||
|
const res = await addMusicToPlaylist(playlistId, music.id)
|
||||||
|
if (res.code === 200 && res.data) {
|
||||||
|
ElMessage.success(`已将《${music.name}》添加到歌单`)
|
||||||
|
isAddToPlaylistDialogVisible.value = false
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.message || '添加失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('添加到歌单失败:', error)
|
||||||
|
ElMessage.error('添加失败,请稍后重试')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 跳转到音乐详情页
|
// 跳转到音乐详情页
|
||||||
const goToMusicDetail = (id) => {
|
const goToMusicDetail = (id) => {
|
||||||
@@ -262,6 +329,11 @@ const handleCommand = (command, music) => {
|
|||||||
ElMessage.success('已添加到播放列表')
|
ElMessage.success('已添加到播放列表')
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
case 'showAddToPlaylistDialog':
|
||||||
|
currentMusicToAdd.value = music
|
||||||
|
fetchUserPlaylists()
|
||||||
|
isAddToPlaylistDialogVisible.value = true
|
||||||
|
break
|
||||||
case 'share':
|
case 'share':
|
||||||
ElMessage.info('分享功能开发中')
|
ElMessage.info('分享功能开发中')
|
||||||
break
|
break
|
||||||
@@ -318,6 +390,29 @@ const handleCurrentChange = (page) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
.dialog-playlist-container {
|
||||||
|
min-height: 150px;
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-playlist-list {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-playlist-item {
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-playlist-item:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
|
||||||
.music-list {
|
.music-list {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|||||||
Reference in New Issue
Block a user