From 19f17145cc8dda59d3a360d939018681a7428d3f Mon Sep 17 00:00:00 2001 From: shangfangjian Date: Sun, 20 Sep 2026 20:29:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=A6=96=E9=A1=B5=E6=9C=AA=E5=BC=80?= =?UTF-8?q?=E8=B5=9B=E9=BB=98=E8=AE=A4=E5=B1=95=E7=A4=BA=E6=9C=AA=E6=9D=A5?= =?UTF-8?q?=203=20=E5=A4=A9,=E6=94=AF=E6=8C=81=E5=B1=95=E5=BC=80=E6=9B=B4?= =?UTF-8?q?=E5=A4=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 showAllUpcoming 状态,默认 false,仅渲染未来 3 天(今/明/后天)的未开赛 - 列表头显示「未来3天 N / 共 M 场」计数 - 「显示后续 N 场未开赛」按钮:展开全部已加载的未开赛 - 展开后提供「收起,仅显示未来 3 天」回退 - 切换联赛/状态时自动重置为 3 天视图 - 空态区分「未来3天暂无比赛」与「暂无赛程」 - 已完赛/全部状态不受影响,展示全部 Co-Authored-By: new-provider/LongCat-2.0 <> --- frontend/src/pages/Matches.tsx | 80 ++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 9 deletions(-) diff --git a/frontend/src/pages/Matches.tsx b/frontend/src/pages/Matches.tsx index 925afc4..7ac436a 100644 --- a/frontend/src/pages/Matches.tsx +++ b/frontend/src/pages/Matches.tsx @@ -194,6 +194,7 @@ export default function Matches() { const [nextCursor, setNextCursor] = useState(null) const [loadingMore, setLoadingMore] = useState(false) const [loading, setLoading] = useState(false) + const [showAllUpcoming, setShowAllUpcoming] = useState(false) // 默认仅展示未来 3 天;true 展开全部 const [predictingId, setPredictingId] = useState(null) const [prediction, setPrediction] = useState(null) const [predictionFor, setPredictionFor] = useState(null) @@ -223,6 +224,7 @@ export default function Matches() { const seq = ++loadSeq.current setLoading(true) setLoadingMore(false) + setShowAllUpcoming(false) // 切换筛选重置为「未来 3 天」视图 setError(null) try { const params = new URLSearchParams({ league, status, limit: '50' }) @@ -275,6 +277,21 @@ export default function Matches() { return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}` } + /** 未来 3 天窗口:今天 00:00 → 第 3 天 00:00(即今天/明天/后天) */ + function addDays(d: Date, n: number): string { + const x = new Date(d) + x.setFullYear(x.getFullYear(), x.getMonth(), x.getDate() + n) + return `${x.getFullYear()}-${String(x.getMonth() + 1).padStart(2, '0')}-${String(x.getDate()).padStart(2, '0')}` + } + const todayKey = todayStr() + const windowEnd = addDays(new Date(), 3) // 不含 + + /** 比赛是否在未来 3 天内(用于默认视图过滤) */ + function withinNext3Days(matchDate: string): boolean { + const key = toLocalDateKey(matchDate) + return key >= todayKey && key < windowEnd + } + /** UTC ISO → 本地日期 YYYY-MM-DD(用于分组) */ function toLocalDateKey(iso: string): string { const d = new Date(iso) @@ -346,6 +363,14 @@ export default function Matches() { const leagueName = LEAGUES.find(l => l.code === league)?.name ?? league + /** 未开赛默认仅展示未来 3 天;其余状态展示全部。showAllUpcoming=true 时展开全部。 */ + const isScheduledView = status === 'scheduled' + const visibleMatches = (!isScheduledView || showAllUpcoming) + ? matches + : matches.filter(m => withinNext3Days(m.match_date)) + // 是否有被折叠的未开赛比赛(用于显示「展开」按钮) + const hasHiddenUpcoming = isScheduledView && !showAllUpcoming && matches.length > visibleMatches.length + /** 状态/模式一组的文字切换 */ const Switch = ({ value, onChange, items }: { value: string @@ -420,7 +445,11 @@ export default function Matches() { - 共 {matches.length} 场 + + {isScheduledView && !showAllUpcoming && hasHiddenUpcoming + ? `未来3天 ${visibleMatches.length} / 共 ${matches.length} 场` + : `共 ${visibleMatches.length} 场`} + @@ -453,17 +482,26 @@ export default function Matches() {
{loading && } - {!loading && matches.length === 0 && ( + {!loading && visibleMatches.length === 0 && (
-

本版暂无赛程

-

请先通过「数据采集」导入 {leagueName} 的比赛数据

- - 前往数据采集 - + {matches.length > 0 ? ( + <> +

未来 3 天暂无 {leagueName} 比赛

+

已导入 {matches.length} 场未开赛,点击下方按钮查看

+ + ) : ( + <> +

本版暂无赛程

+

请先通过「数据采集」导入 {leagueName} 的比赛数据

+ + 前往数据采集 + + + )}
)} - {!loading && groupByDate(matches).map(([dateKey, group]) => ( + {!loading && groupByDate(visibleMatches).map(([dateKey, group]) => (
{/* 日期分组头:sticky 但 z 低于弹窗 z-50 */}
@@ -604,8 +642,32 @@ export default function Matches() {
))} + {/* 未开赛视图:从「未来 3 天」展开全部已加载的未开赛 */} + {!loading && hasHiddenUpcoming && ( +
+ +
+ )} + + {/* 已展开全部但未开赛:提供「收起」回未来 3 天 */} + {!loading && isScheduledView && showAllUpcoming && matches.length > 0 && ( +
+ +
+ )} + {!loading && nextCursor && ( -
+