feat(无限赏): 恢复奖池查看全部弹窗,新增参考价和概率总览
- 恢复无限赏页面"查看全部"按钮和 RewardsPopup 弹窗 - RewardsPopup 顶部新增按档次分类的中奖率概览条 - 奖品项显示参考价(来自后端 price_snapshot_cents) - 每个奖品图片左下角添加档次标签(S赏/A赏/BOSS赏等) - normalizeRewards 新增 product_price 字段提取 - 理性消费提示改为始终显示
This commit is contained in:
parent
495b46ec8b
commit
7487e7224a
@ -6,21 +6,38 @@
|
||||
<text class="rewards-title">{{ title }}</text>
|
||||
<text class="rewards-close" @tap="$emit('update:visible', false)">×</text>
|
||||
</view>
|
||||
|
||||
<!-- 概率总览条 -->
|
||||
<view class="prob-overview" v-if="rewardGroups.length > 0">
|
||||
<view
|
||||
class="prob-item"
|
||||
v-for="group in rewardGroups"
|
||||
:key="'prob-' + group.level"
|
||||
>
|
||||
<view class="prob-dot" :class="getDotClass(group.level)"></view>
|
||||
<text class="prob-label">{{ group.level }}赏</text>
|
||||
<text class="prob-value">{{ group.totalPercent }}%</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<scroll-view scroll-y class="rewards-list">
|
||||
<view v-if="rewardGroups.length > 0">
|
||||
<view class="rewards-group-v2" v-for="group in rewardGroups" :key="group.level">
|
||||
<view class="group-header-row">
|
||||
<text class="group-badge" :class="{ 'badge-boss': group.level === 'BOSS' }">{{ group.level }}赏</text>
|
||||
<text class="group-badge" :class="getBadgeClass(group.level)">{{ group.level }}赏</text>
|
||||
<text class="group-total-prob">该档总概率 {{ group.totalPercent }}%</text>
|
||||
</view>
|
||||
<view v-for="(item, idx) in group.rewards" :key="item.id || idx" class="rewards-item">
|
||||
<image class="rewards-thumb" :src="item.image" mode="aspectFill" />
|
||||
<view class="thumb-wrap">
|
||||
<image class="rewards-thumb" :src="item.image" mode="aspectFill" />
|
||||
<view class="thumb-level-tag" :class="getBadgeClass(group.level)">{{ group.level }}赏</view>
|
||||
</view>
|
||||
<view class="rewards-info">
|
||||
<view class="rewards-name-row">
|
||||
<text class="rewards-name">{{ item.title || '-' }}</text>
|
||||
<view class="rewards-tag" v-if="item.boss">BOSS</view>
|
||||
</view>
|
||||
<text class="rewards-percent">单项概率 {{ formatPercent(item.percent) }}</text>
|
||||
<text class="rewards-price">参考价:¥{{ item.product_price > 0 ? (item.product_price / 100).toFixed(2) : '--' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -54,6 +71,22 @@ defineProps({
|
||||
})
|
||||
|
||||
defineEmits(['update:visible'])
|
||||
|
||||
/** 概率总览圆点颜色 class */
|
||||
function getDotClass(level) {
|
||||
if (level === 'BOSS') return 'dot-boss'
|
||||
if (level === 'S' || level === 'Last') return 'dot-rare'
|
||||
if (level === 'A') return 'dot-a'
|
||||
return 'dot-normal'
|
||||
}
|
||||
|
||||
/** 分组标签颜色 class */
|
||||
function getBadgeClass(level) {
|
||||
if (level === 'BOSS') return 'badge-boss'
|
||||
if (level === 'S' || level === 'Last') return 'badge-rare'
|
||||
if (level === 'A') return 'badge-a'
|
||||
return ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -121,18 +154,84 @@ defineEmits(['update:visible'])
|
||||
padding: $spacing-xs;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
概率总览条
|
||||
============================================ */
|
||||
.prob-overview {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: $spacing-sm $spacing-lg;
|
||||
padding: $spacing-md $spacing-lg;
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
border-bottom: 1rpx solid $border-color-light;
|
||||
}
|
||||
|
||||
.prob-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.prob-dot {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
|
||||
&.dot-boss {
|
||||
background: $accent-gold;
|
||||
box-shadow: 0 0 8rpx rgba(255, 193, 7, 0.5);
|
||||
}
|
||||
|
||||
&.dot-rare {
|
||||
background: $brand-primary;
|
||||
box-shadow: 0 0 8rpx rgba($brand-primary, 0.4);
|
||||
}
|
||||
|
||||
&.dot-a {
|
||||
background: $accent-orange;
|
||||
}
|
||||
|
||||
&.dot-normal {
|
||||
background: $text-tertiary;
|
||||
}
|
||||
}
|
||||
|
||||
.prob-label {
|
||||
font-size: $font-xs;
|
||||
font-weight: 600;
|
||||
color: $text-main;
|
||||
}
|
||||
|
||||
.prob-value {
|
||||
font-size: $font-xs;
|
||||
font-weight: 800;
|
||||
color: $brand-primary;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
奖品列表
|
||||
============================================ */
|
||||
.rewards-list {
|
||||
max-height: 60vh;
|
||||
max-height: 55vh;
|
||||
padding: $spacing-lg;
|
||||
}
|
||||
|
||||
.rewards-group-v2 {
|
||||
margin-bottom: $spacing-lg;
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
padding: $spacing-md;
|
||||
border-radius: $radius-lg;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.group-header-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: $spacing-sm;
|
||||
margin-bottom: $spacing-sm;
|
||||
}
|
||||
@ -144,16 +243,27 @@ defineEmits(['update:visible'])
|
||||
background: rgba($brand-primary, 0.1);
|
||||
padding: 4rpx $spacing-sm;
|
||||
border-radius: $radius-sm;
|
||||
|
||||
|
||||
&.badge-boss {
|
||||
background: $gradient-gold;
|
||||
color: #6b4b1f;
|
||||
}
|
||||
|
||||
&.badge-rare {
|
||||
background: $gradient-brand;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.badge-a {
|
||||
background: rgba($accent-orange, 0.15);
|
||||
color: $accent-orange;
|
||||
}
|
||||
}
|
||||
|
||||
.group-total-prob {
|
||||
font-size: $font-xs;
|
||||
color: $text-sub;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.rewards-item {
|
||||
@ -161,19 +271,51 @@ defineEmits(['update:visible'])
|
||||
align-items: center;
|
||||
padding: $spacing-sm 0;
|
||||
border-bottom: 1rpx solid rgba(0, 0, 0, 0.03);
|
||||
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.rewards-thumb {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: $radius-md;
|
||||
margin-right: $spacing-md;
|
||||
background: $bg-secondary;
|
||||
.thumb-wrap {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
margin-right: $spacing-md;
|
||||
}
|
||||
|
||||
.rewards-thumb {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: $radius-md;
|
||||
background: $bg-secondary;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.thumb-level-tag {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
font-size: 20rpx;
|
||||
font-weight: 700;
|
||||
padding: 2rpx 10rpx;
|
||||
border-radius: 0 $radius-md 0 $radius-md;
|
||||
color: $brand-primary;
|
||||
background: rgba($brand-primary, 0.12);
|
||||
|
||||
&.badge-boss {
|
||||
background: $gradient-gold;
|
||||
color: #6b4b1f;
|
||||
}
|
||||
|
||||
&.badge-rare {
|
||||
background: $gradient-brand;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.badge-a {
|
||||
background: rgba($accent-orange, 0.15);
|
||||
color: $accent-orange;
|
||||
}
|
||||
}
|
||||
|
||||
.rewards-info {
|
||||
@ -185,14 +327,14 @@ defineEmits(['update:visible'])
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $spacing-xs;
|
||||
margin-bottom: $spacing-xs;
|
||||
margin-bottom: 6rpx;
|
||||
}
|
||||
|
||||
.rewards-name {
|
||||
font-size: $font-md;
|
||||
font-weight: 600;
|
||||
color: $text-main;
|
||||
@include text-ellipsis(1);
|
||||
@include text-ellipsis(2);
|
||||
}
|
||||
|
||||
.rewards-tag {
|
||||
@ -205,6 +347,19 @@ defineEmits(['update:visible'])
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.rewards-price {
|
||||
font-size: $font-md;
|
||||
font-weight: 700;
|
||||
color: $brand-primary;
|
||||
display: block;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.rewards-percent {
|
||||
font-size: $font-sm;
|
||||
color: $text-sub;
|
||||
}
|
||||
|
||||
.rewards-qty-tag {
|
||||
font-size: $font-xxs;
|
||||
font-weight: 700;
|
||||
@ -215,11 +370,6 @@ defineEmits(['update:visible'])
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.rewards-percent {
|
||||
font-size: $font-sm;
|
||||
color: $text-sub;
|
||||
}
|
||||
|
||||
.rewards-empty {
|
||||
text-align: center;
|
||||
color: $text-sub;
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<!-- 通过 hideViewAll 控制是否显示查看全部按钮 -->
|
||||
<text v-if="!hideViewAll" class="section-more" @tap="$emit('view-all')">查看全部</text>
|
||||
</view>
|
||||
<view v-if="hideViewAll" class="tip-text">每抽都有概率出以下商品,盲盒消费具有随机性,请理性消费</view>
|
||||
<view class="tip-text">每抽都有概率出以下商品,盲盒消费具有随机性,请理性消费</view>
|
||||
|
||||
<!-- 分组展示 -->
|
||||
<view v-if="grouped && rewardGroups.length > 0">
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
title="奖池配置"
|
||||
:rewards="currentIssueRewards"
|
||||
:grouped="true"
|
||||
:hide-view-all="true"
|
||||
@view-all="rewardsVisible = true"
|
||||
/>
|
||||
</template>
|
||||
<template #records>
|
||||
@ -51,12 +51,11 @@
|
||||
</template>
|
||||
|
||||
<template #modals>
|
||||
<!-- 暂时注释掉奖池详情弹窗 -->
|
||||
<!-- <RewardsPopup
|
||||
<RewardsPopup
|
||||
v-model:visible="rewardsVisible"
|
||||
:title="`${currentIssueTitle} · 奖池与概率`"
|
||||
:reward-groups="rewardGroups"
|
||||
/> -->
|
||||
/>
|
||||
|
||||
<LotteryResultPopup
|
||||
v-model:visible="showResultPopup"
|
||||
|
||||
@ -111,7 +111,8 @@ export function normalizeRewards(list, cleanUrl = (u) => u) {
|
||||
boss: detectBoss(i),
|
||||
min_score: i.min_score || 0,
|
||||
drop_quantity: Number(i.drop_quantity) || 1,
|
||||
level: levelToAlpha(i.prize_level ?? i.level ?? (detectBoss(i) ? 'BOSS' : '赏'))
|
||||
level: levelToAlpha(i.prize_level ?? i.level ?? (detectBoss(i) ? 'BOSS' : '赏')),
|
||||
product_price: Number(i.price_snapshot_cents ?? i.product_price ?? i.price ?? i.reference_price) || 0
|
||||
}))
|
||||
const total = items.reduce((acc, it) => acc + (it.weight > 0 ? it.weight : 0), 0)
|
||||
const enriched = items.map(it => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user