feat(i18n): 更新中英文翻译及国际化支持
- 在Workshop和Line模块中添加新的翻译字段 - 修复页面中硬编码的文本,改为使用翻译 - 更新产品线和车间展示的英文翻译内容 - 为卡片组件添加locale属性传递
This commit is contained in:
@@ -4,6 +4,7 @@ import { constructMetadata } from "@/lib/metadata";
|
|||||||
import { Line } from "@/types/line";
|
import { Line } from "@/types/line";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
import { Locale } from "next-intl";
|
import { Locale } from "next-intl";
|
||||||
|
import { getTranslations } from "next-intl/server";
|
||||||
|
|
||||||
// 强制静态渲染
|
// 强制静态渲染
|
||||||
export const dynamic = "force-static";
|
export const dynamic = "force-static";
|
||||||
@@ -48,6 +49,7 @@ export async function generateMetadata({
|
|||||||
export default async function ProductDetailPage({ params }: { params: Params }) {
|
export default async function ProductDetailPage({ params }: { params: Params }) {
|
||||||
const { locale, slug } = await params;
|
const { locale, slug } = await params;
|
||||||
const line = await getLine(locale, slug);
|
const line = await getLine(locale, slug);
|
||||||
|
const t = await getTranslations({ locale, namespace: "Line" });
|
||||||
|
|
||||||
if (!line) return <div className="p-6">404 - 产线不存在</div>;
|
if (!line) return <div className="p-6">404 - 产线不存在</div>;
|
||||||
|
|
||||||
@@ -82,7 +84,7 @@ export default async function ProductDetailPage({ params }: { params: Params })
|
|||||||
{line.images && line.images.length > 0 && (
|
{line.images && line.images.length > 0 && (
|
||||||
<div className="mb-12">
|
<div className="mb-12">
|
||||||
<h2 className="text-2xl md:text-3xl font-semibold text-gray-800 mb-6">
|
<h2 className="text-2xl md:text-3xl font-semibold text-gray-800 mb-6">
|
||||||
产品图片
|
{t("productImages")}
|
||||||
</h2>
|
</h2>
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
{line.images.map((imgUrl, index) => (
|
{line.images.map((imgUrl, index) => (
|
||||||
@@ -103,7 +105,7 @@ export default async function ProductDetailPage({ params }: { params: Params })
|
|||||||
{line.properties && line.properties.length > 0 && (
|
{line.properties && line.properties.length > 0 && (
|
||||||
<div className="mb-12">
|
<div className="mb-12">
|
||||||
<h2 className="text-2xl md:text-3xl font-semibold text-gray-800 mb-6">
|
<h2 className="text-2xl md:text-3xl font-semibold text-gray-800 mb-6">
|
||||||
产品参数
|
{t("productProperties")}
|
||||||
</h2>
|
</h2>
|
||||||
<ul className="space-y-4">
|
<ul className="space-y-4">
|
||||||
{line.properties.map((prop, index) => (
|
{line.properties.map((prop, index) => (
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ export default async function Page({
|
|||||||
}) {
|
}) {
|
||||||
const { locale } = await params;
|
const { locale } = await params;
|
||||||
// 获取翻译(确保服务端/客户端一致)
|
// 获取翻译(确保服务端/客户端一致)
|
||||||
const t = await getTranslations({ locale, namespace: "Workshop" });
|
const t = await getTranslations({ locale, namespace: "Line" });
|
||||||
|
|
||||||
// 获取产品线数据(顶层 await,Server Component 原生支持)
|
// 获取产品线数据(顶层 await,Server Component 原生支持)
|
||||||
const products: Line[] = await getLines(locale);
|
const products: Line[] = await getLines(locale);
|
||||||
@@ -129,7 +129,7 @@ export default async function Page({
|
|||||||
{products.map((product) => {
|
{products.map((product) => {
|
||||||
// 用稳定的 key(优先用唯一标识,如 id;无 id 则用 title+locale 避免 index 导致的问题)
|
// 用稳定的 key(优先用唯一标识,如 id;无 id 则用 title+locale 避免 index 导致的问题)
|
||||||
const stableKey = `${product.title}-${product.locale}`;
|
const stableKey = `${product.title}-${product.locale}`;
|
||||||
return <ProductCard key={stableKey} product={product} />;
|
return <ProductCard key={stableKey} product={{ ...product, locale }} />;
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { getWorkShop, getWorkShops } from "@/lib/workshop";
|
|||||||
import { WorkShop } from "@/types/workShop";
|
import { WorkShop } from "@/types/workShop";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
import { Locale } from "next-intl";
|
import { Locale } from "next-intl";
|
||||||
|
import { getTranslations } from "next-intl/server";
|
||||||
|
|
||||||
// 固定 Params 类型为普通对象(Next.js 原生传参无异步)
|
// 固定 Params 类型为普通对象(Next.js 原生传参无异步)
|
||||||
type Params = {
|
type Params = {
|
||||||
@@ -45,6 +46,7 @@ export async function generateMetadata({
|
|||||||
export default async function WorkshopDetailPage({ params }: { params: Params }) {
|
export default async function WorkshopDetailPage({ params }: { params: Params }) {
|
||||||
const { locale, slug } = await params;
|
const { locale, slug } = await params;
|
||||||
const workShop = await getWorkShop(locale, slug);
|
const workShop = await getWorkShop(locale, slug);
|
||||||
|
const t = await getTranslations({ locale, namespace: "Workshop" });
|
||||||
|
|
||||||
if (!workShop) return null;
|
if (!workShop) return null;
|
||||||
|
|
||||||
@@ -78,7 +80,7 @@ export default async function WorkshopDetailPage({ params }: { params: Params })
|
|||||||
{workShop.images?.length > 0 && (
|
{workShop.images?.length > 0 && (
|
||||||
<div className="bg-white rounded-xl p-8 shadow-xl mt-12">
|
<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">
|
<h2 className="text-2xl font-semibold text-gray-800 mb-6 border-b pb-3 border-gray-200">
|
||||||
车间图片
|
{t("pageImages")}
|
||||||
</h2>
|
</h2>
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
{workShop.images.map((img, index) => {
|
{workShop.images.map((img, index) => {
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export default async function Page({ params }: { params: Params }) {
|
|||||||
{workShops.length > 0 ? (
|
{workShops.length > 0 ? (
|
||||||
workShops.map((workshop) => {
|
workShops.map((workshop) => {
|
||||||
const stableKey = `${workshop.title}-${workshop.locale}`;
|
const stableKey = `${workshop.title}-${workshop.locale}`;
|
||||||
return <WorkshopCard key={stableKey} workshop={workshop} />;
|
return <WorkshopCard key={stableKey} workshop={{ ...workshop, locale }} />;
|
||||||
})
|
})
|
||||||
) : (
|
) : (
|
||||||
<EmptyState />
|
<EmptyState />
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default function HomeComponent() {
|
|||||||
{/* 轮播图区域, 先用一张图片占位, 宽度100%, 盖度100vh */}
|
{/* 轮播图区域, 先用一张图片占位, 宽度100%, 盖度100vh */}
|
||||||
<img src="/images/home.png" alt={t("carousel")} className="w-screen h-[80vh] object-cover rounded-lg" />
|
<img src="/images/home.png" alt={t("carousel")} className="w-screen h-[80vh] object-cover rounded-lg" />
|
||||||
{/* 公司介绍 - 左右布局 */}
|
{/* 公司介绍 - 左右布局 */}
|
||||||
<div className="flex flex-col lg:flex-row w-full my-16 px-8">
|
<div className="flex flex-col lg:flex-row w-full my-16 px-8 items-center">
|
||||||
{/* 左边视频(图片占位) */}
|
{/* 左边视频(图片占位) */}
|
||||||
<div className="w-full lg:w-1/2 h-[50vh] lg:h-[60vh] relative overflow-hidden">
|
<div className="w-full lg:w-1/2 h-[50vh] lg:h-[60vh] relative overflow-hidden">
|
||||||
<img
|
<img
|
||||||
|
|||||||
@@ -72,56 +72,66 @@
|
|||||||
"Links": {
|
"Links": {
|
||||||
"groups": [
|
"groups": [
|
||||||
{
|
{
|
||||||
"title": "About Us",
|
"title": "About Wuhan Sage",
|
||||||
"links": [
|
"links": [
|
||||||
{
|
{
|
||||||
"href": "/en/about/company",
|
"href": "/en/about/company",
|
||||||
"name": "Company Profile",
|
"name": "Company Introduction",
|
||||||
"useA": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "/en/about/culture",
|
|
||||||
"name": "Corporate Culture",
|
|
||||||
"useA": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "/en/about/base",
|
|
||||||
"name": "Production Base",
|
|
||||||
"useA": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "/en/about/organization",
|
|
||||||
"name": "Organizational Structure",
|
|
||||||
"useA": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "/en/about/awards",
|
|
||||||
"name": "Honors and Qualifications",
|
|
||||||
"useA": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"href": "/en/about/history",
|
|
||||||
"name": "Development History",
|
|
||||||
"useA": true
|
"useA": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title": "News Center",
|
"title": "Workshop Exhibition",
|
||||||
"links": [
|
"links": [
|
||||||
{
|
{
|
||||||
"href": "/en/blog?category=announce",
|
"href": "/en/workshop/assembly",
|
||||||
"name": "Announcements",
|
"name": "Assembly Workshop",
|
||||||
"useA": true
|
"useA": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"href": "/en/blog?category=news",
|
"href": "/en/workshop/heat-treatment",
|
||||||
"name": "News",
|
"name": "Heat Treatment Workshop",
|
||||||
"useA": true
|
"useA": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"href": "/en/blog?category=event",
|
"href": "/en/workshop/machine",
|
||||||
"name": "Events",
|
"name": "Machining Workshop",
|
||||||
|
"useA": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"title": "Mill Unit Products",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": "/en/line/zinc",
|
||||||
|
"name": "Hot-dip Galvanizing / Galvalume Mill Unit",
|
||||||
|
"useA": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/en/line/magnesium",
|
||||||
|
"name": "Zinc-Aluminum-Magnesium Coating Mill Unit",
|
||||||
|
"useA": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/en/line/paint",
|
||||||
|
"name": "Color Coating Mill Unit",
|
||||||
|
"useA": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/en/line/electric-steel",
|
||||||
|
"name": "High-efficiency Electrical Steel (Silicon Steel) Continuous Processing Mill Unit",
|
||||||
|
"useA": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/en/line/carbon-steel",
|
||||||
|
"name": "Carbon Steel Pickling Mill Unit",
|
||||||
|
"useA": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "/en/line/stainless-steel-heat-treatment",
|
||||||
|
"name": "Stainless Steel Continuous Annealing & Pickling Mill Unit",
|
||||||
"useA": true
|
"useA": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -317,10 +327,16 @@
|
|||||||
},
|
},
|
||||||
"Workshop": {
|
"Workshop": {
|
||||||
"pageTitle": "Workshop Exhibition",
|
"pageTitle": "Workshop Exhibition",
|
||||||
"pageDesc": "Workshop Exhibition"
|
"pageDesc": "Workshop Exhibition",
|
||||||
|
"pageImages": "Workshop Images"
|
||||||
|
},
|
||||||
|
"Line": {
|
||||||
|
"pageTitle": "Mill Unit Products",
|
||||||
|
"productImages": "Mill Unit Images",
|
||||||
|
"productProperties": "Mill Unit Properties"
|
||||||
},
|
},
|
||||||
"About": {
|
"About": {
|
||||||
"title": "About Wuhan Saga Engineering Technology",
|
"title": "About Wuhan Saga",
|
||||||
"description": "About Wuhan Saga Engineering Technology"
|
"description": "About Wuhan Saga Engineering Technology"
|
||||||
},
|
},
|
||||||
"TermsOfService": {
|
"TermsOfService": {
|
||||||
|
|||||||
@@ -266,6 +266,7 @@
|
|||||||
},
|
},
|
||||||
"Workshop": {
|
"Workshop": {
|
||||||
"pageTitle": "车间展示",
|
"pageTitle": "车间展示",
|
||||||
"pageDesc": "车间展示"
|
"pageDesc": "车间展示",
|
||||||
|
"pageImages": "车间图片"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user