Files
thebet365/apps/player/src/components/LeagueAccordionItem.vue
Mars bc5b8e0950 perf(assets): Player/Admin 静态图改用 WebP,vs 保留 PNG
Player 端 banner/bg/card/h5bg 等改为 webp 并移除旧 png;Admin 登录背景改 webp;vs 对阵图仍用 png。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-12 11:16:51 +08:00

190 lines
4.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { computed } from 'vue';
import MatchBetCard from './MatchBetCard.vue';
import saishiImg from '../assets/images/saishi.webp';
import cardBg from '../assets/images/card-bg.webp';
const matchCardBg = `url(${cardBg})`;
const props = defineProps<{
leagueId: string;
leagueName: string;
leagueLogoUrl?: string | null;
expanded: boolean;
matches: {
id: string;
homeTeamName: string;
awayTeamName: string;
homeTeamCode?: string;
awayTeamCode?: string;
homeTeamLogoUrl?: string | null;
awayTeamLogoUrl?: string | null;
startTime: string;
bettingOpen?: boolean;
matchPhase?: import('../utils/matchPhase').MatchPhase;
score?: {
htHome: number;
htAway: number;
ftHome: number;
ftAway: number;
} | null;
}[];
}>();
const emit = defineEmits<{ toggle: []; bet: [id: string] }>();
const totalCount = computed(() => props.matches.length);
const liveCount = computed(() => props.matches.filter(m => m.matchPhase === 'closed_pending').length);
const openCount = computed(() => props.matches.filter(m => m.matchPhase === 'open').length);
</script>
<template>
<section class="league-block">
<button type="button" class="league-row" :aria-expanded="expanded" @click="emit('toggle')">
<span class="toggle-icon" :class="{ open: expanded }" aria-hidden="true">
<span class="toggle-mark">{{ expanded ? '' : '+' }}</span>
</span>
<span class="league-info">
<span class="league-title">*{{ leagueName }}</span>
<span class="league-stats">
<span class="stat-item">{{ totalCount }}</span>
<span v-if="liveCount > 0" class="stat-item stat-live">{{ liveCount }}进行中</span>
<span v-if="openCount > 0" class="stat-item stat-open">{{ openCount }}待开赛</span>
</span>
</span>
<img
:src="leagueLogoUrl || saishiImg"
alt=""
class="league-saishi"
/>
</button>
<div v-show="expanded" class="match-panel">
<div class="match-grid">
<MatchBetCard
v-for="match in matches"
:key="match.id"
:match="match"
@bet="emit('bet', $event)"
/>
</div>
</div>
</section>
</template>
<style scoped>
.league-block {
position: relative;
isolation: isolate;
margin-bottom: 12px;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg-card);
overflow: hidden;
}
.league-row {
position: relative;
z-index: 1;
width: 100%;
display: flex;
align-items: center;
gap: 10px;
padding: 12px 16px;
background: none;
border: none;
border-radius: 0;
text-align: left;
cursor: pointer;
}
.league-row::before {
content: '';
position: absolute;
inset: 0;
background: v-bind(matchCardBg) center / 100% 100% no-repeat;
opacity: 0.25;
z-index: -1;
pointer-events: none;
}
.league-row:active {
opacity: 0.92;
}
.toggle-icon {
flex-shrink: 0;
width: 26px;
height: 26px;
border-radius: 50%;
background: #141414;
border: 1px solid var(--border-gold-soft);
display: flex;
align-items: center;
justify-content: center;
}
.toggle-mark {
color: var(--primary-light);
font-size: 17px;
font-weight: 900;
line-height: 1;
margin-top: -1px;
}
.league-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.league-title {
font-size: 13px;
font-weight: 800;
color: #fff;
line-height: 1.35;
min-width: 0;
}
.league-stats {
display: flex;
align-items: center;
gap: 6px;
font-size: 11px;
color: #ccc;
line-height: 1.2;
}
.stat-live {
color: #3db865;
}
.stat-open {
color: #c8a84e;
}
.league-saishi {
flex-shrink: 0;
height: 44px;
width: auto;
max-width: 40px;
object-fit: contain;
margin-left: 4px;
padding-left: 10px;
border-left: 1px solid #2a2a2a;
}
.match-panel {
padding: 10px 0 4px;
}
.match-grid {
display: grid;
grid-template-columns: repeat(1, minmax(0, 1fr));
gap: 8px;
padding: 0 4px;
}
</style>