From 75679e76c511cf4bbf20cb7879264009afa5e4fe Mon Sep 17 00:00:00 2001 From: JSR Date: Fri, 20 Mar 2026 17:34:27 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=94=B9=E4=B8=BA=E8=BF=9C=E7=AB=AF?= =?UTF-8?q?=E4=BC=98=E5=85=88=E5=AE=9E=E6=97=B6=E9=95=9C=E5=83=8F=E5=B9=B6?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E8=87=AA=E5=8A=A8=E5=90=8C=E6=AD=A5=E5=8F=8D?= =?UTF-8?q?=E5=90=91=E8=A6=86=E7=9B=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/commands/database.rs | 42 ++++++++++++++++++++---------- src/App.tsx | 4 +-- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src-tauri/src/commands/database.rs b/src-tauri/src/commands/database.rs index 545209c..864a2cb 100644 --- a/src-tauri/src/commands/database.rs +++ b/src-tauri/src/commands/database.rs @@ -598,24 +598,38 @@ pub async fn realtime_dual_write_sync(app_state: &Arc>) -> Resu state_guard.app_handle.clone() }; - let can_sync = current_remote_and_local_from_state(&app_handle, app_state) - .await? - .is_some(); - if !can_sync { + let Some((local_conn, remote_conn)) = + current_remote_and_local_from_state(&app_handle, app_state).await? + else { return Ok(()); + }; + + // PostgreSQL 远端为主库,实时同步只做远端 -> 本地镜像,避免本地旧快照反向覆盖远端新值。 + let remote_students = load_students(&remote_conn).await?; + for student in remote_students.values() { + let _ = upsert_student(&local_conn, student).await?; } - let result = db_sync_apply_internal( - ConflictStrategy::KeepRemote, - app_handle, - app_state.clone(), - ) - .await?; - if !result.success { - return Err(result - .message - .unwrap_or_else(|| "实时双写同步失败".to_string())); + let remote_reasons = load_reasons(&remote_conn).await?; + for reason in remote_reasons.values() { + let _ = upsert_reason(&local_conn, reason).await?; } + + let remote_tags = load_tags(&remote_conn).await?; + for tag in remote_tags.values() { + let _ = upsert_tag(&local_conn, tag).await?; + } + + let remote_events = load_events(&remote_conn).await?; + for event in remote_events.values() { + let _ = upsert_event(&local_conn, event).await?; + } + + let remote_pairs = load_student_tag_pairs(&remote_conn).await?; + for pair in &remote_pairs { + let _ = ensure_student_tag_pair(&local_conn, pair).await?; + } + Ok(()) } diff --git a/src/App.tsx b/src/App.tsx index 4bbd0f3..2149edf 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -189,7 +189,7 @@ function MainContent(): React.JSX.Element { if (conflicts.length > 0) { const recentLocalMutation = Date.now() - lastLocalMutationAtRef.current < 15000 if (recentLocalMutation) { - const autoApplyRes = await api.dbSyncApply("keep_local") + const autoApplyRes = await api.dbSyncApply("keep_remote") if ( autoApplyRes?.success && autoApplyRes?.data?.success && @@ -206,7 +206,7 @@ function MainContent(): React.JSX.Element { return } - const applyRes = await api.dbSyncApply("keep_local") + const applyRes = await api.dbSyncApply("keep_remote") if (applyRes?.success && applyRes?.data?.success && applyRes?.data?.synced_records > 0) { window.dispatchEvent( new CustomEvent("ss:data-updated", { detail: { category: "all", source: "sync" } })