feat(export): add sns stats card and conversation tab updates

This commit is contained in:
tisonhuang
2026-03-01 15:20:08 +08:00
parent e686bb6247
commit 596baad296
9 changed files with 491 additions and 188 deletions

View File

@@ -1020,6 +1020,10 @@ function registerIpcHandlers() {
return snsService.getSnsUsernames()
})
ipcMain.handle('sns:getExportStats', async () => {
return snsService.getExportStats()
})
ipcMain.handle('sns:debugResource', async (_, url: string) => {
return snsService.debugResource(url)
})

View File

@@ -288,6 +288,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
getTimeline: (limit: number, offset: number, usernames?: string[], keyword?: string, startTime?: number, endTime?: number) =>
ipcRenderer.invoke('sns:getTimeline', limit, offset, usernames, keyword, startTime, endTime),
getSnsUsernames: () => ipcRenderer.invoke('sns:getSnsUsernames'),
getExportStats: () => ipcRenderer.invoke('sns:getExportStats'),
debugResource: (url: string) => ipcRenderer.invoke('sns:debugResource', url),
proxyImage: (payload: { url: string; key?: string | number }) => ipcRenderer.invoke('sns:proxyImage', payload),
downloadImage: (payload: { url: string; key?: string | number }) => ipcRenderer.invoke('sns:downloadImage', payload),

View File

@@ -235,6 +235,13 @@ class SnsService {
this.contactCache = new ContactCacheService(this.configService.get('cachePath') as string)
}
private parseCountValue(row: any): number {
if (!row || typeof row !== 'object') return 0
const raw = row.total ?? row.count ?? row.cnt ?? Object.values(row)[0]
const num = Number(raw)
return Number.isFinite(num) && num > 0 ? Math.floor(num) : 0
}
private parseLikesFromXml(xml: string): string[] {
if (!xml) return []
const likes: string[] = []
@@ -359,6 +366,39 @@ class SnsService {
return { success: true, usernames: result.rows.map((r: any) => r.user_name).filter(Boolean) }
}
async getExportStats(): Promise<{ success: boolean; data?: { totalPosts: number; totalFriends: number }; error?: string }> {
try {
let totalPosts = 0
const postCountResult = await wcdbService.execQuery('sns', null, 'SELECT COUNT(1) AS total FROM SnsTimeLine')
if (postCountResult.success && postCountResult.rows && postCountResult.rows.length > 0) {
totalPosts = this.parseCountValue(postCountResult.rows[0])
}
let totalFriends = 0
const friendCountPrimary = await wcdbService.execQuery(
'sns',
null,
"SELECT COUNT(DISTINCT user_name) AS total FROM SnsTimeLine WHERE user_name IS NOT NULL AND user_name <> ''"
)
if (friendCountPrimary.success && friendCountPrimary.rows && friendCountPrimary.rows.length > 0) {
totalFriends = this.parseCountValue(friendCountPrimary.rows[0])
} else {
const friendCountFallback = await wcdbService.execQuery(
'sns',
null,
"SELECT COUNT(DISTINCT userName) AS total FROM SnsTimeLine WHERE userName IS NOT NULL AND userName <> ''"
)
if (friendCountFallback.success && friendCountFallback.rows && friendCountFallback.rows.length > 0) {
totalFriends = this.parseCountValue(friendCountFallback.rows[0])
}
}
return { success: true, data: { totalPosts, totalFriends } }
} catch (e) {
return { success: false, error: String(e) }
}
}
// 安装朋友圈删除拦截
async installSnsBlockDeleteTrigger(): Promise<{ success: boolean; alreadyInstalled?: boolean; error?: string }> {
return wcdbService.installSnsBlockDeleteTrigger()