【原 因】:防止 重复点击按钮 【过 程】:给支付按钮加一个标记 点击之后改变按钮样式 并且标记点击过 点击过 则不继续执行pay 函数 【影 响】: # 类型 包含: # feat:新功能(feature) # fix:修补bug # docs:文档(documentation) # style: 格式(不影响代码运行的变动) # refactor:重构(即不是新增功能,也不是修改bug的代码变动) # test:增加测试 # chore:构建过程或辅助工具的变动
204 lines
5.3 KiB
Vue
204 lines
5.3 KiB
Vue
<template>
|
|
<view>
|
|
<!-- topbar -->
|
|
<u-navbar title="收银台" bgColor="#d43030" :titleStyle="{ color: '#FFF'}" :autoBack="true" placeholder>
|
|
<view class="u-nav-slot" slot="left">
|
|
<u-icon name="arrow-left" color="#fff" size="19"></u-icon>
|
|
</view>
|
|
</u-navbar>
|
|
<!-- body -->
|
|
<view class="flex column msb bodyBox">
|
|
<view>
|
|
<view class="priceBox fb flex mc">¥{{fullPrice | formatPrice}}</view>
|
|
<view class="fcb fz24 flex mc" v-if="countdown !== ''">
|
|
<span class="m-r-24">支付剩余时间</span>
|
|
<span>{{ countdown }}</span>
|
|
</view>
|
|
<view class="fcb fz24 flex mc" v-else>
|
|
<span>订单加载中···</span>
|
|
</view>
|
|
<view class="flex msb mac rad8 bg-w m-l-24 m-r-24 m-t-24 p-24">
|
|
<view class="flex mac">
|
|
<u--image src="/static/icons/wxPayLogo.svg" width="75rpx" height="60rpx" />
|
|
<view class="fz36 m-l-24">微信支付</view>
|
|
</view>
|
|
<view class="flex border rad-c border-m bg-m checkBox">
|
|
<u-icon name="checkbox-mark" size="40rpx" color="#fff"></u-icon>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view @click="pay" class="butBox fci bg-m rad8 fb fz36 flex mc p-24 m-l-24 m-r-24" :class="isPressed?'bg-g':'bg-m'">确认支付</view>
|
|
</view>
|
|
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import {
|
|
formatPrice,
|
|
formatSeconds
|
|
} from '@/utils/index.js'
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
order_sn: '', //订单号
|
|
fullPrice: 0, //总价格 包括附加费用
|
|
order_time: -1, //订单创建时间
|
|
countdown: '', // 用于显示倒计时
|
|
timer: null, // 存储计时器
|
|
isPressed: false, //支付按钮是否锁定
|
|
}
|
|
},
|
|
onLoad(options) {
|
|
this.$store.dispatch('fetchOrderList')
|
|
this.order_sn = options.order_sn // 从提交订单页面传递过来的订单号
|
|
this.fullPrice = Number(options.fullPrice) // 从提交订单页面传递过来的订单号
|
|
if (this.orderShow) {
|
|
this.order_time = Number(this.orderShow.order_time)
|
|
}
|
|
},
|
|
computed: {
|
|
// 订单详情
|
|
orderShow() {
|
|
if (this.$store.state.orderList && this.$store.state.orderList.length > 0) {
|
|
// 使用 find 查找匹配的订单
|
|
return this.$store.state.orderList.find(item => item.order_sn === this.order_sn) || null
|
|
}
|
|
return null // 如果 orderList 为空或未定义,返回 null
|
|
}
|
|
},
|
|
filters: {
|
|
formatPrice, //格式化价格
|
|
},
|
|
watch: {
|
|
orderShow: {
|
|
handler(val) {
|
|
// 先判断数据有效性
|
|
if (val && val.order_time) {
|
|
this.order_time = Number(val.order_time)
|
|
} else {
|
|
this.order_time = -1 // 重置为无效值
|
|
}
|
|
},
|
|
deep: true,
|
|
immediate: true,
|
|
},
|
|
order_time: {
|
|
handler(val) {
|
|
if (this.timer) {
|
|
clearInterval(this.timer) // 清除已有定时器
|
|
}
|
|
// 如果 order_time 无效,则不启动倒计时
|
|
if (!val || val < 0) return
|
|
this.timer = setInterval(() => {
|
|
const tempTime = this.order_time + 900 - Math.floor(Date.now() / 1000)
|
|
if (tempTime <= 0) {
|
|
this.countdown = '00:00'
|
|
clearInterval(this.timer) // 清除定时器
|
|
// 倒计时结束后跳转到首页
|
|
uni.navigateTo({
|
|
url: '/pages/index/index', // 非 Tab 页的路径
|
|
})
|
|
} else {
|
|
this.countdown = this.formatSeconds(tempTime)
|
|
}
|
|
}, 1000)
|
|
},
|
|
immediate: true, // 确保初次赋值时立即触发
|
|
}
|
|
},
|
|
methods: {
|
|
//秒格式化成 00:00格式
|
|
formatSeconds,
|
|
// 支付方法
|
|
pay() {
|
|
if (this.isPressed) { //防止支付按钮重复点击
|
|
return
|
|
}
|
|
this.isPressed = true
|
|
uni.$u.http.post('/Api/Pay/pay', {
|
|
order_sn: this.order_sn
|
|
}, {
|
|
header: {
|
|
'Token': this.$store.state.userInfo.token,
|
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
}
|
|
}).then((res) => {
|
|
if (res.data.status === 1) {
|
|
// 调用微信支付接口
|
|
this.requestPayment(res.data.payMsg)
|
|
} else {
|
|
uni.showToast({
|
|
title: '支付失败',
|
|
icon: 'error'
|
|
})
|
|
// 延迟跳转到首页
|
|
setTimeout(() => {
|
|
uni.reLaunch({
|
|
url: '/pages/main/order',
|
|
})
|
|
}, 1500) // 1.5秒后跳转
|
|
console.error(res.data.msg)
|
|
}
|
|
})
|
|
},
|
|
// 调用微信支付接口
|
|
requestPayment(payMsg) {
|
|
uni.requestPayment({
|
|
timeStamp: payMsg.timeStamp,
|
|
nonceStr: payMsg.nonceStr,
|
|
package: payMsg.package,
|
|
signType: payMsg.signType,
|
|
paySign: payMsg.paySign,
|
|
success: (res) => {
|
|
uni.showToast({
|
|
title: '支付成功',
|
|
icon: 'success'
|
|
})
|
|
|
|
// 延迟跳转到首页
|
|
setTimeout(() => {
|
|
uni.reLaunch({
|
|
url: '/pages/main/order',
|
|
})
|
|
}, 1500) // 1.5秒后跳转
|
|
},
|
|
fail: (err) => {
|
|
console.error('支付失败:', err)
|
|
uni.showToast({
|
|
title: '支付失败',
|
|
icon: 'error'
|
|
})
|
|
// 延迟跳转到首页
|
|
setTimeout(() => {
|
|
uni.reLaunch({
|
|
url: '/pages/main/order',
|
|
})
|
|
}, 1500) // 1.5秒后跳转
|
|
}
|
|
})
|
|
}
|
|
|
|
},
|
|
destroyed() {
|
|
// 在组件销毁前清除定时器
|
|
clearInterval(this.timer) // 倒计时结束后清除定时器
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.priceBox {
|
|
font-size: 72rpx;
|
|
margin-top: 140rpx;
|
|
}
|
|
|
|
.butBox {
|
|
margin-bottom: 72rpx;
|
|
}
|
|
|
|
.bodyBox {
|
|
height: calc(100vh - 176rpx);
|
|
}
|
|
</style> |