16 KiB
16 KiB
文件预览功能
**本文引用的文件** - [FilePreviewPanel.vue](file://fms-vue/src/components/fms-file/FilePreviewPanel.vue) - [fileVisual.js](file://fms-vue/src/components/fms-file/fileVisual.js) - [FmsFile.vue](file://fms-vue/src/components/fms-file/FmsFile.vue) - [FileListPanel.vue](file://fms-vue/src/components/fms-file/FileListPanel.vue) - [FileCard.vue](file://fms-vue/src/components/fms-file/FileCard.vue) - [fileService.js](file://fms-vue/src/services/fileService.js) - [useFileCategory.js](file://fms-vue/src/components/fms-file/composables/useFileCategory.js)目录
简介
本文件聚焦 FMS 前端“文件预览”能力,围绕 FilePreviewPanel 组件及其协作模块,说明多格式文件的在线预览实现现状、数据流、渲染策略与可扩展点。当前仓库实现了图片类文件的内联预览;其他类型(PDF、Office、文本等)以元信息占位展示,并支持下载。文档同时给出后续扩展建议(如 PDF/Office 的 iframe 或第三方库集成)、性能优化策略(大文件分块、内存管理、缓存)与安全注意事项(XSS 防护、大小限制)。
项目结构
文件预览相关代码集中在 fms-vue 的 fms-file 组件目录下,采用“列表-卡片-预览”三栏布局,通过 Splitter 分割区域,事件与状态在父组件 FmsFile 中协调。
graph TB
A["FmsFile.vue<br/>三栏布局与状态协调"] --> B["FileListPanel.vue<br/>文件列表/上传/分页"]
A --> C["FilePreviewPanel.vue<br/>预览面板"]
B --> D["FileCard.vue<br/>单文件卡片"]
B --> E["fileService.js<br/>上传/下载/预览URL"]
C --> E
C --> F["fileVisual.js<br/>扩展名配色/图片判断/大小格式化"]
B --> F
D --> F
A --> G["useFileCategory.js<br/>分类树数据"]
图表来源
- FmsFile.vue:136-193
- FileListPanel.vue:393-635
- FilePreviewPanel.vue:41-95
- FileCard.vue:60-107
- fileService.js:135-143
- fileVisual.js:40-62
- useFileCategory.js:16-54
章节来源
- FmsFile.vue:1-134
- FileListPanel.vue:1-133
- FilePreviewPanel.vue:1-95
- fileService.js:1-149
- fileVisual.js:1-63
- useFileCategory.js:1-77
核心组件
- FilePreviewPanel.vue:预览面板,负责根据文件类型选择渲染方式(当前仅图片直接显示),并提供上下翻页导航与文件名、大小、扩展名等信息展示。
- fileVisual.js:集中提供扩展名解析、语义配色、图片类型判断、文件大小格式化等工具函数,被多个文件组件复用。
- FmsFile.vue:三栏布局容器,协调分类、列表与预览的状态流转,处理选中文件与前后切换。
- FileListPanel.vue:文件列表与上传逻辑,维护待上传队列、分页、拖拽/粘贴上传、批量操作等。
- FileCard.vue:单文件卡片,展示缩略图/类型标识、操作按钮(预览/下载/删除)。
- fileService.js:文件服务,封装上传(本地/OSS)、凭证缓存、删除、获取预览/下载地址等。
章节来源
- FilePreviewPanel.vue:1-95
- fileVisual.js:1-63
- FmsFile.vue:1-134
- FileListPanel.vue:1-133
- FileCard.vue:1-58
- fileService.js:1-149
架构总览
预览流程从用户点击文件开始,经列表组件触发预览事件,由父组件更新选中文件并传递给预览面板,预览面板计算预览 URL 并渲染内容。
sequenceDiagram
participant U as "用户"
participant L as "FileListPanel.vue"
participant P as "FmsFile.vue"
participant V as "FilePreviewPanel.vue"
participant S as "fileService.js"
U->>L : 点击文件卡片/行
L-->>P : emit("preview", file)
P->>P : 更新 selectedFile
P-->>V : 传递 file + fileList
V->>V : computed(previewUrl = getPreviewUrl(file))
V->>S : getPreviewUrl(fileRow)
S-->>V : 返回 mx_mapfilename
V-->>U : 渲染图片/通用占位
图表来源
详细组件分析
FilePreviewPanel.vue 分析
- 功能要点
- 计算当前索引与总数,支持上一个/下一个导航。
- 基于扩展名判断是否为图片类型,若是则使用 img 标签直接加载预览 URL。
- 非图片类型显示通用占位:扩展名色块、文件名、大小、扩展名等元信息。
- 空态提示“选择文件查看预览”。
- 关键逻辑路径
- 预览 URL:通过 fileService.getPreviewUrl 获取文件存储地址。
- 图片判断:使用 fileVisual.isImageType 对扩展名进行白名单匹配。
- 颜色与大小:extColor/formatSize 统一视觉与单位。
- 可拓展点
- 增加 PDF/Office/文本等类型的分支渲染逻辑(见“附录:扩展与定制指南”)。
flowchart TD
Start(["进入预览"]) --> CheckFile{"是否选择了文件?"}
CheckFile -- 否 --> Empty["显示空态提示"]
CheckFile -- 是 --> IsImg{"是否图片类型?"}
IsImg -- 是 --> ShowImg["img 标签加载预览URL"]
IsImg -- 否 --> Generic["显示通用占位(扩展名/大小/名称)"]
ShowImg --> End(["完成"])
Generic --> End
Empty --> End
图表来源
章节来源
fileVisual.js 分析
- 职责
- 扩展名到颜色的映射表,便于快速识别文件类别。
- 提取扩展名、判断图片类型、格式化文件大小。
- 复杂度
- 查找时间 O(1),空间为常量级映射表。
- 使用范围
- 被 FileCard、FileListPanel、FilePreviewPanel 共同引用,保证视觉一致性。
章节来源
FmsFile.vue 分析
- 职责
- 解析模块信息,加载分类树,管理选中文件与预览导航。
- 通过 Splitter 组织三栏布局,将 FileListPanel 与 FilePreviewPanel 组合。
- 关键点
- onPreviewFile/onPreviewPrev/onPreviewNext 控制预览上下文切换。
- 暴露 moduleId 与 refreshCategories 供外部调用。
章节来源
FileListPanel.vue 分析
- 职责
- 文件分页加载、拖拽/粘贴上传、批量选择与删除、下载。
- 维护 pendingFiles 与 blobUrl 用于上传前图片预览。
- 关键点
- 上传成功后清理 Blob URL,避免内存泄漏。
- 删除时区分待上传与已上传记录的处理差异。
- 下载通过创建 a 标签触发浏览器下载行为。
章节来源
- FileListPanel.vue:1-133
- FileListPanel.vue:155-258
- FileListPanel.vue:280-364
- FileListPanel.vue:366-388
FileCard.vue 分析
- 职责
- 单文件卡片展示:缩略图/类型标识、文件名、大小、操作按钮。
- 图片类型优先使用 blobUrl 或后端地址作为缩略图。
- 关键点
- 未上传文件禁用预览/下载等操作。
- 更多菜单提供“预览”入口。
章节来源
fileService.js 分析
- 职责
- 初始化存储模式(本地/OSS),批量上传(含直传 OSS 与回调保存记录),删除文件,获取预览/下载地址。
- OSS 凭证缓存与过期判断,减少重复请求。
- 关键点
- getPreviewUrl 直接返回文件存储地址(mx_mapfilename)。
- 上传流程根据存储类型分流,OSS 模式下使用 XHR 直传并生成对象名。
章节来源
依赖关系分析
- 组件耦合
- FmsFile 聚合 FileListPanel 与 FilePreviewPanel,通过 props/events 通信,松耦合。
- FilePreviewPanel 依赖 fileService 获取预览 URL,依赖 fileVisual 做类型判断与样式。
- FileListPanel 与 FileCard 共享 fileVisual,保持视觉一致。
- 外部依赖
- HTTP 请求封装在 http.js(通过 fileService 间接使用)。
- UI 组件来自内部 ui 包(Button、Modal、Spin 等)。
graph LR
F["FmsFile.vue"] --> FL["FileListPanel.vue"]
F --> FP["FilePreviewPanel.vue"]
FL --> FC["FileCard.vue"]
FP --> FS["fileService.js"]
FP --> FV["fileVisual.js"]
FL --> FV
FC --> FV
图表来源
- FmsFile.vue:136-193
- FileListPanel.vue:393-635
- FilePreviewPanel.vue:41-95
- FileCard.vue:60-107
- fileService.js:135-143
- fileVisual.js:40-62
章节来源
- FmsFile.vue:136-193
- FileListPanel.vue:393-635
- FilePreviewPanel.vue:41-95
- FileCard.vue:60-107
- fileService.js:135-143
- fileVisual.js:40-62
性能考虑
- 当前实现
- 图片预览直接使用 img 标签加载远程资源,简单高效。
- 上传阶段对图片使用 URL.createObjectURL 生成临时 Blob URL,用于上传前缩略图预览;上传完成后释放,避免内存泄漏。
- 建议优化
- 大文件分块加载:对 PDF/Office/文本等大文件,可采用服务端分片或前端懒加载(如 PDF 分页渲染、文本按需读取片段)。
- 内存管理:及时 revokeObjectURL,避免大量 Blob 累积;对长列表使用虚拟滚动(若未来引入重型表格)。
- 缓存机制:对频繁访问的文件预览 URL 可做短期内存缓存(注意失效策略);对静态资源可使用浏览器缓存头。
- 网络优化:启用 gzip/压缩,CDN 加速静态资源;对图片进行自适应尺寸与 WebP 转换。
[本节为通用指导,不直接分析具体文件]
故障排查指南
- 预览空白
- 检查文件是否包含有效的 mx_mapfilename;确认后端返回的 URL 可访问且跨域策略允许。
- 图片类型判断依赖扩展名,确保文件名后缀正确。
- 上传失败
- 检查 initFileConfig 是否正确返回 storageType;OSS 模式下凭证是否有效且未过期。
- 关注 http 拦截器抛出的错误提示,必要时调整重试或超时配置。
- 内存泄漏
- 确认上传完成后调用 revokeBlobUrls;页面卸载时清理监听与定时器。
- 删除异常
- 区分待上传与已上传记录的删除逻辑;确保 subid 正确传递。
章节来源
结论
当前 FMS 文件预览以图片内联为主,其他类型以元信息占位并支持下载。整体架构清晰、组件职责明确,具备良好的扩展基础。后续可通过引入 PDF/Office 渲染方案(iframe 或第三方库)与文本预览能力,完善多格式在线预览体验;同时结合分块加载、缓存与内存管理策略,提升大文件场景下的性能与稳定性。
[本节为总结性内容,不直接分析具体文件]
附录:扩展与定制指南
新增文件类型的预览支持
- 步骤
- 在 FilePreviewPanel 中增加类型分支:根据扩展名或 MIME 类型选择渲染器。
- 对于 PDF:建议使用 iframe 嵌入后端提供的预览页或使用 PDF.js 在 Canvas 上分页渲染。
- 对于 Office(Word/Excel/PowerPoint):可借助后端转换为 HTML/PDF 后以 iframe 展示,或集成第三方库(如 mammoth.js 转 HTML、SheetJS 渲染表格、pptxjs 等)。
- 对于文本文件:使用
或 CodeMirror 编辑器进行高亮展示,支持分页与搜索。
- 参考位置
- 类型判断与分支逻辑:FilePreviewPanel.vue 中的 isImage 与渲染模板部分。
- 工具函数:fileVisual.js 的 extFromName/isImageType/formatSize。
章节来源
自定义预览样式
- 通过 CSS 变量与组件样式类名进行主题化定制,例如 fp-panel、fp-toolbar、fp-content__chip 等。
- 可在 FilePreviewPanel 中扩展样式,或在应用层覆盖全局样式。
章节来源
安全考虑
- XSS 防护
- 预览 URL 应来自可信后端接口,避免直接拼接用户输入。
- 对 iframe 嵌入的内容需设置合适的 sandbox 属性,限制脚本执行权限。
- 文件大小限制
- 在前端校验文件大小,拒绝过大文件上传;在后端也需设置最大文件大小限制。
- 对文本预览可进行长度限制与分段加载,避免一次性加载超大文本导致卡顿。
- 跨域与资源加载
- 确保预览资源域名在白名单内,必要时配置 CORS。
- 对敏感资源添加鉴权参数(如 token),并在服务端验证。
[本节为通用安全建议,不直接分析具体文件]