feat(player+api): 桌面端钱包/注单栏重构,首页快速下注与移动端体验优化

桌面端:
- 新增 DesktopWalletPageHeader 统一钱包子导航,移除重复大标题
- 重构我的余额页布局(居中窄卡片 + 余额/统计/账户设置)
- 新增 DesktopBetSlipRail 可折叠注单侧栏,优化 BetSlipPanel 交互
- 首页 upcoming 赛事卡片支持胜平负/让球/大小球快速下注
- 优化 DesktopShell 布局、3D 轮播、各账户/消息/充值页面样式

移动端:
- 重构 MobileWalletView 钱包页 UI
- 修复 MarketSelectionsPanel 下注区黑色背景问题
- 新增 PageBackButton 与 useSmartBack 智能返回逻辑
- 优化公告/消息/个人中心等详情页导航

API:
- listUpcomingPublished 支持 includeMarkets,返回首页卡片所需核心玩法
This commit is contained in:
2026-06-30 16:11:27 +08:00
parent ef5b9416cc
commit 7f563326d8
73 changed files with 2866 additions and 1552 deletions

View File

@@ -1,4 +1,4 @@
<script setup lang="ts">
<script setup lang="ts">
import { computed, onMounted, watch } from 'vue';
import { useRoute, RouterView } from 'vue-router';
import { useI18n } from 'vue-i18n';
@@ -7,14 +7,16 @@ import DesktopOddsBetPopover from './DesktopOddsBetPopover.vue';
import SportsCategoryBar from './SportsCategoryBar.vue';
import LeagueSidebar from './LeagueSidebar.vue';
import MatchSidebar from './MatchSidebar.vue';
import BetSlipPanel from './BetSlipPanel.vue';
import DesktopBetSlipRail from './DesktopBetSlipRail.vue';
import FloatingMailbox from '../FloatingMailbox.vue';
import { usePlayerHome } from '../../composables/usePlayerHome';
import { useAuthStore } from '../../stores/auth';
import { useBetSlipStore } from '../../stores/betSlip';
const route = useRoute();
const { locale } = useI18n();
const auth = useAuthStore();
const slip = useBetSlipStore();
const { load: loadPlayerHome } = usePlayerHome();
const layoutMode = computed<'betting' | 'account' | 'hub' | 'marketing'>(() => {
@@ -26,7 +28,7 @@ const layoutMode = computed<'betting' | 'account' | 'hub' | 'marketing'>(() => {
p === '/bets' ||
p.startsWith('/bets/') ||
p.startsWith('/wallet') ||
p === '/profile/cashbacks'
p.startsWith('/profile')
) {
return 'account';
}
@@ -44,6 +46,13 @@ const isBettingDetail = computed(
() => route.path.startsWith('/match/') || route.path.startsWith('/outright/'),
);
const showBetSlipRail = computed(() => {
const p = route.path;
if (p === '/bets' || p.startsWith('/bets/')) return false;
if (p.startsWith('/wallet') || p.startsWith('/profile')) return false;
return true;
});
onMounted(() => {
void loadPlayerHome(true);
});
@@ -61,11 +70,18 @@ watch(
</script>
<template>
<div class="desktop-shell">
<div
class="desktop-shell"
:class="{
'betslip-collapsed': showBetSlipRail && !slip.panelExpanded,
'betslip-hidden': !showBetSlipRail,
}"
>
<header class="desktop-header-wrap">
<DesktopTopNav />
</header>
<div class="desktop-body">
<div class="desktop-main-container">
<!-- Betting Layout -->
<div v-if="layoutMode === 'betting'" class="desktop-layout-betting-wrap">
@@ -85,9 +101,6 @@ watch(
<component v-else :is="Component" :key="viewRoute.fullPath" />
</RouterView>
</main>
<aside class="desktop-betting-right">
<BetSlipPanel />
</aside>
</div>
</div>
@@ -114,7 +127,7 @@ watch(
</div>
<!-- Marketing/Single Column Layout -->
<div v-else class="desktop-layout-marketing">
<div v-else class="desktop-layout-marketing no-scrollbar">
<main class="desktop-marketing-content">
<RouterView v-slot="{ Component, route: viewRoute }">
<KeepAlive v-if="viewRoute.meta.keepAlive" :max="10">
@@ -125,6 +138,8 @@ watch(
</main>
</div>
</div>
<DesktopBetSlipRail v-if="showBetSlipRail" />
</div>
<FloatingMailbox />
<DesktopOddsBetPopover />
</div>