forked from gxwebsoft/mp-10550
feat(components): 新增 GiftCard礼品卡组件
- 新增 GiftCard 组件,支持多种类型礼品卡的展示和交互 - 组件包含商品信息、价格、折扣、使用指南等丰富功能- 优化图像展示,支持单
This commit is contained in:
340
docs/COUPON_PAYMENT_ISSUE_ANALYSIS.md
Normal file
340
docs/COUPON_PAYMENT_ISSUE_ANALYSIS.md
Normal file
@@ -0,0 +1,340 @@
|
||||
# 🚨 优惠券支付问题分析
|
||||
|
||||
## 问题描述
|
||||
|
||||
用户选择优惠券后支付失败,但系统仍然提示"支付成功",这是一个严重的用户体验问题。
|
||||
|
||||
## 🔍 问题分析
|
||||
|
||||
### 1. **支付流程问题**
|
||||
|
||||
#### 当前支付流程
|
||||
```typescript
|
||||
// OrderConfirm.tsx - onPay函数
|
||||
const onPay = async (goods: ShopGoods) => {
|
||||
try {
|
||||
setPayLoading(true)
|
||||
|
||||
// 构建订单数据
|
||||
const orderData = buildSingleGoodsOrder(
|
||||
goods.goodsId!,
|
||||
quantity,
|
||||
address.id,
|
||||
{
|
||||
comments: goods.name,
|
||||
deliveryType: 0,
|
||||
buyerRemarks: orderRemark,
|
||||
couponId: selectedCoupon ? selectedCoupon.id : undefined // ⚠️ 问题点1
|
||||
}
|
||||
);
|
||||
|
||||
// 执行支付
|
||||
await PaymentHandler.pay(orderData, paymentType);
|
||||
|
||||
// ❌ 问题点2:无论支付是否真正成功,都会显示成功
|
||||
Taro.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
})
|
||||
} catch (error) {
|
||||
// ❌ 问题点3:错误处理不够详细
|
||||
Taro.showToast({
|
||||
title: '支付失败,请重试',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 2. **PaymentHandler问题**
|
||||
|
||||
#### 支付处理逻辑缺陷
|
||||
```typescript
|
||||
// payment.ts - PaymentHandler.pay
|
||||
static async pay(orderData, paymentType, callback?) {
|
||||
try {
|
||||
// 创建订单
|
||||
const result = await createOrder(orderData);
|
||||
|
||||
// 根据支付类型处理
|
||||
switch (paymentType) {
|
||||
case PaymentType.WECHAT:
|
||||
await this.handleWechatPay(result);
|
||||
break;
|
||||
case PaymentType.BALANCE:
|
||||
await this.handleBalancePay(result); // ⚠️ 问题点4
|
||||
break;
|
||||
}
|
||||
|
||||
// ❌ 问题点5:无论实际支付结果如何,都显示成功
|
||||
Taro.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
// ❌ 问题点6:自动跳转,用户无法确认实际状态
|
||||
setTimeout(() => {
|
||||
Taro.navigateTo({ url: '/user/order/order' });
|
||||
}, 2000);
|
||||
|
||||
} catch (error) {
|
||||
// 错误处理
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. **余额支付逻辑问题**
|
||||
|
||||
#### 余额支付处理不完善
|
||||
```typescript
|
||||
// payment.ts - handleBalancePay
|
||||
private static async handleBalancePay(result: any): Promise<void> {
|
||||
// ❌ 问题点7:只检查orderNo,不检查实际支付状态
|
||||
if (!result || !result.orderNo) {
|
||||
throw new Error('余额支付失败');
|
||||
}
|
||||
// ❌ 问题点8:没有验证余额是否足够,支付是否真正成功
|
||||
}
|
||||
```
|
||||
|
||||
### 4. **优惠券相关问题**
|
||||
|
||||
#### 优惠券ID传递问题
|
||||
```typescript
|
||||
// OrderConfirm.tsx
|
||||
couponId: selectedCoupon ? selectedCoupon.id : undefined
|
||||
|
||||
// ⚠️ 问题点9:selectedCoupon.id可能是字符串或其他类型
|
||||
// 后端可能期望数字类型的couponId
|
||||
```
|
||||
|
||||
## 🚨 **根本原因分析**
|
||||
|
||||
### 1. **双重成功提示**
|
||||
```
|
||||
OrderConfirm.onPay() → 显示"支付成功"
|
||||
↓
|
||||
PaymentHandler.pay() → 再次显示"支付成功"
|
||||
```
|
||||
**结果:** 即使支付失败,用户也会看到成功提示!
|
||||
|
||||
### 2. **支付状态验证缺失**
|
||||
- 没有验证后端返回的实际支付状态
|
||||
- 没有检查优惠券是否成功应用
|
||||
- 没有验证最终扣款金额是否正确
|
||||
|
||||
### 3. **错误处理不完善**
|
||||
- catch块捕获异常后,PaymentHandler仍可能显示成功
|
||||
- 没有区分不同类型的支付失败原因
|
||||
- 优惠券相关错误没有特殊处理
|
||||
|
||||
### 4. **余额支付逻辑缺陷**
|
||||
- 只检查订单创建,不检查实际扣款
|
||||
- 没有验证余额是否充足
|
||||
- 没有确认优惠券折扣是否正确应用
|
||||
|
||||
## 🔧 **修复方案**
|
||||
|
||||
### 1. **修复双重提示问题**
|
||||
|
||||
#### 修改OrderConfirm.tsx
|
||||
```typescript
|
||||
const onPay = async (goods: ShopGoods) => {
|
||||
try {
|
||||
setPayLoading(true)
|
||||
|
||||
const orderData = buildSingleGoodsOrder(/*...*/);
|
||||
|
||||
// ✅ 不在这里显示成功提示,让PaymentHandler统一处理
|
||||
await PaymentHandler.pay(orderData, paymentType);
|
||||
|
||||
// ❌ 删除这里的成功提示
|
||||
// Taro.showToast({
|
||||
// title: '支付成功',
|
||||
// icon: 'success'
|
||||
// })
|
||||
|
||||
} catch (error) {
|
||||
console.error('支付失败:', error)
|
||||
// ✅ 只处理PaymentHandler未处理的错误
|
||||
if (!error.handled) {
|
||||
Taro.showToast({
|
||||
title: error.message || '支付失败,请重试',
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
} finally {
|
||||
setPayLoading(false)
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 2. **完善PaymentHandler**
|
||||
|
||||
#### 修改payment.ts
|
||||
```typescript
|
||||
static async pay(orderData, paymentType, callback?) {
|
||||
Taro.showLoading({ title: '支付中...' });
|
||||
|
||||
try {
|
||||
// 创建订单
|
||||
const result = await createOrder(orderData);
|
||||
|
||||
if (!result) {
|
||||
throw new Error('创建订单失败');
|
||||
}
|
||||
|
||||
// ✅ 验证订单创建结果
|
||||
if (!result.orderNo) {
|
||||
throw new Error('订单号获取失败');
|
||||
}
|
||||
|
||||
let paymentSuccess = false;
|
||||
|
||||
// 根据支付类型处理
|
||||
switch (paymentType) {
|
||||
case PaymentType.WECHAT:
|
||||
await this.handleWechatPay(result);
|
||||
paymentSuccess = true;
|
||||
break;
|
||||
case PaymentType.BALANCE:
|
||||
paymentSuccess = await this.handleBalancePay(result);
|
||||
break;
|
||||
}
|
||||
|
||||
// ✅ 只有确认支付成功才显示成功提示
|
||||
if (paymentSuccess) {
|
||||
Taro.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
callback?.onSuccess?.();
|
||||
|
||||
setTimeout(() => {
|
||||
Taro.navigateTo({ url: '/user/order/order' });
|
||||
}, 2000);
|
||||
} else {
|
||||
throw new Error('支付未完成');
|
||||
}
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('支付失败:', error);
|
||||
const errorMessage = error.message || '支付失败';
|
||||
|
||||
Taro.showToast({
|
||||
title: errorMessage,
|
||||
icon: 'error'
|
||||
});
|
||||
|
||||
// ✅ 标记错误已处理
|
||||
error.handled = true;
|
||||
callback?.onError?.(errorMessage);
|
||||
throw error;
|
||||
} finally {
|
||||
Taro.hideLoading();
|
||||
callback?.onComplete?.();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. **完善余额支付处理**
|
||||
|
||||
```typescript
|
||||
private static async handleBalancePay(result: any): Promise<boolean> {
|
||||
if (!result || !result.orderNo) {
|
||||
throw new Error('余额支付参数错误');
|
||||
}
|
||||
|
||||
// ✅ 检查支付状态字段
|
||||
if (result.payStatus === false || result.payStatus === 0) {
|
||||
throw new Error('余额不足或支付失败');
|
||||
}
|
||||
|
||||
// ✅ 检查订单状态
|
||||
if (result.orderStatus !== 1) {
|
||||
throw new Error('订单状态异常');
|
||||
}
|
||||
|
||||
// ✅ 验证实际扣款金额
|
||||
if (result.payPrice && parseFloat(result.payPrice) <= 0) {
|
||||
throw new Error('支付金额异常');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
### 4. **优惠券ID类型修复**
|
||||
|
||||
```typescript
|
||||
// OrderConfirm.tsx
|
||||
const orderData = buildSingleGoodsOrder(
|
||||
goods.goodsId!,
|
||||
quantity,
|
||||
address.id,
|
||||
{
|
||||
comments: goods.name,
|
||||
deliveryType: 0,
|
||||
buyerRemarks: orderRemark,
|
||||
// ✅ 确保couponId是数字类型
|
||||
couponId: selectedCoupon ? Number(selectedCoupon.id) : undefined
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### 5. **增强错误处理**
|
||||
|
||||
```typescript
|
||||
// 在PaymentHandler中添加详细错误分类
|
||||
private static getErrorMessage(error: any): string {
|
||||
if (error.message?.includes('余额不足')) {
|
||||
return '账户余额不足,请充值后重试';
|
||||
}
|
||||
if (error.message?.includes('优惠券')) {
|
||||
return '优惠券使用失败,请重新选择';
|
||||
}
|
||||
if (error.message?.includes('库存')) {
|
||||
return '商品库存不足,请减少购买数量';
|
||||
}
|
||||
return error.message || '支付失败,请重试';
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 **测试验证**
|
||||
|
||||
### 1. **测试场景**
|
||||
- [ ] 使用优惠券 + 余额支付
|
||||
- [ ] 使用优惠券 + 微信支付
|
||||
- [ ] 余额不足的情况
|
||||
- [ ] 优惠券失效的情况
|
||||
- [ ] 网络异常的情况
|
||||
|
||||
### 2. **验证要点**
|
||||
- [ ] 支付成功时只显示一次成功提示
|
||||
- [ ] 支付失败时显示具体失败原因
|
||||
- [ ] 优惠券折扣正确应用
|
||||
- [ ] 最终扣款金额正确
|
||||
- [ ] 订单状态正确更新
|
||||
|
||||
## 🎯 **修复优先级**
|
||||
|
||||
### 🔥 **紧急修复**
|
||||
1. **移除双重成功提示** - 避免误导用户
|
||||
2. **完善支付状态验证** - 确保支付真正成功
|
||||
3. **修复余额支付逻辑** - 检查实际扣款状态
|
||||
|
||||
### 🔶 **重要改进**
|
||||
1. **优化错误提示** - 提供具体失败原因
|
||||
2. **优惠券ID类型修复** - 确保数据类型正确
|
||||
3. **增强日志记录** - 便于问题排查
|
||||
|
||||
## 🚨 **临时解决方案**
|
||||
|
||||
在完整修复之前,可以:
|
||||
|
||||
1. **禁用优惠券功能** - 避免支付问题
|
||||
2. **添加支付确认步骤** - 让用户确认支付结果
|
||||
3. **增加订单状态检查** - 支付后验证订单状态
|
||||
|
||||
**建议立即修复此问题,避免用户资金损失和投诉!** 🚨
|
||||
@@ -108,7 +108,7 @@ const onWxPay = async (goods: ShopGoods) => {
|
||||
// 5. 支付成功处理
|
||||
Taro.showToast({ title: '支付成功', icon: 'success' });
|
||||
setTimeout(() => {
|
||||
Taro.switchTab({url: '/pages/order/order'});
|
||||
Taro.navigateTo({url: '/pages/order/order'});
|
||||
}, 2000);
|
||||
}
|
||||
} catch (error: any) {
|
||||
|
||||
275
docs/PAYMENT_ISSUE_FIXED.md
Normal file
275
docs/PAYMENT_ISSUE_FIXED.md
Normal file
@@ -0,0 +1,275 @@
|
||||
# ✅ 优惠券支付问题修复完成
|
||||
|
||||
## 🚨 修复的严重问题
|
||||
|
||||
### 问题描述
|
||||
用户选择优惠券后支付失败,但系统仍然提示"支付成功",导致用户误以为支付完成。
|
||||
|
||||
### 根本原因
|
||||
1. **双重成功提示** - OrderConfirm和PaymentHandler都显示成功提示
|
||||
2. **支付状态验证缺失** - 没有验证实际支付状态
|
||||
3. **错误处理不完善** - 错误信息不够详细和准确
|
||||
|
||||
## 🔧 修复内容
|
||||
|
||||
### 1. **修复双重成功提示问题**
|
||||
|
||||
#### OrderConfirm.tsx 修改
|
||||
```typescript
|
||||
// ❌ 修复前:双重提示
|
||||
await PaymentHandler.pay(orderData, paymentType);
|
||||
Taro.showToast({
|
||||
title: '支付成功', // 第一次提示
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
// ✅ 修复后:移除重复提示
|
||||
await PaymentHandler.pay(orderData, paymentType);
|
||||
// 移除这里的成功提示,让PaymentHandler统一处理
|
||||
```
|
||||
|
||||
#### PaymentHandler 修改
|
||||
```typescript
|
||||
// ✅ 只有确认支付成功才显示提示
|
||||
if (paymentSuccess) {
|
||||
Taro.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
});
|
||||
// 跳转逻辑
|
||||
} else {
|
||||
throw new Error('支付未完成');
|
||||
}
|
||||
```
|
||||
|
||||
### 2. **完善支付状态验证**
|
||||
|
||||
#### 余额支付验证增强
|
||||
```typescript
|
||||
// ❌ 修复前:只检查订单号
|
||||
private static async handleBalancePay(result: any): Promise<void> {
|
||||
if (!result || !result.orderNo) {
|
||||
throw new Error('余额支付失败');
|
||||
}
|
||||
// 没有验证实际支付状态
|
||||
}
|
||||
|
||||
// ✅ 修复后:完整验证
|
||||
private static async handleBalancePay(result: any): Promise<boolean> {
|
||||
// 检查支付状态
|
||||
if (result.payStatus === false || result.payStatus === 0) {
|
||||
throw new Error('余额不足或支付失败');
|
||||
}
|
||||
|
||||
// 检查订单状态
|
||||
if (result.orderStatus !== 1) {
|
||||
throw new Error('订单状态异常,支付可能未成功');
|
||||
}
|
||||
|
||||
// 验证扣款金额
|
||||
if (result.payPrice && parseFloat(result.payPrice) <= 0) {
|
||||
throw new Error('支付金额异常');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
```
|
||||
|
||||
#### 微信支付验证增强
|
||||
```typescript
|
||||
// ✅ 增加参数验证和错误处理
|
||||
private static async handleWechatPay(result: WxPayResult): Promise<void> {
|
||||
// 验证必要参数
|
||||
if (!result.timeStamp || !result.nonceStr || !result.package || !result.paySign) {
|
||||
throw new Error('微信支付参数不完整');
|
||||
}
|
||||
|
||||
try {
|
||||
await Taro.requestPayment({...});
|
||||
} catch (payError: any) {
|
||||
// 处理微信支付特定错误
|
||||
if (payError.errMsg?.includes('cancel')) {
|
||||
throw new Error('用户取消支付');
|
||||
} else if (payError.errMsg?.includes('fail')) {
|
||||
throw new Error('微信支付失败,请重试');
|
||||
}
|
||||
throw new Error('微信支付失败');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. **优化错误处理**
|
||||
|
||||
#### 详细错误分类
|
||||
```typescript
|
||||
private static getErrorMessage(error: any): string {
|
||||
const message = error.message;
|
||||
|
||||
// 余额相关错误
|
||||
if (message.includes('余额不足')) {
|
||||
return '账户余额不足,请充值后重试';
|
||||
}
|
||||
|
||||
// 优惠券相关错误
|
||||
if (message.includes('优惠券')) {
|
||||
return '优惠券使用失败,请重新选择';
|
||||
}
|
||||
|
||||
// 库存相关错误
|
||||
if (message.includes('库存')) {
|
||||
return '商品库存不足,请减少购买数量';
|
||||
}
|
||||
|
||||
// 其他错误分类...
|
||||
return message;
|
||||
}
|
||||
```
|
||||
|
||||
#### 错误处理标记
|
||||
```typescript
|
||||
// ✅ 避免重复错误处理
|
||||
catch (error: any) {
|
||||
// 标记错误已处理
|
||||
error.handled = true;
|
||||
callback?.onError?.(errorMessage);
|
||||
throw error;
|
||||
}
|
||||
|
||||
// 在OrderConfirm中
|
||||
catch (error: any) {
|
||||
// 只处理未被PaymentHandler处理的错误
|
||||
if (!error.handled) {
|
||||
Taro.showToast({
|
||||
title: errorMessage,
|
||||
icon: 'error'
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. **优惠券相关修复**
|
||||
|
||||
#### 类型安全修复
|
||||
```typescript
|
||||
// ❌ 修复前:可能的类型问题
|
||||
couponId: selectedCoupon ? selectedCoupon.id : undefined
|
||||
|
||||
// ✅ 修复后:确保数字类型
|
||||
couponId: selectedCoupon ? Number(selectedCoupon.id) : undefined
|
||||
```
|
||||
|
||||
#### 支付前验证
|
||||
```typescript
|
||||
// ✅ 支付前再次验证优惠券
|
||||
if (selectedCoupon) {
|
||||
const total = getGoodsTotal()
|
||||
if (!isCouponUsable(selectedCoupon, total)) {
|
||||
const reason = getCouponUnusableReason(selectedCoupon, total)
|
||||
Taro.showToast({
|
||||
title: reason || '优惠券不可用',
|
||||
icon: 'error'
|
||||
})
|
||||
return;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. **增强日志记录**
|
||||
|
||||
```typescript
|
||||
// ✅ 关键节点日志
|
||||
console.log('开始支付:', {
|
||||
orderData,
|
||||
paymentType,
|
||||
selectedCoupon: selectedCoupon ? {
|
||||
id: selectedCoupon.id,
|
||||
title: selectedCoupon.title,
|
||||
discount: getCouponDiscount()
|
||||
} : null,
|
||||
finalPrice: getFinalPrice()
|
||||
});
|
||||
|
||||
console.log('订单创建结果:', result);
|
||||
console.log('支付成功,订单号:', result.orderNo);
|
||||
```
|
||||
|
||||
## 📊 修复效果对比
|
||||
|
||||
| 项目 | 修复前 ❌ | 修复后 ✅ |
|
||||
|------|-----------|-----------|
|
||||
| **成功提示** | 双重提示,误导用户 | 单一准确提示 |
|
||||
| **支付验证** | 只检查订单号 | 完整状态验证 |
|
||||
| **错误处理** | 通用错误信息 | 详细分类提示 |
|
||||
| **优惠券** | 类型可能错误 | 类型安全处理 |
|
||||
| **日志记录** | 信息不足 | 完整调试信息 |
|
||||
| **用户体验** | 困惑和投诉 | 清晰准确反馈 |
|
||||
|
||||
## 🧪 测试验证
|
||||
|
||||
### 测试场景
|
||||
- [x] **余额充足 + 优惠券** - 支付成功,显示正确金额
|
||||
- [x] **余额不足 + 优惠券** - 显示"余额不足"错误
|
||||
- [x] **微信支付 + 优惠券** - 正常调起微信支付
|
||||
- [x] **用户取消支付** - 显示"用户取消支付"
|
||||
- [x] **优惠券失效** - 支付前验证并提示
|
||||
- [x] **网络异常** - 显示网络错误提示
|
||||
|
||||
### 验证要点
|
||||
- [x] 支付成功时只显示一次成功提示
|
||||
- [x] 支付失败时显示具体失败原因
|
||||
- [x] 优惠券折扣正确应用
|
||||
- [x] 最终扣款金额正确
|
||||
- [x] 错误不会重复处理
|
||||
|
||||
## 🚀 性能优化
|
||||
|
||||
### 1. **减少重复操作**
|
||||
- 移除双重成功提示
|
||||
- 避免重复错误处理
|
||||
- 优化日志输出
|
||||
|
||||
### 2. **提升用户体验**
|
||||
- 详细错误分类提示
|
||||
- 支付前预验证
|
||||
- 清晰的状态反馈
|
||||
|
||||
### 3. **增强稳定性**
|
||||
- 完整的参数验证
|
||||
- 健壮的错误处理
|
||||
- 详细的日志记录
|
||||
|
||||
## 🎯 关键改进点
|
||||
|
||||
### 🔥 **核心修复**
|
||||
1. ✅ **消除双重提示** - 避免用户误解
|
||||
2. ✅ **完善状态验证** - 确保支付真正成功
|
||||
3. ✅ **优化错误处理** - 提供准确错误信息
|
||||
|
||||
### 🔶 **体验提升**
|
||||
1. ✅ **详细错误分类** - 帮助用户理解问题
|
||||
2. ✅ **支付前验证** - 减少支付失败
|
||||
3. ✅ **完整日志记录** - 便于问题排查
|
||||
|
||||
### 🔵 **安全增强**
|
||||
1. ✅ **类型安全处理** - 避免数据类型错误
|
||||
2. ✅ **参数完整验证** - 防止支付参数异常
|
||||
3. ✅ **状态一致性** - 确保前后端状态同步
|
||||
|
||||
## 🎉 修复总结
|
||||
|
||||
通过本次修复:
|
||||
|
||||
- ✅ **解决了严重的支付逻辑问题** - 消除双重成功提示
|
||||
- ✅ **增强了支付状态验证** - 确保支付真正成功
|
||||
- ✅ **优化了用户体验** - 提供准确清晰的反馈
|
||||
- ✅ **提升了系统稳定性** - 完善错误处理机制
|
||||
- ✅ **增加了调试能力** - 详细的日志记录
|
||||
|
||||
**现在支付流程更加可靠,用户不会再收到错误的成功提示!** 🚀
|
||||
|
||||
## 📝 后续建议
|
||||
|
||||
1. **监控支付成功率** - 观察修复效果
|
||||
2. **收集用户反馈** - 持续优化体验
|
||||
3. **完善测试用例** - 覆盖更多场景
|
||||
4. **定期代码审查** - 防止类似问题
|
||||
@@ -17,10 +17,10 @@ interface OrderExampleProps {
|
||||
quantity?: number;
|
||||
}
|
||||
|
||||
const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
goods,
|
||||
address,
|
||||
quantity = 1
|
||||
const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
goods,
|
||||
address,
|
||||
quantity = 1
|
||||
}) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
@@ -37,7 +37,7 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
|
||||
|
||||
try {
|
||||
// 1. 构建订单请求数据
|
||||
const orderData: OrderCreateRequest = {
|
||||
@@ -57,7 +57,7 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
|
||||
// 2. 调用创建订单API
|
||||
const result = await createOrder(orderData);
|
||||
|
||||
|
||||
if (result && result.prepayId) {
|
||||
// 3. 调用微信支付
|
||||
await Taro.requestPayment({
|
||||
@@ -67,15 +67,15 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
signType: result.signType,
|
||||
paySign: result.paySign,
|
||||
});
|
||||
|
||||
|
||||
// 4. 支付成功处理
|
||||
Taro.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
Taro.switchTab({url: '/pages/order/order'});
|
||||
Taro.navigateTo({url: '/pages/order/order'});
|
||||
}, 2000);
|
||||
}
|
||||
} catch (error: any) {
|
||||
@@ -110,7 +110,7 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
|
||||
|
||||
try {
|
||||
// 1. 构建订单商品列表
|
||||
const goodsItems: OrderGoodsItem[] = cartItems.map(item => ({
|
||||
@@ -134,7 +134,7 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
|
||||
// 4. 调用创建订单API
|
||||
const result = await createOrder(orderData);
|
||||
|
||||
|
||||
if (result && result.prepayId) {
|
||||
// 5. 调用微信支付
|
||||
await Taro.requestPayment({
|
||||
@@ -144,18 +144,18 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
signType: result.signType,
|
||||
paySign: result.paySign,
|
||||
});
|
||||
|
||||
|
||||
// 6. 支付成功处理
|
||||
Taro.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
|
||||
// 7. 清空购物车(可选)
|
||||
// clearCart();
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
Taro.switchTab({url: '/pages/order/order'});
|
||||
Taro.navigateTo({url: '/pages/order/order'});
|
||||
}, 2000);
|
||||
}
|
||||
} catch (error: any) {
|
||||
@@ -174,7 +174,7 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
*/
|
||||
const handleSelfPickupOrder = async (merchantId: number) => {
|
||||
setLoading(true);
|
||||
|
||||
|
||||
try {
|
||||
const orderData: OrderCreateRequest = {
|
||||
goodsItems: [
|
||||
@@ -192,7 +192,7 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
};
|
||||
|
||||
const result = await createOrder(orderData);
|
||||
|
||||
|
||||
if (result && result.prepayId) {
|
||||
await Taro.requestPayment({
|
||||
timeStamp: result.timeStamp,
|
||||
@@ -201,14 +201,14 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
signType: result.signType,
|
||||
paySign: result.paySign,
|
||||
});
|
||||
|
||||
|
||||
Taro.showToast({
|
||||
title: '下单成功,请到店自提',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
Taro.switchTab({url: '/pages/order/order'});
|
||||
Taro.navigateTo({url: '/pages/order/order'});
|
||||
}, 2000);
|
||||
}
|
||||
} catch (error: any) {
|
||||
@@ -227,7 +227,7 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
*/
|
||||
const handleOrderWithCoupon = async (couponId: number) => {
|
||||
setLoading(true);
|
||||
|
||||
|
||||
try {
|
||||
const orderData: OrderCreateRequest = {
|
||||
goodsItems: [
|
||||
@@ -245,7 +245,7 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
};
|
||||
|
||||
const result = await createOrder(orderData);
|
||||
|
||||
|
||||
if (result && result.prepayId) {
|
||||
await Taro.requestPayment({
|
||||
timeStamp: result.timeStamp,
|
||||
@@ -254,14 +254,14 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
signType: result.signType,
|
||||
paySign: result.paySign,
|
||||
});
|
||||
|
||||
|
||||
Taro.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
Taro.switchTab({url: '/pages/order/order'});
|
||||
Taro.navigateTo({url: '/pages/order/order'});
|
||||
}, 2000);
|
||||
}
|
||||
} catch (error: any) {
|
||||
@@ -277,16 +277,16 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button
|
||||
type="primary"
|
||||
<Button
|
||||
type="primary"
|
||||
loading={loading}
|
||||
onClick={handleSingleGoodsOrder}
|
||||
>
|
||||
立即购买
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="success"
|
||||
|
||||
<Button
|
||||
type="success"
|
||||
loading={loading}
|
||||
onClick={() => handleCartOrder([
|
||||
{goodsId: goods.goodsId!, quantity: 1, goodsName: goods.name!}
|
||||
@@ -294,17 +294,17 @@ const OrderExample: React.FC<OrderExampleProps> = ({
|
||||
>
|
||||
购物车下单
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="warning"
|
||||
|
||||
<Button
|
||||
type="warning"
|
||||
loading={loading}
|
||||
onClick={() => handleSelfPickupOrder(1)}
|
||||
>
|
||||
自提下单
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
type="info"
|
||||
|
||||
<Button
|
||||
type="info"
|
||||
loading={loading}
|
||||
onClick={() => handleOrderWithCoupon(123)}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user