fix: 兼容低版本浏览器消息复制

- 为 Chrome 90 增加剪贴板兼容回退

- 统一聊天与智能体试运行的原色对勾反馈
This commit is contained in:
2026-07-22 20:07:34 +08:00
parent 5a3d4788da
commit 9f06c238d3
15 changed files with 423 additions and 83 deletions

View File

@@ -21,6 +21,7 @@ import {
ChatTimeline,
ChatTimelineBuilder,
} from '@easyflow/common-ui';
import { copyTextToClipboard } from '@easyflow/utils';
import {
Delete,
@@ -872,13 +873,15 @@ function handleStop() {
async function handleCopyMessage(item: ChatTimelineMessageItem) {
const text = copyMessageText(item);
if (!text) {
return;
return false;
}
try {
await navigator.clipboard.writeText(text);
ElMessage.success('已复制');
} catch {
await copyTextToClipboard(text);
return true;
} catch (error) {
console.error('复制消息失败:', error);
ElMessage.error('复制失败');
return false;
}
}
@@ -1133,9 +1136,9 @@ onBeforeUnmount(() => {
:image-loader="loadAgentChatImage"
empty-text="选择智能体后开始对话"
:approval-loading="Boolean(approvalLoadingKey)"
:copy-action="handleCopyMessage"
:copyable="canCopyMessage"
@approve="handleApprove"
@copy-message="handleCopyMessage"
@reject="handleReject"
@select-next-variant="() => undefined"
@select-previous-variant="() => undefined"

View File

@@ -14,6 +14,7 @@ import { computed, onMounted, ref, watch } from 'vue';
import { ChatTimeline } from '@easyflow/common-ui';
import { BrushCleaning } from '@easyflow/icons';
import { copyTextToClipboard } from '@easyflow/utils';
import { ElButton, ElMessage } from 'element-plus';
@@ -148,13 +149,15 @@ function canRegenerateMessage(item: ChatTimelineMessageItem) {
async function handleCopyMessage(item: ChatTimelineMessageItem) {
const text = copyMessageText(item).trim();
if (!text) {
return;
return false;
}
try {
await navigator.clipboard.writeText(text);
ElMessage.success('已复制');
} catch {
await copyTextToClipboard(text);
return true;
} catch (error) {
console.error('复制消息失败:', error);
ElMessage.error('复制失败');
return false;
}
}
@@ -310,11 +313,11 @@ async function handleReject(payload: ChatTimelineToolApprovalPayload) {
:image-loader="loadAgentChatImage"
empty-text="输入问题试运行当前智能体"
:approval-loading="approvalLoading"
:copy-action="handleCopyMessage"
:copyable="canCopyMessage"
:regenerable="canRegenerateMessage"
:regenerate-disabled="true"
@approve="handleApprove"
@copy-message="handleCopyMessage"
@regenerate-message="handleRegenerateMessage"
@reject="handleReject"
@select-next-variant="handleSelectNextVariant"

View File

@@ -951,19 +951,6 @@ function scrollToBottom(force = false) {
});
}
async function copyMessageContent(content?: string) {
const normalized = String(content || '').trim();
if (!normalized) {
return;
}
try {
await navigator.clipboard.writeText(normalized);
ElMessage.success('已复制');
} catch {
ElMessage.error('复制失败');
}
}
function resolveKnowledgeView(knowledgeId: string) {
const view = knowledgeMap.value.get(knowledgeId);
if (view) {
@@ -1369,13 +1356,6 @@ function canRegenerateMessage(item: ChatTimeTimelineItem) {
return !!roundId && !!resolveRoundUserPrompt(roundId);
}
async function handleCopyMessage(item: ChatTimeTimelineItem) {
if (!canCopyMessage(item)) {
return;
}
await copyMessageContent(item.content);
}
async function handleRegenerateMessage() {
if (sending.value || isReadOnly.value) {
return;
@@ -1786,6 +1766,7 @@ async function deleteSession(targetSession?: SessionItem) {
:align="item.role === 'user' ? 'end' : 'start'"
:allow-copy="canCopyMessage(item)"
:allow-regenerate="canRegenerateMessage(item)"
:copy-text="String(item.content || '').trim()"
:disabled-variant-next="!canSwitchVariant(item, 'next')"
:disabled-variant-previous="!canSwitchVariant(item, 'previous')"
:regenerate-disabled="sending || isReadOnly"
@@ -1795,7 +1776,6 @@ async function deleteSession(targetSession?: SessionItem) {
Number(item.variantIndex || item.selectedVariantIndex || 1)
"
:variant-total="Number(item.variantCount || 1)"
@copy="handleCopyMessage(item)"
@regenerate="handleRegenerateMessage"
@select-next-variant="selectVariantForMessage(item, 'next')"
@select-previous-variant="