From dbe25904b91b26cb80e2d8383c127406bdec5b57 Mon Sep 17 00:00:00 2001 From: Kris <2893855659@qq.com> Date: Wed, 8 Jul 2026 22:58:06 +0800 Subject: [PATCH] feat(wechat_woc): add delivered parts skip logic for multi-part messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增已发送分片跳过逻辑,支持重复发送时只发送未成功投递的消息分片,避免重复推送已送达内容 --- .../wechat_woc/adapters/outbound_adapter.py | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/backend/package/yuxi/channels/plugins/wechat_woc/adapters/outbound_adapter.py b/backend/package/yuxi/channels/plugins/wechat_woc/adapters/outbound_adapter.py index ad08def3..a2299d2c 100644 --- a/backend/package/yuxi/channels/plugins/wechat_woc/adapters/outbound_adapter.py +++ b/backend/package/yuxi/channels/plugins/wechat_woc/adapters/outbound_adapter.py @@ -252,6 +252,7 @@ class WeChatWocOutboundAdapter: *, idempotency_key: str | None = None, channel_request_id: str | None = None, + delivered_parts: list[int] | None = None, ) -> list[MultiPartReceipt]: """发送多部分消息(文本在前,媒体在后)。 @@ -306,6 +307,7 @@ class WeChatWocOutboundAdapter: """ receipts: list[MultiPartReceipt] = [] seq = 0 + skip_seqs = set(delivered_parts) if delivered_parts else set() # 1. 发送前先校验所有媒体附件的出站能力,避免文本已发后才发现媒体 # 不支持导致文本无法回滚(M-3 修复)。任一媒体不支持即整体失败, @@ -342,23 +344,27 @@ class WeChatWocOutboundAdapter: # 2. 文本在前 if payload.content: - resp = await self._client.send_text( - account_id, - peer_id, - payload.content, - ) - receipts.append( - MultiPartReceipt( - platform_msg_id=_extract_channel_msg_id(resp), - part_type=_PART_TYPE_TEXT, - sequence=seq, - success=True, + if seq not in skip_seqs: + resp = await self._client.send_text( + account_id, + peer_id, + payload.content, + ) + receipts.append( + MultiPartReceipt( + platform_msg_id=_extract_channel_msg_id(resp), + part_type=_PART_TYPE_TEXT, + sequence=seq, + success=True, + ) ) - ) seq += 1 # 3. 媒体在后(图片 / 文件) for attachment in payload.attachments: + if seq in skip_seqs: + seq += 1 + continue # attachment.url 必须为 bridge 容器内可访问的绝对路径(见方法 # docstring 中 ``attachment.url`` 语义重载说明) file_path = attachment.url