v1.0.10 两件大事:
1. 界面中英双语(英文界面无中文残留)
- 新增 web/i18n.js(约 4200 条词条),零依赖零构建
- 后端下发中文数据走 bt4() 查表翻译;独立模块(upstream/netdetail/
realtime/update)纳入翻译并注册切语言重绘钩子
- 后端「状态/聚合」接口只回稳定枚举+原始数值,不下发中文文案
- 顺带修一个真实 XSS:顶层 const 不挂 window,独立脚本 esc 静默退化成零转义
2. 修掉「文字竖着排/错位」(多分辨率反复暴露)
- 单元格 min-content 只有 1 字宽 → word-break:keep-all + 表头 nowrap
- 依赖卡片正文被标签/按钮挤成 27px → .dep-body{flex:1 1 200px} + flex-wrap
- 裸 flex:1(下限为0)给正文 → 一律改 flex:1 1 <px>
- .dep-item 横向容器直接塞块级子项 → 退回块级
- 关键陷阱:auto-fill 布局屏越宽列数越多单卡越窄,窄屏反而测不出来,
真机审计推进到「逐视图点按钮 + 1920/2560 宽视口 + 中英双语」
- 守卫 t-layout.py 扩到 35 条,12 处反向验证全红
3. 修真缺陷:_link_since() 重启检测被误改成 if False:(注释还写着「已修」),
uptime 归零后相减得负数 → 恢复比对 boot_id
附带:新增 25 个检查器(t-*.py)、排版审计工具链(shot-*/ocr-*/live-*)、
版本号兜底值同步到 1.0.10、.gitignore 收纳 i18n/排版排查的一次性脚本。
36 lines
1.7 KiB
JavaScript
36 lines
1.7 KiB
JavaScript
// 校验 PAGES 的 key 是否都在 VIEWS 里有映射。
|
||
// tag:'soon' 的占位页不需要渲染函数(点进去显示「等待作者完善」),自动排除。
|
||
const fs = require('fs');
|
||
// 以脚本自身位置定位,避免依赖运行时的当前目录(否则换个目录跑就 ENOENT)。
|
||
const WEB = require('path').join(__dirname, '..', 'web', 'app.js');
|
||
const path = process.argv[2] || WEB;
|
||
const s = fs.readFileSync(path, 'utf8');
|
||
|
||
// 惰性写法 `const NAV_GROUPS = () => ([ ... ]);` 也要认(见 t-nav-i18n-run)
|
||
const nav = s.match(/const NAV_GROUPS = (?:\(\)\s*=>\s*\()?\[([\s\S]*?)\n\]\)?;/);
|
||
if (!nav) { console.log('✘ 未找到 NAV_GROUPS'); process.exit(1); }
|
||
|
||
const items = [];
|
||
for (const m of nav[1].matchAll(/\{([^{}]*?k:\s*'([a-z0-9]+)'[^{}]*?)\}/g)) {
|
||
const body = m[1];
|
||
const key = m[2];
|
||
const soon = /tag:\s*'soon'/.test(body);
|
||
items.push({ key, soon });
|
||
}
|
||
|
||
const block = s.match(/const VIEWS = \{([\s\S]*?)\n\};/);
|
||
if (!block) { console.log('✘ 未找到 VIEWS 定义'); process.exit(1); }
|
||
const mapped = [];
|
||
for (const m of block[1].matchAll(/^\s*([a-z0-9_]+):/gm)) mapped.push(m[1]);
|
||
|
||
const real = items.filter((x) => !x.soon);
|
||
const soon = items.filter((x) => x.soon);
|
||
const missing = real.filter((x) => !mapped.includes(x.key)).map((x) => x.key);
|
||
const keys = items.map((x) => x.key);
|
||
const extra = mapped.filter((k) => !keys.includes(k));
|
||
|
||
console.log('菜单项:', items.length, '(已实现', real.length, '/ 规划中', soon.length, ')');
|
||
console.log('缺失映射:', missing.length ? missing.join(', ') + ' ✘' : '无 ✔');
|
||
console.log('多余映射:', extra.length ? extra.join(', ') : '无 ✔');
|
||
process.exit(missing.length ? 1 : 0);
|