# Boss 原生 Android 微信式消息转发设计 ## 1. 背景 当前 `Boss` 原生 Android 客户端虽然已经恢复到微信式一级结构,但“消息转发”仍停留在过渡态: - 原生入口还是单独的 `ProjectForwardActivity` - 交互仍然是“选择目标项目 + 填写备注” - 服务端接口 `POST /api/v1/projects/[projectId]/forwards` 也仍以 `targetProjectId + note` 为主 这条链路和用户要求的“微信最新逻辑”存在明显差距。用户已经明确要求: 1. 既支持单条消息转发,也支持多选消息合并转发 2. 转发流程要尽量按微信当前逻辑来 3. 单条消息转发后在目标会话里表现为普通转发消息 4. 多条消息转发后在目标会话里表现为聊天记录卡片 5. 当前一次转发先只允许选择一个目标会话 6. 转发链必须兼容现有线程会话、群聊会话和主 Agent 审批规则 因此,这次工作不是只换一个页面,而是要把“消息转发”升级成一条完整的微信式产品链路: - 原生 Android 交互回到微信式 - 服务端账本结构能表达单条转发和聊天记录卡片 - 目标会话选择页与当前线程会话模型一致 - 群聊和审批规则能继续接入,而不是后续再重做 ## 2. 目标 本次设计完成后,消息转发应满足以下目标: 1. 单条消息可从消息操作菜单直接进入转发流程。 2. 多条消息可通过多选模式进入合并转发流程。 3. 单条和多条转发共用一个微信式目标会话选择页。 4. 单次转发只允许选择一个目标会话。 5. 单条消息转发到目标会话后,显示为普通消息,但保留转发来源元数据。 6. 多条消息转发到目标会话后,显示为一张聊天记录卡片,不是多条普通消息的简单堆叠。 7. 转发目标可以是单线程会话、群聊、`主 Agent`、`审计对话`。 8. 非开发任务状态下,如果转发行为会引发线程之间不应直接沟通的情况,后端必须能返回“需要主 Agent / 用户审批”的结果,而不是直接放行。 9. 这次改造不能破坏现有原生聊天页、会话信息页、群资料页和群聊创建链路。 ## 3. 非目标 本次不做以下事项: 1. 不支持一次转发到多个目标会话。 2. 不支持转发前编辑消息内容。 3. 不支持微信收藏、逐条再编辑、转发到外部应用等额外能力。 4. 不在本次设计中完成“聊天记录卡片详情页”的完整浏览体验,只要求先把卡片消息结构和列表展示落下。 5. 不改变当前原生 Android 架构、登录恢复、群聊模型或主 Agent 主链执行方式。 ## 4. 用户体验设计 ### 4.1 单条消息转发 单条消息转发按微信式链路执行: 1. 用户在聊天页长按某条消息。 2. 弹出轻量消息操作菜单。 3. 菜单中点击 `转发`。 4. 进入统一的 `选择一个会话` 页。 5. 用户选择一个目标会话。 6. 执行转发。 7. 返回目标会话或给出轻量成功提示。 单条转发后的展示规则: - 在目标会话中显示为一条普通消息 - 这条消息保留 `转发` 的轻量来源标识,但整体视觉不能变成控制台卡片 - 账本结构中必须带上来源消息信息,便于后续扩展“查看原始消息” ### 4.2 多选消息合并转发 多选消息合并转发按微信式链路执行: 1. 用户在聊天页对消息执行 `多选` 2. 聊天页进入多选模式 3. 用户勾选多条消息 4. 点击底部 `转发` 5. 进入同一个 `选择一个会话` 页 6. 用户选择一个目标会话 7. 执行合并转发 多选转发后的展示规则: - 在目标会话中只生成一条消息 - 该消息表现为“聊天记录卡片” - 不能把多条消息逐条硬插入目标会话里 ### 4.3 消息操作菜单 单条消息长按后的操作菜单,本次先保留以下动作: - `转发` - `多选` - `复制` - `删除` - `取消` 规则: 1. `转发` 直接进入统一转发流程 2. `多选` 进入消息多选模式 3. 本次不再把“填写备注”作为主流程的一部分 ### 4.4 多选模式 多选模式的页面行为如下: 顶部区域: - 左侧为 `取消` - 中间显示已选消息数量 - 不再显示普通聊天页标题和轻入口 消息区: - 每条消息左侧出现勾选控件 - 已勾选消息有明显选中态 底部区域: - 先只保留 `转发` - 不在本次加入更多多选操作,避免偏离微信主链 ### 4.5 目标会话选择页 单条转发和多选转发共用一个目标会话选择页,规则如下: 1. 页面标题为 `选择一个会话` 2. 页面第一屏直接显示微信式会话列表 3. 会话 cell 沿用当前首页微信式会话样式 4. 当前源会话本身不能作为目标被再次选中 5. 当前一次只能选中一个目标会话 6. 不要求用户填写备注 允许作为目标的会话类型: - 单线程会话 - 群聊会话 - `主 Agent` - `审计对话` ## 5. 数据模型设计 ### 5.1 单条转发消息 单条消息转发后,在目标会话中仍表现为普通消息,但要补充“转发来源”元数据。 本次采用结构: ```ts type ForwardSource = { sourceProjectId: string; sourceProjectName: string; sourceThreadId?: string; sourceThreadTitle?: string; sourceMessageId: string; forwardedBy: string; forwardedAt: string; }; ``` 落账本后的单条消息: ```ts type Message = { id: string; kind: "text" | ...; body: string; forwardSource?: ForwardSource; }; ``` 要求: 1. 转发后的消息仍可作为普通消息渲染 2. 必须保留来源项目、来源消息、来源线程的可追踪信息 3. 不能只把原消息正文复制过去就结束 ### 5.2 多条聊天记录卡片 多条消息转发后,应写成一条新的 bundle 型消息。 本次采用结构: ```ts type ForwardBundleItem = { messageId: string; senderLabel: string; body: string; kind: string; sentAt: string; }; type ForwardBundlePayload = { sourceProjectId: string; sourceProjectName: string; sourceThreadId?: string; sourceThreadTitle?: string; itemCount: number; startedAt: string; endedAt: string; items: ForwardBundleItem[]; }; ``` 落账本后的 bundle 消息: ```ts type Message = { id: string; kind: "forward_bundle"; body: string; forwardBundle?: ForwardBundlePayload; }; ``` 要求: 1. 目标会话中只出现一张聊天记录卡片 2. 卡片中要能生成合理摘要,如消息数、来源会话、时间范围 3. bundle 的完整内容要落到账本,不能只存一个标题 ## 6. 服务端接口设计 ### 6.1 现有接口升级 当前已有: - `POST /api/v1/projects/[projectId]/forwards` 这条接口应从“备注转发”升级成真正的微信式转发接口。 本次采用输入结构: ```ts type ForwardProjectMessageInput = | { mode: "single"; targetProjectId: string; sourceMessageId: string; } | { mode: "bundle"; targetProjectId: string; sourceMessageIds: string[]; }; ``` 当前旧字段 `note` 不再作为主语义字段,允许兼容但不再作为核心交互入口。 ### 6.2 返回结构 接口返回需要至少表达: ```ts { ok: boolean; message?: Message; approvalRequired?: boolean; approvalReason?: string; } ``` 要求: 1. 正常转发成功时返回目标会话中新生成的消息 2. 需要审批时,不直接写入目标会话,而是返回 `approvalRequired=true` 3. 失败时给出明确错误 ## 7. 审批与群聊兼容设计 ### 7.1 正常转发 以下情况可直接放行: - 用户主动把消息转发到自己可见的单线程会话 - 用户主动把消息转发到群聊 - 用户主动把消息转发到 `主 Agent` - 用户主动把消息转发到 `审计对话` ### 7.2 需要审批的场景 如果这次转发在业务语义上会触发: - 非开发任务状态下的线程直接互相沟通 那么后端必须先命中治理规则: 1. 不直接放行 2. 返回 `approvalRequired` 3. 由主 Agent 再向用户请求批准 这次即使还不把完整审批 UI 全做完,也必须在接口和消息层预留这条分支。 ### 7.3 和群聊的关系 转发目标页对群聊和单线程会话一视同仁,目标本质就是会话。 要求: 1. 群聊和单线程会话共用同一套目标选择页 2. 不能因为群聊存在,就做另一套“转群聊”专用流程 3. 后端只在治理规则阶段区分是否需要审批,不在选择页阶段区分 ## 8. Android 原生页面设计 ### 8.1 ProjectDetailActivity 需要补以下交互: 1. 单条消息长按弹出操作菜单 2. 进入多选模式 3. 多选模式顶部与底部状态切换 4. `转发` 入口跳转到统一会话选择页 ### 8.2 新增原生活动页 本次新增: - `ForwardTargetActivity` - 统一目标会话选择页 - 同时服务单条转发和多选转发 `ProjectForwardActivity` 不再承担主转发链路,而是下沉为兼容入口;如果旧入口仍被触发,只负责立即跳转到新的 `ForwardTargetActivity`。 ### 8.3 转发后的返回行为 要求: 1. 转发成功后给出轻量反馈 2. 返回链符合手机直觉 3. 不能出现完成后回退错层、丢当前页状态、或直接退桌面 ## 9. 测试与验收标准 ### 9.1 单条转发验收 1. 长按某条消息,能看到消息菜单 2. 点 `转发` 后进入目标会话选择页 3. 选择一个会话后,成功写入目标会话 4. 目标会话里显示普通转发消息 5. 服务端账本中能看到 `forwardSource` ### 9.2 多条转发验收 1. 进入多选模式并勾选多条消息 2. 点击底部 `转发` 3. 进入同一个目标会话选择页 4. 选择一个会话后,成功写入目标会话 5. 目标会话中只出现一张聊天记录卡片 6. 服务端账本中能看到 `forwardBundle` ### 9.3 目标选择页验收 1. 会话项样式和首页一致 2. 一次只能选中一个目标会话 3. 源会话本身不能被选中 4. 单线程、群聊、主 Agent、审计对话都能正常显示 ### 9.4 审批兼容验收 1. 开发任务场景下,转发能直接通过 2. 命中非开发任务治理规则时,接口返回 `approvalRequired` 3. 命中审批规则时不会把消息错误地直接写进目标会话 ### 9.5 本轮实现完成标准 本轮可以视为完成,当且仅当: 1. 原生 Android 已支持单条转发 2. 原生 Android 已支持多选合并转发 3. 目标会话选择页已经替换当前“备注转发页” 4. 服务端消息结构已经支持 `forwardSource` 和 `forwardBundle` 5. 转发接口已经支持 `single / bundle` 6. 审批闸口已经在接口层和账本层预留