第六轮深度测试:7个并行agent覆盖全部11章,修复21处前端问题

Ch1-2: 用户名注册邀请码错误改为友好文案(原为原始TypeError泄露给用户);
  企业注册页扫描图标补上点击反馈。
Ch3-4: 发名片消息补传typeHint(此前被后端误分类成text,搜索/历史摘要显示成JSON);
  文件卡片按mime大类区分图标颜色(此前所有文件都是同一个灰色通用图标);
  表情面板补上专属退格/发送按钮(浅蓝禁用/深蓝启用两态);订正一处与截图不符的代码注释。
Ch5-6: 群聊设置页"群成员"补上可点击的完整成员列表页(复用MemberPicker字母分组);
  群文件页去掉无依据的硬编码"/10GB"容量上限显示。
Ch7: 收藏点击图片/视频缩略图补上预览;"查找聊天记录-链接"tab补上定位回原消息;
  文件下载页返回入口按来源tab纠正;批量转发成功计数改为按目标会话去重
  (原公式混用"收藏条数"和"目标会话数"两个维度,混选多条收藏转发时可能显示负数);
  收藏/视频tab切换补上URL路由同步。
Ch8: topic.onInfo在通话期间补上事件转发(此前通话中"对方正在输入"和已读回执静默失效);
  主叫等待接听页补上"正在等待对方接受邀请…"文案;语音通话最小化胶囊的还原按钮移出
  拖拽区域(原来嵌在draggable内部,指针捕获可能吞掉点击);修复中等窗宽(641-750px)下
  本地摄像头预览遮挡"切换摄像头"按钮的CSS重叠。
Ch9: 部门树展开时跳过child_count=0的注定空请求;月报字数上限从硬编码1000改为读取
  后端真实的10000;发起会议补上"结束时间需晚于开始时间"的本地校验和更具体的报错;
  日报/月报统计接口补上department_id透传(此前包装函数注释断言后端会忽略,实际已支持)。
Ch10-11: URL风险检测补上g标志(原来一条消息只检查第一个链接,第二个链接哪怕是高危
  也不会被拦截);补上"安全教育"设置入口(原功能完整实现但零入口,需手改hash才能打开);
  修改密码按钮补上busy态反馈;青少年模式PIN页补上"忘记独立密码"入口(后端已支持重置,
  前端未接);"关于我们"补上"联系我们"行。

7个agent同时对全部11章存量后端问题条目逐一复核,结论详见待整理的后端问题清单更新
(Ch1-2发现一条P0级后端问题:验证码固定值"123456",已记录未修复,不在此commit修改
im_be仓库范围内)。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-09-05 03:48:28 +08:00
co-authored by Claude Sonnet 5
parent d42591284f
commit f42b8536e5
19 changed files with 634 additions and 111 deletions
+27 -3
View File
@@ -226,6 +226,16 @@ class CallPanel extends React.PureComponent {
onInfo(info) {
if (info.what != 'call') {
// This call panel takes over topic.onInfo wholesale for the lifetime of the call (including
// while minimized -- the product lets messaging continue during a call), but was only ever
// handling 'call' events itself and dropping everything else on the floor instead of forwarding
// to the handler it displaced (messages-view.jsx's handleInfoReceipt, which drives the "typing"
// indicator and read/received checkmarks). Real-time {info} isn't replayed later, so every
// typing/read/recv update for this topic was silently lost for as long as the panel stayed
// mounted.
if (this.previousOnInfo) {
this.previousOnInfo(info);
}
return;
}
switch (info.event) {
@@ -839,10 +849,18 @@ class CallPanel extends React.PureComponent {
if (this.props.minimized && this.state.audioOnly) {
// Voice calls minimize to a small pill (icon + timer), not the video-shaped box.
return (
// The restore button used to live inside .call-pill.draggable -- dragStart only checks
// event.target.closest('.draggable') before calling setPointerCapture() on the whole
// container, and once a pointer is captured, Pointer Events retargets subsequent events
// (including the click) to the capturing element instead of the button underneath it. The
// video-minimized layout below already keeps its own restore button as a sibling of the
// draggable region for exactly this reason; this pill just hadn't followed the same rule.
<div id="video-container" className="minimized audio-minimized" ref={this.containerRef}>
<div className="call-pill draggable">
<i className="material-icons">call</i>
<span className="call-pill-duration">{formatElapsedTime(this.state.elapsedSeconds)}</span>
<div className="call-pill-row">
<div className="call-pill draggable">
<i className="material-icons">call</i>
<span className="call-pill-duration">{formatElapsedTime(this.state.elapsedSeconds)}</span>
</div>
<button className="full-screen" onClick={this.props.onToggleMinimize}>
<i className="material-icons">{fullScreen}</i>
</button>
@@ -880,6 +898,12 @@ class CallPanel extends React.PureComponent {
title={this.props.title} />
</div>
<div className="caller-name">{peerTitle}</div>
{/* This same !remoteActive branch also renders once the call is live but the peer's
own camera happens to be off -- only the pre-connect phase should claim we're
still waiting on them to answer. Reference screenshots (视频通话—等待对方接受
邀请中.png etc.) and this project's own call-experience-view.jsx demo both show
this line; only the real call-panel.jsx was missing it. */}
{!connected ? <p className="caller-status">正在等待对方接受邀请…</p> : null}
</div>
</>
}