diff --git a/README.md b/README.md
index 0de1c51..af2d8ad 100644
--- a/README.md
+++ b/README.md
@@ -20,9 +20,6 @@ WeFlow 是一个**完全本地**的微信**实时**聊天记录查看、分析
-
-
-
-
-
## 主要功能
- 本地实时查看聊天记录
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/mdassets/us.png b/mdassets/us.png
index e378525..771c7ed 100644
Binary files a/mdassets/us.png and b/mdassets/us.png differ
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 (
+