feat: 营销页面HSI架构改造与四层叙事对齐
- 产品页:双区展示(企业套装+专业产品),分类筛选,统计数据更新 - 方案页:删除服务方式区域,替换为轻量关联推荐卡片 - 方案详情页:添加L3信任层条件渲染,使用V3 Hero+V2 CTA - 独立产品页:从V1组件迁移到V2/V3 - 服务页:视觉升级与组件更新 - 首页:产品矩阵和CTA区域优化
This commit is contained in:
@@ -4,11 +4,6 @@ import dynamic from 'next/dynamic';
|
||||
import { HeroSectionV2 } from '@/components/sections/hero-section-v2';
|
||||
import { SectionSkeleton } from '@/components/ui/loading-skeleton';
|
||||
|
||||
const SocialProofSection = dynamic(
|
||||
() => import('@/components/sections/social-proof-section').then(mod => ({ default: mod.SocialProofSection })),
|
||||
{ loading: () => <SectionSkeleton />, ssr: false }
|
||||
);
|
||||
|
||||
const ProductMatrixSection = dynamic(
|
||||
() => import('@/components/sections/product-matrix-section').then(mod => ({ default: mod.ProductMatrixSection })),
|
||||
{ loading: () => <SectionSkeleton />, ssr: false }
|
||||
@@ -19,6 +14,16 @@ const ChallengeSection = dynamic(
|
||||
{ loading: () => <SectionSkeleton />, ssr: false }
|
||||
);
|
||||
|
||||
const SocialProofSection = dynamic(
|
||||
() => import('@/components/sections/social-proof-section').then(mod => ({ default: mod.SocialProofSection })),
|
||||
{ loading: () => <SectionSkeleton />, ssr: false }
|
||||
);
|
||||
|
||||
const WhyUsSection = dynamic(
|
||||
() => import('@/components/sections/why-us-section').then(mod => ({ default: mod.WhyUsSection })),
|
||||
{ loading: () => <SectionSkeleton />, ssr: false }
|
||||
);
|
||||
|
||||
const CTASection = dynamic(
|
||||
() => import('@/components/sections/cta-section').then(mod => ({ default: mod.CTASection })),
|
||||
{ loading: () => <SectionSkeleton />, ssr: false }
|
||||
@@ -31,6 +36,7 @@ function HomeContentV2() {
|
||||
<ProductMatrixSection />
|
||||
<ChallengeSection />
|
||||
<SocialProofSection />
|
||||
<WhyUsSection />
|
||||
<CTASection />
|
||||
</main>
|
||||
);
|
||||
|
||||
@@ -27,7 +27,9 @@ jest.mock('@/lib/constants', () => ({
|
||||
{
|
||||
id: 'test-product',
|
||||
title: '测试产品',
|
||||
category: '企业软件',
|
||||
category: '企业旗舰系列',
|
||||
categoryId: 'enterprise',
|
||||
tags: ['测试', '示例'],
|
||||
status: '研发中',
|
||||
description: '这是测试产品描述',
|
||||
overview: '这是测试产品概述',
|
||||
@@ -37,6 +39,13 @@ jest.mock('@/lib/constants', () => ({
|
||||
specs: ['规格1', '规格2'],
|
||||
},
|
||||
],
|
||||
PRODUCT_CATEGORIES: [
|
||||
{
|
||||
id: 'enterprise',
|
||||
title: '企业旗舰系列',
|
||||
description: '测试分类描述',
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
describe('ProductDetailPage', () => {
|
||||
@@ -66,7 +75,7 @@ describe('ProductDetailPage', () => {
|
||||
const page = await ProductDetailPage({ params: Promise.resolve({ id: 'test-product' }) });
|
||||
render(page);
|
||||
|
||||
const category = screen.getByText('企业软件');
|
||||
const category = screen.getByText('企业旗舰系列');
|
||||
expect(category).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { notFound } from 'next/navigation';
|
||||
import { StaticLink } from '@/components/ui/static-link';
|
||||
import { PRODUCTS, COMPANY_INFO } from '@/lib/constants';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { PageNav } from '@/components/layout/page-nav';
|
||||
import { getHeroTheme } from '@/lib/constants/hero-themes';
|
||||
import { getProductCrossRefs } from '@/lib/constants/cross-references';
|
||||
import { DetailSwipeNav } from '@/components/ui/detail-swipe-nav';
|
||||
import { CheckCircle2, Zap, Target, Layers, ArrowRight, FlaskConical } from 'lucide-react';
|
||||
import { DetailHeroV3 } from '@/components/detail-v2/detail-hero-v3';
|
||||
import { ProductValueSectionV3 } from '@/components/detail-v2/detail-product-value-v3';
|
||||
import { DetailTrustSectionV2 } from '@/components/detail-v2/detail-trust-section-v2';
|
||||
import { DetailCTASectionV2 } from '@/components/detail-v2/detail-cta-section-v2';
|
||||
import { CrossRecommendGrid } from '@/components/detail/detail-cross-recommend';
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return PRODUCTS.map((product) => ({
|
||||
@@ -22,7 +25,7 @@ export async function generateMetadata({ params }: { params: Promise<{ id: strin
|
||||
|
||||
return {
|
||||
title: `${product.title} - ${COMPANY_INFO.displayName}`,
|
||||
description: product.description,
|
||||
description: `${product.description} | 现代东方美学设计`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -34,151 +37,45 @@ export default async function ProductDetailPage({ params }: { params: Promise<{
|
||||
notFound();
|
||||
}
|
||||
|
||||
const theme = getHeroTheme(product.heroThemeId);
|
||||
const crossRefs = getProductCrossRefs(product.id);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[var(--color-bg-primary)]">
|
||||
<DetailSwipeNav type="product" currentId={product.id} />
|
||||
<div className="pt-32 pb-16">
|
||||
<div className="container-wide">
|
||||
<PageNav items={[{ label: '产品', href: '/products' }, { label: product.title }]} />
|
||||
<div className="max-w-4xl mt-8">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<p className="text-sm font-medium text-[var(--color-brand-primary)] tracking-wide uppercase">{product.category}</p>
|
||||
<span
|
||||
className="text-xs font-medium px-3 py-1 rounded-full border"
|
||||
style={{
|
||||
backgroundColor: 'rgba(var(--color-brand-primary-rgb), 0.08)',
|
||||
color: 'var(--color-brand-primary)',
|
||||
borderColor: 'rgba(var(--color-brand-primary-rgb), 0.15)',
|
||||
}}
|
||||
>
|
||||
{product.status}
|
||||
</span>
|
||||
</div>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-[var(--color-text-primary)] mb-6 tracking-tight">
|
||||
{product.title}
|
||||
</h1>
|
||||
<p className="text-xl text-[var(--color-text-muted)] leading-relaxed">
|
||||
{product.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="container-wide pb-20">
|
||||
<div className="max-w-4xl space-y-16">
|
||||
<section aria-labelledby="product-overview">
|
||||
<h2 id="product-overview" className="text-2xl font-bold text-[var(--color-text-primary)] mb-6">产品概述</h2>
|
||||
<p className="text-lg text-[var(--color-text-muted)] leading-relaxed">
|
||||
{product.overview}
|
||||
</p>
|
||||
</section>
|
||||
{/* L1 - Hero 情感入口 (V3) */}
|
||||
<DetailHeroV3
|
||||
theme={theme}
|
||||
badge={product.category}
|
||||
title={product.title}
|
||||
subtitle={product.description}
|
||||
description={product.overview}
|
||||
primaryAction={{ label: '预约体验', href: '/contact' }}
|
||||
secondaryAction={{ label: '查看方案', href: '/solutions' }}
|
||||
/>
|
||||
|
||||
<section aria-labelledby="product-features">
|
||||
<h2 id="product-features" className="text-2xl font-bold text-[var(--color-text-primary)] mb-6 flex items-center gap-3">
|
||||
<Zap className="w-6 h-6 text-[var(--color-brand-primary)]" />
|
||||
规划功能
|
||||
</h2>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
{product.features.map((feature, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-start gap-3 p-4 bg-[var(--color-bg-tertiary)] rounded-lg hover:bg-[var(--color-brand-primary-bg)] transition-colors"
|
||||
>
|
||||
<CheckCircle2 className="w-5 h-5 text-[var(--color-brand-primary)] mt-0.5 shrink-0" />
|
||||
<span className="text-[var(--color-text-primary)] text-sm">{feature}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
{/* L2 - 价值理性支撑 (V3) */}
|
||||
<ProductValueSectionV3 product={product} />
|
||||
|
||||
<section aria-labelledby="product-benefits">
|
||||
<h2 id="product-benefits" className="text-2xl font-bold text-[var(--color-text-primary)] mb-6 flex items-center gap-3">
|
||||
<Target className="w-6 h-6 text-[var(--color-brand-primary)]" />
|
||||
产品优势
|
||||
</h2>
|
||||
<div className="space-y-3">
|
||||
{product.benefits.map((benefit, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-start gap-3 p-4 rounded-lg bg-[var(--color-brand-primary-bg)]"
|
||||
>
|
||||
<div className="w-1.5 h-1.5 bg-[var(--color-brand-primary)] rounded-full mt-2 shrink-0" />
|
||||
<span className="text-[var(--color-text-primary)] font-medium text-sm">{benefit}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
{/* L3 - 信任证明 (V2) */}
|
||||
<DetailTrustSectionV2
|
||||
caseStudies={product.caseStudies}
|
||||
dataProofs={product.dataProofs}
|
||||
certifications={product.certifications}
|
||||
accentColor={theme.accentColor}
|
||||
/>
|
||||
|
||||
<section aria-labelledby="product-process">
|
||||
<h2 id="product-process" className="text-2xl font-bold text-[var(--color-text-primary)] mb-6 flex items-center gap-3">
|
||||
<Layers className="w-6 h-6 text-[var(--color-brand-primary)]" />
|
||||
预期实施流程
|
||||
</h2>
|
||||
<div className="space-y-4">
|
||||
{product.process.map((step, index) => (
|
||||
<div key={index} className="flex items-start gap-4">
|
||||
<div className="w-8 h-8 bg-[var(--color-brand-primary)] rounded-full flex items-center justify-center shrink-0 text-white text-sm font-bold">
|
||||
{index + 1}
|
||||
</div>
|
||||
<p className="text-[var(--color-text-primary)] pt-1">{step}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
{/* L4 - CTA + 交叉推荐 (V2) */}
|
||||
<DetailCTASectionV2
|
||||
theme={theme}
|
||||
title={`探索 ${product.title} 的无限可能`}
|
||||
description="立即联系我们,获取专属方案和报价"
|
||||
primaryAction={{ label: '预约体验', href: '/contact' }}
|
||||
secondaryAction={{ label: '下载产品手册', href: '#' }}
|
||||
/>
|
||||
|
||||
<section aria-labelledby="product-specs">
|
||||
<h2 id="product-specs" className="text-2xl font-bold text-[var(--color-text-primary)] mb-6">技术规格</h2>
|
||||
<div className="grid md:grid-cols-2 gap-3">
|
||||
{product.specs.map((spec, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-center gap-3 p-3 bg-[var(--color-bg-tertiary)] rounded-lg"
|
||||
>
|
||||
<div className="w-1.5 h-1.5 bg-[var(--color-brand-primary)] rounded-full" />
|
||||
<span className="text-[var(--color-text-primary)] text-sm">{spec}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="bg-[var(--color-brand-primary-bg)] rounded-2xl p-8 md:p-10" aria-labelledby="product-pricing">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-12 h-12 bg-[var(--color-brand-primary)] rounded-xl flex items-center justify-center shrink-0">
|
||||
<FlaskConical className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 id="product-pricing" className="text-2xl font-bold text-[var(--color-text-primary)] mb-3">定价待公布</h2>
|
||||
<p className="text-[var(--color-text-muted)] leading-relaxed mb-6">
|
||||
本产品正在研发中,正式定价将在产品发布时公布。如果您对产品方向感兴趣,欢迎预约早期体验,您的反馈将帮助我们打造更贴合需求的产品。
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Button size="lg" className="bg-[var(--color-brand-primary)] hover:bg-[var(--color-brand-primary-hover)] text-white" asChild>
|
||||
<StaticLink href="/contact">
|
||||
预约体验
|
||||
<ArrowRight className="ml-2 w-4 h-4" />
|
||||
</StaticLink>
|
||||
</Button>
|
||||
<Button variant="outline" size="lg" asChild>
|
||||
<StaticLink href="/contact">关注进展</StaticLink>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="flex justify-center gap-4 pt-8 border-t border-[var(--color-border-primary)]">
|
||||
<Button variant="outline" size="lg" asChild>
|
||||
<StaticLink href="/contact">关注进展</StaticLink>
|
||||
</Button>
|
||||
<Button size="lg" className="bg-[var(--color-brand-primary)] hover:bg-[var(--color-brand-primary-hover)] text-white" asChild>
|
||||
<StaticLink href="/contact">
|
||||
预约体验
|
||||
<ArrowRight className="ml-2 w-4 h-4" />
|
||||
</StaticLink>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<CrossRecommendGrid items={crossRefs} title={`与 ${product.title} 相关的推荐`} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import { Metadata } from 'next';
|
||||
import { PRODUCTS, COMPANY_INFO } from '@/lib/constants';
|
||||
import { getHeroTheme } from '@/lib/constants/hero-themes';
|
||||
import { getProductCrossRefs } from '@/lib/constants/cross-references';
|
||||
import { DetailSwipeNav } from '@/components/ui/detail-swipe-nav';
|
||||
import { DetailHeroV3 } from '@/components/detail-v2/detail-hero-v3';
|
||||
import { ProductValueSectionV3 } from '@/components/detail-v2/detail-product-value-v3';
|
||||
import { DetailTrustSectionV2 } from '@/components/detail-v2/detail-trust-section-v2';
|
||||
import { DetailCTASectionV2 } from '@/components/detail-v2/detail-cta-section-v2';
|
||||
import { CrossRecommendGrid } from '@/components/detail/detail-cross-recommend';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: `睿新ERP管理系统(V3深度精细化版) - ${COMPANY_INFO.displayName}`,
|
||||
description: 'ERP产品页V3版本 - 现代东方美学设计系统 + L1-L5全层次精细化打磨',
|
||||
};
|
||||
|
||||
export default function ERPUpgradeV3Page() {
|
||||
const product = PRODUCTS.find((p) => p.id === 'erp')!;
|
||||
|
||||
const theme = getHeroTheme(product.heroThemeId);
|
||||
const crossRefs = getProductCrossRefs(product.id);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[var(--color-bg-primary)]">
|
||||
<DetailSwipeNav type="product" currentId={product.id} />
|
||||
|
||||
<DetailHeroV3
|
||||
theme={theme}
|
||||
badge="企业旗舰系列"
|
||||
title={product.title}
|
||||
subtitle={product.description}
|
||||
description={product.overview}
|
||||
primaryAction={{ label: '预约体验', href: '/contact' }}
|
||||
secondaryAction={{ label: '查看方案', href: '/solutions' }}
|
||||
/>
|
||||
|
||||
<ProductValueSectionV3 product={product} />
|
||||
|
||||
<DetailTrustSectionV2
|
||||
caseStudies={product.caseStudies}
|
||||
dataProofs={product.dataProofs}
|
||||
certifications={product.certifications}
|
||||
accentColor={theme.accentColor}
|
||||
/>
|
||||
|
||||
<DetailCTASectionV2
|
||||
theme={theme}
|
||||
title={`探索 ${product.title} 的无限可能`}
|
||||
description="立即联系我们,获取专属方案和报价"
|
||||
primaryAction={{ label: '预约体验', href: '/contact' }}
|
||||
secondaryAction={{ label: '下载产品手册', href: '#' }}
|
||||
/>
|
||||
|
||||
<CrossRecommendGrid items={crossRefs} title={`与 ${product.title} 相关的推荐`} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { Metadata } from 'next';
|
||||
import { PRODUCTS, COMPANY_INFO } from '@/lib/constants';
|
||||
import { getHeroTheme } from '@/lib/constants/hero-themes';
|
||||
import { getProductCrossRefs } from '@/lib/constants/cross-references';
|
||||
import { DetailSwipeNav } from '@/components/ui/detail-swipe-nav';
|
||||
import { DetailHeroV2 } from '@/components/detail-v2/detail-hero-v2';
|
||||
import { ProductValueSectionV2 } from '@/components/detail-v2/detail-product-value-v2';
|
||||
import { DetailTrustSectionV2 } from '@/components/detail-v2/detail-trust-section-v2';
|
||||
import { DetailCTASectionV2 } from '@/components/detail-v2/detail-cta-section-v2';
|
||||
import { CrossRecommendGrid } from '@/components/detail/detail-cross-recommend';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: `睿新ERP管理系统(升级版原型) - ${COMPANY_INFO.displayName}`,
|
||||
description: '升级版ERP产品页 - 现代东方美学设计系统',
|
||||
};
|
||||
|
||||
export default function ERPUpgradePage() {
|
||||
const product = PRODUCTS.find((p) => p.id === 'erp')!;
|
||||
|
||||
const theme = getHeroTheme(product.heroThemeId);
|
||||
const crossRefs = getProductCrossRefs(product.id);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[var(--color-bg-primary)]">
|
||||
<DetailSwipeNav type="product" currentId={product.id} />
|
||||
|
||||
<DetailHeroV2
|
||||
theme={theme}
|
||||
badge="企业旗舰系列"
|
||||
title={product.title}
|
||||
subtitle={product.description}
|
||||
description={product.overview}
|
||||
primaryAction={{ label: '预约体验', href: '/contact' }}
|
||||
secondaryAction={{ label: '查看方案', href: '/solutions' }}
|
||||
/>
|
||||
|
||||
<ProductValueSectionV2 product={product} />
|
||||
|
||||
<DetailTrustSectionV2
|
||||
caseStudies={product.caseStudies}
|
||||
dataProofs={product.dataProofs}
|
||||
certifications={product.certifications}
|
||||
accentColor={theme.accentColor}
|
||||
/>
|
||||
|
||||
<DetailCTASectionV2
|
||||
theme={theme}
|
||||
title={`探索 ${product.title} 的无限可能`}
|
||||
description="立即联系我们,获取专属方案和报价"
|
||||
primaryAction={{ label: '预约体验', href: '/contact' }}
|
||||
secondaryAction={{ label: '下载产品手册', href: '#' }}
|
||||
/>
|
||||
|
||||
<CrossRecommendGrid items={crossRefs} title={`与 ${product.title} 相关的推荐`} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,63 +1,168 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { PRODUCTS } from '@/lib/constants';
|
||||
import { ProductCard } from '@/components/ui/product-card';
|
||||
import { useState, useEffect, useMemo } from 'react';
|
||||
import { PRODUCTS, PRODUCT_CATEGORIES, type ProductCategory as ProductCategoryType } from '@/lib/constants';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useReducedMotion } from '@/hooks/use-reduced-motion';
|
||||
import { PageNav } from '@/components/layout/page-nav';
|
||||
import { CTASection } from '@/components/sections/cta-section';
|
||||
import { BreadcrumbSchema } from '@/components/seo/structured-data';
|
||||
import { LoadingState } from '@/components/ui/loading-state';
|
||||
import { ListPageHeroV3 } from '@/components/detail-v2/list-page-hero-v3';
|
||||
import { ProductCardV3 } from '@/components/detail-v2/product-card-v3';
|
||||
import { Package, Lock, Cpu, ArrowRight } from 'lucide-react';
|
||||
|
||||
const enterpriseProducts = PRODUCTS.filter(p => p.categoryId === 'enterprise');
|
||||
const specializedProducts = PRODUCTS.filter(p => p.categoryId === 'specialized');
|
||||
|
||||
export default function ProductsPage() {
|
||||
const shouldReduceMotion = useReducedMotion();
|
||||
const fadeUp = shouldReduceMotion ? {} : { initial: { opacity: 0, y: 20 } };
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [activeCategory, setActiveCategory] = useState<string>('all');
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => setIsLoading(false), 500);
|
||||
return () => clearTimeout(timer);
|
||||
}, []);
|
||||
|
||||
const filteredProducts = useMemo(() => {
|
||||
if (activeCategory === 'all') return PRODUCTS;
|
||||
return PRODUCTS.filter(product => product.categoryId === activeCategory);
|
||||
}, [activeCategory]);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[var(--color-bg-primary)]">
|
||||
<BreadcrumbSchema items={[{ name: '首页', href: '/' }, { name: '产品', href: '/products' }]} />
|
||||
<section className="pt-32 pb-16">
|
||||
|
||||
{/* Hero 区域 (V3) */}
|
||||
<ListPageHeroV3
|
||||
title="企业软件产品矩阵"
|
||||
subtitle="从ERP到BI,覆盖企业数字化全场景"
|
||||
description="六大核心产品互为补充,可根据业务需求灵活组合"
|
||||
stats={[
|
||||
{ value: '6', label: '核心产品' },
|
||||
{ value: '2', label: '产品分区' },
|
||||
{ value: '99%', label: '自主可控' },
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* 双区展示:企业套装 + 专业产品 */}
|
||||
<section className="pb-16">
|
||||
<div className="container-wide">
|
||||
<PageNav items={[{ label: '产品' }]} />
|
||||
{/* 企业套装区域 */}
|
||||
<motion.div
|
||||
{...fadeUp}
|
||||
animate={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="max-w-3xl"
|
||||
className="mb-16"
|
||||
>
|
||||
<p className="text-sm font-medium text-[var(--color-brand-primary)] mb-4 tracking-wide uppercase">Products</p>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-[var(--color-text-primary)] mb-6 tracking-tight">
|
||||
产品
|
||||
</h1>
|
||||
<p className="text-lg text-[var(--color-text-muted)] leading-relaxed">
|
||||
我们正在打造的企业级产品,致力于助力企业高效运营,实现数字化转型
|
||||
<div className="mb-8 flex items-center gap-3">
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-xl bg-blue-50">
|
||||
<Package className="h-5 w-5 text-blue-600" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-xl font-bold text-gray-900">企业套装</h2>
|
||||
<p className="text-sm text-gray-500">6 大核心产品互为补充,覆盖企业数字化全场景</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<LoadingState isLoading={isLoading} variant="card">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{enterpriseProducts.map((product) => (
|
||||
<ProductCardV3 key={product.id} product={product} />
|
||||
))}
|
||||
</div>
|
||||
</LoadingState>
|
||||
</motion.div>
|
||||
|
||||
{/* 专业产品区域 */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5, delay: 0.15 }}
|
||||
>
|
||||
<div className="mb-8 flex items-center gap-3">
|
||||
<div className="flex h-10 w-10 items-center justify-center rounded-xl bg-orange-50">
|
||||
<Cpu className="h-5 w-5 text-orange-600" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-xl font-bold text-gray-900">专业产品</h2>
|
||||
<p className="text-sm text-gray-500">自成体系的独立产品线</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{specializedProducts.length > 0 ? (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{specializedProducts.map((product) => (
|
||||
<ProductCardV3 key={product.id} product={product} />
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="rounded-2xl border-2 border-dashed border-gray-200 bg-gray-50/50 p-12 text-center">
|
||||
<Lock className="mx-auto mb-4 h-12 w-12 text-gray-300" />
|
||||
<h3 className="mb-2 text-lg font-semibold text-gray-700">独立产品即将上线</h3>
|
||||
<p className="mb-6 max-w-md mx-auto text-sm text-gray-500">
|
||||
安全产品、特种行业软件、硬件产品等独立产品线正在规划中,
|
||||
敬请期待。如有需求可提前联系我们。
|
||||
</p>
|
||||
<a
|
||||
href="/contact"
|
||||
className="inline-flex items-center gap-2 rounded-lg bg-[#C41E3A] px-6 py-3 text-sm font-semibold text-white shadow-lg transition-all hover:bg-[#a01829] hover:shadow-xl"
|
||||
>
|
||||
联系我们了解详情
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="pb-20">
|
||||
{/* 分类标签导航(保留作为辅助筛选) */}
|
||||
<section className="border-t border-gray-100 bg-gray-50/50 py-12">
|
||||
<div className="container-wide">
|
||||
<LoadingState isLoading={isLoading} variant="card">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{PRODUCTS.map((product, index) => (
|
||||
<ProductCard
|
||||
key={product.id}
|
||||
title={product.title}
|
||||
description={product.description}
|
||||
href={`/products/${product.id}`}
|
||||
index={index}
|
||||
status={product.status}
|
||||
/>
|
||||
<h3 className="mb-6 text-center text-lg font-semibold text-gray-900">按分类浏览</h3>
|
||||
<div className="flex flex-wrap justify-center gap-2">
|
||||
<button
|
||||
onClick={() => setActiveCategory('all')}
|
||||
className={`px-5 py-2.5 text-sm font-medium rounded-full transition-all ${
|
||||
activeCategory === 'all'
|
||||
? 'bg-[#C41E3A] text-white shadow-md'
|
||||
: 'bg-white text-gray-600 border border-gray-200 hover:border-gray-300'
|
||||
}`}
|
||||
>
|
||||
全部 ({PRODUCTS.length})
|
||||
</button>
|
||||
{PRODUCT_CATEGORIES.map((category: ProductCategoryType) => {
|
||||
const count = PRODUCTS.filter(p => p.categoryId === category.id).length;
|
||||
return (
|
||||
<button
|
||||
key={category.id}
|
||||
onClick={() => setActiveCategory(category.id)}
|
||||
className={`px-5 py-2.5 text-sm font-medium rounded-full transition-all ${
|
||||
activeCategory === category.id
|
||||
? 'bg-[#C41E3A] text-white shadow-md'
|
||||
: 'bg-white text-gray-600 border border-gray-200 hover:border-gray-300'
|
||||
}`}
|
||||
>
|
||||
{category.title} ({count})
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{activeCategory !== 'all' && filteredProducts.length > 0 && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
className="mt-8"
|
||||
>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{filteredProducts.map((product) => (
|
||||
<ProductCardV3 key={product.id} product={product} />
|
||||
))}
|
||||
</div>
|
||||
</LoadingState>
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -72,3 +177,4 @@ export default function ProductsPage() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
'use client';
|
||||
|
||||
import { getHeroTheme } from '@/lib/constants/hero-themes';
|
||||
import { DetailHeroV3 } from '@/components/detail-v2/detail-hero-v3';
|
||||
import { DetailTrustSectionV2 } from '@/components/detail-v2/detail-trust-section-v2';
|
||||
import { DetailCTASectionV2 } from '@/components/detail-v2/detail-cta-section-v2';
|
||||
import { DetailSwipeNav } from '@/components/ui/detail-swipe-nav';
|
||||
import { motion } from 'framer-motion';
|
||||
import { CheckCircle2, Clock, Shield, Lock, Cpu, HardDrive, ArrowRight } from 'lucide-react';
|
||||
import type { StandaloneProduct } from '@/lib/constants/standalone-products';
|
||||
|
||||
interface StandaloneProductClientProps {
|
||||
product: StandaloneProduct;
|
||||
}
|
||||
|
||||
const categoryIcons: Record<string, typeof Shield> = {
|
||||
security: Shield,
|
||||
'specialized-software': Cpu,
|
||||
hardware: HardDrive,
|
||||
};
|
||||
|
||||
export function StandaloneProductClient({ product }: StandaloneProductClientProps) {
|
||||
const theme = getHeroTheme(product.heroThemeId);
|
||||
const Icon = categoryIcons[product.category] || Shield;
|
||||
|
||||
return (
|
||||
<div className="min-h-screen">
|
||||
<DetailSwipeNav type="product" currentId={product.id} />
|
||||
|
||||
<DetailHeroV3
|
||||
theme={theme}
|
||||
badge={product.status === 'coming-soon' ? '敬请期待' : product.badge}
|
||||
title={product.title}
|
||||
subtitle={product.description}
|
||||
primaryAction={
|
||||
product.status === 'coming-soon'
|
||||
? undefined
|
||||
: { label: '了解详情', href: '/contact' }
|
||||
}
|
||||
secondaryAction={{ label: '返回产品列表', href: '/products' }}
|
||||
/>
|
||||
|
||||
{product.status === 'coming-soon' ? (
|
||||
<section className="bg-white py-16 lg:py-20">
|
||||
<div className="container-wide">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="max-w-3xl mx-auto text-center"
|
||||
>
|
||||
<div className="mb-6 flex justify-center">
|
||||
<div className="flex h-20 w-20 items-center justify-center rounded-2xl bg-gray-100 text-gray-400">
|
||||
<Lock className="h-10 w-10" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 className="mb-4 text-2xl font-bold text-gray-900">产品即将上线</h2>
|
||||
<p className="mb-8 text-gray-600 leading-relaxed">
|
||||
{product.title}正在紧张开发中,我们将为您带来更专业的{product.category === 'security' ? '安全防护' : product.category === 'specialized-software' ? '行业解决方案' : '硬件产品'}体验。
|
||||
</p>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 mb-10">
|
||||
{product.previewFeatures.map((feature, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: index * 0.08 }}
|
||||
className="rounded-lg border border-gray-200 bg-gray-50 p-4"
|
||||
>
|
||||
<div className="mb-2 flex h-8 w-8 items-center justify-center rounded-lg bg-white text-gray-400">
|
||||
<Icon className="h-4 w-4" />
|
||||
</div>
|
||||
<h3 className="mb-1 text-sm font-semibold text-gray-900">{feature.title}</h3>
|
||||
<p className="text-xs leading-relaxed text-gray-500">{feature.description}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
|
||||
<a
|
||||
href="/contact"
|
||||
className="inline-flex items-center gap-2 rounded-lg bg-[#C41E3A] px-8 py-3 text-sm font-semibold text-white shadow-md transition-all hover:bg-[#C41E3A]/90 hover:shadow-lg"
|
||||
>
|
||||
获取上线通知
|
||||
<ArrowRight className="h-4 w-4" />
|
||||
</a>
|
||||
<a
|
||||
href="/products"
|
||||
className="inline-flex items-center rounded-lg border border-gray-300 px-6 py-3 text-sm font-semibold text-gray-700 transition-all hover:border-gray-400 hover:bg-gray-50"
|
||||
>
|
||||
查看其他产品
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{product.expectedLaunch && (
|
||||
<p className="mt-6 text-sm text-gray-500">
|
||||
预计上线时间:<span className="font-medium text-gray-700">{product.expectedLaunch}</span>
|
||||
</p>
|
||||
)}
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
) : (
|
||||
<>
|
||||
<section className="bg-white py-16 lg:py-20">
|
||||
<div className="container-wide">
|
||||
<div className="grid grid-cols-1 gap-12 lg:grid-cols-2">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5 }}
|
||||
>
|
||||
<h2 className="mb-6 text-2xl font-bold text-gray-900">核心能力</h2>
|
||||
<ul className="space-y-3">
|
||||
{(product.features ?? []).map((feature, index) => (
|
||||
<motion.li
|
||||
key={index}
|
||||
initial={{ opacity: 0, x: -10 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: index * 0.05 }}
|
||||
className="flex items-start gap-3"
|
||||
>
|
||||
<CheckCircle2 className="mt-0.5 h-5 w-5 shrink-0 text-[#C41E3A]" />
|
||||
<span className="text-sm leading-relaxed text-gray-700">{feature}</span>
|
||||
</motion.li>
|
||||
))}
|
||||
</ul>
|
||||
</motion.div>
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5, delay: 0.15 }}
|
||||
>
|
||||
<h2 className="mb-6 flex items-center gap-2 text-2xl font-bold text-gray-900">
|
||||
<Clock className="h-5 w-5 text-[#C41E3A]" />
|
||||
适用场景
|
||||
</h2>
|
||||
<div className="space-y-4">
|
||||
{(product.useCases ?? []).map((useCase, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, y: 10 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.3, delay: index * 0.06 }}
|
||||
className="rounded-lg border border-red-50 bg-red-50/30 p-4"
|
||||
>
|
||||
<h3 className="mb-1 text-sm font-semibold text-gray-900">{useCase.title}</h3>
|
||||
<p className="text-xs leading-relaxed text-gray-600">{useCase.description}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<DetailTrustSectionV2 accentColor={theme.accentColor} />
|
||||
|
||||
<DetailCTASectionV2
|
||||
theme={theme}
|
||||
title={`了解更多关于${product.title}`}
|
||||
description="联系我们,获取详细的产品资料和方案报价"
|
||||
primaryAction={{ label: '预约演示', href: '/contact' }}
|
||||
secondaryAction={{ label: '下载产品手册', href: '#' }}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Metadata } from 'next';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { STANDALONE_PRODUCTS } from '@/lib/constants/standalone-products';
|
||||
import { StandaloneProductClient } from './client';
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return STANDALONE_PRODUCTS.map((product) => ({
|
||||
id: product.id,
|
||||
}));
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: { params: Promise<{ id: string }> }): Promise<Metadata> {
|
||||
const { id } = await params;
|
||||
const product = STANDALONE_PRODUCTS.find((p) => p.id === id);
|
||||
|
||||
if (!product) {
|
||||
return {
|
||||
title: '产品未找到',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
title: `${product.title} - ${process.env.NEXT_PUBLIC_COMPANY_NAME || 'Novalon'}`,
|
||||
description: product.description,
|
||||
};
|
||||
}
|
||||
|
||||
export default async function StandaloneProductPage({ params }: { params: Promise<{ id: string }> }) {
|
||||
const { id } = await params;
|
||||
const product = STANDALONE_PRODUCTS.find((p) => p.id === id);
|
||||
|
||||
if (!product) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
return <StandaloneProductClient product={JSON.parse(JSON.stringify(product))} />;
|
||||
}
|
||||
@@ -1,196 +1,57 @@
|
||||
'use client';
|
||||
|
||||
import { StaticLink } from '@/components/ui/static-link';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { PageNav } from '@/components/layout/page-nav';
|
||||
import { getHeroTheme } from '@/lib/constants/hero-themes';
|
||||
import { getServiceCrossRefs } from '@/lib/constants/cross-references';
|
||||
import { DetailHeroV3 } from '@/components/detail-v2/detail-hero-v3';
|
||||
import { ServiceValueSectionV3 } from '@/components/detail-v2/service-value-v3';
|
||||
import { DetailTrustSectionV2 } from '@/components/detail-v2/detail-trust-section-v2';
|
||||
import { DetailCTASectionV2 } from '@/components/detail-v2/detail-cta-section-v2';
|
||||
import { CrossRecommendGrid } from '@/components/detail/detail-cross-recommend';
|
||||
import { DetailSwipeNav } from '@/components/ui/detail-swipe-nav';
|
||||
import {
|
||||
CheckCircle2,
|
||||
TrendingUp,
|
||||
Target,
|
||||
Clock,
|
||||
MessageCircle,
|
||||
ArrowRight,
|
||||
} from 'lucide-react';
|
||||
import { SERVICES } from '@/lib/constants';
|
||||
import type { Service } from '@/lib/constants/services';
|
||||
|
||||
interface ServiceDetailClientProps {
|
||||
service: typeof SERVICES[number];
|
||||
service: Service;
|
||||
}
|
||||
|
||||
const challenges: Record<string, { title: string; description: string }[]> = {
|
||||
software: [
|
||||
{ title: '需求不明确', description: '业务部门提不出清晰需求,开发团队反复返工' },
|
||||
{ title: '技术选型困难', description: '技术栈更新快,不知道该选什么技术方案' },
|
||||
{ title: '项目延期', description: '开发进度难以把控,上线时间一拖再拖' },
|
||||
{ title: '维护成本高', description: '系统上线后问题不断,运维压力巨大' },
|
||||
],
|
||||
data: [
|
||||
{ title: '数据孤岛', description: '各系统数据分散,无法整合分析' },
|
||||
{ title: '决策盲区', description: '缺乏数据支撑,决策凭感觉' },
|
||||
{ title: '报表滞后', description: '手工制作报表,时效性差' },
|
||||
{ title: '价值难挖', description: '数据很多,但不知道怎么用' },
|
||||
],
|
||||
consulting: [
|
||||
{ title: '方向不明', description: '数字化转型不知道从哪里入手' },
|
||||
{ title: '技术债务', description: '历史系统包袱重,新技术难以引入' },
|
||||
{ title: '人才短缺', description: '缺乏专业的技术规划和架构人才' },
|
||||
{ title: '投入浪费', description: 'IT投入不少,但看不到明显效果' },
|
||||
],
|
||||
solutions: [
|
||||
{ title: '行业壁垒', description: '不了解行业最佳实践,走弯路' },
|
||||
{ title: '方案碎片化', description: '各系统各自为政,无法协同' },
|
||||
{ title: '实施风险', description: '大型项目实施失败率高' },
|
||||
{ title: '效果难量化', description: '投入产出比不清晰,难以评估' },
|
||||
],
|
||||
};
|
||||
|
||||
const outcomes: Record<string, { value: string; label: string }[]> = {
|
||||
software: [
|
||||
{ value: '30%+', label: '预期开发效率提升' },
|
||||
{ value: '50%+', label: '预期返工率降低' },
|
||||
{ value: '严格', label: '交付质量把控' },
|
||||
],
|
||||
data: [
|
||||
{ value: '实时', label: '数据更新' },
|
||||
{ value: '自助式', label: '分析模式' },
|
||||
{ value: '多维度', label: '可视化报表' },
|
||||
],
|
||||
consulting: [
|
||||
{ value: '清晰', label: '转型方向规划' },
|
||||
{ value: '系统化', label: '技术选型评估' },
|
||||
{ value: '可落地', label: '实施路径设计' },
|
||||
],
|
||||
solutions: [
|
||||
{ value: '标准化', label: '行业方案交付' },
|
||||
{ value: '端到端', label: '全流程实施' },
|
||||
{ value: '持续化', label: '运维优化支持' },
|
||||
],
|
||||
};
|
||||
|
||||
export function ServiceDetailClient({ service }: ServiceDetailClientProps) {
|
||||
const serviceChallenges = challenges[service.id] ?? [];
|
||||
const serviceOutcomes = outcomes[service.id] ?? [];
|
||||
const theme = getHeroTheme(service.heroThemeId);
|
||||
const crossRefs = getServiceCrossRefs(service.id);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[var(--color-bg-primary)]">
|
||||
<DetailSwipeNav type="service" currentId={service.id} />
|
||||
<div className="pt-32 pb-16">
|
||||
<div className="container-wide">
|
||||
<PageNav items={[{ label: '服务', href: '/services' }, { label: service.title }]} />
|
||||
<div className="max-w-4xl mt-8">
|
||||
<p className="text-sm font-medium text-[var(--color-brand-primary)] mb-4 tracking-wide uppercase">Services</p>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-[var(--color-text-primary)] mb-6 tracking-tight">
|
||||
{service.title}
|
||||
</h1>
|
||||
<p className="text-xl text-[var(--color-text-muted)] leading-relaxed">
|
||||
{service.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="container-wide pb-20">
|
||||
<div className="max-w-4xl space-y-16">
|
||||
<section>
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-10 h-10 bg-[var(--color-brand-primary-bg)] rounded-lg flex items-center justify-center">
|
||||
<MessageCircle className="w-5 h-5 text-[var(--color-brand-primary)]" />
|
||||
</div>
|
||||
<h2 className="text-2xl font-bold text-[var(--color-text-primary)]">您可能面临的挑战</h2>
|
||||
</div>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
{serviceChallenges.map((challenge, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="p-4 bg-[var(--color-bg-tertiary)] rounded-lg border border-[var(--color-border-primary)] hover:border-[var(--color-brand-primary)]/30 hover:bg-[var(--color-brand-primary-bg)] transition-colors"
|
||||
>
|
||||
<h3 className="font-semibold text-[var(--color-text-primary)] mb-1 text-sm">{challenge.title}</h3>
|
||||
<p className="text-sm text-[var(--color-text-muted)]">{challenge.description}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
{/* L1 - Hero 情感入口 (V3) */}
|
||||
<DetailHeroV3
|
||||
theme={theme}
|
||||
badge="专业服务"
|
||||
title={service.title}
|
||||
subtitle={service.description}
|
||||
primaryAction={{ label: '立即咨询', href: '/contact' }}
|
||||
secondaryAction={{ label: '查看案例', href: '/cases' }}
|
||||
/>
|
||||
|
||||
<section>
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-10 h-10 bg-[var(--color-brand-primary-bg)] rounded-lg flex items-center justify-center">
|
||||
<Target className="w-5 h-5 text-[var(--color-brand-primary)]" />
|
||||
</div>
|
||||
<h2 className="text-2xl font-bold text-[var(--color-text-primary)]">我们如何帮助您</h2>
|
||||
</div>
|
||||
<p className="text-lg text-[var(--color-text-muted)] leading-relaxed mb-6">
|
||||
{service.overview}
|
||||
</p>
|
||||
<div className="space-y-3">
|
||||
{service.features.map((feature, index) => (
|
||||
<div key={index} className="flex items-start gap-3">
|
||||
<CheckCircle2 className="w-5 h-5 text-[var(--color-brand-primary)] mt-0.5 shrink-0" />
|
||||
<span className="text-[var(--color-text-primary)] text-sm">{feature}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
{/* L2 - 价值理性支撑 (V3) */}
|
||||
<ServiceValueSectionV3 service={service} />
|
||||
|
||||
<section>
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-10 h-10 bg-[var(--color-brand-primary-bg)] rounded-lg flex items-center justify-center">
|
||||
<Clock className="w-5 h-5 text-[var(--color-brand-primary)]" />
|
||||
</div>
|
||||
<h2 className="text-2xl font-bold text-[var(--color-text-primary)]">服务流程</h2>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
{service.process.map((step, index) => (
|
||||
<div key={index} className="flex items-start gap-4">
|
||||
<div className="w-8 h-8 bg-[var(--color-brand-primary)] rounded-full flex items-center justify-center shrink-0 text-white text-sm font-bold">
|
||||
{index + 1}
|
||||
</div>
|
||||
<p className="text-[var(--color-text-primary)] pt-1">{step}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
{/* L3 - 信任证明 (V2) */}
|
||||
<DetailTrustSectionV2
|
||||
caseStudies={service.caseStudies}
|
||||
dataProofs={service.dataProofs}
|
||||
accentColor={theme.accentColor}
|
||||
/>
|
||||
|
||||
<section>
|
||||
<div className="flex items-center gap-3 mb-6">
|
||||
<div className="w-10 h-10 bg-[var(--color-brand-primary-bg)] rounded-lg flex items-center justify-center">
|
||||
<TrendingUp className="w-5 h-5 text-[var(--color-brand-primary)]" />
|
||||
</div>
|
||||
<h2 className="text-2xl font-bold text-[var(--color-text-primary)]">您将获得的改变</h2>
|
||||
</div>
|
||||
<div className="grid sm:grid-cols-3 gap-4">
|
||||
{serviceOutcomes.map((outcome, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="p-6 bg-[var(--color-bg-tertiary)] rounded-lg text-center hover:bg-[var(--color-brand-primary-bg)] transition-colors"
|
||||
>
|
||||
<div className="text-3xl font-bold text-[var(--color-brand-primary)] mb-2">
|
||||
{outcome.value}
|
||||
</div>
|
||||
<div className="text-sm text-[var(--color-text-muted)]">{outcome.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-4 p-4 bg-[var(--color-bg-tertiary)] rounded-lg">
|
||||
<p className="text-sm text-[var(--color-text-muted)]">
|
||||
{service.benefits.join(';')}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
{/* L4 - CTA转化 (V2) */}
|
||||
<DetailCTASectionV2
|
||||
theme={theme}
|
||||
title={`准备好开始${service.title}了吗?`}
|
||||
description="联系我们,获取专属方案和报价"
|
||||
primaryAction={{ label: '预约咨询', href: '/contact' }}
|
||||
secondaryAction={{ label: '了解更多服务', href: '/services' }}
|
||||
/>
|
||||
|
||||
<div className="flex justify-center gap-4 pt-8 border-t border-[var(--color-border-primary)]">
|
||||
<StaticLink href="/services">
|
||||
<Button variant="outline" size="lg">查看其他服务</Button>
|
||||
</StaticLink>
|
||||
<StaticLink href="/contact">
|
||||
<Button size="lg" className="bg-[var(--color-brand-primary)] hover:bg-[var(--color-brand-primary-hover)] text-white">
|
||||
开始您的转型之旅
|
||||
<ArrowRight className="ml-2 w-4 h-4" />
|
||||
</Button>
|
||||
</StaticLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<CrossRecommendGrid items={crossRefs} title="相关解决方案" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@ import { useState, useEffect } from 'react';
|
||||
import { SERVICES } from '@/lib/constants';
|
||||
import { StaticLink } from '@/components/ui/static-link';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { ArrowRight, ArrowUpRight } from 'lucide-react';
|
||||
import { ArrowRight } from 'lucide-react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useReducedMotion } from '@/hooks/use-reduced-motion';
|
||||
import { PageNav } from '@/components/layout/page-nav';
|
||||
import { LoadingState } from '@/components/ui/loading-state';
|
||||
import { ListPageHeroV3 } from '@/components/detail-v2/list-page-hero-v3';
|
||||
import { ServiceCardV3 } from '@/components/detail-v2/solution-service-card-v3';
|
||||
|
||||
export default function ServicesPage() {
|
||||
const shouldReduceMotion = useReducedMotion();
|
||||
@@ -19,75 +20,72 @@ export default function ServicesPage() {
|
||||
const timer = setTimeout(() => setIsLoading(false), 500);
|
||||
return () => clearTimeout(timer);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[var(--color-bg-primary)]">
|
||||
<section className="pt-32 pb-16">
|
||||
<div className="container-wide">
|
||||
<PageNav items={[{ label: '服务' }]} />
|
||||
<motion.div
|
||||
{...fadeUp}
|
||||
animate={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="max-w-3xl"
|
||||
>
|
||||
<p className="text-sm font-medium text-[var(--color-brand-primary)] mb-4 tracking-wide uppercase">Services</p>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-[var(--color-text-primary)] mb-6 tracking-tight">
|
||||
服务
|
||||
</h1>
|
||||
<p className="text-lg text-[var(--color-text-muted)] leading-relaxed">
|
||||
专业技术团队,为您提供全方位的数字化解决方案
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
{/* Hero 区域 (V3) */}
|
||||
<ListPageHeroV3
|
||||
title="专业服务"
|
||||
subtitle="从咨询规划到落地实施,全生命周期数字化支持"
|
||||
description="提供咨询、开发、数据、解决方案等全方位服务"
|
||||
stats={[
|
||||
{ value: '4', label: '服务类型' },
|
||||
{ value: '7×24', label: '响应时间' },
|
||||
{ value: '100%', label: '客户满意' },
|
||||
]}
|
||||
/>
|
||||
|
||||
<section className="pb-20">
|
||||
<section className="pb-16">
|
||||
<div className="container-wide">
|
||||
<LoadingState isLoading={isLoading} variant="card">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{SERVICES.map((service, index) => (
|
||||
<motion.div
|
||||
key={service.id}
|
||||
{...fadeUp}
|
||||
whileInView={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.4, delay: index * 0.1, ease: [0.16, 1, 0.3, 1] }}
|
||||
>
|
||||
<StaticLink
|
||||
href={`/services/${service.id}`}
|
||||
className="group block p-6 rounded-xl border border-[var(--color-border-primary)] bg-[var(--color-bg-primary)] hover:border-[var(--color-brand-primary)]/40 hover:shadow-lg transition-all duration-300 h-full"
|
||||
>
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<span className="inline-flex items-center justify-center w-10 h-10 rounded-lg bg-[var(--color-brand-primary-bg)] text-[var(--color-brand-primary)] text-sm font-bold">
|
||||
{String(index + 1).padStart(2, '0')}
|
||||
</span>
|
||||
<ArrowUpRight className="w-5 h-5 text-[var(--color-text-muted)] group-hover:text-[var(--color-brand-primary)] transition-colors" />
|
||||
</div>
|
||||
<h3 className="text-lg font-semibold text-[var(--color-text-primary)] mb-2 group-hover:text-[var(--color-brand-primary)] transition-colors">
|
||||
{service.title}
|
||||
</h3>
|
||||
<p className="text-sm text-[var(--color-text-muted)] leading-relaxed mb-4">
|
||||
{service.description}
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{service.features.slice(0, 3).map((feature, idx) => (
|
||||
<span
|
||||
key={idx}
|
||||
className="inline-flex items-center text-xs px-2 py-1 bg-[var(--color-bg-tertiary)] text-[var(--color-text-muted)] rounded"
|
||||
>
|
||||
{feature.split(':')[0]}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</StaticLink>
|
||||
</motion.div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
{SERVICES.map((service) => (
|
||||
<ServiceCardV3 key={service.id} service={service} />
|
||||
))}
|
||||
</div>
|
||||
</LoadingState>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="bg-[var(--color-bg-tertiary)] py-20">
|
||||
{/* 服务流程概览 */}
|
||||
<section className="bg-gray-50/50 py-16">
|
||||
<div className="container-wide">
|
||||
<motion.h2
|
||||
{...fadeUp}
|
||||
whileInView={{ opacity: 1 }}
|
||||
viewport={{ once: true }}
|
||||
className="mb-10 max-w-2xl text-center text-2xl font-bold text-gray-900 lg:text-3xl"
|
||||
>
|
||||
我们的服务流程
|
||||
</motion.h2>
|
||||
|
||||
<div className="mx-auto grid max-w-4xl grid-cols-1 gap-8 md:grid-cols-4">
|
||||
{[
|
||||
{ step: '01', title: '需求分析', desc: '深入了解业务场景与痛点' },
|
||||
{ step: '02', title: '方案设计', desc: '量身定制技术解决方案' },
|
||||
{ step: '03', title: '敏捷交付', desc: '快速迭代,持续优化' },
|
||||
{ step: '04', title: '持续支持', desc: '长期陪伴,随时响应' },
|
||||
].map((item, index) => (
|
||||
<motion.div
|
||||
key={item.step}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.4, delay: index * 0.1 }}
|
||||
className="text-center"
|
||||
>
|
||||
<div className="mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-full bg-[#C41E3A] text-lg font-bold text-white shadow-md">
|
||||
{item.step}
|
||||
</div>
|
||||
<h3 className="mb-2 text-base font-semibold text-gray-900">{item.title}</h3>
|
||||
<p className="text-sm text-gray-500">{item.desc}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="py-20">
|
||||
<div className="container-wide text-center">
|
||||
<h2 className="text-3xl font-bold text-[var(--color-text-primary)] mb-6">
|
||||
准备开始您的数字化转型之旅?
|
||||
|
||||
@@ -1,151 +1,59 @@
|
||||
'use client';
|
||||
|
||||
import { motion } from 'framer-motion';
|
||||
import { useReducedMotion } from '@/hooks/use-reduced-motion';
|
||||
import { StaticLink } from '@/components/ui/static-link';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { PageNav } from '@/components/layout/page-nav';
|
||||
import { ArrowRight, AlertTriangle, CheckCircle2, Package } from 'lucide-react';
|
||||
import { DetailSwipeNav } from '@/components/ui/detail-swipe-nav';
|
||||
import { DetailHeroV3 } from '@/components/detail-v2/detail-hero-v3';
|
||||
import { SolutionValueSectionV3 } from '@/components/detail-v2/solution-value-v3';
|
||||
import { DetailTrustSectionV2 } from '@/components/detail-v2/detail-trust-section-v2';
|
||||
import { DetailCTASectionV2 } from '@/components/detail-v2/detail-cta-section-v2';
|
||||
import { CrossRecommendGrid } from '@/components/detail/detail-cross-recommend';
|
||||
import { getHeroTheme } from '@/lib/constants/hero-themes';
|
||||
import { getSolutionCrossRefs } from '@/lib/constants/cross-references';
|
||||
import type { Solution } from '@/lib/constants/solutions';
|
||||
import type { Product } from '@/lib/constants/products';
|
||||
|
||||
interface SolutionDetailClientProps {
|
||||
solution: Solution;
|
||||
relatedProducts: Product[];
|
||||
}
|
||||
|
||||
export function SolutionDetailClient({ solution, relatedProducts }: SolutionDetailClientProps) {
|
||||
const shouldReduceMotion = useReducedMotion();
|
||||
const fadeUp = shouldReduceMotion ? {} : { initial: { opacity: 0, y: 20 } };
|
||||
export function SolutionDetailClient({ solution }: SolutionDetailClientProps) {
|
||||
const theme = getHeroTheme(solution.heroThemeId || 'solution');
|
||||
const crossRefs = getSolutionCrossRefs(solution.id);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[var(--color-bg-primary)]">
|
||||
<div className="pt-32 pb-16">
|
||||
<div className="container-wide">
|
||||
<PageNav items={[{ label: '解决方案', href: '/solutions' }, { label: solution.title }]} />
|
||||
<motion.div
|
||||
{...fadeUp}
|
||||
animate={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="max-w-4xl mt-8"
|
||||
>
|
||||
<p className="text-sm font-medium text-[var(--color-brand-primary)] mb-4 tracking-wide uppercase">
|
||||
{solution.industry}
|
||||
</p>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-[var(--color-text-primary)] mb-4 tracking-tight">
|
||||
{solution.title}
|
||||
</h1>
|
||||
<p className="text-xl text-[var(--color-text-muted)] mb-2">{solution.subtitle}</p>
|
||||
<p className="text-lg text-[var(--color-text-muted)] leading-relaxed">
|
||||
{solution.description}
|
||||
</p>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
<DetailSwipeNav type="solution" currentId={solution.id} />
|
||||
|
||||
<div className="container-wide pb-20">
|
||||
<div className="max-w-4xl space-y-16">
|
||||
<motion.section
|
||||
{...fadeUp}
|
||||
whileInView={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5 }}
|
||||
>
|
||||
<h2 className="text-2xl font-bold text-[var(--color-text-primary)] mb-6 flex items-center gap-3">
|
||||
<AlertTriangle className="w-6 h-6 text-[var(--color-brand-primary)]" />
|
||||
行业痛点
|
||||
</h2>
|
||||
<div className="space-y-3">
|
||||
{solution.challenges.map((challenge, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="flex items-start gap-3 p-4 rounded-lg bg-[var(--color-brand-primary-bg)]"
|
||||
>
|
||||
<AlertTriangle className="w-4 h-4 text-[var(--color-brand-primary)] mt-0.5 shrink-0" />
|
||||
<span className="text-[var(--color-text-primary)] text-sm">{challenge}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.section>
|
||||
{/* L1 - Hero 情感入口 (V3) */}
|
||||
<DetailHeroV3
|
||||
theme={theme}
|
||||
badge={`${solution.industry}解决方案`}
|
||||
title={solution.title}
|
||||
subtitle={solution.subtitle || solution.description}
|
||||
description={solution.description}
|
||||
primaryAction={{ label: '立即咨询', href: '/contact' }}
|
||||
secondaryAction={{ label: '查看案例', href: '/cases' }}
|
||||
/>
|
||||
|
||||
<motion.section
|
||||
{...fadeUp}
|
||||
whileInView={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5, delay: 0.1 }}
|
||||
>
|
||||
<h2 className="text-2xl font-bold text-[var(--color-text-primary)] mb-6 flex items-center gap-3">
|
||||
<CheckCircle2 className="w-6 h-6 text-[var(--color-brand-primary)]" />
|
||||
解决方案
|
||||
</h2>
|
||||
<div className="space-y-4">
|
||||
{solution.solutions.map((sol, index) => (
|
||||
<div key={index} className="flex items-start gap-4">
|
||||
<div className="w-8 h-8 bg-[var(--color-brand-primary)] rounded-full flex items-center justify-center shrink-0 text-white text-sm font-bold">
|
||||
{index + 1}
|
||||
</div>
|
||||
<p className="text-[var(--color-text-primary)] pt-1 leading-relaxed">{sol}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.section>
|
||||
{/* L2 - 价值理性支撑 (V3) */}
|
||||
<SolutionValueSectionV3 solution={solution} />
|
||||
|
||||
{relatedProducts.length > 0 && (
|
||||
<motion.section
|
||||
{...fadeUp}
|
||||
whileInView={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5, delay: 0.2 }}
|
||||
>
|
||||
<h2 className="text-2xl font-bold text-[var(--color-text-primary)] mb-6 flex items-center gap-3">
|
||||
<Package className="w-6 h-6 text-[var(--color-brand-primary)]" />
|
||||
相关产品
|
||||
</h2>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
{relatedProducts.map((product) => (
|
||||
<StaticLink
|
||||
key={product.id}
|
||||
href={`/products/${product.id}`}
|
||||
className="group block p-6 rounded-xl border border-[var(--color-border-primary)] bg-[var(--color-bg-primary)] hover:border-[var(--color-brand-primary)]/40 hover:shadow-lg transition-all duration-300"
|
||||
>
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<h3 className="text-lg font-semibold text-[var(--color-text-primary)] group-hover:text-[var(--color-brand-primary)] transition-colors">
|
||||
{product.title}
|
||||
</h3>
|
||||
{product.status && (
|
||||
<span
|
||||
className="text-xs font-medium px-3 py-1 rounded-full border shrink-0"
|
||||
style={{
|
||||
backgroundColor: product.status === '研发中' ? 'rgba(var(--color-brand-primary-rgb), 0.08)' : product.status === '内测中' ? 'rgba(var(--color-warning-rgb), 0.08)' : 'rgba(var(--color-success-rgb), 0.08)',
|
||||
color: product.status === '研发中' ? 'var(--color-brand-primary)' : product.status === '内测中' ? 'var(--color-warning)' : 'var(--color-success)',
|
||||
borderColor: product.status === '研发中' ? 'rgba(var(--color-brand-primary-rgb), 0.15)' : product.status === '内测中' ? 'rgba(var(--color-warning-rgb), 0.15)' : 'rgba(var(--color-success-rgb), 0.15)',
|
||||
}}
|
||||
>
|
||||
{product.status}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<p className="text-sm text-[var(--color-text-muted)] leading-relaxed">
|
||||
{product.description}
|
||||
</p>
|
||||
</StaticLink>
|
||||
))}
|
||||
</div>
|
||||
</motion.section>
|
||||
)}
|
||||
{/* L3 - 信任证明 (V2) — 条件渲染:有案例/数据/资质时才显示 */}
|
||||
<DetailTrustSectionV2
|
||||
caseStudies={solution.caseStudies}
|
||||
dataProofs={solution.dataProofs}
|
||||
certifications={solution.certifications}
|
||||
accentColor={theme.accentColor}
|
||||
/>
|
||||
|
||||
<div className="flex justify-center gap-4 pt-8 border-t border-[var(--color-border-primary)]">
|
||||
<Button variant="outline" size="lg" asChild>
|
||||
<StaticLink href="/contact">联系我们</StaticLink>
|
||||
</Button>
|
||||
<Button size="lg" className="bg-[var(--color-brand-primary)] hover:bg-[var(--color-brand-primary-hover)] text-white" asChild>
|
||||
<StaticLink href="/contact">
|
||||
预约方案演示
|
||||
<ArrowRight className="ml-2 w-4 h-4" />
|
||||
</StaticLink>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* L4 - CTA转化 (V2) */}
|
||||
<DetailCTASectionV2
|
||||
theme={theme}
|
||||
title={`探索 ${solution.title} 的无限可能`}
|
||||
description="联系我们,获取专属方案和报价"
|
||||
primaryAction={{ label: '立即咨询', href: '/contact' }}
|
||||
secondaryAction={{ label: '下载方案白皮书', href: '#' }}
|
||||
/>
|
||||
|
||||
<CrossRecommendGrid items={crossRefs} title="相关产品与服务" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { Metadata } from 'next';
|
||||
import { notFound } from 'next/navigation';
|
||||
import { SOLUTIONS } from '@/lib/constants/solutions';
|
||||
import { PRODUCTS } from '@/lib/constants/products';
|
||||
import { COMPANY_INFO } from '@/lib/constants';
|
||||
import { SolutionDetailClient } from './client';
|
||||
|
||||
@@ -33,7 +32,5 @@ export default async function SolutionDetailPage({ params }: { params: Promise<{
|
||||
notFound();
|
||||
}
|
||||
|
||||
const relatedProducts = PRODUCTS.filter((p) => solution.relatedProducts.includes(p.id));
|
||||
|
||||
return <SolutionDetailClient solution={JSON.parse(JSON.stringify(solution))} relatedProducts={JSON.parse(JSON.stringify(relatedProducts))} />;
|
||||
return <SolutionDetailClient solution={JSON.parse(JSON.stringify(solution))} />;
|
||||
}
|
||||
|
||||
@@ -1,83 +1,25 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useReducedMotion } from '@/hooks/use-reduced-motion';
|
||||
import { StaticLink } from '@/components/ui/static-link';
|
||||
import { ArrowRight, Lightbulb, Cpu, Users, CheckCircle2, ChevronDown } from 'lucide-react';
|
||||
import {
|
||||
Lightbulb,
|
||||
Cpu,
|
||||
Users,
|
||||
} from 'lucide-react';
|
||||
import { MethodologySection } from '@/components/sections/methodology-section';
|
||||
import { CTASection } from '@/components/sections/cta-section';
|
||||
import { PageNav } from '@/components/layout/page-nav';
|
||||
import { BreadcrumbSchema } from '@/components/seo/structured-data';
|
||||
import { SwipeNavigation } from '@/hooks/use-swipe-gesture';
|
||||
|
||||
const modules = [
|
||||
{
|
||||
icon: Lightbulb,
|
||||
title: '数字化转型咨询',
|
||||
subtitle: '参谋伙伴 — 帮您看清前路,迈对第一步',
|
||||
paragraphs: [
|
||||
'数字化转型最大的成本,是走错方向的成本。',
|
||||
'我们用行业智慧帮您洞察趋势,用理性分析帮您避开陷阱。',
|
||||
'不堆砌概念,只帮您想清楚:该不该做、做什么、怎么做。',
|
||||
],
|
||||
values: ['行业趋势洞察报告', '数字化转型成熟度评估', '个性化实施路径规划'],
|
||||
cta: '预约一次免费诊断',
|
||||
ctaHref: '/contact',
|
||||
accentColor: 'var(--color-brand-primary)',
|
||||
accentBg: 'var(--color-brand-primary-bg)',
|
||||
accentBorder: 'border-l-[var(--color-brand-primary)]',
|
||||
},
|
||||
{
|
||||
icon: Cpu,
|
||||
title: '信息技术解决方案',
|
||||
subtitle: '技术伙伴 — 让技术真正为业务服务',
|
||||
paragraphs: [
|
||||
'我们不追逐"最火"的技术,只选择"最对"的技术。',
|
||||
'将前沿技术深度融入您的业务场景,让每一行代码都产生业务价值。',
|
||||
'您不必懂技术原理,只需要看见业务在增长。',
|
||||
],
|
||||
values: ['业务场景深度调研', '技术方案定制开发', '敏捷交付快速迭代'],
|
||||
cta: '了解技术方案',
|
||||
ctaHref: '/products',
|
||||
accentColor: 'var(--color-accent-blue)',
|
||||
accentBg: 'rgba(37, 99, 235, 0.08)',
|
||||
accentBorder: 'border-l-[var(--color-accent-blue)]',
|
||||
},
|
||||
{
|
||||
icon: Users,
|
||||
title: '长期陪跑服务',
|
||||
subtitle: '同行伙伴 — 从需求到落地,持续陪伴',
|
||||
paragraphs: [
|
||||
'当产品真正为您所用那天,才是我们成为伙伴的开始。',
|
||||
'我们建立长效服务机制,定期回访、持续优化、随时响应。',
|
||||
'在您需要的时候,我们始终在场。',
|
||||
],
|
||||
values: ['专属客户成功经理', '季度业务复盘会', '7×24小时响应通道'],
|
||||
cta: '了解陪跑服务',
|
||||
ctaHref: '/services',
|
||||
accentColor: 'var(--color-success)',
|
||||
accentBg: 'rgba(22, 163, 74, 0.08)',
|
||||
accentBorder: 'border-l-[var(--color-success)]',
|
||||
},
|
||||
];
|
||||
import { ListPageHeroV3 } from '@/components/detail-v2/list-page-hero-v3';
|
||||
import { SolutionCardV3 } from '@/components/detail-v2/solution-service-card-v3';
|
||||
import { SOLUTIONS } from '@/lib/constants/solutions';
|
||||
|
||||
export default function SolutionsPage() {
|
||||
const shouldReduceMotion = useReducedMotion();
|
||||
const fadeUp = shouldReduceMotion ? {} : { initial: { opacity: 0, y: 20 } };
|
||||
const [expandedModules, setExpandedModules] = useState<Set<number>>(new Set([0]));
|
||||
|
||||
const toggleModule = (index: number) => {
|
||||
setExpandedModules(prev => {
|
||||
const next = new Set(prev);
|
||||
if (next.has(index)) {
|
||||
next.delete(index);
|
||||
} else {
|
||||
next.add(index);
|
||||
}
|
||||
return next;
|
||||
});
|
||||
};
|
||||
return (
|
||||
<div className="min-h-screen bg-[var(--color-bg-primary)]">
|
||||
<BreadcrumbSchema items={[{ name: '首页', href: '/' }, { name: '解决方案', href: '/solutions' }]} />
|
||||
@@ -87,118 +29,77 @@ export default function SolutionsPage() {
|
||||
prevLabel="产品方案"
|
||||
nextLabel="服务支持"
|
||||
/>
|
||||
<section className="pt-32 pb-16">
|
||||
|
||||
{/* Hero 区域 (V3) */}
|
||||
<ListPageHeroV3
|
||||
title="行业解决方案"
|
||||
subtitle="针对不同行业的核心痛点,提供端到端数字化路径"
|
||||
description="基于企业套装产品的行业化组合方案"
|
||||
stats={[
|
||||
{ value: '4', label: '行业方案' },
|
||||
{ value: '6+', label: '核心产品' },
|
||||
{ value: '100%', label: '自主可控' },
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* 行业解决方案网格 */}
|
||||
<section className="pb-16">
|
||||
<div className="container-wide">
|
||||
<PageNav items={[{ label: '解决方案' }]} />
|
||||
<motion.div
|
||||
{...fadeUp}
|
||||
animate={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5 }}
|
||||
className="max-w-3xl"
|
||||
>
|
||||
<p className="text-sm font-medium text-[var(--color-brand-primary)] mb-4 tracking-wide uppercase">Solutions</p>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-[var(--color-text-primary)] mb-6 tracking-tight">
|
||||
三种角色,一种身份——您的成长伙伴
|
||||
</h1>
|
||||
<p className="text-lg text-[var(--color-text-muted)] leading-relaxed">
|
||||
我们以伙伴的身份,陪您走过数字化转型的每一步
|
||||
</p>
|
||||
</motion.div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||
{SOLUTIONS.map((solution) => (
|
||||
<SolutionCardV3 key={solution.id} solution={solution} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="pb-20">
|
||||
{/* 方案→服务关联推荐 */}
|
||||
<section className="py-16">
|
||||
<div className="container-wide">
|
||||
<div className="max-w-6xl mx-auto space-y-8">
|
||||
{modules.map((module, index) => {
|
||||
const anchorIds = ['consulting', 'tech', 'accompany'];
|
||||
return (
|
||||
<motion.section
|
||||
key={index}
|
||||
id={anchorIds[index]}
|
||||
{...fadeUp}
|
||||
whileInView={shouldReduceMotion ? {} : { opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.5, delay: index * 0.1 }}
|
||||
className={`p-8 md:p-12 rounded-xl border border-[var(--color-border-primary)] bg-[var(--color-bg-primary)] hover:border-[var(--color-border-primary)] transition-colors`}
|
||||
>
|
||||
<div className="flex items-start gap-4 mb-6">
|
||||
<div className="w-12 h-12 rounded-xl flex items-center justify-center shrink-0" style={{ backgroundColor: module.accentBg }}>
|
||||
<module.icon className="w-6 h-6" style={{ color: module.accentColor }} />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold text-[var(--color-text-primary)] mb-1">
|
||||
模块{['一', '二', '三'][index]}:{module.title}
|
||||
</h2>
|
||||
<p className="text-[var(--color-text-muted)]">{module.subtitle}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4 mb-8">
|
||||
<button
|
||||
onClick={() => toggleModule(index)}
|
||||
className="flex items-center gap-2 text-sm font-medium text-[var(--color-brand-primary)] hover:text-[var(--color-brand-primary-hover)] transition-colors group"
|
||||
aria-expanded={expandedModules.has(index)}
|
||||
>
|
||||
<ChevronDown className={`w-4 h-4 transition-transform duration-200 ${expandedModules.has(index) ? 'rotate-180' : ''}`} />
|
||||
{expandedModules.has(index) ? '收起详情' : '展开了解详情'}
|
||||
</button>
|
||||
<AnimatePresence>
|
||||
{expandedModules.has(index) && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, height: 0 }}
|
||||
animate={{ opacity: 1, height: 'auto' }}
|
||||
exit={{ opacity: 0, height: 0 }}
|
||||
transition={{ duration: 0.3, ease: [0.16, 1, 0.3, 1] }}
|
||||
className="overflow-hidden"
|
||||
{...fadeUp}
|
||||
whileInView={{ opacity: 1 }}
|
||||
viewport={{ once: true }}
|
||||
className="text-center mb-10"
|
||||
>
|
||||
{module.paragraphs.map((p, i) => (
|
||||
<p key={i} className="text-[var(--color-text-primary)] leading-relaxed mb-3 last:mb-0">{p}</p>
|
||||
))}
|
||||
<h2 className="text-2xl font-bold text-gray-900 lg:text-3xl mb-3">
|
||||
从方案到落地,全程陪伴
|
||||
</h2>
|
||||
<p className="text-gray-600 max-w-2xl mx-auto">
|
||||
我们不仅提供行业解决方案,更通过专业服务确保方案真正落地见效
|
||||
</p>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</div>
|
||||
|
||||
<div className="mb-8">
|
||||
<h3 className="text-lg font-semibold text-[var(--color-text-primary)] mb-4 flex items-center gap-2">
|
||||
<CheckCircle2 className="w-5 h-5" style={{ color: module.accentColor }} />
|
||||
核心价值点
|
||||
</h3>
|
||||
<div className="grid md:grid-cols-3 gap-3">
|
||||
{module.values.map((value, i) => (
|
||||
<div key={i} className="flex items-start gap-2 p-3 rounded-lg" style={{ backgroundColor: module.accentBg }}>
|
||||
<div className="w-1.5 h-1.5 rounded-full mt-2 shrink-0" style={{ backgroundColor: module.accentColor }} />
|
||||
<span className="text-sm text-[var(--color-text-primary)]">{value}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center">
|
||||
<StaticLink
|
||||
href={module.ctaHref}
|
||||
className="inline-flex items-center gap-2 px-6 py-3 rounded-lg border-2 font-medium transition-all duration-200 hover:text-white"
|
||||
style={{
|
||||
borderColor: module.accentColor,
|
||||
color: module.accentColor,
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
e.currentTarget.style.backgroundColor = module.accentColor;
|
||||
e.currentTarget.style.color = '#fff';
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.backgroundColor = 'transparent';
|
||||
e.currentTarget.style.color = module.accentColor;
|
||||
}}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 max-w-4xl mx-auto">
|
||||
{[
|
||||
{ icon: Lightbulb, title: '数字化转型咨询', desc: '帮您看清前路,迈对第一步', href: '/services', bgColor: 'rgba(196,30,58,0.06)', color: '#C41E3A' },
|
||||
{ icon: Cpu, title: '信息技术解决方案', desc: '让技术真正为业务服务', href: '/products', bgColor: 'rgba(37,99,235,0.06)', color: '#2563eb' },
|
||||
{ icon: Users, title: '长期陪跑服务', desc: '从需求到落地,持续陪伴', href: '/services', bgColor: 'rgba(22,163,74,0.06)', color: '#16a34a' },
|
||||
].map((item, i) => (
|
||||
<motion.div
|
||||
key={i}
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: i * 0.1 }}
|
||||
>
|
||||
{module.cta}
|
||||
<ArrowRight className="w-4 h-4" />
|
||||
</StaticLink>
|
||||
<StaticLink
|
||||
href={item.href}
|
||||
className="block p-6 rounded-xl bg-white border border-gray-100 hover:border-gray-200 hover:shadow-md transition-all group"
|
||||
>
|
||||
<div
|
||||
className="w-10 h-10 rounded-lg flex items-center justify-center mb-4"
|
||||
style={{ backgroundColor: item.bgColor }}
|
||||
>
|
||||
<item.icon className="w-5 h-5" style={{ color: item.color }} />
|
||||
</div>
|
||||
</motion.section>
|
||||
);
|
||||
})}
|
||||
<h3 className="font-semibold text-gray-900 mb-1 group-hover:text-[#C41E3A] transition-colors">
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-500">{item.desc}</p>
|
||||
</StaticLink>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user