aslan-h5/src/views/AdminCenter.vue

402 lines
12 KiB
Vue

<template>
<div class="fullPage">
<div class="bg">
<MobileHeader title="Admin Center" :isHomePage="true">
<template v-slot:extraFunction>
<div style="color: rgba(187, 146, 255, 1) !important; font-weight: 600" @click="send">
Send
</div>
</template>
</MobileHeader>
<!-- 标签 -->
<div
style="
display: flex;
justify-content: space-around;
border-bottom: 1px solid #cccccc;
background-color: transparent;
position: relative;
"
>
<div
v-for="(item, index) in tabList"
:key="index"
style="font-size: 18px; padding: 10px 0; flex: 1; text-align: center"
class="tab-item"
:class="activeIndex == index ? 'tabName-active' : 'tabName'"
ref="tabItems"
@click="setActiveTab(index)"
>
{{ item.name }}
</div>
<!-- 下划线元素 -->
<div
style="width: 15px; height: 3px; background-color: #bb92ff"
:style="underlineStyle"
></div>
</div>
<!-- BD列表 -->
<div style="padding: 10px" v-show="activeIndex == 0">
<div
v-for="(info, BDIndex) in BDList"
:key="BDIndex"
style="
box-shadow: 0 0 4px 0 #00000066;
padding: 10px;
border-radius: 10px;
margin-bottom: 10px;
transition: all 0.3s ease-out;
"
@click="showUserInfo(BDIndex)"
>
<!-- 基本信息 -->
<div style="display: flex; justify-content: space-between">
<div style="display: flex; align-items: center">
<img
:src="info.userProfile.userAvatar"
alt="../assets/icon/coin.png"
style="width: 36px; height: 36px; border-radius: 50%"
/>
<div style="margin-left: 8px">
<div style="font-weight: 700">{{ info.userProfile.userNickname }}</div>
<div style="font-weight: 700; color: rgba(0, 0, 0, 0.4)">
ID:{{ info.userProfile.account }}
</div>
</div>
</div>
<div style="display: flex; align-items: center">
<img
src="../assets/icon/arrow.png"
alt=""
style="width: 24px; transition: transform 0.5s"
:class="{ rotated: BDIndex == selectedBDIndex }"
/>
</div>
</div>
<!-- 展示信息 -->
<transition name="info-fade">
<div style="display: flex" v-show="BDIndex == selectedBDIndex">
<div style="flex: 1">
<div style="font-weight: 500; color: rgba(0, 0, 0, 0.4)">Host</div>
<div style="font-weight: 600; color: rgba(0, 0, 0, 0.8)">
{{ info.allAnchorCount || 0 }}
</div>
</div>
<div style="flex: 1">
<div style="font-weight: 500; color: rgba(0, 0, 0, 0.4)">Agency</div>
<div style="font-weight: 600; color: rgba(0, 0, 0, 0.8)">
{{ info.agentCount || 0 }}
</div>
</div>
</div>
</transition>
</div>
<!-- 触发加载功能 -->
<div ref="BDloadmore" v-if="showBDLoading"></div>
</div>
<!-- agency列表 -->
<div style="padding: 10px" v-show="activeIndex == 1">
<div
style="
box-shadow: 0 0 4px 0 #00000066;
padding: 10px;
border-radius: 10px;
margin-bottom: 10px;
transition: all 0.3s ease-out;
"
>
<div style="font-weight: 500; color: rgba(0, 0, 0, 0.4)">
Total recharge for the month:
</div>
<div style="font-weight: 600; color: rgba(0, 0, 0, 0.8)">
${{ totalRechargeDetail[0]?.totalAmount || 0 }}
</div>
<div style="font-weight: 500; color: rgba(0, 0, 0, 0.4)">Total recharge last month:</div>
<div style="font-weight: 600; color: rgba(0, 0, 0, 0.8)">
${{ totalRechargeDetail[1]?.totalAmount || 0 }}
</div>
</div>
<div
v-for="(agency, aIndex) in agencyList"
:key="aIndex"
style="
box-shadow: 0 0 4px 0 #00000066;
padding: 10px;
border-radius: 10px;
margin-bottom: 10px;
transition: all 0.3s ease-out;
"
@click="showAgencyInfo(aIndex)"
>
<!-- 基本信息 -->
<div style="display: flex; justify-content: space-between">
<div style="display: flex; align-items: center">
<img :src="agency.userAvatar" alt="" style="width: 36px; border-radius: 50%" />
<div style="margin-left: 8px">
<div style="font-weight: 700">{{ agency.name }}</div>
<div style="font-weight: 700; color: rgba(0, 0, 0, 0.4)">
ID:{{ agency.account }}
</div>
</div>
</div>
<div style="display: flex; align-items: center">
<img
src="../assets/icon/arrow.png"
alt=""
style="
width: 24px;
transition: transform 0.5s cubic-bezier(0.68, -0.55, 0.27, 1.55);
"
:class="{ rotated: aIndex == selectedAgencyIndex }"
/>
</div>
</div>
<!-- 展示信息 -->
<transition name="info-fade">
<div style="display: flex" v-show="aIndex == selectedAgencyIndex">
<div style="flex: 1">
<div style="font-weight: 500; color: rgba(0, 0, 0, 0.4)">This month:</div>
<div style="font-weight: 600; color: rgba(0, 0, 0, 0.8)">
${{ formatPrice(agency.thisMonth) || 0 }}
</div>
</div>
<div style="flex: 1">
<div style="font-weight: 500; color: rgba(0, 0, 0, 0.4)">Last month:</div>
<div style="font-weight: 600; color: rgba(0, 0, 0, 0.8)">
${{ formatPrice(agency.lastMonth) || 0 }}
</div>
</div>
</div>
</transition>
</div>
<!-- 触发加载功能 -->
<div ref="Agloadmore" v-if="showAgLoading"></div>
</div>
</div>
</div>
</template>
<script setup>
import MobileHeader from '../components/MobileHeader.vue'
import { onMounted, ref, computed } from 'vue'
import { getBDList, getAgencyList, getAgencyTotalRecharge } from '@/api/userInfo'
import { useRouter } from 'vue-router'
import { usePageInitializationWithConfig } from '@/utils/pageConfig.js'
import { getUserId } from '@/utils/userStore.js'
import { useDebounce, useThrottle } from '@/utils/useDebounce'
const router = useRouter()
const tabList = ref([
{
id: 1,
name: 'BD',
},
{
id: 2,
name: 'Recharge Agency',
},
])
const activeIndex = ref(0)
const tabItems = ref([]) // 存储标签DOM引用
// 选择标签
const setActiveTab = (index) => {
if (activeIndex.value != index) {
console.log('切换标签')
activeIndex.value = index
selectedBDIndex.value = -1
selectedAgencyIndex.value = -1
}
}
// 计算下划线样式
const underlineStyle = computed(() => {
console.log('计算属性')
if (tabItems.value.length === 0) return {} //没有这个元素
const activeTab = tabItems.value[activeIndex.value]
console.log('选中元素的左边距', activeTab.offsetLeft)
return {
position: 'absolute',
left: `${activeTab.offsetLeft + activeTab.offsetWidth / 2 - 15 / 2}px`,
bottom: '0',
transition: 'left 0.3s ease', // 平滑过渡
}
})
const selectedBDIndex = ref(-1) //选中的BD用户下标
const showUserInfo = (index) => {
selectedBDIndex.value = selectedBDIndex.value != index ? index : -1
} //选中的BD用户
const selectedAgencyIndex = ref(-1) //选中的agency用户下标
const showAgencyInfo = (index) => {
selectedAgencyIndex.value = selectedAgencyIndex.value != index ? index : -1
} //选中的agency用户
const send = async () => {
router.push({ path: '/item-distribution' })
}
// 页面加载时获取申请记录
usePageInitializationWithConfig('ADMIN_CENTER')
const BDList = ref([]) // BD列表
const BDCurrent = ref(1) //BD列表第几页
const showBDLoading = ref(true) //触底加载功能
const totalRechargeDetail = ref([]) //代理消费金额
const agencyList = ref([]) // 代理列表
const agencyCurrent = ref(1) //代理列表第几页
const showAgLoading = ref(true) //触底加载功能
onMounted(async () => {
if (tabItems.value.length > 0) {
underlineStyle.value // 触发计算属性更新
}
getBDs() // 获取BD列表
getAgencise() // 获取代理列表
getAgencyMonthsRecharge() //获取代理总支付
// 开始监听底部元素
if (BDloadmore.value) {
observer.observe(BDloadmore.value)
}
// 开始监听底部元素
if (Agloadmore.value) {
observer.observe(Agloadmore.value)
}
})
// 获取BD列表
const getBDs = async () => {
let data = {
userId: getUserId(),
cursor: BDCurrent.value,
limit: 20,
}
const resBDList = await getBDList(data)
console.log('resBDList:', resBDList)
if (resBDList.status && resBDList.body) {
BDList.value.push(...resBDList.body.records)
if (resBDList.body.total <= resBDList.body.current * resBDList.body.size) {
showBDLoading.value = false
}
}
}
// 获取代理列表
const getAgencyMonthsRecharge = async () => {
const resTotalRecharge = await getAgencyTotalRecharge()
console.log('resTotalRecharge:', resTotalRecharge)
if (resTotalRecharge.status && resTotalRecharge.body) {
totalRechargeDetail.value = resTotalRecharge.body
}
}
// 获取代理列表
const getAgencise = async () => {
let data = {
cursor: agencyCurrent.value,
limit: 20,
}
const resagencyList = await getAgencyList(data)
console.log('resagencyList:', resagencyList)
if (resagencyList.status && resagencyList.body) {
agencyList.value.push(...resagencyList.body.records)
if (resagencyList.body.total <= resagencyList.body.current * resagencyList.body.size) {
showAgLoading.value = false
}
}
}
// 获取底部加载div
const BDloadmore = ref(null)
const Agloadmore = ref(null)
const debouceGetBDList = useThrottle(getBDs, 1000)
const debouceGetAgList = useThrottle(getAgencise, 1000)
// IntersectionObserver配置
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.intersectionRatio > 0) {
console.log('监控')
// 根据目标元素执行对应操作
if (entry.target == BDloadmore.value && BDList.value.length != 0) {
BDCurrent.value++
debouceGetBDList()
}
if (entry.target == Agloadmore.value && agencyList.value.length != 0) {
agencyCurrent.value++
debouceGetAgList()
}
}
})
})
const formatPrice = (value) => {
if (value && value != 0) {
return Number(value).toFixed(2)
}
return 0
}
</script>
<style scoped>
* {
color: black;
font-family: 'SF Pro';
}
.fullPage {
background-color: #ffffff;
min-height: 100vh;
position: relative;
}
.bg {
width: 100vw;
min-height: 100vh;
background-image: url(../assets/images/secondBg.png);
background-size: 100% auto;
background-repeat: no-repeat;
}
.tabName {
color: #00000066;
}
.tabName-active {
color: black;
font-weight: 500;
}
.info-fade-enter-from,
.info-fade-leave-to {
transform: translateY(-10px);
opacity: 0;
}
.info-fade-enter-active {
transition: all 0.5s ease-out;
}
.info-fade-leave-active {
transition: all 0.5s cubic-bezier(1, 0.5, 0.8, 1);
}
.rotated {
transform: rotate(90deg);
}
</style>