/** * Wagtail API v2 通用类型定义。 * 对应后端 apps/core/blocks.py 中的 StreamField Block 结构, * 前后端字段需保持一致(详见 documents/设计方案分析与完善版.md §2.6)。 */ export interface WagtailMeta { type: string; detail_url: string; html_url: string | null; slug: string; first_published_at: string | null; } export interface WagtailPageSummary { id: number; meta: WagtailMeta; title: string; } export interface WagtailListResponse { meta: { total_count: number }; items: T[]; } export interface CTAButtonValue { text: string; link: string; } export interface StatItemValue { value: string; label: string; } export interface FeatureItemValue { icon?: string; title: string; description: string; } export interface FAQItemValue { question: string; answer: string; // richtext HTML } export interface HeroBlockValue { title: string; subtitle?: string; background_image?: { url: string; title: string } | null; buttons: CTAButtonValue[]; } export interface StatsBlockValue { items: StatItemValue[]; } export interface FeatureGridBlockValue { heading?: string; items: FeatureItemValue[]; } export interface FAQBlockValue { items: FAQItemValue[]; } export interface CTABlockValue { heading: string; description?: string; button: CTAButtonValue; } export interface LogoCloudBlockValue { heading?: string; logos: { url: string; title: string }[]; } export type StreamFieldBlock = | { id: string; type: "hero"; value: HeroBlockValue } | { id: string; type: "stats"; value: StatsBlockValue } | { id: string; type: "feature_grid"; value: FeatureGridBlockValue } | { id: string; type: "faq"; value: FAQBlockValue } | { id: string; type: "cta"; value: CTABlockValue } | { id: string; type: "logo_cloud"; value: LogoCloudBlockValue } | { id: string; type: "richtext"; value: string }; export interface HomePageDetail extends WagtailPageSummary { body: StreamFieldBlock[]; seo_title_override?: string; seo_description_override?: string; } export interface BlogPageSummary extends WagtailPageSummary { intro?: string; published_at?: string; } export interface BlogPageDetail extends BlogPageSummary { body: StreamFieldBlock[]; }