# 文件管理模型 **本文档引用的文件** - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java) - [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java) - [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java) - [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [IFileInfoService.java](file://crm-file/src/main/java/com/crm/file/service/IFileInfoService.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件围绕“文件管理数据模型”展开,聚焦于 FileInfo 实体、分片上传状态管理、下载与上传相关 DTO 的数据结构设计,以及文件类型识别、存储路径规则、访问权限控制等关键能力。同时覆盖文件生命周期管理、断点续传状态、临时文件清理、索引设计与查询优化、存储空间统计等,为文件服务开发提供完整的数据模型参考。 ## 项目结构 文件模块位于 crm-file 子模块中,采用分层组织: - api: 对外接口定义 - config: 配置(MinIO、调度任务、文件属性) - constant: 常量(文件类型、状态码等) - controller: HTTP 控制器 - domain: 领域模型(entity 实体、dto 数据传输对象) - mapper: 数据访问层 - service: 业务逻辑实现 - task: 定时任务(如孤儿分片清理) ```mermaid graph TB subgraph "crm-file" API["api/FileApi"] --> CTRL["controller/FileController"] CTRL --> SVC_IMPL["service/impl/FileApiImpl"] SVC_IMPL --> FILE_SVC["service/IFileInfoService"] FILE_SVC --> FILE_SVC_IMPL["service/impl/FileInfoServiceImpl"] FILE_SVC_IMPL --> MAPPER["mapper/FileInfoMapper"] FILE_SVC_IMPL --> ENTITY["domain/entity/FileInfo"] FILE_SVC_IMPL --> DTO["domain/dto/*"] CTRL --> DTO CONFIG["config/*"] --> SVC_IMPL TASK["task/OrphanChunkCleanupTask"] --> MAPPER CONST["constant/FileConstants"] --> SVC_IMPL end ``` 图表来源 - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java) - [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java) - [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java) - [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) 章节来源 - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java) - [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java) - [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java) - [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) ## 核心组件 - 实体与 DTO - FileInfo:文件元数据持久化模型,包含文件标识、名称、大小、类型、存储位置、哈希校验、版本、状态、创建/更新时间等字段。 - FileDownloadDTO:下载请求参数,通常包含文件标识、访问令牌或签名信息、可选的断点续传偏移量等。 - FileInfoDTO:面向前端的文件信息展示对象,脱敏后返回必要字段(如名称、大小、类型、预览链接等)。 - MultipartInitDTO:分片初始化请求体,包含文件名、大小、分片大小、期望 MD5/SHA 等校验值、业务上下文等。 - UploadSession:分片上传会话状态,记录会话 ID、已上传分片集合、当前进度、过期时间、归属用户等。 - 服务与数据访问 - IFileInfoService:文件信息服务接口,定义上传、分片、合并、下载、删除、查询等方法。 - FileInfoServiceImpl:服务实现,协调 MinIO、文件系统、缓存与会话管理,处理文件类型识别、路径生成、权限校验、生命周期管理。 - FileInfoMapper:MyBatis Mapper,负责 FileInfo 实体的 CRUD 与条件查询。 - 配置与常量 - FileProperties:文件存储根路径、分片大小、允许的文件类型、访问域名等配置项。 - MinioConfig:MinIO 客户端连接、桶名、访问密钥等配置。 - SchedulingConfig:定时任务开关与执行周期。 - FileConstants:文件类型枚举、状态码、错误码等常量。 - 任务 - OrphanChunkCleanupTask:定时扫描并清理超时的分片会话与临时分片文件,释放空间。 章节来源 - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java) - [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java) - [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java) - [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java) - [IFileInfoService.java](file://crm-file/src/main/java/com/crm/file/service/IFileInfoService.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) ## 架构总览 文件服务以“控制器 -> 服务 -> 数据访问/外部存储”的分层架构为主,结合配置与常量驱动行为,通过定时任务保障资源健康。 ```mermaid sequenceDiagram participant Client as "客户端" participant Controller as "文件控制器" participant Service as "文件服务(实现)" participant Mapper as "文件Mapper" participant MinIO as "MinIO存储" participant Task as "清理任务" Client->>Controller : "发起分片初始化/上传/下载" Controller->>Service : "调用业务方法" Service->>Service : "类型识别/路径生成/权限校验" Service->>MinIO : "读写分片/合并文件" Service->>Mapper : "持久化FileInfo/更新状态" Mapper-->>Service : "返回结果" Service-->>Controller : "返回DTO/状态" Controller-->>Client : "响应结果" Note over Task,MinIO : "定时任务清理超时分片与临时文件" ``` 图表来源 - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) ## 详细组件分析 ### 实体与 DTO 设计 - FileInfo(文件元数据实体) - 关键字段:唯一标识、原始文件名、扩展名、文件大小、MIME 类型、存储桶与对象键、MD5/SHA 校验值、版本、状态(待上传/上传中/已完成/失败)、创建人/修改人、创建/更新时间、备注等。 - 用途:作为文件全生命周期的主记录,支撑查询、统计、审计。 - FileDownloadDTO(下载请求 DTO) - 关键字段:文件标识、访问令牌或签名、断点续传偏移量、目标格式(如预览转换)等。 - 用途:承载下载入口的参数,支持安全访问与断点续传。 - FileInfoDTO(文件信息 DTO) - 关键字段:文件标识、名称、大小、类型、预览/下载地址、创建时间、状态等。 - 用途:面向前端展示,避免泄露敏感字段。 - MultipartInitDTO(分片初始化 DTO) - 关键字段:文件名、总大小、分片大小、期望校验值、业务上下文、租户/部门标识等。 - 用途:启动分片上传流程,生成会话 ID 并分配初始状态。 - UploadSession(分片会话状态) - 关键字段:会话 ID、已上传分片集合(有序)、当前进度、过期时间、归属用户、业务关联 ID 等。 - 用途:维护分片上传的中间态,支持断点续传与并发合并。 ```mermaid classDiagram class FileInfo { +id +originalName +extension +size +mimeType +bucket +objectKey +md5 +sha256 +version +status +creator +modifier +createdAt +updatedAt +remark } class FileDownloadDTO { +fileId +token +offset +format } class FileInfoDTO { +id +name +size +mimeType +downloadUrl +previewUrl +createdAt +status } class MultipartInitDTO { +fileName +totalSize +chunkSize +expectedHash +bizContext +tenantId } class UploadSession { +sessionId +uploadedChunks +progress +expiresAt +ownerId +bizId } FileInfo <.. FileInfoDTO : "映射" MultipartInitDTO --> UploadSession : "创建会话" FileDownloadDTO --> FileInfo : "按ID解析" ``` 图表来源 - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java) - [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java) - [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java) - [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java) 章节来源 - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java) - [FileInfoDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileInfoDTO.java) - [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java) - [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java) ### 文件类型识别与存储路径规则 - 类型识别 - 基于扩展名与 MIME 类型双重校验,必要时读取文件头进行内容类型推断,防止伪造后缀绕过限制。 - 白名单机制:仅允许配置中的扩展名与 MIME 类型通过。 - 存储路径规则 - 根路径由 FileProperties 指定;对象键采用“日期/租户/部门/业务域/文件名”多级目录结构,便于分区管理与配额统计。 - 文件名去重策略:使用 UUID 或哈希命名,保留原始名称在元数据中。 - 访问权限控制 - 下载需携带有效令牌或签名,服务端校验令牌有效期与权限范围。 - 支持租户隔离与数据可见性上下文,确保跨租户不可见。 章节来源 - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) ### 分片上传与断点续传状态管理 - 分片初始化 - 接收 MultipartInitDTO,生成会话 ID,计算分片数量,初始化 UploadSession 并持久化基础 FileInfo。 - 分片上传 - 客户端按序或乱序上传分片,服务端校验分片序号与完整性,写入临时分片文件,更新会话进度。 - 合并与完成 - 所有分片上传完成后触发合并,校验整体哈希,生成最终对象键,更新 FileInfo 状态为已完成。 - 断点续传 - 支持从上次中断处继续上传,服务端根据 UploadSession 的已上传分片集合跳过重复分片。 ```mermaid flowchart TD Start(["开始"]) --> Init["初始化分片会话
生成会话ID/分片数"] Init --> UploadLoop{"是否还有未上传分片?"} UploadLoop --> |是| UploadChunk["上传分片
校验序号/完整性"] UploadChunk --> UpdateSession["更新会话进度"] UpdateLoop["检查是否全部完成"] --> UploadLoop UploadLoop --> |否| Merge["合并分片
校验整体哈希"] Merge --> Persist["持久化FileInfo
更新状态为已完成"] Persist --> End(["结束"]) ``` 图表来源 - [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java) - [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) 章节来源 - [MultipartInitDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/MultipartInitDTO.java) - [UploadSession.java](file://crm-file/src/main/java/com/crm/file/domain/dto/UploadSession.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) ### 文件生命周期管理 - 阶段划分 - 待上传:创建 FileInfo 记录,等待分片初始化。 - 上传中:分片上传进行中,会话活跃。 - 已完成:合并成功,对象可访问。 - 失败:校验失败或异常回滚,标记失败原因。 - 状态流转 - 通过服务层统一状态机管理,保证幂等性与一致性。 - 审计与追踪 - 记录创建人、修改人、操作时间与备注,便于问题定位与合规审计。 章节来源 - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) ### 临时文件清理与存储空间统计 - 临时文件清理 - 定时任务扫描超时的 UploadSession,删除对应临时分片文件,释放存储空间。 - 清理策略包括最大存活时间、空闲阈值、磁盘水位告警。 - 存储空间统计 - 基于 FileInfo 的 size 字段聚合统计,支持按租户/部门/业务域维度汇总。 - 定期刷新缓存,减少数据库压力。 章节来源 - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) ### 文件索引设计与查询优化 - 索引建议 - 主键 id:快速定位文件记录。 - 唯一键 objectKey:避免重复上传与冲突。 - 复合索引 (tenant_id, biz_id, status):常用过滤场景加速。 - 索引 (created_at):按时间范围查询与归档。 - 查询优化 - 分页查询使用覆盖索引,避免回表。 - 大对象键查询优先使用对象键前缀匹配,减少全表扫描。 - 热点文件引入缓存层(如 Redis),降低读放大。 章节来源 - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [FileInfo.java](file://crm-file/src/main/java/com/crm/file/domain/entity/FileInfo.java) ### 下载流程与访问控制 - 下载流程 - 客户端提交 FileDownloadDTO,服务端校验令牌与权限,生成临时访问链接或直接流式返回。 - 支持断点续传:根据 offset 定位字节范围,返回部分响应。 - 访问控制 - 令牌校验:有效期、作用域、防重放。 - 数据可见性:基于登录用户与数据范围拦截器,确保跨租户不可见。 章节来源 - [FileDownloadDTO.java](file://crm-file/src/main/java/com/crm/file/domain/dto/FileDownloadDTO.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) ## 依赖关系分析 - 内部依赖 - 控制器依赖服务接口,服务实现依赖 Mapper 与配置/常量。 - 定时任务依赖 Mapper 与存储配置。 - 外部依赖 - MinIO 用于对象存储,提供分片上传与合并能力。 - 缓存(可选)用于会话与热点数据。 - 耦合与内聚 - 服务层集中处理类型识别、路径生成、权限校验,保持高内聚。 - Mapper 专注数据访问,降低业务复杂度。 ```mermaid graph LR Controller["控制器"] --> Service["文件服务实现"] Service --> Mapper["文件Mapper"] Service --> Config["配置(FileProperties/MinioConfig)"] Service --> Constants["常量(FileConstants)"] Task["清理任务"] --> Mapper Task --> Config ``` 图表来源 - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) 章节来源 - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) - [FileProperties.java](file://crm-file/src/main/java/com/crm/file/config/FileProperties.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java) - [FileConstants.java](file://crm-file/src/main/java/com/crm/file/constant/FileConstants.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) ## 性能考虑 - 分片大小调优:根据网络与服务器内存调整分片大小,平衡并发与内存占用。 - 合并策略:批量合并与异步合并,避免阻塞主流程。 - 索引与查询:合理索引与分页策略,减少慢查询。 - 缓存:对热点文件信息与下载链接进行缓存,降低后端压力。 - 存储:MinIO 多副本与压缩策略,提升吞吐与可靠性。 [本节为通用指导,不直接分析具体文件] ## 故障排查指南 - 常见问题 - 分片上传失败:检查分片序号、完整性校验、会话是否过期。 - 合并失败:核对整体哈希、分片顺序、对象键冲突。 - 下载失败:令牌无效、权限不足、对象不存在。 - 临时文件堆积:清理任务未运行或阈值设置不当。 - 排查步骤 - 查看 FileInfo 状态与日志,定位失败阶段。 - 检查 UploadSession 是否存在且未过期。 - 验证 MinIO 对象是否存在及权限。 - 确认定时任务执行状态与磁盘水位。 章节来源 - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [FileInfoMapper.java](file://crm-file/src/main/java/com/crm/file/mapper/FileInfoMapper.java) ## 结论 本文件管理数据模型以 FileInfo 为核心,配合多种 DTO 与 UploadSession 实现完整的分片上传、断点续传与下载能力。通过配置与常量驱动类型识别与路径规则,结合权限控制与定时清理任务,形成健壮的文件生命周期管理体系。合理的索引设计与查询优化保障了系统在高并发下的稳定性与可扩展性。 [本节为总结性内容,不直接分析具体文件] ## 附录 - 术语说明 - 分片:将大文件拆分为多个小块独立上传,提高可靠性与速度。 - 对象键:MinIO 中对象的唯一路径标识。 - 令牌:用于鉴权与访问控制的短期凭证。 - 最佳实践 - 始终校验文件类型与大小,防止恶意上传。 - 使用唯一对象键避免冲突。 - 定期清理临时文件,监控存储空间。 - 对热点数据进行缓存与限流保护。 [本节为补充说明,不直接分析具体文件]