shangfutong-ui/jeepay-ui-uapp-cashier/pageMember/payMember/payMember.vue

527 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="page-weapper" :style="{ '--v-primary': calcThemeColor(), '--bg-color': calcThemeColor('bgColor') }">
<view class="header">
<view class="mch-info">
<view @tap="advancedFunc">付款给{{ vdata.mchInfo.mchName }}</view>
<view class="mch-img-box">
<image :src="vdata.mchInfo.storeLogo" mode="aspectFill" class="mch-header"></image>
</view>
</view>
<view class="sub-title">付款金额</view>
<view class="pay-wrapper" @tap="refKey.openKeyBoard()">
<view class="pay-amount"
:style="{ color: vdata.amount ? '' : '#ccccccff', fontSize: vdata.amount ? '100rpx' : '' }">
{{ vdata.amount || '请输入付款金额' }}
<text class="pay-icon"></text>
</view>
</view>
<view class="sub-title">支付方式</view>
<view class="pay-select">
<view class="pay-info">
<image :src="calcThemeColor('imgUrl')" mode="aspectFill" class="pay-img"></image>
<text>{{ vdata.pageTypeInfo?.title }}</text>
</view>
<view class="radio" :class="{ 'radio-selected': vdata.paySelected == vdata.pageTypeInfo.value }"
@tap="vdata.paySelected = vdata.pageTypeInfo.value">
<image src="/static/vipImg/selected-icon.svg" mode="aspectFill"
v-if="vdata.paySelected == vdata.pageTypeInfo.value"></image>
</view>
</view>
<view class="surplus-wrapper">
<view class="member-top">
<view class="member-info">
<image src="/static/vipImg/member-icon.svg" mode="aspectFill" class="member-icon"></image>
<text>会员支付</text>
</view>
<view class="radio" :class="{ 'radio-selected': vdata.paySelected == 'member' }" @tap="() => {
if (!vdata.mbrName) return
vdata.paySelected = 'member'
}">
<image src="/static/vipImg/close-mereber.svg" mode="aspectFill" v-if="!vdata.mbrName"></image>
<image src="/static/vipImg/selected-icon.svg" mode="aspectFill"
v-if="vdata.paySelected == 'member'"></image>
</view>
</view>
<view class="balance-wrapper" @tap="toRech">
<view class="ba-left" v-if="vdata.mbrName">可用余额:<text>¥{{ (vdata.balance / 100).toFixed(2) }}</text>
</view>
<view class="ba-left" style="color:#835511;" v-else> 您还未注册会员 </view>
<view class="ba-right" hover-class="hover-but" hover-stay-time="200">
<text>{{ vdata.mbrName ? '去充值' : '去注册' }}</text>
<image src="/static/vipImg/icon-arrow.svg" mode="aspectFill"></image>
</view>
</view>
</view>
<!-- 充值优惠部分 -->
<view class="member-pref" v-if="amountRules.length">
<view class="sub-title">现充值立享</view>
<view style="padding-top: 11rpx;">
<block v-for="v in amountRules" :key="v.ruleId">
<view class="pref-info">
<view class="pref-title">充值</view>
<text>¥{{ parseFloat((v.rechargeAmount / 100).toFixed(2)) }}</text>
<view class="pref-title">到账</view>
<text>¥{{ parseFloat(((v.rechargeAmount + v.giveAmount) / 100).toFixed(2)) }}</text>
</view>
</block>
</view>
</view>
</view>
<view class="footer-keyboard">
<Keyboard ref="refKey" v-model:value="vdata.amount" :isFixedFlag="vdata.mchInfo.fixedFlag" @pay="payMember"
@remarks="refRemarks.open()" />
</view>
</view>
<ConfirmPay ref="refConfPay" @pay="confirmMemberPay" />
<Remarks ref="refRemarks" v-model:value="vdata.buyerRemark" />
</template>
<script setup>
import { onLoad, onPullDownRefresh, onUnload } from '@dcloudio/uni-app'
import { ref, reactive } from "vue"
import { $apiMembers, $payRemberCard, $getMemberInfo, } from "@/http/apiMember.js"
import { toErrPageFunc } from '@/util/toErrorPageUtil.js'
import { $getPayPackage, $getAdvert } from "@/http/apiManager.js"
import storageManage from '@/util/storageManage.js'
import appConfig from "@/config/appConfig"
import paywayCallFunc from '@/pages/payway/payway.js'
import Remarks from "./components/Remarks.vue"
import Keyboard from "./components/Keyboard.vue"
import ConfirmPay from "./components/ConfirmPay.vue"
// import { Base64 } from 'js-base64'
import { calcThemeColor } from "@/util/member.js"
onLoad(() => {
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: calcThemeColor()
})
// 查询会员信息 token
$apiMembers({ method: 'mbr.info', channelUesrId: Base64.encode(appConfig.channelUserId) }).then(({ bizData }) => {
if (bizData) {
storageManage.iToken(bizData)
getMemberInfo() //存储token 查询会员信息
}
getMchInfos()
})
uni.$on('updateMemberInfos', () => {
console.log('接收页面通讯');
getMemberInfo()
})
getRules()
})
onUnload(() => {
uni.$off('updateMemberInfos')
})
const refConfPay = ref(null)
const refRemarks = ref(null)
const refKey = ref(null)
const amountRules = reactive([])
const vdata = reactive({
amount: '',
paySelected: '',
pageTypeInfo: {},
payOrderInfo: {},
mchInfo: {},
clearStorageFlag: 0, //显示清空缓存的提示
})
const pageType = {
wechatLite: { title: '微信支付', value: 'wechatLite' },
alipayLite: { title: '支付宝支付', value: 'alipayLite' },
wechatH5: { title: '微信支付', value: 'wechatH5' },
alipayH5: { title: '支付宝支付', value: 'alipayH5' },
ysfpayH5: { title: '云闪付', value: 'ysfpayH5' },
otherH5: { title: '银联', value: 'otherH5' }
}
vdata.pageTypeInfo = pageType[appConfig.currentPageType]
vdata.paySelected = appConfig.currentPageType
const toRech = () => uni.navigateTo({ url: '/pageMember/memberInfo/memberInfo' })
// 获取商户信息 门店头像
const getMchInfos = () => {
$apiMembers({ method: 'mch.info' }).then(({ bizData }) => {
if (bizData.fixedFlag) {
vdata.amount = (bizData.amount / 100).toFixed(2)
}
vdata.mchInfo = bizData || {}
})
}
const payMember = () => {
if (vdata.amount <= 0) {
return uni.showToast({
title: '金额必须大于0',
icon: 'none'
})
}
// 非会员支付 直接拉起支付
if (vdata.paySelected != 'member') return pay()
if (vdata.amount > (vdata.balance / 100)) return uni.showToast({ title: '会员余额不足请前去充值', icon: 'none' })
refConfPay.value.open(vdata.amount, vdata.buyerRemark)
}
// 发起支付
function pay () {
vdata.payOrderInfo.amount = vdata.amount
uni.showLoading({
title: '请稍等...',
mask: true
})
$getPayPackage(vdata.amount, vdata.buyerRemark, vdata.mbrId || '', vdata.mbrTel || '').then(({ bizData }) => {
uni.hideLoading()
//订单创建异常
if (bizData.code != '0') {
return toErrPageFunc(bizData.msg);
}
// 订单响应结果
let orderRes = bizData.data;
if (orderRes.orderState != 1) { //订单不是支付中,说明订单异常
return toErrPageFunc(orderRes.errMsg);
}
if (orderRes.payUrl) {
location.href = orderRes.payUrl;
return false;
}
// 以下为调起 jsapi的函数 分为: H5 和 各端小程序
let thisPaywayCallFunc = paywayCallFunc()[appConfig.currentPageType];
thisPaywayCallFunc(orderRes, vdata.payOrderInfo);
}).catch(() => {
uni.hideLoading()
})
}
// 获取会员信息
const getMemberInfo = () => {
$getMemberInfo().then(({ bizData }) => {
console.log('接收页面通讯', bizData);
vdata.balance = bizData.balance
vdata.mbrName = bizData.mbrName
vdata.mbrId = bizData.mbrId
vdata.mbrTel = bizData.mbrTel
})
}
// 查询会员充值规则
const getRules = () => {
$apiMembers().then(({ bizData }) => {
console.log(bizData.records);
amountRules.push(...bizData.records)
})
}
const closePage = {
wechatH5: () => window.WeixinJSBridge.call('closeWindow'),
alipayH5: () => window.AlipayJSBridge.call('closeWebview'),
ysfpayH5: () => { window.WeixinJSBridge.call('closeWindow'); window.AlipayJSBridge.call('closeWebview') },
otherH5: () => { window.WeixinJSBridge.call('closeWindow'); window.AlipayJSBridge.call('closeWebview') }
}
// 会员支付
const confirmMemberPay = () => {
$payRemberCard(vdata.amount, vdata.buyerRemark).then(res => {
uni.showToast({ title: '支付成功' })
refConfPay.value.close()
if (appConfig.currentPageType.includes('H5')) {
// 查询是否开启点金计划 如果开启点金计划 window.open() 打开新页面
$getAdvert({ appPlace: 4 }).then(({ bizData }) => {
if (bizData && bizData.linkUrl) {
uni.reLaunch({ url: '/pages/H5/H5?url=' + bizData.linkUrl })
return false
}
return closePage[appConfig.currentPageType]()
})
return false
}
uni.navigateTo({ url: '/pages/paySuccess/paySuccess?amount=' + vdata.amount + '&member=true' })
vdata.amount = '0'
vdata.buyerRemark = ''
getMemberInfo()
})
}
// 高级功能模块的显示
function advancedFunc () {
vdata.clearStorageFlag = vdata.clearStorageFlag + 1
if (vdata.clearStorageFlag >= 10) {
vdata.clearStorageFlag = 0
// 目前仅清空缓存
uni.showModal({
title: '确认清除缓存?',
success: function (r) {
if (r.confirm) {
uni.clearStorageSync()
return uni.showToast({ title: '已清空' })
}
}
});
}
}
</script>
<style lang="scss" scoped>
.sub-title {
margin: 50rpx;
margin-bottom: 20rpx;
color: #4d4d4dff;
font-size: 25rpx;
}
.radio {
display: flex;
justify-content: center;
align-items: center;
width: 40rpx;
height: 40rpx;
border: 2rpx solid #00000026;
border-radius: 50%;
overflow: hidden;
image {
width: 16rpx;
height: 12rpx;
}
}
.radio-selected {
background-color: var(--v-primary);
}
.page-weapper {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100vh;
background-color: #fff;
border-radius: 50rpx 50rpx 0 0;
.header {
position: relative;
overflow-y: auto;
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
z-index: -1;
height: 40rpx;
background-color: var(--v-primary);
}
.mch-info {
display: flex;
align-items: center;
justify-content: space-between;
margin: 50rpx;
color: #000000ff;
font-size: 30rpx;
.mch-img-box {
border: 1rpx solid #0000000f;
image {
width: 72rpx;
height: 72rpx;
}
}
}
.pay-amount {
display: flex;
align-items: flex-end;
justify-content: space-between;
margin: 0 50rpx;
margin-bottom: 67rpx;
font-size: 50rpx;
color: var(--v-primary);
height: 110rpx;
.pay-icon {
align-self: flex-end;
color: #808080ff;
font-size: 50rpx;
vertical-align: bottom;
}
}
.pay-select {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 30rpx;
margin: 0 35rpx;
margin-top: 20rpx;
height: 100rpx;
background: #52cc701a;
border-radius: 20rpx;
.pay-info {
display: flex;
align-items: center;
image {
width: 40rpx;
height: 40rpx;
}
text {
margin-left: 20rpx;
color: #4d4d4dff;
font-size: 30rpx;
}
}
}
.surplus-wrapper {
margin: 20rpx 35rpx;
padding: 30rpx;
padding-right: 0;
border-radius: 20rpx;
background: #ffbe4c1a;
.member-top {
display: flex;
justify-content: space-between;
padding-right: 30rpx;
.member-info {
display: flex;
align-items: center;
image {
width: 40rpx;
height: 40rpx;
}
text {
margin-left: 20rpx;
color: #4d4d4dff;
font-size: 30rpx;
}
}
}
text {
color: #666;
}
.to-recharge {
display: flex;
align-items: center;
justify-content: center;
height: 50rpx;
width: 120rpx;
background-color: var(--v-primary);
color: #fff;
border-radius: 10rpx;
margin-left: 30rpx;
font-size: 26rpx;
}
.balance-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
margin-left: 60rpx;
margin-top: 30rpx;
padding-top: 15rpx;
height: 70rpx;
border-top: 1rpx solid #0000000f;
.ba-left {
color: #835511ff;
font-size: 25rpx;
font-weight: 400;
text {
color: #ff8000ff;
font-size: 25rpx;
font-weight: 500;
}
}
.ba-right {
display: flex;
align-items: center;
color: #1f7099ff;
font-size: 25rpx;
image {
margin-right: 30rpx;
width: 40rpx;
height: 40rpx;
}
}
}
}
.Prepaid {
margin-left: 60rpx;
}
.rec-info {
display: flex;
margin: 50rpx 60rpx;
font-size: 28rpx;
color: #ccc;
.info-list {
margin-left: 30rpx;
color: var(--v-primary);
.l-item {
margin-bottom: 15rpx;
}
}
}
}
.pay-remarks {
position: absolute;
top: -80rpx;
left: 50%;
transform: translateX(-50%);
color: var(--v-primary);
}
.footer-keyboard {
flex-shrink: 0;
position: relative;
}
}
.pay-wrapper {
height: 100rpx;
}
.member-pref {
display: flex;
.sub-title {
margin-top: 39rpx;
}
.pref-info {
display: flex;
margin: 28rpx 0;
font-size: 24rpx;
view {
color: #4c4c4cff;
}
text {
margin-left: 10rpx;
margin-right: 30rpx;
color: #ff624fff;
font-weight: 500;
}
}
}
.hover-but {
opacity: .5;
}
</style>