@@ -405,13 +405,23 @@ export default function DashboardPage() {
405405 } , [ ] ) ;
406406
407407 // 执行数据同步
408- const doSync = useCallback ( async ( showMessage = true , triggerRefresh = true ) => {
408+ const doSync = useCallback ( async ( showMessage = true , triggerRefresh = true , timeout = 60000 ) => {
409409 if ( syncingRef . current ) return ;
410410 syncingRef . current = true ;
411411 setSyncing ( true ) ;
412412 setSyncStatus ( null ) ;
413413 try {
414- const res = await fetch ( "/api/sync" , { method : "POST" , cache : "no-store" } ) ;
414+ // 创建超时控制器(默认 60 秒,首屏加载时为 5 秒)
415+ const controller = new AbortController ( ) ;
416+ const timeoutId = setTimeout ( ( ) => controller . abort ( ) , timeout ) ;
417+
418+ const res = await fetch ( "/api/sync" , {
419+ method : "POST" ,
420+ cache : "no-store" ,
421+ signal : controller . signal
422+ } ) ;
423+ clearTimeout ( timeoutId ) ;
424+
415425 const data = await res . json ( ) ;
416426 if ( ! res . ok ) {
417427 const errorMsg = `同步失败: ${ data . error || res . statusText } ` ;
@@ -446,7 +456,11 @@ export default function DashboardPage() {
446456 if ( triggerRefresh && inserted > 0 ) setRefreshTrigger ( ( prev ) => prev + 1 ) ;
447457 }
448458 } catch ( err ) {
449- const errorMsg = `同步失败: ${ ( err as Error ) . message } ` ;
459+ // 判断是否为超时错误
460+ const isTimeout = ( err as Error ) . name === "AbortError" ;
461+ const errorMsg = isTimeout
462+ ? "同步超时:数据同步可能需要更长时间,建议稍后手动刷新"
463+ : `同步失败: ${ ( err as Error ) . message } ` ;
450464 setSyncStatus ( errorMsg ) ;
451465 if ( typeof window !== "undefined" ) {
452466 window . localStorage . setItem ( "lastSyncStatus" , errorMsg ) ;
@@ -472,7 +486,7 @@ export default function DashboardPage() {
472486
473487 const run = async ( ) => {
474488 try {
475- await doSync ( true , false ) ;
489+ await doSync ( true , false , 5000 ) ; // 首屏加载使用 5 秒超时
476490 if ( typeof window !== "undefined" ) {
477491 window . sessionStorage . setItem ( autoSyncKey , "1" ) ;
478492 }
@@ -1007,7 +1021,7 @@ export default function DashboardPage() {
10071021 ) : null }
10081022 </ div >
10091023 { loadingOverview ? < span className = "text-sm text-slate-400" > 加载中...</ span > : null }
1010- { showEmpty ? < span className = "text-sm text-slate-400" > 暂无数据,先触发同步</ span > : null }
1024+ { /* { showEmpty ? <span className="text-sm text-slate-400">暂无数据,先触发同步</span> : null} */ }
10111025 </ div >
10121026
10131027 { /* 统计卡片 - 单行填满 */ }
@@ -2208,20 +2222,22 @@ export default function DashboardPage() {
22082222 { syncStatus && (
22092223 < div
22102224 onClick = { ( ) => closeSyncStatus ( ) }
2211- className = { `fixed right-6 top-24 z-50 cursor-pointer rounded-lg border px-4 py-3 shadow-lg transition-opacity hover:opacity-90 ${
2225+ className = { `fixed right-6 top-24 z-50 max-w-[290px] cursor-pointer rounded-lg border px-4 py-3 shadow-lg transition-opacity hover:opacity-90 ${
22122226 syncStatusClosing ? "animate-toast-out" : "animate-toast-in"
22132227 } ${
2214- syncStatus . includes ( "失败" )
2228+ syncStatus . includes ( "失败" ) || syncStatus . includes ( "超时" )
22152229 ? darkMode
2216- ? "border-red -500/40 bg-red-900/80 text-red-100 "
2217- : "border-red-400 bg-red -50 text-red-900 "
2230+ ? "border-rose -500/30 bg-rose-950/60 text-rose-200 "
2231+ : "border-rose-300 bg-rose -50 text-rose-800 "
22182232 : darkMode
22192233 ? "border-green-500/40 bg-green-900/80 text-green-100"
22202234 : "border-green-400 bg-green-50 text-green-900"
22212235 } `}
22222236 >
22232237 < div className = "flex items-center gap-2.5" >
2224- < span className = "text-xl animate-emoji-pop" > { syncStatus . includes ( "失败" ) ? "❌" : "✅" } </ span >
2238+ < span className = "text-xl animate-emoji-pop" >
2239+ { syncStatus . includes ( "失败" ) || syncStatus . includes ( "超时" ) ? "❌" : "✅" }
2240+ </ span >
22252241 < span className = "text-sm font-medium" > { syncStatus } </ span >
22262242 </ div >
22272243 </ div >
@@ -2230,7 +2246,7 @@ export default function DashboardPage() {
22302246 { saveStatus && (
22312247 < div
22322248 onClick = { ( ) => closeSaveStatus ( ) }
2233- className = { `fixed right-6 top-24 z-50 cursor-pointer rounded-lg border px-4 py-3 shadow-lg transition-opacity hover:opacity-90 ${
2249+ className = { `fixed right-6 top-24 z-50 max-w-[290px] cursor-pointer rounded-lg border px-4 py-3 shadow-lg transition-opacity hover:opacity-90 ${
22342250 saveStatusClosing ? "animate-toast-out" : "animate-toast-in"
22352251 } ${
22362252 darkMode
0 commit comments