This commit is contained in:
我是个攻城狮
2026-05-27 16:01:15 +08:00
parent dc43370953
commit c3f5f13bb3
953 changed files with 107635 additions and 11 deletions
+335
View File
@@ -0,0 +1,335 @@
<template>
<view class="pay-container">
<view class="pay_title">请扫码付款</view>
<!-- 支付方式切换 -->
<view class="tab-wrap">
<view
:class="['tab-item', payType === 'alipay' ? 'active' : '']"
@tap="handlePayTypeChange('alipay')"
>
<image src="../../static/img/member/zfbx.png" class="pay-icon" v-if="payType==='alipay'"/>
<image src="../../static/img/member/zfb.png" class="pay-icon" v-else/>
<text>支付宝</text>
</view>
<view
:class="['tab-item', payType === 'wechat' ? 'active' : '']"
@tap="handlePayTypeChange('wechat')"
>
<image src="../../static/img/member/wxx.png" class="pay-icon" v-if="payType==='wechat'" />
<image src="../../static/img/member/wx.png" class="pay-icon" v-else/>
<text>微信</text>
</view>
</view>
<!-- 二维码区 -->
<view class="qr-section">
<image
:src="alipayQrcode"
class="qr-img"
mode="aspectFit"
alt="扫码二维码"
/>
<view class="tip">
<span v-if="leftSeconds > 0">
剩余支付时间
<span class="countdown">
{{ Math.floor(leftSeconds / 60) }}:{{ (leftSeconds % 60).toString().padStart(2, '0') }}
</span>
</span>
<span v-else>
二维码已过期请刷新页面获取新的二维码
</span>
<br/>
</view>
</view>
<!-- 售后说明区 -->
<view class="after-sale">
<view class="as-title">售后说明</view>
<view class="as-item">付款后1个工作日内出具评估报告报告可下载</view>
<view class="as-item">可申请退款售后每笔订单只可申请一次退款</view>
<view class="as-item">我们将跟踪贷款业务结果贷款未成功将自动退款</view>
<view class="as-item">客服电话400-xxxx-xxxx</view>
</view>
</view>
</template>
<script>
export default {
props: {
orderId: {
type: [String, Number],
required: true
}
},
data() {
return {
payType: 'alipay', // 当前选择的支付方式
alipayQrcode: require('../../static/img/member/code.png'),
qrcodeLoaded: false,
endtime: 0, // 服务器返回的结束时刻(时间戳,秒)
leftSeconds: 0,
order_no: '',
payTimer: null, // 定时查询支付状态的timer
countdownTimer: null // 倒计时timer
};
},
watch: {
orderId: {
immediate: true,
handler(newVal) {
// 当 orderId 变化时重新拉取二维码
if (newVal) {
this.resetTimers();
this.qrcodeLoaded = false;
this.alipayQrcode = require('../../static/img/member/code.png');
this.leftSeconds = 0;
this.endtime = 0;
}
}
}
},
created() {
// 组件加载时自动拉取 orderId 的二维码
if (this.orderId) {
this.getQrcode('alipay');
}
},
beforeDestroy() {
// 组件销毁时,清理所有定时器
this.resetTimers();
},
methods: {
resetTimers() {
if (this.payTimer) {
clearInterval(this.payTimer);
this.payTimer = null;
}
if (this.countdownTimer) {
clearInterval(this.countdownTimer);
this.countdownTimer = null;
}
},
async handlePayTypeChange(type) {
if (this.payType === type) return; // 避免重复拉取
this.payType = type;
this.resetTimers();
this.leftSeconds = 0;
this.endtime = 0;
this.alipayQrcode = require('../../static/img/member/code.png');
this.getQrcode(type);
},
// 切换支付方式时,调用后端接口获取二维码
async getQrcode(type) {
if (!this.orderId) return;
this.resetTimers(); // 切换支付方式/刷新二维码前先清理所有定时器
this._post(
'/asset.Asset/pay',
{
pay_type: type === 'alipay' ? 30 : 20,
id: this.orderId
},
res => {
// 正常会有服务端传回支付二维码、截止时间、订单号
this.alipayQrcode = res.data.qr_code_url;
this.order_no = res.data.order_no;
// 假设服务端返回剩余秒数,推荐直接返回leftSeconds,否则自己算
// 兼容两种情况:res.data.leftSeconds 或 res.data.pay_end_time
if (typeof res.data.leftSeconds !== 'undefined') {
this.leftSeconds = res.data.leftSeconds;
this.endtime = Math.floor(Date.now() / 1000) + this.leftSeconds;
} else if (typeof res.data.pay_end_time !== 'undefined') {
this.endtime = res.data.pay_end_time;
this.leftSeconds = this.endtime - Math.floor(Date.now() / 1000);
} else {
// fallback3分钟过期
this.leftSeconds = 180;
this.endtime = Math.floor(Date.now() / 1000) + 180;
}
this.startCountdownAndPayCheck();
},
err => {
this.resetTimers();
// 生成失败时隐藏支付弹窗并提示
this.$emit('close'); // 通知父组件关闭弹窗
const msg = (err && err.data && err.data.msg) ? err.data.msg : '获取二维码失败';
this.$message.error(msg);
}
);
},
startCountdownAndPayCheck() {
// 安全起见再次清理
this.resetTimers();
// 设置倒计时定时器,精确倒计时
this.countdownTimer = setInterval(() => {
if (this.leftSeconds > 0) {
this.leftSeconds -= 1;
}
if (this.leftSeconds <= 0) {
this.leftSeconds = 0;
this.resetTimers();
// 自动关闭弹窗
this.$emit('close');
this.$message.error('二维码已过期,请刷新页面获取新的二维码。');
}
}, 1000);
// 设置支付状态查询定时器
this.payTimer = setInterval(() => {
if (this.order_no && this.leftSeconds > 0) {
this._post(
'/asset.Asset/payStatus',
{
order_no: this.order_no
},
res => {
// 如果支付成功,根据业务逻辑刷新页面/跳转/弹窗...
if (res.data && res.data.pay_status === 20) {
this.resetTimers();
this.$emit('pay-success', this.order_no);
this.$message.success('支付成功');
//支付成功后关闭弹窗,强制刷新页面
this.$emit('close');
this.$nextTick(() => {
window.location.reload();
});
}
// 若未支付则轮询,不需要额外处理
},
err => {
// 支付状态查询失败,也需要轮询,不紧急关闭
// 但你可以根据实际业务在失败次数过多时终止(此处只做错误提示)
// this.$message.error('支付状态查询失败');
}
);
}
}, 3000);
}
}
};
</script>
<style lang="scss">
.pay-container {
width: 65vh;
margin: 0 auto;
display: flex;
flex-direction: column;
align-items: center;
margin-top: -30px;
}
.pay_title{
font-family: Source Han Sans, Source Han Sans;
font-weight: 700;
font-size: 18px;
color: #3D3D3D;
line-height: 22px;
text-align: center;
font-style: normal;
text-transform: none;
margin-bottom: 24px;
}
.tab-wrap {
width: 100%;
display: flex;
justify-content: center;
margin-bottom: 28px;
.tab-item {
width: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 19px;
font-family: Source Han Sans, Source Han Sans;
font-weight: 400;
font-size: 16px;
color: #767676;
border-radius: 6px 6px 0 0;
padding: 12px 38px;
cursor: pointer;
border-bottom: 2px solid #e4e4e4;
.pay-icon {
width: 18px;
height: 18px;
margin-right: 8px;
}
}
.tab-item:last-child {
margin-right: 0;
}
.tab-item.active {
border-bottom: 2px solid #f48612;
box-shadow: 0 6px 18px 0 rgba(244, 134, 18, 0.04);
font-family: Source Han Sans, Source Han Sans;
font-weight: 500;
font-size: 16px;
color: #F78A30;
line-height: 22px;
}
}
.qr-section {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 24px;
.qr-img {
width: 160px;
height: 160px;
border: 1px solid #f2f2f2;
border-radius: 8px;
background: #fcfcfc;
margin-bottom: 14px;
}
.remark {
display: flex;
align-items: center;
font-size: 16px;
color: #666;
margin-bottom: 15px;
.remark-icon {
width: 18px;
height: 18px;
margin-right: 7px;
}
text {
font-size: 16px;
}
}
.tip {
width: 100%;
text-align: center;
font-family: Source Han Sans, Source Han Sans;
font-weight: 400;
font-size: 12px;
color: #767676;
line-height: 22px;
margin-top: 2px;
}
}
.after-sale {
width: 100%;
padding: 20px 0 0 0;
.as-title {
margin-bottom: 7px;
font-family: Source Han Sans, Source Han Sans;
font-weight: 500;
font-size: 14px;
color: #3D3D3D;
}
.as-item {
margin-bottom: 4px;
font-family: Source Han Sans, Source Han Sans;
font-weight: 400;
font-size: 12px;
color: #767676;
line-height: 22px;
text-align: left;
}
}
/* 可以根据实际图片和页面风格微调样式 */
</style>