609 lines
17 KiB
Vue
609 lines
17 KiB
Vue
<template>
|
||
<view class="page-wrapper">
|
||
<view class="re-header" :style="{ '--v-primary': calcThemeColor() }">
|
||
<view class="re-h-main" :class="{ 'no-member-mian': !vdata.isMemebr }">
|
||
<image src="/static/vipImg/member-bg.svg" mode="aspectFill" class="img-bg" />
|
||
<view class="user-info">
|
||
<view class="user-photo">
|
||
<image class="vip-header" src="/static/vipImg/header-top.svg" v-if="vdata.mbrName"
|
||
mode="scaleToFill" />
|
||
<image class="no-vip" :src="vdata.avatarUrl ? vdata.avatarUrl : '/static/vipImg/no-vip.svg'"
|
||
mode="scaleToFill" />
|
||
</view>
|
||
<view class="user-wrapper" :class="{ 'user-wrapper-no-momber': !vdata.isMemebr }">
|
||
<view class="user-name" v-if="vdata.isMemebr">{{ vdata.mbrName || '会员名称' }}</view>
|
||
<view class="user-phone" v-if="vdata.isMemebr">{{ vdata.mbrTel }}</view>
|
||
<view v-if="!vdata.isMemebr">未注册</view>
|
||
<view class="reg-phone" v-if="!vdata.isMemebr" hover-class="hover-but" hover-stay-time="200"
|
||
@tap="refBindPhone.open()">
|
||
手机号注册
|
||
<image src="/static/vipImg/arrow-white.svg" mode="scaleToFill" />
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="bin-info" v-if="vdata.isMemebr">
|
||
<view class="bind-stat">{{ parseFloat((vdata.balance / 100).toFixed(2)) }}</view>
|
||
<view class="bind-info">我的余额(元)</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 充值消费记录 -->
|
||
<view class="re-con" @tap="toRecord">
|
||
<view class="left">
|
||
<image src="/static/img/note-icon.svg" style="width: 40rpx; height: 40rpx;"></image>
|
||
<text>查看充值/消费记录</text>
|
||
</view>
|
||
<view class="right">
|
||
<image src="/static/vipImg/arrow-black.svg" style="width: 40rpx; height: 40rpx;"></image>
|
||
</view>
|
||
</view>
|
||
<view class="sub-title">充值优惠(元)</view>
|
||
<view class="re-rule-wrapper">
|
||
|
||
<block v-for=" v in amountRules " :key="v.ruleId">
|
||
<view class="re-r-item" :class="{ 'pay-amount-selected': vdata.selectedId == v.ruleId }"
|
||
@tap="calcAmount(v.ruleId)">
|
||
<image src="/static/vipImg/selected-re-icon.svg" mode="aspectFill"
|
||
v-if="vdata.selectedId == v.ruleId" />
|
||
<view class="ite-top">
|
||
<text class="pay-icon">¥</text>{{ parseFloat((v.rechargeAmount / 100).toFixed(2)) }}
|
||
</view>
|
||
<view class="ite-bot">
|
||
<text class="icon-give flex-center">赠</text>
|
||
<text class="pay-amount">¥{{ parseFloat((v.giveAmount / 100).toFixed(2)) }}</text>
|
||
</view>
|
||
</view>
|
||
</block>
|
||
|
||
<view class="re-r-item re-r-custom" :class="{ 'pay-amount-selected': vdata.selectedId == 'custom' }"
|
||
v-if="vdata.memberCustomAmountState == 1" @tap="calcAmount('custom')">
|
||
<image src="/static/vipImg/selected-re-icon.svg" mode="aspectFill" v-if="vdata.selectedId == 'custom'" />
|
||
<view class="ite-top ite-top-custom-title">
|
||
自定义
|
||
</view>
|
||
<view class="ite-bot ite-bot-input">
|
||
<input type="digit" placeholder="请输入自定充值义金额" v-model="vdata.rechargeAmount"
|
||
placeholder-style="color:#00000059" style="background: transparent;"
|
||
@input="() => vdata.entryAmount = vdata.rechargeAmount">
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
<view class="re-confirm-but" v-if="vdata.isMemebr">
|
||
<view class="real-amount">实际到账:<text>¥{{ vdata.entryAmount }}</text></view>
|
||
<view class="confirm" hover-class="hover-but" hover-stay-time="200" @tap="confirm">确认充值</view>
|
||
</view>
|
||
<view class="line"></view>
|
||
<view class="sub-title">适用门店</view>
|
||
<view class="store-wrapper">
|
||
<block v-for="(v, i) in storeList " :key="i">
|
||
<view class="store-item">{{ v.storeName }}</view>
|
||
</block>
|
||
</view>
|
||
</view>
|
||
<BindPhone ref="refBindPhone" @success="getMemberInfo" />
|
||
</template>
|
||
<script setup>
|
||
import { onLoad, onPullDownRefresh, onUnload } from '@dcloudio/uni-app'
|
||
import { ref, reactive } from "vue"
|
||
import { $apiMembers, $getMemberInfo, $recharge } from "@/http/apiMember"
|
||
import BindPhone from "./components/BindPhone.vue"
|
||
import paywayCallFunc from '@/pages/payway/payway.js'
|
||
import appConfig from "@/config/appConfig"
|
||
import { calcThemeColor } from "@/util/member.js"
|
||
import storageManage from '@/util/storageManage.js'
|
||
// import { Base64 } from 'js-base64'
|
||
|
||
onLoad(() => {
|
||
uni.setNavigationBarColor({
|
||
frontColor: '#ffffff',
|
||
backgroundColor: '#212327'
|
||
})
|
||
|
||
// 查询是否注册会员
|
||
$apiMembers({ method: 'mbr.info', channelUesrId: Base64.encode(appConfig.channelUserId) }).then(({ bizData }) => {
|
||
if (bizData) {
|
||
storageManage.iToken(bizData)
|
||
getMemberInfo() //存储token 查询会员信息
|
||
vdata.isMemebr = true
|
||
} else {
|
||
vdata.isMemebr = false
|
||
}
|
||
})
|
||
getRules()
|
||
})
|
||
|
||
const vdata = reactive({
|
||
rechargeAmount: '',
|
||
entryAmount: ''
|
||
})
|
||
const amountRules = reactive([])
|
||
const storeList = reactive([])
|
||
const refBindPhone = ref(null)
|
||
const refInput = ref(null)
|
||
const openPopup = () => {
|
||
refBindPhone.value.open()
|
||
}
|
||
|
||
// 获取会员信息
|
||
const getMemberInfo = () => {
|
||
$getMemberInfo().then(({ bizData }) => {
|
||
Object.assign(vdata, bizData)
|
||
vdata.isMemebr = true
|
||
getRules()
|
||
}).catch(er => {
|
||
uni.stopPullDownRefresh()
|
||
})
|
||
}
|
||
// 查询会员充值规则
|
||
const getRules = () => {
|
||
$apiMembers().then(({ bizData }) => {
|
||
getStore()
|
||
vdata.memberCustomAmountState = bizData.memberCustomAmountState
|
||
Object.assign(amountRules, bizData.records)
|
||
if (bizData.length > 0) calcAmount(bizData[0].ruleId)
|
||
|
||
}).catch(er => {
|
||
uni.stopPullDownRefresh()
|
||
})
|
||
}
|
||
const calcAmount = (id) => {
|
||
if (id == 'custom') {
|
||
vdata.selectedId = id
|
||
vdata.rechargeAmount = ''
|
||
vdata.entryAmount = ''
|
||
return
|
||
}
|
||
|
||
vdata.selectedId = id
|
||
const data = amountRules.find(v => v.ruleId == id)
|
||
vdata.entryAmount = ((data.giveAmount + data.rechargeAmount) / 100).toFixed(2)
|
||
vdata.rechargeAmount = ''
|
||
}
|
||
// 手机号注册弹窗
|
||
const bindPhoneOpen = () => {
|
||
refBindPhone.value.open()
|
||
}
|
||
const REG_AMOUNT = /^([0-9]{1}|^[1-9]{1}\d{1,15})(\.\d{1,2})?$/
|
||
|
||
// 确认充值
|
||
const confirm = () => {
|
||
// 请求参数
|
||
let reqParams = {}
|
||
|
||
// 判断 是自定义 还 会员规则 充值
|
||
if (vdata.selectedId == 'custom') {
|
||
if (vdata.rechargeAmount <= 0) {
|
||
return uni.showToast({ title: '充值金额应大于0', icon: 'none' })
|
||
}
|
||
|
||
reqParams.rechargeAmount = vdata.rechargeAmount
|
||
if (!REG_AMOUNT.test(reqParams.rechargeAmount)) {
|
||
return uni.showToast({ title: '充值金额错误 请输入正确金额', icon: 'none' })
|
||
}
|
||
} else {
|
||
reqParams.rechargeRuleId = vdata.selectedId
|
||
if (!reqParams.rechargeRuleId) {
|
||
return uni.showToast({ title: '请选择充值金额', icon: 'none' })
|
||
}
|
||
}
|
||
|
||
$recharge(reqParams).then(({ bizData }) => {
|
||
if (bizData.orderState != 1) { //订单不是支付中,说明订单异常
|
||
return toErrPageFunc(bizData.errMsg);
|
||
}
|
||
if (bizData.payUrl) {
|
||
location.href = bizData.payUrl;
|
||
return false;
|
||
}
|
||
if (['alipayH5', 'alipayLite'].includes(appConfig.currentPageType)) {
|
||
bizData = JSON.parse(bizData.payData)
|
||
} else {
|
||
bizData.payInfo = bizData.payData
|
||
}
|
||
|
||
// 以下为调起 jsapi的函数: 分为: H5 和 各端小程序
|
||
let thisPaywayCallFunc = paywayCallFunc()[appConfig.currentPageType];
|
||
thisPaywayCallFunc(bizData, { amount: bizData.payAmount, fun: paySuccess })
|
||
})
|
||
}
|
||
|
||
// 支付成功回调函数
|
||
function paySuccess () {
|
||
uni.$emit('updateMemberInfos')
|
||
uni.navigateBack()
|
||
}
|
||
|
||
// 获取适用的门店
|
||
const getStore = () => {
|
||
$apiMembers({
|
||
method: 'mch.mbr.recharge.rule.store'
|
||
}).then(({
|
||
bizData
|
||
}) => {
|
||
Object.assign(storeList, bizData)
|
||
uni.stopPullDownRefresh()
|
||
}).catch(er => {
|
||
uni.stopPullDownRefresh()
|
||
})
|
||
}
|
||
const toRecord = () => {
|
||
uni.navigateTo({
|
||
url: '/pageMember/memberRecord/memberRecord'
|
||
})
|
||
}
|
||
onPullDownRefresh(() => {
|
||
getMemberInfo()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.flex-center {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.page-wrapper {
|
||
min-height: 100vh;
|
||
background-color: #fff;
|
||
|
||
.sub-title {
|
||
margin: 50rpx;
|
||
margin-bottom: 0;
|
||
color: #4d4d4dff;
|
||
font-size: 30rpx;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.re-header {
|
||
padding: .1rpx;
|
||
padding-bottom: 0;
|
||
padding-top: 50rpx;
|
||
box-sizing: border-box;
|
||
background-color: #212327;
|
||
|
||
.re-h-main {
|
||
padding: .1rpx;
|
||
position: relative;
|
||
z-index: 10;
|
||
margin: 0 50rpx;
|
||
border-radius: 32rpx 32rpx 0 0;
|
||
overflow: hidden;
|
||
background: linear-gradient(90deg, #fff7ccff 0%, #ffbe4dff 100%);
|
||
|
||
.img-bg {
|
||
position: absolute;
|
||
left: 0;
|
||
top: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
z-index: 1;
|
||
}
|
||
|
||
.user-info {
|
||
display: flex;
|
||
align-items: center;
|
||
margin: 30rpx;
|
||
padding-bottom: 30rpx;
|
||
border-bottom: 1rpx solid #0000000f;
|
||
|
||
.user-name {
|
||
color: #694e2cff;
|
||
font-size: 30rpx;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.user-phone {
|
||
margin-top: 6rpx;
|
||
color: #997a3dff;
|
||
font-size: 25rpx;
|
||
}
|
||
|
||
.user-photo {
|
||
position: relative;
|
||
margin-right: 30rpx;
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
border-radius: 50%;
|
||
background-color: #ccc;
|
||
|
||
image {
|
||
border-radius: 50%;
|
||
}
|
||
|
||
.vip-header {
|
||
position: absolute;
|
||
top: -50rpx;
|
||
left: 50%;
|
||
transform: translateX(-50%);
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
}
|
||
|
||
.no-vip {
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
.bin-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.bind-stat {
|
||
text-align: center;
|
||
color: #212327ff;
|
||
font-size: 60rpx;
|
||
font-weight: 500;
|
||
|
||
}
|
||
|
||
.bind-info {
|
||
margin-top: 10rpx;
|
||
margin-bottom: 30rpx;
|
||
color: #997a3dff;
|
||
font-size: 23rpx
|
||
}
|
||
|
||
.to-recharge {
|
||
font-size: 26rpx;
|
||
border: 2rpx solid #999;
|
||
padding: 8rpx 20rpx;
|
||
color: #313133;
|
||
border-radius: 10rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.bind-phone {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
font-size: 28rpx;
|
||
margin: 0 30rpx;
|
||
margin-top: 100rpx;
|
||
padding: 30rpx 0;
|
||
border-bottom: 1rpx solid #ccc;
|
||
|
||
image {
|
||
margin-right: 10rpx;
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
}
|
||
|
||
.bind-left {
|
||
display: flex;
|
||
align-items: center;
|
||
color: #666;
|
||
}
|
||
|
||
.bind-right {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
width: 160rpx;
|
||
height: 60rpx;
|
||
border: 5rpx solid var(--v-primary);
|
||
color: var(--v-primary);
|
||
font-weight: 600;
|
||
border-radius: 10rpx;
|
||
}
|
||
}
|
||
|
||
.re-rule-wrapper {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
padding: 10rpx;
|
||
|
||
.re-r-item {
|
||
margin: 15rpx;
|
||
padding: 20rpx;
|
||
min-width: 216rpx;
|
||
height: 163rpx;
|
||
box-sizing: border-box;
|
||
background: linear-gradient(270deg, rgb(255, 94, 77, 0.1) 0%, rgb(255, 153, 102, 0.1) 100%);
|
||
border-radius: 26rpx;
|
||
|
||
.ite-top {
|
||
margin-bottom: 10rpx;
|
||
color: #ff624fff;
|
||
font-size: 40rpx;
|
||
font-weight: 500;
|
||
|
||
.pay-icon {
|
||
color: #ff624fff;
|
||
font-size: 25rpx;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
|
||
.ite-bot {
|
||
display: flex;
|
||
align-items: center;
|
||
min-width: 176rpx;
|
||
height: 60rpx;
|
||
color: #fff;
|
||
border-radius: 12rpx;
|
||
font-size: 24rpx;
|
||
background: linear-gradient(270deg, rgb(255, 103, 86) 0%, rgb(249, 147, 100) 100%);
|
||
|
||
.icon-give {
|
||
flex-shrink: 0;
|
||
margin-right: 10rpx;
|
||
width: 60rpx;
|
||
height: 60rpx;
|
||
border-radius: 12rpx;
|
||
background: #ffffff26;
|
||
}
|
||
|
||
.pay-amount {
|
||
margin-right: 15rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.re-r-custom {
|
||
width: 453rpx;
|
||
|
||
.ite-top-custom-title {
|
||
margin-bottom: 20rpx;
|
||
font-size: 25rpx;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.ite-bot-input {
|
||
padding-top: 15rpx;
|
||
width: 100%;
|
||
border-top: 1rpx solid rgba(0, 0, 0, 0.06);
|
||
background: transparent;
|
||
color: #FF624F;
|
||
font-size: 24rpx;
|
||
font-weight: 400;
|
||
|
||
input {
|
||
width: 100%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
.re-confirm-but {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
color: #fff;
|
||
margin: 30rpx;
|
||
height: 110rpx;
|
||
background: #212327ff;
|
||
border-radius: 20rpx;
|
||
|
||
|
||
.real-amount {
|
||
margin-left: 30rpx;
|
||
color: #ffffffff;
|
||
font-size: 25rpx;
|
||
|
||
text {
|
||
color: #FFC766;
|
||
}
|
||
}
|
||
|
||
.confirm {
|
||
width: 260rpx;
|
||
height: 100%;
|
||
background: linear-gradient(270deg, #ff6756ff 0%, #f99364ff 100%);
|
||
border-radius: 20rpx;
|
||
text-align: center;
|
||
line-height: 110rpx;
|
||
}
|
||
}
|
||
|
||
.line {
|
||
margin: 50rpx 30rpx;
|
||
height: 1rpx;
|
||
background: #f2f2f2ff;
|
||
}
|
||
|
||
.store-wrapper {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
padding: 10rpx;
|
||
|
||
.store-item {
|
||
margin: 20rpx;
|
||
padding: 10rpx 30rpx;
|
||
background: #f7f7f7ff;
|
||
border-radius: 12rpx;
|
||
color: #212327ff;
|
||
font-size: 24rpx;
|
||
}
|
||
}
|
||
|
||
.reg-phone {
|
||
position: relative;
|
||
z-index: 10;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
width: 250rpx;
|
||
height: 90rpx;
|
||
border-radius: 12rpx;
|
||
background: linear-gradient(270deg, #ff6756ff 0%, #f99364ff 100%);
|
||
color: #fff;
|
||
|
||
image {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
}
|
||
}
|
||
|
||
// 选中后的样式
|
||
.pay-amount-selected {
|
||
position: relative;
|
||
padding: 15rpx !important;
|
||
border: 5rpx solid #FF5F4D;
|
||
border-radius: 26rpx 5rpx 26rpx 26rpx;
|
||
|
||
image {
|
||
position: absolute;
|
||
top: -5rpx;
|
||
right: -5rpx;
|
||
z-index: 10;
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
}
|
||
}
|
||
|
||
// 充值消费记录
|
||
.re-con {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin: 0 auto;
|
||
width: 690rpx;
|
||
height: 110rpx;
|
||
border-bottom: 1rpx solid rgba(0, 0, 0, 0.06);
|
||
background: rgb(255, 255, 255);
|
||
|
||
.left {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
image {
|
||
margin-right: 10rpx;
|
||
}
|
||
|
||
text {
|
||
color: rgb(51, 51, 51);
|
||
font-size: 30rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 非会员 样式
|
||
.user-wrapper-no-momber {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
width: 100%;
|
||
}
|
||
|
||
.no-member-mian {
|
||
height: 150rpx;
|
||
}
|
||
|
||
.hover-but {
|
||
opacity: 0.5 !important;
|
||
}
|
||
</style> |