From c83c10d7ea1d7e6ae46913d27c9a3ed241756adf Mon Sep 17 00:00:00 2001 From: jingrow Date: Tue, 28 Oct 2025 18:56:49 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96pagetypeOverride.ts=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E8=A6=86=E7=9B=96=E4=BC=98=E5=85=88=E7=BA=A7=E6=8E=92?= =?UTF-8?q?=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/core/registry/pagetypeOverride.ts | 86 +++++++++---------- 1 file changed, 39 insertions(+), 47 deletions(-) diff --git a/apps/jingrow/frontend/src/core/registry/pagetypeOverride.ts b/apps/jingrow/frontend/src/core/registry/pagetypeOverride.ts index b3513f8..a567889 100644 --- a/apps/jingrow/frontend/src/core/registry/pagetypeOverride.ts +++ b/apps/jingrow/frontend/src/core/registry/pagetypeOverride.ts @@ -22,9 +22,7 @@ type SourceEntry = { const allPagetypeViews: Record = {} -function getPathSegments(path: string): string[] { - return path.split('/').filter(Boolean) -} +// 保留占位,若后续需要扩展路径解析可重新启用 function extractAppName(absPath: string): string { // 形如 @apps//frontend/src/... @@ -59,13 +57,43 @@ for (const [p, loader] of Object.entries(globLocal)) { function sortByPriority(a: string, b: string): number { const ra = rankByAppsOrder(allPagetypeViews[a].appName) const rb = rankByAppsOrder(allPagetypeViews[b].appName) - // apps.txt 靠后优先 => 更大的索引优先 if (ra !== rb) return rb - ra - // 同一应用下:路径更短优先,其次字母序 if (a.length !== b.length) return a.length - b.length return a.localeCompare(b) } +// 预索引:按 entity 分组,分别索引 detail 与 toolbar 候选,并在构建时一次性排序 +type Indexed = { detail: string[]; toolbar: string[] } +const indexedByEntity: Record = {} + +function ensureIndexed(entity: string): Indexed { + if (!indexedByEntity[entity]) indexedByEntity[entity] = { detail: [], toolbar: [] } + return indexedByEntity[entity] +} + +// 构建索引 +for (const file of Object.keys(allPagetypeViews)) { + const segs = file.split('/').filter(Boolean) + const len = segs.length + if (len < 5) continue + const fileName = segs[len - 1] + const folderName = segs[len - 2] + const baseName = fileName.replace(/\.vue$/i, '') + const entity = folderName + const bucket = ensureIndexed(entity) + if (baseName === folderName) { + bucket.detail.push(file) + } else if (baseName === `${folderName}_toolbar`) { + bucket.toolbar.push(file) + } +} + +// 候选按优先级排序 +Object.values(indexedByEntity).forEach(({ detail, toolbar }) => { + detail.sort(sortByPriority) + toolbar.sort(sortByPriority) +}) + /** * 解析并返回指定 pagetype 的详情覆盖组件 * @param pagetypeSlug 路由中的原始 pagetype(保持小写与下划线) @@ -74,27 +102,9 @@ export async function resolvePagetypeDetailOverride(pagetypeSlug: string): Promi if (!pagetypeSlug) return null const targetHyphen = pagetypeSlug.toLowerCase() const targetUnderscore = targetHyphen.replace(/-/g, '_') - - const candidates = Object.keys(allPagetypeViews).filter((file) => { - const segs = getPathSegments(file) - const len = segs.length - if (len < 5) return false - const fileName = segs[len - 1] - const folderName = segs[len - 2] - const baseName = fileName.replace(/\.vue$/i, '') - return ( - segs.includes('views') && - segs.includes('pagetype') && - folderName === targetUnderscore && - baseName === targetUnderscore - ) - }) - - if (candidates.length === 0) return null - - candidates.sort(sortByPriority) - - const pick = candidates[0] + const bucket = indexedByEntity[targetUnderscore] + if (!bucket || bucket.detail.length === 0) return null + const pick = bucket.detail[0] try { const mod = await allPagetypeViews[pick].loader() return mod?.default ?? mod @@ -111,27 +121,9 @@ export async function resolvePagetypeToolbarOverride(pagetypeSlug: string): Prom if (!pagetypeSlug) return null const targetHyphen = pagetypeSlug.toLowerCase() const targetUnderscore = targetHyphen.replace(/-/g, '_') - - const candidates = Object.keys(allPagetypeViews).filter((file) => { - const segs = getPathSegments(file) - const len = segs.length - if (len < 5) return false - const fileName = segs[len - 1] - const folderName = segs[len - 2] - const baseName = fileName.replace(/\.vue$/i, '') - return ( - segs.includes('views') && - segs.includes('pagetype') && - folderName === targetUnderscore && - baseName === `${targetUnderscore}_toolbar` - ) - }) - - if (candidates.length === 0) return null - - candidates.sort(sortByPriority) - - const pick = candidates[0] + const bucket = indexedByEntity[targetUnderscore] + if (!bucket || bucket.toolbar.length === 0) return null + const pick = bucket.toolbar[0] try { const mod = await allPagetypeViews[pick].loader() return mod?.default ?? mod