From d49bc443ce53196da806ff98bbebf1603ea4a5ce Mon Sep 17 00:00:00 2001 From: JiaoTianBo Date: Fri, 27 Mar 2026 10:39:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(oss):=20=E5=AE=9E=E7=8E=B0=E5=9F=BA?= =?UTF-8?q?=E4=BA=8EMinIO=E7=9A=84OSS=E6=96=87=E4=BB=B6=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增OssServiceImpl类,实现文件上传、读取、删除等接口 - 集成MinIO客户端,确保存储桶存在并支持文件操作 - 实现文件上传后保存附件元数据至数据库 - 支持通过URL获取文件输入流和读取文件内容 - 提供生成文件访问URL的方法 - 新增FileAttachment实体类,映射文件附件表结构 - 创建FileAttachmentMapper接口,支持文件附件数据库操作 --- .../domain/entity/FileAttachment.java | 95 +++++++++++++++++++ .../mapper/FileAttachmentMapper.java | 12 +++ .../service/oss/impl/OssServiceImpl.java | 41 +++++++- 3 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 src/main/java/cn/yinlihupo/domain/entity/FileAttachment.java create mode 100644 src/main/java/cn/yinlihupo/mapper/FileAttachmentMapper.java diff --git a/src/main/java/cn/yinlihupo/domain/entity/FileAttachment.java b/src/main/java/cn/yinlihupo/domain/entity/FileAttachment.java new file mode 100644 index 0000000..68104aa --- /dev/null +++ b/src/main/java/cn/yinlihupo/domain/entity/FileAttachment.java @@ -0,0 +1,95 @@ +package cn.yinlihupo.domain.entity; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 文件附件实体类 + * 对应数据库表: file_attachment + */ +@Data +@TableName("file_attachment") +public class FileAttachment { + + @TableId(type = IdType.ASSIGN_ID) + private Long id; + + /** + * 文件名称 + */ + private String fileName; + + /** + * 原始文件名 + */ + private String originalName; + + /** + * 文件路径 + */ + private String filePath; + + /** + * 文件URL + */ + private String fileUrl; + + /** + * 文件类型(MIME) + */ + private String fileType; + + /** + * 文件大小(字节) + */ + private Long fileSize; + + /** + * 存储类型: local-本地, oss-对象存储, minio-MinIO + */ + private String storageType; + + /** + * 关联类型: project, task, work_order, risk, report + */ + private String relatedType; + + /** + * 关联ID + */ + private Long relatedId; + + /** + * 上传人ID + */ + private Long uploaderId; + + /** + * EXIF信息(照片专用) + */ + private Object exifData; + + /** + * AI分析结果 + */ + private Object aiAnalysis; + + /** + * 扩展数据 + */ + private Object extraData; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createTime; + + /** + * 删除标记 + */ + @TableLogic + private Integer deleted; +} diff --git a/src/main/java/cn/yinlihupo/mapper/FileAttachmentMapper.java b/src/main/java/cn/yinlihupo/mapper/FileAttachmentMapper.java new file mode 100644 index 0000000..bc5b25b --- /dev/null +++ b/src/main/java/cn/yinlihupo/mapper/FileAttachmentMapper.java @@ -0,0 +1,12 @@ +package cn.yinlihupo.mapper; + +import cn.yinlihupo.domain.entity.FileAttachment; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 文件附件Mapper接口 + */ +@Mapper +public interface FileAttachmentMapper extends BaseMapper { +} diff --git a/src/main/java/cn/yinlihupo/service/oss/impl/OssServiceImpl.java b/src/main/java/cn/yinlihupo/service/oss/impl/OssServiceImpl.java index 8c36ef8..4ed363b 100644 --- a/src/main/java/cn/yinlihupo/service/oss/impl/OssServiceImpl.java +++ b/src/main/java/cn/yinlihupo/service/oss/impl/OssServiceImpl.java @@ -2,6 +2,8 @@ package cn.yinlihupo.service.oss.impl; import cn.yinlihupo.common.config.MinioConfig; import cn.yinlihupo.common.util.DocumentParserUtil; +import cn.yinlihupo.domain.entity.FileAttachment; +import cn.yinlihupo.mapper.FileAttachmentMapper; import cn.yinlihupo.service.oss.OssService; import io.minio.*; import io.minio.errors.*; @@ -25,6 +27,7 @@ public class OssServiceImpl implements OssService { private final MinioClient minioClient; private final MinioConfig minioConfig; + private final FileAttachmentMapper fileAttachmentMapper; @Override public String uploadFile(MultipartFile file, String fileName) { @@ -52,14 +55,48 @@ public class OssServiceImpl implements OssService { log.info("文件上传成功: {}/{}", bucketName, objectName); - // 返回文件URL - return getFileUrl(bucketName, objectName); + // 构建文件URL + String fileUrl = getFileUrl(bucketName, objectName); + + // 保存文件附件记录 + saveFileAttachment(file, fileName, bucketName, objectName, fileUrl); + + return fileUrl; } catch (Exception e) { log.error("文件上传失败: {}", e.getMessage(), e); throw new RuntimeException("文件上传失败: " + e.getMessage(), e); } } + /** + * 保存文件附件记录到数据库 + * + * @param file 上传的文件 + * @param fileName 原始文件名 + * @param bucketName 存储桶名称 + * @param objectName 对象名称 + * @param fileUrl 文件URL + */ + private void saveFileAttachment(MultipartFile file, String fileName, String bucketName, + String objectName, String fileUrl) { + try { + FileAttachment attachment = new FileAttachment(); + attachment.setFileName(objectName); + attachment.setOriginalName(fileName); + attachment.setFilePath(bucketName + "/" + objectName); + attachment.setFileUrl(fileUrl); + attachment.setFileType(file.getContentType()); + attachment.setFileSize(file.getSize()); + attachment.setStorageType("minio"); + + fileAttachmentMapper.insert(attachment); + log.info("文件附件记录保存成功, fileName: {}", fileName); + } catch (Exception e) { + log.error("保存文件附件记录失败: {}", e.getMessage(), e); + // 不影响主流程,仅记录日志 + } + } + @Override public String readFileAsString(String fileUrl) { try (InputStream inputStream = getFileInputStream(fileUrl)) {