# 文件管理系统
**本文引用的文件**
- [FmsApiApplication.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/FmsApiApplication.java)
- [FileController.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/FileController.java)
- [application.yaml](file://fms-api/src/main/resources/application.yaml)
- [README.md](file://fms-api/config/dbconfigs/README.md)
- [FmsFile.vue](file://fms-vue/src/components/fms-file/FmsFile.vue)
- [FileListPanel.vue](file://fms-vue/src/components/fms-file/FileListPanel.vue)
- [FilePreviewPanel.vue](file://fms-vue/src/components/fms-file/FilePreviewPanel.vue)
- [fileService.js](file://fms-vue/src/services/fileService.js)
- [fileVisual.js](file://fms-vue/src/components/fms-file/fileVisual.js)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录:API 与前端使用指南](#附录api-与前端使用指南)
## 简介
本文件管理系统提供前后端一体化的文件管理能力,涵盖文件上传、下载、预览、分类管理、批量操作与进度反馈等。系统支持本地存储与云存储(阿里云 OSS)两种模式,通过统一接口与配置进行切换;前端提供拖拽上传、粘贴上传、多选删除、分页浏览、网格/列表视图切换以及图片在线预览等交互体验。后端提供统一的文件访问与安全控制能力,并持久化文件元数据到数据库。
## 项目结构
仓库采用多模块组织:
- fms-api:Spring Boot 后端服务,提供文件上传、凭证获取、记录保存、删除与静态资源访问等 API。
- fms-vue:Vue 前端应用,包含文件管理组件、服务层与页面演示。
```mermaid
graph TB
subgraph "前端(fms-vue)"
FF["FmsFile.vue"]
FL["FileListPanel.vue"]
FP["FilePreviewPanel.vue"]
FS["fileService.js"]
FV["fileVisual.js"]
end
subgraph "后端(fms-api)"
Cfg["application.yaml"]
FC["FileController.java"]
App["FmsApiApplication.java"]
end
FF --> FL
FF --> FP
FL --> FS
FP --> FS
FS --> FC
FC --> Cfg
App --> FC
```
**图表来源**
- [FmsFile.vue:1-262](file://fms-vue/src/components/fms-file/FmsFile.vue#L1-L262)
- [FileListPanel.vue:1-800](file://fms-vue/src/components/fms-file/FileListPanel.vue#L1-L800)
- [FilePreviewPanel.vue:1-247](file://fms-vue/src/components/fms-file/FilePreviewPanel.vue#L1-L247)
- [fileService.js:1-149](file://fms-vue/src/services/fileService.js#L1-L149)
- [FileController.java:1-113](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/FileController.java#L1-L113)
- [application.yaml:1-34](file://fms-api/src/main/resources/application.yaml#L1-L34)
- [FmsApiApplication.java:1-22](file://fms-api/src/main/java/cn/g3soft/fmsapi/FmsApiApplication.java#L1-L22)
**章节来源**
- [FmsApiApplication.java:1-22](file://fms-api/src/main/java/cn/g3soft/fmsapi/FmsApiApplication.java#L1-L22)
- [application.yaml:1-34](file://fms-api/src/main/resources/application.yaml#L1-L34)
## 核心组件
- 前端组合式组件 FmsFile:负责模块解析、分类树加载、三栏布局(分类/列表/预览)与事件透传。
- 文件列表 FileListPanel:实现分页查询、拖拽/粘贴上传、批量选择、删除、下载、网格/列表视图切换。
- 预览面板 FilePreviewPanel:根据扩展名判断是否为图片,直接渲染图片预览或显示通用信息卡片。
- 文件服务 fileService.js:封装上传策略(本地/OSS)、凭证缓存、预览/下载地址获取与删除接口调用。
- 视觉工具 fileVisual.js:扩展名颜色映射、图片类型判断、文件大小格式化。
- 后端控制器 FileController:暴露 /file/* 接口,处理本地上传、OSS 凭证、记录保存、删除与静态文件访问。
- 配置 application.yaml:定义存储类型、本地存储路径、URL 前缀与 OSS 地址等。
**章节来源**
- [FmsFile.vue:1-262](file://fms-vue/src/components/fms-file/FmsFile.vue#L1-L262)
- [FileListPanel.vue:1-800](file://fms-vue/src/components/fms-file/FileListPanel.vue#L1-L800)
- [FilePreviewPanel.vue:1-247](file://fms-vue/src/components/fms-file/FilePreviewPanel.vue#L1-L247)
- [fileService.js:1-149](file://fms-vue/src/services/fileService.js#L1-L149)
- [fileVisual.js:1-63](file://fms-vue/src/components/fms-file/fileVisual.js#L1-L63)
- [FileController.java:1-113](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/FileController.java#L1-L113)
- [application.yaml:1-34](file://fms-api/src/main/resources/application.yaml#L1-L34)
## 架构总览
系统采用“前端组件 + 服务层 + 后端控制器”的分层架构。前端通过 fileService 抽象上传策略,根据后端返回的 storageType 自动选择本地直传或 OSS 直传;后端通过 FileController 暴露统一接口,并根据配置决定存储行为。
```mermaid
sequenceDiagram
participant UI as "前端界面"
participant Svc as "fileService.js"
participant Ctrl as "FileController.java"
participant Store as "存储(本地/OSS)"
participant DB as "数据库"
UI->>Svc : 初始化配置 initFileConfig()
Svc->>Ctrl : POST /api/file/config
Ctrl-->>Svc : {storageType}
UI->>Svc : upload({files, father, moduleId, cateId})
alt storageType == "local"
Svc->>Ctrl : POST /api/file/upload (FormData)
Ctrl->>DB : 写入文件记录
Ctrl-->>Svc : 文件记录列表
else storageType == "aliyun-oss"
Svc->>Ctrl : POST /api/file/upload-credential
Ctrl-->>Svc : {accessid,policy,signature,dir,host,...}
loop 逐个文件
Svc->>Store : XHR 直传 OSS
Svc->>Ctrl : POST /api/file/save-record (记录)
Ctrl->>DB : 写入文件记录
end
end
UI->>Svc : getPreviewUrl(fileRow)
Svc-->>UI : 预览/下载地址
```
**图表来源**
- [fileService.js:8-85](file://fms-vue/src/services/fileService.js#L8-L85)
- [FileController.java:38-87](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/FileController.java#L38-L87)
- [application.yaml:27-34](file://fms-api/src/main/resources/application.yaml#L27-L34)
## 详细组件分析
### FmsFile 组件(三栏布局与流程编排)
- 功能要点
- 解析模块代码为模块 ID,用于后续文件查询与上传上下文。
- 加载分类树并维护选中分类,驱动中间列表过滤。
- 三栏 Splitter 布局:左侧分类、中间列表、右侧预览。
- 事件透传:uploaded、deleted、selected。
- 关键流程
- 挂载时解析模块与分类,支持初始分类定位。
- 列表选择文件后,右侧预览面板展示。
- 预览导航:上一个/下一个。
```mermaid
flowchart TD
Start(["组件挂载"]) --> Resolve["解析模块ID"]
Resolve --> LoadCate["加载分类树"]
LoadCate --> Ready{"是否就绪?"}
Ready --> |是| ShowLayout["渲染三栏布局"]
Ready --> |否| Wait["等待解析完成"]
ShowLayout --> SelectCate["选择分类"]
SelectCate --> List["加载文件列表"]
List --> Preview["选择文件预览"]
Preview --> Nav["上/下一个预览"]
```
**图表来源**
- [FmsFile.vue:22-133](file://fms-vue/src/components/fms-file/FmsFile.vue#L22-L133)
- [FmsFile.vue:136-194](file://fms-vue/src/components/fms-file/FmsFile.vue#L136-L194)
**章节来源**
- [FmsFile.vue:1-262](file://fms-vue/src/components/fms-file/FmsFile.vue#L1-L262)
### FileListPanel(列表、上传、批量操作)
- 功能要点
- 分页查询 bf_files 视图,支持按 father/moduleId/cateId 过滤。
- 拖拽/粘贴上传,待上传队列与已上传列表合并展示。
- 全选/单选、批量删除、批量下载。
- 网格/列表视图切换,空态提示。
- 关键流程
- 构建查询条件并分页拉取数据。
- 上传触发:本地一次性 FormData 上传;OSS 先获取凭证再逐个直传并回调保存记录。
- 删除:待上传文件从队列移除;已上传文件调用删除接口。
- 下载:通过 getPreviewUrl 生成链接并触发浏览器下载。
```mermaid
sequenceDiagram
participant U as "用户"
participant L as "FileListPanel.vue"
participant S as "fileService.js"
participant C as "FileController.java"
U->>L : 拖拽/选择文件
L->>L : 加入待上传队列
U->>L : 点击上传
L->>S : upload({files, father, moduleId, cateId})
alt 本地模式
S->>C : POST /api/file/upload
C-->>S : 成功(文件记录)
else OSS 模式
S->>C : POST /api/file/upload-credential
C-->>S : 凭证
loop 每个文件
S->>S : XHR 直传 OSS
S->>C : POST /api/file/save-record
end
end
L->>L : 刷新列表
```
**图表来源**
- [FileListPanel.vue:155-258](file://fms-vue/src/components/fms-file/FileListPanel.vue#L155-L258)
- [fileService.js:20-85](file://fms-vue/src/services/fileService.js#L20-L85)
- [FileController.java:48-76](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/FileController.java#L48-L76)
**章节来源**
- [FileListPanel.vue:1-800](file://fms-vue/src/components/fms-file/FileListPanel.vue#L1-L800)
- [fileService.js:1-149](file://fms-vue/src/services/fileService.js#L1-L149)
### FilePreviewPanel(预览与导航)
- 功能要点
- 基于扩展名判断是否为图片,图片直接以
渲染。
- 非图片显示通用信息卡片(文件名、大小、扩展名)。
- 支持上一个/下一个导航,显示当前索引与总数。
- 关键点
- 预览 URL 由 fileService.getPreviewUrl 提供,统一来源便于后续替换。
```mermaid
flowchart TD
PStart["选择文件"] --> CheckImg{"是否图片?"}
CheckImg --> |是| RenderImg["渲染图片"]
CheckImg --> |否| RenderCard["渲染通用信息卡片"]
RenderImg --> Nav{"上/下一个"}
RenderCard --> Nav
Nav --> Next["更新预览文件"]
Next --> PEnd["结束"]
```
**图表来源**
- [FilePreviewPanel.vue:15-39](file://fms-vue/src/components/fms-file/FilePreviewPanel.vue#L15-L39)
- [FilePreviewPanel.vue:72-94](file://fms-vue/src/components/fms-file/FilePreviewPanel.vue#L72-L94)
**章节来源**
- [FilePreviewPanel.vue:1-247](file://fms-vue/src/components/fms-file/FilePreviewPanel.vue#L1-L247)
### fileService.js(上传策略与凭证缓存)
- 功能要点
- 初始化存储模式:调用 /file/config 获取 storageType。
- 上传策略:本地一次请求打包所有文件;OSS 获取凭证后逐个直传并回调保存记录。
- 凭证缓存:避免频繁请求,支持过期时间缓冲。
- 预览/下载:统一通过 getPreviewUrl 获取地址。
- 删除:调用 /file/delete。
- 复杂度与优化
- 批量上传在本地模式下 O(n) 构造 FormData;OSS 模式为 O(n) 次网络请求。
- 凭证缓存减少鉴权开销,提升批量上传吞吐。
```mermaid
flowchart TD
Init["initFileConfig()"] --> Mode{"storageType?"}
Mode --> |local| Local["uploadToLocal()"]
Mode --> |aliyun-oss| Oss["uploadToOss()"]
Local --> Done["返回文件记录"]
Oss --> Cred["getOssCredential()"]
Cred --> Loop{"遍历文件"}
Loop --> XHR["XHR 直传 OSS"]
XHR --> Save["save-record"]
Save --> Loop
Loop --> Done
```
**图表来源**
- [fileService.js:8-32](file://fms-vue/src/services/fileService.js#L8-L32)
- [fileService.js:34-85](file://fms-vue/src/services/fileService.js#L34-L85)
- [fileService.js:87-108](file://fms-vue/src/services/fileService.js#L87-L108)
**章节来源**
- [fileService.js:1-149](file://fms-vue/src/services/fileService.js#L1-L149)
### fileVisual.js(视觉与格式化工具)
- 功能要点
- 扩展名到颜色的映射,便于快速识别文档类型。
- 图片类型判断,用于前端预览分支。
- 文件大小格式化,提升可读性。
**章节来源**
- [fileVisual.js:1-63](file://fms-vue/src/components/fms-file/fileVisual.js#L1-L63)
### 后端 FileController(接口与安全)
- 接口清单
- POST /api/file/config:返回存储模式配置。
- POST /api/file/upload:本地多文件上传,写入数据库记录。
- POST /api/file/upload-credential:获取 OSS 上传凭证。
- POST /api/file/save-record:OSS 直传后保存文件记录。
- POST /api/file/delete:删除文件(含物理删除与记录清理)。
- GET /api/file/static/{fileName:.+}:本地文件访问,带路径穿越防护。
- 安全机制
- 路径规范化与白名单校验,防止目录穿越。
- 统一响应体 ApiResponse 包装错误与成功结果。
- 内容类型与附件头设置,确保浏览器正确下载/预览。
```mermaid
classDiagram
class FileController {
+config() ApiResponse