最近播放完成一半,差清除列表

This commit is contained in:
zilong 2021-10-19 19:17:45 +08:00
parent 0de746e55b
commit 2905728772
8 changed files with 237 additions and 78 deletions

1
src/assets/svgs/Add.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M256 112v288"></path><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M400 256H112"></path></svg>

After

Width:  |  Height:  |  Size: 369 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1634561096494" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2039" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M533.333333 490.666667V128h-42.666666v362.666667H128v42.666666h362.666667v362.666667h42.666666V533.333333h362.666667v-42.666666z" fill="#3D3D3D" p-id="2040"></path></svg>

After

Width:  |  Height:  |  Size: 547 B

View File

@ -1,4 +1,4 @@
import { createStore } from "vuex"; import { createStore, storeKey } from "vuex";
export default createStore({ export default createStore({
state: { state: {
@ -62,6 +62,16 @@ export default createStore({
state.theme = { ...state.theme, ...theme }; state.theme = { ...state.theme, ...theme };
saveLoaclTheme(state.theme); saveLoaclTheme(state.theme);
}, },
savePlayed(state, played) {
// console.log(played)
let p = state.settings.lastPlayed.filter(
(item, idx) => item.id !== played.id && idx < 99
);
p.unshift(played);
// console.log(p)
state.settings.lastPlayed = p;
saveLoaclSettings(state.settings);
},
}, },
actions: {}, actions: {},
modules: {}, modules: {},
@ -74,8 +84,5 @@ function saveLoaclSettings(s) {
); );
} }
function saveLoaclTheme(s) { function saveLoaclTheme(s) {
localStorage.setItem( localStorage.setItem("zmusic.theme", JSON.stringify(s));
"zmusic.theme",
JSON.stringify(s)
);
} }

View File

@ -1,17 +1,137 @@
<script setup> <script setup>
import { h } from "vue"; import { ref, reactive, h, watch, toRaw } from "vue";
import { RouterLink, useRoute } from "vue-router"; import {
import { NButton, NSpace, NIcon, NMenu } from "naive-ui"; RouterLink,
useRoute,
useRouter,
} from "vue-router";
import { useStore } from "vuex";
import {
NButton,
NButtonGroup,
NSpace,
NIcon,
NMenu,
NLayout,
NLayoutHeader,
NLayoutFooter,
NLayoutContent,
NLayoutSider,
NTag,
NDataTable,
useMessage,
} from "naive-ui";
import Play from "@/assets/svgs/Play_.svg";
import Add from "@/assets/svgs/Add.svg";
import dayjs from 'dayjs'
import 'dayjs/locale/zh-cn'
import pubsub from "pubsub-js";
const menuOptions = [ const menuOptions = [
{ {
label: '最近播放', label: "最近播放",
key: "/played", key: "/played",
}, },
]; ];
const route = useRoute() const router = useRouter();
const store = useStore();
let lastPlayed = ref([]);
const createColumns = ({ play ,singerInfo }) => {
return [
{
title: "",
key: "index",
align: "right",
width: 40
},
{
title: "音乐标题",
key: "name",
align: "left",
render(row){
return h(
NButton,
{
style: {
marginRight: "6px",
},
text: true,
size: "small",
onClick: () => play(row.id),
},
{
default: () => row.name,
}
);
}
},
{
title: "歌手",
key: "artists",
render(row) {
const ars = row.artists.map((ar, idx) => {
let r = h(
NButton,
{
style: {
marginRight: "6px",
},
text: true,
size: "small",
onClick: () => singerInfo(ar.id),
},
{
default: () => ar.name,
}
);
return h("span", [idx == 0 ? "" : "/ ", r]);
});
// console.log(ars);
return ars;
},
},
{
title: "播放时间",
key: "date",
width: 100,
render(row){
return h('span', [dayjs(row.date).format('YYYY-MM-DD')])
}
},
];
};
// const message = useMessage();
const columns = createColumns({
play(id){
pubsub.publish('zp.play', {id, im:true})
},
singerInfo(id) {
router.push("/singer/" + id);
},
});
const pagination = {
pageSize: 10,
};
watch(
() => store.state.settings.lastPlayed,
(val, oldVal) => {
lastPlayed.value = toRaw(
store.state.settings.lastPlayed
).map((item,idx)=>{
return {...{index: idx+1}, ...item}
});
},
{
immediate: true,
deep: true,
}
);
const route = useRoute();
</script> </script>
<template> <template>
<div class="top-menu"> <div class="top-menu">
@ -23,61 +143,61 @@ const route = useRoute()
/> />
</div> </div>
<div class="main-content"> <div class="main-content">
<div class="ld-width"> <div class="ld-width">
<div class="lmt-width"> <div class="lmt-width">
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <n-layout>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <n-layout-header
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 style="padding: 6px 12px; font-size: 10px"
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 >
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 {{ lastPlayed.length }}最多100
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌 </n-layout-header>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌 <n-layout has-sider>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <n-layout-content style="padding: 6px 12px">
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌 <n-button-group size="small">
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌 <n-button
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 type="primary"
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 round
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 style="padding-right: 6px"
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 >
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <template #icon>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <n-icon><Play /></n-icon>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 </template>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 播放全部
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 </n-button>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <n-button
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 type="primary"
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 round
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 style="
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 font-size: 26px;
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 padding: 0 6px 0 2px;
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 "
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 >
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <!-- <template #icon> -->
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <n-icon>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <Add />
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 </n-icon>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <!-- </template> -->
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 </n-button>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 </n-button-group>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 </n-layout-content>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <n-layout-sider width="100">
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <n-button size="small">清除列表</n-button>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 </n-layout-sider>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 </n-layout>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 </n-layout>
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 <n-data-table
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌 :bordered="false"
</div> :single-line="true"
:columns="columns"
:data="lastPlayed"
size="small"
/>
</div> </div>
</div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {};
}
</script> </script>
<style> <style></style>
</style>

View File

@ -12,7 +12,7 @@ import { getSongUrl } from "@/network/song";
import pubsub from "pubsub-js"; import pubsub from "pubsub-js";
const store = useStore(); const store = useStore();
const { settings } = store.state; // const { settings } = store.state;
const audioEl = ref(""); const audioEl = ref("");
const playing = ref(false); const playing = ref(false);
let currentTime = 0; let currentTime = 0;
@ -23,9 +23,9 @@ onMounted(() => {
audioEl.value.addEventListener("pause", onPause); audioEl.value.addEventListener("pause", onPause);
audioEl.value.addEventListener("ended", onEnd); audioEl.value.addEventListener("ended", onEnd);
if (settings.songId) { if (store.state.settings.songId) {
pubsub.publish("zp.play", { pubsub.publish("zp.play", {
id: settings.songId, id: store.state.settings.songId,
im: false, im: false,
}); });
// play(settings.songId, false) // play(settings.songId, false)
@ -60,12 +60,13 @@ const play = async (id, im = true) => {
store.commit("saveSettings", { store.commit("saveSettings", {
songId: id, songId: id,
}); });
pubsub.publish('zp.getSongInfo', {id}) pubsub.publish('zp.getSongInfo', {id: store.state.settings.songId, im})
if (im) { if (im) {
audioEl.value.play(); audioEl.value.play();
playing.value = true; playing.value = true;
} }
} }
}) })
.catch((err) => { .catch((err) => {
@ -84,11 +85,12 @@ const resume = async () => {
// console.log(Date.now() - lastPause); // console.log(Date.now() - lastPause);
if (Date.now() - lastPause > 1000 * 60 * 5) { if (Date.now() - lastPause > 1000 * 60 * 5) {
console.log("暂停过了5分钟再次载入歌曲"); console.log("暂停过了5分钟再次载入歌曲");
await play(settings.songId, false); await play(store.state.settings.songId, false);
audioEl.value.currentTime = currentTime; audioEl.value.currentTime = currentTime;
} }
audioEl.value.play(); audioEl.value.play();
playing.value = true; playing.value = true;
pubsub.publish('zp.getSongInfo', {id: store.state.settings.songId, im: true})
} }
}; };

View File

@ -5,7 +5,9 @@ import {
reactive, reactive,
toRef, toRef,
toRefs, toRefs,
toRaw,
} from "vue"; } from "vue";
import {useStore} from 'vuex'
import { NAvatar } from "naive-ui"; import { NAvatar } from "naive-ui";
import pubsub from "pubsub-js"; import pubsub from "pubsub-js";
import { getSongDetial } from "@/network/song"; import { getSongDetial } from "@/network/song";
@ -14,6 +16,7 @@ import 'dayjs/locale/zh-cn'
import duration from 'dayjs/plugin/duration' import duration from 'dayjs/plugin/duration'
import ArtistsSpan from "@/components/ArtistsSpan.vue"; import ArtistsSpan from "@/components/ArtistsSpan.vue";
const store = useStore()
const showInfo = ref(false); const showInfo = ref(false);
const info = reactive({ const info = reactive({
name: "", name: "",
@ -22,13 +25,20 @@ const info = reactive({
}); });
//#region //#region
const songInfo = (id) => { const songInfo = (id, im) => {
getSongDetial(id) getSongDetial(id)
.then((res) => { .then((res) => {
showInfo.value = true; showInfo.value = true;
info.name = res.data.songs[0].name; info.name = res.data.songs[0].name;
info.artists = res.data.songs[0].ar; info.artists = res.data.songs[0].ar;
info.albumPicUrl = res.data.songs[0].al.picUrl; info.albumPicUrl = res.data.songs[0].al.picUrl;
if(im){
store.commit('savePlayed', {...{
id,
date: Date.now(),
}, ...toRaw(info)})
console.log('savePlayed');
}
}) })
.catch((err) => {}); .catch((err) => {});
}; };
@ -46,7 +56,7 @@ function zpTime(time) {
const psToken = pubsub.subscribe("zp", (msg, data) => { const psToken = pubsub.subscribe("zp", (msg, data) => {
switch (msg) { switch (msg) {
case "zp.getSongInfo": case "zp.getSongInfo":
songInfo(data.id); songInfo(data.id, data.im);
break; break;
case "zp.progress": case "zp.progress":
totalTime.value = zpTime(data.total * 1000) totalTime.value = zpTime(data.total * 1000)

View File

@ -111,7 +111,10 @@ const route = useRoute();
<div class="main-content"> <div class="main-content">
<!-- <NScrollbar > --> <!-- <NScrollbar > -->
<div class="ld-width"> <div class="ld-width">
<router-view /> <keep-alive>
<router-view />
</keep-alive>
</div> </div>
<!-- </NScrollbar> --> <!-- </NScrollbar> -->
</div> </div>

View File

@ -66,13 +66,16 @@
<div class="title"> <div class="title">
<span class="name"> <span class="name">
{{ song.name }} {{ song.name }}
<span class="alias"><template <span class="alias"
v-for="(al, idx) in song.alias" ><template
> {{al}} v-for="(al, idx) in song.alias"
</template></span> >
{{ al }}
</template></span
>
</span> </span>
<span class="artist"> <span class="artist">
<ArtistsSpan :artists="song.artists"/> <ArtistsSpan :artists="song.artists" />
</span> </span>
</div> </div>
<span class="icon"></span> <span class="icon"></span>
@ -184,7 +187,7 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref, onMounted, onUnmounted } from "vue";
import { useStore } from "vuex"; import { useStore } from "vuex";
import { import {
NCarousel, NCarousel,
@ -213,6 +216,8 @@ import {
import pubsub from "pubsub-js"; import pubsub from "pubsub-js";
import ArtistsSpan from "@/components/ArtistsSpan.vue"; import ArtistsSpan from "@/components/ArtistsSpan.vue";
console.log("recommend 初始化");
const store = useStore(); const store = useStore();
const play = (id) => { const play = (id) => {
@ -230,18 +235,28 @@ getBanner(0)
.catch((err) => { .catch((err) => {
console.log("getBanner err", err); console.log("getBanner err", err);
}); });
//
let topSongs = ref([]); let topSongs = ref([]);
//
getTopSong() getTopSong()
.then((res) => { .then((res) => {
topSongs.value = res.data.data.filter((item, index) => { topSongs.value = res.data.data.filter((item, index) => {
return index < 20; return index < 10;
}); });
// console.log(topSongs.value); // console.log(topSongs.value);
}) })
.catch((err) => { .catch((err) => {
console.log("getTopSong err", err); console.log("getTopSong err", err);
}); });
// onMounted(() => {
// console.log("onMounted");
// });
// onUnmounted(() => {
// console.log("");
// });
function songAlias(alias) { function songAlias(alias) {
if (alias.length > 0) return "[" + alias.join(",") + "]"; if (alias.length > 0) return "[" + alias.join(",") + "]";
} }