deploy: auto commit repo-root changes 2026-07-03 22:33:26

This commit is contained in:
hajimi
2026-07-03 22:33:26 +08:00
parent 311c6c6224
commit 5a888a730e
82 changed files with 223 additions and 102 deletions
@@ -1,15 +1,8 @@
<template>
<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"
/>
<WorldCupPanel v-if="currentView === 'worldcup'" :initial-tab="worldcupState.tab"
:initial-cid="worldcupState.cid" @back="showMatchCenter" />
<MatchCenterPanel v-else @open-worldcup="openWorldCup" />
</view>
</template>
@@ -31,7 +24,7 @@ const props = withDefaults(defineProps<{
const currentView = ref<ShellView>('worldcup')
const worldcupState = ref<{ tab: string; cid: number | null }>({
tab: 'schedule',
tab: 'live',
cid: null
})
@@ -35,12 +35,26 @@
<view v-if="liveCards.length" class="worldcup-live-grid">
<view v-for="live in liveCards" :key="`live-${live.live_id}`" class="worldcup-live-card"
@tap="openWorldCupLiveCard(live)">
<view class="worldcup-live-card__player-wrap">
<video :id="buildWorldCupLiveVideoId(live)" class="worldcup-live-card__player"
:src="resolveWorldCupLivePlayUrl(live)" :poster="live.home_icon || live.away_icon || ''"
:autoplay="true" :muted="true" :controls="!hideLiveCardControlsOnAndroid"
<view class="worldcup-live-card__player-wrap"
:class="{ 'worldcup-live-card__player-wrap--poster': useLiveCardPosterMode }">
<video v-if="!useLiveCardPosterMode" :id="buildWorldCupLiveVideoId(live)"
class="worldcup-live-card__player" :src="resolveWorldCupLivePlayUrl(live)"
:poster="live.home_icon || live.away_icon || ''" :autoplay="true" :muted="true"
:controls="!hideLiveCardControlsOnAndroid"
:show-play-btn="!hideLiveCardControlsOnAndroid"
:show-fullscreen-btn="!hideLiveCardControlsOnAndroid" object-fit="cover" />
<view v-else class="worldcup-live-card__poster">
<image v-if="resolveWorldCupLivePoster(live)" class="worldcup-live-card__poster-image"
:src="resolveWorldCupLivePoster(live)" mode="aspectFill" />
<view v-else class="worldcup-live-card__poster-empty">
<text>{{ livePosterTitle(live) }}</text>
</view>
<view class="worldcup-live-card__poster-shade"></view>
<view class="worldcup-live-card__play">
<view class="worldcup-live-card__play-icon"></view>
</view>
<text class="worldcup-live-card__status">{{ liveStatusText(live) }}</text>
</view>
</view>
<view class="worldcup-live-card__teams">
@@ -57,10 +71,12 @@
<text class="worldcup-live-card__anchor-name">{{ liveAnchorName(live) }}</text>
</view>
<view class="worldcup-live-card__stats">
<text class="worldcup-live-card__stat">观看 {{ formatLiveCount(live.room_view_count) }}</text>
<text class="worldcup-live-card__stat">关注 {{ formatLiveCount(live.room_focus_count) }}</text>
<text class="worldcup-live-card__stat">观看 {{ formatLiveCount(live.room_view_count)
}}</text>
<text class="worldcup-live-card__stat">关注 {{ formatLiveCount(live.room_focus_count)
}}</text>
</view>
<text class="worldcup-live-card__notice">公告 {{ liveRoomNotice(live) }}</text>
<text class="worldcup-live-card__notice">{{ liveRoomNotice(live) }}</text>
</view>
</view>
@@ -260,7 +276,7 @@ const props = withDefaults(defineProps<{
initialTab?: string
initialCid?: number | null
}>(), {
initialTab: 'schedule',
initialTab: 'live',
initialCid: null
})
@@ -286,13 +302,14 @@ const bracketTabs: { key: BracketTabKey; label: string }[] = [
{ key: '决赛', label: '决赛' }
]
const activeTab = ref<MainTab>('schedule')
const activeTab = ref<MainTab>('live')
const rankingMode = ref<RankingMode>('standings')
const scheduleSort = ref<ScheduleSort>('time')
const activeBracketTab = ref<BracketTabKey>(bracketTabs[0].key)
const scheduleScrollIntoView = ref('')
const statusBarHeight = ref(0)
const hideLiveCardControlsOnAndroid = ref(false)
const useLiveCardPosterMode = ref(false)
const liveCards = ref<WorldCupLiveCardItem[]>([])
const liveCardsLoaded = ref(false)
@@ -449,6 +466,15 @@ const liveRoomNotice = (live: WorldCupLiveCardItem) => {
return normalizeLiveText(live.room_notice) || '暂无公告'
}
const resolveWorldCupLivePoster = (live: WorldCupLiveCardItem) => {
return liveAnchorAvatar(live) || normalizeLiveText(live.home_icon) || normalizeLiveText(live.away_icon)
}
const livePosterTitle = (live: WorldCupLiveCardItem) => {
const teams = [normalizeLiveText(live.home_team), normalizeLiveText(live.away_team)].filter(Boolean)
return teams.length ? teams.join(' VS ') : liveLineTitle(live)
}
const formatLiveCount = (value: unknown) => {
const count = Number(value || 0)
if (!Number.isFinite(count) || count <= 0) return '0'
@@ -484,6 +510,10 @@ const resolveWorldCupLivePlayUrl = (live: WorldCupLiveCardItem) => {
return urls.find((url) => /\.(m3u8|mp4|flv)(\?|$)/i.test(url)) || urls[0] || ''
}
const resolveWorldCupLiveSourceUrl = (live: WorldCupLiveCardItem) => {
return normalizeLiveText(live.source_url) || resolveWorldCupLivePlayUrl(live)
}
const liveStatusText = (live: WorldCupLiveCardItem) => {
if ((live.status ?? 0) === 1) {
return normalizeLiveText(live.current_minute) || '进行中'
@@ -558,7 +588,12 @@ const activeBracketPairs = computed(() => {
const initLayout = () => {
const info = uni.getSystemInfoSync()
hideLiveCardControlsOnAndroid.value = String(info.platform || '').toLowerCase() === 'android'
const isAndroidPlatform = String(info.platform || '').toLowerCase() === 'android'
hideLiveCardControlsOnAndroid.value = isAndroidPlatform
useLiveCardPosterMode.value = false
// #ifdef APP-PLUS
useLiveCardPosterMode.value = isAndroidPlatform
// #endif
// #ifdef APP-PLUS || MP
statusBarHeight.value = info.statusBarHeight || 44
// #endif
@@ -661,12 +696,23 @@ const goMatchDetail = (match: any) => {
uni.navigateTo({ url: `/pages/match_detail/match_detail?id=${id}` })
}
const openWorldCupLiveWebview = (url: string) => {
uni.navigateTo({ url: `/pages/webview/webview?url=${encodeURIComponent(url)}` })
}
const openWorldCupLiveCard = (live: WorldCupLiveCardItem) => {
if (!resolveWorldCupLivePlayUrl(live)) {
const playUrl = resolveWorldCupLivePlayUrl(live)
const sourceUrl = resolveWorldCupLiveSourceUrl(live)
if (!playUrl && !sourceUrl) {
uni.showToast({ title: '暂无直播链接', icon: 'none' })
return
}
if (useLiveCardPosterMode.value) {
openWorldCupLiveWebview(sourceUrl || playUrl)
return
}
try {
const videoContext = uni.createVideoContext(buildWorldCupLiveVideoId(live))
videoContext?.requestFullScreen?.({
@@ -963,9 +1009,9 @@ onMounted(() => {
flex: 1;
height: 0;
min-height: 0;
padding: 0 14rpx 18rpx;
padding-bottom: calc(140rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(140rpx + env(safe-area-inset-bottom));
padding: 0 14rpx 0;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
box-sizing: border-box;
background: #fff;
}
@@ -1047,12 +1093,94 @@ onMounted(() => {
background: #0f172a;
}
.worldcup-live-card__player-wrap--poster {
background: linear-gradient(135deg, #0f172a 0%, #1e40af 100%);
}
.worldcup-live-card__player {
width: 100%;
height: 100%;
display: block;
}
.worldcup-live-card__poster {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
.worldcup-live-card__poster-image {
width: 100%;
height: 100%;
display: block;
}
.worldcup-live-card__poster-empty {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 18rpx;
box-sizing: border-box;
text-align: center;
color: rgba(255, 255, 255, 0.86);
font-size: 22rpx;
font-weight: 600;
line-height: 1.35;
}
.worldcup-live-card__poster-shade {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(15, 23, 42, 0.28);
}
.worldcup-live-card__play {
position: absolute;
left: 50%;
top: 50%;
width: 58rpx;
height: 58rpx;
border-radius: 50%;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.24);
border: 2rpx solid rgba(255, 255, 255, 0.78);
}
.worldcup-live-card__play-icon {
width: 0;
height: 0;
margin-left: 4rpx;
border-top: 12rpx solid transparent;
border-bottom: 12rpx solid transparent;
border-left: 18rpx solid #ffffff;
}
.worldcup-live-card__status {
position: absolute;
right: 12rpx;
top: 12rpx;
max-width: 128rpx;
height: 34rpx;
line-height: 34rpx;
padding: 0 12rpx;
border-radius: 999rpx;
background: rgba(15, 23, 42, 0.58);
color: #ffffff;
font-size: 20rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.worldcup-live-card__top {
display: flex;
align-items: center;