refactor: 暂时移除图片二维码识别功能

- 删除 qrCode-image 右键菜单配置
- 删除 parseQrCodeFromUrl 函数
- 删除 QrCodeToUrlSection 中的 useContextMenuData 相关代码
- 更新相关测试用例
This commit is contained in:
雨霖铃
2026-05-20 21:27:36 +08:00
parent 8e920c2a94
commit 00fe3eddd9
5 changed files with 8 additions and 160 deletions
+4 -33
View File
@@ -42,14 +42,14 @@ describe('background 菜单注册与分流', () => {
);
});
it('应该创建图片二维码识别子菜单', () => {
it('应该创建网页链接转二维码子菜单', () => {
createAllContextMenus();
expect(chrome.contextMenus.create).toHaveBeenCalledWith(
expect.objectContaining({
id: 'qrCode-image',
title: '🖼️ 识别图中的二维码',
contexts: ['image'],
id: 'qrCode-page',
title: '🔗 网页链接转二维码',
contexts: ['page'],
}),
);
});
@@ -79,35 +79,6 @@ describe('background 菜单注册与分流', () => {
});
});
it('当点击 qrCode-image 时应返回 qrCode 功能和 srcUrl', () => {
const info = createMockOnClickData({
menuItemId: 'qrCode-image',
srcUrl: 'https://example.com/image.png',
});
const result = parseContextMenuClick('qrCode-image', info);
expect(result).toEqual({
success: true,
data: { featureKey: 'qrCode', payload: 'https://example.com/image.png' },
});
});
it('当图片为 Base64 内联图时应返回错误', () => {
const info = createMockOnClickData({
menuItemId: 'qrCode-image',
srcUrl:
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==',
});
const result = parseContextMenuClick('qrCode-image', info);
expect(result).toEqual({
success: false,
error: '无法识别 Base64 内联图片,请使用图片文件 URL',
});
});
it('当没有 selectionText 和 srcUrl 时应返回错误', () => {
const info = createMockOnClickData({
menuItemId: 'unknown',
+1 -35
View File
@@ -20,9 +20,8 @@ import ClearIcon from '@mui/icons-material/Clear';
import CopyButton from '@/components/CopyButton';
import { qrCodePageStyles } from '@/config/pageTheme';
import { useSnackbar } from '@/components/GlobalSnackbar';
import { parseQrCodeFromFile, parseQrCodeFromUrl } from '@/utils/qrCodeParser';
import { parseQrCodeFromFile } from '@/utils/qrCodeParser';
import { useTranslation } from 'react-i18next';
import { useContextMenuData } from '@/utils/useContextMenuData';
interface QrCodeToUrlSectionProps {
expanded: boolean;
@@ -47,39 +46,6 @@ 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 () => {
+3 -49
View File
@@ -12,8 +12,8 @@ describe('contextMenu', () => {
});
describe('CONTEXT_MENU_CONFIGS', () => {
it('应该包含 8 个菜单项配置', () => {
expect(CONTEXT_MENU_CONFIGS).toHaveLength(8);
it('应该包含 7 个菜单项配置', () => {
expect(CONTEXT_MENU_CONFIGS).toHaveLength(7);
});
it('应该有一个父级菜单项 Testing Tools', () => {
@@ -36,14 +36,6 @@ describe('contextMenu', () => {
]);
});
it('应该有 1 个 image 上下文的子菜单', () => {
const imageMenus = CONTEXT_MENU_CONFIGS.filter(
(c) => c.contexts[0] === 'image' && c.parentId === 'testing-tools-parent',
);
expect(imageMenus).toHaveLength(1);
expect(imageMenus[0].id).toBe('qrCode-image');
});
it('应该有 2 个 page 上下文的子菜单', () => {
const pageMenus = CONTEXT_MENU_CONFIGS.filter(
(c) => c.contexts[0] === 'page' && c.parentId === 'testing-tools-parent',
@@ -57,7 +49,7 @@ describe('contextMenu', () => {
it('应该为每个配置调用 chrome.contextMenus.create', () => {
createAllContextMenus();
expect(chrome.contextMenus.create).toHaveBeenCalledTimes(8);
expect(chrome.contextMenus.create).toHaveBeenCalledTimes(7);
});
it('应该使用正确的参数创建菜单项', () => {
@@ -89,44 +81,6 @@ describe('contextMenu', () => {
...overrides,
});
it('当点击 qrCode-image 菜单时应返回 qrCode 功能和 srcUrl', () => {
const info = createMockOnClickData({
srcUrl: 'https://example.com/image.png',
});
const result = parseContextMenuClick('qrCode-image', info);
expect(result).toEqual({
success: true,
data: { featureKey: 'qrCode', payload: 'https://example.com/image.png' },
});
});
it('当图片为 Base64 内联图时应返回错误', () => {
const info = createMockOnClickData({
srcUrl:
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==',
});
const result = parseContextMenuClick('qrCode-image', info);
expect(result).toEqual({
success: false,
error: '无法识别 Base64 内联图片,请使用图片文件 URL',
});
});
it('当点击 qrCode-image 菜单但没有 srcUrl 时应返回成功', () => {
const info = createMockOnClickData({});
const result = parseContextMenuClick('qrCode-image', info);
expect(result).toEqual({
success: true,
data: { featureKey: 'qrCode', payload: '' },
});
});
it('当点击 qrCode-page 菜单时应返回 qrCode 功能和 pageUrl', () => {
const info = createMockOnClickData({
pageUrl: 'https://example.com/page',
-22
View File
@@ -52,12 +52,6 @@ export const CONTEXT_MENU_CONFIGS: ContextMenuItemConfig[] = [
contexts: [chrome.contextMenus.ContextType.SELECTION],
parentId: PARENT_MENU_ID,
},
{
id: 'qrCode-image',
title: '🖼️ 识别图中的二维码',
contexts: [chrome.contextMenus.ContextType.IMAGE],
parentId: PARENT_MENU_ID,
},
{
id: 'storageCleaner',
title: '🧹 清理当前网站存储',
@@ -89,22 +83,6 @@ export function parseContextMenuClick(
): ParseResult {
const featureKey = menuItemId as PageType;
if (menuItemId === 'qrCode-image') {
const srcUrl = info.srcUrl || '';
if (srcUrl.startsWith('data:image/')) {
return {
success: false,
error: '无法识别 Base64 内联图片,请使用图片文件 URL',
};
}
return {
success: true,
data: { featureKey: 'qrCode', payload: srcUrl },
};
}
if (menuItemId === 'qrCode-page') {
return {
success: true,
-21
View File
@@ -35,24 +35,3 @@ 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}` };
}
}