import { ThemedText } from "@/components/themed-text"; import { ThemedView } from "@/components/themed-view"; import { fetchOdds } from "@/lib/api"; import { LiveScoreMatch, OddsItem } from "@/types/api"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { ActivityIndicator, StyleSheet, View } from "react-native"; interface OddsCardProps { match: LiveScoreMatch; isDark: boolean; sportId: number; } export function OddsCard({ match, isDark, sportId }: OddsCardProps) { const { t } = useTranslation(); const [odds, setOdds] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { loadOdds(); // 设置每 30 秒自动更新一次 const interval = setInterval(loadOdds, 30000); return () => clearInterval(interval); }, [match.event_key, sportId]); const loadOdds = async () => { try { const data = await fetchOdds(sportId, match.event_key); const matchOdds = data[match.event_key.toString()]; if (matchOdds && matchOdds.data && matchOdds.data.length > 0) { // 优先选择包含常见赔率项的博彩公司,这里暂取第一个 setOdds(matchOdds.data[0]); } } catch (error) { console.error("Load odds error:", error); } finally { setLoading(false); } }; // 提取队名缩写或前3个字母 const homeAbbr = match.event_home_team?.substring(0, 3).toUpperCase() || "HOME"; const awayAbbr = match.event_away_team?.substring(0, 3).toUpperCase() || "AWAY"; // 获取显示的盘口和赔率 const renderOddsContent = () => { if (loading && !odds) { return ( ); } // 尝试寻找亚洲盘口 (AH) 或者 主客和 (1X2) // 这里为了演示演示,优先寻找 AH 相关数据 const ahKey1 = Object.keys(odds || {}).find( (k) => k.startsWith("ah") && k.endsWith("_1") ); const ahKey2 = ahKey1 ? ahKey1.replace("_1", "_2") : null; if (odds && ahKey1 && ahKey2) { const handicapValue = ahKey1.replace("ah", "").replace("_1", ""); return ( {homeAbbr} {odds[ahKey1] || "-"} HDP {handicapValue} {awayAbbr} {odds[ahKey2] || "-"} ); } // 如果没有 AH,显示 1X2 if (odds && odds.odd_1 && odds.odd_2) { return ( {homeAbbr} {odds.odd_1} DRAW {odds.odd_x || "-"} {awayAbbr} {odds.odd_2} ); } return ( {t("detail.empty_odds")} ); }; return ( {t("detail.odds_card.title")} {odds?.odd_bookmakers || "bet365"} {renderOddsContent()} {t("detail.odds_card.disclaimer")} ); } const styles = StyleSheet.create({ container: { margin: 16, borderRadius: 20, padding: 20, backgroundColor: "#FFF", marginBottom: 16, shadowColor: "#000", shadowOpacity: 0.05, shadowRadius: 10, elevation: 2, }, darkContainer: { backgroundColor: "#1E1E20", }, header: { flexDirection: "row", justifyContent: "space-between", alignItems: "center", marginBottom: 20, }, title: { fontSize: 18, fontWeight: "500", }, badge: { backgroundColor: "#1E4D40", paddingHorizontal: 12, paddingVertical: 6, borderRadius: 8, }, badgeText: { color: "#FFF", fontSize: 14, fontWeight: "bold", }, row: { flexDirection: "row", gap: 10, }, item: { flex: 1, flexDirection: "row", justifyContent: "space-between", alignItems: "center", backgroundColor: "#F8F8F8", borderRadius: 10, paddingHorizontal: 12, paddingVertical: 14, }, darkItem: { backgroundColor: "rgba(255,255,255,0.05)", }, team: { fontSize: 14, fontWeight: "500", }, odds: { fontSize: 14, fontWeight: "700", color: "#FF9800", }, disclaimer: { fontSize: 12, color: "#BBB", marginTop: 20, textAlign: "center", }, loadingContainer: { height: 60, justifyContent: "center", alignItems: "center", }, emptyContainer: { height: 60, justifyContent: "center", alignItems: "center", }, });