From 26b25df02704644192cc3132738a286d0c389d70 Mon Sep 17 00:00:00 2001 From: Wenjie Zhang Date: Mon, 29 Dec 2025 19:52:40 +0800 Subject: [PATCH] =?UTF-8?q?fix(AgentMessageComponent):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=89=AA=E8=B4=B4=E6=9D=BF=E5=85=BC=E5=AE=B9=E6=80=A7?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=B9=B6=E4=BC=98=E5=8C=96=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为剪贴板功能添加降级处理方案,当现代API不可用时使用execCommand方法 优化引用样式,添加悬停提示框和箭头指示器 --- web/src/components/AgentMessageComponent.vue | 58 +++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/web/src/components/AgentMessageComponent.vue b/web/src/components/AgentMessageComponent.vue index 61e2eee5..48d3b435 100644 --- a/web/src/components/AgentMessageComponent.vue +++ b/web/src/components/AgentMessageComponent.vue @@ -128,7 +128,22 @@ const isCopied = ref(false); const copyToClipboard = async (text) => { try { - await navigator.clipboard.writeText(text); + if (navigator.clipboard && navigator.clipboard.writeText) { + await navigator.clipboard.writeText(text); + } else { + // 降级处理:使用传统的 execCommand 方法 + const textArea = document.createElement('textarea'); + textArea.value = text; + textArea.style.position = 'fixed'; + textArea.style.left = '-999999px'; + textArea.style.top = '-999999px'; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + const successful = document.execCommand('copy'); + document.body.removeChild(textArea); + if (!successful) throw new Error('execCommand failed'); + } isCopied.value = true; setTimeout(() => { isCopied.value = false; @@ -662,11 +677,50 @@ const parsedData = computed(() => { cite { font-size: 12px; - color: var(--gray-700); + color: var(--gray-800); font-style: normal; background-color: var(--gray-200); border-radius: 4px; outline: 2px solid var(--gray-200); + padding: 0rem 0.25rem; + margin-left: 4px; + cursor: pointer; + user-select: none; + position: relative; + + &:hover::after { + content: attr(source); + position: absolute; + bottom: calc(100% + 6px); + left: 50%; + transform: translateX(-50%); + padding: 8px 12px; + background-color: var(--gray-900); + color: #fff; + font-size: 13px; + line-height: 1.5; + border-radius: 6px; + min-width: 200px; + max-width: 400px; + width: max-content; + white-space: normal; + word-break: break-word; + z-index: 1000; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); + pointer-events: none; + text-align: center; + } + + &:hover::before { + content: ''; + position: absolute; + bottom: 100%; + left: 50%; + transform: translateX(-50%); + border: 5px solid transparent; + border-top-color: var(--gray-900); + z-index: 1000; + } } a {