447 lines
9.3 KiB
Vue
447 lines
9.3 KiB
Vue
<template>
|
|
<div class="lmt-width">
|
|
<n-carousel
|
|
show-arrow
|
|
trigger="hover"
|
|
:autoplay="true"
|
|
style="margin: 0 auto; max-width: 800px"
|
|
>
|
|
<div
|
|
class="wp-carousel"
|
|
v-for="(b, idx) in banners"
|
|
:key="idx"
|
|
>
|
|
<img class="carousel-img" :src="b.imageUrl" />
|
|
<span class="title">{{ b.typeTitle }}</span>
|
|
</div>
|
|
</n-carousel>
|
|
<!-- 最新音乐 -->
|
|
<div>
|
|
<n-button
|
|
text
|
|
icon-placement="right"
|
|
size="large"
|
|
type="primary"
|
|
style="font-size: 1.3em; margin-top: 6px"
|
|
>
|
|
<template #icon>
|
|
<n-icon>
|
|
<ChevronForward />
|
|
</n-icon>
|
|
</template>
|
|
最新音乐
|
|
</n-button>
|
|
<n-grid
|
|
:x-gap="18"
|
|
:y-gap="8"
|
|
:cols="2"
|
|
style="margin: 6px 0"
|
|
>
|
|
<n-grid-item
|
|
v-for="(song, idx) in topSongs"
|
|
key="idx"
|
|
>
|
|
<div class="c2-list">
|
|
<div class="play-btn">
|
|
<img :src="song.album.blurPicUrl" />
|
|
<n-button
|
|
text
|
|
class="start-play-bg"
|
|
type="info"
|
|
>
|
|
<n-icon>
|
|
<PlayCircle @click="play(song.id)" />
|
|
</n-icon>
|
|
</n-button>
|
|
<n-button
|
|
text
|
|
class="start-play"
|
|
type="primary"
|
|
>
|
|
<n-icon>
|
|
<Play @click="play(song.id)" />
|
|
</n-icon>
|
|
</n-button>
|
|
</div>
|
|
<div class="title">
|
|
<span class="name">
|
|
{{ song.name }}
|
|
<span class="alias"
|
|
><template
|
|
v-for="(al, idx) in song.alias"
|
|
>
|
|
{{ al }}
|
|
</template></span
|
|
>
|
|
</span>
|
|
<span class="artist">
|
|
<ArtistsSpan :artists="song.artists" />
|
|
</span>
|
|
</div>
|
|
<span class="icon"></span>
|
|
</div>
|
|
</n-grid-item>
|
|
</n-grid>
|
|
</div>
|
|
<!-- 推荐MV -->
|
|
<div>
|
|
<!-- 标题 -->
|
|
<n-button
|
|
text
|
|
icon-placement="right"
|
|
size="large"
|
|
type="primary"
|
|
style="font-size: 1.3em; margin-top: 6px"
|
|
>
|
|
<template #icon>
|
|
<n-icon>
|
|
<ChevronForward />
|
|
</n-icon>
|
|
</template>
|
|
推荐MV
|
|
</n-button>
|
|
<!-- 列表 -->
|
|
<n-grid
|
|
:x-gap="18"
|
|
:y-gap="8"
|
|
:cols="4"
|
|
style="margin: 6px 0"
|
|
>
|
|
<n-grid-item
|
|
v-for="(mv, idx) in personalizedMV"
|
|
key="idx"
|
|
>
|
|
<div class="mv-c2-list">
|
|
<div class="play-mv">
|
|
<div>
|
|
<img :src="mv.picUrl" />
|
|
</div>
|
|
<n-button
|
|
text
|
|
class="start-play-bg"
|
|
type="info"
|
|
>
|
|
<n-icon>
|
|
<PlayCircle />
|
|
</n-icon>
|
|
</n-button>
|
|
<n-button
|
|
text
|
|
class="start-play"
|
|
type="primary"
|
|
>
|
|
<n-icon>
|
|
<Play />
|
|
</n-icon>
|
|
</n-button>
|
|
</div>
|
|
<div class="title">
|
|
<span class="name">
|
|
{{ mv.name }}
|
|
</span>
|
|
<span class="artist">{{
|
|
mv.artistName
|
|
}}</span>
|
|
</div>
|
|
</div>
|
|
</n-grid-item>
|
|
</n-grid>
|
|
</div>
|
|
<!-- 推荐歌单 -->
|
|
<div>
|
|
<n-button
|
|
text
|
|
icon-placement="right"
|
|
size="large"
|
|
type="primary"
|
|
style="font-size: 1.3em; margin-top: 6px"
|
|
>
|
|
<template #icon>
|
|
<n-icon>
|
|
<ChevronForward />
|
|
</n-icon>
|
|
</template>
|
|
推荐歌单
|
|
</n-button>
|
|
<n-grid
|
|
:x-gap="18"
|
|
:y-gap="8"
|
|
:cols="4"
|
|
style="margin: 6px 0"
|
|
>
|
|
<n-grid-item v-for="p in personalized">
|
|
<n-card
|
|
title
|
|
hoverable
|
|
content-style="padding: 2px 6px;"
|
|
>
|
|
<template #cover>
|
|
<img :src="p.picUrl" />
|
|
</template>
|
|
<span class="card-span">{{ p.name }}</span>
|
|
</n-card>
|
|
</n-grid-item>
|
|
</n-grid>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted, onUnmounted } from "vue";
|
|
import { useStore } from "vuex";
|
|
import {
|
|
NCarousel,
|
|
NScrollbar,
|
|
NGrid,
|
|
NGridItem,
|
|
NCard,
|
|
NButton,
|
|
NIcon,
|
|
NImage,
|
|
} from "naive-ui";
|
|
// import {
|
|
// ChevronForward,
|
|
// PlayCircle,
|
|
// Play,
|
|
// } from "@vicons/ionicons5";
|
|
import PlayCircle from "@/assets/svgs/PlayCircle.svg";
|
|
import Play from "@/assets/svgs/Play_.svg";
|
|
import ChevronForward from "@/assets/svgs/ChevronForward.svg";
|
|
import {
|
|
getBanner,
|
|
getPersonalized,
|
|
getTopSong,
|
|
getPersonalizedMV,
|
|
} from "@/network/discover";
|
|
import pubsub from "pubsub-js";
|
|
import ArtistsSpan from "@/components/ArtistsSpan.vue";
|
|
|
|
// console.log("recommend 初始化");
|
|
|
|
const store = useStore();
|
|
|
|
const play = (id) => {
|
|
pubsub.publish("zp.play", { id, im: true });
|
|
};
|
|
|
|
|
|
//#region 轮播图片
|
|
let banners = ref([]);
|
|
banners.value = store.getters.cache('banners')
|
|
getBanner(0)
|
|
.then((res) => {
|
|
banners.value = res.data.banners;
|
|
store.commit("saveCaches", {
|
|
banners: { data: banners.value, time: Date.now() },
|
|
});
|
|
// console.log(banners.value);
|
|
})
|
|
.catch((err) => {
|
|
console.log("getBanner err", err);
|
|
});
|
|
|
|
//#endregion
|
|
|
|
//#region 最新音乐
|
|
let topSongs = ref([]);
|
|
// topSongs.value = store.getters.cache('topSongs')
|
|
if(store.getters.cache('topSongs'))
|
|
{
|
|
topSongs.value = store.getters.cache('topSongs')
|
|
console.log('载入Caches');
|
|
}
|
|
//最新音乐
|
|
getTopSong()
|
|
.then((res) => {
|
|
topSongs.value = res.data.data.filter((item, index) => {
|
|
return index < 10;
|
|
});
|
|
store.commit("saveCaches", {
|
|
topSongs: { data: topSongs.value, time: Date.now() },
|
|
});
|
|
// console.log(topSongs.value);
|
|
})
|
|
.catch((err) => {
|
|
console.log("getTopSong err", err);
|
|
});
|
|
|
|
function songAlias(alias) {
|
|
if (alias.length > 0) return "[" + alias.join(",") + "]";
|
|
}
|
|
function songArtists(artists) {
|
|
if (artists.length > 0) {
|
|
return artists
|
|
.map((a) => {
|
|
return a.name;
|
|
})
|
|
.join(" ");
|
|
}
|
|
}
|
|
//#endregion
|
|
|
|
//#region 推荐歌单
|
|
let personalized = ref([]);
|
|
personalized.value = store.getters.cache('personalized')
|
|
getPersonalized(8)
|
|
.then((res) => {
|
|
personalized.value = res.data.result;
|
|
store.commit("saveCaches", {
|
|
personalized: { data: personalized.value, time: Date.now() },
|
|
});
|
|
// console.log(personalized.value);
|
|
})
|
|
.catch((err) => {
|
|
console.log("getPersonalized err", err);
|
|
});
|
|
//#endregion
|
|
|
|
//#region 推荐MV
|
|
let personalizedMV = ref([]);
|
|
personalizedMV.value = store.getters.cache('personalizedMV')
|
|
getPersonalizedMV()
|
|
.then((res) => {
|
|
personalizedMV.value = res.data.result;
|
|
store.commit("saveCaches", {
|
|
personalizedMV: { data: personalizedMV.value, time: Date.now() },
|
|
});
|
|
// console.log(personalized.value);
|
|
})
|
|
.catch((err) => {
|
|
console.log("getPersonalizedMV err", err);
|
|
});
|
|
//#endregion
|
|
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
@import "@/assets/css/common.less";
|
|
.wp-carousel {
|
|
position: relative;
|
|
// width: 20em;
|
|
// font-size: 1vw;
|
|
.carousel-img {
|
|
width: 100%;
|
|
border-radius: 6px;
|
|
}
|
|
.title {
|
|
position: absolute;
|
|
color: #fff;
|
|
background-color: #5c18a0ff;
|
|
bottom: 0px;
|
|
right: 0;
|
|
padding: 2px 6px;
|
|
font-size: 0.9em;
|
|
border-top-left-radius: 6px;
|
|
border-bottom-right-radius: 6px;
|
|
}
|
|
}
|
|
|
|
.card-span {
|
|
.text-el-line2();
|
|
}
|
|
|
|
.mv-c2-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
position: relative;
|
|
border: 1px solid #eee;
|
|
border-radius: 6px;
|
|
|
|
.play-mv {
|
|
img {
|
|
width: 100%;
|
|
border-top-left-radius: 6px;
|
|
border-top-right-radius: 6px;
|
|
}
|
|
button {
|
|
display: none;
|
|
}
|
|
|
|
.start-play-bg {
|
|
font-size: 38px;
|
|
position: absolute;
|
|
right: 0px;
|
|
bottom: 42px;
|
|
color: rgba(255, 255, 255, 0.8);
|
|
}
|
|
.start-play {
|
|
font-size: 25px;
|
|
position: absolute;
|
|
right: 5px;
|
|
bottom: 48px;
|
|
}
|
|
|
|
&:hover {
|
|
button {
|
|
display: block;
|
|
}
|
|
}
|
|
}
|
|
|
|
.title {
|
|
padding: 3px;
|
|
.name {
|
|
.text-el-line();
|
|
.alias {
|
|
font-size: 13px;
|
|
color: #888;
|
|
}
|
|
}
|
|
.artist {
|
|
font-size: 13px;
|
|
color: #666;
|
|
.text-el-line();
|
|
}
|
|
}
|
|
}
|
|
|
|
.c2-list {
|
|
display: flex;
|
|
align-items: center;
|
|
position: relative;
|
|
border-radius: 4px;
|
|
border: 1px solid #eee;
|
|
|
|
img {
|
|
width: 60px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.start-play-bg {
|
|
font-size: 30px;
|
|
position: absolute;
|
|
left: 16px;
|
|
top: 16px;
|
|
color: rgba(255, 255, 255, 0.8);
|
|
}
|
|
|
|
.start-play {
|
|
font-size: 16px;
|
|
position: absolute;
|
|
left: 24px;
|
|
top: 23px;
|
|
}
|
|
|
|
.title {
|
|
padding-left: 8px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
.name {
|
|
.text-el-line();
|
|
.alias {
|
|
font-size: 13px;
|
|
color: #888;
|
|
}
|
|
}
|
|
.artist {
|
|
font-size: 13px;
|
|
color: #666;
|
|
.text-el-line();
|
|
}
|
|
}
|
|
// .icon {
|
|
// }
|
|
}
|
|
</style>
|