新增 DesktopShell 及桌面端首页、赛事、钱包、记录等页面,原 H5 视图迁移至 Mobile* 并由路由 wrapper 按视口切换。补齐右侧投注单栏、赔率快捷浮层、联赛/赛事侧栏、串关与定位能力;桌面下注成功改为全局 Toast,修复侧栏成功遮罩被裁剪与底部汇总黑底。同步悬浮客服、公告卡片、三语 i18n、桌面样式体系,以及 API 赛事与 shared 包相关调整。
45 lines
1.4 KiB
JavaScript
45 lines
1.4 KiB
JavaScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const root = path.join(__dirname, '..');
|
|
|
|
function flatten(obj, prefix = '') {
|
|
const out = {};
|
|
for (const [k, v] of Object.entries(obj)) {
|
|
const key = prefix ? `${prefix}.${k}` : k;
|
|
if (v && typeof v === 'object' && !Array.isArray(v)) Object.assign(out, flatten(v, key));
|
|
else out[key] = v;
|
|
}
|
|
return out;
|
|
}
|
|
|
|
function extractKeysFromDir(dir) {
|
|
const keys = new Set();
|
|
const re = /\bt\s*\(\s*['"`]([^'"`]+)['"`]/g;
|
|
function walk(d) {
|
|
for (const ent of fs.readdirSync(d, { withFileTypes: true })) {
|
|
const p = path.join(d, ent.name);
|
|
if (ent.isDirectory()) walk(p);
|
|
else if (ent.name.endsWith('.vue')) {
|
|
const src = fs.readFileSync(p, 'utf8');
|
|
let m;
|
|
while ((m = re.exec(src))) keys.add(m[1]);
|
|
}
|
|
}
|
|
}
|
|
walk(dir);
|
|
return keys;
|
|
}
|
|
|
|
const zhMod = await import('../src/i18n/zh-CN.ts');
|
|
const zh = flatten(zhMod.default);
|
|
const dirs = ['src/views/desktop', 'src/components/desktop'].map((d) => path.join(root, d));
|
|
const used = new Set();
|
|
for (const d of dirs) extractKeysFromDir(d).forEach((k) => used.add(k));
|
|
|
|
const missing = [...used].filter((k) => !(k in zh)).sort();
|
|
console.log(`Missing keys (${missing.length}):`);
|
|
missing.forEach((k) => console.log(` ${k}`));
|