diff --git a/electron/services/chatService.ts b/electron/services/chatService.ts index 43f6dae..2a38eb4 100644 --- a/electron/services/chatService.ts +++ b/electron/services/chatService.ts @@ -1268,6 +1268,15 @@ class ChatService { case 8589934592049: return '[转账]' default: + // 检查是否是 type=87 的群公告消息 + if (xmlType === '87') { + const textAnnouncement = this.extractXmlValue(content, 'textannouncement') + if (textAnnouncement) { + return `[群公告] ${textAnnouncement}` + } + return '[群公告]' + } + // 检查是否是 type=57 的引用消息 if (xmlType === '57') { const title = this.extractXmlValue(content, 'title') @@ -1291,6 +1300,15 @@ class ChatService { const title = this.extractXmlValue(content, 'title') const type = this.extractXmlValue(content, 'type') + // 群公告消息(type 87)特殊处理 + if (type === '87') { + const textAnnouncement = this.extractXmlValue(content, 'textannouncement') + if (textAnnouncement) { + return `[群公告] ${textAnnouncement}` + } + return '[群公告]' + } + if (title) { switch (type) { case '5': @@ -1324,6 +1342,8 @@ class ChatService { return '[小程序]' case '2000': return '[转账]' + case '87': + return '[群公告]' default: return '[消息]' } diff --git a/electron/services/exportService.ts b/electron/services/exportService.ts index d129766..054d2ea 100644 --- a/electron/services/exportService.ts +++ b/electron/services/exportService.ts @@ -413,6 +413,15 @@ class ExportService { if (xmlType) { const title = this.extractXmlValue(content, 'title') + // 群公告消息(type 87) + if (xmlType === '87') { + const textAnnouncement = this.extractXmlValue(content, 'textannouncement') + if (textAnnouncement) { + return `[群公告] ${textAnnouncement}` + } + return '[群公告]' + } + // 转账消息 if (xmlType === '2000') { const feedesc = this.extractXmlValue(content, 'feedesc') @@ -496,6 +505,15 @@ class ExportService { const subType = typeMatch ? parseInt(typeMatch[1], 10) : 0 const title = this.extractXmlValue(normalized, 'title') || this.extractXmlValue(normalized, 'appname') + // 群公告消息(type 87) + if (subType === 87) { + const textAnnouncement = this.extractXmlValue(normalized, 'textannouncement') + if (textAnnouncement) { + return `[群公告]${textAnnouncement}` + } + return '[群公告]' + } + // 转账消息特殊处理 if (subType === 2000 || title.includes('转账') || normalized.includes('transfer')) { const feedesc = this.extractXmlValue(normalized, 'feedesc') @@ -686,6 +704,7 @@ class ExportService { if (xmlType) { switch (xmlType) { + case '87': return '群公告' case '2000': return '转账消息' case '5': return '链接消息' case '6': return '文件消息' diff --git a/src/pages/ChatPage.scss b/src/pages/ChatPage.scss index b86bf2d..4b11448 100644 --- a/src/pages/ChatPage.scss +++ b/src/pages/ChatPage.scss @@ -2510,4 +2510,65 @@ color: white; } } + + .announcement-message { + background: rgba(255, 255, 255, 0.15); + + .announcement-label { + color: rgba(255, 255, 255, 0.8); + } + + .announcement-text { + color: white; + } + + .announcement-icon { + color: white; + } + } +} + +// 群公告消息 +.announcement-message { + display: flex; + gap: 12px; + align-items: flex-start; + padding: 12px 14px; + background: var(--hover-color); + border-radius: 12px; + max-width: 320px; + + .announcement-icon { + flex-shrink: 0; + width: 28px; + height: 28px; + display: flex; + align-items: center; + justify-content: center; + color: #f59e42; + + svg { + width: 20px; + height: 20px; + } + } + + .announcement-content { + flex: 1; + min-width: 0; + + .announcement-label { + font-size: 12px; + color: var(--text-tertiary); + margin-bottom: 4px; + } + + .announcement-text { + font-size: 14px; + color: var(--text-primary); + line-height: 1.5; + word-break: break-word; + white-space: pre-wrap; + } + } } diff --git a/src/pages/ChatPage.tsx b/src/pages/ChatPage.tsx index ee7da3b..ec80405 100644 --- a/src/pages/ChatPage.tsx +++ b/src/pages/ChatPage.tsx @@ -2622,6 +2622,7 @@ function MessageBubble({ message, session, showTime, myAvatarUrl, isGroupChat, o let desc = '' let url = '' let appMsgType = '' + let textAnnouncement = '' try { const content = message.rawContent || message.parsedContent || '' @@ -2635,10 +2636,29 @@ function MessageBubble({ message, session, showTime, myAvatarUrl, isGroupChat, o desc = doc.querySelector('des')?.textContent || '' url = doc.querySelector('url')?.textContent || '' appMsgType = doc.querySelector('appmsg > type')?.textContent || doc.querySelector('type')?.textContent || '' + textAnnouncement = doc.querySelector('textannouncement')?.textContent || '' } catch (e) { console.error('解析 AppMsg 失败:', e) } + // 群公告消息 (type=87) + if (appMsgType === '87') { + const announcementText = textAnnouncement || desc || '群公告' + return ( +