fix: show mileage query loading animation and bump version to 1.1.15
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
shishengliang
2026-09-20 10:07:08 +08:00
parent b15951f08b
commit 61406497cc
6 changed files with 66 additions and 51 deletions
+15 -5
View File
@@ -12,6 +12,7 @@ import type {
import { fetchMonitoring } from './api';
import { exportMileageXlsx } from './xlsx-export';
import VehicleDetailModal from './VehicleDetailModal';
import MileageLoadingOverlay from './MileageLoadingOverlay';
import {
defaultMileageDate,
getRangePreset,
@@ -148,10 +149,14 @@ export default function MonitoringView() {
return inAlertTarget && Math.max(0, v.dailyKm || 0) >= HIGH_MILEAGE_ALERT_KM;
}, [filterTargetNames]);
const queryRequestRef = useRef(0);
// 加载首页数据
const loadFirstPage = useCallback((showPageLoading = true) => {
const requestId = ++queryRequestRef.current;
if (showPageLoading) setPageLoading(true);
return fetchMonitoring(buildInitialMonitoringQuery(monitoringQuery, PAGE_SIZE)).then(d => {
if (requestId !== queryRequestRef.current) return;
setVehicles(d.vehicles);
setStats(d.stats);
setFilterOptions(d.filters);
@@ -162,31 +167,33 @@ export default function MonitoringView() {
setHasMore(d.page < d.totalPages);
setLastRefreshedAt(new Date());
}).catch(() => {}).finally(() => {
if (showPageLoading) setPageLoading(false);
if (requestId === queryRequestRef.current) setPageLoading(false);
});
}, [monitoringQuery, rangeStart, rangeEnd]);
const handleManualRefresh = useCallback(async () => {
if (manualRefreshing) return;
if (manualRefreshing || pageLoading) return;
setManualRefreshing(true);
try {
await loadFirstPage(false);
} finally {
setManualRefreshing(false);
}
}, [loadFirstPage, manualRefreshing]);
}, [loadFirstPage, manualRefreshing, pageLoading]);
// 加载更多
const loadMore = useCallback(() => {
if (loadingMore || !hasMore) return;
if (pageLoading || loadingMore || !hasMore) return;
const requestId = queryRequestRef.current;
const nextPage = page + 1;
setLoadingMore(true);
fetchMonitoring(buildNextPageMonitoringQuery(monitoringQuery, PAGE_SIZE, nextPage)).then(d => {
if (requestId !== queryRequestRef.current) return;
setVehicles(prev => [...prev, ...d.vehicles]);
setPage(nextPage);
setHasMore(nextPage < d.totalPages);
}).catch(() => {}).finally(() => setLoadingMore(false));
}, [monitoringQuery, page, loadingMore, hasMore]);
}, [monitoringQuery, page, pageLoading, loadingMore, hasMore]);
// 筛选/排序变化时重新加载
useEffect(() => {
@@ -302,6 +309,9 @@ export default function MonitoringView() {
return (
<>
<AnimatePresence>
{pageLoading && <MileageLoadingOverlay />}
</AnimatePresence>
{/* 顶部哨兵:离开视口时显示回到顶部按钮 */}
<div ref={topSentinelRef} className="h-0" />