220 lines
4.4 KiB
Vue
220 lines
4.4 KiB
Vue
<template>
|
||
<view v-if="visible" class="rewards-overlay" @touchmove.stop.prevent>
|
||
<view class="rewards-mask" @tap="$emit('update:visible', false)"></view>
|
||
<view class="rewards-panel" @tap.stop>
|
||
<view class="rewards-header">
|
||
<text class="rewards-title">{{ title }}</text>
|
||
<text class="rewards-close" @tap="$emit('update:visible', false)">×</text>
|
||
</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-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="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>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-else class="rewards-empty">{{ emptyText }}</view>
|
||
</scroll-view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { formatPercent } from '@/utils/format'
|
||
|
||
defineProps({
|
||
visible: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
title: {
|
||
type: String,
|
||
default: '奖品与概率'
|
||
},
|
||
rewardGroups: {
|
||
type: Array,
|
||
default: () => []
|
||
},
|
||
emptyText: {
|
||
type: String,
|
||
default: '暂无奖品数据'
|
||
}
|
||
})
|
||
|
||
defineEmits(['update:visible'])
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.rewards-overlay {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
z-index: 1000;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.rewards-mask {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.5);
|
||
}
|
||
|
||
.rewards-panel {
|
||
position: relative;
|
||
width: 90%;
|
||
max-height: 80vh;
|
||
background: $bg-card;
|
||
border-radius: $radius-xl;
|
||
overflow: hidden;
|
||
box-shadow: $shadow-lg;
|
||
animation: slideUp 0.3s ease-out;
|
||
}
|
||
|
||
@keyframes slideUp {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(50rpx);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
.rewards-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: $spacing-lg;
|
||
border-bottom: 1rpx solid $border-color-light;
|
||
}
|
||
|
||
.rewards-title {
|
||
font-size: $font-lg;
|
||
font-weight: 700;
|
||
color: $text-main;
|
||
}
|
||
|
||
.rewards-close {
|
||
font-size: 48rpx;
|
||
color: $text-sub;
|
||
line-height: 1;
|
||
padding: $spacing-xs;
|
||
}
|
||
|
||
.rewards-list {
|
||
max-height: 60vh;
|
||
padding: $spacing-lg;
|
||
}
|
||
|
||
.rewards-group-v2 {
|
||
margin-bottom: $spacing-lg;
|
||
}
|
||
|
||
.group-header-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: $spacing-sm;
|
||
margin-bottom: $spacing-sm;
|
||
}
|
||
|
||
.group-badge {
|
||
font-size: $font-xs;
|
||
font-weight: 700;
|
||
color: $brand-primary;
|
||
background: rgba($brand-primary, 0.1);
|
||
padding: 4rpx $spacing-sm;
|
||
border-radius: $radius-sm;
|
||
|
||
&.badge-boss {
|
||
background: $gradient-gold;
|
||
color: #6b4b1f;
|
||
}
|
||
}
|
||
|
||
.group-total-prob {
|
||
font-size: $font-xs;
|
||
color: $text-sub;
|
||
}
|
||
|
||
.rewards-item {
|
||
display: flex;
|
||
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;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.rewards-info {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.rewards-name-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: $spacing-xs;
|
||
margin-bottom: $spacing-xs;
|
||
}
|
||
|
||
.rewards-name {
|
||
font-size: $font-md;
|
||
font-weight: 600;
|
||
color: $text-main;
|
||
@include text-ellipsis(1);
|
||
}
|
||
|
||
.rewards-tag {
|
||
font-size: $font-xxs;
|
||
font-weight: 700;
|
||
color: #6b4b1f;
|
||
background: $gradient-gold;
|
||
padding: 2rpx 8rpx;
|
||
border-radius: $radius-sm;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.rewards-percent {
|
||
font-size: $font-sm;
|
||
color: $text-sub;
|
||
}
|
||
|
||
.rewards-empty {
|
||
text-align: center;
|
||
color: $text-sub;
|
||
padding: $spacing-xl;
|
||
font-size: $font-sm;
|
||
}
|
||
</style>
|