歌曲库

This commit is contained in:
zjl
2021-10-04 01:32:28 +08:00
parent 0a7980bded
commit 8253a1b62b
13 changed files with 750 additions and 6 deletions
+314
View File
@@ -0,0 +1,314 @@
<template>
<div>
<el-form inline :model="search" @submit.prevent>
<el-form-item label="名称:">
<el-input size="small" v-model="search.name" />
</el-form-item>
<el-form-item label="所属歌单:">
<el-select size="small" v-model="search.lib_id" multiple :max-tag-count="3">
<el-option v-for="musicLib in musicLibs" :key="musicLib._id" :value="musicLib._id" :label="musicLib.name" />
</el-select>
</el-form-item>
<el-form-item label="文件类型:">
<el-select size="small" v-model="search.ext" multiple :max-tag-count="3">
<el-option v-for="ext in exts" :key="ext" :value="ext" :label="ext" />
</el-select>
</el-form-item>
<el-form-item label="标题:">
<el-input size="small" v-model="search.title" />
</el-form-item>
<el-form-item label="唱片集:">
<el-input size="small" v-model="search.album" />
</el-form-item>
<el-form-item label="艺术家:">
<el-input size="small" v-model="search.artist" />
</el-form-item>
</el-form>
<div class="btn-container">
<el-button type="success" plain size="small" icon="el-icon-caret-right" >播放</el-button>
<div class="search-btn">
<el-button type="primary" @click="loadDataBase(true)" size="small" icon="el-icon-search">搜索</el-button>
<el-button @click="reset" size="small" icon="el-icon-refresh-right">重置</el-button>
</div>
</div>
<div class="table-container">
<el-table :data="musicData" v-loading="loading" stripe height="520" @selection-change="dataSelect">
<el-table-column type="selection" width="55" />
<el-table-column prop="name" label="名称" show-overflow-tooltip role=""/>
<el-table-column prop="ext" label="类型" width="100" />
<el-table-column prop="size" label="文件大小" width="150">
<template #default="scope">
{{ prettyBytes(scope.row.size) }}
</template>
</el-table-column>
<el-table-column prop="title" label="标题" show-overflow-tooltip />
<el-table-column prop="album" label="唱片集" />
<el-table-column prop="artist" label="艺术家" />
<el-table-column prop="lib_id" label="所属歌单" >
<template #default="scope">
{{ findMusicLib(scope.row.lib_id) }}
</template>
</el-table-column>
<el-table-column prop="lyric_id" label="歌词" width="120" >
<template #default="scope">
<i :class="scope.row.lyric_id ? 'el-icon-check' : 'el-icon-close'" ></i>
</template>
</el-table-column>
<el-table-column label="操作" width="230" >
<template #default="scope">
<el-button size="mini" plain @click="update(scope.row)">修改</el-button>
<el-button size="mini" plain @click="updateLyric(scope.row)">歌词</el-button>
<el-button type="danger" size="mini" plain @click="remove(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="page-container">
<el-pagination background
:page-sizes="$store.state.pageSizeOpts"
:layout="$store.state.pageLayout"
:total="total"
@size-change="pageSizeChange"
@current-change="pageChange">
</el-pagination>
</div>
<el-dialog v-model="modifyLyricModal" title="编辑歌词" :width="600" >
<el-form ref="lyricForm" :model="lyricFormData" :rules="lyricRuleValidate" :label-width="120">
<el-form-item label="网易云ID" prop="cloud_id">
<el-input v-model="lyricFormData.cloud_id" />
</el-form-item>
<el-form-item label="名称" prop="name">
<el-input v-model="lyricFormData.name" />
</el-form-item>
<el-form-item label="歌词" prop="lyric">
<el-input v-model="lyricFormData.lyric" type="textarea" :rows="4"/>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="modifyLyricModal = false">取消</el-button>
<el-button type="primary" @click="saveLyric" :loading="modalLoading">确定</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="modifyModal" title="修改所属歌单" :width="470" >
<el-radio-group v-model="currentRow.lib_id">
<el-radio v-for="item in musicLibs" :key="item._id" :label="item._id" border>{{item.name}}</el-radio>
</el-radio-group>
<template #footer>
<span class="dialog-footer">
<el-button @click="modifyModal = false">取消</el-button>
<el-button type="primary" @click="updateMusicLib" >确定</el-button>
</span>
</template>
</el-dialog>
<!--
<Drawer title="播放音乐" v-model="musicPlaying" width="720" :mask-closable="false" >
<template v-if="musicPlaying">
<a-player ref="player" :audio="musicList" :lrcType="3" @playing="musicPlay"/>
</template>
</Drawer> -->
</div>
</template>
<script lang="ts">
import { Options } from 'vue-class-component'
import BaseList from '../../model/baselist'
import { Page } from '../../model/common.dto'
import { AxiosResponse } from 'axios'
import { ElButton, ElForm, ElFormItem, ElInput, ElTable, ElTableColumn, ElPagination, ElDialog, ElSelect, ElOption, ElRadioGroup, ElRadio, ElMessage, ElMessageBox } from 'element-plus'
import { ref } from 'vue'
import { MusicModel, MusicLibModel, MusicLyricModel, MusicPlayerItem } from '../../model/api/music'
import prettyBytes from 'pretty-bytes'
// import APlayer, {APlayer as APlayerComponent} from '@moefe/vue-aplayer'
// Vue.use(APlayer, {
// defaultCover: `${Vue.prototype.$http.defaults.baseURL}/api/common/randomBg?id=5ec7770b60990123b7340233`, // 播放器默认封面图片
// productionTip: false, // 是否在控制台输出版本信息
// })
let selectedIds: string[] = []
@Options({
name: 'Music',
components: { ElButton, ElForm, ElFormItem, ElInput, ElTable, ElTableColumn, ElPagination, ElDialog, ElSelect, ElOption, ElRadioGroup, ElRadio }
})
export default class Music extends BaseList<MusicPage> {
// @Ref('player') private readonly player!: APlayerComponent
private readonly lyricForm: any = ref('lyricForm')
search = new MusicPage()
currentRow: MusicModel | null = null
exts: string[] = []
musicLibs: MusicLibModel[] = []
musicData: MusicModel[] = []
modifyModal: boolean = false
modifyLyricModal: boolean = false
lyricRuleValidate = {
cloud_id: [
{ required: true, message: '请输入网易云ID', trigger: 'blur' }
],
name: [
{ required: true, message: '请输入名称', trigger: 'blur' }
],
lyric: [
{ required: true, message: '请输入歌词正文', trigger: 'blur' }
],
}
prettyBytes = prettyBytes
lyricFormData: MusicLyricModel = {}
// 是否正在播放音乐
private musicPlaying: boolean = false
private musicList: MusicPlayerItem[] = []
created() {
this.$http.get('/api/music/listLibs').then(({data}) => {
this.musicLibs = data
this.loadData()
})
this.$http.get('/api/music/listExts').then(({data}) => {
this.exts = data
})
}
async loadData() {
this.loading = true
const { data } = await this.$http.get<MusicPage, AxiosResponse<any>>('/api/music/list', {params: this.search})
selectedIds = []
this.loading = false
this.total = data.total
this.musicData = data.data
}
dataSelect(selection: MusicModel[]) {
selectedIds = selection.map(item => item._id)
}
findMusicLib(value: string): string | null {
const musicLib = this.musicLibs.find(item => item._id === value)
return musicLib ? musicLib.name : null
}
// 根据当前搜索条件播放音乐
// async playMusic() {
// // 显示加载进度条
// this.$Loading.start()
// try {
// const { data } = await this.$http.get('/api/music/list/all', {params: selectedIds.length ? {ids: selectedIds} : this.search})
// this.musicList = data.map((item: MusicModel, index: number) => {
// return {
// id: index + 1,
// name: item.title || item.name,
// artist: item.artist,
// album: item.album,
// url: `${this.$http.defaults.baseURL || ''}/api/common/music/get/${item._id}`,
// cover: `${this.$http.defaults.baseURL || ''}/api/common/music/album/${item._id}`,
// lrc: item.lyric_id ? `${this.$http.defaults.baseURL || ''}/api/common/music/lyric/${item.lyric_id}` : undefined
// }
// })
// // 结束加载进度条
// this.$Loading.finish()
// // 删除原本可能存在的播放器配置(包含播放地址 时间进度等信息)
// localStorage.removeItem('aplayer-setting')
// this.musicPlaying = true
// } catch (err) {
// console.error(err)
// ElMessage.error('获取播放列表失败')
// this.$Loading.error()
// }
// }
update(row: MusicModel) {
this.currentRow = row
this.modifyModal = true
}
remove(row: MusicModel) {
ElMessageBox.confirm(`是否确认删除 ${row.name} `, '确认删除', {type: 'warning'}).then(async () => {
const { data } = await this.$http.delete<{params: {id: string}}, AxiosResponse<any>>('/api/music/delete', {params: {id: row._id}})
if(data.status) {
ElMessage.success(data.message)
this.loadData()
} else {
ElMessage.warning(data.message)
}
}).catch(() => {})
}
async updateLyric(row: MusicModel) {
this.currentRow = row
this.modifyLyricModal = true
if (row.lyric_id) {
const { data } = (await this.$http.get<any, AxiosResponse<any>>('/api/music/lyric/get', {params: {lyricId: row.lyric_id}}))
data.cloud_id = data.cloud_id ? data.cloud_id.toString() : null
this.lyricFormData = data
} else {
this.lyricFormData = {}
}
}
async saveLyric() {
this.lyricForm.validate(async (valid: boolean) => {
if(!valid) return
this.modalLoading = true
const { data } = await this.$http.post<MusicLyricModel, AxiosResponse<any>>(`/api/music/lyric/save?musicId=${this.currentRow ? this.currentRow._id : ''}`, this.lyricFormData)
this.modalLoading = false
this.modifyLyricModal = false
ElMessage.success(data.message)
this.loadData()
// 清空表单
this.lyricFormData = {}
})
}
async updateMusicLib() {
if (!this.currentRow) return
const { data } = await this.$http.post<any, AxiosResponse<any>>('/api/music/updateLib', {id: this.currentRow._id, libId: this.currentRow.lib_id})
ElMessage.success(data.message)
this.modifyModal = false
}
/**
* 创建媒体信息
*/
// musicPlay() {
// if(!('mediaSession' in window.navigator)) return;
// const currentMusic = this.player.currentMusic
// const mediaSession: any = navigator.mediaSession
// mediaSession.metadata = new MediaMetadata({
// title: currentMusic.name,
// artist: currentMusic.artist,
// album: currentMusic.album,
// artwork: [{src: currentMusic.cover}]
// });
// mediaSession.setActionHandler('play', () => { // 播放
// this.player.play()
// })
// mediaSession.setActionHandler('pause', () => { // 暂停
// this.player.pause()
// })
// const currentIndex = this.musicList.findIndex(item => item.id === currentMusic.id)
// mediaSession.setActionHandler('previoustrack', () => { // 上一首
// if (currentIndex === 0) { // 已经是第一首
// this.player.switch(this.musicList.length - 1)
// } else {
// this.player.switch(currentIndex - 1)
// }
// })
// mediaSession.setActionHandler('nexttrack', () => { // 下一首
// if (currentIndex === this.musicList.length - 1) { // 已经是最后一首
// this.player.switch(0)
// } else {
// this.player.switch(currentIndex + 1)
// }
// })
// }
}
class MusicPage extends Page {
name?: string
ext: string[] = []
title?: string
album?: string
artist?: string
lib_id?: string[] = []
reset() {
super.reset()
this.name = undefined
this.ext = []
this.title = undefined
this.album = undefined
this.artist = undefined
this.lib_id = []
}
}
</script>