From 64db9f52ae23de83ea75dabb5abb63b50cf8232c Mon Sep 17 00:00:00 2001 From: XingQue Date: Wed, 1 Jul 2026 17:40:57 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=8E=92=E8=A1=8C=E6=A6=9C=E5=A5=96?= =?UTF-8?q?=E5=8A=B1=E5=B1=95=E7=A4=BA=E3=80=81=E4=BF=B1=E4=B9=90=E9=83=A8?= =?UTF-8?q?=E5=88=86=E6=A6=9C=E5=88=87=E6=8D=A2=E4=B8=8E=E6=89=8B=E5=8A=A8?= =?UTF-8?q?=E9=A2=86=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 集团总榜/本俱乐部榜切换,奖金仅在本俱乐部榜行内展示 - 待领取底栏与规则说明,对接 phbjlxx/phbjllq/phbjlphb Co-authored-by: Cursor --- pages/fighter-rank/fighter-rank.js | 160 ++++++++++++++++++++++++--- pages/fighter-rank/fighter-rank.wxml | 30 ++++- pages/fighter-rank/fighter-rank.wxss | 98 +++++++++++++++- 3 files changed, 271 insertions(+), 17 deletions(-) diff --git a/pages/fighter-rank/fighter-rank.js b/pages/fighter-rank/fighter-rank.js index 452b687..4d3d78d 100644 --- a/pages/fighter-rank/fighter-rank.js +++ b/pages/fighter-rank/fighter-rank.js @@ -9,6 +9,7 @@ import { CLUB_ID } from '../../config/club-config.js' const IS_XZJ = CLUB_ID === 'xzj' const RANK_API = IS_XZJ ? '/yonghu/xzjphbhqsj' : '/yonghu/phbhqsj' +const CLOSED_DATES = ['昨日', '上周', '上月'] const ROLE_LIST = [ { key: 'dashou', label: '接单员' }, @@ -145,6 +146,8 @@ Page({ dateList: DATE_LIST, currentRole: 'dashou', currentDate: '今日', + fanwei: 'jituan', + myClubId: CLUB_ID || 'xq', roleMeta: ROLE_META.dashou, sortLabel: '分红总额', isLoading: true, @@ -153,6 +156,9 @@ Page({ restList: [], isEmpty: false, defaultAvatar: '', + rewardInfo: null, + showClaimBar: false, + claimLoading: false, }, onLoad(options) { @@ -239,6 +245,60 @@ Page({ this.fetchRankList() }, + onScopeTap(e) { + const fanwei = e.currentTarget.dataset.fanwei + if (!fanwei || fanwei === this.data.fanwei) return + this.setData({ fanwei }) + this.fetchRankList() + }, + + onShowRules() { + const r = this.data.rewardInfo + if (!r || !r.tiers || !r.tiers.length) { + wx.showToast({ title: '暂无奖励规则', icon: 'none' }) + return + } + const lines = r.tiers.map((t) => { + const label = t.label || `第${t.rank_from}${t.rank_to > t.rank_from ? '-' + t.rank_to : ''}名` + return `${label}:¥${t.amount}` + }) + const tip = r.period_status === 'open' ? '(本期进行中,结束后可领取)' : '' + wx.showModal({ + title: `${r.title || '排行榜奖励'}${tip}`, + content: [ + `俱乐部:${r.club_id || this.data.myClubId}`, + `排序:${r.sort_label || ''}`, + ...lines, + r.description || '', + ].filter(Boolean).join('\n'), + showCancel: false, + }) + }, + + async onClaimTap() { + const claim = this.data.rewardInfo && this.data.rewardInfo.my_claim + if (!claim || !claim.claim_id || this.data.claimLoading) return + this.setData({ claimLoading: true }) + try { + const res = await request({ + url: '/yonghu/phbjllq', + method: 'POST', + data: { claim_id: claim.claim_id }, + }) + const body = res?.data || {} + if (body.code === 200) { + wx.showToast({ title: `已领取 ¥${claim.amount}`, icon: 'success' }) + await this.fetchRewardInfo() + } else { + wx.showToast({ title: body.msg || '领取失败', icon: 'none' }) + } + } catch (e) { + wx.showToast({ title: '领取失败', icon: 'none' }) + } finally { + this.setData({ claimLoading: false }) + } + }, + onRefreshTap() { this.fetchRankList() }, @@ -267,8 +327,8 @@ Page({ value: m.type === 'money' ? this.formatMoney(v) : this.formatInt(v), } }) - const sortRaw = raw[meta.sortField] - const mainType = meta.mainType || 'money' + const sortRaw = raw[meta.sortField] ?? raw.metric_value + const mainType = raw.metric_label ? (Number.isInteger(Number(sortRaw)) && !String(sortRaw).includes('.') ? 'int' : 'money') : (meta.mainType || 'money') const mainValue = mainType === 'money' ? this.formatMoney(sortRaw) : this.formatInt(sortRaw) @@ -277,30 +337,101 @@ Page({ uid, nicheng, avatar, + clubName: raw.club_name || raw.club_id || '', + rewardAmount: raw.reward_amount || 0, mainType, mainPrefix: mainType === 'money' ? '¥' : '', mainValue, - mainLabel: meta.sortLabel, + mainLabel: raw.metric_label || meta.sortLabel, metrics, } }, - async fetchRankList() { - this.setData({ isLoading: true, isEmpty: false }) + applyRewardToList(list, rewardInfo, fanwei) { + if (fanwei !== 'club') return list + if (!rewardInfo || !rewardInfo.rank_rewards) return list + const map = rewardInfo.rank_rewards + return list.map((item) => ({ + ...item, + rewardAmount: map[item.mingci] || item.rewardAmount || 0, + })) + }, + + async fetchRewardInfo() { try { const res = await request({ - url: RANK_API, + url: '/yonghu/phbjlxx', method: 'POST', - data: { shenfen: this.data.currentRole, riqi: this.data.currentDate }, + data: { + shenfen: this.data.currentRole, + riqi: this.data.currentDate, + club_id: this.data.myClubId, + }, }) const body = res?.data || {} - const ok = body.code === 200 || body.code === 0 - let list = ok && body.data - ? (body.data.list || body.data.paihang_list || body.data.rank_list || []) - : [] + if (body.code !== 200 || !body.data) return + const rewardInfo = body.data + const showClaimBar = !!(rewardInfo.my_claim && rewardInfo.my_claim.status === 'pending') + const { rankList, fanwei } = this.data + const merged = this.applyRewardToList(rankList, rewardInfo, fanwei) + this.setData({ + rewardInfo, + showClaimBar, + rankList: merged, + topThree: merged.slice(0, 3), + restList: merged.slice(3), + }) + } catch (e) { + console.warn('奖励信息加载失败', e) + } + }, + + async fetchRankList() { + this.setData({ isLoading: true, isEmpty: false, showClaimBar: false }) + try { + const { currentRole, currentDate, fanwei, myClubId } = this.data + let list = [] + let rewardFromRank = null + + if (fanwei === 'club') { + const res = await request({ + url: '/yonghu/phbjlphb', + method: 'POST', + data: { + shenfen: currentRole, + riqi: currentDate, + fanwei: 'club', + club_id: myClubId, + }, + }) + const body = res?.data || {} + if (body.code === 200 && body.data) { + list = body.data.list || [] + rewardFromRank = body.data.reward || null + if (body.data.sort_label) { + this.setData({ sortLabel: body.data.sort_label }) + } + } + } else { + const res = await request({ + url: RANK_API, + method: 'POST', + data: { shenfen: currentRole, riqi: currentDate }, + }) + const body = res?.data || {} + const ok = body.code === 200 || body.code === 0 + list = ok && body.data + ? (body.data.list || body.data.paihang_list || body.data.rank_list || []) + : [] + } + if (!Array.isArray(list)) list = [] - const role = this.data.currentRole - const normalized = list.slice(0, 50).map((item, i) => this.normalizeItem(item, i, role)) + const role = currentRole + let normalized = list.slice(0, 50).map((item, i) => this.normalizeItem(item, i, role)) + if (rewardFromRank) { + normalized = this.applyRewardToList(normalized, rewardFromRank, 'club') + this.setData({ rewardInfo: rewardFromRank, showClaimBar: !!(rewardFromRank.my_claim && rewardFromRank.my_claim.status === 'pending') }) + } this.setData({ rankList: normalized, topThree: normalized.slice(0, 3), @@ -309,6 +440,9 @@ Page({ isLoading: false, }) this.ensureAvatars() + if (!rewardFromRank) { + await this.fetchRewardInfo() + } } catch (e) { console.error('排行榜加载失败', e) wx.showToast({ title: '加载失败', icon: 'none' }) diff --git a/pages/fighter-rank/fighter-rank.wxml b/pages/fighter-rank/fighter-rank.wxml index e486bee..efc6fb2 100644 --- a/pages/fighter-rank/fighter-rank.wxml +++ b/pages/fighter-rank/fighter-rank.wxml @@ -25,6 +25,22 @@ >{{item.label}} {{currentDate}} · 按{{sortLabel}} · TOP50 + + + 集团总榜 + 本俱乐部榜 + + + + + 🏆 {{rewardInfo.title || '排行榜奖励'}} + 俱乐部 {{rewardInfo.club_id || myClubId}} + 进行中 · 结束后可领 + 待领取 ¥{{rewardInfo.my_claim.amount}} + 已领取 ¥{{rewardInfo.my_claimed.amount}} + + 规则 › + @@ -54,6 +70,7 @@ {{topThree[1].mainPrefix}}{{topThree[1].mainValue}} {{topThree[1].mainLabel}} + 奖 ¥{{topThree[1].rewardAmount}} {{m.label}} {{m.value}} @@ -72,6 +89,7 @@ {{topThree[0].mainPrefix}}{{topThree[0].mainValue}} {{topThree[0].mainLabel}} + 奖 ¥{{topThree[0].rewardAmount}} {{m.label}} {{m.value}} @@ -90,6 +108,7 @@ {{topThree[2].mainPrefix}}{{topThree[2].mainValue}} {{topThree[2].mainLabel}} + 奖 ¥{{topThree[2].rewardAmount}} {{m.label}} {{m.value}} @@ -114,7 +133,7 @@ {{item.nicheng}} - ID {{item.uid}} + ID {{item.uid}} · {{item.clubName}} {{m.label}} {{m.value}} @@ -122,6 +141,7 @@ {{item.mainPrefix}}{{item.mainValue}} {{item.mainLabel}} + 奖¥{{item.rewardAmount}} @@ -129,6 +149,14 @@ + + + + 🎉 第{{rewardInfo.my_claim.mingci}}名 · 待领取 + ¥{{rewardInfo.my_claim.amount}} + + + diff --git a/pages/fighter-rank/fighter-rank.wxss b/pages/fighter-rank/fighter-rank.wxss index 232f63d..d661947 100644 --- a/pages/fighter-rank/fighter-rank.wxss +++ b/pages/fighter-rank/fighter-rank.wxss @@ -107,8 +107,102 @@ page { } .sort-tip { + display: block; font-size: 22rpx; - color: rgba(255,255,255,0.3); + color: rgba(255,255,255,0.45); + margin-top: 8rpx; +} + +.scope-row { + display: flex; + gap: 12rpx; + margin-top: 16rpx; +} + +.scope-chip { + padding: 10rpx 24rpx; + border-radius: 999rpx; + font-size: 24rpx; + color: rgba(255,255,255,0.65); + background: rgba(20, 26, 40, 0.75); + border: 1rpx solid rgba(255,255,255,0.12); +} + +.scope-chip.on { + color: #fff; + background: rgba(255, 193, 7, 0.35); + border-color: rgba(255, 193, 7, 0.5); +} + +.reward-banner { + margin-top: 16rpx; + padding: 20rpx 24rpx; + border-radius: 16rpx; + background: linear-gradient(135deg, rgba(255,193,7,0.2), rgba(107,163,247,0.15)); + border: 1rpx solid rgba(255,193,7,0.35); + display: flex; + align-items: center; + justify-content: space-between; +} + +.reward-banner-main { + display: flex; + flex-direction: column; + gap: 6rpx; +} + +.reward-tag { font-size: 28rpx; font-weight: 600; color: #ffd666; } +.reward-club { font-size: 22rpx; color: rgba(255,255,255,0.7); } +.reward-status { font-size: 22rpx; color: rgba(255,255,255,0.55); } +.reward-status.pending { color: #52c41a; font-weight: 600; } +.reward-status.claimed { color: #8c8c8c; } +.reward-link { font-size: 24rpx; color: #8EB8FF; } + +.p-reward { + display: block; + margin-top: 6rpx; + font-size: 22rpx; + color: #ffd666; + font-weight: 600; +} + +.lc-reward { + display: block; + margin-top: 4rpx; + font-size: 22rpx; + color: #ffd666; +} + +.claim-bar { + position: fixed; + left: 0; right: 0; bottom: 0; + z-index: 100; + padding: 20rpx 28rpx calc(20rpx + env(safe-area-inset-bottom)); + background: linear-gradient(180deg, rgba(13,17,23,0.2), rgba(13,17,23,0.95)); + display: flex; + align-items: center; + justify-content: space-between; + border-top: 1rpx solid rgba(255,193,7,0.3); +} + +.claim-text { display: flex; flex-direction: column; } +.claim-title { font-size: 26rpx; color: #fff; } +.claim-amount { font-size: 36rpx; font-weight: 700; color: #ffd666; } + +.claim-btn { + margin: 0; + padding: 0 40rpx; + height: 72rpx; + line-height: 72rpx; + font-size: 28rpx; + background: linear-gradient(135deg, #ffc107, #ff9800); + color: #1a1a1a; + border-radius: 999rpx; + border: none; +} + +.bottom-gap { + height: 160rpx; } /* ========== 状态 ========== */ @@ -463,5 +557,3 @@ page { font-size: 20rpx; color: rgba(255,255,255,0.32); } - -.bottom-gap { height: 48rpx; }