feat: 支持右键菜单图片二维码识别

- 在 qrCodeParser.ts 中添加 parseQrCodeFromUrl 函数,支持从图片 URL 解析二维码
- 在 QrCodeToUrlSection 中使用 useContextMenuData 接收右键菜单传递的图片 URL
- 自动下载图片并解析二维码,显示解析结果
This commit is contained in:
雨霖铃
2026-05-20 21:19:39 +08:00
parent 387a95d6a6
commit 8e920c2a94
2 changed files with 56 additions and 1 deletions
+35 -1
View File
@@ -20,8 +20,9 @@ import ClearIcon from '@mui/icons-material/Clear';
import CopyButton from '@/components/CopyButton';
import { qrCodePageStyles } from '@/config/pageTheme';
import { useSnackbar } from '@/components/GlobalSnackbar';
import { parseQrCodeFromFile } from '@/utils/qrCodeParser';
import { parseQrCodeFromFile, parseQrCodeFromUrl } from '@/utils/qrCodeParser';
import { useTranslation } from 'react-i18next';
import { useContextMenuData } from '@/utils/useContextMenuData';
interface QrCodeToUrlSectionProps {
expanded: boolean;
@@ -46,6 +47,39 @@ const QrCodeToUrlSection = ({
const fileInputRef = useRef<HTMLInputElement>(null);
// 处理右键菜单传递的图片 URL
const handleContextMenuData = useCallback(
async (imageUrl: string) => {
try {
setParsing(true);
setParseError('');
setParsedUrl('');
setPreviewUrl(imageUrl);
const result = await parseQrCodeFromUrl(imageUrl);
if (result.success && result.data) {
setParsedUrl(result.data);
showMessage(t('qrCode:parseSuccess'), { severity: 'success', autoHideDuration: 1000 });
} else {
setParseError(result.error || t('qrCode:noQrDetected'));
showMessage(result.error || t('qrCode:noQrDetected'), {
severity: 'error',
autoHideDuration: 1000,
});
}
} catch (error) {
console.error('解析二维码失败:', error);
showMessage(t('qrCode:parseError'), { severity: 'error', autoHideDuration: 300 });
} finally {
setParsing(false);
}
},
[showMessage, t],
);
useContextMenuData({ featureKey: 'qrCode', onData: handleContextMenuData });
// 清理预览 URL,防止内存泄漏
useEffect(() => {
return () => {
+21
View File
@@ -35,3 +35,24 @@ export async function parseQrCodeFromFile(file: File): Promise<QrCodeParseResult
return { success: false, error: errorMsg };
}
}
/**
* 从图片 URL 解析二维码
* 先下载图片,然后调用 parseQrCodeFromFile
*/
export async function parseQrCodeFromUrl(imageUrl: string): Promise<QrCodeParseResult> {
try {
const response = await fetch(imageUrl);
if (!response.ok) {
return { success: false, error: '无法下载图片' };
}
const blob = await response.blob();
const file = new File([blob], 'qrcode.jpg', { type: blob.type || 'image/jpeg' });
return await parseQrCodeFromFile(file);
} catch (err) {
const errorMsg = err instanceof Error ? err.message : String(err);
return { success: false, error: `下载图片失败: ${errorMsg}` };
}
}