feat(admin): 首页卡片配置 + 页头开关验证 + 编辑按钮仅登录可见
- settings.sections:显隐 / 顺序 / 标题覆盖 / 预览条数,HomeView 应用 - /admin 新增「首页卡片」Tab,卡片标题使用展示块标题(常用站点等) - 详情页 [编辑] 仅在登录后渲染(canEdit) - 测试:46 passed;页头禁用、卡片隐藏/改标题/限条数、编辑可见性均实测 - 文档:ADMIN-PLAN、README
This commit is contained in:
@@ -12,6 +12,13 @@ export type HeaderItem = {
|
||||
tone: SettingsTone
|
||||
}
|
||||
|
||||
export type SectionSettings = {
|
||||
hidden: string[]
|
||||
order: string[]
|
||||
titles: Record<string, string>
|
||||
limits: Record<string, number>
|
||||
}
|
||||
|
||||
export type SiteSettings = {
|
||||
header: {
|
||||
enabled: boolean
|
||||
@@ -23,6 +30,7 @@ export type SiteSettings = {
|
||||
hidden: string[]
|
||||
order: string[]
|
||||
}
|
||||
sections: SectionSettings
|
||||
}
|
||||
|
||||
export type SettingsDocument = {
|
||||
@@ -53,6 +61,7 @@ export function defaultSettings(): SiteSettings {
|
||||
],
|
||||
},
|
||||
sidebar: { hidden: [], order: [] },
|
||||
sections: { hidden: [], order: [], titles: {}, limits: {} },
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,8 +124,43 @@ export function applySidebarSettings<T extends { id: string }>(
|
||||
categories: T[],
|
||||
sidebar: SiteSettings['sidebar'],
|
||||
): T[] {
|
||||
const hidden = new Set(sidebar.hidden)
|
||||
const ranks = new Map(sidebar.order.map((id, index) => [id, index]))
|
||||
return orderAndFilter(categories, sidebar)
|
||||
}
|
||||
|
||||
/** 首页卡片:过滤隐藏、按 order 排序(未列出的保持原顺序) */
|
||||
export function applySectionSettings<T extends { id: string }>(
|
||||
categories: T[],
|
||||
sections: SectionSettings,
|
||||
): T[] {
|
||||
return orderAndFilter(categories, sections)
|
||||
}
|
||||
|
||||
/** 卡片标题:设置里的覆盖值优先 */
|
||||
export function sectionTitle(
|
||||
id: string,
|
||||
fallback: string,
|
||||
sections: SectionSettings,
|
||||
): string {
|
||||
const override = sections.titles[id]
|
||||
return override !== undefined && override.trim() !== '' ? override : fallback
|
||||
}
|
||||
|
||||
/** 卡片预览条数:设置里的覆盖值优先 */
|
||||
export function sectionLimit(
|
||||
id: string,
|
||||
fallback: number,
|
||||
sections: SectionSettings,
|
||||
): number {
|
||||
const override = sections.limits[id]
|
||||
return typeof override === 'number' && override > 0 ? override : fallback
|
||||
}
|
||||
|
||||
function orderAndFilter<T extends { id: string }>(
|
||||
categories: T[],
|
||||
config: { hidden: string[]; order: string[] },
|
||||
): T[] {
|
||||
const hidden = new Set(config.hidden)
|
||||
const ranks = new Map(config.order.map((id, index) => [id, index]))
|
||||
|
||||
return categories
|
||||
.filter((category) => !hidden.has(category.id))
|
||||
|
||||
Reference in New Issue
Block a user