diff --git a/common/js/lang.js b/common/js/lang.js index e6c0500..49e174f 100644 --- a/common/js/lang.js +++ b/common/js/lang.js @@ -856,26 +856,31 @@ function normalizeRemoteTreeForPage(tree, langPath) { const segments = String(langPath).split('/').filter(Boolean); if (!segments.length) return tree; - // 沿 langPath 段向下找页面 leaf:同一段同时尝试 camelCase 与 snake_case(bundle 服务器侧 - // 对同一段实际可能用任一种命名,例如 point/order_list 在 bundle 里是 `tree.point.order_list.X`, - // 而 login/login 这种 camel 路径又是 `tree.login.login.X`)。 + // 沿 langPath 段向下找页面 leaf:同一段同时尝试 camelCase、snake_case 与原始段名 + // (bundle 服务器侧对同一段实际可能用任一种命名,例如 point/order_list 在 bundle 里是 + // `tree.point.order_list.X`,而 login/login 这种 camel 路径又是 `tree.login.login.X`; + // 路径含连字符(如 ai-chat/index)时,原始段名 `ai-chat` 是唯一能命中 bundle 的形式)。 let leaf = tree; let hasLeaf = true; for (const segment of segments) { const camel = toCamelCaseName(segment); const snake = toSnakeCaseName(segment); - // 优先 camelCase;没有就回退 snake_case;都没有就放弃 + const raw = segment; + // 优先 camelCase;回退 snake_case;再回退原始段名;都没有就放弃 const key = (leaf && typeof leaf === 'object' && !Array.isArray(leaf) && leaf[camel] !== undefined) ? camel : (leaf && typeof leaf === 'object' && !Array.isArray(leaf) && leaf[snake] !== undefined ? snake - : null); + : (leaf && typeof leaf === 'object' && !Array.isArray(leaf) && raw !== camel && raw !== snake && leaf[raw] !== undefined + ? raw + : null)); if (key === null) { hasLeaf = false; break; } leaf = leaf[key]; } - const lastSegment = toCamelCaseName(segments[segments.length - 1]); - const lastSegmentSnake = toSnakeCaseName(segments[segments.length - 1]); + const rawLast = segments[segments.length - 1]; + const lastSegment = toCamelCaseName(rawLast); + const lastSegmentSnake = toSnakeCaseName(rawLast); const currentPageLeaf = hasLeaf && leaf && typeof leaf === 'object' && !Array.isArray(leaf) ? leaf @@ -883,7 +888,9 @@ function normalizeRemoteTreeForPage(tree, langPath) { ? tree[lastSegment] : (tree[lastSegmentSnake] && typeof tree[lastSegmentSnake] === 'object' && !Array.isArray(tree[lastSegmentSnake]) ? tree[lastSegmentSnake] - : null)); + : (rawLast !== lastSegment && rawLast !== lastSegmentSnake && tree[rawLast] && typeof tree[rawLast] === 'object' && !Array.isArray(tree[rawLast]) + ? tree[rawLast] + : null))); if (!currentPageLeaf) return tree;