feat: 添加专辑列表播放

This commit is contained in:
alger
2024-01-01 00:06:52 +08:00
parent 2dbf5dbf03
commit ecd7a56df0
10 changed files with 90 additions and 47 deletions
+42 -37
View File
@@ -1,37 +1,42 @@
import request from "@/utils/request"; import request from "@/utils/request";
import { IList } from "@/type/list"; import { IList } from "@/type/list";
import type { IListDetail } from "@/type/listDetail"; import type { IListDetail } from "@/type/listDetail";
interface IListByTagParams { interface IListByTagParams {
tag: string; tag: string;
before: number; before: number;
limit: number; limit: number;
} }
interface IListByCatParams { interface IListByCatParams {
cat: string; cat: string;
offset: number; offset: number;
limit: number; limit: number;
} }
// 根据tag 获取歌单列表 // 根据tag 获取歌单列表
export function getListByTag(params: IListByTagParams) { export function getListByTag(params: IListByTagParams) {
return request.get<IList>("/top/playlist/highquality", { params: params }); return request.get<IList>("/top/playlist/highquality", { params: params });
} }
// 根据cat 获取歌单列表 // 根据cat 获取歌单列表
export function getListByCat(params: IListByCatParams) { export function getListByCat(params: IListByCatParams) {
return request.get("/top/playlist", { return request.get("/top/playlist", {
params: params, params: params,
}); });
} }
// 获取推荐歌单 // 获取推荐歌单
export function getRecommendList(limit: number = 30) { export function getRecommendList(limit: number = 30) {
return request.get("/personalized", { params: { limit } }); return request.get("/personalized", { params: { limit } });
} }
// 获取歌单详情 // 获取歌单详情
export function getListDetail(id: number | string) { export function getListDetail(id: number | string) {
return request.get<IListDetail>("/playlist/detail", { params: { id } }); return request.get<IListDetail>("/playlist/detail", { params: { id } });
} }
// 获取专辑内容
export function getAlbum(id: number | string) {
return request.get("/album", { params: { id } });
}
+5 -4
View File
@@ -2,11 +2,11 @@
<n-drawer :show="show" height="70vh" placement="bottom" :drawer-style="{ backgroundColor: 'transparent' }"> <n-drawer :show="show" height="70vh" placement="bottom" :drawer-style="{ backgroundColor: 'transparent' }">
<div class="music-page"> <div class="music-page">
<i class="iconfont icon-icon_error music-close" @click="close"></i> <i class="iconfont icon-icon_error music-close" @click="close"></i>
<div class="music-title">{{ musicList?.name }}</div> <div class="music-title">{{ name }}</div>
<!-- 歌单歌曲列表 --> <!-- 歌单歌曲列表 -->
<div class="music-list"> <div class="music-list">
<n-scrollbar > <n-scrollbar >
<div v-for="(item, index) in musicList?.tracks" :key="item.id" :class="setAnimationClass('animate__bounceInUp')" <div v-for="(item, index) in songList" :key="item.id" :class="setAnimationClass('animate__bounceInUp')"
:style="setAnimationDelay(index, 100)"> :style="setAnimationDelay(index, 100)">
<SongItem :item="formatDetail(item)" @play="handlePlay" /> <SongItem :item="formatDetail(item)" @play="handlePlay" />
</div> </div>
@@ -28,7 +28,8 @@ const store = useStore()
const props = defineProps<{ const props = defineProps<{
show: boolean; show: boolean;
musicList: Playlist; name: string;
songList: any[]
}>() }>()
const emit = defineEmits(['update:show']) const emit = defineEmits(['update:show'])
@@ -45,7 +46,7 @@ const formatDetail = computed(() => (detail: any) => {
}) })
const handlePlay = (item: any) => { const handlePlay = (item: any) => {
const tracks = props.musicList?.tracks || [] const tracks = props.songList || []
const musicIndex = (tracks.findIndex((music: any) => music.id == item.id) || 0) const musicIndex = (tracks.findIndex((music: any) => music.id == item.id) || 0)
store.commit('setPlayList', tracks) store.commit('setPlayList', tracks)
} }
+17
View File
@@ -8,6 +8,7 @@
class="recommend-album-list-item" class="recommend-album-list-item"
:class="setAnimationClass('animate__backInUp')" :class="setAnimationClass('animate__backInUp')"
:style="setAnimationDelay(index, 100)" :style="setAnimationDelay(index, 100)"
@click="handleClick(item)"
> >
<n-image <n-image
class="recommend-album-list-item-img" class="recommend-album-list-item-img"
@@ -19,6 +20,7 @@
</div> </div>
</template> </template>
</div> </div>
<MusicList v-model:show="showMusic" :name="albumName" :song-list="songList" />
</div> </div>
</template> </template>
@@ -27,6 +29,7 @@ import { getNewAlbum } from "@/api/home"
import { ref, onMounted } from "vue"; import { ref, onMounted } from "vue";
import type { IAlbumNew } from "@/type/album" import type { IAlbumNew } from "@/type/album"
import { setAnimationClass, setAnimationDelay, getImgUrl } from "@/utils"; import { setAnimationClass, setAnimationDelay, getImgUrl } from "@/utils";
import { getAlbum } from "@/api/list";
const albumData = ref<IAlbumNew>() const albumData = ref<IAlbumNew>()
@@ -35,6 +38,20 @@ const loadAlbumList = async () => {
albumData.value = data albumData.value = data
} }
const showMusic = ref(false)
const songList = ref([])
const albumName = ref('')
const handleClick = async (item:any) => {
albumName.value = item.name
showMusic.value = true
const res = await getAlbum(item.id)
songList.value = res.data.songs.map((song:any)=>{
song.al.picUrl = song.al.picUrl || item.picUrl
return song
})
}
onMounted(() => { onMounted(() => {
loadAlbumList() loadAlbumList()
}) })
+21 -1
View File
@@ -1,5 +1,5 @@
<template> <template>
<div class="search-item"> <div class="search-item" @click="handleClick">
<div class="search-item-img"> <div class="search-item-img">
<n-image <n-image
:src="getImgUrl(item.picUrl, 'album')" :src="getImgUrl(item.picUrl, 'album')"
@@ -11,20 +11,40 @@
<div class="search-item-name">{{ item.name }}</div> <div class="search-item-name">{{ item.name }}</div>
<div class="search-item-artist">{{ item.desc}}</div> <div class="search-item-artist">{{ item.desc}}</div>
</div> </div>
<MusicList v-model:show="showMusic" :name="item.name" :song-list="songList" />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { getImgUrl } from '@/utils' import { getImgUrl } from '@/utils'
import type {Album} from '@/type/album' import type {Album} from '@/type/album'
import { getAlbum } from '@/api/list';
const props = defineProps<{ const props = defineProps<{
item: { item: {
picUrl: string picUrl: string
name: string name: string
desc: string desc: string
type: string
[key: string]: any
} }
}>() }>()
const songList = ref([])
const showMusic = ref(false)
const handleClick = async () => {
showMusic.value = true
if(props.item.type === '专辑'){
const res = await getAlbum(props.item.id)
songList.value = res.data.songs.map((song:any)=>{
song.al.picUrl = song.al.picUrl || props.item.picUrl
return song
})
}
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
+1
View File
@@ -1,6 +1,7 @@
<template> <template>
<div class="song-item" :class="{'song-mini': mini}"> <div class="song-item" :class="{'song-mini': mini}">
<n-image <n-image
v-if="item.picUrl "
:src="getImgUrl( item.picUrl, '40y40')" :src="getImgUrl( item.picUrl, '40y40')"
class="song-item-img" class="song-item-img"
lazy lazy
+1 -1
View File
@@ -57,7 +57,7 @@ const loadLrc = async (playMusicId: number): Promise<void> => {
} }
// 歌词矫正时间Correction time // 歌词矫正时间Correction time
const correctionTime = ref(0) const correctionTime = ref(0.4)
// 增加矫正时间 // 增加矫正时间
const addCorrectionTime = (time: number) => { const addCorrectionTime = (time: number) => {
+1 -1
View File
@@ -79,7 +79,7 @@ const getSongUrl = async (id: number) => {
const { data } = await getMusicUrl(id) const { data } = await getMusicUrl(id)
let url = '' let url = ''
try { try {
if (data.data[0].freeTrialInfo) { if (data.data[0].freeTrialInfo || !data.data[0].url) {
const res = await getParsingMusicUrl(id) const res = await getParsingMusicUrl(id)
url = res.data.data.url url = res.data.data.url
} }
+1 -1
View File
@@ -91,7 +91,7 @@ watch(
</div> </div>
<PlayBottom/> <PlayBottom/>
</n-scrollbar> </n-scrollbar>
<MusicList v-if="listDetail?.playlist" v-model:show="showMusic" :music-list="listDetail?.playlist" /> <MusicList v-if="listDetail?.playlist" v-model:show="showMusic" :name="listDetail?.playlist.name" :song-list="listDetail?.playlist.tracks" />
</div> </div>
</template> </template>
-1
View File
@@ -123,7 +123,6 @@ const loadSearch = async (keywords: any) => {
songs, songs,
albums albums
} }
console.log('searchDetail',searchDetail.value)
}; };
loadSearch(route.query.keyword); loadSearch(route.query.keyword);
+1 -1
View File
@@ -145,7 +145,7 @@ const handlePlay = (item: any) => {
</n-scrollbar> </n-scrollbar>
</div> </div>
</div> </div>
<MusicList v-if="list" v-model:show="isShowList" :music-list="list" /> <MusicList v-if="list" v-model:show="isShowList" :name="list.name" :song-list="list.tracks" />
</div> </div>
</template> </template>