最近播放完成一半,差清除列表
This commit is contained in:
parent
0de746e55b
commit
2905728772
1
src/assets/svgs/Add.svg
Normal file
1
src/assets/svgs/Add.svg
Normal 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 |
1
src/assets/svgs/JiaHao.svg
Normal file
1
src/assets/svgs/JiaHao.svg
Normal 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 |
@ -1,4 +1,4 @@
|
||||
import { createStore } from "vuex";
|
||||
import { createStore, storeKey } from "vuex";
|
||||
|
||||
export default createStore({
|
||||
state: {
|
||||
@ -62,6 +62,16 @@ export default createStore({
|
||||
state.theme = { ...state.theme, ...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: {},
|
||||
modules: {},
|
||||
@ -74,8 +84,5 @@ function saveLoaclSettings(s) {
|
||||
);
|
||||
}
|
||||
function saveLoaclTheme(s) {
|
||||
localStorage.setItem(
|
||||
"zmusic.theme",
|
||||
JSON.stringify(s)
|
||||
);
|
||||
localStorage.setItem("zmusic.theme", JSON.stringify(s));
|
||||
}
|
||||
|
@ -1,17 +1,137 @@
|
||||
<script setup>
|
||||
import { h } from "vue";
|
||||
import { RouterLink, useRoute } from "vue-router";
|
||||
import { NButton, NSpace, NIcon, NMenu } from "naive-ui";
|
||||
import { ref, reactive, h, watch, toRaw } from "vue";
|
||||
import {
|
||||
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 = [
|
||||
{
|
||||
label: '最近播放',
|
||||
label: "最近播放",
|
||||
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>
|
||||
<template>
|
||||
<div class="top-menu">
|
||||
@ -25,59 +145,59 @@ const route = useRoute()
|
||||
<div class="main-content">
|
||||
<div class="ld-width">
|
||||
<div class="lmt-width">
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<br> 发束带结发十多块放假啊来得及发司法局啊水电费家啊练腹肌
|
||||
<n-layout>
|
||||
<n-layout-header
|
||||
style="padding: 6px 12px; font-size: 10px"
|
||||
>
|
||||
共{{ lastPlayed.length }}首(最多100)
|
||||
</n-layout-header>
|
||||
<n-layout has-sider>
|
||||
<n-layout-content style="padding: 6px 12px">
|
||||
<n-button-group size="small">
|
||||
<n-button
|
||||
type="primary"
|
||||
round
|
||||
style="padding-right: 6px"
|
||||
>
|
||||
<template #icon>
|
||||
<n-icon><Play /></n-icon>
|
||||
</template>
|
||||
播放全部
|
||||
</n-button>
|
||||
<n-button
|
||||
type="primary"
|
||||
round
|
||||
style="
|
||||
font-size: 26px;
|
||||
padding: 0 6px 0 2px;
|
||||
"
|
||||
>
|
||||
<!-- <template #icon> -->
|
||||
<n-icon>
|
||||
<Add />
|
||||
</n-icon>
|
||||
<!-- </template> -->
|
||||
</n-button>
|
||||
</n-button-group>
|
||||
</n-layout-content>
|
||||
<n-layout-sider width="100">
|
||||
<n-button size="small">清除列表</n-button>
|
||||
</n-layout-sider>
|
||||
</n-layout>
|
||||
</n-layout>
|
||||
<n-data-table
|
||||
:bordered="false"
|
||||
:single-line="true"
|
||||
:columns="columns"
|
||||
:data="lastPlayed"
|
||||
size="small"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
|
||||
}
|
||||
export default {};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
<style></style>
|
||||
|
@ -12,7 +12,7 @@ import { getSongUrl } from "@/network/song";
|
||||
import pubsub from "pubsub-js";
|
||||
|
||||
const store = useStore();
|
||||
const { settings } = store.state;
|
||||
// const { settings } = store.state;
|
||||
const audioEl = ref("");
|
||||
const playing = ref(false);
|
||||
let currentTime = 0;
|
||||
@ -23,9 +23,9 @@ onMounted(() => {
|
||||
audioEl.value.addEventListener("pause", onPause);
|
||||
audioEl.value.addEventListener("ended", onEnd);
|
||||
|
||||
if (settings.songId) {
|
||||
if (store.state.settings.songId) {
|
||||
pubsub.publish("zp.play", {
|
||||
id: settings.songId,
|
||||
id: store.state.settings.songId,
|
||||
im: false,
|
||||
});
|
||||
// play(settings.songId, false)
|
||||
@ -60,12 +60,13 @@ const play = async (id, im = true) => {
|
||||
store.commit("saveSettings", {
|
||||
songId: id,
|
||||
});
|
||||
pubsub.publish('zp.getSongInfo', {id})
|
||||
pubsub.publish('zp.getSongInfo', {id: store.state.settings.songId, im})
|
||||
|
||||
if (im) {
|
||||
audioEl.value.play();
|
||||
playing.value = true;
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
@ -84,11 +85,12 @@ const resume = async () => {
|
||||
// console.log(Date.now() - lastPause);
|
||||
if (Date.now() - lastPause > 1000 * 60 * 5) {
|
||||
console.log("暂停过了5分钟,再次载入歌曲");
|
||||
await play(settings.songId, false);
|
||||
await play(store.state.settings.songId, false);
|
||||
audioEl.value.currentTime = currentTime;
|
||||
}
|
||||
audioEl.value.play();
|
||||
playing.value = true;
|
||||
pubsub.publish('zp.getSongInfo', {id: store.state.settings.songId, im: true})
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,9 @@ import {
|
||||
reactive,
|
||||
toRef,
|
||||
toRefs,
|
||||
toRaw,
|
||||
} from "vue";
|
||||
import {useStore} from 'vuex'
|
||||
import { NAvatar } from "naive-ui";
|
||||
import pubsub from "pubsub-js";
|
||||
import { getSongDetial } from "@/network/song";
|
||||
@ -14,6 +16,7 @@ import 'dayjs/locale/zh-cn'
|
||||
import duration from 'dayjs/plugin/duration'
|
||||
import ArtistsSpan from "@/components/ArtistsSpan.vue";
|
||||
|
||||
const store = useStore()
|
||||
const showInfo = ref(false);
|
||||
const info = reactive({
|
||||
name: "",
|
||||
@ -22,13 +25,20 @@ const info = reactive({
|
||||
});
|
||||
|
||||
//#region 取得歌曲信息
|
||||
const songInfo = (id) => {
|
||||
const songInfo = (id, im) => {
|
||||
getSongDetial(id)
|
||||
.then((res) => {
|
||||
showInfo.value = true;
|
||||
info.name = res.data.songs[0].name;
|
||||
info.artists = res.data.songs[0].ar;
|
||||
info.albumPicUrl = res.data.songs[0].al.picUrl;
|
||||
if(im){
|
||||
store.commit('savePlayed', {...{
|
||||
id,
|
||||
date: Date.now(),
|
||||
}, ...toRaw(info)})
|
||||
console.log('savePlayed');
|
||||
}
|
||||
})
|
||||
.catch((err) => {});
|
||||
};
|
||||
@ -46,7 +56,7 @@ function zpTime(time) {
|
||||
const psToken = pubsub.subscribe("zp", (msg, data) => {
|
||||
switch (msg) {
|
||||
case "zp.getSongInfo":
|
||||
songInfo(data.id);
|
||||
songInfo(data.id, data.im);
|
||||
break;
|
||||
case "zp.progress":
|
||||
totalTime.value = zpTime(data.total * 1000)
|
||||
|
@ -111,7 +111,10 @@ const route = useRoute();
|
||||
<div class="main-content">
|
||||
<!-- <NScrollbar > -->
|
||||
<div class="ld-width">
|
||||
<keep-alive>
|
||||
<router-view />
|
||||
</keep-alive>
|
||||
|
||||
</div>
|
||||
<!-- </NScrollbar> -->
|
||||
</div>
|
||||
|
@ -66,13 +66,16 @@
|
||||
<div class="title">
|
||||
<span class="name">
|
||||
{{ song.name }}
|
||||
<span class="alias"><template
|
||||
<span class="alias"
|
||||
><template
|
||||
v-for="(al, idx) in song.alias"
|
||||
> {{al}}
|
||||
</template></span>
|
||||
>
|
||||
{{ al }}
|
||||
</template></span
|
||||
>
|
||||
</span>
|
||||
<span class="artist">
|
||||
<ArtistsSpan :artists="song.artists"/>
|
||||
<ArtistsSpan :artists="song.artists" />
|
||||
</span>
|
||||
</div>
|
||||
<span class="icon"></span>
|
||||
@ -184,7 +187,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import {
|
||||
NCarousel,
|
||||
@ -213,6 +216,8 @@ import {
|
||||
import pubsub from "pubsub-js";
|
||||
import ArtistsSpan from "@/components/ArtistsSpan.vue";
|
||||
|
||||
console.log("recommend 初始化");
|
||||
|
||||
const store = useStore();
|
||||
|
||||
const play = (id) => {
|
||||
@ -230,18 +235,28 @@ getBanner(0)
|
||||
.catch((err) => {
|
||||
console.log("getBanner err", err);
|
||||
});
|
||||
//最新音乐
|
||||
|
||||
let topSongs = ref([]);
|
||||
//最新音乐
|
||||
getTopSong()
|
||||
.then((res) => {
|
||||
topSongs.value = res.data.data.filter((item, index) => {
|
||||
return index < 20;
|
||||
return index < 10;
|
||||
});
|
||||
// console.log(topSongs.value);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("getTopSong err", err);
|
||||
});
|
||||
|
||||
|
||||
// onMounted(() => {
|
||||
// console.log("onMounted");
|
||||
// });
|
||||
// onUnmounted(() => {
|
||||
// console.log("卸载组件");
|
||||
// });
|
||||
|
||||
function songAlias(alias) {
|
||||
if (alias.length > 0) return "[" + alias.join(",") + "]";
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user