Browse Source

refactor: 重构服务咨询模块为独立组件,并在多个页面中复用

nahida 1 month ago
parent
commit
059aa5b82a

+ 3 - 0
src/app/products/[id]/page.tsx

@@ -5,6 +5,7 @@ import './rich.css'
 import MainTitle from "@/components/MainTitle";
 import ContentNotFound from "@/components/ContentNotFound";
 import Image from "next/image";
+import ServiceConsultation from '@/components/support/ServiceConsultation';
 
 export const dynamicParams = true
 const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL as string
@@ -122,6 +123,8 @@ async function Page({
                 dangerouslySetInnerHTML={{__html: res.data.productDetails as string}}
                 className="ql-editor w-9/10 sm:w-7/10 mx-auto sm:px-20 sm:py-10"
             />
+
+            <ServiceConsultation />
         </>
     );
 }

+ 2 - 0
src/app/solutions/[id]/page.tsx

@@ -4,6 +4,7 @@ import {serverGet} from "@/utils/request";
 import './rich.css'
 import MainTitle from "@/components/MainTitle";
 import ContentNotFound from "@/components/ContentNotFound";
+import ServiceConsultation from '@/components/support/ServiceConsultation';
 
 export const dynamicParams = true
 
@@ -61,6 +62,7 @@ async function Page({
         dangerouslySetInnerHTML={{__html: res.data.programDetails as string}}
         className="ql-editor w-9/10 sm:w-7/10 mx-auto sm:px-20 sm:py-10"
       />
+      <ServiceConsultation />
     </>
   );
 }

+ 72 - 69
src/app/solutions/page.tsx

@@ -1,15 +1,16 @@
 import Link from "next/link"
-import {ArrowRightOutlined} from "@ant-design/icons"
+import { ArrowRightOutlined } from "@ant-design/icons"
 import MainTitle from "@/components/MainTitle"
 import Image from "next/image"
 import PaginationClient from "@/components/PaginationClient"
-import {serverGet} from "@/utils/request"
-import {removeHTMLTags} from "@/utils/removeHTMLTags"
+import { serverGet } from "@/utils/request"
+import { removeHTMLTags } from "@/utils/removeHTMLTags"
 import AnimatedSection from "@/components/AnimatedSection";
+import ServiceConsultation from "@/components/support/ServiceConsultation"
 
 export default async function SolutionsPage({
-                                              searchParams,
-                                            }: {
+  searchParams,
+}: {
   searchParams: Promise<{ page?: string }>
 }) {
   // 等待 searchParams 解析
@@ -19,7 +20,7 @@ export default async function SolutionsPage({
   const res = await serverGet<Page<Solution>>("/webSite/getSolution", {
     pageNum: pageNum,
     pageSize: pageSize,
-  },{
+  }, {
     next: {
       revalidate: 180
     },
@@ -29,84 +30,86 @@ export default async function SolutionsPage({
   return (
     <>
       <AnimatedSection effect="slide" direction="left">
-          <div className="w-full h-full flex items-center justify-center text-white text-4xl font-bold">
-              <Image src={"/assets/solutions/1.jpg"} alt={"banner"} width={1920} height={1080}/>
-          </div>
+        <div className="w-full h-full flex items-center justify-center text-white text-4xl font-bold">
+          <Image src={"/assets/solutions/1.jpg"} alt={"banner"} width={1920} height={1080} />
+        </div>
       </AnimatedSection>
 
-        <div className={"py-6 sm:py-10"}>
-            <MainTitle title={"解决方案"} titleLetter={"SOLUTIONS"}/>
+      <div className={"py-6 sm:py-10"}>
+        <MainTitle title={"解决方案"} titleLetter={"SOLUTIONS"} />
       </div>
 
       <AnimatedSection effect="scale">
-      <div className="" style={{ background: "linear-gradient(135deg, #f0f8ff 0%, #e6f3ff 100%)" }}>
-        <div className="w-9/10 sm:w-7/10 mx-auto px-3 sm:px-4 py-4 sm:py-8">
-          <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-6 mb-4 sm:mb-8">
-            {solutionsData.map((solution, index) => (
-              <Link
-                key={solution.id}
-                href={`/solutions/${solution.id}`}
-                className="block h-full cursor-pointer group"
-              >
-                <div
-                  className="h-full shadow-md hover:shadow-lg transition-all duration-300 transform group-hover:-translate-y-1 rounded-xl overflow-hidden bg-white relative"
-                  style={{
-                    backgroundImage: `url("/assets/solutions/2.png")`,
-                    backgroundSize: "cover",
-                  }}
+        <div className="" style={{ background: "linear-gradient(135deg, #f0f8ff 0%, #e6f3ff 100%)" }}>
+          <div className="w-9/10 sm:w-7/10 mx-auto px-3 sm:px-4 py-4 sm:py-8">
+            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3 sm:gap-6 mb-4 sm:mb-8">
+              {solutionsData.map((solution, index) => (
+                <Link
+                  key={solution.id}
+                  href={`/solutions/${solution.id}`}
+                  className="block h-full cursor-pointer group"
                 >
-                  {/* 内容容器 */}
-                  <div className="p-4 sm:p-6 h-full flex flex-col relative z-10">
-                    <div className="mb-2 sm:mb-3">
-                      <h3
-                        className="text-base sm:text-lg font-semibold text-black mb-1 sm:mb-2 line-clamp-2 leading-tight sm:leading-normal drop-shadow-sm">
-                        {solution.programName}
-                      </h3>
-                      <p className="text-xs sm:text-sm text-black/80 mb-2 sm:mb-3 drop-shadow-sm">
-                        {solution.releaseTime}
-                      </p>
-                    </div>
+                  <div
+                    className="h-full shadow-md hover:shadow-lg transition-all duration-300 transform group-hover:-translate-y-1 rounded-xl overflow-hidden bg-white relative"
+                    style={{
+                      backgroundImage: `url("/assets/solutions/2.png")`,
+                      backgroundSize: "cover",
+                    }}
+                  >
+                    {/* 内容容器 */}
+                    <div className="p-4 sm:p-6 h-full flex flex-col relative z-10">
+                      <div className="mb-2 sm:mb-3">
+                        <h3
+                          className="text-base sm:text-lg font-semibold text-black mb-1 sm:mb-2 line-clamp-2 leading-tight sm:leading-normal drop-shadow-sm">
+                          {solution.programName}
+                        </h3>
+                        <p className="text-xs sm:text-sm text-black/80 mb-2 sm:mb-3 drop-shadow-sm">
+                          {solution.releaseTime}
+                        </p>
+                      </div>
 
-                    <div className="flex-1 mb-4">
-                      <p
-                        className="text-black/90 text-xs sm:text-sm leading-relaxed line-clamp-3 sm:line-clamp-4 drop-shadow-sm">
-                        {removeHTMLTags(solution.programDetails)}
-                      </p>
-                    </div>
+                      <div className="flex-1 mb-4">
+                        <p
+                          className="text-black/90 text-xs sm:text-sm leading-relaxed line-clamp-3 sm:line-clamp-4 drop-shadow-sm">
+                          {removeHTMLTags(solution.programDetails)}
+                        </p>
+                      </div>
 
-                    {/* 按钮区域 */}
-                    <div className="mt-auto pt-3 border-t border-white/20">
-                      <div
-                        className="flex items-center gap-2 text-black font-medium transition-colors duration-200"
-                        style={{
-                          textShadow: "0 1px 2px rgba(0,0,0,0.3)",
-                        }}
-                      >
-                        了解更多
-                        <ArrowRightOutlined />
+                      {/* 按钮区域 */}
+                      <div className="mt-auto pt-3 border-t border-white/20">
+                        <div
+                          className="flex items-center gap-2 text-black font-medium transition-colors duration-200"
+                          style={{
+                            textShadow: "0 1px 2px rgba(0,0,0,0.3)",
+                          }}
+                        >
+                          了解更多
+                          <ArrowRightOutlined />
+                        </div>
                       </div>
                     </div>
-                  </div>
 
-                  {/* 装饰性元素 */}
-                  <div
-                    className="absolute top-0 right-0 w-20 h-20 opacity-10"
-                    style={{
-                      background: "radial-gradient(circle, rgba(255,255,255,0.3) 0%, transparent 70%)",
-                      transform: "translate(25%, -25%)",
-                    }}
-                  />
-                </div>
-              </Link>
-            ))}
-          </div>
+                    {/* 装饰性元素 */}
+                    <div
+                      className="absolute top-0 right-0 w-20 h-20 opacity-10"
+                      style={{
+                        background: "radial-gradient(circle, rgba(255,255,255,0.3) 0%, transparent 70%)",
+                        transform: "translate(25%, -25%)",
+                      }}
+                    />
+                  </div>
+                </Link>
+              ))}
+            </div>
 
-          <div className="flex justify-center">
-            <PaginationClient current={pageNum} total={res.data.total} pageSize={pageSize}/>
+            <div className="flex justify-center">
+              <PaginationClient current={pageNum} total={res.data.total} pageSize={pageSize} />
+            </div>
           </div>
         </div>
-      </div>
       </AnimatedSection>
+
+      <ServiceConsultation />
     </>
   )
 }

+ 3 - 66
src/app/support/page.tsx

@@ -1,25 +1,9 @@
 import SubTitle from "@/components/subTitle";
 import Image from "next/image";
-import {serverGet} from "@/utils/request";
 import AnimatedSection from "@/components/AnimatedSection";
-import ServiceFormClient from "@/components/support/ServiceFormClient";
+import ServiceConsultation from "@/components/support/ServiceConsultation";
 
 export default async function ServicePage() {
-  const res = await serverGet("/webSite/getBasicInfo");
-  const basicInfo = res.data[0] || {
-    address: "",
-    companyProfile: "",
-    companyProfileUrl: "",
-    consultationHotline: "",
-    email: "",
-    hardwareIntroduction: "",
-    id: "",
-    qrCodeUrl: "",
-    serviceHotline: "",
-    softwareIntroduction: "",
-    telephone: ""
-  };
-  console.log(basicInfo)
   return (
     <>
       <AnimatedSection effect="slide" direction="left">
@@ -79,55 +63,8 @@ export default async function ServicePage() {
         </section>
       </AnimatedSection>
 
-      {/* Service Consultation Section */}
-      <AnimatedSection effect="slide" direction="left">
-        <section className="bg-[url('/assets/support/3.png')] bg-no-repeat bg-cover py-10 px-4 relative overflow-hidden">
-          {/* Background Light Effects */}
-          <div className="absolute right-0 top-1/2 transform -translate-y-1/2 w-96 h-96 opacity-30">
-            <div
-              className="w-full h-full bg-gradient-radial from-blue-400 via-blue-600 to-transparent rounded-full blur-3xl"></div>
-          </div>
-          <div className="absolute right-20 top-1/2 transform -translate-y-1/2 w-64 h-64 opacity-20">
-            <div
-              className="w-full h-full bg-gradient-radial from-cyan-300 via-blue-500 to-transparent rounded-full blur-2xl"></div>
-          </div>
-
-          <div className="max-w-4/5 mx-auto relative z-10">
-            <div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
-              {/* Left Content */}
-              <div className="text-white">
-                {/* Section Title */}
-                <div className="mb-8 sm:text-left text-center">
-                  <SubTitle title={"服务咨询"} color={"#fff"}/>
-                </div>
-
-                {/* Contact Information & Form */}
-                <ServiceFormClient />
-              </div>
-
-              {/* Right Side - Light Effects Area */}
-              <div className="hidden lg:block space-y-8 pl-12">
-                {/* <div className="text-white">
-                  <p className="text-gray-300 mb-2">中科盛阳服务热线:</p>
-                  <p className="text-5xl font-black text-blue-400 drop-shadow-lg tracking-tight">
-                    {basicInfo.serviceHotline}
-                  </p>
-                </div> */}
-
-                <div className="space-y-4">
-                  <p className="text-gray-300 text-lg font-medium leading-relaxed">
-                    如需自选以下业务,您可以直接拨打相关热线电话:
-                  </p>
-                  <div className="bg-white/5 backdrop-blur-md p-6 rounded-xl border border-white/10 shadow-inner">
-                    <p className="text-gray-400 text-sm mb-1 uppercase tracking-widest font-bold">24小时产品售前咨询服务热线</p>
-                    <p className="text-2xl font-bold text-white tracking-tighter">{basicInfo.consultationHotline}</p>
-                  </div>
-                </div>
-              </div>
-            </div>
-          </div>
-        </section>
-      </AnimatedSection>
+      {/* 服务咨询模块 */}
+      <ServiceConsultation />
     </>
   )
 }

+ 94 - 0
src/components/support/ServiceConsultation.tsx

@@ -0,0 +1,94 @@
+"use client"
+
+import React, { useEffect, useState } from "react";
+import SubTitle from "@/components/subTitle";
+import AnimatedSection from "@/components/AnimatedSection";
+import ServiceFormClient from "./ServiceFormClient";
+import { clientGet } from "@/utils/clientRequest";
+
+/**
+ * 服务咨询模块组件
+ * 包含背景图、灯光效果、表单以及联系信息
+ * 数据在组件内部获取,利用客户端缓存
+ */
+export default function ServiceConsultation() {
+  const [basicInfo, setBasicInfo] = useState<{ consultationHotline: string; telephone: string } | null>(null);
+
+  useEffect(() => {
+    const fetchInfo = async () => {
+      try {
+        const res = await clientGet<BasicInfo[]>("/webSite/getBasicInfo");
+        if (res.code === 200 && res.data?.[0]) {
+          setBasicInfo({
+            consultationHotline: res.data[0].consultationHotline,
+            telephone: res.data[0].telephone
+          });
+        }
+      } catch (error) {
+        console.error("Failed to fetch basic info in ServiceConsultation:", error);
+      }
+    };
+    fetchInfo();
+  }, []);
+
+  return (
+    <AnimatedSection effect="slide" direction="left">
+      <section className="bg-[url('/assets/support/3.png')] bg-no-repeat bg-cover py-10 px-4 relative overflow-hidden">
+        {/* 背景灯光效果 */}
+        <div className="absolute right-0 top-1/2 transform -translate-y-1/2 w-96 h-96 opacity-30">
+          <div
+            className="w-full h-full bg-gradient-radial from-blue-400 via-blue-600 to-transparent rounded-full blur-3xl"></div>
+        </div>
+        <div className="absolute right-20 top-1/2 transform -translate-y-1/2 w-64 h-64 opacity-20">
+          <div
+            className="w-full h-full bg-gradient-radial from-cyan-300 via-blue-500 to-transparent rounded-full blur-2xl"></div>
+        </div>
+
+        <div className="max-w-4/5 mx-auto relative z-10">
+          <div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
+            {/* 左侧表单内容 */}
+            <div className="text-white">
+              {/* 标题 */}
+              <div className="mb-8 sm:text-left text-center">
+                <SubTitle title={"服务咨询"} color={"#fff"}/>
+              </div>
+
+              {/* 咨询表单组件 */}
+              <ServiceFormClient />
+            </div>
+
+            {/* 右侧热线信息展示 */}
+            <div className="hidden lg:block space-y-8 pl-12">
+              <div className="space-y-4">
+                <p className="text-gray-300 text-lg font-medium leading-relaxed">
+                  如需自选以下业务,您可以直接拨打相关热线电话:
+                </p>
+                
+                {/* 骨架屏或默认状态 */}
+                {!basicInfo ? (
+                  <div className="animate-pulse space-y-4">
+                    <div className="h-24 bg-white/5 rounded-xl border border-white/10"></div>
+                    <div className="h-24 bg-white/5 rounded-xl border border-white/10"></div>
+                  </div>
+                ) : (
+                  <>
+                    <div className="bg-white/5 backdrop-blur-md p-6 rounded-xl border border-white/10 shadow-inner transition-all duration-300 hover:bg-white/10">
+                      <p className="text-gray-400 text-sm mb-1 uppercase tracking-widest font-bold">24小时产品售前咨询服务热线</p>
+                      <p className="text-2xl font-bold text-white tracking-tighter">{basicInfo.consultationHotline}</p>
+                    </div>
+                    {basicInfo.telephone && (
+                      <div className="bg-white/5 backdrop-blur-md p-6 rounded-xl border border-white/10 shadow-inner transition-all duration-300 hover:bg-white/10">
+                        <p className="text-gray-400 text-sm mb-1 uppercase tracking-widest font-bold">服务热线</p>
+                        <p className="text-2xl font-bold text-white tracking-tighter">{basicInfo.telephone}</p>
+                      </div>
+                    )}
+                  </>
+                )}
+              </div>
+            </div>
+          </div>
+        </div>
+      </section>
+    </AnimatedSection>
+  );
+}