hookehuyr

feat(订单支付): 优化支付成功后订单状态更新逻辑

修改支付组件和订单页面,使用事件驱动方式更新订单状态
移除页面重新加载方式,提升用户体验和性能
添加支付成功事件处理函数,实现订单状态本地更新
更新相关文档说明优化方案和效果
# 支付成功后订单状态更新优化
## 问题描述
原来的实现中,在我的订单页面支付成功后,使用 `Taro.reLaunch()` 重新加载整个页面来刷新订单状态。这种方式存在以下问题:
1. **用户体验差**:页面重新加载会导致闪烁,用户体验不佳
2. **性能问题**:重新加载整个页面消耗更多资源
3. **状态丢失**:页面重新加载会丢失当前的筛选状态、滚动位置等
4. **不必要的网络请求**:重新加载会触发不必要的数据请求
## 解决方案
### 1. 修改支付组件 (payCard.vue)
#### 添加支付成功事件
```javascript
// 添加 paySuccess 事件到 emit 声明
const emit = defineEmits(['close', 'paySuccess']);
```
#### 修改支付成功处理逻辑
```javascript
// 原来的实现:重新加载页面
if (current_page === 'pages/myOrders/index') {
Taro.reLaunch({
url: '/pages/myOrders/index'
});
}
// 新的实现:发出事件通知父组件
if (current_page === 'pages/myOrders/index') {
// 发出支付成功事件,通知父组件更新订单状态
emit('paySuccess', { orderId: id.value });
}
```
### 2. 修改订单页面 (myOrders/index.vue)
#### 监听支付成功事件
```vue
<!-- 在模板中添加事件监听 -->
<payCard
:visible="show_pay"
:data="payData"
@close="onPayClose"
@paySuccess="onPaySuccess"
/>
```
#### 添加支付成功处理函数
```javascript
/**
* 处理支付成功事件
* @param {Object} data - 支付成功数据
* @param {string} data.orderId - 订单ID
*/
const onPaySuccess = ({ orderId }) => {
// 找到对应的订单并更新状态
const orders = viewMode.value === 'bought' ? boughtOrders.value : soldOrders.value
const order = orders.find(o => o.id === orderId)
if (order) {
// 更新订单状态为已完成
order.status = 'completed'
Taro.showToast({
title: '支付成功,订单已更新',
icon: 'success',
duration: 2000
})
}
}
```
## 优化效果
### 1. 用户体验提升
-**无页面闪烁**:订单状态实时更新,无需重新加载页面
-**保持状态**:筛选条件、滚动位置等状态得以保持
-**响应迅速**:状态更新即时生效,用户感知更好
### 2. 性能优化
-**减少资源消耗**:避免重新加载整个页面
-**减少网络请求**:无需重新获取订单列表数据
-**内存效率**:复用现有组件实例
### 3. 代码维护性
-**事件驱动**:使用标准的 Vue 事件机制
-**组件解耦**:支付组件与页面逻辑分离
-**易于扩展**:可以轻松添加更多支付相关事件
## 技术实现细节
### 事件流程
1. 用户在订单页面点击"去支付"按钮
2. 打开支付弹窗组件 (payCard)
3. 用户完成支付操作
4. 支付组件调用支付检查API确认支付成功
5. 支付组件发出 `paySuccess` 事件,传递订单ID
6. 订单页面监听到事件,根据订单ID更新对应订单状态
7. 页面UI自动响应状态变化,显示最新状态
### 数据流向
```
订单页面 → 支付组件 → 微信支付 → 支付成功 → 事件通知 → 订单页面 → 状态更新
```
## 测试建议
1. **功能测试**
- 在订单页面选择待支付订单进行支付
- 验证支付成功后订单状态是否正确更新为"已完成"
- 确认页面无重新加载现象
2. **状态保持测试**
- 切换到特定筛选标签(如"待支付")
- 滚动到页面中间位置
- 进行支付操作
- 验证支付成功后筛选状态和滚动位置是否保持
3. **边界情况测试**
- 支付失败时的处理
- 网络异常时的处理
- 多个订单同时支付的情况
## 相关文件
- `/src/components/payCard.vue` - 支付组件
- `/src/pages/myOrders/index.vue` - 订单管理页面
## 注意事项
1. 确保支付成功后的状态更新逻辑与后端API保持一致
2. 考虑添加错误处理机制,处理支付过程中的异常情况
3. 如果有其他页面也使用了支付组件,需要相应地添加事件监听
4. 建议在真实环境中测试支付流程的完整性
\ No newline at end of file
......@@ -23,7 +23,7 @@ const App = createApp({
// if (path !== 'pages/index/index' && !wx.getStorageSync("sessionid")) {
if (!wx.getStorageSync("sessionid")) {
console.warn("没有权限");
if (path === 'pages/detail/index') {
if (path === 'pages/productDetail/index') {
Taro.navigateTo({
url: `./pages/auth/index?url=${path}&id=${query.id}`,
})
......
<!--
* @Date: 2023-12-20 14:11:11
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-07-08 20:22:50
* @LastEditTime: 2025-07-09 12:16:16
* @FilePath: /jgdl/src/components/payCard.vue
* @Description: 文件描述
-->
<template>
<div class="pay-card">
<nut-action-sheet v-model:visible="props.visible" title="" @close="onClose">
<nut-action-sheet v-model:visible="visible" title="" @close="onClose">
<view style="padding: 2rem 1rem; text-align: center;">
<view style="font-size: 32rpx;">实付金额</view>
<view style="color: red; margin: 10rpx 0;"><text style="font-size: 50rpx;">¥</text><text style="font-size: 80rpx;">{{ price }}</text></view>
......@@ -47,14 +47,16 @@ const props = defineProps({
},
data: {
type: Object,
default: {},
default: () => ({}),
},
});
const emit = defineEmits(['close']);
const emit = defineEmits(['close', 'paySuccess']);
const visible = ref(false);
const onClose = () => {
emit('close');
visible.value = false;
}
const id = ref('');
......@@ -66,6 +68,7 @@ let timeId = null;
watch(
() => props.visible,
(val) => {
visible.value = val;
if (val) {
id.value = props.data.id;
price.value = props.data.price;
......@@ -74,13 +77,22 @@ watch(
}
)
watch(
() => visible.value,
(val) => {
if (!val) {
emit('close');
}
}
)
onMounted(() => {
// 进入页面后,开始倒计时
timeId = setInterval(() => {
remain_time.value ? remain_time.value -= 1 : 0;
if (remain_time.value === 0) { // 倒计时结束
clearInterval(timeId);
emit('close');
visible.value = false;
}
}, 1000);
})
......@@ -102,8 +114,8 @@ const goToPay = async () => {
package: pay.package,
signType: pay.signType,
paySign: pay.paySign,
success: async (result) => {
emit('close'); // 关闭支付弹框
success: async () => {
visible.value = false; // 关闭支付弹框
Taro.showToast({
title: '支付成功',
icon: 'success',
......@@ -113,16 +125,14 @@ const goToPay = async () => {
const pay_success = await payCheckAPI({ order_id: id.value });
if (pay_success.code) {
let current_page = getCurrentPageUrl();
if (current_page === 'pages/my/index') { // 我的页面打开
// 刷新当前页面
Taro.reLaunch({
url: '/pages/my/index?tab_index=5'
});
if (current_page === 'pages/myOrders/index') { // 我的订单打开
// 发出支付成功事件,通知父组件更新订单状态
emit('paySuccess', { orderId: id.value });
}
if (current_page === 'pages/detail/index') { // 订房确认页打开
if (current_page === 'pages/productDetail/index') { // 详情页打开
// 跳转订单成功页
Taro.navigateTo({
url: '/pages/payInfo/index',
url: '/pages/myOrders/index',
});
}
}
......
<!--
* @Date: 2022-09-19 14:11:06
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-07-09 11:36:52
* @LastEditTime: 2025-07-09 11:47:21
* @FilePath: /jgdl/src/pages/auth/index.vue
* @Description: 文件描述
-->
......@@ -60,7 +60,7 @@ export default {
// }
// TAG:处理分享跳转问题
const params = getCurrentPageParam();
if (getCurrentPageParam().url === 'pages/detail/index') { // 详情页的分享跳转处理
if (getCurrentPageParam().url === 'pages/productDetail/index') { // 详情页的分享跳转处理
Taro.reLaunch({
url: `../../${params.url}?id=${params.id}`
})
......
......@@ -120,7 +120,7 @@
</view>
<!-- 支付组件 -->
<payCard :visible="show_pay" :data="payData" @close="onPayClose" />
<payCard :visible="show_pay" :data="payData" @close="onPayClose" @paySuccess="onPaySuccess" />
<!-- 评价弹窗 -->
<nut-popup v-model:visible="showRatePopup" position="right" :style="{ width: '100%', height: '100%' }" closeable
......@@ -784,6 +784,28 @@ const onPayClose = () => {
}
/**
* 处理支付成功事件
* @param {Object} data - 支付成功数据
* @param {string} data.orderId - 订单ID
*/
const onPaySuccess = ({ orderId }) => {
// 找到对应的订单并更新状态
const orders = viewMode.value === 'bought' ? boughtOrders.value : soldOrders.value
const order = orders.find(o => o.id === orderId)
if (order) {
// 更新订单状态为已完成
order.status = 'completed'
Taro.showToast({
title: '支付成功,订单已更新',
icon: 'success',
duration: 2000
})
}
}
/**
* 查看订单详情
*/
const viewOrderDetail = (orderId) => {
......