diff --git a/src/modules/mileage/MonitoringView.tsx b/src/modules/mileage/MonitoringView.tsx index 0a07c9d..8890c2f 100644 --- a/src/modules/mileage/MonitoringView.tsx +++ b/src/modules/mileage/MonitoringView.tsx @@ -492,6 +492,7 @@ export default function MonitoringView() { const [hasMore, setHasMore] = useState(true); const [loadingMore, setLoadingMore] = useState(false); const [pageLoading, setPageLoading] = useState(true); + const [pageError, setPageError] = useState<{ message: string; scope: 'first' | 'more' } | null>(null); const [manualRefreshing, setManualRefreshing] = useState(false); const [lastRefreshedAt, setLastRefreshedAt] = useState(null); const [showBackToTop, setShowBackToTop] = useState(false); @@ -566,6 +567,7 @@ export default function MonitoringView() { // 加载首页数据 const loadFirstPage = useCallback((showPageLoading = true) => { if (showPageLoading) setPageLoading(true); + setPageError(null); return fetchMonitoring({ sortBy, sortOrder, @@ -597,7 +599,12 @@ export default function MonitoringView() { setPage(1); setHasMore(d.page < d.totalPages); setLastRefreshedAt(new Date()); - }).catch(() => {}).finally(() => { + }).catch(error => { + setPageError({ + message: error instanceof Error ? error.message : '里程数据加载失败,请稍后重试', + scope: 'first', + }); + }).finally(() => { if (showPageLoading) setPageLoading(false); }); }, [sortBy, sortOrder, searchTerm, filterDept, filterCustomer, filterProject, filterEntity, filterRentStatus, filterPlatePrefix, filterTargetNames, filterRegion, filterPlates, appliedMileageRange, rangeStart, rangeEnd, filterBrands, sourcePriority]); @@ -617,6 +624,7 @@ export default function MonitoringView() { if (loadingMore || !hasMore) return; const nextPage = page + 1; setLoadingMore(true); + setPageError(null); fetchMonitoring({ sortBy, sortOrder, @@ -642,7 +650,12 @@ export default function MonitoringView() { setVehicles(prev => [...prev, ...d.vehicles]); setPage(nextPage); setHasMore(nextPage < d.totalPages); - }).catch(() => {}).finally(() => setLoadingMore(false)); + }).catch(error => { + setPageError({ + message: error instanceof Error ? error.message : '更多车辆加载失败,请稍后重试', + scope: 'more', + }); + }).finally(() => setLoadingMore(false)); }, [sortBy, sortOrder, searchTerm, filterDept, filterCustomer, filterProject, filterEntity, filterRentStatus, filterPlatePrefix, filterTargetNames, filterRegion, filterPlates, appliedMileageRange, rangeStart, rangeEnd, page, loadingMore, hasMore, filterBrands, sourcePriority]); // 筛选/排序变化时重新加载 @@ -699,26 +712,6 @@ export default function MonitoringView() { return () => clearInterval(timer); }, [loadFirstPage]); - // 触底检测:用 IntersectionObserver 监听哨兵元素 - const loadMoreRef = useRef(loadMore); - loadMoreRef.current = loadMore; - const sentinelRef = useRef(null); - - useEffect(() => { - const sentinel = sentinelRef.current; - if (!sentinel) return; - const observer = new IntersectionObserver( - (entries) => { - if (entries[0].isIntersecting) { - loadMoreRef.current(); - } - }, - { rootMargin: '200px' } - ); - observer.observe(sentinel); - return () => observer.disconnect(); - }, []); - // 回到顶部按钮:用 IntersectionObserver 检测顶部哨兵是否离开视口 const topSentinelRef = useRef(null); useEffect(() => { @@ -1500,7 +1493,9 @@ export default function MonitoringView() {
车辆详情清单 - {total} 条 + + 已加载 {filteredVehicles.length} / 共 {total} 条 +
车牌 / 数据状态 @@ -1615,16 +1610,40 @@ export default function MonitoringView() { })}
- {filteredVehicles.length === 0 && !loadingMore && ( + {filteredVehicles.length === 0 && !loadingMore && !pageError && (

未找到匹配数据

)} - {/* 加载更多提示 */} - {loadingMore && ( -
- 加载中... + {pageError && ( +
+

{pageError.message}

+ +
+ )} + {hasMore && !pageError && filteredVehicles.length > 0 && ( +
+ + + 已加载 {filteredVehicles.length} / 共 {total} 条 +
)} {!hasMore && filteredVehicles.length > 0 && ( @@ -1632,8 +1651,6 @@ export default function MonitoringView() { 已加载全部 {total} 条
)} - {/* 哨兵元素:进入视口时触发加载更多 */} -