feat: 添加播放历史页面

This commit is contained in:
alger
2023-12-29 16:04:44 +08:00
parent 8da7fdabe5
commit 492164d008
10 changed files with 317 additions and 207 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
{
"version": "0.0.1",
"version": "1.3.0",
"isProxy": false,
"author": "alger"
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "alger-music",
"version": "1.2.0",
"version": "1.3.0",
"description": "这是一个用于音乐播放的应用程序。",
"author": "Alger <algerkc@qq.com>",
"main": "app.js",
+5
View File
@@ -7,6 +7,11 @@ export const getMusicUrl = (id: number) => {
return request.get<IPlayMusicUrl>("/song/url", { params: { id: id } })
}
// 获取歌曲详情
export const getMusicDetail = (ids: Array<number>) => {
return request.get("/song/detail", { params: { ids: ids.join(",")}})
}
// 根据音乐Id获取音乐歌词
export const getMusicLrc = (id: number) => {
return request.get<ILyric>("/lyric", { params: { id: id } })
+4
View File
@@ -45,6 +45,7 @@
import { useStore } from 'vuex'
import type { SongResult } from '@/type/music'
import { getImgUrl } from '@/utils'
import { useMusicHistory } from '@/hooks/MusicHistoryHook'
const props = withDefaults(defineProps<{
item: SongResult
@@ -66,12 +67,15 @@ const isPlaying = computed(() => {
const emits = defineEmits(['play'])
const musicHistory = useMusicHistory()
// 播放音乐 设置音乐详情 打开音乐底栏
const playMusicEvent = (item: any) => {
store.commit('setPlay', item)
store.commit('setIsPlay', true)
store.state.playListIndex = 0
emits('play', item)
musicHistory.addMusic(item)
}
</script>
+39
View File
@@ -0,0 +1,39 @@
// musicHistoryHooks
import { RemovableRef, useLocalStorage } from '@vueuse/core'
import type { SongResult } from '@/type/music'
export const useMusicHistory = () => {
const musicHistory = useLocalStorage<SongResult[]>('musicHistory', [])
const addMusic = (music: SongResult) => {
const index = musicHistory.value.findIndex((item) => item.id === music.id)
if (index !== -1) {
musicHistory.value[index].count =
(musicHistory.value[index].count || 0) + 1
musicHistory.value.unshift(musicHistory.value.splice(index, 1)[0])
} else {
musicHistory.value.unshift({ ...music, count: 1 })
}
}
const delMusic = (music: any) => {
const index = musicHistory.value.findIndex((item) => item.id === music.id)
if (index !== -1) {
musicHistory.value.splice(index, 1)
}
}
const musicList = ref(musicHistory.value)
watch(
() => musicHistory.value,
() => {
musicList.value = musicHistory.value
}
)
return {
musicHistory,
musicList,
addMusic,
delMusic,
}
}
+10
View File
@@ -39,6 +39,16 @@ const layoutRouter = [
},
component: () => import('@/views/mv/index.vue'),
},
{
path: '/history',
name: 'history',
mate: {
title: '历史',
keepAlive: true,
icon: 'icon-a-TicketStar',
},
component: () => import('@/views/history/index.vue'),
},
{
path: '/user',
name: 'user',
+10 -9
View File
@@ -5,15 +5,16 @@ export interface IRecommendMusic {
}
export interface SongResult {
id: number;
type: number;
name: string;
copywriter?: any;
picUrl: string;
canDislike: boolean;
trackNumberUpdateTime?: any;
song: Song;
alg: string;
id: number
type: number
name: string
copywriter?: any
picUrl: string
canDislike: boolean
trackNumberUpdateTime?: any
song: Song
alg: string
count?: number
}
interface Song {
+45
View File
@@ -0,0 +1,45 @@
<template>
<div class="history-page">
<div class="title">播放历史</div>
<n-scrollbar :size="100">
<div class="history-list-content" :class="setAnimationClass('animate__bounceInLeft')">
<div class="history-item" v-for="(item, index) in musicList" :key="item.id"
:class="setAnimationClass('animate__bounceIn')" :style="setAnimationDelay(index, 30)">
<song-item class="history-item-content" :item="item" />
<div class="history-item-delete">
<i class="iconfont icon-close" @click="delMusic(item)"></i>
</div>
</div>
</div>
</n-scrollbar>
</div>
</template>
<script setup lang="ts">
import { useMusicHistory } from '@/hooks/MusicHistoryHook'
import { setAnimationClass, setAnimationDelay } from "@/utils";
const {delMusic, musicList} = useMusicHistory();
</script>
<style scoped lang="scss">
.history-page{
@apply h-full w-full pt-2;
.title{
@apply text-xl font-bold;
}
.history-list-content{
@apply px-4 mt-2;
.history-item{
@apply flex items-center justify-between;
&-content{
@apply flex-1;
}
&-delete{
@apply cursor-pointer rounded-full border-2 border-gray-400 w-8 h-8 flex justify-center items-center;
}
}
}
}
</style>
+1 -1
View File
@@ -97,7 +97,7 @@ watch(
<style lang="scss" scoped>
.list-page {
@apply relative h-full w-full pt-4;
@apply relative h-full w-full pt-2;
}
.recommend {
+14 -8
View File
@@ -72,19 +72,25 @@ const close = () => {
<style scoped lang="scss">
.mv-list {
@apply relative h-full w-full pt-4;
@apply relative h-full w-full pt-2;
&-title {
@apply text-xl font-bold;
}
&-content {
@apply grid gap-6 pb-28 pr-3;
grid-template-columns: repeat(auto-fill, minmax(13%, 1fr));
@apply grid gap-6 pb-28 pr-3 mt-2;
grid-template-columns: repeat(auto-fill, minmax(14%, 1fr));
}
.mv-item {
@apply p-2 rounded-lg;
background-color: #454545;
&-img {
@apply rounded-xl overflow-hidden relative;
@apply rounded-lg overflow-hidden relative;
&:hover img {
@apply hover:scale-110 transition-all duration-300 ease-in-out;
@apply hover:scale-110 transition-all duration-300 ease-in-out object-top;
}
&-img {
@@ -93,11 +99,11 @@ const close = () => {
.top {
@apply absolute w-full h-full top-0 left-0 flex justify-center items-center transition-all duration-300 ease-in-out cursor-pointer;
background-color: #00000088;
background-color: #0000009b;
opacity: 0;
i {
font-size: 50px;
font-size: 40px;
transition: all 0.5s ease-in-out;
opacity: 0;
}
@@ -107,7 +113,7 @@ const close = () => {
}
&:hover i {
@apply transform scale-150 opacity-100;
@apply transform scale-150 opacity-80;
}
.play-count {