diff --git a/src/api/ranking.js b/src/api/ranking.js index 447f9f4..57a40d5 100644 --- a/src/api/ranking.js +++ b/src/api/ranking.js @@ -47,3 +47,17 @@ export const getMyRanking = async (type, dateType) => { throw error } } + +// 获取房间贡献总榜 +export const getRoomContributionTotalRank = async (data) => { + try { + const response = await get( + `/room/contribution/total-rank?startDate=${data.startDate}&endDate=${data.endDate}&size=${data.size}`, + ) + return response + } catch (error) { + console.error('Failed to fetch room contribution total rank:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} diff --git a/src/views/Activities/GulbenFestival/index.vue b/src/views/Activities/GulbenFestival/index.vue index 51cdd62..1fa8556 100644 --- a/src/views/Activities/GulbenFestival/index.vue +++ b/src/views/Activities/GulbenFestival/index.vue @@ -275,7 +275,7 @@ - +
- - *1 - + *1
@@ -965,6 +965,7 @@ :valueIconUrl="coinIcon" :avatar-square="isRoomRankingSection" style="width: 100%" + @click="gotoRankingTarget(rankingTop3[1])" />
@@ -977,6 +978,7 @@ :valueIconUrl="coinIcon" :avatar-square="isRoomRankingSection" style="width: 100%" + @click="gotoRankingTarget(rankingTop3[0])" />
@@ -989,6 +991,7 @@ :valueIconUrl="coinIcon" :avatar-square="isRoomRankingSection" style="width: 100%" + @click="gotoRankingTarget(rankingTop3[2])" />
@@ -1001,6 +1004,7 @@ :imgUrl="imageUrl('RankingItem')" :contentStyle="`padding: 0 8vw`" style="width: 100%; margin: 0 0 5vw; padding: 0" + @click="gotoRankingTarget(listItem)" >
@@ -1284,6 +1288,7 @@ import { useLangStore } from '@/stores/lang' import { getPngUrl } from '@/config/imagePaths.js' import { preloadImages, preloadImagesIdle } from '@/utils/image/imagePreloader.js' import { showError } from '@/utils/toast.js' +import { gotoRoom, viewUserInfo } from '@/utils/appBridge.js' import { handleRewardImageError } from '@/utils/image/imageHandler.js' import { formatRewardDisplay } from '@/utils/rewardFormatter.js' import { @@ -1295,11 +1300,13 @@ import { apiPostCardCombine, apiPostCardDraw, apiPostCardRedeem, + apiPostCardRewardDraw, } from '@/api/activity.js' import { ActTaskList, activityDetail, receiveTickets } from '@/api/lottery' import { getThisWeekRewardsAndGifts } from '@/api/topList.js' import { getMemberProfile } from '@/api/wallet' import { getMyWeekStarRanking, getWeekStarRanking } from '@/api/weeklyStar.js' +import { getRoomContributionTotalRank } from '@/api/ranking.js' import BackgroundLayer from '@/components/BackgroundLayer.vue' import itemCenter from '@/components/itemCenter.vue' import MaskLayer from '@/components/MaskLayer.vue' @@ -1313,6 +1320,11 @@ const coinIcon = new URL('../../../assets/icon/Azizi/coin.png', import.meta.url) const gulbenActivityId = '1001' const kingQueenGiftTemplateId = '1966020557831610370' const weeklyStarPageSize = 10 +const roomRankingParams = { + startDate: '20260518', + endDate: '20260524', + size: 20, +} const isLoading = ref(true) const activeTopTab = ref(pageConfig.modules.tabs.defaultValue) @@ -1325,7 +1337,6 @@ const isCardRedeeming = ref(false) const activeLotteryPoolIndex = ref(0) const activeCollectGameIndex = ref(0) const ruleShow = ref(false) -const activityId = ref(gulbenActivityId) const activityCode = ref(pageConfig.activity.activityCode || '') const activity = ref({}) const Days = ref(0) @@ -1334,15 +1345,15 @@ const Minutes = ref('00') const Seconds = ref('00') const weeklyGifts = ref([ { - giftPhoto: getPngUrl(pageConfig.assetPath, 'redeemRGift'), + giftPhoto: getPngUrl(pageConfig.assetPath, 'redeemR2001'), giftCandy: 0, }, { - giftPhoto: getPngUrl(pageConfig.assetPath, 'redeemSRLamb'), + giftPhoto: getPngUrl(pageConfig.assetPath, 'redeemSR2011'), giftCandy: 0, }, { - giftPhoto: getPngUrl(pageConfig.assetPath, 'redeemSSRGoat'), + giftPhoto: getPngUrl(pageConfig.assetPath, 'redeemSSR2021'), giftCandy: 0, }, ]) @@ -1626,6 +1637,14 @@ const activeLotteryTicketImage = computed( () => activeLotteryPoolMode.value.ticketImage || 'ticketR', ) +const activeLotteryTicketCount = computed(() => + getTicketRemainingCount(activeLotteryPoolMode.value.poolType), +) + +const canLotteryRewardDraw = (drawCount) => { + return activeLotteryTicketCount.value >= drawCount +} + const activeLotteryPrizeRows = computed(() => { const prizes = activeLotteryPrizes.value const rows = [] @@ -1699,15 +1718,15 @@ const cardDrawTicketCount = computed(() => getTicketRemainingCount('CARD')) const maskLayerShow = computed(() => ruleShow.value) const weeklyStarRankingType = computed(() => { + return pageConfig.activity.personalRankActivityType || 'THIS_WEEK' +}) + +const activeRankingLoadKey = computed(() => { if (isRoomRankingSection.value) { - return ( - pageConfig.activity.roomRankActivityType || - pageConfig.activity.personalRankActivityType || - 'THIS_WEEK' - ) + return `room-${roomRankingParams.startDate}-${roomRankingParams.endDate}-${roomRankingParams.size}` } - return pageConfig.activity.personalRankActivityType || 'THIS_WEEK' + return `personal-${weeklyStarRankingType.value}` }) const personalRewardActivityType = computed(() => { @@ -1740,12 +1759,12 @@ const isPersonalRewardSection = computed(() => { const fallbackPersonalRewardTops = computed(() => { const rewardImages = [ - 'redeemRGift', - 'redeemRGoat', - 'redeemRLamp', - 'redeemRLight', - 'redeemRMoon', - 'redeemSRLamb', + 'redeemR2001', + 'redeemR2002', + 'redeemR2003', + 'redeemR2004', + 'redeemR2005', + 'redeemSR2011', ] return Array.from({ length: 3 }, (_, topIndex) => ({ @@ -1804,10 +1823,6 @@ const showTarget = (task) => { return `${task.taskName}(${task.currentValue}/${task.targetValue})` } -const taskActivityId = computed(() => { - return activityId.value || gulbenActivityId -}) - const getActivityDetail = async () => { if (!activityCode.value) { activity.value = {} @@ -1817,19 +1832,17 @@ const getActivityDetail = async () => { const resDetail = await activityDetail(activityCode.value) if (resDetail.status && resDetail.body) { activity.value = resDetail.body - activityId.value = resDetail.body.id || resDetail.body.activityId || activityId.value } else { activity.value = {} } } const getTaskList = async () => { - const activityId = taskActivityId.value - if (!activityId) { + if (!gulbenActivityId) { return } - const resTaskList = await ActTaskList(activityId) + const resTaskList = await ActTaskList(gulbenActivityId) if (resTaskList.status && resTaskList.body) { taskList.value = resTaskList.body } @@ -2002,14 +2015,13 @@ const initData = async () => { } const receiveTaskReward = async (code) => { - const activityId = taskActivityId.value - if (!activityId || !code) { + if (!gulbenActivityId || !code) { return } try { const resReceive = await receiveTickets({ - activityId, + activityId: gulbenActivityId, taskCode: code, }) if (resReceive.status && resReceive.body) { @@ -2101,6 +2113,7 @@ const normalizeWeeklyStarRankingItem = (item = {}, index = 0) => { return { ...item, rank: item.rank || item.ranking || (index === null ? '' : index + 1), + userId: item.userId || item.id || '', userAvatar: item.userAvatar || '', userName: item.userName || item.userNickname || item.nickname || '', amount: item.amount ?? item.quantity ?? item.total ?? 0, @@ -2109,6 +2122,24 @@ const normalizeWeeklyStarRankingItem = (item = {}, index = 0) => { } } +const normalizeRoomContributionRankingItem = (item = {}, index = 0) => { + const profile = item.userProfile || {} + const specialAccount = profile.ownSpecialId?.account || '' + const fallbackAccount = profile.account || '' + + return { + ...item, + rank: item.rank ?? (index === null ? '' : index + 1), + userId: profile.id || item.userId || '', + roomId: profile.inRoomId || '', + userAvatar: profile.userAvatar || profile.roomIcon || '', + userName: profile.userNickname || profile.account || '', + amount: item.totalFormat || item.total || 0, + account: specialAccount || fallbackAccount, + specialAccount, + } +} + const getUserInfo = async () => { if (userInfo.value?.id) { return userInfo.value @@ -2186,8 +2217,62 @@ const getPersonalRanking = async () => { } } -const loadPersonalRankingSection = async () => { - const rankingType = weeklyStarRankingType.value +const getRoomContributionRanking = async () => { + if (rankingLoading.value || !rankingHasMore.value) { + return + } + + rankingLoading.value = true + + try { + const resRanking = await getRoomContributionTotalRank(roomRankingParams) + + if (resRanking.status && resRanking.body) { + const records = Array.isArray(resRanking.body.rankList) ? resRanking.body.rankList : [] + ranking.value = records.map((item, index) => + normalizeRoomContributionRankingItem(item, index), + ) + rankingAdd.value = [] + myRanking.value = resRanking.body.current + ? normalizeRoomContributionRankingItem(resRanking.body.current, null) + : {} + rankingHasMore.value = false + return + } + + ranking.value = [] + rankingAdd.value = [] + myRanking.value = {} + rankingHasMore.value = false + } finally { + rankingLoading.value = false + } +} + +const getCurrentRankingList = async () => { + if (isRoomRankingSection.value) { + await getRoomContributionRanking() + return + } + + await getPersonalRanking() +} + +const gotoRankingTarget = (rankingItem = {}) => { + if (isRoomRankingSection.value) { + console.log('[GulbenFestival] Room Rank click roomId:', rankingItem.roomId, rankingItem) + gotoRoom(rankingItem.roomId) + return + } + + if (isPersonalRankingSection.value) { + console.log('[GulbenFestival] Personal Rank click userId:', rankingItem.userId, rankingItem) + viewUserInfo(rankingItem.userId) + } +} + +const loadRankingSection = async () => { + const rankingType = activeRankingLoadKey.value if (rankingLoaded.value && loadedRankingType.value === rankingType) { observeRankingLoadmore() @@ -2203,10 +2288,14 @@ const loadPersonalRankingSection = async () => { rankingHasMore.value = true try { - const loaders = [getMyPersonalRanking(), getPersonalRanking()] + const loaders = isRoomRankingSection.value + ? [getRoomContributionRanking()] + : [getMyPersonalRanking(), getPersonalRanking()] + if (isPersonalRankingSection.value) { loaders.unshift(getWeeklyGifts()) } + await Promise.all(loaders) observeRankingLoadmore() } catch (error) { @@ -2285,17 +2374,29 @@ const startLotteryAnimation = (resultIndex) => { }) } -// 抽奖接口占位:后续对接接口时在这里替换成 drawOnce / drawTen 的真实请求。 +// 奖励池抽奖:消耗当前奖池奖励票,成功后刷新第一层三种票券数量。 const requestLotteryDraw = async (drawCount) => { + const resRewardDraw = await apiPostCardRewardDraw({ + activityId: gulbenActivityId, + ticketType: activeLotteryPoolMode.value.poolType, + drawCount, + }) + + if (resRewardDraw.status) { + await getCardTicketList() + } else { + return null + } + return { drawCount, prizeIndex: Math.min(3, activeLotteryPrizes.value.length - 1), - results: [], + results: resRewardDraw.body || [], } } const handleLotteryDraw = async (drawCount = 1) => { - if (isLotteryRolling.value) { + if (isLotteryRolling.value || !canLotteryRewardDraw(drawCount)) { return } @@ -2303,8 +2404,13 @@ const handleLotteryDraw = async (drawCount = 1) => { try { const drawResult = await requestLotteryDraw(drawCount) + if (!drawResult) { + return + } const resultIndex = getLotteryResultIndex(drawResult) await startLotteryAnimation(resultIndex) + } catch (error) { + showError(error.errorMsg) } finally { isLotteryRolling.value = false } @@ -2425,7 +2531,7 @@ watch( isRankingSection, (enabled) => { if (enabled) { - loadPersonalRankingSection() + loadRankingSection() } else if (rankingObserver) { rankingObserver.disconnect() } @@ -2433,6 +2539,12 @@ watch( { immediate: true }, ) +watch(activeRankingLoadKey, () => { + if (isRankingSection.value) { + loadRankingSection() + } +}) + watch( isPersonalRewardSection, (enabled) => { @@ -2456,7 +2568,7 @@ onMounted(() => { rankingHasMore.value && !rankingLoading.value ) { - getPersonalRanking() + getCurrentRankingList() } }) }) diff --git a/src/views/Activities/GulbenFestival/page.config.js b/src/views/Activities/GulbenFestival/page.config.js index f57ac4c..adedc01 100644 --- a/src/views/Activities/GulbenFestival/page.config.js +++ b/src/views/Activities/GulbenFestival/page.config.js @@ -19,24 +19,21 @@ export const pageConfig = { background: [ 'barrageBg', 'cardBackBg', - 'draw5BtBg', 'draw1Bt', + 'draw5BtBg', 'GameDrawBtBg', 'Gameticket', 'gameTitleR', 'gameTitleSR', 'gameTitleSSR', 'giftBg', + 'helpBt', 'leftBt', 'lotteryPrizeActiveBg', 'lotteryPrizeBg', 'moduleActiveBg', 'moduleBg', - 'redeemRGift', - 'redeemRGoat', - 'redeemRLamp', - 'redeemRLight', - 'redeemRMoon', + 'RankingItem', 'redeemR2001', 'redeemR2002', 'redeemR2003', @@ -45,13 +42,11 @@ export const pageConfig = { 'redeemSR2011', 'redeemSR2012', 'redeemSR2013', - 'redeemSRLamb', - 'redeemSRScroll', - 'redeemSRTurkey', 'redeemSSR2021', 'redeemSSR2022', - 'redeemSSRGoat', - 'redeemSSRLamb', + 'RewardTop1', + 'RewardTop2', + 'RewardTop3', 'ruleActivity', 'ruleInfoBg', 'taskBtGo', @@ -62,16 +57,25 @@ export const pageConfig = { 'ticketR', 'ticketSR', 'ticketSSR', - 'RankingItem', - 'RewardTop1', - 'RewardTop2', - 'RewardTop3', 'top1', 'top2', 'top3', 'vip1', + 'vip2', + 'vip3', + 'vip4', + 'vip5', + 'vip6', 'userLevel1Bg', + 'userLevel2Bg', + 'userLevel3Bg', + 'userLevel4Bg', + 'userLevel5Bg', 'wealthLevel1Bg', + 'wealthLevel2Bg', + 'wealthLevel3Bg', + 'wealthLevel4Bg', + 'wealthLevel5Bg', ], },