364 lines
13 KiB
Java
364 lines
13 KiB
Java
package com.rj.service.impl;
|
||
|
||
import com.rj.entity.AudioManagement;
|
||
import com.rj.service.IFileUploadService;
|
||
import com.rj.service.IAudioManagementService;
|
||
import com.rj.service.MinIOService;
|
||
import lombok.extern.slf4j.Slf4j;
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.beans.factory.annotation.Value;
|
||
import org.springframework.stereotype.Service;
|
||
import org.springframework.util.StringUtils;
|
||
import org.springframework.web.multipart.MultipartFile;
|
||
|
||
import java.io.File;
|
||
import java.io.IOException;
|
||
import java.nio.file.Files;
|
||
import java.nio.file.Path;
|
||
import java.nio.file.Paths;
|
||
import java.util.HashMap;
|
||
import java.util.Map;
|
||
import java.util.UUID;
|
||
|
||
/**
|
||
* 文件上传服务实现类
|
||
*
|
||
* @author 李中华 ,spllzh
|
||
* @since 2025-08-07
|
||
*/
|
||
@Slf4j
|
||
@Service
|
||
public class FileUploadServiceImpl implements IFileUploadService {
|
||
|
||
@Autowired
|
||
private IAudioManagementService audioManagementService;
|
||
|
||
@Autowired
|
||
private MinIOService minIOService;
|
||
|
||
@Value("${app.audio.upload.path:uploads/audio}")
|
||
private String uploadPath;
|
||
|
||
@Value("${app.audio.access.url:/api/audio/}")
|
||
private String accessUrl;
|
||
|
||
@Value("${app.audio.max.size:10MB}")
|
||
private String maxFileSize;
|
||
|
||
// 支持的音频格式
|
||
private static final String[] SUPPORTED_AUDIO_FORMATS = {
|
||
"mp3", "wav", "m4a", "aac", "ogg", "flac", "wma"
|
||
};
|
||
|
||
@Override
|
||
public Map<String, Object> uploadAudioFile(MultipartFile file, String audioId) throws IOException {
|
||
Map<String, Object> result = new HashMap<>();
|
||
|
||
try {
|
||
// 验证文件
|
||
if (file == null || file.isEmpty()) {
|
||
result.put("success", false);
|
||
result.put("message", "文件不能为空");
|
||
return result;
|
||
}
|
||
|
||
// 验证文件大小
|
||
long maxSize = parseFileSize(maxFileSize);
|
||
if (file.getSize() > maxSize) {
|
||
result.put("success", false);
|
||
result.put("message", "文件大小超过限制,最大允许 " + maxFileSize);
|
||
return result;
|
||
}
|
||
|
||
// 验证文件格式
|
||
String originalFilename = file.getOriginalFilename();
|
||
if (!isValidAudioFormat(originalFilename)) {
|
||
result.put("success", false);
|
||
result.put("message", "不支持的音频格式,支持的格式:" + String.join(", ", SUPPORTED_AUDIO_FORMATS));
|
||
return result;
|
||
}
|
||
|
||
// 直接上传到MinIO,不保存到本地
|
||
log.info("开始上传文件到MinIO...");
|
||
String fileUrl = minIOService.uploadFile(file);
|
||
log.info("文件上传成功,URL: {}", fileUrl);
|
||
|
||
// 获取录音记录并更新
|
||
AudioManagement audio = audioManagementService.getById(audioId);
|
||
if (audio != null) {
|
||
// 更新录音记录的文件信息
|
||
String fileExtension = getFileExtension(originalFilename);
|
||
|
||
audio.setAudioFileUrl(fileUrl);
|
||
audio.setAudioFileSize(file.getSize());
|
||
audio.setAudioFileOriginalName(originalFilename);
|
||
audio.setAudioFileExtension(fileExtension);
|
||
audio.setUploadTime(java.time.LocalDateTime.now());
|
||
audio.setUpdateTime(java.time.LocalDateTime.now());
|
||
|
||
// 保存更新
|
||
audioManagementService.updateById(audio);
|
||
|
||
log.info("录音记录更新成功:audioId={}", audioId);
|
||
} else {
|
||
log.warn("未找到对应的录音记录:audioId={}", audioId);
|
||
}
|
||
|
||
result.put("success", true);
|
||
result.put("message", "文件上传成功");
|
||
result.put("fileUrl", fileUrl);
|
||
result.put("fileSize", file.getSize());
|
||
result.put("originalName", originalFilename);
|
||
|
||
log.info("音频文件上传成功:audioId={}, minioUrl={}, size={}", audioId, fileUrl, file.getSize());
|
||
|
||
} catch (Exception e) {
|
||
log.error("音频文件上传失败:audioId={}, error={}", audioId, e.getMessage(), e);
|
||
result.put("success", false);
|
||
result.put("message", "文件上传失败:" + e.getMessage());
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
@Override
|
||
public Map<String, Object> uploadAudioFileAndUpdateRecord(MultipartFile file, String audioId) throws IOException {
|
||
Map<String, Object> result = new HashMap<>();
|
||
|
||
try {
|
||
// 先上传文件
|
||
Map<String, Object> uploadResult = uploadAudioFile(file, audioId);
|
||
|
||
if (!(Boolean) uploadResult.get("success")) {
|
||
return uploadResult;
|
||
}
|
||
|
||
// 获取录音记录
|
||
AudioManagement audio = audioManagementService.getById(audioId);
|
||
if (audio == null) {
|
||
result.put("success", false);
|
||
result.put("message", "录音记录不存在");
|
||
return result;
|
||
}
|
||
|
||
// 更新录音记录的文件信息
|
||
String fileName = (String) uploadResult.get("fileName");
|
||
String fileUrl = (String) uploadResult.get("fileUrl");
|
||
Long fileSize = (Long) uploadResult.get("fileSize");
|
||
String originalName = (String) uploadResult.get("originalName");
|
||
String fileExtension = getFileExtension(originalName);
|
||
|
||
audio.setAudioFilePath(uploadPath + "/" + fileName);
|
||
audio.setAudioFileUrl(fileUrl);
|
||
audio.setAudioFileSize(fileSize);
|
||
audio.setAudioFileOriginalName(originalName);
|
||
audio.setAudioFileExtension(fileExtension);
|
||
audio.setUploadTime(java.time.LocalDateTime.now());
|
||
audio.setUpdateTime(java.time.LocalDateTime.now());
|
||
|
||
// 保存更新
|
||
boolean updated = audioManagementService.updateById(audio);
|
||
|
||
if (updated) {
|
||
result.put("success", true);
|
||
result.put("message", "音频文件上传成功并更新录音记录");
|
||
result.put("data", uploadResult);
|
||
result.put("audioRecord", audio);
|
||
|
||
log.info("音频文件上传并更新录音记录成功:audioId={}, fileName={}", audioId, fileName);
|
||
} else {
|
||
result.put("success", false);
|
||
result.put("message", "文件上传成功但更新录音记录失败");
|
||
result.put("data", uploadResult);
|
||
}
|
||
|
||
} catch (Exception e) {
|
||
log.error("音频文件上传并更新录音记录失败:audioId={}, error={}", audioId, e.getMessage(), e);
|
||
result.put("success", false);
|
||
result.put("message", "文件上传并更新录音记录失败:" + e.getMessage());
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
@Override
|
||
public String getAudioFileUrl(String audioId) {
|
||
if (StringUtils.isEmpty(audioId)) {
|
||
return null;
|
||
}
|
||
|
||
Path uploadDir = Paths.get(uploadPath);
|
||
File dir = uploadDir.toFile();
|
||
|
||
if (!dir.exists() || !dir.isDirectory()) {
|
||
return null;
|
||
}
|
||
|
||
// 查找对应的音频文件
|
||
File[] files = dir.listFiles((d, name) -> name.startsWith(audioId + "."));
|
||
if (files != null && files.length > 0) {
|
||
String fileName = files[0].getName();
|
||
return accessUrl + fileName;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
@Override
|
||
public boolean deleteAudioFile(String audioId) {
|
||
if (StringUtils.isEmpty(audioId)) {
|
||
return false;
|
||
}
|
||
|
||
try {
|
||
Path uploadDir = Paths.get(uploadPath);
|
||
File dir = uploadDir.toFile();
|
||
|
||
if (!dir.exists() || !dir.isDirectory()) {
|
||
return false;
|
||
}
|
||
|
||
// 查找对应的音频文件
|
||
File[] files = dir.listFiles((d, name) -> name.startsWith(audioId + "."));
|
||
if (files != null && files.length > 0) {
|
||
boolean deleted = files[0].delete();
|
||
if (deleted) {
|
||
log.info("音频文件删除成功:audioId={}, fileName={}", audioId, files[0].getName());
|
||
}
|
||
return deleted;
|
||
}
|
||
|
||
return false;
|
||
} catch (Exception e) {
|
||
log.error("音频文件删除失败:audioId={}, error={}", audioId, e.getMessage(), e);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public boolean audioFileExists(String audioId) {
|
||
if (StringUtils.isEmpty(audioId)) {
|
||
return false;
|
||
}
|
||
|
||
Path uploadDir = Paths.get(uploadPath);
|
||
File dir = uploadDir.toFile();
|
||
|
||
if (!dir.exists() || !dir.isDirectory()) {
|
||
return false;
|
||
}
|
||
|
||
File[] files = dir.listFiles((d, name) -> name.startsWith(audioId + "."));
|
||
return files != null && files.length > 0;
|
||
}
|
||
|
||
@Override
|
||
public Map<String, Object> uploadAudioFileToMinIO(MultipartFile file, String audioId) throws IOException {
|
||
Map<String, Object> result = new HashMap<>();
|
||
|
||
try {
|
||
// 验证文件
|
||
if (file == null || file.isEmpty()) {
|
||
result.put("success", false);
|
||
result.put("message", "文件不能为空");
|
||
return result;
|
||
}
|
||
|
||
// 验证文件大小
|
||
long maxSize = parseFileSize(maxFileSize);
|
||
if (file.getSize() > maxSize) {
|
||
result.put("success", false);
|
||
result.put("message", "文件大小超过限制,最大允许 " + maxFileSize);
|
||
return result;
|
||
}
|
||
|
||
// 验证文件格式
|
||
String originalFilename = file.getOriginalFilename();
|
||
if (!isValidAudioFormat(originalFilename)) {
|
||
result.put("success", false);
|
||
result.put("message", "不支持的音频格式,支持的格式:" + String.join(", ", SUPPORTED_AUDIO_FORMATS));
|
||
return result;
|
||
}
|
||
|
||
// 使用MinIO上传文件
|
||
String minioUrl = minIOService.uploadFile(file);
|
||
|
||
result.put("success", true);
|
||
result.put("message", "文件上传到MinIO成功");
|
||
result.put("fileUrl", minioUrl);
|
||
result.put("fileSize", file.getSize());
|
||
result.put("originalName", originalFilename);
|
||
result.put("audioId", audioId);
|
||
|
||
log.info("音频文件上传到MinIO成功:audioId={}, minioUrl={}, size={}", audioId, minioUrl, file.getSize());
|
||
|
||
} catch (Exception e) {
|
||
log.error("音频文件上传到MinIO失败:audioId={}, error={}", audioId, e.getMessage(), e);
|
||
result.put("success", false);
|
||
result.put("message", "文件上传到MinIO失败:" + e.getMessage());
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* 验证音频文件格式
|
||
*/
|
||
private boolean isValidAudioFormat(String filename) {
|
||
if (StringUtils.isEmpty(filename)) {
|
||
return false;
|
||
}
|
||
|
||
String extension = getFileExtension(filename).toLowerCase();
|
||
for (String format : SUPPORTED_AUDIO_FORMATS) {
|
||
if (format.equals(extension)) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 获取文件扩展名
|
||
*/
|
||
private String getFileExtension(String filename) {
|
||
if (StringUtils.isEmpty(filename)) {
|
||
return "";
|
||
}
|
||
int lastDotIndex = filename.lastIndexOf('.');
|
||
if (lastDotIndex > 0 && lastDotIndex < filename.length() - 1) {
|
||
return filename.substring(lastDotIndex + 1);
|
||
}
|
||
return "";
|
||
}
|
||
|
||
/**
|
||
* 解析文件大小字符串
|
||
*/
|
||
private long parseFileSize(String sizeStr) {
|
||
if (StringUtils.isEmpty(sizeStr)) {
|
||
return 100 * 1024 * 1024; // 默认100MB
|
||
}
|
||
|
||
sizeStr = sizeStr.trim().toUpperCase();
|
||
long multiplier = 1;
|
||
|
||
if (sizeStr.endsWith("KB")) {
|
||
multiplier = 1024;
|
||
sizeStr = sizeStr.substring(0, sizeStr.length() - 2);
|
||
} else if (sizeStr.endsWith("MB")) {
|
||
multiplier = 1024 * 1024;
|
||
sizeStr = sizeStr.substring(0, sizeStr.length() - 2);
|
||
} else if (sizeStr.endsWith("GB")) {
|
||
multiplier = 1024 * 1024 * 1024;
|
||
sizeStr = sizeStr.substring(0, sizeStr.length() - 2);
|
||
}
|
||
|
||
try {
|
||
return Long.parseLong(sizeStr) * multiplier;
|
||
} catch (NumberFormatException e) {
|
||
return 100 * 1024 * 1024; // 默认100MB
|
||
}
|
||
}
|
||
}
|