feat: 完善多账号连接诊断与聊天媒体导出

- 新增微信账号发现、环境诊断和分步数据库连接引导
- 支持按账号安全保存数据库密钥及快速切换账号
- 完善 WCDB 历史消息分片读取和分页状态提示
- 支持导出图片、视频和语音,提供原图优先及缩略图回退
- 更新安装指引、兼容版本说明和相关自动化测试
This commit is contained in:
Wxw-Gu
2026-08-03 10:43:14 +08:00
parent 224308f0e0
commit 08e1294e5d
37 changed files with 2011 additions and 255 deletions
+12 -6
View File
@@ -21,6 +21,7 @@ import type { AppUpdateState } from '../shared/app-update'
import type { CacheSummary } from '../shared/cache'
import type { ExportRequest, ExportJobProgress } from '../shared/export'
import type { ImageDecoderSelectionResult, ImageDecoderStatus } from '../shared/image-decryption'
import type { AccountDiscoveryResult } from '../shared/database-key'
// 渲染器的自定义 API
const api = {
@@ -40,7 +41,9 @@ const api = {
getCacheSummary: (): Promise<CacheSummary> => ipcRenderer.invoke('cache:getSummary'),
clearCache: (scope: 'bootstrap' | 'electron' | 'all'): Promise<CacheSummary> =>
ipcRenderer.invoke('cache:clear', scope),
initDb: (key: string) => ipcRenderer.invoke('db:init', key),
initDb: (key: string, accountRoot: string) => ipcRenderer.invoke('db:init', key, accountRoot),
discoverAccounts: (inputPath: string): Promise<AccountDiscoveryResult> =>
ipcRenderer.invoke('accounts:discover', inputPath),
getBootstrapCache: () => ipcRenderer.invoke('db:getBootstrapCache'),
getStartupCache: () => ipcRenderer.invoke('db:getStartupCache'),
getContacts: (filter?: string) => ipcRenderer.invoke('db:getContacts', filter),
@@ -98,10 +101,11 @@ const api = {
deleteGeneratedReport: (reportId: string) =>
ipcRenderer.invoke('report:deleteGenerated', reportId),
revealGroupReport: (filePath: string) => ipcRenderer.invoke('report:reveal', filePath),
getSavedDbKey: () => ipcRenderer.invoke('key:getSavedDbKey'),
getSavedDbKey: (accountRoot: string) => ipcRenderer.invoke('key:getSavedDbKey', accountRoot),
getDatabaseKeyEnvironment: () => ipcRenderer.invoke('key:getEnvironment'),
readDatabaseKeyClipboard: () => ipcRenderer.invoke('key:readClipboardDbKey'),
autoGetDbKey: (options?: { save?: boolean }) => ipcRenderer.invoke('key:autoGetDbKey', options),
autoGetDbKey: (accountRoot: string, options?: { save?: boolean }) =>
ipcRenderer.invoke('key:autoGetDbKey', accountRoot, options),
autoGetImageKey: (options?: { save?: boolean }) =>
ipcRenderer.invoke('key:autoGetImageKey', options),
getImageKeyConfig: () => ipcRenderer.invoke('image:getConfig'),
@@ -115,9 +119,11 @@ const api = {
saveImageKeyConfig: (request) => ipcRenderer.invoke('image:saveConfig', request),
testImageDecryption: (request) => ipcRenderer.invoke('image:testConfig', request),
clearImageKeyConfig: () => ipcRenderer.invoke('image:clearConfig'),
pasteAndSaveDbKey: () => ipcRenderer.invoke('key:pasteAndSaveDbKey'),
saveDbKey: (key: string) => ipcRenderer.invoke('key:saveDbKey', key),
clearSavedDbKey: () => ipcRenderer.invoke('key:clearSavedDbKey'),
pasteAndSaveDbKey: (accountRoot: string) =>
ipcRenderer.invoke('key:pasteAndSaveDbKey', accountRoot),
saveDbKey: (accountRoot: string, key: string) =>
ipcRenderer.invoke('key:saveDbKey', accountRoot, key),
clearSavedDbKey: (accountRoot: string) => ipcRenderer.invoke('key:clearSavedDbKey', accountRoot),
onWcdbChange: (callback: (payload: { type: string; json: string }) => void) => {
const listener = (
_event: Electron.IpcRendererEvent,