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
@@ -14,6 +14,35 @@ function renderPage(
dbRoot: '',
showDbKey: false,
isFetching: false,
isConnecting: false,
guideStep: 1 as const,
environment: {
platform: 'win32',
osVersion: 'Windows fixture',
appVersion: 'v2.1.6',
wechatVersion: '4.1.9.57',
dataStructureVersion: '微信 4.xWCDB',
dataDirectoryDetected: true,
diagnosticSummary: 'WechatExplorer: v2.1.6',
autoDetectSupported: true,
wechatRunning: true,
accountIdentified: false,
dbConnected: false,
encryptionAvailable: true
},
accounts: [
{
id: 'account-a',
accountRoot: 'C:\\fixture\\account-a',
directoryName: 'account-a',
nickname: '脱敏账号 A',
wxid: 'wxid_fixture_a',
hasSavedDbKey: true,
loginStatus: 'unknown' as const,
selectedByInput: true
}
],
selectedAccountId: 'account-a',
status: '',
statusKind: 'normal' as const,
showMacKeyFaq: false,
@@ -21,8 +50,16 @@ function renderPage(
onModeChange: vi.fn(),
onDbKeyChange: vi.fn(),
onDbRootChange: vi.fn(),
onSelectAccount: vi.fn(),
onSelectDbRoot: vi.fn(),
onToggleDbKey: vi.fn(),
onAutoGetKey: vi.fn(),
onRefreshEnvironment: vi.fn(),
onGuideNext: vi.fn(),
onGuideBack: vi.fn(),
onGuideCancel: vi.fn(),
onValidateConnection: vi.fn(),
onCopyDiagnostics: vi.fn(),
onManualConnect: vi.fn(),
onPasteKey: vi.fn(),
onClearKey: vi.fn(),
@@ -52,4 +89,48 @@ describe('DatabaseConnectionPage', () => {
expect(onManualConnect).toHaveBeenCalledOnce()
expect(screen.getByRole('button', { name: '从剪贴板粘贴并安全保存' })).toBeEnabled()
})
it('restores directory editing and selection after a failed connection', async () => {
const onDbRootChange = vi.fn()
const onSelectDbRoot = vi.fn()
renderPage({
dbKey: 'b'.repeat(64),
dbRoot: 'Z:\\missing-wechat-data',
status: '微信数据目录不存在,请重新选择目录',
statusKind: 'error',
onDbRootChange,
onSelectDbRoot
})
await userEvent.clear(screen.getByLabelText('微信数据目录'))
await userEvent.type(screen.getByLabelText('微信数据目录'), 'C:\\fixture-account')
await userEvent.click(screen.getByRole('button', { name: '选择目录' }))
expect(onDbRootChange).toHaveBeenCalled()
expect(onSelectDbRoot).toHaveBeenCalledOnce()
expect(screen.getByRole('button', { name: '连接数据库' })).toBeEnabled()
})
it('supports forward, back, cancel and safe diagnostic actions in onboarding', async () => {
const onGuideNext = vi.fn()
const onCopyDiagnostics = vi.fn()
const { rerender, props } = renderPage({
mode: 'automatic',
guideStep: 1,
onGuideNext,
onCopyDiagnostics
})
expect(screen.getByText('4.1.9.57')).toBeVisible()
expect(screen.getByText('微信 4.xWCDB')).toBeVisible()
await userEvent.click(screen.getByRole('button', { name: '复制脱敏诊断摘要' }))
await userEvent.click(screen.getByRole('button', { name: '检查完成,继续' }))
expect(onCopyDiagnostics).toHaveBeenCalledOnce()
expect(onGuideNext).toHaveBeenCalledOnce()
rerender(<DatabaseConnectionPage {...props} mode="automatic" guideStep={2} />)
expect(screen.getByRole('button', { name: '我已准备好' })).toBeEnabled()
expect(screen.getByRole('button', { name: '返回上一步' })).toBeEnabled()
expect(screen.getByRole('button', { name: '取消并重新检查' })).toBeEnabled()
})
})