会员中心页面修改,余额明细调整,开通会员页面调整

This commit is contained in:
2025-09-25 20:27:54 +08:00
parent 84f782afa1
commit a39c9f4d72
36 changed files with 2818 additions and 427 deletions

578
user/vip/buy-vip.vue Normal file
View File

@@ -0,0 +1,578 @@
<template>
<view>
<up-navbar bg-color="transparent" title="会员中心" @leftClick="back"></up-navbar>
<view class="top" style=" background-image: url(/static/czzx_header_bg.png);">
<view>
<view class="u-flex">
<up-avatar size="136rpx" shape="square" round="20rpx" :src="shopInfo.coverImg"></up-avatar>
<view class="u-p-l-20">
<view class="shop-name u-line-1">{{shopInfo.shopName||'店铺名称' }}</view>
<view class="no-buy">暂未开通</view>
</view>
</view>
</view>
</view>
<view class="box">
<view class="vip-quanyi">
<template v-if="state.openType=='CONDITION'">
<view class="font-700 color-000 color-000 u-m-t-8">
如何成为会员
</view>
<view class="u-flex u-m-t-20 u-flex-between" v-for="(item,index) in conditionList" :key="index">
<text class="color-000">{{item.title}}</text>
<view class="finish-btn" :class="item.isFinsh?'active':''">
{{item.isFinsh?'已完成':'未完成'}}
</view>
</view>
<view class="u-flex u-flex-between u-m-t-48">
<text class="color-000 font-14 font-700">会员专属权益</text>
<view class="u-flex">
<text class="color-666 u-m-r-4 font-12">会员说明</text>
<up-icon name="question-circle" size="12" @click="modelShow"></up-icon>
</view>
</view>
<view class="u-m-t-32">
<view class="menus menus-tiaojian">
<view class="item " v-for="(item,index) in tiaojian_menus" :key="index">
<view class="u-flex u-flex-x-center u-m-t-4">
<image :src="item.icon" mode="" style="width: 100rpx;height: 100rpx;"></image>
</view>
<view class="font-14 color-333 text-center u-m-t-4 u-flex u-flex-center">
<text class="no-wrap u-m-r-4">{{item.name}}</text>
<up-icon @click="modelShow(item.name)" size="12" name="question-circle" color="#333"
v-if="showQuestion(index,tiaojian_menus)"></up-icon>
</view>
<view class="font-12 color-666 text-center">{{item.desc}}</view>
</view>
</view>
</view>
</template>
<template v-else>
<view class="vip-list">
<view v-for="(item,index) in configList" :key="index" class="vip-list-item"
@click="vipSel=index" :class="{active:vipSel==index}">
<view class="font-16 color-333">{{item.name}}</view>
<view class="u-m-t-16 color-333">
<text class="font-14"></text>
<text style="font-size: 48rpx;">{{item.price}}</text>
</view>
<view class="color-999 font-14 line-through text-center" v-if="item.origin_price">
<text></text>
<text>{{item.origin_price}}</text>
</view>
</view>
</view>
<view class="u-flex u-flex-between u-m-t-48">
<text class="color-000 font-14 font-700">会员专属权益</text>
<view class="u-flex">
<text class="color-666 u-m-r-4 font-12">会员说明</text>
<up-icon name="question-circle" size="12" @click="modelShow('会员说明')"></up-icon>
</view>
</view>
<view class="u-m-t-32">
<view class="menus menus-pays">
<view class="item " v-for="(item,index) in pay_menus" :key="index">
<view class="u-flex u-flex-x-center u-m-t-4">
<image :src="item.icon" mode="" style="width: 100rpx;height: 100rpx;"></image>
</view>
<view class="font-14 color-333 text-center u-m-t-4 u-flex u-flex-center">
<text class="no-wrap u-m-r-4">{{item.name}}</text>
<up-icon @click="modelShow(item.name)" size="12" name="question-circle" color="#333"
v-if="showQuestion(index,pay_menus)&& memberLevel"></up-icon>
</view>
<view class="font-12 color-666 text-center" v-if="item.name=='赠送成长值'">
{{'赠送'+returnReward+'成长值'}}
</view>
<view class="font-12 color-666 text-center"
v-else-if="item.name=='优惠券'&&returCouponList.length">
{{'赠送'+returCouponList.length+'张优惠券'}}
</view>
<view class="font-12 color-666 text-center" v-else-if="item.name=='会员折扣'&&memberLevel">
全店折扣{{memberLevel.discount}}
</view>
<view class="font-12 color-666 text-center" v-else>{{item.desc}}</view>
</view>
</view>
</view>
<button class="buy-btn" @click="buy">立即开通</button>
</template>
</view>
</view>
<up-popup :show="model.show" mode="center" round="16rpx" close-on-click-overlay @close="model.show=false">
<view class="model-box">
<view class="u-flex u-flex-between">
<text class="color-000 font-700 font-16">{{model.title}}</text>
<up-icon name="close-circle" color="#666" size="28rpx" @click="modelHide"></up-icon>
</view>
<view class="u-m-t-18 up-content">
<up-parse :content="modelContent"></up-parse>
</view>
</view>
</up-popup>
<up-popup :show="model.show1" mode="bottom" round="16rpx" close-on-click-overlay @close="model.show1=false">
<view class="model-box">
<view class="u-flex u-flex-between">
<text class="color-000 font-700 font-16">{{model.title}}</text>
<up-icon name="close-circle" color="#666" size="28rpx" @click="modelHide"></up-icon>
</view>
<view class="u-m-t-18 up-content">
<up-parse :content="modelContent"></up-parse>
</view>
</view>
</up-popup>
<registermember :memberOpen="memberOpen" :shopUserInfo="shopInfo" @emitsmemberOpen="emitsmemberOpen">
</registermember>
</view>
</template>
<script setup>
import {
ref,
reactive,
computed
} from "vue"
import {
joinMember
} from '@/common/api/order/index.js'
import * as vipApi from '@/common/api/market/vip.js'
import {
APIusershopInfodetail
} from '@/common/api/member.js'
import {
onLoad
} from '@dcloudio/uni-app'
import registermember from '@/user/components/registermember.vue'
const model = reactive({
show: false,
show1: false,
title: ''
})
const memberOpen=ref(false)
function modelHide() {
model.show = false;
}
function modelShow(name) {
if (name == '消费送积分') {
model.title = '消费送积分'
modelContent.value = `每消耗1元赠送${memberLevel.value.costRewardPoints}积分`
}
if (name == '周期福利') {
model.title = '周期福利'
modelContent.value =
`${memberLevel.value.cycleUnit}赠送${memberLevel.value.cycleRewardPoints}积分,${memberLevel.value.cycleRewardCouponList.length}张优惠券`
}
if (name == '会员说明') {
model.title = '会员说明'
modelContent.value = state.remark
}
model.show = true;
}
const modelContent = ref(`
1、可适用门店全部门店<br>
2、可适用商品部分商品<br>
3、可使用类型堂食<br>
4、可用时间段全时段可用<br>
5、限量规则每人限领3张每日可最多使用3张<br>
6、同享规则与限时折扣同享、与会员价同享<br>
7、其它说明这里是后台配置内容
`)
const state = reactive({
openType: 'CONDITION'
})
const pay_menus = ref([{
name: '赠送成长值',
desc: '赠送成长值',
icon: '/user/static/buy-vip/Frame_220.png',
},
{
name: '优惠券',
desc: '每月赠送2张优惠券',
icon: '/user/static/buy-vip/Frame_221.png'
},
{
name: '享会员价',
desc: '全店会员价',
icon: '/user/static/buy-vip/Frame_222.png'
},
{
name: '会员折扣',
desc: '全店折扣98折',
icon: '/user/static/buy-vip/Frame_223.png'
},
{
name: '消费送积分',
desc: '',
icon: '/user/static/buy-vip/Frame_224.png'
},
{
name: '周期福利',
desc: '',
icon: '/user/static/buy-vip/Frame_225.png'
}
])
const tiaojian_menus = [{
name: '享会员价',
desc: '全店会员价',
icon: '/user/static/buy-vip/Frame_222.png'
},
{
name: '会员折扣',
desc: '全店折扣98折',
icon: '/user/static/buy-vip/Frame_223.png'
},
{
name: '消费送积分',
desc: '',
icon: '/user/static/buy-vip/Frame_224.png'
},
{
name: '周期福利',
desc: '',
icon: '/user/static/buy-vip/Frame_225.png'
}
]
function showQuestion(index, arr) {
const len = arr.length
if (index >= len - 2) {
return true
}
return false
}
function back() {
uni.navigateBack()
}
const configList = ref([])
const vipSel = ref(0)
const conditionList = ref([])
const conditionListMap = {
'BIND_PHONE': '绑定手机号',
'ORDER': '完成消费',
'COST_AMOUNT': '消费达到指定金额',
'RECHARGE_AMOUNT': '充值达到指定金额',
}
const memberLevel = ref(null)
const shopInfo = reactive({})
async function init(shopId) {
const shopRes = await APIusershopInfodetail({
shopId
})
if (shopRes) {
Object.assign(shopInfo, shopRes.shopInfo)
}
const res = await vipApi.config({
shopId: shopId
})
if (res) {
if(res.memberConfig.isSubmitInfo){
memberOpen.value=true;
}
conditionList.value = res.memberConfig.conditionList.map(v => {
const json = {
...v,
isFinsh: res.conditionMap[v.code],
title: conditionListMap[v.code],
}
if (v.code == 'ORDER') {
json.title = json.title + v.value + '次'
}
if (v.code == 'COST_AMOUNT' || v.code == 'RECHARGE_AMOUNT') {
json.title = json.title + v.value + '元'
}
return json
})
configList.value = res.memberConfig.configList
Object.assign(state, res.memberConfig)
memberLevel.value = res.memberLevel
}
}
const returnReward = computed(() => {
const item = configList.value[vipSel.value]
if (item) {
return item.reward
}
return ''
})
const returCouponList = computed(() => {
const item = configList.value[vipSel.value]
if (item.couponList) {
return item.couponList
}
return []
})
const option = reactive({
shopId: ''
})
onLoad((opt) => {
Object.assign(option, opt)
console.log(option);
let shopId = uni.cache.get('shopId')
if (opt.shopId) {
shopId = opt.shopId
}
if (shopId) {
option.shopId = shopId
}
init(shopId)
})
let userInfo = {}
function emitsmemberOpen(e){
memberOpen.value=false
userInfo=e
}
async function buy() {
const json = {
shopId: option.shopId,
name: configList.value[vipSel.value].name,
num: 1,
}
if (state.isSubmitInfo) {
json.sex = userInfo.sex ;
json.birthDay = userInfo.birthDay;
json.nickName = userInfo.nickName
}
const res = await joinMember(json)
}
</script>
<style>
page {
background: #F9F9F9;
}
</style>
<style lang="scss" scoped>
.finish-btn {
padding: 2rpx 28rpx;
border-radius: 40rpx;
font-size: 14px;
border: 2rpx solid #D9D9D9;
padding: 4rpx 28rpx;
&.active {
border: 2rpx solid #FF6300;
color: #FF6300;
}
}
.box {
background-color: rgba(255, 255, 255, .3);
}
.font-700 {
font-weight: 700;
}
.color-one {
color: #558ABF;
}
.color-2 {
color: #273d7a;
}
.top {
background: linear-gradient(283deg, #A9CBF8 11.62%, #E5E7EB 74.58%);
}
.top {
padding: 208rpx 30rpx 78rpx 30rpx;
background-size: cover;
box-sizing: border-box;
height: 530rpx;
.shop-name {
color: #5E3110;
font-size: 16px;
font-weight: 700;
}
.no-buy {
margin-top: 12rpx;
padding: 8rpx 22rpx;
border-radius: 50rpx;
background-color: #F8F8F8;
font-size: 14px;
color: #999;
text-align: center;
}
}
.vip-box {
position: relative;
border-radius: 12px;
overflow: hidden;
padding-left: 6px;
padding-right: 64rpx;
padding-bottom: 24rpx;
.icon {
position: absolute;
right: 42rpx;
top: 0;
.huangguan {
width: 214rpx;
height: 206rpx;
}
}
.tag {
position: absolute;
top: 0;
font-size: 12px;
color: #46739F;
padding: 2px 12px;
background: #c7d0da;
border-radius: 0 0 12px 0;
}
.lv {
color: #273d7a;
font-weight: 700;
font-size: 64rpx;
letter-spacing: 4rpx;
transform: skewX(-10deg);
}
.time {
color: #6988ab;
font-size: 24rpx;
font-weight: 400;
}
.rule {
.exp {}
.desc {
color: #273d7a;
font-size: 24rpx;
font-weight: 400;
}
}
.next-tips {
color: #6988ab;
font-size: 24rpx;
font-weight: 400;
}
}
.progress {
margin-top: 8rpx;
background-color: #BDD5E9;
height: 10rpx;
border-radius: 10rpx;
.block {
height: 100%;
border-radius: 10rpx;
background: linear-gradient(90deg, #F9FBFA 0.03%, #334783 115.59%);
}
}
.vip-quanyi {
padding: 44rpx 28rpx 42rpx 28rpx;
border-radius: 40rpx 40rpx 0 0;
transform: translateY(-140rpx);
background-color: rgba(255, 255, 255, .3);
}
.menus-pays {
display: grid;
/* 每行显示3列每列宽度相等 */
grid-template-columns: repeat(3, 1fr);
/* 列间距 */
column-gap: 10px;
/* 行间距 */
row-gap: 32rpx;
/* 可以添加容器的内边距 */
}
.menus-tiaojian {
display: grid;
/* 每行显示3列每列宽度相等 */
grid-template-columns: repeat(4, 1fr);
/* 列间距 */
column-gap: 10px;
/* 行间距 */
row-gap: 10px;
/* 可以添加容器的内边距 */
}
.model-box {
padding: 32rpx 56rpx;
width: 702rpx;
}
.up-content {
color: #999;
font-size: 12px;
}
.vip-list {
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 36rpx;
.vip-list-item {
border: 4rpx solid #D9D9D9;
border-radius: 40rpx;
overflow: hidden;
transition: all .3s ease-in-out;
background-color: #fff;
padding: 42rpx 34rpx;
&.active {
border: 4rpx solid #FF6300;
background-image: linear-gradient(180deg, #FFC29A -26.17%, #FFF 64.06%);
}
}
}
.buy-btn {
margin-top: 98rpx;
padding: 32rpx 32rpx;
color: #fff;
font-size: 16px;
font-weight: 700;
border-radius: 80rpx;
line-height: 1;
background: linear-gradient(98deg, #fe6d1100 40.64%, #FFD1B4 105.2%), linear-gradient(259deg, #FE6D11 50.14%, #FFD1B4 114.93%);
box-shadow: 0 14rpx 30.4rpx 0 #fe8b435e;
}
</style>

View File

@@ -2,9 +2,9 @@
<view>
<up-navbar bg-color="transparent" title="会员中心" @leftClick="back"></up-navbar>
<view class="top">
<view class="vip-box">
<view class="vip-box" style=" background-image: url(/user/static/Rectangle_25.png);">
<view class="icon">
<image src="/user/images/image_21.png" class="huangguan" mode=""></image>
<image src="/user/static/image_21.png" class="huangguan" mode=""></image>
</view>
<view class="tag">当前等级</view>
<view class="shop-name">店铺名称</view>
@@ -34,10 +34,10 @@
<up-icon name="question-circle" size="12" @click="modelShow"></up-icon>
</view>
</view>
<view class="">
<view class="u-m-t-32">
<view class="menus" :class="state.pay_types=='tiaojian'?'menus-tiaojian' :'menus-pays'">
<view class="item u-m-t-32" v-for="(item,index) in menus" :key="index">
<view class="u-flex u-flex-x-center u-m-t-4">
<view class="item " v-for="(item,index) in menus" :key="index">
<view class="u-flex u-flex-x-center u-m-t-4 u-flex-center">
<image :src="item.icon" mode="" style="width: 100rpx;height: 100rpx;"></image>
</view>
<view class="font-14 color-333 text-center u-m-t-4 u-flex">
@@ -108,54 +108,54 @@
const pay_menus = [{
name: '赠送成长值',
desc: '赠送10000成长值',
icon: '/user/images/Frame_220.png',
icon: '/user/static/Frame_220.png',
},
{
name: '优惠券',
desc: '每月赠送2张优惠券',
icon: '/user/images/Frame_221.png'
icon: '/user/static/Frame_221.png'
},
{
name: '享会员价',
desc: '全店会员价',
icon: '/user/images/Frame_222.png'
icon: '/user/static/Frame_222.png'
},
{
name: '会员折扣',
desc: '全店折扣98折',
icon: '/user/images/Frame_223.png'
icon: '/user/static/Frame_223.png'
},
{
name: '消费送积分',
desc: '',
icon: '/user/images/Frame_224.png'
icon: '/user/static/Frame_224.png'
},
{
name: '周期福利',
desc: '',
icon: '/user/images/Frame_225.png'
icon: '/user/static/Frame_225.png'
}
]
const tiaojian_menus = [{
name: '享会员价',
desc: '全店会员价',
icon: '/user/images/Frame_222.png'
icon: '/user/static/Frame_222.png'
},
{
name: '会员折扣',
desc: '全店折扣98折',
icon: '/user/images/Frame_223.png'
icon: '/user/static/Frame_223.png'
},
{
name: '消费送积分',
desc: '',
icon: '/user/images/Frame_224.png'
icon: '/user/static/Frame_224.png'
},
{
name: '周期福利',
desc: '',
icon: '/user/images/Frame_225.png'
icon: '/user/static/Frame_225.png'
}
]
@@ -199,11 +199,11 @@
}
.top {
padding: 100rpx 30rpx 78rpx 30rpx;
padding: 208rpx 30rpx 78rpx 30rpx;
}
.vip-box {
background-image: url(/user/images/Rectangle_25.png);
background-size: cover;
position: relative;
border-radius: 12px;
@@ -310,7 +310,7 @@
/* 列间距 */
column-gap: 10px;
/* 行间距 */
row-gap: 10px;
row-gap: 32rpx;
/* 可以添加容器的内边距 */
}