源文件
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
<template>
|
||||
<uni-popup ref="popup" type="bottom" :safe-area="false">
|
||||
<view class="sms-wrapper" :style="{ '--v-primary': calcThemeColor() }">
|
||||
<view class="s-title">绑定手机号</view>
|
||||
<view class="phone-input">
|
||||
<image src="/static/vipImg/phone.svg"></image>
|
||||
<input type="number" maxlength="11" style="background: transparent;" v-model="vdata.phoneNumber"
|
||||
placeholder="请输入手机号">
|
||||
</view>
|
||||
<view class="code-wrapper">
|
||||
<view class="code-input">
|
||||
<image src="/static/vipImg/secure-icon.svg"></image>
|
||||
<input type="number" maxlength="6" style="background: transparent;" v-model="vdata.code"
|
||||
placeholder="请输入验证码">
|
||||
</view>
|
||||
<view class="send-sms" hover-class="hover-but" hover-stay-time="200" @tap="sendSMS"
|
||||
v-if="vdata.timeNumber <= 0">
|
||||
发送短信
|
||||
</view>
|
||||
<view class="send-sms" style="color: #ff624fff;font-size: 26rpx;" v-else>{{ vdata.timeNumber }}S后可重新发送
|
||||
</view>
|
||||
</view>
|
||||
<view class="confirm-but" hover-class="hover-but" hover-stay-time="200" @tap="confirm">确认绑定</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue"
|
||||
import { $apiMembers } from "@/http/apiMember"
|
||||
// import { Base64 } from 'js-base64'
|
||||
import storageManage from '@/util/storageManage.js'
|
||||
import appConfig from "@/config/appConfig"
|
||||
import { calcThemeColor } from "@/util/member.js"
|
||||
const emits = defineEmits('success')
|
||||
const vdata = reactive({
|
||||
timeNumber: 0
|
||||
})
|
||||
const popup = ref(null)
|
||||
const open = () => popup.value.open()
|
||||
const close = () => popup.value.close()
|
||||
const sendSMS = () => {
|
||||
uni.showLoading({
|
||||
title: '请稍等',
|
||||
mask: true
|
||||
})
|
||||
validate().then(res => {
|
||||
$apiMembers({
|
||||
method: 'mbr.tel.send.sms.code',
|
||||
mbrTel: Base64.encode(vdata.phoneNumber)
|
||||
}).then(res => {
|
||||
tips('验证码发送成功')
|
||||
countDown()
|
||||
uni.hideLoading()
|
||||
})
|
||||
})
|
||||
}
|
||||
const confirm = () => {
|
||||
validate(true).then(res => {
|
||||
$apiMembers({
|
||||
method: 'mbr.tel.bind',
|
||||
mbrTel: Base64.encode(vdata.phoneNumber),
|
||||
code: Base64.encode(vdata.code),
|
||||
channelUesrId: Base64.encode(appConfig.channelUserId)
|
||||
}).then(({
|
||||
bizData
|
||||
}) => {
|
||||
storageManage.iToken(bizData)
|
||||
emits('success', bizData)
|
||||
uni.$emit('updateMemberInfos')
|
||||
tips('绑定成功')
|
||||
close()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function validate (code) {
|
||||
return new Promise((res, rej) => {
|
||||
if (!vdata.phoneNumber) return rej(tips('请输入手机号'))
|
||||
if (vdata.phoneNumber.length < 11) return rej(tips('手机号格式不正确'))
|
||||
if (code) {
|
||||
if (!vdata.code) return rej(tips('请输入验证码'))
|
||||
if (vdata.code.length < 6) return rej(tips('验证码格式不正确'))
|
||||
}
|
||||
res()
|
||||
})
|
||||
}
|
||||
|
||||
function tips (text) {
|
||||
uni.showToast({ title: text, icon: 'none', mask: true })
|
||||
}
|
||||
|
||||
function countDown () {
|
||||
vdata.timeNumber = 60
|
||||
let inter = setInterval(() => {
|
||||
vdata.timeNumber--
|
||||
if (vdata.timeNumber <= 0) {
|
||||
clearInterval(inter)
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open,
|
||||
close
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.sms-wrapper {
|
||||
margin-top: 100rpx;
|
||||
width: 100vw;
|
||||
height: 900rpx;
|
||||
min-height: 500rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 50rpx 50rpx 0 0;
|
||||
border: .1rpx solid #fff;
|
||||
box-sizing: border-box;
|
||||
padding: 50rpx;
|
||||
|
||||
.s-title {
|
||||
color: #4d4d4dff;
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.code-input,
|
||||
.phone-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 30rpx;
|
||||
margin-top: 40rpx;
|
||||
height: 110rpx;
|
||||
border-radius: 20rpx;
|
||||
background: #f7f7f7ff;
|
||||
|
||||
image {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
|
||||
input {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.phone-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
input {
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.code-input {
|
||||
justify-content: space-between;
|
||||
margin-top: 30rpx;
|
||||
|
||||
input {
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-but {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 200rpx 0 50rpx;
|
||||
height: 110rpx;
|
||||
background: linear-gradient(270deg, #ff6756ff 0%, #f99364ff 100%);
|
||||
color: #fff;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.code-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.send-sms {
|
||||
margin-left: 20rpx;
|
||||
transform: translateY(20rpx);
|
||||
color: var(--v-primary);
|
||||
font-size: 32rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.hover-but {
|
||||
opacity: .5;
|
||||
}
|
||||
</style>
|
||||
609
jeepay-ui-uapp-cashier/pageMember/memberInfo/memberInfo.vue
Normal file
609
jeepay-ui-uapp-cashier/pageMember/memberInfo/memberInfo.vue
Normal file
@@ -0,0 +1,609 @@
|
||||
<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>
|
||||
197
jeepay-ui-uapp-cashier/pageMember/memberRecord/memberRecord.vue
Normal file
197
jeepay-ui-uapp-cashier/pageMember/memberRecord/memberRecord.vue
Normal file
@@ -0,0 +1,197 @@
|
||||
<template>
|
||||
<view class="header-selected">
|
||||
<view :class="{ 'selected-style': pageData.rechargeOrConsume == 'recharge' }" @tap="headerChange('recharge')">充值记录
|
||||
</view>
|
||||
<view :class="{ 'selected-style': pageData.rechargeOrConsume == 'consume' }" @tap="headerChange('consume')">消费记录
|
||||
</view>
|
||||
</view>
|
||||
<view style="height: 110rpx;"></view>
|
||||
<!-- 充值记录 -->
|
||||
<block v-if="pageData.rechargeOrConsume == 'recharge'" v-for="(v, i) in pageData.pageDataList" :key="i">
|
||||
<view class="re-card">
|
||||
<view class="re-amount">
|
||||
<text class="unit">¥</text>
|
||||
{{ (v.entryAmount / 100).toFixed(2) }}
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="title">实付金额</view>
|
||||
<view class="desc">{{ (v.payAmount / 100).toFixed(2) }}元</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="title">赠送金额</view>
|
||||
<view class="desc">{{ (v.giveAmount / 100).toFixed(2) }}元</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="title">充值时间</view>
|
||||
<view class="desc">{{ v.createdAt }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<!-- 消费记录 -->
|
||||
<block v-if="pageData.rechargeOrConsume == 'consume'" v-for="(v, i) in pageData.pageDataList" :key="i">
|
||||
<view class="re-card">
|
||||
<view class="re-amount">
|
||||
<text class="unit">¥</text>
|
||||
{{ (Math.abs(v.changeAmount) / 100).toFixed(2) }}
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="title">消费商户</view>
|
||||
<view class="desc">{{ v.mchName }}</view>
|
||||
</view>
|
||||
<view class="item">
|
||||
<view class="title">消费时间</view>
|
||||
<view class="desc">{{ v.createdAt }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="list-null" v-if="!pageData.hasNext">暂无更多数据</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue"
|
||||
import { onReachBottom } from '@dcloudio/uni-app'
|
||||
import { $getMemberRechargeRecord, $getConsumeRecod } from "@/http/apiMember"
|
||||
const pageData = reactive({
|
||||
rechargeOrConsume: 'recharge',
|
||||
pageDataList: [],
|
||||
hasNext: true
|
||||
})
|
||||
const params = {
|
||||
pageNumber: 1,
|
||||
pageSize: 10
|
||||
}
|
||||
function getMemberRechargeRecord () {
|
||||
$getMemberRechargeRecord(params).then(({ bizData }) => {
|
||||
pageData.hasNext = bizData.hasNext
|
||||
pageData.pageDataList.push(...bizData.records)
|
||||
})
|
||||
}
|
||||
getMemberRechargeRecord()
|
||||
function getConsumeRecod () {
|
||||
params.bizType = 3
|
||||
$getConsumeRecod(params).then(({ bizData }) => {
|
||||
pageData.hasNext = bizData.hasNext
|
||||
pageData.pageDataList.push(...bizData.records)
|
||||
})
|
||||
}
|
||||
function headerChange (val) {
|
||||
pageData.rechargeOrConsume = val
|
||||
pageData.pageDataList = []
|
||||
params.pageNumber = 1
|
||||
pageData.hasNext = true
|
||||
val == 'recharge' ? getMemberRechargeRecord() : getConsumeRecod()
|
||||
}
|
||||
// 触底加载
|
||||
onReachBottom(() => {
|
||||
if (!pageData.hasNext) return
|
||||
params.pageNumber++
|
||||
pageData.rechargeOrConsume == 'recharge' ? getMemberRechargeRecord() : getConsumeRecod()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.header-selected {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
height: 110rpx;
|
||||
background-color: #fff;
|
||||
|
||||
view {
|
||||
position: relative;
|
||||
flex: 0 0 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: rgb(128, 128, 128);
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
transition: .3s ease-out;
|
||||
}
|
||||
|
||||
.selected-style {
|
||||
color: rgb(255, 95, 77);
|
||||
transition: .3s ease-out;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 36rpx;
|
||||
height: 6rpx;
|
||||
background: rgb(255, 95, 77);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.re-card {
|
||||
margin: 20rpx auto;
|
||||
padding: 0 30rpx;
|
||||
padding-bottom: 30rpx;
|
||||
box-sizing: border-box;
|
||||
width: 710rpx;
|
||||
border-radius: 10rpx;
|
||||
background-color: #fff;
|
||||
|
||||
.re-amount {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
height: 100rpx;
|
||||
border-bottom: 1rpx solid rgba(0, 0, 0, 0.06);
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
|
||||
.unit {
|
||||
font-size: 20rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
margin: 15rpx 0;
|
||||
font-size: 26rpx;
|
||||
|
||||
.title {
|
||||
margin-right: 30rpx;
|
||||
color: rgb(128, 128, 128);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-null {
|
||||
position: relative;
|
||||
|
||||
line-height: 110rpx;
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
color: #a6a6a6;
|
||||
|
||||
&::after,
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
|
||||
width: 30%;
|
||||
height: 2rpx;
|
||||
background-color: #ededed;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
&::after {
|
||||
left: 40rpx;
|
||||
}
|
||||
|
||||
&::before {
|
||||
right: 40rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<uni-popup ref="popup" type="center">
|
||||
<view class="c-wrapper" :style="{ '--v-primary': calcThemeColor() }">
|
||||
<view class="c-title">会员余额支付</view>
|
||||
<view class="c-amount">
|
||||
<text>金额</text>
|
||||
¥{{ vdata.amount }}
|
||||
</view>
|
||||
<view class="but-wrapper">
|
||||
<view class="cancel" @tap="close">取消</view>
|
||||
<view class="confirm" @tap="confirm">确认支付</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue"
|
||||
import { calcThemeColor } from "@/util/member.js"
|
||||
const vdata = reactive({})
|
||||
const popup = ref(null)
|
||||
const emits = defineEmits(['pay'])
|
||||
const open = (amount) => {
|
||||
vdata.amount = amount
|
||||
popup.value.open()
|
||||
}
|
||||
const close = () => popup.value.close()
|
||||
const confirm = () => {
|
||||
emits('pay')
|
||||
}
|
||||
defineExpose({ open, close })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.c-wrapper {
|
||||
width: 650rpx;
|
||||
height: 508rpx;
|
||||
padding: 30rpx;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.c-title {
|
||||
margin: 50rpx 0 70rpx 0;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.remarks-content {
|
||||
margin: 30rpx 0;
|
||||
}
|
||||
|
||||
.c-amount {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
color: #000000ff;
|
||||
font-size: 50rpx;
|
||||
font-weight: 500;
|
||||
|
||||
text {
|
||||
margin-bottom: 20rpx;
|
||||
color: #808080ff;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.but-wrapper {
|
||||
display: flex;
|
||||
margin-top: 50rpx;
|
||||
justify-content: space-between;
|
||||
view {
|
||||
flex: 0 0 45%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 90rpx;
|
||||
color: #fff;
|
||||
border-radius: 15rpx;
|
||||
}
|
||||
|
||||
.cancel {
|
||||
color: #808080ff;
|
||||
}
|
||||
.confirm {
|
||||
width: 350rpx;
|
||||
height: 110rpx;
|
||||
border-radius: 20rpx;
|
||||
background-color: var(--v-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,231 @@
|
||||
<template>
|
||||
<view class="key-wrapper" :style="{ '--v-primary': calcThemeColor() }">
|
||||
<view class="key-re">
|
||||
<text @tap="emits('remarks')">添加备注</text>
|
||||
<view class="openOrClose" v-if="!isFixedFlag" @tap="vdata.openOrClose = !vdata.openOrClose">
|
||||
<text>{{ vdata.openOrClose ? '收起' : '展开' }}</text>
|
||||
<image src="/static/vipImg/openOrclose-key.svg" mode="aspectFill" :class="{ 'close-key': !vdata.openOrClose }">
|
||||
</image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pay-but" hover-class="hover-pay" hover-start-time="10" hover-stay-time="60" :style="{ height: vdata.openOrClose ? '0' : '110rpx' }" v-if="!vdata.openOrClose && !isFixedFlag"
|
||||
@tap="emits('pay')">付款</view>
|
||||
<view class="key-mian"
|
||||
:style="{ maxHeight: vdata.openOrClose ? '800rpx' : '0', paddingBottom: vdata.openOrClose ? '50rpx' : '0' }"
|
||||
v-if="!isFixedFlag">
|
||||
<view class="key-left">
|
||||
<block v-for="(v, i) in keyList" :key="i">
|
||||
<view class="k-l-item flex-center" hover-class="hover-but" hover-start-time="10" hover-stay-time="60"
|
||||
:class="{ 'zero': v.val == '0' }" @tap="changeKey(v.val)"> {{ v.val }}</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="key-right">
|
||||
<view class="key-r-del flex-center" hover-class="hover-but" hover-start-time="10" hover-stay-time="60" @tap="deletedNumber">
|
||||
<image src="/static/vipImg/icon-del.svg" mode="aspectFill" class="mch-header"></image>
|
||||
</view>
|
||||
<view class="key-r-pay flex-center" hover-class="hover-pay" hover-start-time="10" hover-stay-time="60" @tap="emits('pay')">付款</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="fixed-wrapper" v-else>
|
||||
<view class="fixed-but flex-center" hover-class="hover-pay" hover-start-time="10" hover-stay-time="60" @tap="emits('pay')">确认支付</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue"
|
||||
import { calcThemeColor } from "@/util/member.js"
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
isFixedFlag: { type: Boolean, default: false }
|
||||
})
|
||||
const vdata = reactive({
|
||||
openOrClose: false
|
||||
})
|
||||
const emits = defineEmits(['update:value', 'pay', 'remarks'])
|
||||
const keyList = [
|
||||
{ val: '1', pos: 'l' },
|
||||
{ val: '2', pos: 'l' },
|
||||
{ val: '3', pos: 'l' },
|
||||
{ val: '4', pos: 'l' },
|
||||
{ val: '5', pos: 'l' },
|
||||
{ val: '6', pos: 'l' },
|
||||
{ val: '7', pos: 'l' },
|
||||
{ val: '8', pos: 'l' },
|
||||
{ val: '9', pos: 'l' },
|
||||
{ val: '0', pos: 'l' },
|
||||
{ val: '.', pos: 'l' },
|
||||
]
|
||||
const changeKey = (val) => {
|
||||
// 禁止 输入长度 大于10位
|
||||
if(props.value.length > 10) return false
|
||||
// 如果值已经是0并且按下不是小数点 直接替换值
|
||||
if (props.value.toString().length == 1 && props.value == 0 && val != '.') return emits('update:value', val)
|
||||
// 只能包含一个小数点
|
||||
if (props.value.toString().includes('.') && val == '.') return
|
||||
// 限制小数点位数
|
||||
if (props.value.toString().includes('.') && props.value.split('.')[1].length >= props.point) return
|
||||
// 长度只有 一位 并且按下结果是小数点 直接 return
|
||||
if (props.value.toString().length == 1 && props.value == 0 && val != '.') return
|
||||
// 如果 清空后直接按下小数点 直接 return
|
||||
if ((props.value === '' || props.value == undefined) && val == '.') return emits('update:value', '0' + val)
|
||||
if (props.value.includes('.') && props.value.split('.')[1].length >= 2) return
|
||||
emitsParent(val)
|
||||
}
|
||||
const deletedNumber = () => {
|
||||
emits('update:value', props.value.slice(0, props.value.length - 1))
|
||||
}
|
||||
// 错误提示
|
||||
function tips (title) {
|
||||
uni.showToast({
|
||||
title,
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
// 向父级传递消息
|
||||
function emitsParent (v) {
|
||||
return emits('update:value', props.value + v)
|
||||
}
|
||||
function openKeyBoard () {
|
||||
if (!vdata.openOrClose) return vdata.openOrClose = true
|
||||
}
|
||||
defineExpose({ openKeyBoard })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.key-re {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 40rpx;
|
||||
color: #1f7099ff;
|
||||
font-size: 25rpx;
|
||||
height: 90rpx;
|
||||
background-color: #fff;
|
||||
border-top: 1rpx solid #e6e6e6ff;
|
||||
border-bottom: 1rpx solid #e6e6e6ff;
|
||||
|
||||
.openOrClose {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
image {
|
||||
width: 50rpx;
|
||||
height: 50rpx;
|
||||
transform: rotate(180deg);
|
||||
transition: 0.3s ease-in-out;
|
||||
}
|
||||
|
||||
.close-key {
|
||||
transform: rotate(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flex-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.key-mian {
|
||||
display: flex;
|
||||
padding: 0 5rpx;
|
||||
padding-top: 10rpx;
|
||||
padding-bottom: 50rpx;
|
||||
max-height: 0;
|
||||
border-top: 1rpx solid #0000001a;
|
||||
background: #f7f7f7ff;
|
||||
color: #000000ff;
|
||||
font-size: 40rpx;
|
||||
font-weight: 500;
|
||||
transition: max-height 0.3s ease-out;
|
||||
overflow: hidden;
|
||||
|
||||
.key-left {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.k-l-item {
|
||||
margin: 8rpx;
|
||||
width: 168rpx;
|
||||
height: 90rpx;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.zero {
|
||||
width: 350rpx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.key-right {
|
||||
.key-r-del {
|
||||
margin: 5rpx;
|
||||
width: 168rpx;
|
||||
height: 90rpx;
|
||||
background-color: #fff;
|
||||
|
||||
image {
|
||||
width: 38rpx;
|
||||
height: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.key-r-pay {
|
||||
margin: 5rpx;
|
||||
margin-top: 20rpx;
|
||||
width: 168rpx;
|
||||
height: 302rpx;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
background-color: var(--v-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fixed-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-end;
|
||||
width: 100%;
|
||||
height: 200rpx;
|
||||
|
||||
.fixed-but {
|
||||
margin: 30rpx;
|
||||
margin-bottom: 70rpx;
|
||||
width: 100%;
|
||||
height: 110rpx;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
border-radius: 20rpx;
|
||||
background-color: var(--v-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.pay-but {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 15rpx auto;
|
||||
width: 719rpx;
|
||||
height: 110rpx;
|
||||
border-radius: 10rpx;
|
||||
color: #fff;
|
||||
background-color: var(--v-primary);
|
||||
transition: height 0.3s ease-in-out;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.hover-but {
|
||||
filter: brightness(80%);
|
||||
}
|
||||
.hover-pay{
|
||||
opacity: .5;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<uni-popup ref="popup" type="center">
|
||||
<view class="c-wrapper" :style="{ '--v-primary': calcThemeColor() }">
|
||||
<view class="c-title">添加支付备注</view>
|
||||
<view class="remarks-content">
|
||||
<textarea class="remarks-input" v-model="pageData.remarkText" placeholder="请输入备注信息" @input="inputChange" maxlength="120" />
|
||||
</view>
|
||||
<view class="conf-but" @tap="close">确认</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref,reactive } from "vue"
|
||||
import { calcThemeColor } from "@/util/member.js"
|
||||
const props = defineProps({
|
||||
value: ''
|
||||
})
|
||||
const emits = defineEmits(['update:value'])
|
||||
const pageData = reactive({
|
||||
remarkText: props.value
|
||||
})
|
||||
const popup = ref(null)
|
||||
const open = (amount) => {
|
||||
popup.value.open()
|
||||
}
|
||||
const close = () => popup.value.close()
|
||||
const inputChange = (e) => {
|
||||
emits('update:value', e.detail.value)
|
||||
}
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.c-wrapper {
|
||||
width: calc(100vw - 60rpx);
|
||||
padding: 30rpx;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
|
||||
.c-title {
|
||||
margin-bottom: 30rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
|
||||
.remarks-content {
|
||||
width: 100%;
|
||||
min-height: 160rpx;
|
||||
|
||||
.remarks-input {
|
||||
width: 100%;
|
||||
height: 100rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.conf-but {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0 30rpx;
|
||||
margin-top: 30rpx;
|
||||
height: 90rpx;
|
||||
background-color: var(--v-primary);
|
||||
border-radius: 15rpx;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
527
jeepay-ui-uapp-cashier/pageMember/payMember/payMember.vue
Normal file
527
jeepay-ui-uapp-cashier/pageMember/payMember/payMember.vue
Normal file
@@ -0,0 +1,527 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user