附件新增携带附件实体返回的接口支持

This commit is contained in:
chenbowen
2025-07-07 18:14:26 +08:00
parent 5e15ab5fae
commit 92959efdc6
3 changed files with 41 additions and 6 deletions

View File

@@ -26,6 +26,8 @@ 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 java.io.IOException;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment; import static cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment;
@@ -48,6 +50,15 @@ public class FileController {
uploadReqVO.getDirectory(), file.getContentType())); uploadReqVO.getDirectory(), file.getContentType()));
} }
@PostMapping("/upload-with-return")
@Operation(summary = "上传文件携带返回实体", description = "上传文件携带返回实体")
public CommonResult<FileRespVO> uploadWithReturn(FileUploadReqVO uploadReqVO) throws IOException {
MultipartFile file = uploadReqVO.getFile();
byte[] content = IoUtil.readBytes(file.getInputStream());
return success(fileService.createFileWhitReturn(content, file.getOriginalFilename(),
uploadReqVO.getDirectory(), file.getContentType()));
}
@GetMapping("/presigned-url") @GetMapping("/presigned-url")
@Operation(summary = "获取文件预签名地址", description = "模式二:前端上传文件:用于前端直接上传七牛、阿里云 OSS 等文件存储器") @Operation(summary = "获取文件预签名地址", description = "模式二:前端上传文件:用于前端直接上传七牛、阿里云 OSS 等文件存储器")
@Parameters({ @Parameters({

View File

@@ -4,8 +4,10 @@ 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.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.controller.admin.file.vo.file.FilePresignedUrlRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileRespVO;
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO; import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import lombok.SneakyThrows;
/** /**
* 文件 Service 接口 * 文件 Service 接口
@@ -34,6 +36,9 @@ public interface FileService {
String createFile(@NotEmpty(message = "文件内容不能为空") byte[] content, String createFile(@NotEmpty(message = "文件内容不能为空") byte[] content,
String name, String directory, String type); String name, String directory, String type);
@SneakyThrows
FileRespVO createFileWhitReturn(byte[] content, String name, String directory, String type);
/** /**
* 生成文件预签名地址信息 * 生成文件预签名地址信息
* *

View File

@@ -10,6 +10,7 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileCreateReqVO; 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.controller.admin.file.vo.file.FilePresignedUrlRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileRespVO;
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 cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient; import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
@@ -34,13 +35,11 @@ public class FileServiceImpl implements FileService {
/** /**
* 上传文件的前缀是否包含日期yyyyMMdd * 上传文件的前缀是否包含日期yyyyMMdd
*
* 目的:按照日期,进行分目录 * 目的:按照日期,进行分目录
*/ */
static boolean PATH_PREFIX_DATE_ENABLE = true; static boolean PATH_PREFIX_DATE_ENABLE = true;
/** /**
* 上传文件的后缀,是否包含时间戳 * 上传文件的后缀,是否包含时间戳
*
* 目的:保证文件的唯一性,避免覆盖 * 目的:保证文件的唯一性,避免覆盖
* 定制:可按需调整成 UUID、或者其他方式 * 定制:可按需调整成 UUID、或者其他方式
*/ */
@@ -60,6 +59,25 @@ public class FileServiceImpl implements FileService {
@Override @Override
@SneakyThrows @SneakyThrows
public String createFile(byte[] content, String name, String directory, String type) { public String createFile(byte[] content, String name, String directory, String type) {
FileDO entity = uploadFile(content, name, directory, type);
return entity.getUrl();
}
@SneakyThrows
@Override
public FileRespVO createFileWhitReturn(byte[] content, String name, String directory, String type) {
FileDO entity = uploadFile(content, name, directory, type);
return new FileRespVO()
.setId(entity.getId())
.setName(entity.getName())
.setPath(entity.getPath())
.setUrl(entity.getUrl())
.setType(entity.getType())
.setSize(entity.getSize())
.setConfigId(entity.getConfigId());
}
private FileDO uploadFile(byte[] content, String name, String directory, String type) throws Exception {
// 1.1 处理 type 为空的情况 // 1.1 处理 type 为空的情况
if (StrUtil.isEmpty(type)) { if (StrUtil.isEmpty(type)) {
type = FileTypeUtils.getMineType(content, name); type = FileTypeUtils.getMineType(content, name);
@@ -82,12 +100,13 @@ public class FileServiceImpl implements FileService {
FileClient client = fileConfigService.getMasterFileClient(); FileClient client = fileConfigService.getMasterFileClient();
Assert.notNull(client, "客户端(master) 不能为空"); Assert.notNull(client, "客户端(master) 不能为空");
String url = client.upload(content, path, type); String url = client.upload(content, path, type);
FileDO entity = new FileDO().setConfigId(client.getId())
.setName(name).setPath(path).setUrl(url)
.setType(type).setSize(content.length);
// 3. 保存到数据库 // 3. 保存到数据库
fileMapper.insert(new FileDO().setConfigId(client.getId()) fileMapper.insert(entity);
.setName(name).setPath(path).setUrl(url) return entity;
.setType(type).setSize(content.length));
return url;
} }
@VisibleForTesting @VisibleForTesting