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 }} +
+ +
+ + +
+
+
+
+