fix(chat): avoid group members sidebar stuck on first init

This commit is contained in:
tisonhuang
2026-03-02 18:45:47 +08:00
parent ce683a539d
commit 698d2c96d7
2 changed files with 40 additions and 2 deletions

View File

@@ -1425,7 +1425,6 @@ function registerIpcHandlers() {
return groupAnalyticsService.getGroupMembersPanelData(chatroomId, normalizedOptions) return groupAnalyticsService.getGroupMembersPanelData(chatroomId, normalizedOptions)
} }
) )
})
ipcMain.handle('groupAnalytics:getGroupMessageRanking', async (_, chatroomId: string, limit?: number, startTime?: number, endTime?: number) => { ipcMain.handle('groupAnalytics:getGroupMessageRanking', async (_, chatroomId: string, limit?: number, startTime?: number, endTime?: number) => {
return groupAnalyticsService.getGroupMessageRanking(chatroomId, limit, startTime, endTime) return groupAnalyticsService.getGroupMessageRanking(chatroomId, limit, startTime, endTime)

View File

@@ -63,6 +63,8 @@ interface GroupMemberContactInfo {
class GroupAnalyticsService { class GroupAnalyticsService {
private configService: ConfigService private configService: ConfigService
private readonly groupMembersPanelCacheTtlMs = 10 * 60 * 1000 private readonly groupMembersPanelCacheTtlMs = 10 * 60 * 1000
private readonly groupMembersPanelMembersTimeoutMs = 12 * 1000
private readonly groupMembersPanelFullTimeoutMs = 25 * 1000
private readonly groupMembersPanelCache = new Map<string, { updatedAt: number; data: GroupMembersPanelEntry[] }>() private readonly groupMembersPanelCache = new Map<string, { updatedAt: number; data: GroupMembersPanelEntry[] }>()
private readonly groupMembersPanelInFlight = new Map< private readonly groupMembersPanelInFlight = new Map<
string, string,
@@ -485,6 +487,31 @@ class GroupAnalyticsService {
} }
} }
private async withPromiseTimeout<T>(
promise: Promise<T>,
timeoutMs: number,
timeoutResult: T
): Promise<T> {
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
return promise
}
let timeoutTimer: ReturnType<typeof setTimeout> | null = null
const timeoutPromise = new Promise<T>((resolve) => {
timeoutTimer = setTimeout(() => {
resolve(timeoutResult)
}, timeoutMs)
})
try {
return await Promise.race([promise, timeoutPromise])
} finally {
if (timeoutTimer) {
clearTimeout(timeoutTimer)
}
}
}
private async buildGroupMemberContactLookup(usernames: string[]): Promise<Map<string, GroupMemberContactInfo>> { private async buildGroupMemberContactLookup(usernames: string[]): Promise<Map<string, GroupMemberContactInfo>> {
const lookup = new Map<string, GroupMemberContactInfo>() const lookup = new Map<string, GroupMemberContactInfo>()
const candidates = this.buildIdCandidates(usernames) const candidates = this.buildIdCandidates(usernames)
@@ -911,7 +938,19 @@ class GroupAnalyticsService {
const conn = await this.ensureConnected() const conn = await this.ensureConnected()
if (!conn.success) return { success: false, error: conn.error } if (!conn.success) return { success: false, error: conn.error }
const fresh = await this.loadGroupMembersPanelDataFresh(normalizedChatroomId, includeMessageCounts) const timeoutMs = includeMessageCounts
? this.groupMembersPanelFullTimeoutMs
: this.groupMembersPanelMembersTimeoutMs
const fresh = await this.withPromiseTimeout(
this.loadGroupMembersPanelDataFresh(normalizedChatroomId, includeMessageCounts),
timeoutMs,
{
success: false,
error: includeMessageCounts
? '群成员发言统计加载超时,请稍后重试'
: '群成员列表加载超时,请稍后重试'
}
)
if (!fresh.success || !fresh.data) { if (!fresh.success || !fresh.data) {
return { success: false, error: fresh.error || '获取群成员面板数据失败' } return { success: false, error: fresh.error || '获取群成员面板数据失败' }
} }