Files
sage-home/app/[locale]/workshop/[slug]/page.tsx
砂糖 99ce2b7fb8 feat: 更新网站配置和内容,优化国际化设置
refactor: 重构产线页面和路由,移除无用代码
style: 调整内容格式和样式,统一中英文标点
docs: 更新产品描述和元数据,完善多语言支持
2026-01-26 16:22:07 +08:00

132 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { LOCALES } from "@/i18n/routing";
import { constructMetadata } from "@/lib/metadata";
import { getWorkShop, getWorkShops } from "@/lib/workshop";
import { WorkShop } from "@/types/workShop";
import { Metadata } from "next";
import { Locale } from "next-intl";
// 固定 Params 类型为普通对象Next.js 原生传参无异步)
type Params = {
locale: string;
slug: string;
};
type MetadataProps = {
params: Params;
};
export async function generateMetadata({
params,
}: MetadataProps): Promise<Metadata> {
const { locale, slug } = await params;
const workShop = await getWorkShop(locale, slug);
console.log(workShop);
console.log(workShop?.slug);
if (!workShop) {
return constructMetadata({
title: "404 - 车间不存在",
description: "请求的车间页面未找到",
noIndex: true,
locale: locale as Locale,
path: `/workshop/${slug}`,
canonicalUrl: `/workshop/${slug}`,
});
}
return constructMetadata({
title: workShop.title,
description: workShop.desc,
locale: locale as Locale,
path: `/workshop/${slug}`,
canonicalUrl: `/workshop/${slug}`,
});
}
// 页面主组件 - 仅保留字段展示+修复 Hydration 错误
export default async function WorkshopDetailPage({ params }: { params: Params }) {
// 🔴 核心修复1移除不必要的 awaitparams 是同步对象)
const { locale, slug } = await params;
const workShop = await getWorkShop(locale, slug);
if (!workShop) return null;
// 兜底处理:避免字段为空导致属性不匹配
const coverSrc = workShop.cover || "";
const coverAlt = workShop.title || "车间封面";
const workshopDesc = workShop.desc || "暂无车间描述";
return (
<div className="min-h-screen bg-gray-50 py-10 px-4 sm:px-6 lg:px-8">
<div className="max-w-6xl mx-auto">
{/* 封面图区域 - 🔴 修复布局属性不一致 */}
<div className="relative rounded-2xl overflow-hidden shadow-lg h-[400px] sm:h-[500px] mb-8">
<img
src={coverSrc}
alt={coverAlt}
className="absolute inset-0 w-full h-full object-cover transition-transform hover:scale-105 duration-700"
// 显式设置属性,确保服务端/客户端一致
loading="lazy"
decoding="async"
/>
</div>
{/* 标题+描述区域 */}
<div className="bg-white rounded-xl p-8 shadow-sm mb-10">
<h1 className="text-3xl sm:text-4xl font-bold text-gray-900 mb-6">
{workShop.title}
</h1>
<p className="text-lg text-gray-700 leading-relaxed">
{workshopDesc}
</p>
</div>
{workShop.images?.length > 0 && (
<div className="bg-white rounded-xl p-8 shadow-sm">
<h2 className="text-2xl font-semibold text-gray-800 mb-6 border-b pb-3 border-gray-200">
</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
{workShop.images.map((img, index) => {
const stableKey = `workshop-${slug}-img-${index}-${img.slice(-8)}`;
const imgAlt = `${workShop.title}-图片${index + 1}`;
return (
<div
key={stableKey}
className="relative rounded-lg overflow-hidden shadow-md h-64 hover:shadow-xl transition-all duration-300"
>
<img
src={img}
alt={imgAlt}
className="absolute inset-0 w-full h-full object-cover transition-transform hover:scale-110 duration-500"
loading="lazy"
decoding="async"
/>
</div>
);
})}
</div>
</div>
)}
</div>
</div>
);
}
export async function generateStaticParams() {
try {
const defaultLocale = LOCALES[0];
const workShops: WorkShop[] = await getWorkShops(defaultLocale);
return LOCALES.flatMap((locale) =>
workShops.map((workShop) => ({
locale,
slug: workShop.slug as string,
}))
);
} catch (error) {
console.error("生成产品静态参数失败:", error);
return [];
}
}