Skip to content

Commit 9f8eb32

Browse files
committed
修复了一些已知问题
1 parent f292328 commit 9f8eb32

19 files changed

Lines changed: 1483 additions & 334 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
**一款现代化的微信聊天记录查看与分析工具**
88

99
[![License](https://img.shields.io/badge/license-CC--BY--NC--SA--4.0-blue.svg)](LICENSE)
10-
[![Version](https://img.shields.io/badge/version-2.1.9-green.svg)](package.json)
10+
[![Version](https://img.shields.io/badge/version-2.2.0-green.svg)](package.json)
1111
[![Platform](https://img.shields.io/badge/platform-Windows-0078D6.svg?logo=windows)]()
1212
[![Electron](https://img.shields.io/badge/Electron-39-47848F.svg?logo=electron)]()
1313
[![React](https://img.shields.io/badge/React-19-61DAFB.svg?logo=react)]()

electron/main.ts

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ protocol.registerSchemesAsPrivileged([
3535
stream: true,
3636
bypassCSP: true
3737
}
38+
},
39+
{
40+
scheme: 'local-image',
41+
privileges: {
42+
secure: true,
43+
supportFetchAPI: true,
44+
bypassCSP: true
45+
}
3846
}
3947
])
4048

@@ -116,7 +124,8 @@ function createWindow() {
116124
webPreferences: {
117125
preload: join(__dirname, 'preload.js'),
118126
contextIsolation: true,
119-
nodeIntegration: false
127+
nodeIntegration: false,
128+
webSecurity: false // 允许加载本地文件
120129
},
121130
titleBarStyle: 'hidden',
122131
titleBarOverlay: {
@@ -198,7 +207,8 @@ function createChatWindow() {
198207
webPreferences: {
199208
preload: join(__dirname, 'preload.js'),
200209
contextIsolation: true,
201-
nodeIntegration: false
210+
nodeIntegration: false,
211+
webSecurity: false // 允许加载本地文件
202212
},
203213
titleBarStyle: 'hidden',
204214
titleBarOverlay: {
@@ -274,7 +284,8 @@ function createGroupAnalyticsWindow() {
274284
webPreferences: {
275285
preload: join(__dirname, 'preload.js'),
276286
contextIsolation: true,
277-
nodeIntegration: false
287+
nodeIntegration: false,
288+
webSecurity: false // 允许加载本地文件
278289
},
279290
titleBarStyle: 'hidden',
280291
titleBarOverlay: {
@@ -361,7 +372,8 @@ function createChatHistoryWindow(sessionId: string, messageId: number) {
361372
webPreferences: {
362373
preload: join(__dirname, 'preload.js'),
363374
contextIsolation: true,
364-
nodeIntegration: false
375+
nodeIntegration: false,
376+
webSecurity: false // 允许加载本地文件
365377
},
366378
titleBarStyle: 'hidden',
367379
titleBarOverlay: {
@@ -428,7 +440,8 @@ function createAnnualReportWindow(year: number) {
428440
webPreferences: {
429441
preload: join(__dirname, 'preload.js'),
430442
contextIsolation: true,
431-
nodeIntegration: false
443+
nodeIntegration: false,
444+
webSecurity: false // 允许加载本地文件
432445
},
433446
titleBarStyle: 'hidden',
434447
titleBarOverlay: {
@@ -501,7 +514,8 @@ function createAgreementWindow() {
501514
webPreferences: {
502515
preload: join(__dirname, 'preload.js'),
503516
contextIsolation: true,
504-
nodeIntegration: false
517+
nodeIntegration: false,
518+
webSecurity: false // 允许加载本地文件
505519
},
506520
titleBarStyle: 'hidden',
507521
titleBarOverlay: {
@@ -564,7 +578,8 @@ function createWelcomeWindow() {
564578
webPreferences: {
565579
preload: join(__dirname, 'preload.js'),
566580
contextIsolation: true,
567-
nodeIntegration: false
581+
nodeIntegration: false,
582+
webSecurity: false // 允许加载本地文件
568583
},
569584
show: false
570585
})
@@ -609,7 +624,8 @@ function createPurchaseWindow() {
609624
icon: iconPath,
610625
webPreferences: {
611626
contextIsolation: true,
612-
nodeIntegration: false
627+
nodeIntegration: false,
628+
webSecurity: false // 允许加载本地文件
613629
},
614630
title: '获取激活码 - 密语',
615631
show: false,
@@ -893,7 +909,8 @@ function createAISummaryWindow(sessionId: string, sessionName: string) {
893909
webPreferences: {
894910
preload: join(__dirname, 'preload.js'),
895911
contextIsolation: true,
896-
nodeIntegration: false
912+
nodeIntegration: false,
913+
webSecurity: false // 允许加载本地文件
897914
},
898915
// 使用自定义标题栏但保留原生窗口控件
899916
frame: false,
@@ -1724,6 +1741,10 @@ function registerIpcHandlers() {
17241741
return chatService.getContactAvatar(username)
17251742
})
17261743

1744+
ipcMain.handle('chat:resolveTransferDisplayNames', async (_, chatroomId: string, payerUsername: string, receiverUsername: string) => {
1745+
return chatService.resolveTransferDisplayNames(chatroomId, payerUsername, receiverUsername)
1746+
})
1747+
17271748
ipcMain.handle('chat:getMyAvatarUrl', async () => {
17281749
const result = chatService.getMyAvatarUrl()
17291750
// 首页会调用这个接口,失败是正常的,不记录错误日志
@@ -1968,6 +1989,40 @@ function registerIpcHandlers() {
19681989
}
19691990
})
19701991

1992+
ipcMain.handle('cache:clearEmojis', async () => {
1993+
logService?.info('Cache', '开始清除表情包缓存')
1994+
try {
1995+
const cacheService = new (await import('./services/cacheService')).CacheService(configService!)
1996+
const result = await cacheService.clearEmojis()
1997+
if (result.success) {
1998+
logService?.info('Cache', '表情包缓存清除成功')
1999+
} else {
2000+
logService?.error('Cache', '表情包缓存清除失败', { error: result.error })
2001+
}
2002+
return result
2003+
} catch (e) {
2004+
logService?.error('Cache', '表情包缓存清除异常', { error: String(e) })
2005+
return { success: false, error: String(e) }
2006+
}
2007+
})
2008+
2009+
ipcMain.handle('cache:clearDatabases', async () => {
2010+
logService?.info('Cache', '开始清除数据库缓存')
2011+
try {
2012+
const cacheService = new (await import('./services/cacheService')).CacheService(configService!)
2013+
const result = await cacheService.clearDatabases()
2014+
if (result.success) {
2015+
logService?.info('Cache', '数据库缓存清除成功')
2016+
} else {
2017+
logService?.error('Cache', '数据库缓存清除失败', { error: result.error })
2018+
}
2019+
return result
2020+
} catch (e) {
2021+
logService?.error('Cache', '数据库缓存清除异常', { error: String(e) })
2022+
return { success: false, error: String(e) }
2023+
}
2024+
})
2025+
19712026
ipcMain.handle('cache:clearAll', async () => {
19722027
logService?.info('Cache', '开始清除所有缓存')
19732028
try {
@@ -2835,7 +2890,8 @@ function createSplashWindow(): BrowserWindow {
28352890
webPreferences: {
28362891
preload: join(__dirname, 'preload.js'),
28372892
contextIsolation: true,
2838-
nodeIntegration: false
2893+
nodeIntegration: false,
2894+
webSecurity: false // 允许加载本地文件
28392895
},
28402896
backgroundColor: '#00000000' // 完全透明的背景色
28412897
})

electron/preload.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ contextBridge.exposeInMainWorld('electronAPI', {
208208
ipcRenderer.invoke('chat:getAllVoiceMessages', sessionId),
209209
getContact: (username: string) => ipcRenderer.invoke('chat:getContact', username),
210210
getContactAvatar: (username: string) => ipcRenderer.invoke('chat:getContactAvatar', username),
211+
resolveTransferDisplayNames: (chatroomId: string, payerUsername: string, receiverUsername: string) =>
212+
ipcRenderer.invoke('chat:resolveTransferDisplayNames', chatroomId, payerUsername, receiverUsername),
211213
getMyAvatarUrl: () => ipcRenderer.invoke('chat:getMyAvatarUrl'),
212214
getMyUserInfo: () => ipcRenderer.invoke('chat:getMyUserInfo'),
213215
downloadEmoji: (cdnUrl: string, md5?: string, productId?: string, createTime?: number) => ipcRenderer.invoke('chat:downloadEmoji', cdnUrl, md5, productId, createTime),
@@ -280,6 +282,8 @@ contextBridge.exposeInMainWorld('electronAPI', {
280282
},
281283
cache: {
282284
clearImages: () => ipcRenderer.invoke('cache:clearImages'),
285+
clearEmojis: () => ipcRenderer.invoke('cache:clearEmojis'),
286+
clearDatabases: () => ipcRenderer.invoke('cache:clearDatabases'),
283287
clearAll: () => ipcRenderer.invoke('cache:clearAll'),
284288
clearConfig: () => ipcRenderer.invoke('cache:clearConfig'),
285289
getCacheSize: () => ipcRenderer.invoke('cache:getCacheSize')

electron/services/cacheService.ts

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export class CacheService {
6262
// 兼容旧的 CipherTalk/Images 路径
6363
paths.push(join(documentsPath, 'CipherTalk', 'Images'))
6464

65-
return [...new Set(paths)] // 去重
65+
return Array.from(new Set(paths)) // 去重
6666
}
6767

6868
/**
@@ -85,58 +85,57 @@ export class CacheService {
8585
}
8686

8787
/**
88-
* 清除所有缓存
88+
* 清除表情包缓存
8989
*/
90-
async clearAll(): Promise<{ success: boolean; error?: string }> {
90+
async clearEmojis(): Promise<{ success: boolean; error?: string }> {
9191
try {
9292
const cachePath = this.getEffectiveCachePath()
93-
94-
if (!existsSync(cachePath)) {
95-
// 同时检查旧的 CipherTalk 目录
96-
const documentsPath = app.getPath('documents')
97-
const oldCipherTalkDir = join(documentsPath, 'CipherTalk')
98-
if (existsSync(oldCipherTalkDir)) {
99-
rmSync(oldCipherTalkDir, { recursive: true, force: true })
93+
const documentsPath = app.getPath('documents')
94+
const emojiPaths = [
95+
join(cachePath, 'Emojis'),
96+
join(documentsPath, 'CipherTalk', 'Emojis'),
97+
]
98+
for (const emojiPath of emojiPaths) {
99+
if (existsSync(emojiPath)) {
100+
rmSync(emojiPath, { recursive: true, force: true })
100101
}
101-
return { success: true }
102102
}
103+
return { success: true }
104+
} catch (e) {
105+
return { success: false, error: String(e) }
106+
}
107+
}
103108

104-
// 清除指定的缓存目录
105-
const dirsToRemove = ['images', 'Images', 'Emojis', 'logs']
106-
107-
for (const dir of dirsToRemove) {
108-
const dirPath = join(cachePath, dir)
109-
if (existsSync(dirPath)) {
110-
rmSync(dirPath, { recursive: true, force: true })
111-
}
109+
/**
110+
* 仅清除数据库缓存(解密后的 .db 文件),不删除图片、表情包、配置等
111+
*/
112+
async clearDatabases(): Promise<{ success: boolean; error?: string }> {
113+
try {
114+
const cachePath = this.getEffectiveCachePath()
115+
if (!existsSync(cachePath)) {
116+
return { success: true }
112117
}
113118

114-
// 获取配置的wxid
115119
const wxid = this.configService.get('myWxid')
116-
117120
if (wxid) {
118-
// 尝试多种可能的文件夹名称
119121
const possibleFolderNames = [
120-
wxid, // 完整的wxid
121-
wxid.replace('wxid_', ''), // 去掉wxid_前缀
122-
wxid.split('_').slice(0, 2).join('_'), // 取前两部分,如 wxid_7r9dov5f7mse12
122+
wxid,
123+
(wxid as string).replace('wxid_', ''),
124+
(wxid as string).split('_').slice(0, 2).join('_'),
123125
]
124-
125126
for (const folderName of possibleFolderNames) {
126127
const wxidFolderPath = join(cachePath, folderName)
127128
if (existsSync(wxidFolderPath)) {
128129
this.clearDbFilesInFolder(wxidFolderPath)
129-
break // 找到一个就停止
130+
break
130131
}
131132
}
132133
}
133-
134-
// 清除根目录下的.db文件
134+
135135
const files = readdirSync(cachePath)
136136
for (const file of files) {
137137
const filePath = join(cachePath, file)
138138
const stat = statSync(filePath)
139-
140139
if (stat.isFile() && file.endsWith('.db')) {
141140
rmSync(filePath, { force: true })
142141
}
@@ -148,6 +147,42 @@ export class CacheService {
148147
}
149148
}
150149

150+
/**
151+
* 清除所有缓存
152+
*/
153+
async clearAll(): Promise<{ success: boolean; error?: string }> {
154+
try {
155+
const cachePath = this.getEffectiveCachePath()
156+
157+
if (!existsSync(cachePath)) {
158+
// 同时检查旧的 CipherTalk 目录
159+
const documentsPath = app.getPath('documents')
160+
const oldCipherTalkDir = join(documentsPath, 'CipherTalk')
161+
if (existsSync(oldCipherTalkDir)) {
162+
rmSync(oldCipherTalkDir, { recursive: true, force: true })
163+
}
164+
return { success: true }
165+
}
166+
167+
// 清除指定的缓存目录
168+
const dirsToRemove = ['images', 'Images', 'Emojis', 'logs']
169+
170+
for (const dir of dirsToRemove) {
171+
const dirPath = join(cachePath, dir)
172+
if (existsSync(dirPath)) {
173+
rmSync(dirPath, { recursive: true, force: true })
174+
}
175+
}
176+
177+
// 清除数据库缓存
178+
await this.clearDatabases()
179+
180+
return { success: true }
181+
} catch (e) {
182+
return { success: false, error: String(e) }
183+
}
184+
}
185+
151186
/**
152187
* 清除文件夹中的.db文件
153188
*/

0 commit comments

Comments
 (0)