实现合并转发(第4章 4.20):后端已支持 bundle 模式,补上前后两端

后端把 POST /v1/im/messages/forward 的 mode="bundle" 实现了(此前直接返回 501,前端因此
只做了逐条转发)。这次把前端两侧都补上。

接收侧(新增 widgets/forward-bundle.jsx)
- 服务端生成的这条消息 head 带 x-im-type:"forward_bundle",content 是
  {bundle_id, title, item_count, preview, items, source_refs, comment},不是 Drafty。
  前端全仓搜这个类型零命中,收到会落到 chat-message 的 "invalid content" 兜底
  (⚠ + 灰字)。本端自己发不出 bundle,但别的端发过来就会踩到。
- 渲染成一张"聊天记录"卡片:标题 + 摘要行 + 展开/收起。items[] 里已经带了每条被转发消息的
  完整快照,所以"查看完整记录"是就地展开,不额外发请求。
- 快照里的 from 是不带 usr 前缀的裸 uid(与收藏快照一致),补前缀后查本地会话缓存拿显示名;
  查不到就不显示发送者,宁可少一行也不要把一串 uid 摆在摘要前面。
- 没有正文的媒体消息用 [图片]/[视频]/[语音]/[文件]/[链接] 标签兜底。

发送侧(batch-forward-dialog.jsx)
- 转发模式改为按"用哪种方式选的目标"推导,这是参考图给的规则:
  转发—逐条转发.png 是单选一个目标、占位写 [逐条转发]共2条消息;
  转发—合并转发—多选状态.png 是多选目标、占位写 [合并转发]共16条消息。
  原来 mode 硬编码 'separate'、占位也写死 [逐条转发]。

样式(base.css)
- 新增 .forward-bundle 一组规则,避免又造一批零样式类。

验证
- 用后端 buildForwardBundle 的真实产出结构,注入真实会话的消息缓存,由真正的 ChatMessage
  渲染:卡片正常显示、未落到 invalid content;展开显示全部 5 条、收起回到 3 条;截图确认视觉正常。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-09-03 21:15:33 +08:00
co-authored by Claude Opus 5
parent c709abbfa4
commit 5bc3fee20b
8 changed files with 296 additions and 48 deletions
+61
View File
@@ -14270,3 +14270,64 @@ div.toast.show {
color: #fff;
background: #347bd7;
}
/* 合并转发卡片(widgets/forward-bundle.jsx,第4章 4.20)。
服务端 mode="bundle" 生成的消息不是 Drafty,单独渲染成一张可展开的"聊天记录"卡片。 */
.forward-bundle {
min-width: 11rem;
max-width: 18rem;
}
.forward-bundle-title {
margin-bottom: 0.35rem;
font-weight: 500;
}
.forward-bundle-lines {
margin: 0;
padding: 0;
list-style: none;
}
.forward-bundle-lines li {
overflow: hidden;
margin: 0.15rem 0;
color: var(--clr-text-secondary);
font-size: 0.85rem;
line-height: 1.35;
text-overflow: ellipsis;
white-space: nowrap;
}
.forward-bundle-lines li b {
font-weight: 500;
}
.forward-bundle-more,
.forward-bundle-count {
display: block;
width: 100%;
margin: 0.4rem 0 0;
padding: 0.35rem 0 0;
border: 0;
border-top: 1px solid var(--clr-divider, #e7e9ec);
border-radius: 0;
box-shadow: none;
background: none;
color: var(--clr-text-secondary);
font-size: 0.8rem;
line-height: 1.3;
text-align: left;
text-transform: none;
}
.forward-bundle-more {
color: #347bd7;
cursor: pointer;
}
.forward-bundle-comment {
margin-top: 0.4rem;
color: var(--clr-text-primary);
font-size: 0.85rem;
}