h5相关
@ -110,6 +110,8 @@
|
||||
data.qualification || data.qualifications || data.agency || {};
|
||||
var record =
|
||||
data.record || data.opening_record || data.openingRecord || {};
|
||||
var application =
|
||||
data.application || data.opening_application || data.openingApplication || {};
|
||||
var joined = Boolean(
|
||||
firstValue(data, ['joined', 'has_joined', 'hasJoined'], false)
|
||||
);
|
||||
@ -197,7 +199,20 @@
|
||||
['reward', 'reward_coins', 'rewardCoins'],
|
||||
'500K'
|
||||
),
|
||||
scoreEndMS:
|
||||
Number(
|
||||
firstValue(
|
||||
record,
|
||||
['score_end_ms', 'scoreEndMs'],
|
||||
firstValue(
|
||||
application,
|
||||
['score_end_ms', 'scoreEndMs'],
|
||||
0
|
||||
)
|
||||
)
|
||||
) || 0,
|
||||
},
|
||||
application: application,
|
||||
joined: joined,
|
||||
};
|
||||
}
|
||||
@ -368,7 +383,10 @@
|
||||
: Promise.resolve({
|
||||
joined: true,
|
||||
qualification: {
|
||||
opening_status: t('agencyOpening.joined', 'Joined'),
|
||||
opening_status: t(
|
||||
'agencyOpening.pendingReview',
|
||||
'Pending Review'
|
||||
),
|
||||
},
|
||||
});
|
||||
|
||||
@ -388,13 +406,9 @@
|
||||
'status_text',
|
||||
'statusText',
|
||||
],
|
||||
t('agencyOpening.joined', 'Joined')
|
||||
t('agencyOpening.pendingReview', 'Pending Review')
|
||||
),
|
||||
});
|
||||
next.qualification.openingStatus = t(
|
||||
'agencyOpening.joined',
|
||||
'Joined'
|
||||
);
|
||||
next.qualification.eligible = false;
|
||||
applyStatus(next);
|
||||
showToast(
|
||||
|
||||
BIN
activity/wheel/assets/other/advanced_gift.webp
Normal file
|
After Width: | Height: | Size: 383 KiB |
BIN
activity/wheel/assets/other/christmasCheckIn_lottery_bg.png
Normal file
|
After Width: | Height: | Size: 195 KiB |
BIN
activity/wheel/assets/other/christmasCheckIn_lottery_go.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
activity/wheel/assets/other/christmasCheckIn_lottery_select.png
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
BIN
activity/wheel/assets/other/gold.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
activity/wheel/assets/other/gold_new.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
BIN
activity/wheel/assets/other/lucky_box_back.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
activity/wheel/assets/other/lucky_box_bg_new.png
Normal file
|
After Width: | Height: | Size: 804 KiB |
BIN
activity/wheel/assets/other/lucky_box_bottom.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
activity/wheel/assets/other/lucky_box_btn.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
activity/wheel/assets/other/lucky_box_center.png
Normal file
|
After Width: | Height: | Size: 567 B |
BIN
activity/wheel/assets/other/lucky_box_close.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
activity/wheel/assets/other/lucky_box_defalute.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
activity/wheel/assets/other/lucky_box_go.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
activity/wheel/assets/other/lucky_box_gold.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
activity/wheel/assets/other/lucky_box_light.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
activity/wheel/assets/other/lucky_box_light2.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
activity/wheel/assets/other/lucky_box_middle.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
activity/wheel/assets/other/lucky_box_reward.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
activity/wheel/assets/other/lucky_box_reward_bg.png
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
activity/wheel/assets/other/lucky_box_rule.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
activity/wheel/assets/other/lucky_box_select.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
activity/wheel/assets/other/lucky_box_three_bg_new.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
activity/wheel/assets/other/lucky_box_three_btn.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
activity/wheel/assets/other/lucky_box_three_default.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
activity/wheel/assets/other/lucky_box_three_go.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
activity/wheel/assets/other/lucky_box_three_gold.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
activity/wheel/assets/other/lucky_box_three_history.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
activity/wheel/assets/other/lucky_box_three_notice.png
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
activity/wheel/assets/other/lucky_box_three_reward_bg.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
BIN
activity/wheel/assets/other/lucky_box_three_rule.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
activity/wheel/assets/other/lucky_box_three_select.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
activity/wheel/assets/other/lucky_box_three_unbtn.png
Normal file
|
After Width: | Height: | Size: 5.5 KiB |
BIN
activity/wheel/assets/other/lucky_box_three_unselect.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
activity/wheel/assets/other/lucky_box_title_top.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
activity/wheel/assets/other/lucky_box_top.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_bg_new.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
activity/wheel/assets/other/lucky_box_tow_btn1.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_btn2.png
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_btn3.png
Normal file
|
After Width: | Height: | Size: 7.5 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_default.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_gold.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_light.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_light2.png
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_middle.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_notice.png
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_pointer.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_reward.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_reward_bg.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_reward_bottom.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_reward_center.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_reward_desc.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_reward_top.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_reward_yuan.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_rule.png
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_rule_top.png
Normal file
|
After Width: | Height: | Size: 6.6 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_turntable.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_unbtn1.png
Normal file
|
After Width: | Height: | Size: 7.3 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_unbtn2.png
Normal file
|
After Width: | Height: | Size: 8.2 KiB |
BIN
activity/wheel/assets/other/lucky_box_tow_unbtn3.png
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
BIN
activity/wheel/assets/other/lucky_box_unbtn.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
BIN
activity/wheel/assets/other/lucky_box_unselect.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
423
activity/wheel/index.html
Normal file
@ -0,0 +1,423 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"
|
||||
/>
|
||||
<title data-i18n="wheel.pageTitle">Yumi Wheel</title>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="../../common/theme.css?v=20260618-wheel-batch2"
|
||||
/>
|
||||
<link rel="stylesheet" href="./style.css?v=20260618-wheel-batch2" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" v-cloak>
|
||||
<main
|
||||
class="wheel-page"
|
||||
:class="pageClass"
|
||||
data-i18n-aria="wheel.pageLabel"
|
||||
aria-label="Yumi Wheel"
|
||||
>
|
||||
<div v-if="pageLoading" class="wheel-loading">
|
||||
{{ common('loading') }}
|
||||
</div>
|
||||
<section v-else class="wheel-stage">
|
||||
<nav class="lucky-tab" aria-label="Wheel type">
|
||||
<button
|
||||
v-for="tab in tabs"
|
||||
v-show="enabled[tab.key]"
|
||||
:key="tab.key"
|
||||
type="button"
|
||||
class="tab-item"
|
||||
:class="[tab.key, { active: currentPage === tab.key }]"
|
||||
@click="handleSelect(tab.key)"
|
||||
>
|
||||
{{ t(tab.labelKey) }}
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<div class="marquee-box" v-if="currentConfig.hasMarqueeBox">
|
||||
<div class="marquee-content">
|
||||
<div
|
||||
class="reward"
|
||||
:class="{ 'reward-active': currentLanguage === 'ar' }"
|
||||
:style="{ animationDuration: durationSpeed }"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in marqueeRewards"
|
||||
:key="index"
|
||||
class="reward-list"
|
||||
>
|
||||
<img
|
||||
:src="item.avatar"
|
||||
class="img"
|
||||
alt=""
|
||||
/>
|
||||
<span
|
||||
>{{ replaceTwo('userAward',
|
||||
item.nickname, item.value) }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="marquee-content" v-else>
|
||||
<div
|
||||
class="reward"
|
||||
:class="{ 'reward-active': currentLanguage === 'ar' }"
|
||||
:style="{ animationDuration: durationSpeed }"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in marqueeRewards"
|
||||
:key="index"
|
||||
class="reward-list"
|
||||
>
|
||||
<img :src="item.avatar" class="img" alt="" />
|
||||
<span
|
||||
>{{ replaceTwo('userAward', item.nickname,
|
||||
item.value) }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lucky-content">
|
||||
<div class="content">
|
||||
<img
|
||||
v-if="currentConfig.lightPrefix"
|
||||
:src="asset(currentConfig.lightPrefix + active.currentBackground + '.png')"
|
||||
class="right"
|
||||
alt=""
|
||||
/>
|
||||
<div
|
||||
class="lottery-grid"
|
||||
:class="currentConfig.gridClass"
|
||||
>
|
||||
<div
|
||||
v-if="currentConfig.type === 'round'"
|
||||
class="turntable-content"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in active.gridItems"
|
||||
:key="item.id || index"
|
||||
class="grid-item"
|
||||
:style="getPrizePosition(index)"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click.stop="openPrizePreview(item)"
|
||||
@keyup.enter.prevent="openPrizePreview(item)"
|
||||
>
|
||||
<div class="item">
|
||||
<img
|
||||
:src="item.merchandise.coverUrl"
|
||||
class="img"
|
||||
alt=""
|
||||
/>
|
||||
<div class="item-gold">
|
||||
<img
|
||||
:src="asset('gold_new.png')"
|
||||
alt=""
|
||||
/>{{ item.value }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-else>
|
||||
<div
|
||||
v-for="(item, index) in active.gridItems"
|
||||
:key="item.id || index"
|
||||
class="grid-item"
|
||||
:class="{ active: active.activeIndex === index }"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click.stop="openPrizePreview(item)"
|
||||
@keyup.enter.prevent="openPrizePreview(item)"
|
||||
>
|
||||
<img
|
||||
v-if="currentPage === 'advanced' && index > 5"
|
||||
:src="asset('advanced_gift.webp')"
|
||||
class="gift-webp"
|
||||
alt=""
|
||||
/>
|
||||
<img
|
||||
:src="item.merchandise.coverUrl"
|
||||
class="img"
|
||||
alt=""
|
||||
/>
|
||||
<div class="item-gold">
|
||||
<img
|
||||
:src="asset('gold_new.png')"
|
||||
alt=""
|
||||
/>{{ item.value }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div
|
||||
v-if="active.isInit && !active.gridItems.length"
|
||||
class="wheel-empty"
|
||||
>
|
||||
{{ common('rewardUnavailable') }}
|
||||
</div>
|
||||
|
||||
<button
|
||||
class="start-button"
|
||||
type="button"
|
||||
:style="pointerStyle()"
|
||||
:disabled="!active.gridItems.length || active.drawAmount <= 0 || active.isSpinning"
|
||||
@click="startLottery"
|
||||
>
|
||||
<template v-if="currentPage === 'advanced'">
|
||||
<span>{{ common('balance') }}:</span>
|
||||
<strong
|
||||
><i></i>{{ userBalance }}</strong
|
||||
>
|
||||
</template>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-start">
|
||||
<button
|
||||
v-for="(item, index) in active.goldBtn"
|
||||
:key="item.value"
|
||||
type="button"
|
||||
class="btn"
|
||||
:class="{ active: active.activeBtnIndex === index }"
|
||||
:style="buttonStyle(index)"
|
||||
:disabled="!active.gridItems.length || active.drawAmount <= 0"
|
||||
@click="handleGoldBtn(index)"
|
||||
>
|
||||
<span>{{ item.name }}</span>
|
||||
<strong
|
||||
>{{ item.value * active.drawAmount }}</strong
|
||||
>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="desc-content">
|
||||
<button
|
||||
class="rule"
|
||||
type="button"
|
||||
:aria-label="common('rule')"
|
||||
@click="active.showRecord = true"
|
||||
></button>
|
||||
<button
|
||||
class="record"
|
||||
type="button"
|
||||
:aria-label="t('historyRecord')"
|
||||
@click="active.showRule = true"
|
||||
></button>
|
||||
</div>
|
||||
<div v-if="currentPage !== 'advanced'" class="user-gold">
|
||||
<img :src="asset('gold_new.png')" alt="" />{{
|
||||
userBalance }}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div
|
||||
v-if="active.showRule"
|
||||
class="wheel-popup"
|
||||
@click.self="active.showRule = false"
|
||||
>
|
||||
<section class="rule-content">
|
||||
<button
|
||||
class="popup-close rule-close"
|
||||
type="button"
|
||||
@click="active.showRule = false"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
<div class="rule-title">{{ common('rule') }}</div>
|
||||
<div
|
||||
v-if="currentPage !== 'advanced'"
|
||||
class="rule-top"
|
||||
></div>
|
||||
<div class="rule-center">
|
||||
<p class="rule-desc">{{ t('rule1') }}</p>
|
||||
<p class="rule-desc">{{ t('rule2') }}</p>
|
||||
<p class="rule-desc">{{ t('rule3') }}</p>
|
||||
</div>
|
||||
<div
|
||||
v-if="currentPage !== 'advanced'"
|
||||
class="rule-bottom"
|
||||
></div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="active.showRecord"
|
||||
class="wheel-popup"
|
||||
@click.self="active.showRecord = false"
|
||||
>
|
||||
<section class="popup-content">
|
||||
<button
|
||||
class="popup-close icon rule-close"
|
||||
type="button"
|
||||
@click="active.showRecord = false"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
<div class="bg-title">{{ t('historyRecord') }}</div>
|
||||
<div
|
||||
v-if="currentPage !== 'advanced'"
|
||||
class="rule-top"
|
||||
></div>
|
||||
<div class="rule-center">
|
||||
<div class="record-list">
|
||||
<article
|
||||
v-for="(item, index) in active.historyRecord"
|
||||
:key="index"
|
||||
class="record-item list"
|
||||
>
|
||||
<header class="item-title">
|
||||
<span class="left"
|
||||
>{{ formatDate(item.createdTime,
|
||||
'yyyy-MM-dd') }}</span
|
||||
>
|
||||
<span
|
||||
>{{ formatDate(item.createdTime,
|
||||
'HH:mm:ss') }}</span
|
||||
>
|
||||
<strong class="right"
|
||||
>X{{ item.drawTimes }}</strong
|
||||
>
|
||||
</header>
|
||||
<div class="box-content">
|
||||
<div
|
||||
v-for="(reward, rewardIndex) in item.rewards"
|
||||
:key="rewardIndex"
|
||||
class="box-desc"
|
||||
>
|
||||
<div
|
||||
class="box previewable-box"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click.stop="openPrizePreview(reward)"
|
||||
@keyup.enter.prevent="openPrizePreview(reward)"
|
||||
>
|
||||
<img
|
||||
:src="reward.coverUrl"
|
||||
class="img"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<span>X{{ reward.count }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
<p v-if="active.finished" class="finished-text">
|
||||
{{ common('noDate') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="currentPage !== 'advanced'"
|
||||
class="rule-bottom"
|
||||
></div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="active.showReward"
|
||||
class="wheel-popup"
|
||||
@click.self="active.showReward = false"
|
||||
>
|
||||
<section class="reward-content">
|
||||
<div class="bg"></div>
|
||||
<div class="title">{{ common('rewards') }}</div>
|
||||
<button
|
||||
class="popup-close reward-close"
|
||||
type="button"
|
||||
@click="active.showReward = false"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
<div class="content">
|
||||
<div class="box-content">
|
||||
<div
|
||||
v-for="(item, index) in active.currentReward.rewards"
|
||||
:key="index"
|
||||
class="box-desc"
|
||||
>
|
||||
<div
|
||||
class="box previewable-box"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click.stop="openPrizePreview(item)"
|
||||
@keyup.enter.prevent="openPrizePreview(item)"
|
||||
>
|
||||
<img
|
||||
:src="item.coverUrl"
|
||||
class="img"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
<span>X{{ item.count }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <p class="tips">
|
||||
{{ replaceOne('rewardTips',
|
||||
active.currentReward.rewardValue) }}
|
||||
</p> -->
|
||||
<button
|
||||
class="again-btn"
|
||||
type="button"
|
||||
@click="startLottery"
|
||||
>
|
||||
{{ t('drawAgain') }}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="preview.open"
|
||||
class="material-preview-overlay"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
aria-label="Close preview"
|
||||
@click="closePrizePreview"
|
||||
@keyup.enter.prevent="closePrizePreview"
|
||||
@keyup.space.prevent="closePrizePreview"
|
||||
@keyup.esc.prevent="closePrizePreview"
|
||||
>
|
||||
<button
|
||||
class="material-preview-close"
|
||||
type="button"
|
||||
aria-label="Close preview"
|
||||
@click.stop="closePrizePreview"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
<div class="material-preview-stage">
|
||||
<img
|
||||
v-if="preview.coverUrl"
|
||||
ref="previewImage"
|
||||
:src="preview.coverUrl"
|
||||
class="material-preview-image"
|
||||
:class="{ 'is-dynamic-hidden': preview.animationReady }"
|
||||
alt=""
|
||||
/>
|
||||
<div
|
||||
ref="previewEffect"
|
||||
class="material-preview-effect"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.16/dist/vue.min.js"></script>
|
||||
<script src="../../common/i18n.js?v=20260618-wheel-batch2"></script>
|
||||
<script src="../../common/api.js?v=20260618-wheel-batch2"></script>
|
||||
<script src="../../common/toast.js?v=20260618-wheel-batch2"></script>
|
||||
<script src="../../common/effect-player.js?v=20260618-wheel-batch2"></script>
|
||||
<script src="./script.js?v=20260618-wheel-batch2"></script>
|
||||
</body>
|
||||
</html>
|
||||
1355
activity/wheel/script.js
Normal file
1183
activity/wheel/style.css
Normal file
@ -756,6 +756,53 @@ var default_api = 'https://api.global-interaction.com/';
|
||||
},
|
||||
};
|
||||
|
||||
// 转盘 H5 只通过 gateway 活动接口读配置、抽奖、查记录和跑马灯提示;页面不再内置 mock 奖品,避免后台资源组未配置时前端仍展示假奖池。
|
||||
// 抽奖 command_id 由页面点击时生成并随请求提交,服务端用它做幂等,网络重试不会重复扣费或重复发奖。
|
||||
var activityWheelAPI = {
|
||||
config: function (wheelID) {
|
||||
return request(
|
||||
'/api/v1/activity/wheel/' +
|
||||
encodeURIComponent(wheelID || 'classic') +
|
||||
'/config',
|
||||
{ method: 'GET' }
|
||||
);
|
||||
},
|
||||
draw: function (wheelID, payload) {
|
||||
return request(
|
||||
'/api/v1/activity/wheel/' +
|
||||
encodeURIComponent(wheelID || 'classic') +
|
||||
'/draw',
|
||||
{
|
||||
method: 'POST',
|
||||
body: payload || {},
|
||||
}
|
||||
);
|
||||
},
|
||||
history: function (wheelID, params) {
|
||||
return request(
|
||||
'/api/v1/activity/wheel/' +
|
||||
encodeURIComponent(wheelID || 'classic') +
|
||||
'/history',
|
||||
{
|
||||
method: 'POST',
|
||||
query: params || {},
|
||||
body: {},
|
||||
}
|
||||
);
|
||||
},
|
||||
hints: function (wheelID) {
|
||||
return request(
|
||||
'/api/v1/activity/wheel/' +
|
||||
encodeURIComponent(wheelID || 'classic') +
|
||||
'/hints',
|
||||
{
|
||||
method: 'POST',
|
||||
body: {},
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
// 邀请活动 H5 只关心当前用户本月状态和领取动作;有效人数、累计充值和最高档差额都以后端聚合事实为准。
|
||||
// 领取时页面必须传入本次点击生成的 command_id,服务端按用户、周期、档位和 command_id 做幂等发奖。
|
||||
var inviteActivityRewardAPI = {
|
||||
@ -938,6 +985,7 @@ var default_api = 'https://api.global-interaction.com/';
|
||||
roleInvitations: roleInvitationAPI,
|
||||
managerCenter: managerCenterAPI,
|
||||
superadminCenter: superadminCenterAPI,
|
||||
activityWheel: activityWheelAPI,
|
||||
level: levelAPI,
|
||||
task: taskAPI,
|
||||
weeklyStar: weeklyStarAPI,
|
||||
|
||||
@ -106,11 +106,7 @@
|
||||
function resolveLang() {
|
||||
var requestedLang = queryLang();
|
||||
if (requestedLang) return normalizeLang(requestedLang) || DEFAULT_LANG;
|
||||
return (
|
||||
normalizeLang(storageGet(STORAGE_KEY)) ||
|
||||
normalizeLang(window.navigator.language) ||
|
||||
DEFAULT_LANG
|
||||
);
|
||||
return DEFAULT_LANG;
|
||||
}
|
||||
|
||||
function load(lang) {
|
||||
|
||||
@ -65,6 +65,27 @@
|
||||
"rechargeReward.idPrefix": "المعرّف:",
|
||||
"rechargeReward.accumulatedRecharge": "إجمالي الشحن:",
|
||||
"rechargeReward.rechargeTitle": "اشحن {amount}",
|
||||
"wheel.pageTitle": "عجلة يومي",
|
||||
"wheel.pageLabel": "عجلة يومي",
|
||||
"wheel.classic": "كلاسيكي",
|
||||
"wheel.inLove": "رفاهية",
|
||||
"wheel.advanced": "متقدم",
|
||||
"wheel.historyRecord": "سجل التاريخ",
|
||||
"wheel.rewardTips": "تهانينا على استلام: هدية ثمينة بقيمة {} قطعة ذهبية! وُضعت في حقيبة الظهر.",
|
||||
"wheel.drawAgain": "اسحب مرة أخرى.",
|
||||
"wheel.userAward": "تهانينا لـ {1} على حصوله على جائزة {2}",
|
||||
"wheel.roomId": "لا يمكن أن يكون معرف الغرفة فارغًا",
|
||||
"wheel.rule1": "1. اختر عجلة واسحب باستخدام العملات.",
|
||||
"wheel.rule2": "2. يتم إرسال الجوائز إلى الحقيبة بعد نجاح السحب.",
|
||||
"wheel.rule3": "3. لا علاقة لهذا النشاط بشركة Apple أو Google.",
|
||||
"wheel.common.loading": "جارٍ التحميل",
|
||||
"wheel.common.rule": "قاعدة",
|
||||
"wheel.common.rewards": "المكافآت",
|
||||
"wheel.common.balance": "الرصيد",
|
||||
"wheel.common.noDate": "لا مزيد من البيانات",
|
||||
"wheel.common.balanceNotEnough": "رصيد غير كاف",
|
||||
"wheel.common.rewardUnavailable": "المكافآت غير متاحة بعد",
|
||||
"wheel.common.requestFailed": "فشل الطلب",
|
||||
"invite.pageAria": "دعوة الأصدقاء",
|
||||
"invite.heroAria": "ادع الأصدقاء واكسب المال",
|
||||
"invite.countdownAria": "العد التنازلي",
|
||||
@ -557,6 +578,7 @@
|
||||
"agencyOpening.joined": "تم الانضمام",
|
||||
"agencyOpening.notJoined": "لم ينضم",
|
||||
"agencyOpening.applied": "تم التقديم",
|
||||
"agencyOpening.pendingReview": "بانتظار المراجعة",
|
||||
"agencyOpening.applySuccess": "تم إرسال الطلب.",
|
||||
"agencyOpening.applyFailed": "فشل الطلب. حاول لاحقا.",
|
||||
"agencyOpening.rewardsTitle": "مكافآت الافتتاح",
|
||||
@ -567,8 +589,8 @@
|
||||
"agencyOpening.rule2": "يجب أن يكون عدد المضيفين أكثر من 10.",
|
||||
"agencyOpening.rule3": "يجب أن يكون عمر الوكالة أقل من 7 أيام.",
|
||||
"agencyOpening.rule4": "يمكن لكل وكالة المشاركة مرة واحدة فقط.",
|
||||
"agencyOpening.rule5": "لا يمكن تشغيل فعالية الافتتاح مع برنامج دعم الوكالات في نفس الوقت.",
|
||||
"agencyOpening.rule6": "ترسل المكافآت خلال 7 أيام بعد المراجعة.",
|
||||
"agencyOpening.rule5": "تبدأ إيرادات الافتتاح بعد موافقة المسؤول وتحتسب لمدة 24 ساعة فقط.",
|
||||
"agencyOpening.rule6": "ترسل المكافآت تلقائيا بعد انتهاء الفعالية.",
|
||||
"agencyOpening.recordTitle": "سجل الافتتاح",
|
||||
"agencyOpening.guildName": "اسم النقابة:",
|
||||
"agencyOpening.created": "تاريخ الإنشاء:",
|
||||
|
||||
@ -65,6 +65,27 @@
|
||||
"rechargeReward.idPrefix": "ID:",
|
||||
"rechargeReward.accumulatedRecharge": "Accumulated Recharge:",
|
||||
"rechargeReward.rechargeTitle": "Recharge {amount}",
|
||||
"wheel.pageTitle": "Yumi Wheel",
|
||||
"wheel.pageLabel": "Yumi Wheel",
|
||||
"wheel.classic": "Classic",
|
||||
"wheel.inLove": "luxury",
|
||||
"wheel.advanced": "Advanced",
|
||||
"wheel.historyRecord": "History Record",
|
||||
"wheel.rewardTips": "Congratulations on receiving: A precious gift worth {} gold coins! Already put in the backpack",
|
||||
"wheel.drawAgain": "Draw again",
|
||||
"wheel.userAward": "Congratulations to {1} for receiving the {2} award",
|
||||
"wheel.roomId": "Room ID cannot be empty",
|
||||
"wheel.rule1": "1. Select a wheel and draw with coins.",
|
||||
"wheel.rule2": "2. Rewards are issued to the backpack after a successful draw.",
|
||||
"wheel.rule3": "3. This activity has no relationship with Apple or Google.",
|
||||
"wheel.common.loading": "Loading",
|
||||
"wheel.common.rule": "rule",
|
||||
"wheel.common.rewards": "Rewards",
|
||||
"wheel.common.balance": "Balance",
|
||||
"wheel.common.noDate": "No more data",
|
||||
"wheel.common.balanceNotEnough": "Insufficient balance",
|
||||
"wheel.common.rewardUnavailable": "Rewards are not available yet",
|
||||
"wheel.common.requestFailed": "Request failed",
|
||||
"invite.pageAria": "Invite friends",
|
||||
"invite.heroAria": "Invite friends make money",
|
||||
"invite.countdownAria": "Countdown",
|
||||
@ -563,6 +584,7 @@
|
||||
"agencyOpening.joined": "Joined",
|
||||
"agencyOpening.notJoined": "Not Joined",
|
||||
"agencyOpening.applied": "Applied",
|
||||
"agencyOpening.pendingReview": "Pending Review",
|
||||
"agencyOpening.applySuccess": "Application submitted.",
|
||||
"agencyOpening.applyFailed": "Application failed. Try again later.",
|
||||
"agencyOpening.rewardsTitle": "Opening Rewards",
|
||||
@ -573,8 +595,8 @@
|
||||
"agencyOpening.rule2": "Host count must be more than 10.",
|
||||
"agencyOpening.rule3": "Agency age must be less than 7 days.",
|
||||
"agencyOpening.rule4": "Each agency can join only once in lifetime.",
|
||||
"agencyOpening.rule5": "Opening Event cannot run with Agency Support Program at the same time.",
|
||||
"agencyOpening.rule6": "Rewards will be sent within 7 days after review.",
|
||||
"agencyOpening.rule5": "Opening revenue starts after admin approval and counts for 24 hours only.",
|
||||
"agencyOpening.rule6": "Rewards will be sent automatically after the activity ends.",
|
||||
"agencyOpening.recordTitle": "Opening Record",
|
||||
"agencyOpening.guildName": "Guild Name:",
|
||||
"agencyOpening.created": "Created:",
|
||||
|
||||
@ -65,6 +65,27 @@
|
||||
"rechargeReward.idPrefix": "ID:",
|
||||
"rechargeReward.accumulatedRecharge": "Recarga acumulada:",
|
||||
"rechargeReward.rechargeTitle": "Recarga {amount}",
|
||||
"wheel.pageTitle": "Rueda de Yumi",
|
||||
"wheel.pageLabel": "Rueda de Yumi",
|
||||
"wheel.classic": "Clásico",
|
||||
"wheel.inLove": "lujo",
|
||||
"wheel.advanced": "Avanzado",
|
||||
"wheel.historyRecord": "Historial",
|
||||
"wheel.rewardTips": "Felicidades por recibir: un regalo valioso de {} monedas de oro. Ya está en la mochila",
|
||||
"wheel.drawAgain": "Girar otra vez",
|
||||
"wheel.userAward": "Felicidades a {1} por recibir el premio {2}",
|
||||
"wheel.roomId": "El ID de la sala no puede estar vacío",
|
||||
"wheel.rule1": "1. Selecciona una rueda y gira con monedas.",
|
||||
"wheel.rule2": "2. Las recompensas se envían a la mochila tras un sorteo exitoso.",
|
||||
"wheel.rule3": "3. Esta actividad no tiene relación con Apple ni Google.",
|
||||
"wheel.common.loading": "Cargando",
|
||||
"wheel.common.rule": "regla",
|
||||
"wheel.common.rewards": "Recompensas",
|
||||
"wheel.common.balance": "Saldo",
|
||||
"wheel.common.noDate": "No hay más datos",
|
||||
"wheel.common.balanceNotEnough": "Saldo insuficiente",
|
||||
"wheel.common.rewardUnavailable": "Las recompensas aún no están disponibles",
|
||||
"wheel.common.requestFailed": "Solicitud fallida",
|
||||
"invite.pageAria": "Invitar amigos",
|
||||
"invite.heroAria": "Invita amigos y gana dinero",
|
||||
"invite.countdownAria": "Cuenta regresiva",
|
||||
@ -557,6 +578,7 @@
|
||||
"agencyOpening.joined": "Unido",
|
||||
"agencyOpening.notJoined": "No unido",
|
||||
"agencyOpening.applied": "Solicitado",
|
||||
"agencyOpening.pendingReview": "Pendiente de revisión",
|
||||
"agencyOpening.applySuccess": "Solicitud enviada.",
|
||||
"agencyOpening.applyFailed": "Solicitud fallida. Inténtalo más tarde.",
|
||||
"agencyOpening.rewardsTitle": "Recompensas de apertura",
|
||||
@ -567,8 +589,8 @@
|
||||
"agencyOpening.rule2": "La cantidad de hosts debe ser mayor que 10.",
|
||||
"agencyOpening.rule3": "La agencia debe tener menos de 7 días.",
|
||||
"agencyOpening.rule4": "Cada agencia solo puede participar una vez.",
|
||||
"agencyOpening.rule5": "El evento de apertura no puede ejecutarse junto con el Programa de soporte de agencias.",
|
||||
"agencyOpening.rule6": "Las recompensas se enviarán dentro de 7 días después de la revisión.",
|
||||
"agencyOpening.rule5": "Los ingresos de apertura comienzan tras la aprobación del admin y solo cuentan durante 24 horas.",
|
||||
"agencyOpening.rule6": "Las recompensas se envían automáticamente cuando termina la actividad.",
|
||||
"agencyOpening.recordTitle": "Registro de apertura",
|
||||
"agencyOpening.guildName": "Nombre del gremio:",
|
||||
"agencyOpening.created": "Creado:",
|
||||
|
||||
@ -32,6 +32,27 @@
|
||||
"rechargeReward.idPrefix": "ID:",
|
||||
"rechargeReward.accumulatedRecharge": "Recharge akumulatif:",
|
||||
"rechargeReward.rechargeTitle": "Recharge {amount}",
|
||||
"wheel.pageTitle": "Yumi Wheel",
|
||||
"wheel.pageLabel": "Yumi Wheel",
|
||||
"wheel.classic": "Classic",
|
||||
"wheel.inLove": "Luxury",
|
||||
"wheel.advanced": "Advanced",
|
||||
"wheel.historyRecord": "Riwayat Hadiah",
|
||||
"wheel.rewardTips": "Selamat mendapatkan: hadiah bernilai {} koin emas! Sudah masuk ke backpack",
|
||||
"wheel.drawAgain": "Undi lagi",
|
||||
"wheel.userAward": "Selamat kepada {1} karena menerima hadiah {2}",
|
||||
"wheel.roomId": "ID room tidak boleh kosong",
|
||||
"wheel.rule1": "1. Pilih wheel dan undi dengan koin.",
|
||||
"wheel.rule2": "2. Hadiah dikirim ke backpack setelah undian berhasil.",
|
||||
"wheel.rule3": "3. Aktivitas ini tidak berhubungan dengan Apple atau Google.",
|
||||
"wheel.common.loading": "Memuat",
|
||||
"wheel.common.rule": "Aturan",
|
||||
"wheel.common.rewards": "Hadiah",
|
||||
"wheel.common.balance": "Saldo",
|
||||
"wheel.common.noDate": "Tidak ada data lagi",
|
||||
"wheel.common.balanceNotEnough": "Saldo tidak cukup",
|
||||
"wheel.common.rewardUnavailable": "Hadiah belum tersedia",
|
||||
"wheel.common.requestFailed": "Permintaan gagal",
|
||||
"invite.pageAria": "Undang teman",
|
||||
"invite.heroAria": "Undang teman dan hasilkan uang",
|
||||
"invite.countdownAria": "Hitung mundur",
|
||||
@ -524,6 +545,7 @@
|
||||
"agencyOpening.joined": "Sudah bergabung",
|
||||
"agencyOpening.notJoined": "Belum bergabung",
|
||||
"agencyOpening.applied": "Sudah diajukan",
|
||||
"agencyOpening.pendingReview": "Menunggu peninjauan",
|
||||
"agencyOpening.applySuccess": "Pengajuan terkirim.",
|
||||
"agencyOpening.applyFailed": "Pengajuan gagal. Coba lagi nanti.",
|
||||
"agencyOpening.rewardsTitle": "Hadiah Pembukaan",
|
||||
@ -534,8 +556,8 @@
|
||||
"agencyOpening.rule2": "Jumlah host harus lebih dari 10.",
|
||||
"agencyOpening.rule3": "Usia agensi harus kurang dari 7 hari.",
|
||||
"agencyOpening.rule4": "Setiap agensi hanya dapat ikut sekali seumur hidup.",
|
||||
"agencyOpening.rule5": "Event Pembukaan tidak dapat berjalan bersama Program Dukungan Agensi.",
|
||||
"agencyOpening.rule6": "Hadiah dikirim dalam 7 hari setelah peninjauan.",
|
||||
"agencyOpening.rule5": "Pendapatan pembukaan mulai dihitung setelah disetujui admin dan hanya berlaku 24 jam.",
|
||||
"agencyOpening.rule6": "Hadiah dikirim otomatis setelah aktivitas berakhir.",
|
||||
"agencyOpening.recordTitle": "Catatan Pembukaan",
|
||||
"agencyOpening.guildName": "Nama guild:",
|
||||
"agencyOpening.created": "Dibuat:",
|
||||
|
||||
@ -32,6 +32,27 @@
|
||||
"rechargeReward.idPrefix": "ID:",
|
||||
"rechargeReward.accumulatedRecharge": "Toplam yükleme:",
|
||||
"rechargeReward.rechargeTitle": "{amount} yükle",
|
||||
"wheel.pageTitle": "Yumi Çarkı",
|
||||
"wheel.pageLabel": "Yumi Çarkı",
|
||||
"wheel.classic": "Klasik",
|
||||
"wheel.inLove": "lüks",
|
||||
"wheel.advanced": "Gelişmiş",
|
||||
"wheel.historyRecord": "Tarih Kaydı",
|
||||
"wheel.rewardTips": "Aldığınız için tebrikler: {} altın değerinde değerli bir hediye! Zaten sırt çantasına koydum",
|
||||
"wheel.drawAgain": "Tekrar çekiliş",
|
||||
"wheel.userAward": "{1}'i {2} ödülünü aldığı için tebrik ederiz",
|
||||
"wheel.roomId": "Oda kimliği boş olamaz",
|
||||
"wheel.rule1": "1. Bir çark seçin ve coin ile çekiliş yapın.",
|
||||
"wheel.rule2": "2. Başarılı çekilişten sonra ödüller çantaya gönderilir.",
|
||||
"wheel.rule3": "3. Bu etkinliğin Apple veya Google ile ilişkisi yoktur.",
|
||||
"wheel.common.loading": "Yükleniyor",
|
||||
"wheel.common.rule": "kural",
|
||||
"wheel.common.rewards": "Ödüller",
|
||||
"wheel.common.balance": "Bakiye",
|
||||
"wheel.common.noDate": "Artık veri yok",
|
||||
"wheel.common.balanceNotEnough": "Yetersiz bakiye",
|
||||
"wheel.common.rewardUnavailable": "Ödüller henüz mevcut değil",
|
||||
"wheel.common.requestFailed": "İstek başarısız",
|
||||
"invite.pageAria": "Arkadaş davet et",
|
||||
"invite.heroAria": "Arkadaş davet et, para kazan",
|
||||
"invite.countdownAria": "Geri sayım",
|
||||
@ -524,6 +545,7 @@
|
||||
"agencyOpening.joined": "Katıldı",
|
||||
"agencyOpening.notJoined": "Katılmadı",
|
||||
"agencyOpening.applied": "Başvuruldu",
|
||||
"agencyOpening.pendingReview": "İnceleme bekliyor",
|
||||
"agencyOpening.applySuccess": "Başvuru gönderildi.",
|
||||
"agencyOpening.applyFailed": "Başvuru başarısız. Daha sonra tekrar deneyin.",
|
||||
"agencyOpening.rewardsTitle": "Açılış Ödülleri",
|
||||
@ -534,8 +556,8 @@
|
||||
"agencyOpening.rule2": "Host sayısı 10'dan fazla olmalıdır.",
|
||||
"agencyOpening.rule3": "Ajans yaşı 7 günden az olmalıdır.",
|
||||
"agencyOpening.rule4": "Her ajans ömür boyu yalnızca bir kez katılabilir.",
|
||||
"agencyOpening.rule5": "Açılış Etkinliği Ajans Destek Programı ile aynı anda çalışamaz.",
|
||||
"agencyOpening.rule6": "Ödüller incelemeden sonra 7 gün içinde gönderilir.",
|
||||
"agencyOpening.rule5": "Açılış geliri admin onayından sonra başlar ve yalnızca 24 saat sayılır.",
|
||||
"agencyOpening.rule6": "Ödüller etkinlik bittikten sonra otomatik gönderilir.",
|
||||
"agencyOpening.recordTitle": "Açılış Kaydı",
|
||||
"agencyOpening.guildName": "Lonca adı:",
|
||||
"agencyOpening.created": "Oluşturuldu:",
|
||||
|
||||
@ -32,6 +32,27 @@
|
||||
"rechargeReward.idPrefix": "ID:",
|
||||
"rechargeReward.accumulatedRecharge": "累计充值:",
|
||||
"rechargeReward.rechargeTitle": "充值 {amount}",
|
||||
"wheel.pageTitle": "Yumi 转盘",
|
||||
"wheel.pageLabel": "Yumi 转盘",
|
||||
"wheel.classic": "Classic",
|
||||
"wheel.inLove": "Luxury",
|
||||
"wheel.advanced": "Advanced",
|
||||
"wheel.historyRecord": "中奖历史",
|
||||
"wheel.rewardTips": "恭喜获得:价值 {} 金币的珍贵礼物!已放入背包",
|
||||
"wheel.drawAgain": "再抽一次",
|
||||
"wheel.userAward": "恭喜 {1} 获得 {2} 奖励",
|
||||
"wheel.roomId": "房间 ID 不能为空",
|
||||
"wheel.rule1": "1. 选择转盘并消耗金币抽奖。",
|
||||
"wheel.rule2": "2. 抽中奖品后会发放到背包。",
|
||||
"wheel.rule3": "3. 本活动与 Apple 或 Google 无关。",
|
||||
"wheel.common.loading": "加载中",
|
||||
"wheel.common.rule": "规则",
|
||||
"wheel.common.rewards": "奖励",
|
||||
"wheel.common.balance": "余额",
|
||||
"wheel.common.noDate": "没有更多数据",
|
||||
"wheel.common.balanceNotEnough": "余额不足",
|
||||
"wheel.common.rewardUnavailable": "奖池暂未开放",
|
||||
"wheel.common.requestFailed": "请求失败",
|
||||
"invite.pageAria": "邀请好友",
|
||||
"invite.heroAria": "邀请好友赚钱",
|
||||
"invite.countdownAria": "倒计时",
|
||||
@ -530,6 +551,7 @@
|
||||
"agencyOpening.joined": "已参加",
|
||||
"agencyOpening.notJoined": "未参加",
|
||||
"agencyOpening.applied": "已申请",
|
||||
"agencyOpening.pendingReview": "待审核",
|
||||
"agencyOpening.applySuccess": "申请已提交",
|
||||
"agencyOpening.applyFailed": "申请失败,请稍后再试",
|
||||
"agencyOpening.rewardsTitle": "开业奖励",
|
||||
@ -540,8 +562,8 @@
|
||||
"agencyOpening.rule2": "主播数量必须大于 10。",
|
||||
"agencyOpening.rule3": "代理创建时间必须小于 7 天。",
|
||||
"agencyOpening.rule4": "每个代理终身只能参加一次。",
|
||||
"agencyOpening.rule5": "开业活动不能和代理扶持计划同时进行。",
|
||||
"agencyOpening.rule6": "奖励会在审核通过后 7 天内发放。",
|
||||
"agencyOpening.rule5": "开业流水从后台同意后开始计算,只统计 24 小时内的房间流水。",
|
||||
"agencyOpening.rule6": "活动结束后按开业流水档位自动发放奖励。",
|
||||
"agencyOpening.recordTitle": "开业记录",
|
||||
"agencyOpening.guildName": "公会名称:",
|
||||
"agencyOpening.created": "创建时间:",
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
<link rel="stylesheet" href="../common/center.css?v=20260608" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="./style.css?v=20260612-manager-bd-leader"
|
||||
href="./style.css?v=20260618-manager-permissions"
|
||||
/>
|
||||
</head>
|
||||
|
||||
@ -474,6 +474,6 @@
|
||||
<script src="../../common/params.js?v=20260608-manager-real"></script>
|
||||
<script src="../../common/jsbridge.js"></script>
|
||||
<script src="../../common/i18n.js?v=20260608"></script>
|
||||
<script src="./script.js?v=20260612-manager-bd-leader"></script>
|
||||
<script src="./script.js?v=20260618-manager-permissions"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -15,6 +15,15 @@
|
||||
'send-frame': 'avatar_frame',
|
||||
'send-car': 'vehicle',
|
||||
};
|
||||
var ACTION_PERMISSION_KEYS = {
|
||||
'send-frame': 'canGrantAvatarFrame',
|
||||
'send-car': 'canGrantVehicle',
|
||||
'update-user-level': 'canUpdateUserLevel',
|
||||
'add-bd-leader': 'canAddBdLeader',
|
||||
'add-admin': 'canAddAdmin',
|
||||
'add-superadmin': 'canAddSuperadmin',
|
||||
'block-user': 'canBlockUser',
|
||||
};
|
||||
var RESOURCE_GRANT_DURATIONS = [
|
||||
{ label: '7 days', ms: 7 * DAY_MS },
|
||||
{ label: '30 days', ms: 30 * DAY_MS },
|
||||
@ -32,6 +41,7 @@
|
||||
loading: true,
|
||||
denied: false,
|
||||
overview: null,
|
||||
permissions: {},
|
||||
resourcesByType: {},
|
||||
};
|
||||
var blockState = {
|
||||
@ -210,6 +220,73 @@
|
||||
};
|
||||
}
|
||||
|
||||
function normalizePermissions(raw) {
|
||||
raw = raw || {};
|
||||
return {
|
||||
canGrantAvatarFrame:
|
||||
raw.canGrantAvatarFrame !== undefined
|
||||
? Boolean(raw.canGrantAvatarFrame)
|
||||
: raw.can_grant_avatar_frame !== undefined
|
||||
? Boolean(raw.can_grant_avatar_frame)
|
||||
: true,
|
||||
canGrantVehicle:
|
||||
raw.canGrantVehicle !== undefined
|
||||
? Boolean(raw.canGrantVehicle)
|
||||
: raw.can_grant_vehicle !== undefined
|
||||
? Boolean(raw.can_grant_vehicle)
|
||||
: true,
|
||||
canUpdateUserLevel:
|
||||
raw.canUpdateUserLevel !== undefined
|
||||
? Boolean(raw.canUpdateUserLevel)
|
||||
: raw.can_update_user_level !== undefined
|
||||
? Boolean(raw.can_update_user_level)
|
||||
: true,
|
||||
canAddBdLeader:
|
||||
raw.canAddBdLeader !== undefined
|
||||
? Boolean(raw.canAddBdLeader)
|
||||
: raw.can_add_bd_leader !== undefined
|
||||
? Boolean(raw.can_add_bd_leader)
|
||||
: true,
|
||||
canAddAdmin:
|
||||
raw.canAddAdmin !== undefined
|
||||
? Boolean(raw.canAddAdmin)
|
||||
: raw.can_add_admin !== undefined
|
||||
? Boolean(raw.can_add_admin)
|
||||
: true,
|
||||
canAddSuperadmin:
|
||||
raw.canAddSuperadmin !== undefined
|
||||
? Boolean(raw.canAddSuperadmin)
|
||||
: raw.can_add_superadmin !== undefined
|
||||
? Boolean(raw.can_add_superadmin)
|
||||
: true,
|
||||
canBlockUser:
|
||||
raw.canBlockUser !== undefined
|
||||
? Boolean(raw.canBlockUser)
|
||||
: raw.can_block_user !== undefined
|
||||
? Boolean(raw.can_block_user)
|
||||
: true,
|
||||
};
|
||||
}
|
||||
|
||||
function canUseAction(action) {
|
||||
var key = ACTION_PERMISSION_KEYS[action];
|
||||
if (!key) return true;
|
||||
return pageState.permissions[key] !== false;
|
||||
}
|
||||
|
||||
function renderActionPermissions() {
|
||||
document.querySelectorAll('[data-action]').forEach(function (button) {
|
||||
var action = button.getAttribute('data-action');
|
||||
button.hidden = !canUseAction(action);
|
||||
});
|
||||
}
|
||||
|
||||
function ensureActionAllowed(action) {
|
||||
if (canUseAction(action)) return true;
|
||||
toast('Permission denied.');
|
||||
return false;
|
||||
}
|
||||
|
||||
function apiSearchUser(keyword) {
|
||||
if (!api || !api.searchUsers) {
|
||||
return Promise.reject(new Error('API not available.'));
|
||||
@ -231,8 +308,12 @@
|
||||
.overview()
|
||||
.then(function (data) {
|
||||
pageState.overview = data || {};
|
||||
pageState.permissions = normalizePermissions(
|
||||
pageState.overview.permissions || pageState.overview
|
||||
);
|
||||
renderActionPermissions();
|
||||
setDenied(false);
|
||||
return refreshBlocks();
|
||||
return canUseAction('block-user') ? refreshBlocks() : Promise.resolve();
|
||||
})
|
||||
.catch(function (error) {
|
||||
setDenied(true);
|
||||
@ -503,6 +584,7 @@
|
||||
toast('Permission denied.');
|
||||
return;
|
||||
}
|
||||
if (!ensureActionAllowed('block-user')) return;
|
||||
var modal = $('blockModal');
|
||||
if (!modal) return;
|
||||
resetBlockSearch();
|
||||
@ -539,6 +621,7 @@
|
||||
toast('Permission denied.');
|
||||
return;
|
||||
}
|
||||
if (!ensureActionAllowed('update-user-level')) return;
|
||||
var modal = $('levelModal');
|
||||
if (!modal) return;
|
||||
resetLevelSearch();
|
||||
@ -693,6 +776,7 @@
|
||||
toast('Permission denied.');
|
||||
return;
|
||||
}
|
||||
if (!ensureActionAllowed(action)) return;
|
||||
ensureGrantModal();
|
||||
grantState.action = action;
|
||||
grantState.resourceType = RESOURCE_TYPES[action] || '';
|
||||
@ -915,6 +999,7 @@
|
||||
toast('Permission denied.');
|
||||
return;
|
||||
}
|
||||
if (!ensureActionAllowed(action)) return;
|
||||
ensureBDLeaderModal();
|
||||
bdLeaderState.action = action;
|
||||
bdLeaderState.title = ACTION_LABELS[action] || 'Add BD Leader';
|
||||
@ -1016,6 +1101,9 @@
|
||||
document.querySelectorAll('[data-action]').forEach(function (button) {
|
||||
button.addEventListener('click', function () {
|
||||
var action = button.getAttribute('data-action');
|
||||
if (!ensureActionAllowed(action)) {
|
||||
return;
|
||||
}
|
||||
if (action === 'block-user') {
|
||||
openBlockModal();
|
||||
return;
|
||||
|
||||