Bläddra i källkod

feat(products): 实现产品分页展示功能- 新增客户端组件ProductGridClient用于产品分页展示
- 集成Ant Design分页组件实现分页逻辑- 添加页面大小控制与当前页状态管理
- 实现产品卡片布局与悬停动画效果
- 配置图片懒加载与默认图片 fallback
- 添加产品详情跳转链接与分页导航
- 更新硬件产品介绍组件支持动态传参
- 将静态文本替换为可配置的hardIntroduction属性
- 将按钮升级为Next.js Link组件支持路由跳转
- 添加关键词查询参数指向硬件产品分类

nahida 7 månader sedan
förälder
incheckning
602b699e33
2 ändrade filer med 72 tillägg och 5 borttagningar
  1. 7 5
      src/components/ProductionHard.tsx
  2. 65 0
      src/components/products/ProductGridClient.tsx

+ 7 - 5
src/components/ProductionHard.tsx

@@ -1,7 +1,8 @@
 import React from 'react';
 import SubTitle from "@/components/subTitle";
+import Link from "next/link";
 
-function ProductionHard() {
+function ProductionHard({hardIntroduction}: {hardIntroduction: string}) {
   return (
     <>
       <div className={"hidden sm:block w-4/5 mx-auto mt-10"}>
@@ -15,7 +16,7 @@ function ProductionHard() {
             <div className="w-24 h-1 bg-blue-400 mx-auto mb-8"></div>
 
             <p className="text-white/90 text-lg md:text-xl leading-relaxed max-w-4xl mx-auto">
-              硬件产品包括:物联网智慧灯杆、物联网智慧园区综合平台、自然灾害应急能力提升平台、物联网环保监测管理平台、水库雨水情测报与大坝安全监测平台等等......
+              {hardIntroduction}
             </p>
           </div>
 
@@ -47,10 +48,11 @@ function ProductionHard() {
             </div>
           </div>
 
-          <div
-            className="bg-blue-500 hover:bg-blue-600 text-white px-8 py-3 text-lg font-medium rounded-lg shadow-lg transition-all duration-200 hover:shadow-xl cursor-pointer">
+          <Link
+            href={"/products?keyword=硬件产品"}
+            className="inline-block w-60 bg-blue-500 hover:bg-blue-600 text-white px-8 py-3 text-lg font-medium rounded-lg shadow-lg transition-all duration-200 hover:shadow-xl cursor-pointer">
             了解更多
-          </div>
+          </Link>
         </div>
       </div>
     </>

+ 65 - 0
src/components/products/ProductGridClient.tsx

@@ -0,0 +1,65 @@
+"use client"
+
+import {useState} from "react"
+import Image from "next/image"
+import {Pagination} from "antd"
+import Link from "next/link";
+
+interface ProductGridProps {
+  products: ProductItem[]
+}
+
+export default function ProductGrid({ products }: ProductGridProps) {
+  const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL as string
+
+  // 分页控制
+  const [currentPage, setCurrentPage] = useState(1)
+  const pageSize = 6
+
+  // 当前页数据
+  const startIndex = (currentPage - 1) * pageSize
+  const currentProducts = products.slice(startIndex, startIndex + pageSize)
+
+  return (
+    <div className="flex flex-col gap-6">
+      {/* 产品网格 */}
+      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 sm:gap-6">
+        {currentProducts.map((product) => (
+          <div
+            key={product.productId}
+            className="bg-white rounded-lg overflow-hidden shadow-lg hover:shadow-xl transition-all duration-300 hover:scale-[1.02]"
+          >
+            <div className="p-2">
+              <Image
+                className={"h-60 object-contain"}
+                src={product.productUrl ? BASE_URL + product.productUrl : "/assets/productions/2.png"}
+                alt={product.productName}
+                width={1000}
+                height={1000}
+              />
+            </div>
+            <div className="p-4 sm:py-6 text-center">
+              <h3 className="text-sm sm:text-base lg:text-lg font-medium text-gray-900 mb-3 sm:mb-4 leading-tight min-h-[2.5rem] sm:min-h-[3rem] flex items-center justify-center">
+                {product.productName}
+              </h3>
+              <Link href={`/products/${product.productId}`} className="bg-blue-500 hover:bg-blue-600 text-white px-4 sm:px-6 py-2 sm:py-2.5 rounded-lg font-medium transition-all duration-200 text-sm sm:text-base hover:scale-105 active:scale-95">
+                了解详情
+              </Link>
+            </div>
+          </div>
+        ))}
+      </div>
+
+      {/* 分页器 */}
+      <div className="flex justify-center">
+        <Pagination
+          current={currentPage}
+          pageSize={pageSize}
+          total={products.length}
+          onChange={(page) => setCurrentPage(page)}
+          showSizeChanger={false}
+        />
+      </div>
+    </div>
+  )
+}