2025-12-18 13:50:39 +08:00
|
|
|
|
import { ref } from 'vue'
|
|
|
|
|
|
import { useAppStore } from '@/stores/app'
|
|
|
|
|
|
|
2025-12-27 15:16:52 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 检测是否支持 Clipboard API(需要安全上下文:HTTPS/localhost)
|
|
|
|
|
|
*/
|
|
|
|
|
|
function isClipboardSupported(): boolean {
|
|
|
|
|
|
return !!(navigator.clipboard && window.isSecureContext)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 降级方案:使用 textarea + execCommand
|
|
|
|
|
|
* 使用 textarea 而非 input,以正确处理多行文本
|
|
|
|
|
|
*/
|
|
|
|
|
|
function fallbackCopy(text: string): boolean {
|
|
|
|
|
|
const textarea = document.createElement('textarea')
|
|
|
|
|
|
textarea.value = text
|
|
|
|
|
|
textarea.style.cssText = 'position:fixed;left:-9999px;top:-9999px'
|
|
|
|
|
|
document.body.appendChild(textarea)
|
|
|
|
|
|
textarea.select()
|
|
|
|
|
|
try {
|
|
|
|
|
|
return document.execCommand('copy')
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
document.body.removeChild(textarea)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-18 13:50:39 +08:00
|
|
|
|
export function useClipboard() {
|
|
|
|
|
|
const appStore = useAppStore()
|
|
|
|
|
|
const copied = ref(false)
|
|
|
|
|
|
|
2025-12-27 15:16:52 +08:00
|
|
|
|
const copyToClipboard = async (
|
|
|
|
|
|
text: string,
|
|
|
|
|
|
successMessage = 'Copied to clipboard'
|
|
|
|
|
|
): Promise<boolean> => {
|
2025-12-18 13:50:39 +08:00
|
|
|
|
if (!text) return false
|
|
|
|
|
|
|
2025-12-27 15:16:52 +08:00
|
|
|
|
let success = false
|
|
|
|
|
|
|
|
|
|
|
|
if (isClipboardSupported()) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
await navigator.clipboard.writeText(text)
|
|
|
|
|
|
success = true
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
success = fallbackCopy(text)
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
success = fallbackCopy(text)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (success) {
|
2025-12-18 13:50:39 +08:00
|
|
|
|
copied.value = true
|
|
|
|
|
|
appStore.showSuccess(successMessage)
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
copied.value = false
|
|
|
|
|
|
}, 2000)
|
2025-12-27 15:16:52 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
appStore.showError('Copy failed')
|
2025-12-18 13:50:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-27 15:16:52 +08:00
|
|
|
|
return success
|
2025-12-18 13:50:39 +08:00
|
|
|
|
}
|
2025-12-27 15:16:52 +08:00
|
|
|
|
|
|
|
|
|
|
return { copied, copyToClipboard }
|
2025-12-18 13:50:39 +08:00
|
|
|
|
}
|