feat(marketing): 重构营销页面与四层叙事组件体系

- 重构 About、Contact、Team 等静态营销页面
- 重构 News 新闻列表与详情页
- 重构 Products 产品目录、详情与独立产品页面
- 重构 Services 与 Solutions 服务/解决方案页面
- 重构 Detail 四层叙事组件 (Hero → Value → Trust → CTA)
- 重构 Sections 页面区块组件 (Hero, CTA, SocialProof, WhyUs 等)
- 新增 SectionHeader、ServiceCard、CaseCard 等可复用组件
This commit is contained in:
张翔
2026-07-07 06:53:40 +08:00
parent 767931202d
commit 829d83522c
57 changed files with 3912 additions and 2380 deletions
+14 -231
View File
@@ -1,233 +1,16 @@
'use client';
import { Metadata } from 'next';
import { COMPANY_INFO } from '@/lib/constants';
import { getPublishedItems } from '@/lib/cms/data-server';
import type { Service } from '@/lib/constants/services';
import ServicesContentV3 from './services-content-v3';
import { NarrativeHero } from '@/components/sections/narrative/NarrativeHero';
import { NarrativeValue } from '@/components/sections/narrative/NarrativeValue';
import { NarrativeCTA } from '@/components/sections/narrative/NarrativeCTA';
import { InkCard } from '@/components/ui/ink-wash';
import { motion } from 'framer-motion';
import { useReducedMotion } from '@/hooks/use-reduced-motion';
import {
Code,
BarChart3,
Lightbulb,
Puzzle,
ClipboardList,
PencilRuler,
Rocket,
HeartHandshake,
Briefcase,
RefreshCcw,
Handshake,
} from 'lucide-react';
import type { ValuePoint } from '@/components/sections/narrative/NarrativeValue';
export const metadata: Metadata = {
title: `服务 - ${COMPANY_INFO.displayName}`,
description: `专业技术团队,为您提供全方位的数字化解决方案。${COMPANY_INFO.displayName}涵盖软件开发、数据分析、咨询服务等核心业务。`,
};
const EASE = [0.25, 1, 0.5, 1] as const;
const SERVICE_MATRIX: ValuePoint[] = [
{
icon: Code,
title: '软件开发',
description: '从需求分析到上线运维,提供全栈定制化开发。企业管理系统、Web/移动应用、数据中台——用扎实的工程能力交付高质量软件。',
stat: '95%',
statLabel: '准时交付率',
},
{
icon: BarChart3,
title: '数据分析',
description: '多源数据整合、可视化看板、预测模型——让数据从"存着"变成"用着",为经营决策提供可量化的洞察支撑。',
stat: '100+',
statLabel: '分析模型',
},
{
icon: Lightbulb,
title: '技术咨询',
description: 'IT 战略规划、技术选型评估、数字化转型路线图——帮您理清方向,规避技术风险,减少试错成本。',
stat: '90%',
statLabel: '方案落地率',
},
{
icon: Puzzle,
title: '方案实施',
description: '深耕制造、零售、金融、医疗等行业,提供从咨询到落地的端到端交付,确保方案不只是 PPT。',
stat: '30+',
statLabel: '行业方案',
},
];
const SERVICE_PROCESS = [
{ icon: ClipboardList, step: '01', title: '需求分析', desc: '深入了解业务场景与真实痛点,而非凭空假设' },
{ icon: PencilRuler, step: '02', title: '方案设计', desc: '量身定制技术路线,拒绝千篇一律的模板' },
{ icon: Rocket, step: '03', title: '敏捷交付', desc: '快速迭代,每个冲刺周期都有可交付成果' },
{ icon: HeartHandshake, step: '04', title: '持续支持', desc: '上线不是终点,长期陪伴才是真正的承诺' },
];
const SERVICE_MODES = [
{
icon: Briefcase,
title: '项目制',
description: '针对明确的需求和交付目标,以项目为单位进行合作。适合有清晰边界的一次性建设类项目。',
highlight: '固定范围 · 固定周期',
},
{
icon: RefreshCcw,
title: '订阅制',
description: '按月或按年持续提供技术支持和迭代优化。适合需要长期维护、持续演进的产品和系统。',
highlight: '持续迭代 · 弹性调整',
},
{
icon: Handshake,
title: '长期陪跑',
description: '以合作伙伴身份深度参与您的数字化进程,从规划到执行全程陪伴。适合正在系统性转型的企业。',
highlight: '深度参与 · 共同成长',
},
];
export default function ServicesPage() {
const shouldReduceMotion = useReducedMotion();
return (
<div className="min-h-screen bg-[var(--color-bg-primary)]">
{/* Layer 1: Hero */}
<NarrativeHero
badge={{ text: '专业服务', variant: 'green' }}
title="从规划到运维的"
highlight="全程陪伴"
subtitle="不只是技术供应商,更是您数字化转型的同行者"
description="12 年行业深耕,我们深知每个项目背后都是真实的业务诉求。从第一次沟通到系统稳定运行,我们始终在您身边。"
primaryCta={{ label: '聊聊您的需求', href: '/contact' }}
secondaryCta={{ label: '查看产品矩阵', href: '/products' }}
stats={[
{ value: '4 大', label: '服务领域' },
{ value: '3 种', label: '合作模式' },
{ value: '全流程', label: '服务保障' },
]}
/>
{/* Layer 2: Service Matrix */}
<NarrativeValue
badge="服务能力"
title="四大核心服务"
highlight="领域"
subtitle="覆盖企业数字化全生命周期的专业能力"
points={SERVICE_MATRIX}
columns={4}
bgVariant="section"
/>
{/* Service Process */}
<section className="section-padding bg-[var(--color-bg-primary)] relative overflow-hidden">
<div className="container-wide relative z-10">
<motion.div
initial={shouldReduceMotion ? {} : { opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: '-100px' }}
transition={{ duration: 0.6, ease: EASE }}
className="mb-14"
>
<div className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-[var(--color-brand-primary-bg)] border border-[var(--color-brand-primary)]/10 mb-4">
<span className="w-1.5 h-1.5 rounded-full bg-[var(--color-brand-primary)]" />
<span className="text-xs font-medium tracking-wider text-[var(--color-brand-primary)]">服务流程</span>
</div>
<h2 className="text-3xl sm:text-4xl font-semibold text-[var(--color-text-primary)] mb-4">
我们的<span className="text-[var(--color-brand-primary)] font-calligraphy ml-1">做事方式</span>
</h2>
<p className="text-base text-[var(--color-text-muted)] max-w-2xl">
没有复杂的流程,只有清晰的四步:听懂需求、想好方案、快速交付、长期陪伴。
</p>
</motion.div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
{SERVICE_PROCESS.map((item, index) => {
const Icon = item.icon;
return (
<motion.div
key={item.step}
initial={shouldReduceMotion ? {} : { opacity: 0, y: 24 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: '-60px' }}
transition={{ duration: 0.5, delay: index * 0.1, ease: EASE }}
className="relative"
>
{/* Connector line */}
{index < SERVICE_PROCESS.length - 1 && (
<div className="hidden lg:block absolute top-10 left-[calc(50%+2rem)] w-[calc(100%-2rem)] h-px bg-[var(--color-border-primary)]" />
)}
<div className="text-center">
<div className="mx-auto mb-5 w-20 h-20 rounded-2xl bg-[var(--color-bg-section)] border border-[var(--color-border-primary)] flex items-center justify-center relative">
<Icon className="w-8 h-8 text-[var(--color-text-primary)]" strokeWidth={1.5} />
<span className="absolute -top-2 -right-2 w-7 h-7 rounded-full bg-[var(--color-brand-primary)] text-white text-xs font-bold flex items-center justify-center">
{item.step}
</span>
</div>
<h3 className="text-base font-semibold text-[var(--color-text-primary)] mb-2">{item.title}</h3>
<p className="text-sm text-[var(--color-text-muted)] leading-relaxed max-w-[200px] mx-auto">{item.desc}</p>
</div>
</motion.div>
);
})}
</div>
</div>
</section>
{/* Service Modes */}
<section className="section-padding bg-[var(--color-bg-section)] relative overflow-hidden">
<div className="container-wide relative z-10">
<motion.div
initial={shouldReduceMotion ? {} : { opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: '-100px' }}
transition={{ duration: 0.6, ease: EASE }}
className="mb-14"
>
<div className="inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-[var(--color-brand-primary-bg)] border border-[var(--color-brand-primary)]/10 mb-4">
<span className="w-1.5 h-1.5 rounded-full bg-[var(--color-brand-primary)]" />
<span className="text-xs font-medium tracking-wider text-[var(--color-brand-primary)]">合作模式</span>
</div>
<h2 className="text-3xl sm:text-4xl font-semibold text-[var(--color-text-primary)] mb-4">
灵活的<span className="text-[var(--color-brand-primary)] font-calligraphy ml-1">合作方式</span>
</h2>
<p className="text-base text-[var(--color-text-muted)] max-w-2xl">
不同企业有不同节奏,我们提供三种合作模式,找到最适合您的那一种。
</p>
</motion.div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{SERVICE_MODES.map((mode, idx) => {
const Icon = mode.icon;
return (
<motion.div
key={mode.title}
initial={shouldReduceMotion ? {} : { opacity: 0, y: 24 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: '-60px' }}
transition={{ duration: 0.5, delay: idx * 0.1, ease: EASE }}
>
<InkCard padding="lg" className="h-full">
<div className="w-12 h-12 rounded-xl bg-[var(--color-brand-primary-bg)] flex items-center justify-center mb-5">
<Icon className="w-6 h-6 text-[var(--color-brand-primary)]" strokeWidth={1.8} />
</div>
<h3 className="text-lg font-semibold text-[var(--color-text-primary)] mb-2">{mode.title}</h3>
<p className="text-sm text-[var(--color-text-muted)] leading-relaxed mb-4">{mode.description}</p>
<div className="inline-flex items-center px-3 py-1 rounded-full bg-[var(--color-bg-section)] border border-[var(--color-border-primary)]">
<span className="text-xs font-medium text-[var(--color-text-secondary)]">{mode.highlight}</span>
</div>
</InkCard>
</motion.div>
);
})}
</div>
</div>
</section>
{/* Layer 4: CTA */}
<NarrativeCTA
title="聊聊您的需求"
description="无论是一个明确的项目,还是一个模糊的想法,我们都愿意坐下来和您一起理清楚。首次咨询免费,没有任何销售压力。"
primaryLabel="预约免费咨询"
primaryHref="/contact"
secondaryLabel="了解我们的团队"
secondaryHref="/team"
/>
</div>
);
}
export default async function ServicesPage() {
const items = await getPublishedItems('service');
const services = items.map((item) => ({ ...item.data, title: item.data.title || item.title } as unknown as Service));
return <ServicesContentV3 services={services} />;
}