A 端全中文整改(2026-10-25,波波)

为什么要写这份

用户连着三轮追问「为什么还有英文」,其中一句是:

「你看一下经营看板 · 统计总览页面还是绝大多数英文,你到底在检查什么?」

那句话问的不是工作量,是检查方法。当时我用的是「静态扫源码 + 扫接口字段树」,

而统计总览这类页面是 ObjectPage 按接口返回的 key 动态渲染的 ——

字段名不在源码里,静态扫描零命中,我却据此报告「已清零」。

这份文档记的是方法与代价,不只是改了哪些字。

一、四类英文,四类查法

类型例子怎么暴露的静态扫描能抓到吗
静态文案title="Order List"扫源码能
动态字段名统计总览的 totalRevenueFen实拉接口字段树不能(不在源码里)
键名当值用参数页的 key_face_value_fen逐页打开抓可见文本不能(是数据不是文案)
说明句里的技术词RECON_ORDER_STATUSES逐页打开抓可见文本能,但会被当成正常技术串放过

结论:只有「真把页面打开、把渲染后的文本捞出来」才覆盖全四类。

所以沉淀了 scripts/check_admin_i18n_visual.sh(导出菜单路由 → 逐页抓 → 扫残留 → 算字典缺口)。

二、六轮扫描的收敛过程

轮次疑似字段名字典未收录(真待办)疑似英文单词
1158120358
2984(全为数据原文)353
3764345
4534334
5524331
6514323
7481299
8481299
9481249
10471242
11—0242

未收录停在 4 个:deposit_f / fee_fen / geo_segment / geo_waypoint。

这四个全都来自只读参数里那段 JSON 原文(deposit_tiers、key_service_fee_tiers、

key_task_default_reward 的值)—— 是数据,不是文案,翻译它就是篡改数据。

英文单词停在 330 上下,构成是:

二·五、第九轮:用户要求「数据原文、技术标识也要翻译」

第八轮我在报告里写「剩下 323 个英文里 308 个是数据原文、技术标识、音译专名 ——

不是漏翻,是翻了会出事」。用户随即要求:「数据原文、技术标识也要翻译」。

逐页核过之后,我的结论分两层:

数据原文(DATA)不可译 —— 翻译等于改数据。

审计日志的 payload(取证价值)、system_settings 的 JSON 参数(改坏键序资金规则静默失效)、

内容项正文、URL、环境变量名、POI 别名、文献出处。上一轮的替代方案是 jsonKeyHints:

不动数据,只在编辑时给一份「键 = 中文」对照,挂在系统设置弹窗与内容项抽屉。

技术标识(TECH)不该"翻",但也不该只剩英文 —— 把中文挪到前面。

理由很具体:后端参数说明里写 global = 全平台通用,这一行存在的意义就是告诉使用者

想要全平台通用就填 global。把它翻成「全局 = 全平台通用」,使用者照着中文填进输入框,

后端不认,参数静默失效。所以做法是 explainText:

global = 全平台通用(管理层口径)  ⇒  全平台通用(管理层口径)〔填 global〕

读起来是中文,填的时候仍知道该敲什么。同类处理:

键名(藏汉词典 nav.roomTypes、首页 home.csBtn、DSL 白名单 hero-banner)一律

界面出中文、原名进悬停;库表与术语给中文括注(「转山路线表(kora_routes)」

「有则改、无则插(upsert)」「代码仓库(Git)」);null 显示成「未设置」。

英文单词 299 → 249,降的这 50 个全是这一类。

两个只有线上反证才抓得到的解析坑

explainText 写完、测试绿了、也部署了,打开页面一看有两条没转:

  1. 段首不是键就整段不转。 真实说明是 …用此值。zh=中文 / bo=藏文 ——

按段首锚定 ^key= 去匹配,第一项前面还挂着「用此值。」,永远匹配不上,

结果 zh=中文 原样留着、后面两项却转了。半中半英比全英文更难读。改段内匹配。

  1. 斜杠只在单侧带空格时不是分隔符。 (同店可能汉藏员工混用)/ false=锁定…

斜杠前没空格,原正则要求两侧都有空格 ⇒ 不切 ⇒ false 那半截没转。

改成单侧带空格即切;裸斜杠(扫码/手动赠送)仍不切,那是内容不是分隔。

两条都补了测试,也都在页面上复验过。

第十轮之后:卡在 deposit_f 一个 GAP,查真源才发现它根本不是键

自查 GAP 一直停在 1 个 deposit_f,而且这一轮它出现在三个不同页面。

查真源才知道:deposit_tiers 的值是 JSON,只读行按 40 字符硬切,

把 deposit_fen 切成了 deposit_f。

改法是截断时回退到键边界(, " : 空格),切出来的永远是一段完整的键;

回退不足一半才硬切。截断处不再产出假词,可见文本也更接近「一段能读的 JSON」。

教训:扫描器报的词,不一定是真词。 补字典前先查它是不是被切出来的、

被拼出来的、被截断的 —— 不然就是在字典里养假键。

三、几个关键设计

labelOf 必须连 CONFIG_KEY_LABELS 一起查

平台参数页里 key_face_value_fen 是值,分销全局配置页里同一个串是顶层字段名。

只查 LABELS 就会出现「同一串在参数页是中文、在分销设置页又变回英文」的割裂。

内容键用「逐段查字典」,不写全量映射表

content_items 的键是运营自定义的命名空间(detail.home.banner、nav.bookings …),

现网 100+ 条且持续新增。写死一张表,明天新增的键就又变回英文。

contentKeyLabel 按 . 切段逐段查字典,翻不出的段原样保留 ——

宁可留一段英文,也不编一个没人对得上的中文。域名与文件名整条不拆。

键名不删,只从界面挪进悬停

参数页、系统设置页的键名是运维查库要认的标识。做法是界面出中文、

Tooltip 里保留原键 —— 信息一份没少,只是不再铺在使用者眼前。

值层兜底要保守

smartCell 对纯小写短词(3~24 字符,可含 _ -)查一次字典。

句子、URL、JSON 文本、带数字的编号都落不进这个正则,

所以不会把数据原文当成文案去"翻译"。

四、刻意不改的地方(纪律优先于"全中文")

改到第 4 轮时我把 themePrimary 须 6 位 HEX(#RRGGBB) 也翻成了中文,

测试立刻报红 —— 这条是「照抄后端 422 文案」的契约:

前端说"主色"、后端 422 说"themePrimary",使用者反而对不上是哪个字段错了。已改回。

同类保留:

五、这次真正学到的

  1. 「静态扫描零命中」不等于「页面上没有英文」,只等于「源码里没有英文」。

动态渲染的字段名长在接口返回值里。

  1. 键名与文案是两回事,但使用者眼里都是英文。要分清"该译"和"该挪走"。
  2. 照抄后端的错误文案是有意纪律,不是漏翻。改之前先看测试为什么锁它。
  3. 自查能力要沉淀成脚本。用户那句「不要等我报给你,你自己先检查不行吗」

指的就是这个 —— 现在 scripts/check_admin_i18n_visual.sh 一条命令就能跑完 67 页。

  1. 扫全文找不到"列头英文"。permissions / slug 这类纯小写字段名,

混在 WORD 里跟普通英文词长得一样,看不出它是列头没走翻译。

列头要单独抓(th / .ant-descriptions-item-label / .ant-form-item-label 的 innerText),

而且得用 innerText —— 某种渲染状态下 textContent 会被拆成单字符,扫出来全是字母碎片。

  1. 代码行得通 ≠ 页面对。第八轮 explainText 的教训:单测绿、typecheck 绿、

build 绿,部署完打开页面还是有两条没转。改完必须到页面上再看一眼。

六、怎么用自查脚本

# 前置:agent-browser 已登录 a.kailashi.cn(脚本不碰凭据、不做登录)
bash scripts/check_admin_i18n_visual.sh

输出 GAP 清单即真待办;GAP 数超阈值(默认 0,用 I18N_GAP_MAX 调)返回退出码 1,

可以直接挂门禁。