import { useState } from 'react'; import type { RefObject } from 'react'; import { Button, Space } from 'antd'; import { CopyOutlined, LinkOutlined } from '@ant-design/icons'; import { copyImageToClipboard } from '../utils/exchangeImage'; import { getErrorMessage } from '../utils/error'; import { message } from '../utils/antdMessage'; interface Props { wrapRef: RefObject; url?: string; disabled?: boolean; } function copyTextToClipboard(text: string): Promise { if (navigator.clipboard?.writeText) { return navigator.clipboard.writeText(text); } // fallback:利用 textarea + execCommand,兼容 http 远程访问 return new Promise((resolve, reject) => { const ta = document.createElement('textarea'); ta.value = text; ta.style.position = 'fixed'; ta.style.left = '-9999px'; document.body.appendChild(ta); ta.select(); try { const ok = document.execCommand('copy'); document.body.removeChild(ta); if (ok) { resolve(); } else { reject(new Error('execCommand copy failed')); } } catch (e) { document.body.removeChild(ta); reject(e); } }); } export default function QrActions({ wrapRef, url, disabled }: Props) { const [copyingImage, setCopyingImage] = useState(false); const [copyingLink, setCopyingLink] = useState(false); const copyImage = async () => { const canvas = wrapRef.current?.querySelector('canvas'); if (!canvas) return; setCopyingImage(true); try { const blob = await new Promise((resolve, reject) => { canvas.toBlob((b) => (b ? resolve(b) : reject(new Error('二维码图片导出失败'))), 'image/png'); }); await copyImageToClipboard(blob); message.success('二维码已复制到剪贴板'); } catch (error) { message.error(getErrorMessage(error)); } finally { setCopyingImage(false); } }; const copyLink = async () => { if (!url) return; setCopyingLink(true); try { await copyTextToClipboard(url); message.success('二维码链接已复制'); } catch (error) { message.error(getErrorMessage(error)); } finally { setCopyingLink(false); } }; return ( ); }