mirror of
https://github.com/algerkong/AlgerMusicPlayer.git
synced 2026-04-30 03:47:22 +08:00
✨ feat: 添加播放历史页面
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "0.0.1",
|
"version": "1.3.0",
|
||||||
"isProxy": false,
|
"isProxy": false,
|
||||||
"author": "alger"
|
"author": "alger"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "alger-music",
|
"name": "alger-music",
|
||||||
"version": "1.2.0",
|
"version": "1.3.0",
|
||||||
"description": "这是一个用于音乐播放的应用程序。",
|
"description": "这是一个用于音乐播放的应用程序。",
|
||||||
"author": "Alger <algerkc@qq.com>",
|
"author": "Alger <algerkc@qq.com>",
|
||||||
"main": "app.js",
|
"main": "app.js",
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ export const getMusicUrl = (id: number) => {
|
|||||||
return request.get<IPlayMusicUrl>("/song/url", { params: { id: id } })
|
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获取音乐歌词
|
// 根据音乐Id获取音乐歌词
|
||||||
export const getMusicLrc = (id: number) => {
|
export const getMusicLrc = (id: number) => {
|
||||||
return request.get<ILyric>("/lyric", { params: { id: id } })
|
return request.get<ILyric>("/lyric", { params: { id: id } })
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import type { SongResult } from '@/type/music'
|
import type { SongResult } from '@/type/music'
|
||||||
import { getImgUrl } from '@/utils'
|
import { getImgUrl } from '@/utils'
|
||||||
|
import { useMusicHistory } from '@/hooks/MusicHistoryHook'
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
item: SongResult
|
item: SongResult
|
||||||
@@ -66,12 +67,15 @@ const isPlaying = computed(() => {
|
|||||||
|
|
||||||
const emits = defineEmits(['play'])
|
const emits = defineEmits(['play'])
|
||||||
|
|
||||||
|
const musicHistory = useMusicHistory()
|
||||||
|
|
||||||
// 播放音乐 设置音乐详情 打开音乐底栏
|
// 播放音乐 设置音乐详情 打开音乐底栏
|
||||||
const playMusicEvent = (item: any) => {
|
const playMusicEvent = (item: any) => {
|
||||||
store.commit('setPlay', item)
|
store.commit('setPlay', item)
|
||||||
store.commit('setIsPlay', true)
|
store.commit('setIsPlay', true)
|
||||||
store.state.playListIndex = 0
|
store.state.playListIndex = 0
|
||||||
emits('play', item)
|
emits('play', item)
|
||||||
|
musicHistory.addMusic(item)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,6 +39,16 @@ const layoutRouter = [
|
|||||||
},
|
},
|
||||||
component: () => import('@/views/mv/index.vue'),
|
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',
|
path: '/user',
|
||||||
name: 'user',
|
name: 'user',
|
||||||
|
|||||||
+10
-9
@@ -5,15 +5,16 @@ export interface IRecommendMusic {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface SongResult {
|
export interface SongResult {
|
||||||
id: number;
|
id: number
|
||||||
type: number;
|
type: number
|
||||||
name: string;
|
name: string
|
||||||
copywriter?: any;
|
copywriter?: any
|
||||||
picUrl: string;
|
picUrl: string
|
||||||
canDislike: boolean;
|
canDislike: boolean
|
||||||
trackNumberUpdateTime?: any;
|
trackNumberUpdateTime?: any
|
||||||
song: Song;
|
song: Song
|
||||||
alg: string;
|
alg: string
|
||||||
|
count?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Song {
|
interface Song {
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -97,7 +97,7 @@ watch(
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.list-page {
|
.list-page {
|
||||||
@apply relative h-full w-full pt-4;
|
@apply relative h-full w-full pt-2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recommend {
|
.recommend {
|
||||||
|
|||||||
+14
-8
@@ -72,19 +72,25 @@ const close = () => {
|
|||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.mv-list {
|
.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 {
|
&-content {
|
||||||
@apply grid gap-6 pb-28 pr-3;
|
@apply grid gap-6 pb-28 pr-3 mt-2;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(13%, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(14%, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
.mv-item {
|
.mv-item {
|
||||||
|
@apply p-2 rounded-lg;
|
||||||
|
background-color: #454545;
|
||||||
&-img {
|
&-img {
|
||||||
@apply rounded-xl overflow-hidden relative;
|
@apply rounded-lg overflow-hidden relative;
|
||||||
|
|
||||||
&:hover img {
|
&: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 {
|
&-img {
|
||||||
@@ -93,11 +99,11 @@ const close = () => {
|
|||||||
|
|
||||||
.top {
|
.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;
|
@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;
|
opacity: 0;
|
||||||
|
|
||||||
i {
|
i {
|
||||||
font-size: 50px;
|
font-size: 40px;
|
||||||
transition: all 0.5s ease-in-out;
|
transition: all 0.5s ease-in-out;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
@@ -107,7 +113,7 @@ const close = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:hover i {
|
&:hover i {
|
||||||
@apply transform scale-150 opacity-100;
|
@apply transform scale-150 opacity-80;
|
||||||
}
|
}
|
||||||
|
|
||||||
.play-count {
|
.play-count {
|
||||||
|
|||||||
Reference in New Issue
Block a user