Files
makemd/docs/01_Architecture/11_Mock_Architecture.md
wurenzhi eafa1bbe94 feat: 添加货币和汇率管理功能
refactor: 重构前端路由和登录逻辑

docs: 更新业务闭环、任务和架构文档

style: 调整代码格式和文件结构

chore: 更新依赖项和配置文件
2026-03-19 19:08:15 +08:00

830 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 低侵入 Mock 架构设计
> 文档创建时间: 2026-03-19 (北京时间)
> 适用项目: Crawlful Hub
> 目标: 实现"不污染代码、AI上下文安全"的Mock方案
---
## 📋 目录
1. [核心原则](#核心原则)
2. [架构概览](#架构概览)
3. [前端Mock方案](#前端mock方案)
4. [后端/BFF Mock方案](#后端bff-mock方案)
5. [目录规范](#目录规范)
6. [AI协作规范](#ai协作规范)
7. [实施任务](#实施任务)
---
## 核心原则
### 1. Mock ≠ 写死数据
**错误做法**: 在组件中直接写死数据
```typescript
const data = [{ id: 1, name: 'Mock商品' }]
```
**正确做法**: 通过数据源抽象层获取
```typescript
const data = await productDataSource.list()
```
### 2. Mock 必须"可插拔"
Mock 应该是:
- ✅ 可开启 / 可关闭
- ✅ 可替换 / 可隔离
- ✅ 环境变量控制
### 3. Mock 属于"数据源层",不是"业务层"
```
业务代码 → DataSource抽象层 → (Mock/真实API)
```
---
## 架构概览
### 三层数据架构
```
┌─────────────────────────────────────────────────────────────┐
│ 前端 (React + Umi) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 业务组件 │ → │ DataSource │ → │ API/Mock │ │
│ │ │ │ 抽象层 │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ BFF 层 (服务编排层) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Service │ → │ Mock切换 │ → │ 真实/Mock │ │
│ │ │ │ │ │ 服务 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 后端微服务层 │
└─────────────────────────────────────────────────────────────┘
```
### Mock 分布策略
| 层级 | 是否Mock | 说明 |
|------|---------|------|
| 前端 | ⚠️ 可选 | 推荐用MSW保持业务代码纯净 |
| DataSource | ✅ 可切换 | 控制入口,环境变量驱动 |
| BFF | ✅ 主力Mock | 最真实,前端无感知 |
| 后端 | ❌ 不建议 | 除非联调测试 |
---
## 前端Mock方案
### 项目实际采用的两种Mock方式
本项目采用**两种Mock方式并存**的策略,根据不同模块的特点选择合适的方案:
#### 方式一DataSource内联Mock推荐用于简单模块
**特点**Mock数据直接写在DataSource文件中通过环境变量切换
**适用场景**
- ✅ 数据结构简单,不需要复杂的网络拦截
- ✅ 快速原型开发无需配置MSW
- ✅ Mock逻辑简单不需要模拟网络延迟和错误
**实现示例**
```typescript
// /dashboard/src/services/productDataSource.ts
class MockProductDataSource implements IProductDataSource {
async fetchProducts(): Promise<Product[]> {
// Mock数据直接内联
return [
{ id: '1', name: '商品A', price: 99.99 },
{ id: '2', name: '商品B', price: 199.99 },
];
}
}
class ApiProductDataSource implements IProductDataSource {
async fetchProducts(): Promise<Product[]> {
const res = await fetch('/api/products');
return res.json();
}
}
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
export const productDataSource = useMock ? new MockProductDataSource() : new ApiProductDataSource();
```
**已实现的模块**
- 产品模块 (productDataSource.ts)
- 订单模块 (orderDataSource.ts)
- 库存模块 (inventoryDataSource.ts)
- 商户模块 (merchantDataSource.ts)
- 供应商模块 (suppliersDataSource.ts)
- 物流模块 (logisticsDataSource.ts)
- 营销模块 (marketingDataSource.ts)
- 财务模块 (financeDataSource.ts)
- 报表模块 (reportsDataSource.ts)
- 设置模块 (settingsDataSource.ts)
- 售后模块 (afterSalesDataSource.ts)
- 返回模块 (returnDataSource.ts)
- 用户资产模块 (userAssetDataSource.ts)
- 任务中心模块 (taskCenterDataSource.ts)
- 分析模块 (analyticsDataSource.ts)
- B2B贸易模块 (b2bTradeDataSource.ts)
- 排行榜模块 (leaderboardDataSource.ts)
- 动态定价模块 (dynamicPricingDataSource.ts)
- 套利模块 (arbitrageDataSource.ts)
- 店铺报表模块 (shopReportDataSource.ts)
- 自动执行模块 (autoExecutionDataSource.ts)
- 广告优化模块 (adOptimizationDataSource.ts)
- AB测试模块 (abTestDataSource.ts)
- 黑名单模块 (blacklistDataSource.ts)
- 独立站点模块 (independentSiteDataSource.ts)
#### 方式二MSW网络层Mock推荐用于复杂模块
**特点**使用MSW拦截HTTP请求Mock数据独立在 `/mock/data/` 目录
**适用场景**
- ✅ 需要模拟真实的网络请求和响应
- ✅ 需要模拟网络延迟、错误状态
- ✅ 需要支持复杂的查询参数和分页
- ✅ 需要多个组件共享同一Mock数据
**实现示例**
```typescript
// /dashboard/src/mock/data/certificate.mock.ts
export const mockCertificates = [...];
// /dashboard/src/mock/msw.ts
export const handlers = [
rest.get('/api/v1/certificate/certificates', (req, res, ctx) => {
return res(
ctx.delay(300), // 模拟网络延迟
ctx.json({ success: true, data: mockCertificates })
);
}),
];
// /dashboard/src/app.ts
if (process.env.REACT_APP_USE_MOCK === 'true') {
const { worker } = await import('./mock/browser');
await worker.start();
}
```
**已实现的模块**
- 证书模块 (certificateDataSource.ts + msw.ts)
- 自动选品模块 (productSelectionDataSource.ts + msw.ts)
### 方案对比
| 方案 | 侵入性 | 推荐度 | 适用场景 |
|------|--------|--------|----------|
| DataSource内联Mock | ⭐⭐ 低 | 🥈 推荐 | 简单模块、快速原型 |
| MSW网络层Mock | ⭐ 最低 | 🥇 最推荐 | 复杂模块、UI测试 |
| 本地Mock Server | ⭐⭐⭐ 中 | 🥉 可选 | 团队共享Mock |
| 硬编码 | ❌ 高 | 🚫 不推荐 | 绝对禁止 |
### 推荐方案:根据模块复杂度选择
#### 1. 目录结构
```
/dashboard/src
/api ← 真实API封装可选
*.ts
/mock ← MSW Mock数据和拦截器
/data ← Mock数据文件仅MSW方式使用
certificate.mock.ts
productSelection.mock.ts
msw.ts ← MSW初始化配置
browser.ts ← 浏览器环境启动
README.md ← Mock使用说明
/services ← 数据源抽象层(所有模块)
*DataSource.ts ← 包含Mock和API两种实现
/types ← 类型定义
datasource.ts ← DataSource接口定义
```
#### 2. DataSource接口定义
```typescript
// /dashboard/src/types/datasource.ts
/**
* [MOCK-001] DataSource抽象接口
* 所有数据源必须实现此接口
* AI注意: 这是抽象层,不涉及具体实现
*/
export interface IDataSource<T, QueryParams = any> {
list(params?: QueryParams): Promise<T[]>;
detail(id: string): Promise<T | null>;
create(data: Partial<T>): Promise<T>;
update(id: string, data: Partial<T>): Promise<T>;
delete(id: string): Promise<void>;
}
export interface ProductQueryParams {
keyword?: string;
category?: string;
status?: string;
page?: number;
pageSize?: number;
}
export interface CertificateQueryParams {
status?: string;
type?: string;
page?: number;
pageSize?: number;
}
```
#### 3. DataSource抽象层实现
```typescript
// /dashboard/src/services/certificateDataSource.ts
import { Certificate } from '@/types/certificate';
import { IDataSource, CertificateQueryParams } from '@/types/datasource';
/**
* [MOCK-002] 证书数据源抽象层
* 通过环境变量自动切换Mock/真实API
* AI注意: 这是唯一入口,业务代码必须调用此层
*/
// 真实API实现
class ApiCertificateDataSource implements IDataSource<Certificate, CertificateQueryParams> {
async list(params?: CertificateQueryParams): Promise<Certificate[]> {
const query = new URLSearchParams(params as any).toString();
const response = await fetch(`/api/v1/certificate/certificates?${query}`);
const result = await response.json();
return result.data || [];
}
async detail(id: string): Promise<Certificate | null> {
const response = await fetch(`/api/v1/certificate/certificates/${id}`);
const result = await response.json();
return result.data || null;
}
async create(data: Partial<Certificate>): Promise<Certificate> {
const response = await fetch('/api/v1/certificate/certificates', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
const result = await response.json();
return result.data;
}
async update(id: string, data: Partial<Certificate>): Promise<Certificate> {
const response = await fetch(`/api/v1/certificate/certificates/${id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
const result = await response.json();
return result.data;
}
async delete(id: string): Promise<void> {
await fetch(`/api/v1/certificate/certificates/${id}`, {
method: 'DELETE',
});
}
}
// Mock实现 (完全独立文件)
class MockCertificateDataSource implements IDataSource<Certificate, CertificateQueryParams> {
private mockData: Certificate[] = [
{
id: '1',
name: 'CE认证证书',
type: 'PRODUCT_CERT',
status: 'APPROVED',
fileUrl: '/files/ce-cert.pdf',
fileName: 'CE-Certificate-2026.pdf',
uploadDate: '2026-03-15',
expiryDate: '2027-03-15',
approvedBy: 'admin',
approvedDate: '2026-03-16',
productId: 'P001',
productName: '工业温度传感器',
notes: '欧盟市场准入认证',
},
// ... 更多Mock数据
];
async list(params?: CertificateQueryParams): Promise<Certificate[]> {
// 模拟网络延迟
await new Promise(resolve => setTimeout(resolve, 300));
let result = [...this.mockData];
if (params?.status) {
result = result.filter(item => item.status === params.status);
}
if (params?.type) {
result = result.filter(item => item.type === params.type);
}
return result;
}
async detail(id: string): Promise<Certificate | null> {
await new Promise(resolve => setTimeout(resolve, 200));
return this.mockData.find(item => item.id === id) || null;
}
async create(data: Partial<Certificate>): Promise<Certificate> {
await new Promise(resolve => setTimeout(resolve, 500));
const newCert: Certificate = {
id: `${Date.now()}`,
...data as Certificate,
status: 'PENDING',
uploadDate: new Date().toISOString().split('T')[0],
};
this.mockData.unshift(newCert);
return newCert;
}
async update(id: string, data: Partial<Certificate>): Promise<Certificate> {
await new Promise(resolve => setTimeout(resolve, 300));
const index = this.mockData.findIndex(item => item.id === id);
if (index === -1) throw new Error('Certificate not found');
this.mockData[index] = { ...this.mockData[index], ...data };
return this.mockData[index];
}
async delete(id: string): Promise<void> {
await new Promise(resolve => setTimeout(resolve, 200));
this.mockData = this.mockData.filter(item => item.id !== id);
}
}
// 导出数据源实例 (环境变量控制)
const useMock = process.env.REACT_APP_USE_MOCK === 'true';
export const certificateDataSource: IDataSource<Certificate, CertificateQueryParams> = useMock
? new MockCertificateDataSource()
: new ApiCertificateDataSource();
// 标记Mock状态 (用于调试)
export const __MOCK__ = useMock;
```
#### 4. MSW配置
```typescript
// /dashboard/src/mock/msw.ts
import { setupWorker, rest } from 'msw';
import { mockCertificates } from './data/certificate.mock';
/**
* [MOCK-003] MSW Mock配置
* 拦截HTTP请求返回Mock数据
* AI注意: 这是网络层拦截,业务代码完全无感知
*/
export const worker = setupWorker(
// 证书列表
rest.get('/api/v1/certificate/certificates', (req, res, ctx) => {
const status = req.url.searchParams.get('status');
const type = req.url.searchParams.get('type');
let data = [...mockCertificates];
if (status) data = data.filter(item => item.status === status);
if (type) data = data.filter(item => item.type === type);
return res(
ctx.delay(300),
ctx.json({
success: true,
data,
total: data.length,
})
);
}),
// 证书详情
rest.get('/api/v1/certificate/certificates/:id', (req, res, ctx) => {
const { id } = req.params;
const cert = mockCertificates.find(item => item.id === id);
if (!cert) {
return res(
ctx.status(404),
ctx.json({ success: false, error: '证书不存在' })
);
}
return res(
ctx.delay(200),
ctx.json({ success: true, data: cert })
);
}),
// 创建证书
rest.post('/api/v1/certificate/certificates', async (req, res, ctx) => {
const body = await req.json();
const newCert = {
id: `${Date.now()}`,
...body,
status: 'PENDING',
uploadDate: new Date().toISOString().split('T')[0],
};
return res(
ctx.delay(500),
ctx.json({ success: true, data: { id: newCert.id } })
);
}),
// 更新证书状态
rest.put('/api/v1/certificate/certificates/:id/status', async (req, res, ctx) => {
const { id } = req.params;
const { status, approvedBy } = await req.json();
return res(
ctx.delay(300),
ctx.json({ success: true })
);
}),
// 删除证书
rest.delete('/api/v1/certificate/certificates/:id', (req, res, ctx) => {
return res(
ctx.delay(200),
ctx.json({ success: true })
);
})
);
```
```typescript
// /dashboard/src/mock/browser.ts
import { worker } from './msw';
export { worker };
```
```typescript
// /dashboard/src/index.tsx (入口文件)
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
/**
* [MOCK-004] MSW启动配置
* 仅在REACT_APP_USE_MOCK=true时启用
*/
async function enableMocking() {
if (process.env.REACT_APP_USE_MOCK !== 'true') {
return;
}
const { worker } = await import('./mock/browser');
return worker.start({
onUnhandledRequest: 'bypass', // 未拦截的请求直接透传
});
}
enableMocking().then(() => {
const root = ReactDOM.createRoot(document.getElementById('root')!);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
});
```
#### 5. 业务组件使用示例
```typescript
// /dashboard/src/pages/Compliance/index.tsx
import { certificateDataSource } from '@/services/certificateDataSource';
const ComplianceManagement: React.FC = () => {
const fetchData = useCallback(async () => {
setLoading(true);
try {
// 调用DataSource层完全无感知是Mock还是真实API
const data = await certificateDataSource.list({
status: activeStatus,
type: activeType,
});
setCertificates(data);
} catch (error) {
message.error('获取证书列表失败');
} finally {
setLoading(false);
}
}, [activeStatus, activeType]);
const handleUploadSubmit = async () => {
try {
const values = await uploadForm.validateFields();
await certificateDataSource.create({
name: values.name,
type: values.type,
expiryDate: values.expiryDate.format('YYYY-MM-DD'),
productId: values.productId,
productName: values.productName,
notes: values.notes,
});
message.success('证书上传成功');
fetchData();
} catch (error) {
message.error('上传失败');
}
};
// ... 其他逻辑
};
```
---
## 后端/BFF Mock方案
### 架构设计
```
BFF层
├─ Service (业务逻辑)
├─ Mock切换器 (环境变量控制)
├─ 真实API客户端
└─ Mock服务
```
### 实现示例
```typescript
// /server/src/bff/services/certificateService.ts
import { CertificateService as RealCertificateService } from '../../services/CertificateService';
import { MockCertificateService } from '../mock/certificateMock';
/**
* [MOCK-005] BFF层证书服务
* 通过环境变量自动切换Mock/真实服务
*/
const useMock = process.env.USE_MOCK === 'true';
export const certificateService = useMock
? new MockCertificateService()
: new RealCertificateService();
// 类型导出,确保调用方类型安全
export type ICertificateService = typeof certificateService;
```
```typescript
// /server/src/bff/mock/certificateMock.ts
import { ICertificateService } from '../services/certificateService';
/**
* [MOCK-006] BFF层Mock服务
* 完全独立的Mock实现
* AI注意: 这是Mock实现不是真实业务逻辑
*/
export class MockCertificateService implements ICertificateService {
private mockData = [
// ... Mock数据
];
async query(options: any) {
await this.delay(300);
return {
items: this.mockData,
total: this.mockData.length,
};
}
async getById(id: string, tenantId: string, shopId: string) {
await this.delay(200);
return this.mockData.find(item => item.id === id) || null;
}
async create(input: any) {
await this.delay(500);
const id = `mock-${Date.now()}`;
// ... 创建逻辑
return id;
}
private delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
```
---
## 目录规范
### 前端目录规范
```
/dashboard/src
/mock ← 所有Mock相关
/data ← Mock数据定义
*.mock.ts
msw.ts ← MSW配置
browser.ts ← 浏览器入口
server.ts ← Node/测试入口
README.md ← Mock使用说明
/services ← DataSource抽象层
*DataSource.ts
/api ← 真实API封装
*.ts
```
### 后端目录规范
```
/server/src
/bff ← BFF层
/mock ← Mock服务
*.ts
/services ← 服务层
*.ts
/api ← API客户端
*.ts
/services ← 真实服务
*.ts
```
### 标记规范
所有Mock文件必须包含以下标记:
```typescript
/**
* [MOCK-XXX] 功能描述
* AI注意: 这是Mock实现不是真实业务逻辑
* 仅在USE_MOCK=true时启用
*/
// 或者
// [MOCK] 此文件为Mock数据AI请勿当作真实业务逻辑
```
---
## AI协作规范
### 1. Mock文件识别规则
AI在分析代码时:
- ✅ 忽略 `/mock` 目录下所有文件
- ✅ 忽略包含 `[MOCK]` 标记的文件
- ✅ 忽略 `__MOCK__` 变量为真的代码路径
### 2. 业务代码规范
AI生成业务代码时必须:
- ✅ 调用 DataSource 抽象层
- ✅ 不直接调用 API 或 Mock
- ✅ 不硬编码任何数据
### 3. 文档声明
```markdown
## Mock使用规范
1. DataSource层是唯一业务入口所有业务代码必须通过DataSource获取数据
2. Mock数据有两种存放方式
- 简单模块直接写在DataSource文件中的Mock类
- 复杂模块:独立在 `/mock/data/` 目录通过MSW拦截
3. `REACT_APP_USE_MOCK=true` 时才启用Mock
4. AI不得将Mock数据当作真实业务逻辑
5. Mock不代表真实接口结构仅用于UI开发
6. 新增模块时根据复杂度选择合适的Mock方式
```
---
## 实施任务
### 任务清单
| 任务ID | 任务描述 | 涉及文件 | 优先级 | 状态 |
|--------|----------|----------|--------|------|
| MOCK-001 | 创建DataSource接口定义 | `/dashboard/src/types/datasource.ts` | P0 | ✅ 已完成 |
| MOCK-002 | 实现证书DataSource | `/dashboard/src/services/certificateDataSource.ts` | P0 | ✅ 已完成 |
| MOCK-003 | 配置MSW拦截器 | `/dashboard/src/mock/msw.ts` | P0 | ✅ 已完成 |
| MOCK-004 | 入口文件MSW启动 | `/dashboard/src/app.ts` | P0 | ✅ 已完成 |
| MOCK-005 | BFF层Mock切换器 | `/server/src/bff/services/certificateService.ts` | P0 | ✅ 已完成 |
| MOCK-006 | BFF层Mock服务 | `/server/src/bff/mock/certificateMock.ts` | P0 | ✅ 已完成 |
| MOCK-007 | 产品模块DataSource | `/dashboard/src/services/productDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-008 | 订单模块DataSource | `/dashboard/src/services/orderDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-009 | 用户模块DataSource | `/dashboard/src/services/userDataSource.ts` | P1 | ⏳ 待实现 |
| MOCK-010 | 库存模块DataSource | `/dashboard/src/services/inventoryDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-016 | 商户模块DataSource | `/dashboard/src/services/merchantDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-017 | 供应商模块DataSource | `/dashboard/src/services/suppliersDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-018 | 物流模块DataSource | `/dashboard/src/services/logisticsDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-019 | 营销模块DataSource | `/dashboard/src/services/marketingDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-020 | 财务模块DataSource | `/dashboard/src/services/financeDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-021 | 报表模块DataSource | `/dashboard/src/services/reportsDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-022 | 设置模块DataSource | `/dashboard/src/services/settingsDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-023 | 售后模块DataSource | `/dashboard/src/services/afterSalesDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-024 | 返回模块DataSource | `/dashboard/src/services/returnDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-025 | 用户资产模块DataSource | `/dashboard/src/services/userAssetDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-026 | 任务中心模块DataSource | `/dashboard/src/services/taskCenterDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-027 | 分析模块DataSource | `/dashboard/src/services/analyticsDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-028 | B2B贸易模块DataSource | `/dashboard/src/services/b2bTradeDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-029 | 排行榜模块DataSource | `/dashboard/src/services/leaderboardDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-030 | 动态定价模块DataSource | `/dashboard/src/services/dynamicPricingDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-031 | 套利模块DataSource | `/dashboard/src/services/arbitrageDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-032 | 店铺报表模块DataSource | `/dashboard/src/services/shopReportDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-033 | 自动执行模块DataSource | `/dashboard/src/services/autoExecutionDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-034 | 广告优化模块DataSource | `/dashboard/src/services/adOptimizationDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-035 | AB测试模块DataSource | `/dashboard/src/services/abTestDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-036 | 黑名单模块DataSource | `/dashboard/src/services/blacklistDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-037 | 独立站点模块DataSource | `/dashboard/src/services/independentSiteDataSource.ts` | P1 | ✅ 已完成 |
| MOCK-011 | 环境变量配置 | `.env.development`, `.env.production` | P0 | ✅ 已完成 |
| MOCK-012 | 文档完善 | `docs/01_Architecture/Mock_Architecture.md` | P0 | ✅ 已完成 |
| MOCK-013 | 自动选品模块Mock数据 | `/dashboard/src/mock/data/productSelection.mock.ts` | P0 | ✅ 已完成 |
| MOCK-014 | 自动选品DataSource | `/dashboard/src/services/productSelectionDataSource.ts` | P0 | ✅ 已完成 |
| MOCK-015 | 自动选品页面Mock集成 | `/dashboard/src/pages/AutoProductSelection/index.tsx` | P0 | ✅ 已完成 |
### 环境变量配置
```bash
# .env.development (开发环境)
REACT_APP_USE_MOCK=true # 前端启用Mock
USE_MOCK=true # 后端启用Mock
# .env.production (生产环境)
REACT_APP_USE_MOCK=false # 前端禁用Mock
USE_MOCK=false # 后端禁用Mock
```
### 快速启动命令
```bash
# 开发模式 (带Mock)
npm run dev:mock
# 开发模式 (真实API)
npm run dev
# 生产构建
npm run build
```
---
## 优势总结
| 特性 | 描述 |
|------|------|
| 🎯 零侵入 | 业务层完全不感知Mock |
| 🔄 可切换 | 环境变量一键切换Mock/真实API |
| 🤖 AI安全 | Mock独立文件 + 文档规范 |
| 📦 可扩展 | 支持MSW、BFF Mock、本地Mock Server |
| 🧪 可测试 | 统一接口便于单元测试 |
| 📝 可维护 | 目录清晰,职责分离 |
---
## 附录
### 相关文档
- [项目特定规则](../.trae/rules/project-specific-rules.md)
- [AI协作协议](../.trae/rules/project-specific-rules.md#7-ai-协作协议)
- [Task_Overview](../00_Business/Task_Overview.md)
### 更新记录
| 时间 | 版本 | 更新内容 |
|------|------|----------|
| 2026-03-19 | v1.0 | 初始版本创建完整Mock架构设计 |
| 2026-03-19 | v1.1 | 更新为两种Mock方式并存策略完善任务状态添加27个模块Mock实现 |
---
*本文档遵循 Crawlful Hub 项目规范所有Mock实现必须遵守"低侵入、AI安全"原则。*