From ad6031651b988b10d663c2c3f5b18b2e946ccd53 Mon Sep 17 00:00:00 2001 From: H3CoF6 <1707889225@qq.com> Date: Wed, 8 Apr 2026 07:00:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E6=B5=81=E7=A8=8B=EF=BC=8C=E5=B0=86=E5=AF=BC=E5=85=A5=E6=8C=89?= =?UTF-8?q?=E9=92=AE=E7=A7=BB=E8=87=B3=E9=A6=96=E9=A1=B5=E5=B9=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E7=9B=AE=E5=BD=95=E9=80=89=E6=8B=A9=E5=92=8C=E8=B4=A6?= =?UTF-8?q?=E5=8F=B7=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/composables/useApi.js | 10 ++ frontend/pages/decrypt.vue | 161 ++---------------- frontend/pages/index.vue | 155 +++++++++++++++-- .../routers/import_decrypted.py | 109 ++++++++---- 4 files changed, 238 insertions(+), 197 deletions(-) diff --git a/frontend/composables/useApi.js b/frontend/composables/useApi.js index 24bb518..c4ac4b6 100644 --- a/frontend/composables/useApi.js +++ b/frontend/composables/useApi.js @@ -62,6 +62,14 @@ export const useApi = () => { }) } + // 导入预览API + const importDecryptedPreview = async (data) => { + return await request('/import_decrypted/preview', { + method: 'POST', + body: data + }) + } + // 导入已解密目录API const importDecrypted = async (data) => { return await request('/import_decrypted', { @@ -613,6 +621,8 @@ export const useApi = () => { detectWechat, detectCurrentAccount, decryptDatabase, + importDecryptedPreview, + importDecrypted, healthCheck, listChatAccounts, getChatAccountInfo, diff --git a/frontend/pages/decrypt.vue b/frontend/pages/decrypt.vue index 399ab33..4e90eed 100644 --- a/frontend/pages/decrypt.vue +++ b/frontend/pages/decrypt.vue @@ -16,31 +16,13 @@ -
-

数据获取

-

选择解密新数据或导入已解密目录

-
- -
- - +
+

数据库解密

+

输入密钥和路径开始解密

- -
+
- - -
-
-
- - - -
-

什么是直接导入?

-

如果您已经有了已解密的数据库文件(扁平化目录结构,含 contact.db, session.db 等)以及 resource 资源目录,可以直接导入。此过程不校验密钥,也不进行实时同步。

-
-
-
- - -
- - -

- - - - {{ formErrors.import_path }} -

-

- - - - 该目录应包含已解密的 .db 文件,若有 resource 文件夹也会一并导入。 -

-
- - -
-
- -
-
-
@@ -518,7 +434,7 @@ import { ref, reactive, computed, onMounted, onBeforeUnmount } from 'vue' import { useApi } from '~/composables/useApi' -const { decryptDatabase, importDecrypted, saveMediaKeys, getSavedKeys, getKeys, getImageKey, getWxStatus } = useApi() +const { decryptDatabase, saveMediaKeys, getSavedKeys, getKeys, getImageKey, getWxStatus } = useApi() const loading = ref(false) const error = ref('') @@ -527,8 +443,12 @@ const currentStep = ref(0) const mediaAccount = ref('') const isGettingDbKey = ref(false) -// 解密模式切换 -const decryptMode = ref('standard') // 'standard' or 'import' +// 步骤定义 +const steps = [ + { title: '数据库解密' }, + { title: '填写图片密钥' }, + { title: '图片解密' } +] // 表单数据 const formData = reactive({ @@ -536,16 +456,10 @@ const formData = reactive({ db_storage_path: '' }) -// 导入数据 -const importData = reactive({ - path: '' -}) - // 表单错误 const formErrors = reactive({ key: '', - db_storage_path: '', - import_path: '' + db_storage_path: '' }) // 图片密钥相关 @@ -784,57 +698,6 @@ const resetDbDecryptProgress = () => { dbDecryptProgress.message = '' } -const handleImport = async () => { - if (!importData.path) { - formErrors.import_path = '请输入已解密目录路径' - return - } - - loading.value = true - error.value = '' - warning.value = '' - formErrors.import_path = '' - - try { - const res = await importDecrypted({ - import_path: importData.path - }) - - if (res.status === 'success') { - mediaAccount.value = res.account - // 模拟一个成功的结果 - decryptResult.value = { - status: 'completed', - success_count: res.imported_files.length, - total_databases: res.imported_files.length, - account_results: { - [res.account]: { - success: res.imported_files.length - } - } - } - - if (process.client && typeof window !== 'undefined') { - sessionStorage.setItem('decryptResult', JSON.stringify(decryptResult.value)) - } - - // 如果有 resource 目录,则提示用户可以跳过图片解密 - if (res.has_resource) { - warning.value = '检测到已包含 resource 资源目录,您可以直接跳转到聊天记录。' - } - - currentStep.value = 1 - await prefillKeysForAccount(mediaAccount.value) - } else { - error.value = res.message || '导入失败' - } - } catch (err) { - error.value = err.message || '导入过程中发生错误' - } finally { - loading.value = false - } -} - // 处理解密 const handleDecrypt = async () => { if (!validateForm()) { diff --git a/frontend/pages/index.vue b/frontend/pages/index.vue index 95995d7..6465479 100644 --- a/frontend/pages/index.vue +++ b/frontend/pages/index.vue @@ -41,6 +41,14 @@ 直接解密 + + @@ -49,27 +57,86 @@ 聊天预览 - - - - - - - - - 年度总结 - + + + +
+
+
+

+ + + + 确认导入账号 +

+ +
+
+ 头像 +
+
+
{{ importPreview.nick }}
+
{{ importPreview.username }}
+
+ +
+
+ 包含数据库 + +
+
+ 包含资源文件 + + {{ importPreview.has_resource ? '是' : '否' }} + +
+
+
+ +
+ + + + {{ importError }} +
+ +
+ + +
+
+
+
+