/** * 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 interface ProductCardItemValue { title: string; description?: string; image?: { url: string; title: string } | null; link?: string; } export interface ProductCardBlockValue { heading?: string; items: ProductCardItemValue[]; } export interface PricingPlanValue { name: string; price: string; features: string[]; highlighted?: boolean; button?: CTAButtonValue | null; } export interface PricingBlockValue { heading?: string; plans: PricingPlanValue[]; } export interface TimelineItemValue { year: string; event: string; } export interface TimelineBlockValue { heading?: string; items: TimelineItemValue[]; } export interface TeamMemberBlockValue { id: number; name: string; role: string; bio: string; photo: { url: string; title: string } | null; } export interface TeamBlockValue { heading?: string; members: TeamMemberBlockValue[]; } export interface TechStackItemValue { icon?: string; label: string; } export interface TechStackBlockValue { heading?: string; items: TechStackItemValue[]; } export interface VideoBlockValue { heading?: string; video_url: string; poster?: { url: string; title: string } | 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: "product_card"; value: ProductCardBlockValue } | { id: string; type: "pricing"; value: PricingBlockValue } | { id: string; type: "timeline"; value: TimelineBlockValue } | { id: string; type: "team"; value: TeamBlockValue } | { id: string; type: "tech_stack"; value: TechStackBlockValue } | { id: string; type: "video"; value: VideoBlockValue } | { 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[]; } export interface SimpleContentPageDetail extends WagtailPageSummary { body: string; // richtext HTML } /** * 全局 Snippet 类型(apps/core/models.py)。 * 通过 /api/v1/custom/core/... 只读接口获取,非 Wagtail Page API。 */ export interface TeamMemberValue { id: number; name: string; role: string; bio: string; photo: { url: string; title: string } | null; } export interface TestimonialValue { id: number; quote: string; author_name: string; author_title: string; author_photo: { url: string; title: string } | null; } export interface PartnerValue { id: number; name: string; website_url: string; logo: { url: string; title: string } | null; } export interface NavigationMenuItemValue { label: string; url: string; open_in_new_tab: boolean; } export interface NavigationMenuValue { name: string; items: NavigationMenuItemValue[]; } export interface SiteSettingsValue { company_name: string; contact_phone: string; contact_email: string; address: string; icp_number: string; icp_url: string; wechat_account: string; weibo_url: string; wechat_qrcode: { url: string; title: string } | null; }