feat: configure hot leagues in match center

This commit is contained in:
hajimi
2026-08-02 02:50:40 +08:00
parent 3e95fad23f
commit 163df0cf85
11 changed files with 109 additions and 67 deletions
@@ -9,22 +9,16 @@
</view>
</view>
<MatchCenterTabsPanel @open-worldcup="openWorldCupCenter" />
<MatchCenterTabsPanel />
</view>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import AiAssistantEntry from '@/components/ai-assistant-entry/ai-assistant-entry.vue'
import { getArticleCate } from '@/api/news'
import MatchCenterTabsPanel from './MatchCenterTabsPanel.vue'
const emit = defineEmits<{
(e: 'open-worldcup', payload: { tab: 'schedule'; cid?: number | null }): void
}>()
const statusBarHeight = ref(0)
const worldCupCateId = ref<number | null>(null)
const initLayout = () => {
uni.getSystemInfo({
@@ -39,27 +33,6 @@ const initLayout = () => {
})
}
const fetchWorldCupCateId = async () => {
if (worldCupCateId.value) return worldCupCateId.value
try {
const cateList = await getArticleCate()
const category = (cateList || []).find((item: any) => {
const name = item?.name || item?.label || item?.title
return String(name) === '世界杯'
})
worldCupCateId.value = category?.id || null
} catch (error) {
console.log('获取世界杯分类失败=>', error)
worldCupCateId.value = null
}
return worldCupCateId.value
}
const openWorldCupCenter = async () => {
const cid = await fetchWorldCupCateId()
emit('open-worldcup', { tab: 'schedule', cid })
}
onMounted(() => {
initLayout()
})
@@ -2,10 +2,12 @@
<view class="match-center-tabs">
<view class="content-tabs">
<view v-for="tab in contentTabs" :key="tab.key" class="content-tabs__item"
:class="{ 'content-tabs__item--active': activeTab === tab.key }" @tap="switchContentTab(tab.key)">
:class="{ 'content-tabs__item--active': activeTab === tab.key && !hotLeagueMode }"
@tap="switchContentTab(tab.key)">
<text>{{ tab.label }}</text>
</view>
<view class="content-tabs__item" @tap="emit('open-worldcup')">
<view class="content-tabs__item" :class="{ 'content-tabs__item--active': hotLeagueMode }"
@tap="openHotLeagues">
<text>热门联赛</text>
</view>
</view>
@@ -42,7 +44,7 @@
<view class="league-tabs__inner">
<view class="league-tab" :class="{ 'league-tab--active': currentLeague === '' }"
@tap="switchLeague('')">
<text>热门</text>
<text>{{ hotLeagueMode ? '全部热门' : '全部' }}</text>
</view>
<view v-for="(league, idx) in leagueTabs" :key="idx" class="league-tab"
:class="{ 'league-tab--active': currentLeague === league.league_name }"
@@ -76,9 +78,9 @@
<u-loading mode="circle" />
<text>加载中...</text>
</view>
<view v-if="!scheduleLoading && !matchGroups.length"
class="content-empty">
<u-empty text="暂无赛事" mode="data" />
<view v-if="!scheduleLoading && !matchGroups.length" class="content-empty">
<u-empty :text="hotLeagueMode && !leagueTabs.length ? '暂无后台配置的热门联赛' : '暂无赛事'"
mode="data" />
</view>
<view v-if="endedNoMore && endedList.length" class="content-nomore">
<text>没有更多赛事了</text>
@@ -271,10 +273,6 @@ type MatchCenterTab = 'schedule' | 'live' | 'odds'
type OddsShowType = '' | 'live' | 'today' | 'early'
type OddsPlatformOption = { key: string; label: string }
const emit = defineEmits<{
(e: 'open-worldcup'): void
}>()
const showStandaloneOddsTab = false
const allContentTabs: { key: MatchCenterTab; label: string }[] = [
@@ -298,6 +296,7 @@ const defaultOddsPlatformOptions: OddsPlatformOption[] = [
]
const activeTab = ref<MatchCenterTab>('schedule')
const hotLeagueMode = ref(false)
const sportTabs = ref<any[]>([])
const currentSport = ref(0)
const currentLeague = ref('')
@@ -409,21 +408,25 @@ const filterScheduleItems = (items: any[]) => {
const dateFiltered = selectedDateKey.value
? items.filter((item: any) => getMatchDateKey(item) === selectedDateKey.value)
: items
if (currentLeague.value) return dateFiltered
const hotItems = dateFiltered.filter((item: any) => Number(item?.is_hot) === 1)
return hotItems.length ? hotItems : dateFiltered
if (!hotLeagueMode.value || currentLeague.value) return dateFiltered
const hotLeagueNames = new Set(leagueTabs.value.map((item: any) => String(item?.league_name || '')))
return dateFiltered.filter((item: any) => hotLeagueNames.has(String(item?.league_name || '')))
}
const leagueTabs = computed(() => {
let leagues: any[] = []
if (currentSport.value === 0) {
const merged: any[] = []
Object.keys(allLeagues.value || {}).forEach((key) => {
const items = (allLeagues.value as any)[key]
if (Array.isArray(items)) merged.push(...items)
if (Array.isArray(items)) leagues.push(...items)
})
return merged
} else {
leagues = allLeagues.value[currentSport.value] || []
}
return allLeagues.value[currentSport.value] || []
if (hotLeagueMode.value) {
leagues = leagues.filter((item: any) => Number(item?.is_hot) === 1)
}
return leagues
})
const matchGroups = computed(() => {
@@ -604,13 +607,23 @@ const refreshCurrentTab = () => {
}
const switchContentTab = (tab: MatchCenterTab) => {
if (activeTab.value === tab) return
if (activeTab.value === tab && !hotLeagueMode.value) return
hotLeagueMode.value = false
activeTab.value = tab
if (tab === 'schedule') void fetchMatchList(true)
if (tab === 'live') void fetchLiveCards()
if (tab === 'odds') void fetchOdds()
}
const openHotLeagues = () => {
if (hotLeagueMode.value) return
hotLeagueMode.value = true
activeTab.value = 'schedule'
currentSport.value = 0
currentLeague.value = ''
void fetchMatchList(true)
}
const switchSport = (value: number) => {
if (currentSport.value === value) return
currentSport.value = value
@@ -2,7 +2,7 @@
<view class="match-shell-page">
<WorldCupPanel v-if="currentView === 'worldcup'" :initial-tab="worldcupState.tab"
:initial-cid="worldcupState.cid" @back="showMatchCenter" />
<MatchCenterPanel v-else @open-worldcup="openWorldCup" />
<MatchCenterPanel v-else />
</view>
</template>
@@ -40,14 +40,6 @@ const applyState = () => {
}
}
const openWorldCup = (payload?: { tab?: string; cid?: number | null }) => {
worldcupState.value = {
tab: payload?.tab || 'live',
cid: payload?.cid ?? null
}
currentView.value = 'worldcup'
}
const showMatchCenter = () => {
currentView.value = 'match'
}