新增营销系统、分销系统、会员功能、门店、提现功能

This commit is contained in:
Shaw
2024-02-08 21:01:37 +08:00
parent 68b3f2dcc3
commit 17c043348a
1398 changed files with 81279 additions and 56269 deletions

View File

@ -0,0 +1,482 @@
<!--
@name: index
@author: kahu4
@date: 2024-01-18 17:35
@descriptionindex
@update: 2024-01-18 17:35
-->
<script setup>
import Header from "@/components/Header/index.vue"
import { useScroll } from "@/hooks/useScroll";
import { onMounted, ref, toRefs, unref } from "vue";
import { getMemberEquityList, getMemberLevelList, getMemberTaskList, getUserMemberLevel } from "@/api/member";
import { EnumTaskButton, taskButtonLabel } from "@/views/member/index/index.data";
import { useJump } from "@/hooks/useJump";
import InviteFriends from "@/components/Share/InviteFriends.vue";
import InviteFriendsPoster from "@/components/Poster/InviteFriends.vue";
import { useShare } from "@/hooks/useShare";
import { useMainStore } from "@/store/store";
import { onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
const {scrollTop} = useScroll();
const loading = ref(false)
const {goHome} = useJump()
// ================================ swiper ================================
const swiperCurrent = ref(0) // 当前swiper选中
/**
*
* @param e
*/
function swiperChange(e) {
swiperCurrent.value = e.detail.current
// 刷新会员权益
doGetMemberEquityList()
}
// ================================ 会员等级列表 ================================
// 当前用户会员信息
const memberLeverInfo = ref({
currentGrowthValue: 0,
currentLevel: null,
needGrowthValue: 0,
nextLevel: null
})
/**
* 获取当前用户会员信息
* @return {Promise<void>}
*/
async function doGetUserMemberLevel() {
try {
loading.value = true
memberLeverInfo.value = await getUserMemberLevel()
} finally {
loading.value = false
}
}
const memberLevelList = ref([])
/**
* 获取会员等级列表
* @return {Promise<void>}
*/
async function doGetMemberLevelList() {
try {
loading.value = true
const data = await getMemberLevelList()
// 获取当前用户的等级id
let index = 0
if (memberLeverInfo.value.currentLevel) {
// 没有会员等级
index = data.findIndex(item => item.id === memberLeverInfo.value.currentLevel.id);
}
swiperCurrent.value = index
memberLevelList.value = data
} finally {
loading.value = false
}
}
// ================================== 会员任务 ==============================================
const memberTaskList = ref([])
/**
* 获取会员任务列表
* @return {Promise<void>}
*/
async function doGetMemberTaskList() {
try {
loading.value = true
memberTaskList.value = await getMemberTaskList()
} finally {
loading.value = false
}
}
function handleTaskButtonClick(type) {
const tabFunc = {
[EnumTaskButton.CONSUME]: goToConsumption,
[EnumTaskButton.INVITE]: goToInvite
}
tabFunc[type]()
}
/**
* 去消费
*/
function goToConsumption() {
goHome()
}
/**
* 去邀请
*/
function goToInvite() {
openShare()
}
// ================================= 会员权益 ====================================================
const memberEquityList = ref([])
/**
* 获取会员权益
* @return {Promise<void>}
*/
async function doGetMemberEquityList() {
try {
loading.value = true
const currentLevelId = memberLevelList.value[swiperCurrent.value].id
memberEquityList.value = await getMemberEquityList({levelId: currentLevelId});
} finally {
loading.value = false
}
}
// ================================ 邀请 =====================================================
const mainStore = useMainStore()
const {user} = toRefs(mainStore)
const {userInvitationShare, shareH5, shareAppMessage, shareTimeline} = useShare()
onShareAppMessage(shareAppMessage)
onShareTimeline(shareTimeline)
const inviteFriendsRef = ref()
const inviteFriendsPosterRef = ref()
function openShare() {
inviteFriendsRef.value.open()
}
function handleShareConfirm(shareItem) {
const share = userInvitationShare(unref(user).invitationCode || '');
if (shareItem.value === 'wechat') {
shareH5()
} else {
inviteFriendsPosterRef.value.open(share)
}
}
onMounted(async () => {
// 1.获取当前用户等级 2.获取会员等级列表(寻找默认选中) 3.获取会员任务列表 4.获取会员权益
await doGetUserMemberLevel()
await doGetMemberLevelList()
await doGetMemberTaskList()
await doGetMemberEquityList()
})
</script>
<template>
<view>
<Header
:header-area-bg="'#fff'"
system-bar-area-bg="#fff"
:scroll-top="scrollTop"
prop-up
>
会员中心
</Header>
<view
class="member"
v-if="memberLevelList.length>0">
<!-- 背景 -->
<view
class="bg"
:style="{
background: `linear-gradient(to bottom, ${memberLevelList[swiperCurrent].colorNum}, #F6F6F6)`
}"
:class="`bg-${swiperCurrent}`"></view>
<!-- swiper -->
<swiper
class="swiper"
previous-margin="24rpx"
next-margin="24rpx"
circular
:current="swiperCurrent"
@change="swiperChange">
<swiper-item
v-for="item in memberLevelList"
:key="item.id"
>
<view
class="swiper-item"
:style="{backgroundImage:`url(${item.backgroundUrl})`,color:item.colorNum}">
<view class="name">
{{ item.levelName }}
</view>
<view class="level">
<template v-if="memberLeverInfo.currentLevel">
当前等级 {{ memberLeverInfo.currentLevel.levelName }}
</template>
<template v-else>
当前不是会员
</template>
</view>
<view class="bottom flex flex-ai__center flex-jc__sb">
<!-- 会员 -->
<template v-if="memberLeverInfo.currentLevel">
<view class="left">
<view class="process">
<view
class="schedule"
:style="{width:`${memberLeverInfo.currentGrowthValue>=item.growthValue?100:memberLeverInfo.currentGrowthValue/item.growthValue}%`,background:item.colorNum}"></view>
</view>
<view
class="tips"
v-if="item.growthValue > memberLeverInfo.currentGrowthValue">
再获取{{ item.growthValue - memberLeverInfo.currentGrowthValue }}经验可升级为{{ item.levelName }}会员
</view>
</view>
<view
class="right"
v-if="memberEquityList.length>0">
尊享以下{{ memberEquityList.length }}项特权
</view>
</template>
<!-- 非会员 -->
<template v-else>
<view class="left">
<view class="process">
<view
class="schedule"
:style="{width:`${memberLeverInfo.currentGrowthValue/item.growthValue}%`,background:item.colorNum}"></view>
</view>
<view
class="tips"
v-if="item.growthValue > memberLeverInfo.currentGrowthValue">
再获取{{ item.growthValue - memberLeverInfo.currentGrowthValue }}经验可升级为{{ item.levelName }}会员
</view>
</view>
<view
class="right"
v-if="memberEquityList.length>0">
尊享以下{{ memberEquityList.length }}项特权
</view>
</template>
</view>
</view>
</swiper-item>
</swiper>
<!-- card 特权-->
<view
class="card"
v-if="memberEquityList.length>0">
<view class="card__inner">
<view class="title">
会员特权
</view>
<view class="grid-box">
<view
class="grid-item flex flex-ai__center flex-jc__center flex-column"
v-for="equity in memberEquityList"
:key="equity.id">
<image :src="equity.iconUrl" />
<view class="name">
{{ equity.typeName }}
</view>
</view>
</view>
</view>
</view>
<!-- card 成长任务-->
<view
class="card"
v-if="memberTaskList.length>0">
<view class="card__inner">
<view class="title">
成长任务
</view>
<view class="list-box">
<view
class="list-item flex flex-ai__center"
v-for="task in memberTaskList"
:key="task.id">
<image :src="task.iconUrl" />
<view class="info flex flex-jc__sb flex-ai__center">
<view class="left">
<view class="name">{{ task.typeName }}</view>
<view class="tips">每次{{ task.typeName }}可获{{ task.growthValue }}成长值</view>
</view>
<view
class="button animation-button"
@click="handleTaskButtonClick(task.type)">
{{ taskButtonLabel[task.type] }}
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 邀请好友 -->
<InviteFriends
ref="inviteFriendsRef"
@share="handleShareConfirm" />
<InviteFriendsPoster ref="inviteFriendsPosterRef" />
</view>
</template>
<style
scoped
lang="scss">
.member {
width: 100%;
position: relative;
@include usePadding(0, 24);
.swiper {
width: 100%;
height: 338rpx;
.swiper-item {
padding: 92rpx 40rpx 20rpx 40rpx;
box-sizing: border-box;
height: 100%;
margin: 0 10rpx;
background-size: 100% 100%;
background-repeat: no-repeat;
position: relative;
transition: all .3s;
.name {
position: relative;
font-size: 48rpx;
font-weight: 600;
}
.level {
font-size: 24rpx;
margin-top: 17rpx;
}
.bottom {
font-size: 20rpx;
position: absolute;
bottom: 20rpx;
width: calc(100% - 80rpx);
.left {
flex-grow: 1;
padding-right: 30rpx;
.process {
width: 100%;
height: 10rpx;
border-radius: 10rpx;
background: #664B301A;
position: relative;
.schedule {
position: absolute;
top: 0;
left: 0;
height: 100%;
border-radius: 10rpx;
}
}
.tips {
margin-top: 12rpx;
}
}
.right {
font-weight: bold;
}
}
}
}
.bg {
width: 100%;
height: 386rpx;
position: absolute;
top: 0;
left: 0;
background: linear-gradient(to bottom, #402E0A, #F6F6F6);
}
.card {
width: 100%;
margin: 24rpx 0;
background: none;
@include usePadding(34, 0);
.card__inner {
width: 100%;
background: #fff;
@include usePadding(32, 32);
border-radius: 15rpx;
.title {
font-size: 32rpx;
font-weight: 600;
}
.grid-box {
display: grid;
grid-template-columns: repeat(4, 1fr);
row-gap: 20rpx;
@include usePadding(0, 16);
.grid-item {
image {
width: 80rpx;
height: 80rpx;
background: #fbfbfb;
border-radius: 10rpx;
margin-bottom: 10rpx;
}
.name {
color: #2B2B2B;
font-size: 24rpx;
}
}
}
.list-box {
.list-item {
margin: 28rpx 0;
image {
width: 80rpx;
height: 80rpx;
background: #fbfbfb;
border-radius: 10rpx;
margin-right: 16rpx;
}
.info {
flex-grow: 1;
.name {
font-size: 32rpx;
}
.tips {
color: $tips-color;
font-size: 24rpx;
}
.button {
@include usePadding(32, 14);
border-radius: 10rpx;
}
}
}
}
}
}
}
</style>