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.
157 lines
8.7 KiB
157 lines
8.7 KiB
<template>
|
|
<view class="po">
|
|
<view class="po-head">
|
|
<view>
|
|
<view class="po-kicker">CAMPUS FARM</view>
|
|
<view class="po-title">松鼠星际农场</view>
|
|
<view class="po-sub">种券、仓库、防御塔和地标争夺,每天都有一点成长</view>
|
|
</view>
|
|
<view class="po-stamina">
|
|
<text class="po-stamina-num">{{state.stamina || 0}}</text>
|
|
<text class="po-stamina-label">体力</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="po-grid">
|
|
<view class="po-card tree">
|
|
<view class="po-tree">
|
|
<view class="po-tree-crown"></view>
|
|
<view class="po-tree-body"></view>
|
|
</view>
|
|
<view class="po-card-title">券树培育</view>
|
|
<view class="po-card-desc">选择周期投入星球券,成熟后返还本金和收益</view>
|
|
<scroll-view scroll-x class="po-cycles">
|
|
<view class="po-cycle" v-for="(c,i) in treeConfigs" :key="i" @tap="$emit('plant', c)">
|
|
<text>{{c.cycleHours}}h</text>
|
|
<text>收益 {{rateText(c.rate)}}</text>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
|
|
<view class="po-card warehouse">
|
|
<view class="po-icon">SAFE</view>
|
|
<view class="po-card-title">松鼠仓库 Lv{{state.warehouseLevel || 1}}</view>
|
|
<view class="po-progress"><view class="po-progress-in" :style="{width: warehousePercent + '%'}"></view></view>
|
|
<view class="po-card-desc">{{state.warehouseTicketCount || 0}} / {{state.warehouseCapacity || 10}} 张安全券</view>
|
|
<view class="po-actions">
|
|
<text @tap="$emit('store')">存入</text>
|
|
<text @tap="$emit('take')">取出</text>
|
|
<text @tap="$emit('upgradeWarehouse')">升级</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="po-card tower">
|
|
<view class="po-icon">TOWER</view>
|
|
<view class="po-card-title">防御塔 Lv{{state.towerLevel || 1}}</view>
|
|
<view class="po-card-desc">拦截 {{state.towerInterceptRate || 0}}% · 伤害 {{state.towerDamage || 0}}</view>
|
|
<view class="po-main-btn" @tap="$emit('upgradeTower')">升级防御</view>
|
|
</view>
|
|
|
|
<view class="po-card search">
|
|
<view class="po-icon">RADAR</view>
|
|
<view class="po-card-title">星际搜查</view>
|
|
<view class="po-card-desc">今日 {{state.dailySearchCount || 0}} 次 · 获得 {{state.dailySearchGain || 0}} 券</view>
|
|
<view class="po-main-btn" @tap="$emit('search')">派出松鼠宇航员</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="po-land">
|
|
<view class="po-land-title">校园地标</view>
|
|
<scroll-view scroll-x class="po-land-scroll">
|
|
<view class="po-land-item" v-for="(l,i) in landmarks" :key="i" @tap="$emit('bid', l)">
|
|
<view class="po-land-icon">{{l.icon || 'LAND'}}</view>
|
|
<view class="po-land-name">{{l.name}}</view>
|
|
<view class="po-land-benefit">{{benefitText(l)}}</view>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
|
|
<view class="po-orders" v-if="treeOrders.length">
|
|
<view class="po-land-title">成长中的券树</view>
|
|
<view class="po-order" v-for="(o,i) in treeOrders" :key="i">
|
|
<view>
|
|
<view class="po-order-title">{{o.cycleHours}}h · 投入{{o.investTickets}}券</view>
|
|
<view class="po-order-desc">预计收获 {{o.expectedTotal}} 券</view>
|
|
</view>
|
|
<view class="po-order-btn" @tap="$emit('harvest', o)">{{o.status === 2 ? '已收' : '收获'}}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
props: {
|
|
data: { type: Object, default: () => ({}) }
|
|
},
|
|
computed: {
|
|
state() {
|
|
return (this.data && this.data.state) || {}
|
|
},
|
|
treeConfigs() {
|
|
return (this.data && this.data.treeConfigs) || []
|
|
},
|
|
treeOrders() {
|
|
return (this.data && this.data.treeOrders) || []
|
|
},
|
|
landmarks() {
|
|
return (this.data && this.data.landmarks) || []
|
|
},
|
|
warehousePercent() {
|
|
const cap = this.state.warehouseCapacity || 10
|
|
return Math.min(100, Math.round(((this.state.warehouseTicketCount || 0) / cap) * 100))
|
|
}
|
|
},
|
|
methods: {
|
|
rateText(rate) {
|
|
return Math.round((Number(rate || 0)) * 100) + '%'
|
|
},
|
|
benefitText(item) {
|
|
if (item.benefitType === 'ticket') return '每日+' + item.benefitValue + '券'
|
|
if (item.benefitType === 'stamina_speed') return '体力+' + item.benefitValue + '%'
|
|
if (item.benefitType === 'search_rate') return '搜查+' + item.benefitValue + '%'
|
|
if (item.benefitType === 'tower_damage') return '防御+' + item.benefitValue + '%'
|
|
return '校园增益'
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.po { margin-top: 24rpx; }
|
|
.po-head { display: flex; justify-content: space-between; align-items: flex-start; padding: 0 10rpx 14rpx; }
|
|
.po-kicker { color: #59CBB5; font-size: 20rpx; font-weight: 900; letter-spacing: 2rpx; }
|
|
.po-title { margin-top: 6rpx; color: #12342F; font-size: 40rpx; font-weight: 900; }
|
|
.po-sub { margin-top: 8rpx; color: #6B817D; font-size: 24rpx; }
|
|
.po-stamina { width: 124rpx; height: 124rpx; border-radius: 44rpx; background: linear-gradient(145deg, rgba(255,255,255,0.96), rgba(225,250,255,0.82)); display: flex; flex-direction: column; align-items: center; justify-content: center; box-shadow: 0 18rpx 42rpx rgba(79,183,255,0.16); }
|
|
.po-stamina-num { color: #22B889; font-size: 36rpx; font-weight: 900; }
|
|
.po-stamina-label { color: #6B817D; font-size: 20rpx; }
|
|
.po-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18rpx; }
|
|
.po-card { position: relative; min-height: 250rpx; padding: 24rpx; border-radius: 38rpx; background: linear-gradient(155deg, rgba(255,255,255,0.9), rgba(241,255,249,0.72)); border: 2rpx solid rgba(255,255,255,0.9); box-shadow: 0 20rpx 46rpx rgba(53,214,166,0.12); overflow: hidden; }
|
|
.po-card.tree { grid-column: span 2; min-height: 280rpx; }
|
|
.po-card-title { color: #12342F; font-size: 30rpx; font-weight: 900; }
|
|
.po-card-desc { margin-top: 10rpx; color: #6B817D; font-size: 23rpx; line-height: 1.5; }
|
|
.po-tree { position: absolute; right: 54rpx; top: 34rpx; width: 140rpx; height: 150rpx; animation: treeBreath 2.6s ease-in-out infinite; }
|
|
.po-tree-crown { width: 130rpx; height: 110rpx; border-radius: 70rpx 70rpx 50rpx 50rpx; background: radial-gradient(circle at 35% 28%, #FFFFFF, #A8F7C1 42%, #35D6A6); box-shadow: 0 18rpx 38rpx rgba(53,214,166,0.24); }
|
|
.po-tree-body { margin: -12rpx auto 0; width: 28rpx; height: 66rpx; border-radius: 20rpx; background: linear-gradient(180deg, #F5C68A, #D8894F); }
|
|
@keyframes treeBreath { 0%,100%{ transform: translateY(0) scale(1); } 50%{ transform: translateY(-10rpx) scale(1.04); } }
|
|
.po-cycles { margin-top: 34rpx; white-space: nowrap; width: 430rpx; }
|
|
.po-cycle { display: inline-flex; flex-direction: column; justify-content: center; width: 132rpx; height: 86rpx; margin-right: 14rpx; padding-left: 20rpx; border-radius: 28rpx; background: rgba(255,255,255,0.82); color: #22B889; font-size: 22rpx; font-weight: 800; box-shadow: 0 12rpx 26rpx rgba(53,214,166,0.1); }
|
|
.po-icon { display: inline-flex; padding: 10rpx 16rpx; margin-bottom: 18rpx; border-radius: 999rpx; background: rgba(255,255,255,0.8); color: #22B889; font-size: 20rpx; font-weight: 900; }
|
|
.po-progress { margin-top: 18rpx; height: 14rpx; border-radius: 999rpx; background: rgba(53,214,166,0.12); overflow: hidden; }
|
|
.po-progress-in { height: 100%; border-radius: 999rpx; background: linear-gradient(90deg, #35D6A6, #4FB7FF); }
|
|
.po-actions { display: flex; gap: 10rpx; margin-top: 18rpx; }
|
|
.po-actions text, .po-main-btn { display: inline-flex; align-items: center; justify-content: center; height: 54rpx; padding: 0 18rpx; border-radius: 999rpx; background: linear-gradient(135deg, #DFFBF1, #E8F6FF); color: #22B889; font-size: 22rpx; font-weight: 800; }
|
|
.po-main-btn { margin-top: 18rpx; }
|
|
.po-land, .po-orders { margin-top: 20rpx; padding: 24rpx; border-radius: 38rpx; background: rgba(255,255,255,0.62); border: 2rpx solid rgba(255,255,255,0.86); box-shadow: 0 18rpx 42rpx rgba(79,183,255,0.1); }
|
|
.po-land-title { color: #12342F; font-size: 30rpx; font-weight: 900; }
|
|
.po-land-scroll { margin-top: 18rpx; white-space: nowrap; width: 100%; }
|
|
.po-land-item { display: inline-flex; flex-direction: column; justify-content: center; width: 190rpx; height: 170rpx; margin-right: 18rpx; padding: 18rpx; border-radius: 32rpx; background: linear-gradient(155deg, rgba(255,255,255,0.92), rgba(247,239,255,0.68)); box-sizing: border-box; }
|
|
.po-land-icon { color: #8F7CFF; font-size: 20rpx; font-weight: 900; }
|
|
.po-land-name { margin-top: 12rpx; color: #12342F; font-size: 27rpx; font-weight: 900; }
|
|
.po-land-benefit { margin-top: 8rpx; color: #6B817D; font-size: 22rpx; }
|
|
.po-order { display: flex; align-items: center; justify-content: space-between; margin-top: 18rpx; padding: 18rpx; border-radius: 28rpx; background: rgba(255,255,255,0.78); }
|
|
.po-order-title { color: #12342F; font-size: 26rpx; font-weight: 800; }
|
|
.po-order-desc { margin-top: 6rpx; color: #6B817D; font-size: 22rpx; }
|
|
.po-order-btn { padding: 14rpx 20rpx; border-radius: 999rpx; background: #22B889; color: #fff; font-size: 22rpx; font-weight: 800; }
|
|
</style>
|
|
|