weixin_58412143 2025-11-07 11:29 采纳率: 83.7%
浏览 11
已结题

支付完成后跳转到一个提示页面再返回i充值页数据不刷新怎么解决,监听路由,visibilitychange事件监听器都不行

微信内置浏览器支付完成后跳转到一个提示页面再返回i充值页数据不刷新怎么解决,监听路由,visibilitychange事件监听器都不行
topUP页面支付跳转到details页做轮询请求后端接口是否成功支付,5秒后自动或者直接返回topUP充值页面,充值金额不是最新的,要刷新才行,

onMounted(() => {
  openID.value = localStorage.getItem("OpenID");
  appID.value = localStorage.getItem("APPID");
  
  // 添加visibilitychange事件监听器
  document.addEventListener('visibilitychange', handleVisibilityChange);
  console.log("首页参数:", cardInfo.value?.CardAvailableCredit);
  
  // 页面加载时,检查是否已缓存卡片信息,如果没有则获取
  try {
    if (localStorage.getItem("AppWeChat") === "1") {
      if (!userStore.cardInfo.EmployeeDeptName) {
        fetchCardInfo();
      }
    } else {
      router.push({
        name: "error",
        query: {
          message: t("PlatformUnavailable"),
        },
      });
      return;
    }
  } catch (error) {
    console.error("获取卡片信息失败:", error);
    // showToast(t('FailedToGetCardInfo'));
  }
});
onUnmounted(() => {
  // 移除visibilitychange事件监听器
  document.removeEventListener('visibilitychange', handleVisibilityChange);
});
// 处理页面可见性变化的函数
const handleVisibilityChange = () => {
  console.log('页面可见性变化:', document.visibilityState);
  // 当页面变为可见时(从其他页面返回),刷新数据
  if (document.visibilityState === 'visible') {
    console.log('页面重新可见,刷新数据...');
    // 清理缓存并刷新数据
    localStorage.removeItem("cardInfo");
    fetchCardInfo();
    // 也可以选择直接刷新页面
    // location.reload();
  }
};
const orderNo = ref("");
const handleRecharge = () => {
  if (!amount.value) {
    showToast(t("PleaseEnterRechargeAmount"));
    return;
  }
  orderNo.value = generateOrderNo(cardInfo.value.EmployeeID, 5);
  // 处理充值逻辑
  showLoadingToast({
    message: t("Recharging"),
    forbidClick: true,
  });

  try {
    passageApi
      .getWeChatRecharge(amount.value * 100, orderNo.value)
      .then((res) => {
        console.log("res", res);
        // 请求成功后关闭loading
        document.querySelector(".van-loading-toast")?.remove();

        // 可以根据响应结果显示成功消息
        if (res && res.success) {
          const payParams = res.data.pay_params;
          console.log("payParams", payParams);
          WeixinJSBridge.invoke(
            "getBrandWCPayRequest",
            {
              appId: payParams.appId,
              timeStamp: payParams.timeStamp,
              nonceStr: payParams.nonceStr,
              package: payParams.package,
              signType: payParams.signType,
              paySign: payParams.paySign,
            },
            function (res) {
              WeixinJSBridge.log(res.err_msg);
              // alert(res.err_code + res.err_desc + res.err_msg);
              if (res.err_msg == "get_brand_wcpay_request:ok") {
                console.log("用户支付成功,等待服务器确认...");
                router.push({
                  name: "payDetails",
                  query: { orderNo: orderNo.value },
                });
                // 先刷新页面
  // setTimeout(() => {
  //   location.reload();
  //   // 刷新后延迟一小段时间再跳转,确保页面已完全加载
  //   setTimeout(() => {
  //     router.push({
  //       name: "payDetails",
  //       query: { orderNo: orderNo.value },
  //     });
  //   }, 300);
  // }, 100);
                // do something
              } else if (res.err_msg == "get_brand_wcpay_request:cancel") {
                alert(t("PaymentCancelled"));
                // setTimeout(() => {
                //   location.reload();
                // }, 100);
                router.push({
                  name: "payDetails",
                  query: { orderNo: orderNo.value },
                });
                // do something
              } else if (res.err_msg == "get_brand_wcpay_request:fail") {
                alert(t("PaymentFailed"));
                // do something
              }
            }
          );
          // setTimeout(() => {
          //   router.push({ name: "home" });
          // }, 1500);
        } else {
          // showToast(res?.message || t('RechargeFailed'));
          console.log("充值接口失败");
        }
      })
      .catch((error) => {
        console.error("充值请求失败:", error);
        showToast(t("RechargeFailed"));
      })
      .finally(() => {
        // 无论请求成功或失败,都关闭loading
        amount.value = "";
        document.querySelector(".van-loading-toast")?.remove();
      });
  } catch (error) {
    // 请求失败时也关闭loading
    document.querySelector(".van-loading-toast")?.remove();
    console.error("充值请求失败:", error);
    showToast(t("RechargeFailed"));
  }
};

details

// 轮询订单状态
const pollOrderStatus = async () => {
  const orderNo = route.query.orderNo;
  // if (!orderNo) {
  //   showToast(t('InvalidOrder'));
  //   return;
  // }
// 
  const poll = async () => {
    attempts++;
    try {
      // const res = await passageApi.queryOrderStatus('50491631762399696474');
      const res = await passageApi.queryOrderStatus(orderNo);
      if (res.success) {
        infoData.value = res.data;

        // 如果已确定最终状态,可以提前停止轮询(但倒计时仍继续)
        if (res.data.RechargeStatus === 1 ) {
          clearInterval(pollingTimer);
        }
      }
    } catch (error) {
      console.error('查询订单失败:', error);
      if (attempts >= maxAttempts) {
        clearInterval(pollingTimer);
      }
    }

    // 继续轮询(直到达到最大次数)
    if (attempts < maxAttempts && !infoData.value?.RechargeStatus) {
      pollingTimer = setTimeout(poll, 1500);
    }
  };

  poll();
};
// Add confetti particles dynamically
  onMounted(() => {
    const orderNo = route.query.orderNo;
    // if (orderNo) {
      pollOrderStatus();
    startCountdown(); // 启动秒倒计时
  // }
  
});

  • 写回答

3条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-11-07 12:42
    关注

    让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。

    如果答案让您满意,请采纳、点赞、关注,非常感谢!
    .
    每日一句正能量,让它带给您好心情:别让懒惰吞噬你的梦想,行动起来,一切都还来得及。
    .

    根据你的描述,这是一个典型的微信支付后页面状态同步问题。在微信内置浏览器中,支付完成后返回原页面时,页面可能不会自动刷新数据。我来分析并提供几种解决方案:

    问题分析

    从你的代码看,主要问题是:

    1. visibilitychange 事件在微信浏览器中可能不可靠
    2. 页面返回时没有强制刷新数据
    3. 支付状态轮询在 details 页面,但返回 topUP 页面时没有同步更新

    解决方案

    方案1:使用页面显示事件 + 本地存储状态同步

    在 topUP 页面的 onMounted 中添加页面显示事件监听:

    onMounted(() => {
      openID.value = localStorage.getItem("OpenID");
      appID.value = localStorage.getItem("APPID");
      
      // 添加页面显示事件监听
      window.addEventListener('pageshow', handlePageShow);
      
      // 原有的 visibilitychange 监听保留作为备用
      document.addEventListener('visibilitychange', handleVisibilityChange);
      
      fetchCardInfo();
    });
    
    
    onUnmounted(() => {
      window.removeEventListener('pageshow', handlePageShow);
      document.removeEventListener('visibilitychange', handleVisibilityChange);
    });
    
    
    // 处理页面显示事件
    const handlePageShow = (event) => {
      console.log('页面显示事件触发', event.persisted);
      // 如果页面是从缓存中恢复的(如支付后返回)
      if (event.persisted) {
        console.log('页面从缓存恢复,刷新数据');
        refreshData();
      }
    };
    
    
    // 统一的刷新数据方法
    const refreshData = () => {
      console.log('执行数据刷新');
      localStorage.removeItem("cardInfo");
      fetchCardInfo();
      
      // 同时检查是否有未完成的支付订单
      checkPendingPayment();
    };
    
    
    // 检查未完成支付
    const checkPendingPayment = async () => {
      const pendingOrder = localStorage.getItem('pendingPaymentOrder');
      if (pendingOrder) {
        try {
          const res = await passageApi.queryOrderStatus(pendingOrder);
          if (res.success && res.data.RechargeStatus === 1) {
            // 支付成功,更新数据
            fetchCardInfo();
            // 清除待处理订单标记
            localStorage.removeItem('pendingPaymentOrder');
          }
        } catch (error) {
          console.error('检查待支付订单失败:', error);
        }
      }
    };
    

    方案2:在支付跳转前标记状态

    修改支付跳转逻辑:

    const handleRecharge = () => {
      if (!amount.value) {
        showToast(t("PleaseEnterRechargeAmount"));
        return;
      }
      
      orderNo.value = generateOrderNo(cardInfo.value.EmployeeID, 5);
      
      // 在跳转前标记有支付订单在进行
      localStorage.setItem('pendingPaymentOrder', orderNo.value);
      
      showLoadingToast({
        message: t("Recharging"),
        forbidClick: true,
      });
      
      // 原有的支付逻辑...
      WeixinJSBridge.invoke(
        "getBrandWCPayRequest",
        {
          appId: payParams.appId,
          timeStamp: payParams.timeStamp,
          nonceStr: payParams.nonceStr,
          package: payParams.package,
          signType: payParams.signType,
          paySign: payParams.paySign,
        },
        function (res) {
          WeixinJSBridge.log(res.err_msg);
          if (res.err_msg == "get_brand_wcpay_request:ok") {
            console.log("用户支付成功,等待服务器确认...");
            // 标记支付成功,等待确认
            localStorage.setItem('paymentSuccess', 'true');
            router.push({
              name: "payDetails",
              query: { orderNo: orderNo.value },
            });
          } else {
            // 支付取消或失败,清除标记
            localStorage.removeItem('pendingPaymentOrder');
            localStorage.removeItem('paymentSuccess');
            router.push({
              name: "payDetails",
              query: { orderNo: orderNo.value },
            });
          }
        }
      );
    };
    

    方案3:在 details 页面返回时传递状态

    在 details 页面的返回逻辑中添加数据刷新:

    // 在 details 页面
    const handleReturn = () => {
      // 在返回前设置刷新标记
      localStorage.setItem('shouldRefreshTopUP', 'true');
      router.back();
    };
    
    
    // 或者在倒计时结束后自动返回时设置
    const startCountdown = () => {
      // 原有的倒计时逻辑...
      
      // 倒计时结束后
      setTimeout(() => {
        localStorage.setItem('shouldRefreshTopUP', 'true');
        router.back();
      }, 5000);
    };
    

    然后在 topUP 页面检查这个标记:

    // 在 topUP 页面的 onMounted 或页面显示事件中
    const checkRefreshFlag = () => {
      const shouldRefresh = localStorage.getItem('shouldRefreshTopUP');
      if (shouldRefresh === 'true') {
        console.log('检测到需要刷新数据的标记');
        refreshData();
        localStorage.removeItem('shouldRefreshTopUP');
      }
    };
    
    
    // 在 handlePageShow 或 handleVisibilityChange 中调用
    const handlePageShow = (event) => {
      if (event.persisted) {
        refreshData();
      }
      checkRefreshFlag(); // 检查刷新标记
    };
    

    方案4:使用路由守卫强制刷新

    在路由配置中添加元信息:

    // 路由配置
    {
      path: '/topUP',
      name: 'topUP',
      component: TopUP,
      meta: {
        requireAuth: true,
        keepAlive: false // 确保不缓存页面
      }
    }
    

    在路由守卫中处理:

    // 路由守卫
    router.beforeEach((to, from, next) => {
      if (from.name === 'payDetails' && to.name === 'topUP') {
        // 从支付详情页返回充值页,强制刷新
        console.log('从支付页面返回,需要刷新数据');
        // 可以在这里设置标记或直接调用刷新方法
      }
      next();
    });
    

    推荐的综合方案

    结合以上几种方法,建议采用:

    1. 主要依赖 pageshow 事件
    2. 备用方案 visibilitychange 事件
    3. 状态同步 使用 localStorage 标记支付状态
    4. 数据刷新 统一的刷新方法

    这样可以在大多数情况下确保数据正确更新,即使某个事件监听失效也有备用方案。

    关键是要在支付流程的各个环节都做好状态标记和数据同步,确保用户返回时能看到最新的余额信息。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 11月15日
  • 已采纳回答 11月7日
  • 创建了问题 11月7日