Files
zkxw/web-admin/src/utils/copy-text.ts
T
2026-06-11 15:42:58 +08:00

65 lines
1.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { h } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
/**
* 将文本写入剪贴板。优先 Clipboard API,HTTP 等非安全上下文回退 execCommand。
*/
export async function copyTextToClipboard(text: string): Promise<boolean> {
if (navigator.clipboard?.writeText) {
try {
await navigator.clipboard.writeText(text)
return true
} catch {
// 权限拒绝或异步后丢失用户手势时,尝试 legacy 方式
}
}
try {
const textarea = document.createElement('textarea')
textarea.value = text
textarea.setAttribute('readonly', '')
textarea.style.cssText = 'position:fixed;left:-9999px;top:0;opacity:0'
document.body.appendChild(textarea)
textarea.focus()
textarea.select()
const ok = document.execCommand('copy')
document.body.removeChild(textarea)
return ok
} catch {
return false
}
}
/**
* 复制文本;失败时弹窗展示内容供手动复制(适用于 HTTP 测试环境等受限场景)。
*/
export async function copyTextWithFallback(
text: string,
options?: { successMessage?: string; fallbackTitle?: string }
): Promise<void> {
const ok = await copyTextToClipboard(text)
if (ok) {
ElMessage.success(options?.successMessage ?? '已复制到剪贴板')
return
}
await ElMessageBox.alert(
h('textarea', {
value: text,
readonly: true,
style:
'width:100%;min-height:88px;padding:8px 12px;border:1px solid var(--el-border-color);border-radius:8px;font-size:14px;line-height:1.5;resize:none;',
onVnodeMounted(vnode) {
const el = vnode.el as HTMLTextAreaElement | null
el?.focus()
el?.select()
}
}),
options?.fallbackTitle ?? '请手动复制短信内容',
{
confirmButtonText: '关闭',
customClass: 'copy-text-fallback-dialog'
}
)
}