Pārlūkot izejas kodu

change TDK of partner and articleDetail

wind 1 mēnesi atpakaļ
vecāks
revīzija
f5ea0621dc

+ 1 - 0
package.json

@@ -11,6 +11,7 @@
   "dependencies": {
     "@ant-design/pro-components": "^2.8.2",
     "antd": "^5.22.4",
+    "jsdom": "^25.0.1",
     "next": "14.2.20",
     "react": "^18.0.0",
     "react-device-detect": "^2.2.3",

+ 20 - 7
src/app/(home)/components/Consultant/index.tsx

@@ -2,16 +2,29 @@
 
 import React, { useState, useEffect } from "react";
 import { isMobile } from "react-device-detect";
-// import Image from "next/image";
-import { Swiper, SwiperSlide } from "swiper/react";
+import Image from "next/image";
+import { Swiper, SwiperSlide, SwiperClass } from "swiper/react";
 import "swiper/css";
 import styles from "./consultant.module.css";
 import { GoChevronLeft, GoChevronRight } from "react-icons/go";
 import { fetchConsultants } from "@/lib/cms";
 
+interface ConsultantType {
+  id: number;
+  cnName?: string | null;
+  enName?: string | null;
+  title?: string | null;
+  desc?: string | null;
+  photo?: string;
+  order?: number | null;
+  createTime?: Date | null;
+  updateTime?: Date | null;
+  status?: string | null;
+}
+
 const Consultant: React.FC = () => {
-  const [swiperRef, setSwiperRef] = useState(null);
-  const [consulantList, setConsulantList] = useState(null);
+  const [swiperRef, setSwiperRef] = useState<SwiperClass | null>(null);
+  const [consulantList, setConsulantList] = useState<ConsultantType[] | null>(null);
   useEffect(() => {
     fetchConsultants().then(({ data: list }) => {
       const records = [...list?.records, ...list?.records];
@@ -20,11 +33,11 @@ const Consultant: React.FC = () => {
   }, []);
 
   const slideToNext = () => {
-    swiperRef.slideNext();
+    swiperRef?.slideNext();
   };
 
   const slideToPrev = () => {
-    swiperRef.slidePrev();
+    swiperRef?.slidePrev();
   };
 
   return (
@@ -44,7 +57,7 @@ const Consultant: React.FC = () => {
                   <SwiperSlide key={index}>
                     <a href={`/partner/${item.id}`} className={styles["col-md-4"]}>
                       <div className={styles.media}>
-                        <img src={item.photo}></img>
+                        <Image alt="photo" width={250} height={194} src={item.photo!} />
                       </div>
 
                       <div className={styles["card-content"]}>

+ 4 - 4
src/app/(home)/components/Customer/index.tsx

@@ -3,7 +3,7 @@
 import React, { useState, useEffect } from "react";
 import Image from "next/image";
 import { isMobile } from "react-device-detect";
-import { Swiper, SwiperSlide } from "swiper/react";
+import { Swiper, SwiperSlide, SwiperClass } from "swiper/react";
 import "swiper/css";
 import "swiper/css/navigation";
 import { GoChevronLeft, GoChevronRight } from "react-icons/go";
@@ -11,15 +11,15 @@ import styles from "./customer.module.css";
 import { fetchCustomers } from "@/lib/cms";
 
 export default function Services() {
-  const [swiperRef, setSwiperRef] = useState(null);
+  const [swiperRef, setSwiperRef] = useState<SwiperClass | null>(null);
   const [customerList, setCustomerList] = useState(null);
 
   const slideToNext = () => {
-    swiperRef.slideNext();
+    swiperRef?.slideNext();
   };
 
   const slideToPrev = () => {
-    swiperRef.slidePrev();
+    swiperRef?.slidePrev();
   };
 
   useEffect(() => {

+ 15 - 1
src/app/articleDetail/[slug]/page.tsx

@@ -3,9 +3,23 @@ import Nav from "@/components/Nav";
 import Footer from "@/components/Footer";
 import styles from "./articleDetail.module.css";
 import { fetchArticleDetail } from "@/lib/cms";
+import { getDesc180 } from "@/lib/parser";
+
+export async function generateMetadata({ params }) {
+  const articleId = params.slug.replace(".html", "");
+  const { data: info } = await fetchArticleDetail(parseInt(articleId as string));
+  const title = info?.title;
+  const content = info?.content;
+  const description = getDesc180(content);
+  return {
+    title: title,
+    description: description,
+    keywords: [],
+  };
+}
 
 export default async function ArticleDetail({ params }: { params: { slug: string } }) {
-  let articleId = params.slug.replace(".html", "");
+  const articleId = params.slug.replace(".html", "");
   const { data: info } = await fetchArticleDetail(parseInt(articleId as string));
 
   const getTitle = () => {

+ 1 - 1
src/app/caseList/page.tsx

@@ -14,7 +14,7 @@ export default async function CaseList() {
           <div className={styles.articleList}>
             {list?.records?.map((item, index) => {
               return (
-                <a href={`/articleDetail/${item.id}.html`}>
+                <a href={`/articleDetail/${item.id}.html`} key={index}>
                   <div className={styles.articleItem}>
                     <img className={styles.articleImg} src={item?.cover} />
 

+ 2 - 2
src/app/contactUs/page.tsx

@@ -6,7 +6,7 @@ import Footer from "@/components/Footer";
 import styles from "./contact.module.css";
 import { addContact } from "@/lib/contact";
 import { ProForm, ProFormInstance } from "@ant-design/pro-components";
-import { Form, Input, message, Modal } from "antd";
+import { Form, Input, Modal } from "antd";
 
 const Contact: React.FC = () => {
   const formRef = useRef<ProFormInstance>(null);
@@ -40,7 +40,7 @@ const Contact: React.FC = () => {
         layout={"horizontal"}
         {...formItemLayout}
         submitter={{
-          render: (props, doms) => {
+          render: () => {
             return <></>;
           },
         }}

+ 24 - 8
src/app/partner/[id]/page.tsx

@@ -5,13 +5,22 @@ import Nav from "@/components/Nav";
 import Footer from "@/components/Footer";
 import styles from "./partner.module.css";
 import { fetchConsultants, fetchConsultantDetail } from "@/lib/cms";
+import { getDescLast } from "@/lib/parser";
 
-export const metadata: Metadata = {
-  title: "吕守升-创始人、战略解码专家-助力中国高潜企业加速发展-高潜咨询",
-  description:
-    "擅长领域:战略管理、组织变革及人力资源管理。著有畅销书《战略解码:跨越战略与执行的鸿沟》,是“战略解码®”方法体系的创始人及商标持有者。",
-  keywords: ["吕守升", "Samson Lv", "创始人", "战略解码专家"],
-};
+export async function generateMetadata({ params }) {
+  const partnerId = params.id;
+  const { data: info } = await fetchConsultantDetail(parseInt(partnerId as string));
+  const cnName = info?.cnName;
+  const enName = info?.enName;
+  const title = info?.title;
+  const desc = info?.desc;
+  const description = getDescLast(desc);
+  return {
+    title: `${cnName}-${title}-助力中国高潜企业加速发展-高潜咨询`,
+    description: description,
+    keywords: [cnName, enName, ...title.split(/[\u3001\uFF0C]+/)],
+  };
+}
 
 export default async function Partner({ params }: { params: { id: string } }) {
   const partnerId = params.id;
@@ -47,7 +56,14 @@ export default async function Partner({ params }: { params: { id: string } }) {
           <div className={styles.info}>
             <div className={styles.left}>
               <div className={styles.imgWrapper}>
-                <img src={info?.photo} className={styles.partnerPhoto} />
+                <Image
+                  alt="photo"
+                  width={275}
+                  height={350}
+                  src={info?.photo}
+                  className={styles.partnerPhoto}
+                  priority={true}
+                />
                 <div className={styles.box}></div>
               </div>
             </div>
@@ -66,7 +82,7 @@ export default async function Partner({ params }: { params: { id: string } }) {
                 return null;
               } else {
                 return (
-                  <a href={`/partner/${item.id}`}>
+                  <a href={`/partner/${item.id}`} key={index}>
                     <div className={styles.item}>
                       <div className={styles.cnName}>{item.cnName}</div>|{" "}
                       <div className={styles.enName}>{item.enName}</div>

+ 24 - 81
src/components/Nav/navMobile.tsx

@@ -2,7 +2,6 @@
 
 import React, { useState } from "react";
 import Link from "next/link";
-import Image from "next/image";
 import styles from "./nav.module.css";
 
 const NavMobile: React.FC = () => {
@@ -26,86 +25,30 @@ const NavMobile: React.FC = () => {
         <div className={styles["nav-line"]} />
         <div className={showMenu === "show" ? styles.show : styles.hide}>
           <div className={styles["nav-sub"]}>
-            <a href="/">
-              <div
-                className={styles.item}
-                onClick={() => {
-                  setShowMenu("hide");
-                }}
-              >
-                首页
-              </div>
-            </a>
-            <a href="/about">
-              <div
-                className={styles.item}
-                onClick={() => {
-                  setShowMenu("hide");
-                }}
-              >
-                关于我们
-              </div>
-            </a>
-            <a href="/#service">
-              <div
-                className={styles.item}
-                onClick={() => {
-                  setShowMenu("hide");
-                }}
-              >
-                业务介绍
-              </div>
-            </a>
-            <a href="/#consultant">
-              <div
-                className={styles.item}
-                onClick={() => {
-                  setShowMenu("hide");
-                }}
-              >
-                顾问介绍
-              </div>
-            </a>
-            <a href="/caseList">
-              <div
-                className={styles.item}
-                onClick={() => {
-                  setShowMenu("hide");
-                }}
-              >
-                经典案例
-              </div>
-            </a>
-            <a href="/contactUs">
-              <div
-                className={styles.item}
-                onClick={() => {
-                  setShowMenu("hide");
-                }}
-              >
-                联系我们
-              </div>
-            </a>
-            <a href={"https://hi-po.com.cn/user/login"}>
-              <div
-                className={styles.item}
-                onClick={() => {
-                  setShowMenu("hide");
-                }}
-              >
-                登录
-              </div>
-            </a>
-            <a href={"https://hi-po.com.cn/user/register"}>
-              <div
-                className={styles.item}
-                onClick={() => {
-                  setShowMenu("hide");
-                }}
-              >
-                注册
-              </div>
-            </a>
+            <Link className={styles.item} href="/">
+              首页
+            </Link>
+            <Link className={styles.item} href="/about">
+              关于我们
+            </Link>
+            <Link className={styles.item} href="/#service" scroll={true}>
+              业务介绍
+            </Link>
+            <Link className={styles.item} href="/#consultant" scroll={true}>
+              顾问介绍
+            </Link>
+            <Link className={styles.item} href="/caseList">
+              经典案例
+            </Link>
+            <Link className={styles.item} href="/contactUs">
+              联系我们
+            </Link>
+            <Link className={styles.item} href={"https://hi-po.com.cn/user/login"}>
+              登录
+            </Link>
+            <Link className={styles.item} href={"https://hi-po.com.cn/user/register"}>
+              注册
+            </Link>
           </div>
         </div>
       </div>

+ 16 - 16
src/components/Nav/navPC.tsx

@@ -18,30 +18,30 @@ const NavPC: React.FC = (props) => {
         </div>
         <div className={styles["navbar-collapse"]}>
           <div className={styles["navbar-content"]}>
-            <a className={styles.link} href="/">
+            <Link className={styles.link} href="/">
               首页
-            </a>
-            <a className={isCurrent("关于我们") ? styles.linkChecked : styles.link} href="/about">
+            </Link>
+            <Link className={isCurrent("关于我们") ? styles.linkChecked : styles.link} href="/about">
               关于我们
-            </a>
-            <a className={styles.link} href="/#service">
+            </Link>
+            <Link className={styles.link} href="/#service">
               业务介绍
-            </a>
-            <a className={isCurrent("顾问介绍") ? styles.linkChecked : styles.link} href="/#consultant">
+            </Link>
+            <Link className={isCurrent("顾问介绍") ? styles.linkChecked : styles.link} href="/#consultant">
               顾问介绍
-            </a>
-            <a className={isCurrent("经典案例") ? styles.linkChecked : styles.link} href="/caseList">
+            </Link>
+            <Link className={isCurrent("经典案例") ? styles.linkChecked : styles.link} href="/caseList">
               经典案例
-            </a>
-            <a className={isCurrent("联系我们") ? styles.linkChecked : styles.link} href="/contactUs">
+            </Link>
+            <Link className={isCurrent("联系我们") ? styles.linkChecked : styles.link} href="/contactUs">
               联系我们
-            </a>
-            <a className={styles.link} href={"https://hi-po.com.cn/user/login"}>
+            </Link>
+            <Link className={styles.link} href={"https://hi-po.com.cn/user/login"}>
               登录
-            </a>
-            <a className={styles.link} href={"https://hi-po.com.cn/user/register"}>
+            </Link>
+            <Link className={styles.link} href={"https://hi-po.com.cn/user/register"}>
               注册
-            </a>
+            </Link>
           </div>
         </div>
       </div>

+ 31 - 0
src/lib/parser.ts

@@ -0,0 +1,31 @@
+const { JSDOM } = require("jsdom");
+
+export function getDesc180(content: string) {
+  let result = "";
+  if (content) {
+    const dom = new JSDOM(content);
+    const document = dom.window.document;
+    const paragraphs = document.querySelectorAll("p");
+
+    let combinedText = "";
+    paragraphs.forEach((p) => {
+      combinedText += p.textContent?.trim() || "";
+    });
+
+    result = combinedText.slice(0, 180);
+  }
+  return result;
+}
+
+export function getDescLast(content: string) {
+  let result = "";
+  if (content) {
+    const dom = new JSDOM(content);
+    const paragraphs = dom.window.document.querySelectorAll("p");
+
+    if (paragraphs.length > 0) {
+      result = paragraphs[paragraphs.length - 1].textContent?.trim() || "";
+    }
+  }
+  return result;
+}