feat(player): 新增桌面端 UI 与响应式双端路由架构
- 将原移动端页面重命名为 Mobile*,新增 22 个 Desktop* 视图与 DesktopShell 布局体系 - 路由入口改为 Wrapper 视图,通过 useViewport(≥1024px)自动切换移动/桌面端 - 新增投注单面板、盘口弹层、联赛侧栏、数据表格等桌面组件及独立样式令牌 - 扩展 betSlip store、串关筛选、冠军盘、Toast/悬浮信箱等交互与三语 i18n - 公告/消息 Hub 拆分移动与桌面实现;API 投注/钱包/充值记录支持 pageSize 分页
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import api from '../../api';
|
||||
import OutrightEventSection, {
|
||||
type OutrightEvent,
|
||||
type OutrightSelection,
|
||||
@@ -10,7 +9,7 @@ import OutrightBetModal, { type OutrightPick } from './OutrightBetModal.vue';
|
||||
import { useAuthStore } from '../../stores/auth';
|
||||
import emptyMatchesImg from '../../assets/images/empty-matches.svg';
|
||||
import GoldSpinner from '../../components/GoldSpinner.vue';
|
||||
import { useOnLocaleChange } from '../../composables/useOnLocaleChange';
|
||||
import { useOutrightEvents } from '../../composables/useOutrightEvents';
|
||||
|
||||
const props = defineProps<{
|
||||
activated?: boolean;
|
||||
@@ -18,14 +17,12 @@ const props = defineProps<{
|
||||
|
||||
const { t } = useI18n();
|
||||
const auth = useAuthStore();
|
||||
const { loading, loadError, events, load } = useOutrightEvents();
|
||||
|
||||
function goLogin() {
|
||||
auth.showLoginPrompt('/bet');
|
||||
}
|
||||
|
||||
const loading = ref(true);
|
||||
const loadError = ref('');
|
||||
const events = ref<OutrightEvent[]>([]);
|
||||
const expanded = ref<Set<string>>(new Set());
|
||||
const modalOpen = ref(false);
|
||||
const activePick = ref<OutrightPick | null>(null);
|
||||
@@ -37,7 +34,6 @@ const totalSelections = computed(() =>
|
||||
|
||||
function syncExpandedAfterLoad() {
|
||||
const ids = events.value.map((e) => e.id);
|
||||
// 只保留仍然存在的 id,且最多保留 1 个
|
||||
const kept = [...expanded.value].filter((id) => ids.includes(id));
|
||||
if (kept.length > 0) {
|
||||
expanded.value = new Set([kept[0]]);
|
||||
@@ -50,59 +46,18 @@ function syncExpandedAfterLoad() {
|
||||
}
|
||||
}
|
||||
|
||||
async function load() {
|
||||
const hadData = events.value.length > 0;
|
||||
if (!hadData) loading.value = true;
|
||||
loadError.value = '';
|
||||
try {
|
||||
const { data } = await api.get('/player/outrights');
|
||||
const list = (data?.data ?? []) as OutrightEvent[];
|
||||
const fresh = list.filter((e) => e.selections?.length > 0);
|
||||
if (!hadData) {
|
||||
events.value = fresh;
|
||||
syncExpandedAfterLoad();
|
||||
} else {
|
||||
mergeOddsOnly(fresh);
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
if (!hadData) events.value = [];
|
||||
const err = e as { response?: { status?: number; data?: { error?: string } } };
|
||||
if (err.response?.status === 403) {
|
||||
loadError.value = t('bet.outright_player_only');
|
||||
} else {
|
||||
loadError.value = err.response?.data?.error ?? t('bet.outright_load_failed');
|
||||
}
|
||||
} finally {
|
||||
if (!hadData) loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function mergeOddsOnly(fresh: OutrightEvent[]) {
|
||||
const freshMap = new Map<string, OutrightEvent>();
|
||||
for (const e of fresh) freshMap.set(e.id, e);
|
||||
|
||||
for (const event of events.value) {
|
||||
const freshEvent = freshMap.get(event.id);
|
||||
if (!freshEvent) continue;
|
||||
const selMap = new Map<string, OutrightSelection>();
|
||||
for (const s of freshEvent.selections) selMap.set(s.id, s);
|
||||
for (const sel of event.selections) {
|
||||
const fs = selMap.get(sel.id);
|
||||
if (fs) {
|
||||
sel.odds = fs.odds;
|
||||
sel.oddsVersion = fs.oddsVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useOnLocaleChange(load);
|
||||
watch(
|
||||
() => events.value.length,
|
||||
(len, prev) => {
|
||||
if (len > 0 && prev === 0) syncExpandedAfterLoad();
|
||||
},
|
||||
);
|
||||
|
||||
// 每次切回优胜冠军 Tab 时静默刷新赔率
|
||||
watch(
|
||||
() => props.activated,
|
||||
(active) => {
|
||||
if (active && events.value.length > 0) void load();
|
||||
if (active && events.value.length > 0) void load({ silent: true });
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user