门店系统 2.1.0 · 企微画面投影 · 架构讲解

企微在云上接待
门店实时看得见

企业微信跑在无影云电脑上接待客户;2.1.0 页把那块屏投给店长——只许看,不许扰

// 投影链路架构 + 排障复盘 · 已上线 · 口径 2026-08-12

// 本文为公开版,具体标识已替换为占位符:PR 号、提交 SHA、功能开关名、手册与规格章节、云机所在城市与台数均已删去。

阿里云无影 WEB SDK IFRAME 容器 LOCKREADONLY ×4 FIXEDRESOLUTION 契约 生产已上线 SSR 后端发票
0
条输入通道全部锁死鼠标 · 键盘 · 触摸 · 剪贴板
0
句话的破图根因容器必须是预置 IFRAME
0
条按机分辨率契约随票下发 · 远端分辨率不动
0
次干净连接收官验证产品页 0 报错 · 正式上线
SCROLL / 向下滚动
01
Topology · Who Talks To Whom

四个角色,两条通道

企微和自动化跑在无影云电脑上;门店页只是把那块屏「看」过来——票据走后端,画面直连浏览器

投影链路拓扑
节点色 = 角色 · 流光 = 数据方向 · 口径 2026-08-12
BRW 店长浏览器 2.1.0 · REACT + IFRAME SRV 门店系统后端 SSR · 只发票 GW 无影网关 · Web SDK ALIYUN WUYING PC 云电脑 · 接待机 企微 + 自动化接待 ① 求票 ② 换票 ④ 画面流 → IFRAME ③ 采集

// 玫红流光 = 画面 · 只从云机流向店长,反向没有任何通道

Design

后端只管发票,画面流不经过它。凭证前置只要求“资源已授权给当前 EndUserId”——没有域名白名单这回事;且 EndUserId 必须复用接待号同一账号:无影是单会话机,换账号连接会把正在接待的会话整个踢下线。

02
Connection Sequence · Swimlane

一次观看,六步走完

谁发起、谁鉴权、谁建流、谁无感——序号跨行跳一次,就是一次交接

请求
鉴权
建流
观看
店长
浏览器
01打开 2.1.0 实时画面页
03SDK 在 iframe 容器里带票连接
05只读观看 · 四条输入通道已锁
门店系统
后端
02校验店长身份 → 向无影换连接票
阿里云
无影
04网关建流 · 从云电脑采集画面
云电脑
接待机
06企微自动化照常接待 · 对观看无感

// 02→03 后端交回浏览器 · 05/06 同列并行:看的人在看,干活的机器不知道

03
Read-Only Lock · Four Channels

只影响投影,绝不碰自动化

观看端的任何输入都可能打进生产会话,四条通道一律锁死

Constraint

云电脑上跑着企微自动化接待——屏幕那头是真实客户。观看端任何一次输入透传,都会直接打进生产会话,所以纪律只有一条:只影响投影、绝不碰自动化

CH-01 · MOUSE鼠标

点击、拖拽、滚轮一律不透传——店长怎么点,远端都不动。

CH-02 · KEYBOARD键盘

按键不进远端,店长本机打字不会落进企微输入框。

CH-03 · TOUCH触摸

门店平板、触屏一体机的手势同样拦截,不进远端。

CH-04 · CLIPBOARD · 曾漏掉剪贴板

本机复制的内容曾可能同步进远端企微输入框——后来补上的第四道锁。剪贴板是独立方法、不在 uiConfig 里,所以最容易漏。

Detail

lockReadOnly() 在 start 前和 onConnected 后各调一次——SDK 建连会重置这些模块,只关一次会被覆盖。文件传输则靠不传 fileTransferConfig 保证没有。

04
Resolution Contract · Per Machine

fixedResolution 是按机契约

它安全的前提是恰好等于云机原生分辨率——那时 setResolution 是 no-op。这是按机契约,不是全局常量。

新云机接入投影的判定
以原生 2560×1600 的机器为例 · 口径 2026-08-12
新云机接入投影NEW DESKTOP 等于该机原生分辨率? FIXEDRESOLUTION 否 · 其他机型 是 · 例:2560×1600 随票下发该机原生分辨率 PER-MACHINE VALUE 直接带票连接 SETRESOLUTION = NO-OP 远端分辨率不动 自动化无感 · ZERO IMPACT

// 根治三件套:resolutionAdaptive:false · fixedResolution 2560×1600 · onConnected 再 setResolution 兜底

05
Debug Trail · The Real Culprit

破图排查:真凶不是 React 树

对照实验一度把嫌疑推给 React 树——直到发现实测台不保真。真凶是一条最基础的容器契约。

排除 域名授权 / 白名单 —— 官方凭证前置只看“资源已授权给当前 EndUserId”,能连上本身就是证明。响应头 · 会话竞争 · 父路径 · StrictMode 也逐一出局。
嫌疑
跑偏
关键对照指向 React 树:裸静态实测台正常、React 产品页破图 —— createPortal 一度排上日程。
反转 实测台不保真:裸静态台给 div 也能连——SDK 容忍、自己往 div 注入子 iframe,恰好把契约偏差掩盖了整段排查。
根因 官方 quick-start 要求 iframeId 指向页面预置的 <iframe>。给 div 时 SDK 在产品页把内嵌 window 导航到 origin 根,被本站 X-Frame-Options 拒掉 —— 破图。
收口 先落地容器修复;再打开实时连接的功能开关、订正「0 尺寸」错误注释、排障结案 —— 产品页三次干净连接 0 报错
教训 「实测台能连、产品页不能」时——先逐字核对最基础的容器契约与官方示例一致没有,再谈框架 / CSP / 会话竞争。已沉淀为团队经验。

// 复盘已归档 · 教训沉淀为“第三方 SDK 先核容器契约”

06
Status · Shipped, One Item Open

已上线:只剩一条待验证

画面已在生产跑通。唯一没关的问题:“连接会不会打断正在进行的接待”——排期在工作时段专场验一次。

层面内容状态
加固只读锁补上剪贴板凑齐四通道;fixedResolution 按机前提写死进注释已合入 MAIN
修复容器 div → iframe(真根因的修复所在)+ onError 监听已合入 MAIN
上线翻开连接开关;产品页三次干净连接 0 报错,分辨率全程 2560×1600已上线
生产 2.1.0店长点「连上看画面」即看企微实时桌面;休眠机也能连,只读不透传运行中
待验证“连接不打断正在进行的接待”——工作时段连一次,15 秒采样分辨率与接待心跳待专场实测
档案设计文档里的排障复盘 · 开通步骤手册已归档
一句话总括:票据走后端、画面直连浏览器;观看端四通道只读、分辨率按机下发。破图根因一句话——容器必须是预置 iframe,不是 React 树;三次干净连接后正式上线。最后一条「工作时段连接不打断接待」待专场验证。
07
Timeline · Research & Releases

三天的脉络:接通 → 修正 → 上线

08-09 到 08-11,投屏这条线三天密集迭代。摘录关键节点——每个调研结论都长在一次版本上

08-09 服务端可见性闸先行 —— Phase A 只做闸,画面尚未接通。
08-09 前端 + 无影换票接通,挂上沉默客户跟进屏;region 按机传,机队跨区不连错。
08-10 就绪判定改真实探活 —— 不再只看配置是否存在。
08-10 2.1.0 屏上线:企微这条线加一屏,直接看企微此刻在跟谁说话。
08-10 真 SDK 逐处校对(客户端四处全错)+ 浏览器实测回填设计文档 —— 画面首次通了
08-11 分辨率改为按机下发并验证;产品页画面仍破图,连接按钮暂不开放。
08-11 只读锁补剪贴板凑齐四通道;fixedResolution 按机契约写死。
08-11 官方文档逐页读完落地:容器改 iframe + onError —— 真根因的修复其实已在这里落地,只是被不保真的实测台遮住了。
08-11 打开实时连接功能开关、排障结案 —— 产品页三次干净连接 0 报错,正式上线
待验证 工作时段实测:接待时段连一次生产机,15 秒采样分辨率与心跳 —— 关掉“连接不打断正在进行的接待”这最后一条。

// 摘录关键节点 · 口径 2026-08-12

Archive

调研与复盘全部落档:实测记录 · 排障复盘(已结案)· 开通步骤手册——每一步结论都能在版本记录里对上号。