payCard.vue 3.9 KB
<!--
 * @Date: 2023-12-20 14:11:11
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-07-03 11:43:29
 * @FilePath: /jgdl/src/components/payCard.vue
 * @Description: 文件描述
-->
<template>
  <div class="pay-card">
    <nut-action-sheet v-model:visible="props.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>
        <view style="font-size: 28rpx; margin-bottom: 20rpx;">支付剩余时间 <text style="color: red;">{{ formatTime(remain_time) }}</text></view>
        <nut-button block color="#fb923c" @tap="goToPay">立即支付</nut-button>
      </view>
    </nut-action-sheet>
  </div>
</template>

<script setup>
import Taro from '@tarojs/taro'
import { ref, watch, onMounted, onUnmounted } from 'vue'
import { getCurrentPageUrl } from "@/utils/weapp";
import { payAPI, payCheckAPI, orderSuccessAPI } from '@/api/index'

/**
 * 格式化时间
 * @param {*} seconds
 */
function formatTime(seconds) {
  const hours = Math.floor(seconds / 3600); // 计算小时数
  const minutes = Math.floor((seconds % 3600) / 60); // 计算分钟数
  const remainingSeconds = seconds % 60; // 计算剩余的秒数

  const formattedHours = String(hours).padStart(2, "0"); // 格式化小时数,保证两位数
  const formattedMinutes = String(minutes).padStart(2, "0"); // 格式化分钟数,保证两位数
  const formattedSeconds = String(remainingSeconds).padStart(2, "0"); // 格式化剩余的秒数,保证两位数

  return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
}

const props = defineProps({
  visible: {
    type: Boolean,
    default: false,
  },
  data: {
    type: Object,
    default: {},
  },
});

const emit = defineEmits(['close']);

const onClose = () => {
  emit('close');
}

const id = ref('');
const price = ref('');
const remain_time = ref('');

let timeId = null;

watch(
  () => props.visible,
  (val) => {
    if (val) {
      id.value = props.data.id;
      price.value = props.data.price;
      remain_time.value = props.data.remain_time;
    }
  }
)

onMounted(() => {
  // 进入页面后,开始倒计时
  timeId = setInterval(() => {
    remain_time.value ? remain_time.value -= 1 : 0;
    if (remain_time.value === 0) { // 倒计时结束
      clearInterval(timeId);
      emit('close');
    }
  }, 1000);
})

onUnmounted(() => {
  timeId && clearInterval(timeId);
})

const goToPay = async () => {
  if (price.value > 0) { // 金额大于0
    // 获取支付参数
    const { code, data } = await payAPI({ order_id: id.value });
    if (code) {
      let pay = data;
      // 触发微信支付操作
      wx.requestPayment({
        timeStamp: pay.timeStamp,
        nonceStr: pay.nonceStr,
        package: pay.package,
        signType: pay.signType,
        paySign: pay.paySign,
        success: async (result) => {
          emit('close'); // 关闭支付弹框
          Taro.showToast({
            title: '支付成功',
            icon: 'success',
            duration: 1000
          });
          // 支付成功后,调用检查接口
          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/detail/index') { // 订房确认页打开
              // 跳转订单成功页
              Taro.navigateTo({
                url: '/pages/payInfo/index',
              });
            }
          }
        }
      });
    }
  }
}
</script>

<style lang="less">

</style>