# 代码审查报告

> **审查日期**: 2026-03-19
> **审查范围**: 全代码库深度检查
> **审查目标**: 逻辑统一性、冗余代码、潜在冲突

---

## 📊 审查概览

| 类别 | 问题数量 | 严重程度 | 状态 |
|------|----------|----------|------|
| 🔴 严重问题 | 3 | 高 | 需立即修复 |
| 🟡 中等问题 | 5 | 中 | 需计划修复 |
| 🟢 轻微问题 | 4 | 低 | 建议优化 |

---

## 🔴 严重问题

### 1. 服务层逻辑重复与不一致

**问题描述**:
`ArbitrageService` 和 `PriceComparisonService` 存在高度重复的逻辑，但实现细节不一致。

**涉及文件**:
- `server/src/services/ArbitrageService.ts`
- `server/src/services/PriceComparisonService.ts`

**具体问题**:

#### 1.1 汇率数据不一致
```typescript
// ArbitrageService.ts (第62行)
private static readonly EXCHANGE_RATE = 7.2;  // 硬编码单一汇率

// PriceComparisonService.ts (第65-71行)
private static readonly EXCHANGE_RATES: Record<string, number> = {
  'CNY-USD': 0.14,
  'USD-CNY': 7.2,
  'CNY-EUR': 0.13,
  'EUR-CNY': 7.7,
  'USD-EUR': 0.92,
  'EUR-USD': 1.09
};
```

**影响**: 两个服务对相同货币对可能计算出不同的汇率结果。

#### 1.2 机会评分算法不一致
```typescript
// ArbitrageService.ts (第465-470行)
private calculateOpportunityScore(profitSnapshot: ProfitSnapshot): number {
  const profitRateScore = Math.min(profitSnapshot.profitRate * 200, 40);
  const roiScore = Math.min(profitSnapshot.roi * 50, 30);
  const netProfitScore = Math.min(profitSnapshot.netProfit / 10, 30);
  return Math.round(profitRateScore + roiScore + netProfitScore);
}

// PriceComparisonService.ts (第381-386行)
private calculateOpportunityScore(profitSnapshot: ProfitSnapshot, priceDiffPercent: number): number {
  const profitRateScore = Math.min(profitSnapshot.profitRate * 200, 40);
  const roiScore = Math.min(profitSnapshot.roi * 50, 30);
  const priceDiffScore = Math.min(priceDiffPercent, 30);  // 不同！
  return Math.round(profitRateScore + roiScore + priceDiffScore);
}
```

**影响**: 相同的利润数据可能产生不同的机会评分。

---

### 2. 利润红线检查未统一调用

**问题描述**:
`PricingService.checkRisk()` 已实现完整的利润红线检查逻辑，但其他服务未调用此方法。

**涉及文件**:
- `server/src/services/PricingService.ts` (定义了 checkRisk)
- `server/src/services/ArbitrageService.ts` (未调用)
- `server/src/services/PriceComparisonService.ts` (未调用)
- `server/src/services/DynamicPricingService.ts` (有自己的检查逻辑)

**现有实现**:
```typescript
// PricingService.ts (第116-135行) - 正确实现
static checkRisk(snapshot: ProfitSnapshot, isB2B: boolean): { 
  isRisk: boolean; 
  message?: string; 
  level: 'BLOCK' | 'WARN' | 'PASS' 
} {
  const profitRate = snapshot.profitRate;
  
  if (isB2B) {
    if (profitRate < 0.15) {  // B2B < 15% 阻止
      return { isRisk: true, message: `...`, level: 'BLOCK' };
    }
  } else {
    if (profitRate < 0.20) {  // B2C < 20% 预警
      return { isRisk: true, message: `...`, level: 'WARN' };
    }
  }
  return { isRisk: false, level: 'PASS' };
}
```

**问题代码**:
```typescript
// ArbitrageService.ts (第107-111行) - 自己实现的检查
if (profitSnapshot.profitRate < 0.05) {
  riskLevel = 'BLOCK';
} else if (profitSnapshot.profitRate < 0.15 || profitSnapshot.roi < 0.2) {
  riskLevel = 'HIGH';
} else if (profitSnapshot.profitRate < 0.25) {
  riskLevel = 'MEDIUM';
}
```

**影响**: 
- 违反项目规则中的利润红线约束
- 不同服务的风险判断标准不一致

---

### 3. 数据库表定义分散

**问题描述**:
数据库表定义分散在两个地方，违反单一职责原则。

**涉及文件**:
- `server/src/database/DatabaseSchema.ts` - 主数据库架构
- `server/src/services/DynamicPricingService.ts` - 内部定义 initTables()

**问题代码**:
```typescript
// DynamicPricingService.ts (第216-299行)
static async initTables() {
  // 在服务内部创建表定义
  const hasConfigTable = await db.schema.hasTable(this.CONFIG_TABLE);
  if (!hasConfigTable) {
    await db.schema.createTable(this.CONFIG_TABLE, (table) => { ... });
  }
  // ...
}
```

**影响**:
- 表定义难以统一管理
- 初始化顺序可能出问题
- 违反项目架构规范

---

## 🟡 中等问题

### 4. 文档与代码不一致

**问题描述**:
`Business_ClosedLoops.md` 中提到的表名与实际代码不匹配。

**涉及文件**:
- `docs/00_Business/Business_ClosedLoops.md`

**不一致内容**:
| 文档中的表名 | 实际代码中的表名 | 状态 |
|-------------|-----------------|------|
| cf_arbitrage_products | ❌ 不存在 | 需补充或删除文档 |
| cf_arbitrage_orders | ❌ 不存在 | 需补充或删除文档 |
| cf_arbitrage_profits | ❌ 不存在 | 需补充或删除文档 |
| cf_pricing_metrics | ❌ 不存在 | 需补充或删除文档 |

---

### 5. 前端 DataSource 模式重复

**问题描述**:
多个 DataSource 文件实现了相同的 Mock/API 切换模式。

**涉及文件**:
- `dashboard/src/services/dynamicPricingDataSource.ts`
- `dashboard/src/services/arbitrageDataSource.ts`
- `dashboard/src/services/shopReportDataSource.ts`

**重复模式**:
```typescript
// 每个文件都有相同的结构
interface IXxxDataSource { ... }

class MockXxxDataSource implements IXxxDataSource { ... }

class ApiXxxDataSource implements IXxxDataSource { ... }

export const xxxDataSource: IXxxDataSource = USE_MOCK
  ? new MockXxxDataSource()
  : new ApiXxxDataSource();
```

**建议**: 抽取为通用的 DataSource 工厂模式。

---

### 6. 状态枚举定义分散

**问题描述**:
相同业务概念的状态枚举在多处重复定义。

**涉及文件**:
- `server/src/services/ArbitrageService.ts`
- `server/src/services/DynamicPricingService.ts`
- `server/src/database/DatabaseSchema.ts`

**示例**:
```typescript
// ArbitrageService.ts
status: 'PENDING' | 'APPROVED' | 'REJECTED' | 'EXECUTING' | 'EXECUTED' | 'FAILED';

// DynamicPricingService.ts  
status: 'PENDING' | 'EXECUTED' | 'REJECTED' | 'EXPIRED';

// DatabaseSchema.ts (cf_arbitrage_opportunities)
table.enum('status', ['PENDING', 'APPROVED', 'REJECTED', 'EXECUTING', 'EXECUTED', 'FAILED']);
```

**建议**: 统一定义在 `shared/types/` 目录下。

---

### 7. 服务实例化模式不一致

**问题描述**:
部分服务使用单例模式，部分不使用。

**涉及文件**:
- `server/src/services/ArbitrageService.ts` - 使用单例
- `server/src/services/PriceComparisonService.ts` - 使用单例
- `server/src/services/DynamicPricingService.ts` - 不使用单例
- `server/src/services/PricingService.ts` - 静态方法，无实例

**影响**: 服务调用方式不统一，增加理解成本。

---

### 8. 缓存策略分散

**问题描述**:
各服务独立定义缓存策略，未统一管理。

**涉及文件**:
- `server/src/services/DynamicPricingService.ts` - CACHE_PREFIX, CACHE_TTL
- `server/src/services/CompetitorPriceService.ts` - CACHE_PREFIX, CACHE_TTL

**建议**: 统一缓存配置管理。

---

## 🟢 轻微问题

### 9. 日志格式不统一

**问题描述**:
不同服务的日志前缀格式不一致。

```typescript
// ArbitrageService.ts
logger.info(`[ArbitrageService] ...`);

// PriceComparisonService.ts
logger.info(`[PriceComparisonService] ...`);

// DynamicPricingService.ts
logger.info(`[DynamicPricing] ...`);  // 缩写
```

---

### 10. 类型导出方式不一致

**问题描述**:
类型导出方式混用。

```typescript
// 方式1: 先定义后导出
export interface ArbitrageOpportunity { ... }

// 方式2: 定义时导出
interface PriceComparison { ... }
export interface PriceComparison { ... }  // 重复声明
```

---

### 11. 错误处理不一致

**问题描述**:
部分服务有详细的错误处理，部分直接抛出异常。

---

### 12. 注释语言混用

**问题描述**:
代码注释中中英文混用，不统一。

---

## 📋 修复方案

### 方案一：统一汇率服务

**优先级**: P0
**预计工时**: 4h

**实施步骤**:
1. 创建 `ExchangeRateService.ts` 统一管理汇率
2. 从外部 API 或配置获取实时汇率
3. 修改 `ArbitrageService` 和 `PriceComparisonService` 调用统一服务

```typescript
// 新建 server/src/services/ExchangeRateService.ts
export class ExchangeRateService {
  private static rates: Record<string, number> = { ... };
  private static lastUpdate: Date;
  
  static async getRate(from: string, to: string): Promise<number> {
    await this.ensureFresh();
    return this.rates[`${from}-${to}`] || 1;
  }
  
  private static async ensureFresh(): Promise<void> {
    // 每小时更新一次
    if (!this.lastUpdate || Date.now() - this.lastUpdate.getTime() > 3600000) {
      await this.fetchLatestRates();
    }
  }
}
```

---

### 方案二：统一机会评分算法

**优先级**: P0
**预计工时**: 2h

**实施步骤**:
1. 在 `PricingService` 中添加 `calculateOpportunityScore` 方法
2. 修改 `ArbitrageService` 和 `PriceComparisonService` 调用统一方法

```typescript
// 在 PricingService.ts 中添加
static calculateOpportunityScore(
  profitSnapshot: ProfitSnapshot,
  options?: { priceDiffPercent?: number; netProfit?: number }
): number {
  const profitRateScore = Math.min(profitSnapshot.profitRate * 200, 40);
  const roiScore = Math.min(profitSnapshot.roi * 50, 30);
  
  // 优先使用价格差异，其次使用净利润
  const thirdScore = options?.priceDiffPercent 
    ? Math.min(options.priceDiffPercent, 30)
    : Math.min((options?.netProfit || profitSnapshot.netProfit) / 10, 30);
  
  return Math.round(profitRateScore + roiScore + thirdScore);
}
```

---

### 方案三：统一利润红线检查

**优先级**: P0
**预计工时**: 3h

**实施步骤**:
1. 修改 `ArbitrageService` 调用 `PricingService.checkRisk()`
2. 修改 `PriceComparisonService` 调用 `PricingService.checkRisk()`
3. 修改 `DynamicPricingService` 使用统一检查

```typescript
// 修改 ArbitrageService.ts
import { PricingService } from './PricingService';

async createOpportunity(...): Promise<ArbitrageOpportunity> {
  // ... 计算利润
  
  // 使用统一的利润红线检查
  const riskCheck = PricingService.checkRisk(profitSnapshot, options?.isB2B || false);
  
  let riskLevel: 'LOW' | 'MEDIUM' | 'HIGH' | 'BLOCK';
  switch (riskCheck.level) {
    case 'BLOCK':
      riskLevel = 'BLOCK';
      break;
    case 'WARN':
      riskLevel = 'HIGH';
      break;
    default:
      riskLevel = profitSnapshot.profitRate >= 0.25 ? 'LOW' : 'MEDIUM';
  }
  
  // ...
}
```

---

### 方案四：集中数据库表定义

**优先级**: P1
**预计工时**: 4h

**实施步骤**:
1. 将 `DynamicPricingService.initTables()` 中的表定义移至 `DatabaseSchema.ts`
2. 在 `DatabaseSchema.initializeAll()` 中统一调用
3. 删除服务中的表创建代码

---

### 方案五：统一状态枚举定义

**优先级**: P1
**预计工时**: 2h

**实施步骤**:
1. 创建 `server/src/shared/types/status.ts`
2. 定义所有业务状态枚举
3. 修改各服务引用统一枚举

```typescript
// 新建 server/src/shared/types/status.ts
export enum ArbitrageStatus {
  PENDING = 'PENDING',
  APPROVED = 'APPROVED',
  REJECTED = 'REJECTED',
  EXECUTING = 'EXECUTING',
  EXECUTED = 'EXECUTED',
  FAILED = 'FAILED'
}

export enum PricingDecisionStatus {
  PENDING = 'PENDING',
  EXECUTED = 'EXECUTED',
  REJECTED = 'REJECTED',
  EXPIRED = 'EXPIRED'
}
```

---

### 方案六：统一 DataSource 工厂

**优先级**: P2
**预计工时**: 3h

**实施步骤**:
1. 创建 `dashboard/src/services/DataSourceFactory.ts`
2. 抽取公共 Mock/API 切换逻辑
3. 重构现有 DataSource 文件

---

## 📊 修复优先级矩阵

| 方案 | 优先级 | 影响范围 | 风险 | 预计工时 |
|------|--------|----------|------|----------|
| 方案一：统一汇率服务 | P0 | 高 | 低 | 4h |
| 方案二：统一机会评分 | P0 | 中 | 低 | 2h |
| 方案三：统一利润红线 | P0 | 高 | 中 | 3h |
| 方案四：集中表定义 | P1 | 中 | 中 | 4h |
| 方案五：统一状态枚举 | P1 | 低 | 低 | 2h |
| 方案六：DataSource工厂 | P2 | 低 | 低 | 3h |

**总预计工时**: 18h

---

## ✅ 验收标准

### 修复后需满足:

1. **汇率统一**: 所有服务使用同一汇率源
2. **评分一致**: 相同输入产生相同的机会评分
3. **红线统一**: 所有利润检查调用 `PricingService.checkRisk()`
4. **表定义集中**: 所有表定义在 `DatabaseSchema.ts`
5. **类型统一**: 状态枚举在 `shared/types/` 统一定义
6. **文档同步**: 文档与代码一致

---

## 📝 执行建议

### 阶段一：紧急修复 (P0)
- 先修复汇率、评分、利润红线三个核心问题
- 预计工时：9h
- 风险：低

### 阶段二：架构优化 (P1)
- 集中表定义、统一状态枚举
- 预计工时：6h
- 风险：中

### 阶段三：代码规范 (P2)
- DataSource 工厂、日志格式、注释语言
- 预计工时：3h
- 风险：低

---

*本报告由代码审查工具生成，建议按优先级逐步修复。*
