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.
259 lines
5.2 KiB
259 lines
5.2 KiB
<template>
|
|
<view class="pt">
|
|
<view class="pt-head">
|
|
<view>
|
|
<text class="pt-kicker">SUPPLY MAP</text>
|
|
<text class="pt-title">星球补给地图</text>
|
|
</view>
|
|
<text class="pt-sub">完成校园行动,点亮补给点</text>
|
|
</view>
|
|
<view class="pt-list">
|
|
<view class="pt-item" v-for="(t, i) in taskCards" :key="i" :class="t.cardClass">
|
|
<view class="pt-route-dot"></view>
|
|
<view class="pt-item-icon">{{t.icon}}</view>
|
|
<view class="pt-item-mid">
|
|
<view class="pt-item-name">{{t.name}}</view>
|
|
<view class="pt-item-desc">{{t.description}}</view>
|
|
</view>
|
|
<view class="pt-item-btn"
|
|
:class="{auto: t.actionType==='auto', done: t.actionType==='claim' && !t.canClaim}"
|
|
@tap="onClick(t)">
|
|
<text>+{{t.rewardTickets}}券</text>
|
|
<text>{{btnText(t)}} <text v-if="t.actionType==='auto'" class="btn-arrow">›</text></text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
tasks: {
|
|
type: Array,
|
|
default: () => []
|
|
}
|
|
},
|
|
computed: {
|
|
taskCards() {
|
|
return (this.tasks || []).map((item, index) => {
|
|
return Object.assign({}, item, {
|
|
icon: this.taskEmoji(item.code),
|
|
cardClass: this.taskClass(item.code) + (index % 2 === 1 ? ' offset' : '')
|
|
})
|
|
})
|
|
}
|
|
},
|
|
methods: {
|
|
taskEmoji(code) {
|
|
const map = {
|
|
waimai: '食',
|
|
group: '团',
|
|
invite: '邀',
|
|
sign: '签'
|
|
}
|
|
return map[code] || '券'
|
|
},
|
|
taskClass(code) {
|
|
const map = {
|
|
waimai: 'type-food',
|
|
group: 'type-group',
|
|
invite: 'type-invite',
|
|
sign: 'type-sign'
|
|
}
|
|
return map[code] || 'type-other'
|
|
},
|
|
btnText(t) {
|
|
if (t.actionType === 'auto') return '去完成'
|
|
if (t.code === 'sign') return t.canClaim ? '签到' : '已领取'
|
|
return t.canClaim ? '领取' : '已领取'
|
|
},
|
|
onClick(t) {
|
|
if (t.actionType === 'auto') {
|
|
this.$emit('go', t)
|
|
return
|
|
}
|
|
if (!t.canClaim) return
|
|
this.$emit('claim', t)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.pt {
|
|
position: relative;
|
|
margin-top: 20rpx;
|
|
}
|
|
|
|
.pt-head {
|
|
display: none;
|
|
}
|
|
|
|
.pt-kicker {
|
|
display: block;
|
|
color: #35D6A6;
|
|
font-size: 18rpx;
|
|
font-weight: 900;
|
|
letter-spacing: 3rpx;
|
|
margin-bottom: 4rpx;
|
|
}
|
|
|
|
.pt-title {
|
|
display: block;
|
|
color: #12342F;
|
|
font-size: 36rpx;
|
|
font-weight: 900;
|
|
}
|
|
|
|
.pt-sub {
|
|
color: #7E9691;
|
|
font-size: 22rpx;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.pt-list {
|
|
position: relative;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16rpx;
|
|
}
|
|
|
|
.pt-list:before {
|
|
display: none;
|
|
}
|
|
|
|
.pt-item {
|
|
position: relative;
|
|
width: 100%;
|
|
min-height: 148rpx;
|
|
box-sizing: border-box;
|
|
padding: 22rpx;
|
|
border-radius: 30rpx;
|
|
background: linear-gradient(145deg, rgba(255,255,255,0.82), rgba(244,255,249,0.64));
|
|
border: 2rpx solid rgba(255,255,255,0.9);
|
|
box-shadow: 0 18rpx 42rpx rgba(53,214,166,0.1);
|
|
overflow: hidden;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 18rpx;
|
|
}
|
|
|
|
.pt-item.offset {
|
|
margin-top: 0;
|
|
transform: none;
|
|
}
|
|
|
|
.pt-item:not(.offset) {
|
|
transform: none;
|
|
}
|
|
|
|
.pt-item:before {
|
|
content: '';
|
|
position: absolute;
|
|
right: -36rpx;
|
|
top: -40rpx;
|
|
width: 150rpx;
|
|
height: 150rpx;
|
|
border-radius: 50%;
|
|
background: rgba(53,214,166,0.12);
|
|
}
|
|
|
|
.pt-item.type-food:before { background: rgba(255,184,77,0.18); }
|
|
.pt-item.type-group:before { background: rgba(79,183,255,0.18); }
|
|
.pt-item.type-invite:before { background: rgba(143,124,255,0.16); }
|
|
.pt-item.type-sign:before { background: rgba(53,214,166,0.16); }
|
|
|
|
.pt-route-dot {
|
|
position: absolute;
|
|
left: 18rpx;
|
|
top: 18rpx;
|
|
width: 20rpx;
|
|
height: 20rpx;
|
|
border-radius: 50%;
|
|
background: #35D6A6;
|
|
border: 5rpx solid rgba(255,255,255,0.9);
|
|
box-shadow: 0 6rpx 16rpx rgba(53,214,166,0.22);
|
|
}
|
|
|
|
.pt-item-icon {
|
|
position: relative;
|
|
width: 76rpx;
|
|
height: 76rpx;
|
|
border-radius: 26rpx;
|
|
background: linear-gradient(145deg, #E5FFF1, #EAF8FF);
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #12342F;
|
|
font-size: 30rpx;
|
|
font-weight: 900;
|
|
box-shadow: inset 0 0 0 1rpx rgba(255,255,255,0.86);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.pt-item-mid {
|
|
position: relative;
|
|
margin-top: 0;
|
|
flex: 1;
|
|
min-width: 0;
|
|
}
|
|
|
|
.pt-item-name {
|
|
color: #12342F;
|
|
font-size: 28rpx;
|
|
font-weight: 900;
|
|
}
|
|
|
|
.pt-item-desc {
|
|
color: #7E9691;
|
|
font-size: 22rpx;
|
|
margin-top: 8rpx;
|
|
line-height: 32rpx;
|
|
min-height: 0;
|
|
}
|
|
|
|
.pt-item-btn {
|
|
position: relative;
|
|
margin-top: 0;
|
|
width: 142rpx;
|
|
height: 82rpx;
|
|
padding: 0;
|
|
border-radius: 28rpx;
|
|
background: linear-gradient(135deg, #35D6A6, #4FB7FF);
|
|
color: #FFFFFF;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-direction: column;
|
|
font-size: 22rpx;
|
|
font-weight: 800;
|
|
box-shadow: 0 12rpx 26rpx rgba(53,214,166,0.22);
|
|
flex-shrink: 0;
|
|
border: 2rpx solid rgba(255,255,255,0.82);
|
|
transition: transform .16s ease, opacity .16s ease;
|
|
}
|
|
|
|
.pt-item-btn.auto {
|
|
background: linear-gradient(135deg, #35D6A6, #4FB7FF);
|
|
color: #FFFFFF;
|
|
box-shadow: 0 12rpx 28rpx rgba(53,214,166,0.24);
|
|
}
|
|
|
|
.pt-item-btn.done {
|
|
background: rgba(18,52,47,0.06);
|
|
color: #9AA9A5;
|
|
box-shadow: none;
|
|
}
|
|
|
|
.pt-item-btn:active {
|
|
transform: scale(.96);
|
|
opacity: .88;
|
|
}
|
|
|
|
.btn-arrow {
|
|
margin-left: 4rpx;
|
|
font-size: 26rpx;
|
|
font-weight: 900;
|
|
}
|
|
</style>
|
|
|