feat(DataManagement): 添加文件预览功能支持多种文件类型

- 实现文本、图片、视频、音频文件的预览功能
- 添加预览模态框支持不同文件类型的展示
- 集成文件类型检测和预览内容加载逻辑
- 添加预览加载状态和错误处理机制
- 实现大文件内容截断和滚动预览功能
- 添加预览窗口关闭和资源清理功能
This commit is contained in:
2026-01-28 11:18:08 +08:00
parent 4233da5b91
commit 3c4b66b451
2 changed files with 194 additions and 69 deletions

View File

@@ -1,4 +1,4 @@
import { App, Button, Descriptions, DescriptionsProps, Modal, Table, Input } from "antd";
import { App, Button, Descriptions, DescriptionsProps, Modal, Table, Input } from "antd";
import { formatBytes, formatDateTime } from "@/utils/unit";
import { Download, Trash2, Folder, File } from "lucide-react";
import { datasetTypeMap } from "../../dataset.const";
@@ -9,6 +9,15 @@ type DatasetFileRow = DatasetFile & {
fileCount?: number;
uploadTime?: string;
};
const PREVIEW_MAX_HEIGHT = 500;
const PREVIEW_MODAL_WIDTH = {
text: 800,
media: 700,
};
const PREVIEW_TEXT_FONT_SIZE = 12;
const PREVIEW_TEXT_PADDING = 12;
const PREVIEW_AUDIO_PADDING = 40;
export default function Overview({
dataset,
@@ -22,17 +31,21 @@ export default function Overview({
pagination,
selectedFiles,
previewVisible,
previewFileName,
previewContent,
setPreviewVisible,
handleDeleteFile,
handleDownloadFile,
handleBatchDeleteFiles,
handleBatchExport,
handleCreateDirectory,
handleDownloadDirectory,
handleDeleteDirectory,
} = filesOperation;
previewFileName,
previewContent,
previewFileType,
previewMediaUrl,
previewLoading,
closePreview,
handleDeleteFile,
handleDownloadFile,
handleBatchDeleteFiles,
handleBatchExport,
handleCreateDirectory,
handleDownloadDirectory,
handleDeleteDirectory,
handlePreviewFile,
} = filesOperation;
// 基本信息
const items: DescriptionsProps["items"] = [
@@ -127,15 +140,16 @@ export default function Overview({
);
}
return (
return (
<Button
type="link"
onClick={() => {}}
loading={previewLoading && previewFileName === record.fileName}
onClick={() => handlePreviewFile(record)}
>
{content}
</Button>
);
},
);
},
},
{
title: "大小",
@@ -370,25 +384,63 @@ export default function Overview({
/>
</div>
</div>
{/* 文件预览弹窗 */}
<Modal
title={`文件预览:${previewFileName}`}
open={previewVisible}
onCancel={() => setPreviewVisible(false)}
footer={null}
width={700}
>
<pre
style={{
whiteSpace: "pre-wrap",
wordBreak: "break-all",
fontSize: 14,
color: "#222",
}}
>
{previewContent}
</pre>
</Modal>
</>
);
}
{/* 文件预览弹窗 */}
<Modal
title={`文件预览:${previewFileName}`}
open={previewVisible}
onCancel={closePreview}
footer={[
<Button key="close" onClick={closePreview}>
</Button>,
]}
width={previewFileType === "text" ? PREVIEW_MODAL_WIDTH.text : PREVIEW_MODAL_WIDTH.media}
>
{previewFileType === "text" && (
<pre
style={{
maxHeight: `${PREVIEW_MAX_HEIGHT}px`,
overflow: "auto",
whiteSpace: "pre-wrap",
wordBreak: "break-all",
fontSize: PREVIEW_TEXT_FONT_SIZE,
color: "#222",
backgroundColor: "#f5f5f5",
padding: `${PREVIEW_TEXT_PADDING}px`,
borderRadius: "4px",
}}
>
{previewContent}
</pre>
)}
{previewFileType === "image" && (
<div style={{ textAlign: "center" }}>
<img
src={previewMediaUrl}
alt={previewFileName}
style={{ maxWidth: "100%", maxHeight: `${PREVIEW_MAX_HEIGHT}px`, objectFit: "contain" }}
/>
</div>
)}
{previewFileType === "video" && (
<div style={{ textAlign: "center" }}>
<video
src={previewMediaUrl}
controls
style={{ maxWidth: "100%", maxHeight: `${PREVIEW_MAX_HEIGHT}px` }}
>
</video>
</div>
)}
{previewFileType === "audio" && (
<div style={{ textAlign: "center", padding: `${PREVIEW_AUDIO_PADDING}px 0` }}>
<audio src={previewMediaUrl} controls style={{ width: "100%" }}>
</audio>
</div>
)}
</Modal>
</>
);
}