2025-07-21 17:56:49 +08:00

264 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="payment-page">
<!-- 倒计时区域 -->
<view class="countdown-section">
<view class="countdown-icon">
<u-icon name="clock" size="22" color="#fff"></u-icon>
</view>
<view class="countdown-text">待支付</view>
<view class="countdown-timer">
<text>剩余</text>
<text class="time-value">{{ countdownTime }}</text>
</view>
</view>
<view class="scrollable-content">
<!-- 学生信息卡片 -->
<XkPayXs />
<!-- 课程信息卡片 -->
<XkPayXkqd />
</view>
<!-- 底部支付区域 -->
<view class="payment-footer">
<view class="total-amount">
<text>总金额</text>
<text class="amount-value">¥{{ totalJe }}</text>
</view>
<view class="action-buttons">
<view class="cancel-btn" @click="cancelRegistration">取消报名</view>
<view class="pay-btn" @click="payNow">立即支付</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import XkPayXs from "@/pages/base/components/XkPayXs/index.vue"
import XkPayXkqd from "@/pages/base/components/XkPayXkqd/index.vue"
import { jzGetQkExpiredTime, jzXkCancelApi, jzXkFqJfjApi } from "@/api/base/server";
import { useUserStore } from "@/store/modules/user";
import { useDataStore } from "@/store/modules/data";
const { getCurXs, getUser } = useUserStore();
const { getData, setData } = useDataStore();
// 学生信息
const curXs = computed(() => getCurXs);
// 课程信息
const xkqdList = computed(() => getData.xkqdList);
// 总金额
const totalJe = computed(() => {
// 循环xkqdList.value 求和
if (!xkqdList.value || !xkqdList.value.length) {
return 0;
}
let total = 0;
for (let i = 0; i < xkqdList.value.length; i++) {
total += xkqdList.value[i].jfje;
}
return total;
});
// 倒计时
const countdownTime = ref("1分20秒");
let timer: any = null;
let seconds = 1 * 60 + 20; // 1分20秒
// 开始倒计时
const startCountdown = () => {
timer = setInterval(() => {
seconds--;
if (seconds <= 0) {
clearInterval(timer);
uni.showModal({
title: "支付超时",
content: "支付已超时,请重新选课",
showCancel: false,
success: () => {
cancelRegistration();
},
});
return;
}
const minutes = Math.floor(seconds / 60);
const remainSeconds = seconds % 60;
countdownTime.value = `${minutes}${remainSeconds}`;
}, 1000);
};
// 返回上一页
const goBack = () => {
uni.reLaunch({
url: getData.backUrl
});
};
// 取消报名
const cancelRegistration = () => {
uni.showModal({
title: "取消报名",
content: "确定要取消报名吗?",
success: async (res) => {
if (res.confirm) {
await jzXkCancelApi({
xsId: getData.xsId,
xkId: getData.xkId
});
uni.showToast({
title: "已取消报名",
icon: "success",
});
goBack();
}
},
});
};
// 立即支付
const payNow = async () => {
try {
const res = await jzXkFqJfjApi({
xsId: getData.xsId,
xkId: getData.xkId,
jffs: "四川农信", // TODO: 目前只支持四川农信
jzId: getUser.jzId,
userId: getUser.userId,
openId: getUser.openId,
});
if (res.resultCode === 1 && res.result) {
setData({
...getData,
...res.result
});
uni.redirectTo({
url: `/pages/base/course-selection/pay-wait?payUrl=${encodeURIComponent(res.result.cashierPayHtml)}`
});
}
} catch (error) {
console.log(error);
uni.showToast({
title: "发起支付失败",
icon: "error",
});
// const url = "https://www.baidu.com";
// uni.redirectTo({
// url: `/pages/base/course-selection/pay-wait?payUrl=${encodeURIComponent(url)}`
// });
}
};
onMounted(async() => {
const res = await jzGetQkExpiredTime({ xsId: getCurXs.id} );
console.log('获取倒计时', res);
seconds = res.result;
startCountdown();
});
onUnmounted(() => {
if (timer) {
clearInterval(timer);
}
});
</script>
<style lang="scss" scoped>
.payment-page {
min-height: 100%;
background-color: #f5f7fa;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
// 可滚动内容区域样式
.scrollable-content {
flex: 1;
overflow-y: auto;
-webkit-overflow-scrolling: touch; // 增强iOS滚动体验
}
.countdown-section {
display: flex;
align-items: center;
padding: 15px;
background-color: #2879ff;
.countdown-icon {
margin-right: 10px;
}
.countdown-text {
font-size: 16px;
font-weight: 500;
color: #fff;
margin-right: auto;
}
.countdown-timer {
font-size: 15px;
color: #fff;
.time-value {
color: #ff4d4f;
font-weight: 500;
}
}
}
.payment-footer {
position: sticky;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
padding: 15px;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
.total-amount {
display: flex;
align-items: center;
margin-bottom: 15px;
font-size: 15px;
color: #333;
.amount-value {
color: #ff6b00;
font-size: 20px;
font-weight: 500;
}
}
.action-buttons {
display: flex;
justify-content: space-between;
.cancel-btn,
.pay-btn {
width: 48%;
height: 44px;
line-height: 44px;
text-align: center;
border-radius: 22px;
font-size: 16px;
}
.cancel-btn {
background-color: #fff;
color: #333;
border: 1px solid #ddd;
}
.pay-btn {
background-color: #ff8c00;
color: #fff;
}
}
}
</style>