<template>
<view class="wrap">
<view class="payComplete">
<image class="img" src="@/static/image/index/6.png" />
<text class="adress">支付完成后填写</text>
</view>
<view class="commodityWrap">
<view class="title">
<text class="border" />
<text>商品信息</text>
</view>
<view class="min">
<image v-if="productObj.picUrl" class="img" :src="productObj.picUrl" />
<image v-else class="img" src="@/static/image/index/defaultImg.png" />
<view class="right">
<view class="name">
<text class="secondaryContent">
{{ productObj.productName }}
</text>
<text class="num"
>¥ {{ productObj.price ? (Number(productObj.price) / 100).toFixed(2) : '0.00' }}</text
>
</view>
<view class="name illustrate">
<text class="secondaryContent">
{{ productObj.productExt }}
</text>
</view>
</view>
</view>
<view class="bottomNum">
<view class="wraps">
<text>选择数量</text>
<up-number-box
@change="valChange"
v-model="chooseNumber"
@blur="onNumberChange"
:min="1"
:max="999"
/>
</view>
</view>
</view>
<view class="commodityWrap payWay">
<view class="title">
<text class="border" />
<text>支付方式</text>
</view>
<view class="payList">
<view class="left">
<image class="img" src="@/static/image/index/8.png" />
<text class="adress">微信支付</text>
</view>
<image class="right" src="@/static/image/index/7.png" />
</view>
</view>
<view class="goPay">
<view class="wraps">
<view class="left">
<text class="name">应付:</text>
<text class="name">¥ </text>
<text class="name">{{ payNumberInteger }}</text>
<text class="name">.{{ payNumberDecimal }}</text>
</view>
<view class="right" @tap="toPay"> 去支付 </view>
</view>
</view>
<view class="bg" v-if="bgShow" />
<view class="bgTwo" v-if="bgShowTwo" />
</view>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { onLoad, onShow, onUnload, onHide } from '@dcloudio/uni-app'
import { productInfoInfo, orderPaid, orderStatus } from '@/api/index'
const state = reactive({
timeQuestions: null
})
const chooseNumber = ref(1)
const chooseNumberSure = ref(1)
const productId = ref('')
const productObj = ref({})
const bizOrderNo = ref('')
const userInfo = ref({})
const isstop = ref(false)
const isBack = ref(false)
// 整数部分
const payNumberInteger = ref('0')
// 小数部分
const payNumberDecimal = ref('00')
const bgShow = ref(false)
const bgShowTwo = ref(false)
onLoad((options) => {
productId.value = options.productId
})
onUnload(() => {
const isScan = uni.getStorageSync('wxScans')
clearInterval(state.timeQuestions)
state.timeQuestions = null
if (isScan && isScan == 'true' && !isBack.value) {
uni.switchTab({
url: '/pages/load/index'
})
// uni.switchTab({
// url: '/pages/index/index'
// })
}
})
onHide(() => {
uni.removeStorageSync('isBack')
uni.removeStorageSync('isChoose')
})
onShow(() => {
bgShow.value = false
bgShowTwo.value = false
userInfo.value = uni.getStorageSync('userInfo') ? JSON.parse(uni.getStorageSync('userInfo')) : {}
productObj.value = {}
chooseNumber.value = 1
chooseNumberSure.value = 1
payNumberInteger.value = '0'
payNumberDecimal.value = '00'
init()
})
const init = () => {
if (uni.getStorageSync('paySuccess') == 'true') {
uni.showLoading({
title: '支付中...'
})
bgShowTwo.value = true
} else {
uni.showLoading({
title: '加载中'
})
}
const param = '?productId=' + productId.value
productInfoInfo(param).then((res: any) => {
if (isstop.value == false) {
uni.hideLoading()
}
if (res.code == 0) {
if (res.data) {
if (res.data.productStatus == 'off') {
uni.removeStorageSync('isBack')
uni.removeStorageSync('isChoose')
bgShowTwo.value = true
uni.showToast({
title: '该商品已下架',
icon: 'none',
duration: 2000
})
setTimeout(() => {
bgShowTwo.value = false
uni.switchTab({
url: '/pages/index/index'
})
}, 2000)
} else {
if (res.data && res.data.productName) {
productObj.value = res.data
const price =
res.data && res.data.price ? (Number(res.data.price) / 100).toFixed(2) : '0.00'
payNumberInteger.value = price.split('.')[0]
payNumberDecimal.value = price.split('.')[1]
}
}
}
}
})
}
const valChange = (e) => {
chooseNumberSure.value = e.value
const price = (
(productObj.value && productObj.value.price ? Number(productObj.value.price) / 100 : 0) *
e.value
).toFixed(2)
payNumberInteger.value = price.split('.')[0]
payNumberDecimal.value = price.split('.')[1]
}
const onNumberChange = (event) => {
if (!event.value) {
chooseNumber.value = 1000
chooseNumberSure.value = 1000
setTimeout(() => {
chooseNumber.value = 1
chooseNumberSure.value = 1
}, 20)
const price =
productObj.value && productObj.value.price
? (Number(productObj.value.price) / 100).toFixed(2)
: '0.00'
payNumberInteger.value = price.split('.')[0]
payNumberDecimal.value = price.split('.')[1]
}
}
//支付
const toPay = () => {
uni.showLoading({
title: '加载中'
})
const param = {
patientId: userInfo.value.patientId,
openid: userInfo.value.openId,
productId: productId.value,
doctorId: userInfo.value.bindDoctorId ? userInfo.value.bindDoctorId : null,
num: chooseNumberSure.value
}
orderPaid(param).then((res: any) => {
uni.hideLoading()
if (res.code == 0) {
const payParam = JSON.parse(res.data.payBody)
bizOrderNo.value = res.data.bizOrderNo
uni.requestPayment({
provider: 'wxpay',
timeStamp: payParam.timeStamp,
nonceStr: payParam.nonceStr,
package: payParam.package,
signType: payParam.signType,
paySign: payParam.paySign,
success: function (res) {
isstop.value = true
bgShow.value = true
uni.setStorageSync('paySuccess', 'true')
loopTime()
console.log('success:' + JSON.stringify(res))
},
fail: function (err) {
isstop.value = false
isBack.value = true
bgShow.value = false
bgShowTwo.value = false
// console.log('支付失败')
uni.removeStorageSync('isBack')
uni.removeStorageSync('isChoose')
uni.redirectTo({
url:
'/packA/pages/pay/nopayIndex?productId=' +
productId.value +
'&chooseNumberSure=' +
chooseNumberSure.value +
'&bizOrderNo=' +
bizOrderNo.value
})
console.log('fail:' + JSON.stringify(err))
}
})
}
})
}
const loopTime = () => {
let s = 0
state.timeQuestions = setInterval(() => {
s++
后端说 orderStatusFun这个方法的接口 两秒内肯定会更新支付状态 所以两秒后调用这个方法
if (s >= 2) {
s = 0
orderStatusFun()
}
}, 1000)
}
const orderStatusFun = () => {
const param = bizOrderNo.value
orderStatus(param).then((res) => {
isstop.value = true
if (res.data.payState == 'PROGRESS') {
console.log('PROGRESS')
} else if (res.data.payState == 'SUCCESS') {
bgShow.value = false
uni.removeStorageSync('paySuccess')
clearInterval(state.timeQuestions)
state.timeQuestions = null
uni.showToast({
title: '支付成功',
icon: 'none',
duration: 2000
})
setTimeout(() => {
isstop.value = false
bgShowTwo.value = false
isBack.value = true
uni.removeStorageSync('isBack')
uni.removeStorageSync('isChoose')
uni.hideLoading()
uni.redirectTo({ url: '/packA/pages/address/index?bizOrderNo=' + bizOrderNo.value })
}, 2000)
} else {
clearInterval(state.timeQuestions)
state.timeQuestions = null
}
})
}
</script>
<style lang="scss" scoped>
.wrap {
min-height: 100vh;
.payComplete {
display: inline-block;
width: calc(100% - 64rpx);
margin: 32rpx 32rpx 24rpx;
padding: 24rpx 32rpx;
border-radius: 16rpx;
background: #fff;
color: #222;
font-size: 32rpx;
font-weight: 700;
.img {
display: inline-block;
width: 32rpx;
height: 32rpx;
margin-right: 16rpx;
vertical-align: middle;
}
.adress {
display: inline-block;
vertical-align: middle;
}
}
.commodityWrap {
margin: 0 32rpx;
overflow: hidden;
border-radius: 16rpx;
background: #fff;
.title {
position: relative;
padding: 24rpx 32rpx;
color: #222;
font-size: 32rpx;
font-weight: 700;
.border {
position: absolute;
top: 50%;
left: 0;
width: 8rpx;
height: 32rpx;
transform: translateY(-50%);
background: #316ffe;
}
}
.min {
padding: 0 32rpx;
.img {
display: inline-block;
width: 136rpx;
height: 136rpx;
border-radius: 12rpx;
vertical-align: top;
}
.right {
display: inline-block;
width: calc(100% - 160rpx);
margin-left: 24rpx;
vertical-align: top;
.name {
position: relative;
width: 100%;
color: #222;
font-size: 28rpx;
font-weight: 700;
.secondaryContent {
display: -webkit-box;
width: calc(100% - 140rpx);
height: 73rpx;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2; /* 定义文本的行数 */
}
.num {
position: absolute;
top: 0;
right: 0;
width: 140rpx;
color: #ff503d;
text-align: right;
white-space: nowrap;
}
&.illustrate {
margin-top: 24rpx;
color: #999;
font-size: 24rpx;
font-weight: 400;
.secondaryContent {
width: 100%;
height: auto;
-webkit-line-clamp: 1;
}
}
}
}
}
::v-deep .bottomNum {
padding: 24rpx 32rpx;
color: #222;
font-size: 30rpx;
.wraps {
position: relative;
height: 56rpx;
line-height: 56rpx;
.u-number-box {
position: absolute;
top: 50%;
right: 0rpx;
transform: translateY(-50%);
border: 1rpx solid #e5e6eb;
border-radius: 4rpx;
.u-number-box__minus,
.u-number-box__input,
.u-number-box__plus {
height: 56rpx !important;
background-color: #fff !important;
}
.u-number-box__input {
width: 80rpx !important;
margin: 0 !important;
border-right: 1rpx solid #e5e6eb;
}
.u-number-box__minus {
border-right: 1rpx solid #e5e6eb;
&.u-number-box__minus--disabled {
.u-icon__icon {
color: #cfcfcf !important;
}
}
}
.u-number-box__plus {
&.u-number-box__minus--disabled {
.u-icon__icon {
color: #cfcfcf !important;
}
}
}
}
}
}
&.payWay {
margin-top: 24rpx;
padding-bottom: 24rpx;
.payList {
position: relative;
margin: 0 32rpx;
padding: 8rpx 0 32rpx;
border-bottom: 1rpx solid #e5e6eb;
.left {
.img {
display: inline-block;
width: 32rpx;
height: 32rpx;
vertical-align: middle;
}
.adress {
display: inline-block;
margin-left: 16rpx;
color: #222;
font-size: 32rpx;
font-weight: 700;
vertical-align: middle;
}
}
.right {
display: block;
position: absolute;
top: calc(50% - 12rpx);
right: 0;
width: 32rpx;
height: 32rpx;
transform: translateY(-50%);
}
}
}
}
.goPay {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
background: #fff;
.wraps {
position: relative;
padding: 32rpx 40rpx;
.left {
color: #222;
font-size: 28rpx;
font-weight: 700;
.name {
&:nth-child(2),
&:nth-child(4) {
color: #ff503d;
font-size: 24rpx;
}
&:nth-child(3) {
color: #ff503d;
font-size: 56rpx;
}
}
}
.right {
position: absolute;
top: 50%;
right: 32rpx;
padding: 22rpx 64rpx;
transform: translateY(-50%);
border-radius: 44rpx;
background: #ff503d;
color: #fff;
font-size: 32rpx;
}
}
}
.bg {
position: fixed;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgb(0 0 0 / 50%);
}
.bgTwo {
position: fixed;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgb(0 0 0 / 0.1%);
}
}
</style>