|
|
<template>
|
|
|
<!-- <isPhone>
|
|
|
|
|
|
</isPhone> -->
|
|
|
<view class="page-box">
|
|
|
<template v-if="info.id">
|
|
|
<view class="info">
|
|
|
<view class="logo">
|
|
|
<u--image :showLoading="true" :src="info.logo_url" width="60px" height="60px"></u--image>
|
|
|
</view>
|
|
|
<text>
|
|
|
{{ info.name }}
|
|
|
</text>
|
|
|
</view>
|
|
|
<view class="con">
|
|
|
<u--text text="付款金额" margin="0 0 8px 8px" bold color="#000000" size="14"></u--text>
|
|
|
<view class="price">
|
|
|
<view>
|
|
|
<u--text text="¥" margin="0 3px 0 0" size="32" bold color="#000000"></u--text>
|
|
|
</view>
|
|
|
<input ref="input" v-model.lazy="total_price" @blur="formatInput" :focus="focusState" border="none"
|
|
|
type="digit" class="input" />
|
|
|
</view>
|
|
|
<coupons v-if="coupon && coupon.length" :activeCoupon.sync="activeCoupon" :coupon="coupon"
|
|
|
:currentPrice="total_price">
|
|
|
</coupons>
|
|
|
</view>
|
|
|
<view class="payList">
|
|
|
|
|
|
<view class="item" @click="pay(3)" v-if="info.pay_type.includes(3)">
|
|
|
<view class="let">
|
|
|
<text>余额支付</text>
|
|
|
<!-- <text v-show="total_price">{{ price || 0 }} ¥</text> -->
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- #ifdef MP-WEIXIN -->
|
|
|
<view style="background: #19be6b;" class="item" @click="pay(2)" v-if="info.pay_type.includes(2)">
|
|
|
<view class="let">
|
|
|
<text>微信</text>
|
|
|
<!-- <text v-show="total_price">{{ price || 0 }} ¥</text> -->
|
|
|
</view>
|
|
|
</view>
|
|
|
<!-- #endif -->
|
|
|
|
|
|
<!-- #ifdef MP-ALIPAY -->
|
|
|
<view style="background: #2979ff;" class="item">
|
|
|
<view class="let" @click="pay(1)" v-if="info.pay_type.includes(1)">
|
|
|
<text>支付宝</text>
|
|
|
<!-- <text v-show="total_price">{{ price || 0 }} ¥</text> -->
|
|
|
</view>
|
|
|
</view>
|
|
|
<!-- #endif -->
|
|
|
|
|
|
|
|
|
<!-- #ifdef H5 -->
|
|
|
<view v-if="$utils.isInWeChatBrowser() && info.pay_type.includes(2)" style="background: #19be6b;"
|
|
|
class="item" @click="pay(2)">
|
|
|
<view class="let">
|
|
|
<text>微信</text>
|
|
|
<!-- <text v-show="total_price">{{ price || 0 }} ¥</text> -->
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<view v-if="$utils.isInAliBrowser() && info.pay_type.includes(1)" style="background: #2979ff;"
|
|
|
class="item" @click="pay(1)">
|
|
|
<view class="let">
|
|
|
<text>支付宝</text>
|
|
|
<!-- <text v-show="total_price">{{ price || 0 }} ¥</text> -->
|
|
|
</view>
|
|
|
</view>
|
|
|
<!-- #endif -->
|
|
|
|
|
|
</view>
|
|
|
</template>
|
|
|
<logins v-if="wcCode != -1" @isLogin="isLogin" :wcCode="wcCode" :type="$utils.isInAliBrowser() || $utils.isInWeChatBrowser() ? 0 : 2"></logins>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import isPhone from "@/components/tools/isPhone/index";
|
|
|
import coupons from '../compontents/coupons.vue';
|
|
|
|
|
|
import logins from '@/components/login/logins.vue'
|
|
|
|
|
|
// #ifndef MP
|
|
|
import wxConfig from '@/utils/wxConfig'
|
|
|
// #endif
|
|
|
|
|
|
export default {
|
|
|
components: {
|
|
|
coupons,
|
|
|
isPhone,
|
|
|
logins
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
order_type: 1,
|
|
|
info: {
|
|
|
pay_type: []
|
|
|
},
|
|
|
total_price: "",
|
|
|
pop: false,
|
|
|
focusState: true,
|
|
|
payCurrent: false,
|
|
|
coupon: [],
|
|
|
activeCoupon: {},
|
|
|
mch_id: 0,
|
|
|
wcCode: -1
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
price() {
|
|
|
console.log(this.activeCoupon);
|
|
|
if (this.activeCoupon?.coupon?.price) {
|
|
|
return (this.total_price - this.activeCoupon.coupon.price)?.toFixed?.(2)
|
|
|
} else {
|
|
|
return (this.total_price)
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
async onLoad(query) {
|
|
|
if (query.wxcode) {
|
|
|
this.wcCode = query.wxcode
|
|
|
query.mch_id = uni.getStorageSync('pay_mch_id')
|
|
|
} else {
|
|
|
if (query.state) {
|
|
|
return uni.showModal({
|
|
|
title: '提示',
|
|
|
content: '登录失败'
|
|
|
})
|
|
|
}
|
|
|
this.wcCode = ''
|
|
|
if (query.mch_id > 0) {
|
|
|
uni.setStorageSync('pay_mch_id', query.mch_id)
|
|
|
}
|
|
|
}
|
|
|
let qrCode = '';
|
|
|
const params = query
|
|
|
const {
|
|
|
mch_id
|
|
|
} = params;
|
|
|
this.mch_id = mch_id || 0
|
|
|
this.$nextTick(() => {
|
|
|
this.init()
|
|
|
})
|
|
|
},
|
|
|
onShow() {
|
|
|
this.watchToMonitor = this.$watch(
|
|
|
// 此处被监听的对象必须是一个函数,否则会报错
|
|
|
() => {
|
|
|
return this.total_price
|
|
|
},
|
|
|
() => {
|
|
|
// do some thing
|
|
|
uni.setStorageSync("支付" + this.mch_id, JSON.stringify(this.total_price))
|
|
|
}, {
|
|
|
deep: true
|
|
|
})
|
|
|
},
|
|
|
onHide() {
|
|
|
this.watchToMonitor()
|
|
|
|
|
|
if (!this.payCurrent) {
|
|
|
this.payCurrent = false
|
|
|
this.focusState = false
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
isLogin() {
|
|
|
// this.init()
|
|
|
},
|
|
|
async init() {
|
|
|
const res = await this.$api.inPersonToPay.storeInfos({
|
|
|
mch_id: this.mch_id,
|
|
|
})
|
|
|
this.info = {
|
|
|
...res.data.store,
|
|
|
...res.data.shop
|
|
|
}
|
|
|
if (!this.info.pay_type) {
|
|
|
this.info.pay_type = []
|
|
|
}
|
|
|
this.coupon = res.data.coupon
|
|
|
},
|
|
|
formatInput() {
|
|
|
if (this.total_price !== null) {
|
|
|
let value = this.total_price.toString();
|
|
|
value = value.replace(/[^\d.]/g, ""); // 去掉非数字和小数点
|
|
|
value = value.replace(/^\./g, ""); // 去掉开头的小数点
|
|
|
value = value.replace(/\.{2,}/g, "."); // 去掉多余的小数点
|
|
|
value = value.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
|
|
|
// 将第一个小数点替换成分隔符
|
|
|
value = parseFloat(value);
|
|
|
if (isNaN(value)) {
|
|
|
value = null;
|
|
|
} else {
|
|
|
value = value.toFixed(2); // 保留两位小数
|
|
|
}
|
|
|
this.total_price = value;
|
|
|
}
|
|
|
},
|
|
|
|
|
|
async pay(type) {
|
|
|
if (this.submit()) return
|
|
|
this.payCurrent = true
|
|
|
let {
|
|
|
order_type
|
|
|
} = this;
|
|
|
const payType = type // 支付类型
|
|
|
let order_no
|
|
|
const res = await this.$api.inPersonToPay.inpersonPaymentOrder({
|
|
|
total_price: this.total_price,
|
|
|
pay_type: type,
|
|
|
mch_id: this.mch_id,
|
|
|
user_coupon_id: this.activeCoupon.id || 0,
|
|
|
})
|
|
|
|
|
|
if (res.code !== 0) {
|
|
|
uni.$u.toast(res.message || "出错了");
|
|
|
return
|
|
|
}
|
|
|
|
|
|
order_no = res.data.order_no // 订单号
|
|
|
|
|
|
uni.showLoading({
|
|
|
title: "请稍等",
|
|
|
mask: true,
|
|
|
});
|
|
|
switch (payType) {
|
|
|
case 1:
|
|
|
await this.payTreasureToPay({
|
|
|
payType,
|
|
|
order_no,
|
|
|
order_type
|
|
|
})
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
// return uni.showModal({
|
|
|
// title: '提示',
|
|
|
// content: '请使用支付宝扫码',
|
|
|
// showCancel: false
|
|
|
// })
|
|
|
// #ifndef MP
|
|
|
await this.wechatPayNow({
|
|
|
payType,
|
|
|
order_no,
|
|
|
order_type
|
|
|
})
|
|
|
// #endif
|
|
|
|
|
|
// #ifdef MP-WEIXIN
|
|
|
await this.wechatPay({
|
|
|
payType,
|
|
|
order_no,
|
|
|
order_type
|
|
|
})
|
|
|
// #endif
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
console.log("余额");
|
|
|
await this.balancePayment({
|
|
|
payType,
|
|
|
order_no,
|
|
|
order_type
|
|
|
})
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
uni.hideLoading();
|
|
|
},
|
|
|
// 余额支付
|
|
|
async balancePayment({
|
|
|
payType,
|
|
|
order_no,
|
|
|
order_type
|
|
|
}) {
|
|
|
try {
|
|
|
const res = await this.$api.pay.OrderPayment({
|
|
|
pay_type: payType,
|
|
|
order_no: order_no,
|
|
|
order_type,
|
|
|
});
|
|
|
|
|
|
if (res.code) {
|
|
|
// this.$u.toast(res.message)
|
|
|
throw new Error(res.message)
|
|
|
};
|
|
|
|
|
|
this.successSubmit(res)
|
|
|
} catch (error) {
|
|
|
this.$u.toast(error.message)
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// H5 微信支付
|
|
|
async wechatPayNow({
|
|
|
payType,
|
|
|
order_no,
|
|
|
order_type
|
|
|
}) {
|
|
|
wxConfig.init(["chooseWXPay"]).then((wx) => {
|
|
|
console.log(wx.chooseWXPay);
|
|
|
})
|
|
|
try {
|
|
|
const res = await this.$api.pay.OrderPayment({
|
|
|
pay_type: payType,
|
|
|
order_no: order_no,
|
|
|
order_type
|
|
|
});
|
|
|
if (res.code) return this.$u.toast(res.message)
|
|
|
if (res.data == -1) {
|
|
|
return this.successSubmit();
|
|
|
}
|
|
|
wxConfig.init(["chooseWXPay"]).then(wx => {
|
|
|
wx.chooseWXPay({
|
|
|
// 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。
|
|
|
// 但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
|
|
|
timestamp: res.data.timeStamp, // 时间戳
|
|
|
nonceStr: res.data.nonceStr, // 支付签名随机串,不长于 32 位
|
|
|
package: res.data.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
|
|
|
signType: res.data.signType, // 签名算法
|
|
|
paySign: res.data.paySign, // 签名
|
|
|
success: function(res) {
|
|
|
if (res.err_msg == "get_brand_wcpay_request:ok" || res.err_Info ==
|
|
|
"success" || res.errMsg == "chooseWXPay:ok") {
|
|
|
this.successSubmit();
|
|
|
} else {
|
|
|
this.failSubmit();
|
|
|
}
|
|
|
},
|
|
|
complete: function(err) {
|
|
|
if (res.err_msg == "get_brand_wcpay_request:ok" || res.err_Info ==
|
|
|
"success" || res.errMsg == "chooseWXPay:ok" || res.errMsg ==
|
|
|
"getBrandWCPayRequest:ok") {
|
|
|
this.successSubmit();
|
|
|
} else {
|
|
|
this.failSubmit();
|
|
|
}
|
|
|
},
|
|
|
})
|
|
|
})
|
|
|
} catch (error) {
|
|
|
this.$u.toast(error.message)
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
// 微信支付
|
|
|
async wechatPay({
|
|
|
payType,
|
|
|
order_no,
|
|
|
order_type
|
|
|
}) {
|
|
|
try {
|
|
|
const res = await this.$api.pay.OrderPayment({
|
|
|
pay_type: payType,
|
|
|
order_no: order_no,
|
|
|
order_type,
|
|
|
});
|
|
|
if (res.code) return this.$u.toast(res.message)
|
|
|
// res为调起微信支付所需参数
|
|
|
// 调起微信支付
|
|
|
await uni.requestPayment({
|
|
|
provider: 'wxpay', // 服务提提供商
|
|
|
timeStamp: res.data.timeStamp, // 时间戳
|
|
|
nonceStr: res.data.nonceStr, // 随机字符串
|
|
|
package: res.data.package,
|
|
|
signType: res.data.signType, // 签名算法
|
|
|
paySign: res.data.paySign, // 签名
|
|
|
success: (res) => {
|
|
|
if (res.errMsg === 'requestPayment:ok') {
|
|
|
this.successSubmit();
|
|
|
}
|
|
|
console.log(res, 'success');
|
|
|
},
|
|
|
fail: (res) => {
|
|
|
console.log(res, 'fail')
|
|
|
if (res.errMsg == 'requestPayment:fail cancel') {
|
|
|
this.failSubmit();
|
|
|
}
|
|
|
|
|
|
},
|
|
|
complete(res) {
|
|
|
console.log(res, 'complete')
|
|
|
}
|
|
|
});
|
|
|
} catch (error) {
|
|
|
this.$u.toast(error.message)
|
|
|
console.log(error)
|
|
|
}
|
|
|
},
|
|
|
|
|
|
// 支付宝支付
|
|
|
async payTreasureToPay({
|
|
|
payType,
|
|
|
order_no,
|
|
|
order_type
|
|
|
}) {
|
|
|
try {
|
|
|
let that = this
|
|
|
const res = await this.$api.pay.OrderPayment({
|
|
|
pay_type: payType,
|
|
|
order_no: order_no,
|
|
|
order_type,
|
|
|
});
|
|
|
if (res.code) return this.$u.toast(res.message)
|
|
|
|
|
|
// #ifdef H5
|
|
|
if (this.$utils.isInAliBrowser()) {
|
|
|
AlipayJSBridge.call("tradePay", {
|
|
|
tradeNO: res.data.trade_no
|
|
|
}, function(data) {
|
|
|
if ("9000" == data.resultCode) {
|
|
|
that.successSubmit(res)
|
|
|
} else {
|
|
|
throw new Error('支付失败,状态码:' + data.resultCode)
|
|
|
}
|
|
|
});
|
|
|
} else {
|
|
|
return uni.showToast({
|
|
|
icon: 'none',
|
|
|
title: '请到支付宝或微信环境中支付'
|
|
|
})
|
|
|
}
|
|
|
|
|
|
// #endif
|
|
|
|
|
|
// #ifdef MP-ALIPAY
|
|
|
// res为调起支付宝支付所需参数
|
|
|
// 调起支付宝支付
|
|
|
uni.requestPayment({
|
|
|
provider: 'alipay', // 服务提供商
|
|
|
orderInfo: res.data.trade_no,
|
|
|
success: (res) => {
|
|
|
console.log(res);
|
|
|
if (res.errMsg === 'requestPayment:ok' && res.resultCode ===
|
|
|
'9000') { // 支付成功的判断条件
|
|
|
this.successSubmit(res)
|
|
|
}
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
if (err.errMsg !== 'requestPayment:fail cancel') { // 不是取消支付的错误才抛出异常
|
|
|
throw new Error(err.errMsg)
|
|
|
}
|
|
|
},
|
|
|
complete: ({
|
|
|
errMsg
|
|
|
}) => {
|
|
|
// if (errMsg) {
|
|
|
// this.$u.toast(errMsg);
|
|
|
// }
|
|
|
}
|
|
|
});
|
|
|
// #endif
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
this.$u.toast(error.message)
|
|
|
}
|
|
|
},
|
|
|
|
|
|
failSubmit() {
|
|
|
this.$u.toast("支付失败")
|
|
|
},
|
|
|
successSubmit() {
|
|
|
this.pop = false
|
|
|
this.$u.toast("支付成功")
|
|
|
|
|
|
setTimeout(() => {
|
|
|
this.toUrl('/subPackages/inPersonToPay/result/index?price=' + this.total_price + '&mch_id=' +
|
|
|
this.mch_id)
|
|
|
uni.removeStorageSync("支付" + this.mch_id)
|
|
|
this.total_price = ""
|
|
|
this.payCurrent = false
|
|
|
}, 300);
|
|
|
},
|
|
|
submit() {
|
|
|
if (!this.total_price) {
|
|
|
this.$u.toast("请输入付款金额")
|
|
|
|
|
|
return true
|
|
|
}
|
|
|
|
|
|
if (this.total_price <= 0) {
|
|
|
this.$u.toast("付款金额低于0元")
|
|
|
|
|
|
return true
|
|
|
}
|
|
|
return false
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
.info {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
margin: 20px;
|
|
|
grid-gap: 32rpx;
|
|
|
grid: 32rpx;
|
|
|
|
|
|
.logo {
|
|
|
border-radius: 26rpx;
|
|
|
border-right-color: rgb(212, 212, 212);
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.con {
|
|
|
padding: 19px;
|
|
|
box-shadow: 0 0.4125rem 2rem 2px rgba(215, 216, 217, .49);
|
|
|
margin: 20px;
|
|
|
border-radius: 20rpx;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
::v-deep {
|
|
|
uni-input {
|
|
|
font-weight: 600 !important;
|
|
|
color: black;
|
|
|
transition: all 0.6s;
|
|
|
font-weight: 600;
|
|
|
min-height: 80px !important;
|
|
|
display: flex;
|
|
|
}
|
|
|
|
|
|
.u-border-bottom {
|
|
|
border-bottom-width: 0.5px !important;
|
|
|
border-color: rgb(224, 223, 223) !important;
|
|
|
border-bottom-style: solid;
|
|
|
}
|
|
|
|
|
|
.u-popup__content {
|
|
|
background-color: transparent;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.input {
|
|
|
font-size: 32px;
|
|
|
padding: 10rpx 2%;
|
|
|
height: 42px;
|
|
|
line-height: 42px;
|
|
|
}
|
|
|
|
|
|
.payList {
|
|
|
// position: fixed;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
bottom: 0;
|
|
|
padding: 12rpx 36rpx 12rpx;
|
|
|
// padding: 12rpx 36rpx calc(constant(safe-area-inset-bottom) + 22rpx);
|
|
|
// padding: 12rpx 36rpx calc(env(safe-area-inset-bottom) + 22rpx);
|
|
|
background: #fff;
|
|
|
|
|
|
padding: 19px;
|
|
|
box-shadow: 0 0.4125rem 2rem 2px rgba(215, 216, 217, .49);
|
|
|
margin: 20px;
|
|
|
border-radius: 40rpx;
|
|
|
|
|
|
.item {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
background: linear-gradient(90deg, #f22407 0%, #f84d17 100%);
|
|
|
|
|
|
padding: 14rpx;
|
|
|
|
|
|
border-radius: 32px;
|
|
|
font-size: 26rpx;
|
|
|
font-weight: bold;
|
|
|
color: #fff;
|
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
transition: all 1s cubic-bezier(0.075, 0.82, 0.165, 1);
|
|
|
|
|
|
&:hover {
|
|
|
opacity: 0.8;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.title {
|
|
|
padding-top: 34rpx;
|
|
|
font-weight: 600;
|
|
|
text-align: center;
|
|
|
}
|
|
|
|
|
|
.item {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: space-between;
|
|
|
height: 80rpx;
|
|
|
|
|
|
.let {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
// justify-content: space-between;
|
|
|
justify-content: center;
|
|
|
}
|
|
|
|
|
|
padding: 0 28rpx;
|
|
|
|
|
|
&:not(:last-child) {
|
|
|
margin-bottom: 20rpx;
|
|
|
border-bottom: 1px solid #f8f8f8;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.m-tit {
|
|
|
margin-bottom: 20rpx;
|
|
|
}
|
|
|
|
|
|
.let {
|
|
|
flex: 1;
|
|
|
overflow: hidden;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
}
|
|
|
|
|
|
.img {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
margin-right: 20rpx;
|
|
|
width: 40rpx;
|
|
|
height: 40rpx;
|
|
|
}
|
|
|
|
|
|
image {
|
|
|
// width: 100%;
|
|
|
height: 40rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
.price {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
|
|
|
border-bottom: 1px solid #f8f8f8;
|
|
|
}
|
|
|
</style>
|
|
|
|
|
|
<style>
|
|
|
page {
|
|
|
background-color: white;
|
|
|
}
|
|
|
</style> |