1- import React from "react" ;
2- import { Modal } from "antd" ;
1+ import React , { useMemo } from "react" ;
2+ import { Modal , Alert } from "antd" ;
33
44interface PreviewModalProps {
55 open : boolean ;
@@ -8,30 +8,77 @@ interface PreviewModalProps {
88 onCancel : ( ) => void ;
99}
1010
11+ const MAX_PREVIEW_LENGTH = 100000 ; // 限制预览字符数为 100KB
12+
1113const PreviewModal : React . FC < PreviewModalProps > = ( {
1214 open,
1315 title,
1416 content,
1517 onCancel,
16- } ) => (
17- < Modal
18- open = { open }
19- title = { title }
20- onCancel = { onCancel }
21- footer = { null }
22- width = { 800 }
23- >
24- < div
25- style = { {
26- maxHeight : 500 ,
27- overflow : "auto" ,
28- borderRadius : 6 ,
29- padding : 12 ,
30- } }
18+ } ) => {
19+ const { displayContent, isTruncated, totalSize, truncatedInfo } = useMemo ( ( ) => {
20+ if ( ! content ) {
21+ return { displayContent : "" , isTruncated : false , totalSize : 0 , truncatedInfo : "" } ;
22+ }
23+
24+ // 检查是否有数据层面的截断标记
25+ const dataLevelTruncated = content . _truncated === true ;
26+ const originalCount = content . _originalCount || 0 ;
27+ let truncatedInfo = "" ;
28+ if ( dataLevelTruncated ) {
29+ const currentCount = content . Groups ?. length || content . chunks ?. length || 0 ;
30+ truncatedInfo = `数据已截断: 仅显示前 ${ currentCount } 条,共 ${ originalCount } 条` ;
31+ }
32+
33+ const fullJson = JSON . stringify ( content , null , 2 ) ;
34+ const totalSize = fullJson . length ;
35+
36+ if ( totalSize <= MAX_PREVIEW_LENGTH ) {
37+ return { displayContent : fullJson , isTruncated : dataLevelTruncated , totalSize, truncatedInfo } ;
38+ }
39+
40+ // 截断内容,保留前 MAX_PREVIEW_LENGTH 字符
41+ const truncated = fullJson . slice ( 0 , MAX_PREVIEW_LENGTH ) ;
42+ return {
43+ displayContent : truncated + "\n\n... (内容已截断)" ,
44+ isTruncated : true ,
45+ totalSize,
46+ truncatedInfo : truncatedInfo || `内容过大,仅显示前 ${ ( MAX_PREVIEW_LENGTH / 1024 ) . toFixed ( 0 ) } KB` ,
47+ } ;
48+ } , [ content ] ) ;
49+
50+ return (
51+ < Modal
52+ open = { open }
53+ title = { title }
54+ onCancel = { onCancel }
55+ footer = { null }
56+ width = { 800 }
3157 >
32- { content ? JSON . stringify ( content , null , 2 ) : "" }
33- </ div >
34- </ Modal >
35- ) ;
58+ { isTruncated && (
59+ < Alert
60+ message = { truncatedInfo || `内容过大 (${ ( totalSize / 1024 / 1024 ) . toFixed ( 2 ) } MB),仅显示前 ${ ( MAX_PREVIEW_LENGTH / 1024 ) . toFixed ( 0 ) } KB` }
61+ type = "warning"
62+ showIcon
63+ style = { { marginBottom : 12 } }
64+ />
65+ ) }
66+ < pre
67+ style = { {
68+ maxHeight : 500 ,
69+ overflow : "auto" ,
70+ borderRadius : 6 ,
71+ padding : 12 ,
72+ backgroundColor : "#f5f5f5" ,
73+ fontSize : 12 ,
74+ whiteSpace : "pre-wrap" ,
75+ wordBreak : "break-all" ,
76+ } }
77+ >
78+ { displayContent }
79+ </ pre >
80+ </ Modal >
81+ ) ;
82+ } ;
3683
3784export default PreviewModal ;
0 commit comments