feat(admin,api,player): 优胜赛配置、赛事管理重构与玩家端投注体验优化
管理端拆分赛事/优胜赛 Tab,新增联赛优胜赔率面板(批量、排序、外侧删除);统一 list-chrome 工具栏对齐与列表页布局;Dashboard 失败重试、Users 操作下拉、小屏侧栏等体验修复。 API 扩展优胜赛与赛事目录接口,完善投注与钱包查询;玩家端重构赛事卡片、串关面板、注单/钱包页,新增注单详情、下注成功动画与下拉刷新。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -16,6 +16,8 @@ import CorrectScoreConfirmModal, {
|
||||
import { isCorrectScoreMarket, parseScoreCode } from '../utils/correctScoreLayout';
|
||||
import { useOnLocaleChange } from '../composables/useOnLocaleChange';
|
||||
import vsImg from '../assets/images/vs.png';
|
||||
import GoldSpinner from '../components/GoldSpinner.vue';
|
||||
import BetSuccessOverlay from '../components/BetSuccessOverlay.vue';
|
||||
import cardBg from '../assets/images/卡片.png';
|
||||
|
||||
const heroCardBg = `url(${cardBg})`;
|
||||
@@ -65,6 +67,7 @@ const expandedKey = ref<string | null>(null);
|
||||
const correctScoreStakes = ref<Record<string, number>>({});
|
||||
const placingCs = ref(false);
|
||||
const csMessage = ref('');
|
||||
const showCsSuccess = ref(false);
|
||||
const csConfirmOpen = ref(false);
|
||||
const csConfirmMarketType = ref<string | null>(null);
|
||||
const marketsByType = computed(() => {
|
||||
@@ -188,6 +191,7 @@ async function placeCorrectScoreBets(marketType: string) {
|
||||
const next = { ...correctScoreStakes.value };
|
||||
for (const sel of entries) delete next[sel.id];
|
||||
correctScoreStakes.value = next;
|
||||
showCsSuccess.value = true;
|
||||
} catch (e: unknown) {
|
||||
csMessage.value =
|
||||
(e as { response?: { data?: { error?: string } } })?.response?.data?.error ||
|
||||
@@ -270,11 +274,11 @@ function hasSlipPickForMarket(marketType: string) {
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div v-if="loading" class="state">{{ t('bet.loading') }}</div>
|
||||
|
||||
<div v-if="loading" class="state">
|
||||
<GoldSpinner :size="36" />
|
||||
</div>
|
||||
<template v-else-if="match">
|
||||
<section class="match-hero">
|
||||
<p class="kickoff">{{ kickoff }}</p>
|
||||
<div class="hero-teams">
|
||||
<!-- home -->
|
||||
<div class="hero-team">
|
||||
@@ -325,6 +329,8 @@ function hasSlipPickForMarket(marketType: string) {
|
||||
<span class="hero-name">{{ match.awayTeamName }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="kickoff">{{ t('bet.kickoff_time') }}{{ kickoff }}</p>
|
||||
</section>
|
||||
|
||||
<section class="markets-section">
|
||||
@@ -391,6 +397,8 @@ function hasSlipPickForMarket(marketType: string) {
|
||||
</section>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<BetSuccessOverlay :show="showCsSuccess" @done="showCsSuccess = false" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@@ -405,6 +413,12 @@ function hasSlipPickForMarket(marketType: string) {
|
||||
justify-content: space-between;
|
||||
padding: 4px 12px 8px;
|
||||
gap: 8px;
|
||||
position: sticky;
|
||||
top: -12px;
|
||||
z-index: 50;
|
||||
margin-top: -12px;
|
||||
background: rgba(0, 0, 0, 0.55);
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
@@ -467,8 +481,9 @@ function hasSlipPickForMarket(marketType: string) {
|
||||
z-index: 1;
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
text-align: center;
|
||||
margin-bottom: 14px;
|
||||
text-align: left;
|
||||
margin-top: 10px;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.hero-teams {
|
||||
@@ -615,13 +630,32 @@ function hasSlipPickForMarket(marketType: string) {
|
||||
}
|
||||
|
||||
.market-list {
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
background: #111;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.market-group + .market-group {
|
||||
border-top: 1px solid #252525;
|
||||
.market-group {
|
||||
border-radius: 8px;
|
||||
border: 1px solid #252525;
|
||||
background: linear-gradient(180deg, #1a1a1a 0%, #151515 100%);
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.35);
|
||||
transition: border-color 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.market-group.open {
|
||||
border-color: rgba(212, 175, 55, 0.25);
|
||||
box-shadow: 0 4px 16px rgba(212, 175, 55, 0.08);
|
||||
}
|
||||
|
||||
.market-group :deep(.row) {
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.market-group.open :deep(.row) {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.market-foot-btn {
|
||||
|
||||
Reference in New Issue
Block a user