From a001f3327c2f0df3546fc3e0eebfea396cbe9403 Mon Sep 17 00:00:00 2001 From: badboyyyyHmm Date: Sat, 2 May 2026 23:50:44 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=B5=8C=E5=A5=97?= =?UTF-8?q?=E5=BC=95=E7=94=A8=E6=B6=88=E6=81=AF=E6=98=BE=E7=A4=BA=E4=B8=BA?= =?UTF-8?q?[=E9=93=BE=E6=8E=A5]=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=88#895?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/services/chatService.ts | 13 ++++++++-- src/pages/ChatPage.tsx | 44 ++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/electron/services/chatService.ts b/electron/services/chatService.ts index bcdb42c..93ee1e9 100644 --- a/electron/services/chatService.ts +++ b/electron/services/chatService.ts @@ -5702,9 +5702,18 @@ class ChatService { case '47': displayContent = '[动画表情]' break - case '49': - displayContent = '[链接]' + case '49': { + // 链接类消息 (type=49):需区分真正的链接和嵌套引用 + // 嵌套引用的 referContent 中 xmlType=57,真正的链接 xmlType=49 或 5 + const decodedReferContent = this.decodeHtmlEntities(referContent || '') + const innerInfo = this.parseType49Message(decodedReferContent) + if (innerInfo.xmlType === '57' && innerInfo.linkTitle) { + displayContent = innerInfo.linkTitle + } else { + displayContent = '[链接]' + } break + } case '42': displayContent = '[名片]' break diff --git a/src/pages/ChatPage.tsx b/src/pages/ChatPage.tsx index 0cf0fdd..2ce45a6 100644 --- a/src/pages/ChatPage.tsx +++ b/src/pages/ChatPage.tsx @@ -10041,10 +10041,30 @@ function MessageBubble({ return [动画表情] } + // 链接类消息:需区分真正的链接和嵌套引用 + // 当一个引用了别的消息的消息被引用(B引用A,C又引用B),那么 B 在 C 的 refermsg 里 type=49 + // 与此同时,一个链接的 type 也是 49,这可能意味着 49 是一个更高级别的分类 + // 因此,不能将 type=49 的引用信息一律视为链接,它也可能是嵌套引用。那么怎么区分呢? + // 答:嵌套引用的 referContent 中 xmlType=57,真正的链接 xmlType=49 或 5 + // 对于更多层的嵌套引用,微信不会保存所有层的信息,因此和两层的情况差不多 + // 注意:需从原始 XML 获取 refermsg > content,而非后端处理过的 quotedContent + if (referType === '49') { + try { + const rawReferContent = q('refermsg > content') || '' + const innerDoc = new DOMParser().parseFromString(rawReferContent, 'text/xml') + const innerXmlType = innerDoc.querySelector('appmsg > type')?.textContent?.trim() + if (innerXmlType === '57') { + const innerTitle = innerDoc.querySelector('title')?.textContent?.trim() || '' + if (innerTitle) return <>{renderTextWithEmoji(cleanMessageContent(innerTitle))} + } + } catch { /* 解析失败降级 */ } + return [链接] + } + // 各类型名称映射 const typeLabels: Record = { '3': '图片', '34': '语音', '43': '视频', - '49': '链接', '50': '通话', '10000': '系统消息', '10002': '撤回消息', + '50': '通话', '10000': '系统消息', '10002': '撤回消息', } if (referType && typeLabels[referType]) { return [{typeLabels[referType]}] @@ -10417,9 +10437,29 @@ function MessageBubble({ } catch { /* 解析失败降级 */ } return [动画表情] } + // 链接类消息:需区分真正的链接和嵌套引用 + // 当一个引用了别的消息的消息被引用(B引用A,C又引用B),那么 B 在 C 的 refermsg 里 type=49 + // 与此同时,一个链接的 type 也是 49,这可能意味着 49 是一个更高级别的分类 + // 因此,不能将 type=49 的引用信息一律视为链接,它也可能是嵌套引用。那么怎么区分呢? + // 答:嵌套引用的 referContent 中 xmlType=57,真正的链接 xmlType=49 或 5 + // 对于更多层的嵌套引用,微信不会保存所有层的信息,因此和两层的情况差不多 + // 注意:需从原始 XML 获取 refermsg > content,而非后端处理过的 quotedContent + if (referType === '49') { + try { + const rawReferContent = parsedDoc?.querySelector('refermsg > content')?.textContent?.trim() || '' + const innerDoc = new DOMParser().parseFromString(rawReferContent, 'text/xml') + const innerXmlType = innerDoc.querySelector('appmsg > type')?.textContent?.trim() + if (innerXmlType === '57') { + const innerTitle = innerDoc.querySelector('title')?.textContent?.trim() || '' + if (innerTitle) return <>{renderTextWithEmoji(cleanMessageContent(innerTitle))} + } + } catch { /* 解析失败降级 */ } + return [链接] + } + // 各类型名称映射 const typeLabels: Record = { '3': '图片', '34': '语音', '43': '视频', - '49': '链接', '50': '通话', '10000': '系统消息', '10002': '撤回消息', + '50': '通话', '10000': '系统消息', '10002': '撤回消息', } if (referType && typeLabels[referType]) { return [{typeLabels[referType]}]