mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-25 15:25:50 +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 // 用于排序
|
sortTimestamp: number // 用于排序
|
||||||
lastTimestamp: number // 用于显示时间
|
lastTimestamp: number // 用于显示时间
|
||||||
lastMsgType: number
|
lastMsgType: number
|
||||||
|
messageCountHint?: number
|
||||||
displayName?: string
|
displayName?: string
|
||||||
avatarUrl?: string
|
avatarUrl?: string
|
||||||
lastMsgSender?: string
|
lastMsgSender?: string
|
||||||
@@ -421,6 +422,21 @@ class ChatService {
|
|||||||
|
|
||||||
const summary = this.cleanString(row.summary || row.digest || row.last_msg || row.lastMsg || '')
|
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 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
|
let displayName = username
|
||||||
@@ -439,6 +455,7 @@ class ChatService {
|
|||||||
sortTimestamp: sortTs,
|
sortTimestamp: sortTs,
|
||||||
lastTimestamp: lastTs,
|
lastTimestamp: lastTs,
|
||||||
lastMsgType,
|
lastMsgType,
|
||||||
|
messageCountHint,
|
||||||
displayName,
|
displayName,
|
||||||
avatarUrl,
|
avatarUrl,
|
||||||
lastMsgSender: row.last_msg_sender,
|
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 {
|
try {
|
||||||
const result = await wcdbService.getMessageCount(sessionId)
|
const result = await wcdbService.getMessageCounts(batch)
|
||||||
const nextCount = result.success && typeof result.count === 'number' ? result.count : 0
|
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
|
counts[sessionId] = nextCount
|
||||||
this.sessionMessageCountCache.set(sessionId, {
|
this.sessionMessageCountCache.set(sessionId, {
|
||||||
count: nextCount,
|
count: nextCount,
|
||||||
updatedAt: Date.now()
|
updatedAt: nowTs
|
||||||
})
|
|
||||||
} catch {
|
|
||||||
counts[sessionId] = 0
|
|
||||||
this.sessionMessageCountCache.set(sessionId, {
|
|
||||||
count: 0,
|
|
||||||
updatedAt: Date.now()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
return { success: true, counts }
|
return { success: true, counts }
|
||||||
} catch (e) {
|
} 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 }> {
|
async getDisplayNames(usernames: string[]): Promise<{ success: boolean; map?: Record<string, string>; error?: string }> {
|
||||||
if (!this.ensureReady()) {
|
if (!this.ensureReady()) {
|
||||||
return { success: false, error: 'WCDB 未连接' }
|
return { success: false, error: 'WCDB 未连接' }
|
||||||
@@ -2093,4 +2127,3 @@ export class WcdbCore {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -218,6 +218,10 @@ export class WcdbService {
|
|||||||
return this.callWorker('getMessageCount', { sessionId })
|
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':
|
case 'getMessageCount':
|
||||||
result = await core.getMessageCount(payload.sessionId)
|
result = await core.getMessageCount(payload.sessionId)
|
||||||
break
|
break
|
||||||
|
case 'getMessageCounts':
|
||||||
|
result = await core.getMessageCounts(payload.sessionIds)
|
||||||
|
break
|
||||||
case 'getDisplayNames':
|
case 'getDisplayNames':
|
||||||
result = await core.getDisplayNames(payload.usernames)
|
result = await core.getDisplayNames(payload.usernames)
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -624,6 +624,10 @@ function ExportPage() {
|
|||||||
const count = prev[session.username]
|
const count = prev[session.username]
|
||||||
if (typeof count === 'number') {
|
if (typeof count === 'number') {
|
||||||
next[session.username] = count
|
next[session.username] = count
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (typeof session.messageCountHint === 'number' && Number.isFinite(session.messageCountHint) && session.messageCountHint >= 0) {
|
||||||
|
next[session.username] = Math.floor(session.messageCountHint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return next
|
return next
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export interface ChatSession {
|
|||||||
sortTimestamp: number // 用于排序
|
sortTimestamp: number // 用于排序
|
||||||
lastTimestamp: number // 用于显示时间
|
lastTimestamp: number // 用于显示时间
|
||||||
lastMsgType: number
|
lastMsgType: number
|
||||||
|
messageCountHint?: number // 会话总消息数提示(若底层直接可取)
|
||||||
displayName?: string
|
displayName?: string
|
||||||
avatarUrl?: string
|
avatarUrl?: string
|
||||||
lastMsgSender?: string
|
lastMsgSender?: string
|
||||||
|
|||||||
Reference in New Issue
Block a user