import { useState, useEffect, memo } from 'react' import { Loader2 } from 'lucide-react' import { Image } from '@/components/ui/image' import { ImagePreview } from '@/components/ui/image-preview' import type { HandleImageAttachmentClick, ImageAttachment, TaskArtifact } from '../../types' import { useNovaKit } from '../../context/useNovaKit' export interface ImageAttachmentItemProps { image: ImageAttachment assetsType: 'assistant' | 'user' onClick?: HandleImageAttachmentClick } /** * 判断是否需要加载 OSS URL */ function needsOssUrl(image: ImageAttachment): boolean { if (image.url && image.url.startsWith('http')) { return false } return !!(image.path || image.url) } /** * 图片附件展示组件 */ export const ImageAttachmentItem = memo(function ImageAttachmentItem({ image, assetsType, onClick, }: ImageAttachmentItemProps) { const { api } = useNovaKit() const initialUrl = image.url?.startsWith('http') ? image.url : '' const [url, setUrl] = useState(initialUrl) const [loading, setLoading] = useState(needsOssUrl(image)) useEffect(() => { if (image.url && image.url.startsWith('http')) { return } const filePath = image.path || image.url || image.file_url if (filePath) { api .getArtifactUrl?.({ ...image, path: filePath } as TaskArtifact) .then((res: { data: string }) => { const fileUrls = res?.data if (fileUrls) { setUrl(fileUrls) image.url = fileUrls } }) .catch((err: Error) => { console.error('获取图片 URL 失败:', err) }) .finally(() => { setLoading(false) }) } }, [image, image.url, image.path, api]) if (loading) { return (
) } if (!url) return null const handleClick = () => { if (onClick) { onClick({ ...image, url: url || image.url }, assetsType) } } if (onClick) { return (
{image.file_name
) } return (
{image.file_name
) })