From d37f53e120ce05e010a5777a52ea1d8c1a656dc5 Mon Sep 17 00:00:00 2001 From: QingXiao <143726276+5xiao0qing5@users.noreply.github.com> Date: Fri, 23 Jan 2026 23:37:16 +0800 Subject: [PATCH] Adjust txt/excel export message formatting --- electron/services/exportService.ts | 109 +++++++++++++++++------------ 1 file changed, 66 insertions(+), 43 deletions(-) diff --git a/electron/services/exportService.ts b/electron/services/exportService.ts index ca6c395..16c52ab 100644 --- a/electron/services/exportService.ts +++ b/electron/services/exportService.ts @@ -305,6 +305,57 @@ class ExportService { } } + private formatPlainExportContent( + content: string, + localType: number, + options: { exportVoiceAsText?: boolean }, + voiceTranscript?: string + ): string { + const safeContent = content || '' + + if (localType === 3) return '[图片]' + if (localType === 1) return this.stripSenderPrefix(safeContent) + if (localType === 34) { + if (options.exportVoiceAsText) { + return voiceTranscript || '[语音消息 - 转文字失败]' + } + return '[其他消息]' + } + if (localType === 10000 || localType === 266287972401) { + return this.cleanSystemMessage(safeContent) + } + + const normalized = this.normalizeAppMessageContent(safeContent) + const isAppMessage = normalized.includes('') + if (localType === 49 || isAppMessage) { + const typeMatch = /(\d+)<\/type>/i.exec(normalized) + const subType = typeMatch ? parseInt(typeMatch[1], 10) : 0 + const title = this.extractXmlValue(normalized, 'title') || this.extractXmlValue(normalized, 'appname') + if (subType === 6) { + const fileName = this.extractXmlValue(normalized, 'filename') || title || '文件' + return `[文件]${fileName}` + } + if (subType === 19 || normalized.includes(' [col.id, col.label])) const lines: string[] = [] - lines.push(columnOrder.map((id) => columnLabelMap.get(id) || id).join('\t')) for (let i = 0; i < sortedMessages.length; i++) { const msg = sortedMessages[i] - const mediaKey = `${msg.localType}_${msg.localId}` - const mediaItem = mediaCache.get(mediaKey) || null - - let contentValue: string - if (mediaItem) { - contentValue = mediaItem.relativePath - } else if (msg.localType === 34 && options.exportVoiceAsText) { - contentValue = voiceTranscriptMap.get(msg.localId) || '[语音消息 - 转文字失败]' - } else { - contentValue = this.parseMessageContent(msg.content, msg.localType) || '' - } + const contentValue = this.formatPlainExportContent( + msg.content, + msg.localType, + options, + voiceTranscriptMap.get(msg.localId) + ) let senderRole: string let senderWxid: string @@ -2242,21 +2277,9 @@ class ExportService { } } - const values: Record = { - index: String(i + 1), - time: this.formatTimestamp(msg.createTime), - senderRole, - senderNickname, - senderWxid, - senderRemark, - messageType: this.getMessageTypeName(msg.localType), - content: contentValue - } - - const line = columnOrder - .map((id) => this.sanitizeTxtValue(values[id] ?? '')) - .join('\t') - lines.push(line) + lines.push(`${this.formatTimestamp(msg.createTime)} '${senderRole}'`) + lines.push(contentValue) + lines.push('') if ((i + 1) % 200 === 0) { const progress = 60 + Math.floor((i + 1) / sortedMessages.length * 30)