From eff2be526021aad56790a84e36f003108116576f Mon Sep 17 00:00:00 2001 From: Qiao Date: Tue, 3 Feb 2026 00:46:23 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=8F=92=E4=BB=B6=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=97=B6=E4=BF=9D=E7=95=99=20data=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新插件时备份 data 文件夹,解压后恢复 - 添加异常处理,确保解压失败时也能恢复 data 文件夹 --- .../src/api/PluginStore.ts | 46 +++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/packages/napcat-webui-backend/src/api/PluginStore.ts b/packages/napcat-webui-backend/src/api/PluginStore.ts index 279d4741..5e9efe17 100644 --- a/packages/napcat-webui-backend/src/api/PluginStore.ts +++ b/packages/napcat-webui-backend/src/api/PluginStore.ts @@ -157,6 +157,8 @@ async function downloadFile (url: string, destPath: string, customMirror?: strin async function extractPlugin (zipPath: string, pluginId: string): Promise { const PLUGINS_DIR = getPluginsDir(); const pluginDir = path.join(PLUGINS_DIR, pluginId); + const dataDir = path.join(pluginDir, 'data'); + const tempDataDir = path.join(PLUGINS_DIR, `${pluginId}.data.backup`); console.log(`[extractPlugin] PLUGINS_DIR: ${PLUGINS_DIR}`); console.log(`[extractPlugin] pluginId: ${pluginId}`); @@ -169,8 +171,19 @@ async function extractPlugin (zipPath: string, pluginId: string): Promise console.log(`[extractPlugin] Created plugins root directory: ${PLUGINS_DIR}`); } - // 如果目录已存在,先删除 + // 如果目录已存在,先备份 data 文件夹,再删除 + let hasDataBackup = false; if (fs.existsSync(pluginDir)) { + // 备份 data 文件夹 + if (fs.existsSync(dataDir)) { + console.log(`[extractPlugin] Backing up data directory: ${dataDir}`); + if (fs.existsSync(tempDataDir)) { + fs.rmSync(tempDataDir, { recursive: true, force: true }); + } + fs.renameSync(dataDir, tempDataDir); + hasDataBackup = true; + } + console.log(`[extractPlugin] Directory exists, removing: ${pluginDir}`); fs.rmSync(pluginDir, { recursive: true, force: true }); } @@ -179,10 +192,35 @@ async function extractPlugin (zipPath: string, pluginId: string): Promise fs.mkdirSync(pluginDir, { recursive: true }); console.log(`[extractPlugin] Created directory: ${pluginDir}`); - // 解压 - await compressing.zip.uncompress(zipPath, pluginDir); + try { + // 解压 + await compressing.zip.uncompress(zipPath, pluginDir); - console.log(`[extractPlugin] Plugin extracted to: ${pluginDir}`); + console.log(`[extractPlugin] Plugin extracted to: ${pluginDir}`); + + // 恢复 data 文件夹 + if (hasDataBackup && fs.existsSync(tempDataDir)) { + // 如果新版本也有 data 文件夹,先删除 + if (fs.existsSync(dataDir)) { + fs.rmSync(dataDir, { recursive: true, force: true }); + } + console.log(`[extractPlugin] Restoring data directory: ${dataDir}`); + fs.renameSync(tempDataDir, dataDir); + } + } catch (e) { + // 解压失败时,尝试恢复 data 文件夹 + if (hasDataBackup && fs.existsSync(tempDataDir)) { + console.log(`[extractPlugin] Extract failed, restoring data directory`); + if (!fs.existsSync(pluginDir)) { + fs.mkdirSync(pluginDir, { recursive: true }); + } + if (fs.existsSync(dataDir)) { + fs.rmSync(dataDir, { recursive: true, force: true }); + } + fs.renameSync(tempDataDir, dataDir); + } + throw e; + } // 列出解压后的文件 const files = fs.readdirSync(pluginDir);