修复全页面走查发现的 P0 前端问题(第一批)

八个 agent 对 11 章逐页对照设计稿+后端源码后,先修其中"功能不可用/崩溃/谎报成功"级别的:

崩溃与数据错误
- content-library-view: Highlight 按 [start,len] 数组解构后端返回的 {start,end} 对象,
  对象不可迭代会直接抛 TypeError,任何文本搜索命中都让整个结果区渲染崩掉。服务端偏移还叠加
  两个问题(Go 字节下标 vs JS UTF-16;偏移基准是全文但 snippet 会被开窗截断),改为在展示
  文本上本地匹配关键词。
- content-library-view: firstAttachment 用 Drafty.attachments,SDK 里硬过滤 tp=='EX'
  只认文件附件,图片(IM)/视频(VD)/语音(AU) 一个都取不到——收藏缩略图、语音播放源、聊天记录
  图片视频宫格全部拿不到资源。改用 Drafty.entities 按类型分派(chat-message.jsx 已有先例)。
- message-center-view: 系统通知的机器码兜底会把真实数据吞掉(日报提醒的 summary 就是日期
  字符串 "2026-08-20",会议通知的 summary 是标题),改为查表命中才替换。
- message-center-view: 会话列表漏了 avatar 字段,每行都只能落到兜底图标;同文件
  frequentContacts() 本来就是对的,照它补上。

功能不可用
- auth-onboarding-view: 首次开启青少年模式是死路——设完密码丢弃了服务端返回的
  enable_action_token,从不调 enableYouthMode,用户走完短信验证+设密码后模式仍是关的。
  现在拿着这个 token 把最后一步做完。
- group-management-view: "投诉/举报"是个 onToast('暂未开放') 死桩,而 target_type='group'
  这条链路早就通了。接上真实举报页。
- tinode-web: 刷新/深链会被弹回首页。两个原因叠加:初始化白名单还是上游 Tinode 的
  ['cred','reset','register'];handleLoginSuccessful 无条件把 hash 改写成 workbench,
  刷新触发的自动登录也走这条。抽出 SIDE_PANEL_VIEWS 常量复用,并区分登录流程与自动登录。
- widgets/meta-message: deleted 分支从未实现,撤回一条消息后时间线上什么都不剩。

谎报成功 / 判定错误
- tinode-web + personal-settings-view: 改密码不返回 Promise,服务端拒绝时照样弹"密码已更新"。
- group-management-view: 禁言批量读 result.succeeded,但该接口返回的是 {topic, items},
  succeeded 恒为 undefined,不管成没成都弹"设置成功"。两个接口结构不同,分开判定。
- workplace-collaboration-view: 会议取消状态写成 'cancelled',后端是 'canceled' 单 l,
  会议取消后"取消会议"按钮还挂着。

样式与显示
- base.css: 删掉旧版 .organization-department 的 padding-left !important,它压过按层级算出的
  内联缩进,导致部门行全平、只有人员行缩进。
- base.css: 补 .youth-password-gate(原来 0 条规则),PIN 框缺 position:relative 和居中。
- security-support-view: shield_lock 不在经典 Material Icons 里(只有 Symbols),会显示成
  字面文本;.risk-info-page 也是 0 条规则,整页渲染成裸项目符号列表。改用 verified_user 并
  补上 .risk-dialog。
- contact-management-view: 好友资料页性别直接输出后端枚举,显示成 "male"。
- workplace-collaboration-view: 层级标注两条路径两种格式(树形深三层变"3级"、搜索硬传"三"),
  统一成一个 helper。

已记录不在前端修的后端缺口:recallMessage 的 version 只能传 1,因为所有消息读取接口
(messagePayload/messageSearchPayload/mediaMessagePayload/favoriteSnapshot)都不下发 version,
冲突错误里也不回传真实值,被编辑过的消息撤回必然失败。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-09-03 18:31:26 +08:00
co-authored by Claude Opus 5
parent c4189646f4
commit 5a07bb4e3b
17 changed files with 365 additions and 138 deletions
+25 -15
View File
@@ -653,21 +653,11 @@
color: #8b929b;
}
.organization-root > .material-icons:first-child {
color: #2f73d2;
}
.organization-department {
padding-left: 1.75rem !important;
}
.organization-department > .material-icons:first-child {
color: #e79a32;
}
.organization-members button {
padding-left: 2.5rem;
}
/* 旧版组织架构的 .organization-root / .organization-department / .organization-members 三条规则
已删除:前两个类名 JSX 里早就没人用了,而 .organization-department 那条
`padding-left: 1.75rem !important` 会压过新版按层级算出来的内联 paddingLeft,
导致一级/二级/三级部门行左边距完全一样、树形层级看不出来(人员行没有 !important,缩进正常,
结果是"部门全平、人员缩进",比不缩进更乱)。新版完整规则在下面 .organization-department 那一块。 */
.organization-members img {
width: 2.5rem;
@@ -6440,6 +6430,26 @@ div.toast.show {
font-size: 1.8rem;
}
/* 青少年模式的 PIN 页复用了下面的 .auth-pin-boxes / .auth-pin-input / .auth-primary,
但它自己的容器类 .youth-password-gate 原来在整个 base.css 里一条规则都没有。缺的正是
.auth-pin-content 提供的两件事:position:relative(.auth-pin-input 是 position:absolute
+ top:11rem,没有定位祖先就会跑到更外层去,点 PIN 框重新聚焦会点空)和 align-items:center
(.auth-pin-boxes 是 grid,父级的 text-align:center 对它无效,不会居中)。 */
.youth-password-gate {
display: flex;
position: relative;
flex-direction: column;
align-items: center;
width: min(100%, 32rem);
margin: 0 auto;
padding: 3rem 2rem 2rem;
}
.youth-password-gate .auth-primary {
width: min(100%, 24rem);
margin-top: 3rem;
}
.auth-pin-boxes {
display: grid;
grid-template-columns: repeat(4, 4rem);