diff --git a/package1/components/planet/planet-adventure-entry.vue b/package1/components/planet/planet-adventure-entry.vue
index 64e88be..43017e3 100644
--- a/package1/components/planet/planet-adventure-entry.vue
+++ b/package1/components/planet/planet-adventure-entry.vue
@@ -1,12 +1,12 @@
-
+
- 开始助推
+ 开始排位
COLLEGE ROCKET
- 学院助推赛
- 玩一局有机会获得更多星球券,为学院争地标
-
+ 学院排位赛
+ 个人前五得现金奖励
+
🚀
@@ -17,8 +17,8 @@
开始PK
COLLEGE ROCKET
- 星球擂台赛
- 看看谁才是PK王
+ 组队PK赛
+ 不服?看看谁才是PK王
@@ -35,26 +35,27 @@
diff --git a/package1/planet/adventure.vue b/package1/planet/adventure.vue
index f17194a..db23814 100644
--- a/package1/planet/adventure.vue
+++ b/package1/planet/adventure.vue
@@ -2,7 +2,7 @@
‹
- {{isDailyMode ? '学院助推赛' : 'PK局'}}
+ {{isDailyMode ? '学院排位赛' : 'PK局'}}
@@ -19,7 +19,12 @@
- {{heroSub}}
+
+ 🏆
+
+ {{heroSub}}
+
+
@@ -29,7 +34,7 @@
- {{['🥇','🥈','🥉'][i] || (i + 1)}}
+ {{gloryMedals[i] || (i + 1)}}
{{item.college || '神秘学院'}}
{{item.nickname || '匿名同学'}}
@@ -69,7 +74,7 @@
先点这里,再开始消除卡牌
- 今日已助推
+ 今日已排位
明天再来为学院继续推进
@@ -175,6 +180,7 @@
avatar: '',
college: '',
colleges: [],
+ gloryMedals: ['🥇','🥈','🥉','4','5'],
collegeModal: false,
home: {},
session: null,
@@ -223,7 +229,7 @@
heroSub() {
if (this.isPkMode) return '同一房间使用完全一致的卡牌布局。每人只有一次机会,退出或失败都会记录成绩。'
if (this.isChallengeMode) return '复刻好友通关布局,挑战同一组卡牌,结束后会显示领先或落后秒数。'
- return '每天1关,通关贡献学院推进值。21:30结算,前三学院成员分别获得3/2/1张星球券。'
+ return '21:30结算学院榜券奖励,前三名学院参与者每人得3/2/1张星球券;个人最快通关前五名可获得现金奖励5/4/3/2/1元。'
},
gameTitle() {
if (this.isPkMode) return '擂台关卡'
@@ -231,11 +237,11 @@
return '今日关卡'
},
startButtonText() {
- if (this.playing) return '助推中'
- if (this.cleared) return this.isDailyMode ? '今日已助推' : '成绩已提交'
+ if (this.playing) return '排位中'
+ if (this.cleared) return this.isDailyMode ? '今日已排位' : '成绩已提交'
if (this.isPkMode) return '开始擂台'
if (this.isChallengeMode) return '开始挑战'
- return '开始助推'
+ return '开始排位'
},
collegeRanks() {
const list = this.home.rankList || []
@@ -305,7 +311,7 @@
if (!this.playing) return '开始后进入倒计时'
if (this.timeLeft <= 30) return '最后冲刺,槽位别满'
if (this.timeLeft <= 60) return '时间紧张,加快决策'
- return '300秒内完成助推'
+ return '300秒内完成排位'
},
riskText() {
if (this.slots.length >= this.slotLimit - 1) return '危险:差1格就满'
@@ -370,7 +376,7 @@
}
const collegeParam = this.college ? ('?college=' + encodeURIComponent(this.college)) : ''
return {
- title: this.college ? `来为${this.college}助力,冲学院助推榜!` : '学院助推赛,来帮学院冲榜',
+ title: this.college ? `来为${this.college}助力,冲学院排位榜!` : '学院排位赛,来帮学院冲榜',
path: '/package1/planet/adventure' + collegeParam
}
},
@@ -441,7 +447,7 @@
regionId: this.regionId
}, false, false, true).then(res => {
if (res.code == 200) {
- this.gloryList = (res.result || []).map((item, index) => {
+ this.gloryList = (res.result || []).slice(0, 5).map((item, index) => {
item._key = item.id || ('glory_' + index)
return item
})
@@ -450,24 +456,15 @@
},
prepareSharedMode() {
if (this.isPkMode && this.roomId && !this.fixedSeed) {
- this.tui.request('/app/planet/adventure/pk/join', 'POST', {
- userId: this.userId,
- regionId: this.regionId,
- nickname: this.nickname,
- avatar: this.avatar,
- college: this.college,
- roomId: this.roomId
- }).then(res => {
- if (res.code != 200 || !res.result) {
- this.tui.toast(res.message)
- return
- }
- this.fixedSeed = res.result.seed
- this.pkInfo = res.result.room
- if (!this.regionId && this.pkInfo) this.regionId = this.pkInfo.regionId || ''
- if (!this.college && res.result.player) this.college = res.result.player.college || ''
- this.roundSeed = this.fixedSeed
- this.buildLevel()
+ this.checkPkRoomAvailable(() => {
+ this.joinPkRoom(res => {
+ this.fixedSeed = res.result.seed
+ this.pkInfo = res.result.room
+ if (!this.regionId && this.pkInfo) this.regionId = this.pkInfo.regionId || ''
+ if (!this.college && res.result.player) this.college = res.result.player.college || ''
+ this.roundSeed = this.fixedSeed
+ this.buildLevel()
+ })
})
}
if (this.isChallengeMode && this.challengeId && !this.fixedSeed) {
@@ -489,6 +486,48 @@
})
}
},
+ checkPkRoomAvailable(next) {
+ this.tui.request('/app/planet/adventure/pk/roomInfo', 'POST', {
+ userId: this.userId,
+ regionId: this.regionId,
+ roomId: this.roomId
+ }, false, false, true).then(res => {
+ if (res.code != 200 || !res.result || !res.result.room) {
+ this.tui.toast(res.message)
+ return
+ }
+ const room = res.result.room
+ const joined = !!res.result.player
+ this.pkInfo = room
+ if (!this.regionId && room) this.regionId = room.regionId || ''
+ if (!this.college && res.result.player) this.college = res.result.player.college || ''
+ if (room.status === 2 || room.status === 3) {
+ this.tui.toast('房间已结束')
+ return
+ }
+ if (!joined && (room.playerCount || 0) >= (room.maxPlayers || 2)) {
+ this.tui.toast('房间人数已满,无法进入')
+ return
+ }
+ if (typeof next === 'function') next()
+ })
+ },
+ joinPkRoom(done) {
+ this.tui.request('/app/planet/adventure/pk/join', 'POST', {
+ userId: this.userId,
+ regionId: this.regionId,
+ nickname: this.nickname,
+ avatar: this.avatar,
+ college: this.college,
+ roomId: this.roomId
+ }).then(res => {
+ if (res.code != 200 || !res.result) {
+ this.tui.toast(res.message)
+ return
+ }
+ if (typeof done === 'function') done(res)
+ })
+ },
schedulePrebuildLevel() {
if (!this.isDailyMode && !this.fixedSeed) return
this.clearPrebuildTimer()
@@ -539,24 +578,15 @@
},
startFixedMode() {
if (!this.fixedSeed && this.isPkMode) {
- this.tui.request('/app/planet/adventure/pk/join', 'POST', {
- userId: this.userId,
- regionId: this.regionId,
- nickname: this.nickname,
- avatar: this.avatar,
- college: this.college,
- roomId: this.roomId
- }).then(res => {
- if (res.code != 200 || !res.result) {
- this.tui.toast(res.message)
- return
- }
- this.fixedSeed = res.result.seed
- this.pkInfo = res.result.room
- this.roomId = res.result.roomId || this.roomId
- if (!this.regionId && this.pkInfo) this.regionId = this.pkInfo.regionId || ''
- if (!this.college && res.result.player) this.college = res.result.player.college || ''
- this.startFixedMode()
+ this.checkPkRoomAvailable(() => {
+ this.joinPkRoom(res => {
+ this.fixedSeed = res.result.seed
+ this.pkInfo = res.result.room
+ this.roomId = res.result.roomId || this.roomId
+ if (!this.regionId && this.pkInfo) this.regionId = this.pkInfo.regionId || ''
+ if (!this.college && res.result.player) this.college = res.result.player.college || ''
+ this.startFixedMode()
+ })
})
return
}
@@ -1125,11 +1155,11 @@
const card = this.cards.find(item => item.id === id)
if (!card) return
if (this.cleared) {
- this.tui.toast('今日已助推,明天再来')
+ this.tui.toast('今日已排位,明天再来')
return
}
if (!this.playing) {
- this.tui.toast('先点击开始助推')
+ this.tui.toast('先点击开始排位')
return
}
this.refreshCardState()
@@ -1231,7 +1261,7 @@
this.cleared = true
this.modal = {
show: true,
- title: '助推成功',
+ title: '排位成功',
sub: `${this.collegeName} 获得 ${progress} 点推进值。分享给好友继续为学院助力,每个人都会随机生成自己的关卡。`,
invite: true,
duration
@@ -1419,6 +1449,11 @@
.hero-kicker { color: #FF9C42; font-size: 22rpx; font-weight: 900; letter-spacing: 2rpx; }
.hero-title { margin-top: 10rpx; font-size: 42rpx; font-weight: 900; }
.hero-sub, .tips { margin-top: 16rpx; color: #6B817D; font-size: 24rpx; line-height: 1.55; }
+ .hero-reward-tip { position: relative; margin-top: 20rpx; padding: 20rpx 22rpx 20rpx 86rpx; border-radius: 24rpx; background: linear-gradient(135deg, rgba(255,247,221,0.96), rgba(255,255,255,0.9) 48%, rgba(229,255,246,0.92)); border: 3rpx solid rgba(255,184,77,0.58); box-shadow: 0 16rpx 34rpx rgba(255,184,77,0.18), inset 0 0 0 2rpx rgba(255,255,255,0.72); overflow: hidden; }
+ .hero-reward-tip:before { content: ''; position: absolute; right: -48rpx; top: -62rpx; width: 180rpx; height: 180rpx; border-radius: 50%; background: radial-gradient(circle, rgba(255,184,77,0.26), transparent 66%); }
+ .hero-reward-tip:after { content: '现金奖励'; position: absolute; right: 18rpx; top: 14rpx; padding: 4rpx 14rpx; border-radius: 999rpx; background: linear-gradient(135deg, #FFB84D, #35D6A6); color: #FFFFFF; font-size: 19rpx; font-weight: 900; }
+ .hero-reward-icon { position: absolute; left: 20rpx; top: 50%; transform: translateY(-50%); width: 48rpx; height: 48rpx; line-height: 48rpx; border-radius: 50%; text-align: center; background: rgba(255,255,255,0.82); box-shadow: 0 8rpx 18rpx rgba(255,184,77,0.18); font-size: 28rpx; }
+ .hero-reward-copy { position: relative; z-index: 1; padding-right: 92rpx; color: #6A4A1D; font-size: 24rpx; line-height: 1.55; font-weight: 800; }
.tips { display: flex; flex-direction: column; gap: 6rpx; }
.countdown-card { margin-top: 16rpx; padding: 18rpx 20rpx; border-radius: 28rpx; background: linear-gradient(135deg, rgba(53,214,166,0.14), rgba(79,183,255,0.16)); border: 2rpx solid rgba(53,214,166,0.22); }
.countdown-card.warning { background: linear-gradient(135deg, rgba(255,184,77,0.18), rgba(255,244,215,0.9)); border-color: rgba(255,184,77,0.42); }
diff --git a/package1/planet/drawResult.vue b/package1/planet/drawResult.vue
index 447aa57..cdb8eb6 100644
--- a/package1/planet/drawResult.vue
+++ b/package1/planet/drawResult.vue
@@ -26,12 +26,18 @@
本商圈暂未开奖,敬请期待 🌌
-
- 中奖名单
-
- {{w.levelName}}
- {{w.userName || '神秘居民'}}
- ¥{{Number(w.amount||0).toFixed(2)}}
+
+ 最近10期中奖记录
+
+
+ 第 {{h.record && h.record.periodNo}} 期
+ {{drawDate(h.record && h.record.drawTime)}}
+
+
+ {{w.levelName}}
+ {{maskName(w.userName)}}
+ ¥{{Number(w.amount||0).toFixed(2)}}
+
@@ -67,6 +73,7 @@
regionId: '',
record: null,
winners: [],
+ history: [],
myWinning: []
}
},
@@ -105,6 +112,7 @@
if (res.code == 200 && res.result) {
this.record = res.result.record
this.winners = res.result.winners || []
+ this.history = res.result.history || []
}
})
},
@@ -127,6 +135,17 @@
if (res.code == 200) this.loadMyWinning()
})
},
+ maskName(name) {
+ if (!name) return '神秘居民'
+ const text = String(name)
+ if (text.length <= 1) return text + '*'
+ if (text.length === 2) return text.charAt(0) + '*'
+ return text.charAt(0) + '*' + text.charAt(text.length - 1)
+ },
+ drawDate(time) {
+ if (!time) return ''
+ return String(time).substring(0, 10)
+ },
goBack() {
const pages = getCurrentPages ? getCurrentPages() : []
if (pages.length > 1) {
@@ -295,6 +314,23 @@
box-shadow: 0 12rpx 28rpx rgba(53,214,166,0.08);
}
+ .dr-history {
+ margin-bottom: 22rpx;
+ padding: 20rpx;
+ border-radius: 30rpx;
+ background: rgba(255,255,255,0.58);
+ border: 1rpx solid rgba(255,255,255,0.86);
+ }
+
+ .dr-history-head {
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 12rpx;
+ color: #42635E;
+ font-size: 24rpx;
+ font-weight: 900;
+ }
+
.dr-w-level {
font-size: 22rpx;
padding: 2rpx 14rpx;
diff --git a/package1/planet/index.vue b/package1/planet/index.vue
index 1b2766c..bdfb6ee 100644
--- a/package1/planet/index.vue
+++ b/package1/planet/index.vue
@@ -37,6 +37,7 @@
@ticketlog="goTicketLog"
@draw="goDrawResult"
@guide="showGuideModal"
+ @poolrule="showPoolRuleModal"
@rank="goRank">
@@ -102,6 +103,44 @@
+
+
+
+
+ CURRENT POOL
+ 本期奖池详情
+
+ ×
+
+ {{drawTimeText}}
+
+
+ ¥{{Number(home.poolAmount || 0).toFixed(2)}}
+ 奖池金额
+
+
+ {{home.joinCount || 0}}
+ 参与人数
+
+
+ {{(home.dailyLoop && home.dailyLoop.poolTicketTotal) || 0}}
+ 总投入券
+
+
+ {{(home.dailyLoop && home.dailyLoop.myWeightTickets) || 0}}
+ 我的权重
+
+
+
+
+ {{r.levelName}}
+ ¥{{Number(r.amount || 0).toFixed(2)}} × {{r.quota || 0}}名
+
+
+ 投入越多权重越高,但权重会递减;每人每期最多中一次,概率仅为实时估算。
+
+
+
BANJINLI GUIDE
@@ -109,7 +148,7 @@
1
- 每天签到、开补给箱、玩学院助推赛都能获得星球券。
+ 每天签到、开补给箱、玩学院排位赛都能获得星球券。
2
@@ -121,7 +160,7 @@
4
- 补给地图里有券树、仓库、防御塔、地标和任务,适合长期经营。
+ 补给地图保留农场券树、防御塔和校园下单给券任务,适合每天顺手经营。
知道怎么玩了
@@ -157,6 +196,7 @@
nickname: '',
avatar: '',
college: '',
+ loadedOnce: false,
home: {
poolAmount: 0,
joinCount: 0,
@@ -181,6 +221,7 @@
data: {},
receiving: false
},
+ poolRuleVisible: false,
guideVisible: false,
huntModal: {
show: false,
@@ -205,6 +246,11 @@
winningAmount() {
const amount = Number((this.winningModal.data && this.winningModal.data.amount) || 0)
return amount.toFixed(2)
+ },
+ drawTimeText() {
+ if (!this.home || !this.home.drawTime) return '每日 22:00 开奖'
+ const text = String(this.home.drawTime)
+ return text.length > 16 ? text.substring(5, 16) + ' 开奖' : text
}
},
onLoad() {
@@ -222,6 +268,11 @@
} catch (e) {}
this.loadHome()
},
+ onShow() {
+ if (this.loadedOnce) {
+ this.loadHome(true)
+ }
+ },
methods: {
initNavHeight() {
try {
@@ -233,6 +284,9 @@
} catch (e) {}
this.navHeight = this.statusBarHeight + 44
},
+ showPoolRuleModal() {
+ this.poolRuleVisible = true
+ },
loadHome(silent) {
if (!this.userId) {
this.tui.toast('请先登录')
@@ -254,6 +308,7 @@
this.loading = false
if (res.code == 200 && res.result) {
this.home = res.result
+ this.loadedOnce = true
this.showUnreadWinning()
} else if (res.message) {
this.tui.toast(res.message)
@@ -749,6 +804,133 @@
height: 60rpx;
}
+ .pool-detail-card {
+ padding: 28rpx;
+ border-radius: 36rpx;
+ background: rgba(255,255,255,0.86);
+ border: 2rpx solid rgba(255,255,255,0.92);
+ box-shadow: 0 18rpx 42rpx rgba(53,214,166,0.12);
+ }
+
+ .pool-rule-mask {
+ position: fixed;
+ top: 0; left: 0; right: 0; bottom: 0;
+ z-index: 75;
+ background: rgba(18,52,47,0.34);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0 32rpx;
+ }
+
+ .pool-detail-modal {
+ width: 100%;
+ max-height: 78vh;
+ overflow-y: auto;
+ background: linear-gradient(155deg, rgba(255,255,255,0.97), rgba(240,255,248,0.9));
+ }
+
+ .pool-detail-head {
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ }
+
+ .pool-detail-kicker {
+ color: #59CBB5;
+ font-size: 20rpx;
+ font-weight: 900;
+ letter-spacing: 2rpx;
+ }
+
+ .pool-detail-title {
+ margin-top: 6rpx;
+ color: #12342F;
+ font-size: 34rpx;
+ font-weight: 900;
+ }
+
+ .pool-detail-time {
+ padding: 8rpx 16rpx;
+ border-radius: 999rpx;
+ background: rgba(255,184,77,0.16);
+ color: #D17812;
+ font-size: 22rpx;
+ font-weight: 900;
+ }
+
+ .modal-time {
+ display: inline-flex;
+ margin-top: 18rpx;
+ }
+
+ .pool-detail-close {
+ width: 56rpx;
+ height: 56rpx;
+ line-height: 52rpx;
+ border-radius: 50%;
+ text-align: center;
+ background: rgba(18,52,47,0.08);
+ color: #42635E;
+ font-size: 42rpx;
+ font-weight: 300;
+ }
+
+ .pool-detail-grid {
+ margin-top: 22rpx;
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 14rpx;
+ }
+
+ .pool-detail-item {
+ padding: 18rpx;
+ border-radius: 24rpx;
+ background: rgba(245,255,251,0.78);
+ display: flex;
+ flex-direction: column;
+ }
+
+ .pool-detail-item text:first-child {
+ color: #12342F;
+ font-size: 32rpx;
+ font-weight: 900;
+ }
+
+ .pool-detail-item text:last-child {
+ margin-top: 6rpx;
+ color: #7E9691;
+ font-size: 22rpx;
+ }
+
+ .reward-list {
+ margin-top: 20rpx;
+ }
+
+ .reward-row {
+ display: flex;
+ justify-content: space-between;
+ padding: 14rpx 4rpx;
+ border-bottom: 1rpx solid rgba(18,52,47,0.06);
+ color: #42635E;
+ font-size: 24rpx;
+ font-weight: 800;
+ }
+
+ .reward-row text:last-child {
+ color: #22B889;
+ }
+
+ .pool-rule {
+ margin-top: 18rpx;
+ padding: 16rpx 18rpx;
+ border-radius: 22rpx;
+ background: rgba(79,183,255,0.1);
+ color: #42635E;
+ font-size: 23rpx;
+ line-height: 1.5;
+ }
+
.planet-quick-row {
margin-top: 24rpx;
display: flex;
diff --git a/package1/planet/more.vue b/package1/planet/more.vue
index 255d47f..49d35f6 100644
--- a/package1/planet/more.vue
+++ b/package1/planet/more.vue
@@ -5,7 +5,7 @@
星球补给地图
-
+
正在加载星球补给...
@@ -22,21 +22,105 @@
-
-
-
-
-
+
+
+
+ TODAY GUIDE
+ 今天先做这三件事
+
+ 补给路线
+
+
+
+ 🎁
+
+ 下单得券
+ 外卖、团购等校园订单完成后系统自动发放星球券。
+
+ 去完成
+
+
+ 🌱
+
+ 种券树
+ 投入闲置星球券,成熟后收回本金和收益。
+
+ 去完成
+
+
+ 🛡️
+
+ 升防御塔
+ 提高被偷券时的拦截、反击和伤害能力。
+
+ 去完成
+
+
+
+
+
+
+
+
+ CAMPUS SUPPLY
+ 校园补给任务
+
+
+
+
+ 💡
+ 重点看右侧按钮:显示“领取”的任务可以直接拿券;显示“去完成”的任务完成校园订单后系统自动发放星球券。
+
+
+
+
+
+
+
+
+ FARM & DEFENSE
+ 经营补给区
+
+ 种券 / 防守
+
+
+
+
+
+
+
+ PLANT TREE
+ 投入 {{treeInput.config.cycleHours || 0}}h 券树
+
+ 收益率 {{rateText(treeInput.config.rate)}}
+ {{treeInputRange}}
+
+
+
+ 最低投入
+ 最高投入
+
+
+ 🌱
+ 成熟后返还本金和收益,超过范围会无法种植。
+
+
+ 取消
+ 确认种植
+
+
+
@@ -65,9 +149,27 @@
tasks: [],
newsList: [],
operate: {}
+ },
+ scrollTarget: '',
+ scrollTop: 0,
+ treeInput: {
+ show: false,
+ config: {},
+ tickets: ''
}
}
},
+ computed: {
+ treeInputMin() {
+ return (this.treeInput.config && this.treeInput.config.minInvest) || 1
+ },
+ treeInputMax() {
+ return (this.treeInput.config && this.treeInput.config.maxInvest) || 0
+ },
+ treeInputRange() {
+ return this.treeInputMax > 0 ? `可投入 ${this.treeInputMin}-${this.treeInputMax} 张` : `最低投入 ${this.treeInputMin} 张`
+ }
+ },
onLoad() {
const sys = uni.getSystemInfoSync()
this.statusBarHeight = sys.statusBarHeight || 20
@@ -92,7 +194,7 @@
return
}
if (!silent) this.loading = true
- this.tui.request('/app/planet/home', 'POST', {
+ this.tui.request('/app/planet/supply', 'POST', {
userId: this.userId,
regionId: this.regionId,
nickname: this.nickname,
@@ -119,22 +221,49 @@
if (res.code == 200) this.loadHome(true)
})
},
- promptTickets(title, callback) {
- uni.showModal({
- title,
- editable: true,
- placeholderText: '输入星球券数量',
- success: (res) => {
- if (!res.confirm) return
- const tickets = parseInt(res.content || '0', 10)
- if (!tickets || tickets <= 0) {
- this.tui.toast('请输入正确数量')
- return
- }
- callback(tickets)
+ scrollToSupply(type) {
+ const id = type === 'task' ? 'supply-task-section' : 'supply-operate-section'
+ this.scrollTarget = ''
+ this.$nextTick(() => {
+ this.scrollTarget = id
+ setTimeout(() => {
+ this.scrollToSupplyByTop(id)
+ }, 80)
+ })
+ },
+ scrollToSupplyByTop(id) {
+ const query = uni.createSelectorQuery().in(this)
+ query.select('.page').boundingClientRect()
+ query.select('#' + id).boundingClientRect()
+ query.select('.page').scrollOffset()
+ query.exec((res) => {
+ const pageRect = res && res[0]
+ const targetRect = res && res[1]
+ const scroll = res && res[2]
+ if (!pageRect || !targetRect || !scroll) return
+ const top = Math.max(0, scroll.scrollTop + targetRect.top - pageRect.top - 8)
+ if (Math.abs(top - this.scrollTop) < 2) {
+ this.scrollTop = Math.max(0, top - 1)
+ this.$nextTick(() => {
+ this.scrollTop = top
+ })
+ return
}
+ this.scrollTop = top
})
},
+ goTask(task) {
+ const map = {
+ waimai: '/package2/group/groupBuyList',
+ group: '/package2/group/studentStoreList'
+ }
+ const url = map[task.code]
+ if (!url) {
+ if (task.code === 'invite') this.tui.toast('邀请页面正在准备中')
+ return
+ }
+ uni.navigateTo({ url })
+ },
operateRequest(url, data, successText) {
this.tui.request(url, 'POST', Object.assign({
userId: this.userId,
@@ -145,9 +274,43 @@
})
},
onPlantTree(config) {
- this.promptTickets(`投入 ${config.cycleHours}h 券树`, (tickets) => {
- this.operateRequest('/app/planet/tree/plant', { configId: config.id, tickets }, '种植成功')
- })
+ this.treeInput = {
+ show: true,
+ config: config || {},
+ tickets: ''
+ }
+ },
+ closeTreeInput() {
+ this.treeInput.show = false
+ },
+ fillTreeMin() {
+ this.treeInput.tickets = String(this.treeInputMin)
+ },
+ fillTreeMax() {
+ if (this.treeInputMax > 0) this.treeInput.tickets = String(this.treeInputMax)
+ },
+ rateText(rate) {
+ return Math.round(Number(rate || 0) * 100) + '%'
+ },
+ confirmPlantTree() {
+ const tickets = parseInt(this.treeInput.tickets || '0', 10)
+ if (!tickets || tickets <= 0) {
+ this.tui.toast('请输入正确数量')
+ return
+ }
+ if (tickets < this.treeInputMin) {
+ this.tui.toast(`最低投入${this.treeInputMin}张`)
+ return
+ }
+ if (this.treeInputMax > 0 && tickets > this.treeInputMax) {
+ this.tui.toast(`最高投入${this.treeInputMax}张`)
+ return
+ }
+ this.closeTreeInput()
+ this.operateRequest('/app/planet/tree/plant', {
+ configId: this.treeInput.config.id,
+ tickets
+ }, '种植成功')
},
onHarvestTree(order) {
if (order.status === 2) {
@@ -192,5 +355,42 @@
.hero-ticket { width: 140rpx; height: 120rpx; border-radius: 34rpx; background: linear-gradient(145deg, #35D6A6, #4FB7FF); color: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; flex-shrink: 0; }
.hero-ticket text:first-child { font-size: 36rpx; font-weight: 900; }
.hero-ticket text:last-child { margin-top: 4rpx; font-size: 20rpx; }
+ .guide-card { position: relative; margin-top: 22rpx; padding: 28rpx; border-radius: 38rpx; background: linear-gradient(145deg, rgba(255,255,255,0.95), rgba(255,249,225,0.76)); border: 3rpx solid rgba(255,184,77,0.38); box-shadow: 0 20rpx 48rpx rgba(255,184,77,0.13); overflow: hidden; }
+ .guide-card:before { content: ''; position: absolute; right: -70rpx; top: -90rpx; width: 240rpx; height: 240rpx; border-radius: 50%; background: radial-gradient(circle, rgba(255,184,77,0.24), transparent 68%); }
+ .guide-title-row, .section-head { position: relative; z-index: 1; display: flex; align-items: flex-start; justify-content: space-between; gap: 18rpx; }
+ .guide-kicker, .section-kicker { color: #59CBB5; font-size: 19rpx; font-weight: 900; letter-spacing: 2rpx; }
+ .guide-title, .section-title { margin-top: 6rpx; color: #12342F; font-size: 34rpx; font-weight: 900; }
+ .guide-tag, .section-pill { flex-shrink: 0; padding: 8rpx 16rpx; border-radius: 999rpx; background: linear-gradient(135deg, #FFB84D, #35D6A6); color: #FFFFFF; font-size: 21rpx; font-weight: 900; box-shadow: 0 10rpx 22rpx rgba(53,214,166,0.16); }
+ .guide-list { position: relative; z-index: 1; margin-top: 22rpx; display: flex; flex-direction: column; gap: 14rpx; }
+ .guide-item { display: flex; align-items: center; gap: 16rpx; padding: 18rpx; border-radius: 28rpx; background: rgba(255,255,255,0.72); border: 1rpx solid rgba(255,255,255,0.9); }
+ .guide-item.primary { background: linear-gradient(135deg, rgba(229,255,241,0.86), rgba(255,255,255,0.72)); }
+ .guide-item.tower { background: linear-gradient(135deg, rgba(232,246,255,0.86), rgba(255,255,255,0.72)); }
+ .guide-item.task { background: linear-gradient(135deg, rgba(255,247,221,0.9), rgba(255,255,255,0.72)); }
+ .guide-icon { width: 56rpx; height: 56rpx; line-height: 56rpx; border-radius: 20rpx; text-align: center; background: rgba(255,255,255,0.82); font-size: 30rpx; box-shadow: 0 8rpx 18rpx rgba(18,52,47,0.06); flex-shrink: 0; }
+ .guide-item view { display: flex; flex-direction: column; }
+ .guide-item view { flex: 1; min-width: 0; }
+ .guide-item view text:first-child { color: #12342F; font-size: 27rpx; font-weight: 900; }
+ .guide-item view text:last-child { margin-top: 6rpx; color: #6B817D; font-size: 22rpx; line-height: 1.4; }
+ .guide-action { flex-shrink: 0; padding: 9rpx 16rpx; border-radius: 999rpx; background: linear-gradient(135deg, #35D6A6, #4FB7FF); color: #FFFFFF; font-size: 21rpx; font-weight: 900; box-shadow: 0 10rpx 20rpx rgba(53,214,166,0.18); }
+ .section-card { margin-top: 24rpx; padding: 26rpx; border-radius: 40rpx; background: rgba(255,255,255,0.72); border: 2rpx solid rgba(255,255,255,0.9); box-shadow: 0 18rpx 44rpx rgba(53,214,166,0.1); }
+ .operate-section { background: linear-gradient(155deg, rgba(255,255,255,0.88), rgba(239,255,249,0.72)); }
+ .task-section { background: linear-gradient(155deg, rgba(255,255,255,0.88), rgba(232,246,255,0.72)); }
+ .section-pill.warn { background: linear-gradient(135deg, #FFB84D, #FF7A59); }
+ .task-tip { margin-top: 20rpx; padding: 18rpx 20rpx; border-radius: 26rpx; background: rgba(255,184,77,0.14); border: 2rpx solid rgba(255,184,77,0.24); color: #7A5420; font-size: 23rpx; line-height: 1.45; font-weight: 800; display: flex; gap: 12rpx; }
+ .task-tip text:first-child { flex-shrink: 0; }
+ .supply-anchor { height: 1rpx; }
+ .tree-input-mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 80; background: rgba(18,52,47,0.36); display: flex; align-items: center; justify-content: center; padding: 0 44rpx; }
+ .tree-input-card { width: 100%; padding: 38rpx 34rpx 30rpx; border-radius: 42rpx; background: linear-gradient(155deg, rgba(255,255,255,0.98), rgba(239,255,249,0.92)); box-shadow: 0 34rpx 80rpx rgba(18,52,47,0.18); border: 2rpx solid rgba(255,255,255,0.92); }
+ .tree-input-kicker { color: #59CBB5; font-size: 20rpx; font-weight: 900; letter-spacing: 3rpx; }
+ .tree-input-title { margin-top: 10rpx; color: #12342F; font-size: 38rpx; font-weight: 900; }
+ .tree-input-sub { margin-top: 18rpx; display: flex; gap: 12rpx; flex-wrap: wrap; }
+ .tree-input-sub text { padding: 8rpx 16rpx; border-radius: 999rpx; background: rgba(53,214,166,0.12); color: #22B889; font-size: 22rpx; font-weight: 900; }
+ .tree-input { margin-top: 24rpx; height: 88rpx; padding: 0 24rpx; border-radius: 24rpx; background: rgba(18,52,47,0.06); color: #12342F; font-size: 30rpx; font-weight: 900; }
+ .tree-quick-row { margin-top: 18rpx; display: flex; gap: 14rpx; }
+ .tree-quick-row view { flex: 1; height: 58rpx; line-height: 58rpx; text-align: center; border-radius: 999rpx; background: rgba(255,184,77,0.16); color: #C27724; font-size: 23rpx; font-weight: 900; }
+ .tree-input-tip { margin-top: 20rpx; padding: 18rpx; border-radius: 24rpx; background: rgba(79,183,255,0.1); color: #42635E; font-size: 23rpx; line-height: 1.45; font-weight: 800; display: flex; gap: 12rpx; }
+ .tree-input-actions { margin-top: 28rpx; display: flex; gap: 16rpx; }
+ .tree-input-actions view { flex: 1; height: 76rpx; line-height: 76rpx; border-radius: 999rpx; text-align: center; font-size: 27rpx; font-weight: 900; background: rgba(18,52,47,0.07); color: #42635E; }
+ .tree-input-actions view:last-child { background: linear-gradient(135deg, #35D6A6, #4FB7FF); color: #FFFFFF; box-shadow: 0 16rpx 32rpx rgba(53,214,166,0.22); }
.bottom-space { height: 60rpx; }
diff --git a/package1/planet/pkHall.vue b/package1/planet/pkHall.vue
index 31e9e8c..ef17ec2 100644
--- a/package1/planet/pkHall.vue
+++ b/package1/planet/pkHall.vue
@@ -9,7 +9,7 @@
CAMPUS ARENA
同一关卡,拼手速和决策
- 独立于每日助推赛,房间内所有人使用同一个 seed。每人一次机会,第一名通吃奖池。
+ 独立于每日排位赛,房间内所有人使用同一个 seed。每人一次机会,第一名通吃奖池。
创建房间
@@ -27,7 +27,7 @@
{{room.roomName || '星球擂台'}}
- {{room.playerCount || 0}}/{{room.maxPlayers || 2}} 人 · 入场 {{room.entryTickets || 1}} 券 · {{room._statusText}}
+ {{room.playerCount || 0}}/{{room.maxPlayers || 2}} 人 · 入场 {{room.entryTickets || 1}} 券 · {{room._statusText}} · {{room._countdownText}}
{{room.poolTickets || 0}}
@@ -63,7 +63,7 @@
{{room.roomName || '星球擂台'}}
- {{room.playerCount || 0}}/{{room.maxPlayers || 2}} 人 · 入场 {{room.entryTickets || 1}} 券
+ {{room.playerCount || 0}}/{{room.maxPlayers || 2}} 人 · 入场 {{room.entryTickets || 1}} 券 · {{room._countdownText}}
{{room.poolTickets || 0}}
@@ -119,6 +119,8 @@
myRecordsPageSize: 10,
myRecordsTotalPages: 1,
myRecordsLoading: false,
+ myTicketCount: null,
+ countdownTimer: null,
showCreate: false,
shareRoom: null,
form: {
@@ -168,6 +170,7 @@
} catch (e) {}
this.college = uni.getStorageSync('planetCollege_' + this.regionId) || ''
if (this.regionId) {
+ this.loadTicketCount()
this.loadMyRooms(true)
this.loadMyRecords(true)
this.loadHotRooms(true)
@@ -175,6 +178,16 @@
if (options.roomId) {
this.joinRoom({ id: options.roomId })
}
+ this.startCountdownTimer()
+ },
+ onUnload() {
+ this.clearCountdownTimer()
+ },
+ onHide() {
+ this.clearCountdownTimer()
+ },
+ onShow() {
+ if (this.userId) this.startCountdownTimer()
},
onShareAppMessage() {
const room = this.shareRoom || {}
@@ -250,6 +263,7 @@
if (res.code == 200 && res.result) {
const records = this.withKeys(res.result.records || [], config.prefix + '_' + nextPage)
this[config.listKey] = reset ? records : this[config.listKey].concat(records)
+ this.refreshCountdowns()
this[config.pageKey] = Number(res.result.current || nextPage)
this[config.totalKey] = Math.max(1, Number(res.result.pages || 1))
}
@@ -266,6 +280,16 @@
loadHotRooms(reset) {
this.loadPageList('hotRooms', reset)
},
+ loadTicketCount() {
+ return this.tui.request('/app/planet/home', 'POST', {
+ userId: this.userId,
+ regionId: this.regionId
+ }, false, false, true).then(res => {
+ if (res.code == 200 && res.result) {
+ this.myTicketCount = Number(res.result.myTicketCount || 0)
+ }
+ })
+ },
loadMoreActive() {
if (this.activeTab === 'myRooms') this.loadMyRooms(false)
else if (this.activeTab === 'myRecords') this.loadMyRecords(false)
@@ -276,6 +300,7 @@
item.password = ''
item._key = item.id || (prefix + '_' + index)
item._statusText = this.roomStatus(item.status)
+ item._countdownText = this.roomCountdownText(item)
if (prefix.indexOf('record') === 0) {
item._title = this.recordTitle(item)
item._meta = this.recordMeta(item)
@@ -285,10 +310,45 @@
return item
})
},
+ startCountdownTimer() {
+ if (this.countdownTimer) return
+ this.refreshCountdowns()
+ this.countdownTimer = setInterval(() => {
+ this.refreshCountdowns()
+ }, 1000)
+ },
+ clearCountdownTimer() {
+ if (!this.countdownTimer) return
+ clearInterval(this.countdownTimer)
+ this.countdownTimer = null
+ },
+ refreshCountdowns() {
+ this.hotRooms = this.hotRooms.map(room => Object.assign({}, room, {
+ _countdownText: this.roomCountdownText(room)
+ }))
+ this.myRooms = this.myRooms.map(room => Object.assign({}, room, {
+ _countdownText: this.roomCountdownText(room)
+ }))
+ },
setShareRoom(room) {
this.shareRoom = room
},
createRoom() {
+ const tickets = Number(this.form.tickets || 1)
+ if (tickets <= 0) {
+ this.tui.toast('请输入入场券数量')
+ return
+ }
+ if (this.myTicketCount === null) {
+ this.loadTicketCount().then(() => {
+ this.createRoom()
+ })
+ return
+ }
+ if (this.myTicketCount < tickets) {
+ this.tui.toast('星球券不足,无法创建房间')
+ return
+ }
this.tui.request('/app/planet/adventure/pk/create', 'POST', {
userId: this.userId,
regionId: this.regionId,
@@ -299,13 +359,15 @@
maxPlayers: this.form.maxPlayers,
publicFlag: this.form.password ? 0 : 1,
password: this.form.password,
- tickets: this.form.tickets
+ tickets: tickets
}).then(res => {
if (res.code != 200 || !res.result) {
this.tui.toast(res.message)
+ this.loadTicketCount()
return
}
this.showCreate = false
+ this.myTicketCount = Math.max(0, this.myTicketCount - tickets)
this.activeTab = 'myRooms'
this.loadMyRooms(true)
this.loadHotRooms(true)
@@ -313,9 +375,38 @@
})
},
joinRoom(room) {
- this.tui.request('/app/planet/adventure/pk/join', 'POST', {
+ this.tui.request('/app/planet/adventure/pk/roomInfo', 'POST', {
userId: this.userId,
regionId: this.regionId,
+ roomId: room.id
+ }, false, false, true).then(infoRes => {
+ if (infoRes.code != 200 || !infoRes.result || !infoRes.result.room) {
+ this.tui.toast(infoRes.message)
+ this.loadHotRooms(true)
+ this.loadMyRooms(true)
+ return
+ }
+ const latestRoom = infoRes.result.room
+ const joined = !!infoRes.result.player
+ if (latestRoom.status === 2 || latestRoom.status === 3) {
+ this.tui.toast('房间已结束')
+ this.loadHotRooms(true)
+ this.loadMyRooms(true)
+ return
+ }
+ if (!joined && (latestRoom.playerCount || 0) >= (latestRoom.maxPlayers || 2)) {
+ this.tui.toast('房间人数已满,无法进入')
+ this.loadHotRooms(true)
+ this.loadMyRooms(true)
+ return
+ }
+ this.doJoinRoom(Object.assign({}, room, latestRoom), joined)
+ })
+ },
+ doJoinRoom(room, joined) {
+ this.tui.request('/app/planet/adventure/pk/join', 'POST', {
+ userId: this.userId,
+ regionId: room.regionId || this.regionId,
nickname: this.nickname,
avatar: this.avatar,
college: this.college,
@@ -324,8 +415,10 @@
}).then(res => {
if (res.code != 200 || !res.result) {
this.tui.toast(res.message)
+ this.loadTicketCount()
return
}
+ this.loadTicketCount()
uni.navigateTo({
url: '/package1/planet/adventure?mode=pk&roomId=' + room.id + '&seed=' + encodeURIComponent(res.result.seed || '')
})
@@ -337,6 +430,26 @@
if (status === 3) return '已取消'
return '等待中'
},
+ roomCountdownText(room) {
+ if (!room || room.status === 2 || room.status === 3) return '已结束'
+ const createdAt = this.parseRoomTime(room.createTime)
+ if (!createdAt) return '30分钟后自动结算'
+ const remain = createdAt + 30 * 60 * 1000 - Date.now()
+ if (remain <= 0) return '结算中'
+ const minutes = Math.floor(remain / 60000)
+ const seconds = Math.floor((remain % 60000) / 1000)
+ return '剩余 ' + this.pad2(minutes) + ':' + this.pad2(seconds) + ' 自动结算'
+ },
+ parseRoomTime(value) {
+ if (!value) return 0
+ if (typeof value === 'number') return value
+ const time = Date.parse(String(value).replace(/-/g, '/'))
+ return isNaN(time) ? 0 : time
+ },
+ pad2(value) {
+ value = Number(value || 0)
+ return value < 10 ? '0' + value : String(value)
+ },
recordTitle(record) {
if (record.cleared === 1) return (record.durationSeconds || 0) + '秒通关'
return '挑战失败'
diff --git a/package1/planet/rank.vue b/package1/planet/rank.vue
index c5e9569..30e15ad 100644
--- a/package1/planet/rank.vue
+++ b/package1/planet/rank.vue
@@ -58,7 +58,10 @@
v-if="podiumSecond"
@tap="onHunt(podiumSecond)">
2
-
+
+
+ 塔
+
{{podiumName(podiumSecond)}}
{{podiumSecond.ticketCount || 0}}券
第二名
@@ -69,7 +72,10 @@
@tap="onHunt(podiumFirst)">
1
-
+
+
+ 塔
+
{{podiumName(podiumFirst)}}
{{podiumFirst.ticketCount || 0}}券
第一名
@@ -79,7 +85,10 @@
v-if="podiumThird"
@tap="onHunt(podiumThird)">
3
-
+
+
+ 塔
+
{{podiumName(podiumThird)}}
{{podiumThird.ticketCount || 0}}券
第三名
@@ -94,7 +103,10 @@
v-for="(item, index) in normalList"
:key="item._rankKey">
#{{item._displayRankNo}}
-
+
+
+ 塔
+
{{item.stealth ? '隐身侠' : (item.nickname || '神秘同学')}}
@@ -244,12 +256,9 @@
}
if (reset) this.loading = true
this.listLoading = true
- this.tui.request('/app/planet/home', 'POST', {
+ this.tui.request('/app/planet/rank/page', 'POST', {
userId: this.userId,
regionId: this.regionId,
- nickname: this.nickname,
- avatar: this.avatar,
- college: this.college,
pageNumber: this.pageNum,
pageSize: this.pageSize
}, false, false, true).then((res) => {
@@ -403,6 +412,7 @@
.crown.gold { background: linear-gradient(145deg, #FFF7B8, #FFB84D); }
.crown.silver { background: linear-gradient(145deg, #FFFFFF, #BFD7FF); color: #28415F; }
.crown.bronze { background: linear-gradient(145deg, #FFE0B8, #C87A35); color: #4A2500; }
+ .podium-avatar-wrap { position: relative; z-index: 2; }
.podium-avatar { position: relative; z-index: 2; width: 112rpx; height: 112rpx; border-radius: 38rpx; border: 6rpx solid rgba(255,255,255,0.88); box-shadow: 0 18rpx 36rpx rgba(0,0,0,0.22); background: rgba(255,255,255,0.22); }
.podium-avatar.champion { width: 136rpx; height: 136rpx; border-radius: 46rpx; border-color: #FFE08A; box-shadow: 0 20rpx 46rpx rgba(255,184,77,0.36); animation: championFloat 2.1s ease-in-out infinite; }
@keyframes championFloat { 0%,100%{ transform: translateY(0); } 50%{ transform: translateY(-8rpx); } }
@@ -417,8 +427,12 @@
.rank-list { margin-top: 18rpx; }
.rank-row { margin-top: 16rpx; padding: 22rpx; border-radius: 34rpx; background: rgba(255,255,255,0.82); border: 2rpx solid rgba(255,255,255,0.94); box-shadow: 0 16rpx 36rpx rgba(53,214,166,0.1); display: flex; align-items: center; }
.rank-no { min-width: 70rpx; color: #22B889; font-size: 28rpx; font-weight: 900; }
+ .avatar-wrap { position: relative; flex-shrink: 0; }
.avatar { width: 86rpx; height: 86rpx; border-radius: 28rpx; border: 4rpx solid rgba(255,255,255,0.94); box-shadow: 0 12rpx 24rpx rgba(18,52,47,0.12); flex-shrink: 0; }
.avatar.stealth { opacity: .58; filter: grayscale(100%); }
+ .tower-badge { position: absolute; right: -10rpx; bottom: -8rpx; z-index: 4; min-width: 42rpx; height: 42rpx; line-height: 42rpx; padding: 0 6rpx; border-radius: 14rpx; background: linear-gradient(135deg, #36516F, #7C8DA6); color: #FFFFFF; font-size: 20rpx; font-weight: 900; text-align: center; border: 3rpx solid rgba(255,255,255,0.95); box-shadow: 0 8rpx 18rpx rgba(18,52,47,0.22); }
+ .tower-badge.champion { right: -8rpx; bottom: -4rpx; background: linear-gradient(135deg, #4A2A00, #FFB84D); }
+ .tower-badge.small { right: -12rpx; bottom: -8rpx; min-width: 38rpx; height: 38rpx; line-height: 38rpx; border-radius: 13rpx; font-size: 18rpx; }
.user-main { flex: 1; min-width: 0; margin-left: 18rpx; }
.user-name { display: flex; align-items: center; color: #12342F; font-size: 28rpx; font-weight: 900; }
.user-name text:first-child { max-width: 220rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
diff --git a/package1/planet/ticketLog.vue b/package1/planet/ticketLog.vue
index d10771d..a7dd083 100644
--- a/package1/planet/ticketLog.vue
+++ b/package1/planet/ticketLog.vue
@@ -35,7 +35,7 @@
- 怒
+ 🏴☠️
{{item.fromUserName || '神秘掠夺者'}}
{{raiderDesc(item)}}