You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

208 lines
12 KiB

5 days ago
<template>
<view class="dl">
<view class="dl-top">
<view>
<view class="dl-kicker">2 MIN DAILY</view>
2 days ago
<view class="dl-title">{{progressTitle}}</view>
<view class="dl-sub">完成任务可获得星球券与开奖权重</view>
</view>
<view class="dl-map" @tap="$emit('more')">
<text>星球补给地图</text>
<text>进入</text>
5 days ago
</view>
</view>
2 days ago
<!-- <view class="progress-overview">
<view class="progress-row">
<text>今日进度 {{doneCount}}/3</text>
<text>{{progressPercent}}%</text>
5 days ago
</view>
2 days ago
<view class="progress-track">
<view class="progress-fill" :style="{width: progressPercent + '%'}"></view>
</view>
</view> -->
<!-- <view class="dl-events">
<view class="dl-event" v-for="(e,i) in events" :key="i">{{e}}</view>
</view> -->
<view
class="main-task"
:class="{done: taskDone('pool')}"
@tap="onJoin">
<view class="main-copy">
<view class="main-icon icon-rocket"></view>
<view>
<view class="main-title">投入星球券</view>
<view class="main-desc">参与今晚奖金池瓜分</view>
</view>
</view>
<view class="main-status">{{taskDone('pool') ? '已参与' : '立即参与'}}</view>
<view class="main-boost">预计提升中奖概率 +{{boostText}}%</view>
<view class="main-arrow"></view>
</view>
5 days ago
<view class="dl-stat">
2 days ago
<view class="stat-card collected">
5 days ago
<text>{{data.todayCollectedTickets || 0}}</text>
<text>今日收券</text>
</view>
2 days ago
<view class="stat-card pooled">
5 days ago
<text>{{data.myPoolTickets || 0}}</text>
<text>已投奖池</text>
</view>
2 days ago
<view class="stat-card probability">
<text>{{data.myProbability || 0}}%</text>
<text>中奖概率</text>
5 days ago
</view>
</view>
2 days ago
<view v-if="rewardFloat.show" class="reward-float" :class="rewardFloat.type">{{rewardFloat.text}}</view>
<view v-if="flying" class="ticket-fly"></view>
5 days ago
</view>
</template>
<script>
export default {
props: {
data: { type: Object, default: () => ({}) },
2 days ago
myTicketCount: { type: Number, default: 0 }
},
data() {
return {
flying: false,
flyTimer: null,
rewardFloat: {
show: false,
text: '',
type: ''
},
rewardTimer: null
}
5 days ago
},
computed: {
events() {
return this.data.events || []
},
2 days ago
doneCount() {
let count = 0
if (this.taskDone('pool')) count += 1
return count
},
progressPercent() {
1 day ago
return this.taskDone('pool') ? 100 : 0
5 days ago
},
2 days ago
progressTitle() {
1 day ago
return this.taskDone('pool') ? '今日已参与奖金池' : '投入星球券瓜分奖金池'
2 days ago
},
boostText() {
const current = Number(this.data.myProbability || 0)
const suggested = Number(this.data.suggestedProbability || 0)
if (suggested > current) return (suggested - current).toFixed(2)
return '1.00'
}
},
beforeDestroy() {
if (this.flyTimer) clearTimeout(this.flyTimer)
if (this.rewardTimer) clearTimeout(this.rewardTimer)
},
methods: {
taskDone(type) {
if (type === 'pool') return (this.data.myPoolTickets || 0) > 0
return false
},
playReward(text, type) {
if (this.rewardTimer) clearTimeout(this.rewardTimer)
this.rewardFloat = {
show: true,
text,
type
}
this.rewardTimer = setTimeout(() => {
this.rewardFloat.show = false
}, 800)
},
onJoin() {
if (this.flying) return
if (this.myTicketCount <= 0) {
this.$emit('join')
return
}
this.flying = true
this.playReward('+开奖权重', 'pool')
this.$emit('join')
if (this.flyTimer) clearTimeout(this.flyTimer)
this.flyTimer = setTimeout(() => {
this.flying = false
}, 940)
5 days ago
}
}
}
</script>
<style lang="scss" scoped>
2 days ago
.dl { margin-top: -20rpx; padding: 28rpx; border-radius: 44rpx; background: linear-gradient(155deg, rgba(255,255,255,0.92), rgba(239,255,249,0.78)); border: 2rpx solid rgba(255,255,255,0.92); box-shadow: 0 26rpx 60rpx rgba(53,214,166,0.14); overflow: visible; position: relative; }
5 days ago
.dl:before { content: ''; position: absolute; right: -90rpx; top: -120rpx; width: 320rpx; height: 320rpx; border-radius: 50%; background: radial-gradient(circle, rgba(79,183,255,0.26), transparent 68%); }
.dl-top { position: relative; z-index: 1; display: flex; align-items: flex-start; justify-content: space-between; }
.dl-kicker { color: #59CBB5; font-size: 20rpx; font-weight: 900; letter-spacing: 2rpx; }
.dl-title { margin-top: 6rpx; color: #12342F; font-size: 42rpx; font-weight: 900; }
.dl-sub { margin-top: 8rpx; color: #6B817D; font-size: 24rpx; }
2 days ago
.dl-map { width: 146rpx; min-height: 82rpx; padding: 12rpx 10rpx; border-radius: 28rpx; background: linear-gradient(145deg, #FFFFFF, #E5FFF1); color: #22B889; display: flex; flex-direction: column; align-items: center; justify-content: center; box-shadow: 0 14rpx 28rpx rgba(53,214,166,0.16); border: 2rpx solid rgba(255,255,255,0.96); flex-shrink: 0; }
.dl-map text:first-child { font-size: 21rpx; font-weight: 900; line-height: 1.18; text-align: center; }
.dl-map text:last-child { margin-top: 8rpx; padding: 4rpx 14rpx; border-radius: 999rpx; background: linear-gradient(135deg, #35D6A6, #4FB7FF); color: #FFFFFF; font-size: 18rpx; font-weight: 900; }
.progress-overview { position: relative; z-index: 1; margin-top: 20rpx; padding: 18rpx 20rpx; border-radius: 30rpx; background: rgba(255,255,255,0.54); border: 1px solid rgba(255,255,255,.7); box-shadow: inset 0 1rpx 0 rgba(255,255,255,0.86); }
.progress-row { display: flex; justify-content: space-between; color: #42635E; font-size: 22rpx; font-weight: 900; }
.progress-row text:last-child { color: #22B889; font-family: DIN, Arial, sans-serif; }
.progress-track { margin-top: 14rpx; height: 14rpx; border-radius: 999rpx; background: rgba(18,52,47,0.08); overflow: hidden; }
.progress-fill { height: 100%; border-radius: inherit; background: linear-gradient(90deg, #34D399, #60A5FA); box-shadow: 0 0 20rpx rgba(52,211,153,0.28); transition: width .2s ease; }
5 days ago
.dl-events { margin-top: 18rpx; }
.dl-event { margin-top: 10rpx; padding: 14rpx 18rpx; border-radius: 24rpx; background: rgba(255,255,255,0.62); color: #42635E; font-size: 24rpx; }
2 days ago
.main-task { position: relative; z-index: 1; margin-top: 22rpx; height: 170rpx; padding: 24rpx 154rpx 24rpx 24rpx; box-sizing: border-box; border-radius: 32rpx; background: linear-gradient(135deg, #FFF7EC, #FFE7C8); border: 1px solid rgba(255,255,255,.78); box-shadow: 0 20rpx 42rpx rgba(255,184,107,0.18), inset 0 1rpx 0 rgba(255,255,255,0.9); overflow: hidden; transition: transform .2s ease; }
.main-task:active, .sub-task:active { transform: scale(.97); }
.main-task.done { filter: saturate(.82); box-shadow: 0 0 30rpx rgba(52,211,153,.25), 0 20rpx 42rpx rgba(255,184,107,0.12); }
.main-task:before { content: ''; position: absolute; right: -70rpx; top: -80rpx; width: 220rpx; height: 220rpx; border-radius: 50%; background: radial-gradient(circle, rgba(255,255,255,0.72), transparent 66%); }
.main-copy { position: relative; z-index: 1; display: flex; align-items: center; }
.main-icon { position: relative; width: 54rpx; height: 54rpx; margin-right: 16rpx; flex-shrink: 0; }
.main-title { color: #5C3310; font-size: 34rpx; font-weight: 900; white-space: nowrap; }
.main-desc { margin-top: 8rpx; color: #9B7043; font-size: 22rpx; font-weight: 800; white-space: nowrap; }
.main-status { position: absolute; right: 76rpx; top: 26rpx; z-index: 1; height: 46rpx; line-height: 46rpx; padding: 0 18rpx; border-radius: 999rpx; background: rgba(255,255,255,0.66); color: #F08322; font-size: 21rpx; font-weight: 900; }
.main-boost { position: absolute; left: 24rpx; bottom: 20rpx; z-index: 1; color: #C27724; font-size: 21rpx; font-weight: 900; }
.main-arrow { position: absolute; right: 28rpx; top: 58rpx; z-index: 1; color: rgba(240,131,34,0.72); font-size: 56rpx; font-weight: 900; }
.sub-task-list { position: relative; z-index: 1; margin-top: 16rpx; display: flex; gap: 14rpx; }
.sub-task { position: relative; flex: 1; height: 148rpx; box-sizing: border-box; padding: 16rpx; border-radius: 30rpx; background: rgba(255,255,255,0.58); backdrop-filter: blur(20px); border: 1px solid rgba(255,255,255,.72); box-shadow: 0 14rpx 30rpx rgba(53,214,166,0.1), inset 0 1rpx 0 rgba(255,255,255,0.84); overflow: hidden; transition: transform .2s ease; }
.sub-task.done { filter: saturate(.72); box-shadow: 0 0 30rpx rgba(52,211,153,.22), 0 12rpx 28rpx rgba(53,214,166,0.08); }
.sub-head { display: flex; align-items: center; justify-content: space-between; }
.task-icon { position: relative; width: 30rpx; height: 30rpx; border-radius: 10rpx; flex-shrink: 0; }
.icon-spark { background: linear-gradient(145deg, rgba(52,211,153,0.18), rgba(52,211,153,0.38)); }
.icon-spark:before { content: ''; position: absolute; left: 11rpx; top: 3rpx; width: 5rpx; height: 20rpx; border-radius: 999rpx; background: #34D399; }
.icon-spark:after { content: ''; position: absolute; left: 3rpx; top: 11rpx; width: 20rpx; height: 5rpx; border-radius: 999rpx; background: #34D399; }
.icon-gift { background: linear-gradient(145deg, rgba(96,165,250,0.2), rgba(96,165,250,0.42)); }
.icon-gift:before { content: ''; position: absolute; left: 4rpx; right: 4rpx; top: 10rpx; height: 12rpx; border-radius: 3rpx; background: #60A5FA; }
.icon-gift:after { content: ''; position: absolute; left: 11rpx; top: 4rpx; width: 5rpx; height: 20rpx; border-radius: 999rpx; background: rgba(255,255,255,0.82); }
.icon-rocket { background: linear-gradient(145deg, rgba(255,184,107,0.2), rgba(255,184,107,0.46)); border-radius: 50% 50% 42% 42%; }
.icon-rocket:before { content: ''; position: absolute; left: 9rpx; top: 4rpx; width: 8rpx; height: 14rpx; border-radius: 999rpx; background: #FFB86B; }
.icon-rocket:after { content: ''; position: absolute; left: 8rpx; bottom: -3rpx; width: 10rpx; height: 8rpx; border-radius: 50%; background: rgba(255,184,107,0.56); }
.task-badge { height: 30rpx; line-height: 30rpx; padding: 0 10rpx; border-radius: 999rpx; background: rgba(229,255,241,0.78); color: #16A779; font-size: 16rpx; font-weight: 900; white-space: nowrap; }
.sub-title { margin-top: 18rpx; color: #12342F; font-size: 27rpx; font-weight: 900; }
.sub-desc { margin-top: 7rpx; color: #7E9691; font-size: 21rpx; font-weight: 800; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dl-stat { margin-top: 18rpx; display: flex; gap: 10rpx; opacity: .72; }
.stat-card { flex: 1; padding: 12rpx 8rpx; border-radius: 22rpx; display: flex; flex-direction: column; align-items: center; background: rgba(255,255,255,0.42); border: 1px solid rgba(255,255,255,0.62); }
.stat-card text:first-child { color: #42635E; font-size: 26rpx; font-weight: 900; font-family: DIN, Arial, sans-serif; }
.stat-card text:last-child { color: #7E9691; font-size: 18rpx; margin-top: 2rpx; font-weight: 800; }
.reward-float { position: absolute; left: 50%; bottom: 160rpx; z-index: 30; transform: translateX(-50%); padding: 10rpx 20rpx; border-radius: 999rpx; background: rgba(255,255,255,0.9); color: #16A779; font-size: 24rpx; font-weight: 900; box-shadow: 0 14rpx 30rpx rgba(53,214,166,0.18); animation: rewardUp .8s ease-out forwards; pointer-events: none; }
.reward-float.pool { color: #F08322; }
.reward-float.hunt { color: #348FEA; }
@keyframes rewardUp {
0% { transform: translate3d(-50%, 16rpx, 0) scale(.86); opacity: 0; }
18% { opacity: 1; }
100% { transform: translate3d(-50%, -46rpx, 0) scale(1); opacity: 0; }
}
.ticket-fly { position: absolute; right: 96rpx; top: 330rpx; width: 70rpx; height: 70rpx; line-height: 70rpx; border-radius: 50%; text-align: center; background: linear-gradient(145deg, #FFF2B8, #FFB84D); color: #9A5A00; font-size: 34rpx; font-weight: 900; box-shadow: 0 14rpx 30rpx rgba(255,184,77,0.34); animation: ticketFly .9s cubic-bezier(.16,.84,.28,1) forwards; z-index: 20; }
@keyframes ticketFly {
0% { transform: translate3d(0, 0, 0) scale(.72) rotate(-8deg); opacity: 0; }
12% { transform: translate3d(-18rpx, -28rpx, 0) scale(1.08) rotate(6deg); opacity: 1; }
72% { opacity: 1; }
100% { transform: translate3d(-190rpx, -610rpx, 0) scale(.34) rotate(18deg); opacity: 0; }
}
5 days ago
</style>