feat(player): 完善 H5 投注端与 API 演示数据

- 球赛/串关/优胜冠军、赛事详情、历史投注与个人资料编辑
- 固定顶栏、公告与底栏,仅内容区滚动
- 底部导航与站点 favicon 使用 logo,登录页精简
- API 种子、冠军盘与历史注单增强

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-02 17:18:11 +08:00
parent 7af2e418c3
commit b5dca1bfb1
75 changed files with 7077 additions and 384 deletions

View File

@@ -0,0 +1,132 @@
<script setup lang="ts">
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
import { teamFlagUrl } from '../utils/teamFlag';
const props = defineProps<{
match: {
id: string;
homeTeamName: string;
awayTeamName: string;
homeTeamCode?: string;
awayTeamCode?: string;
startTime: string;
};
}>();
const emit = defineEmits<{ bet: [id: string] }>();
const { t, locale } = useI18n();
const kickoff = computed(() => {
const d = new Date(props.match.startTime);
return d.toLocaleString(locale.value, {
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
hour12: true,
});
});
const homeFlag = computed(() => teamFlagUrl(props.match.homeTeamCode, props.match.homeTeamName));
const awayFlag = computed(() => teamFlagUrl(props.match.awayTeamCode, props.match.awayTeamName));
</script>
<template>
<article class="match-card">
<div class="kickoff">{{ kickoff }}</div>
<div class="teams-stack">
<div class="side">
<img v-if="homeFlag" :src="homeFlag" alt="" class="flag" />
<span class="name">{{ match.homeTeamName }}</span>
</div>
<span class="vs">VS</span>
<div class="side">
<img v-if="awayFlag" :src="awayFlag" alt="" class="flag" />
<span class="name">{{ match.awayTeamName }}</span>
</div>
</div>
<button type="button" class="bet-btn btn-gold-outline" @click="emit('bet', match.id)">
{{ t('bet.place_bet_short') }}
</button>
</article>
</template>
<style scoped>
.match-card {
background: #1a1a1a;
border: 1px solid #2a2a2a;
border-radius: 6px;
padding: 6px 4px 5px;
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
min-width: 0;
}
.kickoff {
width: 100%;
text-align: center;
font-size: 9px;
line-height: 1.25;
color: var(--text-muted);
font-weight: 600;
}
.teams-stack {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
}
.side {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
min-width: 0;
}
.flag {
width: 22px;
height: 15px;
object-fit: cover;
border-radius: 2px;
box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.06);
}
.name {
width: 100%;
font-size: 10px;
font-weight: 800;
color: var(--primary-light);
line-height: 1.2;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 0 2px;
}
.vs {
font-size: 9px;
font-weight: 800;
color: var(--text-muted);
line-height: 1;
}
.bet-btn {
width: 100%;
margin-top: 2px;
padding: 3px 2px;
border-radius: 4px;
font-size: 10px;
letter-spacing: 0.04em;
line-height: 1.2;
}
</style>