diff --git a/app/products/[...slug]/page.jsx b/app/products/[...slug]/page.jsx index 18167b2..232bf2e 100644 --- a/app/products/[...slug]/page.jsx +++ b/app/products/[...slug]/page.jsx @@ -5,6 +5,7 @@ import { notFound } from 'next/navigation'; import DynamicListPage from "@/components/common/DynamicListPage"; import { Suspense } from 'react'; import { getPageData } from "@/utils/data"; +import ProductImageGallery from "@/components/products/ProductImageGallery"; const baseSlug = 'products'; @@ -123,15 +124,9 @@ export default async function Page({ params, searchParams }) { {/* 图片和附加信息并排显示,响应式优化 */} {(data.image || data.subtitle) && (
- {data.image && ( -
- {data.title} -
- )} + {/* 图片轮播区块 */} + +
{/* 产品标题 */} {data.title && ( @@ -141,7 +136,7 @@ export default async function Page({ params, searchParams }) { )} {/* 产品副标题 */} {data.subtitle && ( -
+
{data.subtitle}
)} @@ -186,4 +181,4 @@ export default async function Page({ params, searchParams }) { } else { notFound(); } -} +} diff --git a/components/products/ProductImageGallery.jsx b/components/products/ProductImageGallery.jsx new file mode 100644 index 0000000..9650497 --- /dev/null +++ b/components/products/ProductImageGallery.jsx @@ -0,0 +1,108 @@ +'use client'; + +import { useState, useEffect } from 'react'; + +const ProductImageGallery = ({ data }) => { + const [currentImageIndex, setCurrentImageIndex] = useState(0); + + // 如果没有attachments,不显示组件 + if (!data?.attachments || data.attachments.length === 0) { + return null; + } + + // 找到主图在attachments中的索引 + const getMainImageIndex = () => { + if (!data.image) return 0; + + const mainImageIndex = data.attachments.findIndex( + attachment => attachment.file_url === data.image + ); + + return mainImageIndex >= 0 ? mainImageIndex : 0; + }; + + const mainImageIndex = getMainImageIndex(); + const currentImage = data.attachments[currentImageIndex]?.file_url || data.attachments[0]?.file_url; + + // 初始化当前索引为主图索引 + useEffect(() => { + setCurrentImageIndex(mainImageIndex); + }, [mainImageIndex]); + + const changeMainImage = (direction) => { + if (data.attachments.length <= 1) return; + + if (direction === 'next') { + setCurrentImageIndex((prev) => (prev + 1) % data.attachments.length); + } else { + setCurrentImageIndex((prev) => (prev - 1 + data.attachments.length) % data.attachments.length); + } + }; + + const changeMainImageByIndex = (index) => { + setCurrentImageIndex(index); + }; + + return ( +
+
+ {/* 主图显示区域 */} +
+ {data?.title + {/* 导航箭头 */} + {data.attachments.length > 1 && ( + <> + + + + )} +
+ + {/* 缩略图列表 - 直接显示attachments */} +
+ {data.attachments.map((attachment, index) => ( +
changeMainImageByIndex(index)} + > + {`${data?.title { + console.error('Image load error:', attachment.file_url); + e.target.style.display = 'none'; + }} + /> +
+ ))} +
+
+
+ ); +}; + +export default ProductImageGallery; diff --git a/public/files/a47e76hv1j_476c0c45.png b/public/files/a47e76hv1j_476c0c45.png new file mode 100644 index 0000000..7df7a7d Binary files /dev/null and b/public/files/a47e76hv1j_476c0c45.png differ diff --git a/public/files/h8ibigsafe_53103f0c.png b/public/files/h8ibigsafe_53103f0c.png new file mode 100644 index 0000000..9f9b5bf Binary files /dev/null and b/public/files/h8ibigsafe_53103f0c.png differ diff --git a/public/files/lpd8ov2ak7_03a99731.png b/public/files/lpd8ov2ak7_03a99731.png new file mode 100644 index 0000000..5658147 Binary files /dev/null and b/public/files/lpd8ov2ak7_03a99731.png differ diff --git a/public/files/lpd8ov2ak7_092f5df0.png b/public/files/lpd8ov2ak7_092f5df0.png new file mode 100644 index 0000000..c1aebb7 Binary files /dev/null and b/public/files/lpd8ov2ak7_092f5df0.png differ diff --git a/public/files/lpd8ov2ak7_323cebbe.png b/public/files/lpd8ov2ak7_323cebbe.png new file mode 100644 index 0000000..d2ff524 Binary files /dev/null and b/public/files/lpd8ov2ak7_323cebbe.png differ diff --git a/public/files/lpd8ov2ak7_3632b8d5.png b/public/files/lpd8ov2ak7_3632b8d5.png new file mode 100644 index 0000000..420b177 Binary files /dev/null and b/public/files/lpd8ov2ak7_3632b8d5.png differ diff --git a/public/files/lpd8ov2ak7_4fe7ffd4.png b/public/files/lpd8ov2ak7_4fe7ffd4.png new file mode 100644 index 0000000..9f78a3c Binary files /dev/null and b/public/files/lpd8ov2ak7_4fe7ffd4.png differ diff --git a/public/files/lpd8ov2ak7_503fe3e4.png b/public/files/lpd8ov2ak7_503fe3e4.png new file mode 100644 index 0000000..8ef674a Binary files /dev/null and b/public/files/lpd8ov2ak7_503fe3e4.png differ diff --git a/public/files/lpd8ov2ak7_85e5a79e.png b/public/files/lpd8ov2ak7_85e5a79e.png new file mode 100644 index 0000000..59dacd8 Binary files /dev/null and b/public/files/lpd8ov2ak7_85e5a79e.png differ diff --git a/public/files/lpd8ov2ak7_91a359f1.png b/public/files/lpd8ov2ak7_91a359f1.png new file mode 100644 index 0000000..5fd5098 Binary files /dev/null and b/public/files/lpd8ov2ak7_91a359f1.png differ diff --git a/public/files/lpd8ov2ak7_9aca70f9.png b/public/files/lpd8ov2ak7_9aca70f9.png new file mode 100644 index 0000000..9ad99dd Binary files /dev/null and b/public/files/lpd8ov2ak7_9aca70f9.png differ diff --git a/public/files/lpd8ov2ak7_9ade59cf.png b/public/files/lpd8ov2ak7_9ade59cf.png new file mode 100644 index 0000000..12a891f Binary files /dev/null and b/public/files/lpd8ov2ak7_9ade59cf.png differ diff --git a/public/files/lpd8ov2ak7_a2e6192a.png b/public/files/lpd8ov2ak7_a2e6192a.png new file mode 100644 index 0000000..16971f7 Binary files /dev/null and b/public/files/lpd8ov2ak7_a2e6192a.png differ diff --git a/public/files/lpd8ov2ak7_edcf6679.png b/public/files/lpd8ov2ak7_edcf6679.png new file mode 100644 index 0000000..6c1c54d Binary files /dev/null and b/public/files/lpd8ov2ak7_edcf6679.png differ diff --git a/utils/data.js b/utils/data.js index 55d80cf..945833e 100644 --- a/utils/data.js +++ b/utils/data.js @@ -82,6 +82,15 @@ export async function processDataItem(item, downloadFiles) { item.file_src = await downloadToLocal(item.file_src); } + // 处理attachments字段 + if (item.attachments && Array.isArray(item.attachments)) { + for (const attachment of item.attachments) { + if (attachment.file_url) { + attachment.file_url = await downloadToLocal(attachment.file_url); + } + } + } + if (item.items && Array.isArray(item.items)) { for (const subItem of item.items) { if (subItem.item_image) {