feat(新页面): 每日充值活动页面
This commit is contained in:
parent
8cc2fb87aa
commit
5a73708900
@ -62,14 +62,50 @@ export const getHistoryTopOne = async (activityType) => {
|
||||
}
|
||||
|
||||
// 获取指定类型活动资源
|
||||
export const activityResource = async (data) => {
|
||||
export const apiGetActivityResource = async (activityType) => {
|
||||
try {
|
||||
const response = await get(
|
||||
`/props-activity-cnf/client/listActivityResource?sysOrigin=${data.sysOrigin}&activityType=${data.activityType}`,
|
||||
`/props-activity-cnf/client/listActivityResource?sysOrigin=LIKEI&activityType=${activityType}`,
|
||||
)
|
||||
return response
|
||||
} catch (error) {
|
||||
console.error('Failed to get this week rewards and gifts:', error)
|
||||
console.error('Failed to get activity resource:', error)
|
||||
console.error('error:' + error.response.errorMsg)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// 获取每日充值活动等级任务信息
|
||||
export const getDailyRechargeInfo = async () => {
|
||||
try {
|
||||
const response = await get('/activity/daily-recharge/info')
|
||||
return response
|
||||
} catch (error) {
|
||||
console.error('Failed to get daily recharge info:', error)
|
||||
console.error('error:' + error.response.errorMsg)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// 领取每日充值活动 task1 历史累计奖励
|
||||
export const claimDailyRechargeTask1 = async () => {
|
||||
try {
|
||||
const response = await post('/activity/daily-recharge/claim/task1')
|
||||
return response
|
||||
} catch (error) {
|
||||
console.error('Failed to claim daily recharge task1 reward:', error)
|
||||
console.error('error:' + error.response.errorMsg)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// 领取每日充值活动 task2 当前等级奖励
|
||||
export const claimDailyRechargeTask2 = async (data) => {
|
||||
try {
|
||||
const response = await post('/activity/daily-recharge/claim/task2', data)
|
||||
return response
|
||||
} catch (error) {
|
||||
console.error('Failed to claim daily recharge task2 reward:', error)
|
||||
console.error('error:' + error.response.errorMsg)
|
||||
throw error
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ export const PUBLIC_PATHS = Object.freeze([
|
||||
'/recharge-reward',
|
||||
'/login-reward',
|
||||
'/activities/poker-ace',
|
||||
'/daily-recharge',
|
||||
'/activities/lucky-dollars-season4',
|
||||
'/activities/lesser-bairam',
|
||||
'/activities/lucky-dollars-season3',
|
||||
|
||||
@ -495,5 +495,16 @@
|
||||
"weekly_rank": "الترتيب الأسبوعي",
|
||||
"daily_rank": "الترتيب اليومي",
|
||||
"weekly_rewards": "المكافآت الأسبوعية",
|
||||
"daily_rewards": "المكافآت اليومية"
|
||||
"daily_rewards": "المكافآت اليومية",
|
||||
|
||||
"active_game_current_daily_recharge_amount": "مبلغ الشحن اليومي الحالي: {amount}.",
|
||||
"active_game_current_daily_game_spending": "إنفاق الألعاب اليومي الحالي: {coins} عملة.",
|
||||
"active_game_task1_detail": "1. الهدف اليومي: أنفق ({progress} عملة). افتح مكافأة {reward} عملة ليوم غد!",
|
||||
"active_game_task2_detail": "2. وصل إلى ({progress}) للمطالبة بالمكافأة الحالية.",
|
||||
"active_game_level_label": "Lv.{level}",
|
||||
"active_game_rule_1": "(1) يتم إصدار جميع مكافآت العملات المكتسبة اليوم في اليوم التالي.",
|
||||
"active_game_rule_2": "(2) يجب المطالبة بالمهمة 2 يدويا.",
|
||||
"active_game_rule_3": "(3) يجب إكمال المهمتين للانتقال إلى المستوى التالي.",
|
||||
"active_game_vap_playback_failed": "فشل تشغيل VAP",
|
||||
"active_game_claim_reward_failed": "فشل المطالبة بالمكافأة"
|
||||
}
|
||||
|
||||
@ -495,5 +495,16 @@
|
||||
"weekly_rank": "সাপ্তাহিক র্যাঙ্ক",
|
||||
"daily_rank": "দৈনিক র্যাঙ্ক",
|
||||
"weekly_rewards": "সাপ্তাহিক পুরস্কার",
|
||||
"daily_rewards": "দৈনিক পুরস্কার"
|
||||
"daily_rewards": "দৈনিক পুরস্কার",
|
||||
|
||||
"active_game_current_daily_recharge_amount": "বর্তমান দৈনিক রিচার্জের পরিমাণ: {amount}.",
|
||||
"active_game_current_daily_game_spending": "বর্তমান দৈনিক গেম খরচ: {coins} কয়েন।",
|
||||
"active_game_task1_detail": "1. দৈনিক লক্ষ্য: খরচ করুন ({progress} কয়েন)। আগামীকালের জন্য {reward} কয়েন পুরস্কার আনলক করুন!",
|
||||
"active_game_task2_detail": "2. বর্তমান পুরস্কার দাবি করতে ({progress}) পৌঁছান।",
|
||||
"active_game_level_label": "Lv.{level}",
|
||||
"active_game_rule_1": "(1) আজ অর্জিত সব কয়েন পুরস্কার পরের দিন দেওয়া হবে।",
|
||||
"active_game_rule_2": "(2) টাস্ক 2 ম্যানুয়ালি দাবি করতে হবে।",
|
||||
"active_game_rule_3": "(3) পরবর্তী লেভেলে যেতে দুটি টাস্কই সম্পন্ন করতে হবে।",
|
||||
"active_game_vap_playback_failed": "VAP প্লেব্যাক ব্যর্থ হয়েছে",
|
||||
"active_game_claim_reward_failed": "পুরস্কার দাবি করতে ব্যর্থ হয়েছে"
|
||||
}
|
||||
|
||||
@ -495,5 +495,16 @@
|
||||
"weekly_rank": "Weekly Rank",
|
||||
"daily_rank": "Daily Rank",
|
||||
"weekly_rewards": "Weekly Rewards",
|
||||
"daily_rewards": "Daily Rewards"
|
||||
"daily_rewards": "Daily Rewards",
|
||||
|
||||
"active_game_current_daily_recharge_amount": "Current daily recharge amount: {amount}.",
|
||||
"active_game_current_daily_game_spending": "Current daily game spending: {coins} coins.",
|
||||
"active_game_task1_detail": "1. Daily Goal: Spend ({progress} coins). Unlock a {reward} coin reward for tomorrow!",
|
||||
"active_game_task2_detail": "2. Reach ({progress}) to claim the current reward.",
|
||||
"active_game_level_label": "Lv.{level}",
|
||||
"active_game_rule_1": "(1) All coin rewards earned today are issued the next day.",
|
||||
"active_game_rule_2": "(2) Task 2 must be claimed manually.",
|
||||
"active_game_rule_3": "(3) You must complete both tasks to proceed to the next level.",
|
||||
"active_game_vap_playback_failed": "VAP playback failed",
|
||||
"active_game_claim_reward_failed": "Failed to claim reward"
|
||||
}
|
||||
|
||||
@ -495,5 +495,16 @@
|
||||
"weekly_rank": "Haftalık Sıralama",
|
||||
"daily_rank": "Günlük Sıralama",
|
||||
"weekly_rewards": "Haftalık Ödüller",
|
||||
"daily_rewards": "Günlük Ödüller"
|
||||
"daily_rewards": "Günlük Ödüller",
|
||||
|
||||
"active_game_current_daily_recharge_amount": "Mevcut günlük yükleme tutarı: {amount}.",
|
||||
"active_game_current_daily_game_spending": "Mevcut günlük oyun harcaması: {coins} coin.",
|
||||
"active_game_task1_detail": "1. Günlük Hedef: Harca ({progress} coin). Yarın için {reward} coin ödülünü aç!",
|
||||
"active_game_task2_detail": "2. Mevcut ödülü almak için ({progress}) seviyesine ulaş.",
|
||||
"active_game_level_label": "Lv.{level}",
|
||||
"active_game_rule_1": "(1) Bugün kazanılan tüm coin ödülleri ertesi gün verilir.",
|
||||
"active_game_rule_2": "(2) Görev 2 manuel olarak alınmalıdır.",
|
||||
"active_game_rule_3": "(3) Sonraki seviyeye geçmek için iki görevi de tamamlamalısınız.",
|
||||
"active_game_vap_playback_failed": "VAP oynatma başarısız",
|
||||
"active_game_claim_reward_failed": "Ödül alınamadı"
|
||||
}
|
||||
|
||||
@ -495,5 +495,16 @@
|
||||
"weekly_rank": "周榜",
|
||||
"daily_rank": "日榜",
|
||||
"weekly_rewards": "周榜奖励",
|
||||
"daily_rewards": "日榜奖励"
|
||||
"daily_rewards": "日榜奖励",
|
||||
|
||||
"active_game_current_daily_recharge_amount": "当前每日充值金额:{amount}。",
|
||||
"active_game_current_daily_game_spending": "当前每日游戏消费:{coins} 金币。",
|
||||
"active_game_task1_detail": "1. 每日目标:消费({progress} 金币)。解锁 {reward} 金币奖励,奖励将在明天发放!",
|
||||
"active_game_task2_detail": "2. 达到({progress})即可领取当前奖励。",
|
||||
"active_game_level_label": "Lv.{level}",
|
||||
"active_game_rule_1": "(1)今天获得的所有金币奖励将在次日发放。",
|
||||
"active_game_rule_2": "(2)任务 2 需要手动领取。",
|
||||
"active_game_rule_3": "(3)必须完成两个任务才能进入下一等级。",
|
||||
"active_game_vap_playback_failed": "VAP 播放失败",
|
||||
"active_game_claim_reward_failed": "领取奖励失败"
|
||||
}
|
||||
|
||||
@ -395,6 +395,12 @@ const router = createRouter({
|
||||
},
|
||||
|
||||
// 限时活动
|
||||
{
|
||||
path: '/activities/active-game',
|
||||
name: 'active-game',
|
||||
component: () => import('../views/Activities/ActiveGame/index.vue'),
|
||||
meta: { requiresAuth: true },
|
||||
}, //2026年5月1日上午5点结束
|
||||
{
|
||||
path: '/activities/poker-ace',
|
||||
name: 'pokerAce',
|
||||
|
||||
@ -61,6 +61,7 @@ const ACTIVITIES = [
|
||||
'/login-reward', // 登录奖励
|
||||
|
||||
'/activities/poker-ace', // 扑克王牌排行榜
|
||||
'/daily-recharge', // 每日充值页面
|
||||
'/activities/lucky-dollars-season4', // 幸运美金活动
|
||||
'/activities/lesser-bairam', // 开斋节打榜
|
||||
'/activities/lucky-dollars-season3', // 斋月打榜
|
||||
|
||||
987
src/views/Activities/DailyRecharge/index.vue
Normal file
987
src/views/Activities/DailyRecharge/index.vue
Normal file
@ -0,0 +1,987 @@
|
||||
<template>
|
||||
<div class="fullPage">
|
||||
<!-- 预加载状态 -->
|
||||
<div v-if="isLoading" class="loading-container">
|
||||
<!-- 页面背景 -->
|
||||
<BackgroundLayer :useCanvas="true" :backgroundImages="[imageUrl('bg')]" />
|
||||
|
||||
<!-- 加载动画 -->
|
||||
<LoadingSpinner />
|
||||
<p>{{ t('loading') }}...</p>
|
||||
</div>
|
||||
|
||||
<!-- 主要内容 -->
|
||||
<div class="active-game-shell scroll">
|
||||
<div class="active-game-stage">
|
||||
<!-- 头部动画(带声音) -->
|
||||
<VapBg class="vap-background-layer" :src="bgVapUrl" />
|
||||
<!-- 页面背景 -->
|
||||
<div class="page-background-layer">
|
||||
<BackgroundLayer
|
||||
:useCanvas="true"
|
||||
:backgroundImages="[imageUrl('bg')]"
|
||||
:layerStyle="{ position: 'absolute', top: 0, left: 0, minHeight: 0, zIndex: 0 }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 页面内容 -->
|
||||
<div class="page-content">
|
||||
<!-- 累计奖励 -->
|
||||
<itemCenter
|
||||
style="padding: 0 3vw"
|
||||
:imgUrl="imageUrl('totalRewardBg')"
|
||||
:contentStyle="`padding:0 7vw;gap:1vw`"
|
||||
>
|
||||
<img
|
||||
v-smart-img
|
||||
src="/src/assets/icon/Azizi/coin.png"
|
||||
alt=""
|
||||
style="display: block; width: 10vw; aspect-ratio: 1/1"
|
||||
/>
|
||||
|
||||
<div
|
||||
style="
|
||||
flex: 1;
|
||||
border-radius: 88px;
|
||||
background: linear-gradient(180deg, #750a00 0%, #c71f10 48.08%, #750a00 100%);
|
||||
padding: 1vw 6px;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
background: linear-gradient(180deg, #ffeeb0 0%, #ffcc46 100%);
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
font-size: 1.2em;
|
||||
font-weight: 500;
|
||||
"
|
||||
>
|
||||
{{ taskInfo.task1PendingCoins }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<img
|
||||
v-smart-img
|
||||
:src="imageUrl(getImgName('receiveBt'))"
|
||||
alt=""
|
||||
style="display: block; width: 25vw"
|
||||
:style="{ filter: canClaimTask1Reward ? 'none' : 'grayscale(1)' }"
|
||||
@click="claimTask1Reward"
|
||||
/>
|
||||
</itemCenter>
|
||||
|
||||
<!-- 等级任务 -->
|
||||
<itemCenter
|
||||
style=""
|
||||
:imgUrl="imageUrl('lvTaskBg')"
|
||||
:contentStyle="`
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
padding: 10vw 8vw 5vw;
|
||||
gap: 8vw;
|
||||
`"
|
||||
>
|
||||
<!-- 标题 -->
|
||||
<div style="display: flex; justify-content: center; align-items: center; height: 11vw">
|
||||
<img
|
||||
v-smart-img
|
||||
:src="imageUrl(`titleLv${currentLevel}`)"
|
||||
alt=""
|
||||
style="width: 18vw"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 内容 -->
|
||||
<div style="width: 100%; display: flex; flex-direction: column; position: relative">
|
||||
<!-- 规则弹窗展示按钮 -->
|
||||
<img
|
||||
v-smart-img
|
||||
src="/src/assets/icon/Azizi/helpWhite.png"
|
||||
alt=""
|
||||
class="ruleBt"
|
||||
@click="openPopup('rule')"
|
||||
/>
|
||||
|
||||
<!-- 信息展示 -->
|
||||
<div style="height: 45vw; display: flex; flex-direction: column; gap: 5vw">
|
||||
<!-- 当前状态 -->
|
||||
<div style="display: flex; align-items: center">
|
||||
<div
|
||||
style="
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2vw;
|
||||
position: relative;
|
||||
"
|
||||
>
|
||||
<div>
|
||||
{{
|
||||
t('active_game_current_daily_recharge_amount', {
|
||||
amount: displayedRechargeAmountText,
|
||||
})
|
||||
}}
|
||||
</div>
|
||||
<div>
|
||||
{{
|
||||
t('active_game_current_daily_game_spending', {
|
||||
coins: displayedSpendCoinsText,
|
||||
})
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<!-- 展示隐藏按钮 -->
|
||||
<img
|
||||
v-smart-img
|
||||
:src="imageUrl(amountVisible ? 'amountShowBt' : 'amountHiddenBt')"
|
||||
alt=""
|
||||
style="width: 5vw; min-width: 0; display: block"
|
||||
@click="toggleAmountVisible"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 任务详情 -->
|
||||
<div style="display: flex; flex-direction: column; gap: 2vw">
|
||||
<!-- 任务一 -->
|
||||
<div :style="{ color: task1Completed ? '#1AFF00' : '#fff' }">
|
||||
{{
|
||||
t('active_game_task1_detail', {
|
||||
progress: task1ProgressText,
|
||||
reward: currentTask1RewardCoinsText,
|
||||
})
|
||||
}}
|
||||
<img
|
||||
v-if="task1Completed"
|
||||
v-smart-img
|
||||
:src="imageUrl('done')"
|
||||
alt=""
|
||||
style="display: inline-block; width: 1em; object-fit: contain"
|
||||
/>
|
||||
</div>
|
||||
<!-- 任务二 -->
|
||||
<div :style="{ color: taskInfo.task2Completed ? '#1AFF00' : '#fff' }">
|
||||
{{
|
||||
t('active_game_task2_detail', {
|
||||
progress: task2ProgressText,
|
||||
})
|
||||
}}
|
||||
<img
|
||||
v-if="taskInfo.task2Completed"
|
||||
v-smart-img
|
||||
:src="imageUrl('done')"
|
||||
alt=""
|
||||
style="display: inline-block; width: 1em; object-fit: contain"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 宝箱展示 -->
|
||||
<div style="display: flex; flex-direction: column; align-items: center">
|
||||
<img
|
||||
v-smart-img
|
||||
:src="imageUrl(currentChestImageName)"
|
||||
alt=""
|
||||
style="width: 38vw; display: block; object-fit: contain"
|
||||
/>
|
||||
|
||||
<!-- 宝箱等级 -->
|
||||
<div style="font-size: 1.5em; font-weight: 700">
|
||||
{{ t('active_game_level_label', { level: currentLevel }) }}
|
||||
</div>
|
||||
|
||||
<!-- 领取按钮 -->
|
||||
<img
|
||||
v-smart-img
|
||||
:src="imageUrl(getImgName(taskRewardButtonImageName))"
|
||||
alt=""
|
||||
style="width: 30vw; display: block; object-fit: contain"
|
||||
:style="{ filter: taskRewardButtonDisabled ? 'grayscale(1)' : 'none' }"
|
||||
@click="claimTask2Reward"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</itemCenter>
|
||||
|
||||
<!-- 等级奖励 -->
|
||||
<itemCenter
|
||||
style=""
|
||||
:imgUrl="imageUrl('LvRewardInfoBg')"
|
||||
:contentStyle="` flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
padding: 8vw 7.5vw 14vw;
|
||||
gap: 4vw;`"
|
||||
>
|
||||
<!-- 标题 -->
|
||||
<div style="display: flex; justify-content: center; align-items: center; height: 11vw">
|
||||
<img
|
||||
v-smart-img
|
||||
:src="imageUrl(getImgName('LvRewardTitle'))"
|
||||
alt=""
|
||||
style="width: 40vw"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 内容 -->
|
||||
<div
|
||||
style="
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2.5vw;
|
||||
position: relative;
|
||||
"
|
||||
>
|
||||
<!-- 开箱进度条 -->
|
||||
<div style="width: 100%; overflow-x: auto" class="scroll">
|
||||
<div class="chest-progress-row">
|
||||
<!-- 进度条 -->
|
||||
<div class="chest-progress-track" :style="progressTrackStyle">
|
||||
<!-- 进度条图片 -->
|
||||
<img
|
||||
v-smart-img
|
||||
:src="imageUrl('progressBar')"
|
||||
alt=""
|
||||
class="chest-progress-bar"
|
||||
:style="progressBarStyle"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 宝箱列表 -->
|
||||
<div class="chest-progress-list">
|
||||
<!-- 开头占位 -->
|
||||
<div></div>
|
||||
<div
|
||||
v-for="chest in chestProgressList"
|
||||
:key="chest.level"
|
||||
style="width: 14vw; cursor: pointer"
|
||||
@click="selectRewardChest(chest.level)"
|
||||
>
|
||||
<!-- 未达成条件 -->
|
||||
<img
|
||||
v-if="!isChestConditionReached(chest.level)"
|
||||
v-smart-img
|
||||
:src="imageUrl(getChestImageName(chest))"
|
||||
alt=""
|
||||
style="display: block; width: 100%; object-fit: contain"
|
||||
/>
|
||||
|
||||
<!-- 达成条件 -->
|
||||
<itemCenter
|
||||
v-else
|
||||
style="width: 100%"
|
||||
:imgUrl="imageUrl('LvActive')"
|
||||
:contentStyle="``"
|
||||
>
|
||||
<img
|
||||
v-smart-img
|
||||
:src="imageUrl(getChestImageName(chest))"
|
||||
alt=""
|
||||
style="display: block; width: 100%; object-fit: contain"
|
||||
/>
|
||||
</itemCenter>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 奖励展示 -->
|
||||
<div class="reward-showcase">
|
||||
<div v-if="mainReward" class="reward-showcase-main">
|
||||
<div
|
||||
style="
|
||||
width: 100%;
|
||||
height: 71vw;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
"
|
||||
>
|
||||
<div class="reward-showcase-vap-wrap">
|
||||
<VapMp4Player
|
||||
v-if="mainReward.sourceUrl"
|
||||
:model-value="true"
|
||||
:src="mainReward.sourceUrl"
|
||||
mode="inline"
|
||||
fit="contain"
|
||||
:loop="true"
|
||||
:mute="true"
|
||||
:auto-close="false"
|
||||
:show-close="false"
|
||||
:show-status="false"
|
||||
@error="handleRewardVapError"
|
||||
/>
|
||||
<img
|
||||
v-else
|
||||
:src="mainReward.cover || ''"
|
||||
alt=""
|
||||
style="display: block; width: 90%; object-fit: contain"
|
||||
@error="(e) => handleRewardImageError(e, mainReward.type)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
"
|
||||
>
|
||||
<div>{{ formatRewardDisplay(mainReward.type, mainReward) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="reward-showcase-grid">
|
||||
<div
|
||||
v-for="(reward, index) in rewardGridList"
|
||||
:key="index"
|
||||
class="reward-showcase-item"
|
||||
>
|
||||
<div
|
||||
style="
|
||||
width: 100%;
|
||||
aspect-ratio: 1/1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
"
|
||||
>
|
||||
<img
|
||||
:src="reward.cover || ''"
|
||||
alt=""
|
||||
style="display: block; width: 90%; object-fit: contain"
|
||||
@error="(e) => handleRewardImageError(e, reward.type)"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style="
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
"
|
||||
>
|
||||
<div>{{ formatRewardDisplay(reward.type, reward) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</itemCenter>
|
||||
</div>
|
||||
|
||||
<!-- 弹窗遮罩层 -->
|
||||
<maskLayer :maskLayerShow="maskLayerShow" @click="closedPopup">
|
||||
<!-- 居中弹窗 -->
|
||||
<div
|
||||
style="
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
"
|
||||
@click="closedPopup"
|
||||
>
|
||||
<!-- 规则弹窗 -->
|
||||
<itemCenter
|
||||
style=""
|
||||
:imgUrl="imageUrl('ruleInfoBg')"
|
||||
:contentStyle="` flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
padding: 8vw 7.5vw 5vw;
|
||||
gap: 4vw;`"
|
||||
>
|
||||
<!-- 标题 -->
|
||||
<div
|
||||
style="display: flex; justify-content: center; align-items: center; height: 11vw"
|
||||
>
|
||||
<img
|
||||
v-smart-img
|
||||
:src="imageUrl(getImgName('ruleTitle'))"
|
||||
alt=""
|
||||
style="width: 18vw"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style="
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
|
||||
font-size: 1.2em;
|
||||
"
|
||||
>
|
||||
<div style="font-size: 1em; color: #fff; font-weight: 700">
|
||||
{{ t('active_game_rule_1') }}
|
||||
</div>
|
||||
<div style="font-size: 1em; color: #fff; font-weight: 700">
|
||||
{{ t('active_game_rule_2') }}
|
||||
</div>
|
||||
<div style="font-size: 1em; color: #fff; font-weight: 700">
|
||||
{{ t('active_game_rule_3') }}
|
||||
</div>
|
||||
</div>
|
||||
</itemCenter>
|
||||
</div>
|
||||
</maskLayer>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { setDocumentDirection } from '@/locales/i18n'
|
||||
import { connectToApp } from '@/utils/appConnector.js'
|
||||
import { getMp4Url, getPngUrl } from '@/config/imagePaths.js'
|
||||
import { preloadImages } from '@/utils/image/imagePreloader.js'
|
||||
import { useLangStore } from '@/stores/lang'
|
||||
import { showError } from '@/utils/toast.js'
|
||||
import { preloadVapConfig } from '@/utils/vapMp4Config.js'
|
||||
import {
|
||||
apiGetActivityResource,
|
||||
claimDailyRechargeTask1,
|
||||
claimDailyRechargeTask2,
|
||||
getDailyRechargeInfo,
|
||||
} from '@/api/activity.js'
|
||||
import { resolveProtectedAssetUrl } from '@/utils/protectedAssets.js'
|
||||
import { handleRewardImageError } from '@/utils/image/imageHandler.js'
|
||||
import { formatRewardDisplay } from '@/utils/rewardFormatter.js'
|
||||
import { useThrottle } from '@/utils/useDebounce.js'
|
||||
|
||||
import BackgroundLayer from '@/components/BackgroundLayer.vue'
|
||||
import itemCenter from '@/components/itemCenter.vue'
|
||||
import maskLayer from '@/components/MaskLayer.vue'
|
||||
import VapMp4Player from '@/components/VapMp4Player.vue'
|
||||
import VapBg from './vapBg.vue'
|
||||
|
||||
const isLoading = ref(true)
|
||||
|
||||
const { t, locale } = useI18n()
|
||||
const langStore = useLangStore()
|
||||
|
||||
const currentLangType = computed(() => {
|
||||
return langStore.selectedLang?.type || 'en'
|
||||
})
|
||||
const isRtlLayout = computed(() => {
|
||||
return currentLangType.value === 'ar'
|
||||
})
|
||||
|
||||
locale.value && setDocumentDirection(locale.value)
|
||||
|
||||
const imageUrl = (filename) => getPngUrl('Activities/ActiveGame/', filename)
|
||||
const mp4Url = (filename) => getMp4Url('Activities/ActiveGame/', filename)
|
||||
const bgVapUrl = mp4Url('bg')
|
||||
const CHEST_PROGRESS_GAP_VW = 2
|
||||
const CHEST_PROGRESS_ITEM_WIDTH_VW = 14
|
||||
const CHEST_PROGRESS_FIRST_CENTER_VW = CHEST_PROGRESS_GAP_VW + CHEST_PROGRESS_ITEM_WIDTH_VW / 2
|
||||
const CHEST_PROGRESS_CENTER_STEP_VW = CHEST_PROGRESS_GAP_VW + CHEST_PROGRESS_ITEM_WIDTH_VW
|
||||
const CHEST_PROGRESS_TRACK_WIDTH_VW =
|
||||
10 * CHEST_PROGRESS_GAP_VW + 10 * CHEST_PROGRESS_ITEM_WIDTH_VW - CHEST_PROGRESS_ITEM_WIDTH_VW / 2
|
||||
|
||||
// 根据语言获取图片名
|
||||
const getImgName = (filename) => {
|
||||
return currentLangType.value == 'en' ? filename : `${filename}_${currentLangType.value}`
|
||||
}
|
||||
|
||||
const ruleShow = ref(false)
|
||||
const amountVisible = ref(false)
|
||||
const claimingTask1Reward = ref(false)
|
||||
const claimingTask2Reward = ref(false)
|
||||
const selectedRewardLevel = ref(1)
|
||||
const activityRewards = ref([])
|
||||
const createDefaultTaskInfo = () => ({
|
||||
task1SpendCoins: 0,
|
||||
task1MaxLevel: 0,
|
||||
task1TodayRewardCoins: 0,
|
||||
task1PendingCoins: 0,
|
||||
task2RechargeAmount: 0,
|
||||
task2TargetAmount: 0,
|
||||
task2Completed: false,
|
||||
task2Claimed: false,
|
||||
task2RewardCoins: 0,
|
||||
levelList: [],
|
||||
})
|
||||
const taskInfo = ref(createDefaultTaskInfo())
|
||||
const maskLayerShow = computed(() => {
|
||||
return ruleShow.value
|
||||
})
|
||||
const normalizeLevel = (levelValue) => {
|
||||
const level = Number(levelValue) || 1
|
||||
return Math.min(Math.max(level, 1), 10)
|
||||
}
|
||||
const levelMap = computed(() => {
|
||||
return new Map(taskInfo.value.levelList.map((item) => [Number(item.level), item]))
|
||||
})
|
||||
const currentLevel = computed(() => {
|
||||
return normalizeLevel(taskInfo.value.task1MaxLevel || 1)
|
||||
})
|
||||
const currentLevelInfo = computed(() => {
|
||||
return levelMap.value.get(currentLevel.value) || {}
|
||||
})
|
||||
const currentChestImageName = computed(() => {
|
||||
return `Lv${currentLevel.value}${currentLevelInfo.value.reached ? '_open' : ''}`
|
||||
})
|
||||
const canClaimTask1Reward = computed(() => {
|
||||
return Number(taskInfo.value.task1PendingCoins) > 0 && !claimingTask1Reward.value
|
||||
})
|
||||
const currentTask2RewardTop = computed(() => {
|
||||
return activityRewards.value[currentLevel.value - 1] || {}
|
||||
})
|
||||
const canClaimTask2Reward = computed(() => {
|
||||
return (
|
||||
!taskInfo.value.task2Claimed &&
|
||||
task1Completed.value &&
|
||||
taskInfo.value.task2Completed &&
|
||||
Boolean(currentTask2RewardTop.value?.rule?.id) &&
|
||||
!claimingTask2Reward.value
|
||||
)
|
||||
})
|
||||
const taskRewardButtonDisabled = computed(() => {
|
||||
return !taskInfo.value.task2Claimed && !canClaimTask2Reward.value
|
||||
})
|
||||
const taskRewardButtonImageName = computed(() => {
|
||||
return taskInfo.value.task2Claimed ? 'receivedBt' : 'receiveBt'
|
||||
})
|
||||
const chestProgressList = computed(() => {
|
||||
return Array.from({ length: 10 }, (_, index) => {
|
||||
const level = index + 1
|
||||
const levelInfo = levelMap.value.get(level) || {}
|
||||
return {
|
||||
level,
|
||||
reached: Boolean(levelInfo.reached),
|
||||
}
|
||||
})
|
||||
})
|
||||
const progressBarWidth = computed(() => {
|
||||
const completedLevelCount = Math.min(Math.max(currentLevel.value - 1, 0), 9)
|
||||
const completedWidth =
|
||||
completedLevelCount === 0
|
||||
? 0
|
||||
: CHEST_PROGRESS_FIRST_CENTER_VW + (completedLevelCount - 1) * CHEST_PROGRESS_CENTER_STEP_VW
|
||||
const currentLevelTaskCount =
|
||||
(task1Completed.value ? 1 : 0) + (taskInfo.value.task2Completed ? 1 : 0)
|
||||
const currentLevelProgressDistance =
|
||||
completedLevelCount === 0 ? CHEST_PROGRESS_FIRST_CENTER_VW : CHEST_PROGRESS_CENTER_STEP_VW
|
||||
const currentLevelWidth = (currentLevelProgressDistance * currentLevelTaskCount) / 2
|
||||
const progressWidth = Math.min(completedWidth + currentLevelWidth, CHEST_PROGRESS_TRACK_WIDTH_VW)
|
||||
|
||||
return `${progressWidth}vw`
|
||||
})
|
||||
const progressTrackStyle = computed(() => {
|
||||
return {
|
||||
width: `${CHEST_PROGRESS_TRACK_WIDTH_VW}vw`,
|
||||
left: isRtlLayout.value ? 'auto' : '0',
|
||||
right: isRtlLayout.value ? '0' : 'auto',
|
||||
justifyContent: isRtlLayout.value ? 'flex-end' : 'flex-start',
|
||||
}
|
||||
})
|
||||
const progressBarStyle = computed(() => {
|
||||
return {
|
||||
width: progressBarWidth.value,
|
||||
transform: isRtlLayout.value ? 'scaleX(-1)' : 'none',
|
||||
}
|
||||
})
|
||||
const task1Completed = computed(() => {
|
||||
return Boolean(currentLevelInfo.value.reached)
|
||||
})
|
||||
const currentTask1TargetCoins = computed(() => {
|
||||
return currentLevelInfo.value.spendCoinsTarget || 0
|
||||
})
|
||||
const currentTask1RewardCoins = computed(() => {
|
||||
return currentLevelInfo.value.rewardCoins || taskInfo.value.task1TodayRewardCoins || 0
|
||||
})
|
||||
const displayedSpendCoins = computed(() => {
|
||||
return amountVisible.value ? taskInfo.value.task1SpendCoins : '***'
|
||||
})
|
||||
const displayedRechargeAmount = computed(() => {
|
||||
return amountVisible.value ? taskInfo.value.task2RechargeAmount : '***'
|
||||
})
|
||||
const isolateLtrText = (value) => {
|
||||
return `\u2066${value}\u2069`
|
||||
}
|
||||
const displayedSpendCoinsText = computed(() => {
|
||||
return isolateLtrText(displayedSpendCoins.value)
|
||||
})
|
||||
const displayedRechargeAmountText = computed(() => {
|
||||
return isolateLtrText(`$${displayedRechargeAmount.value}`)
|
||||
})
|
||||
const currentTask1RewardCoinsText = computed(() => {
|
||||
return isolateLtrText(currentTask1RewardCoins.value)
|
||||
})
|
||||
const task1ProgressText = computed(() => {
|
||||
return isolateLtrText(`${displayedSpendCoins.value}/${currentTask1TargetCoins.value}`)
|
||||
})
|
||||
const task2ProgressText = computed(() => {
|
||||
return isolateLtrText(`$${displayedRechargeAmount.value}/$${taskInfo.value.task2TargetAmount}`)
|
||||
})
|
||||
const selectedRewardTop = computed(() => {
|
||||
return activityRewards.value[selectedRewardLevel.value - 1] || {}
|
||||
})
|
||||
const selectedRewardList = computed(() => {
|
||||
return selectedRewardTop.value?.propsGroup?.activityRewardProps || []
|
||||
})
|
||||
const mainReward = computed(() => {
|
||||
return selectedRewardList.value[0] || null
|
||||
})
|
||||
const rewardGridList = computed(() => {
|
||||
return selectedRewardList.value.slice(1, 7)
|
||||
})
|
||||
|
||||
const toggleAmountVisible = () => {
|
||||
amountVisible.value = !amountVisible.value
|
||||
}
|
||||
|
||||
const selectRewardChest = (level) => {
|
||||
selectedRewardLevel.value = normalizeLevel(level)
|
||||
}
|
||||
|
||||
const isChestConditionReached = (level) => {
|
||||
return Boolean(levelMap.value.get(Number(level))?.reached)
|
||||
}
|
||||
|
||||
const getChestImageName = (chest) => {
|
||||
return `Lv${chest.level}${chest.reached ? '_open' : ''}`
|
||||
}
|
||||
|
||||
const closedPopup = () => {
|
||||
ruleShow.value = false
|
||||
}
|
||||
|
||||
const openPopup = (type) => {
|
||||
closedPopup()
|
||||
switch (type) {
|
||||
case 'rule':
|
||||
ruleShow.value = true
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const handleRewardVapError = (error) => {
|
||||
console.error('Reward VAP playback failed:', error)
|
||||
showError(error?.message || t('active_game_vap_playback_failed'))
|
||||
}
|
||||
|
||||
const claimTask1Reward = useThrottle(async () => {
|
||||
if (!canClaimTask1Reward.value) {
|
||||
return
|
||||
}
|
||||
|
||||
claimingTask1Reward.value = true
|
||||
try {
|
||||
const res = await claimDailyRechargeTask1()
|
||||
if (res.status) {
|
||||
await getDailyRechargeTaskInfo()
|
||||
}
|
||||
} catch (error) {
|
||||
showError(error?.errorMsg || error?.message || t('active_game_claim_reward_failed'))
|
||||
} finally {
|
||||
claimingTask1Reward.value = false
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
const claimTask2Reward = useThrottle(async () => {
|
||||
if (!canClaimTask2Reward.value) {
|
||||
return
|
||||
}
|
||||
|
||||
claimingTask2Reward.value = true
|
||||
try {
|
||||
const res = await claimDailyRechargeTask2({
|
||||
activityType: 'DAILY_RECHARGE_TASK2',
|
||||
ruleId: currentTask2RewardTop.value.rule.id,
|
||||
})
|
||||
if (res.status) {
|
||||
await getDailyRechargeTaskInfo()
|
||||
}
|
||||
} catch (error) {
|
||||
showError(error?.errorMsg || error?.message || t('active_game_claim_reward_failed'))
|
||||
} finally {
|
||||
claimingTask2Reward.value = false
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
const getDailyRechargeTaskInfo = async () => {
|
||||
const res = await getDailyRechargeInfo()
|
||||
if (res.status && res.body) {
|
||||
taskInfo.value = {
|
||||
...createDefaultTaskInfo(),
|
||||
...res.body,
|
||||
levelList: Array.isArray(res.body.levelList) ? res.body.levelList : [],
|
||||
}
|
||||
selectedRewardLevel.value = normalizeLevel(res.body.task1MaxLevel || 1)
|
||||
}
|
||||
}
|
||||
|
||||
const getActivityRewards = async () => {
|
||||
const res = await apiGetActivityResource('DAILY_RECHARGE_TASK2')
|
||||
if (res.status && res.body) {
|
||||
activityRewards.value = Array.isArray(res.body) ? res.body : []
|
||||
}
|
||||
}
|
||||
|
||||
const initData = async () => {
|
||||
await Promise.all([getDailyRechargeTaskInfo(), getActivityRewards()])
|
||||
}
|
||||
|
||||
const preloadCriticalImages = async () => {
|
||||
const chestImages = chestProgressList.value.map((chest) => imageUrl(getChestImageName(chest)))
|
||||
const criticalImages = [
|
||||
imageUrl('bg'),
|
||||
imageUrl('totalRewardBg'),
|
||||
imageUrl('lvTaskBg'),
|
||||
imageUrl('LvRewardInfoBg'),
|
||||
imageUrl('ruleInfoBg'),
|
||||
imageUrl(`titleLv${currentLevel.value}`),
|
||||
imageUrl(currentChestImageName.value),
|
||||
imageUrl('amountShowBt'),
|
||||
imageUrl('amountHiddenBt'),
|
||||
imageUrl('done'),
|
||||
imageUrl('LvActive'),
|
||||
...chestImages,
|
||||
imageUrl(getImgName('LvRewardTitle')),
|
||||
imageUrl(getImgName('receiveBt')),
|
||||
imageUrl(getImgName('receivedBt')),
|
||||
imageUrl(getImgName('ruleTitle')),
|
||||
]
|
||||
|
||||
await Promise.all([
|
||||
preloadImages(criticalImages),
|
||||
preloadVapConfig(resolveProtectedAssetUrl(bgVapUrl)),
|
||||
])
|
||||
}
|
||||
|
||||
const completePreloading = async () => {
|
||||
try {
|
||||
await initData()
|
||||
await preloadCriticalImages()
|
||||
} catch (error) {
|
||||
console.error('预加载过程中发生错误:', error)
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const connectToAppHandler = async () => {
|
||||
await connectToApp(() => {
|
||||
completePreloading()
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
connectToAppHandler()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
* {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.fullPage {
|
||||
height: 100vh;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
background: #220e08;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
background: #220e08;
|
||||
}
|
||||
|
||||
.active-game-shell {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.active-game-stage {
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
position: relative;
|
||||
isolation: isolate;
|
||||
}
|
||||
|
||||
.page-background-layer {
|
||||
position: absolute;
|
||||
top: 120vw;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 0;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.vap-background-layer {
|
||||
width: 100vw;
|
||||
height: 150vw;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.page-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 132vw 2vw 10vw;
|
||||
}
|
||||
|
||||
.chest-progress-row {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.chest-progress-track {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
height: 3vw;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: rgba(103, 41, 0, 0.7);
|
||||
}
|
||||
|
||||
.chest-progress-bar {
|
||||
display: block;
|
||||
height: 3vw;
|
||||
object-fit: cover;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
.chest-progress-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2vw;
|
||||
}
|
||||
|
||||
.reward-showcase {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
gap: 3vw;
|
||||
direction: ltr;
|
||||
unicode-bidi: isolate;
|
||||
}
|
||||
|
||||
.reward-showcase-main,
|
||||
.reward-showcase-item {
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.reward-showcase-main {
|
||||
width: 33vw;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.reward-showcase-vap-wrap {
|
||||
width: 90%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.reward-showcase-grid {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: repeat(3, 1fr);
|
||||
column-gap: 3vw;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
.reward-showcase-text {
|
||||
color: #fff;
|
||||
font-size: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.scroll::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[dir='rtl'] .flipImg {
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
.ruleBt {
|
||||
width: 5vw;
|
||||
min-width: 0;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: -5vw;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
[dir='rtl'] .ruleBt {
|
||||
left: 0px;
|
||||
right: auto;
|
||||
}
|
||||
|
||||
@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>
|
||||
57
src/views/Activities/DailyRecharge/vapBg.vue
Normal file
57
src/views/Activities/DailyRecharge/vapBg.vue
Normal file
@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div class="active-game-page">
|
||||
<VapMp4Player
|
||||
v-model="backgroundVisible"
|
||||
class="vap-background"
|
||||
:src="src"
|
||||
mode="inline"
|
||||
fit="cover"
|
||||
:loop="true"
|
||||
:mute="false"
|
||||
:auto-close="false"
|
||||
:show-status="false"
|
||||
@error="handleVapError"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { showError } from '@/utils/toast.js'
|
||||
import VapMp4Player from '@/components/VapMp4Player.vue'
|
||||
import { preloadVapConfig } from '@/utils/vapMp4Config.js'
|
||||
import { resolveProtectedAssetUrl } from '@/utils/protectedAssets.js'
|
||||
|
||||
const props = defineProps({
|
||||
src: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
})
|
||||
|
||||
const backgroundVisible = ref(true)
|
||||
|
||||
function preloadTestVap() {
|
||||
if (props.src) {
|
||||
preloadVapConfig(resolveProtectedAssetUrl(props.src))
|
||||
}
|
||||
}
|
||||
|
||||
function handleVapError(error) {
|
||||
console.error('VAP playback failed:', error)
|
||||
showError(error?.message || 'VAP playback failed')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
preloadTestVap()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.active-game-page {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user