You've already forked DataMate
feat(annotation): 添加数据集文件内容预览功能
- 添加文件内容预览相关状态管理 - 实现支持多种文本格式文件的预览功能(JSON、JSONL、TXT、CSV等) - 添加文件内容长度限制以避免页面卡顿 - 在数据集预览表格中添加文件名点击预览功能 - 创建文件内容预览弹窗界面 - 添加文件预览加载状态和错误处理
This commit is contained in:
@@ -43,6 +43,12 @@ export default function CreateAnnotationTask({
|
|||||||
const [datasetPreviewLoading, setDatasetPreviewLoading] = useState(false);
|
const [datasetPreviewLoading, setDatasetPreviewLoading] = useState(false);
|
||||||
const [selectedDatasetId, setSelectedDatasetId] = useState<string | null>(null);
|
const [selectedDatasetId, setSelectedDatasetId] = useState<string | null>(null);
|
||||||
|
|
||||||
|
// 文件内容预览相关状态
|
||||||
|
const [fileContentVisible, setFileContentVisible] = useState(false);
|
||||||
|
const [fileContent, setFileContent] = useState("");
|
||||||
|
const [fileContentLoading, setFileContentLoading] = useState(false);
|
||||||
|
const [previewFileName, setPreviewFileName] = useState("");
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!open) return;
|
if (!open) return;
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
@@ -113,6 +119,42 @@ export default function CreateAnnotationTask({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 预览文件内容
|
||||||
|
const handlePreviewFileContent = async (file: any) => {
|
||||||
|
// 支持预览的文本文件类型
|
||||||
|
const textExtensions = ['.json', '.jsonl', '.txt', '.csv', '.tsv', '.xml', '.md', '.yaml', '.yml'];
|
||||||
|
const fileName = file.fileName?.toLowerCase() || '';
|
||||||
|
const isTextFile = textExtensions.some(ext => fileName.endsWith(ext));
|
||||||
|
|
||||||
|
if (!isTextFile) {
|
||||||
|
message.warning("仅支持预览文本类文件(JSON、JSONL、TXT、CSV 等)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setFileContentLoading(true);
|
||||||
|
setPreviewFileName(file.fileName);
|
||||||
|
try {
|
||||||
|
const response = await fetch(`/api/data-management/datasets/${selectedDatasetId}/files/${file.id}/download`);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('下载失败');
|
||||||
|
}
|
||||||
|
const text = await response.text();
|
||||||
|
// 限制预览内容长度,避免大文件导致页面卡顿
|
||||||
|
const maxLength = 50000;
|
||||||
|
if (text.length > maxLength) {
|
||||||
|
setFileContent(text.substring(0, maxLength) + '\n\n... (内容过长,仅显示前 50000 字符)');
|
||||||
|
} else {
|
||||||
|
setFileContent(text);
|
||||||
|
}
|
||||||
|
setFileContentVisible(true);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Preview file content error:", error);
|
||||||
|
message.error("获取文件内容失败");
|
||||||
|
} finally {
|
||||||
|
setFileContentLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const generateXmlFromConfig = (objects: any[], labels: any[]) => {
|
const generateXmlFromConfig = (objects: any[], labels: any[]) => {
|
||||||
let xml = '<View>\n';
|
let xml = '<View>\n';
|
||||||
|
|
||||||
@@ -532,6 +574,7 @@ export default function CreateAnnotationTask({
|
|||||||
</Button>
|
</Button>
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
|
<div className="mb-2 text-xs text-gray-500">点击文件名可预览文本类文件内容</div>
|
||||||
<Table
|
<Table
|
||||||
dataSource={datasetPreviewData}
|
dataSource={datasetPreviewData}
|
||||||
columns={[
|
columns={[
|
||||||
@@ -540,6 +583,17 @@ export default function CreateAnnotationTask({
|
|||||||
dataIndex: "fileName",
|
dataIndex: "fileName",
|
||||||
key: "fileName",
|
key: "fileName",
|
||||||
ellipsis: true,
|
ellipsis: true,
|
||||||
|
render: (text: string, record: any) => (
|
||||||
|
<Button
|
||||||
|
type="link"
|
||||||
|
size="small"
|
||||||
|
className="p-0 h-auto text-left"
|
||||||
|
loading={fileContentLoading && previewFileName === text}
|
||||||
|
onClick={() => handlePreviewFileContent(record)}
|
||||||
|
>
|
||||||
|
{text}
|
||||||
|
</Button>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "大小",
|
title: "大小",
|
||||||
@@ -560,6 +614,34 @@ export default function CreateAnnotationTask({
|
|||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
{/* 文件内容预览弹窗 */}
|
||||||
|
<Modal
|
||||||
|
open={fileContentVisible}
|
||||||
|
onCancel={() => setFileContentVisible(false)}
|
||||||
|
title={`文件预览:${previewFileName}`}
|
||||||
|
width={800}
|
||||||
|
footer={[
|
||||||
|
<Button key="close" onClick={() => setFileContentVisible(false)}>
|
||||||
|
关闭
|
||||||
|
</Button>
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<pre
|
||||||
|
style={{
|
||||||
|
maxHeight: '500px',
|
||||||
|
overflow: 'auto',
|
||||||
|
backgroundColor: '#f5f5f5',
|
||||||
|
padding: '12px',
|
||||||
|
borderRadius: '4px',
|
||||||
|
fontSize: '12px',
|
||||||
|
whiteSpace: 'pre-wrap',
|
||||||
|
wordBreak: 'break-all',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{fileContent}
|
||||||
|
</pre>
|
||||||
|
</Modal>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user