From 323646f1d4b776596644c577a98422e9237fd6af Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 1 Feb 2026 19:00:51 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=94=A8=E6=88=B7=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=9B=BE=E7=89=87=E6=A0=87=E7=AD=BE=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F=EF=BC=8C=E9=9A=90=E8=97=8F=E6=A0=87=E6=B3=A8=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E5=89=8D=E7=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/canvas/CanvasChatPanel.tsx | 144 ++++++++++++++++---------- 1 file changed, 89 insertions(+), 55 deletions(-) diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx index fe8ae06..126c343 100644 --- a/components/canvas/CanvasChatPanel.tsx +++ b/components/canvas/CanvasChatPanel.tsx @@ -856,63 +856,97 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF "flex flex-col gap-2 max-w-[85%]", message.role === 'user' ? "items-end" : "items-start" )}> -
- {/* 附件预览 */} - {(message as any).attachments && (message as any).attachments.length > 0 && ( -
- {(message as any).attachments.map((att: any, i: number) => ( - - ))} -
- )} - - {/* 消息内容 */} -
- {cleanedMessage.parts?.map((part: any, i: number) => { - if (part.type === 'text') { - // 提取并显示图片 - const imageUrls = extractImageUrls(part.text || ''); - const textWithoutImages = (part.text || '') - .replace(/!\[(?:thumb)?\|\|\|[^|]+\|\|\|[^\]]*\]\([^)]+\)/g, '') - .trim(); + {message.role === 'user' ? ( + // 🆕 用户消息:使用图片标签样式(类似输入框) +
+
+ {/* 渲染图片标签和文字混合 */} + {(() => { + const msgAttachments = (message as any).attachments || []; + const fileParts = cleanedMessage.parts?.filter((p: any) => p.type === 'file' && p.url) || []; + const textParts = cleanedMessage.parts?.filter((p: any) => p.type === 'text' && p.text) || []; - return ( -
- {textWithoutImages && {textWithoutImages}} - {imageUrls.length > 0 && ( -
- {imageUrls.map((url, idx) => ( -
- window.open(url, '_blank')} - /> -
- ))} -
- )} -
- ); - } - return null; - })} + // 合并所有图片 + const allImages = [ + ...msgAttachments.map((att: any) => ({ url: att.url, name: att.name || 'Image' })), + ...fileParts.map((p: any) => ({ url: p.url, name: p.name || 'Image' })) + ]; + + // 获取纯文字内容(去掉标注提示前缀) + let textContent = textParts.map((p: any) => p.text).join(' ').trim(); + // 移除标注提示前缀(这是后台处理用的,不需要显示给用户) + textContent = textContent.replace(/【注意:图片中有标注(箭头、圆圈、文字等)标记的区域是需要重点关注或修改的部分,请根据标注进行处理】\n?/g, ''); + + // 解析文字中的图片名称引用,构建混合显示 + const elements: React.ReactNode[] = []; + + // 先添加图片标签 + allImages.forEach((img, idx) => { + elements.push( + + + {img.name} + + ); + }); + + // 添加文字内容 + if (textContent) { + elements.push( + {textContent} + ); + } + + return elements; + })()} +
-
+ ) : ( + // AI 消息:保持原样式 +
+ {/* 消息内容 */} +
+ {cleanedMessage.parts?.map((part: any, i: number) => { + if (part.type === 'text') { + // 提取并显示图片 + const imageUrls = extractImageUrls(part.text || ''); + const textWithoutImages = (part.text || '') + .replace(/!\[(?:thumb)?\|\|\|[^|]+\|\|\|[^\]]*\]\([^)]+\)/g, '') + .trim(); + + return ( +
+ {textWithoutImages && {textWithoutImages}} + {imageUrls.length > 0 && ( +
+ {imageUrls.map((url, idx) => ( +
+ window.open(url, '_blank')} + /> +
+ ))} +
+ )} +
+ ); + } + return null; + })} +
+
+ )}
);