# 支付逻辑重构指南

## 概述

本文档描述了支付逻辑的重构过程，将原本分散的支付代码统一整合，提高了代码的可维护性和复用性。

## 重构前后对比

### 重构前的问题

1. **代码重复**：每个支付方式都有重复的订单构建逻辑
2. **维护困难**：支付逻辑分散在多个方法中
3. **扩展性差**：添加新的支付方式需要修改多处代码

### 重构后的优势

1. **统一入口**：所有支付都通过 `onPay` 方法处理
2. **代码复用**：订单构建逻辑统一封装
3. **易于扩展**：新增支付方式只需在工具类中添加
4. **错误处理统一**：所有支付的错误处理逻辑一致

## 核心改进

### 1. 统一的支付工具类

**文件：** `src/utils/payment.ts`

```typescript
// 支付类型枚举
export enum PaymentType {
  BALANCE = 0,  // 余额支付
  WECHAT = 1,   // 微信支付
  ALIPAY = 3,   // 支付宝支付
}

// 统一支付处理类
export class PaymentHandler {
  static async pay(
    orderData: OrderCreateRequest, 
    paymentType: PaymentType,
    callback?: PaymentCallback
  ): Promise<void> {
    // 统一的支付处理逻辑
  }
}
```

### 2. 订单数据构建函数

```typescript
// 单商品订单
export function buildSingleGoodsOrder(
  goodsId: number,
  quantity: number = 1,
  addressId?: number,
  options?: {
    comments?: string;
    deliveryType?: number;
    couponId?: number;
  }
): OrderCreateRequest

// 购物车订单
export function buildCartOrder(
  cartItems: Array<{ goodsId: number; quantity: number }>,
  addressId?: number,
  options?: { ... }
): OrderCreateRequest
```

### 3. 简化的支付入口

**重构前：**
```typescript
const onWxPay = async (goods: ShopGoods) => {
  // 校验逻辑
  // 构建订单数据
  // 调用创建订单API
  // 处理微信支付
  // 错误处理
}

const onBalancePay = async (goods: ShopGoods) => {
  // 重复的校验逻辑
  // 重复的订单构建逻辑
  // 处理余额支付
  // 重复的错误处理
}

const onPay = async (goods: ShopGoods) => {
  if (payment?.type == 0) {
    await onBalancePay(goods)
  }
  if (payment?.type == 1) {
    await onWxPay(goods)
  }
}
```

**重构后：**
```typescript
const onPay = async (goods: ShopGoods) => {
  // 基础校验
  if (!address || !payment) {
    // 错误提示
    return;
  }

  // 构建订单数据
  const orderData = buildSingleGoodsOrder(
    goods.goodsId!,
    1,
    address.id,
    { comments: goods.name }
  );

  // 选择支付类型
  const paymentType = payment.type === 0 ? PaymentType.BALANCE : PaymentType.WECHAT;

  // 执行支付
  await PaymentHandler.pay(orderData, paymentType);
};
```

## 使用示例

### 1. 单商品下单

```typescript
// 在 orderConfirm/index.tsx 中
const onPay = async (goods: ShopGoods) => {
  if (!address || !payment) return;

  const orderData = buildSingleGoodsOrder(
    goods.goodsId!,
    1,
    address.id,
    {
      comments: goods.name,
      deliveryType: 0
    }
  );

  const paymentType = payment.type === 0 ? PaymentType.BALANCE : PaymentType.WECHAT;
  await PaymentHandler.pay(orderData, paymentType);
};
```

### 2. 购物车批量下单

```typescript
// 在 orderConfirmCart/index.tsx 中
const onPay = async () => {
  if (!address || !cartItems?.length) return;

  const orderData = buildCartOrder(
    cartItems.map(item => ({
      goodsId: item.goodsId!,
      quantity: item.quantity || 1
    })),
    address.id,
    {
      comments: '购物车下单',
      deliveryType: 0
    }
  );

  const paymentType = payment?.type === 0 ? PaymentType.BALANCE : PaymentType.WECHAT;
  await PaymentHandler.pay(orderData, paymentType);
};
```

### 3. 使用优惠券下单

```typescript
const onPayWithCoupon = async (goods: ShopGoods, couponId: number) => {
  const orderData = buildSingleGoodsOrder(
    goods.goodsId!,
    1,
    address.id,
    {
      comments: `使用优惠券购买${goods.name}`,
      couponId: couponId
    }
  );

  await PaymentHandler.pay(orderData, PaymentType.WECHAT);
};
```

### 4. 自提订单

```typescript
const onSelfPickupOrder = async (goods: ShopGoods, merchantId: number) => {
  const orderData = buildSingleGoodsOrder(
    goods.goodsId!,
    1,
    address.id,
    {
      comments: `自提订单 - ${goods.name}`,
      deliveryType: 1,
      selfTakeMerchantId: merchantId
    }
  );

  await PaymentHandler.pay(orderData, PaymentType.WECHAT);
};
```

## 扩展新的支付方式

### 1. 添加支付类型

```typescript
// 在 PaymentType 枚举中添加
export enum PaymentType {
  BALANCE = 0,
  WECHAT = 1,
  ALIPAY = 3,
  UNIONPAY = 4,  // 新增银联支付
}
```

### 2. 实现支付处理方法

```typescript
// 在 PaymentHandler 类中添加
private static async handleUnionPay(result: any): Promise<void> {
  // 银联支付逻辑
}
```

### 3. 在支付分发中添加

```typescript
// 在 PaymentHandler.pay 方法中添加
switch (paymentType) {
  case PaymentType.WECHAT:
    await this.handleWechatPay(result);
    break;
  case PaymentType.BALANCE:
    await this.handleBalancePay(result);
    break;
  case PaymentType.UNIONPAY:  // 新增
    await this.handleUnionPay(result);
    break;
  // ...
}
```

## 优势总结

1. **代码简洁**：支付入口方法从 50+ 行减少到 20+ 行
2. **逻辑清晰**：订单构建、支付处理、错误处理分离
3. **易于测试**：每个功能模块独立，便于单元测试
4. **维护性强**：修改支付逻辑只需在工具类中修改
5. **扩展性好**：新增支付方式无需修改业务代码

## 注意事项

1. **向后兼容**：确保重构后的接口与原有调用方式兼容
2. **错误处理**：统一的错误处理机制，确保用户体验一致
3. **类型安全**：使用 TypeScript 枚举确保支付类型的类型安全
4. **测试覆盖**：对重构后的代码进行充分的测试
