mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-18 09:35:29 +08:00
oss 文件操作
This commit is contained in:
parent
3d47accfeb
commit
552d9b4ca3
@ -0,0 +1,200 @@
|
||||
package com.luban.api.s3.ctrl;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.liuxp.minioplus.api.StorageService;
|
||||
import org.liuxp.minioplus.api.model.vo.CompleteResultVo;
|
||||
import org.liuxp.minioplus.api.model.vo.FileCheckResultVo;
|
||||
import org.liuxp.minioplus.api.model.vo.FilePreShardingVo;
|
||||
import org.liuxp.minioplus.common.enums.MinioPlusErrorCode;
|
||||
import org.liuxp.minioplus.common.enums.StorageBucketEnums;
|
||||
import org.liuxp.minioplus.common.exception.MinioPlusException;
|
||||
import org.liuxp.minioplus.extension.context.Response;
|
||||
import org.liuxp.minioplus.extension.context.UserHolder;
|
||||
import org.liuxp.minioplus.extension.dto.FileCheckDTO;
|
||||
import org.liuxp.minioplus.extension.dto.FileCompleteDTO;
|
||||
import org.liuxp.minioplus.extension.dto.PreShardingDTO;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* 对象存储标准接口定义
|
||||
* 本类的方法是给前端使用的方法
|
||||
*
|
||||
* @author contact@liuxp.me
|
||||
* @since 2024/6/18
|
||||
*/
|
||||
@Slf4j
|
||||
@Controller
|
||||
@RequestMapping("storage2")
|
||||
public class Storage2Controller implements StorageWebAPI {
|
||||
|
||||
/**
|
||||
* 存储引擎Service接口定义
|
||||
*/
|
||||
private final StorageService storageService;
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*
|
||||
* @param storageService 注入存储引擎Service接口定义实现类
|
||||
*/
|
||||
public Storage2Controller(StorageService storageService) {
|
||||
this.storageService = storageService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件预分片方法
|
||||
* 在大文件上传时,为了防止前端重复计算文件MD5值,提供该方法
|
||||
*
|
||||
* @param preShardingDTO 文件预分片入参DTO
|
||||
* @return 预分片结果
|
||||
*/
|
||||
@Override
|
||||
public Response<FilePreShardingVo> sharding(@RequestBody @Validated PreShardingDTO preShardingDTO) {
|
||||
|
||||
FilePreShardingVo resultVo = storageService.sharding(preShardingDTO.getFileSize());
|
||||
|
||||
return Response.success(resultVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传任务初始化
|
||||
* 上传前的预检查:秒传、分块上传和断点续传等特性均基于该方法实现
|
||||
*
|
||||
* @param fileCheckDTO 文件预检查入参
|
||||
* @return 检查结果
|
||||
*/
|
||||
@Override
|
||||
public Response<FileCheckResultVo> init(FileCheckDTO fileCheckDTO) {
|
||||
|
||||
// 取得当前登录用户信息
|
||||
String userId = UserHolder.get();
|
||||
|
||||
FileCheckResultVo resultVo = storageService.init(fileCheckDTO.getFileMd5(), fileCheckDTO.getFullFileName(), fileCheckDTO.getFileSize(), fileCheckDTO.getIsPrivate(), userId);
|
||||
|
||||
return Response.success(resultVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传完成
|
||||
*
|
||||
* @param fileKey 文件KEY
|
||||
* @param fileCompleteDTO 文件完成入参DTO
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Override
|
||||
public Response<Object> complete(String fileKey, FileCompleteDTO fileCompleteDTO) {
|
||||
|
||||
// 取得当前登录用户信息
|
||||
String userId = UserHolder.get();
|
||||
|
||||
// 打印调试日志
|
||||
log.debug("合并文件开始fileKey=" + fileKey + ",partMd5List=" + fileCompleteDTO.getPartMd5List());
|
||||
CompleteResultVo completeResultVo = storageService.complete(fileKey, fileCompleteDTO.getPartMd5List(), userId);
|
||||
|
||||
return Response.success(completeResultVo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*
|
||||
* @param fileKey 文件KEY
|
||||
* @return 文件下载地址
|
||||
*/
|
||||
@Override
|
||||
public ResponseEntity<Void> download(String fileKey) {
|
||||
|
||||
// 取得当前登录用户信息
|
||||
String userId = UserHolder.get();
|
||||
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setLocation(URI.create(storageService.download(fileKey, userId)));
|
||||
return new ResponseEntity<>(headers, HttpStatus.SEE_OTHER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图像
|
||||
*
|
||||
* @param fileKey 文件KEY
|
||||
* @return 原图地址
|
||||
*/
|
||||
@Override
|
||||
public ResponseEntity<Void> previewOriginal(String fileKey) {
|
||||
|
||||
// 取得当前登录用户信息
|
||||
String userId = UserHolder.get();
|
||||
|
||||
// 取得文件读取路径
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setLocation(URI.create(storageService.download(fileKey, userId)));
|
||||
return new ResponseEntity<>(headers, HttpStatus.SEE_OTHER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件预览
|
||||
* 当文件为图片时,返回图片的缩略图
|
||||
* 当文件不是图片时,返回文件类型图标
|
||||
*
|
||||
* @param fileKey 文件KEY
|
||||
* @return 缩略图地址
|
||||
*/
|
||||
@Override
|
||||
public ResponseEntity<Void> previewMedium(String fileKey) {
|
||||
|
||||
// 取得当前登录用户信息
|
||||
String userId = UserHolder.get();
|
||||
|
||||
String url = storageService.preview(fileKey, userId);
|
||||
if (url.length() < 10) {
|
||||
// 当返回值为文件类型时,取得图标
|
||||
url = ICON_PATH + url;
|
||||
}
|
||||
|
||||
// 取得文件读取路径
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setLocation(URI.create(url));
|
||||
return new ResponseEntity<>(headers, HttpStatus.SEE_OTHER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件类型取得图标
|
||||
*
|
||||
* @param fileType 文件扩展名
|
||||
*/
|
||||
@Override
|
||||
public void icon(String fileType) {
|
||||
try {
|
||||
// 根据文件后缀取得桶
|
||||
String storageBucket = StorageBucketEnums.getBucketByFileSuffix(fileType, "");
|
||||
|
||||
ClassPathResource cpr = new ClassPathResource(storageBucket + ".png");
|
||||
|
||||
byte[] bytes = FileCopyUtils.copyToByteArray(cpr.getInputStream());
|
||||
|
||||
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
attr.getResponse().setHeader("content-disposition", "inline");
|
||||
attr.getResponse().setHeader("Content-Length", String.valueOf(bytes.length));
|
||||
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
|
||||
IoUtil.copy(inputStream, attr.getResponse().getOutputStream());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(MinioPlusErrorCode.FILE_ICON_FAILED.getMessage(), e);
|
||||
// 图标获取失败
|
||||
throw new MinioPlusException(MinioPlusErrorCode.FILE_ICON_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
package com.luban.api.s3.ctrl;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.liuxp.minioplus.api.model.vo.FileCheckResultVo;
|
||||
import org.liuxp.minioplus.api.model.vo.FilePreShardingVo;
|
||||
import org.liuxp.minioplus.extension.context.Response;
|
||||
import org.liuxp.minioplus.extension.dto.FileCheckDTO;
|
||||
import org.liuxp.minioplus.extension.dto.FileCompleteDTO;
|
||||
import org.liuxp.minioplus.extension.dto.PreShardingDTO;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
* 对象存储标准接口定义
|
||||
* 本类的方法是给前端使用的方法
|
||||
*
|
||||
* @author contact@liuxp.me
|
||||
* @since 2024/6/18
|
||||
*/
|
||||
@Tag(name = "MinIO Plus 接口")
|
||||
public interface StorageWebAPI {
|
||||
|
||||
/**
|
||||
* 请求地址前缀
|
||||
*/
|
||||
String ROOT_PATH = "/storage";
|
||||
|
||||
/**
|
||||
* 图标请求地址
|
||||
*/
|
||||
String ICON_PATH = "/storage/icon/";
|
||||
|
||||
/**
|
||||
* 文件预分片方法
|
||||
* 在大文件上传时,为了防止前端重复计算文件MD5值,提供该方法
|
||||
*
|
||||
* @param preShardingDTO 文件预分片入参DTO
|
||||
* @return 预分片结果
|
||||
*/
|
||||
@Operation(summary = "文件预分片")
|
||||
@PostMapping("/upload/sharding")
|
||||
@ResponseBody
|
||||
Response<FilePreShardingVo> sharding(@RequestBody @Validated PreShardingDTO preShardingDTO);
|
||||
|
||||
/**
|
||||
* 上传任务初始化
|
||||
* 上传前的预检查:秒传、分块上传和断点续传等特性均基于该方法实现
|
||||
*
|
||||
* @param fileCheckDTO 文件预检查入参
|
||||
* @return 检查结果
|
||||
*/
|
||||
@Operation(summary = "上传任务初始化")
|
||||
@PostMapping("/upload/init")
|
||||
@ResponseBody
|
||||
Response<FileCheckResultVo> init(@RequestBody @Validated FileCheckDTO fileCheckDTO);
|
||||
|
||||
/**
|
||||
* 文件上传完成
|
||||
*
|
||||
* @param fileKey 文件KEY
|
||||
* @param fileCompleteDTO 文件完成入参DTO
|
||||
* @return 是否成功
|
||||
*/
|
||||
@Operation(summary = "上传完成")
|
||||
@PostMapping("/upload/complete/{fileKey}")
|
||||
@ResponseBody
|
||||
Response<Object> complete(@PathVariable("fileKey") String fileKey, @RequestBody FileCompleteDTO fileCompleteDTO);
|
||||
|
||||
/**
|
||||
* 文件下载
|
||||
*
|
||||
* @param fileKey 文件KEY
|
||||
* @return 文件下载地址
|
||||
*/
|
||||
@Operation(summary = "文件下载")
|
||||
@GetMapping("/download/{fileKey}")
|
||||
ResponseEntity<Void> download(@PathVariable("fileKey") String fileKey);
|
||||
|
||||
/**
|
||||
* 获取图像
|
||||
*
|
||||
* @param fileKey 文件KEY
|
||||
* @return 原图地址
|
||||
*/
|
||||
@Operation(summary = "图片预览 - 原图")
|
||||
@GetMapping("/image/{fileKey}")
|
||||
ResponseEntity<Void> previewOriginal(@PathVariable("fileKey") String fileKey);
|
||||
|
||||
/**
|
||||
* 文件预览
|
||||
* 当文件为图片时,返回图片的缩略图
|
||||
* 当文件不是图片时,返回文件类型图标
|
||||
*
|
||||
* @param fileKey 文件KEY
|
||||
* @return 缩略图地址
|
||||
*/
|
||||
@Operation(summary = "图片预览 - 缩略图")
|
||||
@GetMapping("/preview/{fileKey}")
|
||||
ResponseEntity<Void> previewMedium(@PathVariable("fileKey") String fileKey);
|
||||
|
||||
/**
|
||||
* 根据文件类型取得图标
|
||||
*
|
||||
* @param fileType 文件扩展名
|
||||
*/
|
||||
@Operation(summary = "获取图标")
|
||||
@GetMapping("/icon/{fileType}")
|
||||
void icon(@PathVariable("fileType") String fileType);
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user