632 lines
15 KiB
Vue
632 lines
15 KiB
Vue
<template>
|
||
<view class="pay-page">
|
||
<!-- 自定义导航栏 -->
|
||
<custom-navbar title="支付订单" :showBack="true" backgroundColor="#FFFFFF"></custom-navbar>
|
||
|
||
<!-- 支付金额 -->
|
||
<view class="amount-section">
|
||
<image src="/static/images/shop/pay_icon.png" mode="aspectFit" class="pay_icon"></image>
|
||
<view class="amount">
|
||
<text class="symbol">¥</text>
|
||
<text class="value">{{ orderInfo.pay_money }}</text>
|
||
</view>
|
||
<view class="countdown" v-if="countdown">支付剩余时间:
|
||
<uv-count-down :time="countdown * 1000" format="mm:ss" @finish="finish"></uv-count-down>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 支付方式 -->
|
||
<view class="method-section">
|
||
<view class="section-title">选择支付方式</view>
|
||
<view class="method-list">
|
||
<view class="method-item" v-for="(item, index) in methodList" :key="index" @click="selectMethod(item)">
|
||
<view class="method-info">
|
||
<image :src="item.icon" mode="aspectFit" class="method-icon"></image>
|
||
<text class="method-name">{{ item.name }}</text>
|
||
</view>
|
||
<agree-radio :isAgree="item.selected" :yesImg="`/static/images/icons/yes_icon.png`" :radioSize="`40rpx`" :noImg="`/static/images/icons/no_icon.png`"></agree-radio>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 底部支付按钮 -->
|
||
<view class="footer">
|
||
<!-- <view class="total-amount">
|
||
<view class="amount-money">
|
||
<text class="symbol">¥</text>
|
||
<text class="amount">{{ orderInfo.pay_money }}</text>
|
||
</view>
|
||
<text class="amount-lable">应付金额</text>
|
||
</view> -->
|
||
<view class="pay-btn" @click="confirmPay">立即支付</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import customNavbar from '@/components/custom-navbar/custom-navbar.vue'
|
||
import {
|
||
debounce
|
||
} from '../../utils/debounce';
|
||
import request from '@/utils/request'
|
||
|
||
export default {
|
||
components: {
|
||
customNavbar
|
||
},
|
||
data() {
|
||
return {
|
||
table_source:"order",//订单类型order:普通,order_self自营
|
||
orderInfo: {
|
||
id: '',
|
||
pay_money: '',
|
||
number: ''
|
||
},
|
||
urls: {
|
||
order: {
|
||
cancelorder: "/user/cancelorder",
|
||
deleteorder: "/user/deleteorder"
|
||
},
|
||
order_self: {
|
||
cancelorder: "/user/orderSelf/cancel",
|
||
deleteorder: "/user/orderSelf/del"
|
||
}
|
||
},
|
||
serverTitle: '',
|
||
countdown: 0,
|
||
selectedPayment: 'wechat',
|
||
balance: '98489.98',
|
||
timer: null,
|
||
isPay: false,
|
||
methodList: [{
|
||
id: 1,
|
||
name: '微信',
|
||
payment: 'wechat',
|
||
icon: '/static/images/wechat.png',
|
||
selected: true
|
||
},
|
||
{
|
||
id: 2,
|
||
name: '支付宝',
|
||
payment: 'alipay',
|
||
icon: '/static/images/alipay.png',
|
||
selected: false
|
||
},
|
||
// {
|
||
// id: 3,
|
||
// name: '账户余额',
|
||
// payment: 'balance',
|
||
// icon: '/static/images/bankcard.png',
|
||
// selected: false
|
||
// }
|
||
]
|
||
}
|
||
},
|
||
onLoad(options) {
|
||
// this.getUserInfo();
|
||
console.log(options)
|
||
if(options.table_source){
|
||
this.table_source = options.table_source
|
||
}
|
||
if (options.id) {
|
||
this.orderInfo.id = options.id;
|
||
this.orderInfo.number = options.number;
|
||
this.orderInfo.pay_money = options.money;
|
||
this.serverTitle = options.title;
|
||
console.log(this.orderInfo)
|
||
// this.getOrderInfo()
|
||
}
|
||
if (options.number) {
|
||
this.getOderPayCountdown(options.number)
|
||
// this.startCountdown()
|
||
}
|
||
},
|
||
onUnload() {
|
||
if (this.timer) {
|
||
clearInterval(this.timer)
|
||
this.timer = null
|
||
}
|
||
},
|
||
methods: {
|
||
async getOderPayCountdown(number) {
|
||
await request.post('/user/getOderPayCountdown', {
|
||
number: number
|
||
}).then(result => {
|
||
if (result.code == 200) {
|
||
console.log(result[0].countdown)
|
||
|
||
this.countdown = result[0].countdown
|
||
if(!result[0].countdown){
|
||
this.cancelService()
|
||
}
|
||
}
|
||
})
|
||
},
|
||
getUserInfo() {
|
||
request.post('/user/getuser', {
|
||
type: 1
|
||
}).then(result => {
|
||
this.address.name = result.data.username;
|
||
this.address.phone = result.data.account;
|
||
})
|
||
},
|
||
// 取消订单
|
||
async cancelService() {
|
||
let id = '';
|
||
await request.post('/user/getuser', {
|
||
type: 1
|
||
}).then(res => {
|
||
console.log(res)
|
||
id = res.data.id
|
||
})
|
||
let data = {
|
||
orderNo: this.orderInfo.number,
|
||
amount: "0.00",
|
||
cancel_state: 1,
|
||
cancel_id: id
|
||
}
|
||
request.post(this.urls[this.table_source].cancelorder, data).then(res => {
|
||
|
||
console.log(22222, res,data)
|
||
|
||
}).catch(err => {
|
||
console.log(err)
|
||
}).finally(() => {
|
||
setTimeout(() => {
|
||
uni.switchTab({
|
||
url: '/pages/order/userorder-list'
|
||
});
|
||
}, 2000)
|
||
})
|
||
},
|
||
// 获取订单信息
|
||
async getOrderInfo() {
|
||
try {
|
||
const res = await request.post('/order/detail', {
|
||
id: this.orderInfo.id
|
||
})
|
||
if (res.code === 0) {
|
||
this.orderInfo = res.data
|
||
}
|
||
} catch (error) {
|
||
console.error('获取订单信息失败:', error)
|
||
}
|
||
},
|
||
// 选择支付方式
|
||
selectMethod(item) {
|
||
this.selectedPayment = item.payment;
|
||
this.methodList.forEach(method => {
|
||
method.selected = method.id === item.id
|
||
})
|
||
},
|
||
finish() {
|
||
uni.showToast({
|
||
title: '支付超时,请重新下单',
|
||
icon: 'none'
|
||
})
|
||
setTimeout(() => {
|
||
// uni.navigateBack()
|
||
this.cancelService()
|
||
}, 1500)
|
||
},
|
||
// 开始倒计时
|
||
startCountdown() {
|
||
let time = 30 * 60 // 30分钟
|
||
this.timer = setInterval(() => {
|
||
time--
|
||
if (time <= 0) {
|
||
clearInterval(this.timer)
|
||
this.timer = null
|
||
uni.showToast({
|
||
title: '支付超时,请重新下单',
|
||
icon: 'none'
|
||
})
|
||
setTimeout(() => {
|
||
uni.navigateBack()
|
||
}, 1500)
|
||
return
|
||
}
|
||
const minutes = Math.floor(time / 60)
|
||
const seconds = time % 60
|
||
this.countdown = `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
|
||
}, 1000)
|
||
},
|
||
// 确认支付 debounce
|
||
async confirmPay() {
|
||
let that = this;
|
||
if (that.isPay) return;
|
||
try {
|
||
uni.showLoading({
|
||
title: '支付中...'
|
||
})
|
||
console.log(that.selectedPayment)
|
||
switch (that.selectedPayment) {
|
||
case 'wechat':
|
||
// 调用微信支付
|
||
let wechatpayfor = await request.post('/user/wechatpayfor', that.orderInfo);
|
||
console.log('wechatpayfor', wechatpayfor)
|
||
if (wechatpayfor.code == 452) {
|
||
uni.showToast({
|
||
title: wechatpayfor.msg || '支付失败,请重试',
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
this.cancelService()
|
||
return
|
||
}
|
||
const systemInfo = uni.getSystemInfoSync()
|
||
if (systemInfo.platform === 'ios') {
|
||
let appId = wechatpayfor.data.appid;
|
||
delete wechatpayfor.data.appid;
|
||
wechatpayfor.data['appId'] = appId;
|
||
console.log('wechatpayfor2', wechatpayfor)
|
||
}
|
||
console.log('================================')
|
||
uni.hideLoading()
|
||
uni.requestPayment({
|
||
provider: 'wxpay',
|
||
orderInfo: wechatpayfor.data, //微信、支付宝订单数据 【注意微信的订单信息,键值应该全部是小写,不能采用驼峰命名】
|
||
success: function(res) {
|
||
console.log('success:', res);
|
||
console.log(that.orderInfo.id, that.orderInfo.number)
|
||
// let rawdata = JSON.parse(res.rawdata);
|
||
request.post('/user/wechatsearchorder', {
|
||
id: that.orderInfo.id,
|
||
number: that.orderInfo.number
|
||
}).then(orderRes => {
|
||
// if(orderRes.trade_state == 'SUCCESS') {
|
||
that.paySuccess();
|
||
// }else if(orderRes.trade_state == 'NOTPAY') {
|
||
// uni.showModal({
|
||
// title: '提示',
|
||
// content: '该订单未成功支付',
|
||
// success: function (res) {
|
||
// if (res.confirm) {
|
||
// console.log('用户点击确定');
|
||
// } else if (res.cancel) {
|
||
// console.log('用户点击取消');
|
||
// }
|
||
// }
|
||
// });
|
||
// }
|
||
}).catch(err => {
|
||
console.log('查询状态', err)
|
||
})
|
||
},
|
||
fail: function(err) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '该订单未成功支付',
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
console.log('用户点击确定');
|
||
} else if (res.cancel) {
|
||
console.log('用户点击取消');
|
||
}
|
||
}
|
||
});
|
||
console.log('fail:', JSON.stringify(err));
|
||
}
|
||
});
|
||
break
|
||
case 'alipay':
|
||
// 调用支付宝支付
|
||
let orderInfo = {
|
||
...that.orderInfo
|
||
};
|
||
orderInfo.title = that.serverTitle;
|
||
let alipayfor = await request.post('/user/alipayfor', orderInfo);
|
||
if (alipayfor.code == 452) {
|
||
uni.showToast({
|
||
title: alipayfor.msg || '支付失败,请重试',
|
||
icon: 'none',
|
||
duration: 2000
|
||
})
|
||
this.cancelService()
|
||
return
|
||
}
|
||
console.log('alipayfor', alipayfor)
|
||
uni.hideLoading()
|
||
uni.requestPayment({
|
||
provider: 'alipay',
|
||
orderInfo: alipayfor.data, //微信、支付宝订单数据 【注意微信的订单信息,键值应该全部是小写,不能采用驼峰命名】
|
||
success: function(res) {
|
||
console.log('success:', res);
|
||
console.log('id: ', that.orderInfo.id, 'number: ', that.orderInfo
|
||
.number)
|
||
console.log('ali支付成功了====================')
|
||
request.post('/user/alisearchorder', {
|
||
id: that.orderInfo.id,
|
||
number: that.orderInfo.number
|
||
}).then(orderRes => {
|
||
console.log('orderRes', orderRes, orderRes.trade_status)
|
||
|
||
console.log('ali报错了】】】】】】】】】】】】】】')
|
||
// if(orderRes.trade_status == 'TRADE_SUCCESS') {
|
||
that.paySuccess();
|
||
// }else {
|
||
// uni.showModal({
|
||
// title: '提示',
|
||
// content: '该订单未成功支付',
|
||
// success: function (res) {
|
||
// if (res.confirm) {
|
||
// console.log('用户点击确定');
|
||
// } else if (res.cancel) {
|
||
// console.log('用户点击取消');
|
||
// }
|
||
// }
|
||
// });
|
||
// }
|
||
}).catch(err => {
|
||
console.log('ali报错了】】】】】】】】】】】】】】', err)
|
||
console.log('查询状态', err)
|
||
})
|
||
},
|
||
fail: function(err) {
|
||
uni.showModal({
|
||
title: '提示',
|
||
content: '该订单未成功支付',
|
||
success: function(res) {
|
||
if (res.confirm) {
|
||
console.log('用户点击确定');
|
||
} else if (res.cancel) {
|
||
console.log('用户点击取消');
|
||
}
|
||
}
|
||
});
|
||
console.log('fail:', JSON.stringify(err));
|
||
}
|
||
});
|
||
break
|
||
case 'balance':
|
||
// 余额支付直接成功
|
||
const res = await request.post('/user/balancepayfor', that.orderInfo)
|
||
console.log('余额支付结果', res)
|
||
uni.hideLoading()
|
||
if (res.state == 1) {
|
||
that.paySuccess();
|
||
} else if (res.state == 2) {
|
||
uni.showToast({
|
||
title: res.msg
|
||
})
|
||
}
|
||
break
|
||
}
|
||
} catch (error) {
|
||
uni.hideLoading()
|
||
console.error('支付失败', error)
|
||
uni.showToast({
|
||
title: '支付失败,请重试',
|
||
icon: 'none'
|
||
})
|
||
this.isPay = false;
|
||
}
|
||
},
|
||
|
||
// 支付成功
|
||
paySuccess() {
|
||
uni.showToast({
|
||
title: '支付成功',
|
||
icon: 'success'
|
||
})
|
||
if(this.table_source == "order_self"){
|
||
setTimeout(() => {
|
||
uni.redirectTo({
|
||
url:`/pages/order/pay-success?orderId=${this.orderInfo.id}&order_type=6`
|
||
})
|
||
}, 50)
|
||
}else{
|
||
setTimeout(() => {
|
||
uni.redirectTo({
|
||
url: '/pages/order/pay-success?orderId=' + this.orderInfo.id
|
||
})
|
||
}, 50)
|
||
}
|
||
|
||
this.isPay = true;
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="less">
|
||
.pay-page {
|
||
padding-bottom: env(safe-area-inset-bottom);
|
||
}
|
||
|
||
/* 金额展示 */
|
||
.amount-section {
|
||
background-color: transparent;
|
||
padding: 51rpx 32rpx 129rpx 32rpx;
|
||
text-align: center;
|
||
|
||
.pay_icon {
|
||
width: 199rpx;
|
||
height: 178rpx;
|
||
margin-bottom: 34rpx;
|
||
}
|
||
|
||
.amount {
|
||
margin-bottom: 8rpx;
|
||
|
||
.symbol {
|
||
font-family: DINPro, DINPro;
|
||
font-weight: bold;
|
||
font-size: 54rpx;
|
||
color: #333333;
|
||
line-height: 70rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
|
||
.value {
|
||
font-family: DINPro, DINPro;
|
||
font-weight: bold;
|
||
font-size: 88rpx;
|
||
color: #333333;
|
||
line-height: 114rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
|
||
.value2 {
|
||
font-family: DINPro, DINPro;
|
||
font-weight: bold;
|
||
font-size: 56rpx;
|
||
color: #333333;
|
||
line-height: 72rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
|
||
}
|
||
|
||
.countdown {
|
||
font-weight: 400;
|
||
font-size: 26rpx;
|
||
color: #333333;
|
||
line-height: 37rpx;
|
||
text-align: center;
|
||
font-style: normal;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
::v-deep .uv-count-down__text {
|
||
font-weight: 400;
|
||
font-size: 26rpx;
|
||
color: #E8101E;;
|
||
line-height: 37rpx;
|
||
text-align: center;
|
||
font-style: normal;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/* 支付方式 */
|
||
.method-section {
|
||
background-image: url("/static/images/shop/payBj.png");
|
||
background-position: top;
|
||
background-repeat: no-repeat;
|
||
background-size: contain;
|
||
background-color: #fff;
|
||
margin: 0 20rpx;
|
||
padding: 22rpx 26rpx 62rpx 26rpx;
|
||
border-radius: 20rpx;
|
||
}
|
||
|
||
.section-title {
|
||
font-weight: 400;
|
||
font-size: 28rpx;
|
||
color: #333333;
|
||
line-height: 40rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
margin-bottom: 23rpx;
|
||
}
|
||
|
||
.balance-amount {
|
||
font-size: 28rpx;
|
||
color: #999999;
|
||
margin-left: 16rpx;
|
||
}
|
||
|
||
/* 底部按钮 */
|
||
.footer {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
height: 150rpx;
|
||
background-color: #ffffff;
|
||
display: flex;
|
||
flex-flow: row nowrap;
|
||
justify-content: center;
|
||
align-items: center;
|
||
padding: 0 24rpx;
|
||
padding-bottom: env(safe-area-inset-bottom);
|
||
}
|
||
|
||
.total-amount {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-flow: column nowrap;
|
||
justify-content: flex-start;
|
||
align-items: flex-start;
|
||
}
|
||
|
||
.total-amount .symbol {
|
||
font-size: 24rpx;
|
||
font-weight: 500;
|
||
color: #E8101E;
|
||
}
|
||
|
||
.total-amount .amount {
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
color: #E8101E;
|
||
}
|
||
|
||
.amount-lable {
|
||
font-size: 24rpx;
|
||
color: #999999;
|
||
}
|
||
|
||
.pay-btn {
|
||
width: 680rpx;
|
||
height: 88rpx;
|
||
background: linear-gradient( 180deg, #F52540 0%, #E8101E 100%);
|
||
border-radius: 43rpx;
|
||
font-weight: 500;
|
||
font-size: 30rpx;
|
||
color: #FFFFFF;
|
||
line-height: 42rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.method-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 40rpx 0;
|
||
border-bottom: 1rpx solid rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.method-item:last-child {
|
||
border-bottom: none;
|
||
padding-bottom: 0;
|
||
}
|
||
|
||
.method-info {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.method-icon {
|
||
width: 38rpx;
|
||
height: 38rpx;
|
||
margin-right: 20rpx;
|
||
}
|
||
|
||
.method-name {
|
||
font-weight: 500;
|
||
font-size: 30rpx;
|
||
color: #5B5B5B;
|
||
line-height: 42rpx;
|
||
text-align: left;
|
||
font-style: normal;
|
||
}
|
||
|
||
/* 多端适配 */
|
||
/* #ifdef H5 */
|
||
.footer {
|
||
padding-bottom: 0;
|
||
}
|
||
|
||
/* #endif */
|
||
</style> |