mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-24 23:06:51 +00:00
perf(export): batch message count retrieval for large session lists
This commit is contained in:
@@ -29,6 +29,7 @@ export interface ChatSession {
|
||||
sortTimestamp: number // 用于排序
|
||||
lastTimestamp: number // 用于显示时间
|
||||
lastMsgType: number
|
||||
messageCountHint?: number
|
||||
displayName?: string
|
||||
avatarUrl?: string
|
||||
lastMsgSender?: string
|
||||
@@ -421,6 +422,21 @@ class ChatService {
|
||||
|
||||
const summary = this.cleanString(row.summary || row.digest || row.last_msg || row.lastMsg || '')
|
||||
const lastMsgType = parseInt(row.last_msg_type || row.lastMsgType || '0', 10)
|
||||
const messageCountHintRaw =
|
||||
row.message_count ??
|
||||
row.messageCount ??
|
||||
row.msg_count ??
|
||||
row.msgCount ??
|
||||
row.total_count ??
|
||||
row.totalCount ??
|
||||
row.n_msg ??
|
||||
row.nMsg ??
|
||||
row.message_num ??
|
||||
row.messageNum
|
||||
const parsedMessageCountHint = Number(messageCountHintRaw)
|
||||
const messageCountHint = Number.isFinite(parsedMessageCountHint) && parsedMessageCountHint >= 0
|
||||
? Math.floor(parsedMessageCountHint)
|
||||
: undefined
|
||||
|
||||
// 先尝试从缓存获取联系人信息(快速路径)
|
||||
let displayName = username
|
||||
@@ -439,6 +455,7 @@ class ChatService {
|
||||
sortTimestamp: sortTs,
|
||||
lastTimestamp: lastTs,
|
||||
lastMsgType,
|
||||
messageCountHint,
|
||||
displayName,
|
||||
avatarUrl,
|
||||
lastMsgSender: row.last_msg_sender,
|
||||
@@ -812,23 +829,30 @@ class ChatService {
|
||||
}
|
||||
}
|
||||
|
||||
await this.forEachWithConcurrency(pendingSessionIds, 16, async (sessionId) => {
|
||||
const batchSize = 320
|
||||
for (let i = 0; i < pendingSessionIds.length; i += batchSize) {
|
||||
const batch = pendingSessionIds.slice(i, i + batchSize)
|
||||
let batchCounts: Record<string, number> = {}
|
||||
try {
|
||||
const result = await wcdbService.getMessageCount(sessionId)
|
||||
const nextCount = result.success && typeof result.count === 'number' ? result.count : 0
|
||||
const result = await wcdbService.getMessageCounts(batch)
|
||||
if (result.success && result.counts) {
|
||||
batchCounts = result.counts
|
||||
}
|
||||
} catch {
|
||||
// noop
|
||||
}
|
||||
|
||||
const nowTs = Date.now()
|
||||
for (const sessionId of batch) {
|
||||
const nextCountRaw = batchCounts[sessionId]
|
||||
const nextCount = Number.isFinite(nextCountRaw) ? Math.max(0, Math.floor(nextCountRaw)) : 0
|
||||
counts[sessionId] = nextCount
|
||||
this.sessionMessageCountCache.set(sessionId, {
|
||||
count: nextCount,
|
||||
updatedAt: Date.now()
|
||||
})
|
||||
} catch {
|
||||
counts[sessionId] = 0
|
||||
this.sessionMessageCountCache.set(sessionId, {
|
||||
count: 0,
|
||||
updatedAt: Date.now()
|
||||
updatedAt: nowTs
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return { success: true, counts }
|
||||
} catch (e) {
|
||||
|
||||
@@ -1144,6 +1144,40 @@ export class WcdbCore {
|
||||
}
|
||||
}
|
||||
|
||||
async getMessageCounts(sessionIds: string[]): Promise<{ success: boolean; counts?: Record<string, number>; error?: string }> {
|
||||
if (!this.ensureReady()) {
|
||||
return { success: false, error: 'WCDB 未连接' }
|
||||
}
|
||||
|
||||
const normalizedSessionIds = Array.from(
|
||||
new Set(
|
||||
(sessionIds || [])
|
||||
.map((id) => String(id || '').trim())
|
||||
.filter(Boolean)
|
||||
)
|
||||
)
|
||||
if (normalizedSessionIds.length === 0) {
|
||||
return { success: true, counts: {} }
|
||||
}
|
||||
|
||||
try {
|
||||
const counts: Record<string, number> = {}
|
||||
for (let i = 0; i < normalizedSessionIds.length; i += 1) {
|
||||
const sessionId = normalizedSessionIds[i]
|
||||
const outCount = [0]
|
||||
const result = this.wcdbGetMessageCount(this.handle, sessionId, outCount)
|
||||
counts[sessionId] = result === 0 && Number.isFinite(outCount[0]) ? Math.max(0, Math.floor(outCount[0])) : 0
|
||||
|
||||
if (i > 0 && i % 160 === 0) {
|
||||
await new Promise(resolve => setImmediate(resolve))
|
||||
}
|
||||
}
|
||||
return { success: true, counts }
|
||||
} catch (e) {
|
||||
return { success: false, error: String(e) }
|
||||
}
|
||||
}
|
||||
|
||||
async getDisplayNames(usernames: string[]): Promise<{ success: boolean; map?: Record<string, string>; error?: string }> {
|
||||
if (!this.ensureReady()) {
|
||||
return { success: false, error: 'WCDB 未连接' }
|
||||
@@ -2093,4 +2127,3 @@ export class WcdbCore {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -218,6 +218,10 @@ export class WcdbService {
|
||||
return this.callWorker('getMessageCount', { sessionId })
|
||||
}
|
||||
|
||||
async getMessageCounts(sessionIds: string[]): Promise<{ success: boolean; counts?: Record<string, number>; error?: string }> {
|
||||
return this.callWorker('getMessageCounts', { sessionIds })
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取联系人昵称
|
||||
*/
|
||||
|
||||
@@ -54,6 +54,9 @@ if (parentPort) {
|
||||
case 'getMessageCount':
|
||||
result = await core.getMessageCount(payload.sessionId)
|
||||
break
|
||||
case 'getMessageCounts':
|
||||
result = await core.getMessageCounts(payload.sessionIds)
|
||||
break
|
||||
case 'getDisplayNames':
|
||||
result = await core.getDisplayNames(payload.usernames)
|
||||
break
|
||||
|
||||
Reference in New Issue
Block a user