feat(user): 为收藏音乐页面添加更多操作功能
- 添加下拉菜单,支持多种操作 - 实现添加到播放列表、下一首播放、下载音乐、下载歌词等功能 - 优化用户交互,增加确认对话框和提示消息
This commit is contained in:
@@ -1,12 +1,27 @@
|
||||
package com.test.musichouduan.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import com.test.musichouduan.entity.Music;
|
||||
import com.test.musichouduan.service.MusicService;
|
||||
import com.test.musichouduan.dto.Result;
|
||||
import com.test.musichouduan.service.FileService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* 文件控制器
|
||||
*/
|
||||
@@ -16,7 +31,8 @@ public class FileController {
|
||||
|
||||
@Autowired
|
||||
private FileService fileService;
|
||||
|
||||
@Autowired
|
||||
private MusicService musicService;
|
||||
/**
|
||||
* 上传图片
|
||||
*
|
||||
@@ -68,4 +84,73 @@ public class FileController {
|
||||
boolean result = fileService.deleteFile(url);
|
||||
return Result.success("删除成功", result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载音乐
|
||||
*
|
||||
* @param musicId 音乐ID
|
||||
* @return 响应实体
|
||||
*/
|
||||
@GetMapping("/download/music/{musicId}")
|
||||
public ResponseEntity<Resource> downloadMusic(@PathVariable Integer musicId) throws IOException {
|
||||
// 1. 根据 musicId 获取音乐信息
|
||||
Music music = musicService.findMusicById(musicId);
|
||||
if (music == null || music.getUrl() == null || music.getUrl().isEmpty()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
// 2. 获取文件路径
|
||||
String fileUrl = music.getUrl(); // 格式: /upload/musics/xxxxxxxx.mp3
|
||||
String filePath = "music-houduan" + fileUrl; // 转换为相对项目路径
|
||||
Path path = Paths.get(filePath);
|
||||
Resource resource = new InputStreamResource(Files.newInputStream(path));
|
||||
|
||||
// 3. 设置响应头
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
String filename = music.getName() + ".mp3"; // 使用音乐名作为文件名
|
||||
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + URLEncoder.encode(filename, StandardCharsets.UTF_8.name()));
|
||||
headers.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
|
||||
headers.add(HttpHeaders.PRAGMA, "no-cache");
|
||||
headers.add(HttpHeaders.EXPIRES, "0");
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.headers(headers)
|
||||
.contentLength(Files.size(path))
|
||||
.contentType(MediaType.APPLICATION_OCTET_STREAM)
|
||||
.body(resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载歌词
|
||||
*
|
||||
* @param musicId 音乐ID
|
||||
* @return 响应实体
|
||||
*/
|
||||
@GetMapping("/download/lyric/{musicId}")
|
||||
public ResponseEntity<Resource> downloadLyric(@PathVariable Integer musicId) throws IOException {
|
||||
// 1. 根据 musicId 获取音乐信息
|
||||
Music music = musicService.findMusicById(musicId);
|
||||
if (music == null || music.getLyric() == null || music.getLyric().isEmpty()) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
|
||||
// 2. 将歌词文本转换为输入流
|
||||
String lyricContent = music.getLyric();
|
||||
byte[] lyricBytes = lyricContent.getBytes(StandardCharsets.UTF_8);
|
||||
Resource resource = new InputStreamResource(new ByteArrayInputStream(lyricBytes));
|
||||
|
||||
// 3. 设置响应头
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
String filename = music.getName() + ".lrc"; // 使用音乐名作为文件名
|
||||
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + URLEncoder.encode(filename, StandardCharsets.UTF_8.name()));
|
||||
headers.add(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
|
||||
headers.add(HttpHeaders.PRAGMA, "no-cache");
|
||||
headers.add(HttpHeaders.EXPIRES, "0");
|
||||
|
||||
return ResponseEntity.ok()
|
||||
.headers(headers)
|
||||
.contentLength(lyricBytes.length)
|
||||
.contentType(MediaType.TEXT_PLAIN)
|
||||
.body(resource);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,4 +161,12 @@ public interface MusicService {
|
||||
* @return 音乐状态DTO
|
||||
*/
|
||||
MusicStatusDTO getMusicStatus(Long musicId, Long userId);
|
||||
|
||||
/**
|
||||
* 根据ID查找音乐实体
|
||||
*
|
||||
* @param musicId 音乐ID
|
||||
* @return 音乐实体
|
||||
*/
|
||||
Music findMusicById(Integer musicId);
|
||||
}
|
||||
|
||||
@@ -615,6 +615,11 @@ public class MusicServiceImpl implements MusicService {
|
||||
return new MusicStatusDTO(isCollected, isLiked);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Music findMusicById(Integer musicId) {
|
||||
return musicRepository.findById(musicId.longValue()).orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将实体转换为DTO
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user