refactor: 优化网站页面结构和数据展示
- 增强服务数据模型,添加 challenges 和 outcomes 字段 - 简化统计数据配置,改为静态定义 - 重构多个页面组件,优化代码结构 - 新增产品、服务、解决方案相关的布局和组件 - 更新样式和动画配置 - 优化测试用例和类型定义 - 修复 ESLint 错误:移除不必要的 useEffect 和未使用的导入
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { SOLUTIONS } from '@/lib/constants/solutions';
|
||||
import type { Metadata } from 'next';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { SolutionDetailClient } from './solution-detail-client';
|
||||
|
||||
interface PageProps {
|
||||
params: Promise<{ id: string }>;
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return SOLUTIONS.map((solution) => ({
|
||||
id: solution.id,
|
||||
}));
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
|
||||
const { id } = await params;
|
||||
const solution = SOLUTIONS.find((s) => s.id === id);
|
||||
if (!solution) {return { title: '解决方案 - 睿新致远' };}
|
||||
return {
|
||||
title: `${solution.industry}数字化转型方案 - 睿新致远`,
|
||||
description: solution.description,
|
||||
};
|
||||
}
|
||||
|
||||
export default async function SolutionDetailPage({ params }: PageProps) {
|
||||
const { id } = await params;
|
||||
const solution = SOLUTIONS.find((s) => s.id === id);
|
||||
if (!solution) {notFound();}
|
||||
return <SolutionDetailClient solutionId={id} />;
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
'use client';
|
||||
|
||||
import { SOLUTIONS } from '@/lib/constants/solutions';
|
||||
import { PRODUCTS } from '@/lib/constants/products';
|
||||
import { StaticLink } from '@/components/ui/static-link';
|
||||
import { CheckCircle, Phone } from 'lucide-react';
|
||||
import {
|
||||
InkReveal,
|
||||
FadeUp,
|
||||
RippleButton,
|
||||
FloatingElement,
|
||||
StaggerContainer,
|
||||
StaggerItem,
|
||||
InkCard,
|
||||
SealStamp,
|
||||
} from '@/lib/animations';
|
||||
import { ScrollReveal, inkRevealVariants, slideInLeftVariants } from '@/components/ui/scroll-animations';
|
||||
|
||||
interface SolutionDetailClientProps {
|
||||
solutionId: string;
|
||||
}
|
||||
|
||||
export function SolutionDetailClient({ solutionId }: SolutionDetailClientProps) {
|
||||
const solution = SOLUTIONS.find((s) => s.id === solutionId) || null;
|
||||
|
||||
if (!solution) {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center">
|
||||
<p className="text-[#999999]">加载中...</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<main className="min-h-screen">
|
||||
{/* Section 1: Hero */}
|
||||
<section className="relative py-24 md:py-32 bg-gradient-to-b from-white to-[#F8F8F8]">
|
||||
<div className="container-wide">
|
||||
<div className="max-w-4xl mx-auto text-center">
|
||||
<SealStamp
|
||||
delay={0.1}
|
||||
className="inline-block px-4 py-2 bg-[#C41E3A]/20 rounded-full text-[#C41E3A] text-sm mb-6"
|
||||
>
|
||||
{solution.industry}
|
||||
</SealStamp>
|
||||
<InkReveal delay={0.2}>
|
||||
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold text-[#1C1C1C] mb-4">
|
||||
{solution.title}
|
||||
</h1>
|
||||
</InkReveal>
|
||||
<InkReveal delay={0.4}>
|
||||
<p className="text-lg md:text-xl text-[#5C5C5C] mb-4">{solution.subtitle}</p>
|
||||
</InkReveal>
|
||||
<InkReveal delay={0.5}>
|
||||
<p className="text-base text-[#5C5C5C] leading-relaxed mb-10 max-w-2xl mx-auto">
|
||||
{solution.description}
|
||||
</p>
|
||||
</InkReveal>
|
||||
<InkReveal delay={0.6}>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<RippleButton
|
||||
href="/contact"
|
||||
className="border-2 border-[#C41E3A] text-[#C41E3A] hover:bg-[#C41E3A] hover:text-white px-8 py-4 rounded-lg text-lg font-semibold inline-flex items-center justify-center"
|
||||
rippleColor="rgba(196, 30, 58, 0.2)"
|
||||
>
|
||||
预约演示
|
||||
</RippleButton>
|
||||
<RippleButton
|
||||
href="/contact"
|
||||
className="bg-[#C41E3A] hover:bg-[#A01830] text-white px-8 py-4 rounded-lg text-lg font-semibold inline-flex items-center justify-center"
|
||||
rippleColor="rgba(255, 255, 255, 0.3)"
|
||||
>
|
||||
获取定制方案
|
||||
</RippleButton>
|
||||
</div>
|
||||
</InkReveal>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Section 2: Challenges */}
|
||||
<section className="py-20 md:py-28 bg-white">
|
||||
<div className="container-wide">
|
||||
<ScrollReveal variants={slideInLeftVariants} className="mb-12">
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-[#1C1C1C]">行业痛点</h2>
|
||||
<p className="text-[#5C5C5C] mt-2">您是否也面临这些挑战?</p>
|
||||
</ScrollReveal>
|
||||
<StaggerContainer className="grid md:grid-cols-2 gap-6 max-w-5xl">
|
||||
{solution.challenges.map((challenge, index) => (
|
||||
<StaggerItem key={index}>
|
||||
<InkCard
|
||||
className="p-6 bg-[#FFFBF5] rounded-2xl border border-[#C41E3A]/10"
|
||||
hoverScale={1.02}
|
||||
hoverShadow="0 20px 40px rgba(196, 30, 58, 0.08)"
|
||||
>
|
||||
<div className="flex items-start gap-3">
|
||||
<span className="flex-shrink-0 w-8 h-8 rounded-full bg-[#C41E3A]/10 flex items-center justify-center text-[#C41E3A] font-bold text-sm">
|
||||
{index + 1}
|
||||
</span>
|
||||
<p className="text-[#1C1C1C] leading-relaxed">{challenge}</p>
|
||||
</div>
|
||||
</InkCard>
|
||||
</StaggerItem>
|
||||
))}
|
||||
</StaggerContainer>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Section 3: Our Solutions */}
|
||||
<section className="py-20 md:py-28 bg-[#F8F8F8]">
|
||||
<div className="container-wide">
|
||||
<ScrollReveal variants={inkRevealVariants} className="mb-12 text-center">
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-[#1C1C1C]">我们的解决方案</h2>
|
||||
<p className="text-[#5C5C5C] mt-2">针对行业痛点,量身定制</p>
|
||||
</ScrollReveal>
|
||||
<StaggerContainer className="max-w-3xl mx-auto space-y-6">
|
||||
{solution.solutions.map((item, index) => (
|
||||
<StaggerItem key={index}>
|
||||
<div className="flex items-start gap-4 p-6 bg-white rounded-2xl border border-[#E5E5E5]">
|
||||
<CheckCircle className="w-6 h-6 text-[#C41E3A] flex-shrink-0 mt-0.5" />
|
||||
<p className="text-[#1C1C1C] leading-relaxed text-lg">{item}</p>
|
||||
</div>
|
||||
</StaggerItem>
|
||||
))}
|
||||
</StaggerContainer>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Section 4: Related Products */}
|
||||
{solution.relatedProducts.length > 0 && (
|
||||
<section className="py-16 md:py-20 bg-white">
|
||||
<div className="container-wide">
|
||||
<div className="text-center mb-10">
|
||||
<h2 className="text-2xl md:text-3xl font-bold text-[#1C1C1C]">
|
||||
推荐产品
|
||||
</h2>
|
||||
<p className="text-[#5C5C5C] mt-2">即将上市,敬请期待</p>
|
||||
</div>
|
||||
<div className="grid sm:grid-cols-2 gap-6 max-w-3xl mx-auto">
|
||||
{solution.relatedProducts.map((productId) => {
|
||||
const product = PRODUCTS.find((p) => p.id === productId);
|
||||
if (!product) {return null;}
|
||||
return (
|
||||
<FadeUp key={productId}>
|
||||
<StaticLink href={`/products/${productId}`}>
|
||||
<div className="group p-6 bg-[#F8F8F8] rounded-2xl border border-[#E5E5E5] hover:border-[#C41E3A]/30 transition-all">
|
||||
<span className="inline-block px-3 py-1 bg-[#C41E3A]/10 text-[#C41E3A] text-xs font-semibold rounded-full mb-3">
|
||||
{product.category}
|
||||
</span>
|
||||
<h3 className="text-lg font-bold text-[#1C1C1C] mb-2 group-hover:text-[#C41E3A] transition-colors">
|
||||
{product.title}
|
||||
</h3>
|
||||
<p className="text-sm text-[#5C5C5C] line-clamp-2">{product.description}</p>
|
||||
</div>
|
||||
</StaticLink>
|
||||
</FadeUp>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Section 6: CTA */}
|
||||
<section className="relative py-24 md:py-32 bg-gradient-to-r from-[#C41E3A] to-[#E85D75] overflow-hidden">
|
||||
<FloatingElement
|
||||
amplitude={8}
|
||||
duration={5}
|
||||
delay={0.5}
|
||||
className="absolute -top-20 -right-20 pointer-events-none"
|
||||
>
|
||||
<div className="w-[280px] h-[280px] bg-white/10 rounded-full" />
|
||||
</FloatingElement>
|
||||
<FloatingElement
|
||||
amplitude={6}
|
||||
duration={4}
|
||||
delay={1}
|
||||
className="absolute -bottom-16 -left-16 pointer-events-none"
|
||||
>
|
||||
<div className="w-[220px] h-[220px] bg-white/10 rounded-full" />
|
||||
</FloatingElement>
|
||||
<div className="container-wide">
|
||||
<div className="max-w-3xl mx-auto text-center">
|
||||
<InkReveal delay={0}>
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-white mb-6">
|
||||
准备好开启{solution.industry}数字化转型了吗?
|
||||
</h2>
|
||||
</InkReveal>
|
||||
<FadeUp delay={0.15}>
|
||||
<p className="text-lg text-white/90 mb-10">
|
||||
我们的专家团队将为您量身定制专属解决方案
|
||||
</p>
|
||||
</FadeUp>
|
||||
<FadeUp delay={0.3}>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<RippleButton
|
||||
href="/contact"
|
||||
rippleColor="rgba(196, 30, 58, 0.3)"
|
||||
className="bg-white text-[#C41E3A] px-8 py-4 rounded-lg text-lg font-semibold inline-flex items-center justify-center w-full sm:w-auto"
|
||||
>
|
||||
免费获取方案
|
||||
</RippleButton>
|
||||
<RippleButton
|
||||
href="tel:+8613800138000"
|
||||
rippleColor="rgba(255, 255, 255, 0.2)"
|
||||
className="bg-transparent border-2 border-white text-white px-8 py-4 rounded-lg text-lg font-semibold inline-flex items-center justify-center gap-2 w-full sm:w-auto"
|
||||
>
|
||||
<Phone className="w-5 h-5" />
|
||||
电话咨询
|
||||
</RippleButton>
|
||||
</div>
|
||||
</FadeUp>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user