mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-31 17:40:05 +08:00
commit
b2782e1d9a
@ -1,5 +1,7 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client;
|
package cn.iocoder.yudao.framework.file.core.client;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.s3.FilePresignedUrlBO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件客户端
|
* 文件客户端
|
||||||
*
|
*
|
||||||
@ -40,4 +42,14 @@ public interface FileClient {
|
|||||||
*/
|
*/
|
||||||
byte[] getContent(String path) throws Exception;
|
byte[] getContent(String path) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得文件预签名地址
|
||||||
|
*
|
||||||
|
* @param fileName 文件名称
|
||||||
|
* @return 文件预签名地址
|
||||||
|
*/
|
||||||
|
default FilePresignedUrlBO getPresignedObjectUrl(String fileName) throws Exception {
|
||||||
|
throw new UnsupportedOperationException("不支持的操作");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package cn.iocoder.yudao.framework.file.core.client.s3;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件预签名地址 BO
|
||||||
|
*
|
||||||
|
* @author owen
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public class FilePresignedUrlBO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传 URL(用于上传)
|
||||||
|
*/
|
||||||
|
private String uploadUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件 URL(用于读取、下载等)
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
}
|
@ -5,8 +5,10 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.AbstractFileClient;
|
import cn.iocoder.yudao.framework.file.core.client.AbstractFileClient;
|
||||||
import io.minio.*;
|
import io.minio.*;
|
||||||
|
import io.minio.http.Method;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_ALIYUN;
|
import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_ALIYUN;
|
||||||
import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_TENCENT;
|
import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_TENCENT;
|
||||||
@ -117,4 +119,19 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
|||||||
return IoUtil.readBytes(response);
|
return IoUtil.readBytes(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FilePresignedUrlBO getPresignedObjectUrl(String fileName) throws Exception {
|
||||||
|
String uploadUrl = client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
|
||||||
|
.method(Method.PUT)
|
||||||
|
.bucket(config.getBucket())
|
||||||
|
.object(fileName)
|
||||||
|
/**
|
||||||
|
* 过期时间(秒数)取值范围:1秒 ~ 7天
|
||||||
|
* {@link GetPresignedObjectUrlArgs.Builder#validateExpiry(int)}
|
||||||
|
*/
|
||||||
|
.expiry(10, TimeUnit.MINUTES)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
return new FilePresignedUrlBO(uploadUrl, config.getDomain() + "/" + fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,14 +8,17 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
|
||||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.*;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileRespVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileUploadReqVO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
import cn.iocoder.yudao.module.infra.service.file.FileService;
|
import cn.iocoder.yudao.module.infra.service.file.FileService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.annotation.security.PermitAll;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
@ -23,12 +26,6 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import jakarta.annotation.security.PermitAll;
|
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import jakarta.validation.Valid;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
@Tag(name = "管理后台 - 文件存储")
|
@Tag(name = "管理后台 - 文件存储")
|
||||||
@ -50,6 +47,18 @@ public class FileController {
|
|||||||
return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
|
return success(fileService.createFile(file.getOriginalFilename(), path, IoUtil.readBytes(file.getInputStream())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/presigned-url")
|
||||||
|
@Operation(summary = "获取文件预签名地址")
|
||||||
|
public CommonResult<FilePresignedUrlRespVO> getFilePresignedUrl(@RequestParam("fileName") String fileName) throws Exception {
|
||||||
|
return success(fileService.getFilePresignedUrl(fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/create")
|
||||||
|
@Operation(summary = "创建文件")
|
||||||
|
public CommonResult<Long> createFile(@Valid @RequestBody FileCreateReqVO createReqVO) {
|
||||||
|
return success(fileService.createFile(createReqVO));
|
||||||
|
}
|
||||||
|
|
||||||
@DeleteMapping("/delete")
|
@DeleteMapping("/delete")
|
||||||
@Operation(summary = "删除文件")
|
@Operation(summary = "删除文件")
|
||||||
@Parameter(name = "id", description = "编号", required = true)
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.file.vo.file;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 文件创建 Request VO")
|
||||||
|
@Data
|
||||||
|
public class FileCreateReqVO {
|
||||||
|
|
||||||
|
@NotNull(message = "文件配置编号不能为空")
|
||||||
|
@Schema(description = "文件配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11")
|
||||||
|
private Long configId;
|
||||||
|
|
||||||
|
@NotNull(message = "文件路径不能为空")
|
||||||
|
@Schema(description = "文件路径", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao.jpg")
|
||||||
|
private String path;
|
||||||
|
|
||||||
|
@NotNull(message = "原文件名不能为空")
|
||||||
|
@Schema(description = "原文件名", requiredMode = Schema.RequiredMode.REQUIRED, example = "yudao.jpg")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@NotNull(message = "文件 URL不能为空")
|
||||||
|
@Schema(description = "文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/yudao.jpg")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Schema(description = "文件MIME类型", example = "application/octet-stream")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "文件大小", example = "2048", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
private Integer size;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package cn.iocoder.yudao.module.infra.controller.admin.file.vo.file;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Schema(description = "管理后台 - 文件预签名地址 Response VO")
|
||||||
|
@Data
|
||||||
|
public class FilePresignedUrlRespVO {
|
||||||
|
|
||||||
|
@Schema(description = "配置编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11")
|
||||||
|
private Long configId;
|
||||||
|
|
||||||
|
@Schema(description = "文件上传 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/yudao.jpg")
|
||||||
|
private String uploadUrl;
|
||||||
|
|
||||||
|
@Schema(description = "文件 URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/yudao.jpg")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
package cn.iocoder.yudao.module.infra.service.file;
|
package cn.iocoder.yudao.module.infra.service.file;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePresignedUrlRespVO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,6 +31,14 @@ public interface FileService {
|
|||||||
*/
|
*/
|
||||||
String createFile(String name, String path, byte[] content);
|
String createFile(String name, String path, byte[] content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建文件
|
||||||
|
*
|
||||||
|
* @param createReqVO 创建信息
|
||||||
|
* @return 编号
|
||||||
|
*/
|
||||||
|
Long createFile(FileCreateReqVO createReqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除文件
|
* 删除文件
|
||||||
*
|
*
|
||||||
@ -45,4 +55,12 @@ public interface FileService {
|
|||||||
*/
|
*/
|
||||||
byte[] getFileContent(Long configId, String path) throws Exception;
|
byte[] getFileContent(Long configId, String path) throws Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成文件预签名地址信息
|
||||||
|
*
|
||||||
|
* @param fileName 文件名称
|
||||||
|
* @return 预签名地址信息
|
||||||
|
*/
|
||||||
|
FilePresignedUrlRespVO getFilePresignedUrl(String fileName) throws Exception;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,19 @@ import cn.hutool.core.lang.Assert;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClient;
|
import cn.iocoder.yudao.framework.file.core.client.FileClient;
|
||||||
|
import cn.iocoder.yudao.framework.file.core.client.s3.FilePresignedUrlBO;
|
||||||
import cn.iocoder.yudao.framework.file.core.utils.FileTypeUtils;
|
import cn.iocoder.yudao.framework.file.core.utils.FileTypeUtils;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePresignedUrlRespVO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
|
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
|
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
|
||||||
|
|
||||||
@ -66,6 +69,15 @@ public class FileServiceImpl implements FileService {
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long createFile(FileCreateReqVO createReqVO) {
|
||||||
|
// 插入
|
||||||
|
FileDO file = BeanUtils.toBean(createReqVO, FileDO.class);
|
||||||
|
fileMapper.insert(file);
|
||||||
|
// 返回
|
||||||
|
return file.getId();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteFile(Long id) throws Exception {
|
public void deleteFile(Long id) throws Exception {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
@ -95,4 +107,11 @@ public class FileServiceImpl implements FileService {
|
|||||||
return client.getContent(path);
|
return client.getContent(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FilePresignedUrlRespVO getFilePresignedUrl(String fileName) throws Exception {
|
||||||
|
FileClient fileClient = fileConfigService.getMasterFileClient();
|
||||||
|
FilePresignedUrlBO bo = fileClient.getPresignedObjectUrl(fileName);
|
||||||
|
return BeanUtils.toBean(bo, FilePresignedUrlRespVO.class, f -> f.setConfigId(fileClient.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user