3807 lines
125 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- src/views/Activities/Game/index.vue -->
<template>
<div class="fullPage">
<!-- 预加载状态 -->
<div v-if="isLoading" class="loading-container">
<LoadingSpinner />
<p>{{ $t('loading') }}...</p>
</div>
<!-- 主要内容 -->
<div v-if="!isLoading" class="bg" style="">
<!-- 页面背景 -->
<BackgroundLayer :useCanvas="true" :backgroundImages="[imageUrl('bg1'), imageUrl('bg2')]" />
<!-- 重复的背景图层 -->
<div class="background-overlay" :style="{ '--bg2-url': toCssBackgroundImage(imageUrl('bg3')) }"></div>
<!-- 排行榜规则按钮 -->
<img
v-smart-img
:src="imageUrl('historyBt')"
alt=""
style="width: 8vw; position: absolute; z-index: 2; top: 16vw; right: 7vw"
@click="openPopup('rankingHelp')"
/>
<!-- 页面内容 -->
<div
style="
position: relative;
z-index: 2;
margin-top: 145vw;
display: flex;
flex-direction: column;
align-items: center;
"
>
<!-- 倒计时 -->
<itemCenter
style="width: 87%; min-height: 16.76vw"
:imgUrl="imageUrl('timeBg')"
:contentStyle="`direction:ltr;`"
>
<div style="width: 44%; padding: 0 22.5vw 0 5vw; display: flex; justify-content: center">
<div class="timeText" style="padding-bottom: 2vw">{{ Days }}</div>
</div>
<div
style="
padding-top: 2vw;
flex: 1;
min-width: 0;
display: flex;
justify-content: space-between;
"
>
<div style="width: 30%; display: flex; justify-content: center">
<div class="timeText" style="">{{ Hours }}</div>
</div>
<div style="width: 30%; display: flex; justify-content: center">
<div class="timeText" style="">{{ Minutes }}</div>
</div>
<div style="width: 30%; display: flex; justify-content: center">
<div class="timeText" style="">{{ Second }}</div>
</div>
</div>
</itemCenter>
<!-- 切换按钮 -->
<div
style="min-height: 14.58vw; display: flex; justify-content: space-around; margin-top: 2vw"
>
<!-- 排行榜按钮 -->
<div
style="width: 30%; position: relative; display: flex; flex-direction: column-reverse"
@click="handleBt('ranking')"
>
<img
v-show="!rankShow"
v-smart-img
:src="imageUrl(getImgName('rankBt'))"
alt=""
style="display: block; width: 100%"
/>
<img
v-show="rankShow"
v-smart-img
:src="imageUrl(getImgName('rankBtActive'))"
alt=""
style="display: block; width: 100%"
/>
</div>
<!-- 充值榜按钮 -->
<div
style="width: 30%; position: relative; display: flex; flex-direction: column-reverse"
@click="handleBt('recharge')"
>
<img
v-show="!rechargeShow"
v-smart-img
:src="imageUrl(getImgName('rechargeBt'))"
alt=""
style="display: block; width: 100%"
/>
<img
v-show="rechargeShow"
v-smart-img
:src="imageUrl(getImgName('rechargeBtActive'))"
alt=""
style="display: block; width: 100%"
/>
</div>
<!-- 抽奖按钮 -->
<div
style="width: 30%; position: relative; display: flex; flex-direction: column-reverse"
@click="handleBt('lottery')"
>
<img
v-show="!lotteryShow"
v-smart-img
:src="imageUrl(getImgName('lotteryBt'))"
alt=""
style="display: block; width: 100%"
/>
<img
v-show="lotteryShow"
v-smart-img
:src="imageUrl(getImgName('lotteryBtActive'))"
alt=""
style="display: block; width: 100%"
/>
</div>
</div>
<!-- 展示内容 -->
<div style="width: 100%">
<!-- 排行榜模块 -->
<div v-show="rankShow" style="padding-top: 4vw">
<!-- 模块按钮 -->
<div
style="
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
gap: 10vw;
"
>
<!-- 排行榜模块按钮 -->
<div style="width: 30vw; min-width: 0" @click="changeModule('ranking')">
<img
v-smart-img
:src="imageUrl(getImgName('rankingBt'))"
alt=""
:class="{
'grayscale-container': !rankingShow,
}"
style="width: 100%; display: block; object-fit: cover"
/>
</div>
<!-- 奖励模块按钮 -->
<div style="width: 30vw; min-width: 0" @click="changeModule('rewards')">
<img
v-smart-img
:src="imageUrl(getImgName('rewardsBt'))"
alt=""
:class="{
'grayscale-container': !rewardsShow,
}"
style="width: 100%; display: block; object-fit: cover"
/>
</div>
</div>
<!-- 每周礼物 -->
<itemCenter
v-show="rankingShow"
style="min-height: 73.86vw"
:imgUrl="imageUrl('eventGiftsBg')"
>
<div
style="width: 90%; display: flex; justify-content: space-around; margin-top: 10%"
>
<div
v-for="(gift, index) in giftsList"
:key="index"
style="width: 30%; display: flex; flex-direction: column"
>
<itemCenter style="min-height: 27vw" :imgUrl="imageUrl('giftBg')">
<img
:src="gift.giftPhoto"
alt=""
width="60%"
style="display: block; object-fit: cover"
/>
</itemCenter>
<div
style="display: flex; justify-content: center; align-items: center; gap: 2px"
>
<img
v-smart-img
src="/src/assets/icon/Azizi/coin.png"
alt=""
style="display: block; width: 1.3em; aspect-ratio: 1/1"
/>
<div style="color: rgba(255, 255, 255, 1); font-weight: 590">
{{ gift.giftCandy }}
</div>
</div>
</div>
</div>
</itemCenter>
<!-- 排行榜模块 -->
<div v-show="rankingShow" style="padding-top: 4vw">
<!-- 排行榜 -->
<div
style="
padding: 30vw 5vw 10vw;
position: relative;
z-index: 0;
display: flex;
flex-direction: column;
gap: 2vw;
"
>
<!-- 页面背景 -->
<div style="position: absolute; inset: 15vw 3vw 3vw; overflow: hidden">
<img
v-smart-img
:src="imageUrl('rankingImgBg')"
alt=""
style="
position: absolute;
inset: 0;
z-index: -1;
width: 94vw;
"
/>
</div>
<!-- 背景图 -->
<div
style="
position: absolute;
z-index: 0;
inset: 0;
display: flex;
flex-direction: column;
"
>
<!-- 边框头部 -->
<img
v-smart-img
:src="imageUrl('RankingTopBorder')"
alt=""
style="display: block; width: 100%; min-width: 0"
/>
<!-- 边框中部占位 -->
<div style="flex: 1; min-width: 0"></div>
<!-- 边框尾部 -->
<img
v-smart-img
:src="imageUrl('RankingBottomBorder')"
alt=""
style="display: block; width: 100%; min-width: 0"
/>
<!-- 边框中部 -->
<div
style="
position: absolute;
z-index: -1;
inset: 11vw 0 2vw;
display: flex;
flex-direction: column;
"
>
<img
v-smart-img
:src="imageUrl('RankingBorder')"
alt=""
style="display: block; width: 100%; height: 100%; min-width: 0"
/>
</div>
</div>
<!-- 前三 -->
<div>
<!-- 第一 -->
<div style="display: flex; justify-content: center">
<TopUser
rankingType="activity"
ranking="1"
:BorderImgUrl="imageUrl('top1')"
:avatarUrl="RankingHasTop3[0].avatar"
:name="RankingHasTop3[0].nickname"
:distributionValue="RankingHasTop3[0].quantity"
style="width: 45%"
@click="viewUserInfo(RankingHasTop3[0].userId)"
/>
</div>
<!-- 第二三 -->
<div
style="
position: relative;
z-index: 3;
display: flex;
justify-content: space-between;
margin-top: -40vw;
pointer-events: none;
"
>
<div
style="pointer-events: auto; width: 30%"
@click.stop="viewUserInfo(RankingHasTop3[1].userId)"
>
<TopUser
rankingType="activity"
ranking="2"
:BorderImgUrl="imageUrl('top2')"
:avatarUrl="RankingHasTop3[1].avatar"
:name="RankingHasTop3[1].nickname"
:distributionValue="RankingHasTop3[1].quantity"
style="width: 100%"
/>
</div>
<div
style="pointer-events: auto; width: 30%"
@click.stop="viewUserInfo(RankingHasTop3[2].userId)"
>
<TopUser
rankingType="activity"
ranking="3"
:BorderImgUrl="imageUrl('top3')"
:avatarUrl="RankingHasTop3[2].avatar"
:name="RankingHasTop3[2].nickname"
:distributionValue="RankingHasTop3[2].quantity"
style="width: 100%"
/>
</div>
</div>
</div>
<!-- 排行榜 -->
<div
v-for="(listItem, index) in showRanking"
:key="listItem.userId"
style="display: flex; flex-direction: column; gap: 1vw"
>
<!-- 基本信息 -->
<itemCenter
style="min-height: 20.43vw"
:imgUrl="imageUrl('itemFrom4Bg')"
:contentStyle="`padding: 0 2vw`"
:lazy="true"
@click="viewUserInfo(listItem.userId)"
>
<!-- 基本信息 -->
<div
style="
flex: 1;
min-width: 0;
display: flex;
justify-content: space-around;
align-items: center;
gap: 4px;
"
>
<!-- 排名 -->
<div style="width: 9vw; display: flex; justify-content: center">
<div style="color: #ffe601; font-weight: 700">
{{ listItem?.rank }}
</div>
</div>
<!-- 头像 -->
<div style="width: 3.5em; margin: 0 1vw; position: relative; z-index: 0">
<img
:src="listItem?.avatar || ''"
alt=""
style="
display: block;
width: 100%;
aspect-ratio: 1/1;
border-radius: 50%;
object-fit: cover;
"
@error="handleAvatarImageError"
/>
</div>
<!-- 名称id -->
<div style="flex: 1; min-width: 0; display: flex; flex-direction: column">
<!-- 滚动名称 -->
<itemCenter
style="width: 30vw; height: 10vw; min-width: 0"
:imgUrl="imageUrl('userNameBorder')"
:contentStyle="`padding:0;`"
:lazy="true"
>
<div style="width: 100%; margin-top: 1vw">
<div
style="
height: 100%;
display: flex;
align-items: center;
/* justify-content: center; */
overflow: hidden;
"
>
<!-- 滚动容器 -->
<div
v-if="isTextOverflow(listItem?.nickname || '')"
class="scroll-wrapper"
>
<!-- 2套内容 -->
<div class="scroll-content" v-for="value in 2">
<div
style="
color: #fff;
font-size: 1em;
font-weight: 860;
white-space: nowrap;
"
>
{{ listItem?.nickname }}
</div>
</div>
</div>
<div v-else style="width: 100%; text-align: center">
<div
style="
color: #fff;
font-size: 1em;
font-weight: 860;
white-space: nowrap;
"
>
{{ listItem?.nickname }}
</div>
</div>
</div>
</div>
</itemCenter>
<!-- ID -->
<div style="color: #fff; font-weight: 590" class="Textlittle">
{{ $t('user_id_prefix') }}
{{ listItem?.specialAccount || 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="color: #ffe601; font-weight: 700" class="Textlittle">
{{ listItem?.quantity || 0 }}
</div>
</div>
</itemCenter>
</div>
</div>
<!-- 触发加载功能 -->
<!-- <div ref="RankingLoadmore"></div> -->
</div>
<!-- 奖励模块 -->
<div
v-show="rewardsShow"
style="display: flex; flex-direction: column; gap: 4vw; padding: 4vw 0 10vw"
>
<itemCenter
v-for="(rewardsTop, index) in showRewardsTop3"
style="min-height: 112.26vw"
:imgUrl="imageUrl(`rewardTop${index + 1}`)"
:contentStyle="`
inset: 31vw 7vw 21vw;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
gap:6vw 4vw;
`"
>
<div
v-for="(reward, index) in rewardsTop.rewards"
style="
height: 100%;
align-self: stretch;
display: flex;
flex-direction: column;
align-items: center;
"
>
<!-- 奖品图 -->
<div
style="
width: 80%;
height: 75%;
padding: 6vw 0 2vw;
min-width: 0;
aspect-ratio: 1/1;
display: flex;
justify-content: center;
align-items: center;
"
>
<!-- 奖励图片 -->
<img
:src="reward.cover || ''"
alt=""
style="
display: block;
min-width: 0;
width: 80%;
height: 100%;
object-fit: contain;
"
@error="(e) => handleRewardImageError(e, reward.type)"
/>
</div>
<!-- 数值 -->
<div
style="
width: 80%;
height: 5.5vw;
display: flex;
justify-content: center;
align-items: center;
"
>
<div style="min-width: 0; font-size: 1em; font-weight: 590; color: #fff">
{{ formatRewardDisplay(reward.type, reward) }}
</div>
</div>
</div>
</itemCenter>
</div>
</div>
<!-- 充值排行模块 -->
<div v-show="rechargeShow" style="padding-top: 4vw">
<!-- 模块按钮 -->
<div
style="
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
gap: 10vw;
"
>
<!-- 充值排行榜模块按钮 -->
<div style="width: 30vw; min-width: 0" @click="changeModule('rechargeRank')">
<img
v-smart-img
:src="imageUrl(getImgName('rechargeRankBt'))"
alt=""
:class="{
'grayscale-container': !rechargeRankShow,
}"
style="width: 100%; display: block; object-fit: cover"
/>
</div>
<!-- 奖励模块按钮 -->
<div style="width: 30vw; min-width: 0" @click="changeModule('rechargeRewards')">
<img
v-smart-img
:src="imageUrl(getImgName('rewardsBt'))"
alt=""
:class="{
'grayscale-container': !rechargeRewardsShow,
}"
style="width: 100%; display: block; object-fit: cover"
/>
</div>
</div>
<!-- 排行榜模块 -->
<div v-show="rechargeRankShow" style="padding-top: 4vw">
<!-- 排行榜 -->
<div
style="
padding: 30vw 5vw 10vw;
position: relative;
z-index: 0;
display: flex;
flex-direction: column;
gap: 2vw;
"
>
<!-- 页面背景 -->
<div style="position: absolute; inset: 15vw 3vw 3vw; overflow: hidden">
<img
v-smart-img
:src="imageUrl('rankingImgBg')"
alt=""
style="
position: absolute;
inset: 0;
z-index: -1;
width: 94vw;
"
/>
</div>
<!-- 背景图 -->
<div
style="
position: absolute;
z-index: 0;
inset: 0;
display: flex;
flex-direction: column;
"
>
<!-- 边框头部 -->
<img
v-smart-img
:src="imageUrl('RankingTopBorder')"
alt=""
style="display: block; width: 100%; min-width: 0"
/>
<!-- 边框中部占位 -->
<div style="flex: 1; min-width: 0"></div>
<!-- 边框尾部 -->
<img
v-smart-img
:src="imageUrl('RankingBottomBorder')"
alt=""
style="display: block; width: 100%; min-width: 0"
/>
<!-- 边框中部 -->
<div
style="
position: absolute;
z-index: -1;
inset: 11vw 0 2vw;
display: flex;
flex-direction: column;
"
>
<img
v-smart-img
:src="imageUrl('RankingBorder')"
alt=""
style="display: block; width: 100%; height: 100%; min-width: 0"
/>
</div>
</div>
<!-- 前三 -->
<div>
<!-- 第一 -->
<div style="display: flex; justify-content: center">
<TopUser
rankingType="recharge"
ranking="1"
:BorderImgUrl="imageUrl('top1')"
:avatarUrl="rechargeRankingHasTop3[0].userAvatar"
:name="rechargeRankingHasTop3[0].userName"
distributionValue=""
style="width: 45%"
@click="viewUserInfo(rechargeRankingHasTop3[0].userId)"
/>
</div>
<!-- 第二三 -->
<div
style="
position: relative;
z-index: 3;
display: flex;
justify-content: space-between;
margin-top: -40vw;
pointer-events: none;
"
>
<div
style="pointer-events: auto; width: 30%"
@click.stop="viewUserInfo(rechargeRankingHasTop3[1].userId)"
>
<TopUser
rankingType="recharge"
ranking="2"
:BorderImgUrl="imageUrl('top2')"
:avatarUrl="rechargeRankingHasTop3[1].userAvatar"
:name="rechargeRankingHasTop3[1].userName"
distributionValue=""
style="width: 100%"
/>
</div>
<div
style="pointer-events: auto; width: 30%"
@click.stop="viewUserInfo(rechargeRankingHasTop3[2].userId)"
>
<TopUser
rankingType="recharge"
ranking="3"
:BorderImgUrl="imageUrl('top3')"
:avatarUrl="rechargeRankingHasTop3[2].userAvatar"
:name="rechargeRankingHasTop3[2].userName"
distributionValue=""
style="width: 100%"
/>
</div>
</div>
</div>
<!-- 排行榜 -->
<div
v-for="(listItem, index) in showRechargeRanking"
:key="listItem.userId"
style="display: flex; flex-direction: column; gap: 1vw"
>
<!-- 基本信息 -->
<itemCenter
style="min-height: 20.43vw"
:imgUrl="imageUrl('itemFrom4Bg')"
:contentStyle="`padding: 0 2vw`"
:lazy="true"
@click="viewUserInfo(listItem.userId)"
>
<!-- 基本信息 -->
<div
style="
flex: 1;
min-width: 0;
display: flex;
justify-content: space-around;
align-items: center;
gap: 4px;
"
>
<!-- 排名 -->
<div style="width: 9vw; display: flex; justify-content: center">
<div style="color: #ffe601; font-weight: 700">
{{ listItem?.rank }}
</div>
</div>
<!-- 头像 -->
<div style="width: 3.5em; margin: 0 1vw; position: relative; z-index: 0">
<img
:src="listItem?.userAvatar || ''"
alt=""
style="
display: block;
width: 100%;
aspect-ratio: 1/1;
border-radius: 50%;
object-fit: cover;
"
@error="handleAvatarImageError"
/>
</div>
<!-- 名称id -->
<div style="flex: 1; min-width: 0; display: flex; flex-direction: column">
<!-- 滚动名称 -->
<itemCenter
style="width: 30vw; height: 10vw; min-width: 0"
:imgUrl="imageUrl('userNameBorder')"
:contentStyle="`padding:0;`"
:lazy="true"
>
<div style="width: 100%; margin-top: 1vw">
<div
style="
height: 100%;
display: flex;
align-items: center;
/* justify-content: center; */
overflow: hidden;
"
>
<!-- 滚动容器 -->
<div
v-if="isTextOverflow(listItem?.userName || '')"
class="scroll-wrapper"
>
<!-- 2套内容 -->
<div class="scroll-content" v-for="value in 2">
<div
style="
color: #fff;
font-size: 1em;
font-weight: 860;
white-space: nowrap;
"
>
{{ listItem?.userName }}
</div>
</div>
</div>
<div v-else style="width: 100%; text-align: center">
<div
style="
color: #fff;
font-size: 1em;
font-weight: 860;
white-space: nowrap;
"
>
{{ listItem?.userName }}
</div>
</div>
</div>
</div>
</itemCenter>
<!-- ID -->
<div style="color: #fff; font-weight: 590" class="Textlittle">
{{ $t('user_id_prefix') }}
{{ listItem?.specialAccount || listItem?.account }}
</div>
</div>
</div>
<!-- 贡献值 -->
<div
style="
width: auto;
min-width: 0;
display: flex;
align-items: center;
"
>
<div style="color: #fff; font-weight: 700">${{ listItem?.amount }}</div>
</div>
</itemCenter>
</div>
<!-- 触发加载功能 -->
<div ref="RankingLoadmore"></div>
</div>
</div>
<!-- 充值奖励模块 -->
<div
v-show="rechargeRewardsShow"
style="display: flex; flex-direction: column; gap: 2vw; padding: 4vw 0 10vw"
>
<!-- 个人充值信息 -->
<div style="padding: 0 4vw">
<itemCenter
style="min-height: 39.05vw; z-index: 0"
:imgUrl="imageUrl('earningInfoBg')"
:flip="true"
:contentStyle="`inset:7vw 10vw 9vw 9vw;justify-content: space-between;gap: 10vw;`"
>
<!-- 头像 -->
<img
:src="myRechargeRecode?.userAvatar || ''"
alt=""
style="
position: relative;
z-index: -1;
width: 23vw;
min-width: 0;
border-radius: 50%;
aspect-ratio: 1/1;
object-fit: cover;
"
@error="handleAvatarImageError"
/>
<!-- 基本信息 -->
<div
style="
position: relative;
flex: 1;
min-width: 0;
height: 80%;
display: flex;
flex-direction: column;
justify-content: center;
gap: 1vw;
"
>
<!-- 充值帮助按钮 -->
<img
v-smart-img
src="/src/assets/icon/Azizi/helpWhite.png"
alt=""
class="ruleBt"
@click="openPopup('rechargeRankingHelp')"
/>
<!-- 名称 -->
<div
style="
max-width: 70%;
min-width: 0;
font-weight: 500;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
"
>
{{ myRechargeRecode?.userName || '' }}
</div>
<!-- 账号 -->
<div>{{ $t('user_id_prefix') }} {{ myRechargeRecode?.account }}</div>
<!-- 总充值 -->
<div
style="
display: flex;
justify-content: space-between;
align-items: center;
white-space: nowrap;
"
>
<div>
{{ t('Accumulated recharge') }}:${{
formatRechargeAmount(myRechargeRecode?.totalAmount)
}}
</div>
<img
v-show="rechargehidden"
v-smart-img
:src="imageUrl('rechargeNumHidden')"
alt=""
style="width: 5vw; display: block; object-fit: cover"
@click="rechargehidden = !rechargehidden"
/>
<img
v-show="!rechargehidden"
v-smart-img
:src="imageUrl('rechargeNumShow')"
alt=""
style="width: 5vw; display: block; object-fit: cover"
@click="rechargehidden = !rechargehidden"
/>
</div>
</div>
</itemCenter>
</div>
<!-- 充值奖励 -->
<itemCenter
:style="{ minHeight: index <= 2 ? '112.26vw' : '142.39vw' }"
v-for="(rewardsTop, index) in RechargeRewards"
style=""
:imgUrl="topImg[index]"
:contentStyle="rewardContentLayer(index)"
>
<!-- 奖励列表 -->
<div
v-for="(reward, rewardIndex) in rewardsTop.rewardProps"
:key="rewardIndex"
style="
width: 100%;
align-self: stretch;
display: flex;
flex-direction: column;
align-items: center;
"
>
<!-- 奖品图 -->
<div
style="
width: 80%;
height: 75%;
padding: 6vw 0 2vw;
min-width: 0;
aspect-ratio: 1/1;
display: flex;
justify-content: center;
align-items: center;
"
>
<!-- 奖励图片 -->
<img
:src="reward.cover || ''"
alt=""
style="
display: block;
min-width: 0;
width: 80%;
height: 100%;
object-fit: contain;
"
@error="(e) => handleRewardImageError(e, reward.type)"
/>
</div>
<!-- 数值 -->
<div
style="
width: 80%;
height: 5.5vw;
display: flex;
justify-content: center;
align-items: center;
"
>
<div style="min-width: 0; font-size: 1em; font-weight: 590; color: #fff">
{{ formatRewardDisplay(reward.type, reward) }}
</div>
</div>
</div>
<!-- 领取按钮 -->
<div
style="
position: absolute;
bottom: 7vw;
left: 0;
right: 0;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
"
>
<img
v-smart-img
v-if="rewardsTop.claimStatus == -1"
class="grayscale-container"
:src="imageUrl(getImgName('receiveBt'))"
alt=""
style="width: 40vw; display: block; object-fit: cover"
/>
<img
v-smart-img
v-if="rewardsTop.claimStatus == 0"
:src="imageUrl(getImgName('receiveBt'))"
alt=""
style="width: 40vw; display: block; object-fit: cover"
@click="receiveReward(rewardsTop)"
/>
<img
v-smart-img
v-if="rewardsTop.claimStatus == 1"
:src="imageUrl(getImgName('receivedBt'))"
alt=""
style="width: 40vw; display: block; object-fit: cover"
/>
</div>
</itemCenter>
</div>
</div>
<!-- 抽奖模块 -->
<div v-show="lotteryShow" style="padding: 4vw 0 10vw">
<!-- 模块按钮 -->
<div
style="
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
gap: 10vw;
"
>
<!-- 抽奖&任务模块按钮 -->
<div style="width: 30vw; min-width: 0" @click="changeModule('task')">
<img
v-smart-img
:src="imageUrl(getImgName('taskBt'))"
alt=""
:class="{
'grayscale-container': !taskShow,
}"
style="width: 100%; display: block; object-fit: cover"
/>
</div>
<!-- 提现模块按钮 -->
<div style="width: 30vw; min-width: 0" @click="changeModule('withdraw')">
<img
v-smart-img
:src="imageUrl(getImgName('redeemBt'))"
alt=""
:class="{
'grayscale-container': !withdrawShow,
}"
style="width: 100%; display: block; object-fit: cover"
/>
</div>
</div>
<!-- 抽奖模块 -->
<div
v-show="taskShow"
style="
width: 100vw;
position: relative;
display: flex;
flex-direction: column;
gap: 3vw;
"
>
<!-- 中奖历史按钮 -->
<img
v-smart-img
:src="imageUrl('resultBt')"
alt=""
style="width: 6vw; position: absolute; z-index: 2; top: 19.5vw; right: 1vw"
@click="openPopup('history')"
/>
<!-- 奖池 -->
<itemCenter
style="min-height: 99.73vw; margin-top: 6vw"
:imgUrl="imageUrl('lottery')"
:contentStyle="`
inset:9vw 10.5vw 9vw 10vw;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 2vw 2.5vw;
direction: ltr;`"
>
<!-- 抽奖转盘 -->
<div
v-for="(prize, index) in activity.prizeList"
style="
align-self: stretch;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
position: relative;
padding: 0;
"
:style="[getGridPosition(index)]"
>
<!-- 奖品图 -->
<div
style="
width: 70%;
flex: 1;
min-width: 0;
min-height: 0;
padding-top: 20%;
display: flex;
justify-content: center;
align-items: center;
"
>
<img
:src="prize.prizeImage || ''"
:alt="prize.prizeName || ''"
style="width: 70%; display: block; object-fit: cover"
/>
</div>
<!-- 奖励详情 -->
<div
style="
width: 100%;
height: 25%;
min-width: 0;
min-height: 0;
display: flex;
justify-content: center;
align-items: center;
"
>
<div
style="
font-size: 0.9em;
font-weight: 700;
color: #fff;
text-shadow: 0 1px 0 #339370;
white-space: nowrap;
"
>
{{ prize.prizeName }}
</div>
</div>
<!-- 转到的奖品项 -->
<img
v-smart-img
v-show="activeIndex === index"
:src="imageUrl('prizeActiveFrame')"
alt=""
style="
display: block;
width: 105%;
position: absolute;
inset: 50% 0 0 50%;
transform: translate(-50%, -50%);
"
/>
</div>
</itemCenter>
<!-- 我的抽奖券数量 -->
<div style="display: flex; justify-content: center">
<div style="font-size: 1.3em; font-weight: 600">
{{ $t('remaining_lottery_tickets') }}: {{ rollTimes }}
</div>
</div>
<!-- 抽奖按钮 -->
<div style="display: flex; justify-content: center; gap: 4vw" class="drawBts">
<!-- 单抽 -->
<itemCenter
style="min-height: 20.11vw; width: 45vw"
:imgUrl="imageUrl('draw1BtBg')"
:contentStyle="``"
@click="sweepstakes(1)"
>
<div style="color: #fff; font-size: 2em; font-weight: 600">
{{ $t('single_spin') }}
</div>
</itemCenter>
<!-- 10连抽 -->
<itemCenter
style="min-height: 20.11vw; width: 45vw"
:imgUrl="imageUrl('draw10BtBg')"
:contentStyle="``"
@click="sweepstakes(10)"
>
<div style="color: #fff; font-size: 2em; font-weight: 600">
{{ $t('ten_spin') }}
</div>
</itemCenter>
</div>
<!-- 任务列表 -->
<div
style="
position: relative;
z-index: 2;
margin: 0 4vw;
border-radius: 12px;
background:
linear-gradient(
99deg,
rgba(211, 212, 213, 0.15) 12.86%,
rgba(139, 145, 147, 0.15) 15.34%,
rgba(87, 95, 99, 0.15) 17.82%,
rgba(55, 65, 69, 0.15) 18.64%,
rgba(43, 54, 58, 0.15) 19.47%,
rgba(52, 62, 66, 0.15) 22.77%,
rgba(77, 85, 89, 0.15) 26.9%,
rgba(117, 123, 126, 0.15) 32.68%,
rgba(173, 176, 177, 0.15) 38.46%,
rgba(205, 205, 206, 0.15) 41.76%,
rgba(198, 199, 200, 0.15) 43.41%,
rgba(180, 182, 184, 0.15) 45.06%,
rgba(151, 156, 158, 0.15) 46.71%,
rgba(111, 118, 122, 0.15) 49.19%,
rgba(72, 83, 87, 0.15) 50.84%,
rgba(76, 86, 90, 0.15) 52.49%,
rgba(89, 98, 102, 0.15) 54.97%,
rgba(112, 117, 120, 0.15) 57.45%,
rgba(143, 144, 146, 0.15) 59.1%,
rgba(152, 152, 154, 0.15) 59.92%,
rgba(165, 165, 166, 0.15) 63.23%,
rgba(199, 199, 200, 0.15) 70.66%,
rgba(255, 255, 255, 0.15) 78.91%,
rgba(209, 209, 210, 0.15) 81.39%,
rgba(79, 79, 83, 0.15) 87.17%,
rgba(27, 27, 32, 0.15) 90.47%,
rgba(49, 49, 54, 0.15) 91.3%,
rgba(77, 77, 81, 0.15) 92.12%,
rgba(116, 116, 118, 0.15) 92.95%,
rgba(165, 165, 167, 0.15) 94.6%,
rgba(233, 233, 233, 0.15) 95.43%
),
linear-gradient(0deg, #1f0f67 0%, #1f0f67 100%), #e8e8e8;
background-blend-mode: hard-light, normal, normal;
padding: 12px;
display: flex;
flex-direction: column;
gap: 12px;
"
>
<div style="font-weight: 590">{{ t('Task for tickets') }}</div>
<div
v-for="task in taskList"
style="
border-radius: 8px;
border: 1px solid rgba(64, 64, 64, 0.5);
background: rgba(240, 240, 240, 0.3);
box-shadow:
-42px 103px 31px 0 rgba(145, 145, 145, 0),
-27px 66px 29px 0 rgba(145, 145, 145, 0.01),
-15px 37px 24px 0 rgba(145, 145, 145, 0.03),
-7px 17px 18px 0 rgba(145, 145, 145, 0.04),
-2px 4px 10px 0 rgba(145, 145, 145, 0.05);
backdrop-filter: blur(7.5px);
display: flex;
padding: 8px;
justify-content: space-between;
align-items: center;
"
>
<!-- 图标 -->
<div style="width: 20%">
<img
v-if="task.taskType == 1"
v-smart-img
:src="imageUrl('taskTalk')"
alt=""
width="100%"
style="display: block"
/>
<img
v-if="task.taskType == 2"
v-smart-img
:src="imageUrl('taskGift')"
alt=""
width="100%"
style="display: block"
/>
<img
v-if="task.taskType == 4"
v-smart-img
:src="imageUrl('taskGame')"
alt=""
width="100%"
style="display: block"
/>
<img
v-if="task.taskType == 5"
v-smart-img
:src="imageUrl('taskRecharge')"
alt=""
width="100%"
style="display: block"
/>
</div>
<!-- 内容 -->
<div style="width: 60%">
<!-- 任务进度 -->
<div style="color: #fff; font-weight: 590; font-size: 0.9em">
{{ showTarget(task) }}
</div>
<!-- 任务奖励 -->
<div style="display: flex; align-items: center; gap: 8px">
<div style="color: #fff; font-weight: 590">{{ t('Rewards:') }}</div>
<img
v-smart-img
:src="imageUrl('ticket')"
:alt="t('ticket')"
width="15%"
style="display: block"
/>
<div style="color: #fff; font-weight: 590">*{{ task.rewardValue }}</div>
</div>
</div>
<!-- 按钮 -->
<div style="width: 20%">
<!-- 前往任务 -->
<itemCenter
v-if="task.taskStatus == 0"
style="min-height: 7.79vw"
:imgUrl="imageUrl('taskBtGo')"
>
<div style="font-size: 1em; font-weight: 600; white-space: nowrap">
{{ t('task_go') }}
</div>
</itemCenter>
<!-- 领取抽奖券 -->
<itemCenter
v-else-if="task.taskStatus === 1"
style="min-height: 7.79vw"
:imgUrl="imageUrl('taskBtReceive')"
@click="receiveTaskReward(task.taskCode)"
>
<div style="font-size: 1em; font-weight: 600; white-space: nowrap">
{{ t('task_receive') }}
</div>
</itemCenter>
<!-- 已完成 -->
<itemCenter
v-else
style="min-height: 7.79vw"
:imgUrl="imageUrl('taskBtReceived')"
>
<div style="font-size: 0.9em; font-weight: 600; white-space: nowrap">
{{ t('task_received') }}
</div>
</itemCenter>
</div>
</div>
</div>
</div>
<!-- 收益模块 -->
<div
v-show="withdrawShow"
style="width: 100%; padding: 4vw; display: flex; flex-direction: column; gap: 3vw"
>
<!-- 个人信息 -->
<div
style="
border-radius: 12px;
background:
linear-gradient(
99deg,
rgba(211, 212, 213, 0.15) 12.86%,
rgba(139, 145, 147, 0.15) 15.34%,
rgba(87, 95, 99, 0.15) 17.82%,
rgba(55, 65, 69, 0.15) 18.64%,
rgba(43, 54, 58, 0.15) 19.47%,
rgba(52, 62, 66, 0.15) 22.77%,
rgba(77, 85, 89, 0.15) 26.9%,
rgba(117, 123, 126, 0.15) 32.68%,
rgba(173, 176, 177, 0.15) 38.46%,
rgba(205, 205, 206, 0.15) 41.76%,
rgba(198, 199, 200, 0.15) 43.41%,
rgba(180, 182, 184, 0.15) 45.06%,
rgba(151, 156, 158, 0.15) 46.71%,
rgba(111, 118, 122, 0.15) 49.19%,
rgba(72, 83, 87, 0.15) 50.84%,
rgba(76, 86, 90, 0.15) 52.49%,
rgba(89, 98, 102, 0.15) 54.97%,
rgba(112, 117, 120, 0.15) 57.45%,
rgba(143, 144, 146, 0.15) 59.1%,
rgba(152, 152, 154, 0.15) 59.92%,
rgba(165, 165, 166, 0.15) 63.23%,
rgba(199, 199, 200, 0.15) 70.66%,
rgba(255, 255, 255, 0.15) 78.91%,
rgba(209, 209, 210, 0.15) 81.39%,
rgba(79, 79, 83, 0.15) 87.17%,
rgba(27, 27, 32, 0.15) 90.47%,
rgba(49, 49, 54, 0.15) 91.3%,
rgba(77, 77, 81, 0.15) 92.12%,
rgba(116, 116, 118, 0.15) 92.95%,
rgba(165, 165, 167, 0.15) 94.6%,
rgba(233, 233, 233, 0.15) 95.43%
),
linear-gradient(0deg, #1f0f67 0%, #1f0f67 100%), #e8e8e8;
background-blend-mode: hard-light, normal, normal;
padding: 16px 12px;
display: flex;
align-items: center;
gap: 8px;
position: relative;
"
>
<!-- 头像 -->
<img
:src="userInfo.userAvatar || ''"
alt=""
style="
width: 12vw;
min-width: 0;
border-radius: 50%;
aspect-ratio: 1/1;
object-fit: cover;
"
@error="handleAvatarImageError"
/>
<!-- 基本信息 -->
<div
style="
flex: 1;
min-width: 0;
align-self: stretch;
display: flex;
flex-direction: column;
justify-content: space-around;
gap: 4px;
"
>
<!-- 帮助按钮 -->
<!-- <img
v-smart-img
src="/src/assets/icon/Azizi/helpWhite.png"
alt=""
class="ruleBt"
@click="openPopup('withdrawalHelp')"
/> -->
<!-- 名称 -->
<div
style="
max-width: 70%;
min-width: 0;
font-weight: 500;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
"
>
{{ userInfo.userNickname || '' }}
</div>
<!-- <div style="display: flex; justify-content: space-between; align-items: center">
<div style="min-width: 0">
{{ $t('user_id_prefix') }} {{ userInfo.account || '' }}
</div>
<div style="width: auto; font-weight: 600">
{{ t('current_earnings', { amount: currentAmount.availableAmount }) }}
</div>
</div> -->
<div style="display: flex; align-items: center; gap: 2px">
<div style="font-weight: 600">{{ t('current_earnings_label') }}</div>
<img
v-smart-img
src="/src/assets/icon/Azizi/dollar.png"
alt=""
style="display: block; width: 1.5em; object-fit: cover"
/>
<div style="font-size: 1.2em; font-weight: 600">
{{ currentAmount.availableAmount }}
</div>
</div>
</div>
</div>
<!-- 操作抽屉 -->
<div
style="
border-radius: 12px;
background:
linear-gradient(
99deg,
rgba(211, 212, 213, 0.15) 12.86%,
rgba(139, 145, 147, 0.15) 15.34%,
rgba(87, 95, 99, 0.15) 17.82%,
rgba(55, 65, 69, 0.15) 18.64%,
rgba(43, 54, 58, 0.15) 19.47%,
rgba(52, 62, 66, 0.15) 22.77%,
rgba(77, 85, 89, 0.15) 26.9%,
rgba(117, 123, 126, 0.15) 32.68%,
rgba(173, 176, 177, 0.15) 38.46%,
rgba(205, 205, 206, 0.15) 41.76%,
rgba(198, 199, 200, 0.15) 43.41%,
rgba(180, 182, 184, 0.15) 45.06%,
rgba(151, 156, 158, 0.15) 46.71%,
rgba(111, 118, 122, 0.15) 49.19%,
rgba(72, 83, 87, 0.15) 50.84%,
rgba(76, 86, 90, 0.15) 52.49%,
rgba(89, 98, 102, 0.15) 54.97%,
rgba(112, 117, 120, 0.15) 57.45%,
rgba(143, 144, 146, 0.15) 59.1%,
rgba(152, 152, 154, 0.15) 59.92%,
rgba(165, 165, 166, 0.15) 63.23%,
rgba(199, 199, 200, 0.15) 70.66%,
rgba(255, 255, 255, 0.15) 78.91%,
rgba(209, 209, 210, 0.15) 81.39%,
rgba(79, 79, 83, 0.15) 87.17%,
rgba(27, 27, 32, 0.15) 90.47%,
rgba(49, 49, 54, 0.15) 91.3%,
rgba(77, 77, 81, 0.15) 92.12%,
rgba(116, 116, 118, 0.15) 92.95%,
rgba(165, 165, 167, 0.15) 94.6%,
rgba(233, 233, 233, 0.15) 95.43%
),
linear-gradient(0deg, #1f0f67 0%, #1f0f67 100%), #e8e8e8;
background-blend-mode: hard-light, normal, normal;
padding: 12px;
font-weight: 600;
display: flex;
flex-direction: column;
gap: 8px;
"
>
<!-- 转账功能 -->
<div
style="display: flex; justify-content: space-between; align-items: center"
@click="drawerShowBt('transfer')"
v-if="userIdentity.anchor"
>
<div>{{ t('transfer') }}</div>
<img
v-smart-img
class="flipImg"
src="/src/assets/icon/Azizi/arrowWhite.png"
alt=""
style="width: 1em; display: block; transition: all 0.2s ease"
:class="{ rotated: transferShow }"
/>
</div>
<!-- 转账抽屉 -->
<transition name="drawer">
<div
v-if="transferShow"
style="
background-color: transparent;
display: flex;
flex-direction: column;
gap: 12px;
"
>
<!-- 转账对象 -->
<div
v-if="selectedPayee.id"
style="
border-radius: 8px;
border: 1px solid rgba(64, 64, 64, 0.5);
background: rgba(240, 240, 240, 0.3);
box-shadow:
-42px 103px 31px 0 rgba(145, 145, 145, 0),
-27px 66px 29px 0 rgba(145, 145, 145, 0.01),
-15px 37px 24px 0 rgba(145, 145, 145, 0.03),
-7px 17px 18px 0 rgba(145, 145, 145, 0.04),
-2px 4px 10px 0 rgba(145, 145, 145, 0.05);
backdrop-filter: blur(7.5px);
padding: 12px;
"
>
<!-- 基本信息 -->
<div style="display: flex; align-items: center">
<!-- 头像 -->
<div style="position: relative; width: 50px; margin-right: 12px">
<img
:src="selectedPayee.avatar || ''"
:alt="selectedPayee.name || ''"
style="width: 100%; object-fit: cover; border-radius: 50%"
@error="handleAvatarImageError"
/>
</div>
<!-- 个人信息 -->
<div style="flex: 1">
<div style="margin: 0 0 4px 0; font-weight: 700">
{{ selectedPayee.name || '' }}
</div>
<div style="margin: 0; font-size: 0.9em; font-weight: 500">
{{ $t('user_id_prefix') }} {{ selectedPayee.account || '' }}
</div>
</div>
<!-- 换人按钮 -->
<button
style="
border-radius: 12px;
background: linear-gradient(
152deg,
rgba(198, 112, 255, 0.6) 7.01%,
rgba(119, 38, 255, 0.6) 92.99%
);
border: none;
font-weight: 500;
padding: 2px 8px;
"
@click="searchPayee"
>
{{ t('change') }}
</button>
</div>
<!-- 身份图标 -->
<div style="margin-left: 50px; display: flex; gap: 5px">
<img
v-if="selectedPayee.isHost"
v-smart-img
src="/src/assets/icon/identity/host.png"
alt=""
width="30%"
/>
<img
v-if="selectedPayee.isAgency"
v-smart-img
src="/src/assets/icon/identity/agency.png"
alt=""
width="30%"
style="display: block"
/>
<img
v-if="selectedPayee.hasSalary"
v-smart-img
src="/src/assets/icon/identity/coinSeller.png"
alt=""
width="30%"
/>
</div>
</div>
<!-- 空状态 - 默认显示 -->
<div
v-else
style="
display: flex;
justify-content: center;
align-items: center;
border-radius: 8px;
border: 1px solid rgba(64, 64, 64, 0.5);
background: rgba(240, 240, 240, 0.3);
box-shadow:
-42px 103px 31px 0 rgba(145, 145, 145, 0),
-27px 66px 29px 0 rgba(145, 145, 145, 0.01),
-15px 37px 24px 0 rgba(145, 145, 145, 0.03),
-7px 17px 18px 0 rgba(145, 145, 145, 0.04),
-2px 4px 10px 0 rgba(145, 145, 145, 0.05);
backdrop-filter: blur(7.5px);
padding: 12px 0;
"
>
<div
style="
font-weight: 590;
padding: 16px 24px;
border-radius: 20px;
border: 1px solid rgba(156, 156, 156, 0.5);
background: rgba(240, 240, 240, 0.1);
box-shadow:
0 -5px 4px 0 rgba(255, 255, 255, 0.25) inset,
0 4px 4px 0 rgba(255, 255, 255, 0.25) inset,
-42px 103px 31px 0 rgba(145, 145, 145, 0),
-27px 66px 29px 0 rgba(145, 145, 145, 0.01),
-15px 37px 24px 0 rgba(145, 145, 145, 0.03),
-7px 17px 18px 0 rgba(145, 145, 145, 0.04),
-2px 4px 10px 0 rgba(145, 145, 145, 0.05);
backdrop-filter: blur(10px);
"
@click="searchPayee"
>
{{ t('select') }}
</div>
</div>
<!-- 转账金额选择 -->
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px">
<div
v-for="coin in coinOptions"
:key="coin.id"
@click="selectCoin(coin)"
:class="['coin-item', { selected: selectedCoin?.id === coin.id }]"
>
<img
v-smart-img
src="/src/assets/icon/Azizi/dollar.png"
alt=""
style="width: 40%"
/>
<div style="font-weight: 500; color: #fff">{{ coin.price }}</div>
</div>
</div>
<!-- 转账按钮 -->
<div style="display: flex; justify-content: center; align-items: center">
<div
style="
width: 70%;
padding: 12px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 20px;
border: 1px solid rgba(156, 156, 156, 0.5);
background: rgba(240, 240, 240, 0.3);
box-shadow:
0 -5px 4px 0 rgba(255, 255, 255, 0.25) inset,
0 4px 4px 0 rgba(255, 255, 255, 0.25) inset,
-42px 103px 31px 0 rgba(145, 145, 145, 0),
-27px 66px 29px 0 rgba(145, 145, 145, 0.01),
-15px 37px 24px 0 rgba(145, 145, 145, 0.03),
-7px 17px 18px 0 rgba(145, 145, 145, 0.04),
-2px 4px 10px 0 rgba(145, 145, 145, 0.05);
backdrop-filter: blur(10px);
font-weight: 590;
"
@click="transfer"
:disabled="!selectedCoin || !selectedPayee.value?.id"
>
{{ t('transfer') }}
</div>
</div>
</div>
</transition>
<!-- 兑换金币 -->
<div
style="display: flex; justify-content: space-between; align-items: center"
@click="drawerShowBt('exchange')"
>
<div>{{ t('exchange_gold_coins') }}</div>
<img
v-smart-img
class="flipImg"
src="/src/assets/icon/Azizi/arrowWhite.png"
alt=""
style="width: 1em; display: block; transition: all 0.2s ease"
:class="{ rotated: exchangeShow }"
/>
</div>
<!-- 兑换金币抽屉 -->
<transition name="drawer">
<div
v-if="exchangeShow"
style="
background-color: transparent;
display: flex;
flex-direction: column;
gap: 12px;
"
>
<!-- 转账金额选择 -->
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px">
<div
v-for="coin in coinOptions"
:key="coin.id"
@click="selectCoin(coin)"
:class="['coin-item', { selected: selectedCoin?.id == coin.id }]"
>
<img
v-smart-img
src="/src/assets/icon/Azizi/coin.png"
alt=""
style="width: 40%"
/>
<div style="font-size: 0.7em">{{ coin.amount }} coins x1</div>
<div style="display: flex; align-items: center; gap: 2px">
<img
v-smart-img
src="/src/assets/icon/Azizi/dollar.png"
alt=""
style="display: block; width: 1.5em; object-fit: cover"
/>
<div style="font-weight: 500; color: #fff">x{{ coin.price }}</div>
</div>
</div>
</div>
<!-- 转账按钮 -->
<div style="display: flex; justify-content: center; align-items: center">
<div
style="
width: 70%;
padding: 12px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 20px;
border: 1px solid rgba(156, 156, 156, 0.5);
background: rgba(240, 240, 240, 0.3);
box-shadow:
0 -5px 4px 0 rgba(255, 255, 255, 0.25) inset,
0 4px 4px 0 rgba(255, 255, 255, 0.25) inset,
-42px 103px 31px 0 rgba(145, 145, 145, 0),
-27px 66px 29px 0 rgba(145, 145, 145, 0.01),
-15px 37px 24px 0 rgba(145, 145, 145, 0.03),
-7px 17px 18px 0 rgba(145, 145, 145, 0.04),
-2px 4px 10px 0 rgba(145, 145, 145, 0.05);
backdrop-filter: blur(10px);
font-weight: 590;
"
:disabled="!selectedCoin || !selectedPayee.value?.id"
@click="exchangeCoinBt"
>
{{ t('exchange') }}
</div>
</div>
</div>
</transition>
<!-- 提取现金 -->
<div
style="display: flex; justify-content: space-between; align-items: center"
@click="goToWithdraw"
v-if="currentAmount.availableAmount >= 10"
>
<div>{{ t('go_to_withdraw') }}</div>
<img
v-smart-img
class="flipImg"
src="/src/assets/icon/Azizi/arrowWhite.png"
alt=""
style="width: 1em; display: block"
/>
</div>
</div>
</div>
</div>
</div>
<!-- 我的排名占位 -->
<div
v-show="(rankShow && rankingShow) || (rechargeShow && rechargeRankShow)"
style="height: 25vw"
></div>
<!-- 我的排名 -->
<itemCenter
v-show="(rankShow && rankingShow) || (rechargeShow && rechargeRankShow)"
style="min-height: 22.3vw; position: fixed; bottom: -1px; z-index: 3"
:imgUrl="imageUrl('myRankingBg')"
:contentStyle="`padding: 1vw 3vw 0`"
>
<!-- 基本信息 -->
<div
style="
flex: 1;
min-width: 0;
display: flex;
justify-content: space-around;
align-items: center;
gap: 8px;
"
>
<!-- 排名 -->
<div style="width: 10vw; display: flex; justify-content: center">
<div style="color: #ffe601; font-weight: 700">
{{ (rankShow ? myRanking.rank : myRechargeRanking.rank) || 999 }}
</div>
</div>
<!-- 头像 -->
<img
:src="(rankShow ? myRanking.avatar : myRechargeRanking.userAvatar) || ''"
alt=""
style="
display: block;
width: 4em;
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="display: flex; min-width: 0">
<div
style="
color: #fff;
font-size: 1em;
font-weight: 860;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
direction: ltr;
"
>
{{ rankShow ? myRanking.nickname : myRechargeRanking.userName }}
</div>
</div>
</div>
</div>
<!-- 贡献值 -->
<div
style="
width: auto;
min-width: 0;
display: flex;
align-items: center;
"
>
<div
v-if="rankShow"
style="display: flex; justify-content: center; 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="color: #ffe601; font-weight: 700">
{{ myRanking.quantity || 0 }}
</div>
</div>
<div v-else style="color: #fff; font-weight: 700">
${{ myRechargeRanking?.amount || 0 }}
</div>
</div>
</itemCenter>
<!-- 弹窗遮罩层 -->
<maskLayer :maskLayerShow="maskLayerShow" @click="closedPopup">
<!-- 居中弹窗 -->
<div
style="
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
"
@click="closedPopup"
>
<!-- 抽奖结果 -->
<div v-show="resultShow" style="position: relative; width: 90%" @click.stop>
<itemCenter
style="min-height: 92.39vw"
:imgUrl="imageUrl('resultBg')"
:contentStyle="`inset: 20vw 7vw 8vw;
flex-direction: column;
justify-content: space-between;
gap:2vw`"
>
<!-- 奖品图展示 -->
<div
style="
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
height: 45vw;
"
>
<!-- 上一个奖品 -->
<div
style="
width: 8vw;
align-self: stretch;
display: flex;
justify-content: center;
align-items: center;
"
>
<img
v-smart-img
class="flipImg"
v-show="result.length > 1 && resultShowIndex > 0"
:src="imageUrl('resultBack')"
alt=""
style="display: block; width: 80%; object-fit: cover"
@click="resultShowIndex--"
/>
</div>
<!-- 奖品 -->
<img
:src="result[resultShowIndex]?.prize?.prizeImage"
alt=""
width="50%"
style="display: block"
/>
<!-- 下一个奖品 -->
<div
style="
width: 8vw;
align-self: stretch;
display: flex;
justify-content: center;
align-items: center;
"
>
<img
v-smart-img
class="flipImg"
v-show="result.length > 1 && resultShowIndex + 1 < result.length"
:src="imageUrl('resultNext')"
alt=""
style="display: block; width: 80%; object-fit: cover"
@click="resultShowIndex++"
/>
</div>
</div>
<!-- 奖品说明 -->
<div
style="
width: 100%;
height: 5vw;
text-align: center;
font-size: 1.2em;
font-weight: 590;
position: relative;
color: #efd47a;
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
"
>
{{ t('you_get') }} {{ result[resultShowIndex]?.prize?.prizeName }}
<div v-if="result.length > 1" class="resultNum">
{{ resultShowIndex + 1 }} / {{ result.length }}
</div>
</div>
<!-- 关闭弹窗按钮 -->
<div
style="
display: block;
width: 30vw;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
user-select: none;
touch-action: manipulation;
"
@click="closedPopup"
@touchend="closedPopup"
>
<img
v-smart-img
:src="imageUrl('resultGoOnBt')"
alt=""
style="display: block; width: 100%; object-fit: cover; pointer-events: none"
/>
</div>
</itemCenter>
</div>
<!-- 中奖历史 -->
<div v-show="historyShow" style="position: relative; width: 95%" @click.stop>
<itemCenter
style="min-height: 97.53vw"
:imgUrl="imageUrl('historyBg')"
:contentStyle="`padding: 22vw 6vw 11vw;`"
>
<div
style="
width: 100%;
height: 100%;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 8px;
"
class="scrollY"
>
<div
v-for="(record, index) in myRecords"
style="
border-radius: 8px;
border: 1px solid rgba(64, 64, 64, 0.5);
background: rgba(240, 240, 240, 0.3);
box-shadow:
-42px 103px 31px 0 rgba(145, 145, 145, 0),
-27px 66px 29px 0 rgba(145, 145, 145, 0.01),
-15px 37px 24px 0 rgba(145, 145, 145, 0.03),
-7px 17px 18px 0 rgba(145, 145, 145, 0.04),
-2px 4px 10px 0 rgba(145, 145, 145, 0.05);
backdrop-filter: blur(7.5px);
display: flex;
padding: 12px;
justify-content: space-between;
align-items: center;
"
>
<div style="display: flex; align-items: center; gap: 4px">
<img
:src="record?.prize?.prizeImage || ''"
alt=""
style="width: 10vw; min-width: 0; object-fit: cover; display: block"
/>
<div
style="font-weight: 590; font-size: 0.9em; direction: ltr; text-align: left"
>
{{ record?.prize?.prizeName }}
</div>
</div>
<div
style="font-weight: 510; font-size: 0.8em; direction: ltr; text-align: left"
>
{{ formatUTCCustom(record.drawTime) }}
</div>
</div>
</div>
</itemCenter>
</div>
<!-- 排行榜帮助弹窗 -->
<div v-show="rankingHelpShow" style="position: relative; z-index: 0" @click.stop>
<!-- 关闭按钮 -->
<img
v-smart-img
:src="imageUrl('closeBt')"
alt=""
style="width: 8vw; position: absolute; z-index: 9; top: -5vw; right: 3vw"
@click="closedPopup"
/>
<itemCenter
style="min-height: 142.39vw"
:imgUrl="imageUrl(getImgName('helpBg'))"
:contentStyle="`inset:27vw 6vw 10vw;overflow-y: auto;display:block;`"
>
<div class="helpInfo">
<p>{{ $t('ranking_help_rule_1') }}</p>
<p>{{ $t('ranking_help_rule_2') }}</p>
<p>{{ $t('ranking_help_rule_3') }}</p>
<p>{{ $t('ranking_help_rule_4') }}</p>
<p>{{ $t('ranking_help_rule_5') }}</p>
<p>{{ $t('ranking_help_rule_6') }}</p>
<p style="color: darkgray">{{ $t('activity_apple_disclaimer') }}</p>
</div>
</itemCenter>
</div>
<!-- 充值奖励帮助弹窗 -->
<div v-show="rechargeRankingHelpShow" @click.stop>
<itemCenter
style="min-height: 112.26vw"
:imgUrl="imageUrl('rechargeHelpBg')"
:contentStyle="`inset:26vw 6vw 11vw;overflow-y: auto;display:block;`"
>
<div class="helpInfo">
<p>{{ $t('recharge_help_rule_1') }}</p>
<p>{{ $t('recharge_help_rule_2') }}</p>
<p>{{ $t('recharge_help_rule_3') }}</p>
</div>
</itemCenter>
</div>
<!-- 兑换规则弹窗 -->
<div v-show="withdrawalHelpShow" @click.stop>
<itemCenter
style="min-height: 103.46vw"
:imgUrl="imageUrl('withdrawHelpBg')"
:contentStyle="`inset:27vw 6vw 10vw;overflow-y: auto;display:block;`"
>
<div class="helpInfo">
<p>{{ $t('withdrawal_help_rule_1') }}</p>
<p>{{ $t('withdrawal_help_rule_2') }}</p>
<p>{{ $t('withdrawal_help_rule_3') }}</p>
</div>
</itemCenter>
</div>
</div>
</maskLayer>
</div>
</div>
</div>
</template>
<script setup>
import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue'
import { connectToApp } from '@/utils/appConnector.js'
import { useRoute, useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { setDocumentDirection } from '@/locales/i18n'
import { viewUserInfo } from '@/utils/appBridge.js'
import { useLangStore } from '@/stores/lang'
import { getPngUrl } from '@/config/imagePaths.js'
import { toCssBackgroundImage } from '@/utils/protectedAssets.js'
import { preloadImages, preloadImagesIdle } from '@/utils/image/imagePreloader.js'
import { setUserInfo } from '@/utils/userStore.js'
import { formatUTCCustom } from '@/utils/utcFormat.js'
import { showError, showMessage, showSuccess } from '@/utils/toast.js'
import { handleAvatarImageError, handleRewardImageError } from '@/utils/image/imageHandler.js'
import { getSelectedPayee, clearSelectedPayee } from '@/utils/payeeStore.js'
import { useThrottle } from '@/utils/useDebounce'
import { formatRewardDisplay } from '@/utils/rewardFormatter.js'
import { getMemberProfile, getUserIdentity } from '@/api/wallet'
import {
getThisWeekRewardsAndGifts,
getRankingListAndMyRanking,
getOverallRankingTop3, // 获取总榜前三
} from '@/api/activity.js'
import {
ranklist, //获取排行榜
activityDetail, // 获取活动详情
myRecharge, // 获取充值记录
activityRewardConfigs, // 获取活动奖励配置列表
myTickets, // 获取剩余中奖券
myTotalDrawCount, // 获取我的累计抽奖次数
onceDraw, // 执行单次抽奖
multiDraw, // 执行连抽
drawRecords, // 获取中奖记录
ActTaskList, // 获取任务列表
rewardConfigsBadge, // 获取累计抽奖-徽章信息
receiveTickets, // 领取任务奖励
receiveRechargeReward, // 领取充值奖励
receiveRewardBadge, // 领取累计抽奖奖励-徽章
winnerHistory, //获取历史中奖用户
withdrawableAmount, //获取可提现金额
transferActivityDollar, // 转账活动美金
exchangeCoin, //兑换代币
} from '@/api/lottery'
import BackgroundLayer from '@/components/BackgroundLayer.vue'
import TopUser from './components/topUser.vue'
import itemCenter from '@/components/itemCenter.vue'
import maskLayer from '@/components/MaskLayer.vue'
const isLoading = ref(true) // 预加载状态
const { t, locale } = useI18n()
const router = useRouter()
const route = useRoute()
const langStore = useLangStore()
// 当前语言类型
const currentLangType = computed(() => {
return langStore.selectedLang?.type || 'en'
})
// 获取OSS图片URL的函数
const imageUrl = (filename) => getPngUrl('Activities/LesserBairam/', filename)
// 根据语言获取图片名
const getImgName = (filename) => {
return currentLangType.value == 'en' ? filename : `${filename}_${currentLangType.value}`
}
// 倒计时
const Days = ref(0)
const Hours = ref(0)
const Minutes = ref(0)
const Second = ref(0)
let timer = null
// 弹窗展示
const rankingHelpShow = ref(false) // 排行榜帮助弹窗
const rechargeRankingHelpShow = ref(false) // 充值排行榜帮助弹窗
const withdrawalHelpShow = ref(false) // 提现帮助弹窗
const resultShow = ref(false) // 抽奖结果
const historyShow = ref(false) // 历史
const maskLayerShow = computed(() => {
return (
rankingHelpShow.value ||
rechargeRankingHelpShow.value ||
withdrawalHelpShow.value ||
resultShow.value ||
historyShow.value
)
})
// 模块切换展示
const rankShow = ref(true) // 排行榜标签页
const rechargeShow = ref(false) // 充值标签页
const lotteryShow = ref(false) // 抽奖标签页
// 标签页切换
const rankingShow = ref(true) // 排行标签页
const rewardsShow = ref(false) // 奖励标签页
const rechargeRankShow = ref(true) // 充值排行标签页
const rechargeRewardsShow = ref(false) // 充值奖励标签页
const taskShow = ref(true) // 抽奖&任务标签页
const withdrawShow = ref(false) // 提现标签页
// 抽屉展示
const transferShow = ref(false) //转账
const exchangeShow = ref(false) //兑换
const selectedCoin = ref(null) // 选择的币种
const barrageList = ref([]) // 弹幕数据
// 排名模块
const Ranking = ref([]) // 原始排行榜
const myRanking = ref({}) // 我的排名
const rankingPageNo = ref(1) //分页页码
const rankingAdd = ref([]) //加载排行榜项
// 完整排行榜
const rankingTotal = computed(() => {
return [...Ranking.value, ...rankingAdd.value]
})
// 排行榜前3名
const RankingHasTop3 = computed(() => {
let RankingTop3 = rankingTotal.value.filter((_, index) => index < 3)
if (RankingTop3.length < 3) {
let addNullUser = Array.from({ length: 3 - RankingTop3.length }, () => ({
avatar: '',
nickname: '',
account: '',
amount: '',
}))
RankingTop3.push(...addNullUser)
}
return RankingTop3
})
// 排行榜4名开始
const showRanking = computed(() => {
return rankingTotal.value.filter((_, index) => index >= 3)
// return []
})
const rewardsTop3 = ref([]) // 原前3名奖励列表
// 处理后的前3名奖励列表
const showRewardsTop3 = computed(() => {
let newRewardsTop3 = JSON.parse(JSON.stringify(rewardsTop3.value)) // 对 rewardsTop3 进行深拷贝,避免引用问题
return newRewardsTop3
})
// 充值排名模块
const rechargePageNo = ref(1) // 充值排名页码
const rechargeRanking = ref([]) // 充值排名
const addRechargeRanking = ref([]) // 补充的充值排名
const RankingLoadmore = ref(null) //触底模块
const myRechargeRanking = ref({}) // 我的充值排名
// 完整充值排行榜
const rechargeRankingTotal = computed(() => {
return [...rechargeRanking.value, ...addRechargeRanking.value]
})
// 充值排行榜前3名
const rechargeRankingHasTop3 = computed(() => {
let RankingTop3 = rechargeRankingTotal.value.filter((_, index) => index < 3)
if (RankingTop3.length < 3) {
let addNullUser = Array.from({ length: 3 - RankingTop3.length }, () => ({
userAvatar: '',
userName: '',
amount: '',
}))
RankingTop3.push(...addNullUser)
}
return RankingTop3
})
// 排行榜4名开始
const showRechargeRanking = computed(() => {
return rechargeRankingTotal.value.filter((_, index) => index >= 3)
// return []
})
// 充值奖池模块
const myRechargeRecode = ref([]) // 我的充值记录
const RechargeRewards = ref([]) // 充值奖池
const giftsList = ref([]) // 礼物列表
const activity = ref({}) //活动详情和奖池
const activeIndex = ref(0) // 当前高亮格子
const isRolling = ref(false) // 抽奖状态
const rollTimes = ref(0) // 拥有抽奖券量
const totalDraw = ref({}) // 我的总抽奖次数
const currentAmount = ref({ availableAmount: 0 }) //可提现金额
const result = ref([]) // 抽奖结果
const resultShowIndex = ref(0)
const myRecords = ref([]) // 抽奖记录
const userInfo = ref({}) //用户信息
const userIdentity = ref({}) //用户身份
const taskList = ref([]) //任务列表
// 活动截止时间(北京时间 3 月 19 号早上 5 点)
const ACTIVITY_END_TIME = new Date('2026-04-04 05:00:00').getTime()
// 获取每周一早上5点的时间戳沙特时间0点 = 北京时间5点
const getNextMondayInBeijing = () => {
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 isLastWeek = () => {
const nextMonday = getNextMondayInBeijing()
return nextMonday > ACTIVITY_END_TIME
}
// 获取倒计时目标时间
const getTargetTime = () => {
// // 最后一周:使用活动截止时间
// if (isLastWeek()) {
// return ACTIVITY_END_TIME
// }
// // 普通周:使用下周一早上 5 点
// return getNextMondayInBeijing()
return ACTIVITY_END_TIME
}
const targetTime = ref(getTargetTime()) // 闭包保存目标时间 (核心修正)
// 格式化时间
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)
Days.value = Math.floor(totalSeconds / (24 * 3600))
Hours.value = formatTime(Math.floor((totalSeconds % (24 * 3600)) / 3600))
Minutes.value = formatTime(Math.floor((totalSeconds % 3600) / 60))
Second.value = formatTime(Math.floor(totalSeconds % 60))
}
// 切换模块
const handleBt = (type) => {
rankShow.value = type == 'ranking' ? true : false
rechargeShow.value = type == 'recharge' ? true : false
lotteryShow.value = type == 'lottery' ? true : false
drawerShowBt('') // 收起抽屉
selectedCoin.value = null // 清除选择币种
}
// 切换标签页
const changeModule = (module) => {
switch (module) {
case 'ranking':
rankingShow.value = true
rewardsShow.value = false
break
case 'rewards':
rankingShow.value = false
rewardsShow.value = true
break
case 'rechargeRank':
rechargeRankShow.value = true
rechargeRewardsShow.value = false
break
case 'rechargeRewards':
rechargeRankShow.value = false
rechargeRewardsShow.value = true
break
case 'task':
taskShow.value = true
withdrawShow.value = false
break
case 'withdraw':
taskShow.value = false
withdrawShow.value = true
break
}
}
// 抽屉展示
const drawerShowBt = (type) => {
transferShow.value = type == 'transfer' ? !transferShow.value : false
exchangeShow.value = type == 'exchange' ? !exchangeShow.value : false
selectedCoin.value = null
}
const rechargehidden = ref(true) //金额是否隐藏
// 根据隐藏状态处理金额显示的方法
const formatRechargeAmount = (amount) => {
if (rechargehidden.value) {
// 如果隐藏,则将数字替换为*
return String(amount || '0').replace(/\d/g, '*')
} else {
// 如果不隐藏,则正常显示
return amount || '0'
}
}
const topImg = ref([
imageUrl('rechargeReward100'),
imageUrl('rechargeReward500'),
imageUrl('rechargeReward1000'),
imageUrl('rechargeReward3000'),
imageUrl('rechargeReward5000'),
imageUrl('rechargeReward10000'),
]) // top图片
//充值奖励的内容样式
const rewardContentLayer = (index) => {
let gridStyle = ''
if (currentLangType.value == 'ar') {
gridStyle = 'direction: ltr;'
}
if (index == 0) {
return `display: grid;grid-template-columns: repeat(3, 1fr);gap:3vw 3.5vw;padding: 29vw 7vw 26vw 7vw;${gridStyle}`
} else if (index == 1 || index == 2) {
return `display: grid;grid-template-columns: repeat(3, 1fr);gap:3vw 3.5vw;padding: 29vw 7vw 26vw 7vw;${gridStyle}`
} else if (index == 3 || index == 4 || index == 5) {
return `display: grid;grid-template-columns: repeat(3, 1fr);gap:3vw 3.5vw;padding: 29vw 7vw 26vw 7vw;${gridStyle}`
}
}
// 前往搜索代理页
const searchPayee = () => {
router.push({
path: '/search-payee',
query: { from: '/activities/lesser-bairam', activeAction: 'withdraw' },
})
}
// 前往提现页
const goToWithdraw = () => {
router.push({ path: '/cash-out', query: { activityId: '2006671533912581569' } })
}
// 判断文本是否溢出(需要滚动)
const isTextOverflow = (text) => {
// 创建临时元素来测量文本宽度
const tempDiv = document.createElement('div')
tempDiv.style.position = 'absolute'
tempDiv.style.fontSize = '1em'
tempDiv.style.fontWeight = '860'
tempDiv.textContent = text
document.body.appendChild(tempDiv) // 将临时元素添加到文档中
const containerWidth = window.innerWidth * 0.3 // 所在容器宽度
const textWidth = tempDiv.getBoundingClientRect().width // 文本宽度
document.body.removeChild(tempDiv) // 删除临时元素
// 如果文本宽度超过容器宽度,则需要滚动
return textWidth > containerWidth
}
// 转账金币选项
const coinOptions = ref([
{ id: 1, amount: 10500, price: 1 },
{ id: 2, amount: 52500, price: 5 },
{ id: 3, amount: 105000, price: 10 },
])
//选择金币
const selectCoin = (coin) => {
// 单选逻辑:如果已经选中相同的金币,则取消选择;否则选中新的金币
if (selectedCoin.value?.id == coin.id) {
selectedCoin.value = null
} else {
selectedCoin.value = coin
}
}
// 转账
const transfer = async () => {
if (!selectedCoin.value) {
showError(t('please_select_amount'))
return
}
if (!selectedPayee.value?.id) {
showError(t('please_select_payee'))
return
}
// 构造请求参数
const transferData = {
amount: selectedCoin.value.price,
acceptUserId: selectedPayee.value?.id,
activityId: '2006671533912581569',
}
try {
// 调用转账接口
const response = await transferActivityDollar(transferData)
if (response.status) {
showSuccess(
t('transfer_dollar_success', {
price: selectedCoin.value.price,
name: selectedPayee.value?.name,
}),
)
} else {
showError(t('transfer_dollar_failed', { price: selectedCoin.value.price }))
}
selectedCoin.value = null // 重置选择
getDrawableAmount() //刷新可提现金额
} catch (error) {
if (error.errorCode === 5000) {
showMessage(t('insufficient_item_vouchers'))
} else {
showError(error.errorMsg)
}
}
}
//兑换代币
const exchangeCoinBt = async () => {
if (!selectedCoin.value) {
showError(t('please_select_amount'))
return
}
// 构造请求参数
const transferData = {
amount: selectedCoin.value.price,
activityId: '2006671533912581569',
}
try {
// 调用转账接口
const response = await exchangeCoin(transferData)
if (response.status) {
showSuccess(t('exchange_success_coins', { amount: selectedCoin.value.amount }))
} else {
showError(t('exchange_failed_coins', { amount: selectedCoin.value.amount }))
}
// 重置选择
selectedCoin.value = null
getDrawableAmount() //刷新可提现金额
} catch (error) {
if (error.errorCode === 5000) {
showMessage(t('insufficient_item_vouchers'))
} else {
showError(error.errorMsg)
}
}
}
// 打开弹窗
const openPopup = (type) => {
closedPopup(false) //先关闭其他弹窗,不清除抽奖结果
switch (type) {
case 'rankingHelp':
rankingHelpShow.value = true
break
case 'rechargeRankingHelp':
rechargeRankingHelpShow.value = true
break
case 'withdrawalHelp':
withdrawalHelpShow.value = true
break
case 'result':
resultShow.value = true
break
case 'history':
historyShow.value = true
break
default:
break
}
}
// 关闭弹窗
const closedPopup = (clear = true) => {
rankingHelpShow.value = false
rechargeRankingHelpShow.value = false
withdrawalHelpShow.value = false
resultShow.value = false
historyShow.value = false
if (clear) {
result.value = []
}
resultShowIndex.value = 0
}
//奖盘布局
const getGridPosition = (index) => {
//顺时针位置
const positions = [
{ gridArea: '1/1' }, //上左
{ gridArea: '1/2' }, //上中
{ gridArea: '1/3' }, //上右
{ gridArea: '2/3' }, //中右
{ gridArea: '3/3' }, //下右
{ gridArea: '3/2' }, //下中
{ gridArea: '3/1' }, //下左
{ gridArea: '2/1' }, //中左
]
return positions[index]
}
// 抽奖动画
const startLottery = (resultIndex) => {
console.log('开始抽奖动画')
return new Promise((resolve) => {
activeIndex.value = -1
let speed = 200 // 初始速度
let currentCycle = 0 // 当前圈数
let constantSpeedCycle = 0 // 当前匀速圈数
let totalCycles = 1 // 至少旋转2圈数
const roll = () => {
activeIndex.value = (activeIndex.value + 1) % activity.value.prizeList.length
console.log('当前索引:', activeIndex.value)
if (activeIndex.value === resultIndex && speed > 200) {
setTimeout(() => {
resolve() // 抽奖结束
}, 500)
} else {
if (activeIndex.value === activity.value.prizeList.length - 1) {
currentCycle++
}
// 加速旋转
if (currentCycle < totalCycles) {
speed -= 20
} else {
// 匀速旋转
if (activeIndex.value === activity.value.prizeList.length - 1) {
constantSpeedCycle++
}
if (constantSpeedCycle > 2) {
// 最后减速效果
speed += 20
}
}
setTimeout(roll, speed)
}
}
roll()
})
}
// 连抽
const sweepstakes = async (consecutive = 1) => {
if (isRolling.value) return // 防止重复点击
// 检查抽奖次数
if (rollTimes.value >= consecutive) {
isRolling.value = true
let data = {
activityId: '2006671533912581569',
drawCount: consecutive,
}
try {
// 单抽
if (consecutive == 1) {
const resOnceDraw = await onceDraw(data)
if (resOnceDraw.status && resOnceDraw.body) {
getTotalDrawCount() //刷新累计抽奖次数
// getConfigsBadgeInfo() //刷新累计抽奖-徽章信息
getTickets() //重新获取拥有的抽奖券
getDrawableAmount() //刷新可提现金额
result.value = [resOnceDraw.body] // 中奖结果赋值
const resItem = resOnceDraw.body //接口获取的抽奖结果(单抽为对象)
//取抽奖结果的位置
const index = activity.value.prizeList.findIndex(
(prize) => prize.prizeName == resItem?.prize.prizeName,
) //转盘第几位停下
console.log('index:', index)
await startLottery(index)
}
}
//连抽
else {
const resMultiDraw = await multiDraw(data)
if (resMultiDraw.status && resMultiDraw.body) {
getTotalDrawCount() //刷新累计抽奖次数
// getConfigsBadgeInfo() //刷新累计抽奖-徽章信息
getTickets() //重新获取拥有的抽奖券
getDrawableAmount() //刷新可提现金额
result.value = resMultiDraw.body.results // 中奖结果赋值
//取第一个抽奖结果的位置
let index = activity.value.prizeList.findIndex(
(prize) => prize.prizeName == result.value[0]?.prize.prizeName,
)
console.log('index:', index)
await startLottery(index)
}
}
getDrawRecords() // 获取中奖记录
openPopup('result') //打开中奖结果弹窗
isRolling.value = false
} catch (error) {
isRolling.value = false
if (error.response.errorCode == 3274) {
showError('Device has been used by another account')
}
}
}
}
// 展示任务目标
const showTarget = (task) => {
if (task.targetType == 'MIC_TIME') {
let timeType = task.targetValue < 60
let currentValue = timeType ? task.currentValue : task.currentValue / 60
let targetValue = timeType ? task.targetValue : task.targetValue / 60
// 直接去除小数部分(向下取整)
currentValue = Math.floor(currentValue * 10) / 10
targetValue = Math.floor(targetValue * 10) / 10
let timeUnit = timeType ? t('minutes_short') : t('hours_short')
return t('on_mic_progress', {
current: currentValue,
total: targetValue,
unit: timeUnit,
})
} else if (task.targetType == 'SEND_GIFT') {
if (task.taskCode == 'SP_SEND_GIFT_5') {
return t('Send 5 Ramadan gifts ({currentValue}/{targetValue})', {
currentValue: task.currentValue,
targetValue: task.targetValue,
})
}
} else if (task.targetType == 'SAVE_COINS') {
if (task.taskCode == 'SP_SAVE_50000') {
return t('Win 50,000 coins in total across any games ({currentValue}/{targetValue})', {
currentValue: task.currentValue,
targetValue: task.targetValue,
})
} else if (task.taskCode == 'SP_SAVE_100000') {
return t('Win 100,000 coins in total across any games ({currentValue}/{targetValue})', {
currentValue: task.currentValue,
targetValue: task.targetValue,
})
} else if (task.taskCode == 'SP_SAVE_500000') {
return t('Win 500,000 coins in total across any games ({currentValue}/{targetValue})', {
currentValue: task.currentValue,
targetValue: task.targetValue,
})
}
} else if (task.targetType == 'RECHARGE_AMOUNT') {
if (task.taskCode == 'SP_RECHARGE_1') {
return t('Daily total recharge amount: $1 ({currentValue}/{targetValue})', {
currentValue: task.currentValue,
targetValue: task.targetValue,
})
} else if (task.taskCode == 'SP_RECHARGE_10') {
return t('Daily total recharge amount: $10 ({currentValue}/{targetValue})', {
currentValue: task.currentValue,
targetValue: task.targetValue,
})
} else if (task.taskCode == 'SP_RECHARGE_50') {
return t('Daily total recharge amount: $50 ({currentValue}/{targetValue})', {
currentValue: task.currentValue,
targetValue: task.targetValue,
})
} else if (task.taskCode == 'SP_RECHARGE_100') {
return t('Daily total recharge amount: $100 ({currentValue}/{targetValue})', {
currentValue: task.currentValue,
targetValue: task.targetValue,
})
}
} else {
return `${task.taskName}(${task.currentValue}/${task.targetValue})`
}
}
// 选中的收款人
const selectedPayee = ref({})
// 初始化收款人信息
const initializePayee = () => {
const savedPayee = getSelectedPayee()
if (savedPayee) {
Object.assign(selectedPayee.value, savedPayee)
handleBt('lottery') // 抽奖模块
changeModule('withdraw') // 提现标签页
drawerShowBt('transfer') // 转账抽屉
}
}
// 清除当前选中的收款人
const clearPayee = () => {
Object.assign(selectedPayee.value, {
id: null,
account: '',
name: '',
avatar: '',
type: '',
isHost: false,
isAgency: false,
hasSalary: false,
})
clearSelectedPayee()
}
// 获取中奖用户列表
const getWinners = async () => {
const resWinners = await winnerHistory('2006671533912581569')
if (resWinners.status && resWinners.body) {
barrageList.value = resWinners.body
}
}
// 获取用户信息
const getUserInfo = async () => {
if (Object.keys(userInfo.value).length === 0) {
const resUserInfo = await getMemberProfile()
if (resUserInfo.status && resUserInfo.body) {
setUserInfo(resUserInfo.body, null)
userInfo.value = resUserInfo.body
}
}
const resIdentity = await getUserIdentity()
if (resIdentity.status && resIdentity.body) {
userIdentity.value = resIdentity.body
}
}
// 获取排行榜
const getRanking = async () => {
let data = {
activityType: 16,
}
const resRanking = await getRankingListAndMyRanking(data)
if (resRanking.status && resRanking.body) {
myRanking.value = resRanking.body?.currentUserRank //我的排名信息
Ranking.value = resRanking.body?.rankingList
getRewardsAndGifts() // 获取前十名奖励列表
} else {
Ranking.value = []
myRanking.value = {}
}
}
// 获取前3名奖励列表
const getRewardsAndGifts = async () => {
const resRewardsAndGifts = await getThisWeekRewardsAndGifts('2033805143824084994')
if (resRewardsAndGifts.status && resRewardsAndGifts.body) {
giftsList.value = resRewardsAndGifts.body.gifts // 每周礼物
let tempRewardsTop3 = resRewardsAndGifts.body.butOneRewards // 前3奖励
rewardsTop3.value = tempRewardsTop3.filter((_, index) => index < 3)
}
}
// 获取充值排行榜
const getRechargeRanking = async () => {
if (rechargePageNo.value == 0) {
rechargePageNo.value = 1
}
let data = {
activityId: '2006671533912581569',
pageNo: rechargePageNo.value,
pageSize: 20,
}
const resRanking = await ranklist(data)
if (resRanking.status && resRanking.body) {
myRechargeRanking.value = resRanking.body?.currentUser // 我的充值排名
if (resRanking.body.topList.length > 0) {
if (resRanking.body.topList.length == 20) {
addRechargeRanking.value = []
rechargeRanking.value.push(...resRanking.body?.topList)
rechargePageNo.value++
} else {
addRechargeRanking.value = resRanking.body?.topList
}
}
} else {
myRechargeRanking.value = {}
rechargeRanking.value = []
addRechargeRanking.value = []
rechargePageNo.value = 1
}
}
// 获取充值记录
const getMyRecharge = async () => {
const resMyRecharge = await myRecharge('2006671533912581569')
if (resMyRecharge.status && resMyRecharge.body) {
myRechargeRecode.value = resMyRecharge.body
} else {
myRechargeRecode.value = {}
}
}
// 获取充值奖励列表
const getRechargeReward = async () => {
let data = {
activityType: 'CONSUMPTION_ACTIVITY',
activityId: '2006671533912581569',
}
const resActivityReward = await activityRewardConfigs(data)
if (resActivityReward.status && resActivityReward.body) {
RechargeRewards.value = resActivityReward.body.map((rewards) => {
let jsonData = JSON.parse(rewards.jsonData)
let addReward = []
if (rewards.sort == 1) {
addReward = []
} else if (rewards.sort == 2) {
addReward = []
} else if (rewards.sort == 3) {
addReward = []
} else if (rewards.sort == 4) {
addReward = [
{
type: 'GIFT',
cover: imageUrl('reward_gift'),
content: 1,
},
]
} else if (rewards.sort == 5) {
addReward = [
{
type: 'GIFT',
cover: imageUrl('reward_gift'),
content: 1,
},
]
} else if (rewards.sort == 6) {
addReward = [
{
type: 'GIFT',
cover: imageUrl('reward_gift'),
content: 1,
},
{
type: 'PROPS',
detailType: 'AVATAR_FRAME',
cover: imageUrl('reward_frame'),
quantity: 365,
},
{
type: 'PROPS',
detailType: 'RIDE',
cover: imageUrl('reward_ride'),
quantity: 60,
},
]
}
rewards.rewardProps.push(...addReward) //补充奖励项
rewards = {
...rewards,
...jsonData,
}
return rewards
})
} else {
RechargeRewards.value = []
}
}
// 领取充值奖励
const receiveReward = async (rewards) => {
let data = {
activityType: rewards.activityType,
activityId: '2006671533912581569',
ruleId: rewards.ruleId,
}
try {
const resReceive = await receiveRechargeReward(data)
if (resReceive.status && resReceive.body) {
getRechargeReward() // 刷新充值奖励
}
} catch (error) {
showError(error.errorMsg)
}
}
// 获取抽奖奖池
const getActivityDetail = async () => {
getDrawableAmount() //获取可提现金额
const resDetail = await activityDetail('81569')
if (resDetail.status && resDetail.body) {
activity.value = resDetail.body
} else {
activity.value = {}
}
}
// 格式化奖励的展示信息
const showDetail = (type, reward) => {
let showamount = ['GOLD', 'DIAMOND', 'GIFT', 'FRAGMENTS', 'TICKET']
if (showamount.includes(type)) {
return `*${reward.content}`
} else if (type === 'DOLLARS') {
return `$${reward.content}`
} else {
return `${reward.quantity}Days`
}
}
// 获取拥有的抽奖券
const getTickets = async () => {
const resTickets = await myTickets('2006671533912581569')
if (resTickets.status && resTickets.body) {
rollTimes.value = resTickets.body
} else {
rollTimes.value = 0
}
}
// 获取累计抽奖次数
const getTotalDrawCount = async () => {
const resTotalDrawCount = await myTotalDrawCount('2006671533912581569')
if (resTotalDrawCount.status && resTotalDrawCount.body) {
totalDraw.value = resTotalDrawCount.body
}
}
// 可提现金额
const getDrawableAmount = async () => {
const resDrawableAmount = await withdrawableAmount('2006671533912581569')
if (resDrawableAmount.status && resDrawableAmount.body) {
currentAmount.value = resDrawableAmount.body
}
}
// 获取任务列表
const getTaskList = async () => {
const resTaskList = await ActTaskList('2006671533912581569')
if (resTaskList.status && resTaskList.body) {
taskList.value = resTaskList.body
}
}
// 获取中奖记录
const getDrawRecords = async () => {
const resDrawRecords = await drawRecords('81569')
if (resDrawRecords.status && resDrawRecords.body) {
myRecords.value = resDrawRecords.body?.records || []
}
}
// 领取任务奖励
const receiveTaskReward = async (code) => {
let data = {
activityId: '2006671533912581569',
taskCode: code,
}
try {
const resReceive = await receiveTickets(data)
if (resReceive.status && resReceive.body) {
getTaskList() //获取任务列表
getTickets() //获取拥有的抽奖券
}
} catch (error) {
showError(error.errorMsg)
}
}
// 刷新页面数据
const initData = async () => {
await Promise.all([
getUserInfo(), //获取用户信息
initializePayee(), //获取收款人信息
getWinners(), //获取历史中奖用户
getRanking(), //获取排行榜
getRechargeRanking(), // 获取充值排行榜
getMyRecharge(), // 获取充值记录
getRechargeReward(), // 获取充值奖励列表
getActivityDetail(), //获取奖池
getTotalDrawCount(), //刷新累计抽奖次数
getTickets(), //重新获取拥有的抽奖券
getTaskList(), //获取任务列表
getDrawRecords(), // 获取中奖记录
])
}
// 预加载关键图片
const preloadCriticalImages = async () => {
const criticalImages = [
// 背景
imageUrl('bg1'),
imageUrl('bg2'),
// imageUrl('bg3'),
imageUrl('timeBg'), // 倒计时
// 模块按钮
imageUrl(getImgName('rankBt')),
imageUrl(getImgName('rankBtActive')),
imageUrl(getImgName('rechargeBt')),
imageUrl(getImgName('rechargeBtActive')),
imageUrl(getImgName('lotteryBt')),
imageUrl(getImgName('lotteryBtActive')),
// 排行榜标签页
// 标签页按钮
imageUrl(getImgName('rankingBt')),
imageUrl('rewardsBt'),
// 每周礼物
imageUrl('eventGiftsBg'),
imageUrl('giftBg'),
// 排行榜
imageUrl('rankingImgBg'),
imageUrl('RankingTopBorder'),
imageUrl('RankingBottomBorder'),
imageUrl('RankingBorder'),
imageUrl('historyBt'),
imageUrl('itemFrom4Bg'),
imageUrl('userNameBorder'),
// 前三头像框
imageUrl('top1'),
imageUrl('top2'),
imageUrl('top3'),
// 前三奖励
// imageUrl(`rewardTop1`),
// imageUrl(`rewardTop2`),
// imageUrl(`rewardTop3`),
// 充值排行榜标签页
// 标签页按钮
imageUrl(getImgName('rechargeRankBt')),
// 我的充值
// imageUrl('earningInfoBg'),
// imageUrl('rechargeNumHidden'),
// imageUrl('rechargeNumShow'),
// 充值奖励
// imageUrl('rechargeReward100'),
// imageUrl('rechargeReward500'),
// imageUrl('rechargeReward1000'),
// imageUrl('rechargeReward3000'),
// imageUrl('rechargeReward5000'),
// imageUrl('rechargeReward10000'),
// imageUrl(getImgName('receiveBt')),
// imageUrl(getImgName('receivedBt')),
// 提现标签页
// 标签页按钮
// imageUrl(getImgName('taskBt')),
// imageUrl(getImgName('redeemBt')),
// 抽奖模块
// imageUrl('resultBt'),
// imageUrl('lottery'),
// imageUrl('prizeActiveFrame'),
// imageUrl('draw1BtBg'),
// imageUrl('draw10BtBg'),
// 任务列表
// imageUrl('taskTalk'),
// imageUrl('taskGift'),
// imageUrl('taskGame'),
// imageUrl('taskRecharge'),
// imageUrl('ticket'),
// imageUrl('taskBtGo'),
// imageUrl('taskBtReceive'),
// imageUrl('taskBtReceived'),
// imageUrl('myRankingBg'), // 我的排名
// // 中奖结果弹窗
// imageUrl('resultBg'),
// imageUrl('resultBack'),
// imageUrl('resultNext'),
// imageUrl('resultGoOnBt'),
// imageUrl('historyBg'), // 中奖历史弹窗
// imageUrl(getImgName('helpBg')), // 帮助弹窗
// imageUrl('rechargeHelpBg'), // 充值帮助弹窗
// imageUrl('withdrawHelpBg'), // 提现帮助弹窗
]
await preloadImages(criticalImages)
}
// 预加载其他图片
const preloadOtherImages = async () => {
const criticalImages = []
await preloadImagesIdle(criticalImages)
}
// 完成预加载
const completePreloading = async () => {
try {
// 执行所有初始化操作
await Promise.all([
// initData(),
preloadCriticalImages(),
])
} catch (error) {
console.error('预加载过程中发生错误:', error)
} finally {
// 无论成功或失败都结束加载状态
isLoading.value = false
// 等待 DOM 更新后执行 observe
await nextTick()
if (RankingLoadmore.value) {
console.log('监控加载模块')
observer.observe(RankingLoadmore.value)
}
}
}
// 使用工具函数连接APP
const connectToAppHandler = async () => {
await connectToApp(() => {
// 连接成功回调
completePreloading() // 完成预加载
})
}
// 启动倒计时
const startCountdown = () => {
getCountdown() // 立即执行一次
timer = setInterval(getCountdown, 1000) //倒计时每秒更新
}
// 触发节流获取排行榜
const debouceGetRanking = useThrottle(() => {
getRechargeRanking() //加载新的排行榜项
}, 1000)
// IntersectionObserver配置
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.intersectionRatio > 0 && rechargeRankingTotal.value.length != 0) {
console.log('触发RankingLoadmore加载')
debouceGetRanking()
}
})
})
// 组件挂载时检测环境
onMounted(async () => {
console.log('route.query.activeAction:', route.query.activeAction)
if (route.query.activeAction == 'withdraw') {
handleBt('lottery') // 抽奖模块
changeModule('withdraw') // 提现标签页
drawerShowBt('transfer') // 转账抽屉
} else {
handleBt('ranking')
}
await connectToAppHandler()
initData()
startCountdown() //开启倒计时
preloadOtherImages() // 预加载其他图片
})
onUnmounted(() => {
clearInterval(timer) //摧毁计时器
clearPayee() // 清空收款人信息
})
</script>
<style lang="scss" scoped>
* {
color: #fff;
}
.fullPage {
position: relative;
background: #11032d;
}
.bg {
width: 100vw;
min-height: 100vh;
position: relative;
z-index: 1;
overflow: hidden;
}
.background-overlay {
position: absolute;
inset: 236vw 0 0;
background-image: var(--bg2-url);
background-repeat: repeat-y;
background-position: top center;
background-size: 100% auto;
z-index: 0; /* 确保在.bg之下 */
}
.grayscale-container {
filter: grayscale(100%) brightness(90%);
}
.ranking-bg {
background-color: #450b08;
background-image: var(--ranking-bg-url);
background-size: 100% auto;
background-repeat: no-repeat;
position: absolute;
inset: 15vw 2vw 4vw;
z-index: 1;
}
.timeText {
color: #fff;
font-weight: 590;
font-size: 1.7em;
}
.timeGap {
width: 6px;
align-self: stretch;
display: flex;
justify-content: center;
align-items: center;
}
.btTitle {
color: #fff;
font-weight: 700;
}
.topTitle {
font-size: 1.5em;
}
.history-name {
font-size: 0.8em;
}
.history-time {
font-size: 0.8em;
}
.Textlittle {
font-size: 0.9em;
}
.timeBox {
padding: 4vw 0;
display: flex;
justify-content: center;
align-items: center;
}
/* 添加加载动画样式 */
.loading-container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #666;
overflow: hidden;
position: relative;
}
.reward-wrapper {
width: 100%;
overflow: hidden;
}
[dir='rtl'] .reward-wrapper {
left: 4vw;
right: 15vw;
}
@keyframes scroll-left {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-50%);
}
}
@keyframes scroll-right {
0% {
transform: translateX(0);
}
100% {
transform: translateX(50%);
}
}
.scroll-wrapper {
display: flex;
width: fit-content;
}
[dir='ltr'] .scroll-wrapper {
animation: scroll-left 8s linear infinite;
will-change: transform;
}
[dir='rtl'] .scroll-wrapper {
animation: scroll-right 8s linear infinite;
will-change: transform;
}
.scroll-content {
display: flex;
align-items: center;
}
[dir='ltr'] .scroll-content {
margin-left: 4vw;
}
[dir='rtl'] .scroll-content {
margin-left: auto;
margin-right: 4vw;
}
.ruleBt {
width: 5vw;
min-width: 0;
display: block;
position: absolute;
top: 5px;
right: 5px;
}
[dir='rtl'] .ruleBt {
left: 5px;
right: auto;
}
.scrollY::-webkit-scrollbar {
display: none;
}
/* 金币网格 */
.coin-item {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
// transition: all 0.2s;
aspect-ratio: 1/1;
border-radius: 8px;
border: 1px solid rgba(64, 64, 64, 0.5);
background: rgba(240, 240, 240, 0.3);
box-shadow:
-42px 103px 31px 0 rgba(145, 145, 145, 0),
-27px 66px 29px 0 rgba(145, 145, 145, 0.01),
-15px 37px 24px 0 rgba(145, 145, 145, 0.03),
-7px 17px 18px 0 rgba(145, 145, 145, 0.04),
-2px 4px 10px 0 rgba(145, 145, 145, 0.05);
backdrop-filter: blur(7.5px);
direction: ltr;
}
.coin-item.selected {
border-radius: 11px;
border: 2px solid #ced1ff;
box-shadow:
-0.25px -0.25px 1px 0 #655dff,
0.25px 0.25px 1px 0 #735dff,
0 0 3px 0 rgba(93, 96, 255, 0.8),
0 0 5px 0 rgba(93, 104, 255, 0.6),
0 0 4px 0 rgba(0, 0, 210, 0.3);
}
.coin-item:active {
transform: scale(0.98);
}
.resultNum {
position: absolute;
z-index: 9999;
inset: 0;
top: -8vw;
padding-right: 8%;
display: flex;
justify-content: flex-end;
align-items: center;
font-size: 0.9em;
font-weight: 590;
background: linear-gradient(0deg, #f3b700 0%, #ffeec6 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
[dir='rtl'] .resultNum {
direction: ltr;
justify-content: flex-start;
}
.rotated {
transform: rotate(90deg);
}
[dir='rtl'] .flipImg {
transform: scaleX(-1);
}
[dir='rtl'] .flipImg.rotated {
transform: scaleX(-1) rotate(90deg);
}
@media screen and (max-width: 360px) {
* {
font-size: 10px;
}
}
@media screen and (min-width: 360px) {
* {
font-size: 12px;
}
}
@media screen and (min-width: 768px) {
* {
font-size: 24px;
}
}
@media screen and (min-width: 1024px) {
* {
font-size: 32px;
}
}
[dir='rtl'] .timeBox {
flex-direction: row-reverse;
}
.helpInfo {
display: flex;
flex-direction: column;
gap: 1vw;
}
.helpInfo > p {
color: #fff;
font-size: 1.2em;
font-weight: 700;
}
</style>