diff --git a/README.md b/README.md index d0339dc..a811a33 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ - 方向:官网品牌宣传为主,产品矩阵页保留为聚合入口——每产品一句话定位 + 指标证据 + 外链独立站 - 成熟产品走 `externalUrl` 外链(NovaVis → novavis.p.novalon.cn 已实践);未成熟产品官网详情页占位,独立站上线后切换外链 - 参照案例(已核实):IHG 品牌组合页、字节跳动 bytedance.com/products、腾讯 tencent.com/business.html(模式 B:品牌+品牌矩阵聚合页);对照金蝶/用友(模式 C:产品为主,官网承载详情与转化) - - **实施状态**:Phase 1 机制(externalUrl 外链)已就绪;Phase 2 产品矩阵页品牌化改造已完成(`30018bf`);Phase 3 全站对齐核查通过(导航产品入口 / 首页 CTA / 方案页产品组合均已符合品牌化,无需改动);Phase 4 SEO 机制就绪(standalone 外链 redirect、sitemap 已排除外链产品);**信任证据(案例/方法论)为内容待办,待真实素材补齐** + - **实施状态**:Phase 1 机制(externalUrl 外链)已就绪;Phase 2 产品矩阵页品牌化改造已完成(`30018bf`);Phase 3 全站对齐核查通过(导航产品入口 / 首页 CTA / 方案页产品组合均已符合品牌化,无需改动);Phase 4 SEO 机制就绪(standalone 外链 redirect、sitemap 收录 /methodology);**信任证据**:方法论已 CMS 化并上线 /methodology 页面骨架(methodology 内容模型 + 首页 CTA 指向),案例与量化成果待真实素材补齐 ## 项目进度 @@ -173,7 +173,8 @@ - [x] **最终验收确认 (2026-08-02)**:type-check ✅ / lint 0 errors ✅ / 单元测试 90 suites / 1217 tests ✅ / 集成测试 11 suites / 96 tests ✅ / 覆盖率阈值达标 ✅ - [x] **文档同步 (2026-08-02)**:test-strategy-plan.md 版本 1.5,已标记已实现项,保留真实缺口 - [x] **官网产品模块定位决策(2026-08-19)**:确认 IHG/字节式品牌矩阵方向(品牌宣传为主 + 产品矩阵聚合页保留 + 成熟产品外链独立站),已写入 CONTEXT.md / README.md;Phase 0 文档化 + Phase 2 矩阵页品牌化改造完成,Phase 3 全站核查通过,Phase 4 SEO 机制就绪 -- [ ] **信任证据补齐(Phase 4 内容待办)**:首批客户共创案例、方法论/白皮书内容、可量化成果——需提供真实素材后实施(零编造原则) +- [x] **方法论 CMS 化(Phase 4 信任证据·方法论骨架)**:新增 `methodology` 内容模型 + `/methodology` 页面骨架(Hero / 四阶段 / 空态 / CTA),首页 CTA「了解我们的方法论」指向 /methodology,sitemap 收录,视觉基线已生成 +- [ ] **信任证据补齐(Phase 4 内容待办)**:首批客户共创案例与可量化成果——需提供真实素材后实施(零编造原则) ## 技术栈 diff --git a/e2e/visual-regression.spec.ts b/e2e/visual-regression.spec.ts index c574653..73e954d 100644 --- a/e2e/visual-regression.spec.ts +++ b/e2e/visual-regression.spec.ts @@ -15,6 +15,7 @@ const VISUAL_TEST_PAGES = [ { path: '/news', name: 'news', label: '新闻列表' }, { path: '/news/company-founded', name: 'news-detail', label: '新闻详情' }, { path: '/team', name: 'team', label: '团队介绍' }, + { path: '/methodology', name: 'methodology', label: '方法论' }, ]; async function waitForPageStable(page: Page) { diff --git a/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/methodology-fullpage-visual-chromium-desktop.png b/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/methodology-fullpage-visual-chromium-desktop.png new file mode 100644 index 0000000..ab4d6aa Binary files /dev/null and b/e2e/visual-snapshots/visual-chromium-desktop/visual-regression.spec.ts/methodology-fullpage-visual-chromium-desktop.png differ diff --git a/prisma/seed.ts b/prisma/seed.ts index 9118d88..2eb7c8f 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -12,6 +12,7 @@ import { STANDALONE_PRODUCTS } from './seeds/standalone-products'; import { SOLUTIONS } from './seeds/solutions'; import { STATS } from '../src/lib/constants/stats'; import { COMPANY_INFO } from '../src/lib/constants/company'; +import { METHODOLOGY } from '../src/lib/constants/methodology'; import { NAVIGATION_V2, MEGA_DROPDOWN_DATA } from '../src/lib/constants/navigation'; const prisma = new PrismaClient(); @@ -231,6 +232,7 @@ async function main() { 'stat-item', 'standalone-product', 'media', + 'methodology', ]; // 为 super_admin 之外的角色创建权限 @@ -518,6 +520,32 @@ async function main() { ], }, }, + // === methodology === + { + model: { + code: 'methodology', + name: '方法论', + description: '实施方法论 — 四阶段模型(诊断→规划→实施→优化)', + isPageType: true, + urlPattern: '/methodology', + hasVersions: false, + hasDraft: true, + icon: 'route', + fields: [ + { name: 'heroSubtitle', type: 'text', label: 'Hero 标签', required: true }, + { name: 'heroTitle', type: 'textarea', label: 'Hero 主标题', required: true }, + { name: 'heroDescription', type: 'textarea', label: 'Hero 描述', required: true }, + { name: 'phases', type: 'array', label: '方法论阶段', required: true, fields: [ + { name: 'number', type: 'number', label: '序号' }, + { name: 'title', type: 'text', label: '阶段标题', required: true }, + { name: 'subtitle', type: 'text', label: '副标题' }, + { name: 'description', type: 'textarea', label: '阶段描述', required: true }, + { name: 'activities', type: 'json', label: '核心活动', description: 'JSON 字符串数组' }, + { name: 'deliverables', type: 'json', label: '交付物', description: 'JSON 字符串数组' }, + ]}, + ], + }, + }, ]; for (let i = 0; i < modelConfigs.length; i++) { @@ -565,7 +593,7 @@ async function main() { ctaLabel: '预约咨询', ctaHref: '/contact', secondaryCtaLabel: '了解我们的方法论', - secondaryCtaHref: '/services/consulting', + secondaryCtaHref: '/methodology', statValue: '2026', statSubtext: '年正式成立', ctaTitleLine1: '每一次合作,', @@ -582,6 +610,26 @@ async function main() { await seedItems('case-study', CASE_STUDIES as unknown as Record[]); console.log(` ✅ ${CASE_STUDIES.length} 个案例`); + console.log('📝 导入方法论...'); + await seedItems('methodology', [ + { + slug: 'default', + title: '实施方法论', + heroSubtitle: '方法论', + heroTitle: '从诊断到优化\n四阶段推进\n数字化转型', + heroDescription: '基于行业通用框架与核心团队实践,我们以「诊断评估 → 战略规划 → 落地实施 → 持续优化」四阶段推进每个项目,确保每个环节都有可衡量的交付。', + phases: METHODOLOGY.map((p) => ({ + number: p.number, + title: p.title, + subtitle: p.subtitle, + description: p.description, + activities: p.activities, + deliverables: p.deliverables, + })), + }, + ]); + console.log(' ✅ 方法论(四阶段模型)'); + console.log('📝 导入新闻...'); await seedItems('news', NEWS as unknown as Record[]); console.log(` ✅ ${NEWS.length} 条新闻`); diff --git a/src/app/(marketing)/methodology/methodology-content.test.tsx b/src/app/(marketing)/methodology/methodology-content.test.tsx new file mode 100644 index 0000000..d57874f --- /dev/null +++ b/src/app/(marketing)/methodology/methodology-content.test.tsx @@ -0,0 +1,121 @@ +import { describe, it, expect, jest } from '@jest/globals'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; + +// ─── Mocks ─────────────────────────────────────────────────────────────── + +jest.mock('framer-motion', () => ({ + motion: { + div: ({ children, className, style, ...props }: any) => ( +
{children}
+ ), + h1: ({ children, className, ...props }: any) => ( +

{children}

+ ), + p: ({ children, className, ...props }: any) => ( +

{children}

+ ), + }, + useInView: jest.fn(() => true), + AnimatePresence: ({ children }: any) => <>{children}, +})); + +jest.mock('@/components/ui/scroll-reveal', () => ({ + ScrollReveal: ({ children, className }: any) => ( +
{children}
+ ), + StaggerReveal: ({ children, className }: any) => ( +
{children}
+ ), +})); + +jest.mock('@/components/ui/button', () => ({ + Button: ({ children, className, ...props }: any) => ( + + ), +})); + +jest.mock('@/components/ui/page-decoration', () => ({ + EASE_OUT: [0.22, 1, 0.36, 1], +})); + +jest.mock('lucide-react', () => { + const mockIcon = (name: string) => { + const Icon = (props: any) => ; + Icon.displayName = name; + return Icon; + }; + return { + ArrowRight: mockIcon('arrow-right'), + CheckCircle2: mockIcon('check-circle2'), + }; +}); + +// ─── Mock Data ──────────────────────────────────────────────────────────── + +const mockData = { + heroSubtitle: '方法论', + heroTitle: '四阶段推进数字化转型', + heroDescription: '从诊断到优化,步步可衡量。', + phases: [ + { + number: 1, + title: '诊断评估', + subtitle: '了解现状,找准痛点', + description: '深入调研企业现状,识别关键痛点。', + activities: ['业务流程调研', 'IT基础设施评估'], + deliverables: ['成熟度评估报告', '关键痛点清单'], + }, + { + number: 2, + title: '战略规划', + subtitle: '明确方向,制定路线', + description: '制定匹配企业战略的转型路线图。', + activities: ['IT战略对齐'], + deliverables: ['战略规划书'], + }, + ], +}; + +// ─── Tests ──────────────────────────────────────────────────────────────── + +describe('MethodologyContent - 方法论页面', () => { + it('should render hero section', async () => { + const { MethodologyContent } = await import('./methodology-content'); + render(); + + expect(screen.getByText('方法论')).toBeInTheDocument(); + expect(screen.getByText('四阶段推进数字化转型')).toBeInTheDocument(); + expect(screen.getByText('从诊断到优化,步步可衡量。')).toBeInTheDocument(); + }); + + it('should render all methodology phases with activities and deliverables', async () => { + const { MethodologyContent } = await import('./methodology-content'); + render(); + + expect(screen.getByText('诊断评估')).toBeInTheDocument(); + expect(screen.getByText('战略规划')).toBeInTheDocument(); + expect(screen.getAllByText('核心活动').length).toBeGreaterThanOrEqual(1); + expect(screen.getAllByText('交付物').length).toBeGreaterThanOrEqual(1); + expect(screen.getByText('业务流程调研')).toBeInTheDocument(); + expect(screen.getByText('成熟度评估报告')).toBeInTheDocument(); + }); + + it('should render empty state when phases are missing', async () => { + const { MethodologyContent } = await import('./methodology-content'); + render(); + + expect(screen.getByText('方法论内容即将发布')).toBeInTheDocument(); + }); + + it('should render CTA links to services and contact', async () => { + const { MethodologyContent } = await import('./methodology-content'); + render(); + + const links = screen.getAllByRole('link'); + expect(links.some((l) => l.getAttribute('href') === '/services')).toBe(true); + expect(links.some((l) => l.getAttribute('href') === '/contact')).toBe(true); + }); +}); diff --git a/src/app/(marketing)/methodology/methodology-content.tsx b/src/app/(marketing)/methodology/methodology-content.tsx new file mode 100644 index 0000000..036a88a --- /dev/null +++ b/src/app/(marketing)/methodology/methodology-content.tsx @@ -0,0 +1,171 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { ScrollReveal, StaggerReveal } from '@/components/ui/scroll-reveal'; +import { EASE_OUT } from '@/components/ui/page-decoration'; +import { Button } from '@/components/ui/button'; +import { ArrowRight, CheckCircle2 } from 'lucide-react'; + +interface MethodologyPhase { + number?: number; + title: string; + subtitle?: string; + description?: string; + activities?: string[]; + deliverables?: string[]; +} + +interface MethodologyContentProps { + data: Record | null; +} + +export function MethodologyContent({ data }: MethodologyContentProps) { + const heroSubtitle = data?.heroSubtitle || '方法论'; + const heroTitle = data?.heroTitle || '从诊断到优化\n四阶段推进数字化转型'; + const heroDescription = data?.heroDescription || ''; + const phases: MethodologyPhase[] = Array.isArray(data?.phases) ? data.phases : []; + + return ( +
+ {/* Hero:品牌化定位,轻量 CTA */} +
+
+
+ + {heroSubtitle} + + + {heroTitle} + + + {heroDescription} + +
+
+
+ + {/* 阶段骨架:四阶段 Cards,空态占位 */} +
+
+
+
+ +

+ 四阶段推进,步步可衡量 +

+

+ 每个阶段都有明确的交付物与验证标准,确保转型过程可控、结果可量化。 +

+
+ + {phases.length > 0 ? ( +
+
+ + {phases.map((phase, idx) => ( + +
+
+ {phase.number ?? idx + 1} +
+

{phase.title}

+ {phase.subtitle && ( +

{phase.subtitle}

+ )} + {phase.description && ( +

{phase.description}

+ )} + + {phase.activities?.length ? ( +
+

核心活动

+
    + {phase.activities.map((activity, i) => ( +
  • + + {activity} +
  • + ))} +
+
+ ) : null} + + {phase.deliverables?.length ? ( +
+

交付物

+
    + {phase.deliverables.map((deliverable, i) => ( +
  • + + {deliverable} +
  • + ))} +
+
+ ) : null} +
+
+ ))} +
+
+ ) : ( +
+

方法论内容即将发布

+

+ 我们正在沉淀与首批客户共创过程中的方法论实践,完成后将在此呈现完整框架。 +

+
+ )} +
+
+ + {/* CTA:轻量导向服务与联系 */} +
+
+
+ +

+ 与方法论匹配的专业服务 +

+

+ 我们的咨询服务贯穿方法论的每个阶段,从战略规划到落地实施全程陪伴。 +

+ +
+
+
+
+ ); +} diff --git a/src/app/(marketing)/methodology/page.tsx b/src/app/(marketing)/methodology/page.tsx new file mode 100644 index 0000000..325a6f9 --- /dev/null +++ b/src/app/(marketing)/methodology/page.tsx @@ -0,0 +1,18 @@ +import { Metadata } from 'next'; +import { COMPANY_INFO } from '@/lib/constants'; +import { getPublishedItems } from '@/lib/cms/data-server'; +import { MethodologyContent } from './methodology-content'; + +export const metadata: Metadata = { + title: `实施方法论 - ${COMPANY_INFO.displayName}`, + description: `了解${COMPANY_INFO.name}的实施方法论:诊断评估、战略规划、落地实施、持续优化四阶段模型,确保数字化项目可衡量落地。`, +}; + +// ISR:生产环境每 1 小时自动重新验证,CMS 发布/更新时通过 /api/cms/revalidate 主动刷新 +export const revalidate = 3600; + +export default async function MethodologyPage() { + const items = await getPublishedItems('methodology'); + const data = items[0]?.data ?? null; + return ; +} diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts index ecbd3c3..c4b9d1b 100644 --- a/src/app/sitemap.ts +++ b/src/app/sitemap.ts @@ -13,6 +13,7 @@ export default async function sitemap(): Promise { { url: `${BASE_URL}/cases`, lastModified: new Date(), changeFrequency: 'weekly', priority: 0.8 }, { url: `${BASE_URL}/news`, lastModified: new Date(), changeFrequency: 'daily', priority: 0.7 }, { url: `${BASE_URL}/team`, lastModified: new Date(), changeFrequency: 'monthly', priority: 0.6 }, + { url: `${BASE_URL}/methodology`, lastModified: new Date(), changeFrequency: 'monthly', priority: 0.6 }, { url: `${BASE_URL}/contact`, lastModified: new Date(), changeFrequency: 'monthly', priority: 0.7 }, ]; diff --git a/src/lib/cms/content-types.ts b/src/lib/cms/content-types.ts index 2a279ba..b875296 100644 --- a/src/lib/cms/content-types.ts +++ b/src/lib/cms/content-types.ts @@ -1536,6 +1536,42 @@ const legalPageFields: FieldDefinition[] = [ }, ]; +const methodologyFields: FieldDefinition[] = [ + { + name: 'heroSubtitle', + type: 'text', + label: 'Hero 标签', + required: true, + }, + { + name: 'heroTitle', + type: 'textarea', + label: 'Hero 主标题', + required: true, + }, + { + name: 'heroDescription', + type: 'textarea', + label: 'Hero 描述', + required: true, + }, + { + name: 'phases', + type: 'array', + label: '方法论阶段', + description: '四阶段推进模型,如 诊断评估 → 战略规划 → 落地实施 → 持续优化', + required: true, + fields: [ + { name: 'number', type: 'number', label: '序号' }, + { name: 'title', type: 'text', label: '阶段标题', required: true }, + { name: 'subtitle', type: 'text', label: '副标题' }, + { name: 'description', type: 'textarea', label: '阶段描述', required: true }, + { name: 'activities', type: 'json', label: '核心活动', description: 'JSON 字符串数组' }, + { name: 'deliverables', type: 'json', label: '交付物', description: 'JSON 字符串数组' }, + ], + }, +]; + const newsConfig: ContentTypeConfig = { model: { id: 'model-news', @@ -1770,6 +1806,26 @@ const legalPageConfig: ContentTypeConfig = { }, }; +const methodologyConfig: ContentTypeConfig = { + model: { + id: 'model-methodology', + code: 'methodology', + name: '方法论', + description: '实施方法论 — 四阶段模型(诊断→规划→实施→优化)', + fields: methodologyFields, + isPageType: true, + urlPattern: '/methodology', + hasVersions: false, + hasDraft: true, + icon: 'route', + createdAt: '2024-01-01T00:00:00Z', + updatedAt: '2024-01-01T00:00:00Z', + }, + listPage: { + route: '/methodology', + }, +}; + /** @deprecated 旧客户端 CMS 的注册函数,已不再需要 */ export function registerAllContentTypes(): void { // no-op — 数据模型定义已全部移至 CONTENT_TYPE_CONFIGS @@ -1788,4 +1844,5 @@ export const CONTENT_TYPE_CONFIGS = { 'team-page': teamPageConfig, 'contact-page': contactPageConfig, 'legal-page': legalPageConfig, + methodology: methodologyConfig, };