fix: show mileage query loading animation and bump version to 1.1.15
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
@@ -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" />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user