Files
sage-home/app/[locale]/workshop/[slug]/page.tsx
砂糖 e7a428d8f0 feat(i18n): 更新中英文翻译及国际化支持
- 在Workshop和Line模块中添加新的翻译字段
- 修复页面中硬编码的文本,改为使用翻译
- 更新产品线和车间展示的英文翻译内容
- 为卡片组件添加locale属性传递
2026-02-03 17:18:13 +08:00

128 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";
import { getTranslations } from "next-intl/server";
// 固定 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);
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 }) {
const { locale, slug } = await params;
const workShop = await getWorkShop(locale, slug);
const t = await getTranslations({ locale, namespace: "Workshop" });
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-16 px-6 sm:px-8 lg:px-10">
<div className="max-w-7xl mx-auto space-y-12">
{/* 封面图区域 - 强化背景效果 */}
<div className="relative rounded-xl overflow-hidden shadow-lg h-[500px] sm:h-[600px] mb-12 group">
<img
src={coverSrc}
alt={coverAlt}
className="absolute inset-0 w-full h-full object-cover transition-transform duration-500 group-hover:scale-110"
loading="lazy"
decoding="async"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black opacity-40"></div>
</div>
{/* 标题+描述区域 */}
<div className="bg-white rounded-xl p-8 shadow-xl">
<h1 className="text-3xl sm:text-4xl font-bold text-gray-900 mb-6">{workShop.title}</h1>
<p className="text-lg sm:text-xl text-gray-700 leading-relaxed mb-6">{workshopDesc}</p>
</div>
{/* 图片展示区域 */}
{workShop.images?.length > 0 && (
<div className="bg-white rounded-xl p-8 shadow-xl mt-12">
<h2 className="text-2xl font-semibold text-gray-800 mb-6 border-b pb-3 border-gray-200">
{t("pageImages")}
</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-xl overflow-hidden shadow-lg hover:shadow-2xl transition-all duration-300"
>
<img
src={img}
alt={imgAlt}
className="w-full h-full object-cover transition-transform duration-500 hover:scale-105"
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 [];
}
}