Merge branch 'main' of https://git.1024tool.vip/zfc/bindbox-mini
This commit is contained in:
commit
4252a0ed61
@ -74,6 +74,7 @@ async function fetchPackages() {
|
|||||||
// res 应该是数组
|
// res 应该是数组
|
||||||
let list = []
|
let list = []
|
||||||
if (Array.isArray(res)) list = res
|
if (Array.isArray(res)) list = res
|
||||||
|
else if (res && Array.isArray(res.packages)) list = res.packages
|
||||||
else if (res && Array.isArray(res.list)) list = res.list
|
else if (res && Array.isArray(res.list)) list = res.list
|
||||||
else if (res && Array.isArray(res.data)) list = res.data
|
else if (res && Array.isArray(res.data)) list = res.data
|
||||||
|
|
||||||
|
|||||||
@ -276,6 +276,7 @@ async function onPaymentConfirm(paymentData) {
|
|||||||
channel: 'miniapp',
|
channel: 'miniapp',
|
||||||
count: selectedSlots.length,
|
count: selectedSlots.length,
|
||||||
coupon_id: paymentData.coupon ? Number(paymentData.coupon.id) : 0,
|
coupon_id: paymentData.coupon ? Number(paymentData.coupon.id) : 0,
|
||||||
|
use_game_pass: !!paymentData.useGamePass,
|
||||||
slot_index: selectedSlots.map(Number)
|
slot_index: selectedSlots.map(Number)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -67,6 +67,7 @@
|
|||||||
v-model:visible="paymentVisible"
|
v-model:visible="paymentVisible"
|
||||||
:amount="paymentAmount"
|
:amount="paymentAmount"
|
||||||
:coupons="coupons"
|
:coupons="coupons"
|
||||||
|
:gamePasses="gamePasses"
|
||||||
:propCards="propCards"
|
:propCards="propCards"
|
||||||
@confirm="onPaymentConfirm"
|
@confirm="onPaymentConfirm"
|
||||||
/>
|
/>
|
||||||
@ -80,12 +81,33 @@
|
|||||||
:activity-id="activityId"
|
:activity-id="activityId"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<CabinetPreviewPopup
|
||||||
|
v-model:visible="cabinetVisible"
|
||||||
|
:activity-id="activityId"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- 开奖加载弹窗 -->
|
<!-- 开奖加载弹窗 -->
|
||||||
<DrawLoadingPopup
|
<DrawLoadingPopup
|
||||||
:visible="showDrawLoading"
|
:visible="showDrawLoading"
|
||||||
:progress="drawProgress"
|
:progress="drawProgress"
|
||||||
:total="drawTotal"
|
:total="drawTotal"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<GamePassPurchasePopup
|
||||||
|
v-model:visible="purchasePopupVisible"
|
||||||
|
:activity-id="activityId"
|
||||||
|
@success="onPurchaseSuccess"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 悬浮次数卡入口 -->
|
||||||
|
<view v-if="gamePassRemaining > 0 || true" class="game-pass-float" @tap="openPurchasePopup">
|
||||||
|
<view class="badge-content">
|
||||||
|
<text class="badge-icon">🎮</text>
|
||||||
|
<text class="badge-text" v-if="gamePassRemaining > 0">{{ gamePassRemaining }}</text>
|
||||||
|
<text class="badge-text" v-else>充值</text>
|
||||||
|
</view>
|
||||||
|
<view class="badge-label">超值卡</view>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</ActivityPageLayout>
|
</ActivityPageLayout>
|
||||||
</template>
|
</template>
|
||||||
@ -105,6 +127,8 @@ import CabinetPreviewPopup from '@/components/activity/CabinetPreviewPopup.vue'
|
|||||||
import LotteryResultPopup from '@/components/activity/LotteryResultPopup.vue'
|
import LotteryResultPopup from '@/components/activity/LotteryResultPopup.vue'
|
||||||
import DrawLoadingPopup from '@/components/activity/DrawLoadingPopup.vue'
|
import DrawLoadingPopup from '@/components/activity/DrawLoadingPopup.vue'
|
||||||
import PaymentPopup from '@/components/PaymentPopup.vue'
|
import PaymentPopup from '@/components/PaymentPopup.vue'
|
||||||
|
import GamePassPurchasePopup from '@/components/GamePassPurchasePopup.vue'
|
||||||
|
import { getGamePasses } from '@/api/appUser'
|
||||||
// Composables
|
// Composables
|
||||||
import { useActivity, useIssues, useRewards, useRecords } from '../../composables'
|
import { useActivity, useIssues, useRewards, useRecords } from '../../composables'
|
||||||
// API
|
// API
|
||||||
@ -160,6 +184,30 @@ const propCards = ref([])
|
|||||||
const pendingCount = ref(1)
|
const pendingCount = ref(1)
|
||||||
const selectedCoupon = ref(null)
|
const selectedCoupon = ref(null)
|
||||||
const selectedCard = ref(null)
|
const selectedCard = ref(null)
|
||||||
|
const useGamePassFlag = ref(false)
|
||||||
|
|
||||||
|
// ============ 次数卡逻辑 ============
|
||||||
|
const gamePasses = ref(null)
|
||||||
|
const gamePassRemaining = computed(() => gamePasses.value?.total_remaining || 0)
|
||||||
|
const purchasePopupVisible = ref(false)
|
||||||
|
|
||||||
|
async function fetchPasses() {
|
||||||
|
if (!activityId.value) return
|
||||||
|
try {
|
||||||
|
const res = await getGamePasses(activityId.value)
|
||||||
|
gamePasses.value = res || null
|
||||||
|
} catch (e) {
|
||||||
|
gamePasses.value = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openPurchasePopup() {
|
||||||
|
purchasePopupVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPurchaseSuccess() {
|
||||||
|
fetchPasses()
|
||||||
|
}
|
||||||
|
|
||||||
// ============ 业务方法 ============
|
// ============ 业务方法 ============
|
||||||
function showRules() {
|
function showRules() {
|
||||||
@ -198,6 +246,7 @@ function openPayment(count) {
|
|||||||
async function onPaymentConfirm(data) {
|
async function onPaymentConfirm(data) {
|
||||||
selectedCoupon.value = data?.coupon || null
|
selectedCoupon.value = data?.coupon || null
|
||||||
selectedCard.value = data?.card || null
|
selectedCard.value = data?.card || null
|
||||||
|
useGamePassFlag.value = data?.useGamePass || false
|
||||||
paymentVisible.value = false
|
paymentVisible.value = false
|
||||||
await onMachineDraw(pendingCount.value)
|
await onMachineDraw(pendingCount.value)
|
||||||
}
|
}
|
||||||
@ -317,9 +366,15 @@ async function onMachineDraw(count) {
|
|||||||
channel: 'miniapp',
|
channel: 'miniapp',
|
||||||
count: times,
|
count: times,
|
||||||
coupon_id: selectedCoupon.value?.id ? Number(selectedCoupon.value.id) : 0,
|
coupon_id: selectedCoupon.value?.id ? Number(selectedCoupon.value.id) : 0,
|
||||||
item_card_id: selectedCard.value?.id ? Number(selectedCard.value.id) : 0
|
item_card_id: selectedCard.value?.id ? Number(selectedCard.value.id) : 0,
|
||||||
|
use_game_pass: useGamePassFlag.value
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 支付成功刷新次数卡
|
||||||
|
if (useGamePassFlag.value) {
|
||||||
|
fetchPasses()
|
||||||
|
}
|
||||||
|
|
||||||
const orderNo = joinRes?.order_no || joinRes?.data?.order_no || joinRes?.result?.order_no
|
const orderNo = joinRes?.order_no || joinRes?.data?.order_no || joinRes?.result?.order_no
|
||||||
if (!orderNo) throw new Error('未获取到订单号')
|
if (!orderNo) throw new Error('未获取到订单号')
|
||||||
|
|
||||||
@ -386,6 +441,7 @@ onLoad(async (opts) => {
|
|||||||
if (currentIssueId.value) {
|
if (currentIssueId.value) {
|
||||||
fetchWinRecords(id, currentIssueId.value)
|
fetchWinRecords(id, currentIssueId.value)
|
||||||
}
|
}
|
||||||
|
fetchPasses()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听期切换,刷新记录
|
// 监听期切换,刷新记录
|
||||||
@ -553,4 +609,46 @@ watch(currentIssueId, (newId) => {
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 次数卡悬浮入口 */
|
||||||
|
.game-pass-float {
|
||||||
|
position: fixed;
|
||||||
|
right: 32rpx;
|
||||||
|
bottom: calc(180rpx + env(safe-area-inset-bottom));
|
||||||
|
z-index: 990;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
animation: float 3s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-content {
|
||||||
|
background: rgba(255, 255, 255, 0.95);
|
||||||
|
backdrop-filter: blur(10rpx);
|
||||||
|
border-radius: 30rpx;
|
||||||
|
padding: 8rpx 16rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
box-shadow: 0 8rpx 20rpx rgba(0,0,0,0.15);
|
||||||
|
border: 1rpx solid rgba($brand-primary, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-icon { font-size: 28rpx; margin-right: 6rpx; }
|
||||||
|
.badge-text { font-size: 24rpx; font-weight: 800; color: $brand-primary; }
|
||||||
|
|
||||||
|
.badge-label {
|
||||||
|
font-size: 20rpx;
|
||||||
|
color: #fff;
|
||||||
|
background: $gradient-brand;
|
||||||
|
padding: 2rpx 8rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-top: -6rpx;
|
||||||
|
z-index: 2;
|
||||||
|
box-shadow: 0 2rpx 6rpx rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes float {
|
||||||
|
0%, 100% { transform: translateY(0); }
|
||||||
|
50% { transform: translateY(-10rpx); }
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -73,10 +73,22 @@
|
|||||||
<!-- 固定底部操作栏 -->
|
<!-- 固定底部操作栏 -->
|
||||||
<view class="float-bar" v-show="!isPaymentVisible">
|
<view class="float-bar" v-show="!isPaymentVisible">
|
||||||
<view class="float-bar-inner">
|
<view class="float-bar-inner">
|
||||||
|
<view class="selection-info" v-if="selectedCount > 0">
|
||||||
|
已选 <text class="highlight">{{ selectedCount }}</text> 个位置
|
||||||
|
</view>
|
||||||
<view class="selection-info" v-if="selectedCount > 0">
|
<view class="selection-info" v-if="selectedCount > 0">
|
||||||
已选 <text class="highlight">{{ selectedCount }}</text> 个位置
|
已选 <text class="highlight">{{ selectedCount }}</text> 个位置
|
||||||
</view>
|
</view>
|
||||||
<view class="selection-info" v-else>
|
<view class="selection-info" v-else>
|
||||||
|
<!-- 次数卡余额 / 购买入口 -->
|
||||||
|
<view v-if="gamePassRemaining > 0" class="game-pass-badge" @tap="() => {}">
|
||||||
|
<text class="badge-icon">🎮</text>
|
||||||
|
<text class="badge-text" style="font-size: 24rpx; font-weight: bold; color: #10B981;">{{ gamePassRemaining }}</text>
|
||||||
|
</view>
|
||||||
|
<!-- 充值入口 -->
|
||||||
|
<view class="game-pass-buy-btn" @tap="openPurchasePopup">
|
||||||
|
<text>充值特惠</text>
|
||||||
|
</view>
|
||||||
请选择位置
|
请选择位置
|
||||||
</view>
|
</view>
|
||||||
<view class="action-buttons">
|
<view class="action-buttons">
|
||||||
@ -121,10 +133,17 @@
|
|||||||
v-model:visible="paymentVisible"
|
v-model:visible="paymentVisible"
|
||||||
:amount="paymentAmount"
|
:amount="paymentAmount"
|
||||||
:coupons="paymentCoupons"
|
:coupons="paymentCoupons"
|
||||||
|
:gamePasses="gamePasses"
|
||||||
:showCards="false"
|
:showCards="false"
|
||||||
@confirm="onPaymentConfirm"
|
@confirm="onPaymentConfirm"
|
||||||
@cancel="onPaymentCancel"
|
@cancel="onPaymentCancel"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<GamePassPurchasePopup
|
||||||
|
v-model:visible="purchasePopupVisible"
|
||||||
|
:activity-id="activityId"
|
||||||
|
@success="onPurchaseSuccess"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</ActivityPageLayout>
|
</ActivityPageLayout>
|
||||||
</template>
|
</template>
|
||||||
@ -144,6 +163,8 @@ import CabinetPreviewPopup from '@/components/activity/CabinetPreviewPopup.vue'
|
|||||||
import FlipGrid from '@/components/FlipGrid.vue'
|
import FlipGrid from '@/components/FlipGrid.vue'
|
||||||
import YifanSelector from '@/components/YifanSelector.vue'
|
import YifanSelector from '@/components/YifanSelector.vue'
|
||||||
import PaymentPopup from '@/components/PaymentPopup.vue'
|
import PaymentPopup from '@/components/PaymentPopup.vue'
|
||||||
|
import GamePassPurchasePopup from '@/components/GamePassPurchasePopup.vue'
|
||||||
|
import { getGamePasses } from '@/api/appUser'
|
||||||
// Composables
|
// Composables
|
||||||
import { useActivity, useIssues, useRewards, useRecords } from '../../composables'
|
import { useActivity, useIssues, useRewards, useRecords } from '../../composables'
|
||||||
// Utils
|
// Utils
|
||||||
@ -249,6 +270,29 @@ function handlePayment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ============ 次数卡逻辑 ============
|
||||||
|
const gamePasses = ref(null)
|
||||||
|
const gamePassRemaining = computed(() => gamePasses.value?.total_remaining || 0)
|
||||||
|
const purchasePopupVisible = ref(false)
|
||||||
|
|
||||||
|
async function fetchPasses() {
|
||||||
|
if (!activityId.value) return
|
||||||
|
try {
|
||||||
|
const res = await getGamePasses(activityId.value)
|
||||||
|
gamePasses.value = res || null
|
||||||
|
} catch (e) {
|
||||||
|
gamePasses.value = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openPurchasePopup() {
|
||||||
|
purchasePopupVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPurchaseSuccess() {
|
||||||
|
fetchPasses()
|
||||||
|
}
|
||||||
|
|
||||||
// ============ 倒计时相关(一番赏专属) ============
|
// ============ 倒计时相关(一番赏专属) ============
|
||||||
const nowMs = ref(Date.now())
|
const nowMs = ref(Date.now())
|
||||||
let nowTimer = null
|
let nowTimer = null
|
||||||
@ -364,6 +408,8 @@ onLoad(async (opts) => {
|
|||||||
if (currentIssueId.value) {
|
if (currentIssueId.value) {
|
||||||
fetchWinRecords(id, currentIssueId.value)
|
fetchWinRecords(id, currentIssueId.value)
|
||||||
}
|
}
|
||||||
|
// 获取次数卡
|
||||||
|
fetchPasses()
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnload(() => {
|
onUnload(() => {
|
||||||
@ -610,3 +656,53 @@ watch(currentIssueId, (newId) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
/* 浮动操作栏扩展 - 充值按钮 & Badge */
|
||||||
|
.game-pass-badge {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background: rgba(16, 185, 129, 0.15);
|
||||||
|
padding: 6rpx 16rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
border: 1rpx solid rgba(16, 185, 129, 0.3);
|
||||||
|
margin: 0 12rpx;
|
||||||
|
animation: pulse 2s infinite;
|
||||||
|
|
||||||
|
.badge-icon {
|
||||||
|
font-size: 28rpx;
|
||||||
|
margin-right: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #10B981;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-pass-buy-btn {
|
||||||
|
background: linear-gradient(90deg, #FF9F43, #FF6B00);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 22rpx;
|
||||||
|
padding: 6rpx 16rpx;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
margin-right: 12rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
box-shadow: 0 4rpx 8rpx rgba(255, 107, 0, 0.2);
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0% { transform: scale(1); }
|
||||||
|
50% { transform: scale(1.05); }
|
||||||
|
100% { transform: scale(1); }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user