mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-24 23:06:51 +00:00
fix: 修复了群头像导出丢失的问题
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -13,6 +13,7 @@ dist
|
|||||||
dist-electron
|
dist-electron
|
||||||
dist-ssr
|
dist-ssr
|
||||||
*.local
|
*.local
|
||||||
|
test/
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ interface ChatLabMeta {
|
|||||||
platform: string
|
platform: string
|
||||||
type: 'group' | 'private'
|
type: 'group' | 'private'
|
||||||
groupId?: string
|
groupId?: string
|
||||||
|
groupAvatar?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ChatLabMember {
|
interface ChatLabMember {
|
||||||
@@ -425,6 +426,81 @@ class ExportService {
|
|||||||
return { rows, memberSet, firstTime, lastTime }
|
return { rows, memberSet, firstTime, lastTime }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 补齐群成员,避免只导出发言者导致头像缺失
|
||||||
|
private async mergeGroupMembers(
|
||||||
|
chatroomId: string,
|
||||||
|
memberSet: Map<string, { member: ChatLabMember; avatarUrl?: string }>,
|
||||||
|
includeAvatars: boolean
|
||||||
|
): Promise<void> {
|
||||||
|
const result = await wcdbService.getGroupMembers(chatroomId)
|
||||||
|
if (!result.success || !result.members || result.members.length === 0) return
|
||||||
|
|
||||||
|
const rawMembers = result.members as Array<{
|
||||||
|
username?: string
|
||||||
|
avatarUrl?: string
|
||||||
|
nickname?: string
|
||||||
|
displayName?: string
|
||||||
|
remark?: string
|
||||||
|
originalName?: string
|
||||||
|
}>
|
||||||
|
const usernames = rawMembers
|
||||||
|
.map((member) => member.username)
|
||||||
|
.filter((username): username is string => Boolean(username))
|
||||||
|
if (usernames.length === 0) return
|
||||||
|
|
||||||
|
const lookupUsernames = new Set<string>()
|
||||||
|
for (const username of usernames) {
|
||||||
|
lookupUsernames.add(username)
|
||||||
|
const cleaned = this.cleanAccountDirName(username)
|
||||||
|
if (cleaned && cleaned !== username) {
|
||||||
|
lookupUsernames.add(cleaned)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const [displayNames, avatarUrls] = await Promise.all([
|
||||||
|
wcdbService.getDisplayNames(Array.from(lookupUsernames)),
|
||||||
|
includeAvatars ? wcdbService.getAvatarUrls(Array.from(lookupUsernames)) : Promise.resolve({ success: true, map: {} })
|
||||||
|
])
|
||||||
|
|
||||||
|
for (const member of rawMembers) {
|
||||||
|
const username = member.username
|
||||||
|
if (!username) continue
|
||||||
|
|
||||||
|
const cleaned = this.cleanAccountDirName(username)
|
||||||
|
const displayName = displayNames.success && displayNames.map
|
||||||
|
? (displayNames.map[username] || (cleaned ? displayNames.map[cleaned] : undefined) || username)
|
||||||
|
: username
|
||||||
|
const groupNickname = member.nickname || member.displayName || member.remark || member.originalName
|
||||||
|
const avatarUrl = includeAvatars && avatarUrls.success && avatarUrls.map
|
||||||
|
? (avatarUrls.map[username] || (cleaned ? avatarUrls.map[cleaned] : undefined) || member.avatarUrl)
|
||||||
|
: member.avatarUrl
|
||||||
|
|
||||||
|
const existing = memberSet.get(username)
|
||||||
|
if (existing) {
|
||||||
|
if (displayName && existing.member.accountName === existing.member.platformId && displayName !== existing.member.platformId) {
|
||||||
|
existing.member.accountName = displayName
|
||||||
|
}
|
||||||
|
if (groupNickname && !existing.member.groupNickname) {
|
||||||
|
existing.member.groupNickname = groupNickname
|
||||||
|
}
|
||||||
|
if (!existing.avatarUrl && avatarUrl) {
|
||||||
|
existing.avatarUrl = avatarUrl
|
||||||
|
}
|
||||||
|
memberSet.set(username, existing)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const chatlabMember: ChatLabMember = {
|
||||||
|
platformId: username,
|
||||||
|
accountName: displayName
|
||||||
|
}
|
||||||
|
if (groupNickname) {
|
||||||
|
chatlabMember.groupNickname = groupNickname
|
||||||
|
}
|
||||||
|
memberSet.set(username, { member: chatlabMember, avatarUrl })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private resolveAvatarFile(avatarUrl?: string): { data?: Buffer; sourcePath?: string; sourceUrl?: string; ext: string; mime?: string } | null {
|
private resolveAvatarFile(avatarUrl?: string): { data?: Buffer; sourcePath?: string; sourceUrl?: string; ext: string; mime?: string } | null {
|
||||||
if (!avatarUrl) return null
|
if (!avatarUrl) return null
|
||||||
if (avatarUrl.startsWith('data:')) {
|
if (avatarUrl.startsWith('data:')) {
|
||||||
@@ -567,6 +643,9 @@ class ExportService {
|
|||||||
|
|
||||||
const collected = await this.collectMessages(sessionId, cleanedMyWxid, options.dateRange)
|
const collected = await this.collectMessages(sessionId, cleanedMyWxid, options.dateRange)
|
||||||
const allMessages = collected.rows
|
const allMessages = collected.rows
|
||||||
|
if (isGroup) {
|
||||||
|
await this.mergeGroupMembers(sessionId, collected.memberSet, options.exportAvatars === true)
|
||||||
|
}
|
||||||
|
|
||||||
allMessages.sort((a, b) => a.createTime - b.createTime)
|
allMessages.sort((a, b) => a.createTime - b.createTime)
|
||||||
|
|
||||||
@@ -585,6 +664,7 @@ class ExportService {
|
|||||||
return {
|
return {
|
||||||
sender: msg.senderUsername,
|
sender: msg.senderUsername,
|
||||||
accountName: memberInfo.accountName,
|
accountName: memberInfo.accountName,
|
||||||
|
groupNickname: memberInfo.groupNickname,
|
||||||
timestamp: msg.createTime,
|
timestamp: msg.createTime,
|
||||||
type: this.convertMessageType(msg.localType, msg.content),
|
type: this.convertMessageType(msg.localType, msg.content),
|
||||||
content: this.parseMessageContent(msg.content, msg.localType)
|
content: this.parseMessageContent(msg.content, msg.localType)
|
||||||
@@ -603,6 +683,7 @@ class ExportService {
|
|||||||
)
|
)
|
||||||
: new Map<string, string>()
|
: new Map<string, string>()
|
||||||
|
|
||||||
|
const sessionAvatar = avatarMap.get(sessionId)
|
||||||
const members = Array.from(collected.memberSet.values()).map((info) => {
|
const members = Array.from(collected.memberSet.values()).map((info) => {
|
||||||
const avatar = avatarMap.get(info.member.platformId)
|
const avatar = avatarMap.get(info.member.platformId)
|
||||||
return avatar ? { ...info.member, avatar } : info.member
|
return avatar ? { ...info.member, avatar } : info.member
|
||||||
@@ -618,7 +699,8 @@ class ExportService {
|
|||||||
name: sessionInfo.displayName,
|
name: sessionInfo.displayName,
|
||||||
platform: 'wechat',
|
platform: 'wechat',
|
||||||
type: isGroup ? 'group' : 'private',
|
type: isGroup ? 'group' : 'private',
|
||||||
...(isGroup && { groupId: sessionId })
|
...(isGroup && { groupId: sessionId }),
|
||||||
|
...(sessionAvatar && { groupAvatar: sessionAvatar })
|
||||||
},
|
},
|
||||||
members,
|
members,
|
||||||
messages: chatLabMessages
|
messages: chatLabMessages
|
||||||
|
|||||||
Reference in New Issue
Block a user