- Document design audit findings and recommended direction - Add implementation plan for Bain-aligned content differentiation
570 lines
17 KiB
Markdown
570 lines
17 KiB
Markdown
# Bain 对标深化实现计划
|
||
|
||
> **面向 AI 代理的工作者:** 必需子技能:使用 superpowers:subagent-driven-development(推荐)或 superpowers:executing-plans 逐任务实现此计划。步骤使用复选框(`- [ ]`)语法来跟踪进度。
|
||
|
||
**目标:** 在不引入外部图片的前提下,通过数据可视化、结构化文案、页面模块差异化,消除产品/解决方案/服务三页的 AI 模板同质化痕迹,提升案例可信度,并确保所有测试通过。
|
||
|
||
**架构:** 数据层(`products.ts`、`solutions.ts`、`services.ts`、`cases.ts`、`cms/types.ts`)新增差异化字段;UI 层(三个列表页、`sections.tsx`、案例详情页)按新数据结构重新组织卡片布局;测试层同步更新选择器与断言。
|
||
|
||
**技术栈:** Next.js 14 App Router、React 18、TypeScript 5、Tailwind CSS 3、Framer Motion、Lucide React。
|
||
|
||
---
|
||
|
||
## 文件清单
|
||
|
||
| 文件 | 职责 |
|
||
|---|---|
|
||
| `src/lib/constants/products.ts` | 扩展 `Product` 接口与数据:场景定位、能力指标、套装分组、核心能力 pills |
|
||
| `src/lib/constants/solutions.ts` | 扩展 `Solution` 接口与数据:痛点、可量化结果、推荐产品组合 |
|
||
| `src/lib/constants/services.ts` | 调整服务数据,补充能力条目;改造流程常量结构 |
|
||
| `src/lib/constants/cases.ts` | 扩展 `CaseStudy` 接口与数据:项目周期、涉及部门、数据规模、业务问题、verified 标记 |
|
||
| `src/lib/cms/types.ts` | 同步扩展 `CaseStudyData`,与 `cases.ts` 字段保持一致 |
|
||
| `src/app/(marketing)/products/products-content-v3.tsx` | 产品页新布局:套装关系图 + 指标驱动卡片 |
|
||
| `src/app/(marketing)/solutions/solutions-content-v3.tsx` | 解决方案页新布局:问题-结果卡 + 产品组合 pills |
|
||
| `src/app/(marketing)/services/services-content-v3.tsx` | 服务页新布局:能力清单卡片 + 中文流程时间轴 |
|
||
| `src/components/content/sections.tsx` | 改造服务流程时间线:移除 uppercase 英文标签 |
|
||
| `src/components/sections/case-detail-page.tsx` | 案例详情页展示新增可验证维度 |
|
||
| `src/lib/cms/mock-data.ts`(如存在案例相关 mock) | 同步更新 CMS mock 数据,与 `cases.ts` 字段一致 |
|
||
| `e2e/` 相关测试 | 更新选择器,确保不因 DOM 结构变化失败 |
|
||
| `src/**/*.test.ts{,x}` | 更新单元测试,覆盖新字段与组件渲染 |
|
||
|
||
---
|
||
|
||
## 任务 1:扩展产品数据层
|
||
|
||
**文件:**
|
||
- 修改:`src/lib/constants/products.ts`
|
||
|
||
### 步骤 1:扩展 Product 接口
|
||
|
||
在 `Product` 接口中新增以下字段:
|
||
|
||
```typescript
|
||
export interface Product {
|
||
id: string;
|
||
name: string;
|
||
subtitle: string;
|
||
description: string;
|
||
features: string[];
|
||
benefits: string[];
|
||
// ... 已有字段
|
||
scenario?: string;
|
||
metrics?: { value: string; label: string }[];
|
||
bundle: 'enterprise' | 'standalone';
|
||
capabilities?: string[];
|
||
}
|
||
```
|
||
|
||
### 步骤 2:为每个产品填充新字段
|
||
|
||
为 6 款企业产品补充 `scenario`、`metrics`(3 项)、`bundle: 'enterprise'`、`capabilities`(3-4 项)。
|
||
为独立产品(如 NovaVis)补充 `bundle: 'standalone'`。
|
||
|
||
示例(ERP):
|
||
|
||
```typescript
|
||
scenario: '面向中大型制造与零售企业的核心运营系统',
|
||
metrics: [
|
||
{ value: '10 万级', label: 'SKU 支撑' },
|
||
{ value: '200+', label: '标准报表模板' },
|
||
{ value: '99.5%', label: '数据准确率' },
|
||
],
|
||
bundle: 'enterprise',
|
||
capabilities: ['财务核算', '采购管理', '生产计划', '库存控制'],
|
||
```
|
||
|
||
### 步骤 3:运行相关产品单元测试
|
||
|
||
运行:`npx jest --testPathPatterns=products`
|
||
预期:如测试依赖旧字段,按失败提示更新断言,不修改业务语义。
|
||
|
||
---
|
||
|
||
## 任务 2:扩展解决方案数据层
|
||
|
||
**文件:**
|
||
- 修改:`src/lib/constants/solutions.ts`
|
||
|
||
### 步骤 1:扩展 Solution 接口
|
||
|
||
```typescript
|
||
export interface Solution {
|
||
id: string;
|
||
title: string;
|
||
industry: string;
|
||
description: string;
|
||
// ... 已有字段
|
||
painPoints?: string[];
|
||
outcomes?: { value: string; label: string }[];
|
||
recommendedProducts?: string[];
|
||
}
|
||
```
|
||
|
||
### 步骤 2:为每个解决方案填充新字段
|
||
|
||
为 6 个行业解决方案补充:
|
||
- `painPoints`:1-2 个核心痛点(中文)
|
||
- `outcomes`:1-2 个可量化结果
|
||
- `recommendedProducts`:推荐产品 ID 数组(如 `['erp', 'crm', 'bi']`)
|
||
|
||
### 步骤 3:运行相关测试
|
||
|
||
运行:`npx jest --testPathPatterns=solutions`
|
||
预期:通过或按提示更新测试。
|
||
|
||
---
|
||
|
||
## 任务 3:调整服务数据层
|
||
|
||
**文件:**
|
||
- 修改:`src/lib/constants/services.ts`
|
||
|
||
### 步骤 1:为每个服务补充能力条目
|
||
|
||
在 `Service` 接口中确保有 `features` 字段用于能力清单展示。如缺少,新增 `capabilities?: string[]`。
|
||
|
||
为每个服务填充 3-4 个能力条目,例如咨询服务:
|
||
|
||
```typescript
|
||
capabilities: [
|
||
'现状诊断与数字化成熟度评估',
|
||
'业务流程重构与路线图设计',
|
||
'技术架构选型与投资回报测算',
|
||
'变革管理与落地陪跑',
|
||
],
|
||
```
|
||
|
||
### 步骤 2:调整服务流程常量
|
||
|
||
将现有流程数组:
|
||
|
||
```typescript
|
||
const SERVICE_PROCESS = [
|
||
{ step: '01', title: '需求分析', desc: '...' },
|
||
// ...
|
||
];
|
||
```
|
||
|
||
改造为:
|
||
|
||
```typescript
|
||
const SERVICE_PROCESS = [
|
||
{
|
||
phase: '需求分析',
|
||
duration: '2-3 周',
|
||
deliverables: ['业务痛点清单', '现状评估报告', '项目范围说明书'],
|
||
},
|
||
{
|
||
phase: '方案设计',
|
||
duration: '4-6 周',
|
||
deliverables: ['系统架构设计', '实施路线图', '投资测算模型'],
|
||
},
|
||
{
|
||
phase: '敏捷交付',
|
||
duration: '3-6 个月',
|
||
deliverables: ['分阶段上线版本', '用户培训材料', '数据迁移方案'],
|
||
},
|
||
{
|
||
phase: '持续支持',
|
||
duration: '长期',
|
||
deliverables: ['运维监控体系', '迭代优化计划', '知识转移文档'],
|
||
},
|
||
];
|
||
```
|
||
|
||
---
|
||
|
||
## 任务 4:扩展案例数据层
|
||
|
||
**文件:**
|
||
- 修改:`src/lib/constants/cases.ts`
|
||
- 修改:`src/lib/cms/types.ts`
|
||
|
||
### 步骤 1:扩展 CaseStudy 接口
|
||
|
||
```typescript
|
||
export interface CaseStudy {
|
||
id: string;
|
||
slug: string;
|
||
client: string;
|
||
industry: string;
|
||
companySize: string;
|
||
title: string;
|
||
subtitle: string;
|
||
challenge: string;
|
||
solution: string;
|
||
result: string;
|
||
metrics: CaseMetric[];
|
||
timeline: CaseTimelinePhase[];
|
||
services: CaseService[];
|
||
testimonial?: CaseTestimonial;
|
||
color: 'brand' | 'blue' | 'teal' | 'amber' | 'purple';
|
||
featured?: boolean;
|
||
// 新增
|
||
projectDuration?: string;
|
||
departments?: string[];
|
||
dataScale?: string;
|
||
businessProblem?: string;
|
||
verified?: boolean;
|
||
}
|
||
```
|
||
|
||
### 步骤 2:为每个案例填充可验证维度
|
||
|
||
为 `CASE_STUDIES` 中每个案例补充:
|
||
- `projectDuration`
|
||
- `departments`
|
||
- `dataScale`
|
||
- `businessProblem`(比 `challenge` 更具体的一句话)
|
||
- `verified: false`(预留字段,当前未公开验证)
|
||
|
||
### 步骤 3:同步 CMS 类型
|
||
|
||
在 `src/lib/cms/types.ts` 的 `CaseStudyData` 中新增相同字段:
|
||
|
||
```typescript
|
||
export interface CaseStudyData {
|
||
client: string;
|
||
industry: string;
|
||
companySize: string;
|
||
subtitle: string;
|
||
challenge: string;
|
||
solution: string;
|
||
result: string;
|
||
metrics: CaseMetric[];
|
||
timeline: CaseTimelinePhase[];
|
||
services: CaseService[];
|
||
testimonial?: CaseTestimonial;
|
||
color: 'brand' | 'blue' | 'teal' | 'amber' | 'purple';
|
||
featured?: boolean;
|
||
projectDuration?: string;
|
||
departments?: string[];
|
||
dataScale?: string;
|
||
businessProblem?: string;
|
||
verified?: boolean;
|
||
}
|
||
```
|
||
|
||
### 步骤 4:同步 CMS mock 数据
|
||
|
||
如果 `src/lib/cms/mock-data.ts` 或相关文件包含案例 mock 数据,同步添加新字段。
|
||
|
||
### 步骤 5:运行案例相关测试
|
||
|
||
运行:`npx jest --testPathPatterns=cases`
|
||
预期:通过或按提示更新。
|
||
|
||
---
|
||
|
||
## 任务 5:产品页 UI 改造
|
||
|
||
**文件:**
|
||
- 修改:`src/app/(marketing)/products/products-content-v3.tsx`
|
||
|
||
### 步骤 1:改造 Hero 文案
|
||
|
||
将标题中的“产品矩阵”改为问题-结果叙事。例如:
|
||
|
||
```typescript
|
||
<motion.h1 ...>
|
||
<div className="block">用自研产品组合</div>
|
||
<div className="block mt-5">
|
||
<span className="text-brand font-extrabold">支撑企业核心系统升级</span>
|
||
</div>
|
||
</motion.h1>
|
||
```
|
||
|
||
副文案强调“从数据智能到业务协同,每一款产品都经过实战验证”。
|
||
|
||
### 步骤 2:新增套装关系图模块
|
||
|
||
在 Hero 与产品卡片之间新增一个轻量模块 `BundleOverview`:
|
||
|
||
- 展示两列:企业套装(6 款产品)与专业产品(独立产品)。
|
||
- 使用小圆点 + 产品名 + 一句定位。
|
||
- 使用 CSS grid 布局,不引入图片/SVG 复杂度。
|
||
|
||
### 步骤 3:改造产品卡片
|
||
|
||
将 `ProductCard` 从图标中心改为以下结构:
|
||
|
||
```tsx
|
||
<motion.a href={`/products/${product.id}`} ...>
|
||
<div className="flex items-start justify-between mb-4">
|
||
<div>
|
||
<div className="text-xs text-text-muted mb-1">{bundleLabel}</div>
|
||
<h3 className="text-lg font-bold text-text-primary">{product.name}</h3>
|
||
</div>
|
||
<span className="px-2 py-1 text-xs bg-brand/10 text-brand">{product.bundle === 'enterprise' ? '企业套装' : '专业产品'}</span>
|
||
</div>
|
||
<p className="text-sm text-text-secondary mb-4 leading-relaxed">{product.scenario || product.description}</p>
|
||
<div className="grid grid-cols-3 gap-2 mb-4">
|
||
{product.metrics?.map((m) => (
|
||
<div key={m.label} className="text-center p-2 bg-bg-secondary">
|
||
<div className="text-lg font-bold text-text-primary">{m.value}</div>
|
||
<div className="text-xs text-text-muted">{m.label}</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
<div className="flex flex-wrap gap-2">
|
||
{product.capabilities?.map((cap) => (
|
||
<span key={cap} className="px-2 py-1 text-xs border border-border-primary text-text-secondary">{cap}</span>
|
||
))}
|
||
</div>
|
||
</motion.a>
|
||
```
|
||
|
||
移除卡片内大图标。
|
||
|
||
### 步骤 4:运行产品页相关 E2E
|
||
|
||
运行:`npx playwright test p6-missing-paths.spec.ts --config=playwright.local.config.ts --grep "产品"`
|
||
预期:通过。如因 DOM 结构变化失败,更新测试中的选择器。
|
||
|
||
---
|
||
|
||
## 任务 6:解决方案页 UI 改造
|
||
|
||
**文件:**
|
||
- 修改:`src/app/(marketing)/solutions/solutions-content-v3.tsx`
|
||
|
||
### 步骤 1:改造 Hero 文案
|
||
|
||
在副文案中增加结果承诺,例如:
|
||
|
||
```typescript
|
||
<p ...>
|
||
端到端交付可量化的业务成果。
|
||
<br className="hidden sm:block" />
|
||
基于自研产品矩阵,为制造、零售、教育、医疗、金融、物流六大行业沉淀最佳实践。
|
||
</p>
|
||
```
|
||
|
||
### 步骤 2:改造行业卡片
|
||
|
||
将 `SolutionCard` 改为问题-结果卡:
|
||
|
||
```tsx
|
||
<motion.a href={`/solutions/${solution.id}`} ...>
|
||
<div className="flex items-center gap-3 mb-4">
|
||
<Icon className="w-5 h-5 text-text-muted" />
|
||
<h3 className="text-lg font-bold text-text-primary">{solution.industry}</h3>
|
||
</div>
|
||
<div className="mb-4">
|
||
<div className="text-xs text-text-muted mb-2">核心痛点</div>
|
||
<p className="text-sm text-text-secondary leading-relaxed">{solution.painPoints?.join('、')}</p>
|
||
</div>
|
||
<div className="grid grid-cols-2 gap-2 mb-4">
|
||
{solution.outcomes?.map((o) => (
|
||
<div key={o.label} className="p-2 bg-bg-secondary">
|
||
<div className="text-base font-bold text-brand">{o.value}</div>
|
||
<div className="text-xs text-text-muted">{o.label}</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
<div className="pt-4 border-t border-border-primary">
|
||
<div className="text-xs text-text-muted mb-2">推荐产品组合</div>
|
||
<div className="flex flex-wrap gap-2">
|
||
{recommendedProductNames.map((name) => (
|
||
<span key={name} className="px-2 py-1 text-xs bg-bg-secondary text-text-secondary">{name}</span>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</motion.a>
|
||
```
|
||
|
||
### 步骤 3:运行解决方案页相关 E2E
|
||
|
||
运行:`npx playwright test --config=playwright.local.config.ts --grep "解决方案|solution"`
|
||
预期:通过。
|
||
|
||
---
|
||
|
||
## 任务 7:服务页 UI 改造
|
||
|
||
**文件:**
|
||
- 修改:`src/app/(marketing)/services/services-content-v3.tsx`
|
||
|
||
### 步骤 1:改造服务卡片
|
||
|
||
移除大图标居中设计,改为:
|
||
|
||
```tsx
|
||
<motion.a href={`/services/${service.id}`} ...>
|
||
<h3 className="text-lg font-bold text-text-primary mb-2">{service.title}</h3>
|
||
<p className="text-sm text-text-secondary mb-4 leading-relaxed">{service.description}</p>
|
||
<ul className="space-y-2 mb-4">
|
||
{service.capabilities?.slice(0, 4).map((cap) => (
|
||
<li key={cap} className="flex items-start gap-2 text-sm text-text-secondary">
|
||
<CheckCircle2 className="w-4 h-4 text-brand shrink-0 mt-0.5" />
|
||
{cap}
|
||
</li>
|
||
))}
|
||
</ul>
|
||
<div className="flex gap-4 pt-4 border-t border-border-primary">
|
||
{service.metrics?.map((m) => (
|
||
<div key={m.label}>
|
||
<div className="text-base font-bold text-text-primary">{m.value}</div>
|
||
<div className="text-xs text-text-muted">{m.label}</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</motion.a>
|
||
```
|
||
|
||
### 步骤 2:改造流程时间轴
|
||
|
||
将 `SERVICE_PROCESS` 的新结构渲染为时间轴:
|
||
|
||
```tsx
|
||
<div className="relative">
|
||
{SERVICE_PROCESS.map((step, index) => (
|
||
<div key={step.phase} className="relative pl-8 pb-12 last:pb-0">
|
||
<div className="absolute left-0 top-0 w-px h-full bg-border-primary" />
|
||
<div className="absolute left-0 top-1 w-2 h-2 -translate-x-1/2 rounded-full bg-brand" />
|
||
<div className="flex items-center gap-3 mb-2">
|
||
<h4 className="text-base font-bold text-text-primary">{step.phase}</h4>
|
||
<span className="text-xs text-text-muted">{step.duration}</span>
|
||
</div>
|
||
<div className="text-xs text-text-muted mb-2">阶段产出</div>
|
||
<ul className="space-y-1">
|
||
{step.deliverables.map((d) => (
|
||
<li key={d} className="text-sm text-text-secondary">{d}</li>
|
||
))}
|
||
</ul>
|
||
</div>
|
||
))}
|
||
</div>
|
||
```
|
||
|
||
### 步骤 3:运行服务页相关 E2E
|
||
|
||
运行:`npx playwright test --config=playwright.local.config.ts --grep "服务|service"`
|
||
预期:通过。
|
||
|
||
---
|
||
|
||
## 任务 8:sections.tsx 服务流程时间线改造
|
||
|
||
**文件:**
|
||
- 修改:`src/components/content/sections.tsx`
|
||
|
||
### 步骤 1:移除 uppercase 标签
|
||
|
||
找到流程时间线卡片中的以下代码:
|
||
|
||
```tsx
|
||
<span className="text-xs font-bold tracking-[0.2em] uppercase" style={{ color: accentColor }}>
|
||
{step.phase}
|
||
</span>
|
||
```
|
||
|
||
改为:
|
||
|
||
```tsx
|
||
<span className="text-xs font-bold text-text-muted">
|
||
{`第 ${index + 1} 阶段:${step.phase}`}
|
||
</span>
|
||
```
|
||
|
||
找到:
|
||
|
||
```tsx
|
||
<div className="text-xs text-text-muted mb-3 font-medium uppercase tracking-wider">
|
||
交付物
|
||
</div>
|
||
```
|
||
|
||
改为:
|
||
|
||
```tsx
|
||
<div className="text-xs text-text-muted mb-3 font-medium">
|
||
阶段产出
|
||
</div>
|
||
```
|
||
|
||
### 步骤 2:运行相关测试
|
||
|
||
运行:`npx jest --testPathPatterns=sections`
|
||
预期:通过。
|
||
|
||
---
|
||
|
||
## 任务 9:案例详情页展示可验证维度
|
||
|
||
**文件:**
|
||
- 修改:`src/components/sections/case-detail-page.tsx`
|
||
- 修改:`src/app/(marketing)/cases/[slug]/client.tsx`
|
||
|
||
### 步骤 1:传递新增字段
|
||
|
||
在 `client.tsx` 的 `detailData` 中新增字段:
|
||
|
||
```typescript
|
||
const detailData = {
|
||
// ... 已有字段
|
||
projectDuration: data.projectDuration,
|
||
departments: data.departments,
|
||
dataScale: data.dataScale,
|
||
businessProblem: data.businessProblem,
|
||
verified: data.verified,
|
||
};
|
||
```
|
||
|
||
### 步骤 2:改造 CaseDetailPage 组件
|
||
|
||
在案例详情页顶部(Hero 区域)增加可验证维度条:
|
||
|
||
```tsx
|
||
<div className="flex flex-wrap gap-6 text-sm text-text-secondary border-y border-border-primary py-4 mb-8">
|
||
{projectDuration && <div><span className="text-text-muted">项目周期</span> {projectDuration}</div>}
|
||
{departments && <div><span className="text-text-muted">涉及部门</span> {departments.join('、')}</div>}
|
||
{dataScale && <div><span className="text-text-muted">数据规模</span> {dataScale}</div>}
|
||
{verified && <div className="text-brand">✓ 客户授权公开</div>}
|
||
</div>
|
||
```
|
||
|
||
如 `businessProblem` 存在,在 challenge 前增加“具体业务问题”小模块。
|
||
|
||
### 步骤 3:运行案例页相关 E2E
|
||
|
||
运行:`npx playwright test --config=playwright.local.config.ts --grep "案例|case"`
|
||
预期:通过。
|
||
|
||
---
|
||
|
||
## 任务 10:全量验证
|
||
|
||
### 步骤 1:运行功能 E2E
|
||
|
||
运行:`cd e2e && npx playwright test --config=playwright.local.config.ts --project=chromium --grep-invert "visual-regression"`
|
||
预期:**171 passed**
|
||
|
||
### 步骤 2:运行单元测试
|
||
|
||
运行:`npm run test:unit`
|
||
预期:**718 passed**
|
||
|
||
### 步骤 3:类型检查与 Lint
|
||
|
||
运行:`npm run type-check && npm run lint`
|
||
预期:无错误。
|
||
|
||
### 步骤 4:构建检查
|
||
|
||
运行:`npm run build`
|
||
预期:成功。
|
||
|
||
---
|
||
|
||
## 自检清单
|
||
|
||
- [ ] `products.ts` 中每个产品都有 `bundle`、`scenario`、`metrics`、`capabilities`。
|
||
- [ ] `solutions.ts` 中每个方案都有 `painPoints`、`outcomes`、`recommendedProducts`。
|
||
- [ ] `services.ts` 中流程常量已改为 `{ phase, duration, deliverables[] }` 结构。
|
||
- [ ] `cases.ts` 与 `cms/types.ts` 的 `CaseStudyData` 字段保持一致。
|
||
- [ ] 三个列表页卡片不再以大图标为中心。
|
||
- [ ] `services-content-v3.tsx` 中不再出现 `01/02/03/04`。
|
||
- [ ] `sections.tsx` 中不再出现 `uppercase` 阶段标签和“交付物”uppercase 标签。
|
||
- [ ] 全量 E2E、单元测试、type-check、lint 通过。
|