1、后端编写

1.1 歌单服务模块编写

1)Service服务层编写

  1. package com.gmw.musicserver.service;
  2. import com.gmw.musicserver.entity.SongList;
  3. import com.gmw.musicserver.entity.SongSheet;
  4. import com.baomidou.mybatisplus.extension.service.IService;
  5. import java.util.List;
  6. /**
  7. * <p>
  8. * 歌单表 服务类
  9. * </p>
  10. *
  11. * @author 未进化的程序猿
  12. * @since 2022-01-26
  13. */
  14. public interface SongSheetService extends IService<SongSheet> {
  15. /**
  16. *增加歌单
  17. */
  18. public boolean insertSongSheet(SongSheet songSheet);
  19. /**
  20. *修改歌单
  21. */
  22. public boolean updateSongSheet(SongSheet songSheet);
  23. /**
  24. * 删除歌单
  25. */
  26. public boolean deleteSongSheet(Integer id);
  27. /**
  28. * 根据主键查询整个对象
  29. */
  30. public SongSheet selectByPrimaryKey(Integer id);
  31. /**
  32. * 查询所有歌单
  33. */
  34. public List<SongSheet> allSongList();
  35. /**
  36. * 根据标题精确查询歌单列表
  37. */
  38. public List<SongSheet> songListOfTitle(String title);
  39. /**
  40. * 根据标题模糊查询歌单列表
  41. */
  42. public List<SongSheet> likeTitle(String title);
  43. /**
  44. * 根据风格模糊查询歌单列表
  45. */
  46. public List<SongSheet> likeStyle(String style);
  47. }
  1. package com.gmw.musicserver.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.gmw.musicserver.entity.SongSheet;
  4. import com.gmw.musicserver.mapper.SongSheetMapper;
  5. import com.gmw.musicserver.service.SongSheetService;
  6. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  7. import org.springframework.stereotype.Service;
  8. import java.util.List;
  9. /**
  10. * <p>
  11. * 歌单表 服务实现类
  12. * </p>
  13. *
  14. * @author 未进化的程序猿
  15. * @since 2022-01-26
  16. */
  17. @Service
  18. public class SongSheetServiceImpl extends ServiceImpl<SongSheetMapper, SongSheet> implements SongSheetService {
  19. /**
  20. * 增加歌单
  21. *
  22. * @param songSheet
  23. */
  24. @Override
  25. public boolean insertSongSheet(SongSheet songSheet) {
  26. return this.baseMapper.insert(songSheet) > 0;
  27. }
  28. /**
  29. * 修改歌单
  30. *
  31. * @param songSheet
  32. */
  33. @Override
  34. public boolean updateSongSheet(SongSheet songSheet) {
  35. return this.baseMapper.updateById(songSheet) > 0;
  36. }
  37. /**
  38. * 删除歌单
  39. *
  40. * @param id
  41. */
  42. @Override
  43. public boolean deleteSongSheet(Integer id) {
  44. return this.baseMapper.deleteById(id) > 0;
  45. }
  46. /**
  47. * 根据主键查询整个对象
  48. *
  49. * @param id
  50. */
  51. @Override
  52. public SongSheet selectByPrimaryKey(Integer id) {
  53. return this.baseMapper.selectById(id);
  54. }
  55. /**
  56. * 查询所有歌单
  57. */
  58. @Override
  59. public List<SongSheet> allSongList() {
  60. return this.baseMapper.selectList(null);
  61. }
  62. /**
  63. * 根据标题精确查询歌单列表
  64. *
  65. * @param title
  66. */
  67. @Override
  68. public List<SongSheet> songListOfTitle(String title) {
  69. QueryWrapper<SongSheet> queryWrapper = new QueryWrapper<>();
  70. queryWrapper.eq("title",title);
  71. return this.baseMapper.selectList(queryWrapper);
  72. }
  73. /**
  74. * 根据标题模糊查询歌单列表
  75. *
  76. * @param title
  77. */
  78. @Override
  79. public List<SongSheet> likeTitle(String title) {
  80. QueryWrapper<SongSheet> queryWrapper = new QueryWrapper<>();
  81. queryWrapper.like("title",title);
  82. return this.baseMapper.selectList(queryWrapper);
  83. }
  84. /**
  85. * 根据风格模糊查询歌单列表
  86. *
  87. * @param style
  88. */
  89. @Override
  90. public List<SongSheet> likeStyle(String style) {
  91. QueryWrapper<SongSheet> queryWrapper = new QueryWrapper<>();
  92. queryWrapper.like("style",style);
  93. return this.baseMapper.selectList(queryWrapper);
  94. }
  95. }

2)Controller控制层编写

  1. package com.gmw.musicserver.controller;
  2. import com.gmw.musicserver.commonutils.R;
  3. import com.gmw.musicserver.entity.Song;
  4. import com.gmw.musicserver.entity.SongSheet;
  5. import com.gmw.musicserver.service.SongSheetService;
  6. import io.swagger.models.auth.In;
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.web.bind.annotation.*;
  11. import org.springframework.web.multipart.MultipartFile;
  12. import javax.servlet.http.HttpServletRequest;
  13. import java.io.File;
  14. import java.io.IOException;
  15. import java.util.List;
  16. /**
  17. * <p>
  18. * 歌单表 前端控制器
  19. * </p>
  20. *
  21. * @author 未进化的程序猿
  22. * @since 2022-01-26
  23. */
  24. @RestController
  25. @RequestMapping("/musicserver/songSheet")
  26. public class SongSheetController {
  27. public static final Logger logger = LoggerFactory.getLogger(SongSheetController.class);
  28. @Autowired
  29. public SongSheetService songSheetService;
  30. /**
  31. * 添加歌单
  32. */
  33. @PostMapping(value = "/addSongSheet")
  34. public R addSongSheet(HttpServletRequest request){
  35. String title = request.getParameter("title").trim(); //标题
  36. String pic = request.getParameter("pic").trim(); //歌单图片
  37. String introduction = request.getParameter("introduction").trim();//简介
  38. String style = request.getParameter("style").trim(); //风格
  39. //保存到歌单的对象中
  40. SongSheet songSheet = new SongSheet();
  41. songSheet.setTitle(title);
  42. songSheet.setPic(pic);
  43. songSheet.setIntroduction(introduction);
  44. songSheet.setStyle(style);
  45. logger.info("保存的歌单对象: {}",songSheet);
  46. boolean flag = this.songSheetService.insertSongSheet(songSheet);
  47. if(flag){ //保存成功
  48. return R.ok().message("保存歌单成功!!");
  49. }
  50. return R.error().message("保存歌单失败!!");
  51. }
  52. /**
  53. * 修改歌单
  54. */
  55. @PostMapping(value = "/updateSongSheet")
  56. public R updateSongSheet(HttpServletRequest request){
  57. String id = request.getParameter("id").trim(); //主键
  58. String title = request.getParameter("title").trim(); //标题
  59. String introduction = request.getParameter("introduction").trim();//简介
  60. String style = request.getParameter("style").trim(); //风格
  61. //保存到歌单的对象中
  62. SongSheet songSheet = new SongSheet();
  63. songSheet.setId(Integer.parseInt(id));
  64. songSheet.setTitle(title);
  65. songSheet.setIntroduction(introduction);
  66. songSheet.setStyle(style);
  67. logger.info("修改歌单保存的歌单对象: {}",songSheet);
  68. boolean flag = this.songSheetService.updateSongSheet(songSheet);
  69. if(flag){ //保存成功
  70. return R.ok().message("修改歌单成功!!");
  71. }
  72. return R.error().message("修改歌单失败!!");
  73. }
  74. /**
  75. * 删除歌单
  76. */
  77. @GetMapping(value = "/deleteSongSheet")
  78. public R deleteSongSheet(HttpServletRequest request){
  79. String id = request.getParameter("id").trim(); //主键
  80. //-TODO 先查询到数据库中对应的文件地址,删除掉它再进行下面的代码
  81. //通过ID主键查询歌手对象
  82. SongSheet songSheet = this.songSheetService.selectByPrimaryKey(Integer.parseInt(id));
  83. //获取歌曲图片
  84. String songPic = songSheet.getPic();
  85. logger.info("歌单图片: {}",songPic);
  86. //如果文件的相对路径是/img/songListPic/123.jpg就没必要删除
  87. //因为它是当作默认相对路径的,需要用到
  88. if(!songPic.equals("/img/songListPic/123.jpg")){
  89. //获取歌曲保存的文件目录
  90. String songPath = System.getProperty("user.dir") + songPic;
  91. logger.info("获取歌单保存的文件目录: {}",songPath);
  92. File file = new File(songPath);
  93. if(file.isFile()){
  94. //判断如果是文件的话,就删除文件
  95. boolean isDelete = file.delete();
  96. logger.info("是否删除成功: {}",isDelete);
  97. if(!isDelete){
  98. return R.error().message("删除歌曲失败!!");
  99. }
  100. }
  101. }
  102. boolean flag = this.songSheetService.deleteSongSheet(Integer.parseInt(id));
  103. if(flag) {
  104. return R.ok().message("删除歌单成功!!");
  105. }
  106. return R.error().message("删除歌单失败!!");
  107. }
  108. /**
  109. * 根据主键查询整个对象
  110. */
  111. @GetMapping(value = "/selectByPrimaryKey")
  112. public R selectByPrimaryKey(HttpServletRequest request){
  113. String id = request.getParameter("id").trim(); //主键
  114. SongSheet songSheet = this.songSheetService.selectByPrimaryKey(Integer.parseInt(id));
  115. return R.ok().data("songSheet",songSheet);
  116. }
  117. /**
  118. * 查询所有歌单
  119. */
  120. @GetMapping(value = "/allSongSheet")
  121. public R allSongSheet(HttpServletRequest request){
  122. List<SongSheet> songSheetList = this.songSheetService.allSongList();
  123. logger.info("查询所有的歌单: {}",songSheetList);
  124. return R.ok().data("list",songSheetList);
  125. }
  126. /**
  127. * 根据标题精确查询歌单列表
  128. */
  129. @GetMapping(value = "/songListOfTitle")
  130. public R songListOfName(HttpServletRequest request){
  131. String title = request.getParameter("title").trim(); //歌单标题
  132. List<SongSheet> songSheetList = this.songSheetService.songListOfTitle(title);
  133. return R.ok().data("list",songSheetList);
  134. }
  135. /**
  136. * 根据标题模糊查询歌单列表
  137. */
  138. @GetMapping(value = "/likeTitle")
  139. public R likeTitle(HttpServletRequest request){
  140. String title = request.getParameter("title").trim(); //歌单标题
  141. List<SongSheet> songSheetList = this.songSheetService.likeTitle(title);
  142. return R.ok().data("list",songSheetList);
  143. }
  144. /**
  145. * 根据风格模糊查询歌单列表
  146. */
  147. @GetMapping(value = "/likeStyle")
  148. public Object likeStyle(HttpServletRequest request){
  149. String style = request.getParameter("style").trim(); //歌单风格
  150. List<SongSheet> songSheetList = this.songSheetService.likeStyle(style);
  151. return R.ok().data("list",songSheetList);
  152. }
  153. /**
  154. * 更新歌单图片
  155. */
  156. @PostMapping(value = "/updateSongSheetPic")
  157. public R updateSongSheetPic(@RequestParam("file") MultipartFile file, @RequestParam("id")int id){
  158. /**
  159. * 更新歌单图片之前,必须把原来的歌单图片删除掉
  160. */
  161. //通过ID主键查询歌单对象
  162. SongSheet songSheet = this.songSheetService.selectByPrimaryKey(id);
  163. //获取歌曲图片
  164. String pic = songSheet.getPic();
  165. logger.info("歌单图片: {}",pic);
  166. //如果文件的相对路径是/img/songListPic/123.jpg就没必要删除
  167. //因为它是当作默认相对路径的,需要用到
  168. if(!pic.equals("/img/songListPic/123.jpg")){
  169. //获取歌曲保存的文件目录
  170. String songPath = System.getProperty("user.dir") + pic;
  171. logger.info("获取歌单保存的文件目录: {}",songPath);
  172. File file1 = new File(songPath);
  173. if(file1.isFile()){
  174. file1.delete();
  175. }
  176. }
  177. //开始更新歌曲图片
  178. if(file.isEmpty()){
  179. return R.error().message("图片上传失败!!");
  180. }
  181. //文件名=当前时间到毫秒+原来的文件名
  182. String fileName = System.currentTimeMillis()+file.getOriginalFilename();
  183. //文件路径
  184. String filePath = System.getProperty("user.dir")+System.getProperty("file.separator")+"img"
  185. +System.getProperty("file.separator")+"songListPic";
  186. //如果文件路径不存在,新增该路径
  187. File file1 = new File(filePath);
  188. if(!file1.exists()){
  189. file1.mkdir();
  190. }
  191. //实际的文件地址
  192. File dest = new File(filePath+System.getProperty("file.separator")+fileName);
  193. //存储到数据库里的相对文件地址
  194. String storeAvatorPath = "/img/songListPic/"+fileName;
  195. try {
  196. file.transferTo(dest);
  197. SongSheet songSheet1 = new SongSheet();
  198. songSheet1.setId(id);
  199. songSheet1.setPic(storeAvatorPath);
  200. boolean flag = this.songSheetService.updateSongSheet(songSheet1);
  201. if(flag){
  202. return R.ok().message("图片上传成功!!");
  203. }else {
  204. return R.error().message("图片上传失败!!");
  205. }
  206. } catch (IOException e) {
  207. return R.error().message("图片上传失败!!");
  208. }
  209. }
  210. }

1.2 歌单包含歌曲服务模块编写

1)Service服务层编写

  1. package com.gmw.musicserver.service;
  2. import com.baomidou.mybatisplus.extension.service.IService;
  3. import com.gmw.musicserver.entity.SongList;
  4. import java.util.List;
  5. /**
  6. * <p>
  7. * 歌单包含歌曲列表 服务类
  8. * 歌单里面的歌曲service接口
  9. * </p>
  10. *
  11. * @author 未进化的程序猿
  12. * @since 2022-01-26
  13. */
  14. public interface SongListService extends IService<SongList> {
  15. /**
  16. *增加歌单里面的歌曲
  17. */
  18. public boolean insertSongList(SongList songList);
  19. /**
  20. *修改歌单里面的歌曲
  21. */
  22. public boolean updateSongList(SongList songList);
  23. /**
  24. * 删除歌单里面的歌曲
  25. */
  26. public boolean deleteSongList(Integer id);
  27. /**
  28. * 根据歌曲id和歌单id删除
  29. */
  30. public boolean deleteBySongIdAndSongListId(Integer songId,Integer songListId);
  31. /**
  32. * 根据主键查询整个对象
  33. */
  34. public SongList selectByPrimaryKey(Integer id);
  35. /**
  36. * 查询所有歌单里面的歌曲
  37. */
  38. public List<SongList> allSongList();
  39. /**
  40. * 根据歌单id查询所有的歌曲
  41. */
  42. public List<SongList> listSongOfSongListId(Integer songListId);
  43. }
  1. package com.gmw.musicserver.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.gmw.musicserver.entity.SongList;
  4. import com.gmw.musicserver.mapper.SongListMapper;
  5. import com.gmw.musicserver.service.SongListService;
  6. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  7. import org.springframework.stereotype.Service;
  8. import java.util.List;
  9. /**
  10. * <p>
  11. * 歌单包含歌曲列表 服务实现类
  12. * </p>
  13. *
  14. * @author 未进化的程序猿
  15. * @since 2022-01-26
  16. */
  17. @Service
  18. public class SongListServiceImpl extends ServiceImpl<SongListMapper, SongList> implements SongListService {
  19. /**
  20. * 增加歌单里面的歌曲
  21. *
  22. * @param songList
  23. */
  24. @Override
  25. public boolean insertSongList(SongList songList) {
  26. return this.baseMapper.insert(songList) > 0;
  27. }
  28. /**
  29. * 修改歌单里面的歌曲
  30. *
  31. * @param songList
  32. */
  33. @Override
  34. public boolean updateSongList(SongList songList) {
  35. return this.baseMapper.updateById(songList) > 0;
  36. }
  37. /**
  38. * 删除歌单里面的歌曲
  39. *
  40. * @param id
  41. */
  42. @Override
  43. public boolean deleteSongList(Integer id) {
  44. return this.baseMapper.deleteById(id) > 0;
  45. }
  46. /**
  47. * 根据歌曲id和歌单id删除
  48. *
  49. * @param songId
  50. * @param songListId
  51. */
  52. @Override
  53. public boolean deleteBySongIdAndSongListId(Integer songId, Integer songListId) {
  54. QueryWrapper<SongList> queryWrapper = new QueryWrapper<>();
  55. queryWrapper.eq("song_id",songId);
  56. queryWrapper.eq("song_sheet_id",songListId);
  57. return this.baseMapper.delete(queryWrapper) > 0;
  58. }
  59. /**
  60. * 根据主键查询整个对象
  61. *
  62. * @param id
  63. */
  64. @Override
  65. public SongList selectByPrimaryKey(Integer id) {
  66. return this.baseMapper.selectById(id);
  67. }
  68. /**
  69. * 查询所有歌单里面的歌曲
  70. */
  71. @Override
  72. public List<SongList> allSongList() {
  73. return this.baseMapper.selectList(null);
  74. }
  75. /**
  76. * 根据歌单id查询所有的歌曲
  77. *
  78. * @param songListId
  79. */
  80. @Override
  81. public List<SongList> listSongOfSongListId(Integer songListId) {
  82. QueryWrapper<SongList> queryWrapper = new QueryWrapper<>();
  83. queryWrapper.eq("song_sheet_id",songListId);
  84. return this.baseMapper.selectList(queryWrapper);
  85. }
  86. }

2)Controller控制层编写

  1. package com.gmw.musicserver.controller;
  2. import com.gmw.musicserver.commonutils.R;
  3. import com.gmw.musicserver.entity.SongList;
  4. import com.gmw.musicserver.service.SongListService;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.web.bind.annotation.GetMapping;
  9. import org.springframework.web.bind.annotation.PostMapping;
  10. import org.springframework.web.bind.annotation.RequestMapping;
  11. import org.springframework.web.bind.annotation.RestController;
  12. import javax.servlet.http.HttpServletRequest;
  13. import java.util.List;
  14. /**
  15. * <p>
  16. * 歌单包含歌曲列表 前端控制器
  17. * </p>
  18. *
  19. * @author 未进化的程序猿
  20. * @since 2022-01-26
  21. */
  22. @RestController
  23. @RequestMapping("/musicserver/songList")
  24. public class SongListController {
  25. public static final Logger logger = LoggerFactory.getLogger(SongListController.class);
  26. @Autowired
  27. public SongListService songListService;
  28. /**
  29. * 给歌单添加歌曲
  30. */
  31. @PostMapping(value = "/addListSong")
  32. public R addListSong(HttpServletRequest request){
  33. //获取前端传来的参数
  34. String songId = request.getParameter("songId").trim(); //歌曲id
  35. String songListId = request.getParameter("songListId").trim(); //歌单id
  36. SongList songList = new SongList();
  37. songList.setSongId(Integer.parseInt(songId));
  38. songList.setSongSheetId(Integer.parseInt(songListId));
  39. logger.info("歌单添加歌曲对象: {}",songList);
  40. boolean flag = this.songListService.insertSongList(songList);
  41. if(flag){
  42. return R.ok().message("添加歌单歌曲成功!!");
  43. }
  44. return R.error().message("添加歌单歌曲失败!!");
  45. }
  46. /**
  47. * 根据歌单id查询歌曲
  48. */
  49. @GetMapping(value = "/detail")
  50. public R detail(HttpServletRequest request){
  51. String songListId = request.getParameter("songListId");
  52. List<SongList> lists = this.songListService.listSongOfSongListId(Integer.parseInt(songListId));
  53. return R.ok().data("list",lists);
  54. }
  55. /**
  56. * 删除歌单里的歌曲
  57. */
  58. @GetMapping(value = "/delete")
  59. public Object delete(HttpServletRequest request){
  60. String songId = request.getParameter("songId").trim(); //歌曲id
  61. String songListId = request.getParameter("songListId").trim(); //歌单id
  62. boolean flag = this.songListService.deleteBySongIdAndSongListId(Integer.parseInt(songId),Integer.parseInt(songListId));
  63. if (flag){
  64. return R.ok().message("删除歌单歌曲成功!!");
  65. }
  66. return R.error().message("删除歌单歌曲失败!!");
  67. }
  68. }

1.3 在歌曲管理模块Controller控制层中添加(根据歌曲id查询歌曲对象/根据歌手id查询歌曲)

  1. /**
  2. * 根据歌曲id查询歌曲对象
  3. */
  4. @GetMapping(value = "/detail")
  5. public R detail(HttpServletRequest request){
  6. String songId = request.getParameter("songId");
  7. Song song = this.songService.selectByPrimaryKey(Integer.parseInt(songId));
  8. return R.ok().data("song",song);
  9. }
  10. /**
  11. * 根据歌手名称查询歌曲
  12. */
  13. @GetMapping(value = "/songOfSongName")
  14. public R songOfSongName(HttpServletRequest request){
  15. String songName = request.getParameter("songName");
  16. List<Song> songList = this.songService.songOfName(songName);
  17. return R.ok().data("list",songList);
  18. }

2、前端编写

2.1 歌单管理模块

image.png

  1. <template>
  2. <div class="table">
  3. <div class="container">
  4. <div class="handle-box">
  5. <el-button type="primary" size="mini" @click="delAll">批量删除</el-button>
  6. <el-input v-model="select_word" size="mini" placeholder="筛选关键字" class="handle-input"></el-input>
  7. <el-button type="primary" size="mini" @click="centerDialogVisible = true">添加歌单</el-button>
  8. </div>
  9. </div>
  10. <el-table size="mini" ref="multipleTable" border style="width:100%" height="680px" :data="data" @selection-change="handleSelectionChange">
  11. <el-table-column type="selection" width="40"></el-table-column>
  12. <el-table-column label="歌单图片" width="110" align="center">
  13. <template slot-scope="scope">
  14. <div class="songList-img">
  15. <img :src="getUrl(scope.row.pic)" style="width:100%"/>
  16. </div>
  17. <el-upload :action="uploadUrl(scope.row.id)" :before-upload="beforeAvatorUpload"
  18. :on-success="handleAvatorSuccess">
  19. <el-button size="mini">更新图片</el-button>
  20. </el-upload>
  21. </template>
  22. </el-table-column>
  23. <el-table-column prop="title" label="标题" width="120" align="center"></el-table-column>
  24. <el-table-column label="简介">
  25. <template slot-scope="scope">
  26. <p style="height:100px;overflow:scroll">{{scope.row.introduction}}</p>
  27. </template>
  28. </el-table-column>
  29. <el-table-column prop="style" label="风格" width="120" align="center"></el-table-column>
  30. <el-table-column label="歌曲管理" width="110" align="center">
  31. <template slot-scope="scope">
  32. <el-button size="mini" @click="songEdit(scope.row.id)">歌曲管理</el-button>
  33. </template>
  34. </el-table-column>
  35. <el-table-column label="操作" width="150" align="center">
  36. <template slot-scope="scope">
  37. <el-button size="mini" @click="handleEdit(scope.row)">编辑</el-button>
  38. <el-button size="mini" type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
  39. </template>
  40. </el-table-column>
  41. </el-table>
  42. <div class="pagination">
  43. <el-pagination
  44. background
  45. layout = "total,prev,pager,next"
  46. :current-page="currentPage"
  47. :page-size="pageSize"
  48. :total="tableData.length"
  49. @current-change="handleCurrentChange"
  50. >
  51. </el-pagination>
  52. </div>
  53. <el-dialog title="添加歌单" :visible.sync="centerDialogVisible" width="400px" center>
  54. <el-form :model="registerForm" ref="registerForm" label-width="80px">
  55. <el-form-item prop="title" label="标题" size="mini">
  56. <el-input v-model="registerForm.title" placeholder="标题"></el-input>
  57. </el-form-item>
  58. <el-form-item prop="introduction" label="简介" size="mini">
  59. <el-input v-model="registerForm.introduction" placeholder="简介" type="textarea"></el-input>
  60. </el-form-item>
  61. <el-form-item prop="style" label="风格" size="mini">
  62. <el-input v-model="registerForm.style" placeholder="风格"></el-input>
  63. </el-form-item>
  64. </el-form>
  65. <span slot="footer">
  66. <el-button size="mini" @click="centerDialogVisible = false">取消</el-button>
  67. <el-button size="mini" @click="addSongList">确定</el-button>
  68. </span>
  69. </el-dialog>
  70. <el-dialog title="修改歌单" :visible.sync="editVisible" width="400px" center>
  71. <el-form :model="form" ref="form" label-width="80px">
  72. <el-form-item prop="title" label="标题" size="mini">
  73. <el-input v-model="form.title" placeholder="标题"></el-input>
  74. </el-form-item>
  75. <el-form-item prop="introduction" label="简介" size="mini">
  76. <el-input v-model="form.introduction" placeholder="简介" type="textarea"></el-input>
  77. </el-form-item>
  78. <el-form-item prop="style" label="风格" size="mini">
  79. <el-input v-model="form.style" placeholder="风格"></el-input>
  80. </el-form-item>
  81. </el-form>
  82. <span slot="footer">
  83. <el-button size="mini" @click="editVisible = false">取消</el-button>
  84. <el-button size="mini" @click="editSave">确定</el-button>
  85. </span>
  86. </el-dialog>
  87. <el-dialog title="删除歌单" :visible.sync="delVisible" width="300px" center>
  88. <div align="center">删除不可恢复,是否确定删除?</div>
  89. <span slot="footer">
  90. <el-button size="mini" @click="delVisible = false">取消</el-button>
  91. <el-button size="mini" @click="deleteRow">确定</el-button>
  92. </span>
  93. </el-dialog>
  94. </div>
  95. </template>
  96. <script>
  97. import {getAllSongList,setSongList,updateSongList,delSongList} from '../api/songsheet/index';
  98. import { mixin } from '../mixins/index';
  99. export default {
  100. mixins: [mixin],
  101. data(){
  102. return{
  103. centerDialogVisible: false, //添加弹窗是否显示
  104. editVisible: false, //编辑弹窗是否显示
  105. delVisible: false, //删除弹窗是否显示
  106. registerForm:{ //添加框
  107. title: '',
  108. introduction: '',
  109. style: ''
  110. },
  111. form:{ //编辑框
  112. id: '',
  113. title: '',
  114. introduction: '',
  115. style: ''
  116. },
  117. tableData: [],
  118. tempData: [],
  119. select_word: '',
  120. pageSize: 5, //分页每页大小
  121. currentPage: 1, //当前页
  122. idx: -1, //当前选择项
  123. multipleSelection: [] //哪些项已经打勾
  124. }
  125. },
  126. computed:{
  127. //计算当前搜索结果表里的数据
  128. data(){
  129. return this.tableData.slice((this.currentPage - 1) * this.pageSize,this.currentPage * this.pageSize)
  130. }
  131. },
  132. watch:{
  133. //搜索框里面的内容发生变化的时候,搜索结果table列表的内容跟着它的内容发生变化
  134. select_word: function(){
  135. if(this.select_word == ''){
  136. this.tableData = this.tempData;
  137. }else{
  138. this.tableData = [];
  139. for(let item of this.tempData){
  140. if(item.title.includes(this.select_word)){
  141. this.tableData.push(item);
  142. }
  143. }
  144. }
  145. }
  146. },
  147. created(){
  148. this.getData();
  149. },
  150. methods:{
  151. //获取当前页
  152. handleCurrentChange(val){
  153. this.currentPage = val;
  154. },
  155. //查询所有歌单
  156. getData(){
  157. this.tempData = [];
  158. this.tableData = [];
  159. getAllSongList().then(res => {
  160. this.tempData = res.data.list;
  161. this.tableData = res.data.list;
  162. this.currentPage = 1;
  163. })
  164. },
  165. //添加歌单
  166. addSongList(){
  167. var _this = this;
  168. let params = new URLSearchParams();
  169. params.append('title',this.registerForm.title);
  170. params.append('pic','/img/songListPic/123.jpg');
  171. params.append('introduction',this.registerForm.introduction);
  172. params.append('style',this.registerForm.style);
  173. setSongList(params)
  174. .then(res => {
  175. if(res.code == 20000){
  176. this.getData();
  177. this.notify("添加成功","success");
  178. //添加成功后删除文本框里面的值
  179. _this.registerForm = {}
  180. }else{
  181. this.notify("添加失败","error");
  182. _this.registerForm = {}
  183. }
  184. })
  185. .catch(err => {
  186. console.log(err);
  187. });
  188. this.centerDialogVisible = false;
  189. },
  190. //弹出编辑页面
  191. handleEdit(row){
  192. this.editVisible = true;
  193. this.form = {
  194. id: row.id,
  195. title: row.title,
  196. introduction: row.introduction,
  197. style: row.style
  198. }
  199. },
  200. //保存编辑页面修改的数据
  201. editSave(){
  202. let params = new URLSearchParams();
  203. params.append('id',this.form.id);
  204. params.append('title',this.form.title);
  205. params.append('introduction',this.form.introduction);
  206. params.append('style',this.form.style);
  207. updateSongList(params)
  208. .then(res => {
  209. if(res.code == 20000){
  210. this.getData();
  211. this.notify("修改成功","success");
  212. }else{
  213. this.notify("修改失败","error");
  214. }
  215. })
  216. .catch(err => {
  217. console.log(err);
  218. });
  219. this.editVisible = false;
  220. },
  221. //更新图片
  222. uploadUrl(id){
  223. return `${this.$store.state.HOST}/musicserver/songSheet/updateSongSheetPic?id=${id}`
  224. },
  225. //删除一个歌单
  226. deleteRow(){
  227. delSongList(this.idx)
  228. .then(res => {
  229. if(res.code == 20000){
  230. this.getData();
  231. this.notify("删除成功","success");
  232. }else{
  233. this.notify("删除失败","error");
  234. }
  235. })
  236. .catch(err => {
  237. console.log(err);
  238. });
  239. this.delVisible = false;
  240. },
  241. //转向歌曲管理页面,id表示歌单的ID
  242. songEdit(id){
  243. this.$router.push({path:`/ListSong`,query:{id}});
  244. }
  245. }
  246. }
  247. </script>
  248. <style scoped>
  249. .handle-box{
  250. margin-bottom: 20px;
  251. }
  252. .songList-img{
  253. width: 100%;
  254. height: 80px;
  255. border-radius: 5px;
  256. margin-bottom: 5px;
  257. overflow: hidden;
  258. }
  259. .handle-input{
  260. width: 300px;
  261. display: inline-block;
  262. }
  263. .pagination{
  264. display: flex;
  265. justify-content: center;
  266. }
  267. </style>

编写请求后端服务接口方法
image.png

import {get,post} from '../http'

//============歌单相关================
//查询歌单
export const getAllSongList =() => get(`musicserver/songSheet/allSongSheet`);
//添加歌单
export const setSongList = (params) => post(`musicserver/songSheet/addSongSheet`,params);
//编辑歌单
export const updateSongList = (params) => post(`musicserver/songSheet/updateSongSheet`,params);
//删除歌单
export const delSongList = (id) => get(`musicserver/songSheet/deleteSongSheet?id=${id}`);

引入请求后端接口方法
image.png

2.2 歌单包含歌曲模块列表

image.png
image.png

歌曲模块列表展示
image.png

<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="tableData" @selection-change="handleSelectionChange">
            <el-table-column type="selection" width="40"></el-table-column>            
            <el-table-column prop="name" label="歌手-歌名" align="center"></el-table-column>            
            <el-table-column label="操作" width="150" align="center">
                <template slot-scope="scope">
                    <el-button size="mini" type="danger" @click="handleDelete(scope.row.id)">删除</el-button> 
                </template>
            </el-table-column>
        </el-table>
        <el-dialog title="添加歌曲" :visible.sync="centerDialogVisible" width="400px" center>
            <el-form :model="registerForm" ref="registerForm" label-width="80px" action="" id="tf">
                <el-form-item prop="singerName" label="歌手名字" size="mini">
                    <el-input v-model="registerForm.singerName" placeholder="歌手名字"></el-input>
                </el-form-item> 
                <el-form-item prop="songName" label="歌曲名字" size="mini">
                    <el-input v-model="registerForm.songName" placeholder="歌曲名字"></el-input>
                </el-form-item>  
            </el-form>
            <span slot="footer">
                <el-button size="mini" @click="centerDialogVisible = false">取消</el-button>
                <el-button size="mini" @click="getSongId">确定</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 {listSongDetail,listSongAdd,delListSong} from '../api/songlist/index';
import {songOfSongId,songOfSongName} from '../api/song/index'

export default {
    mixins: [mixin],
    data(){
        return{
            centerDialogVisible: false, //添加弹窗是否显示
            delVisible: false,          //删除弹窗是否显示
            registerForm:{      //添加框
                singerName: '',     //歌手名字
                songName: ''        //歌曲名字
            },
            tableData: [],
            tempData: [],
            select_word: '',
            idx: -1,          //当前选择项
            multipleSelection: [],   //哪些项已经打勾
            songListId: ''          //歌单id
        }
    },
    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(){
        //获取歌单管理从路由传过来的歌单id
        this.songListId = this.$route.query.id;
        this.getData();
    },
    methods:{
        //查询所有歌手
        getData(){
            this.tempData = [];
            this.tableData = [];
            //通过歌单id,查询该歌单下的所有歌曲
            listSongDetail(this.songListId).then(res => {
                //通过每一项的歌曲id,获取到每一项的歌曲对象
                for(let item of res.data.list){
                    this.getSong(item.songId);
                }
            })
        },
        //根据歌曲id查询歌曲对象,放到tempData和tableData里面
        getSong(id){
            songOfSongId(id)
            .then(res => {
                this.tempData.push(res.data.song);
                this.tableData.push(res.data.song);
            })
            .catch(err => {
                console.log(err);
            });
        },
        //添加歌曲前的准备,获取到歌曲id        
        getSongId(){
            let _this = this;
            //添加歌曲之前,通过歌手名称+歌曲名称拼接,查找到歌曲对象,并获取到这个对象的歌曲id,然后,传送给后端保存
            var songOfName = _this.registerForm.singerName+"-"+_this.registerForm.songName;
            songOfSongName(songOfName).then(
                res => {
                    _this.addSong(res.data.list[0].id)
                }
            )
        },
        //添加歌曲
        addSong(songId){
            let _this = this;
            let params = new URLSearchParams();
            params.append('songId',songId);
            params.append('songListId',this.songListId);

            listSongAdd(params)
            .then(res => {
                if(res.code == 20000){
                    this.getData();
                    this.notify("添加成功","success");
                }else{
                    this.notify("添加失败","error");
                }
            })
            .catch(err => {
                console.log(err);
            });
            _this.centerDialogVisible = false;
        },
        //删除一条歌曲
        deleteRow(){
            delListSong(this.idx,this.songListId)
            .then(res => {
                if(res.code == 20000){
                    this.getData();
                    this.notify("删除成功","success");
                }else{
                    this.notify("删除失败","error");
                }
            })
            .catch(err => {
                console.log(err);
            });
            this.delVisible = false;
        }
    }   
}
</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>

添加歌曲
image.png
image.png
image.png

添加歌曲之前,通过歌手名称+歌曲名称拼接,查找到歌曲对象,并获取到这个对象的歌曲id,然后,传送给后端保存

image.png
调用请求后端服务接口的方法
image.png
image.png

//根据歌曲id查询歌曲对象
export const songOfSongId =(id) => get(`musicserver/song/detail?songId=${id}`);
//根据歌曲名获取歌曲对象
export const songOfSongName =(songName) => get(`musicserver/song/songOfSongName?songName=${songName}`);

image.png

import {get,post} from '../http'

//============歌单的歌曲相关============
//根据歌单id查询歌曲列表
export const listSongDetail = (songListId) => get(`musicserver/songList/detail?songListId=${songListId}`);
//给歌单增加歌曲
export const listSongAdd = (params) => post(`musicserver/songList/addListSong`,params);
//删除歌单的歌曲
export const delListSong = (songId,songListId) => get(`musicserver/songList/delete?songId=${songId}&songListId=${songListId}`);

引入请求后端接口方法
image.png
添加歌曲
image.png

删除歌曲
image.png
image.png
image.png
image.png
image.png