1908 lines
57 KiB
Vue
1908 lines
57 KiB
Vue
<!-- src/views/Invitation/InviteToRegister.vue -->
|
||
<template>
|
||
<div class="fullPage">
|
||
<!-- 预加载状态 -->
|
||
<div v-if="isLoading" class="loading-container">
|
||
<!-- 页面背景 -->
|
||
<BackgroundLayer :backgroundImages="[imageUrl('bg1New'), imageUrl('bg2'), imageUrl('bg3')]" />
|
||
|
||
<!-- 加载动画 -->
|
||
<LoadingContent>{{ $t('loading') }}...</LoadingContent>
|
||
</div>
|
||
|
||
<!-- 主要内容 -->
|
||
<div v-else style="width: 100vw; min-height: 100vh; overflow: hidden; position: relative">
|
||
<!-- 页面背景 -->
|
||
<BackgroundLayer :backgroundImages="[imageUrl('bg1New'), imageUrl('bg2'), imageUrl('bg3')]" />
|
||
|
||
<!-- 头部导航组件 -->
|
||
<div style="position: absolute; top: 0; left: 0; width: 100%">
|
||
<GeneralHeader
|
||
:isHomePage="true"
|
||
:showHelp="true"
|
||
:backImg="imgUrl"
|
||
:title="t('invitation_to_register')"
|
||
@help="helpInfoShow = true"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 确认邀请码 -->
|
||
<div class="leftBt">
|
||
<!-- 打开输入邀请码 -->
|
||
<itemCenter
|
||
v-if="leftBtType === 'enterCode'"
|
||
style="width: 40%; min-height: 15.63vw"
|
||
:imgUrl="imageUrl('BtBg')"
|
||
:contentStyle="`direction: ltr;justify-content: center;inset: 1vw 6vw 0 0.5vw;`"
|
||
@click="enterCodeShow = true"
|
||
>
|
||
<div :class="['enter', `enter_${currentLangType}`]">{{ t('enter_invitation_code') }}</div>
|
||
</itemCenter>
|
||
<!-- <itemCenter
|
||
style="width: 40%; min-height: 15.63vw"
|
||
:imgUrl="imageUrl('BtBg')"
|
||
:contentStyle="`direction: ltr;justify-content: center;inset: 1vw 6vw 0 0.5vw;`"
|
||
@click="enterCodeShow = true"
|
||
>
|
||
<div :class="['enter', `enter_${currentLangType}`]">{{ t('enter_invitation_code') }}</div>
|
||
</itemCenter> -->
|
||
|
||
<!-- 前往邀请人信息页 -->
|
||
<itemCenter
|
||
v-else-if="leftBtType === 'privateChat'"
|
||
style="width: 40%; min-height: 15.63vw"
|
||
:imgUrl="imageUrl('BtBg')"
|
||
:contentStyle="`direction: ltr;justify-content: center;inset: 1vw 6vw 0 0.5vw;`"
|
||
@click="gotoPrivateChat(myInviter.inviterInfo?.userId)"
|
||
>
|
||
<div :class="['contact', `contact_${currentLangType}`]">
|
||
{{ t('contact_your_inviter') }}
|
||
</div>
|
||
</itemCenter>
|
||
<!-- <itemCenter
|
||
style="width: 40%; min-height: 15.63vw"
|
||
:imgUrl="imageUrl('BtBg')"
|
||
:contentStyle="`direction: ltr;justify-content: center;inset: 1vw 6vw 0 0.5vw;`"
|
||
@click="gotoPrivateChat(myInviter.inviterInfo?.userId)"
|
||
>
|
||
<div :class="['contact', `contact_${currentLangType}`]">
|
||
{{ t('contact_your_inviter') }}
|
||
</div>
|
||
</itemCenter> -->
|
||
</div>
|
||
|
||
<!-- 主体内容 -->
|
||
<div
|
||
style="
|
||
padding-top: 130vw;
|
||
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2vw;
|
||
"
|
||
>
|
||
<!-- 我的邀请码 -->
|
||
<itemCenter
|
||
style="min-height: 141vw"
|
||
:imgUrl="imageUrl(getImgName('myCode'))"
|
||
:contentStyle="`padding: 111vw 10vw 17vw;flex-direction: column;justify-content: flex-start;gap: 0vw;`"
|
||
>
|
||
<!-- 邀请码 -->
|
||
<div
|
||
style="
|
||
width: 90%;
|
||
height: 12vw;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
gap: 4px;
|
||
"
|
||
>
|
||
<div style="font-weight: 600; font-size: 0.9em">{{ t('my_invitation_code') }}</div>
|
||
<div style="font-weight: 590; font-size: 1.1em">
|
||
{{ myInviteInfo.inviteCode || '' }}
|
||
</div>
|
||
<img
|
||
v-if="myInviteInfo.inviteCode"
|
||
v-smart-img
|
||
:src="imageUrl('copy')"
|
||
alt=""
|
||
style="display: block; width: 1.5em; object-fit: cover"
|
||
@click="copyCode(myInviteInfo.inviteCode || '')"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 提示 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-height: 0;
|
||
width: 95%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<div style="font-size: 0.7em; font-weight: 510; color: #e9e9e9">
|
||
{{ t('copy_invitation_code_tip') }}
|
||
</div>
|
||
</div>
|
||
</itemCenter>
|
||
|
||
<!-- 模块切换按钮 -->
|
||
<div
|
||
style="
|
||
min-height: 22.07vw;
|
||
display: flex;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<!-- 收益模块按钮 -->
|
||
<div style="width: 40%; position: relative; min-height: max-content">
|
||
<img
|
||
v-smart-img.noFade
|
||
:src="imageUrl(getImgName('incomeBtActive'))"
|
||
alt=""
|
||
style="display: block; width: 100%"
|
||
:style="{ opacity: showModule === 'income' ? 1 : 0 }"
|
||
@click="showModule = 'income'"
|
||
/>
|
||
<img
|
||
v-smart-img.noFade
|
||
:src="imageUrl(getImgName('incomeBt'))"
|
||
alt=""
|
||
style="display: block; width: 100%; position: absolute; bottom: 0; left: 0"
|
||
:style="{ opacity: showModule === 'income' ? 0 : 1 }"
|
||
@click="showModule = 'income'"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 排行榜模块按钮 -->
|
||
<div style="width: 40%; position: relative">
|
||
<img
|
||
v-smart-img.noFade
|
||
:src="imageUrl(getImgName('earningsRankingBtActive'))"
|
||
alt=""
|
||
style="display: block; width: 100%"
|
||
:style="{ opacity: showModule === 'ranking' ? 1 : 0 }"
|
||
@click="showModule = 'ranking'"
|
||
/>
|
||
<img
|
||
v-smart-img.noFade
|
||
:src="imageUrl(getImgName('earningsRankingBt'))"
|
||
alt=""
|
||
style="display: block; width: 100%; position: absolute; bottom: 0; left: 0"
|
||
:style="{ opacity: showModule === 'ranking' ? 0 : 1 }"
|
||
@click="showModule = 'ranking'"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 收益模块 -->
|
||
<div
|
||
v-show="showModule == 'income'"
|
||
style="display: flex; flex-direction: column; gap: 2vw; padding-bottom: 37vw"
|
||
>
|
||
<!-- 收入展示 -->
|
||
<itemCenter
|
||
style="min-height: 100vw"
|
||
:imgUrl="imageUrl(getImgName('incomeBg'))"
|
||
:contentStyle="`padding: 44vw 8vw 18vw 7vw;display:grid;grid-template-columns: repeat(2, 1fr);gap: 4vw;`"
|
||
>
|
||
<!-- 更多按钮 -->
|
||
<div
|
||
style="
|
||
position: absolute;
|
||
z-index: 2;
|
||
width: 22vw;
|
||
height: 10vw;
|
||
top: 31vw;
|
||
right: 6vw;
|
||
"
|
||
@click="incomeShow = true"
|
||
></div>
|
||
|
||
<!-- 总邀请人数 -->
|
||
<div
|
||
style="
|
||
align-self: stretch;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
padding: 2vw;
|
||
"
|
||
>
|
||
<div style="font-weight: 700; font-size: 0.9em">{{ t('total_invitations') }}</div>
|
||
<div style="font-weight: 600; font-size: 1.1em">
|
||
{{ myInviteIncome.validInviteCount || 0 }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 今日邀请人数 -->
|
||
<div
|
||
style="
|
||
align-self: stretch;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
padding: 2vw;
|
||
"
|
||
>
|
||
<div style="font-weight: 700; font-size: 0.9em">{{ t('todays_invitation') }}</div>
|
||
<div style="font-weight: 600; font-size: 1.1em">
|
||
{{ myInviteIncome.todayInviteCount || 0 }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 总收入 -->
|
||
<div
|
||
style="
|
||
align-self: stretch;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
padding: 2vw;
|
||
"
|
||
>
|
||
<div style="font-weight: 700; font-size: 0.9em">
|
||
{{ t('invitation_total_income') }}
|
||
</div>
|
||
<div style="display: flex; align-items: center">
|
||
<img
|
||
v-smart-img
|
||
src="/src/assets/icon/Azizi/coin.png"
|
||
alt=""
|
||
style="display: block; width: 1.5em"
|
||
/>
|
||
<div style="font-weight: 600; font-size: 1.1em; padding-top: 1vw">
|
||
{{ myInviteIncome.totalIncome || 0 }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 今日收入 -->
|
||
<div
|
||
style="
|
||
align-self: stretch;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
padding: 2vw;
|
||
"
|
||
>
|
||
<div style="font-weight: 700; font-size: 0.9em">{{ t('todays_income') }}</div>
|
||
<div style="display: flex; align-items: center">
|
||
<img
|
||
v-smart-img
|
||
src="/src/assets/icon/Azizi/coin.png"
|
||
alt=""
|
||
style="display: block; width: 1.5em"
|
||
/>
|
||
<div style="font-weight: 600; font-size: 1.1em; padding-top: 1vw">
|
||
{{ myInviteIncome.todayIncome || 0 }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</itemCenter>
|
||
|
||
<!-- 流程展示 -->
|
||
<img
|
||
v-smart-img
|
||
:src="imageUrl(getImgName('example'))"
|
||
alt=""
|
||
style="position: relative; z-index: 2; display: block; width: 100%; object-fit: cover"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 排行榜模块 -->
|
||
<div v-show="showModule == 'ranking'" style="position: relative">
|
||
<!-- 标签页按钮 -->
|
||
<div
|
||
style="
|
||
width: 100vw;
|
||
min-height: 15vw;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
gap: 13vw;
|
||
"
|
||
>
|
||
<!-- 总榜栏目按钮 -->
|
||
<div style="width: 35vw; min-width: 0" @click="changeTag('rankAll')">
|
||
<img
|
||
v-smart-img
|
||
:src="imageUrl(getImgName('listBt'))"
|
||
alt=""
|
||
:class="{
|
||
'grayscale-container': !rankAllShow,
|
||
}"
|
||
style="width: 100%; display: block; object-fit: cover"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 周榜栏目按钮 -->
|
||
<div style="width: 35vw; min-width: 0" @click="changeTag('rankWeek')">
|
||
<img
|
||
v-smart-img
|
||
:src="imageUrl(getImgName('rankBt'))"
|
||
alt=""
|
||
:class="{
|
||
'grayscale-container': !rankWeekShow,
|
||
}"
|
||
style="width: 100%; display: block; object-fit: cover"
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 总榜 -->
|
||
<div v-show="rankAllShow">
|
||
<itemCenter
|
||
style="min-height: 205.33vw"
|
||
:imgUrl="imageUrl('rankingBg')"
|
||
:contentStyle="`padding: 10vw 6vw 10vw;flex-direction: column;justify-content: flex-start;gap:2vw`"
|
||
>
|
||
<!-- 列表 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-height: 0;
|
||
width: 100%;
|
||
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
"
|
||
>
|
||
<!-- 列表项 -->
|
||
<div
|
||
class="overflow-y-auto"
|
||
style="display: flex; flex-direction: column; width: 100%; gap: 2vw"
|
||
>
|
||
<itemCenter
|
||
style="min-height: 22.33vw"
|
||
v-for="(listItem, index) in rankingTotal"
|
||
:key="listItem.userId"
|
||
:imgUrl="imageUrl('rankItemBg')"
|
||
:contentStyle="`padding: 0 5vw`"
|
||
:lazy="true"
|
||
:immediate="index < 10"
|
||
:rootMargin="'100px'"
|
||
:show="rankAllShow"
|
||
@click="viewUserInfo(listItem.userId)"
|
||
>
|
||
<!-- 基本信息 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-width: 0;
|
||
|
||
display: flex;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
|
||
gap: 8px;
|
||
"
|
||
>
|
||
<!-- 排名 -->
|
||
<div style="color: #ffe601; font-weight: 700">
|
||
{{ listItem?.rank }}
|
||
</div>
|
||
|
||
<!-- 头像 -->
|
||
<img
|
||
:src="listItem?.avatar || ''"
|
||
alt=""
|
||
style="
|
||
display: block;
|
||
width: 13vw;
|
||
aspect-ratio: 1/1;
|
||
border-radius: 50%;
|
||
object-fit: cover;
|
||
"
|
||
@error="handleAvatarImageError"
|
||
/>
|
||
|
||
<!-- 名称、id -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-width: 0;
|
||
align-self: stretch;
|
||
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
"
|
||
>
|
||
<div
|
||
style="
|
||
color: #fff;
|
||
font-size: 0.9em;
|
||
font-weight: 860;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
"
|
||
>
|
||
{{ listItem?.nickname }}
|
||
</div>
|
||
<div style="font-size: 0.8em; color: #fff; font-weight: 590">
|
||
{{ $t('user_id_prefix') }} {{ listItem?.account }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 贡献值 -->
|
||
<div
|
||
style="
|
||
width: auto;
|
||
min-width: 0;
|
||
|
||
display: flex;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<img
|
||
v-smart-img
|
||
src="/src/assets/icon/Azizi/coin.png"
|
||
alt=""
|
||
style="display: block; width: 1.5em; aspect-ratio: 1/1; object-fit: cover"
|
||
/>
|
||
<div style="font-size: 0.9em; font-weight: 700">
|
||
{{ listItem?.quantity }}
|
||
</div>
|
||
</div>
|
||
</itemCenter>
|
||
</div>
|
||
</div>
|
||
</itemCenter>
|
||
|
||
<!-- 我的排名占位 -->
|
||
<div style="height: 20vw"></div>
|
||
</div>
|
||
|
||
<!-- 周榜 -->
|
||
<div v-show="rankWeekShow">
|
||
<itemCenter
|
||
style="min-height: 205.33vw"
|
||
:imgUrl="imageUrl('rankingBg')"
|
||
:contentStyle="`padding: 13vw 6vw 10vw;flex-direction: column;justify-content: flex-start;gap:2vw`"
|
||
>
|
||
<!-- 头部 -->
|
||
<div style="width: 100%; min-width: 0; display: flex; align-items: center; gap: 2vw">
|
||
<!-- 倒计时 -->
|
||
<itemCenter
|
||
style="width: 70%; min-width: 0; min-height: 9.87vw"
|
||
:imgUrl="imageUrl('timeBg')"
|
||
:contentStyle="``"
|
||
>
|
||
<div class="timeBox">
|
||
<div class="timeText" style="">{{ WDays }}Day</div>
|
||
<div class="timeText timeGap"></div>
|
||
<div class="timeText" style="">{{ WHours }}</div>
|
||
<div class="timeText timeGap">:</div>
|
||
<div class="timeText" style="">{{ WMinutes }}</div>
|
||
<div class="timeText timeGap">:</div>
|
||
<div class="timeText" style="">{{ WSeconds }}</div>
|
||
</div>
|
||
</itemCenter>
|
||
|
||
<!-- 奖励按钮 -->
|
||
<img
|
||
v-smart-img
|
||
:src="imageUrl(getImgName('rewardBt'))"
|
||
alt=""
|
||
style="flex: 1; min-width: 0; display: block; object-fit: cover"
|
||
@click="rewardShow = true"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 列表 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-height: 0;
|
||
width: 100%;
|
||
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
"
|
||
>
|
||
<!-- 列表项 -->
|
||
<div
|
||
class="overflow-y-auto"
|
||
style="display: flex; flex-direction: column; width: 100%; gap: 2vw"
|
||
>
|
||
<itemCenter
|
||
style="min-height: 22.33vw"
|
||
v-for="(listItem, index) in rankingTotal"
|
||
:key="listItem.userId"
|
||
:imgUrl="imageUrl('rankItemBg')"
|
||
:contentStyle="`padding: 0 5vw`"
|
||
:lazy="true"
|
||
:immediate="index < 10"
|
||
:rootMargin="'100px'"
|
||
:show="rankWeekShow"
|
||
@click="viewUserInfo(listItem.userId)"
|
||
>
|
||
<!-- 基本信息 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-width: 0;
|
||
|
||
display: flex;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
|
||
gap: 8px;
|
||
"
|
||
>
|
||
<!-- 排名 -->
|
||
<div style="color: #ffe601; font-weight: 700">
|
||
{{ listItem?.rank }}
|
||
</div>
|
||
|
||
<!-- 头像 -->
|
||
<img
|
||
:src="listItem?.avatar || ''"
|
||
alt=""
|
||
style="
|
||
display: block;
|
||
width: 13vw;
|
||
aspect-ratio: 1/1;
|
||
border-radius: 50%;
|
||
object-fit: cover;
|
||
"
|
||
@error="handleAvatarImageError"
|
||
/>
|
||
|
||
<!-- 名称、id -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-width: 0;
|
||
align-self: stretch;
|
||
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
"
|
||
>
|
||
<div
|
||
style="
|
||
color: #fff;
|
||
font-size: 0.9em;
|
||
font-weight: 860;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
"
|
||
>
|
||
{{ listItem?.nickname }}
|
||
</div>
|
||
<div style="font-size: 0.8em; color: #fff; font-weight: 590">
|
||
{{ $t('user_id_prefix') }} {{ listItem?.account }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 贡献值 -->
|
||
<div
|
||
style="
|
||
width: auto;
|
||
min-width: 0;
|
||
|
||
display: flex;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<img
|
||
v-smart-img
|
||
src="/src/assets/icon/Azizi/coin.png"
|
||
alt=""
|
||
style="display: block; width: 1.5em; aspect-ratio: 1/1; object-fit: cover"
|
||
/>
|
||
<div style="font-size: 0.9em; font-weight: 700">
|
||
{{ listItem?.quantity }}
|
||
</div>
|
||
</div>
|
||
</itemCenter>
|
||
</div>
|
||
</div>
|
||
</itemCenter>
|
||
|
||
<!-- 我的排名占位 -->
|
||
<div style="height: 30vw"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 邀请按钮 -->
|
||
<div
|
||
style="
|
||
width: 100%;
|
||
position: fixed;
|
||
bottom: 5vw;
|
||
z-index: 3;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
|
||
cursor: pointer;
|
||
-webkit-tap-highlight-color: transparent;
|
||
-webkit-touch-callout: none;
|
||
user-select: none;
|
||
touch-action: manipulation;
|
||
"
|
||
@click="handleInviteClick"
|
||
@touchend="handleInviteClick"
|
||
>
|
||
<img
|
||
v-show="showModule == 'income'"
|
||
v-smart-img
|
||
:src="imageUrl(getImgName('inviteFriendsBt'))"
|
||
alt=""
|
||
style="display: block; width: 90%; object-fit: cover; pointer-events: none"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 我的排名 -->
|
||
<itemCenter
|
||
v-show="showModule == 'ranking' && rankWeekShow"
|
||
style="min-height: 25.33vw; position: fixed; bottom: 0; z-index: 3"
|
||
:imgUrl="imageUrl('rankItemBg')"
|
||
:contentStyle="`padding: 0 7vw`"
|
||
>
|
||
<!-- 基本信息 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-width: 0;
|
||
|
||
display: flex;
|
||
justify-content: space-around;
|
||
align-items: center;
|
||
|
||
gap: 8px;
|
||
"
|
||
>
|
||
<!-- 排名 -->
|
||
<div style="color: #ffe601; font-weight: 700">
|
||
{{ myRanking.rank || 999 }}
|
||
</div>
|
||
|
||
<!-- 头像 -->
|
||
<img
|
||
:src="myRanking.avatar || ''"
|
||
alt=""
|
||
style="
|
||
display: block;
|
||
width: 15vw;
|
||
aspect-ratio: 1/1;
|
||
border-radius: 50%;
|
||
object-fit: cover;
|
||
"
|
||
@error="handleAvatarImageError"
|
||
/>
|
||
|
||
<!-- 名称 -->
|
||
<div style="flex: 1; min-width: 0; display: flex; flex-direction: column">
|
||
<div
|
||
style="
|
||
color: #fff;
|
||
font-weight: 860;
|
||
overflow: hidden;
|
||
white-space: nowrap;
|
||
text-overflow: ellipsis;
|
||
"
|
||
class="UserNickname"
|
||
>
|
||
{{ myRanking.nickname }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 贡献值 -->
|
||
<div
|
||
style="
|
||
width: auto;
|
||
min-width: 0;
|
||
|
||
display: flex;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<img
|
||
v-smart-img
|
||
src="/src/assets/icon/Azizi/coin.png"
|
||
alt=""
|
||
style="display: block; width: 1.5em; aspect-ratio: 1/1; object-fit: cover"
|
||
/>
|
||
<div style="font-weight: 700">
|
||
{{ myRanking.quantity || 0 }}
|
||
</div>
|
||
</div>
|
||
</itemCenter>
|
||
|
||
<!-- 弹窗遮罩层 -->
|
||
<maskLayer :maskLayerShow="maskLayerShow" @click="closedPopup">
|
||
<!-- 帮助模块 -->
|
||
<div v-show="helpInfoShow" style="margin: 20% 0; position: relative" @click.stop>
|
||
<img
|
||
v-smart-img
|
||
:src="imageUrl(getImgName('helpInfo'))"
|
||
alt=""
|
||
width="100%"
|
||
style="display: block"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 输入邀请码模块 -->
|
||
<div
|
||
v-show="enterCodeShow"
|
||
style="
|
||
width: 100vw;
|
||
|
||
padding: 30vw 0 10vw;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
"
|
||
@click="closedPopup"
|
||
>
|
||
<itemCenter
|
||
style="width: 100vw; min-height: 240.66vw"
|
||
:imgUrl="imageUrl(getImgName('enterCodeBg'))"
|
||
:contentStyle="`padding: 31.5vw 6vw 10vw;display: flex;flex-direction: column;justify-content: flex-start;`"
|
||
@click.stop
|
||
>
|
||
<!-- 邀请码 -->
|
||
<div class="bindingUserCode">
|
||
<!-- 输入框 -->
|
||
<input
|
||
v-model="invitationCode"
|
||
type="text"
|
||
style="
|
||
width: 60vw;
|
||
min-width: 0;
|
||
align-self: stretch;
|
||
|
||
color: white;
|
||
font-weight: 510;
|
||
|
||
padding: 4px 8px;
|
||
border: none;
|
||
outline: none;
|
||
background-color: transparent;
|
||
"
|
||
@keyup.enter="confirmInvitationCode"
|
||
/>
|
||
|
||
<!-- 按钮 -->
|
||
<img
|
||
:src="imageUrl(getImgName('confirmBt'))"
|
||
alt=""
|
||
style="display: block; width: 16vw; object-fit: contain"
|
||
@click="confirm"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 邀请奖励 -->
|
||
<div
|
||
style="
|
||
width: 85vw;
|
||
height: 28vw;
|
||
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
gap: 1.3vw;
|
||
"
|
||
:class="['inviteReward', `inviteReward_${currentLangType}`]"
|
||
>
|
||
<div
|
||
v-for="(reward, index) in bindingUserRewards"
|
||
style="align-self: stretch; display: flex; flex-direction: column"
|
||
>
|
||
<!-- 奖励图 -->
|
||
<div
|
||
style="
|
||
width: 100%;
|
||
min-width: 0;
|
||
aspect-ratio: 1/1;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<img
|
||
:src="reward.cover || ''"
|
||
alt=""
|
||
width="70%"
|
||
style="display: block; object-fit: cover"
|
||
@error="(e) => handleRewardImageError(e, reward.type)"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 信息 -->
|
||
<div
|
||
style="
|
||
width: 100%;
|
||
min-width: 0;
|
||
flex: 1;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
"
|
||
>
|
||
{{ showDetail(reward) }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 充值奖励 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-height: 0;
|
||
width: 85vw;
|
||
|
||
display: flex;
|
||
flex-direction: column;
|
||
"
|
||
:class="['rechargeReward', `rechargeReward_${currentLangType}`]"
|
||
>
|
||
<div
|
||
v-for="(Rewards, top) in rechargeRewards"
|
||
style="width: 100%; display: flex; flex-direction: column; gap: 18vw"
|
||
>
|
||
<div style="width: 100%; height: 30vw; display: flex; gap: 12vw">
|
||
<div
|
||
v-for="reward in Rewards"
|
||
style="
|
||
flex: 1;
|
||
min-width: 0;
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
"
|
||
>
|
||
<!-- 奖励图 -->
|
||
<div
|
||
style="
|
||
width: 100%;
|
||
min-width: 0;
|
||
aspect-ratio: 1/1;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<img
|
||
:src="reward.cover || ''"
|
||
alt=""
|
||
width="70%"
|
||
style="display: block; object-fit: cover"
|
||
@error="(e) => handleRewardImageError(e, reward.type)"
|
||
/>
|
||
</div>
|
||
<!-- 信息 -->
|
||
<div
|
||
style="
|
||
width: 100%;
|
||
min-width: 0;
|
||
flex: 1;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
"
|
||
>
|
||
{{ showDetail(reward) }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</itemCenter>
|
||
</div>
|
||
|
||
<!-- 收益&列表 -->
|
||
<div
|
||
v-show="incomeShow"
|
||
style="
|
||
width: 100vw;
|
||
|
||
padding: 25vw 0 10vw;
|
||
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
"
|
||
@click="closedPopup"
|
||
>
|
||
<!-- 收益&列表 -->
|
||
<itemCenter
|
||
style="min-height: 163.33vw"
|
||
:imgUrl="imageUrl(getImgName('incomeListBg'))"
|
||
:contentStyle="`padding: 37vw 6.5vw 10vw 5.5vw;flex-direction: column;gap: 4vw;justify-content: flex-start;`"
|
||
@click.stop
|
||
>
|
||
<!-- 收益 -->
|
||
<div
|
||
style="
|
||
width: 95%;
|
||
height: 37vw;
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 5vw;
|
||
"
|
||
>
|
||
<!-- 总邀请人数 -->
|
||
<div
|
||
style="
|
||
align-self: stretch;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
padding: 2vw;
|
||
"
|
||
>
|
||
<div style="font-weight: 700; font-size: 0.9em">{{ t('total_invitations') }}</div>
|
||
<div style="font-weight: 600; font-size: 1.1em">
|
||
{{ myInviteIncome.validInviteCount || 0 }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 今日邀请人数 -->
|
||
<div
|
||
style="
|
||
align-self: stretch;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
padding: 2vw;
|
||
"
|
||
>
|
||
<div style="font-weight: 700; font-size: 0.9em">{{ t('todays_invitation') }}</div>
|
||
<div style="font-weight: 600; font-size: 1.1em">
|
||
{{ myInviteIncome.todayInviteCount || 0 }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 总收入 -->
|
||
<div
|
||
style="
|
||
align-self: stretch;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
padding: 2vw;
|
||
"
|
||
>
|
||
<div style="font-weight: 700; font-size: 0.9em">
|
||
{{ t('invitation_total_income') }}
|
||
</div>
|
||
<div style="display: flex; align-items: center">
|
||
<img
|
||
v-smart-img
|
||
src="/src/assets/icon/Azizi/coin.png"
|
||
alt=""
|
||
style="display: block; width: 1.5em"
|
||
/>
|
||
<div style="font-weight: 600; font-size: 1.1em; padding-top: 1vw">
|
||
{{ myInviteIncome.totalIncome || 0 }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 今日收入 -->
|
||
<div
|
||
style="
|
||
align-self: stretch;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: space-around;
|
||
padding: 2vw;
|
||
"
|
||
>
|
||
<div style="font-weight: 700; font-size: 0.9em">{{ t('todays_income') }}</div>
|
||
<div style="display: flex; align-items: center">
|
||
<img
|
||
v-smart-img
|
||
src="/src/assets/icon/Azizi/coin.png"
|
||
alt=""
|
||
style="display: block; width: 1.5em"
|
||
/>
|
||
<div style="font-weight: 600; font-size: 1.1em; padding-top: 1vw">
|
||
{{ myInviteIncome.todayIncome || 0 }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 列表 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
min-height: 0;
|
||
width: 100%;
|
||
border-radius: 8px;
|
||
background: rgba(194, 174, 232, 0.2);
|
||
backdrop-filter: blur(1px);
|
||
padding: 12px;
|
||
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
"
|
||
>
|
||
<!-- 头部 -->
|
||
<div style="width: 100%; display: flex; align-items: center">
|
||
<!-- user项 -->
|
||
<div style="flex: 1; font-weight: 590; font-size: 0.8em; text-align: center">
|
||
{{ t('users') }}
|
||
</div>
|
||
|
||
<!-- 时间项 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
font-weight: 590;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<!-- 分割线 -->
|
||
<div
|
||
style="
|
||
width: 1px;
|
||
height: 16px;
|
||
background: linear-gradient(
|
||
rgba(217, 217, 217, 0) 0%,
|
||
#d9d9d9 50%,
|
||
rgba(217, 217, 217, 0) 100%
|
||
);
|
||
"
|
||
></div>
|
||
|
||
<div style="font-weight: 590; font-size: 0.8em; text-align: center">
|
||
{{ t('unbinding_time') }}
|
||
</div>
|
||
|
||
<!-- 分割线 -->
|
||
<div
|
||
style="
|
||
width: 1px;
|
||
height: 16px;
|
||
background: linear-gradient(
|
||
rgba(217, 217, 217, 0) 0%,
|
||
#d9d9d9 50%,
|
||
rgba(217, 217, 217, 0) 100%
|
||
);
|
||
"
|
||
></div>
|
||
</div>
|
||
|
||
<!-- 收入项 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
font-weight: 590;
|
||
text-align: end;
|
||
font-size: 0.8em;
|
||
text-align: center;
|
||
"
|
||
>
|
||
{{ t('prowide_income') }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 列表项 -->
|
||
<div class="overflow-y-auto" style="align-self: stretch; width: 100%">
|
||
<div
|
||
v-for="user in myInviteUsers"
|
||
style="width: 100%; display: flex; align-items: center"
|
||
>
|
||
<!-- ID 项 -->
|
||
<div style="flex: 1; font-weight: 590; font-size: 0.8em; text-align: center">
|
||
{{ t('user_id_prefix') }}{{ user.invitedUserAccount || '-' }}
|
||
</div>
|
||
|
||
<!-- 时间项 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
font-weight: 590;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<div
|
||
style="
|
||
width: 1px;
|
||
height: 16px;
|
||
background: linear-gradient(
|
||
rgba(217, 217, 217, 0) 0%,
|
||
#d9d9d9 50%,
|
||
rgba(217, 217, 217, 0) 100%
|
||
);
|
||
"
|
||
></div>
|
||
<div style="font-weight: 590; font-size: 0.8em">
|
||
{{ user.remainingDays || 0 }}{{ t('day_unit') }}
|
||
</div>
|
||
<div
|
||
style="
|
||
width: 1px;
|
||
height: 16px;
|
||
background: linear-gradient(
|
||
rgba(217, 217, 217, 0) 0%,
|
||
#d9d9d9 50%,
|
||
rgba(217, 217, 217, 0) 100%
|
||
);
|
||
"
|
||
></div>
|
||
</div>
|
||
|
||
<!-- 收入项 -->
|
||
<div
|
||
style="
|
||
flex: 1;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
gap: 4px;
|
||
"
|
||
>
|
||
<img
|
||
v-smart-img
|
||
src="/src/assets/icon/Azizi/coin.png"
|
||
alt=""
|
||
style="display: block; width: 1em"
|
||
/>
|
||
<div style="color: #ffb627; font-size: 1em; font-weight: 590">
|
||
{{ user.provideIncome || 0 }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</itemCenter>
|
||
</div>
|
||
|
||
<!-- 周榜奖励模块 -->
|
||
<div
|
||
v-show="rewardShow"
|
||
style="
|
||
width: 100vw;
|
||
|
||
padding: 25vw 0 10vw;
|
||
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
"
|
||
@click="closedPopup"
|
||
>
|
||
<!-- 收益&列表 -->
|
||
<itemCenter
|
||
style="min-height: 286.13vw"
|
||
:imgUrl="imageUrl(getImgName('weekRewardBg'))"
|
||
:contentStyle="`padding: 57vw 15vw 20vw 15vw;flex-direction: column;gap: 40vw;justify-content: flex-start;`"
|
||
@click.stop
|
||
>
|
||
<div
|
||
v-for="(rewardsTop, index) in rankingRewards"
|
||
style="flex: 1; min-height: 0; display: flex; gap: 11vw"
|
||
>
|
||
<div
|
||
v-for="(reward, index) in rewardsTop.rewards"
|
||
style="
|
||
flex: 1;
|
||
align-self: stretch;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2vw;
|
||
"
|
||
>
|
||
<!-- 奖励图 -->
|
||
<div
|
||
style="
|
||
width: 100%;
|
||
aspect-ratio: 1/1;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
"
|
||
>
|
||
<img
|
||
:src="reward.cover || ''"
|
||
alt=""
|
||
width="70%"
|
||
style="display: block; object-fit: cover"
|
||
@error="(e) => handleRewardImageError(e, reward.type)"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 奖励信息 -->
|
||
<div style="flex: 1; display: flex; justify-content: center; align-items: center">
|
||
<div style="font-size: 1.3em; color: #fff; font-weight: 600">
|
||
{{ formatRewardDisplay(reward.type, reward) }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</itemCenter>
|
||
</div>
|
||
</maskLayer>
|
||
|
||
<!-- 提示弹窗 -->
|
||
<div
|
||
v-show="tipShow"
|
||
style="position: fixed; top: 50vh; display: flex; justify-content: center; width: 100vw"
|
||
>
|
||
<div
|
||
style="
|
||
padding: 12px;
|
||
border-radius: 8px;
|
||
background: rgba(0, 0, 0, 0.4);
|
||
font-weight: 600;
|
||
"
|
||
>
|
||
{{ t('copied_successfully') }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||
import { useI18n } from 'vue-i18n'
|
||
import { useLangStore } from '@/stores/lang'
|
||
import { viewUserInfo, gotoPrivateChat, openAppComponent } from '@/utils/appBridge.js'
|
||
import { showError, showWarning, showSuccess } from '@/utils/toast.js'
|
||
import { useClipboard } from '@vueuse/core'
|
||
import { connectToApp } from '@/utils/appConnector.js'
|
||
import { getPngUrl } from '@/config/imagePaths.js'
|
||
import { preloadImages } from '@/utils/image/imagePreloader.js'
|
||
import { handleAvatarImageError, handleRewardImageError } from '@/utils/image/imageHandler.js'
|
||
import { formatRewardDisplay } from '@/utils/rewardFormatter.js'
|
||
|
||
import {
|
||
getRankingListAndMyRanking, // 获取排行榜和当前用户排名
|
||
getThisWeekRewardsAndGifts, // 获取本周奖励和礼物
|
||
getOverallRanking, // 获取总榜
|
||
} from '@/api/activity.js'
|
||
import {
|
||
getMyInviteCode, // 获取我的邀请码
|
||
bindInviteCode, // 绑定邀请码
|
||
getMyInviteIncome, // 获取收益统计
|
||
getMyInviteUsers, // 有效邀请用户列表
|
||
apiGetBindingUserRewards, // 获取绑定用户奖励
|
||
getMyInviter, // 获取我的邀请人信息
|
||
} from '@/api/invitation.js'
|
||
|
||
import BackgroundLayer from '@/components/BackgroundLayer.vue'
|
||
import GeneralHeader from '@/components/GeneralHeader.vue'
|
||
import itemCenter from '@/components/itemCenter.vue'
|
||
import maskLayer from '@/components/MaskLayer.vue'
|
||
|
||
const imgUrl = new URL('/src/assets/icon/Azizi/arrowBack.png', import.meta.url).href
|
||
|
||
const { t } = useI18n()
|
||
const langStore = useLangStore()
|
||
// 当前语言类型
|
||
const currentLangType = computed(() => {
|
||
return langStore.selectedLang?.type || 'en'
|
||
})
|
||
|
||
// 根据语言获取图片名
|
||
const getImgName = (filename) => {
|
||
return currentLangType.value === 'en' ? filename : `${filename}_${currentLangType.value}`
|
||
}
|
||
|
||
// 获取OSS图片URL的函数
|
||
const imageUrl = (filename) => getPngUrl('invitation/inviteNewUser/', filename)
|
||
|
||
const { copy, isSupported } = useClipboard()
|
||
|
||
// 预加载状态
|
||
const isLoading = ref(true)
|
||
|
||
const invitationCode = ref('') //邀请码
|
||
const myInviteInfo = ref({}) //我的邀请信息
|
||
const myInviter = ref({}) //我的邀请人信息
|
||
const myInviteIncome = ref({}) //邀请用户收益统计
|
||
const myInviteUsers = ref([]) //邀请用户列表
|
||
const bindingUserRewards = ref([]) //绑定用户奖励
|
||
// 充值奖励
|
||
const rechargeRewards = ref(Array(3))
|
||
|
||
// 排行奖励
|
||
const rankingRewards = ref([])
|
||
|
||
const Ranking = ref([]) // 原始排行榜
|
||
const myRanking = ref({}) // 我的排名
|
||
const RankingLoadmore = ref(null) //触底模块
|
||
const rankingPageNo = ref(1) //分页页码
|
||
const rankingAdd = ref([]) //加载排行榜项
|
||
|
||
const OverallRanking = ref([]) // 总榜
|
||
|
||
// 完整排行榜
|
||
const rankingTotal = computed(() => {
|
||
if (rankAllShow.value) {
|
||
return OverallRanking.value
|
||
}
|
||
if (rankWeekShow.value) {
|
||
// return [...Ranking.value, ...rankingAdd.value]
|
||
return Ranking.value
|
||
}
|
||
})
|
||
|
||
const showModule = ref('income') //显示模块
|
||
const rankAllShow = ref(true) //总榜显示
|
||
const rankWeekShow = ref(false) //周榜显示
|
||
const rewardShow = ref(false) //前三奖励显示
|
||
|
||
// 栏目切换
|
||
const changeTag = (tag) => {
|
||
switch (tag) {
|
||
case 'rankWeek':
|
||
rankWeekShow.value = true
|
||
rankAllShow.value = false
|
||
break
|
||
case 'rankAll':
|
||
rankWeekShow.value = false
|
||
rankAllShow.value = true
|
||
break
|
||
}
|
||
}
|
||
|
||
// 弹窗展示
|
||
const helpInfoShow = ref(false) //帮助弹窗
|
||
const enterCodeShow = ref(false) //交易弹窗
|
||
const incomeShow = ref(false) //收益详情弹窗
|
||
const tipShow = ref(false) //提示弹窗
|
||
// 遮罩层展示
|
||
const maskLayerShow = computed(() => {
|
||
return helpInfoShow.value || enterCodeShow.value || incomeShow.value || rewardShow.value
|
||
})
|
||
|
||
// 关闭弹窗
|
||
const closedPopup = () => {
|
||
helpInfoShow.value = false
|
||
enterCodeShow.value = false
|
||
incomeShow.value = false
|
||
rewardShow.value = false
|
||
}
|
||
|
||
// 倒计时相关数据
|
||
const WDays = ref(0)
|
||
const WHours = ref(0)
|
||
const WMinutes = ref(0)
|
||
const WSeconds = ref(0)
|
||
let countdownTimer = null
|
||
|
||
// 按条件展示按钮
|
||
const leftBtType = computed(() => {
|
||
// 数据还未加载完成
|
||
if (!myInviter.value || Object.keys(myInviter.value).length === 0) {
|
||
return null
|
||
}
|
||
|
||
// 优先级1: 如果有邀请人信息且有userId,则显示私聊按钮
|
||
if (myInviter.value.inviterInfo?.userId) {
|
||
return 'privateChat'
|
||
}
|
||
|
||
// 优先级2: 如果没有过期且没有邀请人,则显示输入邀请码按钮
|
||
if (!myInviter.value.myInfo?.expired && !myInviter.value.inviterInfo) {
|
||
return 'enterCode'
|
||
}
|
||
|
||
// 其他情况不显示按钮
|
||
return null
|
||
})
|
||
|
||
// 获取下周一对应的时间戳
|
||
const getNextWeekInBeijing = () => {
|
||
const now = new Date()
|
||
const targetDate = new Date(now.getTime()) // 创建一个基于当前时间的新日期对象
|
||
|
||
// 转换为北京时间来判断星期几
|
||
const utcTime = now.getTime() + now.getTimezoneOffset() * 60000
|
||
const beijingTime = new Date(utcTime + 8 * 3600000) // UTC+8
|
||
|
||
const beijingDay = beijingTime.getDay() // 0=周日, 1=周一, ..., 6=周六
|
||
const beijingHour = beijingTime.getHours()
|
||
|
||
// 转换为 0=周一, 1=周二, ..., 6=周日
|
||
const normalizedDay = beijingDay === 0 ? 6 : beijingDay - 1
|
||
|
||
let daysToAdd
|
||
if (normalizedDay === 0) {
|
||
// 今天是周一
|
||
if (beijingHour >= 5) {
|
||
daysToAdd = 7 // 超过5点,计算到下周一的所需时间
|
||
} else {
|
||
daysToAdd = 0 // 今天
|
||
}
|
||
} else {
|
||
daysToAdd = 7 - normalizedDay // 到下周一的天数
|
||
}
|
||
|
||
// 正确地添加天数
|
||
targetDate.setDate(targetDate.getDate() + daysToAdd) // 添加天数到下周一的当前时间
|
||
targetDate.setHours(5, 0, 0, 0) // 将时间重新设置为早上5点,作为目标时间戳
|
||
|
||
return targetDate.getTime()
|
||
}
|
||
|
||
const targetTime = ref(getNextWeekInBeijing()) // 闭包保存目标时间 (核心修正)
|
||
|
||
// 格式化时间
|
||
const formatTime = (value) => {
|
||
return value < 10 ? `0${value}` : value
|
||
}
|
||
|
||
// 倒计时
|
||
const getCountdown = () => {
|
||
const now = Date.now()
|
||
let diff = targetTime.value - now
|
||
|
||
if (diff <= 0) {
|
||
// 初始化数据
|
||
initData()
|
||
|
||
targetTime.value += 7 * 86400000 // +7天 (更新闭包变量)
|
||
diff = targetTime.value - now
|
||
}
|
||
|
||
const totalSeconds = Math.floor(diff / 1000)
|
||
WDays.value = Math.floor(totalSeconds / (24 * 3600))
|
||
WHours.value = formatTime(Math.floor((totalSeconds % (24 * 3600)) / 3600))
|
||
WMinutes.value = formatTime(Math.floor((totalSeconds % 3600) / 60))
|
||
WSeconds.value = formatTime(Math.floor(totalSeconds % 60))
|
||
}
|
||
|
||
// 启动倒计时
|
||
const startCountdown = () => {
|
||
getCountdown() // 立即执行一次周倒计时
|
||
countdownTimer = setInterval(getCountdown, 1000)
|
||
}
|
||
|
||
// 格式化奖励的展示信息
|
||
const showDetail = (reward) => {
|
||
let showamount = ['GOLD', 'DIAMOND', 'GIFT', 'FRAGMENTS']
|
||
if (showamount.includes(reward.type)) {
|
||
return reward.content
|
||
} else if (reward.type === 'DOLLARS') {
|
||
return `$${reward.content}`
|
||
} else {
|
||
return `${reward.quantity}${t('day_unit')}`
|
||
}
|
||
}
|
||
|
||
// 处理邀请按钮点击
|
||
const handleInviteClick = () => {
|
||
// 确保数据已加载
|
||
if (!myInviteInfo.value?.inviteCode) {
|
||
showError(t('please_wait_loading'))
|
||
return
|
||
}
|
||
|
||
openAppComponent(
|
||
'shareDrawer:' + t('share_invitation_message', { code: myInviteInfo.value?.inviteCode }),
|
||
)
|
||
}
|
||
|
||
// 复制到剪贴板(原生方法)
|
||
const copyCode = (text) => {
|
||
if (isSupported.value) {
|
||
copy(text)
|
||
} else {
|
||
// 降级方案
|
||
const textArea = document.createElement('textarea')
|
||
textArea.value = text
|
||
document.body.appendChild(textArea)
|
||
textArea.select()
|
||
document.execCommand('copy')
|
||
document.body.removeChild(textArea)
|
||
}
|
||
|
||
tipShow.value = true
|
||
setTimeout(() => {
|
||
tipShow.value = false
|
||
}, 2000)
|
||
}
|
||
|
||
// 更改邀请码
|
||
const confirmInvitationCode = () => {
|
||
if (!invitationCode.value.trim()) {
|
||
showWarning(t('please_enter_valid_invitation_code'))
|
||
return
|
||
}
|
||
}
|
||
|
||
// 获取我的邀请码
|
||
const apiGetMyInviteCode = async () => {
|
||
const resCode = await getMyInviteCode()
|
||
if (resCode.status && resCode.body) {
|
||
myInviteInfo.value = resCode.body
|
||
}
|
||
}
|
||
|
||
// 获取我的邀请人信息
|
||
const apiGetMyInviter = async () => {
|
||
const resInviter = await getMyInviter()
|
||
if (resInviter.status && resInviter.body) {
|
||
myInviter.value = resInviter.body || {}
|
||
}
|
||
}
|
||
|
||
// 绑定邀请码
|
||
const confirm = async () => {
|
||
if (!invitationCode.value.trim()) {
|
||
showWarning(t('please_enter_valid_invitation_code'))
|
||
return
|
||
}
|
||
let data = { inviteCode: invitationCode.value.trim(), inviteType: 'REGISTER' }
|
||
try {
|
||
const resBind = await bindInviteCode(data)
|
||
if (resBind.status) {
|
||
showSuccess(t('invitation_code_bound_successfully'))
|
||
apiGetMyInviter() //刷新我的邀请人信息
|
||
} else {
|
||
showError(t('invitation_code_binding_failed'))
|
||
}
|
||
invitationCode.value = ''
|
||
enterCodeShow.value = false
|
||
} catch (error) {
|
||
showError(error.errorMsg)
|
||
}
|
||
}
|
||
|
||
// 获取收益统计
|
||
const apiGetMyInviteIncome = async () => {
|
||
const resIncome = await getMyInviteIncome()
|
||
if (resIncome.status && resIncome.body) {
|
||
myInviteIncome.value = resIncome.body
|
||
}
|
||
}
|
||
|
||
// 有效邀请用户列表
|
||
const apiGetMyInviteUsers = async () => {
|
||
const resUserList = await getMyInviteUsers()
|
||
if (resUserList.status && resUserList.body) {
|
||
myInviteUsers.value = resUserList.body
|
||
// myInviteUsers.value = Array(2).fill(resUserList.body).flat()
|
||
// myInviteUsers.value = []
|
||
}
|
||
}
|
||
|
||
// 绑定用户奖励
|
||
const getBindingUserRewards = async () => {
|
||
let data = ['1983474358707736577']
|
||
const resAwardPool = await apiGetBindingUserRewards(data)
|
||
if (resAwardPool.status && resAwardPool.body) {
|
||
bindingUserRewards.value = resAwardPool.body['1983474358707736577']
|
||
}
|
||
}
|
||
|
||
// 获取排行榜
|
||
const getRanking = async () => {
|
||
let data = {
|
||
activityType: 14,
|
||
}
|
||
const resRanking = await getRankingListAndMyRanking(data)
|
||
if (resRanking.status && resRanking.body) {
|
||
myRanking.value = resRanking.body?.currentUserRank //我的排名信息
|
||
Ranking.value = resRanking.body?.rankingList
|
||
} else {
|
||
Ranking.value = []
|
||
myRanking.value = {}
|
||
}
|
||
}
|
||
|
||
// 获取总榜
|
||
const getOverallList = async () => {
|
||
let data = {
|
||
activityType: 14,
|
||
}
|
||
const resRanking = await getOverallRanking(100, data)
|
||
if (resRanking.status && resRanking.body) {
|
||
OverallRanking.value = resRanking.body || []
|
||
} else {
|
||
OverallRanking.value = []
|
||
}
|
||
}
|
||
|
||
// 获取每周奖励列表
|
||
const getRewardsAndGifts = async () => {
|
||
const resRewardsAndGifts = await getThisWeekRewardsAndGifts('2029443922744954881')
|
||
if (resRewardsAndGifts.status && resRewardsAndGifts.body) {
|
||
rankingRewards.value = resRewardsAndGifts.body.butOneRewards
|
||
}
|
||
}
|
||
|
||
// 获取充值奖励
|
||
const getRechargeRewards = async () => {
|
||
let RewardsId = [['2029448725407711234'], ['2029449081176965121'], ['2029449364032438273']]
|
||
RewardsId.forEach(async (id, index) => {
|
||
const resRechargeRewards = await apiGetBindingUserRewards(id)
|
||
if (resRechargeRewards.status && resRechargeRewards.body) {
|
||
console.log('resRechargeRewards.body.id', resRechargeRewards.body[`${id}`])
|
||
rechargeRewards.value[index] = resRechargeRewards.body[`${id}`]
|
||
}
|
||
})
|
||
}
|
||
|
||
// 预加载关键图片
|
||
const preloadCriticalImages = async () => {
|
||
const criticalImages = [
|
||
imageUrl('bg1New'),
|
||
imageUrl('bg2'),
|
||
imageUrl('bg3'),
|
||
imageUrl('BtBg'),
|
||
imageUrl(getImgName('myCode')),
|
||
imageUrl('copy'),
|
||
imageUrl(getImgName('incomeBtActive')),
|
||
imageUrl(getImgName('incomeBt')),
|
||
imageUrl(getImgName('earningsRankingBtActive')),
|
||
imageUrl(getImgName('earningsRankingBt')),
|
||
imageUrl(getImgName('incomeBg')),
|
||
imageUrl(getImgName('example')),
|
||
imageUrl(getImgName('listBt')),
|
||
imageUrl(getImgName('rankBt')),
|
||
imageUrl(getImgName('rewardBt')),
|
||
imageUrl('rankingBg'),
|
||
imageUrl('timeBg'),
|
||
imageUrl('rankItemBg'),
|
||
|
||
imageUrl(getImgName('inviteFriendsBt')),
|
||
imageUrl(getImgName('helpInfo')),
|
||
imageUrl(getImgName('enterCodeBg')),
|
||
imageUrl(getImgName('confirmBt')),
|
||
imageUrl(getImgName('incomeListBg')),
|
||
imageUrl(getImgName('weekRewardBg')),
|
||
]
|
||
|
||
await preloadImages(criticalImages)
|
||
}
|
||
|
||
// 页面初始化数据
|
||
const initData = async () => {
|
||
await Promise.all([
|
||
apiGetMyInviteCode(), // 获取我的邀请码
|
||
apiGetMyInviter(), // 获取我的邀请人信息
|
||
apiGetMyInviteIncome(), // 获取收益统计
|
||
apiGetMyInviteUsers(), // 有效邀请用户列表
|
||
getBindingUserRewards(), // 绑定用户奖励
|
||
|
||
getRanking(), //获取排行榜
|
||
getOverallList(), //获取总榜
|
||
getRewardsAndGifts(), //获取每周奖励列表
|
||
getRechargeRewards(), //获取充值奖励
|
||
])
|
||
}
|
||
|
||
// 完成预加载
|
||
const completePreloading = async () => {
|
||
try {
|
||
// 执行所有初始化操作
|
||
await Promise.all([initData(), preloadCriticalImages()])
|
||
} catch (error) {
|
||
console.error('预加载过程中发生错误:', error)
|
||
} finally {
|
||
// 无论成功或失败都结束加载状态
|
||
isLoading.value = false
|
||
}
|
||
}
|
||
|
||
// 使用工具函数连接APP
|
||
const connectToAppHandler = async () => {
|
||
await connectToApp(() => {
|
||
// 连接成功回调
|
||
completePreloading() // 完成预加载
|
||
})
|
||
}
|
||
|
||
onMounted(() => {
|
||
startCountdown() //开启倒计时
|
||
connectToAppHandler()
|
||
})
|
||
|
||
onUnmounted(() => {
|
||
// 销毁计时器
|
||
if (countdownTimer) {
|
||
clearInterval(countdownTimer)
|
||
countdownTimer = null
|
||
}
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
* {
|
||
color: white;
|
||
}
|
||
|
||
.fullPage {
|
||
width: 100vw;
|
||
min-height: 100vh;
|
||
background-color: #c7432d;
|
||
position: relative;
|
||
}
|
||
|
||
.grayscale-container {
|
||
filter: grayscale(100%) brightness(90%);
|
||
}
|
||
|
||
.timeBox {
|
||
// margin-top: 1vw;
|
||
width: 80%;
|
||
display: flex;
|
||
justify-content: space-around;
|
||
}
|
||
|
||
.timeText {
|
||
color: #fff;
|
||
font-weight: 590;
|
||
font-size: 1.7em;
|
||
}
|
||
|
||
.timeGap {
|
||
width: 6px;
|
||
align-self: stretch;
|
||
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
[dir='rtl'] .timeBox {
|
||
flex-direction: row-reverse;
|
||
}
|
||
|
||
.overflow-y-auto {
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.overflow-y-auto::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
|
||
.leftBt {
|
||
position: absolute;
|
||
top: 117vw;
|
||
left: 0;
|
||
width: 100vw;
|
||
|
||
direction: ltr;
|
||
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
}
|
||
|
||
.bindingUserCode {
|
||
width: 100%;
|
||
padding-left: 5vw;
|
||
padding-right: 5vw;
|
||
height: 14vw;
|
||
|
||
direction: ltr;
|
||
|
||
display: flex;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.enter {
|
||
font-weight: 590;
|
||
font-size: 0.7em;
|
||
}
|
||
|
||
.enter_ar {
|
||
font-size: 0.9em;
|
||
}
|
||
|
||
.enter_tr {
|
||
font-size: 0.8em;
|
||
}
|
||
.enter_bn {
|
||
font-size: 0.9em;
|
||
}
|
||
|
||
.contact {
|
||
font-weight: 590;
|
||
font-size: 0.6em;
|
||
}
|
||
|
||
.contact_en {
|
||
font-size: 0.8em;
|
||
}
|
||
|
||
.contact_tr {
|
||
font-size: 0.6em;
|
||
}
|
||
|
||
.inviteReward {
|
||
margin-top: 22vw;
|
||
}
|
||
|
||
.inviteReward_bn,
|
||
.inviteReward_tr {
|
||
margin-top: 19vw;
|
||
}
|
||
|
||
.rechargeReward {
|
||
padding: 23.5vw 0 5vw;
|
||
gap: 8.8vw;
|
||
}
|
||
|
||
.rechargeReward_bn,
|
||
.rechargeReward_tr {
|
||
padding: 24.5vw 0 5vw;
|
||
gap: 10vw;
|
||
}
|
||
|
||
/* 添加加载动画样式 */
|
||
.loading-container {
|
||
width: 100vw;
|
||
height: 100vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
color: #666;
|
||
|
||
overflow: hidden;
|
||
position: relative;
|
||
}
|
||
|
||
@media screen and (max-width: 360px) {
|
||
* {
|
||
font-size: 12px;
|
||
}
|
||
}
|
||
|
||
@media screen and (min-width: 360px) {
|
||
* {
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
|
||
@media screen and (min-width: 768px) {
|
||
* {
|
||
font-size: 24px;
|
||
}
|
||
}
|
||
|
||
@media screen and (min-width: 1024px) {
|
||
* {
|
||
font-size: 32px;
|
||
}
|
||
}
|
||
|
||
// [dir='rtl'] .leftBt {
|
||
// align-items: flex-end;
|
||
// }
|
||
|
||
// [dir='rtl'] .bindingUserCode {
|
||
// padding-left: 5vw;
|
||
// padding-right: 3.5vw;
|
||
// }
|
||
</style>
|