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

609 lines
17 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-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>