优化pagetypeOverride.ts模板覆盖优先级排序
This commit is contained in:
parent
f87dfd4400
commit
c83c10d7ea
@ -22,9 +22,7 @@ type SourceEntry = {
|
|||||||
|
|
||||||
const allPagetypeViews: Record<string, SourceEntry> = {}
|
const allPagetypeViews: Record<string, SourceEntry> = {}
|
||||||
|
|
||||||
function getPathSegments(path: string): string[] {
|
// 保留占位,若后续需要扩展路径解析可重新启用
|
||||||
return path.split('/').filter(Boolean)
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractAppName(absPath: string): string {
|
function extractAppName(absPath: string): string {
|
||||||
// 形如 @apps/<app>/frontend/src/...
|
// 形如 @apps/<app>/frontend/src/...
|
||||||
@ -59,13 +57,43 @@ for (const [p, loader] of Object.entries(globLocal)) {
|
|||||||
function sortByPriority(a: string, b: string): number {
|
function sortByPriority(a: string, b: string): number {
|
||||||
const ra = rankByAppsOrder(allPagetypeViews[a].appName)
|
const ra = rankByAppsOrder(allPagetypeViews[a].appName)
|
||||||
const rb = rankByAppsOrder(allPagetypeViews[b].appName)
|
const rb = rankByAppsOrder(allPagetypeViews[b].appName)
|
||||||
// apps.txt 靠后优先 => 更大的索引优先
|
|
||||||
if (ra !== rb) return rb - ra
|
if (ra !== rb) return rb - ra
|
||||||
// 同一应用下:路径更短优先,其次字母序
|
|
||||||
if (a.length !== b.length) return a.length - b.length
|
if (a.length !== b.length) return a.length - b.length
|
||||||
return a.localeCompare(b)
|
return a.localeCompare(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 预索引:按 entity 分组,分别索引 detail 与 toolbar 候选,并在构建时一次性排序
|
||||||
|
type Indexed = { detail: string[]; toolbar: string[] }
|
||||||
|
const indexedByEntity: Record<string, Indexed> = {}
|
||||||
|
|
||||||
|
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 的详情覆盖组件
|
* 解析并返回指定 pagetype 的详情覆盖组件
|
||||||
* @param pagetypeSlug 路由中的原始 pagetype(保持小写与下划线)
|
* @param pagetypeSlug 路由中的原始 pagetype(保持小写与下划线)
|
||||||
@ -74,27 +102,9 @@ export async function resolvePagetypeDetailOverride(pagetypeSlug: string): Promi
|
|||||||
if (!pagetypeSlug) return null
|
if (!pagetypeSlug) return null
|
||||||
const targetHyphen = pagetypeSlug.toLowerCase()
|
const targetHyphen = pagetypeSlug.toLowerCase()
|
||||||
const targetUnderscore = targetHyphen.replace(/-/g, '_')
|
const targetUnderscore = targetHyphen.replace(/-/g, '_')
|
||||||
|
const bucket = indexedByEntity[targetUnderscore]
|
||||||
const candidates = Object.keys(allPagetypeViews).filter((file) => {
|
if (!bucket || bucket.detail.length === 0) return null
|
||||||
const segs = getPathSegments(file)
|
const pick = bucket.detail[0]
|
||||||
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]
|
|
||||||
try {
|
try {
|
||||||
const mod = await allPagetypeViews[pick].loader()
|
const mod = await allPagetypeViews[pick].loader()
|
||||||
return mod?.default ?? mod
|
return mod?.default ?? mod
|
||||||
@ -111,27 +121,9 @@ export async function resolvePagetypeToolbarOverride(pagetypeSlug: string): Prom
|
|||||||
if (!pagetypeSlug) return null
|
if (!pagetypeSlug) return null
|
||||||
const targetHyphen = pagetypeSlug.toLowerCase()
|
const targetHyphen = pagetypeSlug.toLowerCase()
|
||||||
const targetUnderscore = targetHyphen.replace(/-/g, '_')
|
const targetUnderscore = targetHyphen.replace(/-/g, '_')
|
||||||
|
const bucket = indexedByEntity[targetUnderscore]
|
||||||
const candidates = Object.keys(allPagetypeViews).filter((file) => {
|
if (!bucket || bucket.toolbar.length === 0) return null
|
||||||
const segs = getPathSegments(file)
|
const pick = bucket.toolbar[0]
|
||||||
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]
|
|
||||||
try {
|
try {
|
||||||
const mod = await allPagetypeViews[pick].loader()
|
const mod = await allPagetypeViews[pick].loader()
|
||||||
return mod?.default ?? mod
|
return mod?.default ?? mod
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user