diff --git a/app/solutions/[slug]/page.tsx b/app/solutions/[slug]/page.tsx new file mode 100644 index 0000000..6b0b68f --- /dev/null +++ b/app/solutions/[slug]/page.tsx @@ -0,0 +1,39 @@ +import { notFound } from "next/navigation"; +import type { Metadata } from "next"; +import { getSolutionBySlug } from "@/services/solution.service"; +import { BlockRenderer } from "@/blocks/BlockRenderer"; + +interface SolutionDetailPageProps { + params: Promise<{ slug: string }>; +} + +export async function generateMetadata({ + params, +}: SolutionDetailPageProps): Promise { + const { slug } = await params; + const solution = await getSolutionBySlug(slug).catch(() => null); + return { title: solution?.title ?? "解决方案未找到" }; +} + +export default async function SolutionDetailPage({ + params, +}: SolutionDetailPageProps) { + const { slug } = await params; + const solution = await getSolutionBySlug(slug).catch(() => null); + + if (!solution) { + notFound(); + } + + return ( +
+

+ {solution.title} +

+ {solution.industry && ( +

{solution.industry}

+ )} + +
+ ); +} diff --git a/app/solutions/page.tsx b/app/solutions/page.tsx new file mode 100644 index 0000000..c8d33f5 --- /dev/null +++ b/app/solutions/page.tsx @@ -0,0 +1,38 @@ +import Link from "next/link"; +import type { Metadata } from "next"; +import { getSolutionList } from "@/services/solution.service"; + +export const metadata: Metadata = { + title: "解决方案", +}; + +export default async function SolutionListPage() { + const solutions = await getSolutionList().catch(() => []); + + return ( +
+

解决方案

+ +
+ ); +} diff --git a/components/layout/Header.tsx b/components/layout/Header.tsx index 2788fcc..01abefd 100644 --- a/components/layout/Header.tsx +++ b/components/layout/Header.tsx @@ -3,6 +3,7 @@ import Link from "next/link"; const navItems = [ { title: "首页", href: "/" }, { title: "产品", href: "/products" }, + { title: "解决方案", href: "/solutions" }, { title: "案例", href: "/cases" }, { title: "博客", href: "/blog" }, ]; diff --git a/services/solution.service.ts b/services/solution.service.ts new file mode 100644 index 0000000..4e9ae6f --- /dev/null +++ b/services/solution.service.ts @@ -0,0 +1,26 @@ +import { fetchAPI } from "./api-client"; +import type { + SolutionPageDetail, + SolutionPageSummary, + WagtailListResponse, +} from "@/types/wagtail"; + +/** 获取解决方案列表。 */ +export async function getSolutionList(): Promise { + const res = await fetchAPI>( + "/api/v2/pages/?type=solutions.SolutionPage&fields=industry,summary", + { tags: ["solution-list"] }, + ); + return res.items; +} + +/** 根据 slug 获取解决方案详情。 */ +export async function getSolutionBySlug( + slug: string, +): Promise { + const res = await fetchAPI>( + `/api/v2/pages/?type=solutions.SolutionPage&slug=${encodeURIComponent(slug)}&fields=body,industry,summary&limit=1`, + { tags: [`solution:${slug}`] }, + ); + return res.items[0] ?? null; +} diff --git a/types/wagtail.ts b/types/wagtail.ts index 7b21303..8c95b0a 100644 --- a/types/wagtail.ts +++ b/types/wagtail.ts @@ -147,3 +147,12 @@ export interface CaseStudyPageSummary extends WagtailPageSummary { export interface CaseStudyPageDetail extends CaseStudyPageSummary { body: StreamFieldBlock[]; } + +export interface SolutionPageSummary extends WagtailPageSummary { + industry?: string; + summary?: string; +} + +export interface SolutionPageDetail extends SolutionPageSummary { + body: StreamFieldBlock[]; +}