From c7a89f999782d46cf1156037e7ea67aee5a1ef87 Mon Sep 17 00:00:00 2001 From: z2_cc <170238968@qq.com> Date: Wed, 13 May 2026 11:40:21 +0800 Subject: [PATCH] feat: add ChatMessage component with source links --- src/components/ChatMessage/index.jsx | 31 +++++++ src/components/ChatMessage/styles.module.css | 96 ++++++++++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 src/components/ChatMessage/index.jsx create mode 100644 src/components/ChatMessage/styles.module.css diff --git a/src/components/ChatMessage/index.jsx b/src/components/ChatMessage/index.jsx new file mode 100644 index 0000000..07ce066 --- /dev/null +++ b/src/components/ChatMessage/index.jsx @@ -0,0 +1,31 @@ +import React from 'react'; +import styles from './styles.module.css'; + +export default function ChatMessage({ message, isStreaming }) { + const isUser = message.role === 'user'; + + return ( +
+
+ {message.content} + {!isUser && isStreaming && } +
+ {!isUser && message.sources && message.sources.length > 0 && ( +
+
📎 相关文档
+ {message.sources.map((link, i) => ( + + {link.breadcrumb} + + ))} +
+ )} +
+ ); +} diff --git a/src/components/ChatMessage/styles.module.css b/src/components/ChatMessage/styles.module.css new file mode 100644 index 0000000..725a07c --- /dev/null +++ b/src/components/ChatMessage/styles.module.css @@ -0,0 +1,96 @@ +.message { + margin-bottom: 12px; + display: flex; + flex-direction: column; +} + +.messageUser { + align-items: flex-end; +} + +.messageAssistant { + align-items: flex-start; +} + +.bubble { + max-width: 85%; + padding: 10px 14px; + border-radius: 12px; + font-size: 14px; + line-height: 1.6; + word-break: break-word; + white-space: pre-wrap; +} + +.bubbleUser { + background: #e8e8e8; + color: #333; + border-bottom-right-radius: 4px; +} + +.bubbleAssistant { + background: #f0f4ff; + color: #333; + border-bottom-left-radius: 4px; +} + +[data-theme='dark'] .bubbleUser { + background: #3a3a3a; + color: #e0e0e0; +} + +[data-theme='dark'] .bubbleAssistant { + background: #2a2e4a; + color: #e0e0e0; +} + +.sources { + margin-top: 8px; + padding: 8px 10px; + background: rgba(255, 255, 255, 0.6); + border: 1px solid #e0e0e0; + border-radius: 8px; + max-width: 85%; + font-size: 12px; +} + +[data-theme='dark'] .sources { + background: rgba(255, 255, 255, 0.08); + border-color: #444; +} + +.sourcesTitle { + color: #666; + margin-bottom: 4px; + font-weight: 500; +} + +[data-theme='dark'] .sourcesTitle { + color: #aaa; +} + +.sourceLink { + display: block; + color: #466aff; + text-decoration: none; + padding: 2px 0; +} + +.sourceLink:hover { + text-decoration: underline; +} + +.cursor { + display: inline-block; + width: 2px; + height: 16px; + background: #466aff; + margin-left: 2px; + vertical-align: text-bottom; + animation: blink 1s infinite; +} + +@keyframes blink { + 0%, 50% { opacity: 1; } + 51%, 100% { opacity: 0; } +}