JianFeeeee
dda537cda9
fix(channels): 日志截断按字符(中文被切出 U+FFFD)+ 面板排版
## 真实缺陷(v2.0.33 上线后在截图里看到)
日志尾显示成:`能力增强不�`
根因:`tostring(cerr):sub(1, 120)` —— **Lua 的 sub 按字节切**,而中文占 3 字节
⇒ 切在字符中间产生**替换字符 U+FFFD**。一句本来完整的诊断("…能力增强不可用,
已退回兜底表")看起来像**数据损坏**,实际只是截断方式错。
生产实测复现:该条 120 字节截断后,末尾正好落在"不"字的第 1 字节上,
python 侧解码得到 `…能力增强不\ufffd`。**修法**:`plugin.utf8Clip(s, maxBytes)`
先按字节切、再回退到最后一个完整 UTF-8 序列边界(最多退 2 字节)。
三处中文文案截断全部改用它。
## 判据(1 条静态 + 1 条行为 + 变异 1/1)
- `TestLogTruncationIsUTF8Safe`(静态):助手存在 / 三处中文截断不再用裸 sub /
未超长时原样返回 / 回退逻辑处理孤立首字节
- `TestUtf8ClipBehaviour`(**行为**,经 `plugin.__utf8_clip_probe` 走真实函数):
对 6 个长度断言 `utf8.ValidString(out)` 且不超字节上限。静态断言看不出
"结果是否真的合法 UTF-8",所以必须有这一条 —— 实测 n=120 从
`…能力增强不�`(非法)变为 `…能力增强不`(合法)
- 变异:把 utf8Clip 换回裸 sub → 报红
## 排版抛光(截图里可见的三处)
- 头部控件原用 `<h2>` + flex,checkbox 被挤到换行且文字竖排 ⇒ 改 `<b>` +
独立 flex 行 + `white-space:nowrap`
- 长诊断在窄卡片里被**截断**(而截断的尾巴正是最该看的部分)⇒ `word-break`
- 列表加 `line-height`,可读性
## 兼容性
历史 state 里的 41 条老条目没有 `level` 字段 —— 前端 `e.level || "info"`
已容忍,**不需要数据迁移**(判据亦未假设字段必然存在)。
2026-10-16 17:44:04 +08:00
..
2026-10-16 14:52:13 +08:00
2026-10-16 17:44:04 +08:00
2026-10-15 20:31:45 +08:00
2026-10-16 14:52:13 +08:00
2026-10-15 20:31:45 +08:00
2026-10-14 16:52:58 +08:00
2026-10-14 16:52:58 +08:00
2026-10-14 16:52:58 +08:00
2026-10-06 15:02:42 +08:00
2026-10-12 16:37:23 +08:00
2026-10-11 09:23:34 +08:00
2026-10-11 09:23:34 +08:00
2026-10-02 12:41:35 +08:00
2026-10-14 16:52:58 +08:00
2026-10-14 16:52:58 +08:00
2026-10-14 16:52:58 +08:00
2026-10-14 16:52:58 +08:00
2026-10-12 12:32:10 +08:00
2026-10-14 16:52:58 +08:00
2026-10-02 10:45:20 +08:00
2026-10-14 16:52:58 +08:00
2026-10-02 14:07:44 +08:00
2026-10-13 06:57:28 +08:00
2026-10-13 06:57:28 +08:00
2026-10-14 16:52:58 +08:00
2026-10-14 16:52:58 +08:00
2026-10-04 14:50:46 +08:00
2026-10-11 09:35:32 +08:00
2026-10-05 08:17:57 +08:00
2026-10-05 08:17:57 +08:00
2026-10-11 13:25:11 +08:00
2026-10-11 10:03:43 +08:00
2026-10-12 12:32:10 +08:00
2026-10-14 16:52:58 +08:00
2026-10-14 16:52:58 +08:00
2026-10-05 08:17:57 +08:00
2026-10-05 08:17:57 +08:00
2026-10-05 08:17:57 +08:00
2026-10-11 09:35:32 +08:00
2026-10-11 09:35:32 +08:00
2026-10-15 15:02:04 +08:00
2026-10-13 06:57:28 +08:00
2026-10-13 06:57:28 +08:00
2026-10-13 06:57:28 +08:00
2026-10-16 00:56:35 +08:00
2026-10-14 16:52:58 +08:00
2026-10-16 00:56:35 +08:00
2026-10-11 20:50:52 +08:00
2026-10-07 17:37:22 +08:00
2026-10-05 08:17:57 +08:00
2026-10-11 13:25:11 +08:00
2026-10-15 22:43:58 +08:00
2026-10-14 16:52:58 +08:00
2026-10-11 09:35:32 +08:00
2026-10-04 14:50:46 +08:00
2026-10-14 16:52:58 +08:00
2026-10-16 00:56:35 +08:00
2026-10-07 17:37:22 +08:00
2026-10-11 09:35:32 +08:00
2026-10-12 12:32:10 +08:00
2026-10-14 16:52:58 +08:00
2026-10-14 16:52:58 +08:00
2026-10-12 16:32:30 +08:00
2026-10-14 16:52:58 +08:00
2026-10-11 08:17:56 +08:00
2026-10-11 09:35:32 +08:00
2026-10-12 19:07:17 +08:00
2026-10-14 16:52:58 +08:00