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,72 @@
<script setup lang="ts">
import { computed } from 'vue';
import { teamFlagUrl } from '../../utils/teamFlag';
const props = defineProps<{
teamCode: string;
teamName: string;
odds: string;
}>();
const emit = defineEmits<{ pick: [] }>();
const flag = computed(() => teamFlagUrl(props.teamCode, props.teamName));
function formatOdds(odds: string) {
const n = parseFloat(odds);
return Number.isFinite(n) ? n.toFixed(2) : odds;
}
</script>
<template>
<button type="button" class="option-card" @click="emit('pick')">
<img v-if="flag" :src="flag" alt="" class="flag" />
<span class="name">{{ teamName }}</span>
<span class="odds">[ {{ formatOdds(odds) }} ]</span>
</button>
</template>
<style scoped>
.option-card {
width: 100%;
min-width: 0;
padding: 8px 4px 6px;
border-radius: 6px;
background: #1c1c1c;
border: 1px solid #333;
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
text-align: center;
}
.option-card:active {
background: #252525;
border-color: var(--border-gold-soft);
}
.flag {
width: 28px;
height: 19px;
object-fit: cover;
border-radius: 2px;
}
.name {
font-size: 11px;
font-weight: 800;
color: var(--primary-light);
line-height: 1.2;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.odds {
font-size: 11px;
font-weight: 800;
color: var(--primary-light);
}
</style>