diff --git a/src/app/(marketing)/home-content.tsx b/src/app/(marketing)/home-content.tsx index 0352b76..2721c2b 100644 --- a/src/app/(marketing)/home-content.tsx +++ b/src/app/(marketing)/home-content.tsx @@ -9,41 +9,57 @@ import type { ReactNode } from 'react'; const ServicesSection = dynamic( () => import('@/components/sections/services-section').then(mod => ({ default: mod.ServicesSection })), - { + { loading: () => , - ssr: false + ssr: false + } +); + +const HomeSolutionsSection = dynamic( + () => import('@/components/sections/home-solutions-section').then(mod => ({ default: mod.HomeSolutionsSection })), + { + loading: () => , + ssr: false } ); const ProductsSection = dynamic( () => import('@/components/sections/products-section').then(mod => ({ default: mod.ProductsSection })), - { + { loading: () => , - ssr: false + ssr: false } ); const CasesSection = dynamic( () => import('@/components/sections/cases-section').then(mod => ({ default: mod.CasesSection })), - { + { loading: () => , - ssr: false + ssr: false } ); const AboutSection = dynamic( () => import('@/components/sections/about-section').then(mod => ({ default: mod.AboutSection })), - { + { loading: () => , - ssr: false + ssr: false + } +); + +const TeamSection = dynamic( + () => import('@/components/sections/team-section').then(mod => ({ default: mod.TeamSection })), + { + loading: () => , + ssr: false } ); const NewsSection = dynamic( () => import('@/components/sections/news-section').then(mod => ({ default: mod.NewsSection })), - { + { loading: () => , - ssr: false + ssr: false } ); @@ -83,9 +99,11 @@ function HomeContent({ heroStats }: { heroStats: ReactNode }) {
+ +
); diff --git a/src/app/(marketing)/solutions/page.tsx b/src/app/(marketing)/solutions/page.tsx index dbe1b4d..92237cf 100644 --- a/src/app/(marketing)/solutions/page.tsx +++ b/src/app/(marketing)/solutions/page.tsx @@ -7,6 +7,7 @@ import { StaticLink } from '@/components/ui/static-link'; import { Button } from '@/components/ui/button'; import { PageHeader } from '@/components/ui/page-header'; import { ArrowRight, Lightbulb, Cpu, Users, CheckCircle2 } from 'lucide-react'; +import { MethodologySection } from '@/components/sections/methodology-section'; export default function SolutionsPage() { const contentRef = useRef(null); @@ -236,6 +237,8 @@ export default function SolutionsPage() { + + + + +
+ + {/* 团队概述 */} + +

关于我们的团队

+
+

+ 我们的核心团队长期从事技术咨询企业数字化等行业,拥有 12 年以上的深厚积累。 +

+

+ 开发团队成员来自于多个大型传统 IT 企业,具备扎实的工程能力和规范化的交付经验。 +

+

+ 我们相信,优秀的技术咨询不仅需要过硬的技术能力,更需要深入理解客户的业务场景和真实需求。 + 每一位成员都是既懂技术又懂业务的复合型人才。 +

+
+
+ + {/* 团队优势 */} +
+

团队优势

+
+ {TEAM_PILLARS.map((item, idx) => { + const Icon = item.icon; + return ( + = 3 ? 'md:col-span-1 lg:col-start-1' : ''} + > +
+
+ +
+

{item.title}

+

{item.description}

+
+
+ ); + })} +
+
+ + {/* CTA */} + +

想与我们的团队交流?

+ +
+
+
+ + ); +} diff --git a/src/app/(marketing)/team/page.tsx b/src/app/(marketing)/team/page.tsx new file mode 100644 index 0000000..71ad41c --- /dev/null +++ b/src/app/(marketing)/team/page.tsx @@ -0,0 +1,11 @@ +import { COMPANY_INFO } from '@/lib/constants'; +import { TeamClient } from './client'; + +export const metadata = { + title: `核心团队 - ${COMPANY_INFO.name}`, + description: `了解${COMPANY_INFO.name}的核心团队。我们的团队成员拥有丰富的行业经验和技术专长,致力于为客户提供专业的数字化转型服务。`, +}; + +export default function TeamPage() { + return ; +} diff --git a/src/components/layout/header.tsx b/src/components/layout/header.tsx index d7a1c14..36a4369 100644 --- a/src/components/layout/header.tsx +++ b/src/components/layout/header.tsx @@ -36,7 +36,7 @@ function HeaderContent() { if (pathname === '/' && !isScrollingRef.current) { const scrollPosition = window.scrollY + 100; - const sections = ['home', 'services', 'products', 'cases', 'about', 'news']; + const sections = ['home', 'services', 'solutions', 'products', 'cases', 'about', 'news']; for (const sectionId of sections) { const element = document.getElementById(sectionId); diff --git a/src/components/sections/home-solutions-section.tsx b/src/components/sections/home-solutions-section.tsx new file mode 100644 index 0000000..3de6eb7 --- /dev/null +++ b/src/components/sections/home-solutions-section.tsx @@ -0,0 +1,106 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { useInView } from 'framer-motion'; +import { useRef } from 'react'; +import { StaticLink } from '@/components/ui/static-link'; +import { Button } from '@/components/ui/button'; +import { ArrowRight, Lightbulb, Cpu, Users } from 'lucide-react'; + +const SOLUTIONS_OVERVIEW = [ + { + icon: Lightbulb, + title: '参谋伙伴', + subtitle: '数字化转型咨询', + description: '帮您看清前路,迈对第一步。用行业智慧洞察趋势,用理性分析避开陷阱。', + points: ['行业趋势洞察报告', '成熟度评估', '实施路径规划'], + }, + { + icon: Cpu, + title: '技术伙伴', + subtitle: '信息技术解决方案', + description: '让技术真正为业务服务。不追逐"最火"的技术,只选择"最对"的技术。', + points: ['业务场景调研', '技术方案定制', '敏捷交付迭代'], + }, + { + icon: Users, + title: '同行伙伴', + subtitle: '长期陪跑服务', + description: '交付只是开始,陪伴才是常态。项目上线那天,是我们真正成为伙伴的开始。', + points: ['专属客户成功经理', '季度业务复盘', '7×24小时响应'], + }, +]; + +export function HomeSolutionsSection() { + const ref = useRef(null); + const isInView = useInView(ref, { once: true, margin: '-100px' }); + + return ( +
+
+
+ +

+ 三种角色,一种身份 +

+

+ 您的数字化转型成长伙伴——从战略咨询到技术落地,再到长期陪跑 +

+
+ +
+ {SOLUTIONS_OVERVIEW.map((item, idx) => { + const Icon = item.icon; + return ( + +
+
+ +
+

{item.title}

+

{item.subtitle}

+

{item.description}

+
    + {item.points.map((point, i) => ( +
  • +
    + {point} +
  • + ))} +
+
+
+ ); + })} +
+ + + + +
+
+ ); +} diff --git a/src/components/sections/insights-section.test.tsx b/src/components/sections/insights-section.test.tsx deleted file mode 100644 index ac472aa..0000000 --- a/src/components/sections/insights-section.test.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { describe, it, expect, beforeEach, jest } from '@jest/globals'; -import { render, screen } from '@testing-library/react'; -import '@testing-library/jest-dom'; -import { InsightsSection } from './insights-section'; - -jest.mock('@/components/ui/insight-card', () => ({ - InsightCard: ({ title, category }: any) => ( -
-
{title}
-
{category}
-
- ), -})); - -describe('InsightsSection', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - describe('Rendering', () => { - it('should render insights section', () => { - render(); - const section = document.querySelector('section#insights'); - expect(section).toBeInTheDocument(); - }); - - it('should render section heading', () => { - render(); - expect(screen.getByRole('heading', { level: 2 })).toBeInTheDocument(); - }); - - it('should render section description', () => { - render(); - expect(screen.getByText(/分享前沿技术趋势/)).toBeInTheDocument(); - }); - - it('should render insight cards', () => { - render(); - const cards = screen.getAllByTestId('insight-card'); - expect(cards.length).toBeGreaterThan(0); - }); - - it('should render insight titles', () => { - render(); - expect(screen.getByText('2025年技术趋势:AI驱动的数字化转型')).toBeInTheDocument(); - }); - - it('should render insight categories', () => { - render(); - expect(screen.getByText('技术趋势')).toBeInTheDocument(); - }); - - it('should render view all button', () => { - render(); - expect(screen.getByText('查看全部洞察')).toBeInTheDocument(); - }); - }); - - describe('Accessibility', () => { - it('should have section id', () => { - render(); - const section = document.querySelector('section#insights'); - expect(section).toBeInTheDocument(); - }); - }); - - describe('Styling', () => { - it('should have correct background', () => { - render(); - const section = document.querySelector('section.bg-\\[\\#FAFAFA\\]'); - expect(section).toBeInTheDocument(); - }); - - it('should have container', () => { - render(); - const container = document.querySelector('.container-wide'); - expect(container).toBeInTheDocument(); - }); - - it('should have grid layout', () => { - render(); - const grid = document.querySelector('.grid'); - expect(grid).toBeInTheDocument(); - }); - }); -}); diff --git a/src/components/sections/insights-section.tsx b/src/components/sections/insights-section.tsx deleted file mode 100644 index e34c50e..0000000 --- a/src/components/sections/insights-section.tsx +++ /dev/null @@ -1,129 +0,0 @@ -'use client'; - -import { useEffect, useState, useRef } from 'react'; -import { InsightCard } from '@/components/ui/insight-card'; -import { Button } from '@/components/ui/button'; -import { ArrowRight } from 'lucide-react'; - -interface Insight { - id: string; - title: string; - excerpt: string; - category: string; - readTime: string; - publishedAt: string; - imageUrl?: string; - href: string; - featured?: boolean; -} - -const MOCK_INSIGHTS: Insight[] = [ - { - id: '1', - title: '2025年技术趋势:AI驱动的数字化转型', - excerpt: '深入探讨人工智能如何重塑企业技术架构,以及如何把握AI时代的机遇', - category: '技术趋势', - readTime: '8 分钟', - publishedAt: '2026-02-10', - imageUrl: '/insights/ai-trend.jpg', - href: '/insights/ai-trend-2025', - featured: true, - }, - { - id: '2', - title: '微服务架构最佳实践指南', - excerpt: '从单体应用到微服务的演进之路,包含实战案例和避坑指南', - category: '架构设计', - readTime: '12 分钟', - publishedAt: '2026-02-08', - imageUrl: '/insights/microservices.jpg', - href: '/insights/microservices-best-practices', - }, - { - id: '3', - title: '云原生技术栈选型指南', - excerpt: 'Kubernetes、Docker、Service Mesh等技术栈的深度对比与选型建议', - category: '云原生', - readTime: '10 分钟', - publishedAt: '2026-02-05', - imageUrl: '/insights/cloud-native.jpg', - href: '/insights/cloud-native-stack-guide', - }, -]; - -export function InsightsSection() { - const [isVisible, setIsVisible] = useState(false); - const sectionRef = useRef(null); - - useEffect(() => { - const observer = new IntersectionObserver( - ([entry]) => { - if (entry?.isIntersecting) { - setIsVisible(true); - } - }, - { threshold: 0.1 } - ); - - if (sectionRef.current) { - observer.observe(sectionRef.current); - } - - return () => observer.disconnect(); - }, []); - - return ( -
-
-
-

- 技术洞察 -

-

- 分享前沿技术趋势、最佳实践和深度思考,助力企业数字化转型 -

-
- -
- {MOCK_INSIGHTS.map((insight) => ( - - ))} -
- -
- -
-
-
- ); -} diff --git a/src/components/sections/methodology-section.tsx b/src/components/sections/methodology-section.tsx new file mode 100644 index 0000000..a8102f5 --- /dev/null +++ b/src/components/sections/methodology-section.tsx @@ -0,0 +1,83 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { useInView } from 'framer-motion'; +import { useRef } from 'react'; +import { METHODOLOGY } from '@/lib/constants/methodology'; +import { CheckCircle2 } from 'lucide-react'; + +export function MethodologySection() { + const ref = useRef(null); + const isInView = useInView(ref, { once: true, margin: '-100px' }); + + return ( +
+
+ +

+ 实施方法论 +

+

+ 经过多年实践验证的四阶段模型,确保每个项目都能科学推进、高效落地 +

+
+ +
+ {/* 连接线 */} +
+ +
+ {METHODOLOGY.map((phase, idx) => ( + +
+ {/* 阶段编号 */} +
+ {phase.number} +
+ +

{phase.title}

+

{phase.subtitle}

+

{phase.description}

+ +
+

核心活动

+
    + {phase.activities.map((activity, i) => ( +
  • + + {activity} +
  • + ))} +
+
+ +
+

交付物

+
    + {phase.deliverables.map((deliverable, i) => ( +
  • + + {deliverable} +
  • + ))} +
+
+
+
+ ))} +
+
+
+
+ ); +} diff --git a/src/components/sections/products-section.tsx b/src/components/sections/products-section.tsx index 930a68f..b8de894 100644 --- a/src/components/sections/products-section.tsx +++ b/src/components/sections/products-section.tsx @@ -85,19 +85,6 @@ export function ProductsSection() { - {product.pricing && ( -
-

价格方案

-
- {Object.entries(product.pricing).map(([key, value]) => ( -

- {value} -

- ))} -
-
- )} - +
+ + + ); +} diff --git a/src/components/sections/testimonials-section.test.tsx b/src/components/sections/testimonials-section.test.tsx deleted file mode 100644 index 5e4094b..0000000 --- a/src/components/sections/testimonials-section.test.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { describe, it, expect, beforeEach, jest } from '@jest/globals'; -import { render, screen } from '@testing-library/react'; -import '@testing-library/jest-dom'; -import { TestimonialsSection } from './testimonials-section'; - -jest.mock('@/components/ui/testimonial-card', () => ({ - TestimonialCard: ({ author, quote }: any) => ( -
-
{author}
-
{quote}
-
- ), -})); - -describe('TestimonialsSection', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - describe('Rendering', () => { - it('should render testimonials section', () => { - render(); - const section = document.querySelector('section#testimonials'); - expect(section).toBeInTheDocument(); - }); - - it('should render section heading', () => { - render(); - expect(screen.getByRole('heading', { level: 2 })).toBeInTheDocument(); - }); - - it('should render section description', () => { - render(); - expect(screen.getByText(/听听我们的客户怎么说/)).toBeInTheDocument(); - }); - - it('should render testimonial cards', () => { - render(); - const cards = screen.getAllByTestId('testimonial-card'); - expect(cards.length).toBeGreaterThan(0); - }); - - it('should render testimonial authors', () => { - render(); - expect(screen.getByText('张总')).toBeInTheDocument(); - }); - - it('should render testimonial quotes', () => { - render(); - expect(screen.getByText(/睿新致远的团队非常专业/)).toBeInTheDocument(); - }); - }); - - describe('Accessibility', () => { - it('should have section id', () => { - render(); - const section = document.querySelector('section#testimonials'); - expect(section).toBeInTheDocument(); - }); - }); - - describe('Styling', () => { - it('should have correct background', () => { - render(); - const section = document.querySelector('section.bg-white'); - expect(section).toBeInTheDocument(); - }); - - it('should have container', () => { - render(); - const container = document.querySelector('.container-wide'); - expect(container).toBeInTheDocument(); - }); - - it('should have grid layout', () => { - render(); - const grid = document.querySelector('.grid'); - expect(grid).toBeInTheDocument(); - }); - }); -}); diff --git a/src/components/sections/testimonials-section.tsx b/src/components/sections/testimonials-section.tsx deleted file mode 100644 index 6312c28..0000000 --- a/src/components/sections/testimonials-section.tsx +++ /dev/null @@ -1,103 +0,0 @@ -'use client'; - -import { useEffect, useState, useRef } from 'react'; -import { TestimonialCard } from '@/components/ui/testimonial-card'; - -interface Testimonial { - id: string; - quote: string; - author: string; - position: string; - company: string; - avatarUrl?: string; - rating?: number; -} - -const MOCK_TESTIMONIALS: Testimonial[] = [ - { - id: '1', - quote: '睿新致远的团队非常专业,他们不仅理解我们的业务需求,还能提供超出预期的技术解决方案。数字化转型后,我们的运营效率提升了40%。', - author: '张总', - position: '总经理', - company: '某制造企业', - avatarUrl: '/testimonials/avatar-1.jpg', - rating: 5, - }, - { - id: '2', - quote: '选择睿新致远是我们最正确的决定。他们的数据中台解决方案帮助我们实现了数据资产的统一管理,决策效率大幅提升。', - author: '李经理', - position: '信息部经理', - company: '某零售集团', - avatarUrl: '/testimonials/avatar-2.jpg', - rating: 5, - }, - { - id: '3', - quote: '从需求分析到系统上线,睿新致远的团队都表现出极高的专业素养。他们的ERP系统让我们的业务流程更加标准化、透明化。', - author: '王总监', - position: '运营总监', - company: '某物流企业', - avatarUrl: '/testimonials/avatar-3.jpg', - rating: 5, - }, -]; - -export function TestimonialsSection() { - const [isVisible, setIsVisible] = useState(false); - const sectionRef = useRef(null); - - useEffect(() => { - const observer = new IntersectionObserver( - ([entry]) => { - if (entry?.isIntersecting) { - setIsVisible(true); - } - }, - { threshold: 0.1 } - ); - - if (sectionRef.current) { - observer.observe(sectionRef.current); - } - - return () => observer.disconnect(); - }, []); - - return ( -
-
-
-

- 客户评价 -

-

- 听听我们的客户怎么说 -

-
- -
- {MOCK_TESTIMONIALS.map((testimonial) => ( - - ))} -
-
-
- ); -} diff --git a/src/lib/constants/navigation.ts b/src/lib/constants/navigation.ts index f21b36c..97625a3 100644 --- a/src/lib/constants/navigation.ts +++ b/src/lib/constants/navigation.ts @@ -7,6 +7,7 @@ export interface NavigationItem { export const NAVIGATION: NavigationItem[] = [ { id: 'home', label: '首页', href: '/' }, { id: 'services', label: '核心业务', href: '/' }, + { id: 'solutions', label: '解决方案', href: '/' }, { id: 'products', label: '产品服务', href: '/' }, { id: 'cases', label: '成功案例', href: '/' }, { id: 'about', label: '关于我们', href: '/' },