/** * 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 interface CaseStudyBlockValue { case_page: WagtailPageSummary | null; summary?: string; } /** 与后端 apps/forms/models.py FIELD_TYPE_CHOICES 保持一致 */ export type FormFieldType = "text" | "textarea" | "email" | "tel" | "select"; export interface FormFieldDef { label: string; field_key: string; field_type: FormFieldType; required: boolean; choices: string[]; } export interface FormDefinitionValue { id: number; name: string; submit_button_text: string; success_message: string; fields: FormFieldDef[]; } export interface FormBlockValue { form: FormDefinitionValue | null; } 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: "case_study"; value: CaseStudyBlockValue } | { id: string; type: "form"; value: FormBlockValue } | { 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[]; } export interface ProductPageSummary extends WagtailPageSummary { summary?: string; } export interface ProductPageDetail extends ProductPageSummary { body: StreamFieldBlock[]; } export interface CaseStudyPageSummary extends WagtailPageSummary { client_name: string; industry?: string; published_at?: string; summary?: string; } export interface CaseStudyPageDetail extends CaseStudyPageSummary { body: StreamFieldBlock[]; } export interface SolutionPageSummary extends WagtailPageSummary { industry?: string; summary?: string; } export interface SolutionPageDetail extends SolutionPageSummary { body: StreamFieldBlock[]; }