mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-24 16:27:23 +08:00
✨ feat: 添加专辑列表播放
This commit is contained in:
+42
-37
@@ -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 } });
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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,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
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user