feat(system): 新增大文件分片上传功能

- 在ISysOssService接口中增加文件流式上传方法,支持避免OOM
- 实现SysOssServiceImpl中的文件流式上传逻辑
- 新增BigUploadController控制器处理分片上传、合并、恢复与清理
- 添加ChunkedUploadService服务类管理分片上传业务逻辑
- 创建BigUploadCleanupScheduler定时任务清理过期分片
- 提供FileMultipartFile适配器将File对象转换为MultipartFile
This commit is contained in:
2025-12-15 17:26:21 +08:00
parent 7f5d6c1143
commit b568affb14
6 changed files with 511 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.File;
import java.util.Collection;
import java.util.List;
@@ -26,6 +27,15 @@ public interface ISysOssService {
SysOssVo upload(MultipartFile file, Long isPublic);
/**
* 文件流式上传避免OOM
*
* @param file 本地文件
* @param originalFileName 原始文件名(用于记录与后缀)
* @param isPublic 是否公开
*/
SysOssVo upload(File file, String originalFileName, Long isPublic);
void download(Long ossId, HttpServletResponse response) throws IOException;
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);

View File

@@ -34,6 +34,7 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
@@ -147,6 +148,34 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
return this.matchingUrl(sysOssVo);
}
@Override
public SysOssVo upload(File file, String originalFileName, Long isPublic) {
// 1. 解析文件后缀
String suffix = StringUtils.substring(originalFileName, originalFileName.lastIndexOf("."), originalFileName.length());
// 2. 获取OSS客户端
OssClient storage = OssFactory.instance();
UploadResult uploadResult;
try {
// 关键用InputStream流式上传而非加载整个文件到内存
uploadResult = storage.uploadSuffix(file, suffix);
} catch (Exception e) {
throw new ServiceException(e.getMessage());
}
SysOss oss = new SysOss();
oss.setUrl(uploadResult.getUrl());
oss.setFileSuffix(suffix);
oss.setFileName(uploadResult.getFilename());
oss.setOriginalName(originalFileName);
oss.setService(storage.getConfigKey());
oss.setCreateBy(LoginHelper.getNickName());
oss.setOwnerId(LoginHelper.getUserId());
oss.setIsPublic(isPublic == null ? 0 : isPublic);
baseMapper.insert(oss);
SysOssVo sysOssVo = new SysOssVo();
BeanCopyUtils.copy(oss, sysOssVo);
return this.matchingUrl(sysOssVo);
}
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {