- 管理端按联赛展示单场,新增赛事/单场流程与列表展开状态保持 - 盘口赔率迁至独立页面,保存按钮仅在有修改时高亮 - API 新增联赛列表与子场查询,按 locale 返回队名并修复编译 - 波胆其它选项与促销标签等 i18n 补齐,文案更易懂
80 lines
2.2 KiB
TypeScript
80 lines
2.2 KiB
TypeScript
import { ref, computed } from 'vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
import api from '../api';
|
|
import type { BannerItem } from '../components/BannerCarousel.vue';
|
|
import { resolveBanners } from '../constants/defaultBanner';
|
|
import { resolveAnnouncements } from '../constants/defaultAnnouncement';
|
|
|
|
export interface PlayerHomeMatch {
|
|
id: string;
|
|
leagueName?: string;
|
|
leagueLogoUrl?: string | null;
|
|
homeTeamName: string;
|
|
awayTeamName: string;
|
|
homeTeamCode?: string;
|
|
awayTeamCode?: string;
|
|
homeTeamLogoUrl?: string | null;
|
|
awayTeamLogoUrl?: string | null;
|
|
startTime: string;
|
|
isHot?: boolean;
|
|
displayOrder?: number;
|
|
}
|
|
|
|
interface HomePayload {
|
|
banners?: BannerItem[];
|
|
announcements?: Array<{ translation?: { title?: string; body?: string } }>;
|
|
ticker?: Array<{ translation?: { title?: string; body?: string } }>;
|
|
notices?: Array<{ translation?: { title?: string; body?: string } }>;
|
|
hotMatches?: PlayerHomeMatch[];
|
|
}
|
|
|
|
const homeRaw = ref<HomePayload | null>(null);
|
|
const loading = ref(false);
|
|
|
|
function collectAnnouncementLines(data: HomePayload | null): string[] {
|
|
if (!data) return [];
|
|
const source =
|
|
data.announcements && data.announcements.length > 0
|
|
? data.announcements
|
|
: [...(data.ticker ?? []), ...(data.notices ?? [])];
|
|
|
|
const lines: string[] = [];
|
|
for (const item of source) {
|
|
const text = item.translation?.title || item.translation?.body;
|
|
if (text) lines.push(text);
|
|
}
|
|
return lines;
|
|
}
|
|
|
|
/** 管理端公共内容 → 玩家端首页/跑马灯(单例,避免重复请求) */
|
|
export function usePlayerHome() {
|
|
const { t } = useI18n();
|
|
|
|
async function load() {
|
|
loading.value = true;
|
|
try {
|
|
const { data } = await api.get('/player/home');
|
|
homeRaw.value = (data.data ?? null) as HomePayload | null;
|
|
} catch {
|
|
homeRaw.value = null;
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
}
|
|
|
|
const banners = computed(() => resolveBanners(homeRaw.value?.banners));
|
|
const announcements = computed(() =>
|
|
resolveAnnouncements(collectAnnouncementLines(homeRaw.value), t('home.announcement_default')),
|
|
);
|
|
const hotMatches = computed(() => homeRaw.value?.hotMatches ?? []);
|
|
|
|
return {
|
|
homeRaw,
|
|
loading,
|
|
load,
|
|
banners,
|
|
announcements,
|
|
hotMatches,
|
|
};
|
|
}
|