diff --git a/easyflow-ui-admin/app/src/views/ai/bots/pages/setting/config.vue b/easyflow-ui-admin/app/src/views/ai/bots/pages/setting/config.vue index 7fc2611..394c6d6 100644 --- a/easyflow-ui-admin/app/src/views/ai/bots/pages/setting/config.vue +++ b/easyflow-ui-admin/app/src/views/ai/bots/pages/setting/config.vue @@ -291,13 +291,57 @@ const handleAnonymousAccessChange = ( handleDialogOptionsStrChange('anonymousEnabled', value); }; +const copyText = async (value: string) => { + // 优先使用现代剪贴板 API;在非安全上下文或权限受限场景自动走降级逻辑。 + try { + if (navigator.clipboard?.writeText) { + await navigator.clipboard.writeText(value); + return; + } + } catch { + // ignore and fallback + } + + const textarea = document.createElement('textarea'); + textarea.value = value; + textarea.setAttribute('readonly', ''); + textarea.style.position = 'fixed'; + textarea.style.left = '-9999px'; + textarea.style.top = '0'; + textarea.style.opacity = '0'; + textarea.style.pointerEvents = 'none'; + + document.body.appendChild(textarea); + + const selection = document.getSelection(); + const previousRange = + selection && selection.rangeCount > 0 ? selection.getRangeAt(0) : null; + + textarea.focus(); + textarea.select(); + textarea.setSelectionRange(0, textarea.value.length); + const copied = document.execCommand('copy'); + + document.body.removeChild(textarea); + if (selection) { + selection.removeAllRanges(); + if (previousRange) { + selection.addRange(previousRange); + } + } + + if (!copied) { + throw new Error('copy_failed'); + } +}; + const handleCopyValue = async (value: string, successMessage?: string) => { if (!value) { ElMessage.warning($t('bot.chatPublishBaseUrlMissing')); return; } try { - await navigator.clipboard.writeText(value); + await copyText(value); ElMessage.success(successMessage || $t('bot.publicChatCopySuccess')); } catch { ElMessage.error($t('bot.publicChatCopyFail'));