Files
2026-04-14 16:54:04 +08:00

531 lines
16 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-pages">
<view class="payment u-skeleton">
<!-- Header -->
<view class="payment-header">
<price-format
class="u-skeleton-fillet"
:subscript-size="40"
:first-size="56"
:second-size="40"
:price="amount"
:weight="500"
/>
<template v-if="timeout > 0">
<view class="payment-count-down">
<text>支付剩余时间</text>
<u-count-down
:timestamp="timeout"
:show-days="false"
:show-hours="false"
:font-size="22"
/>
</view>
</template>
</view>
<!-- Main -->
<view class="payment-main">
<view class="payway-container u-skeleton-fillet flex">
<!-- Payway -->
<u-radio-group v-model="payway" class="flex-1">
<view class="payway">
<view
class="payway-item"
v-for="item in paywayList"
:key="item.id"
@click="changePayway(item.pay_way)"
>
<u-image
:src="item.image"
width="48"
height="48"
mode="scaleToFill"
/>
<view class="payway-item-content">
<text class="payway-item-content-name">{{ item.name }}</text>
<text class="payway-item-content-tips">{{ item.extra }}</text>
</view>
<u-radio
shape="circle"
:name="item.pay_way"
:active-color="colorConfig.primary"
/>
</view>
</view>
</u-radio-group>
<template v-if="!paywayList.length">
<view class="payway-empty">暂无支付方式</view>
</template>
</view>
</view>
<!-- Footer -->
<view class="payment-footer">
<view
:class="{ 'payment-submit--disabled': loadingPay }"
class="payment-submit"
@tap="handlePrepay"
>
<u-loading mode="circle" :show="loadingPay" />
<text v-show="!loadingPay">立即支付</text>
</view>
</view>
</view>
<u-popup
v-model="Alipayshow"
mode="bottom"
height="600rpx"
safe-area-inset-bottom
border-radius="20"
closeable
@close="handleclose"
>
<view class="Alipay">
<view class="m-t-50">
<price-format
class="u-skeleton-fillet"
:subscript-size="40"
:first-size="56"
:second-size="40"
:price="amount"
:weight="500"
/>
</view>
<view class="flex row-between m-t-50" style="width: 100%">
<text class="bold">支付方式</text>
<text class="bold">支付宝</text>
</view>
<view class="p-20 m-t-50 m-b-50" style="width: 100%; background-color: #f7f7f7"
>请复制链接,粘贴至浏览器并支付
<view style="color: red; font-size: 20rpx">
(为了账户安全请勿分享此链接)
</view>
</view>
<button class="btn" @click="oncopy">复制链接</button>
</view>
</u-popup>
<u-skeleton :loading="loadingSkeleton" :animation="true" bgColor="#FFF" />
</view>
</template>
<script>
/**
* @description 支付页面
* @query {String} from 订单来源: order-商品订单; recharge-充值订单;
* @query {Number} order_id 订单ID
*/
import { prepay, getPayway } from '@/api/app'
import { wxpay, alipay } from '@/utils/pay'
import { getPayResult } from '@/api/order'
import { getUserInfo } from '@/api/user'
import { copy } from '@/utils/tools'
export default {
name: 'Payment',
data() {
return {
from: '', // 订单来源
order_id: '', // 订单ID
amount: 0, // 支付金额
timeout: 0, // 倒计时间戳
payway: '', // 支付方式
paywayList: [], // 支付方式列表
showAgain: false,
loadingSkeleton: true, // 骨架屏Loading
loadingPay: false, // 支付处理中Loading
Alipayshow: false,
userInfo: {},
key: ''
}
},
methods: {
// 更改支付方式
changePayway(value) {
this.$set(this, 'payway', value)
},
oncopy() {
copy(this.key)
},
handleclose() {
getPayResult({
from: this.from,
order_id: this.order_id,
id: this.order_id
}).then(({ data }) => {
if (data.pay_status) {
this.result = 'success'
} else {
this.result = 'fail'
}
this.$Router.back(1)
})
},
// 初始化页面数据
initPageData() {
// 获取支付方式
getPayway({
from: this.from,
order_id: this.order_id
})
.then((res) => {
if (res.code != 1) throw new Error(res.msg)
return res.data
})
.then((data) => {
this.loadingSkeleton = false
this.amount = data.order_amount
this.paywayList = data.pay_way
this.payway = this.paywayList[0]?.pay_way
// 倒计时
const startTimestamp = new Date().getTime()
const endTimestamp = data.cancel_time
this.timeout = endTimestamp - startTimestamp / 1000
})
.catch((err) => {
throw new Error(err)
})
},
// 预支付处理
handlePrepay() {
if (this.loadingPay) return
this.loadingPay = true
// #ifdef MP-WEIXIN
if (this.userInfo.mnp_auth == 0 && this.payway == 1) {
uni.showModal({
content: '当前账号未微信授权,请前往个人设置授权',
confirmText: '前往授权',
success: ({ confirm }) => {
if (confirm) {
this.$Router.replaceAll({
path: '/bundle/pages/user_set/user_set',
query: {
form: 'payment'
}
})
}
}
})
return
}
// #endif
// #ifdef H5
if (this.userInfo.oa_auth == 0 && this.payway == 1) {
uni.showModal({
content: '当前账号未微信授权,请前往个人设置授权',
confirmText: '前往授权',
success: ({ confirm }) => {
if (confirm) {
this.$Router.replaceAll({
path: '/bundle/pages/user_set/user_set',
query: {
form: 'payment'
}
})
}
}
})
return
}
// #endif
prepay(
{
from: this.from,
order_id: this.order_id,
pay_way: this.payway
},
this.$store.getters.token
)
.then(({ code, data, pay_way }) => {
switch (code) {
case 1:
this.handleWechatPay(data)
break
case 10001:
this.handleAlipayPay(data, pay_way)
break
case 20001:
this.handleWalletPay()
break
case 30001:
this.handledownPay()
break
}
})
.catch((err) => {})
.finally(() => {
setTimeout(() => {
this.loadingPay = false
}, 500)
})
},
// 微信支付
handleWechatPay(data) {
wxpay(data)
.then((res) => {
console.log(res)
this.handPayResult(res)
})
.catch((err) => {
console.log(err)
})
},
// 支付宝支付
handleAlipayPay(data, pay_way) {
this.key = `${this.$store.state.app.config.base_domain}mobile/bundle/pages/toAlipay/toAlipay?id=${this.order_id}&from=${this.from}&pay_way=${this.payway}&key=${this.$store.getters.token}`
uni.$on('Alipay', () => {
this.Alipayshow = true
})
alipay(
data,
pay_way,
{
order_id: this.order_id,
from: this.from,
pay_way: this.payway
},
this.$store.getters.token
)
.then((res) => {
console.log(res)
this.handPayResult(res)
})
.catch((err) => {
console.log(err)
})
},
// 钱包余额支付
handleWalletPay() {
console.log('支付成功')
//余额支付成功
this.handPayResult('success')
},
// 线下支付
handledownPay() {
console.log('支付成功')
//支付成功
this.handPayResult('success')
},
getUserInfoFun() {
getUserInfo().then((res) => {
if (res.code == 1) {
this.userInfo = res.data
}
})
},
// 支付后处理
handPayResult(result) {
// 页面出栈
//记录支付结果
this.result = result
// uni.navigateBack()
this.$Router.back(1)
}
},
onLoad() {
const options = this.$Route.query
const from = options?.from || 'trade'
const order_id = options?.order_id
this.getUserInfoFun()
try {
if (!from && !order_id) throw new Error('页面参数有误')
this.from = from
this.order_id = order_id
this.initPageData()
} catch (err) {
console.log(err)
// uni.navigateBack()
this.$Router.back()
}
},
onShow() {
if (this.showAgain) {
getPayResult({
from: this.from,
order_id: this.order_id,
id: this.order_id
}).then(({ data }) => {
if (data.pay_status) {
this.result = 'success'
} else {
this.result = 'fail'
}
this.$Router.back(1)
})
}
},
onHide() {
this.showAgain = true
},
onUnload() {
switch (this.result) {
case 'success':
uni.$emit('payment', {
result: true,
order_id: this.order_id,
from: this.from
})
break
case 'fail':
default:
uni.$emit('payment', {
result: false,
order_id: this.order_id,
from: this.from
})
}
}
}
</script>
<style lang="scss">
page {
height: 100%;
padding: 0;
}
.payment-pages {
height: 100%;
.payment {
display: flex;
flex-direction: column;
height: calc(100% - env(safe-area-inset-bottom));
&-header {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 300rpx;
background: linear-gradient(270deg, #ff2c3c 0%, #f95f2f 100%);
color: #ffffff;
}
&-main {
flex: 1;
margin-top: -40rpx;
padding: 0 20rpx;
overflow: hidden;
}
&-footer {
display: flex;
align-items: center;
height: 100rpx;
padding: 0 20rpx;
background-color: #ffffff;
}
.payway-container {
padding: 0 20rpx;
border-radius: 7px;
background-color: #ffffff;
.payway-empty {
width: 100%;
display: flex;
justify-content: center;
padding: 20rpx 0;
font-size: 26rpx;
color: $-color-muted;
}
}
.payway {
width: 100%;
&-item {
display: flex;
align-items: center;
height: 120rpx;
&:nth-child(n + 2) {
border-top: $-dashed-border;
}
&-content {
flex: 1;
display: flex;
flex-direction: column;
margin-left: 16rpx;
&-name {
font-size: 28rpx;
color: $-color-black;
}
&-tips {
font-size: 22rpx;
color: $-color-muted;
}
}
}
}
&-count-down {
display: flex;
justify-content: center;
align-items: center;
padding: 7rpx 25rpx;
border-radius: 60px;
margin-top: 10rpx;
font-size: 22rpx;
background-color: #ffffff;
color: $-color-normal;
}
&-submit {
flex: 1;
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 74rpx;
font-size: 28rpx;
border-radius: 60px;
background: linear-gradient(270deg, #ff2c3c 0%, #f95f2f 100%);
color: #ffffff;
&--disabled::before {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
display: block;
content: '';
background: rgba(255, 255, 255, 0.3) !important;
}
}
}
}
.Alipay {
padding: 20rpx;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.btn {
background: linear-gradient(270deg, #ff2c3c 0%, #f95f2f 100%);
border-radius: 12rpx;
width: 100%;
height: 80rpx;
line-height: 80rpx;
font-size: 28rpx;
color: white;
}
}
</style>