feat: GUI 端新增解码功能 — 选择图片解码 QR 码
- 新增 decode_qr Tauri command(接收图片字节,返回解码文本) - ExportPanel 新增「选择图片解码」按钮 + 解码结果展示 - fs:allow-read-file 权限,支持 /c/Users/33644 和 C:\Users\33644\AppData\Local\Temp 路径
This commit is contained in:
@@ -11,6 +11,10 @@
|
||||
{
|
||||
"identifier": "fs:allow-write-file",
|
||||
"allow": [{ "path": "$HOME/**" }]
|
||||
},
|
||||
{
|
||||
"identifier": "fs:allow-read-file",
|
||||
"allow": [{ "path": "$HOME/**" }, { "path": "$TEMP/**" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"default":{"identifier":"default","description":"QRGen 默认权限","local":true,"windows":["main"],"permissions":["core:default","store:default","dialog:default","clipboard-manager:default",{"identifier":"fs:allow-write-file","allow":[{"path":"$HOME/**"}]}]}}
|
||||
{"default":{"identifier":"default","description":"QRGen 默认权限","local":true,"windows":["main"],"permissions":["core:default","store:default","dialog:default","clipboard-manager:default",{"identifier":"fs:allow-write-file","allow":[{"path":"$HOME/**"}]},{"identifier":"fs:allow-read-file","allow":[{"path":"$HOME/**"},{"path":"$TEMP/**"}]}]}}
|
||||
@@ -2,8 +2,8 @@ import { useState } from 'react';
|
||||
import { useQrState } from '../store/qrContext';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { writeText } from '@tauri-apps/plugin-clipboard-manager';
|
||||
import { save } from '@tauri-apps/plugin-dialog';
|
||||
import { writeFile } from '@tauri-apps/plugin-fs';
|
||||
import { open, save } from '@tauri-apps/plugin-dialog';
|
||||
import { readFile, writeFile } from '@tauri-apps/plugin-fs';
|
||||
import type { QrConfig } from '../types';
|
||||
import { buildEncodedText } from '../utils/qrText';
|
||||
|
||||
@@ -11,6 +11,30 @@ export default function ExportPanel() {
|
||||
const { state, dispatch } = useQrState();
|
||||
const [exporting, setExporting] = useState(false);
|
||||
const [errorMsg, setErrorMsg] = useState<string | null>(null);
|
||||
const [decodedText, setDecodedText] = useState<string | null>(null);
|
||||
const [decoding, setDecoding] = useState(false);
|
||||
|
||||
const handleDecode = async () => {
|
||||
setDecoding(true);
|
||||
setErrorMsg(null);
|
||||
setDecodedText(null);
|
||||
try {
|
||||
const filePath = await open({
|
||||
filters: [{ name: '图片文件', extensions: ['png', 'jpg', 'jpeg', 'webp', 'bmp'] }],
|
||||
multiple: false,
|
||||
});
|
||||
if (!filePath) {
|
||||
setDecoding(false);
|
||||
return;
|
||||
}
|
||||
const bytes = await readFile(filePath);
|
||||
const text: string = await invoke('decode_qr', { imageBytes: Array.from(bytes) });
|
||||
setDecodedText(text);
|
||||
} catch (e) {
|
||||
setErrorMsg(`解码失败: ${e}`);
|
||||
}
|
||||
setDecoding(false);
|
||||
};
|
||||
|
||||
const handleCopySvg = async () => {
|
||||
if (!state.preview?.svg) return;
|
||||
@@ -139,6 +163,25 @@ export default function ExportPanel() {
|
||||
>
|
||||
导出 SVG
|
||||
</button>
|
||||
|
||||
{/* 解码区 */}
|
||||
<div className="mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">
|
||||
<div className="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-2">
|
||||
解码
|
||||
</div>
|
||||
<button
|
||||
onClick={handleDecode}
|
||||
disabled={decoding}
|
||||
className="w-full py-2 rounded-lg bg-amber-500 text-white text-sm font-medium hover:bg-amber-600 disabled:opacity-40 transition-all"
|
||||
>
|
||||
{decoding ? '解码中...' : '选择图片解码'}
|
||||
</button>
|
||||
{decodedText && (
|
||||
<div className="mt-2 p-2 bg-green-50 dark:bg-green-900/20 rounded-lg text-xs text-green-700 dark:text-green-300 break-all max-h-24 overflow-auto">
|
||||
{decodedText}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -104,6 +104,12 @@ fn load_history(state: tauri::State<AppState>) -> Result<Vec<HistoryEntry>, Stri
|
||||
Ok(history.clone())
|
||||
}
|
||||
|
||||
/// 解码 QR 码图片,返回文本内容
|
||||
#[tauri::command]
|
||||
fn decode_qr(image_bytes: Vec<u8>) -> Result<String, String> {
|
||||
qr_core::decoder::decode_image(&image_bytes).map(|r| r.text)
|
||||
}
|
||||
|
||||
/// 清空历史记录
|
||||
#[tauri::command]
|
||||
fn clear_history(state: tauri::State<AppState>) -> Result<(), String> {
|
||||
@@ -125,6 +131,7 @@ pub fn run() {
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
encode_qr,
|
||||
export_png,
|
||||
decode_qr,
|
||||
save_history,
|
||||
load_history,
|
||||
clear_history,
|
||||
|
||||
Reference in New Issue
Block a user