Skip to content

Commit 5df3bae

Browse files
committed
fix(#856): 修复导入配置时卡死的问题
1 parent 38c56da commit 5df3bae

2 files changed

Lines changed: 43 additions & 41 deletions

File tree

src-tauri/src/backup.rs

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ use std::process::Command;
22
use std::path::Path;
33
use std::fs;
44
use tauri::{command, AppHandle, Manager};
5-
use tauri_plugin_store::StoreExt;
6-
use serde_json::Value;
75

86
#[command]
97
pub async fn export_app_data(app_handle: AppHandle, output_path: String) -> Result<(), String> {
@@ -65,42 +63,28 @@ pub async fn import_app_data(app_handle: AppHandle, zip_path: String) -> Result<
6563
return Err(format!("Unzip command failed: {}", stderr_msg));
6664
}
6765

68-
// 处理 store.json
66+
// 处理 store.json - 直接替换文件而不是循环 set
6967
let store_path = temp_dir.join("store.json");
7068
if store_path.exists() {
71-
let store_content = fs::read_to_string(&store_path)
72-
.map_err(|e| format!("Failed to read store.json: {}", e))?;
73-
74-
let store_data: Value = serde_json::from_str(&store_content)
75-
.map_err(|e| format!("Failed to parse store.json: {}", e))?;
76-
77-
// 获取 store 实例并保存数据
78-
let store = app_handle.store("store.json")
79-
.map_err(|e| format!("Failed to get store: {}", e))?;
80-
81-
if let Value::Object(obj) = store_data {
82-
for (key, value) in obj {
83-
store.set(&key, value);
84-
}
85-
}
86-
87-
store.save().map_err(|e| format!("Failed to save store: {}", e))?;
69+
let dest_store_path = app_data_dir.join("store.json");
70+
fs::copy(&store_path, &dest_store_path)
71+
.map_err(|e| format!("Failed to copy store.json: {}", e))?;
8872
}
8973

90-
// 复制其他文件(除了 store.json)
74+
// 复制其他文件
9175
for entry in fs::read_dir(&temp_dir)
9276
.map_err(|e| format!("Failed to read temp directory: {}", e))? {
9377
let entry = entry.map_err(|e| format!("Failed to read directory entry: {}", e))?;
9478
let file_name = entry.file_name();
95-
96-
// 跳过 store.json,因为已经通过 store API 处理了
79+
80+
// 跳过 store.json,已经在上面处理过了
9781
if file_name == "store.json" {
9882
continue;
9983
}
100-
84+
10185
let src_path = entry.path();
10286
let dest_path = app_data_dir.join(&file_name);
103-
87+
10488
if src_path.is_file() {
10589
fs::copy(&src_path, &dest_path)
10690
.map_err(|e| format!("Failed to copy file {}: {}", file_name.to_string_lossy(), e))?;

src/app/core/setting/dev/set-config.tsx

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Item, ItemMedia, ItemContent, ItemTitle, ItemDescription, ItemActions }
33
import { FileJson } from "lucide-react";
44
import { open, save } from "@tauri-apps/plugin-dialog";
55
import { useToast } from "@/hooks/use-toast";
6-
import { BaseDirectory, copyFile, readTextFile } from "@tauri-apps/plugin-fs";
6+
import { BaseDirectory, copyFile, readTextFile, writeTextFile } from "@tauri-apps/plugin-fs";
77
import { Store } from "@tauri-apps/plugin-store";
88
import { isMobileDevice } from "@/lib/check";
99
import { relaunch } from "@tauri-apps/plugin-process";
@@ -13,23 +13,41 @@ export default function SetConfig() {
1313
const t = useTranslations('settings.dev');
1414
const { toast } = useToast()
1515
async function handleImport() {
16-
const file = await open({
17-
title: t('importConfigTitle'),
18-
})
19-
if (file) {
20-
const content = await readTextFile(file, { baseDir: BaseDirectory.AppData })
21-
const jsonContent = JSON.parse(content)
22-
const store = await Store.load('store.json');
23-
Object.keys(jsonContent).forEach((key: string) => {
24-
store.set(key, jsonContent[key])
16+
try {
17+
const file = await open({
18+
title: t('importConfigTitle'),
2519
})
26-
if (isMobileDevice()) {
27-
toast({
28-
description: t('importConfigSuccessMobile'),
29-
})
30-
} else {
31-
relaunch()
20+
if (file) {
21+
// 验证 JSON 格式
22+
const content = await readTextFile(file)
23+
JSON.parse(content)
24+
25+
// 直接将文件写入 store.json 位置
26+
await writeTextFile('store.json', content, { baseDir: BaseDirectory.AppData })
27+
28+
// 关闭已加载的 store 实例(如果有)
29+
const existingStore = await Store.get('store.json')
30+
if (existingStore) {
31+
await existingStore.close()
32+
}
33+
34+
// 重新加载 store,会自动从磁盘读取新写入的文件
35+
await Store.load('store.json')
36+
37+
if (isMobileDevice()) {
38+
toast({
39+
description: t('importConfigSuccessMobile'),
40+
})
41+
} else {
42+
relaunch()
43+
}
3244
}
45+
} catch (error) {
46+
toast({
47+
title: '导入失败',
48+
description: error instanceof Error ? error.message : String(error),
49+
variant: 'destructive'
50+
})
3351
}
3452
}
3553
async function handleExport() {

0 commit comments

Comments
 (0)