You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.8 KiB
5.8 KiB
支付逻辑重构指南
概述
本文档描述了支付逻辑的重构过程,将原本分散的支付代码统一整合,提高了代码的可维护性和复用性。
重构前后对比
重构前的问题
- 代码重复:每个支付方式都有重复的订单构建逻辑
- 维护困难:支付逻辑分散在多个方法中
- 扩展性差:添加新的支付方式需要修改多处代码
重构后的优势
- 统一入口:所有支付都通过
onPay
方法处理 - 代码复用:订单构建逻辑统一封装
- 易于扩展:新增支付方式只需在工具类中添加
- 错误处理统一:所有支付的错误处理逻辑一致
核心改进
1. 统一的支付工具类
文件: src/utils/payment.ts
// 支付类型枚举
export enum PaymentType {
BALANCE = 0, // 余额支付
WECHAT = 1, // 微信支付
ALIPAY = 3, // 支付宝支付
}
// 统一支付处理类
export class PaymentHandler {
static async pay(
orderData: OrderCreateRequest,
paymentType: PaymentType,
callback?: PaymentCallback
): Promise<void> {
// 统一的支付处理逻辑
}
}
2. 订单数据构建函数
// 单商品订单
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. 简化的支付入口
重构前:
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)
}
}
重构后:
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. 单商品下单
// 在 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. 购物车批量下单
// 在 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. 使用优惠券下单
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. 自提订单
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. 添加支付类型
// 在 PaymentType 枚举中添加
export enum PaymentType {
BALANCE = 0,
WECHAT = 1,
ALIPAY = 3,
UNIONPAY = 4, // 新增银联支付
}
2. 实现支付处理方法
// 在 PaymentHandler 类中添加
private static async handleUnionPay(result: any): Promise<void> {
// 银联支付逻辑
}
3. 在支付分发中添加
// 在 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;
// ...
}
优势总结
- 代码简洁:支付入口方法从 50+ 行减少到 20+ 行
- 逻辑清晰:订单构建、支付处理、错误处理分离
- 易于测试:每个功能模块独立,便于单元测试
- 维护性强:修改支付逻辑只需在工具类中修改
- 扩展性好:新增支付方式无需修改业务代码
注意事项
- 向后兼容:确保重构后的接口与原有调用方式兼容
- 错误处理:统一的错误处理机制,确保用户体验一致
- 类型安全:使用 TypeScript 枚举确保支付类型的类型安全
- 测试覆盖:对重构后的代码进行充分的测试