1、后端编写
1.1 Service服务层
package com.gmw.musicserver.service;import com.gmw.musicserver.entity.Song;import com.baomidou.mybatisplus.extension.service.IService;import java.util.List;/*** <p>* 歌曲表 服务类* 歌曲service接口* </p>** @author 未进化的程序猿* @since 2022-01-26*/public interface SongService extends IService<Song> {/***增加*/public boolean insertSong(Song song);/***修改*/public boolean updateSong(Song song);/*** 删除*/public boolean deleteSong(Integer id);/*** 根据主键查询整个对象*/public Song selectByPrimaryKey(Integer id);/*** 查询所有歌曲*/public List<Song> allSong();/*** 根据歌名模糊查询列表*/public List<Song> songOfName(String name);/*** 根据歌手id查询*/public List<Song> songOfSingerId(Integer singerId);}
package com.gmw.musicserver.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.gmw.musicserver.entity.Song;import com.gmw.musicserver.mapper.SongMapper;import com.gmw.musicserver.service.SongService;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import org.springframework.stereotype.Service;import java.util.List;/*** <p>* 歌曲表 服务实现类* </p>** @author 未进化的程序猿* @since 2022-01-26*/@Servicepublic class SongServiceImpl extends ServiceImpl<SongMapper, Song> implements SongService {/*** 添加歌曲* @param song* @return*/@Overridepublic boolean insertSong(Song song) {return this.baseMapper.insert(song) > 0;}/*** 更新歌曲* @param song* @return*/@Overridepublic boolean updateSong(Song song) {return this.baseMapper.updateById(song) > 0;}/*** 删除歌曲* @param id* @return*/@Overridepublic boolean deleteSong(Integer id) {return this.baseMapper.deleteById(id) > 0;}/*** 根据主键id查询歌曲对象* @param id* @return*/@Overridepublic Song selectByPrimaryKey(Integer id) {return this.baseMapper.selectById(id);}/*** 查询所有的歌曲* @return*/@Overridepublic List<Song> allSong() {return this.baseMapper.selectList(null);}/*** 根据歌曲名称模糊查询所有的歌曲* @param name* @return*/@Overridepublic List<Song> songOfName(String name) {QueryWrapper<Song> queryWrapper = new QueryWrapper<>();queryWrapper.like("name",name);return this.baseMapper.selectList(queryWrapper);}/*** 根据歌手名称查询所有的歌曲* @param singerId* @return*/@Overridepublic List<Song> songOfSingerId(Integer singerId) {QueryWrapper<Song> queryWrapper = new QueryWrapper<>();queryWrapper.eq("singer_id",singerId);return this.baseMapper.selectList(queryWrapper);}}
1.2 Controller控制层
package com.gmw.musicserver.controller;import com.gmw.musicserver.commonutils.R;import com.gmw.musicserver.entity.Singer;import com.gmw.musicserver.entity.Song;import com.gmw.musicserver.service.SongService;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;import java.io.File;import java.io.IOException;import java.util.List;/*** <p>* 歌曲表 前端控制器* </p>** @author 未进化的程序猿* @since 2022-01-26*/@RestController@RequestMapping("/musicserver/song")public class SongController {private static final Logger logger = LoggerFactory.getLogger(SongController.class);@Autowiredpublic SongService songService;@PostMapping(value = "/addSong")public R addSong(HttpServletRequest request, @RequestParam("file")MultipartFile file){//获取前端传来的参数String singerId = request.getParameter("singerId").trim(); //所属歌手idString name = request.getParameter("name").trim(); //歌名String introduction = request.getParameter("introduction").trim(); //简介String pic = "/img/songPic/tubiao.jpg"; //默认图片String lyric = request.getParameter("lyric").trim(); //歌词//上传歌曲文件//先判断上传的文件是否为空if(file.isEmpty()){return R.error().message("歌曲上传失败!!");}//文件名=当前时间到毫秒+原来的文件名String fileName = System.currentTimeMillis() + file.getOriginalFilename();logger.info("文件名: {}",fileName);//上传歌曲的文件路径String filePath = System.getProperty("user.dir") + System.getProperty("file.separator")+ "audio" + System.getProperty("file.separator") + "song";logger.info("上传歌曲的文件地址: {}",filePath);//如果文件路径不存在,新增该路径File file1 = new File(filePath);if(!file1.exists()){file1.mkdir();}//实际的文件地址String fileDist = filePath + System.getProperty("file.separator") + fileName;logger.info("实际保存歌曲的文件地址: {}",fileDist);File fileDest = new File(fileDist);//存储到数据库里的相对文件地址String storeUrlPath = "/audio/song/"+fileName;logger.info("存储到数据库里的相对文件地址: {}",storeUrlPath);try {//保存上传图片file.transferTo(fileDest);//上传图片之后,保存歌曲的信息Song song = new Song();song.setSingerId(Integer.parseInt(singerId)); //歌手的IDsong.setName(name); //歌曲的名称song.setIntroduction(introduction); //歌曲的专辑song.setPic(pic); //歌曲的图片song.setLyric(lyric); //歌曲的歌词song.setUrl(storeUrlPath); //歌曲的播放地址logger.info("歌曲对象: {}",song);boolean flag = this.songService.insertSong(song);if(flag){return R.ok().message("添加歌曲成功!!").data("storeUrlPath",storeUrlPath);}else {return R.error().message("添加歌曲失败!!");}} catch (IOException e) {return R.error().message("添加歌曲失败!!");}}/*** 根据歌手id查询歌曲*/@GetMapping(value = "/singer/detail")public R songOfSingerId(HttpServletRequest request){String singerId = request.getParameter("singerId");List<Song> songList = this.songService.songOfSingerId(Integer.parseInt(singerId));logger.info("根据歌手id查询歌曲: {}",songList);return R.ok().data("list",songList);}/*** 修改歌曲*/@PostMapping(value = "/updateSong")public Object updateSong(HttpServletRequest request){String id = request.getParameter("id").trim(); //主键String name = request.getParameter("name").trim(); //歌名String introduction = request.getParameter("introduction").trim();//专辑String lyric = request.getParameter("lyric").trim(); //歌词//保存到歌手的对象中Song song = new Song();song.setId(Integer.parseInt(id));song.setName(name);song.setIntroduction(introduction);song.setLyric(lyric);logger.info("编辑歌曲对象: {}",song);boolean flag = this.songService.updateSong(song);if(flag){ //保存成功return R.ok().message("歌曲修改成功!!");}return R.error().message("歌曲修改失败!!");}/*** 删除歌曲*/@GetMapping(value = "/deleteSong")public R deleteSong(HttpServletRequest request){String id = request.getParameter("id").trim(); //主键//-TODO 先查询到数据库中对应的文件地址,删除掉它再进行下面的代码//通过ID主键查询歌手对象Song song = this.songService.selectByPrimaryKey(Integer.parseInt(id));//获取歌曲图片String songPic = song.getPic();logger.info("歌曲图片: {}",songPic);//如果文件的相对路径是/img/songPic/tubiao.jpg就没必要删除//因为它是当作默认相对路径的,需要用到if(!songPic.equals("/img/songPic/tubiao.jpg")){//获取歌曲保存的文件目录String songPath = System.getProperty("user.dir") + songPic;logger.info("获取歌曲保存的文件目录: {}",songPath);File file = new File(songPath);if(file.isFile()){//判断如果是文件的话,就删除文件boolean isDelete = file.delete();logger.info("是否删除成功: {}",isDelete);if(!isDelete){return R.error().message("删除歌曲失败!!");}}}//获取歌曲播放地址String songUrl = song.getUrl();logger.info("获取歌曲播放地址: {}",songUrl);//获取歌曲保存的文件目录String fileSongUrlPath = System.getProperty("user.dir") + songUrl;logger.info("获取歌曲播放地址: {}",fileSongUrlPath);File delUrlFile = new File(fileSongUrlPath);if(delUrlFile.isFile()){//判断如果是文件的话,就删除文件boolean isDelete = delUrlFile.delete();logger.info("是否删除成功: {}",isDelete);if(!isDelete){return R.error().message("删除歌曲失败!!");}}boolean flag = this.songService.deleteSong(Integer.parseInt(id));if(flag){return R.ok().message("删除歌曲成功!!");}return R.error().message("删除歌曲失败!!");}/*** 更新歌曲图片*/@PostMapping(value = "/updateSongPic")public R updateSongPic(@RequestParam("file") MultipartFile file, @RequestParam("id")int id){/*** 更新歌曲之前,必须把原来的歌曲图片删除掉*///通过ID主键查询歌手对象Song song = this.songService.selectByPrimaryKey(id);//获取歌曲图片String songPic = song.getPic();logger.info("歌曲图片: {}",songPic);//如果文件的相对路径是/img/songPic/tubiao.jpg就没必要删除//因为它是当作默认相对路径的,需要用到if(!songPic.equals("/img/songPic/tubiao.jpg")){//获取歌曲保存的文件目录String songPath = System.getProperty("user.dir") + songPic;logger.info("获取歌曲保存的文件目录: {}",songPath);File file1 = new File(songPath);if(file1.isFile()){file1.delete();}}//开始更新歌曲图片if(file.isEmpty()){return R.error().message("上传歌曲失败!!");}//文件名=当前时间到毫秒+原来的文件名String fileName = System.currentTimeMillis()+file.getOriginalFilename();//文件路径String filePath = System.getProperty("user.dir")+System.getProperty("file.separator")+"img"+System.getProperty("file.separator")+"songPic";//如果文件路径不存在,新增该路径File file1 = new File(filePath);if(!file1.exists()){file1.mkdir();}//实际的文件地址File dest = new File(filePath+System.getProperty("file.separator")+fileName);//存储到数据库里的相对文件地址String storeAvatorPath = "/img/songPic/"+fileName;try {file.transferTo(dest);Song song1 = new Song();song1.setId(id); //歌曲IDsong1.setPic(storeAvatorPath); //歌曲图片相对地址boolean flag = this.songService.updateSong(song1);if(flag){return R.ok().message("更新歌曲图片成功!!");}else {return R.error().message("更新歌曲图片失败!!");}} catch (IOException e) {return R.error().message("更新歌曲图片失败!!");}}/*** 更新歌曲*/@PostMapping(value = "/updateSongUrl")public R updateSongUrl(@RequestParam("file") MultipartFile avatorFile, @RequestParam("id")int id){/*** 更新歌曲之前,必须把原来的歌曲文件删除掉*///通过ID主键查询歌手对象Song song = this.songService.selectByPrimaryKey(id);//获取歌曲播放地址String songUrl = song.getUrl();logger.info("获取歌曲播放地址: {}",songUrl);//获取歌曲保存的文件目录String fileSongUrlPath = System.getProperty("user.dir") + songUrl;logger.info("获取歌曲播放地址: {}",fileSongUrlPath);File delUrlFile = new File(fileSongUrlPath);if(delUrlFile.isFile()){delUrlFile.delete();}//开始文件上传if(avatorFile.isEmpty()){return R.error().message("文件上传失败!!");}//文件名=当前时间到毫秒+原来的文件名String fileName = System.currentTimeMillis()+avatorFile.getOriginalFilename();//文件路径String filePath = System.getProperty("user.dir")+System.getProperty("file.separator")+ "audio" + System.getProperty("file.separator") + "song";//如果文件路径不存在,新增该路径File file1 = new File(filePath);if(!file1.exists()){file1.mkdir();}//实际的文件地址File dest = new File(filePath+System.getProperty("file.separator")+fileName);//存储到数据库里的相对文件地址String storeAvatorPath = "/audio/song/"+fileName;try {avatorFile.transferTo(dest);Song song1 = new Song();song1.setId(id);song1.setUrl(storeAvatorPath);boolean flag = this.songService.updateSong(song1);if(flag){return R.ok().message("更新歌曲播放文件成功!!");}else {return R.error().message("更新歌曲播放文件失败!!");}} catch (IOException e) {return R.error().message("更新歌曲播放文件失败!!");}}}
1.3 配置图片、音频定位各种文件或头像地址

package com.gmw.musicserver.config;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 定位各种文件或头像地址*/@Configurationpublic class FileConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {/*** 歌手头像地址*/registry.addResourceHandler("/img/singerPic/**").addResourceLocations("file:" + System.getProperty("user.dir") + System.getProperty("file.separator")+ "img" + System.getProperty("file.separator")+ "singerPic" + System.getProperty("file.separator"));/*** 歌单图片地址*/registry.addResourceHandler("/img/songListPic/**").addResourceLocations("file:" + System.getProperty("user.dir") + System.getProperty("file.separator")+ "img" + System.getProperty("file.separator")+ "songListPic" + System.getProperty("file.separator"));/*** 歌曲图片地址*/registry.addResourceHandler("/img/songPic/**").addResourceLocations("file:" + System.getProperty("user.dir") + System.getProperty("file.separator")+ "img" + System.getProperty("file.separator")+ "songPic" + System.getProperty("file.separator"));/*** 歌曲播放地址*/registry.addResourceHandler("/audio/song/**").addResourceLocations("file:" + System.getProperty("user.dir") + System.getProperty("file.separator")+ "audio" + System.getProperty("file.separator")+ "song" + System.getProperty("file.separator"));}}
2、前端编写
<template><div class="table"><div class="crumbs"><i class="el-icon-tickets"></i>歌曲信息</div><div class="container"><div class="handle-box"><el-button type="primary" size="mini" @click="delAll">批量删除</el-button><el-input v-model="select_word" size="mini" placeholder="请输入歌曲名" class="handle-input"></el-input><el-button type="primary" size="mini" @click="centerDialogVisible = true">添加歌曲</el-button></div></div><el-table size="mini" ref="multipleTable" border style="width:100%" height="680px" :data="data" @selection-change="handleSelectionChange"><el-table-column type="selection" width="40"></el-table-column><el-table-column label="歌曲图片" width="110" align="center"><template slot-scope="scope"><div class="song-img"><img :src="getUrl(scope.row.pic)" style="width:100%"/></div><div class="play" @click="setSongUrl(scope.row.url,scope.row.name)"><div v-if="toggle == scope.row.name"><svg class="icon"><use xlink:href="#icon-zanting"></use></svg></div><div v-if="toggle != scope.row.name"><svg class="icon"><use xlink:href="#icon-bofanganniu"></use></svg></div></div></template></el-table-column><el-table-column prop="name" label="歌手-歌名" width="120" align="center"></el-table-column><el-table-column prop="introduction" label="专辑" width="150" align="center"></el-table-column><el-table-column label="歌词" align="center"><template slot-scope="scope"><ul style="height:100px;overflow:scroll;"><li v-for="(item,index) in parseLyric(scope.row.lyric)" :key="index">{{item}}</li></ul></template></el-table-column><el-table-column label="资源更新" align="center" width="100"><template slot-scope="scope"><el-upload :action="uploadUrl(scope.row.id)" :before-upload="beforeAvatorUpload":on-success="handleAvatorSuccess"><el-button size="mini">更新图片</el-button></el-upload><br/><el-upload :action="uploadSongUrl(scope.row.id)" :before-upload="beforeSongUpload":on-success="handleSongSuccess"><el-button size="mini">更新歌曲</el-button></el-upload></template></el-table-column><el-table-column label="操作" width="150" align="center"><template slot-scope="scope"><el-button size="mini" @click="handleEdit(scope.row)">编辑</el-button><el-button size="mini" type="danger" @click="handleDelete(scope.row.id)">删除</el-button></template></el-table-column></el-table><div class="pagination"><el-paginationbackgroundlayout = "total,prev,pager,next":current-page="currentPage":page-size="pageSize":total="tableData.length"@current-change="handleCurrentChange"></el-pagination></div><el-dialog title="添加歌曲" :visible.sync="centerDialogVisible" width="400px" center><el-form :model="registerForm" ref="registerForm" label-width="80px" action="" id="tf"><div><label>歌名</label><el-input type="text" name="name"></el-input></div><div><label>专辑</label><el-input type="text" name="introduction"></el-input></div><div><label>歌词</label><el-input type="textarea" name="lyric"></el-input></div><div><label>歌曲上传</label><input type="file" name="file"></div></el-form><span slot="footer"><el-button size="mini" @click="centerDialogVisible = false">取消</el-button><el-button size="mini" @click="addSong">确定</el-button></span></el-dialog><el-dialog title="修改歌曲" :visible.sync="editVisible" width="400px" center><el-form :model="form" ref="form" label-width="80px"><el-form-item prop="name" label="歌手-歌名" size="mini"><el-input v-model="form.name" placeholder="歌手-歌名"></el-input></el-form-item><el-form-item prop="introduction" label="专辑" size="mini"><el-input v-model="form.introduction" placeholder="专辑"></el-input></el-form-item><el-form-item prop="lyric" label="歌词" size="mini"><el-input v-model="form.lyric" placeholder="歌词" type="textarea"></el-input></el-form-item></el-form><span slot="footer"><el-button size="mini" @click="editVisible = false">取消</el-button><el-button size="mini" @click="editSave">确定</el-button></span></el-dialog><el-dialog title="删除歌曲" :visible.sync="delVisible" width="300px" center><div align="center">删除不可恢复,是否确定删除?</div><span slot="footer"><el-button size="mini" @click="delVisible = false">取消</el-button><el-button size="mini" @click="deleteRow">确定</el-button></span></el-dialog></div></template><script>import { mixin } from '../mixins/index';import {mapGetters} from 'vuex';import '@/assets/js/iconfont.js';import {songOfSingerId,updateSong,delSong} from '../api/song/index';export default {mixins: [mixin],data(){return{singerId: '', //歌手idsingerName: '', //歌手名centerDialogVisible: false, //添加弹窗是否显示editVisible: false, //编辑弹窗是否显示delVisible: false, //删除弹窗是否显示registerForm:{ //添加框name: '',singerName: '',introduction: '',lyric: ''},form:{ //编辑框id: '',name: '',introduction: '',lyric: ''},tableData: [],tempData: [],select_word: '',pageSize: 5, //分页每页大小currentPage: 1, //当前页idx: -1, //当前选择项multipleSelection: [], //哪些项已经打勾toggle: false //播放器的图标状态}},computed:{...mapGetters(['isPlay']),//计算当前搜索结果表里的数据data(){return this.tableData.slice((this.currentPage - 1) * this.pageSize,this.currentPage * this.pageSize)}},watch:{//搜索框里面的内容发生变化的时候,搜索结果table列表的内容跟着它的内容发生变化select_word: function(){if(this.select_word == ''){this.tableData = this.tempData;}else{this.tableData = [];for(let item of this.tempData){if(item.name.includes(this.select_word)){this.tableData.push(item);}}}}},created(){this.singerId = this.$route.query.id;this.singerName = this.$route.query.name;this.getData();},destroyed() {this.$store.commit('setIsPlay',false);},methods:{//获取当前页handleCurrentChange(val){this.currentPage = val;},//查询所有歌手getData(){this.tempData = [];this.tableData = [];songOfSingerId(this.singerId).then(res => {this.tempData = res.data.list;this.tableData = res.data.list;this.currentPage = 1;})},//添加歌手addSong(){let _this = this;var form = new FormData(document.getElementById('tf'));form.append('singerId',this.singerId);form.set('name',this.singerName+'-'+form.get('name'));if(!form.get('lyric')){form.set('lyric','[00:00:00]暂无歌词');}var req = new XMLHttpRequest();req.onreadystatechange = function(){//req.readyState == 4 获取到返回的完整数据//req.status == 200 和后台正常交互完成if(req.readyState == 4 && req.status == 200){let res = JSON.parse(req.response);if(res.code){_this.getData();_this.registerForm = {};_this.notify(res.msg,'success');}else{_this.notify('保存失败','error');}}}req.open('post',`${_this.$store.state.HOST}/musicserver/song/addSong`,false);req.send(form);_this.centerDialogVisible = false;},//弹出编辑页面handleEdit(row){this.editVisible = true;this.form = {id: row.id,name: row.name,introduction: row.introduction,lyric: row.lyric}},//保存编辑页面修改的数据editSave(){let params = new URLSearchParams();params.append('id',this.form.id);params.append('name',this.form.name);params.append('introduction',this.form.introduction);params.append('lyric',this.form.lyric);updateSong(params).then(res => {if(res.code == 20000){this.getData();this.notify("修改成功","success");}else{this.notify("修改失败","error");}}).catch(err => {console.log(err);});this.editVisible = false;},//更新图片uploadUrl(id){return `${this.$store.state.HOST}/musicserver/song/updateSongPic?id=${id}`},//删除一名歌手deleteRow(){delSong(this.idx).then(res => {if(res.code == 20000){this.getData();this.notify("删除成功","success");}else{this.notify("删除失败","error");}}).catch(err => {console.log(err);});this.delVisible = false;},//解析歌词parseLyric(text){let lines = text.split("\n");let pattern = /\[\d{2}:\d{2}.(\d{3}|\d{2})\]/g;let result = [];for(let item of lines){let value = item.replace(pattern,'');result.push(value);}return result;},//上传歌曲之前的校验beforeSongUpload(file){var testMsg = file.name.substring(file.name.lastIndexOf('.') + 1);if(testMsg!='mp3'){this.$message({message: '上传文件只能是mp3格式',type: 'error'});return false;}return true;},//上传歌曲成功之后要做的工作handleSongSuccess(res){let _this = this;if(res.code == 20000){_this.getData();_this.$notify({title: '上传成功',type: 'success'});}else{_this.$notify({title: '上传失败',type: 'error'});}},//更新歌曲urluploadSongUrl(id){return `${this.$store.state.HOST}/musicserver/song/updateSongUrl?id=${id}`},//切换播放歌曲setSongUrl(url,name) {this.toggle = name;this.$store.commit('setUrl',this.$store.state.HOST + url);if(this.isPlay){this.$store.commit('setIsPlay',false);}else{this.$store.commit('setIsPlay',true);}}}}</script><style scoped>.handle-box{margin-bottom: 20px;}.song-img{width: 100%;height: 80px;border-radius: 5px;margin-bottom: 5px;overflow: hidden;}.handle-input{width: 300px;display: inline-block;}.pagination{display: flex;justify-content: center;}.play {position: absolute;z-index: 100;width: 80px;height: 80px;display: flex;align-items: center;justify-content: center;cursor: pointer;top: 18px;left: 15px;}.icon {width: 2em;height: 2em;color: white;fill: currentColor;overflow: hidden;}</style>
2.1 添加歌曲


<el-dialog title="添加歌曲" :visible.sync="centerDialogVisible" width="400px" center>
<el-form :model="registerForm" ref="registerForm" label-width="80px" action="" id="tf">
<div>
<label>歌名</label>
<el-input type="text" name="name"></el-input>
</div>
<div>
<label>专辑</label>
<el-input type="text" name="introduction"></el-input>
</div>
<div>
<label>歌词</label>
<el-input type="textarea" name="lyric"></el-input>
</div>
<div>
<label>歌曲上传</label>
<input type="file" name="file">
</div>
</el-form>
<span slot="footer">
<el-button size="mini" @click="centerDialogVisible = false">取消</el-button>
<el-button size="mini" @click="addSong">确定</el-button>
</span>
</el-dialog>

:visible.sync=”centerDialogVisible” 当centerDialogVisible为true时,会弹出文本输入框,否则隐藏
编写请求后端接口方法

import {get,post} from '../http'
//============歌曲相关================
//根据歌手id查询歌曲
export const songOfSingerId =(id) => get(`musicserver/song/singer/detail?singerId=${id}`);
//编辑歌曲
export const updateSong = (params) => post(`musicserver/song/updateSong`,params);
//删除歌曲
export const delSong = (id) => get(`musicserver/song/deleteSong?id=${id}`);
编写添加歌曲方法

//添加歌手
addSong(){
let _this = this;
var form = new FormData(document.getElementById('tf'));
form.append('singerId',this.singerId); //添加歌手的id到form中
form.set('name',this.singerName+'-'+form.get('name')); //设置歌曲的名称格式为:歌手名称-歌曲名称
if(!form.get('lyric')){
form.set('lyric','[00:00:00]暂无歌词');
}
var req = new XMLHttpRequest();
req.onreadystatechange = function(){
//req.readyState == 4 获取到返回的完整数据
//req.status == 200 和后台正常交互完成
if(req.readyState == 4 && req.status == 200){
let res = JSON.parse(req.response);
if(res.code){
_this.getData();
_this.registerForm = {};
_this.notify(res.msg,'success');
}else{
_this.notify('保存失败','error');
}
}
}
req.open('post',`${_this.$store.state.HOST}/musicserver/song/addSong`,false);
req.send(form);
_this.centerDialogVisible = false;
},
2.2 查询/修改/删除跟歌手管理模块一样(省略)
2.3 歌词显示

解析歌词(歌词前面带有[00:00.22]格式的替换为空字符串)
//解析歌词
parseLyric(text){
let lines = text.split("\n");
let pattern = /\[\d{2}:\d{2}.(\d{3}|\d{2})\]/g; //歌词前面带有[00:00.22]格式的替换为空字符串
let result = [];
for(let item of lines){
let value = item.replace(pattern,'');
result.push(value);
}
return result;
},
进行歌词的解析
2.4 更新歌曲图片/更新歌曲文件


<el-upload :action="uploadUrl(scope.row.id)" :before-upload="beforeAvatorUpload"
:on-success="handleAvatorSuccess">
<el-button size="mini">更新图片</el-button>
</el-upload>
<br/>
<el-upload :action="uploadSongUrl(scope.row.id)" :before-upload="beforeSongUpload"
:on-success="handleSongSuccess">
<el-button size="mini">更新歌曲</el-button>
</el-upload>
1)更新歌曲图片
:action=”uploadUrl(scope.row.id)” 表示要访问的后台地址,并携带歌曲的id,通过id修改歌曲图像
//更新图片
uploadUrl(id){
return `${this.$store.state.HOST}/musicserver/song/updateSongPic?id=${id}`
},
:before-upload=”beforeAvatorUpload” 表示文件上传之前,进行哪些操作,比如:上传的文件类型、大小都可以做限制;
//上传图片之前的校验
beforeAvatorUpload(file){
const isJPG = (file.type === 'image/jpeg')||(file.type === 'image/png');
if(!isJPG){
this.$message.error('上传头像图片只能是jpg或png格式');
return false;
}
const isLt2M = (file.size / 1024 /1024) < 2;
if(!isLt2M){
this.$message.error('上传头像图片大小不能超过2MB');
return false;
}
return true;
},
:on-success=”handleAvatorSuccess” 表示上传成功后需要进行哪些操作,比如:提示上传成功或者失败
//上传图片成功之后要做的工作
handleAvatorSuccess(res){
let _this = this;
if(res.code == 20000){
_this.getData();
_this.$notify({
title: '上传成功',
type: 'success'
});
}else{
_this.$notify({
title: '上传失败',
type: 'error'
});
}
},
2)更新歌曲文件
:action=”uploadSongUrl(scope.row.id)” 表示要访问的后台地址,并携带歌曲的id,通过id修改歌曲图像 
//更新歌曲url
uploadSongUrl(id){
return `${this.$store.state.HOST}/musicserver/song/updateSongUrl?id=${id}`
},
:before-upload=”beforeSongUpload” 表示文件上传之前,进行哪些操作,比如:上传的文件类型、大小都可以做限制;
//上传歌曲之前的校验
beforeSongUpload(file){
var testMsg = file.name.substring(file.name.lastIndexOf('.') + 1);
if(testMsg!='mp3'){
this.$message({
message: '上传文件只能是mp3格式',
type: 'error'
});
return false;
}
return true;
},
:on-success=”handleSongSuccess” 表示上传成功后需要进行哪些操作,比如:提示上传成功或者失败
//上传歌曲成功之后要做的工作
handleSongSuccess(res){
let _this = this;
if(res.code == 20000){
_this.getData();
_this.$notify({
title: '上传成功',
type: 'success'
});
}else{
_this.$notify({
title: '上传失败',
type: 'error'
});
}
},
2.5 页面播放歌曲
1)设置全局共享属性:id、url、isPlay
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state:{
HOST: 'http://127.0.0.1:8888',
isPlay: false, //是否播放中
url: '', //歌曲地址
id: '' //歌曲id
},
getters: { //获取共享属性的方法
isPlay: state => state.isPlay,
url: state => state.url,
id: state => state.id
},
mutations: { //设置共享属性的方法
setIsPlay: (state,isPlay) => {state.isPlay = isPlay},
setUrl: (state,url) => {state.url = url},
setId: (state,id) => {state.id = id}
}
})
export default store
2)创建SongAudio.vue组件,专门用来播放音乐
<template>
<div class="song-audio">
<audio id="player"
:src="url"
controls = "controls"
preload = "true"
@canplay="startPlay"
@ended="ended"
></audio>
</div>
</template>
<script>
import {mapGetters} from 'vuex';
export default {
name: 'song-audio',
computed: {
...mapGetters([
'id',
'url',
'isPlay'
])
},
watch:{
//监听播放还是暂停
isPlay: function(){
this.togglePlay();
}
},
methods:{
//获取链接后准备播放
startPlay(){
let player = document.querySelector('#player');
//开始播放
player.play();
},
//播放完成之后触发
ended(){
this.isPlay = false
},
//开始、暂停
togglePlay() {
let player = document.querySelector('#player');
if(this.isPlay){
player.play();
}else{
player.pause();
}
}
}
}
</script>
<style>
.song-audio {
display: none;
}
</style>
3)在App.vue页面中,引入该组件
<template>
<div id="app">
<SongAudio />
<router-view></router-view>
</div>
</template>
<script>
import SongAudio from './components/SongAudio';
export default {
name: 'App',
components: {
SongAudio
}
}
</script>
<style>
</style>
4)在SongPage.vue歌曲页面中进行参数的设置


//切换播放歌曲
setSongUrl(url,name) {
this.toggle = name;
this.$store.commit('setUrl',this.$store.state.HOST + url);
if(this.isPlay){
this.$store.commit('setIsPlay',false);
}else{
this.$store.commit('setIsPlay',true);
}
}
