Jelajahi Sumber

feat(header): 添加商务合作导航项- 在导航菜单中新增"商务合作"链接
- 更新路径映射以支持新路由

feat(about): 优化荣誉证书展示功能

- 实现移动端和桌面端不同的图片展示策略
- 添加图片预览弹窗功能
- 支持点击图片放大查看- 增加自动播放和拖拽功能- 优化图片加载和显示效果

feat(types): 新增多个业务类型定义

- 添加首页基础信息接口定义
- 新增新闻动态接口定义
- 添加解决方案接口定义
- 增加产品中心相关接口定义- 定义产品分类、类型和详细信息接口

nahida 7 bulan lalu
induk
melakukan
63abe31189
3 mengubah file dengan 277 tambahan dan 19 penghapusan
  1. 75 18
      src/components/about/Honor.tsx
  2. 2 0
      src/components/headerBlock.tsx
  3. 200 1
      src/types/index.ts

+ 75 - 18
src/components/about/Honor.tsx

@@ -1,32 +1,87 @@
 'use client'
-import React from 'react';
+import React, {useEffect, useState} from 'react';
 import {Carousel, Tabs, TabsProps} from "antd";
 import Image from "next/image";
 
-function Honor({honorList}: {honorList: HonorInfo[]}) {
+function Honor({ honorList }: { honorList: HonorInfo[] }) {
   const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL;
-  function CategoryCarousel({ images }: { images: Array<{ id: string; url: string;}> }) {
-    // 将图片按每页3个分组
-    const imageGroups = []
-    for (let i = 0; i < images.length; i += 3) {
-      imageGroups.push(images.slice(i, i + 3))
+  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
+  const [isMobile, setIsMobile] = useState(false);
+
+  // 判断是否是小屏
+  useEffect(() => {
+    const checkMobile = () => setIsMobile(window.innerWidth < 640);
+    checkMobile();
+    window.addEventListener("resize", checkMobile);
+    return () => window.removeEventListener("resize", checkMobile);
+  }, []);
+
+  // 预览层
+  function PreviewModal({ url, onClose }: { url: string, onClose: () => void }) {
+    return (
+      <div
+        className="fixed inset-0 bg-black/80 flex items-center justify-center z-50"
+        onClick={onClose}
+      >
+        <div
+          className="relative max-w-5xl w-full flex justify-center border border-white/20 rounded-lg"
+          onClick={(e) => e.stopPropagation()}
+        >
+          <Image
+            src={url}
+            alt="预览"
+            width={1000}
+            height={800}
+            className="max-h-[90vh] object-contain rounded-lg"
+          />
+          <button
+            onClick={onClose}
+            className="absolute top-4 right-4 bg-white text-black rounded-full px-3 py-1 shadow hover:bg-gray-200"
+          >
+            ✕
+          </button>
+        </div>
+      </div>
+    );
+  }
+
+  // Carousel
+  function CategoryCarousel({ images }: { images: Array<{ id: string; url: string }> }) {
+    let imageGroups: Array<typeof images> = [];
+
+    if (isMobile) {
+      // 移动端:每页一个
+      imageGroups = images.map((img) => [img]);
+    } else {
+      // 桌面端:每页三个
+      for (let i = 0; i < images.length; i += 3) {
+        imageGroups.push(images.slice(i, i + 3));
+      }
     }
 
     return (
       <div className="relative">
-        <Carousel arrows dots={true} infinite={false}>
+        <Carousel arrows draggable dots infinite={false} autoplay autoplaySpeed={2500}>
           {imageGroups.map((group, groupIndex) => (
             <div key={groupIndex}>
-              <div className="grid grid-cols-1 sm:grid-cols-3 gap-6 p-4">
+              <div
+                className={`grid ${
+                  isMobile ? "grid-cols-1" : "grid-cols-3"
+                } gap-6 p-4`}
+              >
                 {group.map((image) => (
-                  <div key={image.id} className="relative group">
+                  <div
+                    key={image.id}
+                    className="relative group cursor-pointer"
+                    onClick={() => setPreviewUrl(BASE_URL + image.url)}
+                  >
                     <div className="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow duration-300">
                       <Image
-                        src={ BASE_URL + image.url || "/placeholder.svg"}
-                        alt={"证书"}
+                        src={BASE_URL + image.url || "/placeholder.svg"}
+                        alt="证书"
                         width={400}
                         height={300}
-                        className="w-full h-48 object-cover group-hover:scale-105 transition-transform duration-300"
+                        className="w-full h-auto max-h-100 min-h-100 object-contain group-hover:scale-105 transition-transform duration-300"
                       />
                       <div className="p-4">
                         <p className="text-sm text-gray-600 text-center">证书</p>
@@ -39,19 +94,21 @@ function Honor({honorList}: {honorList: HonorInfo[]}) {
           ))}
         </Carousel>
       </div>
-    )
+    );
   }
 
-  const tabItems: TabsProps["items"] = honorList.map((honor,index) => ({
+  const tabItems: TabsProps["items"] = honorList.map((honor, index) => ({
     key: honor.id || index.toString(),
     label: honor.certificateType || "未知",
     children: <CategoryCarousel images={honor.fileList || []} />,
-  }))
+  }));
+
   return (
     <>
-      <Tabs defaultActiveKey="honor" items={tabItems} className="w-full" centered/>
+      <Tabs defaultActiveKey={honorList[0]?.id || "0"} items={tabItems} className="w-full" centered />
+      {previewUrl && <PreviewModal url={previewUrl} onClose={() => setPreviewUrl(null)} />}
     </>
   );
 }
 
-export default Honor;
+export default Honor;

+ 2 - 0
src/components/headerBlock.tsx

@@ -19,6 +19,7 @@ const Navigation: React.FC = () => {
     "/news": "news",
     "/support": "support",
     "/about": "about",
+    "/business": "business",
   }
   const selectedKey = pathToKey[pathname] || ""
 
@@ -28,6 +29,7 @@ const Navigation: React.FC = () => {
     { key: "solutions", label: "解决方案", href: "/solutions" },
     { key: "news", label: "新闻动态", href: "/news" },
     { key: "support", label: "服务支持", href: "/support" },
+    { key: "business", label: "商务合作", href: "/business" },
     { key: "about", label: "关于我们", href: "/about" },
   ]
 

+ 200 - 1
src/types/index.ts

@@ -46,4 +46,203 @@ interface HonorInfo {
    * 文件列表
    */
   fileList?: {id: string; url: string;}[];
-}
+}
+
+/**
+ * 首页基础信息
+ */
+interface BasicInfo {
+  /**
+   * 主键
+   */
+  id?: string;
+
+  /**
+   * 公司简介
+   */
+  companyProfile?: string;
+
+  /**
+   * 公司简介2
+   */
+  companyProfileTwo?: string;
+
+  /**
+   * 公司简介图片地址
+   */
+  companyProfileUrl?: string;
+
+  /**
+   * 软件简介
+   */
+  softwareIntroduction?: string;
+
+  /**
+   * 硬件简介
+   */
+  hardwareIntroduction?: string;
+
+  /**
+   * 电话
+   */
+  telephone?: string;
+
+  /**
+   * 服务热线
+   */
+  serviceHotline?: string;
+
+  /**
+   * 咨询热线
+   */
+  consultationHotline?: string;
+
+  /**
+   * 邮箱
+   */
+  email?: string;
+
+  /**
+   * 地址
+   */
+  address?: string;
+
+  /**
+   * 二维码图片地址
+   */
+  qrCodeUrl?: string;
+}
+
+interface NewsUpdates {
+  /**
+   * 主键
+   */
+  id?: string;
+
+  /**
+   * 新闻名称
+   */
+  newsName?: string;
+
+  /**
+   * 新闻详情
+   */
+  newsDetails?: string;
+
+  /**
+   * 新闻图片地址
+   */
+  newsUrl: string;
+
+  /**
+   * 发布时间
+   */
+  releaseTime?: string;
+
+  /**
+   * 是否为特别新闻
+   */
+  isSpecial?: boolean;
+}
+
+interface Solution {
+  /**
+   * 主键
+   */
+  id?: string;
+
+  /**
+   * 方案名称
+   */
+  programName?: string;
+
+  /**
+   * 发布时间
+   */
+  releaseTime?: string;
+  /**
+   * 方案详情
+   */
+  programDetails?: string;
+
+  /**
+   * 方案图片地址
+   */
+  productUrl?: string;
+
+  /**
+   * 创建人
+   */
+  createBy?: string;
+
+  /**
+   * 创建时间
+   */
+  createTime?: string;
+
+  /**
+   * 修改人
+   */
+  updateBy?: string;
+
+  /**
+   * 修改时间
+   */
+  updateTime?: string;
+}
+// 产品详细信息接口
+interface ProductItem {
+  // 产品唯一标识符
+  productId: string;
+  // 产品名称
+  productName: string;
+  // 产品分类
+  productCategory: string;
+  // 产品类型
+  productType: string;
+  // 产品图片URL地址
+  productUrl: string | null;
+}
+
+// 产品类型接口
+interface ProductType {
+  // 产品类型名称
+  productTypeName: string;
+  // 该类型下的产品列表
+  productCenters: ProductItem[];
+}
+
+// 产品分类接口
+interface ProductCategory {
+  // 产品分类名称
+  productCategoryName: string;
+  // 该分类下的产品类型列表
+  productTypes: ProductType[];
+}
+
+interface ProductCenter {
+  // 主键
+  id?: string;
+
+  // 产品分类
+  productCategory?: string;
+
+  // 产品类型
+  productType?: string;
+
+  // 产品名称
+  productName?: string;
+
+  // 产品详情
+  productDetails?: string;
+
+  // 产品图片地址
+  productUrl?: string;
+
+  // 创建人
+  createBy?: string;
+
+  // 修改人
+  updateBy?: string;
+
+}