378 lines
9.2 KiB
Vue
378 lines
9.2 KiB
Vue
<template>
|
|
<div class="fullPage">
|
|
<!-- 预加载状态 -->
|
|
<div v-if="isLoading" class="loading-container">
|
|
<!-- 页面背景 -->
|
|
<BackgroundLayer
|
|
:useCanvas="true"
|
|
:backgroundImages="[imageUrl('bg1'), imageUrl('bg2'), imageUrl('bg3')]"
|
|
/>
|
|
|
|
<!-- 加载动画 -->
|
|
<LoadingSpinner />
|
|
<p>{{ t('loading') }}...</p>
|
|
</div>
|
|
|
|
<!-- 主要内容 -->
|
|
<div
|
|
v-if="!isLoading"
|
|
style="width: 100vw; min-height: 100vh; overflow: hidden; position: relative"
|
|
>
|
|
<!-- 页面背景 -->
|
|
<BackgroundLayer
|
|
:useCanvas="true"
|
|
:backgroundImages="[imageUrl('bg1'), imageUrl('bg2'), imageUrl('bg3')]"
|
|
/>
|
|
<!-- 重复的背景图层 -->
|
|
<!-- <div class="background-overlay" :style="{ '--bg2-url': `url(${imageUrl('bg3')})` }"></div> -->
|
|
|
|
<!-- 页面内容 -->
|
|
<div style="position: relative; z-index: 2; margin: 85vw 0 10vw">
|
|
<!-- 登录奖励池 -->
|
|
<itemCenter
|
|
style="min-height: 136.33vw"
|
|
:imgUrl="imageUrl('rewards')"
|
|
:contentStyle="`
|
|
padding: 21.5vw 6.5vw 12vw;
|
|
|
|
display: grid;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
grid-template-rows: repeat(3, 1fr);
|
|
gap: 10.5vw 2.5vw;
|
|
|
|
direction: ltr;
|
|
`"
|
|
>
|
|
<div
|
|
v-for="(reward, index) in rewardInfo?.propsGroup?.activityRewardProps"
|
|
:key="index"
|
|
style="align-self: stretch; position: relative"
|
|
:style="[getGridPosition(index)]"
|
|
@click="receiveTaskReward()"
|
|
>
|
|
<div
|
|
style="position: absolute; inset: 0; z-index: 2"
|
|
v-if="index != currentDay - 1 || (index == currentDay - 1 && todayReceived)"
|
|
@click.stop
|
|
>
|
|
<img
|
|
v-smart-img
|
|
:src="showImgUrl(index)"
|
|
alt=""
|
|
style="width: 100%; height: 100%; display: block; object-fit: cover"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</itemCenter>
|
|
|
|
<!-- 规则 -->
|
|
<img
|
|
v-smart-img
|
|
:src="imageUrl(getImgName('ruleInfo'))"
|
|
alt=""
|
|
style="width: 100%; display: block; object-fit: cover"
|
|
/>
|
|
</div>
|
|
<!-- 弹窗遮罩层 -->
|
|
<maskLayer :maskLayerShow="maskLayerShow" @click="closedPopup">
|
|
<!-- 居中弹窗 -->
|
|
<div
|
|
style="
|
|
width: 100vw;
|
|
height: 100vh;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
"
|
|
@click="closedPopup"
|
|
></div>
|
|
</maskLayer>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed, 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 { preloadImages } from '@/utils/image/imagePreloader.js'
|
|
import { showError, showSuccess } from '@/utils/toast.js'
|
|
import { handleAvatarImageError, handleRewardImageError } from '@/utils/image/imageHandler.js'
|
|
import { formatRewardDisplay } from '@/utils/rewardFormatter.js'
|
|
|
|
import { apiGetLoginRewards, apiGetTodayLoginStatus, postReceiveLoginReward } from '@/api/task.js'
|
|
|
|
import BackgroundLayer from '@/components/BackgroundLayer.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/LoginReward/', filename)
|
|
|
|
// 根据语言获取图片名
|
|
const getImgName = (filename) => {
|
|
return currentLangType.value === 'ar' ? `${filename}_ar` : filename
|
|
}
|
|
|
|
const rewardInfo = ref({}) // 奖池列表
|
|
const currentDay = ref(0) // 当前天数
|
|
const days = ref(0) // 当前签到天数
|
|
const todayReceived = ref(false) // 今日是否已领取
|
|
|
|
// 展示不同图片
|
|
const showImgUrl = (index) => {
|
|
// 未领取状态
|
|
if (index > currentDay.value - 1) {
|
|
if (index < 6) {
|
|
return imageUrl('itemLock')
|
|
} else {
|
|
return imageUrl('itemBigLock')
|
|
}
|
|
}
|
|
|
|
// 已领取状态
|
|
else if (index < currentDay.value - 1) {
|
|
if (index < 6) {
|
|
return imageUrl(getImgName('itemReceived'))
|
|
} else {
|
|
return imageUrl(getImgName('itemBigReceived'))
|
|
}
|
|
}
|
|
|
|
// 当天领取状态
|
|
else if (index == currentDay.value - 1 && todayReceived.value) {
|
|
if (index < 6) {
|
|
return imageUrl(getImgName('itemReceived'))
|
|
} else {
|
|
return imageUrl(getImgName('itemBigReceived'))
|
|
}
|
|
}
|
|
}
|
|
|
|
// 弹窗展示
|
|
const helpShow = ref(false) // 帮助
|
|
const maskLayerShow = computed(() => {
|
|
return helpShow.value
|
|
})
|
|
|
|
// 打开弹窗
|
|
const openPopup = (type) => {
|
|
closedPopup(false) //先关闭其他弹窗,不清除抽奖结果
|
|
switch (type) {
|
|
case 'help':
|
|
helpShow.value = true
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
// 关闭弹窗
|
|
const closedPopup = (clear = true) => {
|
|
helpShow.value = false
|
|
// 清空数据
|
|
if (clear) {
|
|
}
|
|
}
|
|
|
|
//奖池布局
|
|
const getGridPosition = (index) => {
|
|
//顺时针位置
|
|
const positions = [
|
|
{ gridArea: '1/1' }, //上左
|
|
{ gridArea: '1/2' }, //上中
|
|
{ gridArea: '1/3' }, //上右
|
|
{ gridArea: '2/1' }, //中左
|
|
{ gridArea: '2/2' }, //中中
|
|
{ gridArea: '2/3' }, //中右
|
|
{ gridRow: '3', gridColumn: '1 / -1' }, //下整行
|
|
]
|
|
return positions[index]
|
|
}
|
|
|
|
// 每日签到奖励列表
|
|
const getLoginRewards = async () => {
|
|
const resLoginRewards = await apiGetLoginRewards('DAILY_REGISTER_AZIZI')
|
|
if (resLoginRewards.status && resLoginRewards.body) {
|
|
rewardInfo.value = resLoginRewards.body?.rewards?.[0] || {}
|
|
days.value = resLoginRewards.body?.days || 0
|
|
currentDay.value = resLoginRewards.body?.currentDay || 0
|
|
|
|
console.log('currentDay.value:', currentDay.value)
|
|
if (days.value == currentDay.value) {
|
|
todayReceived.value = true
|
|
} else {
|
|
todayReceived.value = false
|
|
}
|
|
}
|
|
}
|
|
|
|
// 今天是否已签到
|
|
const getTodayLoginStatus = async () => {
|
|
const resTodayLoginStatus = await apiGetTodayLoginStatus('1')
|
|
if (resTodayLoginStatus.status && resTodayLoginStatus.body) {
|
|
todayReceived.value = resTodayLoginStatus.body
|
|
}
|
|
}
|
|
|
|
// 领取任务奖励
|
|
const receiveTaskReward = async () => {
|
|
let data = {
|
|
id: rewardInfo.value.rule.id,
|
|
resourceGroupId: rewardInfo.value.rule.resourceGroupId,
|
|
dailyKey: '1',
|
|
}
|
|
try {
|
|
const resReceive = await postReceiveLoginReward(data)
|
|
if (resReceive.status && resReceive.body) {
|
|
getLoginRewards() // 每日签到奖励列表
|
|
}
|
|
} catch (error) {
|
|
showError(error.errorMsg)
|
|
}
|
|
}
|
|
|
|
// 刷新页面数据
|
|
const initData = async () => {
|
|
await Promise.all([
|
|
getLoginRewards(), // 每日签到奖励列表
|
|
])
|
|
}
|
|
|
|
// 预加载关键图片
|
|
const preloadCriticalImages = async () => {
|
|
const criticalImages = [
|
|
imageUrl('bg1'),
|
|
imageUrl('bg2'),
|
|
imageUrl('bg3'),
|
|
imageUrl('rewards'),
|
|
imageUrl(getImgName('ruleInfo')),
|
|
imageUrl('itemLock'),
|
|
imageUrl('itemBigLock'),
|
|
imageUrl(getImgName('itemReceived')),
|
|
imageUrl(getImgName('itemBigReceived')),
|
|
]
|
|
|
|
await preloadImages(criticalImages)
|
|
}
|
|
|
|
// 完成预加载
|
|
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(() => {
|
|
connectToAppHandler()
|
|
})
|
|
|
|
onUnmounted(() => {})
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
* {
|
|
color: #fff;
|
|
}
|
|
|
|
.fullPage {
|
|
position: relative;
|
|
background: #142c24;
|
|
}
|
|
|
|
.bg {
|
|
width: 100vw;
|
|
min-height: 100vh;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.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之下 */
|
|
}
|
|
|
|
/* 添加加载动画样式 */
|
|
.loading-container {
|
|
width: 100vw;
|
|
height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
color: #666;
|
|
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
.scrollY::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
|
|
[dir='rtl'] .flipImg {
|
|
transform: scaleX(-1);
|
|
}
|
|
|
|
@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;
|
|
}
|
|
}
|
|
</style>
|