This commit is contained in:
2026-07-03 10:28:04 +08:00
parent 67287cc4ef
commit f8fc44c68a
3 changed files with 58 additions and 9 deletions
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -28,7 +28,7 @@
} }
})(); })();
</script> </script>
<script type="module" crossorigin src="/assets/index-BMI_pA0X.js"></script> <script type="module" crossorigin src="/assets/index-oaHVVvP0.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-D7ShJUt4.css"> <link rel="stylesheet" crossorigin href="/assets/index-D7ShJUt4.css">
</head> </head>
<body> <body>
@@ -242,6 +242,13 @@ const AdminGenerationAiRecords: React.FC = () => {
const [videoPlaying, setVideoPlaying] = useState(false); const [videoPlaying, setVideoPlaying] = useState(false);
const videoRef = useRef<HTMLVideoElement | null>(null); const videoRef = useRef<HTMLVideoElement | null>(null);
// 资源预览弹窗(附件 / 最终结果)
const [resourcePreview, setResourcePreview] = useState<{
url: string;
type: 'image' | 'video';
title: string;
} | null>(null);
const load = useCallback(async () => { const load = useCallback(async () => {
setLoading(true); setLoading(true);
try { try {
@@ -385,6 +392,21 @@ const AdminGenerationAiRecords: React.FC = () => {
window.open(apiUrl(url), '_blank', 'noopener,noreferrer'); window.open(apiUrl(url), '_blank', 'noopener,noreferrer');
}; };
/** 弹窗预览资源(图片/视频) */
const handlePreviewResource = (url: string, type: 'image' | 'video', title: string) => {
if (isBlobUrl(url)) {
message.warning('本地临时素材已失效,暂无法查看');
return;
}
if (isUrlExpired(url)) {
message.warning('链接已超时,请刷新列表或重新搜索后再查看');
return;
}
setResourcePreview({ url: apiUrl(url), type, title });
};
const handleCloseResourcePreview = () => setResourcePreview(null);
const columns = useMemo(() => [ const columns = useMemo(() => [
{ {
title: '用户', key: 'user', width: 150, title: '用户', key: 'user', width: 150,
@@ -922,10 +944,9 @@ const AdminGenerationAiRecords: React.FC = () => {
)} )}
/> />
<RangePicker <RangePicker
showTime
value={createdRange} value={createdRange}
onChange={(dates) => { setCreatedRange(dates); }} onChange={(dates) => { setCreatedRange(dates); }}
placeholder={['创建开始', '创建结束']} placeholder={['开始日期', '结束日期']}
/> />
<Input <Input
placeholder="用户ID搜索" placeholder="用户ID搜索"
@@ -1064,7 +1085,7 @@ const AdminGenerationAiRecords: React.FC = () => {
key={idx} key={idx}
size="small" size="small"
icon={refType === 'video' ? <PlayCircleOutlined /> : <LinkOutlined />} icon={refType === 'video' ? <PlayCircleOutlined /> : <LinkOutlined />}
onClick={() => handleOpenExternalResource(refUrl, refType === 'video' ? '视频附件' : '图片附件')} onClick={() => handlePreviewResource(refUrl, refType === 'video' ? 'video' : 'image', title)}
> >
{title} {title}
</Button> </Button>
@@ -1085,10 +1106,10 @@ const AdminGenerationAiRecords: React.FC = () => {
size="small" size="small"
type="link" type="link"
icon={<PlayCircleOutlined />} icon={<PlayCircleOutlined />}
onClick={() => handleOpenExternalResource(preview.videoUrl, '视频')} onClick={() => handlePreviewResource(preview.videoUrl!, 'video', '生成视频')}
style={{ padding: 0 }} style={{ padding: 0 }}
> >
</Button> </Button>
) : null} ) : null}
{preview.genType === 'image' && preview.imageUrl ? ( {preview.genType === 'image' && preview.imageUrl ? (
@@ -1096,10 +1117,10 @@ const AdminGenerationAiRecords: React.FC = () => {
size="small" size="small"
type="link" type="link"
icon={<FileImageOutlined />} icon={<FileImageOutlined />}
onClick={() => handleOpenExternalResource(preview.imageUrl, '图片')} onClick={() => handlePreviewResource(preview.imageUrl!, 'image', '生成图片')}
style={{ padding: 0 }} style={{ padding: 0 }}
> >
</Button> </Button>
) : null} ) : null}
</div> </div>
@@ -1122,6 +1143,34 @@ const AdminGenerationAiRecords: React.FC = () => {
<Empty description="暂无详情" /> <Empty description="暂无详情" />
)} )}
</Modal> </Modal>
{/* 资源预览弹窗(附件 / 最终结果) */}
<Modal
title={resourcePreview?.title || '资源预览'}
open={!!resourcePreview}
onCancel={handleCloseResourcePreview}
footer={null}
width={resourcePreview?.type === 'video' ? 800 : 600}
destroyOnHidden
>
{resourcePreview ? (
resourcePreview.type === 'video' ? (
<video
key={resourcePreview.url}
src={resourcePreview.url}
controls
autoPlay
style={{ width: '100%', maxHeight: 600, background: '#000', borderRadius: 8 }}
/>
) : (
<img
src={resourcePreview.url}
alt={resourcePreview.title}
style={{ width: '100%', maxHeight: 600, objectFit: 'contain', borderRadius: 8 }}
/>
)
) : null}
</Modal>
</div> </div>
); );
}; };