246 lines
5.2 KiB
Markdown
246 lines
5.2 KiB
Markdown
# 前端订单提交实现文档
|
||
|
||
## 概述
|
||
|
||
本文档描述了前端订单提交的完整实现,包括单商品下单、购物车批量下单等场景。
|
||
|
||
## 核心改进
|
||
|
||
### 1. 统一的API接口
|
||
|
||
**新的订单创建接口:**
|
||
```typescript
|
||
// 订单商品项
|
||
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. 标题长度限制
|
||
|
||
**工具函数:**
|
||
```typescript
|
||
// 截取文本,限制长度
|
||
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`
|
||
|
||
**核心逻辑:**
|
||
```typescript
|
||
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`
|
||
|
||
**核心逻辑:**
|
||
```typescript
|
||
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. 测试订单标题长度限制功能
|