From 887d205f6523e6cd88efbefeb0871d026e65e627 Mon Sep 17 00:00:00 2001 From: yuchenglong Date: Fri, 16 Jan 2026 18:02:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=BA=E5=A4=9A=E4=B8=AA=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=92=8CAPI=E6=B7=BB=E5=8A=A0=E7=94=A8=E6=88=B7=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E7=8A=B6=E6=80=81=E6=A3=80=E6=9F=A5=EF=BC=8C=E7=A1=AE?= =?UTF-8?q?=E4=BF=9D=E5=8F=AA=E6=9C=89=E5=9C=A8=E7=94=A8=E6=88=B7=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E5=90=8E=E6=89=8D=E8=83=BD=E6=9F=A5=E8=AF=A2=E5=92=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=94=B6=E8=97=8F=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/(tabs)/favorite.tsx | 8 +++++ app/(tabs)/finished.tsx | 30 +++++++++++------- app/(tabs)/index.tsx | 32 +++++++++++-------- app/(tabs)/live.tsx | 30 +++++++++++------- app/(tabs)/upcoming.tsx | 33 ++++++++++++-------- components/live-detail/live-score-header.tsx | 7 +++++ components/match-detail/score-header.tsx | 7 +++++ lib/api.ts | 10 ++++++ 8 files changed, 107 insertions(+), 50 deletions(-) diff --git a/app/(tabs)/favorite.tsx b/app/(tabs)/favorite.tsx index a24bed1..dfb9410 100644 --- a/app/(tabs)/favorite.tsx +++ b/app/(tabs)/favorite.tsx @@ -5,6 +5,7 @@ import { IconSymbol, IconSymbolName } from "@/components/ui/icon-symbol"; import { Colors } from "@/constants/theme"; import { useTheme } from "@/context/ThemeContext"; import { fetchFavorites, removeFavorite } from "@/lib/api"; +import { storage } from "@/lib/storage"; import { FavoriteItem, Match } from "@/types/api"; import { Image } from "expo-image"; import { useRouter } from "expo-router"; @@ -67,6 +68,13 @@ export default function FavoriteScreen() { if (loading) return; setLoading(true); try { + const token = await storage.getAccessToken(); + if (!token) { + setFavorites([]); + setHasMore(false); + return; + } + const currentPage = isRefresh ? 1 : page; const res = await fetchFavorites(activeTab, currentPage); if (isRefresh) { diff --git a/app/(tabs)/finished.tsx b/app/(tabs)/finished.tsx index 4bdcad4..2770ccc 100644 --- a/app/(tabs)/finished.tsx +++ b/app/(tabs)/finished.tsx @@ -15,6 +15,7 @@ import { fetchSports, fetchTodayMatches, } from "@/lib/api"; +import { storage } from "@/lib/storage"; import { League, Match, Sport } from "@/types/api"; import React, { useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -316,18 +317,23 @@ export default function HomeScreen() { deviceTimeZone ); - // 直接传递 match.id 查询是否收藏,并更新列表状态 - const listWithFavStatus = await Promise.all( - list.map(async (m) => { - try { - const favRes = await checkFavorite("match", m.id); - return { ...m, fav: favRes.isFavorite }; - } catch (error) { - console.error(`Check favorite failed for match ${m.id}:`, error); - return m; - } - }) - ); + const token = await storage.getAccessToken(); + let listWithFavStatus = list; + + if (token) { + // 直接传递 match.id 查询是否收藏,并更新列表状态 + listWithFavStatus = await Promise.all( + list.map(async (m) => { + try { + const favRes = await checkFavorite("match", m.id); + return { ...m, fav: favRes.isFavorite }; + } catch (error) { + console.error(`Check favorite failed for match ${m.id}:`, error); + return m; + } + }) + ); + } // 将收藏的比赛置顶 const sortedList = [...listWithFavStatus].sort((a, b) => { diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 97dbea0..b948451 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -15,6 +15,7 @@ import { fetchSports, fetchTodayMatches, } from "@/lib/api"; +import { storage } from "@/lib/storage"; import { League, Match, Sport } from "@/types/api"; import React, { useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -316,19 +317,24 @@ export default function HomeScreen() { deviceTimeZone ); - // 直接传递 match.id 查询是否收藏,并更新列表状态 - const listWithFavStatus = await Promise.all( - list.map(async (m) => { - try { - // 查询比赛是否已被收藏 - const favRes = await checkFavorite("match", m.id); - return { ...m, fav: favRes.isFavorite }; - } catch (error) { - console.error(`Check favorite failed for match ${m.id}:`, error); - return m; - } - }) - ); + const token = await storage.getAccessToken(); + let listWithFavStatus = list; + + if (token) { + // 直接传递 match.id 查询是否收藏,并更新列表状态 + listWithFavStatus = await Promise.all( + list.map(async (m) => { + try { + // 查询比赛是否已被收藏 + const favRes = await checkFavorite("match", m.id); + return { ...m, fav: favRes.isFavorite }; + } catch (error) { + console.error(`Check favorite failed for match ${m.id}:`, error); + return m; + } + }) + ); + } // 将收藏的比赛置顶 const sortedList = [...listWithFavStatus].sort((a, b) => { diff --git a/app/(tabs)/live.tsx b/app/(tabs)/live.tsx index f4abec3..5fbd11f 100644 --- a/app/(tabs)/live.tsx +++ b/app/(tabs)/live.tsx @@ -6,6 +6,7 @@ import { Colors } from "@/constants/theme"; import { useAppState } from "@/context/AppStateContext"; import { useTheme } from "@/context/ThemeContext"; import { checkFavorite, fetchLiveScore } from "@/lib/api"; +import { storage } from "@/lib/storage"; import { LiveScoreMatch, Match } from "@/types/api"; import { useRouter } from "expo-router"; import React, { useEffect, useState } from "react"; @@ -66,18 +67,23 @@ export default function LiveScreen() { isLive: true, })); - // 直接传递 match.id 查询是否收藏,并更新列表状态 - const listWithFavStatus = await Promise.all( - converted.map(async (m) => { - try { - const favRes = await checkFavorite("match", m.id); - return { ...m, fav: favRes.isFavorite }; - } catch (error) { - console.error(`Check favorite failed for match ${m.id}:`, error); - return m; - } - }) - ); + const token = await storage.getAccessToken(); + let listWithFavStatus = converted; + + if (token) { + // 直接传递 match.id 查询是否收藏,并更新列表状态 + listWithFavStatus = await Promise.all( + converted.map(async (m) => { + try { + const favRes = await checkFavorite("match", m.id); + return { ...m, fav: favRes.isFavorite }; + } catch (error) { + console.error(`Check favorite failed for match ${m.id}:`, error); + return m; + } + }) + ); + } // 将收藏的比赛置顶 const sortedList = [...listWithFavStatus].sort((a, b) => { diff --git a/app/(tabs)/upcoming.tsx b/app/(tabs)/upcoming.tsx index 5f98023..4d063ae 100644 --- a/app/(tabs)/upcoming.tsx +++ b/app/(tabs)/upcoming.tsx @@ -13,6 +13,7 @@ import { fetchSports, fetchUpcomingMatches, } from "@/lib/api"; +import { storage } from "@/lib/storage"; import { League, Sport, UpcomingMatch } from "@/types/api"; import React, { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -261,7 +262,8 @@ export default function HomeScreen() { }; const loadMatches = async () => { - if (selectedSportId === null) return; + const token = await storage.getAccessToken(); + if (selectedSportId === null || !token) return; setLoading(true); try { @@ -271,18 +273,23 @@ export default function HomeScreen() { selectedLeagueKey || "" ); - // 直接传递 match.id 查询是否收藏,并更新列表状态 - const listWithFavStatus = await Promise.all( - list.map(async (m) => { - try { - const favRes = await checkFavorite("match", m.id.toString()); - return { ...m, fav: favRes.isFavorite }; - } catch (error) { - console.error(`Check favorite failed for match ${m.id}:`, error); - return m; - } - }) - ); + const token = await storage.getAccessToken(); + let listWithFavStatus = list; + + if (token) { + // 直接传递 match.id 查询是否收藏,并更新列表状态 + listWithFavStatus = await Promise.all( + list.map(async (m) => { + try { + const favRes = await checkFavorite("match", m.id.toString()); + return { ...m, fav: favRes.isFavorite }; + } catch (error) { + console.error(`Check favorite failed for match ${m.id}:`, error); + return m; + } + }) + ); + } // 将收藏的比赛置顶 const sortedList = [...listWithFavStatus].sort((a, b) => { diff --git a/components/live-detail/live-score-header.tsx b/components/live-detail/live-score-header.tsx index 604eca6..f028d5f 100644 --- a/components/live-detail/live-score-header.tsx +++ b/components/live-detail/live-score-header.tsx @@ -1,6 +1,7 @@ import { ThemedText } from "@/components/themed-text"; import { IconSymbol } from "@/components/ui/icon-symbol"; import { addFavorite, checkFavorite, removeFavorite } from "@/lib/api"; +import { storage } from "@/lib/storage"; import { LiveScoreMatch } from "@/types/api"; import { LinearGradient } from "expo-linear-gradient"; import { useRouter } from "expo-router"; @@ -46,6 +47,8 @@ export function LiveScoreHeader({ match, topInset }: LiveScoreHeaderProps) { // 检查收藏状态 React.useEffect(() => { const loadFavStatus = async () => { + const token = await storage.getAccessToken(); + if (!token) return; try { const res = await checkFavorite("match", match.event_key.toString()); setIsFav(res.isFavorite); @@ -59,6 +62,8 @@ export function LiveScoreHeader({ match, topInset }: LiveScoreHeaderProps) { // 检查主队收藏状态 React.useEffect(() => { const loadHomeFav = async () => { + const token = await storage.getAccessToken(); + if (!token) return; try { const res = await checkFavorite("team", match.home_team_key.toString()); setIsHomeFav(res.isFavorite); @@ -74,6 +79,8 @@ export function LiveScoreHeader({ match, topInset }: LiveScoreHeaderProps) { // 检查客队收藏状态 React.useEffect(() => { const loadAwayFav = async () => { + const token = await storage.getAccessToken(); + if (!token) return; try { const res = await checkFavorite("team", match.away_team_key.toString()); setIsAwayFav(res.isFavorite); diff --git a/components/match-detail/score-header.tsx b/components/match-detail/score-header.tsx index f7faa75..9e6c4c9 100644 --- a/components/match-detail/score-header.tsx +++ b/components/match-detail/score-header.tsx @@ -1,6 +1,7 @@ import { ThemedText } from "@/components/themed-text"; import { IconSymbol } from "@/components/ui/icon-symbol"; import { addFavorite, checkFavorite, removeFavorite } from "@/lib/api"; +import { storage } from "@/lib/storage"; import { MatchDetailData } from "@/types/api"; import { LinearGradient } from "expo-linear-gradient"; import { useRouter } from "expo-router"; @@ -30,6 +31,8 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) { // 检查比赛收藏状态 React.useEffect(() => { const loadFavStatus = async () => { + const token = await storage.getAccessToken(); + if (!token) return; try { const res = await checkFavorite("match", match.eventKey.toString()); setIsFav(res.isFavorite); @@ -45,6 +48,8 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) { // 检查主队收藏状态 React.useEffect(() => { const loadHomeFav = async () => { + const token = await storage.getAccessToken(); + if (!token) return; try { const res = await checkFavorite("team", match.homeTeamKey.toString()); setIsHomeFav(res.isFavorite); @@ -60,6 +65,8 @@ export function ScoreHeader({ data, isDark, topInset }: ScoreHeaderProps) { // 检查客队收藏状态 React.useEffect(() => { const loadAwayFav = async () => { + const token = await storage.getAccessToken(); + if (!token) return; try { const res = await checkFavorite("team", match.awayTeamKey.toString()); setIsAwayFav(res.isFavorite); diff --git a/lib/api.ts b/lib/api.ts index 61b99de..c1d67b9 100644 --- a/lib/api.ts +++ b/lib/api.ts @@ -431,6 +431,11 @@ export const fetchUserProfile = async (): Promise => { export const addFavorite = async (request: FavoriteRequest): Promise => { try { + const token = await storage.getAccessToken(); + if (!token) { + // throw new Error("Please login first"); + return; + } // console.log("Adding favorite with request:", request); const response = await apiClient.post>( API_ENDPOINTS.FAVORITES, @@ -451,6 +456,11 @@ export const removeFavorite = async (request: { typeId: string; }): Promise => { try { + const token = await storage.getAccessToken(); + if (!token) { + // throw new Error("Please login first"); + return; + } console.log("Removing favorite with request:", request); const response = await apiClient.delete>( API_ENDPOINTS.FAVORITES,