From 16073bd9f149f836845a2a0f49471a138640d384 Mon Sep 17 00:00:00 2001 From: hajimi Date: Sun, 2 Aug 2026 01:26:13 +0800 Subject: [PATCH] feat: match home focus games to channels --- uniapp/src/pages/index/index.vue | 96 +++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/uniapp/src/pages/index/index.vue b/uniapp/src/pages/index/index.vue index f1b7914..78a16c4 100644 --- a/uniapp/src/pages/index/index.vue +++ b/uniapp/src/pages/index/index.vue @@ -186,10 +186,16 @@ const pageNo = ref(1) const pageSize = 10 const channelScrollLeft = ref(0) const channelDragging = ref(false) +const FOCUS_MATCH_LIMIT = 2 +const FOCUS_MATCH_CACHE_TTL = 60 * 1000 let channelDragStartX = 0 let channelDragStartScrollLeft = 0 let channelDragMoved = false let channelDragBlockedUntil = 0 +let focusMatchRequestId = 0 +let fallbackFocusMatchData: any = null +let fallbackFocusMatchLoadedAt = 0 +let fallbackFocusMatchPromise: Promise | null = null const primaryChannels = computed(() => { return allChannels.value @@ -274,12 +280,94 @@ const loadChannels = async () => { } } +const getMatchGroups = (data: any) => ({ + live: Array.isArray(data?.live) ? data.live : [], + upcoming: Array.isArray(data?.upcoming) ? data.upcoming : [] +}) + +const normalizeLeagueName = (name: any) => String(name || '').trim().toLowerCase() + +const uniqueMatches = (matches: any[]) => { + const seen = new Set() + return matches.filter((match: any) => { + const key = match?.id + ? `id_${match.id}` + : `${match?.league_name || ''}_${match?.home_team || ''}_${match?.away_team || ''}_${match?.match_time || ''}` + if (seen.has(key)) return false + seen.add(key) + return true + }) +} + +const getCurrentFocusLeagueName = () => { + const channel = allChannels.value[currentChannel.value] + return channel?.specialType === 'category' ? String(channel.name || '').trim() : '' +} + +const getFallbackFocusMatchData = async () => { + const cacheValid = fallbackFocusMatchData + && Date.now() - fallbackFocusMatchLoadedAt < FOCUS_MATCH_CACHE_TTL + if (cacheValid) return fallbackFocusMatchData + if (fallbackFocusMatchPromise) return fallbackFocusMatchPromise + + fallbackFocusMatchPromise = getMatchList() + .then((data: any) => { + fallbackFocusMatchData = data || {} + fallbackFocusMatchLoadedAt = Date.now() + return fallbackFocusMatchData + }) + .finally(() => { + fallbackFocusMatchPromise = null + }) + return fallbackFocusMatchPromise +} + +const getFallbackFocusMatches = (data: any, excludedLeagueName = '') => { + const { live, upcoming } = getMatchGroups(data) + const excludedLeagueKey = normalizeLeagueName(excludedLeagueName) + const matches = uniqueMatches([ + ...live.filter((match: any) => Number(match?.is_hot) === 1), + ...upcoming.filter((match: any) => Number(match?.is_hot) === 1), + ...live, + ...upcoming + ]) + if (!excludedLeagueKey) return matches + return matches.filter((match: any) => normalizeLeagueName(match?.league_name) !== excludedLeagueKey) +} + const loadFocusMatches = async () => { + const requestId = ++focusMatchRequestId + const leagueName = getCurrentFocusLeagueName() + let selectedMatches: any[] = [] + try { - const data = await getMatchList() - const priorityMatches = [...(data?.live || []), ...(data?.upcoming || [])] - focusMatches.value = priorityMatches.slice(0, 2) + if (leagueName) { + try { + const leagueData = await getMatchList({ league_name: leagueName }) + const { live, upcoming } = getMatchGroups(leagueData) + selectedMatches = uniqueMatches([...live, ...upcoming]).slice(0, FOCUS_MATCH_LIMIT) + } catch (error) { + console.log(`获取${leagueName}焦点赛程失败=>`, error) + } + } + + if (selectedMatches.length < FOCUS_MATCH_LIMIT) { + try { + const fallbackData = await getFallbackFocusMatchData() + const selectedIds = new Set(selectedMatches.map((match: any) => String(match?.id || ''))) + const fallbackMatches = getFallbackFocusMatches(fallbackData, leagueName) + .filter((match: any) => !selectedIds.has(String(match?.id || ''))) + selectedMatches = [...selectedMatches, ...fallbackMatches].slice(0, FOCUS_MATCH_LIMIT) + } catch (error) { + if (!selectedMatches.length) throw error + console.log('获取其他热门焦点赛程失败=>', error) + } + } + + if (requestId !== focusMatchRequestId) return + focusMatches.value = selectedMatches } catch (error) { + if (requestId !== focusMatchRequestId) return console.log('获取首页焦点赛程失败=>', error) focusMatches.value = [] } @@ -321,6 +409,7 @@ const switchChannel = (index: number) => { if (Date.now() < channelDragBlockedUntil) return if (currentChannel.value === index) return currentChannel.value = index + loadFocusMatches() reloadFeed() } @@ -496,6 +585,7 @@ const onChannelChanged = (data: any) => { const selectedIndex = findChannelIndexById(selectedChannel?.id) switchChannel(selectedIndex >= 0 ? selectedIndex : 0) } else { + loadFocusMatches() reloadFeed() } }