feat(player): theme-3 移动端/PC 双端拆分与桌面投注工作台
新增 DesktopShell 及桌面端首页、赛事、钱包、记录等页面,原 H5 视图迁移至 Mobile* 并由路由 wrapper 按视口切换。补齐右侧投注单栏、赔率快捷浮层、联赛/赛事侧栏、串关与定位能力;桌面下注成功改为全局 Toast,修复侧栏成功遮罩被裁剪与底部汇总黑底。同步悬浮客服、公告卡片、三语 i18n、桌面样式体系,以及 API 赛事与 shared 包相关调整。
This commit is contained in:
68
apps/player/src/composables/useOutrightEvents.ts
Normal file
68
apps/player/src/composables/useOutrightEvents.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import api from '../api';
|
||||
import type { OutrightEvent } from '../components/outright/OutrightEventSection.vue';
|
||||
import type { OutrightSelection } from '../components/outright/OutrightEventSection.vue';
|
||||
import { useOnLocaleChange } from './useOnLocaleChange';
|
||||
|
||||
export function useOutrightEvents() {
|
||||
const { t } = useI18n();
|
||||
const loading = ref(true);
|
||||
const loadError = ref('');
|
||||
const events = ref<OutrightEvent[]>([]);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function load(options?: { silent?: boolean }) {
|
||||
const hadData = events.value.length > 0;
|
||||
if (!hadData && !options?.silent) 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;
|
||||
} 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 && !options?.silent) loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
useOnLocaleChange(load);
|
||||
|
||||
return {
|
||||
loading,
|
||||
loadError,
|
||||
events,
|
||||
load,
|
||||
mergeOddsOnly,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user