import type { ChapterViewModel } from './types'; /** * 与后端 `CHAPTER_ORDER` / `CHAPTER_CATEGORIES` 顺序一致;对应 i18n `memoir.frameworkChapters.*`。 */ export const FRAMEWORK_CHAPTER_KEYS = [ 'chapter1', 'chapter2', 'chapter3', 'chapter4', 'chapter5', 'chapter6', 'chapter7', 'chapter8', ] as const; export type FrameworkChapterKey = (typeof FRAMEWORK_CHAPTER_KEYS)[number]; /** 与后端 `CHAPTER_ORDER` 一致(用于占位章节缺省 category) */ export const CHAPTER_CATEGORY_BY_ORDER_INDEX = [ 'childhood', 'education', 'career_early', 'career_achievement', 'career_challenge', 'family', 'beliefs', 'summary', ] as const; export function buildFrameworkChapterPlaceholders( tr: (key: string) => string, ): ChapterViewModel[] { return FRAMEWORK_CHAPTER_KEYS.map((key, orderIndex) => ({ id: `framework:${key}`, title: tr(`frameworkChapters.${key}`), category: '', orderIndex, isEmpty: true, isNew: false, hasImages: false, allImagesReady: false, pendingImageCount: 0, failedImageCount: 0, coverImageUrl: null, updatedAt: null, wordCount: 0, })); } /** * 列表页始终展示 8 个框架槽位:已有章节用接口数据,其余槽位仍用框架占位(与「零章节」时一致)。 */ export function mergeFrameworkChaptersWithFetched( placeholders: ChapterViewModel[], fetched: ChapterViewModel[], ): ChapterViewModel[] { const byOrder = new Map(); for (const vm of fetched) { byOrder.set(vm.orderIndex, vm); } return placeholders.map((p) => byOrder.get(p.orderIndex) ?? p); }