refactor(link): 营销页站内链接统一 StaticLink(静态托管适配)+ 删除 0 引用死代码组件 + QA 页 client/server 拆分

This commit is contained in:
2026-08-31 12:03:12 +08:00
parent 77b455c04e
commit 08a020105f
26 changed files with 297 additions and 571 deletions
@@ -2,6 +2,7 @@
import { motion } from 'framer-motion';
import { ScrollReveal } from '@/components/ui/scroll-reveal';
import { StaticLink } from '@/components/ui/static-link';
import { BrandCalligraphyName } from '@/components/ui/brand-calligraphy-name';
import {
ArrowRight,
@@ -355,20 +356,20 @@ export default function BrandContent() {
从一次深入的业务诊断开始,开启您的数据驱动之旅。
</p>
<div className="flex flex-col sm:flex-row gap-4 sm:gap-6">
<a
<StaticLink
href="/contact"
className="group inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base bg-brand text-white transition-all duration-300 hover:bg-brand/90 min-h-[52px]"
>
预约咨询
<ArrowRight className="w-5 h-5 transition-transform duration-300 group-hover:translate-x-1" />
</a>
<a
</StaticLink>
<StaticLink
href="/cases"
className="group inline-flex items-center justify-center gap-2 px-10 py-5 font-semibold text-base text-dark-text-primary border border-dark-border hover:border-dark-text-muted transition-all duration-300 min-h-[52px]"
>
查看客户案例
<ChevronRight className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-1" />
</a>
</StaticLink>
</div>
</ScrollReveal>
</div>
@@ -2,6 +2,7 @@
import { useState, useMemo } from 'react';
import { motion } from 'framer-motion';
import { StaticLink } from '@/components/ui/static-link';
import { Building2, ArrowUpRight, Target, Lightbulb, Filter } from 'lucide-react';
import {
type CaseStudy,
@@ -308,19 +309,19 @@ export default function CasesContentV3({
让我们聊聊您的挑战,看看能创造什么样的成果。
</p>
<div className="flex flex-col sm:flex-row gap-4 sm:gap-6">
<a
<StaticLink
href="/contact"
className="group inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base bg-brand text-white transition-all duration-300 hover:bg-brand/90 min-h-[52px] touch-manipulation"
>
预约咨询
<ArrowUpRight className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-0.5 group-hover:-translate-y-0.5" />
</a>
<a
</StaticLink>
<StaticLink
href="/services"
className="inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base text-ink border border-border-primary hover:border-border-secondary hover:bg-white transition-all duration-300 min-h-[52px] touch-manipulation"
>
了解服务
</a>
</StaticLink>
</div>
</motion.div>
</div>
+11 -7
View File
@@ -5,6 +5,7 @@ import Image from 'next/image';
import { motion } from 'framer-motion';
import { ScrollReveal, StaggerReveal } from '@/components/ui/scroll-reveal';
import { Badge } from '@/components/ui/badge';
import { StaticLink } from '@/components/ui/static-link';
import { HeroProductVisual } from '@/components/sections/hero-product-visual';
import { ArrowRight, Lightbulb, Database, Layers, Code, Puzzle, Server } from 'lucide-react';
import { cn } from '@/lib/utils';
@@ -335,13 +336,13 @@ function TrustSection({ pageCopy }: { pageCopy?: HomePageCopy | null }) {
</div>
))}
</div>
<a
<StaticLink
href="/contact"
className="group inline-flex shrink-0 items-center gap-2 text-sm font-semibold text-ink hover:text-brand transition-colors"
>
<span>{earlyCtaLabel}</span>
<ArrowRight className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-1" />
</a>
</StaticLink>
</div>
</StaggerReveal>
</div>
@@ -398,7 +399,10 @@ function NarrativeSection({ pageCopy }: { pageCopy?: HomePageCopy | null }) {
<StaggerReveal key={act.number} staggerDelay={0.08}>
<div className="group relative h-full bg-white p-8 sm:p-10 md:p-12 transition-colors duration-300 hover:bg-bg-secondary">
<div className="flex items-start justify-between mb-8">
<span className="text-4xl sm:text-5xl font-black text-text-hint tabular-nums leading-none">
<span
aria-hidden="true"
className="text-4xl sm:text-5xl font-black text-text-hint tabular-nums leading-none"
>
{act.number}
</span>
</div>
@@ -524,13 +528,13 @@ function CasesSection({ cases, pageCopy }: { cases?: Record<string, any>[]; page
<p className="text-text-secondary leading-relaxed text-lg mb-8">
{casesDesc}
</p>
<a
<StaticLink
href="/contact"
className="group inline-flex items-center gap-3 text-ink font-semibold text-sm"
>
成为首批共创客户
<ArrowRight className="w-4 h-5 transition-transform duration-300 group-hover:translate-x-2 text-text-secondary group-hover:text-brand" />
</a>
</StaticLink>
</ScrollReveal>
<ScrollReveal delay={0.15}>
<div className="bain-card p-10 sm:p-12 bg-bg-secondary">
@@ -556,13 +560,13 @@ function CasesSection({ cases, pageCopy }: { cases?: Record<string, any>[]; page
</h2>
</ScrollReveal>
<ScrollReveal delay={0.1}>
<a
<StaticLink
href="/cases"
className="group inline-flex items-center gap-3 text-ink font-semibold text-sm"
>
查看全部案例
<ArrowRight className="w-4 h-5 transition-transform duration-300 group-hover:translate-x-2 text-text-secondary group-hover:text-brand" />
</a>
</StaticLink>
</ScrollReveal>
</div>
@@ -2,6 +2,7 @@
import { motion } from 'framer-motion';
import { ScrollReveal, StaggerReveal } from '@/components/ui/scroll-reveal';
import { StaticLink } from '@/components/ui/static-link';
import { EASE_OUT } from '@/components/ui/page-decoration';
import { Button } from '@/components/ui/button';
import { ArrowRight, CheckCircle2 } from 'lucide-react';
@@ -154,13 +155,13 @@ export function MethodologyContent({ data }: MethodologyContentProps) {
</p>
<div className="flex flex-wrap justify-center gap-6">
<Button size="xl" asChild>
<a href="/services">
<StaticLink href="/services">
了解我们的服务
<ArrowRight className="w-5 h-5 ml-2" />
</a>
</StaticLink>
</Button>
<Button size="xl" variant="outline" asChild>
<a href="/contact">联系我们</a>
<StaticLink href="/contact">联系我们</StaticLink>
</Button>
</div>
</ScrollReveal>
+2 -2
View File
@@ -75,7 +75,7 @@ function NewsCard({ newsItem, index }: { newsItem: NewsItem; index: number }) {
}
export default function NewsContentV3({ news, pageCopy }: { news?: NewsItem[]; pageCopy?: Record<string, unknown> | null }) {
const NEWS = news ?? [];
const NEWS = useMemo(() => news ?? [], [news]);
const [selectedCategory, setSelectedCategory] = useState('全部');
const [searchQuery, setSearchQuery] = useState('');
const [currentPage, setCurrentPage] = useState(1);
@@ -94,7 +94,7 @@ export default function NewsContentV3({ news, pageCopy }: { news?: NewsItem[]; p
newsItem.excerpt.toLowerCase().includes(searchQuery.toLowerCase());
return matchesCategory && matchesSearch;
});
}, [selectedCategory, searchQuery]);
}, [selectedCategory, searchQuery, NEWS]);
const totalPages = Math.ceil(filteredNews.length / ITEMS_PER_PAGE);
const paginatedNews = useMemo(() => {
@@ -1,6 +1,7 @@
'use client';
import { ScrollReveal } from '@/components/ui/scroll-reveal';
import { StaticLink } from '@/components/ui/static-link';
import { Badge } from '@/components/ui/badge';
import { Calendar, ArrowLeft, Newspaper, ArrowRight } from 'lucide-react';
import { SectionLabel, EASE_OUT } from '@/components/ui/page-decoration';
@@ -63,9 +64,9 @@ export default function NewsDetailContentV3({ news, relatedNews = [] }: NewsDeta
<div className="max-w-container mx-auto px-4 sm:px-6 lg:px-10 relative z-10">
<ScrollReveal>
<nav aria-label="breadcrumb" className="flex items-center gap-2 text-sm text-text-muted mb-8 sm:mb-10">
<a href="/news" className="hover:text-brand transition-colors duration-300">
<StaticLink href="/news" className="hover:text-brand transition-colors duration-300">
新闻动态
</a>
</StaticLink>
<span>/</span>
<span className="text-text-secondary line-clamp-1">{news.title}</span>
</nav>
@@ -145,20 +146,20 @@ export default function NewsDetailContentV3({ news, relatedNews = [] }: NewsDeta
{/* Navigation */}
<ScrollReveal>
<div className="mt-16 sm:mt-20 flex flex-col sm:flex-row justify-center gap-4">
<a
<StaticLink
href="/news"
className="inline-flex items-center justify-center gap-2 px-8 py-4 font-medium text-base text-ink border border-border-primary hover:border-border-secondary hover:bg-bg-secondary transition-all duration-300"
>
<ArrowLeft className="w-4 h-4" />
返回新闻列表
</a>
<a
</StaticLink>
<StaticLink
href="/contact"
className="group inline-flex items-center justify-center gap-2 px-8 py-4 font-medium text-base bg-brand text-white transition-all duration-300 hover:bg-brand/90"
>
联系我们
<ArrowRight className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-1" />
</a>
</StaticLink>
</div>
</ScrollReveal>
</div>
@@ -1,6 +1,7 @@
'use client';
import { ScrollReveal, StaggerReveal } from '@/components/ui/scroll-reveal';
import { StaticLink } from '@/components/ui/static-link';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import {
@@ -153,10 +154,10 @@ export default function ErpUpgradeContentV2({ item }: ErpUpgradeContentV2Props)
<ScrollReveal delay={0.3}>
<div className="mt-12 flex flex-wrap gap-4">
<Button size="xl" asChild>
<a href="/contact">
<StaticLink href="/contact">
免费诊断咨询
<ArrowRight className="w-5 h-5 ml-2" />
</a>
</StaticLink>
</Button>
<Button size="xl" variant="outline" asChild>
<a href="#features">了解功能模块</a>
@@ -404,13 +405,13 @@ export default function ErpUpgradeContentV2({ item }: ErpUpgradeContentV2Props)
<div className="flex flex-wrap gap-6 justify-center">
<Button size="xl" asChild>
<a href="/contact">
<StaticLink href="/contact">
预约免费诊断
<ArrowRight className="w-5 h-5 ml-2" />
</a>
</StaticLink>
</Button>
<Button size="xl" variant="outline" asChild>
<a href="/products/erp">查看产品详情</a>
<StaticLink href="/products/erp">查看产品详情</StaticLink>
</Button>
</div>
</ScrollReveal>
@@ -2,6 +2,7 @@
import { motion } from 'framer-motion';
import { ScrollReveal, StaggerReveal } from '@/components/ui/scroll-reveal';
import { StaticLink } from '@/components/ui/static-link';
import { Button } from '@/components/ui/button';
import { ArrowRight, Package, Check, Settings, Users, FileText, Cpu, Shield, TrendingUp } from 'lucide-react';
import { SectionLabel, EASE_OUT } from '@/components/ui/page-decoration';
@@ -89,13 +90,13 @@ function DetailHero({ product }: DetailHeroProps) {
className="flex flex-wrap gap-6"
>
<Button size="xl" asChild>
<a href="/contact">
<StaticLink href="/contact">
预约体验
<ArrowRight className="w-5 h-5 ml-2" />
</a>
</StaticLink>
</Button>
<Button size="xl" variant="outline" asChild>
<a href="/products">查看更多产品</a>
<StaticLink href="/products">查看更多产品</StaticLink>
</Button>
</motion.div>
</div>
@@ -403,15 +404,29 @@ function CTASection({ product }: CTASectionProps) {
<div className="flex flex-wrap justify-center gap-6">
<Button size="xl" asChild>
<a href="/contact">
<StaticLink href="/contact">
预约演示
<ArrowRight className="w-5 h-5 ml-2" />
</a>
</StaticLink>
</Button>
<Button size="xl" variant="outline" asChild>
<a href="/products">查看更多产品</a>
<StaticLink href="/products">查看更多产品</StaticLink>
</Button>
</div>
{/* 站内入口:ERP 升级专题(与 erp-upgrade-content-v2 的反向链接形成互链闭环) */}
{product.id === 'erp' && (
<div className="mt-10 inline-flex flex-wrap items-center justify-center gap-x-2 gap-y-1 text-sm text-text-secondary">
正在使用旧版 ERP?
<StaticLink
href="/products/erp-upgrade"
className="inline-flex items-center gap-1 font-medium text-brand hover:underline"
>
了解睿新 ERP 升级专题
<ArrowRight className="w-4 h-4" />
</StaticLink>
</div>
)}
</ScrollReveal>
</div>
</section>
@@ -136,13 +136,13 @@ function HeroSection({ pageCopy }: { pageCopy?: PageCopy | null }) {
className="flex flex-wrap gap-6"
>
<Button size="xl" asChild>
<a href="/services">
<StaticLink href="/services">
{ctaPrimary}
<ArrowRight className="w-5 h-5 ml-2" />
</a>
</StaticLink>
</Button>
<Button size="xl" variant="outline" asChild>
<a href="/solutions">{ctaSecondary}</a>
<StaticLink href="/solutions">{ctaSecondary}</StaticLink>
</Button>
</motion.div>
@@ -425,7 +425,7 @@ function SuiteCombosSection({ products }: { products: Product[] }) {
.filter(Boolean);
return (
<a
<StaticLink
key={idx}
href="/solutions"
className="group p-10 lg:p-12 bg-white hover:bg-bg-secondary transition-all duration-500 overflow-hidden"
@@ -465,7 +465,7 @@ function SuiteCombosSection({ products }: { products: Product[] }) {
<ArrowRight className="w-4 h-4" />
</motion.div>
</div>
</a>
</StaticLink>
);
})}
</StaggerReveal>
@@ -498,13 +498,13 @@ function CTASection({ pageCopy }: { pageCopy?: PageCopy | null }) {
<div className="flex flex-wrap justify-center gap-6">
<Button size="xl" asChild>
<a href="/services">
<StaticLink href="/services">
了解我们的服务
<ArrowRight className="w-5 h-5 ml-2" />
</a>
</StaticLink>
</Button>
<Button size="xl" variant="outline" asChild>
<a href="/contact">联系我们</a>
<StaticLink href="/contact">联系我们</StaticLink>
</Button>
</div>
</ScrollReveal>
@@ -1,6 +1,7 @@
'use client';
import { getHeroTheme } from '@/lib/constants/hero-themes';
import { StaticLink } from '@/components/ui/static-link';
import { DetailHero } from '@/components/detail/detail-hero';
import { DetailTrustSection } from '@/components/detail/detail-trust-section';
import { DetailCTASection } from '@/components/detail/detail-cta-section';
@@ -112,19 +113,19 @@ export function StandaloneProductClient({ item }: StandaloneProductClientProps)
)}
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
<a
<StaticLink
href="/contact"
className="inline-flex items-center gap-2 rounded-lg bg-brand px-8 py-3 text-sm font-semibold text-white shadow-md transition-all hover:bg-brand/90 hover:shadow-lg"
>
获取上线通知
<ArrowRight className="h-4 w-4" />
</a>
<a
</StaticLink>
<StaticLink
href="/products"
className="inline-flex items-center rounded-lg border border-border-primary px-6 py-3 text-sm font-semibold text-text-secondary transition-all hover:border-border-secondary hover:bg-bg-secondary"
>
查看其他产品
</a>
</StaticLink>
</div>
</motion.div>
</div>
@@ -1,6 +1,7 @@
'use client';
import { motion } from 'framer-motion';
import { StaticLink } from '@/components/ui/static-link';
import { ArrowUpRight, CheckCircle2, Zap, Clock, Users, Award, TrendingUp, Shield } from 'lucide-react';
import type { LucideIcon } from 'lucide-react';
import type { Service, CaseStudy } from '@/lib/constants/services';
@@ -80,13 +81,13 @@ function DetailHero({ service }: { service: Service }) {
transition={{ duration: 0.8, delay: 0.9, ease: EASE_OUT }}
className="flex flex-col sm:flex-row gap-4 sm:gap-6"
>
<a
<StaticLink
href="/contact"
className="group inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base bg-brand text-white transition-all duration-300 hover:bg-brand/90 min-h-[52px] touch-manipulation"
>
免费咨询
<ArrowUpRight className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-0.5 group-hover:-translate-y-0.5" />
</a>
</StaticLink>
<a
href="#cases"
className="inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base text-ink border border-border-primary hover:border-ink/30 transition-all duration-300 min-h-[52px] touch-manipulation"
@@ -336,19 +337,19 @@ function CTASection() {
首次咨询免费,没有任何销售压力。
</p>
<div className="flex flex-col sm:flex-row gap-4 sm:gap-6">
<a
<StaticLink
href="/contact"
className="group inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base bg-brand text-white transition-all duration-300 hover:bg-brand/90 min-h-[52px] touch-manipulation"
>
预约免费咨询
<ArrowUpRight className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-0.5 group-hover:-translate-y-0.5" />
</a>
<a
</StaticLink>
<StaticLink
href="/services"
className="inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base text-ink border border-border-primary hover:border-ink/30 transition-all duration-300 min-h-[52px] touch-manipulation"
>
返回服务列表
</a>
</StaticLink>
</div>
</motion.div>
</div>
@@ -126,19 +126,19 @@ function HeroSection({ pageCopy }: { pageCopy?: PageCopy | null }) {
transition={{ duration: 0.8, delay: 0.7, ease: EASE_OUT }}
className="flex flex-col sm:flex-row gap-4 sm:gap-6"
>
<a
<StaticLink
href="/contact"
className="group inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base bg-brand text-white transition-all duration-300 hover:bg-brand/90 min-h-[52px] touch-manipulation"
>
{ctaPrimary}
<ArrowUpRight className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-0.5 group-hover:-translate-y-0.5" />
</a>
<a
</StaticLink>
<StaticLink
href="/products"
className="inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base text-ink border border-border-primary hover:border-ink/30 transition-all duration-300 min-h-[52px] touch-manipulation"
>
{ctaSecondary}
</a>
</StaticLink>
</motion.div>
<motion.div
@@ -364,19 +364,19 @@ function CTASection({ pageCopy }: { pageCopy?: PageCopy | null }) {
))}
</p>
<div className="flex flex-col sm:flex-row gap-4 sm:gap-6">
<a
<StaticLink
href="/contact"
className="group inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base bg-brand text-white transition-all duration-300 hover:bg-brand/90 min-h-[52px] touch-manipulation"
>
预约免费咨询
<ArrowUpRight className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-0.5 group-hover:-translate-y-0.5" />
</a>
<a
</StaticLink>
<StaticLink
href="/team"
className="inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base text-ink border border-border-primary hover:border-ink/30 transition-all duration-300 min-h-[52px] touch-manipulation"
>
了解我们的团队
</a>
</StaticLink>
</div>
</motion.div>
</div>
@@ -2,6 +2,7 @@
import { motion } from 'framer-motion';
import { ScrollReveal, StaggerReveal } from '@/components/ui/scroll-reveal';
import { StaticLink } from '@/components/ui/static-link';
import { Button } from '@/components/ui/button';
import { ArrowRight, Factory, ShoppingCart, Heart, GraduationCap, Lightbulb, Settings, Users, TrendingUp, Package, BookOpen, MessageSquare, Calendar, Smartphone, Route, Shield, Truck } from 'lucide-react';import { SectionLabel, EASE_OUT } from '@/components/ui/page-decoration';
import type { Solution } from '@/lib/constants/solutions';
@@ -83,13 +84,13 @@ function DetailHero({ solution }: DetailHeroProps) {
className="flex flex-wrap gap-6"
>
<Button size="xl" asChild>
<a href="/contact">
<StaticLink href="/contact">
获取方案详情
<ArrowRight className="w-5 h-5 ml-2" />
</a>
</StaticLink>
</Button>
<Button size="xl" variant="outline" asChild>
<a href="/products">查看产品</a>
<StaticLink href="/products">查看产品</StaticLink>
</Button>
</motion.div>
</div>
@@ -491,13 +492,13 @@ function CTASection({ solution }: CTASectionProps) {
<div className="flex flex-wrap justify-center gap-6">
<Button size="xl" asChild>
<a href="/contact">
<StaticLink href="/contact">
预约咨询
<ArrowRight className="w-5 h-5 ml-2" />
</a>
</StaticLink>
</Button>
<Button size="xl" variant="outline" asChild>
<a href="/solutions">查看更多方案</a>
<StaticLink href="/solutions">查看更多方案</StaticLink>
</Button>
</div>
</ScrollReveal>
@@ -74,19 +74,19 @@ function HeroSection({ pageCopy }: { pageCopy?: PageCopy | null }) {
transition={{ duration: 0.8, delay: 0.7, ease: EASE_OUT }}
className="flex flex-col sm:flex-row gap-4 sm:gap-6"
>
<a
<StaticLink
href="/contact"
className="group inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base bg-brand text-white transition-all duration-300 hover:bg-brand/90 min-h-[52px] touch-manipulation"
>
{ctaPrimary}
<ArrowUpRight className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-0.5 group-hover:-translate-y-0.5" />
</a>
<a
</StaticLink>
<StaticLink
href="/products"
className="inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base text-ink border border-border-primary hover:border-ink/30 transition-all duration-300 min-h-[52px] touch-manipulation"
>
{ctaSecondary}
</a>
</StaticLink>
</motion.div>
<motion.div
@@ -240,19 +240,19 @@ function CTASection({ pageCopy }: { pageCopy?: PageCopy | null }) {
{ctaDescription}
</p>
<div className="flex flex-col sm:flex-row gap-4 sm:gap-6">
<a
<StaticLink
href="/contact"
className="group inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base bg-brand text-white transition-all duration-300 hover:bg-brand/90 min-h-[52px] touch-manipulation"
>
获取定制方案
<ArrowUpRight className="w-4 h-4 transition-transform duration-300 group-hover:translate-x-0.5 group-hover:-translate-y-0.5" />
</a>
<a
</StaticLink>
<StaticLink
href="/products"
className="inline-flex items-center justify-center gap-3 px-10 py-5 font-semibold text-base text-ink border border-border-primary hover:border-ink/30 transition-all duration-300 min-h-[52px] touch-manipulation"
>
浏览产品
</a>
</StaticLink>
</div>
</motion.div>
</div>