Skip to content

Commit c9f378c

Browse files
committed
Merge remote-tracking branch 'upstream/main' into feat/wx-key
2 parents b3d12fd + a20df89 commit c9f378c

25 files changed

Lines changed: 4337 additions & 448 deletions

README.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<div align="center">
66
<h1>WeChatDataAnalysis - 微信数据库解密与分析工具</h1>
77
<p>一个专门用于微信4.x版本数据库解密的工具(支持聊天记录实时更新)</p>
8-
<p><b>特别致谢</b>:<a href="https://github.com/ycccccccy/echotrace">echotrace</a>(本项目大量功能参考其实现,提供了重要技术支持)</p>
8+
<p><b>特别致谢</b>:<a href="https://github.com/ycccccccy/echotrace">echotrace</a>、<a href="https://github.com/hicccc77/WeFlow">WeFlow</a>(本项目大量功能参考其实现,提供了重要技术支持)</p>
99
<img src="https://img.shields.io/github/v/tag/LifeArchiveProject/WeChatDataAnalysis" alt="Version" />
1010
<img src="https://img.shields.io/github/stars/LifeArchiveProject/WeChatDataAnalysis" alt="Stars" />
1111
<img src="https://gh-down-badges.linkof.link/LifeArchiveProject/WeChatDataAnalysis" alt="Downloads" />
@@ -66,7 +66,7 @@
6666

6767
## 年度总结
6868

69-
年度总结现在支持 4 种不同风格(style1-4)。如果你对某个风格有更好的修改建议,或有新风格的点子,欢迎到 Issue 区反馈:https://github.com/LifeArchiveProject/WeChatDataAnalysis/issues
69+
年度总结现在支持 3 种不同风格(style1、style2、style3)。如果你对某个风格有更好的修改建议,或有新风格的点子,欢迎到 Issue 区反馈:https://github.com/LifeArchiveProject/WeChatDataAnalysis/issues
7070

7171
> ⚠️ **提醒**:年度总结目前还不是最终版本,后续还会增加新总结或新风格。
7272
@@ -82,12 +82,10 @@
8282
<td><img src="frontend/public/style2.png" alt="年度总结 Style 2" width="400"/></td>
8383
</tr>
8484
<tr>
85-
<td align="center"><b>Style 3</b></td>
86-
<td align="center"><b>Style 4</b></td>
85+
<td align="center" colspan="2"><b>Style 3</b></td>
8786
</tr>
8887
<tr>
89-
<td><img src="frontend/public/style3.png" alt="年度总结 Style 3" width="400"/></td>
90-
<td><img src="frontend/public/style4.png" alt="年度总结 Style 4" width="400"/></td>
88+
<td align="center" colspan="2"><img src="frontend/public/style3.png" alt="年度总结 Style 3" width="400"/></td>
9189
</tr>
9290
</table>
9391

@@ -196,19 +194,22 @@ npm run dist
196194
1. **[echotrace](https://github.com/ycccccccy/echotrace)** - 微信数据解析/取证工具
197195
- 本项目大量功能参考并复用其实现思路,提供了重要技术支持
198196

199-
2. **[wx_key](https://github.com/ycccccccy/wx_key)** - 微信数据库与图片密钥提取工具
197+
2. **[WeFlow](https://github.com/hicccc77/WeFlow)** - 微信数据分析工具
198+
- 提供了重要的功能参考和技术支持
199+
200+
3. **[wx_key](https://github.com/ycccccccy/wx_key)** - 微信数据库与图片密钥提取工具
200201
- 支持获取微信 4.x 数据库密钥与缓存图片密钥
201202
- 本项目推荐使用此工具获取密钥
202203

203-
3. **[wechat-dump-rs](https://github.com/0xlane/wechat-dump-rs)** - Rust实现的微信数据库解密工具
204+
4. **[wechat-dump-rs](https://github.com/0xlane/wechat-dump-rs)** - Rust实现的微信数据库解密工具
204205
- 提供了SQLCipher 4.0解密的正确实现参考
205206
- 本项目的HMAC验证和页面处理逻辑基于此项目的实现
206207

207-
4. **[oh-my-wechat](https://github.com/chclt/oh-my-wechat)** - 微信聊天记录查看工具
208+
5. **[oh-my-wechat](https://github.com/chclt/oh-my-wechat)** - 微信聊天记录查看工具
208209
- 提供了优秀的聊天记录界面设计参考
209210
- 本项目的聊天界面风格参考了此项目的实现
210211

211-
5. **[vue3-wechat-tool](https://github.com/Ele-Cat/vue3-wechat-tool)** - 微信聊天记录工具(Vue3)
212+
6. **[vue3-wechat-tool](https://github.com/Ele-Cat/vue3-wechat-tool)** - 微信聊天记录工具(Vue3)
212213
- 提供了聊天记录展示与交互的实现参考
213214

214215
## Star History
@@ -222,3 +223,4 @@ npm run dist
222223
---
223224

224225
**免责声明**: 本工具仅供学习研究使用,使用者需自行承担使用风险。开发者不对因使用本工具造成的任何损失负责。
226+

desktop/src/main.cjs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,25 @@ function registerWindowIpc() {
611611
return getCloseBehavior();
612612
}
613613
});
614+
615+
ipcMain.handle("dialog:chooseDirectory", async (_event, options) => {
616+
try {
617+
const result = await dialog.showOpenDialog({
618+
title: String(options?.title || "选择文件夹"),
619+
properties: ["openDirectory", "createDirectory"],
620+
});
621+
return {
622+
canceled: !!result?.canceled,
623+
filePaths: Array.isArray(result?.filePaths) ? result.filePaths : [],
624+
};
625+
} catch (err) {
626+
logMain(`[main] dialog:chooseDirectory failed: ${err?.message || err}`);
627+
return {
628+
canceled: true,
629+
filePaths: [],
630+
};
631+
}
632+
});
614633
}
615634

616635
async function main() {

desktop/src/preload.cjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ contextBridge.exposeInMainWorld("wechatDesktop", {
1111

1212
getCloseBehavior: () => ipcRenderer.invoke("app:getCloseBehavior"),
1313
setCloseBehavior: (behavior) => ipcRenderer.invoke("app:setCloseBehavior", String(behavior || "")),
14+
15+
chooseDirectory: (options = {}) => ipcRenderer.invoke("dialog:chooseDirectory", options),
1416
});

frontend/app.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ onBeforeUnmount(() => {
3030
})
3131
3232
const route = useRoute()
33-
const isChatRoute = computed(() => route.path?.startsWith('/chat') || route.path?.startsWith('/sns'))
33+
const isChatRoute = computed(() => route.path?.startsWith('/chat') || route.path?.startsWith('/sns') || route.path?.startsWith('/contacts'))
3434
3535
const rootClass = computed(() => {
3636
const base = 'bg-gradient-to-br from-green-50 via-emerald-50 to-green-100'

frontend/assets/css/tailwind.css

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -730,35 +730,39 @@
730730
}
731731

732732
.header-btn {
733-
@apply flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-lg bg-white border border-gray-200 text-gray-700 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed;
733+
@apply flex items-center gap-1.5 text-xs px-3 py-1.5 rounded-md bg-white border border-gray-200 text-gray-700 transition-all duration-150 disabled:opacity-50 disabled:cursor-not-allowed shadow-sm;
734734
}
735735

736736
.header-btn:hover:not(:disabled) {
737-
@apply bg-gray-50 border-gray-300;
737+
@apply bg-gray-50 border-gray-300 shadow;
738738
}
739739

740740
.header-btn:active:not(:disabled) {
741-
@apply bg-gray-100;
741+
@apply bg-gray-100 scale-95;
742+
}
743+
744+
.header-btn svg {
745+
@apply w-3.5 h-3.5;
742746
}
743747

744748
.header-btn-icon {
745-
@apply w-8 h-8 flex items-center justify-center rounded-lg bg-white border border-gray-200 text-gray-600 transition-all duration-200;
749+
@apply w-8 h-8 flex items-center justify-center rounded-lg bg-transparent border border-transparent text-gray-600 transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed;
746750
}
747751

748752
.header-btn-icon:hover {
749-
@apply bg-gray-50 border-gray-300 text-gray-800;
753+
@apply bg-transparent border-transparent text-gray-800;
750754
}
751755

752756
.header-btn-icon-active {
753-
@apply bg-[#03C160]/10 border-[#03C160] text-[#03C160];
757+
@apply bg-transparent border-transparent text-[#03C160];
754758
}
755759

756760
.header-btn-icon-active:hover {
757-
@apply bg-[#03C160]/15;
761+
@apply bg-transparent;
758762
}
759763

760764
.message-filter-select {
761-
@apply text-xs px-2 py-1.5 rounded-lg bg-white border border-gray-200 text-gray-700 focus:outline-none focus:ring-2 focus:ring-[#03C160]/20 focus:border-[#03C160] transition-all disabled:opacity-50 disabled:cursor-not-allowed;
765+
@apply text-xs px-2 py-1.5 rounded-lg bg-transparent border-0 text-gray-700 focus:outline-none focus:ring-0 transition-all disabled:opacity-50 disabled:cursor-not-allowed;
762766
}
763767

764768
/* 搜索侧边栏样式 */

frontend/composables/useApi.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ export const useApi = () => {
292292
message_types: Array.isArray(data.message_types) ? data.message_types : [],
293293
include_media: data.include_media == null ? true : !!data.include_media,
294294
media_kinds: Array.isArray(data.media_kinds) ? data.media_kinds : ['image', 'emoji', 'video', 'video_thumb', 'voice', 'file'],
295+
output_dir: data.output_dir == null ? null : String(data.output_dir || '').trim(),
295296
allow_process_key_extract: !!data.allow_process_key_extract,
296297
privacy_mode: !!data.privacy_mode,
297298
file_name: data.file_name || null
@@ -313,6 +314,36 @@ export const useApi = () => {
313314
return await request(`/chat/exports/${encodeURIComponent(String(exportId))}`, { method: 'DELETE' })
314315
}
315316

317+
// 联系人
318+
const listChatContacts = async (params = {}) => {
319+
const query = new URLSearchParams()
320+
if (params && params.account) query.set('account', params.account)
321+
if (params && params.keyword) query.set('keyword', params.keyword)
322+
if (params && params.include_friends != null) query.set('include_friends', String(!!params.include_friends))
323+
if (params && params.include_groups != null) query.set('include_groups', String(!!params.include_groups))
324+
if (params && params.include_officials != null) query.set('include_officials', String(!!params.include_officials))
325+
const url = '/chat/contacts' + (query.toString() ? `?${query.toString()}` : '')
326+
return await request(url)
327+
}
328+
329+
const exportChatContacts = async (payload = {}) => {
330+
return await request('/chat/contacts/export', {
331+
method: 'POST',
332+
body: {
333+
account: payload.account || null,
334+
output_dir: payload.output_dir || '',
335+
format: payload.format || 'json',
336+
include_avatar_link: payload.include_avatar_link == null ? true : !!payload.include_avatar_link,
337+
keyword: payload.keyword || null,
338+
contact_types: {
339+
friends: payload?.contact_types?.friends == null ? true : !!payload.contact_types.friends,
340+
groups: payload?.contact_types?.groups == null ? true : !!payload.contact_types.groups,
341+
officials: payload?.contact_types?.officials == null ? true : !!payload.contact_types.officials,
342+
}
343+
}
344+
})
345+
}
346+
316347
// WeChat Wrapped(年度总结)
317348
const getWrappedAnnual = async (params = {}) => {
318349
const query = new URLSearchParams()
@@ -388,6 +419,8 @@ export const useApi = () => {
388419
getChatExport,
389420
listChatExports,
390421
cancelChatExport,
422+
listChatContacts,
423+
exportChatContacts,
391424
getWrappedAnnual,
392425
getWrappedAnnualMeta,
393426
getWrappedAnnualCard,

0 commit comments

Comments
 (0)