时里院子市集
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.2 KiB

前端订单提交实现文档

概述

本文档描述了前端订单提交的完整实现,包括单商品下单、购物车批量下单等场景。

核心改进

1. 统一的API接口

新的订单创建接口:

// 订单商品项
interface OrderGoodsItem {
  goodsId: number;
  quantity: number;
  skuId?: number;
  specInfo?: string;
}

// 创建订单请求
interface OrderCreateRequest {
  goodsItems: OrderGoodsItem[];
  addressId?: number;
  payType: number;
  couponId?: number;
  comments?: string;
  deliveryType?: number;
  selfTakeMerchantId?: number;
  title?: string;
}

// 微信支付返回数据
interface WxPayResult {
  prepayId: string;
  orderNo: string;
  timeStamp: string;
  nonceStr: string;
  package: string;
  signType: string;
  paySign: string;
}

2. 标题长度限制

工具函数:

// 截取文本,限制长度
export function truncateText(text: string, maxLength: number = 30): string {
  if (!text) return '';
  if (text.length <= maxLength) return text;
  return text.substring(0, maxLength);
}

// 生成订单标题
export function generateOrderTitle(goodsNames: string[], maxLength: number = 30): string {
  if (!goodsNames || goodsNames.length === 0) return '商品订单';
  
  let title = goodsNames.length === 1 
    ? goodsNames[0] 
    : `${goodsNames[0]}${goodsNames.length}件商品`;
    
  return truncateText(title, maxLength);
}

实现细节

1. 单商品下单

文件: src/shop/orderConfirm/index.tsx

核心逻辑:

const onWxPay = async (goods: ShopGoods) => {
  // 1. 校验收货地址
  if (!address) {
    Taro.showToast({ title: '请选择收货地址', icon: 'error' });
    return;
  }

  Taro.showLoading({title: '支付中...'});
  
  try {
    // 2. 构建订单数据
    const orderData: OrderCreateRequest = {
      goodsItems: [{ goodsId: goods.goodsId!, quantity: 1 }],
      addressId: address.id,
      payType: 1,
      comments: goods.name,
      deliveryType: 0
    };

    // 3. 创建订单
    const result = await createOrder(orderData);
    
    // 4. 微信支付
    if (result && result.prepayId) {
      await Taro.requestPayment({
        timeStamp: result.timeStamp,
        nonceStr: result.nonceStr,
        package: result.package,
        signType: result.signType,
        paySign: result.paySign,
      });
      
      // 5. 支付成功处理
      Taro.showToast({ title: '支付成功', icon: 'success' });
      setTimeout(() => {
        Taro.navigateTo({url: '/pages/order/order'});
      }, 2000);
    }
  } catch (error: any) {
    Taro.showToast({ title: error.message || '下单失败', icon: 'error' });
  } finally {
    Taro.hideLoading();
  }
};

2. 购物车批量下单

文件: src/shop/orderConfirmCart/index.tsx

核心逻辑:

const onCartPay = async () => {
  // 1. 校验
  if (!address || !cartItems || cartItems.length === 0) {
    // 错误处理
    return;
  }

  try {
    // 2. 构建批量商品数据
    const orderData: OrderCreateRequest = {
      goodsItems: cartItems.map(item => ({
        goodsId: item.goodsId!,
        quantity: item.quantity || 1
      })),
      addressId: address.id,
      payType: 1,
      comments: '购物车下单',
      deliveryType: 0
    };

    // 3. 创建订单并支付
    const result = await createOrder(orderData);
    // ... 支付逻辑
  } catch (error) {
    // 错误处理
  }
};

数据流程

1. 前端提交流程

用户点击支付
    ↓
校验地址和商品
    ↓
构建OrderCreateRequest
    ↓
调用createOrder API
    ↓
后端返回WxPayResult
    ↓
调用微信支付
    ↓
支付成功跳转

2. 后端处理流程

接收OrderCreateRequest
    ↓
参数校验
    ↓
构建订单主表
    ↓
保存订单商品明细
    ↓
库存扣减
    ↓
生成订单标题(≤30字)
    ↓
创建微信支付
    ↓
返回支付参数

关键特性

1. 数据安全

  • 前端只传递商品ID和数量
  • 价格、库存等敏感信息由后端实时获取
  • 防止前端数据篡改

2. 业务完整性

  • 统一的订单创建流程
  • 完整的错误处理机制
  • 支持多种下单场景

3. 用户体验

  • 清晰的加载状态
  • 友好的错误提示
  • 自动跳转到订单页面

扩展功能

1. 支持的下单类型

  • 单商品立即购买
  • 购物车批量下单
  • 自提订单
  • 使用优惠券下单

2. 支持的配送方式

  • 快递配送 (deliveryType: 0)
  • 到店自提 (deliveryType: 1)

3. 支持的支付方式

  • 微信支付 (payType: 1)
  • 余额支付 (payType: 0)
  • 其他支付方式...

注意事项

  1. 标题长度限制:订单标题最多30个汉字,超过自动截取
  2. 库存校验:后端会实时校验商品库存
  3. 地址校验:确保收货地址属于当前用户
  4. 错误处理:完善的异常捕获和用户提示
  5. 支付安全:支付参数由后端生成,前端不可篡改

测试建议

  1. 测试单商品下单流程
  2. 测试购物车批量下单
  3. 测试各种异常情况(库存不足、地址无效等)
  4. 测试支付成功和失败的处理
  5. 测试订单标题长度限制功能