From 77ecb078a3fb908ca8b253ae1acaf376504922e9 Mon Sep 17 00:00:00 2001 From: WorkBuddy Date: Tue, 22 Sep 2026 15:39:19 +0800 Subject: [PATCH] =?UTF-8?q?fix(admin):=20=E6=97=A5=E5=BF=97=E9=A1=B5?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E4=BF=9D=E6=8C=81=E5=80=92=E5=BA=8F,?= =?UTF-8?q?=E6=89=93=E5=BC=80=E8=87=AA=E5=8A=A8=E5=AE=9A=E4=BD=8D=E5=88=B0?= =?UTF-8?q?=E9=A1=B6=E9=83=A8(=E6=9C=80=E6=96=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 按用户预期调整方案:列表保持最新在最上面(后端倒序),打开页面/ 自动刷新时 scrollTop=0 定位顶部;向下滚动回看历史时暂停定位, 拉回顶部即恢复。替代上一版的时间正序+贴底方案。 --- frontend/src/admin/pages/Logs.tsx | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/frontend/src/admin/pages/Logs.tsx b/frontend/src/admin/pages/Logs.tsx index 28768e6..5aeb361 100644 --- a/frontend/src/admin/pages/Logs.tsx +++ b/frontend/src/admin/pages/Logs.tsx @@ -7,7 +7,7 @@ * - 缓冲上限 2000 条,进程重启后清零 */ -import { useEffect, useState, useCallback, useRef, useMemo } from 'react' +import { useEffect, useState, useCallback, useRef } from 'react' import { fetchLogs } from '../dal' import type { LogEntry } from '../types' import { Card, CardBody, CardHeader, Badge, SectionHeader, Alert, Spinner, SkeletonBlock } from '../components' @@ -53,24 +53,21 @@ export default function LogsPage() { }, [load]) const scrollRef = useRef(null) - const userScrolledUp = useRef(false) + const userScrolledDown = useRef(false) - // 检测用户是否向上滚动过 + // 检测用户是否向下滚动回看历史(旧日志在下方) const handleScroll = () => { const el = scrollRef.current if (!el) return - const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 50 - userScrolledUp.current = !atBottom + const atTop = el.scrollTop < 50 + userScrolledDown.current = !atTop } - // 后端返回最新在前;渲染转为时间正序(旧→新),配合「自动贴底」滚动: - // 打开页面/自动刷新默认定位到最新日志,用户上滚回看时暂停跟随 - const ordered = useMemo(() => [...entries].reverse(), [entries]) - - // 加载后自动滚动到底部(仅当用户未向上滚动时) + // 列表最新在最上面(后端倒序返回);打开页面/自动刷新时定位到顶部=最新。 + // 用户向下滚动回看历史时暂停定位,拉回顶部即恢复。 useEffect(() => { - if (autoRefresh && !userScrolledUp.current && scrollRef.current) { - scrollRef.current.scrollTop = scrollRef.current.scrollHeight + if (autoRefresh && !userScrolledDown.current && scrollRef.current) { + scrollRef.current.scrollTop = 0 } }, [entries, autoRefresh]) @@ -146,7 +143,7 @@ export default function LogsPage() {

暂无匹配的日志

) : (
- {ordered.map((e, i) => { + {entries.map((e, i) => { const badge = LEVEL_BADGE[e.level] ?? { status: 'info' as const, text: e.level } return (